feat(goal-run): add multi-checkpoint goal orchestration with H5 and admin surfaces.

Persist goal runs in MySQL, bind agent runs to checkpoints, expose awaiting-approval
UX in chat, and add admin inspection routes with local verify scripts.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-01 17:03:16 +08:00
parent 43bc8bbc2b
commit 666db0b939
47 changed files with 4417 additions and 4 deletions
+46 -2
View File
@@ -620,6 +620,7 @@ export function createAgentRunGateway({
process.env.MEMIND_AGENT_SESSION_COMPACT_CHAR_COUNT,
120_000,
),
goalRunService = null,
workerIdentity = null,
}) {
const worker = normalizeAgentRunWorkerIdentity(workerIdentity ?? {});
@@ -1025,6 +1026,8 @@ export function createAgentRunGateway({
toolMode = 'chat',
taskType = null,
forceDeepReasoning = false,
goalRunId = null,
goalCheckpointId = null,
}) {
const normalizedRequestId = String(requestId ?? '').trim();
if (!normalizedRequestId) {
@@ -1088,16 +1091,18 @@ export function createAgentRunGateway({
});
await pool.query(
`INSERT INTO h5_agent_runs
(id, user_id, agent_session_id, request_id, status, attempts,
(id, user_id, agent_session_id, goal_run_id, goal_checkpoint_id, request_id, status, attempts,
user_message_json, error_message, created_at, updated_at, started_at, completed_at,
required_runtime_root, required_build_id,
claimed_worker_id, claimed_runtime_root, claimed_build_id)
VALUES (?, ?, ?, ?, 'queued', 0, ?, NULL, ?, ?, NULL, NULL,
VALUES (?, ?, ?, ?, ?, ?, 'queued', 0, ?, NULL, ?, ?, NULL, NULL,
?, ?, NULL, NULL, NULL)`,
[
runId,
userId,
sessionId || null,
goalRunId || null,
goalCheckpointId || null,
normalizedRequestId,
serializeMessage(runMessage),
createdAt,
@@ -1106,11 +1111,19 @@ export function createAgentRunGateway({
worker.buildId,
],
);
if (goalCheckpointId && goalRunService?.attachAgentRunToCheckpoint) {
await goalRunService.attachAgentRunToCheckpoint({
checkpointId: goalCheckpointId,
agentRunId: runId,
});
}
await appendEvent(runId, 'queued', {
sessionId: sessionId || null,
toolMode: normalizedToolMode,
taskType: normalizedTaskType,
forceDeepReasoning: Boolean(forceDeepReasoning),
goalRunId: goalRunId || null,
goalCheckpointId: goalCheckpointId || null,
requiredRuntimeRoot: worker.runtimeRoot,
requiredBuildId: worker.buildId,
});
@@ -1470,9 +1483,28 @@ export function createAgentRunGateway({
await appendEvent(runId, 'intent_routed', routing);
if (routingDecision === CHAT_INTENT_ROUTE.AGENT && chatIntentRouter?.applyAgentOrchestration) {
const grantedSkills = await resolveGrantedSkills(row.user_id);
let goalContext = null;
if (goalRunService && row.goal_run_id) {
try {
const goal = await goalRunService.getGoalRun({
userId: row.user_id,
goalRunId: row.goal_run_id,
});
const envelope = goalRunService.buildGoalContextEnvelope(goal);
if (envelope) {
goalContext = { injectionEnabled: true, envelope };
}
} catch (err) {
console.warn(
'[AgentRun] goal context envelope failed open:',
err instanceof Error ? err.message : err,
);
}
}
userMessage = chatIntentRouter.applyAgentOrchestration(userMessage, routing, {
grantedSkills,
memoryContext: agentMemoryContext,
goalContext,
});
}
}
@@ -2203,6 +2235,18 @@ export function createAgentRunGateway({
stopHeartbeat();
const terminalRun = await getRunById(runId).catch(() => null);
if (terminalRun && TERMINAL_STATUSES.has(terminalRun.status)) {
if (goalRunService?.onAgentRunCompleted && terminalRun.goal_checkpoint_id) {
await goalRunService.onAgentRunCompleted({
agentRunId: runId,
status: terminalRun.status,
outputSummary: extractRunDisplayText(terminalRun)?.slice(0, 500) ?? null,
}).catch((err) => {
console.warn(
'[AgentRun] goal run completion callback failed:',
err instanceof Error ? err.message : err,
);
});
}
await quiesceTerminalSession(runId, {
userId: terminalRun.user_id ?? row.user_id,
sessionId: terminalRun.agent_session_id ?? row.agent_session_id ?? null,