"""渠道被驱动适配器包。 聚合导出 18 个被驱动适配器实现与 ``DrivenAdapters`` 聚合 dataclass, 供框架层装配使用。 装配策略分两类(§4.12): - **请求级 / 无状态适配器**(14 个)经 ``create_driven_adapters(db, outbox_config, redis_client, arq_pool, execution_port)`` factory 构造: 需要共享 ``AsyncSession`` 的适配器(``ChannelPersistenceAdapter`` / ``ConversationAdapter`` / ``SqlAlchemyTransactionAdapter``)共享同一 ``db``; 无状态适配器(Logger / Tracer)使用模块级全局实例;``identity_resolver`` 默认为 ``None``,由插件注册时注入。 - **独立装配路径适配器**(4 个)不经过工厂,不进入 ``DrivenAdapters`` 聚合: ``ContentReviewRepositoryAdapter`` / ``DefaultContentModerationAdapter`` 是 应用级单例(在 ``factory.create_host_bootstrap`` 构造并注册 DI); ``InmemoryRealtimeMetricsAdapter`` 是进程内单例(在 ``create_channel_use_cases`` 装配);``MessageOpsPortAdapter`` 是请求级 + 插件依赖(持有插件适配器注册表,在 ``create_channel_use_cases`` 装配)。 注:``__init__.py`` 的"导出"仅指 ``__all__`` 与 import 语句集中声明,不等于 "纳入工厂/聚合"。``RedisConfigAdapter`` / ``RedisCacheAdapter`` 接受 ``redis_client``,``ARQQueueAdapter`` 接受 ``arq_pool``,``AgentRunAdapter`` 接受 ``execution_port``(构造注入,INV-5 / ADP-001 / ADP-005 / ADP-022)。 """ from __future__ import annotations from collections.abc import Mapping from arq import ArqRedis from redis.asyncio import Redis from sqlalchemy.ext.asyncio import AsyncSession from yuxi.channels.contract.dtos.config import ConfigScope from yuxi.channels.contract.dtos.outbox import OutboxConfig from yuxi.channels.contract.ports.driven.agent_run_execution_port import ( AgentRunExecutionPort, ) from yuxi.channels.contract.ports.driven.aggregate import DrivenAdapters # 被驱动适配器(请求级 / 无状态,14 个,经 create_driven_adapters 工厂装配) from .agent_access_config_adapter import AgentAccessConfigAdapter from .agent_run_adapter import AgentRunAdapter from .agent_run_execution_adapter import AgentRunExecutionAdapter from .arq_queue_adapter import ARQQueueAdapter from .channel_persistence_adapter import ChannelPersistenceAdapter # 独立装配路径适配器(5 个,不经过工厂,不进入 DrivenAdapters 聚合) from .content_review_repository_adapter import ContentReviewRepositoryAdapter from .conversation_adapter import ConversationAdapter from .default_content_moderation_adapter import DefaultContentModerationAdapter from .identity_resolver_adapter import IdentityResolverAdapter from .inmemory_realtime_metrics_adapter import InmemoryRealtimeMetricsAdapter from .masking_adapter import MaskingAdapter from .message_ops_port_adapter import MessageOpsPortAdapter from .opentelemetry_tracer_adapter import OpenTelemetryTracerAdapter from .redis_cache_adapter import RedisCacheAdapter from .redis_config_adapter import RedisConfigAdapter from .service_account_adapter import ServiceAccountAdapter from .sqlalchemy_transaction_adapter import SqlAlchemyTransactionAdapter from .structured_logger_adapter import StructuredLoggerAdapter # 无状态适配器全局实例(Masking / Logger / Tracer),跨请求复用,避免重复构造。 # Masking 无状态无依赖,最先构造;Logger 注入 Masking 以便日志 kwargs 自动脱敏; # Tracer 注入 Logger 以便在追踪故障降级时记录日志(避免静默吞异常)。 _masking_adapter = MaskingAdapter() _logger_adapter = StructuredLoggerAdapter(masking_port=_masking_adapter) _tracer_adapter = OpenTelemetryTracerAdapter(_logger_adapter) def create_driven_adapters( db: AsyncSession, outbox_config: OutboxConfig, redis_client: Redis, arq_pool: ArqRedis, execution_port: AgentRunExecutionPort, key_to_scope_map: Mapping[str, ConfigScope] | None = None, ) -> DrivenAdapters: """创建被驱动适配器聚合实例。 请求级适配器(``ChannelPersistenceAdapter`` / ``ConversationAdapter`` / ``SqlAlchemyTransactionAdapter````) 共享同一 ``db`` 会话以保证事务一致性;无状态适配器(Logger / Tracer) 使用模块级全局实例;其余适配器按需构造。``ConversationAdapter`` 仅依赖 共享 ``db`` 会话(合并策略开关决策已上移至 usecase 层,``ConfigPort`` / ``PersistencePort`` 死依赖已移除)。``RedisConfigAdapter`` / ``RedisCacheAdapter`` 接受 ``redis_client`` 执行配置读写与缓存操作; ``ARQQueueAdapter`` 接受 ``arq_pool`` 入队;``AgentRunAdapter`` 接受 ``execution_port`` 委托 Agent 运行技术操作(构造注入,INV-5 / ADP-001 / ADP-005 / ADP-022)。``identity_resolver`` 默认为 ``None``,由插件注册时注入。 Args: db: SQLAlchemy 异步会话,由框架层注入,persistence / conversation / transaction 适配器共享此会话。 outbox_config: 发件箱配置,注入到 ``ChannelPersistenceAdapter`` 替代 直接读取全局 ``app_config``(§6.1 应用服务层禁止依赖具体技术适配器)。 redis_client: ``redis.asyncio.Redis`` 客户端实例,注入到 ``RedisConfigAdapter`` 与 ``RedisCacheAdapter``(构造注入,INV-5)。 arq_pool: ``arq.ArqRedis`` 连接池实例,注入到 ``ARQQueueAdapter`` 用于入队(构造注入,ADP-005)。 execution_port: ``AgentRunExecutionPort`` 实例,注入到 ``AgentRunAdapter`` 委托 Agent 运行技术操作(构造注入,ADP-001)。 key_to_scope_map: F-02 配置作用域映射(``key → ConfigScope``), 注入到 ``RedisConfigAdapter`` 供 ``_build_key`` 校验 key→scope 一致性。为 ``None`` 时不校验(向后兼容)。 Returns: DrivenAdapters 聚合实例。 """ config = RedisConfigAdapter( redis_client=redis_client, logger=_logger_adapter, key_to_scope_map=key_to_scope_map, ) persistence = ChannelPersistenceAdapter(db, outbox_config=outbox_config, logger=_logger_adapter) # 服务账号适配器单例:仅依赖 logger,共享注入到 AgentRunAdapter / 管道阶段 / AccountHandler service_account = ServiceAccountAdapter(logger=_logger_adapter) # Agent 渠道访问配置适配器单例:仅依赖 logger,注入到 agent-run-enqueue 阶段 agent_access_config = AgentAccessConfigAdapter(logger=_logger_adapter) return DrivenAdapters( persistence=persistence, conversation=ConversationAdapter(db, logger=_logger_adapter), agent_run=AgentRunAdapter( execution_port=execution_port, logger=_logger_adapter, service_account_port=service_account, ), queue=ARQQueueAdapter(arq_pool=arq_pool, logger=_logger_adapter), config=config, cache=RedisCacheAdapter(redis_client=redis_client, logger=_logger_adapter), logger=_logger_adapter, tracer=_tracer_adapter, masking=_masking_adapter, transaction=SqlAlchemyTransactionAdapter(db), identity_resolver=None, service_account=service_account, agent_access_config=agent_access_config, ) __all__ = [ # 聚合与工厂 "DrivenAdapters", "create_driven_adapters", # 被驱动适配器(请求级 / 无状态,14 个,经 create_driven_adapters 工厂装配) "ChannelPersistenceAdapter", "ConversationAdapter", "AgentRunAdapter", "AgentRunExecutionAdapter", "AgentAccessConfigAdapter", "ARQQueueAdapter", "MaskingAdapter", "RedisConfigAdapter", "RedisCacheAdapter", "ServiceAccountAdapter", "StructuredLoggerAdapter", "OpenTelemetryTracerAdapter", "IdentityResolverAdapter", "SqlAlchemyTransactionAdapter", # 独立装配路径适配器(4 个,不经过工厂,不进入 DrivenAdapters 聚合) "ContentReviewRepositoryAdapter", "DefaultContentModerationAdapter", "InmemoryRealtimeMetricsAdapter", "MessageOpsPortAdapter", ]