/** * Memory Store — memória persistente estruturada do runtime. * * Categorias: episodic, semantic, procedural, decision, failure, skill, project. * Local: .izanagi/state/memory.json (estado do runtime) + .agents/memoria/ (markdown humano). * * Complementa (não substitui) a memória markdown existente de .agents/memoria/. * * Toda mutação (recordAgentRun/recordSkillRun/recordModelRun/recordFailure/ * invalidateFailure/archiveFailure/addLearning) persiste em disco na hora — * não fica só em memória esperando um `.save()` explícito no fim do run. Se * o processo for encerrado no meio de uma execução (Ctrl+C, crash, terminal * fechado), o que já foi registrado até aquele ponto não se perde. */ import type { FailurePattern, MemoryCategory, MemoryEntry, RuntimeState } from '../types.js'; import { type Trajectory, type TrajectoryStep } from '../evolution/trajectories.js'; export declare const STATE_FILE_REL: string; export interface MemoryStoreOptions { baseDir: string; } export declare class MemoryStore { private readonly opts; private readonly stateFile; private readonly memoryDir; private state; constructor(opts: MemoryStoreOptions); private load; /** Persiste o estado atual. */ save(): void; get raw(): RuntimeState; /** * Onde este store de fato lê e grava. Público para que quem IMPRIME o * caminho imprima o mesmo que a escrita usou: a raiz de estado de um projeto * inicializado é `/.agents`, então um literal relativo ao `cwd` * aponta para outro lugar (e às vezes para um arquivo antigo que existe). */ get stateFilePath(): string; /** Onde vive a memória markdown deste projeto. Mesmo motivo de `stateFilePath`. */ get memoryDirPath(): string; recordAgentRun(agent: string, opts: { success: boolean; score: number; tokens: number; domains?: string[]; }): void; /** * Estatística do agente. Com `domain`, devolve o recorte daquele domínio — * e `undefined` quando não há histórico ali, o que é diferente de "vai mal": * quem chama precisa tratar ausência como ausência de sinal, não como falha. */ agentStats(agent: string, domain?: string): import("../types.js").AgentStats | undefined; recordSkillRun(skill: string, opts: { success: boolean; score: number; tokens: number; }): void; skillStats(skill: string): import("../types.js").SkillStats; recordModelRun(modelId: string, opts: { success: boolean; score: number; tokens: number; }): void; modelStats(modelId: string): import("../types.js").ModelStats; /** * Taxa de sucesso histórica por modelo (0-1), pronta para alimentar * `RoutingContext.historicalPerformance` do ModelRouter. Modelos sem * histórico ficam de fora do mapa (o router trata ausência como neutro). */ historicalPerformance(): Record; /** * Registra o caminho percorrido por um run. O simétrico de `recordFailure`: * o `LearningEngine` já convertia falha em padrão reutilizável, e sucesso não * virava nada além de estatística agregada. * * Devolve a trajetória consolidada, ou `null` quando a execução é curta * demais para ser procedimento (menos de 2 tarefas verificadas). */ recordTrajectory(input: { steps: TrajectoryStep[]; objective: string; domains?: string[]; success: boolean; }): Trajectory | null; /** Trajetórias que já se repetiram o bastante e ainda não viraram skill. */ recurrentTrajectories(): Trajectory[]; listTrajectories(limit?: number): Trajectory[]; /** Marca a trajetória como já sintetizada, para não gerar a skill duas vezes. */ markTrajectorySynthesized(signature: string, skill: string): boolean; /** * Registra (ou consolida) um padrão de falha reutilizável. * Se o mesmo pattern já existe, incrementa occurrences e atualiza confiança. */ recordFailure(pattern: Partial & { pattern: string; rootCause: string; solution: string; }): FailurePattern; /** * Invalida um padrão: a solução registrada não se aplica mais (ex.: causa * raiz mudou com uma refatoração). Some da busca ativa, mas fica no * histórico — se a mesma falha recorrer de verdade, `recordFailure` * reativa sozinho. Devolve false se o pattern não existe. */ invalidateFailure(pattern: string, reason?: string): boolean; /** * Arquiva um padrão: decisão manual e final de não usá-lo mais. Ao * contrário de invalidação, uma recorrência não reativa sozinha — exige * `recordFailure` explícito tratando como novo, ou reversão manual do status. * Devolve false se o pattern não existe. */ archiveFailure(pattern: string): boolean; /** Busca padrões de falha relevantes para uma tarefa (match por tags/symptoms). Ignora invalidated/archived por padrão. */ findRelevantFailures(query: string, opts?: { includeInactive?: boolean; }): FailurePattern[]; listFailures(limit?: number, opts?: { includeInactive?: boolean; }): FailurePattern[]; private entryFile; /** * Lista entradas de memória markdown existentes. * * Por padrão o conteúdo vem CORTADO em 4000 chars, porque uma entrada inteira * indo para o contexto de um prompt é justamente o que a arquitetura proíbe. * `full: true` devolve o arquivo completo, e existe porque BUSCAR sobre o * conteúdo cortado significava não encontrar nada além do começo do arquivo. */ listEntries(opts?: { full?: boolean; }): MemoryEntry[]; /** * Busca por termo nas entradas markdown. * * Duas correções sobre a versão anterior, e as duas mudam o RESULTADO, não a * velocidade: * * - varre o arquivo INTEIRO. Antes buscava sobre o conteúdo já cortado em * 4000 chars, então tudo que o projeto aprendeu depois das primeiras * páginas de cada arquivo era invisível para a busca — recall truncado em * silêncio, que é a pior forma de estar errado; * - devolve a JANELA em volta da ocorrência, não o começo do arquivo. Quem * busca "erro de timeout" quer o trecho sobre timeout, não a primeira * entrada do arquivo de erros. */ search(query: string, limit?: number): Array; /** * Acrescenta conhecimento REUTILIZÁVEL à camada semântica. * * Esta camada era lida (`listEntries`, `search`) e nunca escrita pelo * runtime: `.agents/memoria/semantica.md` só mudava quando uma pessoa o * editava. O que o runtime gravava era `addLearning`, numa lista plana que a * busca não alcança. Na prática, a memória semântica do projeto não * aprendia nada com a execução. * * Duas regras, e as duas existem para a camada não virar depósito: * * - só entra o que tem TÍTULO estável, e um título que já está no arquivo * não entra de novo. Sem isso, cada run acrescentaria uma variação do que * já estava lá e a busca passaria a devolver dez cópias do mesmo fato; * - o corpo tem teto. Conhecimento reutilizável é curto por natureza: o * detalhe da execução mora no trace e no artefato, que têm store próprio. * * Devolve `false` quando não gravou (título repetido ou entrada vazia), para * que quem chamou possa dizer "não aprendi nada novo" em vez de presumir. */ appendKnowledge(input: { category?: MemoryCategory; title: string; body: string; source?: string; }): boolean; addLearning(text: string, source: string, confidence?: number): void; listLearnings(limit?: number): { id: string; text: string; source: string; createdAt: string; confidence: number; }[]; } //# sourceMappingURL=store.d.ts.map