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:
1 parent
74c2ed45aa
commit
cf2c4ff0e6
14 files changed
+1360
-26
No files matched your search
@@ -4,6 +4,7 @@ import { defineTask, type OutboxRouteFn, type TaskRegistry } from "@umt/tasks";
|
||||
import { z } from "zod";
|
||||
import type { ServerContext } from "../types.ts";
|
||||
import { retryTask } from "./capabilities.ts";
|
||||
import { interactionReady, markWaitingForUser } from "./interaction.ts";
|
||||
import {
|
||||
annotateRunSummary,
|
||||
applyRecoveryOutcome,
|
||||
@@ -90,11 +91,17 @@ export function registerAgentTasks(registry: TaskRegistry, env: () => AgentEnv)
|
||||
break;
|
||||
}
|
||||
const waitMs = Math.max(0, Date.parse(sus.deadline) - Date.now());
|
||||
// 等用户(方案选择 / 审批)与等子会话共用挂起机制;步骤名保持 subagent-await-N 以兼容已有运行的步骤历史
|
||||
const user = sus.kind === "options" || sus.kind === "approval";
|
||||
const fact = `subagent-await-${n}`;
|
||||
const engineRunId = t.runId;
|
||||
await t.step.run(`${fact}-arm`, () => setAwaitWake(e.ctx, runId, { engineRunId, fact }));
|
||||
await t.step.run(`${fact}-arm`, async () => {
|
||||
await setAwaitWake(e.ctx, runId, { engineRunId, fact });
|
||||
if (user) await markWaitingForUser(e.ctx, runId, sus);
|
||||
return null;
|
||||
});
|
||||
await t.step.waitForFact<true>(fact, {
|
||||
check: () => awaitReady(e.ctx, runId, sus),
|
||||
check: () => (user ? interactionReady(e.ctx, runId, sus) : awaitReady(e.ctx, runId, sus)),
|
||||
timeout: `${AWAIT_POLL_SEC}s`,
|
||||
maxRounds: Math.max(1, Math.ceil(waitMs / 1000 / AWAIT_POLL_SEC) + 1),
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user