@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.
Files changed (46) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +190 -0
  3. package/NOTICE +40 -0
  4. package/README.md +381 -0
  5. package/SECURITY.md +57 -0
  6. package/dist/cli/index.js +3016 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/edge/index.cjs +2000 -0
  9. package/dist/edge/index.cjs.map +1 -0
  10. package/dist/edge/index.d.cts +598 -0
  11. package/dist/edge/index.d.ts +598 -0
  12. package/dist/edge/index.js +1987 -0
  13. package/dist/edge/index.js.map +1 -0
  14. package/dist/index.cjs +2071 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.cts +39 -0
  17. package/dist/index.d.ts +39 -0
  18. package/dist/index.js +2057 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/integrations/index.cjs +123 -0
  21. package/dist/integrations/index.cjs.map +1 -0
  22. package/dist/integrations/index.d.cts +285 -0
  23. package/dist/integrations/index.d.ts +285 -0
  24. package/dist/integrations/index.js +117 -0
  25. package/dist/integrations/index.js.map +1 -0
  26. package/dist/otel/index.cjs +93 -0
  27. package/dist/otel/index.cjs.map +1 -0
  28. package/dist/otel/index.d.cts +105 -0
  29. package/dist/otel/index.d.ts +105 -0
  30. package/dist/otel/index.js +91 -0
  31. package/dist/otel/index.js.map +1 -0
  32. package/dist/types-DQ7-9sk3.d.cts +758 -0
  33. package/dist/types-DQ7-9sk3.d.ts +758 -0
  34. package/dist/vercel/index.cjs +209 -0
  35. package/dist/vercel/index.cjs.map +1 -0
  36. package/dist/vercel/index.d.cts +210 -0
  37. package/dist/vercel/index.d.ts +210 -0
  38. package/dist/vercel/index.js +206 -0
  39. package/dist/vercel/index.js.map +1 -0
  40. package/dist/web/index.cjs +2000 -0
  41. package/dist/web/index.cjs.map +1 -0
  42. package/dist/web/index.d.cts +2 -0
  43. package/dist/web/index.d.ts +2 -0
  44. package/dist/web/index.js +1987 -0
  45. package/dist/web/index.js.map +1 -0
  46. 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 };