UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

120 lines (119 loc) • 5.16 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. /** * The stages' view of the `improve_ledger` table: record an attempt, and load * the rows candidate selection reads before it spends an LLM call. The * repository owns the schema and the outcome → cadence rule. */ import fs from "node:fs"; import { getStateDbPath, withImmediateTransaction, withStateDb } from "../../core/state-db.js"; import { warn } from "../../core/warn.js"; import { isContentDrivenRow, isLedgerBlocked, listImproveLedgerRows, PAIR_PASS_LEDGER_SOURCE, recordImproveLedger, } from "../../storage/repositories/improve-ledger-repository.js"; import { openSqliteReadSnapshot } from "../../storage/sqlite-read-snapshot.js"; export { isContentDrivenRow, isLedgerBlocked, PAIR_PASS_LEDGER_SOURCE }; /** An improve candidate's durable state key: its index item_ref, else its conceptId. */ export function stateKey(ref, itemRef) { return itemRef ?? ref; } /** The conceptId part of a durable key (`bundle//conceptId` → `conceptId`). */ export function stripBundle(ref) { const boundary = ref.indexOf("//"); return boundary >= 0 ? ref.slice(boundary + 2) : ref; } function ledgerDbPath(access) { return access?.proposalsCtx?.dbPath ?? access?.eventsCtx?.dbPath; } /** * Run `fn` against the ledger's database: the run's borrowed handle, a read * snapshot for a read-only caller (`undefined` when state.db does not exist), * or a managed open. */ function withLedgerDb(access, fn) { const borrowed = access?.eventsCtx?.db; if (borrowed) return fn(borrowed); const dbPath = ledgerDbPath(access); if (access?.readOnly) { const db = openSqliteReadSnapshot(dbPath ?? getStateDbPath()); if (!db) return undefined; try { return fn(db); } finally { db.close(); } } return withStateDb(fn, dbPath !== undefined ? { path: dbPath } : undefined); } /** * Record what a stage just did with one or more refs. Best-effort: a failure * is a warning, never an error on top of an LLM result. (Proposal mints and * decisions write the ledger in their own transactions.) */ export function recordLedgerAttempt(access, inputs) { const list = Array.isArray(inputs) ? inputs : [inputs]; if (list.length === 0 || access?.readOnly || access?.eventsCtx?.readOnly) return; const now = access?.proposalsCtx?.now ?? access?.eventsCtx?.now ?? Date.now; const at = new Date(now()).toISOString(); try { withLedgerDb(access, (db) => withImmediateTransaction(db, () => { for (const input of list) { recordImproveLedger(db, { stashDir: input.stashDir, ref: input.ref, source: input.source, outcome: input.outcome, at, ...(input.proposalId !== undefined ? { proposalId: input.proposalId } : {}), ...(input.detail !== undefined ? { detail: input.detail } : {}), ...(input.contentHash !== undefined ? { contentHash: input.contentHash } : {}), }); } })); } catch (error) { const first = list[0]; const more = list.length > 1 ? ` (+${list.length - 1} more)` : ""; warn(`[improve] ledger write failed for ${first.ref}${more} (${first.source} → ${first.outcome}): ${error instanceof Error ? error.message : String(error)}`); } } export function ledgerKey(source, ref) { return `${source}\0${ref}`; } /** Read state.db through `fn` without creating it: `undefined` when there is none yet. */ export function readLedgerDb(access, fn) { if (!access?.eventsCtx?.db && !fs.existsSync(ledgerDbPath(access) ?? getStateDbPath())) return undefined; return withLedgerDb(access, fn); } /** Every ledger row for `sources` in one query; no state.db yet means nothing was attempted. */ export function loadLedgerSnapshot(access, stashDir, sources) { const out = new Map(); try { readLedgerDb(access, (db) => { for (const row of listImproveLedgerRows(db, stashDir, sources)) out.set(ledgerKey(row.source, row.ref), row); }); } catch (error) { warn(`[improve] ledger read failed: ${error instanceof Error ? error.message : String(error)}`); } return out; } /** The row for a candidate under its durable key. */ export function ledgerRowFor(snapshot, source, ref, itemRef) { return snapshot.get(ledgerKey(source, stateKey(ref, itemRef))); } /** `ref → last_attempt_at` for one source over a candidate set (the signal-delta cursor). */ export function lastAttemptByRef(snapshot, source, candidates) { const out = new Map(); for (const candidate of candidates) { const row = ledgerRowFor(snapshot, source, candidate.ref, candidate.itemRef); if (row) out.set(candidate.ref, row.lastAttemptAt); } return out; }