reasonix 0.46.0 → 0.46.1

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 (147) hide show
  1. package/README.md +3 -0
  2. package/README.zh-CN.md +3 -0
  3. package/dashboard/dist/app.js +76 -6
  4. package/dashboard/dist/app.js.map +1 -1
  5. package/dist/cli/{acp-LGBLHBKY.js → acp-LKJU5DZX.js} +19 -19
  6. package/dist/cli/chat-W7LAWEN6.js +51 -0
  7. package/dist/cli/chunk-2425HK6U.js +0 -0
  8. package/dist/cli/chunk-25T6CVUP.js +0 -0
  9. package/dist/cli/{chunk-5I2C4JEO.js → chunk-2AASOSD5.js} +6 -6
  10. package/dist/cli/{chunk-5I2C4JEO.js.map → chunk-2AASOSD5.js.map} +1 -1
  11. package/dist/cli/chunk-2UQP6H6T.js +0 -0
  12. package/dist/cli/{chunk-HVUZWNSP.js → chunk-3AAG2CUT.js} +2 -2
  13. package/dist/cli/chunk-5QCB62C4.js +0 -0
  14. package/dist/cli/chunk-6OWJV3YW.js +0 -0
  15. package/dist/cli/{chunk-IJ7JA32V.js → chunk-6VANO7KB.js} +44 -8
  16. package/dist/cli/chunk-6VANO7KB.js.map +1 -0
  17. package/dist/cli/{chunk-LIR2HBQH.js → chunk-7LOJS3LV.js} +2 -2
  18. package/dist/cli/{chunk-I4L2GTSE.js → chunk-7SGGXNB2.js} +2 -2
  19. package/dist/cli/{chunk-CBIQWMS6.js → chunk-7YW6TPXK.js} +7 -7
  20. package/dist/cli/{chunk-A3TSSDS2.js → chunk-C72TNHDE.js} +2 -2
  21. package/dist/cli/chunk-CXVWUPA3.js +0 -0
  22. package/dist/cli/{chunk-AVFXO2EZ.js → chunk-DGA5QYFM.js} +107 -4
  23. package/dist/cli/chunk-DGA5QYFM.js.map +1 -0
  24. package/dist/cli/{chunk-JNAQYELD.js → chunk-DHRVZJ2D.js} +2 -2
  25. package/dist/cli/{chunk-5ACMUK4Q.js → chunk-E7TAHQ4A.js} +2 -1
  26. package/dist/cli/{chunk-C53JQES5.js → chunk-EAOL43HB.js} +3 -3
  27. package/dist/cli/chunk-FEZK652I.js +0 -0
  28. package/dist/cli/chunk-HNXDZGC6.js +0 -0
  29. package/dist/cli/{chunk-QJDDIK3Z.js → chunk-IYQ325V7.js} +2 -2
  30. package/dist/cli/chunk-J5XJHLWM.js +0 -0
  31. package/dist/cli/{chunk-4CTDEJUF.js → chunk-JLQDNLZF.js} +2 -2
  32. package/dist/cli/chunk-JMBMLOBP.js +0 -0
  33. package/dist/cli/{chunk-RDRC3XDT.js → chunk-JVFEJAJX.js} +2 -2
  34. package/dist/cli/{chunk-GTZTQNX5.js → chunk-JVQT5IYP.js} +7 -7
  35. package/dist/cli/{chunk-YY227BIQ.js → chunk-K3AIFMI6.js} +2 -2
  36. package/dist/cli/{chunk-ZZYBBX5N.js → chunk-M4E5JK6S.js} +23 -9
  37. package/dist/cli/chunk-M4E5JK6S.js.map +1 -0
  38. package/dist/cli/{chunk-V26WPN3J.js → chunk-MIIZJD5O.js} +28 -1
  39. package/dist/cli/chunk-MIIZJD5O.js.map +1 -0
  40. package/dist/cli/{chunk-4HCP2UQW.js → chunk-NCBP5D6E.js} +2 -2
  41. package/dist/cli/chunk-PLHAZOLZ.js +0 -0
  42. package/dist/cli/{chunk-HKWSPKMU.js → chunk-R2ASNSEO.js} +8 -8
  43. package/dist/cli/chunk-S4XVGLRW.js +0 -0
  44. package/dist/cli/{chunk-W7YGWUWU.js → chunk-SE7C5ZSI.js} +3 -3
  45. package/dist/cli/{chunk-KQU2TYIL.js → chunk-SPXN5JIT.js} +1128 -675
  46. package/dist/cli/chunk-SPXN5JIT.js.map +1 -0
  47. package/dist/cli/chunk-SZ5XES2N.js +0 -0
  48. package/dist/cli/{chunk-WK3UFQY3.js → chunk-TDSBASOF.js} +2 -2
  49. package/dist/cli/chunk-TEUDEGX2.js +0 -0
  50. package/dist/cli/chunk-TUK7OWJA.js +0 -0
  51. package/dist/cli/{chunk-XSU4QVFW.js → chunk-WQ6ZRDQM.js} +12 -3
  52. package/dist/cli/chunk-WQ6ZRDQM.js.map +1 -0
  53. package/dist/cli/{chunk-R3CTO2HM.js → chunk-WRONKNIH.js} +2 -2
  54. package/dist/cli/chunk-X53B3JIX.js +0 -0
  55. package/dist/cli/chunk-XJXDHAES.js +0 -0
  56. package/dist/cli/{chunk-MJ6W5UN3.js → chunk-XPAUNFOL.js} +2 -2
  57. package/dist/cli/chunk-XXC2BYTV.js +0 -0
  58. package/dist/cli/{chunk-NVURFF27.js → chunk-YRLC2EDF.js} +2 -2
  59. package/dist/cli/{chunk-WL6SNQ5T.js → chunk-ZOQHVQON.js} +9 -93
  60. package/dist/cli/chunk-ZOQHVQON.js.map +1 -0
  61. package/dist/cli/chunk-ZZM6QJ4W.js +0 -0
  62. package/dist/cli/{code-DFHSASJ4.js → code-2JIHL5M2.js} +29 -30
  63. package/dist/cli/code-2JIHL5M2.js.map +1 -0
  64. package/dist/cli/{commands-OCU42XG4.js → commands-OPT5AJNH.js} +4 -4
  65. package/dist/cli/{commit-XCQIQCYG.js → commit-KA37H6GM.js} +3 -3
  66. package/dist/cli/{desktop-ZCUG7LMF.js → desktop-5ONTRU3C.js} +20 -20
  67. package/dist/cli/devtools-HW3WDT3Q.js +0 -0
  68. package/dist/cli/{diff-66B2KWOJ.js → diff-SOIA7AKH.js} +8 -8
  69. package/dist/cli/{doctor-Y73CPPRZ.js → doctor-RCUP4XRV.js} +9 -9
  70. package/dist/cli/{events-NGZ2OJYH.js → events-6KHITNX4.js} +3 -3
  71. package/dist/cli/index.js +39 -88
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/{mcp-MPVGBBJF.js → mcp-JP5OWD6R.js} +2 -2
  74. package/dist/cli/{mcp-browse-4XOTC3FJ.js → mcp-browse-ONCJJPJN.js} +2 -2
  75. package/dist/cli/{mcp-inspect-CEMGKKAH.js → mcp-inspect-TPLHW5JA.js} +4 -4
  76. package/dist/cli/{prompt-2D7ID24X.js → prompt-RJDNCQAP.js} +3 -3
  77. package/dist/cli/{prune-sessions-OJEYYLHY.js → prune-sessions-MKEATRVL.js} +2 -2
  78. package/dist/cli/{replay-AKYQNAQJ.js → replay-4NILJG4U.js} +8 -8
  79. package/dist/cli/{run-5DPQFSP6.js → run-WFGXB4SB.js} +17 -18
  80. package/dist/cli/run-WFGXB4SB.js.map +1 -0
  81. package/dist/cli/{server-TQ2IHYQJ.js → server-5VFQP3PV.js} +13 -13
  82. package/dist/cli/{sessions-KY54NG45.js → sessions-5XDJDALO.js} +28 -14
  83. package/dist/cli/sessions-5XDJDALO.js.map +1 -0
  84. package/dist/cli/{setup-XPIOZWS7.js → setup-F6XSWLRA.js} +7 -7
  85. package/dist/cli/setup-F6XSWLRA.js.map +1 -0
  86. package/dist/cli/{stats-X2VTWKNS.js → stats-ALHBZICE.js} +6 -6
  87. package/dist/cli/update-6ITLPRDV.js +0 -0
  88. package/dist/cli/{version-7O6A5T7Q.js → version-JVRAHBMM.js} +14 -14
  89. package/dist/index.d.ts +23 -13
  90. package/dist/index.js +1112 -1090
  91. package/dist/index.js.map +1 -1
  92. package/package.json +1 -1
  93. package/dist/cli/.-3G6VX5S7.js +0 -327
  94. package/dist/cli/.-6YRPB2C7.js +0 -329
  95. package/dist/cli/.-EYSVINK3.js +0 -317
  96. package/dist/cli/chat-ECK5ZGMV.js +0 -51
  97. package/dist/cli/chunk-AVFXO2EZ.js.map +0 -1
  98. package/dist/cli/chunk-IJ7JA32V.js.map +0 -1
  99. package/dist/cli/chunk-KQU2TYIL.js.map +0 -1
  100. package/dist/cli/chunk-V26WPN3J.js.map +0 -1
  101. package/dist/cli/chunk-WL6SNQ5T.js.map +0 -1
  102. package/dist/cli/chunk-XSU4QVFW.js.map +0 -1
  103. package/dist/cli/chunk-ZZYBBX5N.js.map +0 -1
  104. package/dist/cli/code-DFHSASJ4.js.map +0 -1
  105. package/dist/cli/doctor-Y73CPPRZ.js.map +0 -1
  106. package/dist/cli/prompt-2D7ID24X.js.map +0 -1
  107. package/dist/cli/run-5DPQFSP6.js.map +0 -1
  108. package/dist/cli/sessions-KY54NG45.js.map +0 -1
  109. package/dist/cli/setup-XPIOZWS7.js.map +0 -1
  110. package/dist/cli/stats-X2VTWKNS.js.map +0 -1
  111. /package/dist/cli/{acp-LGBLHBKY.js.map → acp-LKJU5DZX.js.map} +0 -0
  112. /package/dist/cli/{.-3G6VX5S7.js.map → chat-W7LAWEN6.js.map} +0 -0
  113. /package/dist/cli/{chunk-HVUZWNSP.js.map → chunk-3AAG2CUT.js.map} +0 -0
  114. /package/dist/cli/{chunk-LIR2HBQH.js.map → chunk-7LOJS3LV.js.map} +0 -0
  115. /package/dist/cli/{chunk-I4L2GTSE.js.map → chunk-7SGGXNB2.js.map} +0 -0
  116. /package/dist/cli/{chunk-CBIQWMS6.js.map → chunk-7YW6TPXK.js.map} +0 -0
  117. /package/dist/cli/{chunk-A3TSSDS2.js.map → chunk-C72TNHDE.js.map} +0 -0
  118. /package/dist/cli/{chunk-JNAQYELD.js.map → chunk-DHRVZJ2D.js.map} +0 -0
  119. /package/dist/cli/{chunk-5ACMUK4Q.js.map → chunk-E7TAHQ4A.js.map} +0 -0
  120. /package/dist/cli/{chunk-C53JQES5.js.map → chunk-EAOL43HB.js.map} +0 -0
  121. /package/dist/cli/{chunk-QJDDIK3Z.js.map → chunk-IYQ325V7.js.map} +0 -0
  122. /package/dist/cli/{chunk-4CTDEJUF.js.map → chunk-JLQDNLZF.js.map} +0 -0
  123. /package/dist/cli/{chunk-RDRC3XDT.js.map → chunk-JVFEJAJX.js.map} +0 -0
  124. /package/dist/cli/{chunk-GTZTQNX5.js.map → chunk-JVQT5IYP.js.map} +0 -0
  125. /package/dist/cli/{chunk-YY227BIQ.js.map → chunk-K3AIFMI6.js.map} +0 -0
  126. /package/dist/cli/{chunk-4HCP2UQW.js.map → chunk-NCBP5D6E.js.map} +0 -0
  127. /package/dist/cli/{chunk-HKWSPKMU.js.map → chunk-R2ASNSEO.js.map} +0 -0
  128. /package/dist/cli/{chunk-W7YGWUWU.js.map → chunk-SE7C5ZSI.js.map} +0 -0
  129. /package/dist/cli/{chunk-WK3UFQY3.js.map → chunk-TDSBASOF.js.map} +0 -0
  130. /package/dist/cli/{chunk-R3CTO2HM.js.map → chunk-WRONKNIH.js.map} +0 -0
  131. /package/dist/cli/{chunk-MJ6W5UN3.js.map → chunk-XPAUNFOL.js.map} +0 -0
  132. /package/dist/cli/{chunk-NVURFF27.js.map → chunk-YRLC2EDF.js.map} +0 -0
  133. /package/dist/cli/{commands-OCU42XG4.js.map → commands-OPT5AJNH.js.map} +0 -0
  134. /package/dist/cli/{commit-XCQIQCYG.js.map → commit-KA37H6GM.js.map} +0 -0
  135. /package/dist/cli/{desktop-ZCUG7LMF.js.map → desktop-5ONTRU3C.js.map} +0 -0
  136. /package/dist/cli/{diff-66B2KWOJ.js.map → diff-SOIA7AKH.js.map} +0 -0
  137. /package/dist/cli/{.-6YRPB2C7.js.map → doctor-RCUP4XRV.js.map} +0 -0
  138. /package/dist/cli/{events-NGZ2OJYH.js.map → events-6KHITNX4.js.map} +0 -0
  139. /package/dist/cli/{mcp-MPVGBBJF.js.map → mcp-JP5OWD6R.js.map} +0 -0
  140. /package/dist/cli/{mcp-browse-4XOTC3FJ.js.map → mcp-browse-ONCJJPJN.js.map} +0 -0
  141. /package/dist/cli/{mcp-inspect-CEMGKKAH.js.map → mcp-inspect-TPLHW5JA.js.map} +0 -0
  142. /package/dist/cli/{.-EYSVINK3.js.map → prompt-RJDNCQAP.js.map} +0 -0
  143. /package/dist/cli/{prune-sessions-OJEYYLHY.js.map → prune-sessions-MKEATRVL.js.map} +0 -0
  144. /package/dist/cli/{replay-AKYQNAQJ.js.map → replay-4NILJG4U.js.map} +0 -0
  145. /package/dist/cli/{server-TQ2IHYQJ.js.map → server-5VFQP3PV.js.map} +0 -0
  146. /package/dist/cli/{chat-ECK5ZGMV.js.map → stats-ALHBZICE.js.map} +0 -0
  147. /package/dist/cli/{version-7O6A5T7Q.js.map → version-JVRAHBMM.js.map} +0 -0
@@ -3,28 +3,28 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
3
3
  import {
4
4
  formatMcpLifecycleEvent,
5
5
  formatMcpSlowToast
6
- } from "./chunk-4HCP2UQW.js";
6
+ } from "./chunk-NCBP5D6E.js";
7
7
  import {
8
8
  buildTransportFromSpec,
9
9
  preflightStdioSpec
10
- } from "./chunk-NVURFF27.js";
10
+ } from "./chunk-YRLC2EDF.js";
11
11
  import {
12
12
  bridgeMcpTools
13
- } from "./chunk-WL6SNQ5T.js";
13
+ } from "./chunk-ZOQHVQON.js";
14
14
  import {
15
15
  McpClient,
16
16
  inspectMcpServer
17
- } from "./chunk-XSU4QVFW.js";
17
+ } from "./chunk-WQ6ZRDQM.js";
18
18
  import {
19
19
  t
20
- } from "./chunk-IJ7JA32V.js";
20
+ } from "./chunk-6VANO7KB.js";
21
21
  import {
22
22
  normalizeMcpConfig,
23
23
  overlayMatchedSpec,
24
24
  parseMcpSpec,
25
25
  readConfig,
26
26
  specToRaw
27
- } from "./chunk-AVFXO2EZ.js";
27
+ } from "./chunk-DGA5QYFM.js";
28
28
 
29
29
  // src/mcp/summary.ts
30
30
  function buildMcpServerSummary(opts) {
@@ -310,4 +310,4 @@ function createMcpRuntime(ctx) {
310
310
  export {
311
311
  createMcpRuntime
312
312
  };
313
- //# sourceMappingURL=chunk-GTZTQNX5.js.map
313
+ //# sourceMappingURL=chunk-JVQT5IYP.js.map
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  useColor
5
- } from "./chunk-I4L2GTSE.js";
5
+ } from "./chunk-7SGGXNB2.js";
6
6
  import {
7
7
  Box_default,
8
8
  Text,
@@ -621,4 +621,4 @@ export {
621
621
  SingleSelect,
622
622
  MultiSelect
623
623
  };
624
- //# sourceMappingURL=chunk-YY227BIQ.js.map
624
+ //# sourceMappingURL=chunk-K3AIFMI6.js.map
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
+ import {
4
+ loadPricingOverride
5
+ } from "./chunk-DGA5QYFM.js";
3
6
 
4
7
  // src/telemetry/stats.ts
5
8
  var DEEPSEEK_PRICING = {
@@ -9,6 +12,16 @@ var DEEPSEEK_PRICING = {
9
12
  "deepseek-chat": { inputCacheHit: 28e-4, inputCacheMiss: 0.14, output: 0.28 },
10
13
  "deepseek-reasoner": { inputCacheHit: 28e-4, inputCacheMiss: 0.14, output: 0.28 }
11
14
  };
15
+ function pricingFor(model, path) {
16
+ const defaults = DEEPSEEK_PRICING[model];
17
+ const override = loadPricingOverride(path)[model];
18
+ if (!override) return defaults;
19
+ const pricing = { ...defaults, ...override };
20
+ if (pricing.inputCacheHit === void 0 || pricing.inputCacheMiss === void 0 || pricing.output === void 0) {
21
+ return void 0;
22
+ }
23
+ return pricing;
24
+ }
12
25
  var CLAUDE_SONNET_PRICING = { input: 3, output: 15 };
13
26
  var DEEPSEEK_CONTEXT_TOKENS = {
14
27
  "deepseek-v4-flash": 1e6,
@@ -17,24 +30,24 @@ var DEEPSEEK_CONTEXT_TOKENS = {
17
30
  "deepseek-reasoner": 1e6
18
31
  };
19
32
  var DEFAULT_CONTEXT_TOKENS = 131072;
20
- function costUsd(model, usage) {
21
- const p = DEEPSEEK_PRICING[model];
33
+ function costUsd(model, usage, path) {
34
+ const p = pricingFor(model, path);
22
35
  if (!p) return 0;
23
36
  return (usage.promptCacheHitTokens * p.inputCacheHit + usage.promptCacheMissTokens * p.inputCacheMiss + usage.completionTokens * p.output) / 1e6;
24
37
  }
25
- function inputCostUsd(model, usage) {
26
- const p = DEEPSEEK_PRICING[model];
38
+ function inputCostUsd(model, usage, path) {
39
+ const p = pricingFor(model, path);
27
40
  if (!p) return 0;
28
41
  return (usage.promptCacheHitTokens * p.inputCacheHit + usage.promptCacheMissTokens * p.inputCacheMiss) / 1e6;
29
42
  }
30
- function outputCostUsd(model, usage) {
31
- const p = DEEPSEEK_PRICING[model];
43
+ function outputCostUsd(model, usage, path) {
44
+ const p = pricingFor(model, path);
32
45
  if (!p) return 0;
33
46
  return usage.completionTokens * p.output / 1e6;
34
47
  }
35
- function cacheSavingsUsd(model, hitTokens) {
48
+ function cacheSavingsUsd(model, hitTokens, path) {
36
49
  if (hitTokens <= 0) return 0;
37
- const p = DEEPSEEK_PRICING[model];
50
+ const p = pricingFor(model, path);
38
51
  if (!p) return 0;
39
52
  return hitTokens * (p.inputCacheMiss - p.inputCacheHit) / 1e6;
40
53
  }
@@ -137,6 +150,7 @@ function round(n, digits) {
137
150
 
138
151
  export {
139
152
  DEEPSEEK_PRICING,
153
+ pricingFor,
140
154
  DEEPSEEK_CONTEXT_TOKENS,
141
155
  DEFAULT_CONTEXT_TOKENS,
142
156
  costUsd,
@@ -146,4 +160,4 @@ export {
146
160
  claudeEquivalentCost,
147
161
  SessionStats
148
162
  };
149
- //# sourceMappingURL=chunk-ZZYBBX5N.js.map
163
+ //# sourceMappingURL=chunk-M4E5JK6S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/telemetry/stats.ts"],"sourcesContent":["import type { Usage } from \"../client.js\";\nimport { loadPricingOverride } from \"../config.js\";\n\n/** USD per 1M tokens; display currency conversion happens at the UI boundary. */\nexport const DEEPSEEK_PRICING: Record<\n string,\n { inputCacheHit: number; inputCacheMiss: number; output: number }\n> = {\n \"deepseek-v4-flash\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n \"deepseek-v4-pro\": { inputCacheHit: 0.003625, inputCacheMiss: 0.435, output: 0.87 },\n // Compat aliases — priced as v4-flash per the deprecation notice.\n \"deepseek-chat\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n \"deepseek-reasoner\": { inputCacheHit: 0.0028, inputCacheMiss: 0.14, output: 0.28 },\n};\n\nexport type ModelPricing = (typeof DEEPSEEK_PRICING)[string];\n\nexport function pricingFor(model: string, path?: string): ModelPricing | undefined {\n const defaults = DEEPSEEK_PRICING[model];\n const override = loadPricingOverride(path)[model];\n if (!override) return defaults;\n const pricing = { ...defaults, ...override };\n if (\n pricing.inputCacheHit === undefined ||\n pricing.inputCacheMiss === undefined ||\n pricing.output === undefined\n ) {\n return undefined;\n }\n return pricing as ModelPricing;\n}\n\n/** Reference Claude Sonnet 4.6 pricing (USD per 1M tokens). */\nexport const CLAUDE_SONNET_PRICING = { input: 3.0, output: 15.0 };\n\n/** Prompt-side window only; completion caps live server-side and don't affect this gauge. */\nexport const DEEPSEEK_CONTEXT_TOKENS: Record<string, number> = {\n \"deepseek-v4-flash\": 1_000_000,\n \"deepseek-v4-pro\": 1_000_000,\n \"deepseek-chat\": 1_000_000,\n \"deepseek-reasoner\": 1_000_000,\n};\n\n/** Fallback when the caller's model id isn't in the table — safe lower bound. */\nexport const DEFAULT_CONTEXT_TOKENS = 131_072;\n\nexport function costUsd(model: string, usage: Usage, path?: string): number {\n const p = pricingFor(model, path);\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss +\n usage.completionTokens * p.output) /\n 1_000_000\n );\n}\n\n/** Input-side cost only (prompt, cache hit + miss). Used for the panel breakdown. */\nexport function inputCostUsd(model: string, usage: Usage, path?: string): number {\n const p = pricingFor(model, path);\n if (!p) return 0;\n return (\n (usage.promptCacheHitTokens * p.inputCacheHit +\n usage.promptCacheMissTokens * p.inputCacheMiss) /\n 1_000_000\n );\n}\n\n/** Output-side cost only (completion tokens). Used for the panel breakdown. */\nexport function outputCostUsd(model: string, usage: Usage, path?: string): number {\n const p = pricingFor(model, path);\n if (!p) return 0;\n return (usage.completionTokens * p.output) / 1_000_000;\n}\n\nexport function cacheSavingsUsd(model: string, hitTokens: number, path?: string): number {\n if (hitTokens <= 0) return 0;\n const p = pricingFor(model, path);\n if (!p) return 0;\n return (hitTokens * (p.inputCacheMiss - p.inputCacheHit)) / 1_000_000;\n}\n\nexport function claudeEquivalentCost(usage: Usage): number {\n return (\n (usage.promptTokens * CLAUDE_SONNET_PRICING.input +\n usage.completionTokens * CLAUDE_SONNET_PRICING.output) /\n 1_000_000\n );\n}\n\nexport interface TurnStats {\n turn: number;\n model: string;\n usage: Usage;\n cost: number;\n cacheHitRatio: number;\n}\n\nexport interface SessionSummary {\n turns: number;\n totalCostUsd: number;\n totalInputCostUsd: number;\n /** Output-side (completion) cost aggregated across the session. */\n totalOutputCostUsd: number;\n /** @deprecated Claude reference; kept for benchmarks + replay compat, no longer surfaced in the TUI. */\n claudeEquivalentUsd: number;\n /** @deprecated. Same as claudeEquivalentUsd — synthetic ratio, not a real measurement. */\n savingsVsClaudePct: number;\n cacheHitRatio: number;\n /** Floor estimate for next call — actual cost = this + user delta + new tool outputs. */\n lastPromptTokens: number;\n lastTurnCostUsd: number;\n}\n\nexport class SessionStats {\n readonly turns: TurnStats[] = [];\n /** Cost from prior runs of a resumed session, restored from session meta. */\n private _carryoverCost = 0;\n /** Turn count from prior runs of a resumed session. */\n private _carryoverTurns = 0;\n private _carryoverCacheHit = 0;\n private _carryoverCacheMiss = 0;\n /** Last turn's promptTokens before exit — surfaced via summary() until the next live turn lands. */\n private _carryoverLastPromptTokens = 0;\n\n /** Seed totals from a resumed session's persisted meta — only call once at construction. */\n seedCarryover(opts: {\n totalCostUsd?: number;\n turnCount?: number;\n cacheHitTokens?: number;\n cacheMissTokens?: number;\n lastPromptTokens?: number;\n }): void {\n if (typeof opts.totalCostUsd === \"number\" && opts.totalCostUsd > 0) {\n this._carryoverCost = opts.totalCostUsd;\n }\n if (typeof opts.turnCount === \"number\" && opts.turnCount > 0) {\n this._carryoverTurns = opts.turnCount;\n }\n if (typeof opts.cacheHitTokens === \"number\" && opts.cacheHitTokens > 0) {\n this._carryoverCacheHit = opts.cacheHitTokens;\n }\n if (typeof opts.cacheMissTokens === \"number\" && opts.cacheMissTokens > 0) {\n this._carryoverCacheMiss = opts.cacheMissTokens;\n }\n if (typeof opts.lastPromptTokens === \"number\" && opts.lastPromptTokens > 0) {\n this._carryoverLastPromptTokens = opts.lastPromptTokens;\n }\n }\n\n reset(): void {\n this.turns.length = 0;\n this._carryoverCost = 0;\n this._carryoverTurns = 0;\n this._carryoverCacheHit = 0;\n this._carryoverCacheMiss = 0;\n this._carryoverLastPromptTokens = 0;\n }\n\n record(turn: number, model: string, usage: Usage): TurnStats {\n const cost = costUsd(model, usage);\n const stats: TurnStats = {\n turn,\n model,\n usage,\n cost,\n cacheHitRatio: usage.cacheHitRatio,\n };\n this.turns.push(stats);\n return stats;\n }\n\n get totalCost(): number {\n return this._carryoverCost + this.turns.reduce((sum, t) => sum + t.cost, 0);\n }\n\n get totalClaudeEquivalent(): number {\n return this.turns.reduce((sum, t) => sum + claudeEquivalentCost(t.usage), 0);\n }\n\n get savingsVsClaude(): number {\n const c = this.totalClaudeEquivalent;\n return c > 0 ? 1 - this.totalCost / c : 0;\n }\n\n get totalInputCost(): number {\n return this.turns.reduce((sum, t) => sum + inputCostUsd(t.model, t.usage), 0);\n }\n\n get totalOutputCost(): number {\n return this.turns.reduce((sum, t) => sum + outputCostUsd(t.model, t.usage), 0);\n }\n\n get aggregateCacheHitRatio(): number {\n let hit = this._carryoverCacheHit;\n let miss = this._carryoverCacheMiss;\n for (const t of this.turns) {\n hit += t.usage.promptCacheHitTokens;\n miss += t.usage.promptCacheMissTokens;\n }\n const denom = hit + miss;\n return denom > 0 ? hit / denom : 0;\n }\n\n summary(): SessionSummary {\n const last = this.turns[this.turns.length - 1];\n return {\n turns: this.turns.length + this._carryoverTurns,\n totalCostUsd: round(this.totalCost, 6),\n totalInputCostUsd: round(this.totalInputCost, 6),\n totalOutputCostUsd: round(this.totalOutputCost, 6),\n claudeEquivalentUsd: round(this.totalClaudeEquivalent, 6),\n savingsVsClaudePct: round(this.savingsVsClaude * 100, 2),\n cacheHitRatio: round(this.aggregateCacheHitRatio, 4),\n lastPromptTokens: last?.usage.promptTokens ?? this._carryoverLastPromptTokens,\n lastTurnCostUsd: round(last?.cost ?? 0, 6),\n };\n }\n}\n\nfunction round(n: number, digits: number): number {\n const f = 10 ** digits;\n return Math.round(n * f) / f;\n}\n"],"mappings":"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","names":[]}
@@ -3,6 +3,9 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
3
3
  import {
4
4
  createParser
5
5
  } from "./chunk-25T6CVUP.js";
6
+ import {
7
+ loadRateLimit
8
+ } from "./chunk-DGA5QYFM.js";
6
9
 
7
10
  // src/retry.ts
8
11
  var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
@@ -122,6 +125,8 @@ var DeepSeekClient = class {
122
125
  timeoutMs;
123
126
  retry;
124
127
  _fetch;
128
+ minChatIntervalMs;
129
+ nextChatRequestAt = 0;
125
130
  constructor(opts = {}) {
126
131
  const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;
127
132
  if (!apiKey) {
@@ -136,6 +141,26 @@ var DeepSeekClient = class {
136
141
  this.timeoutMs = opts.timeoutMs ?? 66e4;
137
142
  this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
138
143
  this.retry = opts.retry ?? {};
144
+ const rpm = opts.rateLimit?.rpm ?? loadRateLimit()?.rpm;
145
+ this.minChatIntervalMs = rpm ? Math.ceil(6e4 / rpm) : 0;
146
+ }
147
+ async waitForChatRateLimit(signal) {
148
+ if (this.minChatIntervalMs <= 0) return;
149
+ const now = Date.now();
150
+ const waitMs = Math.max(0, this.nextChatRequestAt - now);
151
+ this.nextChatRequestAt = Math.max(now, this.nextChatRequestAt) + this.minChatIntervalMs;
152
+ if (waitMs <= 0) return;
153
+ await new Promise((resolve, reject) => {
154
+ const timer = setTimeout(resolve, waitMs);
155
+ signal?.addEventListener(
156
+ "abort",
157
+ () => {
158
+ clearTimeout(timer);
159
+ reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
160
+ },
161
+ { once: true }
162
+ );
163
+ });
139
164
  }
140
165
  buildPayload(opts, stream) {
141
166
  const payload = {
@@ -192,6 +217,7 @@ var DeepSeekClient = class {
192
217
  const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
193
218
  const signal = opts.signal ?? ctrl.signal;
194
219
  try {
220
+ await this.waitForChatRateLimit(signal);
195
221
  const resp = await fetchWithRetry(
196
222
  this._fetch,
197
223
  `${this.baseUrl}/chat/completions`,
@@ -228,6 +254,7 @@ var DeepSeekClient = class {
228
254
  const signal = opts.signal ?? ctrl.signal;
229
255
  let resp;
230
256
  try {
257
+ await this.waitForChatRateLimit(signal);
231
258
  resp = await fetchWithRetry(
232
259
  this._fetch,
233
260
  `${this.baseUrl}/chat/completions`,
@@ -313,4 +340,4 @@ export {
313
340
  pickPrimaryBalance,
314
341
  DeepSeekClient
315
342
  };
316
- //# sourceMappingURL=chunk-V26WPN3J.js.map
343
+ //# sourceMappingURL=chunk-MIIZJD5O.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/retry.ts","../../src/client.ts"],"sourcesContent":["/** No retry on aborts or mid-stream body errors — re-billing the user for desynced output is worse than failing. */\n\nexport interface RetryOptions {\n /** Maximum total attempts (including the first). Default 4. */\n maxAttempts?: number;\n /** Initial backoff in ms. Doubles each retry, with jitter. Default 500. */\n initialBackoffMs?: number;\n /** Upper bound on any single backoff delay. Default 10000 (10s). */\n maxBackoffMs?: number;\n /** HTTP statuses to treat as retryable. Default [408, 429, 500, 502, 503, 504]. */\n retryableStatuses?: readonly number[];\n /** Abort signal; we do NOT retry once aborted. */\n signal?: AbortSignal;\n /** Telemetry hook — called before each wait. */\n onRetry?: (info: RetryInfo) => void;\n}\n\nexport interface RetryInfo {\n attempt: number;\n reason: string;\n waitMs: number;\n}\n\nconst DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504] as const;\n\nexport async function fetchWithRetry(\n fetchFn: typeof fetch,\n url: string,\n init: RequestInit,\n opts: RetryOptions = {},\n): Promise<Response> {\n const maxAttempts = opts.maxAttempts ?? 4;\n const initial = opts.initialBackoffMs ?? 500;\n const cap = opts.maxBackoffMs ?? 10_000;\n const retryable = new Set(opts.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES);\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (opts.signal?.aborted) throw new Error(\"aborted\");\n\n try {\n const resp = await fetchFn(url, init);\n\n // Success or non-retryable failure: return as-is.\n if (resp.ok || !retryable.has(resp.status)) return resp;\n\n // Retryable but out of attempts: return the last response so the caller\n // can surface the status to the user.\n if (attempt === maxAttempts - 1) return resp;\n\n // Drain the body so the connection can be reused on the next attempt.\n await resp.text().catch(() => undefined);\n\n const waitMs = computeWait(attempt, initial, cap, resp.headers.get(\"Retry-After\"));\n opts.onRetry?.({ attempt: attempt + 1, reason: `http ${resp.status}`, waitMs });\n await sleep(waitMs, opts.signal);\n } catch (err) {\n lastError = err;\n // Respect explicit aborts — do not retry.\n if (isAbortError(err) || opts.signal?.aborted) throw err;\n if (attempt === maxAttempts - 1) throw err;\n\n const waitMs = computeWait(attempt, initial, cap, null);\n opts.onRetry?.({\n attempt: attempt + 1,\n reason: `network: ${messageOf(err)}`,\n waitMs,\n });\n await sleep(waitMs, opts.signal);\n }\n }\n\n throw lastError ?? new Error(\"fetchWithRetry: loop exited unexpectedly\");\n}\n\nfunction computeWait(\n attempt: number,\n initial: number,\n cap: number,\n retryAfter: string | null,\n): number {\n if (retryAfter) {\n const seconds = Number.parseFloat(retryAfter);\n if (Number.isFinite(seconds) && seconds > 0) {\n return Math.min(seconds * 1000, cap);\n }\n }\n const exp = initial * 2 ** attempt;\n // Jitter range [75%, 125%] to spread retries out when many clients hit 429 together.\n const jitter = exp * (0.75 + Math.random() * 0.5);\n return Math.min(Math.max(jitter, 0), cap);\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve();\n return new Promise((resolve, reject) => {\n const timer = setTimeout(resolve, ms);\n if (signal) {\n const onAbort = () => {\n clearTimeout(timer);\n reject(new Error(\"aborted\"));\n };\n if (signal.aborted) onAbort();\n else signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!err || typeof err !== \"object\") return false;\n const name = (err as { name?: unknown }).name;\n return name === \"AbortError\";\n}\n\nfunction messageOf(err: unknown): string {\n if (err instanceof Error) return err.message;\n try {\n return String(err);\n } catch {\n return \"unknown error\";\n }\n}\n","import { type EventSourceMessage, createParser } from \"eventsource-parser\";\nimport { loadRateLimit } from \"./config.js\";\nimport { type RetryOptions, fetchWithRetry } from \"./retry.js\";\nimport type { ChatMessage, ChatRequestOptions, RawUsage, ToolCall, ToolSpec } from \"./types.js\";\n\nexport class Usage {\n constructor(\n public promptTokens = 0,\n public completionTokens = 0,\n public totalTokens = 0,\n public promptCacheHitTokens = 0,\n public promptCacheMissTokens = 0,\n ) {}\n\n get cacheHitRatio(): number {\n const denom = this.promptCacheHitTokens + this.promptCacheMissTokens;\n return denom > 0 ? this.promptCacheHitTokens / denom : 0;\n }\n\n static fromApi(raw: RawUsage | undefined | null): Usage {\n const u = raw ?? {};\n const promptTokens = u.prompt_tokens ?? 0;\n const cacheHitTokens = u.prompt_cache_hit_tokens ?? 0;\n const cacheMissTokens =\n u.prompt_cache_miss_tokens ?? Math.max(0, promptTokens - cacheHitTokens);\n return new Usage(\n promptTokens,\n u.completion_tokens ?? 0,\n u.total_tokens ?? 0,\n cacheHitTokens,\n cacheMissTokens,\n );\n }\n}\n\nexport interface ChatResponse {\n content: string;\n reasoningContent: string | null;\n toolCalls: ToolCall[];\n usage: Usage;\n raw: unknown;\n}\n\nexport interface StreamChunk {\n contentDelta?: string;\n reasoningDelta?: string;\n toolCallDelta?: { index: number; id?: string; name?: string; argumentsDelta?: string };\n usage?: Usage;\n finishReason?: string;\n raw: any;\n}\n\nexport interface BalanceInfo {\n currency: string;\n total_balance: string;\n granted_balance?: string;\n topped_up_balance?: string;\n}\n\nexport interface UserBalance {\n is_available: boolean;\n balance_infos: BalanceInfo[];\n}\n\n/** Largest `total_balance` wins — the wallet the user actually paid for and expects to see ticking down. */\nexport function pickPrimaryBalance(infos: ReadonlyArray<BalanceInfo>): BalanceInfo | null {\n if (infos.length === 0) return null;\n let best = infos[0]!;\n for (let i = 1; i < infos.length; i++) {\n if (Number(infos[i]!.total_balance) > Number(best.total_balance)) best = infos[i]!;\n }\n return best;\n}\n\nexport interface ModelInfo {\n id: string;\n object: \"model\";\n owned_by: string;\n}\n\nexport interface ModelList {\n object: \"list\";\n data: ModelInfo[];\n}\n\nexport interface DeepSeekClientOptions {\n apiKey?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n rateLimit?: { rpm?: number };\n /** Retry configuration. Pass `{ maxAttempts: 1 }` to disable retries. */\n retry?: RetryOptions;\n}\n\nexport class DeepSeekClient {\n readonly apiKey: string;\n readonly baseUrl: string;\n readonly timeoutMs: number;\n readonly retry: RetryOptions;\n private readonly _fetch: typeof fetch;\n private readonly minChatIntervalMs: number;\n private nextChatRequestAt = 0;\n\n constructor(opts: DeepSeekClientOptions = {}) {\n const apiKey = opts.apiKey ?? process.env.DEEPSEEK_API_KEY;\n if (!apiKey) {\n throw new Error(\n \"DEEPSEEK_API_KEY is not set. Put it in .env or pass apiKey to DeepSeekClient.\",\n );\n }\n this.apiKey = apiKey;\n let url = opts.baseUrl ?? process.env.DEEPSEEK_BASE_URL ?? \"https://api.deepseek.com\";\n // Manual trim — `/\\/+$/` is O(n²) on slash-heavy non-matches per CodeQL js/polynomial-redos.\n while (url.endsWith(\"/\")) url = url.slice(0, -1);\n this.baseUrl = url;\n // 11 min. DeepSeek's load-balancer may keep a connection open for\n // up to 10 minutes while the request waits in queue (non-streaming\n // sends empty lines, streaming sends `:` SSE keep-alive comments —\n // both are invisible to our parsers, so neither surfaces until the\n // real response starts). Timing out at the legacy 2-min default\n // killed queued requests prematurely, burned the queue slot on\n // retry, and could loop through the whole queue repeatedly.\n // Setting 11 min lets the server's own 10-min cap close the\n // connection first (clean EOF → natural retry), and our timer\n // is a safety net for genuinely hung sockets.\n this.timeoutMs = opts.timeoutMs ?? 660_000;\n this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.retry = opts.retry ?? {};\n const rpm = opts.rateLimit?.rpm ?? loadRateLimit()?.rpm;\n this.minChatIntervalMs = rpm ? Math.ceil(60_000 / rpm) : 0;\n }\n\n private async waitForChatRateLimit(signal?: AbortSignal): Promise<void> {\n if (this.minChatIntervalMs <= 0) return;\n const now = Date.now();\n const waitMs = Math.max(0, this.nextChatRequestAt - now);\n this.nextChatRequestAt = Math.max(now, this.nextChatRequestAt) + this.minChatIntervalMs;\n if (waitMs <= 0) return;\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, waitMs);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(timer);\n reject(signal.reason ?? new DOMException(\"Aborted\", \"AbortError\"));\n },\n { once: true },\n );\n });\n }\n\n private buildPayload(opts: ChatRequestOptions, stream: boolean) {\n const payload: Record<string, unknown> = {\n model: opts.model,\n messages: opts.messages,\n stream,\n };\n if (opts.tools?.length) payload.tools = opts.tools;\n if (opts.temperature !== undefined) payload.temperature = opts.temperature;\n if (opts.maxTokens !== undefined) payload.max_tokens = opts.maxTokens;\n if (opts.responseFormat) payload.response_format = opts.responseFormat;\n // V4 thinking-mode toggle: lives under `extra_body.thinking.type` per\n // DeepSeek's docs. Docs also note that in thinking mode `temperature`,\n // `top_p`, `presence_penalty`, `frequency_penalty` are silently\n // ignored — we don't strip them here because the server's explicit\n // \"setting won't report an error\" contract means leaving them in is\n // safe and keeps the request payload diffable against OpenAI tooling.\n if (opts.thinking) {\n payload.extra_body = { thinking: { type: opts.thinking } };\n }\n if (opts.reasoningEffort) {\n payload.reasoning_effort = opts.reasoningEffort;\n }\n return payload;\n }\n\n /** Returns null on failure so callers can degrade — session must keep working without balance UI. */\n async getBalance(opts: { signal?: AbortSignal } = {}): Promise<UserBalance | null> {\n try {\n const resp = await this._fetch(`${this.baseUrl}/user/balance`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n signal: opts.signal,\n });\n if (!resp.ok) return null;\n const data = (await resp.json()) as UserBalance;\n if (!data || !Array.isArray(data.balance_infos)) return null;\n return data;\n } catch {\n return null;\n }\n }\n\n /** Returns null on failure — callers fall back to a hardcoded model hint. */\n async listModels(opts: { signal?: AbortSignal } = {}): Promise<ModelList | null> {\n try {\n const resp = await this._fetch(`${this.baseUrl}/models`, {\n method: \"GET\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n signal: opts.signal,\n });\n if (!resp.ok) return null;\n const data = (await resp.json()) as ModelList;\n if (!data || !Array.isArray(data.data)) return null;\n return data;\n } catch {\n return null;\n }\n }\n\n async chat(opts: ChatRequestOptions): Promise<ChatResponse> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n try {\n await this.waitForChatRateLimit(signal);\n const resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(this.buildPayload(opts, false)),\n signal,\n },\n { ...this.retry, signal },\n );\n if (!resp.ok) {\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text()}`);\n }\n const data: any = await resp.json();\n const choice = data.choices?.[0]?.message ?? {};\n return {\n content: choice.content ?? \"\",\n reasoningContent: choice.reasoning_content ?? null,\n toolCalls: choice.tool_calls ?? [],\n usage: Usage.fromApi(data.usage),\n raw: data,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n async *stream(opts: ChatRequestOptions): AsyncGenerator<StreamChunk> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n const signal = opts.signal ?? ctrl.signal;\n\n let resp: Response;\n try {\n await this.waitForChatRateLimit(signal);\n // Only the initial fetch is retried. Once the server has started sending\n // the stream body we do NOT retry — a mid-stream retry would re-bill and\n // desync the session context.\n resp = await fetchWithRetry(\n this._fetch,\n `${this.baseUrl}/chat/completions`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"text/event-stream\",\n },\n body: JSON.stringify(this.buildPayload(opts, true)),\n signal,\n },\n { ...this.retry, signal },\n );\n } catch (err) {\n clearTimeout(timer);\n throw err;\n }\n if (!resp.ok || !resp.body) {\n clearTimeout(timer);\n throw new Error(`DeepSeek ${resp.status}: ${await resp.text().catch(() => \"\")}`);\n }\n\n const queue: StreamChunk[] = [];\n let done = false;\n const parser = createParser({\n onEvent: (ev: EventSourceMessage) => {\n if (!ev.data || ev.data === \"[DONE]\") {\n done = true;\n return;\n }\n try {\n const json = JSON.parse(ev.data);\n const delta = json.choices?.[0]?.delta ?? {};\n const finishReason = json.choices?.[0]?.finish_reason ?? undefined;\n const chunk: StreamChunk = { raw: json, finishReason };\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n chunk.contentDelta = delta.content;\n }\n if (typeof delta.reasoning_content === \"string\" && delta.reasoning_content.length > 0) {\n chunk.reasoningDelta = delta.reasoning_content;\n }\n if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {\n const tc = delta.tool_calls[0];\n chunk.toolCallDelta = {\n index: tc.index ?? 0,\n id: tc.id,\n name: tc.function?.name,\n argumentsDelta: tc.function?.arguments,\n };\n }\n if (json.usage) {\n chunk.usage = Usage.fromApi(json.usage);\n }\n queue.push(chunk);\n } catch {\n /* skip malformed sse frame */\n }\n },\n });\n\n const reader = resp.body.getReader();\n const decoder = new TextDecoder();\n try {\n while (true) {\n if (queue.length > 0) {\n yield queue.shift()!;\n continue;\n }\n if (done) break;\n const { value, done: streamDone } = await reader.read();\n if (streamDone) break;\n parser.feed(decoder.decode(value, { stream: true }));\n }\n while (queue.length > 0) yield queue.shift()!;\n } finally {\n clearTimeout(timer);\n reader.releaseLock();\n }\n }\n}\n\nexport type { ChatMessage, ToolCall, ToolSpec };\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  t
5
- } from "./chunk-IJ7JA32V.js";
5
+ } from "./chunk-6VANO7KB.js";
6
6
 
7
7
  // src/cli/ui/mcp-lifecycle.ts
8
8
  var STATE = {
@@ -47,4 +47,4 @@ export {
47
47
  formatMcpLifecycleEvent,
48
48
  formatMcpSlowToast
49
49
  };
50
- //# sourceMappingURL=chunk-4HCP2UQW.js.map
50
+ //# sourceMappingURL=chunk-NCBP5D6E.js.map
File without changes
@@ -9,31 +9,31 @@ import {
9
9
  import {
10
10
  DeepSeekClient,
11
11
  pickPrimaryBalance
12
- } from "./chunk-V26WPN3J.js";
12
+ } from "./chunk-MIIZJD5O.js";
13
13
  import {
14
14
  loadDotenv
15
15
  } from "./chunk-2UQP6H6T.js";
16
16
  import {
17
17
  checkOllamaStatus
18
- } from "./chunk-LIR2HBQH.js";
18
+ } from "./chunk-7LOJS3LV.js";
19
19
  import {
20
20
  indexExists
21
- } from "./chunk-4CTDEJUF.js";
21
+ } from "./chunk-JLQDNLZF.js";
22
22
  import {
23
23
  loadHooks
24
- } from "./chunk-A3TSSDS2.js";
24
+ } from "./chunk-C72TNHDE.js";
25
25
  import {
26
26
  listSessions
27
- } from "./chunk-5ACMUK4Q.js";
27
+ } from "./chunk-E7TAHQ4A.js";
28
28
  import {
29
29
  t
30
- } from "./chunk-IJ7JA32V.js";
30
+ } from "./chunk-6VANO7KB.js";
31
31
  import {
32
32
  defaultConfigPath,
33
33
  loadBaseUrl,
34
34
  readConfig,
35
35
  resolveSemanticEmbeddingConfig
36
- } from "./chunk-AVFXO2EZ.js";
36
+ } from "./chunk-DGA5QYFM.js";
37
37
  import {
38
38
  VERSION
39
39
  } from "./chunk-XXC2BYTV.js";
@@ -449,4 +449,4 @@ export {
449
449
  formatDoctorJson,
450
450
  doctorCommand
451
451
  };
452
- //# sourceMappingURL=chunk-HKWSPKMU.js.map
452
+ //# sourceMappingURL=chunk-R2ASNSEO.js.map
File without changes
@@ -7,10 +7,10 @@ import {
7
7
  defaultUsageLogPath,
8
8
  formatLogSize,
9
9
  readUsageLog
10
- } from "./chunk-R3CTO2HM.js";
10
+ } from "./chunk-WRONKNIH.js";
11
11
  import {
12
12
  t
13
- } from "./chunk-IJ7JA32V.js";
13
+ } from "./chunk-6VANO7KB.js";
14
14
 
15
15
  // src/cli/commands/stats.ts
16
16
  import { existsSync, readFileSync } from "fs";
@@ -150,4 +150,4 @@ export {
150
150
  statsCommand,
151
151
  renderDashboard
152
152
  };
153
- //# sourceMappingURL=chunk-W7YGWUWU.js.map
153
+ //# sourceMappingURL=chunk-SE7C5ZSI.js.map