ForcePilot/backend/package/yuxi/channels/plugins/wechat_woc/entry.py

188 lines
9.4 KiB
Python
Raw Normal View History

"""微信 wechat_wocWechatOnCloud渠道插件入口。
实现 ``CHANNEL_ENTRY`` 契约注册 13 个适配器与生命周期钩子返回
``PluginManifest``由宿主在 loaded 阶段通过 ``importlib`` 导入并调用
调用顺序严格违反顺序将触发 ``PermissionDeniedError``
1. 获取端口实例仅在 manifest ``accessible_ports`` 声明集合内取用
宿主在 ``PluginHostImpl._checkPortAccess`` 中校验
2. 实例化 ``WocBridgeClient`` ``WeChatWocLifecycleHandler``
3. 注册 13 个适配器puller / stream_connector / inbound / outbound /
session / status / login / lifecycle / probeable / doctor / wizard /
whitelist / directory
4. 注册生命周期钩子鸭子类型调用
5. 返回 ``PluginManifest``能力边界由 manifest 字段静态声明宿主在加载
期通过 ``PluginCapabilityChecker.check`` 校验
F-03 单真相源本入口仅承接 discover 阶段解析的 ``ChannelManifest``
不再重复构造声明性字段capabilities / config_schema / accessible_ports /
injectable_pipelines / resource_quota / env_vars / credential_strategy
所有声明性字段以 ``manifest.json`` 为唯一真相源本函数仅负责适配器实例化
client 实例化LifecycleHandler 构造与 ``registerAdapter`` 调用
适配器 DI 说明
- ``puller`` 接收 ``(client, config_port, logger_port)``需从 ConfigPort
读取 ``poll_interval_ms`` / ``max_batch_size``
- ``stream_connector`` 接收 ``(client, config_port, logger_port)``SSE
长连接由 ``WocBridgeClient.stream_messages`` 建立 ConfigPort 读取
``sse_heartbeat_interval_ms`` / ``sse_connect_timeout_ms`` / ``max_batch_size``
- ``outbound`` 接收 ``(client, config_port, logger_port)``需从 ConfigPort
CHANNEL 作用域读取 ``max_message_length``P2-2
- ``inbound`` / ``doctor`` / ``wizard`` / ``directory`` 接收
``(client, logger_port)``仅做协议转换
- ``login`` 接收 ``(client, logger_port)``扫码状态由 ``QrLoginService``
承载适配器不缓存登录态
- ``lifecycle`` 接收 ``(cache_port, logger_port)``账户删除/禁用时清理
CachePort 缓存不调用 bridge API
- ``probeable`` 接收 ``(client, persistence_port, logger_port)``需动态
发现 account_id 调用 bridge ``/api/status`` 探活
- ``whitelist`` 接收 ``(cache_port, logger_port)``白名单数据本地存储于
CachePort不调用 bridge API
- ``session`` / ``status`` 适配器无状态INV-5 ``__init__`` 参数
仅做协议转换所有数据从 raw_event.payload 提取
传输管理wechat_woc 通过 ``TransportManager`` ``both`` 模式管理消息
接收manifest ``transport_mode: "both"``
- ``StreamWorker``优先通过 ``WeChatWocStreamConnectorAdapter`` 建立
SSE 长连接实时接收消息bridge 1.5.0端到端延迟 1s
- ``PullerWorker``降级SSE 不可用或 bridge < 1.5.0 时降级为短轮询
``/api/messages/since``2s 间隔
两者由传输引擎通过 ``ChannelAccountOnline`` / ``ChannelAccountOffline``
领域事件触发启停``LifecycleAdapter`` ``LifecycleHandler`` 不自管理
传输任务决策 3
依赖方向 import ``yuxi.channels.contract.*`` + 标准库 + 同插件内部模块
不污染框架层
"""
from __future__ import annotations
from yuxi.channels.contract.plugin.entry import PluginHost
from yuxi.channels.contract.plugin.manifest import (
ChannelManifest,
PluginManifest,
)
from ._constants import DEFAULT_MAX_CONNECTIONS
from .adapters.capability_prover import WocCapabilityProver
from .adapters.directory_adapter import WeChatWocDirectoryAdapter
from .adapters.doctor_adapter import WeChatWocDoctorAdapter
from .adapters.inbound_adapter import WeChatWocInboundAdapter
from .adapters.lifecycle_adapter import WeChatWocLifecycleAdapter
from .adapters.login_adapter import WeChatWocLoginAdapter
from .adapters.outbound_adapter import WeChatWocOutboundAdapter
from .adapters.probeable_adapter import WeChatWocProbeableAdapter
from .adapters.puller_adapter import WeChatWocPullerAdapter
from .adapters.session_adapter import WeChatWocSessionAdapter
from .adapters.status_adapter import WeChatWocStatusAdapter
from .adapters.stream_connector_adapter import WeChatWocStreamConnectorAdapter
from .adapters.whitelist_adapter import WeChatWocWhitelistAdapter
from .adapters.wizard_adapter import WeChatWocWizardAdapter
from .lifecycle import WeChatWocLifecycleHandler
from .woc_bridge_client import WocBridgeClient
# 已注册适配器类型列表(与 registerAdapter 调用顺序一致)。
# 此处为运行时适配器清单,非声明性字段,需与下方 registerAdapter 调用保持一致。
_ADAPTER_TYPES: tuple[str, ...] = (
"puller",
"stream_connector",
"inbound",
"outbound",
"session",
"status",
"login",
"lifecycle",
"probeable",
"doctor",
"wizard",
"whitelist",
"directory",
)
def channel_entry(host: PluginHost, manifest: ChannelManifest) -> PluginManifest:
"""微信 wechat_woc 渠道插件入口。
由宿主在 loaded 阶段调用完成端口获取客户端与生命周期钩子实例化
适配器注册返回 ``PluginManifest``能力边界accessible_ports /
injectable_pipelines / resource_quota / config_schema / env_vars /
credential_strategy discover 阶段解析的 ``manifest`` 静态字段
承载宿主在加载期通过 ``PluginCapabilityChecker.check`` 校验本函数
不重复构造声明性字段F-03 单真相源
参数
host: 插件宿主提供端口获取与扩展点注册 API
manifest: 渠道清单 discover 阶段从 ``manifest.json`` 解析得到
承载所有声明性字段本函数复用其 ``config_schema`` 注入
``LifecycleHandler``并直接作为返回 ``PluginManifest.manifest``
"""
# 1. 获取端口实例(仅在 manifest accessible_ports 声明集合内取用)
# WocBridgeClient 仅依赖 ConfigPort/CachePort/LoggerPortbridge_url
# 由 CredentialService 通过 ConfigPort→CachePort 管理);
# PersistencePort 供 ProbeableAdapter 动态发现 account_id。
config_port = host.getConfigPort()
logger_port = host.getLoggerPort()
cache_port = host.getCachePort()
persistence_port = host.getPersistencePort()
# 2. 实例化 WocBridgeClient 与 LifecycleHandler
# 依赖关系为单向handler 在 onInit 调 client.attach_http_client 注入
# HTTP 连接池client 不引用 handler。先创建 client再创建 handler
# 并通过构造器注入。config_schema 取自 manifestF-03 单真相源)。
client = WocBridgeClient(
config_port,
cache_port,
logger_port,
plugin_version=manifest.version,
)
handler = WeChatWocLifecycleHandler(
config_port,
logger_port,
cache_port,
manifest.config_schema,
client,
max_connections=(
manifest.resource_quota.max_connections if manifest.resource_quota is not None else DEFAULT_MAX_CONNECTIONS
),
)
# 3. 注册 13 个适配器12 必选 + 1 可选 directory
# puller/outbound 接收 (client, config_port, logger_port)
# stream_connector/inbound/doctor/wizard/directory/login 接收
# (client, logger_port)lifecycle/whitelist 接收
# (cache_port, logger_port)probeable 接收
# (client, persistence_port, logger_port)session/status 无状态。
host.registerAdapter("puller", WeChatWocPullerAdapter(client, config_port, logger_port))
host.registerAdapter("stream_connector", WeChatWocStreamConnectorAdapter(client, config_port, logger_port))
host.registerAdapter("inbound", WeChatWocInboundAdapter(client, logger_port))
host.registerAdapter("outbound", WeChatWocOutboundAdapter(client, config_port, logger_port))
host.registerAdapter("session", WeChatWocSessionAdapter())
host.registerAdapter("status", WeChatWocStatusAdapter())
host.registerAdapter("login", WeChatWocLoginAdapter(client, logger_port))
host.registerAdapter("lifecycle", WeChatWocLifecycleAdapter(cache_port, logger_port))
host.registerAdapter("probeable", WeChatWocProbeableAdapter(client, persistence_port, logger_port))
host.registerAdapter("doctor", WeChatWocDoctorAdapter(client, logger_port))
host.registerAdapter("wizard", WeChatWocWizardAdapter(client, logger_port))
host.registerAdapter("whitelist", WeChatWocWhitelistAdapter(cache_port, logger_port))
host.registerAdapter("directory", WeChatWocDirectoryAdapter(client, logger_port))
# 4. 注册能力证明者FR-08 增强)
# 对 manifest 声明的媒体出站能力进行运行时证明,避免 bridge 实际未
# 实现媒体发送时仍按声明能力调用project_memory 硬约束)。
host.registerCapabilityProver(WocCapabilityProver(client))
# 5. 注册生命周期钩子
# PluginHost Protocol 未声明 registerLifecycleHandler但 PluginHostImpl
# 已实现,运行时通过鸭子类型调用。
host.registerLifecycleHandler(handler)
# 6. 返回 PluginManifestmanifest 直接复用入参adapters 为运行时清单)
return PluginManifest(
manifest=manifest,
adapters=_ADAPTER_TYPES,
)
CHANNEL_ENTRY = channel_entry