reasonix 0.33.0 → 0.33.2

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 (31) hide show
  1. package/dist/cli/{chat-EIFLHBZ6.js → chat-ZMSAXE77.js} +6 -5
  2. package/dist/cli/{chunk-Q5GRLZJF.js → chunk-63KAV5DX.js} +8 -1
  3. package/dist/cli/{chunk-Q5GRLZJF.js.map → chunk-63KAV5DX.js.map} +1 -1
  4. package/dist/cli/chunk-DAEAAVDF.js +199 -0
  5. package/dist/cli/chunk-DAEAAVDF.js.map +1 -0
  6. package/dist/cli/{chunk-Q6YFXW7H.js → chunk-G7M3QWEN.js} +27 -213
  7. package/dist/cli/chunk-G7M3QWEN.js.map +1 -0
  8. package/dist/cli/{chunk-LVQX5KGF.js → chunk-OW7IHE6M.js} +45 -18
  9. package/dist/cli/chunk-OW7IHE6M.js.map +1 -0
  10. package/dist/cli/{chunk-D5DKXIP5.js → chunk-WVJL7ZO2.js} +15 -24
  11. package/dist/cli/chunk-WVJL7ZO2.js.map +1 -0
  12. package/dist/cli/{code-F4KJOE3K.js → code-R4TXQQEE.js} +6 -5
  13. package/dist/cli/{code-F4KJOE3K.js.map → code-R4TXQQEE.js.map} +1 -1
  14. package/dist/cli/{doctor-3TGB2NZN.js → doctor-V5HLCMSQ.js} +3 -2
  15. package/dist/cli/index.js +10 -9
  16. package/dist/cli/index.js.map +1 -1
  17. package/dist/cli/{replay-TMJASRC4.js → replay-Q43DSMG6.js} +2 -2
  18. package/dist/cli/{run-JMEOTQCG.js → run-HK3FP266.js} +3 -2
  19. package/dist/cli/{run-JMEOTQCG.js.map → run-HK3FP266.js.map} +1 -1
  20. package/dist/cli/{sessions-MOJAALJI.js → sessions-3XU2GGHX.js} +3 -2
  21. package/dist/cli/{sessions-MOJAALJI.js.map → sessions-3XU2GGHX.js.map} +1 -1
  22. package/dist/cli/{version-3MYFE4G6.js → version-5SGI2SEE.js} +3 -2
  23. package/dist/cli/{version-3MYFE4G6.js.map → version-5SGI2SEE.js.map} +1 -1
  24. package/dist/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/dist/cli/chunk-D5DKXIP5.js.map +0 -1
  27. package/dist/cli/chunk-LVQX5KGF.js.map +0 -1
  28. package/dist/cli/chunk-Q6YFXW7H.js.map +0 -1
  29. /package/dist/cli/{chat-EIFLHBZ6.js.map → chat-ZMSAXE77.js.map} +0 -0
  30. /package/dist/cli/{doctor-3TGB2NZN.js.map → doctor-V5HLCMSQ.js.map} +0 -0
  31. /package/dist/cli/{replay-TMJASRC4.js.map → replay-Q43DSMG6.js.map} +0 -0
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  chatCommand
4
- } from "./chunk-LVQX5KGF.js";
4
+ } from "./chunk-OW7IHE6M.js";
5
5
  import "./chunk-BQNUJJN7.js";
6
6
  import "./chunk-RFX7TYVV.js";
7
- import "./chunk-Q5GRLZJF.js";
7
+ import "./chunk-63KAV5DX.js";
8
8
  import "./chunk-CPOV2O73.js";
9
- import "./chunk-Q6YFXW7H.js";
9
+ import "./chunk-G7M3QWEN.js";
10
10
  import "./chunk-I6YIAK6C.js";
11
11
  import "./chunk-XJLZ4HKU.js";
12
12
  import "./chunk-XHQIK7B6.js";
@@ -14,7 +14,8 @@ import "./chunk-6TMHAK5D.js";
14
14
  import "./chunk-SDE5U32Z.js";
15
15
  import "./chunk-ZPTSJGX5.js";
16
16
  import "./chunk-MHDNZXJJ.js";
17
- import "./chunk-D5DKXIP5.js";
17
+ import "./chunk-WVJL7ZO2.js";
18
+ import "./chunk-DAEAAVDF.js";
18
19
  import "./chunk-KMWKGPFZ.js";
19
20
  import "./chunk-3Q3C4W66.js";
20
21
  import "./chunk-4DCHFFEY.js";
@@ -36,4 +37,4 @@ import "./chunk-ORM6PK57.js";
36
37
  export {
37
38
  chatCommand
38
39
  };
39
- //# sourceMappingURL=chat-EIFLHBZ6.js.map
40
+ //# sourceMappingURL=chat-ZMSAXE77.js.map
@@ -65,6 +65,12 @@ function formatCost(costUsd, currency, fractionDigits = 4) {
65
65
  const amount = cur === "CNY" ? costUsd * USD_TO_CNY : costUsd;
66
66
  return formatBalance(amount, cur, { fractionDigits });
67
67
  }
68
+ function balanceColor(amount, currency) {
69
+ const cny = (currency ?? "CNY") === "USD" ? amount * USD_TO_CNY : amount;
70
+ if (cny < 5) return TONE.err;
71
+ if (cny < 20) return TONE.warn;
72
+ return TONE.brand;
73
+ }
68
74
 
69
75
  // src/cli/ui/primitives.tsx
70
76
  import { Text, useStdout } from "ink";
@@ -93,7 +99,8 @@ export {
93
99
  CARD,
94
100
  formatBalance,
95
101
  formatCost,
102
+ balanceColor,
96
103
  ChromeRule,
97
104
  Bar
98
105
  };
99
- //# sourceMappingURL=chunk-Q5GRLZJF.js.map
106
+ //# sourceMappingURL=chunk-63KAV5DX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/ui/theme/tokens.ts","../../src/cli/ui/primitives.tsx"],"sourcesContent":["export const FG = {\n strong: \"#e6edf3\",\n body: \"#c9d1d9\",\n sub: \"#8b949e\",\n meta: \"#6e7681\",\n faint: \"#484f58\",\n} as const;\n\nexport const TONE = {\n brand: \"#79c0ff\",\n accent: \"#d2a8ff\",\n violet: \"#b395f5\",\n ok: \"#7ee787\",\n warn: \"#f0b07d\",\n err: \"#ff8b81\",\n info: \"#79c0ff\",\n} as const;\n\n/** Used only while a card is streaming/running, so live cards stand out from settled history. */\nexport const TONE_ACTIVE = {\n brand: \"#a5d6ff\",\n accent: \"#e2c5ff\",\n violet: \"#c8aaff\",\n ok: \"#a8f5ad\",\n warn: \"#ffc99e\",\n err: \"#ffaba3\",\n info: \"#a5d6ff\",\n} as const;\n\nexport const SURFACE = {\n bg: \"#0a0c10\",\n bgInput: \"#0d1015\",\n bgCode: \"#06080c\",\n bgElev: \"#11141a\",\n} as const;\n\nexport const CARD = {\n user: { color: FG.meta, glyph: \"◇\" },\n reasoning: { color: TONE.accent, glyph: \"◆\" },\n streaming: { color: TONE.brand, glyph: \"◈\" },\n task: { color: TONE.warn, glyph: \"▶\" },\n tool: { color: TONE.info, glyph: \"▣\" },\n plan: { color: TONE.accent, glyph: \"⊞\" },\n diff: { color: TONE.ok, glyph: \"±\" },\n error: { color: TONE.err, glyph: \"✖\" },\n warn: { color: TONE.warn, glyph: \"⚠\" },\n usage: { color: FG.meta, glyph: \"Σ\" },\n subagent: { color: TONE.violet, glyph: \"⌬\" },\n approval: { color: TONE.warn, glyph: \"?\" },\n search: { color: TONE.info, glyph: \"⊙\" },\n memory: { color: FG.meta, glyph: \"⌑\" },\n ctx: { color: TONE.brand, glyph: \"◔\" },\n doctor: { color: FG.meta, glyph: \"⚕\" },\n branch: { color: TONE.violet, glyph: \"⎇\" },\n} as const;\n\nexport type CardTone = keyof typeof CARD;\n\n/** DeepSeek prices in CNY; our internal table is USD divided by 7.2. Multiply back for display. */\nexport const USD_TO_CNY = 7.2;\n\nconst SYMBOL: Record<string, string> = { USD: \"$\", CNY: \"¥\" };\n\n/** Format an amount already in `currency`. Undefined currency → CNY (matches pre-fix behavior). */\nexport function formatBalance(\n amount: number,\n currency?: string,\n opts?: { fractionDigits?: number; label?: boolean },\n): string {\n const cur = currency ?? \"CNY\";\n const sym = SYMBOL[cur];\n const digits = opts?.fractionDigits ?? 2;\n const body = sym ? `${sym}${amount.toFixed(digits)}` : `${cur} ${amount.toFixed(digits)}`;\n return opts?.label ? `w ${body}` : body;\n}\n\n/** Format an internal USD cost in the wallet's display currency. Undefined currency → CNY. */\nexport function formatCost(costUsd: number, currency?: string, fractionDigits = 4): string {\n const cur = currency ?? \"CNY\";\n const amount = cur === \"CNY\" ? costUsd * USD_TO_CNY : costUsd;\n return formatBalance(amount, cur, { fractionDigits });\n}\n\n/** Threshold color for a wallet balance. USD is converted to CNY before the threshold check. */\nexport function balanceColor(amount: number, currency?: string): string {\n const cny = (currency ?? \"CNY\") === \"USD\" ? amount * USD_TO_CNY : amount;\n if (cny < 5) return TONE.err;\n if (cny < 20) return TONE.warn;\n return TONE.brand;\n}\n","import { Text, useStdout } from \"ink\";\n// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React from \"react\";\nimport { COLOR } from \"./theme.js\";\n\n/**\n * Faint full-width horizontal rule. Width tracks the terminal columns\n * minus 2 cells so it lines up exactly under content rendered inside\n * a `paddingX={1}` parent — the standard chrome layout. Used by the\n * top chrome bar, the replay StatsPanel, and the bottom ctx footer.\n */\nexport function ChromeRule(): React.ReactElement {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const w = Math.max(20, cols - 2);\n return <Text dimColor>{\"─\".repeat(w)}</Text>;\n}\n\n/** Compact binary-K formatter — `1234 → \"1.2K\"`, `131072 → \"128K\"`. */\nexport function formatTokens(n: number): string {\n if (n < 1024) return String(n);\n const k = n / 1024;\n return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;\n}\n\n/**\n * Filled / empty progress bar. `▰▱` glyphs have distinct shapes so the\n * boundary stays visible even when the terminal collapses to 8-color slots.\n */\nexport function Bar({\n ratio,\n color,\n cells = 14,\n dim,\n}: {\n ratio: number;\n color: string;\n cells?: number;\n dim?: boolean;\n}): React.ReactElement {\n const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));\n return (\n <Text>\n <Text color={color} dimColor={dim}>\n {\"▰\".repeat(filled)}\n </Text>\n <Text dimColor>{\"▱\".repeat(cells - filled)}</Text>\n </Text>\n );\n}\n\n/**\n * `▣ ctx ▰▰▱▱… 14K/128K (11%)` — the canonical context-pressure cell.\n * Used by the persistent footer (chat) and StatsPanel (replay). Color\n * thresholds match the `/compact` warning policy in the loop:\n * green <60% · amber 60-80% · red ≥80% (with `· /compact` hint).\n */\nexport function ContextCell({\n ratio,\n promptTokens,\n ctxMax,\n showBar,\n}: {\n ratio: number;\n promptTokens: number;\n ctxMax: number;\n showBar?: boolean;\n}): React.ReactElement {\n if (promptTokens === 0) {\n return (\n <Text>\n <Text color={COLOR.info} dimColor>\n {\"▣ ctx \"}\n </Text>\n <Text dimColor>— (no turns yet)</Text>\n </Text>\n );\n }\n const color = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;\n const pct = Math.round(ratio * 100);\n return (\n <Text>\n <Text color={COLOR.info}>{\"▣ ctx \"}</Text>\n <Bar ratio={ratio} color={color} cells={showBar ? 14 : 10} />\n <Text> </Text>\n <Text color={color} bold>\n {formatTokens(promptTokens)}/{formatTokens(ctxMax)}\n </Text>\n <Text dimColor> ({pct}%)</Text>\n {ratio >= 0.8 ? (\n <Text color={COLOR.err} bold>\n {\" · /compact\"}\n </Text>\n ) : null}\n </Text>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/ui/theme/tokens.ts","../../src/cli/ui/primitives.tsx"],"sourcesContent":["export const FG = {\n strong: \"#e6edf3\",\n body: \"#c9d1d9\",\n sub: \"#8b949e\",\n meta: \"#6e7681\",\n faint: \"#484f58\",\n} as const;\n\nexport const TONE = {\n brand: \"#79c0ff\",\n accent: \"#d2a8ff\",\n violet: \"#b395f5\",\n ok: \"#7ee787\",\n warn: \"#f0b07d\",\n err: \"#ff8b81\",\n info: \"#79c0ff\",\n} as const;\n\n/** Used only while a card is streaming/running, so live cards stand out from settled history. */\nexport const TONE_ACTIVE = {\n brand: \"#a5d6ff\",\n accent: \"#e2c5ff\",\n violet: \"#c8aaff\",\n ok: \"#a8f5ad\",\n warn: \"#ffc99e\",\n err: \"#ffaba3\",\n info: \"#a5d6ff\",\n} as const;\n\nexport const SURFACE = {\n bg: \"#0a0c10\",\n bgInput: \"#0d1015\",\n bgCode: \"#06080c\",\n bgElev: \"#11141a\",\n} as const;\n\nexport const CARD = {\n user: { color: FG.meta, glyph: \"◇\" },\n reasoning: { color: TONE.accent, glyph: \"◆\" },\n streaming: { color: TONE.brand, glyph: \"◈\" },\n task: { color: TONE.warn, glyph: \"▶\" },\n tool: { color: TONE.info, glyph: \"▣\" },\n plan: { color: TONE.accent, glyph: \"⊞\" },\n diff: { color: TONE.ok, glyph: \"±\" },\n error: { color: TONE.err, glyph: \"✖\" },\n warn: { color: TONE.warn, glyph: \"⚠\" },\n usage: { color: FG.meta, glyph: \"Σ\" },\n subagent: { color: TONE.violet, glyph: \"⌬\" },\n approval: { color: TONE.warn, glyph: \"?\" },\n search: { color: TONE.info, glyph: \"⊙\" },\n memory: { color: FG.meta, glyph: \"⌑\" },\n ctx: { color: TONE.brand, glyph: \"◔\" },\n doctor: { color: FG.meta, glyph: \"⚕\" },\n branch: { color: TONE.violet, glyph: \"⎇\" },\n} as const;\n\nexport type CardTone = keyof typeof CARD;\n\n/** DeepSeek prices in CNY; our internal table is USD divided by 7.2. Multiply back for display. */\nexport const USD_TO_CNY = 7.2;\n\nconst SYMBOL: Record<string, string> = { USD: \"$\", CNY: \"¥\" };\n\n/** Format an amount already in `currency`. Undefined currency → CNY (matches pre-fix behavior). */\nexport function formatBalance(\n amount: number,\n currency?: string,\n opts?: { fractionDigits?: number; label?: boolean },\n): string {\n const cur = currency ?? \"CNY\";\n const sym = SYMBOL[cur];\n const digits = opts?.fractionDigits ?? 2;\n const body = sym ? `${sym}${amount.toFixed(digits)}` : `${cur} ${amount.toFixed(digits)}`;\n return opts?.label ? `w ${body}` : body;\n}\n\n/** Format an internal USD cost in the wallet's display currency. Undefined currency → CNY. */\nexport function formatCost(costUsd: number, currency?: string, fractionDigits = 4): string {\n const cur = currency ?? \"CNY\";\n const amount = cur === \"CNY\" ? costUsd * USD_TO_CNY : costUsd;\n return formatBalance(amount, cur, { fractionDigits });\n}\n\n/** Threshold color for a wallet balance. USD is converted to CNY before the threshold check. */\nexport function balanceColor(amount: number, currency?: string): string {\n const cny = (currency ?? \"CNY\") === \"USD\" ? amount * USD_TO_CNY : amount;\n if (cny < 5) return TONE.err;\n if (cny < 20) return TONE.warn;\n return TONE.brand;\n}\n","import { Text, useStdout } from \"ink\";\n// biome-ignore lint/style/useImportType: tsconfig jsx=react needs React in value scope for JSX compilation\nimport React from \"react\";\nimport { COLOR } from \"./theme.js\";\n\n/**\n * Faint full-width horizontal rule. Width tracks the terminal columns\n * minus 2 cells so it lines up exactly under content rendered inside\n * a `paddingX={1}` parent — the standard chrome layout. Used by the\n * top chrome bar, the replay StatsPanel, and the bottom ctx footer.\n */\nexport function ChromeRule(): React.ReactElement {\n const { stdout } = useStdout();\n const cols = stdout?.columns ?? 80;\n const w = Math.max(20, cols - 2);\n return <Text dimColor>{\"─\".repeat(w)}</Text>;\n}\n\n/** Compact binary-K formatter — `1234 → \"1.2K\"`, `131072 → \"128K\"`. */\nexport function formatTokens(n: number): string {\n if (n < 1024) return String(n);\n const k = n / 1024;\n return k >= 100 ? `${k.toFixed(0)}K` : `${k.toFixed(1)}K`;\n}\n\n/**\n * Filled / empty progress bar. `▰▱` glyphs have distinct shapes so the\n * boundary stays visible even when the terminal collapses to 8-color slots.\n */\nexport function Bar({\n ratio,\n color,\n cells = 14,\n dim,\n}: {\n ratio: number;\n color: string;\n cells?: number;\n dim?: boolean;\n}): React.ReactElement {\n const filled = Math.max(0, Math.min(cells, Math.round(ratio * cells)));\n return (\n <Text>\n <Text color={color} dimColor={dim}>\n {\"▰\".repeat(filled)}\n </Text>\n <Text dimColor>{\"▱\".repeat(cells - filled)}</Text>\n </Text>\n );\n}\n\n/**\n * `▣ ctx ▰▰▱▱… 14K/128K (11%)` — the canonical context-pressure cell.\n * Used by the persistent footer (chat) and StatsPanel (replay). Color\n * thresholds match the `/compact` warning policy in the loop:\n * green <60% · amber 60-80% · red ≥80% (with `· /compact` hint).\n */\nexport function ContextCell({\n ratio,\n promptTokens,\n ctxMax,\n showBar,\n}: {\n ratio: number;\n promptTokens: number;\n ctxMax: number;\n showBar?: boolean;\n}): React.ReactElement {\n if (promptTokens === 0) {\n return (\n <Text>\n <Text color={COLOR.info} dimColor>\n {\"▣ ctx \"}\n </Text>\n <Text dimColor>— (no turns yet)</Text>\n </Text>\n );\n }\n const color = ratio >= 0.8 ? COLOR.err : ratio >= 0.6 ? COLOR.warn : COLOR.ok;\n const pct = Math.round(ratio * 100);\n return (\n <Text>\n <Text color={COLOR.info}>{\"▣ ctx \"}</Text>\n <Bar ratio={ratio} color={color} cells={showBar ? 14 : 10} />\n <Text> </Text>\n <Text color={color} bold>\n {formatTokens(promptTokens)}/{formatTokens(ctxMax)}\n </Text>\n <Text dimColor> ({pct}%)</Text>\n {ratio >= 0.8 ? (\n <Text color={COLOR.err} bold>\n {\" · /compact\"}\n </Text>\n ) : null}\n </Text>\n );\n}\n"],"mappings":";;;AAAO,IAAM,KAAK;AAAA,EAChB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AACT;AAEO,IAAM,OAAO;AAAA,EAClB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AACR;AAGO,IAAM,cAAc;AAAA,EACzB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AACR;AAEO,IAAM,UAAU;AAAA,EACrB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,IAAM,OAAO;AAAA,EAClB,MAAM,EAAE,OAAO,GAAG,MAAM,OAAO,SAAI;AAAA,EACnC,WAAW,EAAE,OAAO,KAAK,QAAQ,OAAO,SAAI;AAAA,EAC5C,WAAW,EAAE,OAAO,KAAK,OAAO,OAAO,SAAI;AAAA,EAC3C,MAAM,EAAE,OAAO,KAAK,MAAM,OAAO,SAAI;AAAA,EACrC,MAAM,EAAE,OAAO,KAAK,MAAM,OAAO,SAAI;AAAA,EACrC,MAAM,EAAE,OAAO,KAAK,QAAQ,OAAO,SAAI;AAAA,EACvC,MAAM,EAAE,OAAO,KAAK,IAAI,OAAO,OAAI;AAAA,EACnC,OAAO,EAAE,OAAO,KAAK,KAAK,OAAO,SAAI;AAAA,EACrC,MAAM,EAAE,OAAO,KAAK,MAAM,OAAO,SAAI;AAAA,EACrC,OAAO,EAAE,OAAO,GAAG,MAAM,OAAO,SAAI;AAAA,EACpC,UAAU,EAAE,OAAO,KAAK,QAAQ,OAAO,SAAI;AAAA,EAC3C,UAAU,EAAE,OAAO,KAAK,MAAM,OAAO,IAAI;AAAA,EACzC,QAAQ,EAAE,OAAO,KAAK,MAAM,OAAO,SAAI;AAAA,EACvC,QAAQ,EAAE,OAAO,GAAG,MAAM,OAAO,SAAI;AAAA,EACrC,KAAK,EAAE,OAAO,KAAK,OAAO,OAAO,SAAI;AAAA,EACrC,QAAQ,EAAE,OAAO,GAAG,MAAM,OAAO,SAAI;AAAA,EACrC,QAAQ,EAAE,OAAO,KAAK,QAAQ,OAAO,SAAI;AAC3C;AAKO,IAAM,aAAa;AAE1B,IAAM,SAAiC,EAAE,KAAK,KAAK,KAAK,OAAI;AAGrD,SAAS,cACd,QACA,UACA,MACQ;AACR,QAAM,MAAM,YAAY;AACxB,QAAM,MAAM,OAAO,GAAG;AACtB,QAAM,SAAS,MAAM,kBAAkB;AACvC,QAAM,OAAO,MAAM,GAAG,GAAG,GAAG,OAAO,QAAQ,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI,OAAO,QAAQ,MAAM,CAAC;AACvF,SAAO,MAAM,QAAQ,KAAK,IAAI,KAAK;AACrC;AAGO,SAAS,WAAW,SAAiB,UAAmB,iBAAiB,GAAW;AACzF,QAAM,MAAM,YAAY;AACxB,QAAM,SAAS,QAAQ,QAAQ,UAAU,aAAa;AACtD,SAAO,cAAc,QAAQ,KAAK,EAAE,eAAe,CAAC;AACtD;AAGO,SAAS,aAAa,QAAgB,UAA2B;AACtE,QAAM,OAAO,YAAY,WAAW,QAAQ,SAAS,aAAa;AAClE,MAAI,MAAM,EAAG,QAAO,KAAK;AACzB,MAAI,MAAM,GAAI,QAAO,KAAK;AAC1B,SAAO,KAAK;AACd;;;ACzFA,SAAS,MAAM,iBAAiB;AAEhC,OAAO,WAAW;AASX,SAAS,aAAiC;AAC/C,QAAM,EAAE,OAAO,IAAI,UAAU;AAC7B,QAAM,OAAO,QAAQ,WAAW;AAChC,QAAM,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC;AAC/B,SAAO,oCAAC,QAAK,UAAQ,QAAE,SAAI,OAAO,CAAC,CAAE;AACvC;AAaO,SAAS,IAAI;AAAA,EAClB;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AACF,GAKuB;AACrB,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,KAAK,MAAM,QAAQ,KAAK,CAAC,CAAC;AACrE,SACE,oCAAC,YACC,oCAAC,QAAK,OAAc,UAAU,OAC3B,SAAI,OAAO,MAAM,CACpB,GACA,oCAAC,QAAK,UAAQ,QAAE,SAAI,OAAO,QAAQ,MAAM,CAAE,CAC7C;AAEJ;","names":[]}
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/tokenizer.ts
4
+ import { existsSync, readFileSync } from "fs";
5
+ import { createRequire } from "module";
6
+ import { dirname, join } from "path";
7
+ import { fileURLToPath } from "url";
8
+ import { gunzipSync } from "zlib";
9
+ function buildByteToChar() {
10
+ const result = new Array(256);
11
+ const bs = [];
12
+ for (let b = 33; b <= 126; b++) bs.push(b);
13
+ for (let b = 161; b <= 172; b++) bs.push(b);
14
+ for (let b = 174; b <= 255; b++) bs.push(b);
15
+ const cs = bs.slice();
16
+ let n = 0;
17
+ for (let b = 0; b < 256; b++) {
18
+ if (!bs.includes(b)) {
19
+ bs.push(b);
20
+ cs.push(256 + n);
21
+ n++;
22
+ }
23
+ }
24
+ for (let i = 0; i < bs.length; i++) {
25
+ result[bs[i]] = String.fromCodePoint(cs[i]);
26
+ }
27
+ return result;
28
+ }
29
+ var cached = null;
30
+ function resolveDataPath() {
31
+ if (process.env.REASONIX_TOKENIZER_PATH) return process.env.REASONIX_TOKENIZER_PATH;
32
+ const candidates = [];
33
+ try {
34
+ const here = dirname(fileURLToPath(import.meta.url));
35
+ candidates.push(join(here, "..", "data", "deepseek-tokenizer.json.gz"));
36
+ candidates.push(join(here, "..", "..", "data", "deepseek-tokenizer.json.gz"));
37
+ } catch {
38
+ }
39
+ try {
40
+ const req = createRequire(import.meta.url);
41
+ candidates.push(
42
+ join(dirname(req.resolve("reasonix/package.json")), "data", "deepseek-tokenizer.json.gz")
43
+ );
44
+ } catch {
45
+ }
46
+ for (const p of candidates) {
47
+ if (existsSync(p)) return p;
48
+ }
49
+ return candidates[0] ?? join(process.cwd(), "data", "deepseek-tokenizer.json.gz");
50
+ }
51
+ function loadTokenizer() {
52
+ if (cached) return cached;
53
+ const buf = readFileSync(resolveDataPath());
54
+ const json = gunzipSync(buf).toString("utf8");
55
+ const data = JSON.parse(json);
56
+ const mergeRank = /* @__PURE__ */ new Map();
57
+ for (let i = 0; i < data.model.merges.length; i++) {
58
+ mergeRank.set(data.model.merges[i], i);
59
+ }
60
+ const splitRegexes = [];
61
+ for (const p of data.pre_tokenizer.pretokenizers) {
62
+ if (p.type === "Split") {
63
+ splitRegexes.push(new RegExp(p.pattern.Regex, "gu"));
64
+ }
65
+ }
66
+ const addedMap = /* @__PURE__ */ new Map();
67
+ const addedContents = [];
68
+ for (const t of data.added_tokens) {
69
+ if (!t.special) {
70
+ addedMap.set(t.content, t.id);
71
+ addedContents.push(t.content);
72
+ }
73
+ }
74
+ addedContents.sort((a, b) => b.length - a.length);
75
+ const addedPattern = addedContents.length ? new RegExp(addedContents.map(escapeRegex).join("|"), "g") : null;
76
+ cached = {
77
+ vocab: data.model.vocab,
78
+ mergeRank,
79
+ splitRegexes,
80
+ byteToChar: buildByteToChar(),
81
+ addedPattern,
82
+ addedMap
83
+ };
84
+ return cached;
85
+ }
86
+ function escapeRegex(s) {
87
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
88
+ }
89
+ function applySplit(chunks, re) {
90
+ const out = [];
91
+ for (const chunk of chunks) {
92
+ if (!chunk) continue;
93
+ re.lastIndex = 0;
94
+ let last = 0;
95
+ for (const m of chunk.matchAll(re)) {
96
+ const idx = m.index ?? 0;
97
+ if (idx > last) out.push(chunk.slice(last, idx));
98
+ if (m[0].length > 0) out.push(m[0]);
99
+ last = idx + m[0].length;
100
+ }
101
+ if (last < chunk.length) out.push(chunk.slice(last));
102
+ }
103
+ return out;
104
+ }
105
+ function byteLevelEncode(s, byteToChar) {
106
+ const bytes = new TextEncoder().encode(s);
107
+ let out = "";
108
+ for (let i = 0; i < bytes.length; i++) out += byteToChar[bytes[i]];
109
+ return out;
110
+ }
111
+ function bpeEncode(piece, mergeRank) {
112
+ if (piece.length <= 1) return piece ? [piece] : [];
113
+ let word = Array.from(piece);
114
+ while (true) {
115
+ let bestIdx = -1;
116
+ let bestRank = Number.POSITIVE_INFINITY;
117
+ for (let i = 0; i < word.length - 1; i++) {
118
+ const pair = `${word[i]} ${word[i + 1]}`;
119
+ const rank = mergeRank.get(pair);
120
+ if (rank !== void 0 && rank < bestRank) {
121
+ bestRank = rank;
122
+ bestIdx = i;
123
+ if (rank === 0) break;
124
+ }
125
+ }
126
+ if (bestIdx < 0) break;
127
+ word = [
128
+ ...word.slice(0, bestIdx),
129
+ word[bestIdx] + word[bestIdx + 1],
130
+ ...word.slice(bestIdx + 2)
131
+ ];
132
+ if (word.length === 1) break;
133
+ }
134
+ return word;
135
+ }
136
+ function encode(text) {
137
+ if (!text) return [];
138
+ const t = loadTokenizer();
139
+ const ids = [];
140
+ const process2 = (segment) => {
141
+ if (!segment) return;
142
+ let chunks = [segment];
143
+ for (const re of t.splitRegexes) chunks = applySplit(chunks, re);
144
+ for (const chunk of chunks) {
145
+ if (!chunk) continue;
146
+ const byteLevel = byteLevelEncode(chunk, t.byteToChar);
147
+ const pieces = bpeEncode(byteLevel, t.mergeRank);
148
+ for (const p of pieces) {
149
+ const id = t.vocab[p];
150
+ if (id !== void 0) ids.push(id);
151
+ }
152
+ }
153
+ };
154
+ if (t.addedPattern) {
155
+ t.addedPattern.lastIndex = 0;
156
+ let last = 0;
157
+ for (const m of text.matchAll(t.addedPattern)) {
158
+ const idx = m.index ?? 0;
159
+ if (idx > last) process2(text.slice(last, idx));
160
+ const id = t.addedMap.get(m[0]);
161
+ if (id !== void 0) ids.push(id);
162
+ last = idx + m[0].length;
163
+ }
164
+ if (last < text.length) process2(text.slice(last));
165
+ } else {
166
+ process2(text);
167
+ }
168
+ return ids;
169
+ }
170
+ function countTokens(text) {
171
+ return encode(text).length;
172
+ }
173
+ function estimateConversationTokens(messages) {
174
+ let total = 0;
175
+ for (const m of messages) {
176
+ if (typeof m.content === "string" && m.content) {
177
+ total += countTokens(m.content);
178
+ }
179
+ if (m.tool_calls && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
180
+ total += countTokens(JSON.stringify(m.tool_calls));
181
+ }
182
+ }
183
+ return total;
184
+ }
185
+ function estimateRequestTokens(messages, toolSpecs) {
186
+ let total = estimateConversationTokens(messages);
187
+ if (toolSpecs && toolSpecs.length > 0) {
188
+ total += countTokens(JSON.stringify(toolSpecs));
189
+ }
190
+ return total;
191
+ }
192
+
193
+ export {
194
+ resolveDataPath,
195
+ countTokens,
196
+ estimateConversationTokens,
197
+ estimateRequestTokens
198
+ };
199
+ //# sourceMappingURL=chunk-DAEAAVDF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tokenizer.ts"],"sourcesContent":["/** Encode-only DeepSeek V3 tokenizer port; ~3% drift vs API (chat-template framing not replayed). */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { gunzipSync } from \"node:zlib\";\n\ninterface AddedToken {\n id: number;\n content: string;\n special: boolean;\n normalized: boolean;\n}\n\ninterface SplitPretokenizer {\n type: \"Split\";\n pattern: { Regex: string };\n behavior: \"Isolated\" | \"Removed\" | string;\n invert: boolean;\n}\n\ninterface ByteLevelPretokenizer {\n type: \"ByteLevel\";\n add_prefix_space: boolean;\n trim_offsets: boolean;\n use_regex: boolean;\n}\n\ntype Pretokenizer = SplitPretokenizer | ByteLevelPretokenizer;\n\ninterface TokenizerData {\n added_tokens: AddedToken[];\n pre_tokenizer: {\n type: \"Sequence\";\n pretokenizers: Pretokenizer[];\n };\n model: {\n type: \"BPE\";\n vocab: Record<string, number>;\n merges: string[];\n };\n}\n\ninterface LoadedTokenizer {\n vocab: Record<string, number>;\n mergeRank: Map<string, number>;\n splitRegexes: RegExp[];\n byteToChar: string[];\n /** Non-special added tokens only — special tokens in user text tokenize byte-by-byte (HF default). */\n addedPattern: RegExp | null;\n addedMap: Map<string, number>;\n}\n\n/** GPT-2 byte→unicode map; lets byte-level BPE vocab serialize as readable JSON strings. */\nfunction buildByteToChar(): string[] {\n const result: string[] = new Array(256);\n const bs: number[] = [];\n for (let b = 33; b <= 126; b++) bs.push(b);\n for (let b = 161; b <= 172; b++) bs.push(b);\n for (let b = 174; b <= 255; b++) bs.push(b);\n const cs = bs.slice();\n let n = 0;\n for (let b = 0; b < 256; b++) {\n if (!bs.includes(b)) {\n bs.push(b);\n cs.push(256 + n);\n n++;\n }\n }\n for (let i = 0; i < bs.length; i++) {\n result[bs[i]!] = String.fromCodePoint(cs[i]!);\n }\n return result;\n}\n\nlet cached: LoadedTokenizer | null = null;\n\n/** Two ../data candidates needed: dist/index.js AND dist/cli/index.js resolve to different roots. */\nexport function resolveDataPath(): string {\n if (process.env.REASONIX_TOKENIZER_PATH) return process.env.REASONIX_TOKENIZER_PATH;\n const candidates: string[] = [];\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n candidates.push(join(here, \"..\", \"data\", \"deepseek-tokenizer.json.gz\"));\n candidates.push(join(here, \"..\", \"..\", \"data\", \"deepseek-tokenizer.json.gz\"));\n } catch {\n /* import.meta.url unavailable — skip to the package resolution step. */\n }\n try {\n const req = createRequire(import.meta.url);\n candidates.push(\n join(dirname(req.resolve(\"reasonix/package.json\")), \"data\", \"deepseek-tokenizer.json.gz\"),\n );\n } catch {\n /* Not installed as `reasonix/` — the earlier candidates still may hit. */\n }\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n // Nothing exists — return the first candidate anyway so readFileSync\n // surfaces a concrete path in the ENOENT message (better than silent miss).\n return candidates[0] ?? join(process.cwd(), \"data\", \"deepseek-tokenizer.json.gz\");\n}\n\nfunction loadTokenizer(): LoadedTokenizer {\n if (cached) return cached;\n const buf = readFileSync(resolveDataPath());\n const json = gunzipSync(buf).toString(\"utf8\");\n const data = JSON.parse(json) as TokenizerData;\n\n const mergeRank = new Map<string, number>();\n for (let i = 0; i < data.model.merges.length; i++) {\n mergeRank.set(data.model.merges[i]!, i);\n }\n\n const splitRegexes: RegExp[] = [];\n for (const p of data.pre_tokenizer.pretokenizers) {\n if (p.type === \"Split\") {\n // All three Split rules use Isolated — matches become their own\n // pre-tokens and so do the in-between stretches. The ByteLevel\n // stage in the Sequence does no extra splitting here\n // (use_regex:false), so our 3 Split regexes are the whole story.\n splitRegexes.push(new RegExp(p.pattern.Regex, \"gu\"));\n }\n }\n\n const addedMap = new Map<string, number>();\n const addedContents: string[] = [];\n for (const t of data.added_tokens) {\n if (!t.special) {\n addedMap.set(t.content, t.id);\n addedContents.push(t.content);\n }\n }\n // Longest-first ensures greedy matching doesn't lose a longer token\n // to a shorter prefix (e.g. `<think>` before `<`).\n addedContents.sort((a, b) => b.length - a.length);\n const addedPattern = addedContents.length\n ? new RegExp(addedContents.map(escapeRegex).join(\"|\"), \"g\")\n : null;\n\n cached = {\n vocab: data.model.vocab,\n mergeRank,\n splitRegexes,\n byteToChar: buildByteToChar(),\n addedPattern,\n addedMap,\n };\n return cached;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction applySplit(chunks: string[], re: RegExp): string[] {\n const out: string[] = [];\n for (const chunk of chunks) {\n if (!chunk) continue;\n // Reset lastIndex — reusing a /g regex across matchAll iterations\n // is safe (matchAll internally advances), but across different\n // input strings we want a clean start.\n re.lastIndex = 0;\n let last = 0;\n for (const m of chunk.matchAll(re)) {\n const idx = m.index ?? 0;\n if (idx > last) out.push(chunk.slice(last, idx));\n if (m[0].length > 0) out.push(m[0]);\n last = idx + m[0].length;\n }\n if (last < chunk.length) out.push(chunk.slice(last));\n }\n return out;\n}\n\n/** UTF-8 bytes of `s`, each mapped to its byte-level visible char. */\nfunction byteLevelEncode(s: string, byteToChar: string[]): string {\n const bytes = new TextEncoder().encode(s);\n let out = \"\";\n for (let i = 0; i < bytes.length; i++) out += byteToChar[bytes[i]!];\n return out;\n}\n\nfunction bpeEncode(piece: string, mergeRank: Map<string, number>): string[] {\n if (piece.length <= 1) return piece ? [piece] : [];\n let word: string[] = Array.from(piece);\n while (true) {\n let bestIdx = -1;\n let bestRank = Number.POSITIVE_INFINITY;\n for (let i = 0; i < word.length - 1; i++) {\n const pair = `${word[i]} ${word[i + 1]}`;\n const rank = mergeRank.get(pair);\n if (rank !== undefined && rank < bestRank) {\n bestRank = rank;\n bestIdx = i;\n if (rank === 0) break; // 0 is already the best possible\n }\n }\n if (bestIdx < 0) break;\n word = [\n ...word.slice(0, bestIdx),\n word[bestIdx]! + word[bestIdx + 1]!,\n ...word.slice(bestIdx + 2),\n ];\n if (word.length === 1) break;\n }\n return word;\n}\n\nexport function encode(text: string): number[] {\n if (!text) return [];\n const t = loadTokenizer();\n const ids: number[] = [];\n\n const process = (segment: string) => {\n if (!segment) return;\n let chunks: string[] = [segment];\n for (const re of t.splitRegexes) chunks = applySplit(chunks, re);\n for (const chunk of chunks) {\n if (!chunk) continue;\n const byteLevel = byteLevelEncode(chunk, t.byteToChar);\n const pieces = bpeEncode(byteLevel, t.mergeRank);\n for (const p of pieces) {\n const id = t.vocab[p];\n // If not in vocab we silently skip: shouldn't happen for\n // byte-level BPE (every single byte has its own vocab entry),\n // but if a future tokenizer update breaks that invariant we'd\n // rather under-count than throw from a UI gauge.\n if (id !== undefined) ids.push(id);\n }\n }\n };\n\n if (t.addedPattern) {\n t.addedPattern.lastIndex = 0;\n let last = 0;\n for (const m of text.matchAll(t.addedPattern)) {\n const idx = m.index ?? 0;\n if (idx > last) process(text.slice(last, idx));\n const id = t.addedMap.get(m[0]);\n if (id !== undefined) ids.push(id);\n last = idx + m[0].length;\n }\n if (last < text.length) process(text.slice(last));\n } else {\n process(text);\n }\n return ids;\n}\n\nexport function countTokens(text: string): number {\n return encode(text).length;\n}\n\n/** Doesn't add chat-template framing overhead; under-counts ~3-6% vs real `prompt_tokens`. */\nexport function estimateConversationTokens(\n messages: Array<{ content?: string | null; tool_calls?: unknown }>,\n): number {\n let total = 0;\n for (const m of messages) {\n if (typeof m.content === \"string\" && m.content) {\n total += countTokens(m.content);\n }\n // Tool-call arguments are serialized as JSON in the prompt by the\n // chat template; their bytes WILL count upstream, so we count\n // them too. Stringify-once is cheap relative to the tokenize.\n if (m.tool_calls && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {\n total += countTokens(JSON.stringify(m.tool_calls));\n }\n }\n return total;\n}\n\n/** Tool specs ride in a separate request blob; must be counted separately for an accurate preflight. */\nexport function estimateRequestTokens(\n messages: Array<{ content?: string | null; tool_calls?: unknown }>,\n toolSpecs?: ReadonlyArray<unknown> | null,\n): number {\n let total = estimateConversationTokens(messages);\n if (toolSpecs && toolSpecs.length > 0) {\n total += countTokens(JSON.stringify(toolSpecs));\n }\n return total;\n}\n\n/** Exposed for tests — resets the lazy-load singleton. */\nexport function _resetForTests(): void {\n cached = null;\n}\n"],"mappings":"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","names":["process"]}