Skip to content

运行架构与生命周期 ​

宿主怎么发现你的插件、什么时候实例化、什么时候禁止启用、谁和谁互斥。


1. 流水线与插件插入点 ​

宿主以流水线为中心:音频/字幕进来 → 识别 → 翻译 → 展示/朗读。插件挂在明确的扩展点上:

[音频捕获 / 浏览器字幕]
        │
        ▼
 process_audio          ← middleware
        │
        ▼
      VAD 断句
        │
        ▼
      ASR 识别           ← asr Provider
        │
        ▼
 process_transcript     ← middleware
        │
        ▼
 术语 Prompt 注入 + MT   ← mt Provider + glossary
        │
        ▼
 process_translation    ← middleware
        │
        ├──► UI 字幕
        └──► TTS 朗读    ← tts Provider
                │
                ▼
        process_tts_audio  ← middleware
                │
                ▼
            声卡播放
  • 中间件按 priority 升序执行(数字越小越先跑,默认 100)。单个中间件抛异常会被隔离,不拖垮整条链。
  • 术语库只作用于已启用的词库:按当前 source_lang→target_lang 过滤词条 → 翻译前注入提示词 / 原文侧校正 → mt.translate(...) → 中间件改译文 → 术语正/反双向替换。云端千问 ASR 另会把词表转为即时热词。
  • interpretation 是旁路:宿主切入同传模式后不再挂载/驱动标准 ASR → MT → TTS 流水线, 音频帧直接进同传 Provider(见 interpretation)。
  • 浏览器字幕(caption_bridge)走 feed_direct_caption 轻量路径。

2. 发现与加载 ​

本地 extensions/            ──┐
%APPDATA%/transbox/extensions/ ─┼─► PluginRegistry 扫描 mod.json ─► 按 type 挂载
Steam 创意工坊 content/<AppID>/ ─┤
<数据目录>/workshop/<id>/       ─┘   (仅自发行版)

按 type 分发:

type挂载方式
glossary / i18n / theme作为数据挂载(词库 / 字典 / 样式令牌),不 import Python
asr / mt / tts / middleware / assistant / interpretation / toolimportlib 加载 Python 类,按需实例化
caption_bridge / caption_extractor接进字幕桥链路(见 caption_extractor)

同 id 优先级:local > steam > web。 随应用发布的 bundled 插件可被工坊版本覆盖——仅当工坊版本 semver 更高。

type=tool 的已启用插件在扫描阶段就会预加载实例(因为要注册热键)。 所以 tool 插件的 initialize() 会在启动时跑——里面别做重活。


3. 生命周期 ​

发现 → 解析 mod.json →(启用时)实例化 + initialize(config) → 使用 → 停用 shutdown()
阶段宿主动作你的责任
扫描读 mod.json、跑依赖门禁、恢复上次启用状态清单写正确
启用建实例、调 initialize(config)只做准备:解析配置、检查文件;不启服务、不加载权重
使用宿主按需调 ensure_loaded() / 引擎接口 / action_*请求入口自己兜底「确保就绪」
改配置持久化 + 调 update_config(delta) + 广播 config.changed热同步内部状态
停用 / 退出 / 释放显存调 shutdown() → unregister_plugin_hotkeys / close_plugin_windows / 取消事件订阅必须 kill 自己的子进程
卸载从 sys.path 回收 libs/ vendor/不要在其他地方留状态

外部插件(非内置)的 initialize() 跑在后台线程,宿主在需要前会调 wait_async_init() 等它收敛。所以 initialize 里阻塞几秒不会卡 UI —— 但也不要用它启动服务。


4. 双轨分流与单例复用 ​

自 v0.2 起,入站(上轨 🎧 对方/系统声音)与出站(下轨 🎙️ 我方麦克风)在 ASR / MT / TTS 三层全链路解耦:

  1. 插件作者零改动:ASR / MT / TTS 插件只遵循标准 Provider 接口,不必为双轨写特殊逻辑。
  2. 宿主智能分流:流水线按数据流向(source="peer" / "self")自动分发到对应的活跃引擎。
  3. 显存安全单例复用:上下轨选中同一模型时,宿主严格复用同一实例引用(outbound is inbound), 保持 1 倍显存开销;并发调用由引擎内部锁保护。
  4. 静默旁路:下轨未分配(none)时,下轨音频流与推理完全短路,零 CPU/GPU/网络开销。

对插件的实际要求只有两条:

  • 实现标准的 Provider 接口(见 Provider 签名);
  • 支持流式的引擎,若要能同时服务两轨,需返回 supports_concurrent_streams = True (底层是单活句柄就返回 False,宿主会自动降级另一轨)。

5. 启用与互斥规则 ​

每类 type 的启用 / 停用动作:

type启用时停用时
glossary注册进全局术语管理器注销
i18n切换到该语言;与其他第三方语言包互斥若当前是该语言则回退 zh-CN
theme(full)应用主题;与其他 full 主题互斥回退默认主题
同插槽 UI 扩展占用同一插槽时互斥停用他人移除该插槽组件
asr / mt / tts可设为当前引擎若是活跃引擎则回退到其它已启用引擎
interpretation切入同传模式;旁路标准 ASR+MT+TTS退出同传并回退标准流水线
middleware挂入中间件管理器卸载
caption_bridge联动 Web 字幕服务联动关闭服务
内置默认主题禁止禁用—

通用规则:

  • 启用即生效 / 停用即回退。
  • 同类引擎互斥:asr / mt / tts / interpretation 各自只有一个「当前引擎」, 由用户在设置页选定(set_active_provider)。生效引擎只是配置变更,不会预热或加载模型。
  • UI 插槽互斥(仅这些槽位,同级之间):overlay_background、caption_view、audio_level、 alert_capsule、overlay_decorations、settings_background、history_background、 dialog_background、window_background、copilot_window。
  • 全量主题(style_layer=full)与局部 UI 插槽扩展可以并存 —— 启用波形条不会把用户的主题踢下线。
  • settings_view 不参与任何互斥:每个插件有自己的设置表单。
  • i18n 整包语言包互斥(同一时间只有一个界面语言)。
  • 显示/展示类插件可多开:glossary、middleware、tool、assistant。

6. 依赖门禁(三处) ​

宿主在三道关口检查 requires_plugins / requires_runtime:

时机行为
启动扫描依赖未就位(未安装 / 未启用 / 版本过低 / 运行库缺失)→ 强制停用该插件
打开启用开关拒绝启用 + 浮层提示(插件名、缺什么、怎么处理)
选为 ASR/MT/TTS 引擎拒绝(与启用同一道门禁)
启动同传就绪检查返回 missing_dependency → 阻断并给人话原因

宿主不会静默安装前置插件(含代码的插件不允许静默安装);卡片上提供「安装 / 启用 / 更新 / 下载运行库」入口,由用户点。


相关 ​

TransBox - 赋能全人类无界限跨语言交流