@theokit/sdk 5.9.2 → 5.11.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 (133) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/{agent-WQ4LLTSY.cjs → agent-5DOR5T3E.cjs} +12 -10
  3. package/dist/{agent-WQ4LLTSY.cjs.map → agent-5DOR5T3E.cjs.map} +1 -1
  4. package/dist/{agent-enXXu447.d.ts → agent-CmKwSyyD.d.ts} +27 -0
  5. package/dist/{agent-GZVZXKME.js → agent-GWKRARAL.js} +11 -9
  6. package/dist/{agent-GZVZXKME.js.map → agent-GWKRARAL.js.map} +1 -1
  7. package/dist/{agent-Dh2YHSLj.d.cts → agent-XMkGzff_.d.cts} +27 -0
  8. package/dist/{chunk-PEIV7LOU.js → chunk-4PHSVR2R.js} +68 -37
  9. package/dist/chunk-4PHSVR2R.js.map +1 -0
  10. package/dist/{chunk-KXKT3HSD.cjs → chunk-5H2GJXGC.cjs} +4 -4
  11. package/dist/{chunk-KXKT3HSD.cjs.map → chunk-5H2GJXGC.cjs.map} +1 -1
  12. package/dist/{chunk-JU76WCW7.cjs → chunk-5OHB5HJF.cjs} +123 -92
  13. package/dist/chunk-5OHB5HJF.cjs.map +1 -0
  14. package/dist/{chunk-EVH3OUMY.js → chunk-74OA5DIM.js} +189 -43
  15. package/dist/chunk-74OA5DIM.js.map +1 -0
  16. package/dist/chunk-7KIN3L2S.js +103 -0
  17. package/dist/chunk-7KIN3L2S.js.map +1 -0
  18. package/dist/{chunk-EXI7EHDN.js → chunk-7Y23B7XX.js} +3 -3
  19. package/dist/{chunk-EXI7EHDN.js.map → chunk-7Y23B7XX.js.map} +1 -1
  20. package/dist/chunk-ASK2OQM5.cjs +84 -0
  21. package/dist/chunk-ASK2OQM5.cjs.map +1 -0
  22. package/dist/{chunk-QY3CIMUV.cjs → chunk-BZKF7TXX.cjs} +192 -44
  23. package/dist/chunk-BZKF7TXX.cjs.map +1 -0
  24. package/dist/{chunk-ZDF2IJKC.js → chunk-DPY2M74T.js} +3 -3
  25. package/dist/{chunk-ZDF2IJKC.js.map → chunk-DPY2M74T.js.map} +1 -1
  26. package/dist/{chunk-X7Z2FEI7.cjs → chunk-FYEHYQ7T.cjs} +8 -8
  27. package/dist/{chunk-X7Z2FEI7.cjs.map → chunk-FYEHYQ7T.cjs.map} +1 -1
  28. package/dist/{chunk-OZLQ6ZFM.js → chunk-IZDDSLL2.js} +4 -3
  29. package/dist/chunk-IZDDSLL2.js.map +1 -0
  30. package/dist/{chunk-DLUCTZ56.cjs → chunk-L3C6CCBG.cjs} +15 -15
  31. package/dist/{chunk-DLUCTZ56.cjs.map → chunk-L3C6CCBG.cjs.map} +1 -1
  32. package/dist/chunk-LZJXEPEQ.js +58 -0
  33. package/dist/chunk-LZJXEPEQ.js.map +1 -0
  34. package/dist/{chunk-FR6COQXZ.cjs → chunk-N7ZIPW2N.cjs} +3 -3
  35. package/dist/{chunk-FR6COQXZ.cjs.map → chunk-N7ZIPW2N.cjs.map} +1 -1
  36. package/dist/{chunk-RX3CFWQ2.cjs → chunk-NQVWSSX2.cjs} +6 -5
  37. package/dist/chunk-NQVWSSX2.cjs.map +1 -0
  38. package/dist/chunk-NWS2CS3Y.cjs +61 -0
  39. package/dist/chunk-NWS2CS3Y.cjs.map +1 -0
  40. package/dist/chunk-R5YPDAKD.cjs +108 -0
  41. package/dist/chunk-R5YPDAKD.cjs.map +1 -0
  42. package/dist/chunk-RGQICWFU.js +82 -0
  43. package/dist/chunk-RGQICWFU.js.map +1 -0
  44. package/dist/{chunk-N7KYUNFO.js → chunk-W2ZVTEOD.js} +3 -3
  45. package/dist/{chunk-N7KYUNFO.js.map → chunk-W2ZVTEOD.js.map} +1 -1
  46. package/dist/{chunk-47Z6LP3I.js → chunk-X3LOJJMO.js} +88 -28
  47. package/dist/chunk-X3LOJJMO.js.map +1 -0
  48. package/dist/{chunk-M2CCHC66.js → chunk-Z5BAFHPU.js} +3 -3
  49. package/dist/{chunk-M2CCHC66.js.map → chunk-Z5BAFHPU.js.map} +1 -1
  50. package/dist/{chunk-VZ2JZ2EH.cjs → chunk-ZD66GFH5.cjs} +89 -27
  51. package/dist/chunk-ZD66GFH5.cjs.map +1 -0
  52. package/dist/{compact-session-4QHBBGEY.cjs → compact-session-2AETONOS.cjs} +12 -12
  53. package/dist/{compact-session-4QHBBGEY.cjs.map → compact-session-2AETONOS.cjs.map} +1 -1
  54. package/dist/{compact-session-PVAWTKKL.js → compact-session-F2UDGZCN.js} +3 -3
  55. package/dist/{compact-session-PVAWTKKL.js.map → compact-session-F2UDGZCN.js.map} +1 -1
  56. package/dist/{cron-DTuaPMVI.d.ts → cron-BPccQCO8.d.ts} +1 -1
  57. package/dist/{cron-QTgcwcZt.d.cts → cron-Blj6wMYg.d.cts} +1 -1
  58. package/dist/cron.cjs +11 -9
  59. package/dist/cron.d.cts +2 -2
  60. package/dist/cron.d.ts +2 -2
  61. package/dist/cron.js +10 -8
  62. package/dist/eval.cjs +14 -12
  63. package/dist/eval.cjs.map +1 -1
  64. package/dist/eval.js +10 -8
  65. package/dist/eval.js.map +1 -1
  66. package/dist/fs-session-store-3VI4CPTX.js +11 -0
  67. package/dist/{fs-session-store-LCZBM3LT.js.map → fs-session-store-3VI4CPTX.js.map} +1 -1
  68. package/dist/fs-session-store-IQ6PEHYF.cjs +20 -0
  69. package/dist/{fs-session-store-SVEMRE4K.cjs.map → fs-session-store-IQ6PEHYF.cjs.map} +1 -1
  70. package/dist/{index-manager-6B2UF5S3.js → index-manager-JVYIVTZG.js} +5 -4
  71. package/dist/{index-manager-6B2UF5S3.js.map → index-manager-JVYIVTZG.js.map} +1 -1
  72. package/dist/{index-manager-M3FHJCHQ.cjs → index-manager-YGXRFJMZ.cjs} +6 -5
  73. package/dist/{index-manager-M3FHJCHQ.cjs.map → index-manager-YGXRFJMZ.cjs.map} +1 -1
  74. package/dist/index.cjs +62 -145
  75. package/dist/index.cjs.map +1 -1
  76. package/dist/index.d.cts +12 -3
  77. package/dist/index.d.ts +12 -3
  78. package/dist/index.js +27 -115
  79. package/dist/index.js.map +1 -1
  80. package/dist/{inject-session-O24XGRR6.js → inject-session-E5UDFVLI.js} +3 -3
  81. package/dist/{inject-session-O24XGRR6.js.map → inject-session-E5UDFVLI.js.map} +1 -1
  82. package/dist/{inject-session-OMLFL2V3.cjs → inject-session-W4UKACYJ.cjs} +4 -4
  83. package/dist/{inject-session-OMLFL2V3.cjs.map → inject-session-W4UKACYJ.cjs.map} +1 -1
  84. package/dist/internal/budget/normalize-usage.d.ts +81 -0
  85. package/dist/internal/llm/anthropic-shared.d.ts +6 -0
  86. package/dist/internal/llm/openai.d.ts +3 -5
  87. package/dist/internal/llm/openrouter-system.d.ts +1 -0
  88. package/dist/internal/llm/types.d.ts +10 -5
  89. package/dist/internal/memory/dreaming/phases.d.ts +2 -0
  90. package/dist/internal/memory/dreaming/run.d.ts +5 -0
  91. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +2 -0
  92. package/dist/internal/memory/storage/fact-ceiling.d.cts +19 -0
  93. package/dist/internal/memory/storage/fact-ceiling.d.ts +19 -0
  94. package/dist/internal/memory/storage/index.cjs +40 -31
  95. package/dist/internal/memory/storage/index.d.cts +1 -0
  96. package/dist/internal/memory/storage/index.d.ts +1 -0
  97. package/dist/internal/memory/storage/index.js +3 -2
  98. package/dist/internal/memory/storage/markdown-store.d.cts +3 -1
  99. package/dist/internal/memory/storage/markdown-store.d.ts +3 -1
  100. package/dist/internal/memory/types.d.ts +6 -0
  101. package/dist/internal/persistence/index.cjs +7 -6
  102. package/dist/internal/persistence/index.cjs.map +1 -1
  103. package/dist/internal/persistence/index.js +2 -1
  104. package/dist/internal/persistence/index.js.map +1 -1
  105. package/dist/internal/runtime/registry/agent-registry-store.d.ts +2 -0
  106. package/dist/models.cjs +5 -50
  107. package/dist/models.cjs.map +1 -1
  108. package/dist/models.js +3 -51
  109. package/dist/models.js.map +1 -1
  110. package/dist/persistence.cjs +7 -6
  111. package/dist/persistence.cjs.map +1 -1
  112. package/dist/persistence.js +2 -1
  113. package/dist/persistence.js.map +1 -1
  114. package/dist/subagents-loader.d.cts +1 -1
  115. package/dist/subagents-loader.d.ts +1 -1
  116. package/dist/types/agent.d.ts +27 -0
  117. package/docs/error-codes.md +29 -26
  118. package/docs/harness-capability-map.md +6 -1
  119. package/package.json +1 -1
  120. package/dist/chunk-47Z6LP3I.js.map +0 -1
  121. package/dist/chunk-BKMDRBJ7.js +0 -180
  122. package/dist/chunk-BKMDRBJ7.js.map +0 -1
  123. package/dist/chunk-EVH3OUMY.js.map +0 -1
  124. package/dist/chunk-JU76WCW7.cjs.map +0 -1
  125. package/dist/chunk-OF2CLCTH.cjs +0 -186
  126. package/dist/chunk-OF2CLCTH.cjs.map +0 -1
  127. package/dist/chunk-OZLQ6ZFM.js.map +0 -1
  128. package/dist/chunk-PEIV7LOU.js.map +0 -1
  129. package/dist/chunk-QY3CIMUV.cjs.map +0 -1
  130. package/dist/chunk-RX3CFWQ2.cjs.map +0 -1
  131. package/dist/chunk-VZ2JZ2EH.cjs.map +0 -1
  132. package/dist/fs-session-store-LCZBM3LT.js +0 -10
  133. package/dist/fs-session-store-SVEMRE4K.cjs +0 -19
@@ -325,7 +325,10 @@ async function consumeAnthropicResponse(response) {
325
325
  toolCalls: extractAnthropicToolCalls(data),
326
326
  stopReason: mapAnthropicStopReason(data.stop_reason ?? null),
327
327
  inputTokens: data.usage?.input_tokens,
328
- outputTokens: data.usage?.output_tokens
328
+ outputTokens: data.usage?.output_tokens,
329
+ // B-412 — the counters the Bedrock and Vertex Anthropic clients used to drop.
330
+ cacheReadTokens: data.usage?.cache_read_input_tokens,
331
+ cacheWriteTokens: data.usage?.cache_creation_input_tokens
329
332
  };
330
333
  }
331
334
  async function parseHttpErrorBody(response) {
@@ -538,13 +541,9 @@ var AnthropicClient = class {
538
541
  }
539
542
  const accumulator = new AnthropicStreamAccumulator();
540
543
  for await (const record of parseSseStream(response.body, signal)) {
541
- if (record.event === "ping" || record.event === "message_start") continue;
542
- let parsed;
543
- try {
544
- parsed = JSON.parse(record.data);
545
- } catch {
546
- continue;
547
- }
544
+ if (record.event === "ping") continue;
545
+ const parsed = parseAnthropicFrame(record);
546
+ if (parsed === void 0) continue;
548
547
  const events = accumulator.consume(parsed);
549
548
  for (const event of events) yield event;
550
549
  }
@@ -556,6 +555,30 @@ var AnthropicClient = class {
556
555
  return accumulator.finish();
557
556
  }
558
557
  };
558
+ var CONTENT_FRAMES = /* @__PURE__ */ new Set([
559
+ "content_block_start",
560
+ "content_block_delta",
561
+ "message_delta"
562
+ ]);
563
+ function parseAnthropicFrame(record) {
564
+ try {
565
+ return JSON.parse(record.data);
566
+ } catch (parseErr) {
567
+ const event = record.event;
568
+ const size = `${record.data.length} chars`;
569
+ if (CONTENT_FRAMES.has(event)) {
570
+ throw new NetworkError(
571
+ `Anthropic SSE ${event} frame (${size}) is not valid JSON; the turn would lose content`,
572
+ { code: "stream_malformed_frame", cause: parseErr }
573
+ );
574
+ }
575
+ diag(
576
+ `[theokit-sdk] skipped an Anthropic SSE ${event} frame (${size}) that is not valid JSON
577
+ `
578
+ );
579
+ return void 0;
580
+ }
581
+ }
559
582
  var AnthropicStreamAccumulator = class {
560
583
  text = "";
561
584
  stopReason = "end_turn";
@@ -590,6 +613,11 @@ var AnthropicStreamAccumulator = class {
590
613
  if (event.type === "message_delta") {
591
614
  this.handleMessageDelta(event);
592
615
  }
616
+ if (event.type === "message_start") {
617
+ const usage = event.message?.usage;
618
+ if (typeof usage?.input_tokens === "number") this.inputTokens = usage.input_tokens;
619
+ this.readCacheCounters(usage);
620
+ }
593
621
  return [];
594
622
  }
595
623
  handleToolStart(start) {
@@ -642,14 +670,26 @@ var AnthropicStreamAccumulator = class {
642
670
  this.sawStopReason = true;
643
671
  }
644
672
  this.stopReason = mapAnthropicStopReason(md.delta.stop_reason);
645
- if (md.usage?.input_tokens !== void 0) this.inputTokens = md.usage.input_tokens;
646
- if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
647
- if (md.usage?.cache_creation_input_tokens !== void 0 && md.usage.cache_creation_input_tokens > 0) {
648
- this.cacheWriteTokens = md.usage.cache_creation_input_tokens;
649
- }
650
- if (md.usage?.cache_read_input_tokens !== void 0 && md.usage.cache_read_input_tokens > 0) {
651
- this.cacheReadTokens = md.usage.cache_read_input_tokens;
673
+ const input = md.usage?.input_tokens;
674
+ if (typeof input === "number" && (input > 0 || this.inputTokens === void 0)) {
675
+ this.inputTokens = input;
652
676
  }
677
+ if (md.usage?.output_tokens !== void 0) this.outputTokens = md.usage.output_tokens;
678
+ this.readCacheCounters(md.usage);
679
+ }
680
+ /**
681
+ * T3.8 / B-412 / B-475 — the cache counters, from `message_start` and then `message_delta`. A
682
+ * value above 0 replaces the earlier one. A zero, a null or an absent field leaves it in place,
683
+ * so a `message_delta` that zero-fills its usage does not erase what `message_start` reported;
684
+ * a counter no event reports above 0 stays unreported (usage-accumulator strips zero entries).
685
+ * The `typeof` check is there because the wire is JSON: a null arrives although the type
686
+ * declares none.
687
+ */
688
+ readCacheCounters(usage) {
689
+ const write = usage?.cache_creation_input_tokens;
690
+ if (typeof write === "number" && write > 0) this.cacheWriteTokens = write;
691
+ const read = usage?.cache_read_input_tokens;
692
+ if (typeof read === "number" && read > 0) this.cacheReadTokens = read;
653
693
  }
654
694
  /** M2 #61 — whether the terminal `message_delta` (stop_reason) was seen. */
655
695
  get finishReasonSeen() {
@@ -1228,6 +1268,117 @@ function toOllamaTools(tools) {
1228
1268
  }));
1229
1269
  }
1230
1270
 
1271
+ // src/internal/budget/normalize-usage.ts
1272
+ function int(v) {
1273
+ if (typeof v === "number") return Number.isFinite(v) ? Math.max(0, Math.trunc(v)) : 0;
1274
+ if (typeof v === "string") {
1275
+ const n = Number.parseInt(v, 10);
1276
+ return Number.isFinite(n) ? Math.max(0, n) : 0;
1277
+ }
1278
+ return 0;
1279
+ }
1280
+ function buildTotal(buckets) {
1281
+ return buckets.inputTokens + buckets.outputTokens + buckets.cacheReadTokens + buckets.cacheWriteTokens;
1282
+ }
1283
+ function omitUndefined(usage) {
1284
+ return {
1285
+ inputTokens: usage.inputTokens,
1286
+ outputTokens: usage.outputTokens,
1287
+ ...usage.cacheReadTokens > 0 ? { cacheReadTokens: usage.cacheReadTokens } : {},
1288
+ ...usage.cacheWriteTokens > 0 ? { cacheWriteTokens: usage.cacheWriteTokens } : {},
1289
+ ...usage.reasoningTokens > 0 ? { reasoningTokens: usage.reasoningTokens } : {},
1290
+ totalTokens: usage.totalTokens
1291
+ };
1292
+ }
1293
+ function inferApiMode(provider) {
1294
+ const p = provider.toLowerCase();
1295
+ if (p === "anthropic" || p === "claude" || p === "bedrock_anthropic") {
1296
+ return "anthropic_messages";
1297
+ }
1298
+ if (p === "openai-codex" || p === "codex") return "openai_responses";
1299
+ return "openai_chat_completions";
1300
+ }
1301
+ function normalizeUsage(rawUsage, opts) {
1302
+ if (rawUsage === null || rawUsage === void 0) {
1303
+ return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1304
+ }
1305
+ if (typeof rawUsage !== "object") {
1306
+ return { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1307
+ }
1308
+ const raw = rawUsage;
1309
+ const mode = opts.apiMode ?? inferApiMode(opts.provider);
1310
+ if (mode === "anthropic_messages") return normalizeAnthropic(raw);
1311
+ if (mode === "openai_responses") return normalizeOpenAIResponses(raw);
1312
+ return normalizeOpenAIChat(raw);
1313
+ }
1314
+ function normalizeAnthropic(raw) {
1315
+ const inputTokens = int(raw.input_tokens);
1316
+ const outputTokens = int(raw.output_tokens);
1317
+ const cacheReadTokens = int(raw.cache_read_input_tokens);
1318
+ const cacheWriteTokens = int(raw.cache_creation_input_tokens);
1319
+ const usage = {
1320
+ inputTokens,
1321
+ outputTokens,
1322
+ cacheReadTokens,
1323
+ cacheWriteTokens,
1324
+ reasoningTokens: 0,
1325
+ totalTokens: buildTotal({ inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens })
1326
+ };
1327
+ return omitUndefined(usage);
1328
+ }
1329
+ function normalizeOpenAIResponses(raw) {
1330
+ const inputTotal = int(raw.input_tokens);
1331
+ const outputTokens = int(raw.output_tokens);
1332
+ const inputDetails = raw.input_tokens_details ?? {};
1333
+ const outputDetails = raw.output_tokens_details ?? {};
1334
+ const cacheReadTokens = int(inputDetails.cached_tokens);
1335
+ const cacheWriteTokens = int(inputDetails.cache_creation_tokens);
1336
+ const reasoningTokens = int(outputDetails.reasoning_tokens);
1337
+ const inputTokens = Math.max(0, inputTotal - cacheReadTokens - cacheWriteTokens);
1338
+ const usage = {
1339
+ inputTokens,
1340
+ outputTokens,
1341
+ cacheReadTokens,
1342
+ cacheWriteTokens,
1343
+ reasoningTokens,
1344
+ totalTokens: buildTotal({ inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens })
1345
+ };
1346
+ return omitUndefined(usage);
1347
+ }
1348
+ function sent(v) {
1349
+ return v !== void 0 && v !== null;
1350
+ }
1351
+ function splitChatCompletionsPrompt(raw) {
1352
+ const details = raw.prompt_tokens_details ?? {};
1353
+ const bucket = (nested, topLevel) => sent(nested) || sent(topLevel) ? int(nested) || int(topLevel) : void 0;
1354
+ const cacheReadTokens = bucket(details.cached_tokens, raw.cache_read_input_tokens);
1355
+ const cacheWriteTokens = bucket(details.cache_write_tokens, raw.cache_creation_input_tokens);
1356
+ const cached = (cacheReadTokens ?? 0) + (cacheWriteTokens ?? 0);
1357
+ return {
1358
+ ...sent(raw.prompt_tokens) ? { inputTokens: Math.max(0, int(raw.prompt_tokens) - cached) } : {},
1359
+ ...cacheReadTokens !== void 0 ? { cacheReadTokens } : {},
1360
+ ...cacheWriteTokens !== void 0 ? { cacheWriteTokens } : {}
1361
+ };
1362
+ }
1363
+ function normalizeOpenAIChat(raw) {
1364
+ const outputTokens = int(raw.completion_tokens);
1365
+ const completionDetails = raw.completion_tokens_details ?? {};
1366
+ const split = splitChatCompletionsPrompt(raw);
1367
+ const inputTokens = split.inputTokens ?? 0;
1368
+ const cacheReadTokens = split.cacheReadTokens ?? 0;
1369
+ const cacheWriteTokens = split.cacheWriteTokens ?? 0;
1370
+ const reasoningTokens = int(completionDetails.reasoning_tokens);
1371
+ const usage = {
1372
+ inputTokens,
1373
+ outputTokens,
1374
+ cacheReadTokens,
1375
+ cacheWriteTokens,
1376
+ reasoningTokens,
1377
+ totalTokens: buildTotal({ inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens })
1378
+ };
1379
+ return omitUndefined(usage);
1380
+ }
1381
+
1231
1382
  // src/internal/base-url.ts
1232
1383
  function getConfiguredBaseUrl() {
1233
1384
  const value = process.env.THEOKIT_API_BASE_URL;
@@ -1504,6 +1655,16 @@ function assistantMessage(message) {
1504
1655
  return result;
1505
1656
  }
1506
1657
 
1658
+ // src/internal/llm/openrouter-system.ts
1659
+ function encodeOpenRouterSystemContent(system) {
1660
+ if (!Array.isArray(system) || !system.some((block) => block.cacheable === true)) {
1661
+ return void 0;
1662
+ }
1663
+ return system.map(
1664
+ (block) => block.cacheable === true ? { type: "text", text: block.text, cache_control: { type: "ephemeral" } } : { type: "text", text: block.text }
1665
+ );
1666
+ }
1667
+
1507
1668
  // src/internal/llm/openai.ts
1508
1669
  function deriveChatPath(baseUrl) {
1509
1670
  try {
@@ -1646,11 +1807,8 @@ var OpenAIStreamAccumulator = class {
1646
1807
  allowedToolNames;
1647
1808
  text = "";
1648
1809
  stopReason = "end_turn";
1649
- inputTokens;
1650
- outputTokens;
1651
- cacheReadTokens;
1652
- cacheWriteTokens;
1653
- reasoningTokens;
1810
+ /** The stream's `usage` object, a later chunk replacing an earlier one per top-level field. */
1811
+ usage = {};
1654
1812
  toolCalls = /* @__PURE__ */ new Map();
1655
1813
  /** R7: present only when recovery is enabled AND the request declares tools — holds suspected
1656
1814
  * leaked-dialect content back from the `text_delta` stream. `undefined` ⇒ stream immediately. */
@@ -1684,18 +1842,7 @@ var OpenAIStreamAccumulator = class {
1684
1842
  return { type: "reasoning_delta", text: reasoning };
1685
1843
  }
1686
1844
  applyUsage(usage) {
1687
- if (usage?.prompt_tokens !== void 0) this.inputTokens = usage.prompt_tokens;
1688
- if (usage?.completion_tokens !== void 0) this.outputTokens = usage.completion_tokens;
1689
- const cachedDetail = usage?.prompt_tokens_details?.cached_tokens;
1690
- if (cachedDetail !== void 0) this.cacheReadTokens = cachedDetail;
1691
- const reasoningDetail = usage?.completion_tokens_details?.reasoning_tokens;
1692
- if (reasoningDetail !== void 0) this.reasoningTokens = reasoningDetail;
1693
- if (usage?.cache_read_input_tokens !== void 0) {
1694
- this.cacheReadTokens = usage.cache_read_input_tokens;
1695
- }
1696
- if (usage?.cache_creation_input_tokens !== void 0) {
1697
- this.cacheWriteTokens = usage.cache_creation_input_tokens;
1698
- }
1845
+ if (usage !== void 0) this.usage = { ...this.usage, ...usage };
1699
1846
  }
1700
1847
  applyContentDelta(content) {
1701
1848
  if (typeof content !== "string" || content.length === 0) return void 0;
@@ -1766,11 +1913,10 @@ var OpenAIStreamAccumulator = class {
1766
1913
  stopReason,
1767
1914
  text,
1768
1915
  toolCalls,
1769
- inputTokens: this.inputTokens,
1770
- outputTokens: this.outputTokens,
1771
- cacheReadTokens: this.cacheReadTokens,
1772
- cacheWriteTokens: this.cacheWriteTokens,
1773
- reasoningTokens: this.reasoningTokens
1916
+ // D376: the prompt split (cache buckets out of inputTokens) has one owner, normalize-usage.ts.
1917
+ ...splitChatCompletionsPrompt(this.usage),
1918
+ outputTokens: this.usage.completion_tokens,
1919
+ reasoningTokens: this.usage.completion_tokens_details?.reasoning_tokens
1774
1920
  });
1775
1921
  }
1776
1922
  };
@@ -1791,10 +1937,10 @@ function applyToolsRequest(body, request) {
1791
1937
  }
1792
1938
  function buildOpenAIBody(request, providerName) {
1793
1939
  const messages = [];
1940
+ const systemParts = providerName === "openrouter" ? encodeOpenRouterSystemContent(request.system) : void 0;
1794
1941
  const systemText = openAISystemText(request.system);
1795
- if (systemText.length > 0) {
1796
- messages.push({ role: "system", content: systemText });
1797
- }
1942
+ if (systemParts !== void 0) messages.push({ role: "system", content: systemParts });
1943
+ else if (systemText.length > 0) messages.push({ role: "system", content: systemText });
1798
1944
  for (const message of request.messages) {
1799
1945
  for (const out of toOpenAIMessages(message)) messages.push(out);
1800
1946
  }
@@ -3291,6 +3437,6 @@ async function autoCompactIfNeeded(opts) {
3291
3437
  }
3292
3438
  }
3293
3439
 
3294
- export { COMPACT_SUMMARY_MARKER, COMPACT_USER_MESSAGE_MAX_TOKENS, CircuitBreaker, DEFAULT_PRE_COMPACT_TIMEOUT_MS, abortError, autoCompactIfNeeded, buildDefaultSummarizer, compactSessionTranscript, discoverProviderPlugins, getConfiguredBaseUrl, httpRequest, isCompactSummary, isFixtureApiKey, mapOllamaHttpError, mapOllamaTransportError, mergeExplicitApiKey, parseSseStream, presentProviderCredentialEnvVars, readErrorResponseBody, relayStream, renderToolResultContentText, resolveProviderChain, resolveRunProvider, resolveSummarizerRoute, shouldAutoCompact, shouldUseFixtureMode, shouldUseRealLocalRuntime, tryFirstEvent, validateApiKeyShape };
3295
- //# sourceMappingURL=chunk-EVH3OUMY.js.map
3296
- //# sourceMappingURL=chunk-EVH3OUMY.js.map
3440
+ export { COMPACT_SUMMARY_MARKER, COMPACT_USER_MESSAGE_MAX_TOKENS, CircuitBreaker, DEFAULT_PRE_COMPACT_TIMEOUT_MS, abortError, autoCompactIfNeeded, buildDefaultSummarizer, compactSessionTranscript, discoverProviderPlugins, getConfiguredBaseUrl, httpRequest, inferApiMode, isCompactSummary, isFixtureApiKey, mapOllamaHttpError, mapOllamaTransportError, mergeExplicitApiKey, normalizeUsage, parseSseStream, presentProviderCredentialEnvVars, readErrorResponseBody, relayStream, renderToolResultContentText, resolveProviderChain, resolveRunProvider, resolveSummarizerRoute, shouldAutoCompact, shouldUseFixtureMode, shouldUseRealLocalRuntime, tryFirstEvent, validateApiKeyShape };
3441
+ //# sourceMappingURL=chunk-74OA5DIM.js.map
3442
+ //# sourceMappingURL=chunk-74OA5DIM.js.map