import { LearningMemory, LearningMemoryRecord } from '@happyvertical/smrt-core'; import { DatabaseInterface } from '@happyvertical/sql'; import { DirectivePrincipal } from './directive-principal.js'; import { DirectiveProposal, DirectiveProposalCollection } from './directive-proposal.js'; import { Feedback, FeedbackCollection } from './feedback.js'; /** The (normalised) persona shape handed to the reflector. */ export interface ReflectionPersona { id: string; tenantId: string; agentClass?: string; name?: string; instructions?: string; memoryScope?: string; } /** * The persona a run consolidates over — accepts a persisted `AgentPersona` * directly (its `id` / `tenantId` are validated at run time). */ export interface ReflectionPersonaInput { id?: string | null; tenantId?: string | null; agentClass?: string; name?: string; instructions?: string; memoryScope?: string; } /** The consolidated input handed to the reflector (the AI boundary). */ export interface ReflectionInput { persona: ReflectionPersona; /** The persona's current effective instructions (resolved via prompts). */ currentInstructions: string; /** Recent episodes for the persona's memory scope. */ episodes: LearningMemoryRecord[]; /** Recent feedback signals for the persona. */ feedback: Feedback[]; } /** A candidate rewrite returned by the reflector. */ export interface DirectiveDraft { /** Proposed replacement instructions. */ instructions: string; /** Model-authored explanation. */ rationale: string; /** Optional aggregate confidence in `[0, 1]`. */ confidence?: number; } /** * The reflection boundary: consolidate episodes + feedback into a proposed * instruction rewrite, or `null` to propose nothing. Injected so the AI call is * the only thing mocked in tests. */ export type DirectiveReflector = (input: ReflectionInput) => Promise | DirectiveDraft | null; /** Options for {@link ReflectionRunner}. */ export interface ReflectionRunnerOptions { db: DatabaseInterface; /** The autonomous principal — must NOT hold `personas.activate-directive`. */ principal: DirectivePrincipal; /** The reflection boundary (AI call), injected. */ reflect: DirectiveReflector; proposals?: DirectiveProposalCollection; feedback?: FeedbackCollection; /** Clock, injectable for deterministic lookback in tests. */ now?: () => Date; } /** Options for a single {@link ReflectionRunner.run} pass over one persona. */ export interface ReflectionRunOptions { persona: ReflectionPersonaInput; /** The persona-scoped learning memory (see `personaLearningMemory`). */ memory: LearningMemory; /** Episode scope to recall for evidence. Omit to skip episode gathering. */ episodeScope?: string; /** Only consider feedback newer than this many ms ago. */ lookbackMs?: number; /** Cap on feedback rows considered. Default 50. */ feedbackLimit?: number; /** Neutral point for `rating` signals during reinforcement. Default 0. */ ratingNeutral?: number; /** Override the target prompt key (default the persona instructions key). */ promptKey?: string; } /** Result of a {@link ReflectionRunner.run} pass. */ export interface ReflectionRunResult { /** Newly created pending proposals (0 or 1). */ proposals: DirectiveProposal[]; /** Number of feedback signals that adjusted memory reinforcement. */ reinforced: number; /** Number of candidate rewrites suppressed (deduped / no-op). */ skipped: number; } /** * Consolidates feedback + episodes into pending directive proposals under a * principal that cannot activate them. */ export declare class ReflectionRunner { private readonly db; private readonly reflect; private readonly now; private readonly _principal; private proposalsCol?; private feedbackCol?; constructor(options: ReflectionRunnerOptions); /** * The autonomous principal this runner acts as. Exposed so callers can prove * it cannot activate a proposal (it lacks `personas.activate-directive`). */ get principal(): DirectivePrincipal; /** * Run one reflection pass for a persona. */ run(options: ReflectionRunOptions): Promise; private proposalsCollection; private feedbackCollection; } //# sourceMappingURL=reflection-runner.d.ts.map