feat(agent): automation-first sessions with step plan, option choice and inline approval

- agent.plan emits plan_updated; system prompt asks for a plan first and updates while executing
- agent.propose_options registers a decision and suspends the run (waitForFact, no worker slot);
  the answer or timeout (recommended/stop) resumes it as the tool result
- console-session runs get inline approvals for plan-bound capabilities: approve replays the call
  with the approval, reject fails it with the reason and records it on the decision
- proposeFirst blocks execute capabilities until an option is chosen; E12 covers all paths

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-28 21:07:01 +08:00
1 parent 74c2ed45aa
commit cf2c4ff0e6
14 files changed
+1360 -26

No files matched your search

+27 -2
View File
@@ -16,6 +16,25 @@ export type SubagentEventBody = Extract<
{ type: "subagent_spawned" | "subagent_event" | "subagent_completed" }
>;
/**
* 由服务端(而不是模型 / harness)产生、追加进会话事件流的事件:子会话镜像与会话交互
* (步骤清单、方案选择、审批卡)。与运行时自身事件共用 seq(单写者)。
*/
export type InjectedEventBody = Extract<
AgentRunEventBody,
{
type:
| "subagent_spawned"
| "subagent_event"
| "subagent_completed"
| "plan_updated"
| "options_proposed"
| "options_resolved"
| "approval_requested"
| "approval_resolved";
}
>;
/** 调用能力时使用的业务身份;授权回调据此到 automation_grant / approval 查询 */
export interface AgentActor {
actorId: string;
@@ -47,6 +66,12 @@ export interface CreateRunSpec {
* 运行时在每次工具调用与每轮请求前把它加到自己的用量上再比预算。由调用方缓存,须同步返回。
*/
externalUsage?: () => ExternalUsage;
/**
* 挂起后可重放的"不可重放"能力(replay=never,如 download.submit 等审批)。给了它时,这类能力对 harness 声明为
* replay=safe,真正执行前用调用级 memo 区分首次与重放:重放时只有 replayGate 返回 true(本次恢复正是为了它,
* 如审批已决定)才重新调用注册中心(授权 / 账本照常),否则按"执行被中断、外部结果未知"返回错误(与 never 语义一致)。
*/
replayGate?: (capabilityId: string, invocationId: string) => boolean;
}
export interface ExternalUsage {
@@ -80,10 +105,10 @@ export interface AgentRunHandle {
resume(): Promise<RunOutcome>;
abort(reason?: string): Promise<void>;
/**
* 往本会话事件流追加一条子代理事件(subagent_*),与运行时自身事件共用 seq 计数(单写者)。
* 往本会话事件流追加一条服务端事件(子会话镜像 / 步骤清单 / 方案 / 审批),与运行时自身事件共用 seq 计数(单写者)。
* 会话已关闭时返回 false,调用方自行落库。
*/
appendEvent(body: SubagentEventBody): boolean;
appendEvent(body: InjectedEventBody): boolean;
/** 本会话自身已用量(不含子会话) */
stats(): { toolCalls: number; usage: AgentUsageTotals };
compact(customInstructions?: string): Promise<void>;