CODING AGENT HARNESS · SOURCE AUDITREPORT 04 / 18
04

Open Interpreter

Codex 安全底盘之上做多 Harness 协议仿真;独特价值是“统一 IR,模型原生手感”。

Rust · Multi-Harness Compatibility LayerApache-2.0main
SOURCE
VERIFIED
Repository
openinterpreter/openinterpreter
Commit
aaf0aebf8203559711df6ed25b265a3f096bd3ea
Commit date
2026-07-27T03:34:00-07:00
Findings
26
Citations
72
Tracked files
5,907
EXECUTIVE READING

先给结论,再进入源码

核心机制

Codex turn/step 快照循环;Harness 前后置整形

上下文

调用配对、多模态裁剪、Harness-aware compact

安全边界

审批与权限 profile 双轴;三平台原生沙箱

适用建设

多模型 A/B、Harness 研究、Codex 生态兼容

值得借鉴

  • 协议与 Harness 三层解耦
  • 兼容工具不绕过沙箱/观测
  • 复用成熟 Codex 控制面

需要警惕

  • 适配矩阵爆炸
  • catalog 与 routing 存在接口不一致
  • 独立 analytics 默认启用

直接带走

  • 内部统一 Prompt/ResponseItem IR
  • 适配器单一集成点
  • Harness-aware compaction tests
00 · METHOD

研究口径:先锁提交,再沿运行链读代码

README POLICY

README 只用于定位;结论来自 Rust turn/step 主循环、Harness 路由与逐个请求适配器、工具别名/文件安全、上下文与压缩、权限/原生沙箱、MCP、Hooks、Skills、Multi-agent、Rollout、产品打包与对应测试。

FACT POLICY

把 Open Interpreter 独有的多 Harness 兼容层与继承自 Codex 的共享运行时分开陈述;同时区分模型可见工具名、内部 dispatch runtime 和真实 OS 隔离。

INFERENCE POLICY

不把提示词宣称当代码强制;不推断远端模型服务或分析后端;仓库身份只按本提交的入口、包布局、产品检测与兼容测试陈述。

L1运行实现
L2接口契约
L3测试证明
L4文档佐证
L5明确推断

本页引用 36 个不同源码/测试文件;证据角色分布:实现 53 · 配置 1 · 测试 5 · 契约 13。代码块是固定提交中的原文截取,长区间仅在中部折叠,首尾行号保持真实。

01 · TECHNICAL MAPS

架构总图与单轮执行链路

两张图均由本页证据账本生成,并通过 Archify showcase 9 项校验(0 error / 0 warning)。图可单独打开、搜索、缩放和追踪关系。

FIGURE 01Open Interpreter Harness 架构图全屏打开 ↗
FIGURE 02用户输入到工具回写的技术链路全屏打开 ↗
02 · COVERAGE MAP

审计维度与证据等级

源码身份与成熟度 verified L1 / L3

当前快照是 Rust/Codex 分叉式产品,保留 Codex SDK/协议兼容并通过包变体重品牌。

架构与 Agent Loop verified L1 / L2 / L3

turn/step 状态机、step 快照、pending input、自动压缩与 stop hook。

Harness、Provider 与协议路由 verified L1 / L2 / L3

Responses/Chat/Messages、provider 默认 harness、请求/响应整形与兼容边界。

上下文、压缩与恢复 verified L1 / L2 / L3

规范化历史、工具配对、多模态裁剪、Harness-aware 压缩。

工具、编辑与执行 verified L1 / L2 / L3

可见 spec 与 registry 分离、代码模式、Harness aliases、文件变更事件。

权限、审批与沙箱 verified L1 / L2 / L3

审批与权限 profile、路径双重校验、macOS/Linux/Windows 原生隔离。

MCP、扩展、Skills 与 Hooks verified L1 / L2 / L3

MCP catalog、Skills/Plugins/Extensions、完整 hooks 生命周期。

子 Agent 与协作 verified L1 / L2 / L3

线程树控制面、fork/message/resume、深度与并发限制;Harness aliases 可复用同一子 Agent 系统。

持久化与观测 verified L1 / L2 / L3

JSONL rollout、SQLite 镜像、文件变更 lifecycle、Open Interpreter 独立 analytics endpoint 与 opt-out。

01
DIMENSION · IDENTITY-MATURITY

源码身份与成熟度

本章共 3 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

01
L1事实oi-identity-001

当前源码不是经典 Python Open Interpreter,而是 Rust/Codex 兼容分叉

源码事实

核心目录、crate、app-server 协议和 Python/TypeScript SDK 仍以 codex/openai-codex 命名;Open Interpreter 通过 Product::OpenInterpreter、interpreter/i 入口、.openinterpreter HOME 和 open-interpreter 包变体建立产品身份。

白话解释

它不是在旧 Python 循环上继续打补丁,而是把一套 Codex 级 Rust Harness 换了产品入口,再加入自己的多 Harness 能力。

对自研 Harness 的含义

评估时必须把它与同批次的 openai/codex 分开:共享基座很多,但 Open Interpreter 的差异主要落在品牌、provider/harness 选择和协议仿真。

关键源码 · 实现
codex-rs/product-info/src/lib.rs · L45–L79
   45  /// Product channel information used by branded package variants.
   46  #[derive(Debug, Clone, Copy, PartialEq, Eq)]
   47  pub enum Product {
   48      Codex,
   49      OpenInterpreter,
   50  }
   51  
   52  impl Product {
   53      /// A binary shipped inside an Open Interpreter package is Open
   54      /// Interpreter unconditionally — identity must never depend on what the
   55      /// executable happens to be named or aliased to. The argv0 and env-var
   56      /// checks only exist for development builds run straight out of the
   57      /// cargo target directory.
   58      pub fn current() -> Self {
   59          if std::env::var_os(OPEN_INTERPRETER_BRAND_ENV_VAR).is_some()
   60              || is_open_interpreter_argv0()
   61              || is_open_interpreter_install()
   62          {
   63              Self::OpenInterpreter
   64          } else {
   65              Self::Codex
   66          }
   67      }
   68  
      … 1 lines omitted; exact range 45–79 …
   70          match self {
   71              Product::Codex => "OpenAI Codex",
   72              Product::OpenInterpreter => "Open Interpreter",
   73          }
   74      }
   75  
   76      pub fn command_name(self) -> &'static str {
   77          match self {
   78              Product::Codex => "codex",
   79              Product::OpenInterpreter => "interpreter",
查看全部 3 处证据
  • 实现 codex-rs/product-info/src/lib.rs:45–79 Codex/OpenInterpreter 产品检测与显示名/命令名。
  • 实现 scripts/install/install-open-interpreter.sh:13–25 interpreter/i、release asset 与 .openinterpreter HOME 映射到共用安装器。
  • 配置 scripts/codex_package/targets.py:60–85 open-interpreter 包变体。
02
L3事实oi-identity-002

兼容性是被测试的产品契约,不只是目录遗留

源码事实

仓库用 interpreter 二进制替换 CODEX_EXEC_PATH,运行 @openai/codex-sdk 的 thread resume 测试;包布局测试也检查 interpreter 与 i alias 以及 code-mode host。

白话解释

“还能被 Codex SDK 当成 Codex 用”是 CI 级目标,不是偶然能跑。

对自研 Harness 的含义

企业接入可复用 Codex 客户端生态;代价是内部命名和上游演进耦合很深。

关键源码 · 测试
scripts/test-codex-sdk-compat.sh · L21–L36
   21  cd "${repo_root}"
   22  
   23  if [[ ! -d node_modules || ! -d sdk/typescript/node_modules ]]; then
   24    "${pnpm_command[@]}" install --frozen-lockfile --filter @openai/codex-sdk...
   25  fi
   26  
   27  "${pnpm_command[@]}" --filter @openai/codex-sdk run build
   28  
   29  CODEX_EXEC_PATH="${interpreter_bin}" "${pnpm_command[@]}" \
   30    --dir sdk/typescript \
   31    exec jest \
   32    --runInBand \
   33    tests/run.test.ts \
   34    --testNamePattern "resumes thread by id"
   35  
   36  echo "Codex SDK compatibility passed with ${interpreter_bin}"
查看全部 2 处证据
  • 测试 scripts/test-codex-sdk-compat.sh:21–36 用 interpreter 执行 Codex SDK resume 测试。
  • 测试 scripts/codex_package/test_layout.py:19–63 Open Interpreter 包入口与 alias 布局契约。
03
L5推断oi-maturity-001

优势是“一个安全底盘,多种模型原生手感”;主要成本是兼容矩阵爆炸

源码事实

本提交同时维护 15 类 Harness enum、三种 wire protocol、多个独立 request builder、数千行 alias/adapter 与 Harness-aware compaction,并以大量路由/快照/包测试约束行为。

白话解释

它最像“Coding Agent 兼容器”:同一套沙箱和会话底盘,让不同模型吃到熟悉的提示词与工具格式。

对自研 Harness 的含义

建设自有 Agent 时可借鉴“内部统一 IR + 外部 Harness adapter”;但必须为路由、历史翻译、工具参数、压缩和错误恢复建立组合测试,否则适配越多越难证明正确。

边界
  • 这是基于当前源码形态的工程判断,不代表每种 Harness 在目标 benchmark 上一定优于 Native。
关键源码 · 实现
codex-rs/core/src/harness/request.rs · L75–L231
   75  pub(crate) fn build_chat_harness_request(
   76      route: ChatHarnessRoute,
   77      turn: ChatHarnessTurn<'_>,
   78  ) -> Result<ChatHarnessRequest, CodexErr> {
   79      let ChatHarnessTurn {
   80          prompt,
   81          harness,
   82          harness_guidance,
   83          model_info,
   84          effort,
   85          thread_id,
   86          session_source,
   87      } = turn;
   88      let guided_prompt = prompt_with_harness_guidance(prompt, harness, harness_guidance);
   89      let yolo_mode = prompt
   90          .base_instructions
   91          .text
   92          .contains("Approval policy is currently never.");
   93      let (request_body, tool_kinds, title_request, postprocess) = match route {
   94          ChatHarnessRoute::DeepSeekTui => {
   95              let (request_body, tool_kinds) = build_deepseek_tui_request(&guided_prompt, model_info)
   96                  .map_err(|err| {
   97                      CodexErr::InvalidRequest(format!("invalid deepseek-tui request: {err}"))
   98                  })?;
      … 123 lines omitted; exact range 75–231 …
  222          }
  223          ChatHarnessPostprocess::SweAgentActionCalls { has_submit_review } => {
  224              inject_swe_agent_action_calls(stream, has_submit_review)
  225          }
  226          ChatHarnessPostprocess::Terminus2ActionCalls {
  227              request_kind,
  228              pending_completion,
  229          } => inject_terminus_2_action_calls(stream, request_kind, pending_completion),
  230      }
  231  }
查看全部 4 处证据
  • 实现 codex-rs/core/src/harness/request.rs:75–231 集中但广泛的 Harness request/postprocess 矩阵。
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:102–254 庞大的工具别名矩阵。
  • 实现 codex-rs/core/src/compact.rs:600–815 Harness-aware 长上下文交接。
  • 契约 LICENSE:1–20 Apache License 2.0。
02
DIMENSION · HARNESS-ROUTING

Harness、Provider 与协议路由

本章共 5 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

04
L1事实oi-harness-001

核心差异是一层多 Harness 仿真目录

源码事实

源码内有 Claude Code/full+bare、DeepSeek TUI、Kimi CLI、Kimi Code、Little Coder、mini-swe-agent、OpenCode、Pi、Qwen Code、SWE-agent、Terminus 2、ZCode 与 Minimal 等独立请求构造器;app-server 将主要可选项按 wire API 编成 catalog。

白话解释

同一个底盘能换不同“驾驶舱”:改变系统提示词、消息格式、工具名称与参数,去适配最合适的模型习惯。

对自研 Harness 的含义

这比普通 provider adapter 更深,但也不是把这些项目的完整运行时都嵌入进来。

边界
  • catalog 的可选项与底层 enum 并非一一相等,例如 ZCode 存在于底层实现但未列入这一段 UI catalog。
关键源码 · 实现
codex-rs/core/src/harness/mod.rs · L1–L18
    1  pub(crate) mod claude_code;
    2  mod claude_code_prompt;
    3  pub(crate) mod deepseek_tui;
    4  pub(crate) mod guidance;
    5  pub(crate) mod kimi_cli;
    6  pub(crate) mod kimi_code;
    7  pub(crate) mod little_coder;
    8  pub(crate) mod mini_swe_agent;
    9  pub(crate) mod minimal;
   10  pub(crate) mod opencode;
   11  pub(crate) mod pi;
   12  pub(crate) mod qwen_code;
   13  pub(crate) mod request;
   14  pub(crate) mod routing;
   15  pub(crate) mod session_skills;
   16  pub(crate) mod swe_agent;
   17  pub(crate) mod terminus_2;
   18  pub(crate) mod zcode;
查看全部 3 处证据
  • 实现 codex-rs/core/src/harness/mod.rs:1–18 所有 Harness 模块入口。
  • 契约 codex-rs/app-server/src/interpreter_catalog.rs:29–118 按 Messages/Chat/All wire 分类的 Harness catalog。
  • 契约 codex-rs/tools/src/harness.rs:1–99 Harness enum 与配置名解析。
05
L2事实oi-harness-002

Provider、Wire API、Harness 是三层独立选择

源码事实

app-server DTO 分开暴露 Provider、Model、Harness;Provider 包含 base URL/env key/wire API,Harness 是可推荐的独立选项。默认推断按 provider/model/base URL 把 Claude→claude-code、Kimi→kimi-code、Qwen→qwen-code、DeepSeek→claude-code-bare。

白话解释

“连哪家服务器”“用哪个模型”“让请求长得像哪个 Coding Agent”不是同一个开关。

对自研 Harness 的含义

可做跨模型的 Harness A/B;默认映射是产品经验规则,不代表所有组合都兼容。

关键源码 · 契约
codex-rs/app-server-protocol/src/protocol/v2/interpreter.rs · L8–L44
    8  #[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
    9  #[serde(rename_all = "lowercase")]
   10  #[ts(export_to = "v2/")]
   11  pub enum WireApiDto {
   12      Responses,
   13      Chat,
   14      Messages,
   15  }
   16  
   17  #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
   18  #[serde(rename_all = "camelCase")]
   19  #[ts(export_to = "v2/")]
   20  pub struct InterpreterProvider {
   21      pub id: String,
   22      pub name: String,
   23      pub description: String,
   24      pub is_current: bool,
   25      #[ts(optional)]
   26      pub base_url: Option<String>,
   27      #[ts(optional)]
   28      pub wire_api: Option<WireApiDto>,
   29      #[ts(optional)]
   30      pub env_key: Option<String>,
   31      pub configured: bool,
      … 3 lines omitted; exact range 8–44 …
   35  #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
   36  #[serde(rename_all = "camelCase")]
   37  #[ts(export_to = "v2/")]
   38  pub struct InterpreterHarness {
   39      #[ts(optional)]
   40      pub id: Option<String>,
   41      pub label: String,
   42      pub description: String,
   43      pub is_recommended: bool,
   44  }
查看全部 3 处证据
  • 契约 codex-rs/app-server-protocol/src/protocol/v2/interpreter.rs:8–44 WireApi、Provider、Harness DTO。
  • 契约 codex-rs/app-server-protocol/src/protocol/v2/interpreter.rs:78–137 model/harness list 与 set API。
  • 实现 codex-rs/model-provider-info/src/lib.rs:161–223 provider/model 到默认 harness 的启发式映射。
06
L3事实oi-harness-003

路由矩阵在代码里硬校验,不兼容组合直接报错

源码事实

Responses 原生走 Responses;Chat 非 Claude Harness 走 chat compatibility;Claude full/bare 可对 Responses/Chat 做 profile shaping;Messages 只允许 Claude 与 ZCode 原生路径,其他 Harness 和 Native Messages 返回 InvalidRequest。单元测试覆盖这些分支。

白话解释

不是把任意协议和任意外壳随便相乘;路由表会在发请求前拦住不支持的组合。

对自研 Harness 的含义

错误更早、更可诊断;catalog 的 Native/ALL 表述仍需与 routing 的 Native+Messages 拒绝一起理解。

边界
  • app-server catalog 把 Native 标成 ALL_WIRE_APIS,但底层 routing 对 Native+Messages 明确报错;这是当前提交可见的接口不一致。
关键源码 · 实现
codex-rs/core/src/harness/routing.rs · L5–L151
    5  #[derive(Debug, Clone, Copy, Eq, PartialEq)]
    6  pub(crate) enum MessagesHarnessRoute {
    7      ClaudeCode,
    8      ZCode,
    9  }
   10  
   11  /// Which claude-code tool/prompt surface a non-Messages wire should shape.
   12  ///
   13  /// `claude-code` and `claude-code-bare` share the same shaping primitives but
   14  /// differ in system prompt and tool set; this carries that distinction onto the
   15  /// Responses and Chat transports.
   16  #[derive(Debug, Clone, Copy, Eq, PartialEq)]
   17  pub(crate) enum ClaudeCodeProfileRoute {
   18      Full,
   19      Bare,
   20  }
   21  
   22  #[derive(Debug, Clone, Copy, Eq, PartialEq)]
   23  pub(crate) enum ChatHarnessRoute {
   24      DeepSeekTui,
   25      KimiCode,
   26      KimiCli,
   27      LittleCoder,
   28      MiniSweAgent,
      … 113 lines omitted; exact range 5–151 …
  142          (WireApi::Messages, Harness::Native) => Err(CodexErr::InvalidRequest(
  143              "wire_api = \"messages\" requires a harness-native transport; configure harness = \"claude-code\" or \"claude-code-bare\" for Anthropic-style sessions"
  144                  .to_string(),
  145          )),
  146          (WireApi::Messages, Harness::Other(harness_name)) => Err(CodexErr::InvalidRequest(
  147              format!(
  148                  "wire_api = \"messages\" is not supported by harness = \"{harness_name}\""
  149              ),
  150          )),
  151      }
查看全部 2 处证据
  • 实现 codex-rs/core/src/harness/routing.rs:5–151 完整 transport route matrix 与错误分支。
  • 测试 codex-rs/core/src/harness/routing.rs:185–270 Responses/Chat/Messages 与 Claude profile 的路由测试。
07
L1事实oi-harness-004

请求仿真的单一入口统一处理前置与后置整形

源码事实

request.rs 明确声明为 model client 与 chat harness emulation 的单一集成点;它按 route 调各 builder,判断 YOLO、可加 Harness guidance、为 OpenCode 生成独立 title request,并为 mini-SWE/SWE-agent/Terminus 2 注入响应流后处理。

白话解释

每种外壳的怪癖被收在一个总路由器里:发出前改请求,回来后必要时把文本动作翻译成工具动作。

对自研 Harness 的含义

新增 Harness 的改动面较集中;后处理型工具提取比原生 function call 更脆弱,必须依赖格式测试。

关键源码 · 契约
codex-rs/core/src/harness/request.rs · L1–L8
    1  //! The single integration point between the model client and
    2  //! chat-completions harness emulation.
    3  //!
    4  //! `client.rs` resolves a [`ChatHarnessRoute`] and calls
    5  //! [`build_chat_harness_request`]; everything harness-specific — guidance
    6  //! injection, per-harness request building, and response-stream
    7  //! postprocessing — lives here. Adding a chat harness means adding a route
    8  //! arm in this module, not editing the client.
查看全部 3 处证据
  • 契约 codex-rs/core/src/harness/request.rs:1–8 单一 Harness 集成点声明。
  • 契约 codex-rs/core/src/harness/request.rs:42–73 turn 输入、请求输出与 postprocess 类型。
  • 实现 codex-rs/core/src/harness/request.rs:75–231 各 Harness builder、title request 和 response postprocess 分发。
08
L1事实oi-harness-005

各 Harness 不只换 prompt,还重写历史和工具协议

源码事实

例如 Pi builder 生成自己的 system prompt/tools/thinking 配置,把 ResponseItem 历史改成 Chat messages,跳过 contextual user message、配对工具调用与结果、保留 reasoning_content,并把 LocalShell/Custom tool call 映射成 Pi 认识的名字;Little Coder 与 OpenCode 各自拥有不同 system prompt、tool kinds 和 title/search-agent 逻辑。

白话解释

这不是贴一张角色卡,而是把整段对话和工具说明书翻译成目标 Agent 的“母语”。

对自研 Harness 的含义

模型行为更接近目标 Harness;翻译层必须维护 call/result 配对和隐藏上下文,升级成本高。

关键源码 · 实现
codex-rs/core/src/harness/pi.rs · L21–L120
   21      })];
   22      messages.extend(build_messages(prompt.get_formatted_input())?);
   23      let tools = build_tools();
   24      let tool_kinds = tools
   25          .iter()
   26          .filter_map(|tool| {
   27              tool.get("function")
   28                  .and_then(|function| function.get("name"))
   29                  .and_then(Value::as_str)
   30                  .map(|name| (name.to_string(), ToolOutputKind::Function))
   31          })
   32          .collect();
   33  
   34      Ok((
   35          json!({
   36              "model": model_info.slug,
   37              "messages": messages,
   38              "stream": true,
   39              "stream_options": {
   40                  "include_usage": true,
   41              },
   42              "store": false,
   43              "tools": tools,
   44              "thinking": {
      … 66 lines omitted; exact range 21–120 …
  111                                  }
  112                              ],
  113                          }));
  114                      }
  115                  }
  116                  "developer" => {}
  117                  _ => {}
  118              },
  119              ResponseItem::FunctionCall {
  120                  name,
查看全部 3 处证据
  • 实现 codex-rs/core/src/harness/pi.rs:21–120 Pi request body、system prompt 与历史转换。
  • 实现 codex-rs/core/src/harness/pi.rs:121–225 Pi tool call/result、reasoning 与 LocalShell 映射。
  • 实现 codex-rs/core/src/harness/opencode.rs:1–180 OpenCode request、title/search-agent 适配。
03
DIMENSION · ARCHITECTURE-LOOP

架构与 Agent Loop

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

09
L1事实oi-loop-001

共享内核仍是 turn 内多 step 的流式工具循环

源码事实

run_turn 先做预压缩、注入 skills/plugins、运行 session/user hooks并记录输入;随后循环捕获 step context、构造历史、流式 sampling。模型要求工具或有 pending input 就继续,否则运行 stop/after-agent hook 后结束。

白话解释

一次用户请求会反复经历“取固定快照—问模型—跑工具—把结果放回去”,直到模型真正收尾。

对自研 Harness 的含义

Harness 仿真共享同一个成熟执行底盘,不需要每种 Harness 重写 agent loop。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L140–L228
  140  ///
  141  /// - If the model requests a function call, we execute it and send the output
  142  ///   back to the model in the next sampling request.
  143  /// - If the model sends only an assistant message, we record it in the
  144  ///   conversation history and consider the turn complete.
  145  ///
  146  pub(crate) async fn run_turn(
  147      sess: Arc<Session>,
  148      turn_context: Arc<TurnContext>,
  149      turn_extension_data: Arc<codex_extension_api::ExtensionData>,
  150      input: Vec<TurnInput>,
  151      prewarmed_client_session: Option<ModelClientSession>,
  152      cancellation_token: CancellationToken,
  153  ) -> CodexResult<Option<String>> {
  154      let mut client_session =
  155          prewarmed_client_session.unwrap_or_else(|| sess.services.model_client.new_session());
  156      // TODO(ccunningham): Pre-turn compaction runs before context updates and the
  157      // new user message are recorded. Estimate pending incoming items (context
  158      // diffs/full reinjection + user input) and trigger compaction preemptively
  159      // when they would push the thread over the compaction threshold.
  160      if let Err(err) = run_pre_sampling_compact(&sess, &turn_context, &mut client_session).await {
  161          if matches!(err, CodexErr::TurnAborted) {
  162              return Err(err);
  163          }
      … 55 lines omitted; exact range 140–228 …
  219      ));
  220  
  221      // `ModelClientSession` is turn-scoped and caches WebSocket + sticky routing state, so we reuse
  222      // one instance across retries within this turn.
  223      // Pending input is drained into history before building the next model request.
  224      // However, we defer that drain until after sampling in two cases:
  225      // 1. At the start of a turn, so the fresh turn input in `input` gets sampled first.
  226      // 2. After auto-compact, when model/tool continuation needs to resume before any steer.
  227  
  228      let mut next_step_context = Some(first_step_context);
查看全部 3 处证据
  • 实现 codex-rs/core/src/session/turn.rs:140–228 turn 初始化、skills/plugins/hooks 与 turn-scoped client。
  • 实现 codex-rs/core/src/session/turn.rs:229–324 pending input、step snapshot 与 sampling。
  • 实现 codex-rs/core/src/session/turn.rs:355–460 自动压缩、Harness 特例、stop hook 与结束条件。
10
L1事实oi-loop-002

step 快照让上下文、工具清单与工具执行看到同一世界

源码事实

每个循环只 capture 一次 StepContext,注释明确要求 context、advertised tools 和 tool calls 共享同一 request view;world state 变化被记录到 rollout,下一 step 才重新采样环境。

白话解释

模型看到的工具说明和真正执行工具时的权限/目录不会在同一步里偷偷漂移。

对自研 Harness 的含义

降低并发配置变化导致的 TOCTOU 类语义错位;动态变更需要等下一 step 生效。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L243–L292
  243          let window_id = sess.current_window_id().await;
  244          super::rollout_budget::maybe_record_reminder(
  245              sess.as_ref(),
  246              turn_context.as_ref(),
  247              &window_id,
  248          )
  249          .await;
  250  
  251          // Capture once so context, advertised tools, and tool calls share one request view.
  252          let step_context = match next_step_context.take() {
  253              Some(step_context) => step_context,
  254              None => sess.capture_step_context(Arc::clone(&turn_context)).await,
  255          };
  256          let sampling_request_result: CodexResult<_> = async {
  257              super::time_reminder::maybe_record_current_time_reminder(
  258                  sess.as_ref(),
  259                  turn_context.as_ref(),
  260                  &window_id,
  261              )
  262              .await?;
  263  
  264              world_state = sess
  265                  .record_step_world_state_if_changed(&world_state, step_context.as_ref())
  266                  .await;
      … 16 lines omitted; exact range 243–292 …
  283                  Arc::clone(&sess),
  284                  Arc::clone(&step_context),
  285                  Arc::clone(&turn_extension_data),
  286                  Arc::clone(&turn_diff_tracker),
  287                  &mut client_session,
  288                  &responses_metadata,
  289                  sampling_request_input,
  290                  cancellation_token.child_token(),
  291              )
  292              .await
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/turn.rs:243–292 step context 单次捕获和 world state 记录。
  • 契约 codex-rs/core/src/session/step_context.rs:1–54 step-scoped 配置、MCP、环境和工具快照。
04
DIMENSION · CONTEXT-COMPACTION

上下文、压缩与恢复

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

11
L1事实oi-context-001

历史管理维护调用配对、多模态能力和可见 token 成本

源码事实

ContextManager 记录 ResponseItem 后按输入模态规范化:补齐缺失 call output、删除孤儿 output、剥离不支持的图片/音频;工具输出按策略截断,并用模型可见字节估算 token。

白话解释

上下文不是简单 messages 数组;它会修账,保证工具订单和回执成对,并避免把模型根本不能看的媒体继续塞回去。

对自研 Harness 的含义

恢复和压缩后的协议更稳定;token 估算是启发式下界,不等于 provider tokenizer。

关键源码 · 实现
codex-rs/core/src/context_manager/history.rs · L40–L186
   40  pub(crate) struct ContextManager {
   41      /// The oldest items are at the beginning of the vector. Snapshots share the vector until a
   42      /// caller needs to mutate it, avoiding deep copies for read-only history consumers.
   43      items: Arc<Vec<ResponseItem>>,
   44      /// Bumped whenever history is rewritten, such as compaction or rollback.
   45      history_version: u64,
   46      token_info: Option<TokenUsageInfo>,
   47      /// Reference context snapshot used for diffing and producing model-visible
   48      /// settings update items.
   49      ///
   50      /// This is the baseline for the next regular model turn, and may already
   51      /// match the current turn after context updates are persisted.
   52      ///
   53      /// When this is `None`, settings diffing treats the next turn as having no
   54      /// baseline and emits a full reinjection of context state. Rollback may
   55      /// also clear this when it trims a mixed initial-context developer bundle
   56      /// whose non-diff fragments no longer exist in the surviving history.
   57      reference_context_item: Option<TurnContextItem>,
   58      /// World state most recently appended to model-visible history.
   59      world_state_baseline: Option<WorldStateSnapshot>,
   60  }
   61  
   62  impl ContextManager {
   63      pub(crate) fn new() -> Self {
      … 113 lines omitted; exact range 40–186 …
  177          let base_tokens =
  178              i64::try_from(approx_token_count(&base_instructions.text)).unwrap_or(i64::MAX);
  179  
  180          let items_tokens = self
  181              .items
  182              .iter()
  183              .map(estimate_item_token_count)
  184              .fold(0i64, i64::saturating_add);
  185  
  186          Some(base_tokens.saturating_add(items_tokens))
查看全部 3 处证据
  • 实现 codex-rs/core/src/context_manager/history.rs:40–186 历史结构、记录、prompt normalization 与 token estimate。
  • 实现 codex-rs/core/src/context_manager/history.rs:328–368 调用配对、媒体剥离与工具输出截断。
  • 契约 codex-rs/core/src/context_manager/history.rs:493–505 模型可见 token 粗估规则。
12
L1事实oi-context-002

压缩是 Harness-aware 的,而不是统一摘要模板

源码事实

压缩先用当前 Harness 生成摘要请求,然后 build_harness_compacted_history:ZCode、Claude Code bare 等可走各自 replacement history;普通路径用 summary prefix。还会从 harness read 调用重建相关文件内容,并识别 no-truncate 标记。

白话解释

换了驾驶舱,压缩后的“交接便笺”也要换写法,否则目标模型会读不懂或丢失刚看过的文件。

对自研 Harness 的含义

长会话兼容性更好;每新增 Harness 都必须测试压缩与恢复,否则短任务能跑、长任务会失真。

关键源码 · 实现
codex-rs/core/src/compact.rs · L299–L389
  299                      history.remove_first_item();
  300                      retries = 0;
  301                      continue;
  302                  }
  303                  sess.set_total_tokens_full(turn_context.as_ref()).await;
  304                  sess.track_turn_codex_error(turn_context.as_ref(), &e);
  305                  let event = EventMsg::Error(e.to_error_event(/*message_prefix*/ None));
  306                  sess.send_event(&turn_context, event).await;
  307                  return Err(e);
  308              }
  309              Err(e) => {
  310                  if retries < max_retries {
  311                      retries += 1;
  312                      let delay = backoff(retries);
  313                      sess.notify_stream_error(
  314                          turn_context.as_ref(),
  315                          format!("Reconnecting... {retries}/{max_retries}"),
  316                          e,
  317                      )
  318                      .await;
  319                      tokio::time::sleep(delay).await;
  320                      continue;
  321                  } else {
  322                      sess.track_turn_codex_error(turn_context.as_ref(), &e);
      … 57 lines omitted; exact range 299–389 …
  380      .await;
  381      sess.recompute_token_usage(&turn_context).await;
  382  
  383      sess.emit_turn_item_completed(&turn_context, compaction_item)
  384          .await;
  385      let warning = EventMsg::Warning(WarningEvent {
  386          message: "Heads up: Long threads and multiple compactions can cause the model to be less accurate. Start a new thread when possible to keep threads small and targeted.".to_string(),
  387      });
  388      sess.send_event(&turn_context, warning).await;
  389      Ok(summary_suffix)
查看全部 3 处证据
  • 实现 codex-rs/core/src/compact.rs:299–389 压缩请求、replacement history 与 rollout 记录。
  • 实现 codex-rs/core/src/compact.rs:600–689 Harness-specific compacted history。
  • 实现 codex-rs/core/src/compact.rs:718–815 从 Harness read 轨迹恢复文件上下文与 no-truncate 标记。
05
DIMENSION · TOOLS-EDITING

工具、编辑与执行

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

13
L1事实oi-tools-001

模型可见工具与内部可分发 runtime 分离

源码事实

Tool plan 先按 exposure 去重、生成模型可见 spec,再由全部 runtimes 建 ToolRegistry;dispatch-only handler 可以不可见但仍接住兼容工具名。Code mode 又把允许的工具 schema 包进 execute/wait 两个工具。

白话解释

给模型看的菜单和厨房真正能接的订单不是同一张表;旧别名可以藏在后厨,不污染新模型的菜单。

对自研 Harness 的含义

兼容多 Harness 时能避免重复工具;隐藏 handler 仍属于攻击面,必须受同一权限检查。

关键源码 · 实现
codex-rs/core/src/tools/spec_plan.rs · L240–L268
  240      let mut seen_tool_names = HashSet::new();
  241      for runtime in &runtimes {
  242          let tool_name = runtime.tool_name();
  243          if !seen_tool_names.insert(tool_name.clone()) {
  244              continue;
  245          }
  246          let exposure = runtime.exposure();
  247          if exposure.is_direct() && !is_hidden_by_code_mode_only(turn_context, &tool_name, exposure)
  248          {
  249              let spec = runtime.spec();
  250              specs.push(spec_for_model_request(
  251                  turn_context,
  252                  exposure,
  253                  &tool_name,
  254                  spec,
  255              ));
  256          }
  257      }
  258      specs.extend(hosted_specs);
  259  
  260      let registry = ToolRegistry::from_tools(runtimes);
  261      let model_visible_specs = merge_into_namespaces(specs)
  262          .into_iter()
  263          .filter(|spec| {
  264              namespace_tools_enabled(turn_context) || !matches!(spec, ToolSpec::Namespace(_))
  265          })
  266          .collect();
  267  
  268      (model_visible_specs, registry)
查看全部 3 处证据
  • 实现 codex-rs/core/src/tools/spec_plan.rs:240–268 visible specs 与 registry 分离。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:432–495 Code mode 嵌套工具构造。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:719–735 统一 exec 可见、legacy shell dispatch-only。
14
L1事实oi-tools-002

Harness aliases 将十余套工具名收敛到共享执行器

源码事实

HarnessAliasHandler 覆盖 Bash/Read/Write/Edit/Glob/Grep、Claude task、Kimi goal/cron、DeepSeek diagnostics/git/file、OpenCode task/todo、ZCode plan/skill 等;spec plan 按当前 Harness 添加可见或 dispatch-only alias。

白话解释

Claude 叫 Read、Pi 叫 read、OpenCode 叫 task,都可以落到同一套真实能力上。

对自研 Harness 的含义

跨 Harness 复用强;别名层很大,参数语义和错误文本需要逐 Harness 回归。

关键源码 · 实现
codex-rs/core/src/tools/handlers/harness_aliases.rs · L102–L254
  102  #[derive(Clone, Copy)]
  103  pub enum HarnessAliasHandler {
  104      Agent,
  105      Bash,
  106      BashLower,
  107      Read,
  108      ReadLower,
  109      ReadMediaFile,
  110      Write,
  111      WriteLower,
  112      Edit,
  113      EditLower,
  114      Glob,
  115      GlobLower,
  116      Grep,
  117      GrepLower,
  118      AskUserQuestion,
  119      TaskList,
  120      TaskOutput,
  121      TaskStop,
  122      ChecklistAdd,
  123      ChecklistList,
  124      ChecklistUpdate,
  125      ChecklistWrite,
      … 119 lines omitted; exact range 102–254 …
  245              Self::DeepSeekWriteFile => handle_deepseek_write_file(invocation).await,
  246              Self::OpenCodeTask => handle_opencode_task(invocation).await,
  247              Self::OpenCodeTodoWrite => handle_opencode_todowrite(invocation).await,
  248              Self::ZCodeTodoRead => handle_zcode_todo_read(invocation).await,
  249              Self::ZCodeTodoWrite => handle_zcode_todo_write(invocation).await,
  250              Self::ZCodeEnterPlanMode => handle_zcode_enter_plan_mode(invocation).await,
  251              Self::ZCodeExitPlanMode => handle_zcode_exit_plan_mode(invocation).await,
  252              Self::ZCodeReadSessionContext => handle_zcode_read_session_context(invocation).await,
  253              Self::ZCodeSkill => handle_zcode_skill(invocation).await,
  254          }
查看全部 2 处证据
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:102–254 alias 枚举、工具名、并发声明和 dispatch。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:610–685 按 Harness 装载不同可见/隐藏 alias。
15
L1事实oi-tools-003

Harness 写文件也进入统一 FileChange lifecycle

源码事实

Write/Edit alias 先读取旧内容构建 Add/Update unified diff,发 Started,再执行写入;成功发 Completed,失败发 Failed。事件通过 TurnItem::FileChange 进入会话与 rollout,而不是只返回一句工具文本。

白话解释

即使模型说的是别家 Agent 的 Write/Edit,前端仍能看到正式的文件改动卡片、diff、成功或失败状态。

对自研 Harness 的含义

兼容层不会绕过观测与审计;这是当前提交的主变更点。

关键源码 · 实现
codex-rs/core/src/tools/handlers/harness_aliases.rs · L1749–L1821
 1749  #[derive(Deserialize)]
 1750  struct WriteArgs {
 1751      #[serde(alias = "file_path", alias = "filePath")]
 1752      path: String,
 1753      content: String,
 1754      #[serde(default)]
 1755      mode: Option<String>,
 1756  }
 1757  
 1758  #[derive(Clone, Copy)]
 1759  enum HarnessFileChangeStage<'a> {
 1760      Started,
 1761      Completed,
 1762      Failed(&'a str),
 1763  }
 1764  
 1765  fn harness_file_change(
 1766      path: &Path,
 1767      previous_content: Option<&str>,
 1768      updated_content: &str,
 1769  ) -> HashMap<PathBuf, FileChange> {
 1770      let change = match previous_content {
 1771          Some(previous_content) => FileChange::Update {
 1772              unified_diff: similar::TextDiff::from_lines(previous_content, updated_content)
      … 39 lines omitted; exact range 1749–1821 …
 1812                  .await;
 1813          }
 1814          HarnessFileChangeStage::Completed | HarnessFileChangeStage::Failed(_) => {
 1815              invocation
 1816                  .session
 1817                  .emit_turn_item_completed(&invocation.turn, item)
 1818                  .await;
 1819          }
 1820      }
 1821  }
查看全部 3 处证据
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:1749–1821 FileChange Add/Update 与 started/completed/failed emitter。
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:1823–1925 Write alias 的安全路径、diff 和 lifecycle。
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:1927–2025 Edit alias 的读前置、替换、错误和 lifecycle。
16
L1事实oi-tools-004

工具并发用读写锁表达,而不是一律并发

源码事实

ToolCallRuntime 查询 handler 是否支持并发;并发工具取得共享 read lock,写入/交互等排他工具取得 write lock,因此同组读工具可并行,任何排他工具会等待并阻塞后续组。

白话解释

多个搜索可以一起跑,但写文件或问用户会像闸门一样独占执行通道。

对自研 Harness 的含义

兼顾吞吐和副作用顺序;alias 自己也声明 Edit/Write/AskUserQuestion 不并行。

关键源码 · 实现
codex-rs/core/src/tools/parallel.rs · L42–L138
   42  pub(crate) struct ToolCallRuntime {
   43      router: Arc<ToolRouter>,
   44      session: Arc<Session>,
   45      // Tool calls may run later, so retain the step whose tool list advertised them.
   46      step_context: Arc<StepContext>,
   47      tracker: SharedTurnDiffTracker,
   48      parallel_execution: Arc<RwLock<()>>,
   49  }
   50  
   51  impl ToolCallRuntime {
   52      pub(crate) fn new(
   53          router: Arc<ToolRouter>,
   54          session: Arc<Session>,
   55          step_context: Arc<StepContext>,
   56          tracker: SharedTurnDiffTracker,
   57      ) -> Self {
   58          Self {
   59              router,
   60              session,
   61              step_context,
   62              tracker,
   63              parallel_execution: Arc::new(RwLock::new(())),
   64          }
   65      }
      … 63 lines omitted; exact range 42–138 …
  129          let abort_dispatch_span = dispatch_span.clone();
  130  
  131          let mut dispatch_handle: AbortOnDropHandle<Result<AnyToolResult, FunctionCallError>> =
  132              AbortOnDropHandle::new(tokio::spawn(async move {
  133                  let _guard = if supports_parallel {
  134                      Either::Left(lock.read().await)
  135                  } else {
  136                      Either::Right(lock.write().await)
  137                  };
  138                  // Admission through the parallel-execution gate marks the end
查看全部 2 处证据
  • 实现 codex-rs/core/src/tools/parallel.rs:42–138 共享 RwLock 与 read/write admission。
  • 契约 codex-rs/core/src/tools/handlers/harness_aliases.rs:196–205 Harness alias 并发能力声明。
06
DIMENSION · PERMISSIONS-SANDBOX

权限、审批与沙箱

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

17
L1事实oi-security-001

Harness 文件工具先过策略,且同时检查原路径与规范化路径

源码事实

checked_read_path/checked_write_path 解析相对 cwd 后调用 file_system_sandbox_policy;policy_candidates_for_path 同时检查输入路径、canonical path,目标不存在时检查 canonical parent+filename,防止 symlink/别名绕过。

白话解释

即使换成 Claude/Pi 风格的 Read/Write,也不能因为路径里有软链接或奇怪别名绕过沙箱。

对自研 Harness 的含义

兼容层与原生工具共享安全边界;搜索 walk 还跳过 symlink、限制 64 层和 5 万项。

关键源码 · 实现
codex-rs/core/src/tools/handlers/harness_fs.rs · L39–L94
   39  pub(crate) fn resolve_model_path(
   40      invocation: &ToolInvocation,
   41      path: &str,
   42  ) -> Result<PathBuf, FunctionCallError> {
   43      let path = normalize_model_path_text(path);
   44      let path = PathBuf::from(path);
   45      if path.is_absolute() {
   46          Ok(path)
   47      } else {
   48          Ok(primary_cwd(invocation).join(path))
   49      }
   50  }
   51  
   52  pub(crate) fn checked_read_path(
   53      invocation: &ToolInvocation,
   54      path: &str,
   55      operation: &str,
   56  ) -> Result<PathBuf, FunctionCallError> {
   57      let path = resolve_model_path(invocation, path)?;
   58      ensure_read_allowed(invocation, &path, operation)?;
   59      Ok(path)
   60  }
   61  
   62  pub(crate) fn checked_write_path(
      … 22 lines omitted; exact range 39–94 …
   85      ensure_allowed(invocation, path, AccessKind::Write, operation)
   86  }
   87  
   88  pub(crate) fn read_search_file(path: &Path) -> Option<String> {
   89      let metadata = fs::symlink_metadata(path).ok()?;
   90      let file_type = metadata.file_type();
   91      if !file_type.is_file() || file_type.is_symlink() || metadata.len() > MAX_SEARCH_FILE_BYTES {
   92          return None;
   93      }
   94      fs::read_to_string(path).ok()
查看全部 3 处证据
  • 实现 codex-rs/core/src/tools/handlers/harness_fs.rs:39–94 路径解析与读写 policy gate。
  • 实现 codex-rs/core/src/tools/handlers/harness_fs.rs:97–149 有界 walk、symlink 和目录排除。
  • 实现 codex-rs/core/src/tools/handlers/harness_fs.rs:158–204 原路径/canonical path 双重权限检查。
18
L1事实oi-security-002

审批和能力授权是两条轴,OS 沙箱是真实进程变换

源码事实

配置将 approval policy 与 permission profile 分开编译;执行时根据平台把命令变换成 macOS sandbox-exec/Seatbelt、Linux seccomp+bubblewrap/landlock 或 Windows restricted token/private desktop,SandboxType::None 才是不变换。

白话解释

“要不要先问你”与“即使你同意,它最多能碰哪里”是两回事;后者不是提示词,而是操作系统级限制。

对自研 Harness 的含义

这是该分叉继承的最重要企业能力之一;选择 danger/full access 或 SandboxType::None 会主动撤掉这层保护。

关键源码 · 实现
codex-rs/core/src/config/permissions.rs · L170–L260
  170          unix_sockets: feature_config.unix_sockets.as_ref().map(|unix_sockets| {
  171              NetworkUnixSocketPermissionsToml {
  172                  entries: unix_sockets
  173                      .iter()
  174                      .map(|(path, permission)| {
  175                          let permission = match permission {
  176                              NetworkProxyUnixSocketPermissionToml::Allow => {
  177                                  NetworkUnixSocketPermissionToml::Allow
  178                              }
  179                              NetworkProxyUnixSocketPermissionToml::Deny => {
  180                                  NetworkUnixSocketPermissionToml::Deny
  181                              }
  182                          };
  183                          (path.clone(), permission)
  184                      })
  185                      .collect(),
  186              }
  187          }),
  188          allow_local_binding: feature_config.allow_local_binding,
  189          mitm: None,
  190      }
  191      .apply_to_network_proxy_config(config);
  192  }
  193  
      … 57 lines omitted; exact range 170–260 …
  251          }
  252      }
  253  }
  254  
  255  fn insert_special_filesystem_permission_toml(
  256      entries: &mut BTreeMap<String, FilesystemPermissionToml>,
  257      value: FileSystemSpecialPath,
  258      access: FileSystemAccessMode,
  259  ) {
  260      match value {
查看全部 3 处证据
  • 实现 codex-rs/core/src/config/permissions.rs:170–260 permission profile 与 sandbox policy 编译。
  • 实现 codex-rs/sandboxing/src/manager.rs:280–352 权限 profile 到 runtime FS/network policy。
  • 实现 codex-rs/sandboxing/src/manager.rs:357–410 None、macOS Seatbelt、Linux sandbox 进程变换。
07
DIMENSION · MCP-EXTENSIONS-HOOKS

MCP、扩展、Skills 与 Hooks

本章共 4 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

19
L1事实oi-mcp-001

MCP、Apps、Plugins、Extensions 都在 step 工具计划中受快照控制

源码事实

turn 开始根据用户明确提及的 plugins/apps 构建注入;step context 持有 MCP 配置快照,spec plan 再把 MCP resource、extension、dynamic tools 与 core tools 合并,模型可见 spec 和实际 registry 同步生成。

白话解释

连接器不是随时从全局表里飘进来,而是在这一轮、这一步被拍成快照后再装进工具箱。

对自研 Harness 的含义

可复现性和权限边界较清楚;插件配置变化通常下一 step 才生效。

关键源码 · 实现
codex-rs/core/src/session/turn.rs · L546–L650
  546      step_context: &StepContext,
  547      input: &[TurnInput],
  548      cancellation_token: &CancellationToken,
  549  ) -> Option<(Vec<ResponseItem>, HashSet<String>)> {
  550      let turn_context = step_context.turn.as_ref();
  551      // Guardian input embeds the parent transcript as untrusted evidence. Do not interpret skill or
  552      // plugin mentions from that generated prompt as requests to inject additional instructions.
  553      if crate::guardian::is_guardian_reviewer_source(&turn_context.session_source) {
  554          return Some((Vec::new(), HashSet::new()));
  555      }
  556  
  557      let user_input = input
  558          .iter()
  559          .filter_map(|item| match item {
  560              TurnInput::UserInput { content, .. } => Some(content.as_slice()),
  561              TurnInput::ResponseItem(_) | TurnInput::InterAgentCommunication(_) => None,
  562          })
  563          .flatten()
  564          .cloned()
  565          .collect::<Vec<_>>();
  566      let tracking = build_track_events_context(
  567          turn_context.model_info.slug.clone(),
  568          sess.thread_id.to_string(),
  569          turn_context.sub_id.clone(),
      … 71 lines omitted; exact range 546–650 …
  641          &mentioned_skills,
  642          Some(skills_outcome),
  643          Some(&turn_context.session_telemetry),
  644          &sess.services.analytics_events_client,
  645          tracking.clone(),
  646      )
  647      .await;
  648  
  649      for message in skill_warnings {
  650          sess.send_event(turn_context, EventMsg::Warning(WarningEvent { message }))
查看全部 2 处证据
  • 实现 codex-rs/core/src/session/turn.rs:546–650 plugin mention、MCP connector snapshot 与 skill injection。
  • 实现 codex-rs/core/src/tools/spec_plan.rs:590–608 shell、alias、MCP、collab、extension、dynamic tool 统一计划。
20
L1事实oi-instructions-001

AGENTS.md 从项目根到 cwd 合并,局部 override 优先且有总预算

源码事实

loader 先定位 project root,再从根到 cwd 搜索 AGENTS.override.md/AGENTS.md;每层只取第一个候选,按顺序拼接并受 project_doc_max_bytes 限制,读取通过环境文件系统抽象。

白话解释

仓库总规矩先读,子目录的局部规矩后读;局部 override 能盖住普通 AGENTS 文件,所有说明不能无限占上下文。

对自研 Harness 的含义

适合 monorepo 分层治理;超预算内容会截断,因此关键安全规则不应只放在大文件末尾。

关键源码 · 契约
codex-rs/core/src/agents_md.rs · L1–L49
    1  //! AGENTS.md discovery and user instruction assembly.
    2  //!
    3  //! Project-level documentation is primarily stored in files named `AGENTS.md`.
    4  //! Additional fallback filenames can be configured via `project_doc_fallback_filenames`.
    5  //! We include the concatenation of all files found along the path from the
    6  //! project root to the current working directory as follows:
    7  //!
    8  //! 1.  Determine the project root by walking upwards from the current working
    9  //!     directory until a configured `project_root_markers` entry is found.
   10  //!     When `project_root_markers` is unset, the default marker list is used
   11  //!     (`.git`). If no marker is found, only the current working directory is
   12  //!     considered. An empty marker list disables parent traversal.
   13  //! 2.  Collect every `AGENTS.md` found from the project root down to the
   14  //!     current working directory (inclusive) and concatenate their contents in
   15  //!     that order.
   16  //! 3.  We do **not** walk past the project root.
   17  
   18  use crate::config::Config;
   19  use crate::context::UserInstructions as ContextUserInstructions;
   20  use crate::environment_selection::TurnEnvironmentSnapshot;
   21  use codex_config::ConfigLayerSource;
   22  use codex_config::ConfigLayerStackOrdering;
   23  use codex_config::default_project_root_markers;
   24  use codex_config::merge_toml_values;
      … 15 lines omitted; exact range 1–49 …
   40  pub const LOCAL_AGENTS_MD_FILENAME: &str = "AGENTS.override.md";
   41  
   42  /// When both user and project AGENTS.md docs are present, they will be
   43  /// concatenated with the following separator.
   44  const AGENTS_MD_SEPARATOR: &str = "\n\n--- project-doc ---\n\n";
   45  
   46  // Metadata probes are cheap and the exec-server transport already bounds total in-flight calls.
   47  // This covers typical project hierarchies in one remote round trip without monopolizing that
   48  // transport when independent startup discovery runs concurrently.
   49  const MAX_CONCURRENT_ANCESTOR_PROBES: usize = 256;
查看全部 3 处证据
  • 契约 codex-rs/core/src/agents_md.rs:1–49 根到 cwd 的层级规则与文件名优先级。
  • 实现 codex-rs/core/src/agents_md.rs:51–150 多环境加载、总预算和截断。
  • 实现 codex-rs/core/src/agents_md.rs:153–231 project root、候选文件与有界并发探测。
21
L3事实oi-instructions-002

Skills developer block 不允许被 Harness 转换悄悄丢掉

源码事实

session_skills.rs 明确规定 runtime skills 在 Harness 上层组装成 developer block,每个 Harness 必须映射到最接近的原生格式;解析器支持多行描述、plugin:skill 名称和预算压力下的 rN alias,并有单元测试。

白话解释

换成 Claude/Kimi/Pi 外壳时,用户装的技能仍要跟过去,不能因为消息格式翻译而消失。

对自研 Harness 的含义

跨 Harness 行为更一致;每个 builder 仍需正确调用这些 helper。

关键源码 · 契约
codex-rs/core/src/harness/session_skills.rs · L1–L65
    1  //! Helpers for surfacing the session's `<skills_instructions>` developer
    2  //! block in emulated harness requests.
    3  //!
    4  //! The workspace harness instruction-role rule says runtime skills are
    5  //! assembled above the harness layer as a `<skills_instructions>` developer
    6  //! block in `prompt.input` and must never be dropped per-harness; each harness
    7  //! maps the block to the closest shape it supports. These helpers locate the
    8  //! block in the prompt input and parse its `### Available skills` entries so
    9  //! harnesses can re-render them in their native skills format.
   10  
   11  use codex_protocol::models::ContentItem;
   12  use codex_protocol::models::ResponseItem;
   13  use codex_protocol::protocol::SKILLS_INSTRUCTIONS_CLOSE_TAG;
   14  use codex_protocol::protocol::SKILLS_INSTRUCTIONS_OPEN_TAG;
   15  
   16  /// A skill entry parsed from the `### Available skills` list of the session's
   17  /// `<skills_instructions>` developer block. Entries render natively as
   18  /// `- name: description (file: path)`; `path` may be an absolute path or an
   19  /// `rN/...` alias path when the skills list was rendered under budget
   20  /// pressure.
   21  #[derive(Debug, Clone, PartialEq, Eq)]
   22  pub(crate) struct SessionSkill {
   23      pub(crate) name: String,
   24      pub(crate) description: String,
      … 31 lines omitted; exact range 1–65 …
   56  }
   57  
   58  /// Parses the session's skills from the `<skills_instructions>` developer
   59  /// block in the prompt input. Returns an empty list when the session has no
   60  /// skills block.
   61  pub(crate) fn parse_session_skills(items: &[ResponseItem]) -> Vec<SessionSkill> {
   62      find_skills_instructions_text(items)
   63          .map(parse_skills_instructions)
   64          .unwrap_or_default()
   65  }
查看全部 3 处证据
  • 契约 codex-rs/core/src/harness/session_skills.rs:1–65 skills developer block 的跨 Harness 保留规则。
  • 实现 codex-rs/core/src/harness/session_skills.rs:67–116 多行技能条目与 plugin 名解析。
  • 测试 codex-rs/core/src/harness/session_skills.rs:118–199 单行、多行、plugin alias 和 developer-role 测试。
22
L2事实oi-hooks-001

Hooks 覆盖会话、输入、权限、工具、压缩、停止和子 Agent 生命周期

源码事实

hook event 类型与 runtime 调用点覆盖 SessionStart、UserPromptSubmit、PermissionRequest、PreToolUse/PostToolUse/PostToolUseFailure、PreCompact、Stop、SubagentStart/SubagentStop;hook 可返回附加上下文、权限决定或阻止继续。

白话解释

外部治理系统能在关键关口插卡:开始前补上下文,危险动作前审批,工具后审计,结束前决定是否继续。

对自研 Harness 的含义

适合企业策略和观测;hook 自身是高权限扩展点,配置来源必须受信。

关键源码 · 契约
codex-rs/hooks/src/types.rs · L1–L152
    1  use std::sync::Arc;
    2  
    3  use chrono::DateTime;
    4  use chrono::SecondsFormat;
    5  use chrono::Utc;
    6  use codex_protocol::ThreadId;
    7  use codex_utils_absolute_path::AbsolutePathBuf;
    8  use futures::future::BoxFuture;
    9  use serde::Serialize;
   10  use serde::Serializer;
   11  
   12  pub type HookFn = Arc<dyn for<'a> Fn(&'a HookPayload) -> BoxFuture<'a, HookResult> + Send + Sync>;
   13  
   14  #[derive(Debug)]
   15  pub enum HookResult {
   16      /// Success: hook completed successfully.
   17      Success,
   18      /// FailedContinue: hook failed, but other subsequent hooks should still execute and the
   19      /// operation should continue.
   20      FailedContinue(Box<dyn std::error::Error + Send + Sync + 'static>),
   21      /// FailedAbort: hook failed, other subsequent hooks should not execute, and the operation
   22      /// should be aborted.
   23      FailedAbort(Box<dyn std::error::Error + Send + Sync + 'static>),
   24  }
      … 118 lines omitted; exact range 1–152 …
  143                  "thread_id": thread_id.to_string(),
  144                  "turn_id": "turn-1",
  145                  "input_messages": ["hello"],
  146                  "last_assistant_message": "hi",
  147              },
  148          });
  149  
  150          assert_eq!(actual, expected);
  151      }
  152  }
查看全部 2 处证据
  • 契约 codex-rs/hooks/src/types.rs:1–152 Hook event/input/output 契约。
  • 实现 codex-rs/core/src/hook_runtime.rs:1–260 Session/Prompt/Permission/Tool/Compact/Stop/Subagent hook 调度。
08
DIMENSION · COLLABORATION-SUBAGENTS

子 Agent 与协作

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

23
L1事实oi-agent-001

多 Agent 是共享控制面的线程树

源码事实

AgentControl 在 root session 创建并共享给所有子 Agent,维护 thread id、parent/child edges、spawn depth、状态与执行 limiter;spawn、message、interrupt、wait、resume 都落到同一 CodexThreadManager。

白话解释

子 Agent 不是主函数里临时递归一下,而是有独立会话和持久关系的线程树。

对自研 Harness 的含义

可以跨步等待、续跑和观测;也需要全局驻留数、运行数和深度限制。

关键源码 · 实现
codex-rs/core/src/agent/control.rs · L88–L180
   88  
   89  /// Control-plane handle for multi-agent operations.
   90  /// `AgentControl` is held by each session (via `SessionServices`). It provides capability to
   91  /// spawn new agents and the inter-agent communication layer.
   92  /// An `AgentControl` instance is intended to be created at most once per root thread/session
   93  /// tree. That same `AgentControl` is then shared with every sub-agent spawned from that root,
   94  /// which keeps the registry scoped to that root thread rather than the entire `ThreadManager`.
   95  #[derive(Clone, Default)]
   96  pub(crate) struct AgentControl {
   97      /// ID shared by the whole agent control session. This means every sub-agents from a common
   98      /// root share the same session ID.
   99      session_id: SessionId,
  100      /// Weak handle back to the global thread registry/state.
  101      /// This is `Weak` to avoid reference cycles and shadow persistence of the form
  102      /// `ThreadManagerState -> CodexThread -> Session -> SessionServices -> ThreadManagerState`.
  103      manager: Weak<ThreadManagerState>,
  104      state: Arc<AgentRegistry>,
  105      v2_residency: Arc<V2Residency>,
  106      agent_execution_limiter: Arc<AgentExecutionLimiter>,
  107      /// Session-scoped state shared by the root thread and every cloned sub-agent control handle.
  108      rollout_budget: Arc<RolloutBudget>,
  109  }
  110  
  111  impl AgentControl {
      … 59 lines omitted; exact range 88–180 …
  171          communication: InterAgentCommunication,
  172          agent_communication_context: AgentCommunicationContext,
  173      ) -> CodexResult<String> {
  174          let state = self.upgrade()?;
  175          self.ensure_execution_capacity_for_turn_start(agent_id, communication.trigger_turn)
  176              .await?;
  177          self.send_inter_agent_communication_after_capacity_check(
  178              agent_id,
  179              &state,
  180              communication,
查看全部 3 处证据
  • 实现 codex-rs/core/src/agent/control.rs:88–180 共享 AgentControl、线程管理和 execution limiter。
  • 实现 codex-rs/core/src/agent/control.rs:520–640 spawn 准备、角色/昵称与线程启动。
  • 实现 codex-rs/core/src/agent/control.rs:659–750 线程边持久化与后代遍历。
24
L1事实oi-agent-002

Harness 自己的 Agent/Task 工具复用同一子 Agent 系统

源码事实

Claude/Kimi/ZCode alias 可把 Agent、TaskOutput、TaskStop 等目标工具名映射到内部 multi-agent handler;OpenCode task 也走专用 alias。模型看到的是目标 Harness 语言,后台仍是同一个 AgentControl。

白话解释

外面看像 Claude 的 Agent 工具或 OpenCode 的 task,里面其实都在同一棵线程树上派工。

对自研 Harness 的含义

协作能力不会因换 Harness 丢失;目标 Harness 原生的所有细节并不保证完全复刻。

关键源码 · 实现
codex-rs/core/src/tools/spec_plan.rs · L616–L685
  616      if harness.is_claude_code() {
  617          planned_tools.add(HarnessAliasHandler::Agent);
  618          planned_tools.add_dispatch_only(HarnessAliasHandler::TaskOutput);
  619          planned_tools.add_dispatch_only(HarnessAliasHandler::TaskStop);
  620      }
  621      planned_tools.add(HarnessAliasHandler::Bash);
  622      planned_tools.add(HarnessAliasHandler::BashLower);
  623      planned_tools.add(HarnessAliasHandler::Read);
  624      planned_tools.add(HarnessAliasHandler::ReadLower);
  625      planned_tools.add(HarnessAliasHandler::Write);
  626      planned_tools.add(HarnessAliasHandler::WriteLower);
  627      planned_tools.add(HarnessAliasHandler::Edit);
  628      planned_tools.add(HarnessAliasHandler::EditLower);
  629      planned_tools.add(HarnessAliasHandler::Glob);
  630      planned_tools.add(HarnessAliasHandler::GlobLower);
  631      planned_tools.add(HarnessAliasHandler::Grep);
  632      planned_tools.add(HarnessAliasHandler::GrepLower);
  633      planned_tools.add(HarnessAliasHandler::AskUserQuestion);
  634      if matches!(harness, Harness::KimiCode) {
  635          planned_tools.add_dispatch_only(HarnessAliasHandler::Agent);
  636          planned_tools.add_dispatch_only(HarnessAliasHandler::ReadMediaFile);
  637          planned_tools.add_dispatch_only(HarnessAliasHandler::TaskList);
  638          planned_tools.add_dispatch_only(HarnessAliasHandler::TaskOutput);
  639          planned_tools.add_dispatch_only(HarnessAliasHandler::TaskStop);
      … 36 lines omitted; exact range 616–685 …
  676      if matches!(harness, Harness::ZCode) {
  677          planned_tools.add_dispatch_only(HarnessAliasHandler::Agent);
  678          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeTodoRead);
  679          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeTodoWrite);
  680          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeEnterPlanMode);
  681          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeExitPlanMode);
  682          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeReadSessionContext);
  683          planned_tools.add_dispatch_only(HarnessAliasHandler::ZCodeSkill);
  684      }
  685  }
查看全部 3 处证据
  • 实现 codex-rs/core/src/tools/spec_plan.rs:616–685 Claude/Kimi/OpenCode/ZCode 的 Agent/Task alias 装配。
  • 实现 codex-rs/core/src/tools/handlers/harness_aliases.rs:264–420 Claude Agent 参数到内部 spawn 的转换。
  • 实现 codex-rs/core/src/tools/handlers/multi_agents.rs:1–100 共享 collaboration tool surface。
09
DIMENSION · PERSISTENCE-OBSERVABILITY

持久化与观测

本章共 2 个可定位结论;结论按“实现事实 → 白话解释 → 工程影响 → 源码摘录”展开。

25
L1事实oi-observe-001

JSONL rollout 是可恢复事件事实源,SQLite/trace 是查询与诊断层

源码事实

会话把 SessionMeta、TurnContext、WorldState、ResponseItem、Compacted、EventMsg 和 inter-agent communication 记录为 RolloutItem;重建器按 turn complete/abort/rollback/compact 复原历史,rollout-trace 再把原始事件归约成会话、工具和推理视图。

白话解释

先保存完整流水账,再从流水账还原聊天、文件、工具和子 Agent 发生了什么。

对自研 Harness 的含义

恢复与审计能力强;事件 schema 演进、敏感字段保留和磁盘生命周期需要治理。

关键源码 · 实现
codex-rs/core/src/session/rollout_reconstruction.rs · L116–L288
  116          rollout_items: &[RolloutItem],
  117      ) -> RolloutReconstruction {
  118          // Replay metadata should already match the shape of the future lazy reverse loader, even
  119          // while history materialization still uses an eager bridge. Scan newest-to-oldest,
  120          // stopping once a surviving replacement-history checkpoint and the required resume metadata
  121          // are both known; then replay only the buffered surviving tail forward to preserve exact
  122          // history semantics.
  123          let has_legacy_compaction_without_window_number =
  124              rollout_items.iter().any(|item| {
  125                  matches!(item, RolloutItem::Compacted(compacted) if compacted.window_number.is_none())
  126              });
  127          let initial_window = if has_legacy_compaction_without_window_number {
  128              None
  129          } else {
  130              rollout_items.iter().find_map(|item| match item {
  131                  RolloutItem::SessionMeta(session_meta) => session_meta
  132                      .meta
  133                      .context_window
  134                      .as_ref()
  135                      .and_then(reconstructed_window_from_session_context_window),
  136                  _ => None,
  137              })
  138          };
  139          let mut base_replacement_history: Option<&[ResponseItem]> = None;
      … 139 lines omitted; exact range 116–288 …
  279                      active_segment.counts_as_user_turn = true;
  280                  }
  281                  RolloutItem::EventMsg(_)
  282                  | RolloutItem::SessionMeta(_)
  283                  | RolloutItem::InterAgentCommunicationMetadata { .. } => {}
  284              }
  285  
  286              if base_replacement_history.is_some()
  287                  && previous_turn_settings.is_some()
  288                  && !matches!(reference_context_item, TurnReferenceContextItem::NeverSet)
查看全部 3 处证据
  • 实现 codex-rs/core/src/session/rollout_reconstruction.rs:116–288 RolloutItem 分类与 turn/compact/rollback 重建。
  • 实现 codex-rs/rollout/src/recorder.rs:1–260 JSONL rollout recorder、writer 与恢复入口。
  • 实现 codex-rs/rollout-trace/src/reducer/mod.rs:1–220 原始 rollout 到诊断模型的 reducer。
26
L1风险oi-observe-002

Open Interpreter 使用独立分析端点,默认启用但可显式关闭

源码事实

AnalyticsEventsClient 在 analytics_enabled != Some(false) 时创建队列;Open Interpreter 把任何 provider 的事件发送到 oi-new-api.fly.dev 的固定端点,配置 [analytics] enabled=false 可关闭;队列满会丢事件而不阻塞主循环。

白话解释

默认会发产品使用事件到 Open Interpreter 的后端,用户可以在配置里关掉;遥测故障不会卡住编码任务。

对自研 Harness 的含义

企业部署应在基线配置里明确关闭或审查字段,而不是假设换了自建模型就没有遥测。

关键源码 · 实现
codex-rs/analytics/src/client.rs · L54–L105
   54  const ANALYTICS_EVENTS_QUEUE_SIZE: usize = 256;
   55  const ANALYTICS_EVENTS_TIMEOUT: Duration = Duration::from_secs(10);
   56  const ANALYTICS_EVENT_DEDUPE_MAX_KEYS: usize = 4096;
   57  // Open Interpreter analytics endpoint. This replaces upstream Codex's
   58  // `{chatgpt_base_url}/codex/analytics-events/events` so events from any
   59  // provider land in our infra. Disabled the same way Codex does it:
   60  // set `[analytics] enabled = false` in `~/.codex/config.toml`.
   61  const INTERPRETER_ANALYTICS_URL: &str = "https://oi-new-api.fly.dev/v0/interpreter-events";
   62  const LOCAL_ANALYTICS_EVENTS_PATH: &str = "/codex/analytics-events/events";
   63  
   64  #[derive(Clone)]
   65  pub(crate) struct AnalyticsEventsQueue {
   66      pub(crate) sender: mpsc::Sender<AnalyticsFact>,
   67      pub(crate) app_used_emitted_keys: Arc<Mutex<HashSet<(String, String)>>>,
   68      pub(crate) plugin_used_emitted_keys: Arc<Mutex<HashSet<(String, String)>>>,
   69  }
   70  
   71  #[derive(Clone)]
   72  pub struct AnalyticsEventsClient {
   73      queue: Option<AnalyticsEventsQueue>,
   74  }
   75  
   76  #[derive(Clone, Debug, Eq, PartialEq)]
   77  enum AnalyticsEventsDestination {
      … 18 lines omitted; exact range 54–105 …
   96              if let Err(err) = crate::analytics_capture::initialize(&path) {
   97                  tracing::error!(
   98                      path = %path.display(),
   99                      "failed to initialize analytics event capture; network delivery remains disabled: {err}"
  100                  );
  101              }
  102              tracing::warn!(
  103                  path = %path.display(),
  104                  "analytics event capture enabled; network delivery is disabled"
  105              );
查看全部 3 处证据
  • 实现 codex-rs/analytics/src/client.rs:54–105 独立 endpoint、关闭方式和本地 capture。
  • 实现 codex-rs/analytics/src/client.rs:140–215 有界队列、drop-on-full 与 opt-out 初始化。
  • 测试 codex-rs/analytics/src/client_tests.rs:240–290 Open Interpreter endpoint 测试。
APPENDIX · SOURCE INDEX

本报告引用过的实现文件

这是一份代码阅读索引,不是仓库文件总表。机器候选扫描覆盖整个仓库;进入结论的文件必须经人工沿调用链复核。

  1. 01codex-rs/product-info/src/lib.rsL45–79
  2. 02scripts/install/install-open-interpreter.shL13–25
  3. 03scripts/codex_package/targets.pyL60–85
  4. 04scripts/test-codex-sdk-compat.shL21–36
  5. 05scripts/codex_package/test_layout.pyL19–63
  6. 06codex-rs/core/src/harness/mod.rsL1–18
  7. 07codex-rs/app-server/src/interpreter_catalog.rsL29–118
  8. 08codex-rs/tools/src/harness.rsL1–99
  9. 09codex-rs/app-server-protocol/src/protocol/v2/interpreter.rsL8–44, 78–137
  10. 10codex-rs/model-provider-info/src/lib.rsL161–223
  11. 11codex-rs/core/src/harness/routing.rsL5–151, 185–270
  12. 12codex-rs/core/src/harness/request.rsL1–8, 42–73, 75–231, 75–231
  13. 13codex-rs/core/src/harness/pi.rsL21–120, 121–225
  14. 14codex-rs/core/src/harness/opencode.rsL1–180
  15. 15codex-rs/core/src/session/turn.rsL140–228, 229–324, 355–460, 243–292, 546–650
  16. 16codex-rs/core/src/session/step_context.rsL1–54
  17. 17codex-rs/core/src/context_manager/history.rsL40–186, 328–368, 493–505
  18. 18codex-rs/core/src/compact.rsL299–389, 600–689, 718–815, 600–815
  19. 19codex-rs/core/src/tools/spec_plan.rsL240–268, 432–495, 719–735, 610–685, 590–608, 616–685
  20. 20codex-rs/core/src/tools/handlers/harness_aliases.rsL102–254, 1749–1821, 1823–1925, 1927–2025, 196–205, 264–420, 102–254
  21. 21codex-rs/core/src/tools/parallel.rsL42–138
  22. 22codex-rs/core/src/tools/handlers/harness_fs.rsL39–94, 97–149, 158–204
  23. 23codex-rs/core/src/config/permissions.rsL170–260
  24. 24codex-rs/sandboxing/src/manager.rsL280–352, 357–410
  25. 25codex-rs/core/src/agents_md.rsL1–49, 51–150, 153–231
  26. 26codex-rs/core/src/harness/session_skills.rsL1–65, 67–116, 118–199
  27. 27codex-rs/hooks/src/types.rsL1–152
  28. 28codex-rs/core/src/hook_runtime.rsL1–260
  29. 29codex-rs/core/src/agent/control.rsL88–180, 520–640, 659–750
  30. 30codex-rs/core/src/tools/handlers/multi_agents.rsL1–100
  31. 31codex-rs/core/src/session/rollout_reconstruction.rsL116–288
  32. 32codex-rs/rollout/src/recorder.rsL1–260
  33. 33codex-rs/rollout-trace/src/reducer/mod.rsL1–220
  34. 34codex-rs/analytics/src/client.rsL54–105, 140–215
  35. 35codex-rs/analytics/src/client_tests.rsL240–290
  36. 36LICENSEL1–20