CODING AGENT HARNESS · SOURCE AUDITREPORT 08 / 18
08

Oh My Pi

机制覆盖面最广的一类个人 Harness:上下文策略、多方言、Agent hub、OTEL 都很强,但默认 yolo/宿主执行偏激进。

TypeScript · Maximalist Personal HarnessMITmain
SOURCE
VERIFIED
Repository
can1357/oh-my-pi
Commit
ed4c78bc0faafcc79f61cfd0baca7a8413ba74bf
Commit date
2026-07-28T02:06:13+02:00
Findings
23
Citations
73
Tracked files
5,867
EXECUTIVE READING

先给结论,再进入源码

核心机制

强化 Agent loop + 大型 session maintenance 状态机

上下文

compact/handoff/shake/snapcompact + 四种 memory backend

安全边界

Approval 完整但默认 yolo;主 Agent 宿主执行

适用建设

高级个人用户、复杂长任务、多 Agent 实验

值得借鉴

  • 上下文维护策略最丰富
  • Agent 协作控制面完整
  • 观测与机制测试密集

需要警惕

  • 默认 yolo
  • 隔离默认 none
  • 同进程扩展供应链风险

直接带走

  • 多策略 context maintenance
  • 兄弟 Agent hub
  • run coverage 与成本 span
00 · METHOD

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

README POLICY

README 仅作入口地图;核心事实来自 agent loop、AgentSession、task、compaction、approval、MCP、memory、discovery、extension、storage、telemetry 与测试源码。

FACT POLICY

把 oh-my-pi 作为独立演进的 Pi 衍生 Harness 分析,只归因固定提交中实际实现和默认配置。

INFERENCE POLICY

严格区分 tool approval、子任务工作区隔离与 OS/process sandbox;配置存在不等于默认开启。

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

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

01 · TECHNICAL MAPS

架构总图与单轮执行链路

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

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

审计维度与证据等级

架构与 Agent Loop verified L1 / L2 / L3

已审计 loop、session maintenance、steering/asides、yield、错误恢复和 goal continuation。

Provider 与协议方言 verified L1 / L2 / L3

已审计 provider catalog、多协议 stream、in-band dialect 与 watchdog。

上下文、压缩与记忆 verified L1 / L2 / L3

已审计多策略压缩、prune/shake/snapcompact、handoff 和长期记忆后端。

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

已审计内建工具面、调度、宿主 shell、approval 和 output guard。

MCP 与连接器 verified L1 / L2 / L3

已审计多来源配置、stdio/SSE/HTTP、OAuth、缓存、订阅、reconnect 与动态工具刷新。

子 Agent 与协作 verified L1 / L2 / L3

已审计 batch/async/typed yield、递归、预算、park/revive、hub 和工作区隔离。

指令、插件与 Skills verified L1 / L2 / L3

已审计 capability discovery、跨生态兼容、system/rules/skills/commands/extensions/hooks/marketplace。

会话与观测 verified L1 / L2 / L3

已审计 session tree/storage、artifact、OTEL GenAI spans、cost 与 UI/RPC/ACP/collab surface。

测试、基准与成熟度 verified L2 / L3

1858 个 TS 测试文件、metaharness 与 edit benchmark;不等同于公开 coding success 基准成绩。

01
DIMENSION · ARCHITECTURE-LOOP

架构与 Agent Loop

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

01
L1事实omp-architecture-001

核心是强化 Agent loop,产品层再叠加大型 Session maintenance 状态机

源码事实

packages/agent 处理模型、工具、steering 和 telemetry;产品 AgentSession 在 agent_end 后按优先级处理 yield、空 stop、goal compaction、异常 stop、stream stall、model fallback、todo、async wake 和 session_stop。

白话解释

内层发动机负责每一步,外层管家负责一步结束后判断要不要重试、压缩、换模型、继续目标或等待后台工作。

对自研 Harness 的含义

自治恢复能力强,但 session maintenance 已成为复杂调度器,修改顺序容易产生竞态。

关键源码 · 实现
packages/agent/src/agent-loop.ts · L879–L918
  879  /**
  880   * Main loop logic shared by agentLoop and agentLoopContinue.
  881   */
  882  async function runLoop(
  883  	currentContext: AgentContext,
  884  	newMessages: AgentMessage[],
  885  	config: AgentLoopConfig,
  886  	signal: AbortSignal | undefined,
  887  	stream: EventStream<AgentEvent, AgentMessage[]>,
  888  	streamFn?: StreamFn,
  889  	initialMessages: AgentMessage[] = [],
  890  ): Promise<void> {
  891  	const telemetry = resolveTelemetry(config.telemetry, config.sessionId);
  892  	const invokeAgentSpan = startInvokeAgentSpan(telemetry, config.model);
  893  	const stepCounter = { count: 0 };
  894  	let caughtError: unknown;
  895  	try {
  896  		await runInActiveSpan(invokeAgentSpan, () =>
  897  			runLoopBody(
  898  				currentContext,
  899  				newMessages,
  900  				config,
  901  				signal,
  902  				stream,
      … 6 lines omitted; exact range 879–918 …
  909  		);
  910  	} catch (err) {
  911  		caughtError = err;
  912  		throw err;
  913  	} finally {
  914  		finishInvokeAgentSpan(telemetry, invokeAgentSpan, {
  915  			stepCount: stepCounter.count,
  916  			errorObject: caughtError,
  917  		});
  918  	}
查看全部 3 处证据
  • 实现 packages/agent/src/agent-loop.ts:879–918 runLoop 与 invoke_agent telemetry 边界。
  • 实现 packages/coding-agent/src/session/agent-session.ts:2491–2619 yield、empty stop、goal compaction、unexpected stop 与 retry 路由。
  • 实现 packages/coding-agent/src/session/agent-session.ts:2621–2740 abort、model fallback、todo、async wake 与 session_stop。
02
L1事实omp-loop-001

steering 不只在轮间排队,还能在工具执行中协作中断

源码事实

loop 每轮前和 stop boundary 轮询 steering/asides;工具批运行时同时使用 hard abort 与 cooperative steeringSignal,interruptible 等待工具会被 steer 打断,普通有副作用工具只收到软信号并在边界注入消息。

白话解释

用户插话时,纯等待可以立刻停;正在改文件的工具不会粗暴半路杀死,而是完成到安全边界再让模型听新指令。

对自研 Harness 的含义

中断语义按工具类型区分,明显优于统一 AbortController。

关键源码 · 实现
packages/agent/src/agent-loop.ts · L999–L1048
  999  		// Check for steering messages at start (user may have typed while waiting).
 1000  		// Skip when the run is already externally aborted — dequeuing would strand
 1001  		// the messages in a run that is about to die.
 1002  		let pendingMessages: AgentMessage[];
 1003  		try {
 1004  			pendingMessages = signal?.aborted ? [] : (await config.getSteeringMessages?.()) || [];
 1005  		} catch (error) {
 1006  			stream.push({ type: "turn_start" });
 1007  			emitInputMessages(stream, messagesToEmit);
 1008  			throw error;
 1009  		}
 1010  		let harmonyRetryAttempt = 0;
 1011  		let harmonyTruncateResumeCount = 0;
 1012  		let pausedTurnContinuations = 0;
 1013  
 1014  		// Soft tool requirement lifecycle (reminder then escalation; see SoftToolRequirement).
 1015  		// The host-owned state survives only a gate stop between Agent.prompt calls.
 1016  		// Resolved once per logical turn at the fetch site below and reused across
 1017  		// Harmony-leak re-samples (which re-enter the same turn) so the consuming
 1018  		// getToolChoice is never advanced twice; the flag resets at the message boundary.
 1019  		let hostToolChoice: ToolChoice | undefined;
 1020  		let softRequiredTool: string | undefined;
 1021  		let softSatisfies: SoftToolRequirement["satisfies"];
 1022  		let directiveResolvedForTurn = false;
      … 16 lines omitted; exact range 999–1048 …
 1039  				// Park at the turn boundary while the process-wide pause gate is
 1040  				// engaged (host /pause). An external abort releases the park so a
 1041  				// cancelled run still unwinds while everything else stays frozen.
 1042  				if (agentPauseGate.paused) await agentPauseGate.waitUntilResumed(signal);
 1043  
 1044  				// Build the provider-bound context before opening the turn. Queue
 1045  				// messages are added now but their events remain deferred until
 1046  				// provider preparation either succeeds or opens an error turn.
 1047  				const turnMessages = messagesToEmit;
 1048  				messagesToEmit = [];
查看全部 4 处证据
  • 实现 packages/agent/src/agent-loop.ts:999–1048 起始 steering 与内外循环。
  • 实现 packages/agent/src/agent-loop.ts:1402–1438 stop boundary 的 steering/asides 决策。
  • 实现 packages/agent/src/agent-loop.ts:2231–2250 hard/soft steering signal 合同。
  • 实现 packages/agent/src/agent-loop.ts:2318–2344 工具执行中检测并触发中断。
03
L1事实omp-loop-002

工具调度支持 shared/exclusive 并发和完整 pre-dispatch 改写

源码事实

tool calls 在流结束前完成参数校验与 beforeToolCall,改写后的参数回写 assistant snapshot;执行时 shared calls 并发,exclusive 会等待之前 exclusive 和所有 shared;afterToolCall 可规范化结果。

白话解释

先把所有施工单审核、改好并固化,再按“可并行/独占”排程,日志看到的参数就是实际执行参数。

对自研 Harness 的含义

既能并发提速,也能避免 edit/bash 等副作用互撞;第三方结果还在单一边界做防腐。

关键源码 · 实现
packages/agent/src/agent-loop.ts · L2067–L2200
 2067  /** Per-call outcome of the pre-dispatch prepare phase (validation + `beforeToolCall`). */
 2068  interface PreparedToolCall {
 2069  	tool: AgentTool<any> | undefined;
 2070  	/** Validated (possibly hook-revised) execution args; raw args when validation failed. */
 2071  	args: Record<string, unknown>;
 2072  	validationErrorMessage?: string;
 2073  	blocked?: boolean;
 2074  	blockReason?: string;
 2075  	prepareError?: unknown;
 2076  }
 2077  
 2078  /**
 2079   * Prepare results computed in the stream-done branch (before `message_start`/
 2080   * `message_end`) so a `beforeToolCall` args revision is baked into the message
 2081   * every consumer snapshots. `executeToolCalls` consumes them; a message that
 2082   * bypassed the streamed path (e.g. Harmony-recovered) is prepared at dispatch
 2083   * time instead.
 2084   */
 2085  const preparedDispatchByMessage = new WeakMap<AssistantMessage, Map<string, PreparedToolCall>>();
 2086  
 2087  function resolveToolForCall(
 2088  	tools: AgentTool<any>[] | undefined,
 2089  	toolCall: AgentToolCall,
 2090  	resolveFallbackTool: AgentLoopConfig["resolveFallbackTool"],
      … 100 lines omitted; exact range 2067–2200 …
 2191  			toolCall.arguments = beforeResult.args;
 2192  			entry.args = revised;
 2193  		}
 2194  	}
 2195  	return prepared;
 2196  }
 2197  /**
 2198   * Execute tool calls from an assistant message.
 2199   */
 2200  async function executeToolCalls(
查看全部 3 处证据
  • 实现 packages/agent/src/agent-loop.ts:2067–2200 pre-dispatch validation、hook 与 assistant snapshot。
  • 实现 packages/agent/src/agent-loop.ts:2408–2538 执行上下文、结果规范化和 after hook。
  • 实现 packages/agent/src/agent-loop.ts:2660–2692 shared/exclusive 排程与 allSettled。
02
DIMENSION · PROVIDERS-DIALECTS

Provider 与协议方言

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

04
L1事实omp-dialect-001

原生 tool calling 之外还有多种 in-band 方言和 Harmony 泄漏修复

源码事实

loop 支持 glm、hermes、kimi、xml、anthropic、deepseek、harmony、qwen3、gemini、gemma、minimax 方言,在 system/history/stream 三处编码;另检测 GPT-5 Harmony 协议泄漏并尝试恢复 tool call。

白话解释

一些本地模型不会说标准函数调用,它会把工具协议写进文本再解析;对模型意外吐出的内部协议也有专门清洗和恢复。

对自研 Harness 的含义

小模型/非标准模型兼容面很广,但解析器是额外攻击面和回归矩阵。

关键源码 · 实现
packages/agent/src/agent-loop.ts · L26–L45
   26  import {
   27  	type Dialect,
   28  	encodeInbandToolHistory,
   29  	renderInbandToolPrompt,
   30  	renderToolExamples,
   31  	wrapInbandToolStream,
   32  } from "@oh-my-pi/pi-ai/dialect";
   33  import * as AIError from "@oh-my-pi/pi-ai/error";
   34  import { type CursorExecResolvedCarrier, kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
   35  import {
   36  	createHarmonyAuditEvent,
   37  	detectHarmonyLeakInAssistantMessage,
   38  	extractHarmonyRemoved,
   39  	type HarmonyDetection,
   40  	type HarmonyRecoveredToolCall,
   41  	isHarmonyLeakMitigationTarget,
   42  	recoverHarmonyToolCall,
   43  	signalListLabel,
   44  } from "@oh-my-pi/pi-ai/utils/harmony-leak";
   45  import { preferredDialect } from "@oh-my-pi/pi-catalog/identity";
查看全部 3 处证据
  • 实现 packages/agent/src/agent-loop.ts:26–45 in-band dialect 与 Harmony utilities。
  • 实现 packages/agent/src/agent-loop.ts:167–186 支持的 dialect 枚举。
  • 实现 packages/agent/src/agent-loop.ts:157–165 Harmony leak interruption。
05
L1事实omp-provider-001

模型目录和协议实现分离,Provider 覆盖极广

源码事实

catalog 维护 AIML、Alibaba、Bedrock、Anthropic、Azure、Cerebras、Cloudflare、Cursor、DeepSeek、Devin、Fireworks、Copilot、Google、Groq、HF、Kimi、LiteLLM、Moonshot、Ollama、OpenAI 等大量 provider;AI 包实现 Anthropic/OpenAI Responses/Completions/Codex、Gemini/Vertex、Bedrock、Cursor/Devin 等不同 transport。

白话解释

模型“有哪些”由目录管理,模型“怎么说话”由协议驱动管理,两者不是一张巨型 if/else。

对自研 Harness 的含义

适合作为多模型网关前端,但 catalog 更新、认证和协议正确性必须分开测试。

关键源码 · 实现
packages/catalog/src/provider-models/descriptors.ts · L1–L66
    1  /**
    2   * The provider catalog table: one entry per chat-model provider, carrying the
    3   * catalog half of what used to live in `@oh-my-pi/pi-ai`'s registry definitions
    4   * (default model, runtime model-manager factory, discovery wiring). The auth
    5   * half (env keys, OAuth login/refresh) stays in the pi-ai registry, which
    6   * type-checks itself against `KnownProvider` from this table.
    7   */
    8  import type { ModelManagerConfig, ProviderCatalogEntry, ProviderDescriptor } from "./descriptor-types";
    9  import { googleModelManagerOptions, googleVertexModelManagerOptions } from "./google";
   10  import { ollamaCloudModelManagerOptions } from "./ollama";
   11  import {
   12  	aimlApiModelManagerOptions,
   13  	alibabaCodingPlanModelManagerOptions,
   14  	alibabaTokenPlanModelManagerOptions,
   15  	anthropicModelManagerOptions,
   16  	basetenModelManagerOptions,
   17  	cerebrasModelManagerOptions,
   18  	cloudflareAiGatewayModelManagerOptions,
   19  	coreWeaveModelManagerOptions,
   20  	deepseekModelManagerOptions,
   21  	firepassModelManagerOptions,
   22  	fireworksModelManagerOptions,
   23  	githubCopilotModelManagerOptions,
   24  	groqModelManagerOptions,
      … 32 lines omitted; exact range 1–66 …
   57  	zhipuCodingPlanModelManagerOptions,
   58  } from "./openai-compat";
   59  import {
   60  	cursorModelManagerOptions,
   61  	devinModelManagerOptions,
   62  	gitLabDuoWorkflowModelManagerOptions,
   63  	zaiModelManagerOptions,
   64  } from "./special";
   65  
   66  export const CATALOG_PROVIDERS = [
查看全部 3 处证据
  • 实现 packages/catalog/src/provider-models/descriptors.ts:1–66 catalog/runtime/auth 分层与 provider manager imports。
  • 配置 packages/catalog/src/provider-models/descriptors.ts:66–180 provider catalog 前半段。
  • 契约 packages/ai/src/providers/register-builtins.ts:33–163 协议模块类型和 lazy registry。
06
L1事实omp-provider-002

流式请求有首事件与空闲双 watchdog,并识别本地工具忙碌

源码事实

provider wrapper 分别设置 first-item 和 idle timeout;synthetic start 不算真实进展,本地 server-side tool bridge 忙碌时暂停误判,Google CLI 冷推理有独立 5 分钟首事件 floor。

白话解释

模型一直没开口和说到一半卡死是两种超时;如果它其实在调用本地工具,不会被错杀。

对自研 Harness 的含义

对长思考、多协议和 server-side tools 的可靠性处理很细。

关键源码 · 实现
packages/ai/src/providers/register-builtins.ts · L181–L230
  181  const LAZY_STREAM_IDLE_TIMEOUT_ERROR = "Provider stream stalled while waiting for the next event";
  182  const LAZY_STREAM_FIRST_EVENT_TIMEOUT_ERROR = "Provider stream timed out while waiting for the first event";
  183  
  184  function hasFinalResult(
  185  	source: AsyncIterable<AssistantMessageEvent>,
  186  ): source is AsyncIterable<AssistantMessageEvent> & { result(): Promise<AssistantMessage> } {
  187  	return typeof (source as { result?: unknown }).result === "function";
  188  }
  189  
  190  /**
  191   * floor used when neither caller option nor env var pins a value. Generic env
  192   * vars (`PI_STREAM_FIRST_EVENT_TIMEOUT_MS`, `PI_STREAM_IDLE_TIMEOUT_MS`) still
  193   * take precedence unless a provider opts into OpenAI-family idle flooring for
  194   * local backends that users historically tuned with `PI_OPENAI_STREAM_IDLE_TIMEOUT_MS`.
  195   */
  196  interface LazyStreamLimits {
  197  	defaultFirstEventTimeoutMs?: number;
  198  	defaultIdleTimeoutMs?: number;
  199  	/**
  200  	 * The provider implementation already wraps its upstream transport with
  201  	 * stream timeouts. Keep the lazy loader from racing it with generic errors.
  202  	 */
  203  	providerHandlesStreamTimeouts?: boolean;
  204  	/**
      … 16 lines omitted; exact range 181–230 …
  221  	defaultFirstEventTimeoutMs: 300_000,
  222  };
  223  
  224  const PROVIDER_HANDLED_STREAM_TIMEOUTS: LazyStreamLimits = {
  225  	providerHandlesStreamTimeouts: true,
  226  };
  227  
  228  const OPENAI_IDLE_FLOORED_LAZY_STREAM_LIMITS: LazyStreamLimits = {
  229  	openAIIdleEnvFloorsFirstEvent: true,
  230  };
查看全部 2 处证据
  • 实现 packages/ai/src/providers/register-builtins.ts:181–230 watchdog 配置与 provider 特例。
  • 实现 packages/ai/src/providers/register-builtins.ts:232–289 首事件/空闲超时与 local work guard。
03
DIMENSION · CONTEXT-COMPACTION-MEMORY

上下文、压缩与记忆

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

07
L1事实omp-context-001

压缩不是单一摘要,而是 context-full/handoff/shake/snapcompact 多策略

源码事实

CompactionSettings 支持 context-full、handoff、shake、snapcompact、off;默认 reserve 同时取固定值和窗口 15% 的较大者,对小窗口再防止 reserve 不可能;threshold 可按 token 或百分比。

白话解释

可以选择传统摘要、交接文档、删除低价值块或 frame 化压缩;预算还会随模型窗口缩放。

对自研 Harness 的含义

策略实验空间很大,但同一会话跨模型/策略迁移要处理兼容性。

关键源码 · 契约
packages/agent/src/compaction/compaction.ts · L148–L189
  148  	summary: string;
  149  	/** Short PR-style summary for display purposes. */
  150  	shortSummary?: string;
  151  	firstKeptEntryId: string;
  152  	tokensBefore: number;
  153  	/** Hook-specific data (e.g., ArtifactIndex, version markers for structured compaction) */
  154  	details?: T;
  155  	/** Hook-provided data to persist alongside compaction entry. */
  156  	preserveData?: Record<string, unknown>;
  157  }
  158  
  159  // ============================================================================
  160  // Types
  161  // ============================================================================
  162  
  163  export interface CompactionSettings {
  164  	enabled: boolean;
  165  	strategy?: "context-full" | "handoff" | "shake" | "snapcompact" | "off";
  166  	thresholdPercent?: number;
  167  	thresholdTokens?: number;
  168  	midTurnEnabled?: boolean;
  169  	/**
  170  	 * Tokens reserved below the context window for the next prompt + response.
  171  	 *
      … 8 lines omitted; exact range 148–189 …
  180  	remoteEnabled?: boolean;
  181  	remoteEndpoint?: string;
  182  	remoteStreamingV2Enabled?: boolean;
  183  	v2RetainedMessageBudget?: number;
  184  }
  185  
  186  /** Reserve applied when {@link CompactionSettings.reserveTokens} is unset. */
  187  export const DEFAULT_RESERVE_TOKENS = 16384;
  188  
  189  // reserveTokens is deliberately absent: an unset reserve is what marks it as
查看全部 2 处证据
  • 契约 packages/agent/src/compaction/compaction.ts:148–189 compaction result/settings/strategy。
  • 实现 packages/agent/src/compaction/compaction.ts:265–343 reserve 与 threshold 解析。
08
L1事实omp-context-002

传统摘要保留近期原文、拆分超长 turn、迁移文件操作和旧 archive

源码事实

cut point 只选合法用户/branch/custom 边界,允许 split turn;历史和 turn prefix 可并行摘要,合并旧 summary,提取 read/modified files。旧 snapcompact archive 在换到不兼容模型时重新展开为本地可读摘要。

白话解释

远处历史压成结构化摘要,最近工作保留原文;一个回合过长就拆开。换模型时也不会把上一家模型才懂的压缩黑盒直接留下。

对自研 Harness 的含义

兼顾近期保真、文件状态和跨 provider 可移植性。

关键源码 · 实现
packages/agent/src/compaction/compaction.ts · L501–L636
  501  	const cutPoints: number[] = [];
  502  	for (let i = startIndex; i < endIndex; i++) {
  503  		const entry = entries[i];
  504  		switch (entry.type) {
  505  			case "message": {
  506  				const role = entry.message.role as string;
  507  				switch (role) {
  508  					case "bashExecution":
  509  					case "hookMessage":
  510  					case "branchSummary":
  511  					case "compactionSummary":
  512  					case "user":
  513  					case "assistant":
  514  						cutPoints.push(i);
  515  						break;
  516  					case "toolResult":
  517  						break;
  518  				}
  519  				break;
  520  			}
  521  			case "thinking_level_change":
  522  			case "model_change":
  523  			case "compaction":
  524  			case "branch_summary":
      … 102 lines omitted; exact range 501–636 …
  627  		}
  628  		if (prevEntry.type === "message") {
  629  			// Stop if we hit any message
  630  			break;
  631  		}
  632  		// Include this non-message entry (bash, settings change, etc.)
  633  		cutIndex--;
  634  	}
  635  
  636  	// Determine if this is a split turn
查看全部 3 处证据
  • 实现 packages/agent/src/compaction/compaction.ts:501–636 合法 cut point 与 split turn。
  • 实现 packages/agent/src/compaction/compaction.ts:1145–1270 remote archive 可移植性、摘要区间与 file ops。
  • 实现 packages/agent/src/compaction/compaction.ts:1530–1607 历史/turn prefix 并行摘要、short summary 与 file ops 合并。
09
L1事实omp-context-003

工具输出还有独立 prune/protection/shake 层

源码事实

pruning 可清除已消费和被更新结果,tool-protection 保护关键工具/最近预算;shake 依据角色、工具类型、错误/无用标志和 token 权重删除低价值块,并主动失效消息 token cache。

白话解释

不是等整本对话太厚才总结,旧日志、重复读取和明确无用结果会先做局部瘦身;关键结果和最近工作有保护圈。

对自研 Harness 的含义

上下文治理覆盖工具层,但启发式误删需用回归样本监控。

关键源码 · 实现
packages/agent/src/compaction/pruning.ts · L1–L260
    1  /**
    2   * Tool output pruning utilities for compaction.
    3   */
    4  
    5  import type { ToolResultMessage } from "@oh-my-pi/pi-ai";
    6  import type { AgentMessage, AgentToolCall } from "../types";
    7  import { estimateTokens } from "./compaction";
    8  import type { SessionEntry, SessionMessageEntry } from "./entries";
    9  import { invalidateMessageCache } from "./message-cache";
   10  import {
   11  	collectToolCallsById,
   12  	isProtectedToolResult,
   13  	isSkillReadToolResult,
   14  	type ProtectedToolMatcher,
   15  } from "./tool-protection";
   16  import { splitReadSelector } from "./utils";
   17  
   18  export interface PruneConfig {
   19  	/** Keep the most recent tool output tokens intact. */
   20  	protectTokens: number;
   21  	/** Only prune if total savings meets this threshold. */
   22  	minimumSavings: number;
   23  	/** Tool-result protection matchers. String entries protect every result from that tool; predicates may inspect the paired tool call. */
   24  	protectedTools: ProtectedToolMatcher[];
      … 226 lines omitted; exact range 1–260 …
  251  	const candidates = config.supersedeKey
  252  		? collectSupersededResults(entries, toolCallsById, config.supersedeKey, config.protectedTools)
  253  		: [];
  254  	if (config.pruneUseless) {
  255  		const exclude = new Set(candidates.map(candidate => candidate.message));
  256  		candidates.push(...collectUselessResults(entries, toolCallsById, config.protectedTools, exclude));
  257  		candidates.sort((a, b) => a.index - b.index);
  258  	}
  259  	if (candidates.length === 0) return { prunedCount: 0, tokensSaved: 0 };
  260  
查看全部 3 处证据
  • 实现 packages/agent/src/compaction/pruning.ts:1–260 tool output prune 与 superseded result 处理。
  • 实现 packages/agent/src/compaction/tool-protection.ts:1–56 关键工具和近期预算保护。
  • 实现 packages/agent/src/compaction/shake.ts:1–260 shake 评分和删除策略。
10
L1事实omp-memory-001

长期记忆有 off/local/Mnemopi/Hindsight 四种后端

源码事实

runtime 以 memory.backend 为唯一选择器;local 将 rollout 摘要写 SQLite/markdown 且 learned.md 可写但不可结构化搜索,Mnemopi 是本地 SQLite+embedding+实体/三元组/时间/召回/整合管线,Hindsight 为远端后端。主 session 才启动并动态刷新 memory tools/system prompt。

白话解释

记忆可以关掉、只做本地日志总结、启用本地语义记忆库,或接远端记忆服务;子 Agent 默认不各自建长期脑库。

对自研 Harness 的含义

上下文和长期记忆分层清楚,但多后端的隐私、成本与一致性需要治理。

关键源码 · 实现
packages/coding-agent/src/memory-backend/resolve.ts · L6–L24
    6  /**
    7   * Pick the active memory backend for a Settings instance.
    8   *
    9   * Selection rules (single source of truth — every memory consumer routes
   10   * through this):
   11   *   - `memory.backend === "hindsight"`  → Hindsight remote memory
   12   *   - `memory.backend === "mnemopi"`  → local Mnemopi SQLite memory
   13   *   - `memory.backend === "local"`      → local rollout summary pipeline
   14   *   - everything else                   → no-op
   15   *
   16   * `memories.enabled` remains accepted only as a legacy migration input. Once
   17   * a config is loaded, `memory.backend` is the sole runtime selector.
   18   */
   19  export async function resolveMemoryBackend(settings: Settings): Promise<MemoryBackend> {
   20  	const id = settings.get("memory.backend");
   21  	if (id === "hindsight") return (await import("../hindsight/backend")).hindsightBackend;
   22  	if (id === "mnemopi") return (await import("../mnemopi/backend")).mnemopiBackend;
   23  	if (id === "local") return localBackend;
   24  	return offBackend;
查看全部 4 处证据
  • 实现 packages/coding-agent/src/memory-backend/resolve.ts:6–24 后端唯一选择器。
  • 实现 packages/coding-agent/src/memory-backend/local-backend.ts:11–46 local rollout summary/learned 能力边界。
  • 实现 packages/coding-agent/src/session/session-memory.ts:169–221 串行切换、主会话 gate、工具和 prompt 刷新。
  • 实现 packages/mnemopi/src/core/orchestrator.ts:1–63 本地 Mnemopi 编排入口。
04
DIMENSION · TOOLS-EDITING-EXECUTION

工具、编辑与执行

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

11
L1事实omp-tools-001

内建工具面远超文件与 shell

源码事实

registry 包含 read/bash/edit/write、AST grep/edit、LSP、eval kernels、glob/grep、browser、computer、GitHub、web search、image inspect/gen、checkpoint/rewind、todo/goal、task/hub/yield、memory tools、skills 管理等;SDK 再合并 extension/custom/MCP/RPC host tools。

白话解释

它更像一套本地 Agent 操作系统,而不是四件套 coding CLI。

对自研 Harness 的含义

覆盖广但默认 prompt/tool schema 成本和安全面都更大,需要动态激活与分组。

关键源码 · 实现
packages/coding-agent/src/tools/index.ts · L38–L105
   38  import { AskTool } from "./ask";
   39  import { AstEditTool } from "./ast-edit";
   40  import { AstGrepTool } from "./ast-grep";
   41  import { BashTool } from "./bash";
   42  import { BrowserTool } from "./browser";
   43  import { type BuiltinToolName, type HiddenToolName, normalizeToolNames } from "./builtin-names";
   44  import { type CheckpointState, CheckpointTool, type CompletedRewindState, RewindTool } from "./checkpoint";
   45  import { ComputerTool } from "./computer";
   46  import { DebugTool } from "./debug";
   47  import { EvalTool } from "./eval";
   48  import { resolveEvalBackends } from "./eval-backends";
   49  import { GithubTool } from "./gh";
   50  import { GlobTool } from "./glob";
   51  import { GrepTool } from "./grep";
   52  import { HubTool, isIrcEnabled } from "./hub";
   53  import { InspectImageTool } from "./inspect-image";
   54  import { LearnTool } from "./learn";
   55  import { ManageSkillTool } from "./manage-skill";
   56  import { MemoryEditTool } from "./memory-edit";
   57  import { MemoryRecallTool } from "./memory-recall";
   58  import { MemoryReflectTool } from "./memory-reflect";
   59  import { MemoryRetainTool } from "./memory-retain";
   60  import { wrapToolWithMetaNotice } from "./output-meta";
   61  import { ReadTool } from "./read";
      … 34 lines omitted; exact range 38–105 …
   96  export * from "./memory-reflect";
   97  export * from "./memory-retain";
   98  export * from "./read";
   99  export * from "./report-tool-issue";
  100  export * from "./resolve";
  101  export * from "./review";
  102  export * from "./todo";
  103  export * from "./tts";
  104  export * from "./vibe";
  105  export * from "./write";
查看全部 3 处证据
  • 实现 packages/coding-agent/src/tools/index.ts:38–105 工具 imports/exports。
  • 实现 packages/coding-agent/src/tools/index.ts:393–434 builtin registry 与 hidden tools。
  • 实现 packages/coding-agent/src/sdk.ts:2531–2586 builtins、extensions、custom、deferred MCP 合并。
12
L1风险omp-approval-001

Approval 分级完整,但默认是 yolo

源码事实

工具声明 read/write/exec tier 和可按参数计算的 policy;user per-tool allow/prompt/deny 高优先级。always-ask 只自动 read,write 自动 read+write,yolo 自动所有 tier;settings 默认 tools.approvalMode=yolo。

白话解释

门卫机制很成熟,但默认把门敞开;用户不改设置时,bash、browser、task 等执行级工具通常不询问。

对自研 Harness 的含义

面向个人效率是合理选择,企业默认策略应反转为 write 或 always-ask。

关键源码 · 契约
packages/coding-agent/src/tools/approval.ts · L13–L39
   13  export type ApprovalPolicy = "allow" | "deny" | "prompt";
   14  export type ApprovalMode = "always-ask" | "write" | "yolo";
   15  
   16  type ApprovalSubject = Pick<AgentTool, "name" | "approval" | "formatApprovalDetails">;
   17  
   18  export interface ResolvedApproval {
   19  	policy: ApprovalPolicy;
   20  	tier: ToolTier;
   21  	reason?: string;
   22  	override: boolean;
   23  	source?: "tool" | "user" | "mode";
   24  }
   25  
   26  const POLICY_VALUES: ReadonlySet<ApprovalPolicy> = new Set(["allow", "deny", "prompt"]);
   27  const TIER_VALUES: ReadonlySet<ToolTier> = new Set(["read", "write", "exec"]);
   28  
   29  const TIER_RANK: Record<ToolTier, number> = {
   30  	read: 0,
   31  	write: 1,
   32  	exec: 2,
   33  };
   34  
   35  const APPROVAL_MODE_MAX_TIER: Record<ApprovalMode, ToolTier> = {
   36  	"always-ask": "read",
   37  	write: "write",
   38  	yolo: "exec",
   39  };
查看全部 3 处证据
  • 契约 packages/coding-agent/src/tools/approval.ts:13–39 policy、mode 和 tier 排名。
  • 实现 packages/coding-agent/src/tools/approval.ts:99–185 工具/用户/mode 三层决策。
  • 配置 packages/coding-agent/src/config/settings-schema.ts:3600–3647 per-tool policy 与 yolo 默认值。
13
L1限制omp-sandbox-001

主 Agent 默认宿主执行;子任务 isolation 默认 none 且主要隔离工作区

源码事实

bash runner 使用宿主 shell/native process;源码未给主 Agent 建容器/namespace sandbox。task isolation 可选 APFS/btrfs/ZFS/reflink/overlayfs/ProjFS/block clone/worktree/copy,并用 patch 或 branch 合并,但默认 mode=none。

白话解释

子工人可以拿一份独立项目副本,防止同时改乱代码;这不自动隔离网络、进程和主机秘密,而且默认连副本也不开。

对自研 Harness 的含义

工作区隔离与安全沙箱必须分开标注;无人值守仍需外层 VM/container。

关键源码 · 实现
packages/coding-agent/src/session/bash-runner.ts · L1–L220
    1  import * as path from "node:path";
    2  import type { Agent } from "@oh-my-pi/pi-agent-core";
    3  import { logger } from "@oh-my-pi/pi-utils";
    4  import type { Settings } from "../config/settings";
    5  import { type BashResult, executeBash as executeBashCommand } from "../exec/bash-executor";
    6  import type { ExtensionRunner } from "../extensibility/extensions";
    7  import { outputMeta } from "../tools/output-meta";
    8  import { clampTimeout } from "../tools/tool-timeouts";
    9  import type { BashExecutionMessage } from "./messages";
   10  import type { SessionManager } from "./session-manager";
   11  
   12  /** Destination that owns a bash result after a session or branch transition. */
   13  export type BashAppendDestination =
   14  	| { kind: "current"; manager: SessionManager }
   15  	| { kind: "detached"; manager: SessionManager }
   16  	| { kind: "branch"; manager: SessionManager; parentId: string | null };
   17  
   18  /** Reference-counted session target captured when a bash execution starts. */
   19  export interface BashSessionTarget {
   20  	sessionId: string;
   21  	refs: number;
   22  	destination?: BashAppendDestination;
   23  	pending?: Promise<BashAppendDestination>;
   24  }
      … 186 lines omitted; exact range 1–220 …
  211  	/** Resolves destinations opened by beginSessionTransition. */
  212  	finishSessionTransition(transition: BashSessionTransition, success: boolean): void {
  213  		const manager = this.#host.sessionManager;
  214  		const currentDestination: BashAppendDestination = { kind: "current", manager };
  215  		let oldDestination: BashAppendDestination = currentDestination;
  216  		if (success && transition.resolveOld) {
  217  			const currentFile = manager.getSessionFile();
  218  			const sameFile =
  219  				transition.oldSessionFile === currentFile ||
  220  				(transition.oldSessionFile !== undefined &&
查看全部 3 处证据
  • 实现 packages/coding-agent/src/session/bash-runner.ts:1–220 宿主 bash/native runner。
  • 配置 packages/coding-agent/src/config/settings-schema.ts:4359–4405 子任务 isolation backends 与 none 默认。
  • 实现 packages/coding-agent/src/task/isolation-runner.ts:1–240 工作区准备、运行与变更合并。
05
DIMENSION · MCP-CONNECTORS

MCP 与连接器

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

14
L1事实omp-mcp-001

MCP 是完整内建连接器,不是插件样例

源码事实

MCPManager 从多来源配置发现服务器,并行连接、缓存 tools、订阅 resources、接收 notifications、动态刷新;transport 支持 stdio、legacy SSE、Streamable HTTP,HTTP 保存 session id、处理 server request/notification、401/403 刷新后重试。

白话解释

它不仅能调用 MCP 工具,还管理连接、认证、资源订阅、服务端推送和重连生命周期。

对自研 Harness 的含义

连接器成熟度高,适合企业工具生态;同时需审计远端 URL、headers 和本地 command 配置。

关键源码 · 实现
packages/coding-agent/src/mcp/manager.ts · L282–L380
  282  	setNotificationsEnabled(enabled: boolean): void {
  283  		const wasEnabled = this.#notificationsEnabled;
  284  		this.#notificationsEnabled = enabled;
  285  		if (enabled === wasEnabled) return;
  286  
  287  		this.#notificationsEpoch += 1;
  288  		const notificationEpoch = this.#notificationsEpoch;
  289  
  290  		if (enabled) {
  291  			// Subscribe to all connected servers that support it
  292  			for (const [name, connection] of this.#connections) {
  293  				if (connection.capabilities.resources?.subscribe && connection.resources) {
  294  					const uris = connection.resources.map(r => r.uri);
  295  					this.#subscribeAndTrack(name, connection, uris, notificationEpoch);
  296  				}
  297  			}
  298  			return;
  299  		}
  300  
  301  		// Unsubscribe from all servers
  302  		for (const [name, connection] of this.#connections) {
  303  			const uris = this.#subscribedResources.get(name);
  304  			if (uris && uris.size > 0) {
  305  				void unsubscribeFromResources(connection, Array.from(uris)).catch(error => {
      … 65 lines omitted; exact range 282–380 …
  371  
  372  		// Prepare connection tasks
  373  		const connectionTasks: ConnectionTask[] = [];
  374  
  375  		for (const [name, config] of Object.entries(configs)) {
  376  			if (sources[name]) {
  377  				this.#sources.set(name, sources[name]);
  378  				const existing = this.#connections.get(name);
  379  				if (existing) {
  380  					existing._source = sources[name];
查看全部 4 处证据
  • 实现 packages/coding-agent/src/mcp/manager.ts:282–380 resource subscriptions、discovery 与并行连接。
  • 实现 packages/coding-agent/src/mcp/loader.ts:44–124 tool cache、manager 生命周期与 custom tool bridge。
  • 实现 packages/coding-agent/src/mcp/transports/http.ts:41–149 HTTP/SSE listener、session 和 server push。
  • 实现 packages/coding-agent/src/mcp/transports/http.ts:181–258 请求、timeout、auth refresh 和 session id。
15
L1事实omp-mcp-002

可直接吸收 Claude、Gemini、OpenCode 等生态的 MCP 配置

源码事实

capability discovery providers 解析本产品、Claude、Gemini CLI、OpenCode、Codex、Cline、Cursor、VSCode/Windsurf 等配置;OpenCode local/remote 和 Gemini mcpServers 被归一成同一 stdio/SSE/HTTP contract,并保留 source metadata。

白话解释

用户换工具时不必手工重写全部 MCP 配置,OMP 会读取其他 Agent 的配置并统一格式。

对自研 Harness 的含义

迁移体验突出,但跨生态自动加载需有来源可见性和项目 trust。

关键源码 · 实现
packages/coding-agent/src/discovery/opencode.ts · L88–L167
   88  // MCP Servers (opencode.json → mcp)
   89  // =============================================================================
   90  
   91  /** OpenCode MCP server config (from opencode.json "mcp" key) */
   92  interface OpenCodeMCPConfig {
   93  	type?: "local" | "remote";
   94  	command?: string | string[];
   95  	args?: string[];
   96  	env?: Record<string, string>;
   97  	environment?: Record<string, string>;
   98  	url?: string;
   99  	headers?: Record<string, string>;
  100  	enabled?: boolean;
  101  	timeout?: number;
  102  }
  103  
  104  function stringArray(value: unknown): string[] | undefined {
  105  	if (!Array.isArray(value)) return undefined;
  106  	for (const item of value) {
  107  		if (typeof item !== "string") return undefined;
  108  	}
  109  	return value;
  110  }
  111  
      … 46 lines omitted; exact range 88–167 …
  158  	// Project-level: opencode.json in project root
  159  	const projectConfigPath = path.join(ctx.cwd, "opencode.json");
  160  	const projectConfig = await loadJsonConfig(projectConfigPath);
  161  	if (projectConfig) {
  162  		const result = extractMCPServers(projectConfig, projectConfigPath, "project");
  163  		items.push(...result.items);
  164  		if (result.warnings) warnings.push(...result.warnings);
  165  	}
  166  
  167  	return { items, warnings };
查看全部 3 处证据
  • 实现 packages/coding-agent/src/discovery/opencode.ts:88–167 OpenCode MCP 配置发现。
  • 实现 packages/coding-agent/src/discovery/opencode.ts:170–220 transport/env/headers 归一化。
  • 实现 packages/coding-agent/src/discovery/gemini.ts:43–119 Gemini MCP 配置归一化。
06
DIMENSION · SUBAGENTS-COLLABORATION

子 Agent 与协作

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

16
L1事实omp-subagent-001

Task 是内建多 Agent 调度器,支持 batch、async 与结构化 yield

源码事实

TaskTool 发现 bundled/user/project agent;batch call 强制 shared context 和非空 tasks,每项可选 agent/effort/isolation/outputSchema;async 交给 job manager,sync 按 semaphore 并发并合并 usage/artifacts。子 Agent 必须通过 yield 交付,可增量分段并做 schema validation。

白话解释

主 Agent 可以一次发一组有共同背景的任务,每个工人独立选角色和输出合同;结果不是随便一段聊天,而是显式交付。

对自研 Harness 的含义

比 subprocess 示例级子 Agent 更接近真正控制平面。

关键源码 · 实现
packages/coding-agent/src/task/index.ts · L1–L53
    1  /**
    2   * Task tool - Delegate tasks to specialized agents.
    3   *
    4   * Discovers agent definitions from:
    5   *   - Bundled agents (shipped with omp-coding-agent)
    6   *   - ~/.omp/agent/agents/*.md (user-level)
    7   *   - .omp/agents/*.md (project-level)
    8   *
    9   * Supports:
   10   *   - Single agent spawn per call (parallelism = parallel task calls)
   11   *   - Batch spawning + shared context per call when `task.batch` is enabled
   12   *   - Background execution through AsyncJobManager when `async.enabled` is enabled
   13   *   - Progress tracking via JSON events
   14   *   - Session artifacts for debugging
   15   */
   16  import path from "node:path";
   17  import type { AgentTool, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
   18  import type { Usage } from "@oh-my-pi/pi-ai";
   19  import { $env, logger, prompt } from "@oh-my-pi/pi-utils";
   20  import type { ToolSession } from "..";
   21  import type { Theme } from "../modes/theme/theme";
   22  import subagentUserPromptTemplate from "../prompts/system/subagent-user-prompt.md" with { type: "text" };
   23  import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
   24  import taskAsyncContractTemplate from "../prompts/tools/task-async-contract.md" with { type: "text" };
      … 19 lines omitted; exact range 1–53 …
   44  import type { AsyncJobManager } from "../async";
   45  import { hasResolvableTranscript } from "../internal-urls/registry-helpers";
   46  import { AgentRegistry } from "../registry/agent-registry";
   47  import { type DiscoveryResult, discoverAgents } from "./discovery";
   48  import { generateTaskName } from "./name-generator";
   49  import { AgentOutputManager } from "./output-manager";
   50  import { mapWithConcurrencyLimitAllSettled, Semaphore } from "./parallel";
   51  import { renderResult, renderCall as renderTaskCall } from "./render";
   52  import { repairTaskParams } from "./repair-args";
   53  import { resolveEffectiveSubagentPolicy, runStructuredSubagent, StructuredSubagentError } from "./structured-subagent";
查看全部 3 处证据
  • 实现 packages/coding-agent/src/task/index.ts:1–53 TaskTool 能力和依赖。
  • 实现 packages/coding-agent/src/task/index.ts:230–329 batch schema、shared context 和 spawn normalization。
  • 实现 packages/coding-agent/src/task/yield-assembly.ts:120–198 typed incremental/terminal yield 组装。
17
L1事实omp-subagent-002

递归、并发、预算、闲置 park 与冷恢复都有硬合同

源码事实

默认 maxConcurrency=32、maxRecursionDepth=2、softRequestBudget=200,超过预算提示收尾、1.5x 强制 yield;idle 420 秒后可 park 到磁盘。reviver 从 session_init 恢复 cwd、tools、spawn policy、depth、MCP gate 和 yield requirement,缺失 workspace 时只保留 transcript。

白话解释

工人不会无限生工人,也能在闲置时卸载、之后按原权限复活;恢复时不凭猜测重建能力。

对自研 Harness 的含义

长任务资源治理和 durable collaboration 明显领先多数 CLI Agent。

关键源码 · 配置
packages/coding-agent/src/config/settings-schema.ts · L4505–L4614
 4505  	"task.maxConcurrency": {
 4506  		type: "number",
 4507  		default: 32,
 4508  		ui: {
 4509  			tab: "tasks",
 4510  			group: "Subagents",
 4511  			label: "Max Concurrent Tasks",
 4512  			description: "Maximum number of subagents running concurrently",
 4513  			options: [
 4514  				{ value: "0", label: "Unlimited" },
 4515  				{ value: "1", label: "1 task" },
 4516  				{ value: "2", label: "2 tasks" },
 4517  				{ value: "4", label: "4 tasks" },
 4518  				{ value: "8", label: "8 tasks" },
 4519  				{ value: "16", label: "16 tasks" },
 4520  				{ value: "32", label: "32 tasks" },
 4521  				{ value: "64", label: "64 tasks" },
 4522  			],
 4523  		},
 4524  	},
 4525  
 4526  	"task.enableLsp": {
 4527  		type: "boolean",
 4528  		default: false,
      … 76 lines omitted; exact range 4505–4614 …
 4605  	"task.softRequestBudgetNotice": {
 4606  		type: "boolean",
 4607  		default: true,
 4608  		ui: {
 4609  			tab: "tasks",
 4610  			group: "Subagents",
 4611  			label: "Soft Request Budget Notice",
 4612  			description:
 4613  				"Inject one steering notice when a subagent crosses its soft request budget, asking it to wrap up before the 1.5x forced-yield stop.",
 4614  		},
查看全部 2 处证据
  • 配置 packages/coding-agent/src/config/settings-schema.ts:4505–4614 并发、深度、runtime、idle TTL 和软预算默认。
  • 实现 packages/coding-agent/src/task/persisted-revive.ts:45–139 持久子 Agent 冷恢复与 capability clamp。
18
L1事实omp-subagent-003

兄弟 Agent 可用 hub 实时协作,不只回传父节点

源码事实

同批多个子 Agent 会收到 hub 协作建议;AgentRegistry 维护 live/idle/parked 实例,hub 支持 list/message/broadcast/wait,主会话与 RPC 也能显示和路由子 Agent 状态。

白话解释

几个工人不必各做各的等老板汇总,可以在工作中互相发消息、广播冲突和等待对方。

对自研 Harness 的含义

减少串行 handoff,但需要冲突检测、消息审计和身份权限。

关键源码 · Prompt
packages/coding-agent/src/task/index.ts · L412–L429
  412  /**
  413   * Suggestion — never a rejection — nudging the spawner to coordinate via the
  414   * hub when one call creates ≥2 live siblings and it still holds spawn
  415   * capacity. Returns undefined when there is nothing to coordinate or peer
  416   * messaging is unavailable.
  417   */
  418  export function buildCoordinationAdvisory(
  419  	items: TaskItem[],
  420  	depthCapacity: boolean,
  421  	ircEnabled: boolean,
  422  ): string | undefined {
  423  	if (!depthCapacity || !ircEnabled || items.length < 2) return undefined;
  424  	return (
  425  		`Coordinate: ${items.length} siblings are running together. If their work overlaps, have them ` +
  426  		`message each other via \`hub\` (by id, or "all" to broadcast) before editing shared files — ` +
  427  		`live coordination beats a serial handoff. Check \`hub\` op:"list" to see who is doing what.`
  428  	);
  429  }
查看全部 3 处证据
  • Prompt packages/coding-agent/src/task/index.ts:412–429 同批 sibling hub 协作提醒。
  • 实现 packages/coding-agent/src/tools/hub/index.ts:1–260 hub list/message/wait 工具入口。
  • 实现 packages/coding-agent/src/registry/agent-registry.ts:1–218 Agent identity/status/session registry。
07
DIMENSION · INSTRUCTIONS-PLUGINS-SKILLS

指令、插件与 Skills

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

19
L1事实omp-instructions-001

指令层兼容多个 Agent 生态,并支持 @include

源码事实

system builder 组合 personality、tool inventory、环境、workspace tree、active repo、project rules、skills、goals/memory/plan/task guidance;context capability 从父目录到 cwd 加载 AGENTS/CLAUDE/GEMINI 等,近目录后置,并展开相对 @path imports、去重同内容。

白话解释

它会把多种 Agent 留在仓库里的说明书都读成统一规则,越靠近当前目录的规则越显眼,还能在规则里引用其他文件。

对自研 Harness 的含义

跨工具迁移成本低,但最终 prompt provenance 和冲突诊断至关重要。

关键源码 · 实现
packages/coding-agent/src/system-prompt.ts · L332–L405
  332  export interface LoadContextFilesOptions {
  333  	/** Working directory to start walking up from. Default: getProjectDir() */
  334  	cwd?: string;
  335  }
  336  
  337  function dedupeExactContextFiles(
  338  	contextFiles: Array<{ path: string; content: string; depth?: number }>,
  339  ): Array<{ path: string; content: string; depth?: number }> {
  340  	const lastIndexByContent = new Map<string, number>();
  341  	for (const [index, file] of contextFiles.entries()) {
  342  		// Keep the closest matching context entry when content is byte-for-byte identical.
  343  		lastIndexByContent.set(file.content, index);
  344  	}
  345  
  346  	return contextFiles.filter((file, index) => lastIndexByContent.get(file.content) === index);
  347  }
  348  
  349  /**
  350   * Load all project context files using the capability API.
  351   * Returns {path, content, depth} entries for all discovered context files.
  352   * Files are sorted by depth (descending) so files closer to cwd appear last/more prominent.
  353   */
  354  export async function loadProjectContextFiles(
  355  	options: LoadContextFilesOptions = {},
      … 40 lines omitted; exact range 332–405 …
  396  	if (result.items.length === 0) return null;
  397  
  398  	const projectLevel = result.items.find(item => item.level === "project");
  399  	if (projectLevel) {
  400  		return projectLevel.content;
  401  	}
  402  
  403  	const userLevel = result.items.find(item => item.level === "user");
  404  	return userLevel?.content ?? null;
  405  }
查看全部 3 处证据
  • 实现 packages/coding-agent/src/system-prompt.ts:332–405 context files、@imports、排序、去重与 system override。
  • 契约 packages/coding-agent/src/discovery/opencode.ts:1–40 OpenCode context/skills/commands/extensions/MCP 兼容能力。
  • 契约 packages/coding-agent/src/discovery/gemini.ts:1–37 Gemini system/context/extensions/MCP 兼容能力。
20
L1风险omp-plugins-001

Extensions、hooks、custom tools 与 marketplace 都是同进程高权限扩展

源码事实

extension loader 直接加载 JS/TS,API 可改 provider request、system/context、tool call/result、session lifecycle 并注册 tools/providers/UI;hooks 有独立 runner,plugins 可从 npm/git/marketplace 安装并兼容 legacy Pi/Claude manifests。

白话解释

插件几乎能改 Agent 的每个关节,也能执行宿主代码;插件市场因此既是生态优势,也是供应链入口。

对自研 Harness 的含义

企业需要签名、来源锁定、版本 pin、审批和最小权限进程边界。

关键源码 · 实现
packages/coding-agent/src/extensibility/extensions/loader.ts · L120–L230
  120  		throw new ExtensionRuntimeNotInitializedError();
  121  	}
  122  
  123  	setServiceTier(): void {
  124  		throw new ExtensionRuntimeNotInitializedError();
  125  	}
  126  
  127  	getSessionName(): string | undefined {
  128  		throw new ExtensionRuntimeNotInitializedError();
  129  	}
  130  
  131  	setSessionName(): Promise<void> {
  132  		throw new ExtensionRuntimeNotInitializedError();
  133  	}
  134  }
  135  
  136  /**
  137   * ExtensionAPI implementation for an extension.
  138   * Registration methods write to the extension object.
  139   * Action methods delegate to the shared runtime.
  140   */
  141  class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
  142  	readonly logger = logger;
  143  	readonly typebox = TypeBox;
      … 77 lines omitted; exact range 120–230 …
  221  
  222  	sendMessage<T = unknown>(
  223  		message: CustomMessagePayload<T>,
  224  		options?: { triggerTurn?: boolean; deliverAs?: "steer" | "followUp" | "nextTurn" },
  225  	): void {
  226  		this.runtime.sendMessage(message, options);
  227  	}
  228  
  229  	sendUserMessage(
  230  		content: string | (TextContent | ImageContent)[],
查看全部 4 处证据
  • 实现 packages/coding-agent/src/extensibility/extensions/loader.ts:120–230 extension module load 与 API registration。
  • 契约 packages/coding-agent/src/extensibility/extensions/types.ts:1040–1150 provider/agent/tool/session hooks 与 registerTool。
  • 实现 packages/coding-agent/src/extensibility/hooks/runner.ts:268–420 hook tool/before_agent 执行与错误处理。
  • 实现 packages/coding-agent/src/extensibility/plugins/loader.ts:1–220 plugin/marketplace/legacy compatibility 装载。
08
DIMENSION · SESSIONS-OBSERVABILITY

会话与观测

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

21
L1事实omp-session-001

会话是树形事件账本,存储层可替换

源码事实

SessionManager 保留 parentId 树、message/compaction/branch/model/thinking/custom/session_init 等 entry;storage contract 支持 append/read/list/lock,仓库实现 indexed local、SQL、Redis 等后端并把大对象放 blob/artifact store。

白话解释

聊天、分支、压缩和配置变化都作为事件保存;存哪里可以从个人本地换到服务端数据库。

对自研 Harness 的含义

同一 Harness 可从 CLI 扩到多用户服务,但多后端一致性/锁/迁移成为核心基础设施。

关键源码 · 契约
packages/coding-agent/src/session/session-storage.ts · L1–L260
    1  import * as fs from "node:fs";
    2  import * as fsp from "node:fs/promises";
    3  import * as path from "node:path";
    4  import { hasFsCode, isEnoent, logger, peekFileEnds, Snowflake, toError } from "@oh-my-pi/pi-utils";
    5  import { overlayTitleSlotContent, type SessionTitleUpdate, serializeTitleSlot } from "./session-title-slot";
    6  
    7  const utf8Decoder = new TextDecoder("utf-8");
    8  
    9  export interface SessionStorageStat {
   10  	size: number;
   11  	mtimeMs: number;
   12  	mtime: Date;
   13  }
   14  
   15  export interface SessionStorageWriter {
   16  	/**
   17  	 * Append one newline-terminated line. File and memory storage perform the
   18  	 * write synchronously in-body; indexed backends queue in call order.
   19  	 *
   20  	 * `line` MUST include the trailing newline.
   21  	 */
   22  	append(line: string): Promise<void>;
   23  	/** Resolve once all queued appends complete. No fsync. */
   24  	flush(): Promise<void>;
      … 226 lines omitted; exact range 1–260 …
  251  	}
  252  
  253  	async writeTextAtomic(fpath: string, content: string, options?: WriteTextAtomicOptions): Promise<void> {
  254  		const dir = path.resolve(fpath, "..");
  255  		const tempPath = path.join(dir, `.${path.basename(fpath)}.${Snowflake.next()}.tmp`);
  256  		await fs.promises.mkdir(dir, { recursive: true });
  257  		try {
  258  			await fs.promises.writeFile(tempPath, content);
  259  		} catch (err) {
  260  			this.#discardTemp(tempPath, fpath);
查看全部 4 处证据
  • 契约 packages/coding-agent/src/session/session-storage.ts:1–260 storage 与 lock/list/append 合同。
  • 实现 packages/coding-agent/src/session/session-manager.ts:1–220 session manager/tree 初始化。
  • 实现 packages/coding-agent/src/session/redis-session-storage.ts:1–180 Redis 服务端存储实现入口。
  • 实现 packages/coding-agent/src/session/sql-session-storage.ts:1–180 SQL 存储实现入口。
22
L1事实omp-observability-001

观测层原生实现 OTEL GenAI spans、成本与 run coverage

源码事实

loop 生成 invoke_agent→chat/execute_tool 层级和 handoff,覆盖 GenAI semantic conventions、provider/model/usage/cache/reasoning、tool args/results、TTFT、cost、gateway headers、自定义 attributes;内容捕获默认关闭/可 summary/full。

白话解释

不仅有终端日志,每次模型和工具调用都能变成标准 trace,还能关联费用和网关调用 ID;敏感内容是否进 trace 可配置。

对自研 Harness 的含义

是 14 个项目中企业观测设计最完整的一档。

关键源码 · 契约
packages/agent/src/telemetry.ts · L1–L24
    1  /**
    2   * OpenTelemetry instrumentation for the agent loop.
    3   *
    4   * Implements the OpenTelemetry GenAI semantic conventions
    5   * (https://opentelemetry.io/docs/specs/semconv/gen-ai/) plus `pi.gen_ai.*`
    6   * extension attributes for run summaries, dashboard summaries, and cost hints
    7   * that are useful to downstream observability UIs.
    8   *
    9   * Span hierarchy emitted by the loop:
   10   *
   11   *   invoke_agent {agent.name}         (one per runLoop, gen_ai.operation.name=invoke_agent)
   12   *   ├── chat {model}                  (one per LLM call, gen_ai.operation.name=chat)
   13   *   ├── execute_tool {tool.name}      (one per tool call, gen_ai.operation.name=execute_tool)
   14   *   └── ...
   15   *
   16   * The `handoff` operation is emitted via the public {@link recordHandoff}
   17   * helper for hosts that route work between named agents.
   18   *
   19   * Activation is opt-in: callers pass an {@link AgentTelemetryConfig} on
   20   * `AgentLoopConfig.telemetry`. When unset, every helper short-circuits and
   21   * the loop performs zero tracer lookups. When set but no OTEL SDK is
   22   * registered, `@opentelemetry/api` returns a no-op tracer and all calls are
   23   * cheap pass-throughs.
   24   */
查看全部 4 处证据
  • 契约 packages/agent/src/telemetry.ts:1–24 span hierarchy 和 opt-in 行为。
  • 契约 packages/agent/src/telemetry.ts:66–174 GenAI/OpenAI/Pi attribute surface。
  • 契约 packages/agent/src/telemetry.ts:313–360 telemetry config、内容捕获和 cost hooks。
  • 实现 packages/agent/src/agent-loop.ts:652–737 run summary/coverage detailed API。
09
DIMENSION · TESTS-BENCHMARKS-MATURITY

测试、基准与成熟度

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

23
L3事实omp-tests-001

机制测试和基准工程极密集,但仍需外部成功率验证

源码事实

固定提交含 1858 个 *.test.ts,其中 coding-agent 1163 个,覆盖 MCP reconnect/OAuth/transport、task isolation/revive/budget、compaction、providers、tools、UI 和 storage;另有 metaharness、TypeScript edit benchmark、native/hashline/memory benchmarks。

白话解释

零件级和故障恢复考试数量非常大,也有专门实验 Harness;但仓库内测试多不代表在 SWE-bench 或真实企业任务上一定胜出。

对自研 Harness 的含义

工程可靠性证据强;横向结论应把“机制覆盖”与“端到端任务成功率”分开。

关键源码 · 测试
packages/coding-agent/test/task/isolation-runner.test.ts · L1–L100
    1  import { afterEach, describe, expect, it, vi } from "bun:test";
    2  import * as fs from "node:fs/promises";
    3  import * as os from "node:os";
    4  import * as path from "node:path";
    5  import * as executorModule from "@oh-my-pi/pi-coding-agent/task/executor";
    6  import {
    7  	applyEligibleNestedPatches,
    8  	mergeIsolatedChanges,
    9  	runIsolatedSubprocess,
   10  } from "@oh-my-pi/pi-coding-agent/task/isolation-runner";
   11  import type { SingleResult } from "@oh-my-pi/pi-coding-agent/task/types";
   12  import * as worktreeModule from "@oh-my-pi/pi-coding-agent/task/worktree";
   13  import * as gitModule from "@oh-my-pi/pi-coding-agent/utils/git";
   14  import * as natives from "@oh-my-pi/pi-natives";
   15  import { $ } from "bun";
   16  
   17  function result(overrides: Partial<SingleResult> = {}): SingleResult {
   18  	return {
   19  		index: 0,
   20  		id: "NestedOnly",
   21  		agent: "task",
   22  		agentSource: "bundled",
   23  		task: "Do nested work",
   24  		assignment: "Do nested work",
      … 66 lines omitted; exact range 1–100 …
   91  				untrackedPatch: "",
   92  			},
   93  			nested: [],
   94  		};
   95  		const rootPatch = "diff --git a/task.txt b/task.txt\n--- a/task.txt\n+++ b/task.txt\n@@ -1 +1 @@\n-old\n+new\n";
   96  
   97  		vi.spyOn(worktreeModule, "ensureIsolation").mockResolvedValue({
   98  			mergedDir: isolationDir,
   99  			backend: natives.IsoBackendKind.Rcopy,
  100  			fellBack: false,
查看全部 4 处证据
  • 测试 packages/coding-agent/test/task/isolation-runner.test.ts:1–100 子任务隔离测试入口。
  • 测试 packages/coding-agent/test/mcp-reconnect-storm.test.ts:1–93 MCP 重连风暴测试入口。
  • 测试 packages/coding-agent/test/agent-session-auto-compaction-progress-guard.test.ts:1–100 自动压缩进度/循环保护测试入口。
  • 实现 packages/metaharness/src/runner.ts:1–160 实验/benchmark Harness runner。
APPENDIX · SOURCE INDEX

本报告引用过的实现文件

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

  1. 01packages/agent/src/agent-loop.tsL879–918, 999–1048, 1402–1438, 2231–2250, 2318–2344, 2067–2200, 2408–2538, 2660–2692, 26–45, 167–186, 157–165, 652–737
  2. 02packages/coding-agent/src/session/agent-session.tsL2491–2619, 2621–2740
  3. 03packages/catalog/src/provider-models/descriptors.tsL1–66, 66–180
  4. 04packages/ai/src/providers/register-builtins.tsL33–163, 181–230, 232–289
  5. 05packages/agent/src/compaction/compaction.tsL148–189, 265–343, 501–636, 1145–1270, 1530–1607
  6. 06packages/agent/src/compaction/pruning.tsL1–260
  7. 07packages/agent/src/compaction/tool-protection.tsL1–56
  8. 08packages/agent/src/compaction/shake.tsL1–260
  9. 09packages/coding-agent/src/memory-backend/resolve.tsL6–24
  10. 10packages/coding-agent/src/memory-backend/local-backend.tsL11–46
  11. 11packages/coding-agent/src/session/session-memory.tsL169–221
  12. 12packages/mnemopi/src/core/orchestrator.tsL1–63
  13. 13packages/coding-agent/src/tools/index.tsL38–105, 393–434
  14. 14packages/coding-agent/src/sdk.tsL2531–2586
  15. 15packages/coding-agent/src/tools/approval.tsL13–39, 99–185
  16. 16packages/coding-agent/src/config/settings-schema.tsL3600–3647, 4359–4405, 4505–4614
  17. 17packages/coding-agent/src/session/bash-runner.tsL1–220
  18. 18packages/coding-agent/src/task/isolation-runner.tsL1–240
  19. 19packages/coding-agent/src/mcp/manager.tsL282–380
  20. 20packages/coding-agent/src/mcp/loader.tsL44–124
  21. 21packages/coding-agent/src/mcp/transports/http.tsL41–149, 181–258
  22. 22packages/coding-agent/src/discovery/opencode.tsL88–167, 170–220, 1–40
  23. 23packages/coding-agent/src/discovery/gemini.tsL43–119, 1–37
  24. 24packages/coding-agent/src/task/index.tsL1–53, 230–329, 412–429
  25. 25packages/coding-agent/src/task/yield-assembly.tsL120–198
  26. 26packages/coding-agent/src/task/persisted-revive.tsL45–139
  27. 27packages/coding-agent/src/tools/hub/index.tsL1–260
  28. 28packages/coding-agent/src/registry/agent-registry.tsL1–218
  29. 29packages/coding-agent/src/system-prompt.tsL332–405
  30. 30packages/coding-agent/src/extensibility/extensions/loader.tsL120–230
  31. 31packages/coding-agent/src/extensibility/extensions/types.tsL1040–1150
  32. 32packages/coding-agent/src/extensibility/hooks/runner.tsL268–420
  33. 33packages/coding-agent/src/extensibility/plugins/loader.tsL1–220
  34. 34packages/coding-agent/src/session/session-storage.tsL1–260
  35. 35packages/coding-agent/src/session/session-manager.tsL1–220
  36. 36packages/coding-agent/src/session/redis-session-storage.tsL1–180
  37. 37packages/coding-agent/src/session/sql-session-storage.tsL1–180
  38. 38packages/agent/src/telemetry.tsL1–24, 66–174, 313–360
  39. 39packages/coding-agent/test/task/isolation-runner.test.tsL1–100
  40. 40packages/coding-agent/test/mcp-reconnect-storm.test.tsL1–93
  41. 41packages/coding-agent/test/agent-session-auto-compaction-progress-guard.test.tsL1–100
  42. 42packages/metaharness/src/runner.tsL1–160