本次提交包含多项核心功能迭代与优化: 1. 新增KF客服会话类型,完善聊天类型枚举 2. 新增消息撤回操作类型与身份置信度排序方法 3. 新增控制面结果DTO与敏感字段注册表端口 4. 新增身份合并回滚、重试失败投递目标等业务能力 5. 优化Outbox投递逻辑与熔断器状态判断 6. 修复部分代码冗余与类型不匹配问题 7. 新增数据库索引并发创建与路由绑定清理逻辑 8. 优化会话关闭服务与插件重载并发控制
752 lines
27 KiB
Python
752 lines
27 KiB
Python
"""配置 schema 元数据契约层定义。
|
||
|
||
定义配置字段的完整 schema 元数据(``CONFIG_SCHEMA``),包括键、类型、
|
||
是否必填、默认值、是否可热更新与约束,作为配置 schema 的唯一真相源
|
||
(§13.1 配置分层 / §6.1 契约层职责)。适配器(如 ``RedisConfigAdapter``)
|
||
与应用层(如 ``ConfigManager``)共享引用本模块,消除 schema 元数据
|
||
下沉至适配器层的 DRY 违反。
|
||
|
||
``HOT_RELOADABLE_KEYS`` / ``NON_HOT_RELOADABLE_KEYS`` 从 ``CONFIG_SCHEMA``
|
||
派生,供 ``ConfigManager`` 做热更新策略校验(ADP-030)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from yuxi.channels.contract.dtos.config import ConfigField, ConfigScope
|
||
|
||
# 配置 schema:全部配置字段的完整元数据(FR-37 配置热更新)。
|
||
# 48 个可热更新字段 + 14 个不可热更新字段,共 62 个。
|
||
# 字段顺序:先可热更新(hot_reloadable=True),后不可热更新(hot_reloadable=False)。
|
||
CONFIG_SCHEMA: tuple[ConfigField, ...] = (
|
||
# === 可热更新字段(hot_reloadable=True)===
|
||
ConfigField(
|
||
key="dm_policy",
|
||
type="json",
|
||
required=False,
|
||
default="allow",
|
||
hot_reloadable=True,
|
||
title="私信策略",
|
||
description="控制私信/群聊的自动回复与路由策略,如是否允许陌生人私信、是否自动创建会话等。",
|
||
category="消息策略",
|
||
),
|
||
ConfigField(
|
||
key="allow_from",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
title="来源白名单",
|
||
description="允许向当前账户发起对话的对端白名单,未配置时不限制。",
|
||
category="访问控制",
|
||
),
|
||
ConfigField(
|
||
key="rate_limit",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
title="消息限流",
|
||
description="控制账户级别的消息发送频率限制,防止滥用或触发渠道风控。",
|
||
category="限流与预算",
|
||
),
|
||
ConfigField(
|
||
key="bot_loop_budget",
|
||
type="json",
|
||
required=False,
|
||
default={"max_replies_per_hour": 20, "cooldown_seconds": 60},
|
||
hot_reloadable=True,
|
||
title="Bot 循环预算",
|
||
description=(
|
||
"Bot 循环预算配置,包含 max_replies_per_hour"
|
||
"(每小时最大回复数,≤0 表示不限制)和 cooldown_seconds(冷却秒数)。"
|
||
),
|
||
category="限流与预算",
|
||
),
|
||
# FR-08~14 功能开关(Task 30)
|
||
ConfigField(
|
||
key="rich_message_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="富消息开关",
|
||
description="是否启用富媒体消息(卡片、按钮等)发送能力。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="status_writeback_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="状态回写开关",
|
||
description="是否将渠道用户状态(在线/离开等)回写到知识库。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="agent_prompt_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="Agent 提示开关",
|
||
description="是否在消息中附加 Agent 提示上下文。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="channel_tools_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="渠道工具开关",
|
||
description="是否允许 Agent 调用渠道相关工具。",
|
||
category="功能开关",
|
||
),
|
||
# AC-22: 消息操作开关默认"开"(FR-12)
|
||
ConfigField(
|
||
key="message_ops_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
title="消息操作开关",
|
||
description="总开关:是否启用消息操作(反应、置顶、卡片更新等)。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="streaming_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="流式响应开关",
|
||
description="是否启用流式(打字机效果)响应输出。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="enable_typing",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
title="输入中提示开关",
|
||
description="是否向用户展示'正在输入'状态提示。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="directory_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
title="目录服务开关",
|
||
description="是否启用渠道目录(用户/群组列表)查询能力。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="command_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
title="命令处理开关",
|
||
description="是否启用以 command_prefix 开头的命令解析与处理。",
|
||
category="功能开关",
|
||
),
|
||
# FR-12 消息操作细粒度开关(PRD §FR-12 配置项)。
|
||
# AC-22 默认行为:表情反应"开"、置顶"关"、卡片更新"关"。
|
||
ConfigField(
|
||
key="enable_reaction",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
title="表情反应开关",
|
||
description="是否允许对消息添加表情反应。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="enable_pin",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="消息置顶开关",
|
||
description="是否允许置顶/取消置顶消息。",
|
||
category="功能开关",
|
||
),
|
||
ConfigField(
|
||
key="enable_card_update",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="卡片更新开关",
|
||
description="是否允许更新已发送的卡片消息。",
|
||
category="功能开关",
|
||
),
|
||
# FR-15 管理员命令权限白名单(账户级,JSON 数组,存放允许执行 ADMIN 权限命令的 peer_id)
|
||
ConfigField(
|
||
key="admin_users",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="管理员白名单",
|
||
description="允许执行 ADMIN 权限命令的 peer_id 列表,账户级配置。",
|
||
category="身份与权限",
|
||
),
|
||
# FR-29 入站提及策略(账户级,JSON,含 allowed_implicit_kinds 列表,
|
||
# 控制哪些隐式提及类型被视为"已提及",未配置时默认空策略)
|
||
ConfigField(
|
||
key="mention_policy",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="提及策略",
|
||
description="控制哪些隐式提及类型被视为'已提及',影响命令触发与会话路由。",
|
||
category="消息策略",
|
||
),
|
||
# FR-07 会话合并策略开关(默认禁用)
|
||
ConfigField(
|
||
key="merge_strategy_enabled",
|
||
type="bool",
|
||
required=False,
|
||
default=False,
|
||
hot_reloadable=True,
|
||
title="会话合并开关",
|
||
description="是否启用按策略自动合并会话。",
|
||
category="会话策略",
|
||
),
|
||
# FR-06 跨渠道身份策略(默认隔离,可选 association 开启跨渠道关联)
|
||
ConfigField(
|
||
key="cross_channel_identity_strategy",
|
||
type="str",
|
||
required=False,
|
||
default="isolation",
|
||
hot_reloadable=True,
|
||
title="跨渠道身份策略",
|
||
description="跨渠道身份关联策略:isolation(隔离)或 association(关联)。",
|
||
category="身份与权限",
|
||
),
|
||
# 可配置值(Task 30)
|
||
ConfigField(
|
||
key="command_prefix",
|
||
type="str",
|
||
required=False,
|
||
default="/",
|
||
hot_reloadable=True,
|
||
title="命令前缀",
|
||
description="命令触发前缀,默认为 '/'。",
|
||
category="命令与交互",
|
||
),
|
||
ConfigField(
|
||
key="fence_ttl_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=120,
|
||
hot_reloadable=True,
|
||
title="围栏 TTL",
|
||
description="对话围栏(fence)的默认过期时间(秒)。",
|
||
category="命令与交互",
|
||
),
|
||
ConfigField(
|
||
key="streaming_min_chunk_interval_ms",
|
||
type="int",
|
||
required=False,
|
||
default=200,
|
||
hot_reloadable=True,
|
||
title="流式最小间隔",
|
||
description="流式响应相邻分块之间的最小间隔(毫秒)。",
|
||
category="流式与传输体验",
|
||
),
|
||
ConfigField(
|
||
key="streaming_ttl_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=60,
|
||
hot_reloadable=True,
|
||
title="流式 TTL",
|
||
description="流式响应状态的最大保留时间(秒)。",
|
||
category="流式与传输体验",
|
||
),
|
||
ConfigField(
|
||
key="typing_ttl_ms",
|
||
type="int",
|
||
required=False,
|
||
default=10000,
|
||
hot_reloadable=True,
|
||
title="输入提示 TTL",
|
||
description="'正在输入'提示状态的最大持续时间(毫秒)。",
|
||
category="流式与传输体验",
|
||
),
|
||
ConfigField(
|
||
key="durability_policy_default",
|
||
type="str",
|
||
required=False,
|
||
default="required",
|
||
hot_reloadable=True,
|
||
title="默认持久化策略",
|
||
description="消息默认持久化策略:required / best_effort / none。",
|
||
category="可靠性",
|
||
),
|
||
# FR-24 分阶段 ACK 策略(PRD §FR-24)。
|
||
# 四阶段策略:after_record / after_agent_dispatch / after_persist / manual,
|
||
# 默认 after_agent_dispatch(平衡可靠性与响应速度)。
|
||
ConfigField(
|
||
key="ack_policy",
|
||
type="str",
|
||
required=False,
|
||
default="after_agent_dispatch",
|
||
hot_reloadable=True,
|
||
title="ACK 策略",
|
||
description="分阶段 ACK 策略:after_record / after_agent_dispatch / after_persist / manual。",
|
||
category="可靠性",
|
||
),
|
||
# 手动策略下插件忘记 ACK 时核心兜底超时(默认 60s)自动 ACK。
|
||
ConfigField(
|
||
key="ack_fallback_timeout_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=60,
|
||
hot_reloadable=True,
|
||
title="ACK 兜底超时",
|
||
description="手动 ACK 策略下,插件忘记 ACK 时核心自动 ACK 的超时时间(秒)。",
|
||
category="可靠性",
|
||
),
|
||
# 传输引擎配置
|
||
ConfigField(
|
||
key="transport.stall_timeout_ms",
|
||
type="int",
|
||
required=False,
|
||
default=120000,
|
||
hot_reloadable=True,
|
||
title="传输停滞超时",
|
||
description="传输流判定为停滞的超时时间(毫秒)。",
|
||
category="传输引擎",
|
||
),
|
||
ConfigField(
|
||
key="transport.backoff_schedule",
|
||
type="str",
|
||
required=False,
|
||
default="1,2,5,10,30",
|
||
hot_reloadable=True,
|
||
title="传输退避序列",
|
||
description="传输重试的退避时间序列,逗号分隔的秒数列表。",
|
||
category="传输引擎",
|
||
),
|
||
ConfigField(
|
||
key="transport.backoff_jitter",
|
||
type="float",
|
||
required=False,
|
||
default=0.2,
|
||
hot_reloadable=True,
|
||
title="传输退避抖动",
|
||
description="传输重试退避的随机抖动系数。",
|
||
category="传输引擎",
|
||
),
|
||
# StreamWorker 断线重连指数退避参数(Task 10.3),与 TransportConfig
|
||
# DTO 字段一一对应,由 base_worker._loadConfig 通过 ConfigPort 读取。
|
||
ConfigField(
|
||
key="transport.stream_reconnect_backoff_ms",
|
||
type="int",
|
||
required=False,
|
||
default=1000,
|
||
hot_reloadable=True,
|
||
title="流重连初始退避",
|
||
description="StreamWorker 断线重连的指数退避基数(毫秒),每次重连翻倍直至达到最大退避上限。",
|
||
category="传输引擎",
|
||
),
|
||
ConfigField(
|
||
key="transport.stream_reconnect_max_backoff_ms",
|
||
type="int",
|
||
required=False,
|
||
default=30000,
|
||
hot_reloadable=True,
|
||
title="流重连最大退避",
|
||
description="StreamWorker 断线重连指数退避的上限(毫秒),避免退避时间无限增长。",
|
||
category="传输引擎",
|
||
),
|
||
# FR-22 Outbox 重试策略(OBX-POLICY-UPDATE),JSON 格式:
|
||
# {"max_retry": int, "ttl_seconds": int, "retry_backoff_schedule": [int, ...]}
|
||
# 由 OutboxHandler.updateRetryPolicy 双写到 ConfigPort(Redis),
|
||
# 支持跨请求 / 跨进程最终一致性。
|
||
ConfigField(
|
||
key="outbox_retry_policy",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
title="Outbox 重试策略",
|
||
description="出站消息重试策略,包含 max_retry / ttl_seconds / retry_backoff_schedule。",
|
||
category="可靠性",
|
||
),
|
||
# FR-22 Outbox Scanner-Worker 协调(Task 10):Scanner 判定
|
||
# SENT_UNCONFIRMED 无回执超时与 Worker 重试锁 TTL,原为硬编码
|
||
# 300s/60s,现统一收敛至 CONFIG_SCHEMA,支持热更新。
|
||
ConfigField(
|
||
key="outbox_sent_unconfirmed_timeout_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=300,
|
||
hot_reloadable=True,
|
||
title="Outbox SENT_UNCONFIRMED 超时(秒)",
|
||
description="Scanner 判定 SENT_UNCONFIRMED 消息无回执的超时秒数,超过此时间视为可能已发送但无回执",
|
||
category="可靠性",
|
||
),
|
||
ConfigField(
|
||
key="outbox_retry_lock_ttl_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=60,
|
||
hot_reloadable=True,
|
||
title="Outbox 重试锁 TTL(秒)",
|
||
description="Worker 单条消息重试的分布式锁 TTL,覆盖一次网络调用+DB持久化+事件发布的完整周期",
|
||
category="可靠性",
|
||
),
|
||
# === 渠道用户与 Agent 交互链路优化(Task 6/7/8)===
|
||
# 身份解析置信度阈值(账户级,scope=ACCOUNT),低于此阈值的解析结果视为
|
||
# 未命中,进入 channel_guest 身份生成路径。缺口补齐:原 _getThreshold
|
||
# 使用硬编码默认值,现统一收敛至 CONFIG_SCHEMA。
|
||
ConfigField(
|
||
key="identity_confidence_threshold",
|
||
type="float",
|
||
required=False,
|
||
default=0.5,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="身份置信度阈值",
|
||
description="身份解析结果低于此阈值时视为未命中,进入 channel_guest 生成路径。",
|
||
category="身份与权限",
|
||
),
|
||
# 新建 Agent 的默认渠道访问级别(全局级,scope=GLOBAL),取值如
|
||
# "none" / "read" / "write" 等,由 Agent 创建流程读取。
|
||
ConfigField(
|
||
key="channel_access_default_level",
|
||
type="str",
|
||
required=False,
|
||
default="none",
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="默认渠道访问级别",
|
||
description="新建 Agent 默认的渠道访问级别,如 none / read / write。",
|
||
category="身份与权限",
|
||
),
|
||
# 渠道访客身份置信度(全局级,scope=GLOBAL),channel_guest 身份生成时
|
||
# 使用此置信度,低于 identity_confidence_threshold 以避免被误判为
|
||
# 已解析身份。
|
||
ConfigField(
|
||
key="channel_guest_confidence",
|
||
type="float",
|
||
required=False,
|
||
default=0.3,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="访客身份置信度",
|
||
description="channel_guest 身份生成时使用的置信度,应低于身份置信度阈值。",
|
||
category="身份与权限",
|
||
),
|
||
# 是否启用管理员手动绑定功能(全局级,scope=GLOBAL),控制渠道用户与
|
||
# 统一身份的手动绑定入口是否可用。
|
||
ConfigField(
|
||
key="enable_channel_user_binding",
|
||
type="bool",
|
||
required=False,
|
||
default=True,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="手动绑定开关",
|
||
description="是否启用管理员手动绑定渠道用户与统一身份的功能入口。",
|
||
category="身份与权限",
|
||
),
|
||
# === 渠道账号运营流程优化(Task 14:契约层 CONFIG_SCHEMA 健康检查配置键)===
|
||
# 以下 2 个键均为渠道级(scope=CHANNEL),归属 ConfigPort(Redis 热重载,
|
||
# CHANNEL 业务策略体系),不得声明在 app_config。
|
||
# 凭证失效计数阈值。健康检查探活返回 401/403 时计入凭证失效计数,
|
||
# 达阈值后调聚合根 markFailed。窗口外(credential_failure_window_seconds)
|
||
# 重置计数。
|
||
ConfigField(
|
||
key="credential_failure_threshold",
|
||
type="int",
|
||
required=False,
|
||
default=3,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.CHANNEL,
|
||
title="凭证失效阈值",
|
||
description="健康检查中凭证失效计数的阈值。",
|
||
category="健康检查",
|
||
),
|
||
# 凭证失效计数窗口(秒)。窗口外的失效计数被重置,避免历史故障永久影响账号状态。
|
||
ConfigField(
|
||
key="credential_failure_window_seconds",
|
||
type="int",
|
||
required=False,
|
||
default=300,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.CHANNEL,
|
||
title="凭证失效窗口",
|
||
description="凭证失效计数的滑动窗口时长(秒)。",
|
||
category="健康检查",
|
||
),
|
||
# 审计日志保留策略(全局级,scope=GLOBAL)。JSON 格式:
|
||
# {"retention_days": int, "cleanup_interval_hours": int}
|
||
# 控制审计日志的保留天数与清理周期,由审计清理任务读取。
|
||
ConfigField(
|
||
key="audit_retention_policy",
|
||
type="json",
|
||
required=False,
|
||
default={"retention_days": 90, "cleanup_interval_hours": 24},
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="审计保留策略",
|
||
description="审计日志保留天数与清理周期配置,JSON 格式。",
|
||
category="审计与登录",
|
||
),
|
||
# 扫码登录重定向 URI(全局级,scope=GLOBAL)。扫码登录成功后的前端跳转地址,
|
||
# 为空时使用默认跳转行为。
|
||
ConfigField(
|
||
key="qr_login_redirect_uri",
|
||
type="str",
|
||
required=False,
|
||
default="",
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="扫码登录跳转地址",
|
||
description="扫码登录成功后的前端跳转地址。",
|
||
category="审计与登录",
|
||
),
|
||
# 渠道熔断器配置(GLOBAL 作用域),由 ChannelCircuitBreaker 读取。
|
||
# 包含连续失败阈值与恢复超时时间;未配置时使用组件内默认值。
|
||
ConfigField(
|
||
key="circuit_breaker",
|
||
type="json",
|
||
required=False,
|
||
default={"threshold": 5, "recovery_timeout": 60.0},
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.GLOBAL,
|
||
title="渠道熔断器配置",
|
||
description="渠道 API 熔断器参数,包含连续失败阈值与恢复超时时间。",
|
||
category="可靠性",
|
||
),
|
||
# === 不可热更新字段(hot_reloadable=False)===
|
||
ConfigField(
|
||
key="webhook_port",
|
||
type="int",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
title="Webhook 端口",
|
||
description="渠道 Webhook 服务监听端口。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="webhook_secret",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
title="Webhook 密钥",
|
||
description="渠道 Webhook 签名验证密钥,敏感字段。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="tls_cert",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
title="TLS 证书",
|
||
description="TLS 证书内容,敏感字段。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="tls_key",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
title="TLS 私钥",
|
||
description="TLS 私钥内容,敏感字段。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="plugin_entry",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
title="插件入口",
|
||
description="插件入口模块路径。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="database_url",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
title="数据库地址",
|
||
description="业务数据库连接地址,敏感字段。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="redis_url",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
title="Redis 地址",
|
||
description="Redis 连接地址,敏感字段。",
|
||
category="基础设施",
|
||
),
|
||
ConfigField(
|
||
key="transport.max_restart_attempts",
|
||
type="int",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
title="最大重启尝试",
|
||
description="传输进程异常后的最大重启次数。",
|
||
category="传输引擎",
|
||
),
|
||
ConfigField(
|
||
key="transport.graceful_shutdown_timeout_s",
|
||
type="float",
|
||
required=False,
|
||
default=10.0,
|
||
hot_reloadable=False,
|
||
title="优雅关闭超时",
|
||
description="传输进程优雅关闭的最大等待时间(秒)。",
|
||
category="传输引擎",
|
||
),
|
||
# === 渠道账号运营流程优化(Task 3:契约层 CONFIG_SCHEMA 凭证配置键)===
|
||
# 以下 3 个键均为账户级(scope=ACCOUNT),归属 ConfigPort(Redis 热重载,
|
||
# CHANNEL 业务策略/toggles/TTLs 体系),不得声明在 app_config。
|
||
# 凭证包,敏感字段加密存储。由 CredentialService 唯一写入入口维护,
|
||
# 包含 bot_token/app_secret/user_access_token 等渠道认证凭证。
|
||
ConfigField(
|
||
key="credentials",
|
||
type="dict",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="渠道凭证包",
|
||
description="渠道认证凭证集合,敏感字段。",
|
||
category="凭证与登录态",
|
||
),
|
||
# 登录态:unlogged/logging_in/logged_in/logout_failed。由 QrLoginService
|
||
# 通过 ConfigPort 维护,区分扫码会话状态与最终凭证落库状态。
|
||
ConfigField(
|
||
key="login_status",
|
||
type="str",
|
||
required=False,
|
||
default="unlogged",
|
||
hot_reloadable=False,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="登录状态",
|
||
description="当前账户扫码登录状态。",
|
||
category="凭证与登录态",
|
||
),
|
||
# 凭证版本号,每次 rotateCredentials 自增。用于乐观锁控制与缓存失效判定。
|
||
ConfigField(
|
||
key="credential_version",
|
||
type="int",
|
||
required=False,
|
||
default=0,
|
||
hot_reloadable=False,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="凭证版本",
|
||
description="凭证轮换版本号,用于乐观锁与缓存失效。",
|
||
category="凭证与登录态",
|
||
),
|
||
# FR17-P0-3 已应用迁移列表(ACCOUNT 作用域,target=channel_type 或
|
||
# {channel_type}:{account_id})。由 PluginLifecycleManager 在插件 onStart
|
||
# 成功后追加 manifest.version 标记配置已加载,DoctorService 只读不写。
|
||
# hot_reloadable=False:非业务策略,启动期写入,无需热更新。
|
||
# default=[] 让首次加载时 ConfigPort.get 返回空列表而非 NotFoundError,
|
||
# 避免 PluginLifecycleManager 与 DoctorService 的 catch 块接不到异常。
|
||
ConfigField(
|
||
key="applied_migrations",
|
||
type="json",
|
||
required=False,
|
||
default=[],
|
||
hot_reloadable=False,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="已应用迁移",
|
||
description="账户已应用的插件迁移版本列表。",
|
||
category="凭证与登录态",
|
||
),
|
||
# 渠道命令声明(CHANNEL 作用域),由各渠道 CommandAdapter 读取。
|
||
# 存储命令列表 JSON,未配置时适配器回退为内置默认命令。
|
||
ConfigField(
|
||
key="commands",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.CHANNEL,
|
||
title="渠道命令列表",
|
||
description="渠道自定义命令声明,未配置时使用内置默认命令。",
|
||
category="功能开关",
|
||
),
|
||
# 安装向导状态(CHANNEL 作用域),由 WizardService 读写。
|
||
# 存储已应用步骤的配置补丁聚合,支持跨会话恢复向导进度。
|
||
ConfigField(
|
||
key="wizard_state",
|
||
type="json",
|
||
required=False,
|
||
default={},
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.CHANNEL,
|
||
title="向导状态",
|
||
description="安装向导已应用步骤的配置补丁聚合,用于跨会话恢复向导进度。",
|
||
category="运营流程",
|
||
),
|
||
# 安装向导最终配置(CHANNEL 作用域),由 WizardService.finalize 写入。
|
||
# 存储向导聚合后的完整渠道配置,供账户创建后运行时读取。
|
||
ConfigField(
|
||
key="channel_config",
|
||
type="json",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=True,
|
||
scope=ConfigScope.CHANNEL,
|
||
title="渠道向导配置",
|
||
description="安装向导 finalize 后写入的聚合渠道配置,供运行时读取。",
|
||
category="运营流程",
|
||
),
|
||
# 用户级访问令牌(ACCOUNT 作用域),由 LoginAdapter 在登出时读取。
|
||
# 企业微信 OAuth 无独立 user_access_token,此键供 logout 检测登录态存在性。
|
||
ConfigField(
|
||
key="user_access_token",
|
||
type="str",
|
||
required=False,
|
||
default=None,
|
||
hot_reloadable=False,
|
||
sensitive=True,
|
||
scope=ConfigScope.ACCOUNT,
|
||
title="用户访问令牌",
|
||
description="用户级 OAuth 访问令牌,用于登录态检测与登出清理。",
|
||
category="凭证与登录态",
|
||
),
|
||
)
|
||
|
||
# 可热更新的配置项键集合(FR-37),从 CONFIG_SCHEMA 派生。
|
||
HOT_RELOADABLE_KEYS = frozenset(f.key for f in CONFIG_SCHEMA if f.hot_reloadable)
|
||
|
||
# 不可热更新的配置项键集合(FR-37),从 CONFIG_SCHEMA 派生。
|
||
NON_HOT_RELOADABLE_KEYS = frozenset(f.key for f in CONFIG_SCHEMA if not f.hot_reloadable)
|
||
|
||
__all__ = ["CONFIG_SCHEMA", "HOT_RELOADABLE_KEYS", "NON_HOT_RELOADABLE_KEYS"]
|