ForcePilot/backend/package/yuxi/channels/contract/plugin/entry.py
Kris b88c0ae29e feat(channels): 批量新增多渠道网关限界上下文基础代码与契约
新增完整的 channels 限界上下文模块,包含契约层、领域核心层、应用服务、管道编排、插件体系、基础设施组合根等全层级代码,新增飞书与微信 iLink 渠道插件基础结构,补充各类 DTO、端口协议与领域服务实现。
2026-07-02 03:22:12 +08:00

260 lines
8.6 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.

"""插件入口契约。
定义插件宿主 Protocol``PluginHost``)与插件入口类型别名
``CHANNEL_ENTRY``)。插件通过 ``CHANNEL_ENTRY`` 函数注册,由宿主在
loaded 阶段调用,返回 ``PluginManifest``。
"""
from __future__ import annotations
from collections.abc import Callable
from typing import Any, Protocol, runtime_checkable
from yuxi.channels.contract.dtos.plugin import DomainEvent
from yuxi.channels.contract.dtos.route import MatchTier
from yuxi.channels.contract.plugin.extension_point import (
ConfigSource,
EventSubscription,
StageSlot,
)
from yuxi.channels.contract.plugin.manifest import PluginManifest, ResourceQuota
from yuxi.channels.contract.ports.driven import (
AgentRunPort,
AuditLogRepositoryPort,
CachePort,
ChannelAccountRepositoryPort,
ChannelSessionRepositoryPort,
ConfigPort,
ConversationPort,
IdempotencyRepositoryPort,
IdentityResolverPort,
LoggerPort,
OutboxRepositoryPort,
PairingRepositoryPort,
PersistenceHealthPort,
PersistencePort,
QueuePort,
TracerPort,
UserIdentityRepositoryPort,
)
class PluginAdapter(Protocol):
"""插件适配器标记 Protocol。
标识 ``PluginHost.registerAdapter`` 接受的适配器实例类型。渠道插件
可注册的适配器包括 ``contract.plugin.adapters`` 中定义的 23 类适配器
协议InboundAdapter / OutboundAdapter / SessionAdapter / RichMessageAdapter
/ StreamingAdapter / DirectoryAdapter / CommandAdapter / WizardAdapter
/ DoctorAdapter / WhitelistAdapter / ToolsAdapter / MessageOpsAdapter
/ StatusAdapter / MentionAdapter / IdentityResolverAdapter / LifecycleAdapter
/ LoginAdapter / ProbeableAdapter / ContentModerationAdapter / PullerAdapter
/ StreamConnectorAdapter / AttachmentUploadable / WebhookTestable
渠道上下文提供者端口ChannelContextProviderPort它们各自定义独立
的处理方法,无公共方法基类,故本 Protocol 作为类型边界用于静态检查
与文档化,不含公共方法声明。
"""
...
#: 路由匹配器类型别名。
#:
#: 接收绑定上下文,返回匹配的路由绑定或 ``None``。插件通过
#: ``registerMatcher`` 注入自定义匹配函数,供 ``RouteResolver`` 遍历
#: 层级时调用执行匹配逻辑。使用 ``Any`` 避免运行时解析
#: ``BindingContext``TYPE_CHECKING 导入,见 ``TierMatcher``)。
Matcher = Callable[..., Any]
@runtime_checkable
class PluginHost(Protocol):
"""插件宿主 Protocol。
由宿主实现,向插件提供被驱动端口获取、扩展点注册、能力边界声明与
事件发布能力。使用 ``@runtime_checkable`` 装饰以支持 ``isinstance``
检查。
资源访问约束INV-I7 / FF-ADAPTER-01 / FR-32
- 插件 **不得** 直接访问宿主的 ``settings``、``logger``、数据库连接池、
Redis 客户端,**必须** 通过 ``PluginHost`` 提供的端口获取方法获取依赖。
- 插件 **不得** 修改宿主的中间件链、路由表、事件订阅器,**只能** 通过
扩展点注册方法注入自身逻辑。
- 插件能力声明 **必须** 通过 ``CapabilityProver`` 验证,验证失败 **不得**
启动插件。
插件必须通过 ``PluginHost`` 完成以下三类操作:
1. 端口获取:通过 ``getXxxPort()`` 方法获取被驱动端口,访问配置、日志、
持久化、缓存、追踪、队列、会话、Agent 运行与身份解析能力。
2. 扩展点注册:通过 ``registerXxx()`` 方法注册适配器、阶段槽位、事件订阅
与配置源,向宿主注入自身逻辑。
3. 能力边界声明:通过 ``declareXxx()`` 方法声明可访问端口、可注入管道与
资源配额,由宿主强制约束。
"""
def getConfigPort(self) -> ConfigPort:
"""获取配置端口。"""
...
def getLoggerPort(self) -> LoggerPort:
"""获取日志端口。"""
...
def getPersistencePort(self) -> PersistencePort:
"""获取持久化端口。"""
...
def getCachePort(self) -> CachePort:
"""获取缓存端口。"""
...
def getTracerPort(self) -> TracerPort:
"""获取追踪端口。"""
...
def getQueuePort(self) -> QueuePort:
"""获取队列端口。"""
...
def getConversationPort(self) -> ConversationPort:
"""获取会话端口。"""
...
def getAgentRunPort(self) -> AgentRunPort:
"""获取 Agent 运行端口。"""
...
def getIdentityResolverPort(self) -> IdentityResolverPort:
"""获取身份解析端口。"""
...
def getChannelAccountRepositoryPort(self) -> ChannelAccountRepositoryPort:
"""获取渠道账户仓储端口。"""
...
def getChannelSessionRepositoryPort(self) -> ChannelSessionRepositoryPort:
"""获取渠道会话仓储端口。"""
...
def getPairingRepositoryPort(self) -> PairingRepositoryPort:
"""获取配对仓储端口。"""
...
def getAuditLogRepositoryPort(self) -> AuditLogRepositoryPort:
"""获取审计日志仓储端口。"""
...
def getOutboxRepositoryPort(self) -> OutboxRepositoryPort:
"""获取发件箱仓储端口。"""
...
def getUserIdentityRepositoryPort(self) -> UserIdentityRepositoryPort:
"""获取用户身份仓储端口。"""
...
def getIdempotencyRepositoryPort(self) -> IdempotencyRepositoryPort:
"""获取幂等性仓储端口。"""
...
def getPersistenceHealthPort(self) -> PersistenceHealthPort:
"""获取持久化健康端口。"""
...
def registerAdapter(self, adapter_type: str, adapter: PluginAdapter) -> None:
"""注册适配器。
参数:
adapter_type: 适配器类型。
adapter: 适配器实例。
"""
...
def registerStageSlot(self, slot: StageSlot) -> None:
"""注册管道阶段槽位。
参数:
slot: 阶段槽位实例。
"""
...
def registerEventSubscription(self, subscription: EventSubscription) -> None:
"""注册事件订阅。
参数:
subscription: 事件订阅实例。
"""
...
def registerConfigSource(self, source: ConfigSource) -> None:
"""注册配置源。
参数:
source: 配置源实例。
"""
...
def registerMatchTier(self, tier: MatchTier) -> None:
"""注册路由匹配层级FR-04
参数:
tier: 匹配层级配置。
"""
...
def registerMatcher(self, name: str, matcher: Matcher) -> None:
"""注册匹配层级的匹配器FR-04
为已注册的层级绑定匹配函数,供 ``RouteResolver`` 在遍历层级时调用
执行匹配逻辑。插件通过本方法注入自定义匹配规则。
参数:
name: 层级名称(必须已通过 ``registerMatchTier`` 注册)。
matcher: 匹配器函数,接收绑定上下文,返回路由绑定或 None。
"""
...
def declareAccessiblePorts(self, ports: tuple[str, ...]) -> None:
"""声明可访问的端口列表。
参数:
ports: 可访问的端口名称元组。
"""
...
def declareInjectablePipelines(self, pipelines: tuple[str, ...]) -> None:
"""声明可注入的管道列表。
参数:
pipelines: 可注入的管道名称元组。
"""
...
def declareResourceQuota(self, quota: ResourceQuota) -> None:
"""声明资源配额。
参数:
quota: 资源配额实例。
"""
...
async def publishEvent(self, event: DomainEvent) -> None:
"""发布领域事件。
宿主负责将事件分发到订阅者。支持的事件类型:
PluginDiscovered/PluginLoaded/PluginStarted/PluginPaused/
PluginResumed/PluginStopped/PluginUnloaded/PluginFailed/
PairingApproved/PairingRevoked/ConfigChanged/ChannelDegraded/ChannelRecovered。
参数:
event: 领域事件。
"""
...
#: 插件入口类型别名。
#:
#: 每个渠道插件 **必须** 通过 ``CHANNEL_ENTRY`` 契约注册,**不得** 隐式全局
#: 注入FR-32。由宿主在 loaded 阶段调用,返回 ``PluginManifest``,包含
#: 元数据、适配器、阶段、事件订阅等。
CHANNEL_ENTRY = Callable[[PluginHost], PluginManifest]