ForcePilot/backend/package/yuxi/channels/contract/policy/config_schema.py
Kris 8eead29de0 refactor: 批量清理冗余空行,优化部分枚举使用方式
1.  移除所有适配器文件中多余的空导入行
2.  调整ValidationError继承,移除不必要的ValueError继承
3.  修正多处ChannelType使用方式,从.value改为直接使用枚举实例
4.  优化飞书插件部分硬编码渠道类型为枚举实例
5.  更新wechat_ilink插件清单与适配器配置
6.  新增飞书目录适配器缓存清理支持判断与iLink生命周期适配器凭据轮换支持判断
7.  优化配置处理器历史查询逻辑,区分键不存在与无历史记录场景
2026-07-04 00:14:56 +08:00

153 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""配置 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"]