/** * Example: Closed-Loop Feedback Persistence (Darwin → External Memory) * * After Darwin's multi-critic evaluates an agent run, this example shows * how to persist critic findings as external lessons that the NEXT agent * run can consult. We call the polarity rule "symmetric self-evolution" * because it writes BOTH success patterns and failure modes — not only * one side. This is structurally aligned with reflective self-improvement * approaches like GEPA (Genetic-Pareto, ICLR 2026 Oral, arXiv 2507.19457) * and the closed-loop pattern used by NousResearch's hermes-agent-self- * evolution repo. * * Why a separate persistence layer? * - darwin_db.darwin_experiments.feedback_report is great for analytics * but it never reaches the agent's prompt on the next run * - If your agents already read from a memory store (Mem0, Zep, Letta, * Cognee, a Postgres table, or even a markdown directory), pipe the * critic findings into THAT store so the next run sees them as context * * This example uses an in-memory store for demonstration. Replace with * your real backend (database, vector store, file system, etc.). * * Run: npx tsx examples/closed-loop-feedback.ts */ import type { MultiCriticResult } from '../src/evolution/multi-critic.js'; export type FeedbackPolarity = 'mistake' | 'pattern'; export interface FeedbackInput { /** Darwin agent name (matches AGENT_CRITIC_MAP key). */ agentName: string; /** The original task / prompt the agent ran. */ topic: string; /** Length of the agent's output in characters. */ outputLength: number; /** Median critic score (0-10). */ medianScore: number; /** Combined report text from all critics. */ combinedReport: string; /** Per-critic scores (NEGATIVE score = critic failed). */ criticScores: Array<{ critic: string; score: number; }>; } export interface FeedbackRecord { polarity: FeedbackPolarity; content: string; tags: string[]; /** 0-1, higher = more confident this is a real signal. */ confidence: number; } /** Pluggable storage backend. Implement against your real store. */ export interface FeedbackStore { save(record: FeedbackRecord): Promise; } /** Below this score → persist as 'mistake'. */ export declare const DEFAULT_LOW_THRESHOLD = 5; /** At/above this score → persist as 'pattern'. */ export declare const DEFAULT_HIGH_THRESHOLD = 8; /** Skip persistence when output is below this length (likely CLI failure). */ export declare const DEFAULT_MIN_OUTPUT_CHARS = 200; /** * Decide whether to persist this run and which polarity. * Mid-range scores (5..8) are intentionally NOT persisted — mediocre runs * are noise. We want strong signal in both directions. */ export declare function shouldPersist(input: FeedbackInput, options?: { lowThreshold?: number; highThreshold?: number; minOutputChars?: number; }): { persist: boolean; reason: string; polarity?: FeedbackPolarity; }; export declare function buildContent(input: FeedbackInput, polarity: FeedbackPolarity): string; export declare function buildTags(input: FeedbackInput, polarity: FeedbackPolarity): string[]; export declare function computeConfidence(input: FeedbackInput, polarity: FeedbackPolarity): number; /** * Persist a Darwin critic result to your external memory store. * Non-blocking — store errors are caught and surfaced as { persisted: false }. */ export declare function persistFeedback(input: FeedbackInput, store: FeedbackStore, options?: { lowThreshold?: number; highThreshold?: number; minOutputChars?: number; }): Promise<{ persisted: boolean; reason: string; polarity?: FeedbackPolarity; }>; /** * Bridge a Darwin MultiCriticResult into FeedbackInput shape. * Pure helper — no I/O. */ export declare function fromMultiCriticResult(result: MultiCriticResult, meta: { agentName: string; topic: string; outputLength: number; }): FeedbackInput; //# sourceMappingURL=closed-loop-feedback.d.ts.map