iii Worker 统一 CLI 与环境契约:用 --url / --namespace / --config 让每个 Worker 可被任意监督器注入
iii Worker 统一 CLI 与环境契约用 --url / --namespace / --config 让每个 Worker 可被任意监督器注入【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii导读iii 的 worker 舰队由几十个二进制组成http、state、storage、database、llm-router、shell、bridge 等它们在如何找到引擎、如何声明命名空间、如何接收配置上长期各说各话导致任何上层监督器compose daemon、iii worker、sandbox都无法注入一份统一的契约。本文基于仓库 tech-specs/2026-07-14-worker-compose/cli-contract.md 的规范讲解这条CLI/环境契约三个参数--url、--namespace、--config与其环境变量回退III_URL、III_NAMESPACE、III_CONFIG以及零参数registerWorker()如何让它成为文档默认行为。读完你将理解这套契约的现状背景、标准形态、迁移路径以及它在源码中的落地痕迹。为什么需要一份契约41 个二进制的现状规范开篇就点出了问题的本质监督器只能注入 worker 愿意读取的东西而今天它们彼此之间没有任何共识。A supervisor can only inject what workers agree to read. Today they agree on nothing.原文档用一张表格总结了当时的现状WorkerEngine addressEnv readhttp / state / storage / database / harness--urlflag默认ws://127.0.0.1:49134nonellm-router--urlflagIII_WS_URLshell / codex / devin / email / bridge / lsp / hermesvariesIII_URLany SDKregister_worker显式代码参数none这张表格揭示了三类不一致默认值硬编码一组 worker 只接受--url旗标默认地址硬编码为ws://127.0.0.1:49134且完全不读任何环境变量。仓库源码印证了这一点——engine/src/workers/external.rs 的注释明确写着它们硬编码的ws://127.0.0.1:49134默认值MOT-3970引擎不得不在 spawn 时把真实端口通过III_ENGINE_URL/III_URL注入子进程以覆盖该默认值engine/examples/python/echo_invoker.py 也展示了DEFAULT_BRIDGE_URL os.environ.get(III_URL, ws://127.0.0.1:49134)这种读环境变量、否则回退硬编码的折中写法。环境变量命名分裂llm-router 读III_WS_URLshell 系读III_URL名字不统一监督器无法预判该注入哪个。SDK 完全脱钩register_worker()要求显式传入地址参数不读取任何地址相关的环境变量意味着通过 SDK 注册的 worker 无法从环境获得引擎地址。其结果正如 README 所概括的没有任何两个 worker 二进制对如何找到引擎达成一致……监督器无法注入一个不存在的契约——CLI/环境标准正是为了创造这个契约。标准三个参数每个都有旗标与环境回退规范给出的标准非常精简每个 worker 二进制接受相同的三个参数每个参数都有旗标flag和环境变量env两种来源旗标优先。ParameterFlagEnvengine address--urlIII_URLnamespace--namespaceIII_NAMESPACEconfiguration--configIII_CONFIG解析后的负载或句柄——由配置库锁定几个需要展开理解的点旗标优先flags winning当命令行与环境中同时存在时以命令行显式传入的值为准。这一优先级规则在 compose daemon 侧同样成立——crates/iii-compose/src/cli.rs 展示了引擎地址的解析顺序显式 CLI 值优先其次回退III_URL环境变量最后才是本地默认值。III_CONFIG交付的是解析后的负载或句柄它不是一个配置文件路径这么简单。如 crates/iii-compose/src/configuration.rs 所述契约允许以文件路径形式交付配置使 worker 无需凭据即可获取自身配置。究竟交付值还是句柄由配套的配置库config registration library统一锁定避免每个二进制各自实现一套解析。保留键reserved keysdaemon 会把这三个值注入它衍生的每一个子进程hooks 也包括在内worker-compose.yaml中不能声明这些键来覆盖它们保证监督器的注入永远生效。零参数注册registerWorker() 的默认值就是环境契约规范里最关键的一条约定是registerWorker()/register_worker()不带任何参数时读取环境契约显式参数仍然优先——但零参数形式是文档默认因此教程代码里不出现任何地址和命名空间同一份代码在 compose 下、在iii worker下、或手工启动时都能运行。这条约定让零代码上手成为可能这也是 README 中 2026-07-13 评审确定的原则之一开发者无需知道引擎地址、无需理解命名空间只要环境被注入代码就能连上正确的引擎、注册到正确的命名空间。仓库中的 SDK 实现已经能看到这条契约的落地Node SDKsdk/packages/node/iii/tests/env-contract.test.ts 是一个专门为环境契约编写的测试——registerWorker()无参数调用时会从注入的环境如III_URLws://engine.example:9000读取地址无注入时回退到DEFAULT_ENGINE_URL。Python SDKsdk/packages/python/iii/src/iii/iii.py 的register_worker()文档字符串明确写着地址来自III_URL。Rust SDKsdk/packages/rust/iii/src/iii.rs 在注册时解析命名空间优先级是显式 namespace 选项 III_NAMESPACE环境变量 无由引擎应用其默认值并处理了III_NAMESPACE为空字符串时视为未设置的边界情况FOO在 shell 中表示未设置。需要特别说明原规范文档给出的引用是sdk/packages/rust/iii/src/lib.rs:96当前仓库中 SDK 已演进为iii.rs等模块化结构但其语义一致——注册入口读取III_NAMESPACE/III_URL环境变量正是契约要统一的SDK 从环境读取行为。隐式启动package:// 二进制的完整启动故事契约的第二个直接收益是package 型二进制的隐式启动契约就位后package://二进制不再需要启动脚本compose 直接用标准旗标 exec 解析出的制品。这就是 34/41 个今天完全不带scripts:的舰队 worker 的全部启动故事——也解释了为什么scripts.md中的run只服务于本地 worker。含义拆解对package://registry 分发的二进制制品启动就是exec artifact --url … --namespace … --config …一行命令无脚本。这与 scripts.md 的契约完全咬合hooks 对所有 worker 类型都执行在 daemon 宿主上但run只对path://有意义对package://而言启动即 exec 标准 CLI 契约。对path://本地目录、monorepo 开发场景run: pnpm dev这类命令才是必要的——因此run被限定为本地 worker 专属。迁移纯增量additive旧二进制立即受益规范明确迁移策略是增量式的二进制保留现有旗标标准额外增加环境变量回退并统一命名。compose daemon 只依赖环境契约——旧 worker 从它们读取III_URL/III_NAMESPACE/III_CONFIG的那一天起就能在 compose 下运行而这只需共享库的一次依赖升级。共存期间iii worker和 iii-worker-ops 保持原样运行。这意味着无破坏性变更现有--url旗标继续工作只是多了一条 env 回退路径。一次性升级共享的配置注册库config registration library每个 SDK 包一个 crate/package 封装落地后发布版二进制免费获得旗标支持——舰队不必维护 41 套手工参数解析器原文档明确这是 2026-07-13 评审列出的下一步。共存安全在全部 worker 完成迁移前iii worker与 iii-worker-ops 路径不受影响。契约如何与其余五份文档协同cli-contract 是 2026-07-14 worker compose 提案 的六份契约之一它与另外五份的关系决定了它为什么必须是现在就定义的标准与 configuration.md 的关系配置交付compose daemon 先向 configuration worker 拉取基础配置、合并config_override再把最终配置通过标准契约--config/env交给 worker。这正是daemon 交付值而非指针的实现通道——见 configuration.md 中的流程图configuration worker → daemon 合并 → 标准契约 → worker start。若没有统一契约daemon 无法在 spawn 时把最终值注入每个不同类型的 worker。与 scripts.md 的关系hook 执行上下文scripts.md 规定 hooks 的环境是container 解析后的 env——与run得到的一致宿主环境 注入的 url/namespace/config其中注入的三项正是本契约的三个参数。与 namespace.md 的关系命名空间作为运行时参数--namespace/标准 env由 daemon 注入代码不变、registerWorker()从环境拾取——namespace 模型的协议改动正是本契约中--namespace旗标背后的设计。与 lifecycle.md 的关系就绪判定readiness worker 在引擎上的注册可见注册动作由 SDK 完成而 SDK 连接引擎所需的地址就来自本契约注入的III_URL。引擎路由与仲裁、daemon 监督的分工依赖 worker 能通过统一契约连回正确的引擎。与 compose-file.md 的关系身份与保留键compose-file.md 规定容器 id 以III_WORKER_NAME到达子进程且文件不能覆盖保留键——保留键正是本契约的三个参数保证了 compose 文件的声明永远无法越过 daemon 注入的地址/命名空间/配置。从源码确认的契约落地痕迹除了 SDK 侧的读取逻辑引擎与 compose daemon 的源码已经存在与本契约一致的环境变量处理引擎侧注入engine/src/workers/external.rs 在 spawn 外部 worker 时写入III_ENGINE_URL与III_URL值指向引擎实际 worker-listener 端口ws://127.0.0.1:{worker_manager_port}并注明在每次 respawn 时重新导出保证被监督重启的 daemon 保持同一契约。compose daemon 侧读取crates/iii-compose/src/lib.rs 与 crates/iii-compose/src/cli.rs 从III_URL读取引擎地址crates/iii-compose/src/daemon.rs 进一步说明--namespace是 daemon 自身的命名空间回答这个 daemon 属于哪个命名空间与 namespace.md 的模型对应。默认地址的一致性SDK 侧如 sdk/packages/rust/helpers/src/observability/telemetry/types.rs 默认ws://localhost:49134与引擎侧注释中的硬编码默认ws://127.0.0.1:49134指向同一监听端口的约定这正是契约要规范化的默认地址基准。总结cli-contract.md定义了 iii worker 舰队的一条最小公共契约--url/III_URL、--namespace/III_NAMESPACE、--config/III_CONFIG旗标优先、env 兜底、SDK 零参数注册读取环境、daemon 全量注入且键位保留。它没有发明新机制而是把散落在 41 个二进制里的地址发现方式统一成一个可被监督器注入的标准——这让package://二进制免脚本启动成为可能让配置以解析后的值而不是首次启动种子的方式到达 worker也让 compose、iii worker与手工启动三种方式共享同一份代码。从仓库现状看引擎的III_URL注入、SDK 的III_NAMESPACE读取、Node SDK 的环境契约测试都是这条标准正在被落地的早期证据。【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考