session_save_experience
Records structured behavioral events like corrections, successes, failures, and learning moments to enable pattern detection and improve agent performance.
Instructions
Record a typed experience event. Unlike session_save_ledger (flat logs), this captures structured behavioral data for pattern detection.
Event Types:
correction: Agent was corrected by user
success: Task completed successfully
failure: Task failed
learning: New knowledge acquired
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project | Yes | Project identifier. | |
| event_type | Yes | Type of behavioral event. | |
| context | Yes | What the agent was doing when the event occurred. | |
| action | Yes | What action was tried. | |
| outcome | Yes | What happened as a result. | |
| correction | No | What should have been done instead (for correction type). | |
| confidence_score | No | Agent's confidence in the outcome (1-100). | |
| role | No | Optional. Agent role for Hivemind scoping. Omit to let the server auto-resolve from dashboard settings. |
Implementation Reference
- The handler implementation for session_save_experience, which processes the tool arguments, saves the event as a ledger entry, and queues an embedding update.
export async function sessionSaveExperienceHandler(args: unknown) { if (!isSessionSaveExperienceArgs(args)) { throw new Error("Invalid arguments for session_save_experience"); } const { project, event_type, context: ctx, action, outcome, correction, confidence_score, role } = args; const storage = await getStorage(); debugLog(`[session_save_experience] Recording ${event_type} event for project="${project}"`); // Format structured summary from event fields let summary = `[${event_type.toUpperCase()}] ${ctx} → ${action} → ${outcome}`; if (event_type === "correction" && correction) { summary += ` | CORRECTION: ${correction}`; } // Auto-extract keywords from the structured summary const keywords = toKeywordArray(summary); debugLog(`[session_save_experience] Extracted ${keywords.length} keywords: ${keywords.slice(0, 5).join(", ")}...`); const effectiveRole = role || await getSetting("default_role", "global"); const result = await storage.saveLedger({ project, conversation_id: "experience-event", user_id: PRISM_USER_ID, role: effectiveRole, event_type, summary, decisions: [ `Context: ${ctx}`, `Action: ${action}`, `Outcome: ${outcome}`, ...(correction ? [`Correction: ${correction}`] : []), ], keywords, confidence_score: typeof confidence_score === "number" ? confidence_score : undefined, // Corrections start with importance 1 to jumpstart visibility importance: event_type === "correction" ? 1 : 0, }); // Fire-and-forget embedding generation if (GOOGLE_API_KEY && result) { const embeddingText = summary; const savedEntry = Array.isArray(result) ? result[0] : result; const entryId = (savedEntry as any)?.id; if (entryId) { getLLMProvider().generateEmbedding(embeddingText) .then(async (embedding) => { await storage.patchLedger(entryId, { embedding: JSON.stringify(embedding), }); debugLog(`[session_save_experience] Embedding saved for entry ${entryId}`); }) .catch((err) => { console.error(`[session_save_experience] Embedding failed (non-fatal): ${err.message}`); }); } } return { content: [{ type: "text", text: `✅ Experience recorded: ${event_type} for project "${project}"\n` + `Summary: ${summary}\n` + (confidence_score !== undefined ? `Confidence: ${confidence_score}%\n` : "") + `Importance: ${event_type === "correction" ? 1 : 0} (upvote to increase)`, }], isError: false, }; } - The tool definition and type guard for session_save_experience.
export const SESSION_SAVE_EXPERIENCE_TOOL: Tool = { name: "session_save_experience", description: "Record a typed experience event. Unlike session_save_ledger (flat logs), " + "this captures structured behavioral data for pattern detection.\n\n" + "Event Types:\n" + "- **correction**: Agent was corrected by user\n" + "- **success**: Task completed successfully\n" + "- **failure**: Task failed\n" + "- **learning**: New knowledge acquired", inputSchema: { type: "object", properties: { project: { type: "string", description: "Project identifier.", }, event_type: { type: "string", enum: ["correction", "success", "failure", "learning"], description: "Type of behavioral event.", }, context: { type: "string", description: "What the agent was doing when the event occurred.", }, action: { type: "string", description: "What action was tried.", }, outcome: { type: "string", description: "What happened as a result.", }, correction: { type: "string", description: "What should have been done instead (for correction type).", }, confidence_score: { type: "integer", minimum: 1, maximum: 100, description: "Agent's confidence in the outcome (1-100).", }, role: { type: "string", description: "Optional. Agent role for Hivemind scoping. Omit to let the server auto-resolve from dashboard settings.", }, }, required: ["project", "event_type", "context", "action", "outcome"], }, }; export function isSessionSaveExperienceArgs( args: unknown ): args is { project: string; event_type: string; context: string; action: string; outcome: string; correction?: string; confidence_score?: number; role?: string; } { return ( typeof args === "object" && args !== null && "project" in args && typeof (args as any).project === "string" && "event_type" in args && typeof (args as any).event_type === "string" && "context" in args && typeof (args as any).context === "string" && "action" in args && typeof (args as any).action === "string" && "outcome" in args && typeof (args as any).outcome === "string" ); } - src/server.ts:132-132 (registration)Registration of SESSION_SAVE_EXPERIENCE_TOOL in src/server.ts.
SESSION_SAVE_EXPERIENCE_TOOL,