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:
+12
-13
@@ -6,6 +6,8 @@ import { jsonrepair } from 'jsonrepair';
|
||||
import { reconcileAgentSession } from './session-reconcile.mjs';
|
||||
import { resolveSessionAccess } from './session-broker.mjs';
|
||||
import { resolveBillingTokenState } from './billing-token-state.mjs';
|
||||
import { buildMindspaceJobExperiencePayload } from './experience-schema.mjs';
|
||||
import { formatExperienceInjectionBlock } from './experience-service.mjs';
|
||||
|
||||
const insecureDispatcher = new Agent({
|
||||
connect: { rejectUnauthorized: false },
|
||||
@@ -429,7 +431,7 @@ export function createMindSpaceAgentRunner({
|
||||
sourceAssetIds: claim.allowedAssets.map((asset) => asset.assetId),
|
||||
});
|
||||
// Record the outcome as shared experience so other instances benefit.
|
||||
await recordExperience(claim, sessionId, parsed);
|
||||
await recordExperience(jobId, claim, sessionId, parsed);
|
||||
return completed;
|
||||
} catch (error) {
|
||||
if (claim?.jobToken) {
|
||||
@@ -452,27 +454,24 @@ export function createMindSpaceAgentRunner({
|
||||
try {
|
||||
const hits = await experienceService.search(instruction, { limit: 3 });
|
||||
if (!hits.length) return '';
|
||||
const lines = hits.map((h) => `- ${h.title}: ${h.body}`).join('\n');
|
||||
return `# 相关经验(供参考,来自历史任务)\n${lines}`;
|
||||
return formatExperienceInjectionBlock(hits);
|
||||
} catch {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// Persists a one-line lesson from a completed job. Best-effort; never throws.
|
||||
async function recordExperience(claim, sessionId, parsed) {
|
||||
async function recordExperience(jobId, claim, sessionId, parsed) {
|
||||
if (!experienceService) return;
|
||||
try {
|
||||
const title = String(parsed?.title ?? claim.instruction ?? '').slice(0, 200);
|
||||
const summary = String(parsed?.summary ?? '').trim();
|
||||
if (!title || !summary) return;
|
||||
await experienceService.record({
|
||||
kind: 'task_outcome',
|
||||
title,
|
||||
body: summary,
|
||||
sourceSessionId: sessionId,
|
||||
sourceUserId: claim.userId,
|
||||
const payload = buildMindspaceJobExperiencePayload({
|
||||
claim,
|
||||
sessionId,
|
||||
parsed,
|
||||
jobId,
|
||||
});
|
||||
if (!payload) return;
|
||||
await experienceService.record(payload);
|
||||
} catch {
|
||||
// swallow — experience recording is non-critical
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user