Add Experience V1 schema migration and agent-run completion extractor.
Extend h5_experience with structured fields, wire mindspace-agent-runner and agent-run-gateway to persist task_outcome records with provenance, and add local migration and verification scripts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -49,6 +49,7 @@ import {
|
||||
isDirectEscalationContextEnabledForUser,
|
||||
resolveDirectEscalationContextPolicy,
|
||||
} from './chat-task-intent-config.mjs';
|
||||
import { extractAgentRunExperience } from './experience-extractor.mjs';
|
||||
|
||||
const DEFAULT_RUN_RETRY_DELAYS_MS = [1500, 5000, 15000];
|
||||
const TERMINAL_STATUSES = new Set(['succeeded', 'failed']);
|
||||
@@ -849,6 +850,7 @@ export function createAgentRunGateway({
|
||||
conversationMemoryService = null,
|
||||
syncUserPagesOnSuccess = null,
|
||||
observePersonalMemoryOnSuccess = null,
|
||||
experienceService = null,
|
||||
observeWorkflowRun = null,
|
||||
observeWorkflowValidation = null,
|
||||
isSessionExternallyBusy = null,
|
||||
@@ -905,6 +907,7 @@ export function createAgentRunGateway({
|
||||
const queuedDispatches = [];
|
||||
const queuedDispatchSet = new Set();
|
||||
const suggestionRepairTriggered = new Set();
|
||||
const runExecutionContext = new Map();
|
||||
|
||||
function enqueueRun(runId) {
|
||||
if (!runId || inFlight.has(runId) || queuedDispatchSet.has(runId)) return false;
|
||||
@@ -2566,6 +2569,7 @@ export function createAgentRunGateway({
|
||||
|
||||
try {
|
||||
const execution = await runWithTimeout(runId, () => executeRun(row, runId));
|
||||
runExecutionContext.set(runId, execution);
|
||||
await finalizeSuccessfulRun(runId, row, execution.sessionId, execution);
|
||||
} catch (err) {
|
||||
const latest = await getRunById(runId);
|
||||
@@ -2669,6 +2673,26 @@ export function createAgentRunGateway({
|
||||
stopHeartbeat();
|
||||
const terminalRun = await getRunById(runId).catch(() => null);
|
||||
if (terminalRun && TERMINAL_STATUSES.has(terminalRun.status)) {
|
||||
const executionContext = runExecutionContext.get(runId) ?? null;
|
||||
runExecutionContext.delete(runId);
|
||||
if (experienceService?.record) {
|
||||
await extractAgentRunExperience({
|
||||
experienceService,
|
||||
pool,
|
||||
row: terminalRun,
|
||||
runId,
|
||||
status: terminalRun.status,
|
||||
sessionId: terminalRun.agent_session_id ?? row.agent_session_id ?? null,
|
||||
errorMessage: terminalRun.error_message ?? null,
|
||||
toolEvidence: executionContext?.toolEvidence ?? null,
|
||||
routing: executionContext?.routing ?? null,
|
||||
}).catch((err) => {
|
||||
console.warn(
|
||||
'[AgentRun] experience extraction failed:',
|
||||
err instanceof Error ? err.message : err,
|
||||
);
|
||||
});
|
||||
}
|
||||
if (goalRunService?.onAgentRunCompleted && terminalRun.goal_checkpoint_id) {
|
||||
await goalRunService.onAgentRunCompleted({
|
||||
agentRunId: runId,
|
||||
|
||||
Reference in New Issue
Block a user