/** * Autonomous memory — canonical path whitelist + tier utilities. * * Single source of truth for the 8 stable memory documents. Every write * goes through {@link assertWritablePath}; every reader can ask * {@link getTierForPath} what a row belongs to. Adding or removing a * path means editing this file — and exactly this file. * * ## Why a whitelist? * * Earlier upstream-faithful designs used date-keyed files * (`memory/YYYY-MM-DD.md`), which have three problems for a persistent * multi-user agent: * * 1. **Unbounded growth** — one row per day per agent per user, forever. * 2. **LLM routing ambiguity** — "which date file do I read?" has no * good answer, so the model reads (and ranks against) all of them. * 3. **No natural deduplication** — the same fact written across three * days returns three near-identical hits. * * With 8 stable canonical documents the LLM knows *exactly* where to * write ("is this a preference? → `memory/user/preferences.md`") and * each row accumulates via UPSERT instead of piling up new rows. * * ## Two tiers * * - **Agent tier** (`memory/agent/*`) — operational knowledge that * every caller of the agent benefits from. Stored with `user_id = NULL`. * Shared across all users of a collaborative agent; the only tier that * exists for isolated/autonomous agents with no invoker. * * - **User tier** (`memory/user/*`) — per-invoker personalization. * Stored with `user_id = `. Read path filters so User A never * sees User B's rows, even for the same agent. Not writable unless the * flush scope carries a non-empty `userId`. * * The tier of a path is a function of its prefix (`memory/agent/` vs * `memory/user/`), so adding a new document is one line here + the * constant array entry; no store or route code has to change. */ import type { MemoryScope } from './types'; /** Tier discriminator — the two kinds of memory a row can belong to. */ export type MemoryTier = 'agent' | 'user'; /** Every canonical document the flush phase is allowed to write. */ export interface MemoryPathDescriptor { /** Full path including the `memory/` prefix. */ path: string; /** Which tier the path lives under. */ tier: MemoryTier; /** Short label shown in UI tier badges and the flush prompt rubric. */ label: string; /** One-line description — fed to the LLM to make routing unambiguous. */ description: string; } /** Agent-tier documents — shared across all users of the agent. */ export declare const MEMORY_AGENT_PATHS: readonly MemoryPathDescriptor[]; /** User-tier documents — per-invoker, never shared across users. */ export declare const MEMORY_USER_PATHS: readonly MemoryPathDescriptor[]; /** All 8 canonical documents in display order: agent tier first, user tier second. */ export declare const MEMORY_ALL_PATHS: readonly MemoryPathDescriptor[]; /** Set of all whitelisted paths — for `has()` lookups. */ export declare const MEMORY_WRITABLE_PATHS: ReadonlySet; /** Returns the descriptor for a canonical path, or `undefined` if not on the whitelist. */ export declare function getPathDescriptor(path: string): MemoryPathDescriptor | undefined; /** * Returns the tier a given path belongs to. * * For unknown paths (e.g. legacy date-keyed rows that predate this schema), * falls back to inspecting the `memory/agent/` or `memory/user/` prefix. * Anything that matches neither is classified as `agent` — it will surface * in the admin UI under the agent-tier header and stay read-only there. */ export declare function getTierForPath(path: string): MemoryTier; /** * Paths that are legal to write **for this caller's scope**. * * If `scope.userId` is absent (isolated/autonomous agent), the user-tier * paths are dropped. This is the list the flush prompt renders into its * rubric — the LLM never sees paths it cannot write to. */ export declare function getWritablePathsForScope(scope: Pick): readonly MemoryPathDescriptor[]; /** * Validates a write path against the whitelist AND the caller's scope. * * Throws with an actionable message when: * - the path is missing the `memory/` prefix * - the path is not on the 8-doc whitelist * - the path is user-tier but `scope.userId` is missing * * The store's append() is the single call site; other callers should * never hit this directly. Kept as a standalone function for testability. */ export declare function assertWritablePath(path: string, scope: Pick): MemoryPathDescriptor; /** * Renders the whitelist as a compact bullet list, used inside the flush * prompt so the LLM sees the authoritative rubric at inference time. * * Output shape: * - memory/agent/playbook.md [Playbook, shared] — * - memory/agent/pitfalls.md [Pitfalls, shared] — * ... * * The `[Label, shared|private]` tag tells the model whether the doc is * visible to all users (agent tier) or only to the caller (user tier). * Filtered to only the paths writable for the given scope. */ export declare function renderPathsRubric(scope: Pick): string;