ForcePilot/backend/package/yuxi/channels/adapters/__init__.py

185 lines
9.2 KiB
Python
Raw Normal View History

"""渠道被驱动适配器包。
聚合导出 18 个被驱动适配器实现与 ``DrivenAdapters`` 聚合 dataclass
供框架层装配使用
装配策略分两类§4.12
- **请求级 / 无状态适配器**14 ``create_driven_adapters(db,
session_factory, outbox_config, redis_client, arq_pool, execution_port)``
factory 构造
``ChannelPersistenceAdapter`` 为无状态适配器注入 ``session_factory``
``Callable[[], AsyncSession]``通过 ``_session_scope(tx)`` 按需获取
session``tx`` 非空时复用应用层主事务 session``tx`` ``None`` 时自主
创建并提交``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 Callable, 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 .inmemory_tracer_adapter import InMemoryTracerAdapter
from .masking_adapter import MaskingAdapter
from .message_ops_port_adapter import MessageOpsPortAdapter
from .redis_cache_adapter import RedisCacheAdapter
from .redis_config_adapter import RedisConfigAdapter
from .redis_realtime_metrics_adapter import RedisRealtimeMetricsAdapter
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 = InMemoryTracerAdapter(_logger_adapter)
def create_driven_adapters(
db: AsyncSession,
session_factory: Callable[[], AsyncSession],
outbox_config: OutboxConfig,
redis_client: Redis,
arq_pool: ArqRedis,
execution_port: AgentRunExecutionPort,
key_to_scope_map: Mapping[str, ConfigScope] | None = None,
declared_keys: set[str] | None = None,
) -> DrivenAdapters:
"""创建被驱动适配器聚合实例。
``ChannelPersistenceAdapter`` 为无状态适配器注入 ``session_factory``
``Callable[[], AsyncSession]``通过 ``_session_scope(tx)`` 按需获取
session``tx`` 非空时复用应用层主事务 sessionC-I1 透传``tx``
``None`` 时通过 ``session_factory()`` 创建独立 session 并自主提交
``ConversationAdapter`` / ``SqlAlchemyTransactionAdapter`` 为请求级事务
边界适配器共享同一 ``db`` 会话以保证事务一致性无状态适配器
Logger / Tracer使用模块级全局实例其余适配器按需构造
``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 异步会话请求级由框架层注入conversation /
transaction 适配器共享此会话以保证事务一致性
session_factory: ``Callable[[], AsyncSession]``注入到
``ChannelPersistenceAdapter`` ``_session_scope(None)`` 创建
独立 session无状态适配器不持有请求级 ``db``
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`` 校验 keyscope
一致性 ``None`` 时不校验向后兼容
declared_keys: §13.1 已声明的配置键集合注入到
``RedisConfigAdapter`` ``_assertDeclared`` 校验键合法性
``None`` 时回退到模块级 ``_DECLARED_KEYS``仅含
CONFIG_SCHEMA 向后兼容
Returns:
DrivenAdapters 聚合实例
"""
config = RedisConfigAdapter(
redis_client=redis_client,
logger=_logger_adapter,
key_to_scope_map=key_to_scope_map,
declared_keys=declared_keys,
)
persistence = ChannelPersistenceAdapter(session_factory, 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",
"InMemoryTracerAdapter",
"IdentityResolverAdapter",
"SqlAlchemyTransactionAdapter",
# 独立装配路径适配器5 个,不经过工厂,不进入 DrivenAdapters 聚合)
"ContentReviewRepositoryAdapter",
"DefaultContentModerationAdapter",
"InmemoryRealtimeMetricsAdapter",
"RedisRealtimeMetricsAdapter",
"MessageOpsPortAdapter",
]