e2m2e.api.mcp.worker#

长任务工具 worker 子进程(#588 / #576 Phase 2,子进程隔离架构)。

python -m e2m2e.api.mcp.worker 一次性执行一个工具调用,供传输层把 分钟级长计算(转移搜索、族生成)隔离到可 kill 的子进程:

  • stdin 读一行 JSON 请求 {"tool": name, "arguments": {...}, "config": {...}, "binary_dtype": "f32"|"f64"}——config 缺省时从环境变量重建 (见 config.py),存在时经 Config.from_payload 还原:注入的配置 穿透子进程,未知字段报错而非静默降级(#601);声明 binary_dtype 且 工具在帧清单内时画布数组出帧(#607)

  • stdout 按行输出 {"type": "progress", "fraction": ..., "message": ...}``(节流,见 ``_PROGRESS_MIN_INTERVAL_SEC)与最终一行 ``{"type": "result", "envelope": {...}, "binary_frames": N}``(统一 信封,见 envelope.py;N>0 时行后紧跟 N 个原始帧字节,帧格式同 ADR 0035 §3)

  • stderr 原样透传到父进程日志;正常路径退出码 0(工具失败以信封表达)

取消 = 父进程 kill 本进程:Rust 族生成在 GIL 释放下整段运行,协作式 检查点失效,Python 工作线程不可杀——进程 kill 是唯一可靠打断手段。 数据安全:catalog 落盘是工具方法末尾的一次性原子写(tmp + os.replace), kill 只丢当前任务,不损坏已入库记录。

不 import mcp SDK:worker 只依赖执行核心与 Facade/Config(与 sidecar 同款约束,缺 [mcp] extra 也能跑)。

Functions#

run_request(→ None)

执行一个工具请求,进度行与结果行经 emit_line 输出。

main(→ int)

stdin 一行请求 → stdout 进度/结果行(+ 帧)→ 退出。

Module Contents#

e2m2e.api.mcp.worker.run_request(request: dict[str, Any], emit_line: collections.abc.Callable[[bytes], None], facade: Any = None) → None#

执行一个工具请求,进度行与结果行经 emit_line 输出。

纯进程内逻辑(可测):emit_line 收到不含换行符的完整 JSON 行 (字节);结果行后按声明追加原始帧字节。进度回调可能从算法层线程 触发(Rust drainer),输出以锁串行化;结果行与帧始终在进度行之后, 且彼此原子(同一锁内写出)。任何失败都翻译成错误信封,不向 stderr 抛 traceback、不泄漏细节(api/ 边界契约)。

facade 是测试注入缝:缺省自建 ``Facade(Config())``(与生产路径 一致)。

e2m2e.api.mcp.worker.main() → int#

stdin 一行请求 → stdout 进度/结果行(+ 帧)→ 退出。