@takk/racs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/LICENSE +190 -0
- package/NOTICE +40 -0
- package/README.md +381 -0
- package/SECURITY.md +57 -0
- package/dist/cli/index.js +3016 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/edge/index.cjs +2000 -0
- package/dist/edge/index.cjs.map +1 -0
- package/dist/edge/index.d.cts +598 -0
- package/dist/edge/index.d.ts +598 -0
- package/dist/edge/index.js +1987 -0
- package/dist/edge/index.js.map +1 -0
- package/dist/index.cjs +2071 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +39 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +2057 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.cjs +123 -0
- package/dist/integrations/index.cjs.map +1 -0
- package/dist/integrations/index.d.cts +285 -0
- package/dist/integrations/index.d.ts +285 -0
- package/dist/integrations/index.js +117 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/otel/index.cjs +93 -0
- package/dist/otel/index.cjs.map +1 -0
- package/dist/otel/index.d.cts +105 -0
- package/dist/otel/index.d.ts +105 -0
- package/dist/otel/index.js +91 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/types-DQ7-9sk3.d.cts +758 -0
- package/dist/types-DQ7-9sk3.d.ts +758 -0
- package/dist/vercel/index.cjs +209 -0
- package/dist/vercel/index.cjs.map +1 -0
- package/dist/vercel/index.d.cts +210 -0
- package/dist/vercel/index.d.ts +210 -0
- package/dist/vercel/index.js +206 -0
- package/dist/vercel/index.js.map +1 -0
- package/dist/web/index.cjs +2000 -0
- package/dist/web/index.cjs.map +1 -0
- package/dist/web/index.d.cts +2 -0
- package/dist/web/index.d.ts +2 -0
- package/dist/web/index.js +1987 -0
- package/dist/web/index.js.map +1 -0
- package/package.json +189 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/drift/Fingerprints.ts","../../src/errors.ts","../../src/ledger/Ledger.ts","../../src/stats/hash.ts","../../src/stats/tokens.ts","../../src/plan/Planner.ts","../../src/plan/PrefixAnalyzer.ts","../../src/providers/profiles.ts","../../src/schedule/TtlKeeper.ts","../../src/core/createRACS.ts","../../src/state/kv.ts","../../src/state/memory.ts"],"names":["profitable","reasoning"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Drift detection of RACS (Remote Agent Context Store): per-lineage fingerprints of plan\n * segment hashes, compared across consecutive plans to catch the silent cache killer, a\n * \"stable\" prefix that quietly changed and invalidated every cached token after the change.\n *\n * Fingerprints hold segment ids, content hashes, and declared stabilities only, never\n * prompt content, so serialized fingerprints leak nothing.\n *\n * @packageDocumentation\n */\n\nimport type { DriftReport, PlanInput, Stability } from '../types.js';\n\n/** Hash and declared stability of one segment at observation time. */\ninterface SegmentFingerprint {\n hash: string;\n stability: Stability;\n}\n\n/** Everything remembered about the latest plan of one lineage. */\ninterface LineageRecord {\n prefixKey: string;\n /** Token count of the stable prefix behind `prefixKey`, reported on later drift. */\n tokens: number;\n segments: Map<string, SegmentFingerprint>;\n}\n\n/** One serialized segment fingerprint, see {@link FingerprintsJSON}. */\nexport interface FingerprintSegmentJSON {\n /** Segment id, see {@link PlanInput} segment identity rules. */\n readonly id: string;\n /** Caller- or engine-computed content hash observed for the segment. */\n readonly hash: string;\n /** Stability the segment was declared with at observation time. */\n readonly stability: Stability;\n}\n\n/** One serialized lineage record, see {@link FingerprintsJSON}. */\nexport interface FingerprintEntryJSON {\n /** Lineage key: `agentId` when given, otherwise `provider:model`. */\n readonly key: string;\n /** Prefix key the lineage produced last. */\n readonly prefixKey: string;\n /** Token count of the stable prefix behind that key. */\n readonly tokens: number;\n /** Segment fingerprints of the last observed plan. */\n readonly segments: readonly FingerprintSegmentJSON[];\n}\n\n/**\n * Serialized fingerprint state, produced by {@link Fingerprints.toJSON} and consumed by\n * {@link Fingerprints.fromJSON}. Entries are ordered least-recently-observed first, so a\n * round trip preserves eviction order exactly.\n */\nexport interface FingerprintsJSON {\n /** The eviction cap the store was running with. */\n readonly capacity: number;\n /** Lineage records, least-recently-observed first. */\n readonly entries: readonly FingerprintEntryJSON[];\n}\n\n/**\n * Bounded, LRU-evicting store of per-lineage plan fingerprints.\n *\n * Lineage key: `agentId` when the input carries one, otherwise the `provider:model` pair,\n * matching the drift contract on {@link DriftReport}, the same agent and model lineage is\n * compared against itself across plans.\n *\n * Change semantics: only stable and semi segments count. A volatile segment is DECLARED to\n * differ on every call, so its churn, including its appearance or disappearance, is\n * expected behavior and never drift. For a segment present in both plans the current\n * declaration decides, a segment the caller re-declared volatile has opted out of drift\n * tracking from that plan onward. For a removed segment only the previous declaration\n * exists and is used.\n */\nexport class Fingerprints {\n private readonly capacity: number;\n /** Map iteration order doubles as recency order, oldest lineage first. */\n private readonly records = new Map<string, LineageRecord>();\n\n /**\n * @param capacity - Cap on distinct tracked lineages before LRU eviction.\n */\n constructor(capacity = 1000) {\n this.capacity = capacity;\n }\n\n /**\n * Records the fingerprint of one plan and compares it with the previous plan of the same\n * lineage.\n *\n * @param input - The plan input, provides the lineage key and segment stabilities.\n * @param prefixKey - Deterministic prefix key the plan produced.\n * @param segmentHashes - Segment id to content hash, as the planner derived them.\n * @param totalTokens - Token count of the stable prefix behind `prefixKey`. Stored, and\n * reported as `invalidatedTokens` if a later plan drifts to a different key, because\n * those are exactly the previously cached tokens the drift killed.\n * @param now - Milliseconds since the Unix epoch, from the injected engine clock.\n * @returns `undefined` on the first observation of a lineage and when nothing relevant\n * changed. Otherwise a {@link DriftReport} naming the changed, added, or removed\n * stable and semi segments, with `invalidatedTokens` equal to the previous stable\n * prefix size when the prefix key changed, and zero when the key survived.\n */\n observe(\n input: PlanInput,\n prefixKey: string,\n segmentHashes: ReadonlyMap<string, string>,\n totalTokens: number,\n now: number,\n ): DriftReport | undefined {\n const key = input.agentId ?? `${input.provider}:${input.model}`;\n\n const stabilityOf = new Map<string, Stability>();\n for (const segment of input.segments) {\n stabilityOf.set(segment.id, segment.stability);\n }\n const next = new Map<string, SegmentFingerprint>();\n for (const [id, hash] of segmentHashes) {\n // A hash without a matching segment declaration cannot prove instability, so it is\n // treated as volatile and excluded from drift rather than reported on a guess.\n next.set(id, { hash, stability: stabilityOf.get(id) ?? 'volatile' });\n }\n\n const previous = this.records.get(key);\n // Delete-then-set keeps Map iteration order as recency order for LRU eviction.\n this.records.delete(key);\n this.records.set(key, { prefixKey, tokens: totalTokens, segments: next });\n if (this.records.size > this.capacity) {\n const oldest = this.records.keys().next();\n if (!oldest.done) {\n this.records.delete(oldest.value);\n }\n }\n\n if (previous === undefined) {\n return undefined;\n }\n\n const changed = new Set<string>();\n for (const [id, fingerprint] of next) {\n if (fingerprint.stability === 'volatile') {\n continue;\n }\n const before = previous.segments.get(id);\n if (before === undefined || before.hash !== fingerprint.hash) {\n changed.add(id);\n }\n }\n for (const [id, fingerprint] of previous.segments) {\n if (!next.has(id) && fingerprint.stability !== 'volatile') {\n changed.add(id);\n }\n }\n\n if (changed.size === 0 && prefixKey === previous.prefixKey) {\n return undefined;\n }\n return {\n ...(input.agentId !== undefined ? { agentId: input.agentId } : {}),\n prefixKey,\n previousKey: previous.prefixKey,\n changedSegmentIds: [...changed].sort(),\n invalidatedTokens: prefixKey === previous.prefixKey ? 0 : previous.tokens,\n timestamp: now,\n };\n }\n\n /**\n * Removes every lineage record whose latest prefix key satisfies `predicate` and returns\n * the distinct prefix keys removed. Engine-level invalidation calls this when the host\n * clears prefixes, for example on credential rotation: a removed lineage simply restarts\n * drift tracking at its next plan, and first observations never report drift.\n */\n prune(predicate: (prefixKey: string) => boolean): readonly string[] {\n const removed = new Set<string>();\n for (const [key, record] of [...this.records]) {\n if (predicate(record.prefixKey)) {\n this.records.delete(key);\n removed.add(record.prefixKey);\n }\n }\n return [...removed];\n }\n\n /**\n * Serializes every lineage record, least-recently-observed first. Pure JSON data, no\n * prompt content, round-trips through {@link Fingerprints.fromJSON}.\n */\n toJSON(): FingerprintsJSON {\n const entries: FingerprintEntryJSON[] = [];\n for (const [key, record] of this.records) {\n const segments: FingerprintSegmentJSON[] = [];\n for (const [id, fingerprint] of record.segments) {\n segments.push({ id, hash: fingerprint.hash, stability: fingerprint.stability });\n }\n entries.push({ key, prefixKey: record.prefixKey, tokens: record.tokens, segments });\n }\n return { capacity: this.capacity, entries };\n }\n\n /**\n * Rebuilds a fingerprint store from {@link Fingerprints.toJSON} output, restoring\n * lineage records, their segment maps, and their recency order.\n *\n * @param json - A previously serialized store.\n */\n static fromJSON(json: FingerprintsJSON): Fingerprints {\n const store = new Fingerprints(json.capacity);\n for (const entry of json.entries) {\n const segments = new Map<string, SegmentFingerprint>();\n for (const segment of entry.segments) {\n segments.set(segment.id, { hash: segment.hash, stability: segment.stability });\n }\n store.records.set(entry.key, {\n prefixKey: entry.prefixKey,\n tokens: entry.tokens,\n segments,\n });\n }\n return store;\n }\n}\n","/**\n * Error model for RACS (Remote Agent Context Store).\n *\n * RACS throws exactly one error class so that host applications can catch and branch on a\n * single type, then dispatch on the stable machine-readable {@link RacsError.code}. New codes\n * may be added in minor versions, so consumers must treat the code space as open and fall back\n * gracefully on codes they do not recognize.\n *\n * @packageDocumentation\n */\n\n/**\n * The only error type thrown by RACS.\n *\n * Invariants:\n * - `name` is always the literal string `'RacsError'`, safe for cross-realm checks where\n * `instanceof` fails (multiple bundles, workers, iframes).\n * - `code` is a stable, machine-readable, SCREAMING_SNAKE identifier prefixed with `ERR_`.\n * It never changes meaning across versions, although new codes may appear in minors.\n * - `message` is human-readable English prose intended for logs, never for parsing.\n *\n * @example\n * ```ts\n * try {\n * racs.plan(input);\n * } catch (error) {\n * if (error instanceof RacsError && error.code === 'ERR_INVALID_INPUT') {\n * // The caller sent a malformed PlanInput, fix the call site.\n * }\n * }\n * ```\n */\nexport class RacsError extends Error {\n /**\n * Stable machine-readable error code, for example `'ERR_INVALID_INPUT'`.\n *\n * Branch on this field, never on `message`. The code space is minor-extensible.\n */\n readonly code: string;\n\n /**\n * @param message - Human-readable description of what went wrong and how to fix it.\n * @param code - Stable machine-readable code, see {@link RacsError.code}.\n */\n constructor(message: string, code: string) {\n super(message);\n this.name = 'RacsError';\n this.code = code;\n }\n\n /**\n * Builds a {@link RacsError} with code `'ERR_INVALID_INPUT'`.\n *\n * Used for every caller-side contract violation: malformed segments, a segment carrying\n * neither `content` nor `contentHash`, negative token counts, unknown TTL strings, and any\n * other input the type system cannot reject for untyped JavaScript callers.\n *\n * @param message - Human-readable description of the invalid input.\n * @returns A new error instance, never thrown by this factory itself.\n */\n static invalid(message: string): RacsError {\n return new RacsError(message, 'ERR_INVALID_INPUT');\n }\n}\n","/**\n * Usage ledger of RACS (Remote Agent Context Store): aggregates normalized provider usage\n * reports into per-prefix and ledger-wide hit ratios and USD savings.\n *\n * The ledger holds aggregates only, never prompt content, so its serialized form leaks\n * nothing. It is synchronous, allocation-light, and bounded: at most `maxPrefixes` distinct\n * prefixes are tracked, with least-recently-used eviction beyond that.\n *\n * @packageDocumentation\n */\n\nimport type { CacheUsage, LedgerStats, PrefixStats, PricingTable, ProviderId } from '../types.js';\n\n/**\n * Mutable per-prefix running totals. The two write tiers are kept apart because their\n * write premiums differ, see {@link Ledger.stats} for the USD math.\n */\ninterface PrefixAggregate {\n provider: ProviderId;\n model: string;\n calls: number;\n readTokens: number;\n write5mTokens: number;\n write1hTokens: number;\n uncachedTokens: number;\n}\n\n/**\n * One serialized prefix aggregate, see {@link LedgerJSON}.\n */\nexport interface LedgerEntryJSON {\n /** Aggregate key: the usage `prefixKey`, or `provider:model` for plan-less usage. */\n readonly key: string;\n /** Provider of the aggregated calls. */\n readonly provider: ProviderId;\n /** Model of the aggregated calls, the {@link PricingTable} lookup key. */\n readonly model: string;\n /** Number of usage records aggregated. */\n readonly calls: number;\n /** Total tokens served from cache. */\n readonly readTokens: number;\n /** Total tokens written to 5-minute-TTL caches. */\n readonly write5mTokens: number;\n /** Total tokens written to 1-hour-TTL caches. */\n readonly write1hTokens: number;\n /** Total input tokens that were neither read from nor written to cache. */\n readonly uncachedTokens: number;\n}\n\n/**\n * Serialized ledger state, the shape produced by {@link Ledger.toJSON} and consumed by\n * {@link Ledger.fromJSON}. Entries are ordered least-recently-used first, so a round trip\n * preserves eviction order exactly. Pricing is configuration, not state, and is therefore\n * re-supplied to `fromJSON` instead of being serialized.\n */\nexport interface LedgerJSON {\n /** The eviction cap the ledger was running with. */\n readonly maxPrefixes: number;\n /** Per-prefix aggregates, least-recently-used first. */\n readonly entries: readonly LedgerEntryJSON[];\n}\n\n/**\n * Bounded, LRU-evicting accumulator of {@link CacheUsage} records.\n *\n * Aggregation key: `usage.prefixKey` when the call executed a RACS plan, otherwise the\n * synthetic `provider:model` pair, so plan-less calls still aggregate into ledger totals\n * as {@link CacheUsage.prefixKey} documents.\n *\n * Hit-ratio definition: `readTokens / (readTokens + writeTokens + uncachedTokens)`, the\n * share of all input-side token traffic that was served from cache. The denominator counts\n * cached reads, cache writes of both TTL tiers, and uncached input, so a prefix that keeps\n * paying write premiums without ever reading back scores zero, exactly the failure the\n * ratio exists to expose. A zero denominator reports a ratio of zero. Uncached input\n * derives from the all-in {@link CacheUsage.inputTokens} convention, see\n * {@link Ledger.record}, so the denominator equals the all-in billed input when the\n * source reports consistently.\n *\n * USD math, computed only for models the {@link PricingTable} covers:\n * - `savedUsd = readTokens / 1e6 * (inputPerMTok - cacheReadPerMTok)`, what the cached\n * reads would have cost at base input price minus what they actually cost. Requires\n * `cacheReadPerMTok`, without it the model counts as not covered for savings.\n * - `writeSpendUsd` is the write PREMIUM over base input price, not the full write bill:\n * `write5mTokens / 1e6 * (cacheWrite5mPerMTok - inputPerMTok)` plus the 1-hour tier\n * likewise. A mispriced table can make a tier premium negative, which would silently\n * inflate savings, so each tier term is clamped at zero before summing.\n * - `netUsd = savedUsd - writeSpendUsd`, negative when caching lost money.\n *\n * Ledger-wide USD totals sum every prefix whose model the pricing table covers, prefixes\n * without pricing contribute only token statistics, and the USD fields are omitted\n * entirely when no aggregated prefix is covered.\n */\nexport class Ledger {\n private readonly pricing: PricingTable | undefined;\n private readonly maxPrefixes: number;\n /** Map iteration order doubles as recency order: oldest first, see {@link Ledger.record}. */\n private readonly aggregates = new Map<string, PrefixAggregate>();\n\n /**\n * @param pricing - Per-model price cards for USD figures, always user-supplied. Without\n * it every token-denominated statistic is still reported, just no USD.\n * @param maxPrefixes - Cap on distinct tracked prefixes before LRU eviction.\n */\n constructor(pricing?: PricingTable, maxPrefixes = 1000) {\n this.pricing = pricing;\n this.maxPrefixes = maxPrefixes;\n }\n\n /**\n * Ingests one normalized usage record into the aggregate for its prefix.\n *\n * Per call, `uncachedTokens` accumulates\n * `max(0, inputTokens - cacheReadTokens - cacheWriteTokens5m - cacheWriteTokens1h)`:\n * {@link CacheUsage.inputTokens} is the ALL-IN billed input including cached reads and\n * cache writes of both tiers, so the uncached remainder subtracts all three. Clamped at\n * zero because a source reporting more cached traffic than billed input is a reporting\n * artifact that must not drive the aggregate negative.\n *\n * @param usage - The normalized usage report, see {@link CacheUsage}.\n * @returns `hit` is true when the call read at least one cached token. `evicted` names\n * the least-recently-used prefix key dropped to stay within `maxPrefixes`, present\n * only when an eviction happened.\n */\n record(usage: CacheUsage): { hit: boolean; evicted?: string } {\n const key = usage.prefixKey ?? `${usage.provider}:${usage.model}`;\n const aggregate: PrefixAggregate = this.aggregates.get(key) ?? {\n provider: usage.provider,\n model: usage.model,\n calls: 0,\n readTokens: 0,\n write5mTokens: 0,\n write1hTokens: 0,\n uncachedTokens: 0,\n };\n // Delete-then-set moves the key to the end of Map iteration order, which keeps the\n // oldest aggregate first and makes eviction a read of the first key.\n this.aggregates.delete(key);\n this.aggregates.set(key, aggregate);\n\n aggregate.calls += 1;\n aggregate.readTokens += usage.cacheReadTokens;\n aggregate.write5mTokens += usage.cacheWriteTokens5m ?? 0;\n aggregate.write1hTokens += usage.cacheWriteTokens1h ?? 0;\n aggregate.uncachedTokens += Math.max(\n 0,\n usage.inputTokens -\n usage.cacheReadTokens -\n (usage.cacheWriteTokens5m ?? 0) -\n (usage.cacheWriteTokens1h ?? 0),\n );\n aggregate.provider = usage.provider;\n aggregate.model = usage.model;\n\n const hit = usage.cacheReadTokens > 0;\n let evicted: string | undefined;\n if (this.aggregates.size > this.maxPrefixes) {\n const oldest = this.aggregates.keys().next();\n if (!oldest.done) {\n evicted = oldest.value;\n this.aggregates.delete(oldest.value);\n }\n }\n return evicted === undefined ? { hit } : { hit, evicted };\n }\n\n /**\n * Returns ledger-wide statistics with the per-prefix breakdown, optionally narrowed to\n * one prefix key or one provider. The breakdown is sorted by prefix key ascending for\n * stable, diffable output. USD presence rules are documented on {@link Ledger}.\n *\n * @param filter - Optional narrowing, both fields combine conjunctively when given.\n */\n stats(filter?: { prefixKey?: string; provider?: ProviderId }): LedgerStats {\n const prefixes: PrefixStats[] = [];\n let calls = 0;\n let readTokens = 0;\n let writeTokens = 0;\n let uncachedTokens = 0;\n let savedUsd = 0;\n let writeSpendUsd = 0;\n let priced = false;\n\n for (const [key, aggregate] of this.aggregates) {\n if (filter?.prefixKey !== undefined && key !== filter.prefixKey) {\n continue;\n }\n if (filter?.provider !== undefined && aggregate.provider !== filter.provider) {\n continue;\n }\n const stat = this.prefixStats(key, aggregate);\n prefixes.push(stat);\n calls += aggregate.calls;\n readTokens += aggregate.readTokens;\n writeTokens += aggregate.write5mTokens + aggregate.write1hTokens;\n uncachedTokens += aggregate.uncachedTokens;\n if (stat.savedUsd !== undefined) {\n savedUsd += stat.savedUsd;\n priced = true;\n }\n if (stat.writeSpendUsd !== undefined) {\n writeSpendUsd += stat.writeSpendUsd;\n priced = true;\n }\n }\n\n prefixes.sort((a, b) => (a.prefixKey < b.prefixKey ? -1 : a.prefixKey > b.prefixKey ? 1 : 0));\n const denominator = readTokens + writeTokens + uncachedTokens;\n return {\n calls,\n hitRatio: denominator === 0 ? 0 : readTokens / denominator,\n readTokens,\n writeTokens,\n uncachedTokens,\n ...(priced ? { savedUsd, netUsd: savedUsd - writeSpendUsd } : {}),\n prefixes,\n };\n }\n\n /**\n * Serializes every aggregate, least-recently-used first. The result is pure JSON data,\n * carries no prompt content, and round-trips through {@link Ledger.fromJSON}.\n */\n toJSON(): LedgerJSON {\n const entries: LedgerEntryJSON[] = [];\n for (const [key, aggregate] of this.aggregates) {\n entries.push({\n key,\n provider: aggregate.provider,\n model: aggregate.model,\n calls: aggregate.calls,\n readTokens: aggregate.readTokens,\n write5mTokens: aggregate.write5mTokens,\n write1hTokens: aggregate.write1hTokens,\n uncachedTokens: aggregate.uncachedTokens,\n });\n }\n return { maxPrefixes: this.maxPrefixes, entries };\n }\n\n /**\n * Rebuilds a ledger from {@link Ledger.toJSON} output, restoring aggregates and their\n * recency order. Pricing is configuration, pass the current table, it is deliberately\n * not part of the snapshot so stale prices never resurrect from persistence.\n *\n * @param json - A previously serialized ledger.\n * @param pricing - The pricing table to compute USD figures with from now on.\n */\n static fromJSON(json: LedgerJSON, pricing?: PricingTable): Ledger {\n const ledger = new Ledger(pricing, json.maxPrefixes);\n for (const entry of json.entries) {\n ledger.aggregates.set(entry.key, {\n provider: entry.provider,\n model: entry.model,\n calls: entry.calls,\n readTokens: entry.readTokens,\n write5mTokens: entry.write5mTokens,\n write1hTokens: entry.write1hTokens,\n uncachedTokens: entry.uncachedTokens,\n });\n }\n return ledger;\n }\n\n /** Computes one {@link PrefixStats} from a live aggregate, USD rules per {@link Ledger}. */\n private prefixStats(key: string, aggregate: PrefixAggregate): PrefixStats {\n const writeTokens = aggregate.write5mTokens + aggregate.write1hTokens;\n const denominator = aggregate.readTokens + writeTokens + aggregate.uncachedTokens;\n const hitRatio = denominator === 0 ? 0 : aggregate.readTokens / denominator;\n\n const price = this.pricing?.[aggregate.model];\n let savedUsd: number | undefined;\n let writeSpendUsd: number | undefined;\n if (price !== undefined) {\n if (price.cacheReadPerMTok !== undefined) {\n savedUsd = (aggregate.readTokens / 1e6) * (price.inputPerMTok - price.cacheReadPerMTok);\n }\n const premium5m =\n price.cacheWrite5mPerMTok === undefined\n ? 0\n : Math.max(\n 0,\n (aggregate.write5mTokens / 1e6) * (price.cacheWrite5mPerMTok - price.inputPerMTok),\n );\n const premium1h =\n price.cacheWrite1hPerMTok === undefined\n ? 0\n : Math.max(\n 0,\n (aggregate.write1hTokens / 1e6) * (price.cacheWrite1hPerMTok - price.inputPerMTok),\n );\n writeSpendUsd = premium5m + premium1h;\n }\n\n return {\n prefixKey: key,\n calls: aggregate.calls,\n hitRatio,\n readTokens: aggregate.readTokens,\n writeTokens,\n uncachedTokens: aggregate.uncachedTokens,\n ...(savedUsd !== undefined ? { savedUsd } : {}),\n ...(writeSpendUsd !== undefined ? { writeSpendUsd } : {}),\n };\n }\n}\n","/**\n * Deterministic, non-cryptographic hashing primitives for RACS (Remote Agent Context\n * Store): prefix keys, combined keys, and seeded short identifiers.\n *\n * Everything here is pure, allocation-light, dependency-free, and runs identically in\n * browsers, edge runtimes, workers, and Node. No randomness, no clock, no platform globals.\n *\n * Security stance: FNV-1a is NOT a cryptographic hash. It is trivially invertible and\n * collision-constructible by an adversary, so values produced by this module must never\n * gate a security decision (authentication, authorization, integrity verification). They\n * exist solely to give byte-equal inputs equal keys for cache bookkeeping.\n *\n * @packageDocumentation\n */\n\n/**\n * FNV-1a 64-bit offset basis and prime, per the reference parameters published by\n * Fowler, Noll, and Vo (http://www.isthe.com/chongo/tech/comp/fnv/, retrieved June 2026).\n */\nconst FNV_OFFSET_BASIS = 0xcbf29ce484222325n;\nconst FNV_PRIME = 0x100000001b3n;\nconst MASK_64 = 0xffffffffffffffffn;\n\n/**\n * Joins key parts with the ASCII unit separator (U+001F). Hex output is confined to\n * `[0-9a-f]`, so the separator can never occur inside a hash and joined keys cannot\n * collide by concatenation ambiguity (\"ab\" + \"c\" versus \"a\" + \"bc\").\n */\nconst KEY_SEPARATOR = '\\u001f';\n\n/**\n * Core FNV-1a 64-bit loop over the UTF-16 code units of `text`, two bytes per unit, low\n * byte first. Hashing code units directly, instead of UTF-8 bytes, keeps the function free\n * of any encoder dependency and free of per-call allocations, at the cost of producing\n * digests that differ from byte-wise UTF-8 FNV implementations. That is fine: these\n * digests are compared only against other digests produced by this same function.\n */\nfunction fnv1a64Value(text: string): bigint {\n let hash = FNV_OFFSET_BASIS;\n for (let index = 0; index < text.length; index += 1) {\n const unit = text.charCodeAt(index);\n hash ^= BigInt(unit & 0xff);\n hash = (hash * FNV_PRIME) & MASK_64;\n hash ^= BigInt(unit >>> 8);\n hash = (hash * FNV_PRIME) & MASK_64;\n }\n return hash;\n}\n\n/**\n * Hashes `text` with FNV-1a 64-bit over its UTF-16 code units (two bytes per code unit,\n * low byte first) and returns the digest as a fixed-width 16-character lowercase hex\n * string.\n *\n * Determinism: pure function of the input, identical across runtimes and runs.\n *\n * Collision odds, non-adversarial inputs: with a 64-bit digest the birthday bound puts the\n * probability of any collision among n distinct inputs at roughly n^2 / 2^65, about 1 in\n * 37 million for one million distinct prefixes, reaching 50 percent only near 5 billion\n * inputs. Acceptable for cache-key bookkeeping, where a collision costs at worst one\n * misattributed statistic, never a wrong answer to the host.\n *\n * Non-cryptographic: an adversary can construct collisions at will. Never use the result\n * for security decisions, see the module-level security stance.\n *\n * @param text - The string to hash, hashed as-is with no normalization.\n * @returns 16 lowercase hex characters, zero-padded, for example '0a1b2c3d4e5f6789'.\n */\nexport function fnv1a64(text: string): string {\n return fnv1a64Value(text).toString(16).padStart(16, '0');\n}\n\n/**\n * Derives one key from several parts by joining them with a separator that cannot appear\n * in hex output (U+001F) and hashing the joined string with {@link fnv1a64}.\n *\n * The separator guarantees that part boundaries contribute to the digest, so\n * `combineKeys(['ab', 'c'])` and `combineKeys(['a', 'bc'])` differ even though their\n * concatenations are equal. Used to fuse segment hashes, provider, model, and agent\n * identity into one prefix key.\n *\n * Same non-cryptographic caveats and collision odds as {@link fnv1a64}.\n *\n * @param parts - Key components in significance order, empty parts are preserved.\n * @returns 16 lowercase hex characters identifying the part sequence.\n */\nexport function combineKeys(parts: readonly string[]): string {\n return fnv1a64(parts.join(KEY_SEPARATOR));\n}\n\n/**\n * Produces a deterministic short identifier from a seeded counter and a salt: the FNV-1a\n * 64-bit digest of `salt`, the separator, and the counter rendered in decimal, encoded in\n * base36. Same counter and salt always yield the same id, which is how plan ids stay\n * reproducible under {@link https://www.npmjs.com/package/@takk/racs | RACS}'s\n * never-call-the-global-random-generator rule.\n *\n * Output is 1 to 13 lowercase base36 characters (a 64-bit value needs at most 13 digits\n * in base36), typically 13.\n *\n * Non-cryptographic and predictable by design: anyone knowing the salt and counter can\n * recompute the id. Never use it as a secret, a session token, or any security-relevant\n * value. Collision odds follow {@link fnv1a64}.\n *\n * @param seededCounter - Monotonic counter from the engine's seeded id generator.\n * @param salt - Stable namespace string, for example the engine seed rendered as text.\n * @returns Deterministic base36 identifier, for example '2kgal12c8744o'.\n */\nexport function shortId(seededCounter: number, salt: string): string {\n return fnv1a64Value(`${salt}${KEY_SEPARATOR}${String(seededCounter)}`).toString(36);\n}\n","/**\n * Token estimation helpers for RACS (Remote Agent Context Store).\n *\n * Estimates exist to gate minimum-token planning decisions (is this prefix long enough to\n * cache at all, does the write premium pay back), never to bill anyone. Exact counts come\n * from provider usage reports recorded after the fact, and callers with a real tokenizer\n * should pass explicit token counts, which always win, see {@link tokensOf}.\n *\n * Pure module: no dependencies, no randomness, no clock, runs everywhere.\n *\n * @packageDocumentation\n */\n\n/**\n * Characters per token in the industry rule-of-thumb heuristic for English-leaning text,\n * \"1 token ~= 4 characters\" as published in OpenAI's tokenizer guidance and echoed across\n * provider documentation (retrieved June 2026). Real ratios vary by language, code\n * density, and tokenizer, which is why this number only feeds planning thresholds.\n */\nconst CHARS_PER_TOKEN = 4;\n\n/**\n * Estimates the token count of `content` as the ceiling of its UTF-16 length divided by\n * 4, the industry characters-per-token heuristic (see {@link CHARS_PER_TOKEN}).\n *\n * Accuracy contract: this is a planning estimate, not a measurement. It is typically\n * within tens of percent for English prose and can be off by more for CJK text or dense\n * code. Exact counts come from provider usage reports; estimates only gate minimum-token\n * planning such as the `'below-minimum'` lint and break-even math. Pass exact counts from\n * a provider tokenizer whenever precision matters.\n *\n * @param content - The text to estimate, measured by UTF-16 length, no normalization.\n * @returns Non-negative integer estimate, 0 for the empty string.\n */\nexport function estimateTokens(content: string): number {\n return Math.ceil(content.length / CHARS_PER_TOKEN);\n}\n\n/**\n * Resolves the token count of one segment-shaped value, preferring an explicit `tokens`\n * field over the {@link estimateTokens} heuristic on `content`.\n *\n * Resolution order:\n * 1. `tokens` when present, the caller measured it with a real tokenizer, trust it.\n * 2. `estimateTokens(content)` when only `content` is present.\n * 3. 0 when neither is present, which is the hash-only privacy mode without a declared\n * count: the segment deliberately contributes nothing to break-even math.\n *\n * @param segment - Any object carrying optional `content` and `tokens` fields.\n * @returns Explicit count, estimate, or 0, in that order of preference.\n */\nexport function tokensOf(segment: { content?: string; tokens?: number }): number {\n if (typeof segment.tokens === 'number') {\n return segment.tokens;\n }\n if (typeof segment.content === 'string') {\n return estimateTokens(segment.content);\n }\n return 0;\n}\n","/**\n * The directive planner of RACS (Remote Agent Context Store).\n *\n * One pure class maps an analyzed prompt onto the cache-control surface of one provider\n * family: explicit breakpoints, routing keys, server-side cache resources, or a reasoned\n * no-op for passive providers. The planner is deterministic and stateless, it reads no\n * clock and no random source, so identical inputs always yield identical directives. The\n * engine core owns fingerprinting, drift tracking, refresh timing, and telemetry.\n *\n * @packageDocumentation\n */\n\nimport { combineKeys } from '../stats/hash.js';\nimport { tokensOf } from '../stats/tokens.js';\nimport type {\n BreakEven,\n CacheDirective,\n CacheTtl,\n LintFinding,\n PlanInput,\n Pricing,\n PromptSegment,\n ProviderProfile,\n SegmentRole,\n} from '../types.js';\n\n/**\n * Aggregates the analysis stage computed once, so the planner never recounts the prompt.\n */\nexport interface PlanAnalysis {\n /** Findings the lint pass produced, context the planner extends through extraFindings. */\n findings: LintFinding[];\n /** Token count of the cacheable stable prefix, exact or estimated per segment rules. */\n stableTokens: number;\n /** Token count of the whole prompt, same exact-or-estimated provenance. */\n totalTokens: number;\n /**\n * Count of leading segments, in request order, forming the left-anchored cacheable\n * prefix. Prefix caches reuse nothing past this boundary on any provider family.\n */\n orderedStableBoundary: number;\n}\n\n/**\n * The planner's contribution to one cache plan, merged by the engine core with the plan\n * identity, the fingerprints, and the analysis findings.\n */\nexport interface PlannerResult {\n /** Provider-faithful instructions in application order. */\n directives: CacheDirective[];\n /** Cache economics, present when profile multipliers or pricing allow computing them. */\n breakEven?: BreakEven;\n /** One dense human-readable sentence per planning decision. */\n reasoning: string;\n /** Findings only the planning stage can detect, appended to the analysis findings. */\n extraFindings: LintFinding[];\n}\n\n/**\n * Breakpoint selection priority per segment role. Anthropic hashes the request prefix as\n * tools, then system, then messages (Anthropic prompt caching docs, June 2026), and Amazon\n * Bedrock `cachePoint` follows the same request anatomy (AWS Bedrock prompt caching docs,\n * June 2026), so a marker after each large stable region in that order preserves partial\n * reuse when a later region drifts.\n */\nconst ROLE_WEIGHT: Readonly<Record<SegmentRole, number>> = {\n tools: 4,\n system: 3,\n documents: 2,\n history: 1,\n dynamic: 0,\n};\n\n/** Window lengths of the two breakpoint-family TTL tiers, see {@link CacheTtl}. */\nconst TTL_SECONDS: Readonly<Record<CacheTtl, number>> = { '5m': 300, '1h': 3600 };\n\n/**\n * Reuse-interval ceilings for TTL tier choice. The two-tier 5-minute and 1-hour model is\n * the breakpoint-family standard as of June 2026 (Anthropic prompt caching docs). The\n * ceilings keep 60s and 300s of refresh headroom under the 300s and 3600s windows, so a\n * keep-warm touch scheduled at 90 percent of the TTL still lands before expiry despite\n * timer jitter.\n */\nconst FIVE_MINUTE_INTERVAL_CEILING = 240;\nconst ONE_HOUR_INTERVAL_CEILING = 3300;\n\n/**\n * Resource-family TTL bounds. Google Gemini `cachedContents` defaults to a 3600 second TTL\n * and bills storage per token-hour while the resource stays alive (Google Gemini API\n * caching docs, June 2026).\n */\nconst RESOURCE_TTL_MIN_SECONDS = 300;\nconst RESOURCE_TTL_DEFAULT_SECONDS = 3600;\n\n/** Formats counts for reasoning prose without dragging float noise into the sentence. */\nconst formatCount = (value: number): string =>\n Number.isInteger(value) ? value.toString() : value.toFixed(2);\n\n/** Formats small USD amounts for reasoning prose at three significant digits. */\nconst formatUsd = (value: number): string => `${value.toPrecision(3)} USD`;\n\n/**\n * Effective seconds between calls sharing this prefix. Per the {@link PlanInput} contract\n * `intervalSeconds` wins over `callsPerHour` when both are present.\n */\nconst intervalSecondsOf = (input: PlanInput): number | undefined => {\n const reuse = input.reuse;\n if (reuse === undefined) {\n return undefined;\n }\n if (reuse.intervalSeconds !== undefined) {\n return reuse.intervalSeconds;\n }\n if (reuse.callsPerHour !== undefined && reuse.callsPerHour > 0) {\n return 3600 / reuse.callsPerHour;\n }\n return undefined;\n};\n\n/** Effective calls per hour, the demand side of every break-even comparison. */\nconst callsPerHourOf = (input: PlanInput): number | undefined => {\n const reuse = input.reuse;\n if (reuse === undefined) {\n return undefined;\n }\n if (reuse.intervalSeconds !== undefined && reuse.intervalSeconds > 0) {\n return 3600 / reuse.intervalSeconds;\n }\n if (reuse.callsPerHour !== undefined) {\n return reuse.callsPerHour;\n }\n return undefined;\n};\n\n/**\n * Write multiplier for the chosen tier, from the profile when it carries one, otherwise\n * derived from the pricing table. Multipliers are price-relative, so pricing is optional.\n */\nconst writeMultiplierFor = (\n ttl: CacheTtl,\n profile: ProviderProfile,\n pricing?: Pricing,\n): number | undefined => {\n const fromProfile = ttl === '1h' ? profile.writeMultiplier1h : profile.writeMultiplier5m;\n if (fromProfile !== undefined) {\n return fromProfile;\n }\n if (pricing !== undefined && pricing.inputPerMTok > 0) {\n const writePrice = ttl === '1h' ? pricing.cacheWrite1hPerMTok : pricing.cacheWrite5mPerMTok;\n if (writePrice !== undefined) {\n return writePrice / pricing.inputPerMTok;\n }\n }\n return undefined;\n};\n\n/** Read multiplier, profile first, pricing-derived second, same rationale as above. */\nconst readMultiplierFor = (profile: ProviderProfile, pricing?: Pricing): number | undefined => {\n if (profile.readMultiplier !== undefined) {\n return profile.readMultiplier;\n }\n if (pricing !== undefined && pricing.inputPerMTok > 0 && pricing.cacheReadPerMTok !== undefined) {\n return pricing.cacheReadPerMTok / pricing.inputPerMTok;\n }\n return undefined;\n};\n\n/** One contiguous run of same-role non-volatile segments inside the cacheable prefix. */\ninterface StableSpan {\n readonly role: SegmentRole;\n readonly tokens: number;\n readonly endSegmentId: string;\n readonly endIndex: number;\n}\n\n/**\n * Groups the left-anchored cacheable prefix into role spans. Iteration stops at the first\n * volatile segment because prefix caches are strictly left-anchored, nothing written past\n * a volatile span could ever be read back.\n */\nconst stableSpansOf = (segments: readonly PromptSegment[], boundary: number): StableSpan[] => {\n const spans: StableSpan[] = [];\n let open: StableSpan | undefined;\n const limit = Math.min(boundary, segments.length);\n for (let index = 0; index < limit; index += 1) {\n const segment = segments[index];\n if (segment === undefined || segment.stability === 'volatile') {\n break;\n }\n const tokens = tokensOf(segment);\n if (open !== undefined && open.role === segment.role) {\n open = {\n role: open.role,\n tokens: open.tokens + tokens,\n endSegmentId: segment.id,\n endIndex: index,\n };\n } else {\n if (open !== undefined) {\n spans.push(open);\n }\n open = { role: segment.role, tokens, endSegmentId: segment.id, endIndex: index };\n }\n }\n if (open !== undefined) {\n spans.push(open);\n }\n return spans;\n};\n\n/**\n * Break-even economics for the breakpoint family inside the TTL window, stated in\n * base-input-token equivalents because the multipliers are price-relative, which is\n * exactly why pricing stays optional.\n *\n * Reuse model, refresh-on-use: breakpoint providers refresh the cache TTL at no\n * additional cost every time the cached content is read (Anthropic prompt caching\n * documentation, \"the cache TTL is refreshed each time the cached content is used\",\n * retrieved June 2026). When the declared reuse interval fits inside the TTL window the\n * entry therefore survives indefinitely under steady traffic: the write premium is paid\n * once, every read recovers `coveredTokens * (1 - readMultiplier)`, and the\n * `minReusesToProfit`-th repaying read always arrives, so profitability reduces to each\n * read actually saving, that is `readMultiplier < 1`. `expectedReuses` is reported over a\n * one-hour horizon as `max(1, round(callsPerHour))` in the reasoning prose. Without a\n * declared reuse pattern (`callsPerHour` undefined) a single reuse is assumed and\n * profitability compares it to `minReusesToProfit`, because no traffic statement exists\n * for the survival argument to lean on.\n *\n * @param coveredTokens - Tokens actually covered up to the last placed marker, the span\n * the write premium is paid on, see the coverage computation in the breakpoint planner.\n */\nconst breakpointBreakEven = (\n coveredTokens: number,\n ttl: CacheTtl,\n callsPerHour: number | undefined,\n profile: ProviderProfile,\n pricing?: Pricing,\n): BreakEven | undefined => {\n const writeMultiplier = writeMultiplierFor(ttl, profile, pricing);\n const readMultiplier = readMultiplierFor(profile, pricing);\n if (writeMultiplier === undefined || readMultiplier === undefined) {\n return undefined;\n }\n const writePremiumTokens = Math.max(0, coveredTokens * (writeMultiplier - 1));\n const savingsPerReuse = coveredTokens * (1 - readMultiplier);\n const minReusesToProfit =\n savingsPerReuse > 0\n ? Math.ceil(writePremiumTokens / savingsPerReuse)\n : Number.POSITIVE_INFINITY;\n if (callsPerHour === undefined) {\n const profitable = 1 >= minReusesToProfit;\n const reasoning = `The ${ttl} write multiplier ${formatCount(writeMultiplier)} prices the premium at ${formatCount(writePremiumTokens)} base-token equivalents, each reuse at read multiplier ${formatCount(readMultiplier)} recovers ${formatCount(savingsPerReuse)}, so ${formatCount(minReusesToProfit)} reuse(s) repay the write against the single assumed reuse (no reuse pattern was declared; multipliers are price-relative, the math holds with or without a pricing table), ${profitable ? 'profitable' : 'not profitable'}.`;\n return { writePremiumTokens, minReusesToProfit, profitable, reasoning };\n }\n const expectedReuses = Math.max(1, Math.round(callsPerHour));\n const profitable = Number.isFinite(minReusesToProfit);\n const reasoning = `The ${ttl} write multiplier ${formatCount(writeMultiplier)} prices the premium at ${formatCount(writePremiumTokens)} base-token equivalents, each reuse at read multiplier ${formatCount(readMultiplier)} recovers ${formatCount(savingsPerReuse)}, so ${formatCount(minReusesToProfit)} reuse(s) repay the single write; reads refresh the ${ttl} window at no extra cost (refresh-on-use), steady declared reuse keeps the entry alive indefinitely at about ${formatCount(expectedReuses)} reuse(s) per hour (multipliers are price-relative, the math holds with or without a pricing table), ${profitable ? 'profitable' : 'not profitable'}.`;\n return { writePremiumTokens, minReusesToProfit, profitable, reasoning };\n};\n\n/**\n * Break-even economics for the keep-warm band, the SAME touch-cost model that justifies\n * keeping the tier, so the branch reasoning and the break-even verdict can never\n * contradict each other.\n *\n * Model: when the reuse interval outruns the widest TTL window, scheduled refresh touches\n * at 90 percent of the TTL keep the entry alive at read price (refresh-on-use, Anthropic\n * prompt caching documentation, June 2026). Each real reuse recovers\n * `coveredTokens * (1 - r)` and carries `refreshesPerHour / callsPerHour` touches costing\n * `coveredTokens * r` each, so the net per reuse is the savings minus the touch share,\n * and the single write premium is repaid after `ceil(premium / net)` reuses. The\n * keep-warm branch is entered only when the net is strictly positive, so a kept tier is\n * always profitable here; a non-positive net never reaches this function because the\n * planner declines the tier instead.\n */\nconst keepWarmBreakEven = (\n coveredTokens: number,\n ttl: CacheTtl,\n callsPerHour: number,\n refreshesPerHour: number,\n readMultiplier: number,\n profile: ProviderProfile,\n pricing?: Pricing,\n): BreakEven | undefined => {\n const writeMultiplier = writeMultiplierFor(ttl, profile, pricing);\n if (writeMultiplier === undefined || callsPerHour <= 0) {\n return undefined;\n }\n const writePremiumTokens = Math.max(0, coveredTokens * (writeMultiplier - 1));\n const savingsPerReuse = coveredTokens * (1 - readMultiplier);\n const touchCostPerReuse = (refreshesPerHour / callsPerHour) * coveredTokens * readMultiplier;\n const netPerReuse = savingsPerReuse - touchCostPerReuse;\n const profitable = netPerReuse > 0;\n const minReusesToProfit = profitable\n ? Math.ceil(writePremiumTokens / netPerReuse)\n : Number.POSITIVE_INFINITY;\n const reasoning = `Keep-warm economics: each reuse recovers ${formatCount(savingsPerReuse)} base-token equivalents and carries ${formatCount(touchCostPerReuse)} of scheduled refresh touches (${formatCount(refreshesPerHour)} touch(es) per hour at read multiplier ${formatCount(readMultiplier)} spread over ${formatCount(callsPerHour)} call(s) per hour), netting ${formatCount(netPerReuse)}, so the single ${ttl} write premium of ${formatCount(writePremiumTokens)} is repaid after ${formatCount(minReusesToProfit)} reuse(s), ${profitable ? 'profitable' : 'not profitable'}.`;\n return { writePremiumTokens, minReusesToProfit, profitable, reasoning };\n};\n\n/**\n * Storage economics for the resource family: storage cost per hour versus read savings per\n * call times calls per hour. USD-denominated because per-token-hour storage has no\n * price-relative form, so this needs the pricing table to exist.\n */\nconst resourceBreakEven = (\n stableTokens: number,\n callsPerHour: number,\n profile: ProviderProfile,\n pricing?: Pricing,\n): BreakEven | undefined => {\n const storagePerMTokHour = pricing?.storagePerMTokHour ?? profile.storagePerMTokHour;\n if (storagePerMTokHour === undefined || pricing === undefined || pricing.inputPerMTok <= 0) {\n return undefined;\n }\n const readPerMTok =\n pricing.cacheReadPerMTok ??\n (profile.readMultiplier === undefined\n ? undefined\n : pricing.inputPerMTok * profile.readMultiplier);\n if (readPerMTok === undefined) {\n return undefined;\n }\n const savingsPerCallUsd = (stableTokens / 1_000_000) * (pricing.inputPerMTok - readPerMTok);\n if (savingsPerCallUsd <= 0) {\n return undefined;\n }\n const storagePerHourUsd = (stableTokens / 1_000_000) * storagePerMTokHour;\n const writePremiumTokens = (storagePerHourUsd / pricing.inputPerMTok) * 1_000_000;\n const minReusesToProfit = Math.ceil(storagePerHourUsd / savingsPerCallUsd);\n const profitable = callsPerHour >= minReusesToProfit;\n const reasoning = `Keeping ${formatCount(stableTokens)} tokens resident bills ${formatUsd(storagePerHourUsd)} per hour of storage (${formatCount(writePremiumTokens)} base-token equivalents), each cached read saves ${formatUsd(savingsPerCallUsd)}, so ${formatCount(minReusesToProfit)} reuse(s) per hour break even against ${formatCount(callsPerHour)} expected, ${profitable ? 'profitable' : 'not profitable'}.`;\n return { writePremiumTokens, minReusesToProfit, profitable, reasoning };\n};\n\n/**\n * Maps one analyzed prompt to provider-faithful cache directives, per adapter family.\n *\n * Family semantics implemented here are research snapshots of June 2026, sources cited on\n * the constants above, and every number flows from the {@link ProviderProfile}, so a\n * profile override updates the planner without a release.\n */\nexport class Planner {\n /**\n * Produces directives, break-even economics, and planner-stage findings for one input.\n *\n * @param input - The prompt being planned, segments in request order.\n * @param profile - Effective provider profile, overrides already merged by the core.\n * @param analysis - Aggregates the analysis stage computed, see {@link PlanAnalysis}.\n * @param prefixKey - Deterministic key of the stable prefix, computed by the core.\n * @param pricing - Optional model price card, refines multipliers and storage math.\n * @param knownResource - Resource family only: whether the core already tracks a live\n * cache resource for this prefix. First sight emits `'create'`, later sights `'reuse'`,\n * and the core swaps `'reuse'` for `'refresh'` when its clock sits inside the last 10\n * percent of the TTL window, the planner emits the shape, the core decides the timing.\n */\n plan(\n input: PlanInput,\n profile: ProviderProfile,\n analysis: PlanAnalysis,\n prefixKey: string,\n pricing?: Pricing,\n knownResource = false,\n ): PlannerResult {\n const result = this.planFamily(input, profile, analysis, prefixKey, pricing, knownResource);\n if (profile.notes !== undefined && profile.notes !== '') {\n return { ...result, reasoning: `${result.reasoning} Provider note: ${profile.notes}` };\n }\n return result;\n }\n\n private planFamily(\n input: PlanInput,\n profile: ProviderProfile,\n analysis: PlanAnalysis,\n prefixKey: string,\n pricing: Pricing | undefined,\n knownResource: boolean,\n ): PlannerResult {\n switch (profile.family) {\n case 'breakpoint':\n return this.planBreakpoint(input, profile, analysis, pricing);\n case 'routing-key':\n return this.planRoutingKey(input, profile, analysis, prefixKey);\n case 'resource':\n return this.planResource(input, profile, analysis, prefixKey, knownResource, pricing);\n default:\n // 'passive' and any family a newer minor may add degrade to the no-op family.\n return this.planPassive(profile);\n }\n }\n\n /**\n * Breakpoint family (anthropic, bedrock, hermes, microsoft-foundry): explicit markers,\n * one TTL tier chosen from the declared reuse. The deepest stable boundary is always\n * marked because the last marker determines left-anchored coverage, remaining budget\n * goes to the largest stable spans by role weight. Economics follow the refresh-on-use\n * model documented on {@link breakpointBreakEven} inside the TTL window and the\n * touch-cost model on {@link keepWarmBreakEven} beyond it; when neither sustains the\n * cache the planner declines with a reasoned `'none'` plus a `'write-premium-trap'`\n * finding, so an emitted breakpoint plan is never knowingly unprofitable.\n */\n private planBreakpoint(\n input: PlanInput,\n profile: ProviderProfile,\n analysis: PlanAnalysis,\n pricing?: Pricing,\n ): PlannerResult {\n const extraFindings: LintFinding[] = [];\n const minCacheable = profile.minCacheableTokens ?? 0;\n if (analysis.stableTokens < minCacheable) {\n return {\n directives: [\n {\n kind: 'none',\n reason: `stable prefix is ${formatCount(analysis.stableTokens)} tokens, below the provider minimum of ${formatCount(minCacheable)}, the provider would silently cache nothing`,\n },\n ],\n reasoning: `Skipped caching because the ${formatCount(analysis.stableTokens)}-token stable prefix sits below the ${formatCount(minCacheable)}-token provider minimum, a marker there would buy nothing.`,\n extraFindings,\n };\n }\n\n const spans = stableSpansOf(input.segments, analysis.orderedStableBoundary);\n const deepest = spans[spans.length - 1];\n if (deepest === undefined) {\n const first = input.segments[0];\n if (first !== undefined && first.stability === 'volatile') {\n extraFindings.push({\n severity: 'error',\n code: 'breakpoint-after-volatile',\n segmentId: first.id,\n message: `the only breakpoint candidate follows volatile segment '${first.id}', a span written there could never be read back; move volatile content after the stable prefix`,\n });\n return {\n directives: [\n {\n kind: 'none',\n reason:\n 'every breakpoint candidate sits after a volatile segment, a written span could never be read back',\n },\n ],\n reasoning:\n 'Refused to place a breakpoint after a volatile segment, the written span could never be read back, so the write premium would be pure loss.',\n extraFindings,\n };\n }\n return {\n directives: [\n { kind: 'none', reason: 'no left-anchored stable prefix exists to mark for caching' },\n ],\n reasoning: 'Skipped caching, the prompt carries no left-anchored stable prefix to mark.',\n extraFindings,\n };\n }\n\n const budget = profile.maxBreakpoints ?? 1;\n if (budget <= 0) {\n return {\n directives: [\n { kind: 'none', reason: 'the provider profile allows zero cache breakpoints' },\n ],\n reasoning: 'Skipped caching, the effective profile grants no breakpoint slots.',\n extraFindings,\n };\n }\n\n const sentences: string[] = [];\n const interval = intervalSecondsOf(input);\n const callsPerHour = callsPerHourOf(input);\n const tiers: readonly CacheTtl[] = profile.ttls ?? ['5m'];\n const supports1h = tiers.includes('1h');\n let ttl: CacheTtl;\n let keepWarm: { refreshesPerHour: number; readMultiplier: number } | undefined;\n if (interval === undefined) {\n ttl = tiers.includes('5m') || !supports1h ? '5m' : '1h';\n sentences.push(\n `No reuse pattern was declared, defaulting to the ${ttl} tier, the lowest write premium the profile offers, with a single assumed reuse for break-even.`,\n );\n } else if (interval <= FIVE_MINUTE_INTERVAL_CEILING && tiers.includes('5m')) {\n ttl = '5m';\n sentences.push(\n `Reuse every ${formatCount(interval)}s fits the 5m tier with ${formatCount(TTL_SECONDS['5m'] - interval)}s of refresh headroom before the 300s window closes, and every read refreshes the window at no cost.`,\n );\n } else if (interval <= ONE_HOUR_INTERVAL_CEILING && supports1h) {\n ttl = '1h';\n sentences.push(\n `Reuse every ${formatCount(interval)}s overruns the 5m tier, the 1h tier holds it with ${formatCount(TTL_SECONDS['1h'] - interval)}s of refresh headroom under the 3600s window, and every read refreshes the window at no cost.`,\n );\n } else {\n const widest: CacheTtl = supports1h ? '1h' : '5m';\n const refreshesPerHour = 3600 / TTL_SECONDS[widest];\n const readMultiplier = readMultiplierFor(profile, pricing);\n // Decline at equality too: a net of exactly zero never repays the write premium,\n // and a kept tier must always be repayable, see keepWarmBreakEven.\n if (\n callsPerHour === undefined ||\n readMultiplier === undefined ||\n readMultiplier >= 1 ||\n callsPerHour * (1 - readMultiplier) <= refreshesPerHour * readMultiplier\n ) {\n extraFindings.push({\n severity: 'warning',\n code: 'write-premium-trap',\n message: `the declared reuse every ${formatCount(interval)}s outruns the widest ${widest} window and the traffic cannot cover keep-warm touches, so the write premium on ${formatCount(analysis.stableTokens)} stable tokens would never be repaid; raise reuse density or skip caching`,\n });\n return {\n directives: [\n {\n kind: 'none',\n reason: 'reuse interval exceeds provider TTL, caching would re-write every call',\n },\n ],\n reasoning: `Reuse every ${formatCount(interval)}s exceeds what the widest ${widest} window holds with refresh headroom, every call would pay the write premium again, so no marker is placed.`,\n extraFindings,\n };\n }\n ttl = widest;\n keepWarm = { refreshesPerHour, readMultiplier };\n sentences.push(\n `Reuse every ${formatCount(interval)}s exceeds the ${widest} window, but ${formatCount(callsPerHour)} calls per hour against ${formatCount(refreshesPerHour)} keep-warm touches per hour at read multiplier ${formatCount(readMultiplier)} keep refresh-keeping profitable, so the ${widest} tier stays on with touches scheduled at 90 percent of the TTL.`,\n );\n }\n\n // The deepest stable boundary is ALWAYS marked: the last marker determines the\n // left-anchored coverage, so dropping the final span by role weight would silently\n // shrink what the plan claims to cache. Remaining slots go to the largest stable\n // spans by role weight for partial-reuse protection when a later region drifts.\n const ranked = [...spans.slice(0, -1)].sort((a, b) => {\n const byWeight = ROLE_WEIGHT[b.role] - ROLE_WEIGHT[a.role];\n if (byWeight !== 0) {\n return byWeight;\n }\n if (b.tokens !== a.tokens) {\n return b.tokens - a.tokens;\n }\n return a.endIndex - b.endIndex;\n });\n const chosen = [deepest, ...ranked.slice(0, Math.max(0, budget - 1))].sort(\n (a, b) => a.endIndex - b.endIndex,\n );\n const directives: CacheDirective[] = chosen.map((span) => ({\n kind: 'breakpoint',\n segmentId: span.endSegmentId,\n ttl,\n }));\n // Coverage is left-anchored and runs to the LAST chosen marker, which is the forced\n // deepest boundary, so every stable span at or before it counts as covered.\n const lastChosen = chosen[chosen.length - 1] ?? deepest;\n let coveredTokens = 0;\n for (const span of spans) {\n if (span.endIndex <= lastChosen.endIndex) {\n coveredTokens += span.tokens;\n }\n }\n const placement = chosen\n .map(\n (span) =>\n `${span.role} ending at '${span.endSegmentId}', ${formatCount(span.tokens)} tokens`,\n )\n .join('; ');\n sentences.push(\n `Placed ${formatCount(directives.length)} of ${formatCount(budget)} allowed breakpoints: the deepest stable boundary '${deepest.endSegmentId}' is always marked because the last marker determines left-anchored coverage, and the remaining slots go to the largest stable spans weighted tools over system over documents over history (${placement}) because the provider hashes tools, then system, then messages, so each extra marker preserves partial reuse when a later region drifts, covering ${formatCount(coveredTokens)} of ${formatCount(analysis.totalTokens)} prompt tokens.`,\n );\n\n const breakEven =\n keepWarm !== undefined && callsPerHour !== undefined\n ? keepWarmBreakEven(\n coveredTokens,\n ttl,\n callsPerHour,\n keepWarm.refreshesPerHour,\n keepWarm.readMultiplier,\n profile,\n pricing,\n )\n : breakpointBreakEven(\n coveredTokens,\n ttl,\n interval === undefined ? undefined : callsPerHour,\n profile,\n pricing,\n );\n if (breakEven !== undefined) {\n sentences.push(breakEven.reasoning);\n if (!breakEven.profitable) {\n extraFindings.push({\n severity: 'warning',\n code: 'write-premium-trap',\n message: `expected reuse inside the ${ttl} window does not repay the cache write premium on ${formatCount(coveredTokens)} covered stable tokens; raise reuse density, choose a longer TTL tier, or skip caching`,\n });\n }\n }\n\n return {\n directives,\n ...(breakEven !== undefined ? { breakEven } : {}),\n reasoning: sentences.join(' '),\n extraFindings,\n };\n }\n\n /**\n * Routing-key family (openai, xai, mistral, moonshot, openrouter): the provider caches\n * implicitly, the key only steers identical prefixes to the same cache shard, and the\n * extended 24-hour retention tier rides along when supported and the reuse is sparse\n * (OpenAI `prompt_cache_key` retention as of June 2026).\n */\n private planRoutingKey(\n input: PlanInput,\n profile: ProviderProfile,\n analysis: PlanAnalysis,\n prefixKey: string,\n ): PlannerResult {\n const interval = intervalSecondsOf(input);\n const wantsRetention =\n profile.supportsRetention === true && interval !== undefined && interval > 3600;\n const directives: CacheDirective[] = [\n {\n kind: 'routing-key',\n key: prefixKey,\n ...(wantsRetention ? { retention: '24h' as const } : {}),\n },\n ];\n const retentionNote =\n wantsRetention && interval !== undefined\n ? `, and reuse every ${formatCount(interval)}s outlives the default cache window, so the 24h retention tier is requested behind the key`\n : '';\n return {\n directives,\n reasoning: `${profile.id} caches prefixes automatically on the server, the routing key only pins the ${formatCount(analysis.stableTokens)}-token stable prefix of ${formatCount(analysis.totalTokens)} prompt tokens to one cache shard, so keeping that prefix byte-stable is the real lever${retentionNote}.`,\n extraFindings: [],\n };\n }\n\n /**\n * Resource family (google): the cache is a server resource the host creates, reuses,\n * refreshes, and deletes, billed per token-hour of storage while it stays alive.\n */\n private planResource(\n input: PlanInput,\n profile: ProviderProfile,\n analysis: PlanAnalysis,\n prefixKey: string,\n knownResource: boolean,\n pricing?: Pricing,\n ): PlannerResult {\n const extraFindings: LintFinding[] = [];\n const interval = intervalSecondsOf(input);\n const ttlSeconds =\n interval === undefined\n ? RESOURCE_TTL_DEFAULT_SECONDS\n : Math.min(RESOURCE_TTL_DEFAULT_SECONDS, Math.max(RESOURCE_TTL_MIN_SECONDS, interval * 4));\n // Guards untyped callers handing an empty prefix key, the directive shape stays valid\n // and deterministic by deriving identity from the same lineage fields the core uses.\n const resourceKey =\n prefixKey !== ''\n ? prefixKey\n : combineKeys([input.provider, input.model, input.agentId ?? '']);\n const callsPerHour = callsPerHourOf(input) ?? 1;\n const breakEven = resourceBreakEven(analysis.stableTokens, callsPerHour, profile, pricing);\n if (callsPerHour < 1) {\n extraFindings.push({\n severity: 'warning',\n code: 'write-premium-trap',\n message: `the storage trap: at ${formatCount(callsPerHour)} reuses per hour, per-token-hour storage on ${formatCount(analysis.stableTokens)} resident tokens outruns the read savings; raise reuse density or rely on implicit provider caching`,\n });\n return {\n directives: [\n {\n kind: 'none',\n reason:\n 'below one reuse per hour the per-token-hour storage bill outruns the read savings, the storage trap, so no cache resource is worth keeping alive',\n },\n ],\n ...(breakEven !== undefined ? { breakEven } : {}),\n reasoning: `Skipped the cache resource because ${formatCount(callsPerHour)} reuses per hour cannot cover storage billed for every hour the resource stays alive, the classic resource-family storage trap.`,\n extraFindings,\n };\n }\n const action: 'create' | 'reuse' = knownResource ? 'reuse' : 'create';\n const directives: CacheDirective[] = [{ kind: 'resource', action, resourceKey, ttlSeconds }];\n const sentences: string[] = [\n `${action === 'create' ? 'Creating' : 'Reusing'} the server-side cache resource for this prefix with a ${formatCount(ttlSeconds)}s TTL, four times the ${interval === undefined ? 'default-assumed' : `${formatCount(interval)}s`} reuse interval clamped to [${formatCount(RESOURCE_TTL_MIN_SECONDS)}, ${formatCount(RESOURCE_TTL_DEFAULT_SECONDS)}], and the core swaps reuse for refresh inside the last 10 percent of that window.`,\n ];\n if (breakEven !== undefined) {\n sentences.push(breakEven.reasoning);\n if (!breakEven.profitable) {\n extraFindings.push({\n severity: 'warning',\n code: 'write-premium-trap',\n message: `at ${formatCount(callsPerHour)} reuses per hour the per-token-hour storage bill on ${formatCount(analysis.stableTokens)} resident tokens exceeds the read savings; raise reuse density or shorten the resource TTL`,\n });\n }\n }\n return {\n directives,\n ...(breakEven !== undefined ? { breakEven } : {}),\n reasoning: sentences.join(' '),\n extraFindings,\n };\n }\n\n /**\n * Passive family (groq, deepseek, ollama, lmstudio, huggingface, custom): no control\n * surface exists, stable-first ordering and accounting are the whole contribution.\n */\n private planPassive(profile: ProviderProfile): PlannerResult {\n return {\n directives: [\n {\n kind: 'none',\n reason:\n 'provider caches automatically (or exposes no controls); RACS contributes structure linting and analytics',\n },\n ],\n reasoning: `${profile.id} exposes no cache control surface, so stable-first segment ordering is the entire optimization, and the ledger still accounts every cached token the provider reports.`,\n extraFindings: [],\n };\n }\n}\n","/**\n * Deterministic structural linting of a {@link PlanInput} segment list, the documented\n * failure modes of production prefix caching caught before a single token is billed.\n *\n * Provider semantics this module leans on, researched June 2026:\n * - Prefix caches are strictly left-anchored on every provider family, so one volatile\n * byte invalidates everything after it (Anthropic prompt caching docs, June 2026;\n * OpenAI prompt caching guide, June 2026).\n * - Breakpoint providers hash tool definitions ahead of the message list, so a volatile\n * `'tools'` segment defeats the cache for the whole request (Anthropic `cache_control`\n * semantics, June 2026).\n * - Prefixes below the provider minimum are silently uncached, no error, no usage signal\n * (1024 tokens on most Anthropic and OpenAI models as of June 2026); the minimum itself\n * always comes from the {@link ProviderProfile}, never from constants here.\n *\n * Privacy contract: content heuristics run only on segments that carry `content`.\n * Hash-only segments (only `contentHash` present) are skipped by design, RACS never sees\n * their text so there is nothing to scan. Finding messages never embed matched substrings,\n * because findings travel inside persisted plans while segment content must never be\n * persisted; matches are referenced by a short content digest instead, which still lets\n * the owner locate the offending text in their own prompt source.\n *\n * Determinism: pure function of the input and profile, no clock, no randomness, findings\n * are emitted in a fixed order (structural lints, then per-segment scans in segment order,\n * then the prefix-level summary).\n */\n\nimport { fnv1a64 } from '../stats/hash.js';\nimport { tokensOf } from '../stats/tokens.js';\nimport type { LintFinding, PlanInput, PromptSegment, ProviderProfile } from '../types.js';\n\n/** Result of one {@link PrefixAnalyzer.analyze} pass, pure data. */\nexport interface PrefixAnalysis {\n /** Lint findings in deterministic emission order. */\n findings: LintFinding[];\n /** Token total of the longest stable-or-semi run from the start, the cacheable prefix. */\n stableTokens: number;\n /** Token total of the whole prompt, exact or estimated per segment rules. */\n totalTokens: number;\n /** Index of the first volatile segment, `segments.length` when none is volatile. */\n orderedStableBoundary: number;\n}\n\n/** ISO-8601 datetime, date plus time with optional seconds, fraction, and offset. */\nconst ISO_8601_DATETIME =\n /\\b\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:?\\d{2})?\\b/;\n\n/** Unix epoch in seconds (10 digits) or milliseconds (13 digits), exact-length runs only. */\nconst UNIX_EPOCH = /\\b(?:\\d{13}|\\d{10})\\b/;\n\n/**\n * The words 'today' or 'current time' within 32 characters of a digit on the same line,\n * the shape of an interpolated \"Today is ...\" or \"current time: ...\" system-prompt line.\n * Bounded quantifiers only, linear scan, no catastrophic backtracking.\n */\nconst RELATIVE_TIME_NEAR_DIGITS =\n /\\b(?:today|current time)\\b[^0-9\\n\\r]{0,32}[0-9]|[0-9][^0-9\\n\\r]{0,32}\\b(?:today|current time)\\b/i;\n\n/** UUID v4 shape: version nibble 4, variant nibble 8 through b. */\nconst UUID_V4 = /\\b[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\\b/i;\n\n/** Maximal run of 24 or more hex characters, the shape of request and trace ids. */\nconst HEX_RUN = /\\b[0-9a-f]{24,}\\b/i;\n\n/**\n * Candidate base64-style run of 24 or more characters with optional padding. Greedy\n * matching makes each match maximal, candidates are then filtered in code to require at\n * least one digit and one letter, which excludes long prose words and long plain numbers.\n */\nconst BASE64_RUN = /[A-Za-z0-9+/]{24,}={0,2}/g;\n\n/** Short digest of a matched substring, safe to persist where the substring is not. */\nconst digestOf = (match: string): string => fnv1a64(match).slice(0, 8);\n\n/** First match of a non-global pattern, `undefined` when the pattern does not occur. */\nconst firstMatch = (pattern: RegExp, content: string): string | undefined => {\n const result = pattern.exec(content);\n return result ? result[0] : undefined;\n};\n\n/**\n * Structural linter over a segment list and one provider profile. Stateless, every call\n * is independent, safe to share one instance across plans.\n */\nexport class PrefixAnalyzer {\n /**\n * Runs every structural lint and computes the prefix geometry the planner needs.\n *\n * @param input - The plan input whose segments are analyzed, in request order.\n * @param profile - Effective provider profile, supplies `minCacheableTokens`.\n * @returns Findings plus the cacheable-prefix token counts and the volatile boundary.\n */\n analyze(input: PlanInput, profile: ProviderProfile): PrefixAnalysis {\n const segments = input.segments;\n\n let totalTokens = 0;\n let orderedStableBoundary = segments.length;\n let stableTokens = 0;\n for (const [index, segment] of segments.entries()) {\n const tokens = tokensOf(segment);\n totalTokens += tokens;\n if (index < orderedStableBoundary) {\n if (segment.stability === 'volatile') {\n orderedStableBoundary = index;\n } else {\n stableTokens += tokens;\n }\n }\n }\n\n const findings: LintFinding[] = [];\n this.lintSegmentOrder(segments, orderedStableBoundary, findings);\n this.lintVolatileEarly(\n segments,\n orderedStableBoundary,\n stableTokens,\n totalTokens,\n profile,\n findings,\n );\n for (const segment of segments) {\n this.lintSegment(segment, findings);\n }\n this.lintBelowMinimum(stableTokens, profile, findings);\n\n return { findings, stableTokens, totalTokens, orderedStableBoundary };\n }\n\n /** `'segment-order'`: the first volatile segment that precedes a cacheable one. */\n private lintSegmentOrder(\n segments: readonly PromptSegment[],\n orderedStableBoundary: number,\n findings: LintFinding[],\n ): void {\n const volatileSegment = segments[orderedStableBoundary];\n if (volatileSegment === undefined) {\n return;\n }\n for (let index = orderedStableBoundary + 1; index < segments.length; index += 1) {\n const later = segments[index];\n if (later !== undefined && later.stability !== 'volatile') {\n findings.push({\n severity: 'warning',\n code: 'segment-order',\n segmentId: volatileSegment.id,\n message:\n `Volatile segment '${volatileSegment.id}' precedes ${later.stability} segment ` +\n `'${later.id}'. Prefix caches are left-anchored, so every token after ` +\n `'${volatileSegment.id}' is unreachable for the cache. Reorder stable-first: move ` +\n `'${later.id}' and every other stable segment ahead of '${volatileSegment.id}'.`,\n });\n return;\n }\n }\n }\n\n /**\n * `'volatile-early'`: a volatile segment inside the first half of total tokens and\n * before any breakpoint-eligible boundary, the silent-cache-killer layout.\n *\n * A boundary is breakpoint-eligible only inside the leading stable run (a span that\n * contains volatile content can never be read back), so eligibility reduces to the\n * leading run reaching the provider minimum. The first volatile segment is reported, it\n * is the one that caps the run. Its start offset equals `stableTokens` by construction.\n */\n private lintVolatileEarly(\n segments: readonly PromptSegment[],\n orderedStableBoundary: number,\n stableTokens: number,\n totalTokens: number,\n profile: ProviderProfile,\n findings: LintFinding[],\n ): void {\n const volatileSegment = segments[orderedStableBoundary];\n if (volatileSegment === undefined || totalTokens === 0) {\n return;\n }\n const minimumEligible =\n profile.minCacheableTokens !== undefined && profile.minCacheableTokens > 0\n ? profile.minCacheableTokens\n : 1;\n const inFirstHalf = stableTokens * 2 < totalTokens;\n if (inFirstHalf && stableTokens < minimumEligible) {\n findings.push({\n severity: 'error',\n code: 'volatile-early',\n segmentId: volatileSegment.id,\n message:\n `Volatile segment '${volatileSegment.id}' sits inside the first half of the prompt ` +\n `(${stableTokens} of ${totalTokens} tokens precede it) and before any ` +\n `breakpoint-eligible boundary (provider minimum ${minimumEligible} tokens on ` +\n `'${profile.id}'). Nothing in this prompt can ever be cached. The usual culprits are ` +\n `timestamps or session metadata interpolated into the system prompt; move every ` +\n `per-call value to the end of the prompt and keep the opening segments byte-stable.`,\n });\n }\n }\n\n /** Per-segment lints: declaration checks always, content heuristics only with content. */\n private lintSegment(segment: PromptSegment, findings: LintFinding[]): void {\n if (segment.role === 'tools' && segment.stability === 'volatile') {\n findings.push({\n severity: 'error',\n code: 'unstable-tools',\n segmentId: segment.id,\n message:\n `Tools segment '${segment.id}' is declared volatile. Breakpoint providers hash tool ` +\n `definitions first, so volatile tools defeat the cache for the entire request. Tool ` +\n `instability is almost always a serialization bug, fix key ordering or remove ` +\n `timestamps from descriptions, then declare the segment stable.`,\n });\n }\n if (segment.role === 'dynamic' && segment.stability === 'stable') {\n findings.push({\n severity: 'info',\n code: 'missing-stability',\n segmentId: segment.id,\n message:\n `Segment '${segment.id}' has the dynamic role but is declared stable. Dynamic content ` +\n `is expected to differ on every call, which contradicts the declaration. Declare it ` +\n `volatile, or change the role if the content really is byte-stable.`,\n });\n }\n const content = segment.content;\n if (typeof content !== 'string') {\n return;\n }\n if (segment.stability === 'stable' || segment.stability === 'semi') {\n this.lintTimestamps(segment, content, findings);\n }\n if (segment.stability === 'stable') {\n this.lintIdentifiers(segment, content, findings);\n }\n }\n\n /** `'timestamp-in-stable'`: timestamp-like content inside a stable or semi segment. */\n private lintTimestamps(segment: PromptSegment, content: string, findings: LintFinding[]): void {\n const hits: string[] = [];\n const iso = firstMatch(ISO_8601_DATETIME, content);\n if (iso !== undefined) {\n hits.push(`an ISO-8601 datetime (digest ${digestOf(iso)})`);\n }\n const epoch = firstMatch(UNIX_EPOCH, content);\n if (epoch !== undefined) {\n hits.push(`a 10-or-13-digit unix epoch (digest ${digestOf(epoch)})`);\n }\n if (RELATIVE_TIME_NEAR_DIGITS.test(content)) {\n hits.push(`the words 'today' or 'current time' near digits`);\n }\n if (hits.length === 0) {\n return;\n }\n findings.push({\n severity: 'warning',\n code: 'timestamp-in-stable',\n segmentId: segment.id,\n message:\n `Segment '${segment.id}' is declared ${segment.stability} but contains ` +\n `${hits.join(', and ')}. A timestamp changes the prefix on every call and silently ` +\n `defeats the cache. Move live time values into a volatile segment at the prompt tail.`,\n });\n }\n\n /** `'identifier-in-stable'`: per-request identifier shapes inside a stable segment. */\n private lintIdentifiers(segment: PromptSegment, content: string, findings: LintFinding[]): void {\n let kind: string | undefined;\n let match = firstMatch(UUID_V4, content);\n if (match !== undefined) {\n kind = 'a UUID v4-like identifier';\n } else {\n match = firstMatch(HEX_RUN, content);\n if (match !== undefined) {\n kind = 'a hex run of 24 or more characters';\n } else {\n for (const candidate of content.matchAll(BASE64_RUN)) {\n const text = candidate[0];\n if (text !== undefined && /\\d/.test(text) && /[a-z]/i.test(text)) {\n match = text;\n kind = 'a base64-like run of 24 or more characters';\n break;\n }\n }\n }\n }\n if (match === undefined || kind === undefined) {\n return;\n }\n findings.push({\n severity: 'warning',\n code: 'identifier-in-stable',\n segmentId: segment.id,\n message:\n `Segment '${segment.id}' is declared stable but contains ${kind} ` +\n `(digest ${digestOf(match)}). Session ids and request ids churn per call, the same ` +\n `failure mode as a timestamp. Move per-request identifiers into a volatile segment.`,\n });\n }\n\n /** `'below-minimum'`: the stable prefix is silently uncacheable on this provider. */\n private lintBelowMinimum(\n stableTokens: number,\n profile: ProviderProfile,\n findings: LintFinding[],\n ): void {\n const minimum = profile.minCacheableTokens;\n if (minimum === undefined || minimum <= 0 || stableTokens >= minimum) {\n return;\n }\n findings.push({\n severity: 'info',\n code: 'below-minimum',\n message:\n `The stable prefix totals ${stableTokens} tokens, below the ${minimum}-token minimum ` +\n `'${profile.id}' will cache. The provider would silently cache nothing. Lengthen the ` +\n `stable prefix, or accept that this prompt rides uncached on this provider.`,\n });\n }\n}\n","/**\n * Shipped provider profiles for RACS (Remote Agent Context Store), the numbers the planner\n * reasons with.\n *\n * Every named provider is a thin parameterization of exactly one {@link AdapterFamily}, which\n * is why one table covers the whole provider landscape without per-provider code paths. The\n * values document provider semantics as researched in June 2026, each entry cites its source\n * and retrieval date in JSDoc. Providers change terms faster than packages release, so every\n * value is overridable per engine instance through {@link RACSOptions.profiles}, merged by\n * {@link resolveProfile}.\n *\n * @packageDocumentation\n */\n\nimport { RacsError } from '../errors.js';\nimport type { AdapterFamily, ProviderId, ProviderProfile, RACSOptions } from '../types.js';\n\n/**\n * The four cache-control mechanisms RACS implements, used to validate profile overrides at\n * runtime on behalf of untyped JavaScript callers, see {@link AdapterFamily}.\n */\nconst ADAPTER_FAMILIES: readonly AdapterFamily[] = [\n 'breakpoint',\n 'routing-key',\n 'resource',\n 'passive',\n];\n\n/**\n * The shipped profile table, one entry per {@link ProviderId}, semantics as documented in\n * June 2026. Treat as read-only defaults: the planner must always go through\n * {@link resolveProfile} so per-engine overrides apply.\n */\nexport const PROVIDER_PROFILES: Readonly<Record<ProviderId, ProviderProfile>> = {\n /**\n * Anthropic Claude API, explicit `cache_control` breakpoints with two TTL tiers.\n *\n * Writes cost 1.25x base input on the 5-minute tier and 2x on the 1-hour tier, cached\n * reads cost 0.1x, at most 4 breakpoints per request. The 1024-token minimum is the\n * conservative common case: the newest frontier models cache from 512 tokens and the\n * small models require 4096, override per model through {@link RACSOptions.profiles}\n * when targeting those.\n *\n * Source: Anthropic prompt caching documentation,\n * https://docs.claude.com/en/docs/build-with-claude/prompt-caching, retrieved June 2026.\n */\n anthropic: {\n id: 'anthropic',\n family: 'breakpoint',\n minCacheableTokens: 1024,\n maxBreakpoints: 4,\n ttls: ['5m', '1h'],\n writeMultiplier5m: 1.25,\n writeMultiplier1h: 2,\n readMultiplier: 0.1,\n notes:\n 'Explicit cache_control breakpoints, up to 4 per request, 5m and 1h TTL tiers. ' +\n 'Minimum cacheable prefix is 1024 tokens in the common case, 512 on the newest ' +\n 'frontier models, 4096 on small models, override per model via options.profiles.',\n },\n /**\n * OpenAI, automatic server-side prefix caching steered by `prompt_cache_key`.\n *\n * Caches in 128-token increments above a 1024-token minimum, no write counter and no\n * write premium. The cached-read discount varies between 50 and 90 percent by model, so\n * the 0.25 read multiplier is a conservative default, override per model when the exact\n * discount is known. Extended 24-hour retention attaches to `prompt_cache_key`, hence\n * `supportsRetention`.\n *\n * Source: OpenAI prompt caching guide,\n * https://platform.openai.com/docs/guides/prompt-caching, retrieved June 2026.\n */\n openai: {\n id: 'openai',\n family: 'routing-key',\n minCacheableTokens: 1024,\n readMultiplier: 0.25,\n supportsRetention: true,\n notes:\n 'Automatic prefix caching in 128-token increments above 1024 tokens, ' +\n 'prompt_cache_key routing, no write counter, read discount varies 50 to 90 percent ' +\n 'by model so 0.25 is a conservative default.',\n },\n /**\n * Google Gemini, implicit caching on 2.5 and newer models plus the explicit\n * `cachedContents` resource lifecycle with caller-set TTL and per-token-hour storage\n * billing at 1.0 USD per million tokens per hour.\n *\n * Source: Google Gemini API context caching documentation,\n * https://ai.google.dev/gemini-api/docs/caching, retrieved June 2026.\n */\n google: {\n id: 'google',\n family: 'resource',\n minCacheableTokens: 2048,\n readMultiplier: 0.1,\n storagePerMTokHour: 1.0,\n notes:\n 'Implicit caching on 2.5+ models plus explicit cachedContents lifecycle with TTL ' +\n 'and per-token-hour storage billing.',\n },\n /**\n * Amazon Bedrock, `cachePoint` blocks on the Converse API, Anthropic-equivalent\n * breakpoint semantics and multipliers.\n *\n * Source: Amazon Bedrock prompt caching documentation,\n * https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html, retrieved\n * June 2026.\n */\n bedrock: {\n id: 'bedrock',\n family: 'breakpoint',\n minCacheableTokens: 1024,\n maxBreakpoints: 4,\n ttls: ['5m', '1h'],\n writeMultiplier5m: 1.25,\n writeMultiplier1h: 2,\n readMultiplier: 0.1,\n notes: 'cachePoint blocks on the Converse API, Anthropic-equivalent breakpoint semantics.',\n },\n /**\n * xAI Grok, automatic prefix caching, steerable with the `x-grok-conv-id` header and\n * `prompt_cache_key`, cached reads at roughly 0.16x base input.\n *\n * Source: xAI API documentation, https://docs.x.ai/, retrieved June 2026.\n */\n xai: {\n id: 'xai',\n family: 'routing-key',\n minCacheableTokens: 1024,\n readMultiplier: 0.16,\n notes:\n 'Automatic prefix caching, steerable via the x-grok-conv-id header and prompt_cache_key.',\n },\n /**\n * Groq, automatic prefix caching on gpt-oss models with no control surface, cached reads\n * at 0.5x base input, entries expire after roughly 2 hours idle.\n *\n * Source: Groq prompt caching documentation,\n * https://console.groq.com/docs/prompt-caching, retrieved June 2026.\n */\n groq: {\n id: 'groq',\n family: 'passive',\n minCacheableTokens: 128,\n readMultiplier: 0.5,\n notes: 'Automatic on gpt-oss models, no controls, entries expire after 2 hours idle.',\n },\n /**\n * DeepSeek, disk-based automatic context caching with cache hit and miss token\n * reporting, cached reads at 0.1x base input.\n *\n * Source: DeepSeek context caching documentation,\n * https://api-docs.deepseek.com/guides/kv_cache, retrieved June 2026.\n */\n deepseek: {\n id: 'deepseek',\n family: 'passive',\n readMultiplier: 0.1,\n notes: 'Disk-based automatic context caching with hit and miss token reporting.',\n },\n /**\n * Mistral, automatic caching in 64-token blocks with `prompt_cache_key` routing, cached\n * reads at 0.1x base input.\n *\n * Source: Mistral platform documentation, https://docs.mistral.ai/, retrieved June 2026.\n */\n mistral: {\n id: 'mistral',\n family: 'routing-key',\n minCacheableTokens: 64,\n readMultiplier: 0.1,\n notes: '64-token cache blocks, prompt_cache_key routing.',\n },\n /**\n * OpenRouter normalizes `cache_control` passthrough and `cached_tokens` reporting across\n * upstream providers. The numbers are conservative defaults because the effective\n * discount is whatever the routed upstream charges.\n *\n * Source: OpenRouter prompt caching documentation,\n * https://openrouter.ai/docs/features/prompt-caching, retrieved June 2026.\n */\n openrouter: {\n id: 'openrouter',\n family: 'routing-key',\n minCacheableTokens: 1024,\n readMultiplier: 0.25,\n notes:\n 'Normalizes cache_control passthrough and cached_tokens reporting across upstreams, ' +\n 'effective discount depends on the routed upstream.',\n },\n /**\n * Moonshot Kimi, platform caching reached through the OpenAI-compatible surface. The\n * public semantics are less documented than peers as of June 2026, so the profile\n * carries conservative defaults mirroring the OpenAI numbers.\n *\n * Source: Moonshot platform documentation, https://platform.moonshot.ai/docs, retrieved\n * June 2026.\n */\n moonshot: {\n id: 'moonshot',\n family: 'routing-key',\n minCacheableTokens: 1024,\n readMultiplier: 0.25,\n notes:\n 'Kimi platform caching via the OpenAI-compatible surface, semantics less documented, ' +\n 'conservative defaults.',\n },\n /**\n * Ollama, local runtime KV reuse with no billing dimension, analytics measure\n * latency-motivated reuse only.\n *\n * Source: Ollama documentation, https://docs.ollama.com/, retrieved June 2026.\n */\n ollama: {\n id: 'ollama',\n family: 'passive',\n notes: 'Local runtime KV reuse, no billing, analytics measure latency-motivated reuse only.',\n },\n /**\n * LM Studio, local runtime KV reuse with no billing dimension, same posture as Ollama.\n *\n * Source: LM Studio documentation, https://lmstudio.ai/docs, retrieved June 2026.\n */\n lmstudio: {\n id: 'lmstudio',\n family: 'passive',\n notes: 'Local runtime KV reuse, no billing, analytics measure latency-motivated reuse only.',\n },\n /**\n * Hugging Face Inference Endpoints expose no public prefix-cache controls as of\n * June 2026, so the profile is passive and carries no numbers.\n *\n * Source: Hugging Face Inference Endpoints documentation,\n * https://huggingface.co/docs/inference-endpoints, retrieved June 2026.\n */\n huggingface: {\n id: 'huggingface',\n family: 'passive',\n notes: 'Inference Endpoints without public prefix-cache controls as of June 2026.',\n },\n /**\n * Claude models on Microsoft Foundry honor `cache_control` unchanged, so the profile\n * mirrors the Anthropic numbers.\n *\n * Source: Microsoft Foundry documentation for Anthropic Claude models,\n * https://learn.microsoft.com/en-us/azure/ai-foundry/, retrieved June 2026.\n */\n 'microsoft-foundry': {\n id: 'microsoft-foundry',\n family: 'breakpoint',\n minCacheableTokens: 1024,\n maxBreakpoints: 4,\n ttls: ['5m', '1h'],\n writeMultiplier5m: 1.25,\n writeMultiplier1h: 2,\n readMultiplier: 0.1,\n notes: 'Claude on Microsoft Foundry honors cache_control, Anthropic breakpoint semantics.',\n },\n /**\n * Nous Research Hermes Agent rides Anthropic `cache_control` semantics with its fixed\n * system_and_3 layout, the system prompt plus the last 3 messages, so the multipliers,\n * the 1024-token cacheable minimum, and the breakpoint budget are the Anthropic numbers\n * and RACS plans superior layouts for it.\n *\n * Sources: Hermes Agent system_and_3 cache layout, observed June 2026, and Anthropic\n * prompt caching documentation,\n * https://docs.claude.com/en/docs/build-with-claude/prompt-caching, retrieved June 2026.\n */\n hermes: {\n id: 'hermes',\n family: 'breakpoint',\n minCacheableTokens: 1024,\n maxBreakpoints: 4,\n ttls: ['5m', '1h'],\n writeMultiplier5m: 1.25,\n writeMultiplier1h: 2,\n readMultiplier: 0.1,\n notes:\n 'Hermes Agent system_and_3 layout (system plus last 3 messages) rides Anthropic ' +\n 'cache_control semantics, RACS plans superior layouts for it.',\n },\n /**\n * Escape hatch for providers RACS does not name yet, fully caller-defined through\n * {@link RACSOptions.profiles}. Defaults to passive so a bare 'custom' plan still orders\n * segments, lints, and accounts usage without inventing numbers.\n */\n custom: {\n id: 'custom',\n family: 'passive',\n notes: 'Fully caller-defined via the options.profiles override.',\n },\n};\n\n/**\n * Returns the effective profile for one provider: the shipped table entry shallow-merged\n * with the caller's per-engine override from {@link RACSOptions.profiles}.\n *\n * Merge rules:\n * - Shallow: every override field replaces the shipped field wholesale, `ttls` included.\n * - Override fields holding `undefined` at runtime (possible for untyped JavaScript\n * callers) are ignored rather than clobbering shipped values.\n * - `id` is not overridable, the result always names the requested provider.\n *\n * @param id - Provider whose profile to resolve.\n * @param overrides - Per-provider override map, see {@link RACSOptions.profiles}.\n * @returns The merged profile the planner actually uses.\n * @throws RacsError code `'ERR_INVALID_INPUT'` when `id` names no shipped profile (only\n * reachable from untyped callers) or when the merged `family` is not a known\n * {@link AdapterFamily}.\n */\nexport function resolveProfile(\n id: ProviderId,\n overrides?: RACSOptions['profiles'],\n): ProviderProfile {\n const base: ProviderProfile | undefined = PROVIDER_PROFILES[id];\n if (base === undefined) {\n throw RacsError.invalid(\n `Unknown provider id '${String(id)}', expected one of: ` +\n `${Object.keys(PROVIDER_PROFILES).join(', ')}.`,\n );\n }\n const override = overrides?.[id];\n if (override === undefined) {\n return base;\n }\n const merged: ProviderProfile = {\n ...base,\n ...(override.family !== undefined ? { family: override.family } : {}),\n ...(override.minCacheableTokens !== undefined\n ? { minCacheableTokens: override.minCacheableTokens }\n : {}),\n ...(override.maxBreakpoints !== undefined ? { maxBreakpoints: override.maxBreakpoints } : {}),\n ...(override.ttls !== undefined ? { ttls: override.ttls } : {}),\n ...(override.writeMultiplier5m !== undefined\n ? { writeMultiplier5m: override.writeMultiplier5m }\n : {}),\n ...(override.writeMultiplier1h !== undefined\n ? { writeMultiplier1h: override.writeMultiplier1h }\n : {}),\n ...(override.readMultiplier !== undefined ? { readMultiplier: override.readMultiplier } : {}),\n ...(override.supportsRetention !== undefined\n ? { supportsRetention: override.supportsRetention }\n : {}),\n ...(override.storagePerMTokHour !== undefined\n ? { storagePerMTokHour: override.storagePerMTokHour }\n : {}),\n ...(override.notes !== undefined ? { notes: override.notes } : {}),\n id: base.id,\n };\n if (!ADAPTER_FAMILIES.includes(merged.family)) {\n throw RacsError.invalid(\n `Profile override for '${id}' sets family '${String(merged.family)}', expected one ` +\n `of: ${ADAPTER_FAMILIES.join(', ')}.`,\n );\n }\n return merged;\n}\n","/**\n * Keep-warm scheduling of RACS (Remote Agent Context Store): tracks when each cached\n * prefix was last written and when a refresh touch is due, so the host can keep caches\n * warm at read price instead of paying the write premium again after expiry.\n *\n * The keeper computes WHEN, the host runs the timer and the warming call, per the product\n * invariant, RACS never talks to any provider network API.\n *\n * @packageDocumentation\n */\n\nimport type { CachePlan, CacheTtl, RefreshEntry } from '../types.js';\n\n/**\n * Fraction of the TTL window after which the keep-warm touch is scheduled.\n *\n * The 90 percent headroom is the production heartbeat convention for prompt-cache\n * keep-warm loops (as observed across Anthropic prompt caching deployments, June 2026):\n * touching at 100 percent races cache expiry against timer drift, queue delay, and request\n * latency, one lost race costs a full write premium, while touching much earlier wastes\n * paid reads on a cache that had plenty of life left. One tenth of the window absorbs the\n * jitter of ordinary schedulers at both the 5-minute and 1-hour tiers.\n */\nconst REFRESH_FRACTION = 0.9;\n\n/**\n * Converts a TTL declaration to milliseconds. The `'5m'` (300 seconds) and `'1h'`\n * (3600 seconds) tiers are the breakpoint-family standard as of June 2026, see\n * {@link CacheTtl}. Resource-family TTLs arrive as arbitrary second counts.\n */\nfunction ttlToMillis(ttl: CacheTtl | number): number {\n if (ttl === '5m') {\n return 300_000;\n }\n if (ttl === '1h') {\n return 3_600_000;\n }\n return ttl * 1000;\n}\n\n/**\n * Serialized keeper state, produced by {@link TtlKeeper.toJSON} and consumed by\n * {@link TtlKeeper.fromJSON}. {@link RefreshEntry} is already pure JSON data, so entries\n * serialize verbatim, ordered least-recently-tracked first to preserve eviction order.\n */\nexport interface TtlKeeperJSON {\n /** The eviction cap the keeper was running with. */\n readonly capacity: number;\n /** Keep-warm entries, least-recently-tracked first. */\n readonly entries: readonly RefreshEntry[];\n}\n\n/**\n * Bounded, LRU-evicting registry of keep-warm entries, one per prefix key.\n *\n * Tracked directives: `'breakpoint'` directives with their `'5m'` or `'1h'` tier, and\n * `'resource'` directives with their `ttlSeconds`. `'routing-key'`, `'none'`, and plans\n * without cache writes track nothing, there is no host-controlled expiry to keep warm. A\n * `'resource'` directive with action `'delete'` removes the entry instead, a deleted\n * resource must not be kept warm.\n *\n * When one plan carries several tracked directives with different TTLs, the SHORTEST one\n * drives the schedule: a refresh touch rewarms every span of the prefix at once, and the\n * earliest-expiring span bounds how long the whole prefix stays warm.\n */\nexport class TtlKeeper {\n private readonly capacity: number;\n /** Map iteration order doubles as recency order, oldest entry first. */\n private readonly entries = new Map<string, RefreshEntry>();\n\n /**\n * @param capacity - Cap on distinct tracked prefixes before LRU eviction.\n */\n constructor(capacity = 1000) {\n this.capacity = capacity;\n }\n\n /**\n * Records or replaces the keep-warm entry for the plan's prefix.\n *\n * `refreshAt = lastWriteAt + 0.9 * ttlMillis`, see {@link REFRESH_FRACTION} for why\n * 90 percent.\n *\n * @param plan - The plan whose directives describe the cache writes to keep warm.\n * @param now - Milliseconds since the Unix epoch, from the injected engine clock,\n * taken as the moment of the cache write.\n */\n track(plan: CachePlan, now: number): void {\n let ttl: CacheTtl | number | undefined;\n for (const directive of plan.directives) {\n if (directive.kind === 'breakpoint') {\n if (ttl === undefined || ttlToMillis(directive.ttl) < ttlToMillis(ttl)) {\n ttl = directive.ttl;\n }\n } else if (directive.kind === 'resource') {\n if (directive.action === 'delete') {\n this.remove(plan.prefixKey);\n return;\n }\n if (ttl === undefined || ttlToMillis(directive.ttlSeconds) < ttlToMillis(ttl)) {\n ttl = directive.ttlSeconds;\n }\n }\n }\n if (ttl === undefined) {\n return;\n }\n\n const entry: RefreshEntry = {\n prefixKey: plan.prefixKey,\n provider: plan.provider,\n model: plan.model,\n ttl,\n lastWriteAt: now,\n refreshAt: now + REFRESH_FRACTION * ttlToMillis(ttl),\n };\n // Delete-then-set keeps Map iteration order as recency order for LRU eviction.\n this.entries.delete(plan.prefixKey);\n this.entries.set(plan.prefixKey, entry);\n if (this.entries.size > this.capacity) {\n const oldest = this.entries.keys().next();\n if (!oldest.done) {\n this.entries.delete(oldest.value);\n }\n }\n }\n\n /**\n * Returns every entry whose refresh touch is due at or before `now`, most overdue first,\n * ties broken by prefix key for deterministic output. Read-only: the host performs the\n * warming call and then reports it through {@link TtlKeeper.markRefreshed}.\n *\n * @param now - Milliseconds since the Unix epoch, from the injected engine clock.\n */\n due(now: number): RefreshEntry[] {\n const due: RefreshEntry[] = [];\n for (const entry of this.entries.values()) {\n if (entry.refreshAt <= now) {\n due.push(entry);\n }\n }\n due.sort((a, b) =>\n a.refreshAt === b.refreshAt\n ? a.prefixKey < b.prefixKey\n ? -1\n : a.prefixKey > b.prefixKey\n ? 1\n : 0\n : a.refreshAt - b.refreshAt,\n );\n return due;\n }\n\n /**\n * Slides the TTL window after the host touched the cache: `lastWriteAt` becomes `now`\n * and `refreshAt` moves to 90 percent of the entry's TTL after it. Unknown prefixes are\n * ignored, the host may legitimately refresh a prefix the keeper already evicted.\n *\n * @param prefixKey - The prefix the host kept warm.\n * @param now - Milliseconds since the Unix epoch of the touch.\n */\n markRefreshed(prefixKey: string, now: number): void {\n const entry = this.entries.get(prefixKey);\n if (entry === undefined) {\n return;\n }\n const updated: RefreshEntry = {\n ...entry,\n lastWriteAt: now,\n refreshAt: now + REFRESH_FRACTION * ttlToMillis(entry.ttl),\n };\n this.entries.delete(prefixKey);\n this.entries.set(prefixKey, updated);\n }\n\n /**\n * Drops the entry for a prefix, used when the host abandons a cache or a resource\n * directive deletes it. Unknown prefixes are ignored.\n */\n remove(prefixKey: string): void {\n this.entries.delete(prefixKey);\n }\n\n /**\n * Serializes every entry, least-recently-tracked first. Pure JSON data, round-trips\n * through {@link TtlKeeper.fromJSON}.\n */\n toJSON(): TtlKeeperJSON {\n return { capacity: this.capacity, entries: [...this.entries.values()] };\n }\n\n /**\n * Rebuilds a keeper from {@link TtlKeeper.toJSON} output, restoring entries and their\n * recency order.\n *\n * @param json - A previously serialized keeper.\n */\n static fromJSON(json: TtlKeeperJSON): TtlKeeper {\n const keeper = new TtlKeeper(json.capacity);\n for (const entry of json.entries) {\n keeper.entries.set(entry.prefixKey, entry);\n }\n return keeper;\n }\n}\n","/**\n * Engine core of RACS (Remote Agent Context Store): wires the analyzer, the planner, the\n * ledger, drift fingerprints, the keep-warm keeper, and the resource registry behind the\n * one public {@link RACS} surface.\n *\n * The core owns everything stateful: deterministic plan identity, prefix bookkeeping,\n * telemetry fan-out, and persistence. The modules it wires stay pure or self-contained, so\n * this file is the only place where their interactions are decided.\n *\n * Determinism: plan ids derive from a seeded counter ({@link RACSOptions.seed}, default 7)\n * through the seeded short-id generator, never from the platform UUID or the global random\n * generator. The clock is read once per mutating call and is injectable for tests.\n *\n * @packageDocumentation\n */\n\nimport { Fingerprints } from '../drift/Fingerprints.js';\nimport { RacsError } from '../errors.js';\nimport { Ledger } from '../ledger/Ledger.js';\nimport { Planner } from '../plan/Planner.js';\nimport { PrefixAnalyzer } from '../plan/PrefixAnalyzer.js';\nimport { resolveProfile } from '../providers/profiles.js';\nimport { TtlKeeper } from '../schedule/TtlKeeper.js';\nimport { combineKeys, fnv1a64, shortId } from '../stats/hash.js';\nimport type {\n CacheDirective,\n CachePlan,\n CacheUsage,\n DriftReport,\n LedgerStats,\n LintFinding,\n PlanInput,\n PricingTable,\n PromptSegment,\n ProviderId,\n ProviderProfile,\n RACS,\n RACSOptions,\n RefreshEntry,\n StateBackend,\n StateSnapshot,\n TelemetryEvent,\n TelemetryListener,\n} from '../types.js';\n\n/** Default seed of the deterministic plan-id generator, see {@link RACSOptions.seed}. */\nconst DEFAULT_SEED = 7;\n\n/** Default cap on distinct tracked prefixes, see {@link RACSOptions.maxPrefixes}. */\nconst DEFAULT_MAX_PREFIXES = 1000;\n\n/**\n * Capacity of the drift ring. Two hundred reports cover days of drift on a misbehaving\n * deployment while keeping the ring, and therefore every snapshot, small enough for edge\n * KV value limits.\n */\nconst DRIFT_RING_CAPACITY = 200;\n\n/**\n * Fraction of a resource TTL window after which a planned `'reuse'` is swapped for\n * `'refresh'`. Mirrors the keep-warm convention of the TtlKeeper: touching inside the last\n * 10 percent of the window renews it before expiry while absorbing scheduler jitter.\n */\nconst RESOURCE_REFRESH_FRACTION = 0.9;\n\n/** Live registry entry for one resource-family cache, see {@link CacheDirective}. */\ninterface ResourceRecord {\n /** Provider the resource lives on, the attribution key of provider-scoped invalidation. */\n provider: ProviderId;\n ttlSeconds: number;\n lastWriteAt: number;\n}\n\n/** Serialized registry entry, persisted inside {@link StateSnapshot.data}. */\ninterface ResourceRecordJSON {\n readonly key: string;\n readonly provider: ProviderId;\n readonly ttlSeconds: number;\n readonly lastWriteAt: number;\n}\n\n/** True for any non-null object, the first gate of every defensive restore check. */\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/** Structural check for one persisted resource registry entry. */\nfunction isResourceRecordJSON(value: unknown): value is ResourceRecordJSON {\n return (\n isRecord(value) &&\n typeof value.key === 'string' &&\n typeof value.provider === 'string' &&\n typeof value.ttlSeconds === 'number' &&\n typeof value.lastWriteAt === 'number'\n );\n}\n\n/** Structural check for one persisted drift report. */\nfunction isDriftReport(value: unknown): value is DriftReport {\n return (\n isRecord(value) &&\n (value.agentId === undefined || typeof value.agentId === 'string') &&\n typeof value.prefixKey === 'string' &&\n typeof value.previousKey === 'string' &&\n Array.isArray(value.changedSegmentIds) &&\n value.changedSegmentIds.every((id) => typeof id === 'string') &&\n typeof value.invalidatedTokens === 'number' &&\n typeof value.timestamp === 'number'\n );\n}\n\n/** Throws RacsError `'ERR_INVALID_INPUT'` unless `value` is a finite non-negative number. */\nfunction requireCount(value: unknown, field: string): void {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {\n throw RacsError.invalid(\n `${field} must be a finite non-negative number, received ${String(value)}.`,\n );\n }\n}\n\n/**\n * Validates one {@link PlanInput} on behalf of untyped JavaScript callers: segments\n * non-empty, ids unique and non-empty, every segment carrying `content` or `contentHash`,\n * token counts sane. The provider id is validated separately by `resolveProfile`, which\n * throws the same `'ERR_INVALID_INPUT'` code for unknown providers.\n */\nfunction validatePlanInput(input: PlanInput): void {\n if (!isRecord(input)) {\n throw RacsError.invalid(`PlanInput must be an object, received ${typeof input}.`);\n }\n if (typeof input.model !== 'string' || input.model === '') {\n throw RacsError.invalid('PlanInput.model must be a non-empty model identifier string.');\n }\n if (!Array.isArray(input.segments) || input.segments.length === 0) {\n throw RacsError.invalid('PlanInput.segments must be a non-empty array of prompt segments.');\n }\n const seen = new Set<string>();\n for (const segment of input.segments) {\n if (typeof segment.id !== 'string' || segment.id === '') {\n throw RacsError.invalid('Every segment needs a non-empty string id unique within the plan.');\n }\n if (seen.has(segment.id)) {\n throw RacsError.invalid(\n `Segment id '${segment.id}' appears more than once, ids must be unique within one plan.`,\n );\n }\n seen.add(segment.id);\n if (\n typeof segment.content !== 'string' &&\n (typeof segment.contentHash !== 'string' || segment.contentHash === '')\n ) {\n throw RacsError.invalid(\n `Segment '${segment.id}' carries neither content nor contentHash, provide at least one ` +\n `so the segment can be keyed.`,\n );\n }\n if (segment.tokens !== undefined) {\n requireCount(segment.tokens, `Segment '${segment.id}' tokens`);\n }\n }\n}\n\n/** Validates one {@link CacheUsage} on behalf of untyped JavaScript callers. */\nfunction validateUsage(usage: CacheUsage): void {\n if (!isRecord(usage)) {\n throw RacsError.invalid(`CacheUsage must be an object, received ${typeof usage}.`);\n }\n // Widened to unknown because the ProviderId union cannot overlap '' at the type level,\n // while untyped JavaScript callers can still hand in anything at runtime.\n const provider: unknown = usage.provider;\n if (typeof provider !== 'string' || provider === '') {\n throw RacsError.invalid('CacheUsage.provider must be a non-empty provider id string.');\n }\n if (typeof usage.model !== 'string' || usage.model === '') {\n throw RacsError.invalid('CacheUsage.model must be a non-empty model identifier string.');\n }\n requireCount(usage.inputTokens, 'CacheUsage.inputTokens');\n requireCount(usage.cacheReadTokens, 'CacheUsage.cacheReadTokens');\n if (usage.cacheWriteTokens5m !== undefined) {\n requireCount(usage.cacheWriteTokens5m, 'CacheUsage.cacheWriteTokens5m');\n }\n if (usage.cacheWriteTokens1h !== undefined) {\n requireCount(usage.cacheWriteTokens1h, 'CacheUsage.cacheWriteTokens1h');\n }\n if (usage.timestamp !== undefined) {\n requireCount(usage.timestamp, 'CacheUsage.timestamp');\n }\n}\n\n/**\n * Keying hash of one segment. Per the {@link PromptSegment} content contract `contentHash`\n * wins when both fields are present, content alone is hashed with FNV-1a 64.\n */\nfunction hashOf(segment: PromptSegment): string {\n if (typeof segment.contentHash === 'string' && segment.contentHash !== '') {\n return segment.contentHash;\n }\n return fnv1a64(segment.content ?? '');\n}\n\n/** The one concrete {@link RACS} implementation, constructed by {@link createRACS}. */\nclass RacsEngine implements RACS {\n private readonly profiles: RACSOptions['profiles'];\n private readonly pricing: PricingTable | undefined;\n private readonly maxPrefixes: number;\n private readonly clock: () => number;\n private readonly salt: string;\n private readonly state: StateBackend | undefined;\n private readonly analyzer = new PrefixAnalyzer();\n private readonly planner = new Planner();\n /** Replaced wholesale when a persisted section restores, hence not readonly. */\n private ledger: Ledger;\n private fingerprints: Fingerprints;\n private keeper: TtlKeeper;\n /** Live resource-family caches by resource key, the planner's `knownResource` source. */\n private readonly resources = new Map<string, ResourceRecord>();\n /** Chronological drift ring, oldest first, newest last, capacity {@link DRIFT_RING_CAPACITY}. */\n private readonly driftRing: DriftReport[] = [];\n /**\n * Every prefix key registered for keeper and resource bookkeeping, capped at\n * maxPrefixes, each mapped to its provider so {@link RACS.invalidate} can clear by\n * provider, the shape credential rotation needs.\n */\n private readonly prefixKeys = new Map<string, ProviderId>();\n private readonly listeners: TelemetryListener[] = [];\n private planCounter = 0;\n /** Resolves when the state backend finished restoring, awaited by flush to avoid races. */\n private readonly restored: Promise<void>;\n\n constructor(options: RACSOptions = {}) {\n this.profiles = options.profiles;\n this.pricing = options.pricing;\n this.maxPrefixes = options.maxPrefixes ?? DEFAULT_MAX_PREFIXES;\n this.clock = options.clock ?? ((): number => Date.now());\n this.salt = String(options.seed ?? DEFAULT_SEED);\n this.state = options.state;\n this.ledger = new Ledger(this.pricing, this.maxPrefixes);\n this.fingerprints = new Fingerprints(this.maxPrefixes);\n this.keeper = new TtlKeeper(this.maxPrefixes);\n this.restored = this.state === undefined ? Promise.resolve() : this.restore(this.state);\n }\n\n plan(input: PlanInput): CachePlan {\n validatePlanInput(input);\n const profile = resolveProfile(input.provider, this.profiles);\n const now = this.clock();\n\n const segmentHashes = new Map<string, string>();\n for (const segment of input.segments) {\n segmentHashes.set(segment.id, hashOf(segment));\n }\n\n const analysis = this.analyzer.analyze(input, profile);\n\n // The prefix key fuses the ordered hashes of the left-anchored stable run with the\n // provider, model, and agent lineage, so equal keys mean byte-equal cacheable prefixes\n // and different agents never share keys even on identical content.\n const stableHashes: string[] = [];\n for (const segment of input.segments.slice(0, analysis.orderedStableBoundary)) {\n stableHashes.push(segmentHashes.get(segment.id) ?? '');\n }\n const prefixKey = combineKeys([\n ...stableHashes,\n input.provider,\n input.model,\n input.agentId ?? '',\n ]);\n\n let knownResource = false;\n if (profile.family === 'resource') {\n const record = this.resources.get(prefixKey);\n if (record !== undefined) {\n if (now >= record.lastWriteAt + record.ttlSeconds * 1000) {\n // The TTL window fully elapsed, the server already expired the resource, so the\n // next directive must be a create, not a reuse of a dead handle.\n this.resources.delete(prefixKey);\n } else {\n knownResource = true;\n }\n }\n }\n\n const result = this.planner.plan(\n input,\n profile,\n analysis,\n prefixKey,\n this.pricing?.[input.model],\n knownResource,\n );\n\n // The planner emits the reuse shape, the core owns the timing: inside the last 10\n // percent of the TTL window a reuse is swapped for a refresh so the host renews the\n // resource before the server expires it.\n const directives: CacheDirective[] = result.directives.map((directive) => {\n if (directive.kind !== 'resource' || directive.action !== 'reuse') {\n return directive;\n }\n const record = this.resources.get(directive.resourceKey);\n if (\n record !== undefined &&\n now >= record.lastWriteAt + RESOURCE_REFRESH_FRACTION * record.ttlSeconds * 1000\n ) {\n return { ...directive, action: 'refresh' as const };\n }\n return directive;\n });\n\n this.planCounter += 1;\n const plan: CachePlan = {\n planId: `rx-${this.planCounter}-${shortId(this.planCounter, this.salt)}`,\n provider: input.provider,\n model: input.model,\n family: profile.family,\n prefixKey,\n stableTokens: analysis.stableTokens,\n totalTokens: analysis.totalTokens,\n directives,\n findings: [...analysis.findings, ...result.extraFindings],\n ...(result.breakEven !== undefined ? { breakEven: result.breakEven } : {}),\n reasoning: result.reasoning,\n };\n\n // Drift tracking is lineage-bounded inside Fingerprints itself, so it runs even when\n // the prefix cap below degrades registration: a drifting prefix is exactly the signal\n // a saturated deployment must not lose.\n const report = this.fingerprints.observe(\n input,\n prefixKey,\n segmentHashes,\n analysis.stableTokens,\n now,\n );\n if (report !== undefined) {\n this.pushDrift(report);\n this.emit({ type: 'prefix.drifted', report });\n }\n\n if (!this.prefixKeys.has(prefixKey) && this.prefixKeys.size >= this.maxPrefixes) {\n // Degraded mode: the plan itself is still served in full, but the new key gets no\n // keep-warm tracking and no resource bookkeeping, so the bounded stores cannot grow\n // past the cap. The ledger applies its own LRU cap at recording time.\n this.emit({\n type: 'limit.reached',\n scope: 'prefixes',\n detail:\n `The ${this.maxPrefixes}-prefix cap is reached, plan for new prefix ` +\n `'${prefixKey}' was served without keep-warm tracking or resource bookkeeping.`,\n timestamp: now,\n });\n } else {\n this.prefixKeys.set(prefixKey, input.provider);\n this.keeper.track(plan, now);\n this.applyResourceDirectives(input.provider, directives, now);\n }\n\n this.emit({ type: 'plan.created', plan, timestamp: now });\n return plan;\n }\n\n lint(input: PlanInput): readonly LintFinding[] {\n validatePlanInput(input);\n const profile = resolveProfile(input.provider, this.profiles);\n return this.analyzer.analyze(input, profile).findings;\n }\n\n record(usage: CacheUsage): void {\n validateUsage(usage);\n const timestamp = usage.timestamp ?? this.clock();\n const stamped: CacheUsage = usage.timestamp !== undefined ? usage : { ...usage, timestamp };\n const { hit, evicted } = this.ledger.record(stamped);\n this.emit({ type: 'usage.recorded', usage: stamped, hit, timestamp });\n if (evicted !== undefined) {\n this.emit({\n type: 'limit.reached',\n scope: 'ledger',\n detail: `The ledger evicted least-recently-used aggregate '${evicted}' to stay within its cap.`,\n timestamp,\n });\n }\n }\n\n stats(filter?: { prefixKey?: string; provider?: ProviderId }): LedgerStats {\n return this.ledger.stats(filter);\n }\n\n schedule(now?: number): readonly RefreshEntry[] {\n const at = now ?? this.clock();\n const due = this.keeper.due(at);\n for (const entry of due) {\n this.emit({ type: 'refresh.due', entry, timestamp: at });\n }\n return due;\n }\n\n markRefreshed(prefixKey: string, now?: number): void {\n this.keeper.markRefreshed(prefixKey, now ?? this.clock());\n }\n\n drifts(limit?: number): readonly DriftReport[] {\n if (limit === undefined) {\n return [...this.driftRing];\n }\n if (limit <= 0) {\n return [];\n }\n return this.driftRing.slice(-limit);\n }\n\n invalidate(filter?: { readonly prefixKey?: string; readonly provider?: ProviderId }): number {\n const now = this.clock();\n const keyFilter = filter?.prefixKey;\n const providerFilter = filter?.provider;\n const matchesKey = (key: string): boolean => keyFilter === undefined || key === keyFilter;\n\n // Resolve the matching prefix set first, then clear every store in one pass. The\n // prefix registry attributes a provider to each tracked prefix, and the resource\n // registry carries its own attribution, so provider-scoped invalidation covers both.\n const matched = new Set<string>();\n for (const [key, provider] of this.prefixKeys) {\n if (matchesKey(key) && (providerFilter === undefined || provider === providerFilter)) {\n matched.add(key);\n }\n }\n for (const [key, record] of this.resources) {\n if (matchesKey(key) && (providerFilter === undefined || record.provider === providerFilter)) {\n matched.add(key);\n }\n }\n // Fingerprint lineages carry no provider attribution of their own, so under a provider\n // filter only prefixes attributed above are pruned. Without one, every lineage whose\n // prefix key matches goes, including lineages for capped prefixes the registry never\n // tracked, exactly the ones a full clear must not leave behind.\n const pruned = this.fingerprints.prune((key) =>\n providerFilter === undefined ? matchesKey(key) : matched.has(key),\n );\n for (const key of pruned) {\n matched.add(key);\n }\n\n for (const key of matched) {\n this.prefixKeys.delete(key);\n this.keeper.remove(key);\n const record = this.resources.get(key);\n if (record !== undefined) {\n this.resources.delete(key);\n // The host mirrors this delete onto the provider, the handle may be orphaned or\n // scoped to a rotated credential, see the invalidate contract on the RACS type.\n this.emit({\n type: 'resource.action',\n directive: {\n kind: 'resource',\n action: 'delete',\n resourceKey: key,\n ttlSeconds: record.ttlSeconds,\n },\n timestamp: now,\n });\n }\n }\n return matched.size;\n }\n\n profileOf(provider: ProviderId): ProviderProfile {\n return resolveProfile(provider, this.profiles);\n }\n\n on(listener: TelemetryListener): () => void {\n this.listeners.push(listener);\n return (): void => {\n const index = this.listeners.indexOf(listener);\n if (index !== -1) {\n this.listeners.splice(index, 1);\n }\n };\n }\n\n async flush(): Promise<void> {\n if (this.state === undefined) {\n return;\n }\n // A flush issued before the startup restore resolves must not overwrite the persisted\n // snapshot with the empty pre-restore state, so it waits for the restore first.\n await this.restored;\n const resources: ResourceRecordJSON[] = [];\n for (const [key, record] of this.resources) {\n resources.push({\n key,\n provider: record.provider,\n ttlSeconds: record.ttlSeconds,\n lastWriteAt: record.lastWriteAt,\n });\n }\n const snapshot: StateSnapshot = {\n version: 1,\n savedAt: this.clock(),\n data: {\n ledger: this.ledger.toJSON(),\n fingerprints: this.fingerprints.toJSON(),\n keeper: this.keeper.toJSON(),\n resources,\n drifts: [...this.driftRing],\n },\n };\n await this.state.save(snapshot);\n }\n\n async close(): Promise<void> {\n await this.flush();\n this.listeners.length = 0;\n }\n\n /** Appends one drift report, dropping the oldest beyond {@link DRIFT_RING_CAPACITY}. */\n private pushDrift(report: DriftReport): void {\n this.driftRing.push(report);\n if (this.driftRing.length > DRIFT_RING_CAPACITY) {\n this.driftRing.shift();\n }\n }\n\n /**\n * Mirrors resource directives into the registry and telemetry: create and refresh start\n * a new TTL window, delete drops the record, reuse leaves the window untouched because\n * reading a resource does not rewrite its server-side TTL.\n */\n private applyResourceDirectives(\n provider: ProviderId,\n directives: readonly CacheDirective[],\n now: number,\n ): void {\n for (const directive of directives) {\n if (directive.kind !== 'resource') {\n continue;\n }\n if (directive.action === 'delete') {\n this.resources.delete(directive.resourceKey);\n } else if (directive.action === 'create' || directive.action === 'refresh') {\n this.resources.set(directive.resourceKey, {\n provider,\n ttlSeconds: directive.ttlSeconds,\n lastWriteAt: now,\n });\n }\n this.emit({ type: 'resource.action', directive, timestamp: now });\n }\n }\n\n /** Synchronous fan-out over a copy of the listener list, exceptions swallowed. */\n private emit(event: TelemetryEvent): void {\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch {\n // Listener exceptions are swallowed by contract, telemetry must never break the\n // engine's own hot path, see TelemetryListener.\n }\n }\n }\n\n /**\n * Defensive startup restore: each snapshot section is applied inside its own try/catch\n * with structural checks first, so one corrupt section never poisons the others and a\n * corrupt snapshot degrades to a fresh engine, never to a crash.\n */\n private async restore(state: StateBackend): Promise<void> {\n let snapshot: StateSnapshot | undefined;\n try {\n snapshot = await state.load();\n } catch {\n return;\n }\n if (snapshot === undefined) {\n return;\n }\n const data: Readonly<Record<string, unknown>> = snapshot.data;\n try {\n const section = data.ledger;\n if (\n isRecord(section) &&\n typeof section.maxPrefixes === 'number' &&\n Array.isArray(section.entries)\n ) {\n this.ledger = Ledger.fromJSON(\n { maxPrefixes: section.maxPrefixes, entries: section.entries },\n this.pricing,\n );\n }\n } catch {\n // Corrupt ledger section skipped, aggregates restart empty.\n }\n try {\n const section = data.fingerprints;\n if (\n isRecord(section) &&\n typeof section.capacity === 'number' &&\n Array.isArray(section.entries)\n ) {\n this.fingerprints = Fingerprints.fromJSON({\n capacity: section.capacity,\n entries: section.entries,\n });\n }\n } catch {\n // Corrupt fingerprint section skipped, drift baselines restart empty.\n }\n try {\n const section = data.keeper;\n if (\n isRecord(section) &&\n typeof section.capacity === 'number' &&\n Array.isArray(section.entries)\n ) {\n this.keeper = TtlKeeper.fromJSON({ capacity: section.capacity, entries: section.entries });\n }\n } catch {\n // Corrupt keeper section skipped, refresh schedule restarts empty.\n }\n try {\n const section = data.resources;\n if (Array.isArray(section)) {\n for (const item of section) {\n if (isResourceRecordJSON(item)) {\n this.resources.set(item.key, {\n provider: item.provider,\n ttlSeconds: item.ttlSeconds,\n lastWriteAt: item.lastWriteAt,\n });\n }\n }\n }\n } catch {\n // Corrupt resource section skipped, the registry restarts empty.\n }\n try {\n const section = data.drifts;\n if (Array.isArray(section)) {\n const reports: DriftReport[] = [];\n for (const item of section) {\n if (isDriftReport(item)) {\n reports.push(item);\n }\n }\n // Restored reports predate anything observed since construction, so they go in\n // front of the ring before it is re-trimmed oldest-first.\n this.driftRing.unshift(...reports.slice(-DRIFT_RING_CAPACITY));\n while (this.driftRing.length > DRIFT_RING_CAPACITY) {\n this.driftRing.shift();\n }\n }\n } catch {\n // Corrupt drift section skipped, the ring restarts empty.\n }\n // The prefix registry is derived state and is not persisted; reseeding it from the\n // restored keeper and resource keys keeps the maxPrefixes accounting honest across\n // restarts instead of resetting the cap to zero. Both sources carry the provider, so\n // provider-scoped invalidation keeps working across restarts too.\n for (const entry of this.keeper.toJSON().entries) {\n this.prefixKeys.set(entry.prefixKey, entry.provider);\n }\n for (const [key, record] of this.resources) {\n this.prefixKeys.set(key, record.provider);\n }\n }\n}\n\n/**\n * Creates one RACS (Remote Agent Context Store) engine, the single entry point of the\n * package. Zero-config by default: no options yields a fully working in-memory engine with\n * the shipped provider profiles, seed 7, a 1000-prefix cap, and the platform wall clock.\n *\n * Persistence note: when {@link RACSOptions.state} is given, the previous snapshot is\n * restored asynchronously after construction, section by section, skipping anything\n * corrupt. Hosts that need restored state before their first plan should `await\n * racs.flush()` once after construction, flush waits for the restore to settle.\n *\n * @param options - See {@link RACSOptions}, every field optional.\n * @returns The engine, see {@link RACS} for the full surface contract.\n *\n * @example\n * ```ts\n * const racs = createRACS({ seed: 42 });\n * const plan = racs.plan({\n * provider: 'anthropic',\n * model: 'claude-sonnet-4-5',\n * segments: [\n * { id: 'system', role: 'system', stability: 'stable', content: SYSTEM_PROMPT },\n * { id: 'turn', role: 'dynamic', stability: 'volatile', content: userTurn },\n * ],\n * reuse: { intervalSeconds: 60 },\n * });\n * // Apply plan.directives to the API call the host owns, then report usage back:\n * racs.record({ provider: 'anthropic', model: 'claude-sonnet-4-5', prefixKey: plan.prefixKey,\n * inputTokens: 5000, cacheReadTokens: 4200 });\n * ```\n */\nexport function createRACS(options: RACSOptions = {}): RACS {\n return new RacsEngine(options);\n}\n","/**\n * Key-value state backend of RACS (Remote Agent Context Store): one JSON string under one\n * key in any structural {@link KvLike} store, the persistence shape for edge runtimes and\n * multi-instance hosts that already run Redis, Upstash, or Cloudflare KV.\n *\n * RACS never constructs the client and never sees connection credentials, the host passes\n * a ready object, per the product invariant.\n *\n * @packageDocumentation\n */\n\nimport { RacsError } from '../errors.js';\nimport type { KvLike, StateBackend, StateSnapshot } from '../types.js';\n\n/** Human-readable rendering of an unknown thrown value for error messages. */\nfunction describe(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Parses and validates one serialized snapshot. Duplicated from the file backend on\n * purpose, the state backends stay self-contained so bundlers tree-shake each one\n * independently.\n *\n * @throws RacsError code `'ERR_STATE_LOAD'` when the text is not valid JSON or not a\n * snapshot-shaped object.\n * @throws RacsError code `'ERR_STATE_VERSION'` unless `version` is the literal 1.\n */\nfunction parseSnapshot(text: string, source: string): StateSnapshot {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (error: unknown) {\n throw new RacsError(\n `RACS state at ${source} is not valid JSON: ${describe(error)}`,\n 'ERR_STATE_LOAD',\n );\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new RacsError(\n `RACS state at ${source} is not a snapshot object, found ${typeof parsed}.`,\n 'ERR_STATE_LOAD',\n );\n }\n const record = parsed as Record<string, unknown>;\n if (record.version !== 1) {\n throw new RacsError(\n `RACS state at ${source} has unsupported snapshot version ${String(record.version)}, expected 1.`,\n 'ERR_STATE_VERSION',\n );\n }\n const savedAt = record.savedAt;\n const data = record.data;\n if (typeof savedAt !== 'number' || typeof data !== 'object' || data === null) {\n throw new RacsError(\n `RACS state at ${source} is missing the savedAt or data field of a version 1 snapshot.`,\n 'ERR_STATE_LOAD',\n );\n }\n return { version: 1, savedAt, data: data as Readonly<Record<string, unknown>> };\n}\n\n/**\n * Creates a state backend persisting snapshots as one JSON string in a key-value store.\n *\n * Any client exposing string get, set, and delete wraps into {@link KvLike} in one line,\n * no adapter package needed:\n *\n * @example\n * ```ts\n * // Redis (node-redis or ioredis):\n * const state = kvState({\n * get: (k) => redis.get(k),\n * set: (k, v) => redis.set(k, v),\n * delete: (k) => redis.del(k),\n * });\n *\n * // Upstash Redis:\n * const state = kvState({\n * get: (k) => upstash.get<string>(k),\n * set: (k, v) => upstash.set(k, v),\n * delete: (k) => upstash.del(k),\n * });\n *\n * // Cloudflare KV (a binding named RACS_KV):\n * const state = kvState({\n * get: (k) => env.RACS_KV.get(k),\n * set: (k, v) => env.RACS_KV.put(k, v),\n * delete: (k) => env.RACS_KV.delete(k),\n * });\n * ```\n *\n * Load tolerates both `null` and `undefined` from `get`, the two absence conventions in\n * the wild, and returns `undefined` for either, the normal first-run case. A present but\n * unparseable value throws RacsError `'ERR_STATE_LOAD'`, and a parseable value with the\n * wrong snapshot version throws RacsError `'ERR_STATE_VERSION'`.\n *\n * @param kv - The ready client, see {@link KvLike}.\n * @param key - Storage key for the snapshot, namespace it per engine when several engines\n * share one store.\n */\nexport function kvState(kv: KvLike, key = 'racs:state'): StateBackend {\n return {\n async load(): Promise<StateSnapshot | undefined> {\n const raw = await kv.get(key);\n if (raw === undefined || raw === null) {\n return undefined;\n }\n return parseSnapshot(raw, `kv key \"${key}\"`);\n },\n async save(snapshot: StateSnapshot): Promise<void> {\n await kv.set(key, JSON.stringify(snapshot));\n },\n };\n}\n","/**\n * In-memory state backend of RACS (Remote Agent Context Store): the zero-config default\n * persistence shape, a snapshot held in a closure variable. Nothing survives the process,\n * which is exactly right for tests, demos, and hosts that persist elsewhere.\n *\n * @packageDocumentation\n */\n\nimport type { StateBackend, StateSnapshot } from '../types.js';\n\n/**\n * Creates a state backend that keeps the latest snapshot in memory.\n *\n * Each call returns an independent backend with its own closure variable, two engines\n * given two `memoryState()` results never see each other's snapshots. The snapshot object\n * is stored by reference, callers must treat saved snapshots as immutable, which the\n * {@link StateSnapshot} readonly contract already requires.\n *\n * @returns A {@link StateBackend} whose `load` resolves to the last saved snapshot, or\n * `undefined` before the first save.\n */\nexport function memoryState(): StateBackend {\n let snapshot: StateSnapshot | undefined;\n return {\n load(): Promise<StateSnapshot | undefined> {\n return Promise.resolve(snapshot);\n },\n save(next: StateSnapshot): Promise<void> {\n snapshot = next;\n return Promise.resolve();\n },\n };\n}\n"]}
|