提供者能力系统¶
V2 绝不能假设每个提供者都能做到 Codex 能做的事情。提供者的行为应通过能力和策略来表达,而不是在编排逻辑中散布基于提供者名称的条件判断。
能力形态¶
type ProviderCapabilities = {
sessions: SessionCapabilities;
threads: ThreadCapabilities;
turns: TurnCapabilities;
streaming: StreamingCapabilities;
tools: ToolCapabilities;
approvals: ApprovalCapabilities;
planning: PlanningCapabilities;
subagents: SubagentCapabilities;
context: ContextCapabilities;
checkpointing: CheckpointCapabilities;
identity: IdentityCapabilities;
};
能力应由每个适配器在会话开始时进行版本化并发出。
会话能力¶
type SessionCapabilities = {
supportsMultipleProviderThreadsPerSession: boolean;
supportsModelSwitchInSession: boolean;
supportsProviderSwitchingViaHandoff: boolean;
supportsRuntimeModeSwitchInSession: boolean;
pendingRequestsSurviveRestart: boolean;
};
策略示例:
- 如果不支持模型切换,则启动新的提供者会话。
- 如果待处理请求在重启后无法保留,则将旧请求标记为
not_resumable。
提供者线程恢复不是一种能力,而是适配器必需的原语。适配器必须能够从已存储的提供者游标/会话/线程句柄启动,或返回运行时恢复失败。
线程能力¶
type ThreadCapabilities = {
canCreateEmptyThread: boolean;
canReadThreadSnapshot: boolean;
canRollbackThread: boolean;
canForkThread: boolean;
canForkFromTurn: boolean;
canForkFromSubagentThread: boolean;
exposesNativeThreadId: boolean;
};
Codex 可以暴露强线程 ID 和回滚快照。Claude 可能通过自身的模型/会话原语支持原生分叉。其他提供者可能只支持应用级合成分叉。
回合能力¶
type TurnCapabilities = {
exposesNativeTurnId: boolean;
emitsTurnStarted: boolean;
emitsTurnCompleted: boolean;
supportsInterrupt: boolean;
supportsActiveSteering: boolean;
supportsSteeringByInterruptRestart: boolean;
supportsQueuedMessages: boolean;
terminalStatusQuality: "strong" | "weak" | "none";
};
如果 terminalStatusQuality 为 weak,V2 应使用适配器策略推断终止状态,但仍需相应标记关联强度。
supportsActiveSteering 表示提供者可以直接修改进行中的回合。supportsSteeringByInterruptRestart 表示 V2 可以通过中断当前回合并启动替代尝试来实现应用级转向。大多数提供者在支持中断和正常后续回合的情况下,应支持后者。
流式能力¶
type StreamingCapabilities = {
streamsAssistantText: boolean;
streamsReasoning: boolean;
streamsToolOutput: boolean;
streamsPlanText: boolean;
emitsMessageCompleted: boolean;
};
如果未发出消息完成事件,规范化器会在根运行终止时关闭助手消息。
工具能力¶
type ToolCapabilities = {
exposesToolItemIds: boolean;
emitsToolStarted: boolean;
emitsToolCompleted: boolean;
emitsToolOutput: boolean;
supportsMcpTools: boolean;
supportsDynamicToolCallbacks: boolean;
};
较弱的提供者可能只生成文本形式的工具摘要。适配器仍然可以通过作用域序数创建有序的 turnItems 和执行节点。
审批能力¶
type ApprovalCapabilities = {
supportsCommandApproval: boolean;
supportsFileReadApproval: boolean;
supportsFileChangeApproval: boolean;
supportsApplyPatchApproval: boolean;
approvalsHaveNativeRequestIds: boolean;
approvalCallbacksAreLiveOnly: boolean;
approvalsCanOriginateFromSubagents: boolean;
};
如果子代理等执行节点可响应,UI 应显示来自任何执行节点的待处理审批。
规划能力¶
type PlanningCapabilities = {
emitsPlanUpdated: boolean;
emitsTodoList: boolean;
emitsProposedPlan: boolean;
supportsStructuredQuestions: boolean;
planDeltasHaveItemIds: boolean;
};
映射策略:
emitsTodoList:更新实时运行进度。emitsProposedPlan:创建可接受/可实施的计划工件。supportsStructuredQuestions:创建可响应用户输入请求。
如果提供者只发出普通助手文本,应用不应假装其拥有结构化计划。
子代理能力¶
type SubagentCapabilities = {
supportsSubagents: boolean;
exposesSubagentThreadIds: boolean;
emitsSubagentLifecycle: boolean;
canWaitForSubagents: boolean;
canCloseSubagents: boolean;
canForkSubagentThread: boolean;
};
当 exposesSubagentThreadIds 为 true 时,子代理的提供者线程将成为可寻址的 ProviderThread 记录。当为 false 时,如果提供者暴露了足够的生命周期信息,子代理仍可作为嵌套执行节点显示。
上下文交接能力¶
上下文交接控制提供者切换和提供者线程重建。
type ContextCapabilities = {
acceptsSystemContext: boolean;
acceptsDeveloperContext: boolean;
acceptsSyntheticUserContext: boolean;
canGenerateSummaries: boolean;
canConsumeHandoffSummaries: boolean;
supportsDeltaHandoff: boolean;
supportsFullThreadHandoff: boolean;
maxRecommendedHandoffChars: number | null;
};
策略示例:
- 如果
supportsDeltaHandoff可用,则携带仅包含提供者外部运行的摘要返回到先前的提供者线程。 - 如果增量交接不受支持或质量较低,则创建带有完整线程摘要的新提供者线程。
- 如果提供者无法接受显式上下文,则提供者切换应要求合成用户上下文,或标记为不受支持。
- 如果没有任何提供者能够生成摘要,则使用应用配置的摘要提供者或本地摘要生成能力。
检查点能力¶
检查点功能主要由应用拥有,但提供者会话回滚则取决于提供者。
type CheckpointCapabilities = {
appCanCheckpointFilesystem: boolean;
supportsNestedCheckpointScopes: boolean;
providerCanRollbackConversation: boolean;
providerRollbackReturnsSnapshot: boolean;
providerCanReadConversationSnapshot: boolean;
};
如果提供商不支持回滚,文件系统回滚仍可进行,但提供商对话状态必须重启或标记为分歧。嵌套检查点作用域由应用拥有;提供商仅影响其嵌套提供商对话能否回滚以匹配恢复后的文件系统状态。
身份能力¶
type IdentityCapabilities = {
nativeThreadIds: "strong" | "weak" | "none";
nativeTurnIds: "strong" | "weak" | "none";
nativeItemIds: "strong" | "weak" | "none";
nativeRequestIds: "strong" | "weak" | "none";
};
这控制归一化器如何关联事件:
strong:使用原生 ID 作为作用域内的提供商引用。weak:使用原生 ID 加上序数/指纹。none:按作用域序数分配。
降级策略¶
每个功能都应声明当能力缺失时会发生什么。
示例:
interrupt unsupported
-> stop session if allowed, otherwise mark unsupported
active steering unsupported
-> interrupt active turn and restart the run as a steering replacement attempt
fork unsupported
-> synthetic fork from app projection if policy allows
rollback unsupported
-> restore filesystem checkpoint, restart provider context, mark provider state divergent
nested checkpoint unsupported
-> capture only root-run checkpoint and record child filesystem activity as uncheckpointed
provider switch return unsupported
-> create fresh provider thread with full app-thread summary
structured approvals unsupported
-> provider runs under configured sandbox policy; no approval UI
plan_updated unsupported
-> no live todo UI; rely on assistant messages
UI 不应将不支持的行为隐藏在提供商特定错误之后。它应接收类型化的能力结果。
适配器契约¶
每个提供商适配器应暴露:
type ProviderAdapter = {
getCapabilities(): ProviderCapabilities;
startSession(input): ProviderSession;
ensureProviderThread(input): ProviderThread;
sendRun(input): ProviderTurnStartResult;
steerRun?(input): void;
interrupt(input): void;
respondToRequest(input): void;
readThreadSnapshot?(input): ProviderThreadSnapshot;
rollbackThread?(input): ProviderThreadSnapshot | void;
forkThread?(input): ProviderThread;
streamEvents(): Stream<ProviderAdapterEvent>;
};
可选方法受能力保护。编排层不应在未检查能力或未经策略包装器处理的情况下调用可选方法。
原始提供商帧应由提供商传输层/运行时作为有界诊断信息记录。适配器流应暴露归一化后的提供商事件,V2 归一化器可将其转换为应用编排事件。
能力驱动的 UI¶
UI 应获得能力感知的交互提示:
- 根据分支来源显示或隐藏分支操作。
- 将中断显示为可用、破坏性回退或不可用。
- 将审批显示为可响应或已过期。
- 仅在存在结构化计划工件时显示计划/待办面板。
- 仅当应用检查点存在时显示回滚,并标注提供商回滚支持。
这使产品在 Codex、Claude、Cursor、OpenCode 及未来的提供商之间保持可预测性。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 t3/t3code