附录 C:固定快照、源码摘录与来源说明
C.1 四本参考读物
- claude-code-source-book,提交
08d220798172bb8161199e4cac9bc4aada3cca2e。用途:参考阅读路线;新书正文独立重写,关键架构结论以固定源码核查。 - deepseek-harness-book,提交
28d22f1c85726e1954788b5279d00cd54b947c0c。用途:参考阅读路线;新书正文独立重写,关键架构结论以固定源码核查。 - pi-beginner-book-zh,提交
84235722f81991f91d0dd482ec934122fe23bdd9。用途:参考阅读路线;新书正文独立重写,关键架构结论以固定源码核查。 - codex-engineering-book,提交
817c68806802bbb032124f259774e42514391b8c。用途:参考阅读路线;新书正文独立重写,关键架构结论以固定源码核查。
C.2 实际源码快照
- Claude Code 2.1.88 提取快照:Aias00/claude-code-source-book@08d2207。
- DeepSeek Harness:deepseek-ai/deepseek-harness@687f282。
- Pi:earendil-works/pi@16f5f0a。
- Codex:openai/codex@57d4fac。
Claude Code 链接指向用户提供快照的保存仓库,不是官方开源声明。各条目保存文件哈希与少量逐字摘录;解释以列明快照为限。完整机器可读记录见下载区 sources.json。
C.3 三十六处核查入口
cc-entry · Claude Code 2.1.88 提取快照
查看 source/entrypoints/cli.tsx 第 31–45 行。文件 SHA-256:87d4d49ed7512cf225d074e8f41aa3fb2f69eed19b9199e7eb30ddfd252a324f。
核查要点:快速路径与动态导入将轻量参数处理和完整 CLI 加载分开。
* Fast-path for --version has zero imports beyond this file.
*/
async function main(): Promise<void> {
const args = process.argv.slice(2);
// Fast-path for --version/-v: zero module loading needed
if (args.length === 1 && (args[0] === '--version' || args[0] === '-v' || args[0] === '-V')) {
// MACRO.VERSION is inlined at build time
// biome-ignore lint/suspicious/noConsole:: intentional console output
console.log(`${MACRO.VERSION} (Claude Code)`);
return;
}
// For all other paths, load the startup profiler
const {cc-loop · Claude Code 2.1.88 提取快照
查看 source/query.ts 第 239–253 行。文件 SHA-256:74e0ce0d86cfd453add8dc1d15ccb6311b02964b8321e3721b8e71fbd87252ce。
核查要点:异步生成器驱动对话循环;完整控制流需连同依赖与停止条件阅读。
}
async function* queryLoop(
params: QueryParams,
consumedCommandUuids: string[],
): AsyncGenerator<
| StreamEvent
| RequestStartEvent
| Message
| TombstoneMessage
| ToolUseSummaryMessage,
Terminal
> {
// Immutable params — never reassigned during the query loop.
const {cc-engine · Claude Code 2.1.88 提取快照
查看 source/QueryEngine.ts 第 182–196 行。文件 SHA-256:7df34a6a6d106927403d49e3405dfaf70da37cae5b644b658ebaf0b877988af6。
核查要点:会话级编排由 QueryEngine 提供,区别于单次模型请求。
* persists across turns.
*/
export class QueryEngine {
private config: QueryEngineConfig
private mutableMessages: Message[]
private abortController: AbortController
private permissionDenials: SDKPermissionDenial[]
private totalUsage: NonNullableUsage
private hasHandledOrphanedPermission = false
private readFileState: FileStateCache
// Turn-scoped skill discovery tracking (feeds was_discovered on
// tengu_skill_tool_invocation). Must persist across the two
// processUserInputContext rebuilds inside submitMessage, but is cleared
// at the start of each submitMessage to avoid unbounded growth across
// many turns in SDK mode.cc-stream · Claude Code 2.1.88 提取快照
查看 source/services/tools/StreamingToolExecutor.ts 第 38–52 行。文件 SHA-256:ee17dce704af73787c9ed76dbbc638167521e5c1f68c9436149378bb3358601c。
核查要点:工具执行状态、进度与取消属于专门的执行器。
* - Results are buffered and emitted in the order tools were received
*/
export class StreamingToolExecutor {
private tools: TrackedTool[] = []
private toolUseContext: ToolUseContext
private hasErrored = false
private erroredToolDescription = ''
// Child of toolUseContext.abortController. Fires when a Bash tool errors
// so sibling subprocesses die immediately instead of running to completion.
// Aborting this does NOT abort the parent — query.ts won't end the turn.
private siblingAbortController: AbortController
private discarded = false
// Signal to wake up getRemainingResults when progress is available
private progressAvailableResolve?: () => voidcc-permission · Claude Code 2.1.88 提取快照
查看 source/hooks/useCanUseTool.tsx 第 25–39 行。文件 SHA-256:3689b30326118e94bb53a8cc1fa1761d1c0b1bff6489162f1dd0771ec8b8b953。
核查要点:工具授权是带工具输入和执行上下文的决策接口。
import { createPermissionContext, createPermissionQueueOps } from './toolPermission/PermissionContext.js';
import { logPermissionDecision } from './toolPermission/permissionLogging.js';
export type CanUseToolFn<Input extends Record<string, unknown> = Record<string, unknown>> = (tool: ToolType, input: Input, toolUseContext: ToolUseContext, assistantMessage: AssistantMessage, toolUseID: string, forceDecision?: PermissionDecision<Input>) => Promise<PermissionDecision<Input>>;
function useCanUseTool(setToolUseConfirmQueue, setToolPermissionContext) {
const $ = _c(3);
let t0;
if ($[0] !== setToolPermissionContext || $[1] !== setToolUseConfirmQueue) {
t0 = async (tool, input, toolUseContext, assistantMessage, toolUseID, forceDecision) => new Promise(resolve => {
const ctx = createPermissionContext(tool, input, toolUseContext, assistantMessage, toolUseID, setToolPermissionContext, createPermissionQueueOps(setToolUseConfirmQueue));
if (ctx.resolveIfAborted(resolve)) {
return;
}
const decisionPromise = forceDecision !== undefined ? Promise.resolve(forceDecision) : hasPermissionsToUseTool(tool, input, toolUseContext, assistantMessage, toolUseID);
return decisionPromise.then(async result => {
if (result.behavior === "allow") {cc-budget · Claude Code 2.1.88 提取快照
查看 source/utils/toolResultStorage.ts 第 922–936 行。文件 SHA-256:db2bf39064319eefccebf49cf5c4521b42a13bc63caf2c57b21113f6204e6bcd。
核查要点:工具输出预算与持久化替换不等同于模型摘要。
* when the feature is off or no replacement occurred.
*/
export async function applyToolResultBudget(
messages: Message[],
state: ContentReplacementState | undefined,
writeToTranscript?: (records: ToolResultReplacementRecord[]) => void,
skipToolNames?: ReadonlySet<string>,
): Promise<Message[]> {
if (!state) return messages
const result = await enforceToolResultBudget(messages, state, skipToolNames)
if (result.newlyReplaced.length > 0) {
writeToTranscript?.(result.newlyReplaced)
}
return result.messages
}cc-compact · Claude Code 2.1.88 提取快照
查看 source/services/compact/autoCompact.ts 第 158–172 行。文件 SHA-256:1946b5ea23fa2eda91955378641258fb8f19e7742f06ce17d6caae7f2d3c921a。
核查要点:自动压缩有独立触发判断,不能把日志长度直接当作请求长度。
}
export async function shouldAutoCompact(
messages: Message[],
model: string,
querySource?: QuerySource,
// Snip removes messages but the surviving assistant's usage still reflects
// pre-snip context, so tokenCountWithEstimation can't see the savings.
// Subtract the rough-delta that snip already computed.
snipTokensFreed = 0,
): Promise<boolean> {
// Recursion guards. session_memory and compact are forked agents that
// would deadlock.
if (querySource === 'session_memory' || querySource === 'compact') {
return falsecc-storage · Claude Code 2.1.88 提取快照
查看 source/utils/sessionStorage.ts 第 137–151 行。文件 SHA-256:8a123ebce1ee72b9081d34b8f3697e5fcc9c7576df5b98e4206bb28414134412。
核查要点:持久化条目有自身类型边界,不是所有 UI 进度都等于对话正文。
* messages on resume (see #14373, #23537).
*/
export function isTranscriptMessage(entry: Entry): entry is TranscriptMessage {
return (
entry.type === 'user' ||
entry.type === 'assistant' ||
entry.type === 'attachment' ||
entry.type === 'system'
)
}
/**
* Entries that participate in the parentUuid chain. Used on the write path
* (insertMessageChain, useLogMessages) to skip progress when assigning
* parentUuid. Old transcripts with progress already in the chain are handleddsh-agent · DeepSeek Harness
查看 packages/core/agent-loop/src/agent.ts 第 96–110 行。文件 SHA-256:4add12f5c22bb1b8cf1dbc239c9b09fa3351feff2c936cb2b8900036468bd01b。
核查要点:默认驱动器围绕 session、inbox、scope 与 phase 组织运行。
/** Drives one session through turn and step boundaries. */
export class ReactLoopAgent implements Agent {
readonly inbox: ReactLoopInbox
private phase: Phase
private activityDone: Promise<void> = Promise.resolve()
/** The agent-scoped registration boundary; the lifecycle owner unwinds it after the driver exits. */
readonly scope: Scope
readonly ctx: Context
/** Fused dispatcher, built once in the constructor so hot-path dispatches never allocate. */
private readonly dispatch: AgentEventDispatch
/** Whether this loop instance has appended its initial/resume request anchor. */dsh-session · DeepSeek Harness
查看 packages/core/session/src/index.ts 第 982–996 行。文件 SHA-256:c1f08f7dcf4075eeebb13e6ea06b3f348bfeb85b8a5d4e4bfd1c3b93c1959332。
核查要点:模型历史由会话日志的有效 surface 派生;缓存受 generation 管理。
* @returns a fresh array of the shared, frozen derived history.
*/
deriveMessages(): Message[] {
const surface = this.surface
const nodes = surface.nodes
const generation = surface.contentGeneration
if (generation !== this.derivedGeneration) {
this.derived = []
this.derivedNodes = 0
this.derivedGeneration = generation
}
for (const seq of nodes.slice(this.derivedNodes)) {
// Surface sequences are built from this.log — seq is always a valid
// index by construction. The non-null assertion expresses that invariant.
// oxlint-disable-next-line typescript/no-non-null-assertiondsh-scheduler · DeepSeek Harness
查看 packages/core/agent-loop/src/tool-calls.ts 第 58–72 行。文件 SHA-256:5c7e8d8ff0028b436efdd13e5dffa4801d2311c211c3af039e7dab705f87b303。
核查要点:调度区分独占屏障和有界并行,完整实现在同文件。
* @param acceptContext - accepts committed result context for the next step boundary.
*/
export async function executeToolCalls(
ctx: Context,
turn: number,
step: number,
toolCalls: ToolCallBlock[],
signal: AbortSignal,
acceptContext: (context: UserMessage) => void,
): Promise<{ concluded: boolean }> {
const agent = ctx.agents.requireInitiator()
const { session } = agent
// Inputs are distinct because tools/execute wrappers may replace `exec.signal`.
const planned: PlannedCall[] = toolCalls.map(block => ({dsh-registry · DeepSeek Harness
查看 packages/core/tools/src/index.ts 第 1309–1323 行。文件 SHA-256:398bcdeb221e450d088510830b77d99a513e65ab31e40ade71688a19cdf5e6aa。
核查要点:并发安全声明缺失、异常或不为 true 时回退独占。
* @returns the fail-closed scheduling mode.
*/
executionMode(exec: ToolExecutionInput): ToolExecutionMode {
const tool = this.resolveExecution(exec.name, exec.agent, exec.parent !== undefined)
if (!tool?.isConcurrencySafe) return { kind: 'exclusive' }
try {
const concurrencySafe: unknown = tool.isConcurrencySafe(exec.arguments)
return concurrencySafe === true ? { kind: 'parallel' } : { kind: 'exclusive' }
} catch {
return { kind: 'exclusive' }
}
}
/**
* Run the `tools/ptc-dispatch-log` waterfall over one settled sub-dispatchdsh-events · DeepSeek Harness
查看 packages/core/agent/src/dispatch.ts 第 52–66 行。文件 SHA-256:6dc2702311305b9ecc8c8a932417bb7929f7313722fbb432a899e53d16efc6e0。
核查要点:通知 emit、等待 serial 与包围执行 waterfall 的语义不同。
* the agent itself injected into the payload.
*/
export interface AgentEventDispatch {
/**
* Fire-and-forget notification in the agent's scope. Every listener is
* invoked; synchronous throws and returned-promise rejections are logged and
* contained per listener, so a notification cannot veto lifecycle progress
* or starve a later observer.
* @param name - the agent-subject event to emit.
* @param payload - the event's payload fields; `agent` is injected.
*/
emit<K extends AgentSubjectEvent>(name: K, payload: PayloadRest<K>): void
/**
* Awaited in-order dispatch (Cordis `serial`) in the agent's scope.
* @param name - the agent-subject event to dispatch.dsh-lifecycle · DeepSeek Harness
查看 packages/core/agent-loop/src/index.ts 第 102–116 行。文件 SHA-256:3ea0262656c8ddcaa3be315c150bdc2af09371031c3c471d4ded511e21c6e86b。
核查要点:插件工厂追踪启动任务和活跃代理,承担有序卸载责任。
/** Factory-level ownership: live agent teardowns plus config startup work. */
class FactoryOwnership {
private accepting = true
private readonly teardown = new AbortController()
private readonly inactive = Promise.withResolvers<void>()
private readonly liveAgents = new Set<() => Promise<void>>()
private startupTasks = new Set<Promise<void>>()
constructor(private readonly fiber: Context['fiber']) {}
/** Aborts (reason: `agent loop is not active` error) when factory teardown begins. */
get signal(): AbortSignal {
return this.teardown.signal
}dsh-generation · DeepSeek Harness
查看 packages/session/session-persistence-jsonl/src/generation.ts 第 253–267 行。文件 SHA-256:43a400aaa47be789173ef4d5dd3226bce374cbfac300c2bff199b5a7d108efd6。
核查要点:JSONL generation 与文件稳定性在持久化提供方实现。
* @returns the stable bytes (or the committed prefix) and their stat identity.
*/
export async function readStableJsonlFile(
path: string,
signal?: AbortSignal,
): Promise<StablePhysicalFile> {
return defaultGenerationRuntime.readStable(path, signal)
}
async function readStableSnapshot(
path: string,
signal: AbortSignal | undefined,
fs: GenerationFileSystem,
): Promise<StablePhysicalFile> {
signal?.throwIfAborted()dsh-provider · DeepSeek Harness
查看 packages/llm/llm-deepseek/src/transport.ts 第 20–34 行。文件 SHA-256:7d1f6ed8fe861ee71ba2d0c6a2a9e8512ddc1b6dc17d43a8795ab520a38746b6。
核查要点:供应商传输错误转换成框架统一的 LlmError。
* @returns a stable error consumed by LlmRuntime and llm-retry.
*/
export function providerError(raw: unknown, status: number | undefined, headers?: Headers): LlmError {
const envelope = typeof raw === 'object' && raw !== null ? raw as Record<string, unknown> : {}
const error = typeof envelope.error === 'object' && envelope.error !== null ? envelope.error as Record<string, unknown> : {}
const message = typeof error.message === 'string' ? error.message : `DeepSeek Messages request failed (${status ?? 'stream error'})`
const type = typeof error.type === 'string' ? error.type : ''
const detail = `${type} ${typeof error.code === 'string' ? error.code : ''} ${message}`
let code: string
if (status === 401 || status === 403 || ['authentication_error', 'permission_error'].includes(type)) code = 'AUTH'
else if (isQuotaExceededError(detail) || status === 402) code = 'QUOTA'
else if (status === 429 || type === 'rate_limit_error') code = 'RATE_LIMIT'
else if (isContextWindowExceededError(detail)) code = 'CONTEXT_WINDOW_EXCEEDED'
else if (status === 400 || status === 413 || type === 'invalid_request_error') code = 'INVALID_REQUEST'
else if ((status !== undefined && status >= 500) || ['api_error', 'overloaded_error'].includes(type)) code = 'SERVER'dsh-sandbox · DeepSeek Harness
查看 packages/sandbox/sandbox/src/index.ts 第 123–137 行。文件 SHA-256:46592025ce36d04ff8d1bfa9d6594dd8d1527883649ccf40ff7a169e94e68dc6。
核查要点:沙箱不可用具有显式失败类型;不能默认为拥有隔离。
* failure.
*/
export const SANDBOX_UNAVAILABLE = 'SANDBOX_UNAVAILABLE'
/**
* Thrown when {@link SandboxProvider.confine} cannot enforce the requested
* mode. Carries {@link SANDBOX_UNAVAILABLE} through the structured error
* channel.
*/
export class SandboxUnavailableError extends HarnessError {
constructor(mode: ConfinedSandboxMode, detail?: string) {
super(
`sandbox mode "${mode}" is requested but no sandbox backend is usable on this host; `
+ 'refusing to run the command unconfined. Install bubblewrap or run a Landlock-enforcing '
+ 'kernel (Linux), ensure sandbox-exec is usable (macOS), or ensure the ACL 'pi-agent · Pi
查看 packages/agent/src/agent.ts 第 371–385 行。文件 SHA-256:7024a3145a6ebc951a0f030164adb1dfb12d33d6e0dbbac15ef0efda49c87457。
核查要点:Agent 阻止同时启动第二个 prompt,运行中输入走 steer/followUp。
async prompt(message: AgentMessage | AgentMessage[]): Promise<void>;
async prompt(input: string, images?: ImageContent[]): Promise<void>;
async prompt(input: string | AgentMessage | AgentMessage[], images?: ImageContent[]): Promise<void> {
if (this.activeRun) {
throw new Error(
"Agent is already processing a prompt. Use steer() or followUp() to queue messages, or wait for completion.",
);
}
const messages = this.normalizePromptInput(input, images);
await this.runPromptMessages(messages);
}
/** Continue from the current transcript. The last message must be a user or tool-result message. */
async continue(): Promise<void> {
if (this.activeRun) {pi-loop · Pi
查看 packages/agent/src/agent-loop.ts 第 161–175 行。文件 SHA-256:28a2b03e34a7e32f004aa851e54d3b5be9dad71c392205614cbc9abdf3a9020a。
核查要点:循环、模型流与宿主上下文转换可以分开组合。
* Main loop logic shared by agentLoop and agentLoopContinue.
*/
async function runLoop(
initialContext: AgentContext,
newMessages: AgentMessage[],
initialConfig: AgentLoopConfig,
signal: AbortSignal | undefined,
emit: AgentEventSink,
streamFunction: StreamFn,
): Promise<void> {
let currentContext = initialContext;
let config = initialConfig;
let lastCompletedTurn: PrepareNextTurnContext | undefined;
let explicitContinuation = false;
// Check for steering messages at start (user may have typed while waiting)pi-convert · Pi
查看 packages/agent/src/agent-loop.ts 第 388–402 行。文件 SHA-256:28a2b03e34a7e32f004aa851e54d3b5be9dad71c392205614cbc9abdf3a9020a。
核查要点:先变换应用上下文,再转换为模型兼容消息。
// Apply context transform if configured (AgentMessage[] → AgentMessage[])
let messages = context.messages;
if (config.transformContext) {
messages = await config.transformContext(messages, signal);
}
// Convert to LLM-compatible messages (AgentMessage[] → Message[])
const llmMessages = await config.convertToLlm(messages);
const llmContext = normalizeContext({ messages: llmMessages });
// Resolve API key (important for expiring tokens)
const resolvedApiKey =
(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;pi-truncated · Pi
查看 packages/agent/src/agent-loop.ts 第 266–280 行。文件 SHA-256:28a2b03e34a7e32f004aa851e54d3b5be9dad71c392205614cbc9abdf3a9020a。
核查要点:截断响应中的工具调用走失败结果,不直接执行潜在不完整参数。
// them all instead of executing potentially borked calls.
const executedToolBatch =
message.stopReason === "length"
? await failToolCallsFromTruncatedMessage(toolCalls, emit)
: await executeToolCalls(currentContext, message, config, signal, emit);
toolResults.push(...executedToolBatch.messages);
hasMoreToolCalls = !executedToolBatch.terminate;
for (const result of toolResults) {
currentContext.messages.push(result);
newMessages.push(result);
}
}
lastCompletedTurn = {pi-order · Pi
查看 packages/agent/src/agent-loop.ts 第 644–658 行。文件 SHA-256:28a2b03e34a7e32f004aa851e54d3b5be9dad71c392205614cbc9abdf3a9020a。
核查要点:并行结果整理回模型原调用顺序,区别于工具完成事件顺序。
}
const orderedFinalizedCalls = await Promise.all(
finalizedCalls.map((entry) => (typeof entry === "function" ? entry() : Promise.resolve(entry))),
);
const messages: ToolResultMessage[] = [];
for (const finalized of orderedFinalizedCalls) {
const toolResultMessage = createToolResultMessage(finalized);
await emitToolResultMessage(toolResultMessage, emit);
messages.push(toolResultMessage);
}
return {
messages,
terminate: shouldTerminateToolBatch(orderedFinalizedCalls),pi-stream-contract · Pi
查看 packages/agent/src/types.ts 第 31–45 行。文件 SHA-256:2e116ef60fdaca4e26be5a1ace8d8b47f545d648d365de60b8c9f9d1ba629ee4。
核查要点:模型流函数是注入的协议边界;错误契约见定义前注释。
* final AssistantMessage with stopReason "error" or "aborted" and errorMessage.
*/
export type StreamFn = (
model: Model<Api>,
context: TranscriptContext,
options?: SimpleStreamOptions,
) => AssistantMessageEventStream | Promise<AssistantMessageEventStream>;
/**
* Configuration for how tool calls from a single assistant message are executed.
*
* - "sequential": each tool call is prepared, executed, and finalized before the next one starts.
* - "parallel": tool calls are prepared sequentially, then allowed tools execute concurrently.
* `tool_execution_end` is emitted in tool completion order after each tool is finalized,
* while tool-result message artifacts are emitted later in assistant source order.pi-session · Pi
查看 packages/coding-agent/src/core/session-manager.ts 第 574–588 行。文件 SHA-256:450d82c529933214e088b8422f00061815e617f352f6c834689787a314064bff。
核查要点:会话条目树被解析为当前有效模型上下文。
/** Build the finalized model context from the canonical session projection. */
export function buildSessionContext(
entries: SessionEntry[],
leafId?: string | null,
byId?: Map<string, SessionEntry>,
): SessionContext {
const { messages, thinkingLevel, model } = buildSessionProjection(entries, leafId, byId);
return { messages, thinkingLevel, model };
}
/**
* Compute the default session directory for a cwd.
* Encodes cwd into a safe directory name under ~/.pi/agent/sessions/.
*/pi-compaction · Pi
查看 packages/coding-agent/src/core/compaction/compaction.ts 第 857–871 行。文件 SHA-256:f5bbc427e337be708bd15297806c0acaf7cb0ee65cc4af77e6e48c3e3937894f。
核查要点:压缩先准备范围,摘要生成在另一执行阶段。
}
export function prepareCompaction(
pathEntries: SessionEntry[],
settings: CompactionSettings,
): CompactionPreparation | undefined {
if (pathEntries.length > 0 && pathEntries[pathEntries.length - 1].type === "compaction") {
return undefined;
}
const projection = buildSessionProjection(pathEntries);
const projectedEntries = projection.entries;
const sourceEntries = projectedEntries.map((entry) => entry.sourceEntry);
// The newest compaction is projected first. Older compaction entries can still
// occur in its retained raw range, but their projected contribution is empty.pi-read · Pi
查看 packages/coding-agent/src/core/tools/read.ts 第 84–98 行。文件 SHA-256:c3c64f7105599455d3066568074796e2ddb143cb210da4981b0eb632aa3d2811。
核查要点:读取工具的声明、执行与展示可按定义入口继续追踪。
}
export function createReadToolDefinition(
cwd: string,
options?: ReadToolOptions,
): ToolDefinition<typeof readSchema, ReadToolDetails | undefined> {
const autoResizeImages = options?.autoResizeImages ?? true;
const fallbackResizeOptions = options?.resizeOptions;
const ops = options?.operations ?? defaultReadOperations;
return {
name: "read",
label: "read",
description: `Read the contents of a file. Supports text files and images (jpg, png, gif, webp, bmp). Images are sent as attachments. For text files, output is truncated to ${DEFAULT_MAX_LINES} lines or ${DEFAULT_MAX_BYTES / 1024}KB (whichever is hit first). Use offset/limit for large files. When you need the full file, continue with offset until complete.`,
promptSnippet: readToolSystemPromptContribution.snippet,
promptGuidelines: [...readToolSystemPromptContribution.guidelines],pi-extension · Pi
查看 packages/coding-agent/src/core/extensions/runner.ts 第 362–376 行。文件 SHA-256:3cd6d1ad18e8e4c7adf722aed9291bc64f06e3a7d461755c21e3cba4819f4e5e。
核查要点:应用扩展有自己的运行器,不能与底层 Agent 钩子直接等同。
};
export class ExtensionRunner {
private extensions: Extension[];
private runtime: ExtensionRuntime;
private uiContext: ExtensionUIContext;
private mode: ExtensionMode = "print";
private cwd: string;
private sessionManager: SessionManager;
private modelRegistry: ModelRegistry;
private errorListeners: Set<ExtensionErrorListener> = new Set();
private getModel: () => Model<any> | undefined = () => undefined;
private getScopedModels: () => readonly ScopedModel[] = () => [];
private isIdleFn: () => boolean = () => true;
private isProjectTrustedFn: () => boolean = () => true;codex-input · Codex
查看 codex-rs/core/src/codex_thread.rs 第 415–429 行。文件 SHA-256:8bb0072b4c30a3b736f4b898cbae5a949301283d6bb4e6a74e0f5b01781d6daf。
核查要点:输入提交先进入会话控制边界,而不是直接请求模型。
/// turn, or declined it without recording or enqueueing the input.
/// User input and named standalone function-call outputs are accepted.
pub async fn start_or_steer_turn(
&self,
request: impl Into<WithTurnExtensionData<TurnInputRequest>>,
) -> CodexResult<TurnInputSubmission> {
self.submit_turn_input_with_mode(request, TurnInputMode::StartOrSteer)
.await
}
/// Starts a regular turn only when the thread is idle.
///
/// Core declines the input without recording or enqueueing it when idle
/// work cannot start.
pub async fn start_turn_if_idle(codex-turn · Codex
查看 codex-rs/core/src/session/turn.rs 第 171–185 行。文件 SHA-256:076bf9522cba976a9b171d3a33403dfb7927330a73fe66afd4e8648f4b1c3629。
核查要点:Turn 编排模型会话、上下文准备与取消。
/// conversation history and consider the turn complete.
///
pub(crate) async fn run_turn(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
mut input: Vec<TurnInput>,
mcp_startup_requirements: &mut McpStartupRequirements,
prewarmed_client_session: Option<ModelClientSession>,
cancellation_token: CancellationToken,
) -> CodexResult<Option<String>> {
let auto_compaction_enabled = sess
.services
.thread_extension_data
.get::<AutoCompactionDisabled>()
.is_none();codex-followup · Codex
查看 codex-rs/core/src/session/turn.rs 第 608–622 行。文件 SHA-256:076bf9522cba976a9b171d3a33403dfb7927330a73fe66afd4e8648f4b1c3629。
核查要点:继续生成既可能由模型工作触发,也可能由待处理输入触发。
.instrument(trace_span!("run_turn.collect_post_sampling_state"))
.await;
let needs_follow_up = model_needs_follow_up || has_pending_input;
let token_limit_reached = token_status.token_limit_reached;
super::async_compaction::maybe_start(
&sess,
&step_context,
&world_state,
if needs_follow_up {
CompactionPhase::MidTurn
} else {
CompactionPhase::PostTurn
},
&cancellation_token,codex-router · Codex
查看 codex-rs/core/src/tools/router.rs 第 83–97 行。文件 SHA-256:7345f8d2c467637e3d646d5510770457db89e4259e0515d5175de363e2c9c79e。
核查要点:模型可见工具规格与执行注册表组成一份完成的工具计划。
/// One finalized tool plan: its advertised surfaces and matching executable runtimes.
pub struct ToolRouter {
registry: ToolRegistry,
model_visible_specs: Arc<[ToolSpec]>,
tool_mode: ToolMode,
code_mode_tool_names: BTreeMap<String, ToolName>,
tool_namespaces_info: Option<TurnToolNamespacesInfo>,
can_manage_children: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ToolSuggestPresentation {
ListTool,
RecommendationContext,codex-orchestrator · Codex
查看 codex-rs/core/src/tools/orchestrator.rs 第 1–13 行。文件 SHA-256:8996f718b818804473c151a8a643747c2b5ab69b05f4630eee143fac7daa0bb5。
核查要点:编排器协调审批、沙箱选择与受限失败后的重试。
//! Coordinates tool approval, sandbox selection, and retries after sandbox denial.
//! Guardian approval applies to the reviewed authority; escalating a sandboxed
//! attempt requires a fresh review of the retry.
use crate::config::NetworkProxySpec;
use crate::guardian::GuardianReviewContext;
use crate::network_policy_decision::network_approval_context_from_payload;
use crate::sandboxing::SandboxPermissions;
use crate::tools::approvals::ApprovalAction;
use crate::tools::approvals::ApprovalContext;
use crate::tools::approvals::ApprovalResolutionSource;
use crate::tools::flat_tool_name;
use crate::tools::network_approval::ActiveNetworkApproval;
use crate::tools::network_approval::DeferredNetworkApproval;codex-parallel · Codex
查看 codex-rs/core/src/tools/parallel.rs 第 49–63 行。文件 SHA-256:f575c018ab1452d99ccf9fa4630e5af5e92bbc9eb3e5457ea17ab5be8ae946d0。
核查要点:执行调度共享读写锁状态;具体并发资格须查看分派路径。
step_context: Arc<StepContext>,
tracker: SharedTurnDiffTracker,
parallel_execution: Arc<RwLock<()>>,
}
impl ToolCallRuntime {
pub(crate) fn new(
session: Arc<Session>,
step_context: Arc<StepContext>,
tracker: SharedTurnDiffTracker,
) -> Self {
Self {
session,
step_context,
tracker,codex-process · Codex
查看 codex-rs/core/src/unified_exec/process_manager.rs 第 877–891 行。文件 SHA-256:7eba3d82a54ad77cb989991ead28b39fe4aa1df24ddea020a0a36adb2d0fca5a。
核查要点:长进程使用 process_id 等句柄继续交互,不等于一次同步命令。
)
)]
pub(crate) async fn write_stdin(
&self,
context: &UnifiedExecContext,
request: WriteStdinRequest<'_>,
) -> Result<ExecCommandToolOutput, UnifiedExecError> {
let result = self.write_stdin_inner(context, request).await;
let outcome = match &result {
Ok(output) if output.process_id.is_some() => "yielded",
Ok(_) => "exited",
Err(_) if context.cancellation_token.is_cancelled() => "cancelled",
Err(_) => "failed",
};
tracing::Span::current().record("outcome", outcome);codex-compact · Codex
查看 codex-rs/core/src/compact.rs 第 115–129 行。文件 SHA-256:7501febae5a93a943e22c17ddb4009d6fea587cef40c6d5c6cf1b0754737be0d。
核查要点:上下文压缩是独立任务,具有执行与替换历史的边界。
}
pub(crate) async fn run_inline_auto_compact_task(
sess: Arc<Session>,
turn_context: Arc<TurnContext>,
replacement_step_context: Arc<StepContext>,
world_state: Arc<WorldState>,
reason: CompactionReason,
phase: CompactionPhase,
) -> CodexResult<()> {
let prompt = turn_context
.config
.compact_prompt
.as_deref()
.unwrap_or(SUMMARIZATION_PROMPT)codex-events · Codex
查看 codex-rs/protocol/src/protocol.rs 第 1467–1481 行。文件 SHA-256:9dc4ca7be855139716a72f1d291b5829affc07a19394647d1d9bbb09d4091941。
核查要点:协议事件承载核心和前端之间的状态,而不是靠解析终端文本。
#[ts(tag = "type")]
#[strum(serialize_all = "snake_case")]
pub enum EventMsg {
/// Error while executing a submission
Error(ErrorEvent),
/// Warning issued while processing a submission. Unlike `Error`, this
/// indicates the turn continued but the user should still be notified.
Warning(WarningEvent),
/// Provider-owned authentication recovery has started for the current turn.
AuthRecoveryStarted(AuthRecoveryEvent),
/// Provider-owned authentication recovery has completed for the current turn.
AuthRecoveryCompleted(AuthRecoveryEvent),C.4 版权与解释范围
本书为独立编写的非官方中文工程读物,采用 AI 辅助整理与代码核查,不代表上游项目审核或背书。正文和随书实验是新编内容;没有把四本参考书的章节复制拼接为新书。
本仓库根 MIT 许可仅适用于新增正文、实验代码、构建脚本与自制图示。上游代码短摘录与原始声明保留其原有条款,不能因本书的许可而扩大使用授权。
- DeepSeek Harness:Copyright (c) 2026 DeepSeek,MIT,见
licenses/DEEPSEEK-MIT.txt。 - Pi:Copyright (c) 2025 Mario Zechner,MIT,见
licenses/PI-MIT.txt。 - Codex:Apache-2.0,原许可和 NOTICE 见
licenses/CODEX-APACHE-2.0.txt、licenses/CODEX-NOTICE.txt。 - Claude Code:© Anthropic PBC. All rights reserved. 条款见
licenses/CLAUDE-CODE-NOTICE.txt中原始链接。资料来自用户提供的 2.1.88 提取快照,源码引用指向用户保存快照的镜像,而非声称该代码采用开源许可。
精确源码提交、路径、行号、文件 SHA-256 与短摘录记录在 book/sources.json;四本参考读物的提交记录在 book/reference-books.json。本书的解释与实验推导不应被当作上游项目的运行验证或安全认证。
本书新增内容的 MIT 许可
MIT License
Copyright (c) 2026 Aias00
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
以下为上游许可或声明的原文,分别适用于对应的摘录,不改变其适用范围。
CLAUDE-CODE-NOTICE.txt
© Anthropic PBC. All rights reserved. Use is subject to the Legal Agreements outlined here: https://code.claude.com/docs/en/legal-and-compliance.
CODEX-APACHE-2.0.txt
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2025 OpenAI
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
CODEX-NOTICE.txt
OpenAI Codex
Copyright 2025 OpenAI
This project includes code derived from [Ratatui](https://github.com/ratatui/ratatui), licensed under the MIT license.
Copyright (c) 2016-2022 Florian Dehau
Copyright (c) 2023-2025 The Ratatui Developers
DEEPSEEK-MIT.txt
MIT License
Copyright (c) 2026 DeepSeek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
PI-MIT.txt
MIT License
Copyright (c) 2025 Mario Zechner
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.