@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/integrations/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Sibling-package bridges of RACS (Remote Agent Context Store): four adapters wiring a\n * running engine to the rest of the @takk family, @takk/noeticos parameter tuning,\n * @takk/behavioralai behavioral observability, @takk/modelchain model routing, and\n * @takk/keymesh credential rotation.\n *\n * Optional-peer pattern: every sibling shape in this module is a LOCAL structural\n * interface. Nothing here imports a sibling package at runtime or at the type level, so\n * the siblings stay optional peer dependencies, the published real objects satisfy these\n * shapes structurally, and the zero-runtime-dependency invariant of the package survives\n * intact. Hosts pass ready instances in, exactly as they do with `KvLike` stores.\n *\n * Privacy posture, shared by every bridge: only prefix keys (hashes), token counts, USD\n * figures derived from counts, agent identifiers, and hit flags ever cross a bridge.\n * Prompt content never does, RACS never holds it in the first place.\n *\n * @packageDocumentation\n */\n\nimport type { CachePlan, CacheUsage, PlanInput, PricingTable, ProviderId, RACS } from '../types.js';\n\n/**\n * Structural freeze surface of a @takk/noeticos runtime, as {@link noeticosBridge}\n * consumes it.\n *\n * The published package exposes freezing as the module-level functions\n * `freezeTuning(runtime, agentId, reason)` and `releaseTuning(runtime, agentId)` next to\n * the `NoeticOS` runtime interface; {@link noeticosAdapter} folds that pair into this\n * object in one line. Any other tuning runtime can satisfy the same two methods directly.\n */\nexport interface NoeticOSLike {\n /** Pauses parameter tuning for the agent, recording the reason in the audit trail. */\n freeze(agentId: string, reason: string): void;\n /** Resumes parameter tuning for the agent. Releasing a non-frozen agent is a no-op. */\n release(agentId: string): void;\n}\n\n/**\n * Module shape of the real @takk/noeticos package, structurally: the two module-level\n * tuning functions the bridge needs. Members are method-style on purpose, method\n * parameters are checked bivariantly, so the published functions, whose first parameter\n * is the concrete `NoeticOS` runtime, satisfy `unknown` here without this module ever\n * naming the sibling type.\n */\nexport interface NoeticosModuleLike {\n /** The published `freezeTuning(runtime, agentId, reason)`. */\n freezeTuning(runtime: unknown, agentId: string, reason: string): void;\n /** The published `releaseTuning(runtime, agentId)`. */\n releaseTuning(runtime: unknown, agentId: string): void;\n}\n\n/**\n * Folds the real @takk/noeticos module surface into a {@link NoeticOSLike} bound to one\n * runtime, in one line per method.\n *\n * @param noeticosModule - The imported module, or any object carrying `freezeTuning` and\n * `releaseTuning` with the published signatures.\n * @param runtime - The `NoeticOS` runtime the functions act on, opaque to this package.\n * @returns A {@link NoeticOSLike} bound to that runtime.\n *\n * @example\n * ```ts\n * import * as noeticos from '@takk/noeticos';\n * import { noeticosAdapter } from '@takk/racs/integrations';\n *\n * const runtime = noeticos.createNoeticOS();\n * const like = noeticosAdapter(noeticos, runtime);\n * like.freeze('support-agent', 'manual maintenance window');\n * ```\n */\nexport function noeticosAdapter(\n noeticosModule: NoeticosModuleLike,\n runtime: unknown,\n): NoeticOSLike {\n return {\n freeze: (agentId, reason): void => noeticosModule.freezeTuning(runtime, agentId, reason),\n release: (agentId): void => noeticosModule.releaseTuning(runtime, agentId),\n };\n}\n\n/** Per-agent freeze bookkeeping of {@link noeticosBridge}. */\ninterface FreezeState {\n /** Prefix key the lineage drifted to, the baseline stable plans are counted against. */\n prefixKey: string;\n /** Consecutive zero-drift plans observed since the latest drift. */\n stablePlans: number;\n /** The drifting plan's own `'plan.created'` event is still pending and must not count. */\n skipNext: boolean;\n}\n\n/**\n * Freezes @takk/noeticos parameter tuning across prompt-prefix discontinuities.\n *\n * Rationale: parameter tuning must not learn across a prefix discontinuity, the reward\n * landscape moved. A drifted prefix changes hit ratio, latency, and cost all at once, so\n * reward samples taken right after the drift would be credited to parameter choices that\n * had nothing to do with them.\n *\n * Behavior: on every `'prefix.drifted'` event carrying an agentId (it flows in from\n * {@link PlanInput.agentId}), the bridge freezes that agent with a reason naming the\n * changed segments, then counts subsequent `'plan.created'` events for the agent with\n * zero drift and releases after `releaseAfterStablePlans` of them (default 3). A new\n * drift during the count re-freezes, which refreshes the audit trail, and restarts the\n * count.\n *\n * Disposal: the returned function only unsubscribes from telemetry. Agents frozen at\n * that moment stay frozen, releasing tuning silently would be a policy decision only the\n * host can take.\n *\n * @example\n * ```ts\n * import * as noeticos from '@takk/noeticos';\n * import { createRACS } from '@takk/racs';\n * import { noeticosAdapter, noeticosBridge } from '@takk/racs/integrations';\n *\n * const racs = createRACS();\n * const runtime = noeticos.createNoeticOS();\n * const dispose = noeticosBridge(racs, noeticosAdapter(noeticos, runtime), {\n * releaseAfterStablePlans: 3,\n * });\n * // Plans carrying an agentId now freeze that agent's tuning on prefix drift:\n * racs.plan({\n * agentId: 'support-agent',\n * provider: 'anthropic',\n * model: 'claude-sonnet-4-5',\n * segments: [{ id: 'system', role: 'system', stability: 'stable', content: SYSTEM }],\n * });\n * ```\n */\nexport function noeticosBridge(\n racs: RACS,\n noeticos: NoeticOSLike,\n options?: { readonly releaseAfterStablePlans?: number },\n): () => void {\n const releaseAfter = options?.releaseAfterStablePlans ?? 3;\n const frozen = new Map<string, FreezeState>();\n return racs.on((event) => {\n if (event.type === 'prefix.drifted') {\n const agentId = event.report.agentId;\n if (agentId === undefined) {\n return;\n }\n const segments = event.report.changedSegmentIds.join(', ');\n try {\n noeticos.freeze(\n agentId,\n `RACS prefix drift: changed segments [${segments}], ` +\n `${event.report.invalidatedTokens} cached prefix tokens invalidated.`,\n );\n } catch {\n // Telemetry listeners must not throw, see TelemetryListener; a failing sibling\n // call is contained here instead of leaning on the engine's safety net.\n }\n frozen.set(agentId, {\n prefixKey: event.report.prefixKey,\n stablePlans: 0,\n skipNext: true,\n });\n return;\n }\n if (event.type !== 'plan.created') {\n return;\n }\n // The prefix key embeds the agent identity, so matching on it is matching the agent.\n for (const [agentId, state] of frozen) {\n if (state.prefixKey !== event.plan.prefixKey) {\n continue;\n }\n if (state.skipNext) {\n // The drifting plan emits 'prefix.drifted' first and 'plan.created' second; the\n // skip flag keeps that plan from counting toward its own release.\n state.skipNext = false;\n break;\n }\n state.stablePlans += 1;\n if (state.stablePlans >= releaseAfter) {\n frozen.delete(agentId);\n try {\n noeticos.release(agentId);\n } catch {\n // Same containment as freeze above.\n }\n }\n break;\n }\n });\n}\n\n/**\n * The synthetic turn {@link behavioralaiBridge} reports, a narrow structural slice of\n * the sibling's `TurnObservation`, field names verbatim from the published\n * @takk/behavioralai types.\n */\nexport interface CacheTurnObservation {\n /** Behavioral profile the turn belongs to, the bridge's `options.agentId`. */\n readonly agentId: string;\n /** End-to-end latency in milliseconds. Declared for shape parity, never populated. */\n readonly latencyMs?: number;\n /** Cache-write spend of the call in USD, present when pricing covers the model. */\n readonly costUsd?: number;\n /** Always false, a recorded usage is a completed call. */\n readonly error?: boolean;\n /** Keys and counts only: the prefix key (a hash) and the hit flag. */\n readonly metadata?: Readonly<Record<string, string>>;\n}\n\n/**\n * Structural observation surface of a @takk/behavioralai engine. The real\n * `BehavioralAI.observe(turn)` returns a drift report; the bridge has no use for it, so\n * the return type stays `unknown`.\n */\nexport interface BehavioralAILike {\n /** Ingests one observed turn into the behavioral fingerprint. */\n observe(turn: CacheTurnObservation): unknown;\n}\n\n/**\n * Cache-write spend of one usage record in USD, `undefined` when the table does not\n * cover the model or misses a TTL tier the call wrote to: an unpriceable turn is omitted\n * entirely rather than underreported.\n */\nfunction writeCostUsd(usage: CacheUsage, pricing: PricingTable | undefined): number | undefined {\n const card = pricing?.[usage.model];\n if (card === undefined) {\n return undefined;\n }\n const write5m = usage.cacheWriteTokens5m ?? 0;\n const write1h = usage.cacheWriteTokens1h ?? 0;\n if (write5m > 0 && card.cacheWrite5mPerMTok === undefined) {\n return undefined;\n }\n if (write1h > 0 && card.cacheWrite1hPerMTok === undefined) {\n return undefined;\n }\n const spend =\n write5m * (card.cacheWrite5mPerMTok ?? 0) + write1h * (card.cacheWrite1hPerMTok ?? 0);\n return spend / 1_000_000;\n}\n\n/**\n * Turns the cache itself into a behaviorally observed agent of @takk/behavioralai.\n *\n * Behavior: on every `'usage.recorded'` event the bridge reports one synthetic turn\n * under `options.agentId` (default `'racs-cache'`): `error` false, `metadata` carrying\n * the prefix key (when the usage was linked to a plan) and the hit flag as\n * `'true' | 'false'`, and `costUsd` set to the call's cache-write spend when pricing\n * covers the model. A healthy cache fingerprints as near-zero write cost and hit\n * `'true'` almost always, so a hit-ratio collapse, a burst of misses paying write\n * premiums, shifts the fingerprint and surfaces as behavioral drift in the sibling.\n *\n * Pricing design, the simplest honest one: the per-turn write cost is computed from the\n * usage record's own write token counts and the table passed in `options.pricing` (same\n * shape as `RACSOptions.pricing`). Reading `racs.stats` instead would only offer\n * cumulative aggregates, and deriving per-turn deltas from those would need shadow state\n * and would misattribute under interleaved recording. Without pricing coverage `costUsd`\n * is omitted, never guessed.\n *\n * Privacy posture: keys and counts only. The bridge forwards the prefix key (a hash), a\n * hit flag, and a USD figure derived from token counts. Prompt content never crosses.\n *\n * @example\n * ```ts\n * import { createBehavioralAI } from '@takk/behavioralai';\n * import { createRACS } from '@takk/racs';\n * import { behavioralaiBridge } from '@takk/racs/integrations';\n *\n * const racs = createRACS();\n * const behavioral = createBehavioralAI();\n * const dispose = behavioralaiBridge(racs, behavioral, {\n * pricing: {\n * 'claude-sonnet-4-5': {\n * inputPerMTok: 3,\n * cacheReadPerMTok: 0.3,\n * cacheWrite5mPerMTok: 3.75,\n * cacheWrite1hPerMTok: 6,\n * },\n * },\n * });\n * racs.record({\n * provider: 'anthropic',\n * model: 'claude-sonnet-4-5',\n * prefixKey: plan.prefixKey,\n * inputTokens: 5000,\n * cacheReadTokens: 4200,\n * });\n * // -> behavioral.observe({ agentId: 'racs-cache', costUsd: 0, error: false,\n * // metadata: { prefixKey: plan.prefixKey, hit: 'true' } })\n * ```\n */\nexport function behavioralaiBridge(\n racs: RACS,\n behavioral: BehavioralAILike,\n options?: { readonly agentId?: string; readonly pricing?: PricingTable },\n): () => void {\n const agentId = options?.agentId ?? 'racs-cache';\n const pricing = options?.pricing;\n return racs.on((event) => {\n if (event.type !== 'usage.recorded') {\n return;\n }\n const costUsd = writeCostUsd(event.usage, pricing);\n const turn: CacheTurnObservation = {\n agentId,\n error: false,\n metadata: {\n ...(event.usage.prefixKey !== undefined ? { prefixKey: event.usage.prefixKey } : {}),\n hit: event.hit ? 'true' : 'false',\n },\n ...(costUsd !== undefined ? { costUsd } : {}),\n };\n try {\n behavioral.observe(turn);\n } catch {\n // Telemetry listeners must not throw, see TelemetryListener; a failing sibling\n // call is contained here instead of leaning on the engine's safety net.\n }\n });\n}\n\n/** Per-model cache planning surface returned by {@link modelchainBridge}. */\nexport interface ModelchainCachePlanner {\n /**\n * Plans the cache for one routed model: `base` is the model-agnostic plan input,\n * `modelId` is the id the router actually picked. Because the deterministic prefix key\n * includes the model, every routed model gets its own prefix key, fingerprint lineage,\n * and keep-warm schedule, which is exactly right: provider caches are per-model, a\n * prefix cached for one model is cold for every other.\n */\n planForModel(base: Omit<PlanInput, 'model'>, modelId: string): CachePlan;\n}\n\n/**\n * Pure helper for @takk/modelchain routed traffic: per-model cache plans from one shared\n * base input. No subscriptions, no state, just {@link RACS.plan} with the routed model\n * spliced in.\n *\n * @example\n * ```ts\n * import { createModelchain } from '@takk/modelchain';\n * import { createRACS } from '@takk/racs';\n * import { modelchainBridge } from '@takk/racs/integrations';\n *\n * const racs = createRACS();\n * const planner = modelchainBridge(racs);\n * const router = createModelchain({ models });\n *\n * const response = await router.complete({ prompt: userTurn, system: SYSTEM });\n * // CompletionResponse.modelId names the model the router picked; plan its cache:\n * const plan = planner.planForModel(\n * {\n * provider: 'openai',\n * segments: [\n * { id: 'system', role: 'system', stability: 'stable', content: SYSTEM },\n * { id: 'turn', role: 'dynamic', stability: 'volatile', content: userTurn },\n * ],\n * reuse: { intervalSeconds: 45 },\n * },\n * response.modelId,\n * );\n * ```\n */\nexport function modelchainBridge(racs: RACS): ModelchainCachePlanner {\n return {\n planForModel(base: Omit<PlanInput, 'model'>, modelId: string): CachePlan {\n return racs.plan({ ...base, model: modelId });\n },\n };\n}\n\n/**\n * The keymesh telemetry events that signal credentials in flux, names verbatim from the\n * published @takk/keymesh event union. The bridge subscribes to `'key.rotated'` and\n * `'circuit.open'`; `'all.exhausted'` is part of the structural surface so hosts can\n * hang their own handlers off the same {@link KeymeshLike} object.\n */\nexport type KeymeshCredentialEventName = 'key.rotated' | 'circuit.open' | 'all.exhausted';\n\n/**\n * Structural on/off pair of a keymesh client, the `KeymeshExtras` surface every\n * `createKeymesh` client carries. The real methods are generic over the full event\n * union; this narrowed method pair is satisfied by them structurally.\n */\nexport interface KeymeshLike {\n /** Subscribes a handler to one telemetry event. */\n on(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;\n /** Unsubscribes a previously subscribed handler. */\n off(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;\n}\n\n/**\n * Invalidates provider-scoped cache state when @takk/keymesh signals credentials in\n * flux: on `'key.rotated'` and on `'circuit.open'` the bridge calls\n * `racs.invalidate({ provider })` once per provider in `options.providers`, clearing\n * fingerprints, keep-warm schedules, and resource registry entries, with one\n * `'resource.action'` delete event per dropped resource for the host to mirror.\n *\n * Why rotation invalidates: cache entries and cachedContent handles may be scoped to the\n * credential or workspace that created them. Gemini `cachedContents` especially, a\n * resource created under a rotated or disabled key may be unreachable or orphaned, and\n * silently still billing storage. Routing-key and breakpoint caches can land in a\n * different account-side namespace under the new credential. Re-planning from scratch\n * costs one write premium; planning against a dead handle costs failed calls. The same\n * logic covers `'circuit.open'`: a credential in cooldown leaves its provider-side\n * resources unrefreshable, so they expire mid-schedule anyway.\n *\n * @example\n * ```ts\n * import { createKeymesh } from '@takk/keymesh';\n * import { createRACS } from '@takk/racs';\n * import { keymeshBridge } from '@takk/racs/integrations';\n *\n * const racs = createRACS();\n * const gemini = createKeymesh({ provider: geminiAdapter, keys: geminiKeys });\n * const dispose = keymeshBridge(racs, gemini, { providers: ['google'] });\n * // From here a rotation or an opened circuit clears every google-attributed prefix\n * // and the host re-plans, recreating provider resources under the new credential.\n * ```\n */\nexport function keymeshBridge(\n racs: RACS,\n keymesh: KeymeshLike,\n options: { readonly providers: readonly ProviderId[] },\n): () => void {\n const onCredentialChange = (): void => {\n for (const provider of options.providers) {\n racs.invalidate({ provider });\n }\n };\n keymesh.on('key.rotated', onCredentialChange);\n keymesh.on('circuit.open', onCredentialChange);\n return (): void => {\n keymesh.off('key.rotated', onCredentialChange);\n keymesh.off('circuit.open', onCredentialChange);\n };\n}\n"]}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { P as PlanInput, a as CachePlan, R as RACS, h as PricingTable, j as ProviderId } from '../types-DQ7-9sk3.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sibling-package bridges of RACS (Remote Agent Context Store): four adapters wiring a
|
|
5
|
+
* running engine to the rest of the @takk family, @takk/noeticos parameter tuning,
|
|
6
|
+
* @takk/behavioralai behavioral observability, @takk/modelchain model routing, and
|
|
7
|
+
* @takk/keymesh credential rotation.
|
|
8
|
+
*
|
|
9
|
+
* Optional-peer pattern: every sibling shape in this module is a LOCAL structural
|
|
10
|
+
* interface. Nothing here imports a sibling package at runtime or at the type level, so
|
|
11
|
+
* the siblings stay optional peer dependencies, the published real objects satisfy these
|
|
12
|
+
* shapes structurally, and the zero-runtime-dependency invariant of the package survives
|
|
13
|
+
* intact. Hosts pass ready instances in, exactly as they do with `KvLike` stores.
|
|
14
|
+
*
|
|
15
|
+
* Privacy posture, shared by every bridge: only prefix keys (hashes), token counts, USD
|
|
16
|
+
* figures derived from counts, agent identifiers, and hit flags ever cross a bridge.
|
|
17
|
+
* Prompt content never does, RACS never holds it in the first place.
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Structural freeze surface of a @takk/noeticos runtime, as {@link noeticosBridge}
|
|
24
|
+
* consumes it.
|
|
25
|
+
*
|
|
26
|
+
* The published package exposes freezing as the module-level functions
|
|
27
|
+
* `freezeTuning(runtime, agentId, reason)` and `releaseTuning(runtime, agentId)` next to
|
|
28
|
+
* the `NoeticOS` runtime interface; {@link noeticosAdapter} folds that pair into this
|
|
29
|
+
* object in one line. Any other tuning runtime can satisfy the same two methods directly.
|
|
30
|
+
*/
|
|
31
|
+
interface NoeticOSLike {
|
|
32
|
+
/** Pauses parameter tuning for the agent, recording the reason in the audit trail. */
|
|
33
|
+
freeze(agentId: string, reason: string): void;
|
|
34
|
+
/** Resumes parameter tuning for the agent. Releasing a non-frozen agent is a no-op. */
|
|
35
|
+
release(agentId: string): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Module shape of the real @takk/noeticos package, structurally: the two module-level
|
|
39
|
+
* tuning functions the bridge needs. Members are method-style on purpose, method
|
|
40
|
+
* parameters are checked bivariantly, so the published functions, whose first parameter
|
|
41
|
+
* is the concrete `NoeticOS` runtime, satisfy `unknown` here without this module ever
|
|
42
|
+
* naming the sibling type.
|
|
43
|
+
*/
|
|
44
|
+
interface NoeticosModuleLike {
|
|
45
|
+
/** The published `freezeTuning(runtime, agentId, reason)`. */
|
|
46
|
+
freezeTuning(runtime: unknown, agentId: string, reason: string): void;
|
|
47
|
+
/** The published `releaseTuning(runtime, agentId)`. */
|
|
48
|
+
releaseTuning(runtime: unknown, agentId: string): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Folds the real @takk/noeticos module surface into a {@link NoeticOSLike} bound to one
|
|
52
|
+
* runtime, in one line per method.
|
|
53
|
+
*
|
|
54
|
+
* @param noeticosModule - The imported module, or any object carrying `freezeTuning` and
|
|
55
|
+
* `releaseTuning` with the published signatures.
|
|
56
|
+
* @param runtime - The `NoeticOS` runtime the functions act on, opaque to this package.
|
|
57
|
+
* @returns A {@link NoeticOSLike} bound to that runtime.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import * as noeticos from '@takk/noeticos';
|
|
62
|
+
* import { noeticosAdapter } from '@takk/racs/integrations';
|
|
63
|
+
*
|
|
64
|
+
* const runtime = noeticos.createNoeticOS();
|
|
65
|
+
* const like = noeticosAdapter(noeticos, runtime);
|
|
66
|
+
* like.freeze('support-agent', 'manual maintenance window');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare function noeticosAdapter(noeticosModule: NoeticosModuleLike, runtime: unknown): NoeticOSLike;
|
|
70
|
+
/**
|
|
71
|
+
* Freezes @takk/noeticos parameter tuning across prompt-prefix discontinuities.
|
|
72
|
+
*
|
|
73
|
+
* Rationale: parameter tuning must not learn across a prefix discontinuity, the reward
|
|
74
|
+
* landscape moved. A drifted prefix changes hit ratio, latency, and cost all at once, so
|
|
75
|
+
* reward samples taken right after the drift would be credited to parameter choices that
|
|
76
|
+
* had nothing to do with them.
|
|
77
|
+
*
|
|
78
|
+
* Behavior: on every `'prefix.drifted'` event carrying an agentId (it flows in from
|
|
79
|
+
* {@link PlanInput.agentId}), the bridge freezes that agent with a reason naming the
|
|
80
|
+
* changed segments, then counts subsequent `'plan.created'` events for the agent with
|
|
81
|
+
* zero drift and releases after `releaseAfterStablePlans` of them (default 3). A new
|
|
82
|
+
* drift during the count re-freezes, which refreshes the audit trail, and restarts the
|
|
83
|
+
* count.
|
|
84
|
+
*
|
|
85
|
+
* Disposal: the returned function only unsubscribes from telemetry. Agents frozen at
|
|
86
|
+
* that moment stay frozen, releasing tuning silently would be a policy decision only the
|
|
87
|
+
* host can take.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import * as noeticos from '@takk/noeticos';
|
|
92
|
+
* import { createRACS } from '@takk/racs';
|
|
93
|
+
* import { noeticosAdapter, noeticosBridge } from '@takk/racs/integrations';
|
|
94
|
+
*
|
|
95
|
+
* const racs = createRACS();
|
|
96
|
+
* const runtime = noeticos.createNoeticOS();
|
|
97
|
+
* const dispose = noeticosBridge(racs, noeticosAdapter(noeticos, runtime), {
|
|
98
|
+
* releaseAfterStablePlans: 3,
|
|
99
|
+
* });
|
|
100
|
+
* // Plans carrying an agentId now freeze that agent's tuning on prefix drift:
|
|
101
|
+
* racs.plan({
|
|
102
|
+
* agentId: 'support-agent',
|
|
103
|
+
* provider: 'anthropic',
|
|
104
|
+
* model: 'claude-sonnet-4-5',
|
|
105
|
+
* segments: [{ id: 'system', role: 'system', stability: 'stable', content: SYSTEM }],
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
declare function noeticosBridge(racs: RACS, noeticos: NoeticOSLike, options?: {
|
|
110
|
+
readonly releaseAfterStablePlans?: number;
|
|
111
|
+
}): () => void;
|
|
112
|
+
/**
|
|
113
|
+
* The synthetic turn {@link behavioralaiBridge} reports, a narrow structural slice of
|
|
114
|
+
* the sibling's `TurnObservation`, field names verbatim from the published
|
|
115
|
+
* @takk/behavioralai types.
|
|
116
|
+
*/
|
|
117
|
+
interface CacheTurnObservation {
|
|
118
|
+
/** Behavioral profile the turn belongs to, the bridge's `options.agentId`. */
|
|
119
|
+
readonly agentId: string;
|
|
120
|
+
/** End-to-end latency in milliseconds. Declared for shape parity, never populated. */
|
|
121
|
+
readonly latencyMs?: number;
|
|
122
|
+
/** Cache-write spend of the call in USD, present when pricing covers the model. */
|
|
123
|
+
readonly costUsd?: number;
|
|
124
|
+
/** Always false, a recorded usage is a completed call. */
|
|
125
|
+
readonly error?: boolean;
|
|
126
|
+
/** Keys and counts only: the prefix key (a hash) and the hit flag. */
|
|
127
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Structural observation surface of a @takk/behavioralai engine. The real
|
|
131
|
+
* `BehavioralAI.observe(turn)` returns a drift report; the bridge has no use for it, so
|
|
132
|
+
* the return type stays `unknown`.
|
|
133
|
+
*/
|
|
134
|
+
interface BehavioralAILike {
|
|
135
|
+
/** Ingests one observed turn into the behavioral fingerprint. */
|
|
136
|
+
observe(turn: CacheTurnObservation): unknown;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Turns the cache itself into a behaviorally observed agent of @takk/behavioralai.
|
|
140
|
+
*
|
|
141
|
+
* Behavior: on every `'usage.recorded'` event the bridge reports one synthetic turn
|
|
142
|
+
* under `options.agentId` (default `'racs-cache'`): `error` false, `metadata` carrying
|
|
143
|
+
* the prefix key (when the usage was linked to a plan) and the hit flag as
|
|
144
|
+
* `'true' | 'false'`, and `costUsd` set to the call's cache-write spend when pricing
|
|
145
|
+
* covers the model. A healthy cache fingerprints as near-zero write cost and hit
|
|
146
|
+
* `'true'` almost always, so a hit-ratio collapse, a burst of misses paying write
|
|
147
|
+
* premiums, shifts the fingerprint and surfaces as behavioral drift in the sibling.
|
|
148
|
+
*
|
|
149
|
+
* Pricing design, the simplest honest one: the per-turn write cost is computed from the
|
|
150
|
+
* usage record's own write token counts and the table passed in `options.pricing` (same
|
|
151
|
+
* shape as `RACSOptions.pricing`). Reading `racs.stats` instead would only offer
|
|
152
|
+
* cumulative aggregates, and deriving per-turn deltas from those would need shadow state
|
|
153
|
+
* and would misattribute under interleaved recording. Without pricing coverage `costUsd`
|
|
154
|
+
* is omitted, never guessed.
|
|
155
|
+
*
|
|
156
|
+
* Privacy posture: keys and counts only. The bridge forwards the prefix key (a hash), a
|
|
157
|
+
* hit flag, and a USD figure derived from token counts. Prompt content never crosses.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { createBehavioralAI } from '@takk/behavioralai';
|
|
162
|
+
* import { createRACS } from '@takk/racs';
|
|
163
|
+
* import { behavioralaiBridge } from '@takk/racs/integrations';
|
|
164
|
+
*
|
|
165
|
+
* const racs = createRACS();
|
|
166
|
+
* const behavioral = createBehavioralAI();
|
|
167
|
+
* const dispose = behavioralaiBridge(racs, behavioral, {
|
|
168
|
+
* pricing: {
|
|
169
|
+
* 'claude-sonnet-4-5': {
|
|
170
|
+
* inputPerMTok: 3,
|
|
171
|
+
* cacheReadPerMTok: 0.3,
|
|
172
|
+
* cacheWrite5mPerMTok: 3.75,
|
|
173
|
+
* cacheWrite1hPerMTok: 6,
|
|
174
|
+
* },
|
|
175
|
+
* },
|
|
176
|
+
* });
|
|
177
|
+
* racs.record({
|
|
178
|
+
* provider: 'anthropic',
|
|
179
|
+
* model: 'claude-sonnet-4-5',
|
|
180
|
+
* prefixKey: plan.prefixKey,
|
|
181
|
+
* inputTokens: 5000,
|
|
182
|
+
* cacheReadTokens: 4200,
|
|
183
|
+
* });
|
|
184
|
+
* // -> behavioral.observe({ agentId: 'racs-cache', costUsd: 0, error: false,
|
|
185
|
+
* // metadata: { prefixKey: plan.prefixKey, hit: 'true' } })
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
declare function behavioralaiBridge(racs: RACS, behavioral: BehavioralAILike, options?: {
|
|
189
|
+
readonly agentId?: string;
|
|
190
|
+
readonly pricing?: PricingTable;
|
|
191
|
+
}): () => void;
|
|
192
|
+
/** Per-model cache planning surface returned by {@link modelchainBridge}. */
|
|
193
|
+
interface ModelchainCachePlanner {
|
|
194
|
+
/**
|
|
195
|
+
* Plans the cache for one routed model: `base` is the model-agnostic plan input,
|
|
196
|
+
* `modelId` is the id the router actually picked. Because the deterministic prefix key
|
|
197
|
+
* includes the model, every routed model gets its own prefix key, fingerprint lineage,
|
|
198
|
+
* and keep-warm schedule, which is exactly right: provider caches are per-model, a
|
|
199
|
+
* prefix cached for one model is cold for every other.
|
|
200
|
+
*/
|
|
201
|
+
planForModel(base: Omit<PlanInput, 'model'>, modelId: string): CachePlan;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Pure helper for @takk/modelchain routed traffic: per-model cache plans from one shared
|
|
205
|
+
* base input. No subscriptions, no state, just {@link RACS.plan} with the routed model
|
|
206
|
+
* spliced in.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* import { createModelchain } from '@takk/modelchain';
|
|
211
|
+
* import { createRACS } from '@takk/racs';
|
|
212
|
+
* import { modelchainBridge } from '@takk/racs/integrations';
|
|
213
|
+
*
|
|
214
|
+
* const racs = createRACS();
|
|
215
|
+
* const planner = modelchainBridge(racs);
|
|
216
|
+
* const router = createModelchain({ models });
|
|
217
|
+
*
|
|
218
|
+
* const response = await router.complete({ prompt: userTurn, system: SYSTEM });
|
|
219
|
+
* // CompletionResponse.modelId names the model the router picked; plan its cache:
|
|
220
|
+
* const plan = planner.planForModel(
|
|
221
|
+
* {
|
|
222
|
+
* provider: 'openai',
|
|
223
|
+
* segments: [
|
|
224
|
+
* { id: 'system', role: 'system', stability: 'stable', content: SYSTEM },
|
|
225
|
+
* { id: 'turn', role: 'dynamic', stability: 'volatile', content: userTurn },
|
|
226
|
+
* ],
|
|
227
|
+
* reuse: { intervalSeconds: 45 },
|
|
228
|
+
* },
|
|
229
|
+
* response.modelId,
|
|
230
|
+
* );
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
declare function modelchainBridge(racs: RACS): ModelchainCachePlanner;
|
|
234
|
+
/**
|
|
235
|
+
* The keymesh telemetry events that signal credentials in flux, names verbatim from the
|
|
236
|
+
* published @takk/keymesh event union. The bridge subscribes to `'key.rotated'` and
|
|
237
|
+
* `'circuit.open'`; `'all.exhausted'` is part of the structural surface so hosts can
|
|
238
|
+
* hang their own handlers off the same {@link KeymeshLike} object.
|
|
239
|
+
*/
|
|
240
|
+
type KeymeshCredentialEventName = 'key.rotated' | 'circuit.open' | 'all.exhausted';
|
|
241
|
+
/**
|
|
242
|
+
* Structural on/off pair of a keymesh client, the `KeymeshExtras` surface every
|
|
243
|
+
* `createKeymesh` client carries. The real methods are generic over the full event
|
|
244
|
+
* union; this narrowed method pair is satisfied by them structurally.
|
|
245
|
+
*/
|
|
246
|
+
interface KeymeshLike {
|
|
247
|
+
/** Subscribes a handler to one telemetry event. */
|
|
248
|
+
on(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;
|
|
249
|
+
/** Unsubscribes a previously subscribed handler. */
|
|
250
|
+
off(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Invalidates provider-scoped cache state when @takk/keymesh signals credentials in
|
|
254
|
+
* flux: on `'key.rotated'` and on `'circuit.open'` the bridge calls
|
|
255
|
+
* `racs.invalidate({ provider })` once per provider in `options.providers`, clearing
|
|
256
|
+
* fingerprints, keep-warm schedules, and resource registry entries, with one
|
|
257
|
+
* `'resource.action'` delete event per dropped resource for the host to mirror.
|
|
258
|
+
*
|
|
259
|
+
* Why rotation invalidates: cache entries and cachedContent handles may be scoped to the
|
|
260
|
+
* credential or workspace that created them. Gemini `cachedContents` especially, a
|
|
261
|
+
* resource created under a rotated or disabled key may be unreachable or orphaned, and
|
|
262
|
+
* silently still billing storage. Routing-key and breakpoint caches can land in a
|
|
263
|
+
* different account-side namespace under the new credential. Re-planning from scratch
|
|
264
|
+
* costs one write premium; planning against a dead handle costs failed calls. The same
|
|
265
|
+
* logic covers `'circuit.open'`: a credential in cooldown leaves its provider-side
|
|
266
|
+
* resources unrefreshable, so they expire mid-schedule anyway.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* import { createKeymesh } from '@takk/keymesh';
|
|
271
|
+
* import { createRACS } from '@takk/racs';
|
|
272
|
+
* import { keymeshBridge } from '@takk/racs/integrations';
|
|
273
|
+
*
|
|
274
|
+
* const racs = createRACS();
|
|
275
|
+
* const gemini = createKeymesh({ provider: geminiAdapter, keys: geminiKeys });
|
|
276
|
+
* const dispose = keymeshBridge(racs, gemini, { providers: ['google'] });
|
|
277
|
+
* // From here a rotation or an opened circuit clears every google-attributed prefix
|
|
278
|
+
* // and the host re-plans, recreating provider resources under the new credential.
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function keymeshBridge(racs: RACS, keymesh: KeymeshLike, options: {
|
|
282
|
+
readonly providers: readonly ProviderId[];
|
|
283
|
+
}): () => void;
|
|
284
|
+
|
|
285
|
+
export { type BehavioralAILike, type CacheTurnObservation, type KeymeshCredentialEventName, type KeymeshLike, type ModelchainCachePlanner, type NoeticOSLike, type NoeticosModuleLike, behavioralaiBridge, keymeshBridge, modelchainBridge, noeticosAdapter, noeticosBridge };
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { P as PlanInput, a as CachePlan, R as RACS, h as PricingTable, j as ProviderId } from '../types-DQ7-9sk3.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Sibling-package bridges of RACS (Remote Agent Context Store): four adapters wiring a
|
|
5
|
+
* running engine to the rest of the @takk family, @takk/noeticos parameter tuning,
|
|
6
|
+
* @takk/behavioralai behavioral observability, @takk/modelchain model routing, and
|
|
7
|
+
* @takk/keymesh credential rotation.
|
|
8
|
+
*
|
|
9
|
+
* Optional-peer pattern: every sibling shape in this module is a LOCAL structural
|
|
10
|
+
* interface. Nothing here imports a sibling package at runtime or at the type level, so
|
|
11
|
+
* the siblings stay optional peer dependencies, the published real objects satisfy these
|
|
12
|
+
* shapes structurally, and the zero-runtime-dependency invariant of the package survives
|
|
13
|
+
* intact. Hosts pass ready instances in, exactly as they do with `KvLike` stores.
|
|
14
|
+
*
|
|
15
|
+
* Privacy posture, shared by every bridge: only prefix keys (hashes), token counts, USD
|
|
16
|
+
* figures derived from counts, agent identifiers, and hit flags ever cross a bridge.
|
|
17
|
+
* Prompt content never does, RACS never holds it in the first place.
|
|
18
|
+
*
|
|
19
|
+
* @packageDocumentation
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Structural freeze surface of a @takk/noeticos runtime, as {@link noeticosBridge}
|
|
24
|
+
* consumes it.
|
|
25
|
+
*
|
|
26
|
+
* The published package exposes freezing as the module-level functions
|
|
27
|
+
* `freezeTuning(runtime, agentId, reason)` and `releaseTuning(runtime, agentId)` next to
|
|
28
|
+
* the `NoeticOS` runtime interface; {@link noeticosAdapter} folds that pair into this
|
|
29
|
+
* object in one line. Any other tuning runtime can satisfy the same two methods directly.
|
|
30
|
+
*/
|
|
31
|
+
interface NoeticOSLike {
|
|
32
|
+
/** Pauses parameter tuning for the agent, recording the reason in the audit trail. */
|
|
33
|
+
freeze(agentId: string, reason: string): void;
|
|
34
|
+
/** Resumes parameter tuning for the agent. Releasing a non-frozen agent is a no-op. */
|
|
35
|
+
release(agentId: string): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Module shape of the real @takk/noeticos package, structurally: the two module-level
|
|
39
|
+
* tuning functions the bridge needs. Members are method-style on purpose, method
|
|
40
|
+
* parameters are checked bivariantly, so the published functions, whose first parameter
|
|
41
|
+
* is the concrete `NoeticOS` runtime, satisfy `unknown` here without this module ever
|
|
42
|
+
* naming the sibling type.
|
|
43
|
+
*/
|
|
44
|
+
interface NoeticosModuleLike {
|
|
45
|
+
/** The published `freezeTuning(runtime, agentId, reason)`. */
|
|
46
|
+
freezeTuning(runtime: unknown, agentId: string, reason: string): void;
|
|
47
|
+
/** The published `releaseTuning(runtime, agentId)`. */
|
|
48
|
+
releaseTuning(runtime: unknown, agentId: string): void;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Folds the real @takk/noeticos module surface into a {@link NoeticOSLike} bound to one
|
|
52
|
+
* runtime, in one line per method.
|
|
53
|
+
*
|
|
54
|
+
* @param noeticosModule - The imported module, or any object carrying `freezeTuning` and
|
|
55
|
+
* `releaseTuning` with the published signatures.
|
|
56
|
+
* @param runtime - The `NoeticOS` runtime the functions act on, opaque to this package.
|
|
57
|
+
* @returns A {@link NoeticOSLike} bound to that runtime.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import * as noeticos from '@takk/noeticos';
|
|
62
|
+
* import { noeticosAdapter } from '@takk/racs/integrations';
|
|
63
|
+
*
|
|
64
|
+
* const runtime = noeticos.createNoeticOS();
|
|
65
|
+
* const like = noeticosAdapter(noeticos, runtime);
|
|
66
|
+
* like.freeze('support-agent', 'manual maintenance window');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
declare function noeticosAdapter(noeticosModule: NoeticosModuleLike, runtime: unknown): NoeticOSLike;
|
|
70
|
+
/**
|
|
71
|
+
* Freezes @takk/noeticos parameter tuning across prompt-prefix discontinuities.
|
|
72
|
+
*
|
|
73
|
+
* Rationale: parameter tuning must not learn across a prefix discontinuity, the reward
|
|
74
|
+
* landscape moved. A drifted prefix changes hit ratio, latency, and cost all at once, so
|
|
75
|
+
* reward samples taken right after the drift would be credited to parameter choices that
|
|
76
|
+
* had nothing to do with them.
|
|
77
|
+
*
|
|
78
|
+
* Behavior: on every `'prefix.drifted'` event carrying an agentId (it flows in from
|
|
79
|
+
* {@link PlanInput.agentId}), the bridge freezes that agent with a reason naming the
|
|
80
|
+
* changed segments, then counts subsequent `'plan.created'` events for the agent with
|
|
81
|
+
* zero drift and releases after `releaseAfterStablePlans` of them (default 3). A new
|
|
82
|
+
* drift during the count re-freezes, which refreshes the audit trail, and restarts the
|
|
83
|
+
* count.
|
|
84
|
+
*
|
|
85
|
+
* Disposal: the returned function only unsubscribes from telemetry. Agents frozen at
|
|
86
|
+
* that moment stay frozen, releasing tuning silently would be a policy decision only the
|
|
87
|
+
* host can take.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import * as noeticos from '@takk/noeticos';
|
|
92
|
+
* import { createRACS } from '@takk/racs';
|
|
93
|
+
* import { noeticosAdapter, noeticosBridge } from '@takk/racs/integrations';
|
|
94
|
+
*
|
|
95
|
+
* const racs = createRACS();
|
|
96
|
+
* const runtime = noeticos.createNoeticOS();
|
|
97
|
+
* const dispose = noeticosBridge(racs, noeticosAdapter(noeticos, runtime), {
|
|
98
|
+
* releaseAfterStablePlans: 3,
|
|
99
|
+
* });
|
|
100
|
+
* // Plans carrying an agentId now freeze that agent's tuning on prefix drift:
|
|
101
|
+
* racs.plan({
|
|
102
|
+
* agentId: 'support-agent',
|
|
103
|
+
* provider: 'anthropic',
|
|
104
|
+
* model: 'claude-sonnet-4-5',
|
|
105
|
+
* segments: [{ id: 'system', role: 'system', stability: 'stable', content: SYSTEM }],
|
|
106
|
+
* });
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
declare function noeticosBridge(racs: RACS, noeticos: NoeticOSLike, options?: {
|
|
110
|
+
readonly releaseAfterStablePlans?: number;
|
|
111
|
+
}): () => void;
|
|
112
|
+
/**
|
|
113
|
+
* The synthetic turn {@link behavioralaiBridge} reports, a narrow structural slice of
|
|
114
|
+
* the sibling's `TurnObservation`, field names verbatim from the published
|
|
115
|
+
* @takk/behavioralai types.
|
|
116
|
+
*/
|
|
117
|
+
interface CacheTurnObservation {
|
|
118
|
+
/** Behavioral profile the turn belongs to, the bridge's `options.agentId`. */
|
|
119
|
+
readonly agentId: string;
|
|
120
|
+
/** End-to-end latency in milliseconds. Declared for shape parity, never populated. */
|
|
121
|
+
readonly latencyMs?: number;
|
|
122
|
+
/** Cache-write spend of the call in USD, present when pricing covers the model. */
|
|
123
|
+
readonly costUsd?: number;
|
|
124
|
+
/** Always false, a recorded usage is a completed call. */
|
|
125
|
+
readonly error?: boolean;
|
|
126
|
+
/** Keys and counts only: the prefix key (a hash) and the hit flag. */
|
|
127
|
+
readonly metadata?: Readonly<Record<string, string>>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Structural observation surface of a @takk/behavioralai engine. The real
|
|
131
|
+
* `BehavioralAI.observe(turn)` returns a drift report; the bridge has no use for it, so
|
|
132
|
+
* the return type stays `unknown`.
|
|
133
|
+
*/
|
|
134
|
+
interface BehavioralAILike {
|
|
135
|
+
/** Ingests one observed turn into the behavioral fingerprint. */
|
|
136
|
+
observe(turn: CacheTurnObservation): unknown;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Turns the cache itself into a behaviorally observed agent of @takk/behavioralai.
|
|
140
|
+
*
|
|
141
|
+
* Behavior: on every `'usage.recorded'` event the bridge reports one synthetic turn
|
|
142
|
+
* under `options.agentId` (default `'racs-cache'`): `error` false, `metadata` carrying
|
|
143
|
+
* the prefix key (when the usage was linked to a plan) and the hit flag as
|
|
144
|
+
* `'true' | 'false'`, and `costUsd` set to the call's cache-write spend when pricing
|
|
145
|
+
* covers the model. A healthy cache fingerprints as near-zero write cost and hit
|
|
146
|
+
* `'true'` almost always, so a hit-ratio collapse, a burst of misses paying write
|
|
147
|
+
* premiums, shifts the fingerprint and surfaces as behavioral drift in the sibling.
|
|
148
|
+
*
|
|
149
|
+
* Pricing design, the simplest honest one: the per-turn write cost is computed from the
|
|
150
|
+
* usage record's own write token counts and the table passed in `options.pricing` (same
|
|
151
|
+
* shape as `RACSOptions.pricing`). Reading `racs.stats` instead would only offer
|
|
152
|
+
* cumulative aggregates, and deriving per-turn deltas from those would need shadow state
|
|
153
|
+
* and would misattribute under interleaved recording. Without pricing coverage `costUsd`
|
|
154
|
+
* is omitted, never guessed.
|
|
155
|
+
*
|
|
156
|
+
* Privacy posture: keys and counts only. The bridge forwards the prefix key (a hash), a
|
|
157
|
+
* hit flag, and a USD figure derived from token counts. Prompt content never crosses.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { createBehavioralAI } from '@takk/behavioralai';
|
|
162
|
+
* import { createRACS } from '@takk/racs';
|
|
163
|
+
* import { behavioralaiBridge } from '@takk/racs/integrations';
|
|
164
|
+
*
|
|
165
|
+
* const racs = createRACS();
|
|
166
|
+
* const behavioral = createBehavioralAI();
|
|
167
|
+
* const dispose = behavioralaiBridge(racs, behavioral, {
|
|
168
|
+
* pricing: {
|
|
169
|
+
* 'claude-sonnet-4-5': {
|
|
170
|
+
* inputPerMTok: 3,
|
|
171
|
+
* cacheReadPerMTok: 0.3,
|
|
172
|
+
* cacheWrite5mPerMTok: 3.75,
|
|
173
|
+
* cacheWrite1hPerMTok: 6,
|
|
174
|
+
* },
|
|
175
|
+
* },
|
|
176
|
+
* });
|
|
177
|
+
* racs.record({
|
|
178
|
+
* provider: 'anthropic',
|
|
179
|
+
* model: 'claude-sonnet-4-5',
|
|
180
|
+
* prefixKey: plan.prefixKey,
|
|
181
|
+
* inputTokens: 5000,
|
|
182
|
+
* cacheReadTokens: 4200,
|
|
183
|
+
* });
|
|
184
|
+
* // -> behavioral.observe({ agentId: 'racs-cache', costUsd: 0, error: false,
|
|
185
|
+
* // metadata: { prefixKey: plan.prefixKey, hit: 'true' } })
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
declare function behavioralaiBridge(racs: RACS, behavioral: BehavioralAILike, options?: {
|
|
189
|
+
readonly agentId?: string;
|
|
190
|
+
readonly pricing?: PricingTable;
|
|
191
|
+
}): () => void;
|
|
192
|
+
/** Per-model cache planning surface returned by {@link modelchainBridge}. */
|
|
193
|
+
interface ModelchainCachePlanner {
|
|
194
|
+
/**
|
|
195
|
+
* Plans the cache for one routed model: `base` is the model-agnostic plan input,
|
|
196
|
+
* `modelId` is the id the router actually picked. Because the deterministic prefix key
|
|
197
|
+
* includes the model, every routed model gets its own prefix key, fingerprint lineage,
|
|
198
|
+
* and keep-warm schedule, which is exactly right: provider caches are per-model, a
|
|
199
|
+
* prefix cached for one model is cold for every other.
|
|
200
|
+
*/
|
|
201
|
+
planForModel(base: Omit<PlanInput, 'model'>, modelId: string): CachePlan;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Pure helper for @takk/modelchain routed traffic: per-model cache plans from one shared
|
|
205
|
+
* base input. No subscriptions, no state, just {@link RACS.plan} with the routed model
|
|
206
|
+
* spliced in.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```ts
|
|
210
|
+
* import { createModelchain } from '@takk/modelchain';
|
|
211
|
+
* import { createRACS } from '@takk/racs';
|
|
212
|
+
* import { modelchainBridge } from '@takk/racs/integrations';
|
|
213
|
+
*
|
|
214
|
+
* const racs = createRACS();
|
|
215
|
+
* const planner = modelchainBridge(racs);
|
|
216
|
+
* const router = createModelchain({ models });
|
|
217
|
+
*
|
|
218
|
+
* const response = await router.complete({ prompt: userTurn, system: SYSTEM });
|
|
219
|
+
* // CompletionResponse.modelId names the model the router picked; plan its cache:
|
|
220
|
+
* const plan = planner.planForModel(
|
|
221
|
+
* {
|
|
222
|
+
* provider: 'openai',
|
|
223
|
+
* segments: [
|
|
224
|
+
* { id: 'system', role: 'system', stability: 'stable', content: SYSTEM },
|
|
225
|
+
* { id: 'turn', role: 'dynamic', stability: 'volatile', content: userTurn },
|
|
226
|
+
* ],
|
|
227
|
+
* reuse: { intervalSeconds: 45 },
|
|
228
|
+
* },
|
|
229
|
+
* response.modelId,
|
|
230
|
+
* );
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
declare function modelchainBridge(racs: RACS): ModelchainCachePlanner;
|
|
234
|
+
/**
|
|
235
|
+
* The keymesh telemetry events that signal credentials in flux, names verbatim from the
|
|
236
|
+
* published @takk/keymesh event union. The bridge subscribes to `'key.rotated'` and
|
|
237
|
+
* `'circuit.open'`; `'all.exhausted'` is part of the structural surface so hosts can
|
|
238
|
+
* hang their own handlers off the same {@link KeymeshLike} object.
|
|
239
|
+
*/
|
|
240
|
+
type KeymeshCredentialEventName = 'key.rotated' | 'circuit.open' | 'all.exhausted';
|
|
241
|
+
/**
|
|
242
|
+
* Structural on/off pair of a keymesh client, the `KeymeshExtras` surface every
|
|
243
|
+
* `createKeymesh` client carries. The real methods are generic over the full event
|
|
244
|
+
* union; this narrowed method pair is satisfied by them structurally.
|
|
245
|
+
*/
|
|
246
|
+
interface KeymeshLike {
|
|
247
|
+
/** Subscribes a handler to one telemetry event. */
|
|
248
|
+
on(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;
|
|
249
|
+
/** Unsubscribes a previously subscribed handler. */
|
|
250
|
+
off(event: KeymeshCredentialEventName, handler: (event: unknown) => void): void;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Invalidates provider-scoped cache state when @takk/keymesh signals credentials in
|
|
254
|
+
* flux: on `'key.rotated'` and on `'circuit.open'` the bridge calls
|
|
255
|
+
* `racs.invalidate({ provider })` once per provider in `options.providers`, clearing
|
|
256
|
+
* fingerprints, keep-warm schedules, and resource registry entries, with one
|
|
257
|
+
* `'resource.action'` delete event per dropped resource for the host to mirror.
|
|
258
|
+
*
|
|
259
|
+
* Why rotation invalidates: cache entries and cachedContent handles may be scoped to the
|
|
260
|
+
* credential or workspace that created them. Gemini `cachedContents` especially, a
|
|
261
|
+
* resource created under a rotated or disabled key may be unreachable or orphaned, and
|
|
262
|
+
* silently still billing storage. Routing-key and breakpoint caches can land in a
|
|
263
|
+
* different account-side namespace under the new credential. Re-planning from scratch
|
|
264
|
+
* costs one write premium; planning against a dead handle costs failed calls. The same
|
|
265
|
+
* logic covers `'circuit.open'`: a credential in cooldown leaves its provider-side
|
|
266
|
+
* resources unrefreshable, so they expire mid-schedule anyway.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* import { createKeymesh } from '@takk/keymesh';
|
|
271
|
+
* import { createRACS } from '@takk/racs';
|
|
272
|
+
* import { keymeshBridge } from '@takk/racs/integrations';
|
|
273
|
+
*
|
|
274
|
+
* const racs = createRACS();
|
|
275
|
+
* const gemini = createKeymesh({ provider: geminiAdapter, keys: geminiKeys });
|
|
276
|
+
* const dispose = keymeshBridge(racs, gemini, { providers: ['google'] });
|
|
277
|
+
* // From here a rotation or an opened circuit clears every google-attributed prefix
|
|
278
|
+
* // and the host re-plans, recreating provider resources under the new credential.
|
|
279
|
+
* ```
|
|
280
|
+
*/
|
|
281
|
+
declare function keymeshBridge(racs: RACS, keymesh: KeymeshLike, options: {
|
|
282
|
+
readonly providers: readonly ProviderId[];
|
|
283
|
+
}): () => void;
|
|
284
|
+
|
|
285
|
+
export { type BehavioralAILike, type CacheTurnObservation, type KeymeshCredentialEventName, type KeymeshLike, type ModelchainCachePlanner, type NoeticOSLike, type NoeticosModuleLike, behavioralaiBridge, keymeshBridge, modelchainBridge, noeticosAdapter, noeticosBridge };
|