ForcePilot/backend/package/yuxi/channels/contract/policy/config_schema.py

153 lines
12 KiB
Python
Raw Normal View History

"""配置 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
# 配置 schema全部配置字段的完整元数据FR-37 配置热更新)。
# 40 个可热更新字段 + 13 个不可热更新字段,共 53 个。
# 字段顺序先可热更新hot_reloadable=True后不可热更新hot_reloadable=False
CONFIG_SCHEMA: tuple[ConfigField, ...] = (
# === 可热更新字段hot_reloadable=True===
ConfigField(key="dm_policy", type="json", required=False, default=None, hot_reloadable=True),
ConfigField(key="allow_from", type="json", required=False, default=None, hot_reloadable=True),
ConfigField(key="rate_limit", type="json", required=False, default=None, hot_reloadable=True),
ConfigField(key="bot_loop_budget", type="int", required=False, default=0, hot_reloadable=True),
# FR-08~14 功能开关Task 30
ConfigField(key="rich_message_enabled", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="status_writeback_enabled", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="agent_prompt_enabled", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="channel_tools_enabled", type="bool", required=False, default=False, hot_reloadable=True),
# AC-22: 消息操作开关默认"开"FR-12
ConfigField(key="message_ops_enabled", type="bool", required=False, default=True, hot_reloadable=True),
ConfigField(key="streaming_enabled", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="enable_typing", type="bool", required=False, default=True, hot_reloadable=True),
ConfigField(key="directory_enabled", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="command_enabled", type="bool", required=False, default=True, hot_reloadable=True),
# FR-12 消息操作细粒度开关PRD §FR-12 配置项)。
# AC-22 默认行为:表情反应"开"、置顶"关"、卡片更新"关"。
ConfigField(key="enable_reaction", type="bool", required=False, default=True, hot_reloadable=True),
ConfigField(key="enable_pin", type="bool", required=False, default=False, hot_reloadable=True),
ConfigField(key="enable_card_update", type="bool", required=False, default=False, hot_reloadable=True),
# FR-15 管理员命令权限白名单账户级JSON 数组,存放允许执行 ADMIN 权限命令的 peer_id
ConfigField(key="admin_users", type="json", required=False, default=None, hot_reloadable=True),
# FR-29 入站提及策略账户级JSON含 allowed_implicit_kinds 列表,
# 控制哪些隐式提及类型被视为"已提及",未配置时默认空策略)
ConfigField(key="mention_policy", type="json", required=False, default=None, hot_reloadable=True),
# FR-07 会话合并策略开关(默认禁用)
ConfigField(key="merge_strategy_enabled", type="bool", required=False, default=False, hot_reloadable=True),
# FR-06 跨渠道身份策略(默认隔离,可选 association 开启跨渠道关联)
ConfigField(
key="cross_channel_identity_strategy", type="str", required=False, default="isolation", hot_reloadable=True
),
# 可配置值Task 30
ConfigField(key="command_prefix", type="str", required=False, default="/", hot_reloadable=True),
ConfigField(key="fence_ttl_seconds", type="int", required=False, default=120, hot_reloadable=True),
ConfigField(key="streaming_min_chunk_interval_ms", type="int", required=False, default=200, hot_reloadable=True),
ConfigField(key="streaming_ttl_seconds", type="int", required=False, default=60, hot_reloadable=True),
ConfigField(key="typing_ttl_ms", type="int", required=False, default=10000, hot_reloadable=True),
ConfigField(key="durability_policy_default", type="str", required=False, default="required", hot_reloadable=True),
# 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),
# 手动策略下插件忘记 ACK 时核心兜底超时(默认 60s自动 ACK。
ConfigField(key="ack_fallback_timeout_seconds", type="int", required=False, default=60, hot_reloadable=True),
# 传输引擎配置
ConfigField(key="transport.stall_timeout_ms", type="int", required=False, default=120000, hot_reloadable=True),
ConfigField(
key="transport.backoff_schedule", type="str", required=False, default="1,2,5,10,30", hot_reloadable=True
),
ConfigField(key="transport.backoff_jitter", type="float", required=False, default=0.2, hot_reloadable=True),
# FR-22 Outbox 重试策略OBX-POLICY-UPDATEJSON 格式:
# {"max_retry": int, "ttl_seconds": int, "retry_backoff_schedule": [int, ...]}
# 由 OutboxHandler.updateRetryPolicy 双写到 ConfigPortRedis
# 支持跨请求 / 跨进程最终一致性。
ConfigField(key="outbox_retry_policy", type="json", required=False, default=None, hot_reloadable=True),
# === 渠道用户与 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),
# 新建 Agent 的默认渠道访问级别全局级scope=GLOBAL取值如
# "none" / "read" / "write" 等,由 Agent 创建流程读取。
ConfigField(key="channel_access_default_level", type="str", required=False, default="none", hot_reloadable=True),
# 渠道访客身份置信度全局级scope=GLOBALchannel_guest 身份生成时
# 使用此置信度,低于 identity_confidence_threshold 以避免被误判为
# 已解析身份。
ConfigField(key="channel_guest_confidence", type="float", required=False, default=0.3, hot_reloadable=True),
# 是否启用管理员手动绑定功能全局级scope=GLOBAL控制渠道用户与
# 统一身份的手动绑定入口是否可用。
ConfigField(key="enable_channel_user_binding", type="bool", required=False, default=True, hot_reloadable=True),
# === 渠道账号运营流程优化Task 14契约层 CONFIG_SCHEMA 健康检查配置键)===
# 以下 2 个键均为渠道级scope=CHANNEL归属 ConfigPortRedis 热重载,
# CHANNEL 业务策略体系),不得声明在 app_config。
# 凭证失效计数阈值。健康检查探活返回 401/403 时计入凭证失效计数,
# 达阈值后调聚合根 markFailed。窗口外credential_failure_window_seconds
# 重置计数。
ConfigField(key="credential_failure_threshold", type="int", required=False, default=3, hot_reloadable=True),
# 凭证失效计数窗口(秒)。窗口外的失效计数被重置,避免历史故障永久影响账号状态。
ConfigField(key="credential_failure_window_seconds", type="int", required=False, default=300, hot_reloadable=True),
# 审计日志保留策略全局级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,
),
# 扫码登录重定向 URI全局级scope=GLOBAL。扫码登录成功后的前端跳转地址
# 为空时使用默认跳转行为。
ConfigField(key="qr_login_redirect_uri", type="str", required=False, default="", hot_reloadable=True),
# === 不可热更新字段hot_reloadable=False===
ConfigField(key="webhook_port", type="int", required=False, default=None, hot_reloadable=False),
ConfigField(key="webhook_secret", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="tls_cert", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="tls_key", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="plugin_entry", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="database_url", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="redis_url", type="str", required=False, default=None, hot_reloadable=False),
ConfigField(key="transport.max_restart_attempts", type="int", required=False, default=None, hot_reloadable=False),
ConfigField(
key="transport.graceful_shutdown_timeout_s", type="float", required=False, default=10.0, hot_reloadable=False
),
# === 渠道账号运营流程优化Task 3契约层 CONFIG_SCHEMA 凭证配置键)===
# 以下 3 个键均为账户级scope=ACCOUNT归属 ConfigPortRedis 热重载,
# 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),
# 登录态unlogged/logging_in/logged_in/logout_failed。由 QrLoginService
# 通过 ConfigPort 维护,区分扫码会话状态与最终凭证落库状态。
ConfigField(key="login_status", type="str", required=False, default="unlogged", hot_reloadable=False),
# 凭证版本号,每次 rotateCredentials 自增。用于乐观锁控制与缓存失效判定。
ConfigField(key="credential_version", type="int", required=False, default=0, hot_reloadable=False),
# 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),
)
# 可热更新的配置项键集合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"]