@seanhogg/builderforce-memory 2026.7.14 → 2026.9.28

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 (225) hide show
  1. package/README.md +10 -0
  2. package/dist/bridges/AnthropicBridge.d.ts +9 -1
  3. package/dist/bridges/AnthropicBridge.d.ts.map +1 -1
  4. package/dist/bridges/AnthropicBridge.js +58 -2
  5. package/dist/bridges/AnthropicBridge.js.map +1 -1
  6. package/dist/bridges/CachingBridge.d.ts +9 -1
  7. package/dist/bridges/CachingBridge.d.ts.map +1 -1
  8. package/dist/bridges/CachingBridge.js +24 -1
  9. package/dist/bridges/CachingBridge.js.map +1 -1
  10. package/dist/bridges/OpenAIBridge.d.ts +4 -1
  11. package/dist/bridges/OpenAIBridge.d.ts.map +1 -1
  12. package/dist/bridges/OpenAIBridge.js +40 -2
  13. package/dist/bridges/OpenAIBridge.js.map +1 -1
  14. package/dist/bridges/SemanticCachingBridge.d.ts +8 -1
  15. package/dist/bridges/SemanticCachingBridge.d.ts.map +1 -1
  16. package/dist/bridges/SemanticCachingBridge.js +26 -1
  17. package/dist/bridges/SemanticCachingBridge.js.map +1 -1
  18. package/dist/bridges/TransformerBridge.d.ts +13 -0
  19. package/dist/bridges/TransformerBridge.d.ts.map +1 -1
  20. package/dist/bridges/VertexAIBridge.d.ts +102 -0
  21. package/dist/bridges/VertexAIBridge.d.ts.map +1 -0
  22. package/dist/bridges/VertexAIBridge.js +224 -0
  23. package/dist/bridges/VertexAIBridge.js.map +1 -0
  24. package/dist/bridges/index.d.ts +3 -1
  25. package/dist/bridges/index.d.ts.map +1 -1
  26. package/dist/bridges/index.js +1 -0
  27. package/dist/bridges/index.js.map +1 -1
  28. package/dist/eval/EvalHarness.d.ts +37 -0
  29. package/dist/eval/EvalHarness.d.ts.map +1 -0
  30. package/dist/eval/EvalHarness.js +178 -0
  31. package/dist/eval/EvalHarness.js.map +1 -0
  32. package/dist/eval/graders.d.ts +76 -0
  33. package/dist/eval/graders.d.ts.map +1 -0
  34. package/dist/eval/graders.js +168 -0
  35. package/dist/eval/graders.js.map +1 -0
  36. package/dist/eval/index.d.ts +26 -0
  37. package/dist/eval/index.d.ts.map +1 -0
  38. package/dist/eval/index.js +26 -0
  39. package/dist/eval/index.js.map +1 -0
  40. package/dist/eval/types.d.ts +97 -0
  41. package/dist/eval/types.d.ts.map +1 -0
  42. package/dist/eval/types.js +5 -0
  43. package/dist/eval/types.js.map +1 -0
  44. package/dist/evermind/contract.d.ts +40 -0
  45. package/dist/evermind/contract.d.ts.map +1 -0
  46. package/dist/evermind/contract.js +13 -0
  47. package/dist/evermind/contract.js.map +1 -0
  48. package/dist/evermind/index.d.ts +15 -0
  49. package/dist/evermind/index.d.ts.map +1 -0
  50. package/dist/evermind/index.js +4 -0
  51. package/dist/evermind/index.js.map +1 -0
  52. package/dist/evermind/memoryBlock.d.ts +7 -0
  53. package/dist/evermind/memoryBlock.d.ts.map +1 -0
  54. package/dist/evermind/memoryBlock.js +37 -0
  55. package/dist/evermind/memoryBlock.js.map +1 -0
  56. package/dist/evermind/recall.d.ts +48 -0
  57. package/dist/evermind/recall.d.ts.map +1 -0
  58. package/dist/evermind/recall.js +105 -0
  59. package/dist/evermind/recall.js.map +1 -0
  60. package/dist/index.d.ts +18 -3
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +14 -1
  63. package/dist/index.js.map +1 -1
  64. package/dist/ingest/IngestionPipeline.d.ts +95 -0
  65. package/dist/ingest/IngestionPipeline.d.ts.map +1 -0
  66. package/dist/ingest/IngestionPipeline.js +295 -0
  67. package/dist/ingest/IngestionPipeline.js.map +1 -0
  68. package/dist/ingest/index.d.ts +10 -0
  69. package/dist/ingest/index.d.ts.map +1 -0
  70. package/dist/ingest/index.js +8 -0
  71. package/dist/ingest/index.js.map +1 -0
  72. package/dist/ingest/parsers.d.ts +53 -0
  73. package/dist/ingest/parsers.d.ts.map +1 -0
  74. package/dist/ingest/parsers.js +306 -0
  75. package/dist/ingest/parsers.js.map +1 -0
  76. package/dist/ingest/types.d.ts +114 -0
  77. package/dist/ingest/types.d.ts.map +1 -0
  78. package/dist/ingest/types.js +19 -0
  79. package/dist/ingest/types.js.map +1 -0
  80. package/dist/memory/MemoryStore.d.ts +33 -0
  81. package/dist/memory/MemoryStore.d.ts.map +1 -1
  82. package/dist/memory/MemoryStore.js +29 -3
  83. package/dist/memory/MemoryStore.js.map +1 -1
  84. package/dist/memory/index.d.ts +1 -1
  85. package/dist/memory/index.d.ts.map +1 -1
  86. package/dist/orchestration/AgentGraph.d.ts +104 -0
  87. package/dist/orchestration/AgentGraph.d.ts.map +1 -0
  88. package/dist/orchestration/AgentGraph.js +364 -0
  89. package/dist/orchestration/AgentGraph.js.map +1 -0
  90. package/dist/orchestration/checkpoint.d.ts +58 -0
  91. package/dist/orchestration/checkpoint.d.ts.map +1 -0
  92. package/dist/orchestration/checkpoint.js +92 -0
  93. package/dist/orchestration/checkpoint.js.map +1 -0
  94. package/dist/orchestration/index.d.ts +14 -0
  95. package/dist/orchestration/index.d.ts.map +1 -0
  96. package/dist/orchestration/index.js +10 -0
  97. package/dist/orchestration/index.js.map +1 -0
  98. package/dist/orchestration/patterns.d.ts +159 -0
  99. package/dist/orchestration/patterns.d.ts.map +1 -0
  100. package/dist/orchestration/patterns.js +371 -0
  101. package/dist/orchestration/patterns.js.map +1 -0
  102. package/dist/orchestration/types.d.ts +146 -0
  103. package/dist/orchestration/types.d.ts.map +1 -0
  104. package/dist/orchestration/types.js +20 -0
  105. package/dist/orchestration/types.js.map +1 -0
  106. package/dist/rag/EnterpriseRetriever.d.ts +114 -0
  107. package/dist/rag/EnterpriseRetriever.d.ts.map +1 -0
  108. package/dist/rag/EnterpriseRetriever.js +240 -0
  109. package/dist/rag/EnterpriseRetriever.js.map +1 -0
  110. package/dist/rag/index.d.ts +6 -0
  111. package/dist/rag/index.d.ts.map +1 -0
  112. package/dist/rag/index.js +5 -0
  113. package/dist/rag/index.js.map +1 -0
  114. package/dist/retrieval/bm25.d.ts +48 -1
  115. package/dist/retrieval/bm25.d.ts.map +1 -1
  116. package/dist/retrieval/bm25.js +59 -13
  117. package/dist/retrieval/bm25.js.map +1 -1
  118. package/dist/retrieval/index.d.ts +2 -2
  119. package/dist/retrieval/index.d.ts.map +1 -1
  120. package/dist/retrieval/index.js +1 -1
  121. package/dist/retrieval/index.js.map +1 -1
  122. package/dist/runtime/SSMRuntime.d.ts +1 -1
  123. package/dist/runtime/SSMRuntime.d.ts.map +1 -1
  124. package/dist/telemetry/InstrumentedBridge.d.ts +62 -0
  125. package/dist/telemetry/InstrumentedBridge.d.ts.map +1 -0
  126. package/dist/telemetry/InstrumentedBridge.js +120 -0
  127. package/dist/telemetry/InstrumentedBridge.js.map +1 -0
  128. package/dist/telemetry/MetricsRegistry.d.ts +88 -0
  129. package/dist/telemetry/MetricsRegistry.d.ts.map +1 -0
  130. package/dist/telemetry/MetricsRegistry.js +167 -0
  131. package/dist/telemetry/MetricsRegistry.js.map +1 -0
  132. package/dist/telemetry/Tracer.d.ts +137 -0
  133. package/dist/telemetry/Tracer.d.ts.map +1 -0
  134. package/dist/telemetry/Tracer.js +244 -0
  135. package/dist/telemetry/Tracer.js.map +1 -0
  136. package/dist/telemetry/exporters.d.ts +68 -0
  137. package/dist/telemetry/exporters.d.ts.map +1 -0
  138. package/dist/telemetry/exporters.js +145 -0
  139. package/dist/telemetry/exporters.js.map +1 -0
  140. package/dist/telemetry/index.d.ts +19 -0
  141. package/dist/telemetry/index.d.ts.map +1 -0
  142. package/dist/telemetry/index.js +12 -0
  143. package/dist/telemetry/index.js.map +1 -0
  144. package/dist/telemetry/pricing.d.ts +74 -0
  145. package/dist/telemetry/pricing.d.ts.map +1 -0
  146. package/dist/telemetry/pricing.js +98 -0
  147. package/dist/telemetry/pricing.js.map +1 -0
  148. package/dist/telemetry/traceparent.d.ts +50 -0
  149. package/dist/telemetry/traceparent.d.ts.map +1 -0
  150. package/dist/telemetry/traceparent.js +77 -0
  151. package/dist/telemetry/traceparent.js.map +1 -0
  152. package/dist/telemetry/types.d.ts +90 -0
  153. package/dist/telemetry/types.d.ts.map +1 -0
  154. package/dist/telemetry/types.js +17 -0
  155. package/dist/telemetry/types.js.map +1 -0
  156. package/dist/vectorstore/MemoryVectorStore.d.ts +72 -0
  157. package/dist/vectorstore/MemoryVectorStore.d.ts.map +1 -0
  158. package/dist/vectorstore/MemoryVectorStore.js +205 -0
  159. package/dist/vectorstore/MemoryVectorStore.js.map +1 -0
  160. package/dist/vectorstore/RestVectorStore.d.ts +79 -0
  161. package/dist/vectorstore/RestVectorStore.d.ts.map +1 -0
  162. package/dist/vectorstore/RestVectorStore.js +170 -0
  163. package/dist/vectorstore/RestVectorStore.js.map +1 -0
  164. package/dist/vectorstore/dialects.d.ts +101 -0
  165. package/dist/vectorstore/dialects.d.ts.map +1 -0
  166. package/dist/vectorstore/dialects.js +618 -0
  167. package/dist/vectorstore/dialects.js.map +1 -0
  168. package/dist/vectorstore/filter.d.ts +42 -0
  169. package/dist/vectorstore/filter.d.ts.map +1 -0
  170. package/dist/vectorstore/filter.js +132 -0
  171. package/dist/vectorstore/filter.js.map +1 -0
  172. package/dist/vectorstore/index.d.ts +15 -0
  173. package/dist/vectorstore/index.d.ts.map +1 -0
  174. package/dist/vectorstore/index.js +11 -0
  175. package/dist/vectorstore/index.js.map +1 -0
  176. package/dist/vectorstore/types.d.ts +151 -0
  177. package/dist/vectorstore/types.d.ts.map +1 -0
  178. package/dist/vectorstore/types.js +30 -0
  179. package/dist/vectorstore/types.js.map +1 -0
  180. package/package.json +39 -5
  181. package/src/bridges/AnthropicBridge.ts +68 -3
  182. package/src/bridges/CachingBridge.ts +28 -2
  183. package/src/bridges/OpenAIBridge.ts +48 -3
  184. package/src/bridges/SemanticCachingBridge.ts +29 -2
  185. package/src/bridges/TransformerBridge.ts +16 -0
  186. package/src/bridges/VertexAIBridge.ts +297 -0
  187. package/src/bridges/index.ts +3 -1
  188. package/src/eval/EvalHarness.ts +214 -0
  189. package/src/eval/graders.ts +218 -0
  190. package/src/eval/index.ts +26 -0
  191. package/src/eval/types.ts +107 -0
  192. package/src/evermind/contract.ts +39 -0
  193. package/src/evermind/index.ts +18 -0
  194. package/src/evermind/memoryBlock.ts +38 -0
  195. package/src/evermind/recall.ts +122 -0
  196. package/src/index.ts +232 -0
  197. package/src/ingest/IngestionPipeline.ts +378 -0
  198. package/src/ingest/index.ts +46 -0
  199. package/src/ingest/parsers.ts +318 -0
  200. package/src/ingest/types.ts +116 -0
  201. package/src/memory/MemoryStore.ts +55 -3
  202. package/src/memory/index.ts +1 -1
  203. package/src/orchestration/AgentGraph.ts +462 -0
  204. package/src/orchestration/checkpoint.ts +129 -0
  205. package/src/orchestration/index.ts +63 -0
  206. package/src/orchestration/patterns.ts +532 -0
  207. package/src/orchestration/types.ts +128 -0
  208. package/src/rag/EnterpriseRetriever.ts +348 -0
  209. package/src/rag/index.ts +18 -0
  210. package/src/retrieval/bm25.ts +71 -13
  211. package/src/retrieval/index.ts +2 -2
  212. package/src/telemetry/InstrumentedBridge.ts +152 -0
  213. package/src/telemetry/MetricsRegistry.ts +263 -0
  214. package/src/telemetry/Tracer.ts +310 -0
  215. package/src/telemetry/exporters.ts +187 -0
  216. package/src/telemetry/index.ts +56 -0
  217. package/src/telemetry/pricing.ts +129 -0
  218. package/src/telemetry/traceparent.ts +89 -0
  219. package/src/telemetry/types.ts +105 -0
  220. package/src/vectorstore/MemoryVectorStore.ts +250 -0
  221. package/src/vectorstore/RestVectorStore.ts +236 -0
  222. package/src/vectorstore/dialects.ts +702 -0
  223. package/src/vectorstore/filter.ts +148 -0
  224. package/src/vectorstore/index.ts +53 -0
  225. package/src/vectorstore/types.ts +149 -0
package/README.md CHANGED
@@ -69,6 +69,16 @@ Generic build step types (compose your own pipeline via the step registry):
69
69
 
70
70
  ---
71
71
 
72
+ ## Evermind recall contract (`@seanhogg/builderforce-memory/evermind`)
73
+
74
+ A dependency-free subpath a browser chat client can import without the rest of the runtime:
75
+
76
+ - `EvermindRecallItem`, `EvermindRecallResult` — what a project Evermind recall returns.
77
+ - `rankEvermindRecall`, `hashRecallQuery` — the lexical recall ranker.
78
+ - `countReconciledMemories` — which recalled memories an answer restates (write-through reconcile).
79
+ - `formatEvermindMemoryBlock` — the recalled-memory prompt block, each item neutralised with `sanitizeRecalledFact`.
80
+ - `EVERMIND_MIN_TEACH_CHARS` — the teach floor below which a turn is never contributed.
81
+
72
82
  ## Installation
73
83
 
74
84
  ```bash
@@ -4,7 +4,7 @@
4
4
  * Uses the /v1/messages endpoint. System prompts are passed as the top-level
5
5
  * `system` field (not a message role), per the Anthropic spec.
6
6
  */
7
- import type { TransformerBridge, BridgeGenerateOptions } from './TransformerBridge.js';
7
+ import type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
8
8
  export interface AnthropicBridgeOptions {
9
9
  /** Anthropic API key. */
10
10
  apiKey: string;
@@ -38,7 +38,15 @@ export declare class AnthropicBridge implements TransformerBridge {
38
38
  private readonly _systemPrompt;
39
39
  private readonly _maxTokens;
40
40
  private readonly _cacheSystem;
41
+ private _lastCall;
41
42
  constructor(opts: AnthropicBridgeOptions);
43
+ /**
44
+ * Provider-reported usage for the last call. Anthropic splits input tokens
45
+ * three ways — fresh, cache read, and cache write — and each is billed at a
46
+ * different rate, so a cost model that only reads `input_tokens` is wrong on
47
+ * exactly the cache-heavy traffic this bridge is tuned to produce.
48
+ */
49
+ get lastCall(): BridgeCallInfo | undefined;
42
50
  generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
43
51
  stream(prompt: string, opts?: BridgeGenerateOptions): AsyncIterable<string>;
44
52
  private _buildBody;
@@ -1 +1 @@
1
- {"version":3,"file":"AnthropicBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/AnthropicBridge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,MAAM,WAAW,sBAAsB;IACnC,yBAAyB;IACzB,MAAM,EAAU,MAAM,CAAC;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,2DAA2D;IAC3D,UAAU,CAAC,EAAK,MAAM,CAAC;IACvB,4CAA4C;IAC5C,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,iEAAiE;IACjE,SAAS,CAAC,EAAM,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAI,OAAO,CAAC;CAC3B;AAID,qBAAa,eAAgB,YAAW,iBAAiB;IACrD,QAAQ,CAAC,iBAAiB,EAAG,IAAI,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;gBAE5B,IAAI,EAAE,sBAAsB;IASlC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,aAAa,CAAC,MAAM,CAAC;IAmBtF,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,MAAM;CAWjB"}
1
+ {"version":3,"file":"AnthropicBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/AnthropicBridge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEvG,MAAM,WAAW,sBAAsB;IACnC,yBAAyB;IACzB,MAAM,EAAU,MAAM,CAAC;IACvB;;;;OAIG;IACH,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,2DAA2D;IAC3D,UAAU,CAAC,EAAK,MAAM,CAAC;IACvB,4CAA4C;IAC5C,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,iEAAiE;IACjE,SAAS,CAAC,EAAM,MAAM,CAAC;IACvB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAI,OAAO,CAAC;CAC3B;AAID,qBAAa,eAAgB,YAAW,iBAAiB;IACrD,QAAQ,CAAC,iBAAiB,EAAG,IAAI,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAW;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAW;IAExC,OAAO,CAAC,SAAS,CAA6B;gBAElC,IAAI,EAAE,sBAAsB;IASxC;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IA0B1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,aAAa,CAAC,MAAM,CAAC;IA4CtF,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,MAAM;CAWjB"}
@@ -14,6 +14,7 @@ export class AnthropicBridge {
14
14
  _systemPrompt;
15
15
  _maxTokens;
16
16
  _cacheSystem;
17
+ _lastCall;
17
18
  constructor(opts) {
18
19
  this._apiKey = opts.apiKey;
19
20
  this._model = opts.model ?? 'claude-haiku-4-5';
@@ -22,6 +23,15 @@ export class AnthropicBridge {
22
23
  this._maxTokens = opts.maxTokens ?? 1024;
23
24
  this._cacheSystem = opts.cacheSystem ?? true;
24
25
  }
26
+ /**
27
+ * Provider-reported usage for the last call. Anthropic splits input tokens
28
+ * three ways — fresh, cache read, and cache write — and each is billed at a
29
+ * different rate, so a cost model that only reads `input_tokens` is wrong on
30
+ * exactly the cache-heavy traffic this bridge is tuned to produce.
31
+ */
32
+ get lastCall() {
33
+ return this._lastCall;
34
+ }
25
35
  async generate(prompt, opts = {}) {
26
36
  const body = this._buildBody(prompt, opts, false);
27
37
  const res = await this._fetch(body);
@@ -34,6 +44,9 @@ export class AnthropicBridge {
34
44
  if (typeof content !== 'string') {
35
45
  throw new SSMError('BRIDGE_RESPONSE_INVALID', 'Unexpected Anthropic response shape.');
36
46
  }
47
+ this._lastCall = {
48
+ usage: readAnthropicUsage(json.usage, json.model ?? opts.model ?? this._model),
49
+ };
37
50
  return content;
38
51
  }
39
52
  async *stream(prompt, opts = {}) {
@@ -46,7 +59,32 @@ export class AnthropicBridge {
46
59
  if (!res.body) {
47
60
  throw new SSMError('BRIDGE_RESPONSE_INVALID', 'Anthropic streaming response has no body.');
48
61
  }
49
- yield* parseAnthropicStream(res.body);
62
+ const model = opts.model ?? this._model;
63
+ let input = 0, output = 0, cacheRead = 0, cacheWrite = 0, reportedModel = model;
64
+ yield* parseAnthropicStream(res.body, (event) => {
65
+ // `message_start` carries the input split; `message_delta` the running
66
+ // output count. Both are folded so the final usage is provider-measured.
67
+ const start = event.message?.usage;
68
+ const delta = event.usage;
69
+ const usage = start ?? delta;
70
+ if (!usage)
71
+ return;
72
+ if (typeof event.message?.model === 'string')
73
+ reportedModel = event.message.model;
74
+ input = Math.max(input, Number(usage.input_tokens) || 0);
75
+ output = Math.max(output, Number(usage.output_tokens) || 0);
76
+ cacheRead = Math.max(cacheRead, Number(usage.cache_read_input_tokens) || 0);
77
+ cacheWrite = Math.max(cacheWrite, Number(usage.cache_creation_input_tokens) || 0);
78
+ });
79
+ this._lastCall = {
80
+ usage: {
81
+ model: reportedModel,
82
+ inputTokens: input,
83
+ outputTokens: output,
84
+ cachedInputTokens: cacheRead,
85
+ cacheWriteTokens: cacheWrite,
86
+ },
87
+ };
50
88
  }
51
89
  _buildBody(prompt, opts, stream) {
52
90
  const sys = opts.systemPrompt ?? this._systemPrompt;
@@ -81,7 +119,7 @@ export class AnthropicBridge {
81
119
  }
82
120
  }
83
121
  // ── SSE parser (Anthropic event format) ──────────────────────────────────────
84
- async function* parseAnthropicStream(body) {
122
+ async function* parseAnthropicStream(body, onEvent) {
85
123
  const reader = body.getReader();
86
124
  const decoder = new TextDecoder();
87
125
  let buffer = '';
@@ -100,6 +138,7 @@ async function* parseAnthropicStream(body) {
100
138
  const data = trimmed.slice(6);
101
139
  try {
102
140
  const event = JSON.parse(data);
141
+ onEvent?.(event);
103
142
  // content_block_delta events carry the streamed text
104
143
  if (event['type'] === 'content_block_delta') {
105
144
  const text = event.delta?.text;
@@ -117,4 +156,21 @@ async function* parseAnthropicStream(body) {
117
156
  reader.releaseLock();
118
157
  }
119
158
  }
159
+ /**
160
+ * Maps an Anthropic `usage` object onto the canonical {@link LlmUsage} shape.
161
+ * Absent when the response omits usage (an older gateway shim), in which case
162
+ * `InstrumentedBridge` falls back to an estimate and flags it as such.
163
+ */
164
+ function readAnthropicUsage(usage, model) {
165
+ if (!usage || typeof usage !== 'object')
166
+ return undefined;
167
+ const u = usage;
168
+ return {
169
+ model,
170
+ inputTokens: Number(u['input_tokens']) || 0,
171
+ outputTokens: Number(u['output_tokens']) || 0,
172
+ cachedInputTokens: Number(u['cache_read_input_tokens']) || 0,
173
+ cacheWriteTokens: Number(u['cache_creation_input_tokens']) || 0,
174
+ };
175
+ }
120
176
  //# sourceMappingURL=AnthropicBridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnthropicBridge.js","sourceRoot":"","sources":["../../src/bridges/AnthropicBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AnthropicBridge.js","sourceRoot":"","sources":["../../src/bridges/AnthropicBridge.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@
15
15
  * Streaming is delegated straight through and never cached — a token stream is
16
16
  * consumed once and caching it would defeat its purpose.
17
17
  */
18
- import type { TransformerBridge, BridgeGenerateOptions } from './TransformerBridge.js';
18
+ import type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
19
19
  import { ResponseCache, type ResponseCacheOptions } from './ResponseCache.js';
20
20
  export interface CachingBridgeOptions extends ResponseCacheOptions {
21
21
  /**
@@ -28,11 +28,19 @@ export interface CachingBridgeOptions extends ResponseCacheOptions {
28
28
  export declare class CachingBridge implements TransformerBridge {
29
29
  private readonly _inner;
30
30
  private readonly _cache;
31
+ private _lastCall;
31
32
  constructor(inner: TransformerBridge, opts?: CachingBridgeOptions);
32
33
  /** Mirrors the wrapped bridge so callers can still gate on streaming support. */
33
34
  get supportsStreaming(): boolean;
34
35
  /** The underlying cache — exposed for stats inspection and manual eviction. */
35
36
  get cache(): ResponseCache;
37
+ /**
38
+ * A hit is declared here rather than inferred downstream, which is what turns
39
+ * the cache-hit rate into a measured metric. On a miss the inner bridge's own
40
+ * provider-reported usage is passed through unchanged, so decorating a bridge
41
+ * never downgrades its cost accounting to an estimate.
42
+ */
43
+ get lastCall(): BridgeCallInfo | undefined;
36
44
  generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
37
45
  /**
38
46
  * Streaming is delegated to the inner bridge unchanged and is never cached.
@@ -1 +1 @@
1
- {"version":3,"file":"CachingBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/CachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAiB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAC9D;;;;OAIG;IACH,KAAK,CAAC,EAAG,aAAa,CAAC;CAC1B;AAED,qBAAa,aAAc,YAAW,iBAAiB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,KAAK,EAAE,iBAAiB,EAAE,IAAI,GAAE,oBAAyB;IAKrE,iFAAiF;IACjF,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,+EAA+E;IAC/E,IAAI,KAAK,IAAI,aAAa,CAEzB;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBjF;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC;CAM9E"}
1
+ {"version":3,"file":"CachingBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/CachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,aAAa,EAAiB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAC9D;;;;OAIG;IACH,KAAK,CAAC,EAAG,aAAa,CAAC;CAC1B;AAED,qBAAa,aAAc,YAAW,iBAAiB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,OAAO,CAAC,SAAS,CAA6B;gBAElC,KAAK,EAAE,iBAAiB,EAAE,IAAI,GAAE,oBAAyB;IAKrE,iFAAiF;IACjF,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,+EAA+E;IAC/E,IAAI,KAAK,IAAI,aAAa,CAEzB;IAED;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCjF;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC;CAM9E"}
@@ -19,6 +19,7 @@ import { ResponseCache, buildCacheKey } from './ResponseCache.js';
19
19
  export class CachingBridge {
20
20
  _inner;
21
21
  _cache;
22
+ _lastCall;
22
23
  constructor(inner, opts = {}) {
23
24
  this._inner = inner;
24
25
  this._cache = opts.cache ?? new ResponseCache(opts);
@@ -31,6 +32,15 @@ export class CachingBridge {
31
32
  get cache() {
32
33
  return this._cache;
33
34
  }
35
+ /**
36
+ * A hit is declared here rather than inferred downstream, which is what turns
37
+ * the cache-hit rate into a measured metric. On a miss the inner bridge's own
38
+ * provider-reported usage is passed through unchanged, so decorating a bridge
39
+ * never downgrades its cost accounting to an estimate.
40
+ */
41
+ get lastCall() {
42
+ return this._lastCall;
43
+ }
34
44
  async generate(prompt, opts = {}) {
35
45
  const key = buildCacheKey({
36
46
  prompt,
@@ -41,10 +51,23 @@ export class CachingBridge {
41
51
  topP: opts.topP,
42
52
  });
43
53
  const cached = this._cache.get(key);
44
- if (cached !== undefined)
54
+ if (cached !== undefined) {
55
+ this._lastCall = {
56
+ cacheHit: true,
57
+ cacheTier: 'exact',
58
+ usage: {
59
+ model: opts.model ?? 'unknown',
60
+ inputTokens: 0,
61
+ outputTokens: 0,
62
+ localCacheHit: true,
63
+ },
64
+ };
45
65
  return cached;
66
+ }
46
67
  const value = await this._inner.generate(prompt, opts);
47
68
  this._cache.set(key, value, Date.now());
69
+ const inner = this._inner.lastCall;
70
+ this._lastCall = { cacheHit: false, ...(inner?.usage ? { usage: inner.usage } : {}) };
48
71
  return value;
49
72
  }
50
73
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"CachingBridge.js","sourceRoot":"","sources":["../../src/bridges/CachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,aAAa,EAAE,aAAa,EAA6B,MAAM,oBAAoB,CAAC;AAW7F,MAAM,OAAO,aAAa;IACL,MAAM,CAAqB;IAC3B,MAAM,CAAiB;IAExC,YAAY,KAAwB,EAAE,OAA6B,EAAE;QACjE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,iFAAiF;IACjF,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACzC,CAAC;IAED,+EAA+E;IAC/E,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC3D,MAAM,GAAG,GAAG,aAAa,CAAC;YACtB,MAAM;YACN,KAAK,EAAS,IAAI,CAAC,KAAK;YACxB,YAAY,EAAG,IAAI,CAAC,YAAY;YAChC,SAAS,EAAK,IAAI,CAAC,SAAS;YAC5B,WAAW,EAAG,IAAI,CAAC,WAAW;YAC9B,IAAI,EAAU,IAAI,CAAC,IAAI;SAC1B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QAExC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAc,EAAE,IAA4B;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACJ"}
1
+ {"version":3,"file":"CachingBridge.js","sourceRoot":"","sources":["../../src/bridges/CachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,aAAa,EAAE,aAAa,EAA6B,MAAM,oBAAoB,CAAC;AAW7F,MAAM,OAAO,aAAa;IACL,MAAM,CAAqB;IAC3B,MAAM,CAAiB;IAEhC,SAAS,CAA6B;IAE9C,YAAY,KAAwB,EAAE,OAA6B,EAAE;QACjE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,iFAAiF;IACjF,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACzC,CAAC;IAED,+EAA+E;IAC/E,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;;OAKG;IACH,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC3D,MAAM,GAAG,GAAG,aAAa,CAAC;YACtB,MAAM;YACN,KAAK,EAAS,IAAI,CAAC,KAAK;YACxB,YAAY,EAAG,IAAI,CAAC,YAAY;YAChC,SAAS,EAAK,IAAI,CAAC,SAAS;YAC5B,WAAW,EAAG,IAAI,CAAC,WAAW;YAC9B,IAAI,EAAU,IAAI,CAAC,IAAI;SAC1B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,SAAS,GAAG;gBACb,QAAQ,EAAG,IAAI;gBACf,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAM;oBACP,KAAK,EAAc,IAAI,CAAC,KAAK,IAAI,SAAS;oBAC1C,WAAW,EAAQ,CAAC;oBACpB,YAAY,EAAO,CAAC;oBACpB,aAAa,EAAM,IAAI;iBAC1B;aACJ,CAAC;YACF,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACtF,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,MAAc,EAAE,IAA4B;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACJ"}
@@ -4,7 +4,7 @@
4
4
  * Supports both non-streaming and streaming (SSE) completions.
5
5
  * Compatible with any OpenAI-compatible endpoint via the `baseUrl` option.
6
6
  */
7
- import type { TransformerBridge, BridgeGenerateOptions } from './TransformerBridge.js';
7
+ import type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
8
8
  export interface OpenAIBridgeOptions {
9
9
  /** OpenAI API key (or compatible service key). */
10
10
  apiKey: string;
@@ -18,6 +18,7 @@ export interface OpenAIBridgeOptions {
18
18
  maxTokens?: number;
19
19
  }
20
20
  export declare class OpenAIBridge implements TransformerBridge {
21
+ private _lastCall;
21
22
  readonly supportsStreaming: true;
22
23
  private readonly _apiKey;
23
24
  private readonly _model;
@@ -25,6 +26,8 @@ export declare class OpenAIBridge implements TransformerBridge {
25
26
  private readonly _systemPrompt;
26
27
  private readonly _maxTokens;
27
28
  constructor(opts: OpenAIBridgeOptions);
29
+ /** Provider-reported usage for the last call — see {@link BridgeCallInfo}. */
30
+ get lastCall(): BridgeCallInfo | undefined;
28
31
  generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
29
32
  stream(prompt: string, opts?: BridgeGenerateOptions): AsyncIterable<string>;
30
33
  private _buildBody;
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAIBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/OpenAIBridge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,MAAM,WAAW,mBAAmB;IAChC,kDAAkD;IAClD,MAAM,EAAU,MAAM,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,EAAQ,MAAM,CAAC;IACvB,qDAAqD;IACrD,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,wCAAwC;IACxC,SAAS,CAAC,EAAM,MAAM,CAAC;CAC1B;AAED,qBAAa,YAAa,YAAW,iBAAiB;IAClD,QAAQ,CAAC,iBAAiB,EAAG,IAAI,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;gBAE3B,IAAI,EAAE,mBAAmB;IAQ/B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,aAAa,CAAC,MAAM,CAAC;IAmBtF,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,MAAM;CAUjB"}
1
+ {"version":3,"file":"OpenAIBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/OpenAIBridge.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEvG,MAAM,WAAW,mBAAmB;IAChC,kDAAkD;IAClD,MAAM,EAAU,MAAM,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,EAAQ,MAAM,CAAC;IACvB,qDAAqD;IACrD,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,wCAAwC;IACxC,SAAS,CAAC,EAAM,MAAM,CAAC;CAC1B;AAED,qBAAa,YAAa,YAAW,iBAAiB;IAClD,OAAO,CAAC,SAAS,CAA6B;IAE9C,QAAQ,CAAC,iBAAiB,EAAG,IAAI,CAAU;IAE3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;gBAE3B,IAAI,EAAE,mBAAmB;IAQrC,8EAA8E;IAC9E,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,aAAa,CAAC,MAAM,CAAC;IA6BtF,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,MAAM;CAUjB"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import { SSMError } from '../errors/SSMError.js';
8
8
  export class OpenAIBridge {
9
+ _lastCall;
9
10
  supportsStreaming = true;
10
11
  _apiKey;
11
12
  _model;
@@ -19,6 +20,10 @@ export class OpenAIBridge {
19
20
  this._systemPrompt = opts.systemPrompt ?? '';
20
21
  this._maxTokens = opts.maxTokens ?? 512;
21
22
  }
23
+ /** Provider-reported usage for the last call — see {@link BridgeCallInfo}. */
24
+ get lastCall() {
25
+ return this._lastCall;
26
+ }
22
27
  async generate(prompt, opts = {}) {
23
28
  const body = this._buildBody(prompt, opts, false);
24
29
  const res = await this._fetch(body);
@@ -31,6 +36,9 @@ export class OpenAIBridge {
31
36
  if (typeof content !== 'string') {
32
37
  throw new SSMError('BRIDGE_RESPONSE_INVALID', 'Unexpected OpenAI response shape.');
33
38
  }
39
+ this._lastCall = {
40
+ usage: readOpenAIUsage(json.usage, json.model ?? opts.model ?? this._model),
41
+ };
34
42
  return content;
35
43
  }
36
44
  async *stream(prompt, opts = {}) {
@@ -43,7 +51,16 @@ export class OpenAIBridge {
43
51
  if (!res.body) {
44
52
  throw new SSMError('BRIDGE_RESPONSE_INVALID', 'OpenAI streaming response has no body.');
45
53
  }
46
- yield* parseOpenAIStream(res.body);
54
+ const model = opts.model ?? this._model;
55
+ let usage;
56
+ yield* parseOpenAIStream(res.body, (event) => {
57
+ // Only emitted because `_buildBody` sets `stream_options.include_usage`;
58
+ // without it OpenAI streams no usage at all and cost would be a guess.
59
+ const reported = readOpenAIUsage(event.usage, event.model ?? model);
60
+ if (reported)
61
+ usage = reported;
62
+ });
63
+ this._lastCall = usage ? { usage } : {};
47
64
  }
48
65
  _buildBody(prompt, opts, stream) {
49
66
  const sys = opts.systemPrompt ?? this._systemPrompt;
@@ -58,6 +75,10 @@ export class OpenAIBridge {
58
75
  temperature: opts.temperature ?? 0.7,
59
76
  top_p: opts.topP ?? 0.9,
60
77
  stream,
78
+ // Without this the streaming response carries no usage block, so
79
+ // cost-per-request on streamed calls would silently fall back to an
80
+ // estimate. Non-streaming requests reject the field, hence the guard.
81
+ ...(stream ? { stream_options: { include_usage: true } } : {}),
61
82
  });
62
83
  }
63
84
  _fetch(body) {
@@ -72,7 +93,7 @@ export class OpenAIBridge {
72
93
  }
73
94
  }
74
95
  // ── SSE parser ────────────────────────────────────────────────────────────────
75
- async function* parseOpenAIStream(body) {
96
+ async function* parseOpenAIStream(body, onEvent) {
76
97
  const reader = body.getReader();
77
98
  const decoder = new TextDecoder();
78
99
  let buffer = '';
@@ -93,6 +114,7 @@ async function* parseOpenAIStream(body) {
93
114
  return;
94
115
  try {
95
116
  const chunk = JSON.parse(data);
117
+ onEvent?.(chunk);
96
118
  const delta = chunk.choices?.[0]?.delta?.content;
97
119
  if (typeof delta === 'string' && delta.length > 0)
98
120
  yield delta;
@@ -107,4 +129,20 @@ async function* parseOpenAIStream(body) {
107
129
  reader.releaseLock();
108
130
  }
109
131
  }
132
+ /** Maps an OpenAI `usage` object onto the canonical {@link LlmUsage} shape. */
133
+ function readOpenAIUsage(usage, model) {
134
+ if (!usage || typeof usage !== 'object')
135
+ return undefined;
136
+ const u = usage;
137
+ const cached = Number(u['prompt_tokens_details']?.['cached_tokens']) || 0;
138
+ const prompt = Number(u['prompt_tokens']) || 0;
139
+ return {
140
+ model,
141
+ // OpenAI reports `prompt_tokens` INCLUSIVE of cached tokens; the canonical
142
+ // shape keeps them disjoint so the two rates are applied exactly once each.
143
+ inputTokens: Math.max(0, prompt - cached),
144
+ outputTokens: Number(u['completion_tokens']) || 0,
145
+ cachedInputTokens: cached,
146
+ };
147
+ }
110
148
  //# sourceMappingURL=OpenAIBridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAIBridge.js","sourceRoot":"","sources":["../../src/bridges/OpenAIBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OpenAIBridge.js","sourceRoot":"","sources":["../../src/bridges/OpenAIBridge.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * Streaming is delegated straight through and never cached.
13
13
  */
14
- import type { TransformerBridge, BridgeGenerateOptions } from './TransformerBridge.js';
14
+ import type { TransformerBridge, BridgeGenerateOptions, BridgeCallInfo } from './TransformerBridge.js';
15
15
  import { SemanticCache, type SemanticCacheOptions } from '../cache/SemanticCache.js';
16
16
  export interface SemanticCachingBridgeOptions extends Omit<SemanticCacheOptions, never> {
17
17
  /** Provide a shared SemanticCache instance instead of constructing one. */
@@ -20,10 +20,17 @@ export interface SemanticCachingBridgeOptions extends Omit<SemanticCacheOptions,
20
20
  export declare class SemanticCachingBridge implements TransformerBridge {
21
21
  private readonly _inner;
22
22
  private readonly _cache;
23
+ private _lastCall;
23
24
  constructor(inner: TransformerBridge, opts: SemanticCachingBridgeOptions);
24
25
  get supportsStreaming(): boolean;
25
26
  /** The underlying SemanticCache — exposed for stats inspection. */
26
27
  get cache(): SemanticCache;
28
+ /**
29
+ * Reports which tier answered (`l1` local vector scan, `l2` shared backend, or
30
+ * a miss), so the saving from paraphrase reuse is attributable per tier rather
31
+ * than lumped into one "cache" number.
32
+ */
33
+ get lastCall(): BridgeCallInfo | undefined;
27
34
  generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
28
35
  /** Streaming is delegated unchanged and never cached. */
29
36
  stream(prompt: string, opts?: BridgeGenerateOptions): AsyncIterable<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"SemanticCachingBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/SemanticCachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAErF,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC;IACnF,2EAA2E;IAC3E,KAAK,CAAC,EAAG,aAAa,CAAC;CAC1B;AAED,qBAAa,qBAAsB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;gBAE5B,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,4BAA4B;IAKxE,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,mEAAmE;IACnE,IAAI,KAAK,IAAI,aAAa,CAEzB;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IAYjF,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC;CAM9E"}
1
+ {"version":3,"file":"SemanticCachingBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/SemanticCachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvG,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAErF,MAAM,WAAW,4BAA6B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC;IACnF,2EAA2E;IAC3E,KAAK,CAAC,EAAG,aAAa,CAAC;CAC1B;AAED,qBAAa,qBAAsB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IAExC,OAAO,CAAC,SAAS,CAA6B;gBAElC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,4BAA4B;IAKxE,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,mEAAmE;IACnE,IAAI,KAAK,IAAI,aAAa,CAEzB;IAED;;;;OAIG;IACH,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,CAEzC;IAEK,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,qBAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BjF,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC;CAM9E"}
@@ -15,6 +15,7 @@ import { SemanticCache } from '../cache/SemanticCache.js';
15
15
  export class SemanticCachingBridge {
16
16
  _inner;
17
17
  _cache;
18
+ _lastCall;
18
19
  constructor(inner, opts) {
19
20
  this._inner = inner;
20
21
  this._cache = opts.cache ?? new SemanticCache(opts);
@@ -26,11 +27,35 @@ export class SemanticCachingBridge {
26
27
  get cache() {
27
28
  return this._cache;
28
29
  }
30
+ /**
31
+ * Reports which tier answered (`l1` local vector scan, `l2` shared backend, or
32
+ * a miss), so the saving from paraphrase reuse is attributable per tier rather
33
+ * than lumped into one "cache" number.
34
+ */
35
+ get lastCall() {
36
+ return this._lastCall;
37
+ }
29
38
  async generate(prompt, opts = {}) {
30
39
  // Match on system + prompt meaning so different system contexts don't
31
40
  // cross-hit; partition further by model via the stored meta.
32
41
  const queryText = opts.systemPrompt ? `${opts.systemPrompt}\n${prompt}` : prompt;
33
- const { response } = await this._cache.getOrGenerate(queryText, () => this._inner.generate(prompt, opts), opts.model ? { model: opts.model } : undefined);
42
+ const { response, cached, tier } = await this._cache.getOrGenerate(queryText, () => this._inner.generate(prompt, opts), opts.model ? { model: opts.model } : undefined);
43
+ if (cached) {
44
+ this._lastCall = {
45
+ cacheHit: true,
46
+ ...(tier ? { cacheTier: tier } : {}),
47
+ usage: {
48
+ model: opts.model ?? 'unknown',
49
+ inputTokens: 0,
50
+ outputTokens: 0,
51
+ localCacheHit: true,
52
+ },
53
+ };
54
+ }
55
+ else {
56
+ const inner = this._inner.lastCall;
57
+ this._lastCall = { cacheHit: false, ...(inner?.usage ? { usage: inner.usage } : {}) };
58
+ }
34
59
  return response;
35
60
  }
36
61
  /** Streaming is delegated unchanged and never cached. */
@@ -1 +1 @@
1
- {"version":3,"file":"SemanticCachingBridge.js","sourceRoot":"","sources":["../../src/bridges/SemanticCachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,aAAa,EAA6B,MAAM,2BAA2B,CAAC;AAOrF,MAAM,OAAO,qBAAqB;IACb,MAAM,CAAqB;IAC3B,MAAM,CAAiB;IAExC,YAAY,KAAwB,EAAE,IAAkC;QACpE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACzC,CAAC;IAED,mEAAmE;IACnE,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC3D,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACjF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAChD,SAAS,EACT,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EACxC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CACjD,CAAC;QACF,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,yDAAyD;IACzD,MAAM,CAAC,MAAc,EAAE,IAA4B;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACJ"}
1
+ {"version":3,"file":"SemanticCachingBridge.js","sourceRoot":"","sources":["../../src/bridges/SemanticCachingBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,aAAa,EAA6B,MAAM,2BAA2B,CAAC;AAOrF,MAAM,OAAO,qBAAqB;IACb,MAAM,CAAqB;IAC3B,MAAM,CAAiB;IAEhC,SAAS,CAA6B;IAE9C,YAAY,KAAwB,EAAE,IAAkC;QACpE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,iBAAiB;QACjB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACzC,CAAC;IAED,mEAAmE;IACnE,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,IAAI,QAAQ;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAA8B,EAAE;QAC3D,sEAAsE;QACtE,6DAA6D;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACjF,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAC9D,SAAS,EACT,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EACxC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CACjD,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACT,IAAI,CAAC,SAAS,GAAG;gBACb,QAAQ,EAAG,IAAI;gBACf,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpC,KAAK,EAAM;oBACP,KAAK,EAAU,IAAI,CAAC,KAAK,IAAI,SAAS;oBACtC,WAAW,EAAI,CAAC;oBAChB,YAAY,EAAG,CAAC;oBAChB,aAAa,EAAE,IAAI;iBACtB;aACJ,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;YACnC,IAAI,CAAC,SAAS,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC1F,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED,yDAAyD;IACzD,MAAM,CAAC,MAAc,EAAE,IAA4B;QAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;CACJ"}
@@ -6,6 +6,8 @@
6
6
  * distillation. The interface is structural — any object with the right
7
7
  * shape works, no base class required.
8
8
  */
9
+ import type { BridgeCallInfo } from '../telemetry/types.js';
10
+ export type { BridgeCallInfo };
9
11
  export interface BridgeGenerateOptions {
10
12
  /** Max tokens to generate. Default per-adapter (typically 512). */
11
13
  maxTokens?: number;
@@ -24,6 +26,17 @@ export interface TransformerBridge {
24
26
  * Must resolve to the assistant's reply text only (not including the prompt).
25
27
  */
26
28
  generate(prompt: string, opts?: BridgeGenerateOptions): Promise<string>;
29
+ /**
30
+ * Usage and cache outcome of the most recent `generate()`/`stream()`.
31
+ *
32
+ * Optional so third-party bridges stay valid, but every bridge in this package
33
+ * populates it: it is what lets `InstrumentedBridge` report *provider-measured*
34
+ * tokens and cost instead of a character-count estimate, and what lets the
35
+ * caching decorators declare a hit so the cache-hit rate is a fact rather than
36
+ * an inference. Not concurrency-safe by design — read it immediately after the
37
+ * call, or use `InstrumentedBridge`, which does.
38
+ */
39
+ readonly lastCall?: BridgeCallInfo;
27
40
  /**
28
41
  * Streaming variant — yields tokens incrementally.
29
42
  * Check `supportsStreaming` before calling.
@@ -1 +1 @@
1
- {"version":3,"file":"TransformerBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/TransformerBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,qBAAqB;IAClC,mEAAmE;IACnE,SAAS,CAAC,EAAM,MAAM,CAAC;IACvB,iEAAiE;IACjE,WAAW,CAAC,EAAI,MAAM,CAAC;IACvB,+DAA+D;IAC/D,IAAI,CAAC,EAAW,MAAM,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,sDAAsD;IACtD,KAAK,CAAC,EAAU,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExE;;;OAGG;IACH,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAE7E,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACvC"}
1
+ {"version":3,"file":"TransformerBridge.d.ts","sourceRoot":"","sources":["../../src/bridges/TransformerBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,WAAW,qBAAqB;IAClC,mEAAmE;IACnE,SAAS,CAAC,EAAM,MAAM,CAAC;IACvB,iEAAiE;IACjE,WAAW,CAAC,EAAI,MAAM,CAAC;IACvB,+DAA+D;IAC/D,IAAI,CAAC,EAAW,MAAM,CAAC;IACvB,wEAAwE;IACxE,YAAY,CAAC,EAAG,MAAM,CAAC;IACvB,sDAAsD;IACtD,KAAK,CAAC,EAAU,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAExE;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAEnC;;;OAGG;IACH,MAAM,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAE7E,4DAA4D;IAC5D,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;CACvC"}