@x-code-cli/core 0.1.7 → 0.1.9

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 (92) hide show
  1. package/dist/agent/file-ingest.d.ts +62 -0
  2. package/dist/agent/file-ingest.d.ts.map +1 -0
  3. package/dist/agent/file-ingest.js +390 -0
  4. package/dist/agent/file-ingest.js.map +1 -0
  5. package/dist/agent/light-compact.d.ts +13 -0
  6. package/dist/agent/light-compact.d.ts.map +1 -0
  7. package/dist/agent/light-compact.js +106 -0
  8. package/dist/agent/light-compact.js.map +1 -0
  9. package/dist/agent/loop-guard.d.ts +50 -0
  10. package/dist/agent/loop-guard.d.ts.map +1 -0
  11. package/dist/agent/loop-guard.js +107 -0
  12. package/dist/agent/loop-guard.js.map +1 -0
  13. package/dist/agent/loop-state.d.ts +11 -0
  14. package/dist/agent/loop-state.d.ts.map +1 -1
  15. package/dist/agent/loop-state.js +3 -1
  16. package/dist/agent/loop-state.js.map +1 -1
  17. package/dist/agent/loop.d.ts +2 -2
  18. package/dist/agent/loop.d.ts.map +1 -1
  19. package/dist/agent/loop.js +73 -8
  20. package/dist/agent/loop.js.map +1 -1
  21. package/dist/agent/messages.d.ts +5 -2
  22. package/dist/agent/messages.d.ts.map +1 -1
  23. package/dist/agent/messages.js.map +1 -1
  24. package/dist/agent/provider-compat.d.ts +7 -0
  25. package/dist/agent/provider-compat.d.ts.map +1 -1
  26. package/dist/agent/provider-compat.js +122 -0
  27. package/dist/agent/provider-compat.js.map +1 -1
  28. package/dist/agent/stream-utils.d.ts +7 -0
  29. package/dist/agent/stream-utils.d.ts.map +1 -1
  30. package/dist/agent/stream-utils.js.map +1 -1
  31. package/dist/agent/system-prompt.js +3 -3
  32. package/dist/agent/system-prompt.js.map +1 -1
  33. package/dist/agent/tool-execution.d.ts.map +1 -1
  34. package/dist/agent/tool-execution.js +68 -26
  35. package/dist/agent/tool-execution.js.map +1 -1
  36. package/dist/agent/tool-result-sanitize.d.ts +8 -0
  37. package/dist/agent/tool-result-sanitize.d.ts.map +1 -0
  38. package/dist/agent/tool-result-sanitize.js +77 -0
  39. package/dist/agent/tool-result-sanitize.js.map +1 -0
  40. package/dist/agent/vision-fallback.d.ts +22 -0
  41. package/dist/agent/vision-fallback.d.ts.map +1 -0
  42. package/dist/agent/vision-fallback.js +127 -0
  43. package/dist/agent/vision-fallback.js.map +1 -0
  44. package/dist/index.d.ts +10 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +6 -1
  47. package/dist/index.js.map +1 -1
  48. package/dist/knowledge/session-usage.d.ts +24 -0
  49. package/dist/knowledge/session-usage.d.ts.map +1 -0
  50. package/dist/knowledge/session-usage.js +86 -0
  51. package/dist/knowledge/session-usage.js.map +1 -0
  52. package/dist/providers/cache-control.d.ts +29 -0
  53. package/dist/providers/cache-control.d.ts.map +1 -0
  54. package/dist/providers/cache-control.js +93 -0
  55. package/dist/providers/cache-control.js.map +1 -0
  56. package/dist/providers/capabilities.d.ts +15 -0
  57. package/dist/providers/capabilities.d.ts.map +1 -0
  58. package/dist/providers/capabilities.js +38 -0
  59. package/dist/providers/capabilities.js.map +1 -0
  60. package/dist/tools/index.d.ts +31 -5
  61. package/dist/tools/index.d.ts.map +1 -1
  62. package/dist/tools/index.js +1 -10
  63. package/dist/tools/index.js.map +1 -1
  64. package/dist/tools/read-file.d.ts +29 -1
  65. package/dist/tools/read-file.d.ts.map +1 -1
  66. package/dist/tools/read-file.js +103 -10
  67. package/dist/tools/read-file.js.map +1 -1
  68. package/dist/tools/shell-provider.d.ts +13 -0
  69. package/dist/tools/shell-provider.d.ts.map +1 -0
  70. package/dist/tools/shell-provider.js +74 -0
  71. package/dist/tools/shell-provider.js.map +1 -0
  72. package/dist/tools/shell-utils.d.ts +1 -7
  73. package/dist/tools/shell-utils.d.ts.map +1 -1
  74. package/dist/tools/shell-utils.js +0 -17
  75. package/dist/tools/shell-utils.js.map +1 -1
  76. package/dist/tools/truncate.d.ts +36 -0
  77. package/dist/tools/truncate.d.ts.map +1 -0
  78. package/dist/tools/truncate.js +118 -0
  79. package/dist/tools/truncate.js.map +1 -0
  80. package/dist/tools/web-search.js +2 -2
  81. package/dist/tools/web-search.js.map +1 -1
  82. package/dist/types/index.d.ts +8 -0
  83. package/dist/types/index.d.ts.map +1 -1
  84. package/dist/types/index.js.map +1 -1
  85. package/dist/utils/shell-error.d.ts +12 -0
  86. package/dist/utils/shell-error.d.ts.map +1 -0
  87. package/dist/utils/shell-error.js +73 -0
  88. package/dist/utils/shell-error.js.map +1 -0
  89. package/dist/utils.d.ts.map +1 -1
  90. package/dist/utils.js +104 -10
  91. package/dist/utils.js.map +1 -1
  92. package/package.json +21 -12
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAExD,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAuFA,CAAA;AAE3B,sFAAsF;AACtF,MAAM,UAAU,iBAAiB,CAAC,OAIjC;IACC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,IAAI,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC;SACvE,OAAO,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC;SACvC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAClC,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,IAAI,SAAS,CAAC;SACpD,OAAO,CAAC,gBAAgB,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAE/D,IAAI,OAAO,EAAE,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/agent/system-prompt.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAE7D,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAuFA,CAAA;AAE3B,sFAAsF;AACtF,MAAM,UAAU,iBAAiB,CAAC,OAIjC;IACC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAA;IAExC,IAAI,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC;SACvE,OAAO,CAAC,YAAY,EAAE,aAAa,CAAC,IAAI,CAAC;SACzC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAClC,OAAO,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,IAAI,SAAS,CAAC;SACpD,OAAO,CAAC,gBAAgB,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IAE/D,IAAI,OAAO,EAAE,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAA;IAC7C,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../src/agent/tool-execution.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAmIhD,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAA;AA6DxF,oEAAoE;AACpE,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,QAAQ,EAAE,EACrB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,IAAI,CAAC,CAIf"}
1
+ {"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../src/agent/tool-execution.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAsHhD,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAA;AA0HxF,oEAAoE;AACpE,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,QAAQ,EAAE,EACrB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,cAAc,GACxB,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -1,11 +1,12 @@
1
1
  // @x-code-cli/core — Tool execution & dispatch
2
- import { execa } from 'execa';
3
2
  import fs from 'node:fs/promises';
4
3
  import path from 'node:path';
5
4
  import { checkPermission } from '../permissions/index.js';
6
5
  import { truncateToolResult } from '../tools/index.js';
7
6
  import { clearProgressReporter, reportProgress } from '../tools/progress.js';
8
- import { getShellConfig } from '../tools/shell-utils.js';
7
+ import { getShellProvider } from '../tools/shell-provider.js';
8
+ import { foldShellErrorNoise } from '../utils/shell-error.js';
9
+ import { checkForLoop, recordToolCall } from './loop-guard.js';
9
10
  import { toolResultMessage } from './messages.js';
10
11
  /** Count occurrences of a substring without creating intermediate arrays. */
11
12
  function countOccurrences(content, search) {
@@ -55,29 +56,7 @@ async function executeWriteTool(toolName, input, toolCallId) {
55
56
  }
56
57
  /** Execute a shell command with streaming. */
57
58
  async function executeShell(command, timeout, callbacks, toolCallId) {
58
- const { executable, args, type } = getShellConfig();
59
- // On Windows, force the console codepage to UTF-8 (65001) at the OS level
60
- // BEFORE PowerShell starts parsing the command. This ensures even parse errors
61
- // (e.g. `&&` on PS 5.1) produce UTF-8 output instead of GBK garbled text.
62
- // We wrap via `cmd.exe /c "chcp 65001 >nul && powershell ..."` because
63
- // [Console]::OutputEncoding only takes effect after parsing completes.
64
- let proc;
65
- if (type === 'powershell') {
66
- const escapedCommand = command.replace(/"/g, '\\"');
67
- const psCmd = `chcp 65001 >nul && ${executable} ${args.join(' ')} "${escapedCommand}"`;
68
- proc = execa('cmd.exe', ['/c', psCmd], {
69
- timeout,
70
- reject: false,
71
- env: { ...process.env, PYTHONIOENCODING: 'utf-8' },
72
- });
73
- }
74
- else {
75
- proc = execa(executable, [...args, command], {
76
- timeout,
77
- reject: false,
78
- env: { ...process.env, PYTHONIOENCODING: 'utf-8' },
79
- });
80
- }
59
+ const proc = getShellProvider().spawn(command, { timeout });
81
60
  reportProgress(toolCallId, 'Running command...');
82
61
  const onChunk = (chunk) => {
83
62
  const s = chunk.toString();
@@ -95,7 +74,16 @@ async function executeShell(command, timeout, callbacks, toolCallId) {
95
74
  proc.stdout?.on('data', onChunk);
96
75
  proc.stderr?.on('data', onChunk);
97
76
  const result = await proc;
98
- const output = [result.stdout, result.stderr].filter(Boolean).join('\n').trim();
77
+ // Fold PowerShell/cmd multi-line error blocks to a single line before they
78
+ // reach the model. A misquoted command on Windows emits 5–10 lines per
79
+ // attempt; across a loop of failed retries those stacks accumulate faster
80
+ // than the actual diagnostic signal. execa's stdout/stderr are typed as
81
+ // `string | unknown[] | Uint8Array` — we spawn with default string mode, so
82
+ // a cast is safe, but keep a defensive fallback for non-string just in case.
83
+ const toStr = (v) => (typeof v === 'string' ? v : '');
84
+ const stdout = foldShellErrorNoise(toStr(result.stdout));
85
+ const stderr = foldShellErrorNoise(toStr(result.stderr));
86
+ const output = [stdout, stderr].filter(Boolean).join('\n').trim();
99
87
  if (result.exitCode !== 0) {
100
88
  const text = output ? `${output}\nExit code ${result.exitCode}` : `Exit code ${result.exitCode}`;
101
89
  return { output: text, isError: true };
@@ -112,10 +100,18 @@ function pushToolResult(state, callbacks, toolCallId, toolName, output, isError
112
100
  clearProgressReporter(toolCallId);
113
101
  callbacks.onToolResult(toolCallId, output, isError);
114
102
  }
103
+ /** Tools whose execution is driven by the AI SDK (they have an `execute` on
104
+ * the tool definition). By the time we see them in `processToolCalls`, the
105
+ * tool has already run and its result is already in `state.messages`. We
106
+ * can't pre-block these — only record for loop detection and annotate. */
107
+ const AUTO_EXECUTED_TOOLS = new Set(['readFile', 'glob', 'grep', 'listDir', 'webFetch', 'webSearch', 'saveKnowledge']);
115
108
  /** Handle a single tool call. Returns when the call has been fully dispatched. */
116
109
  async function handleToolCall(tc, state, options, callbacks) {
117
110
  const { toolName, input, toolCallId } = tc;
118
111
  // ── askUser tool ──
112
+ // Skip the loop guard for askUser — the model asking the user the same
113
+ // clarifying question twice is almost always intentional (e.g. the user
114
+ // answered ambiguously) and blocking it would silently break the UX.
119
115
  if (toolName === 'askUser') {
120
116
  const question = input.question;
121
117
  const optionsList = input.options;
@@ -123,6 +119,52 @@ async function handleToolCall(tc, state, options, callbacks) {
123
119
  pushToolResult(state, callbacks, toolCallId, toolName, `User answered: ${answer}`);
124
120
  return;
125
121
  }
122
+ // ── Doom-loop detection ──
123
+ // For manual tools we pre-block. For auto-executed tools the call has
124
+ // already run (result landed in state.messages via collectTurnResponse);
125
+ // we still record the hash and, on soft-block, push a supplemental notice
126
+ // so the next turn sees a clear stop signal. On hard-block, we additionally
127
+ // prompt the user before returning.
128
+ const isAutoExecuted = AUTO_EXECUTED_TOOLS.has(toolName);
129
+ const loopCheck = checkForLoop(state, toolName, input, toolCallId);
130
+ if (loopCheck.kind !== 'ok') {
131
+ recordToolCall(state, toolName, input);
132
+ if (isAutoExecuted) {
133
+ // The tool result already exists in state.messages. Append a follow-up
134
+ // user-role notice so the model's next step has explicit context that
135
+ // this path is spinning — without this nudge, some models keep trying.
136
+ state.messages.push({
137
+ role: 'user',
138
+ content: `[loop-guard] ${loopCheck.message}`,
139
+ });
140
+ callbacks.onToolResult(toolCallId, `[loop-guard] ${loopCheck.message}`, true);
141
+ }
142
+ else {
143
+ // Manual tool — short-circuit by synthesising the result. The tool body
144
+ // never runs; no side effects, no permission prompt.
145
+ pushToolResult(state, callbacks, toolCallId, toolName, `[loop-guard] ${loopCheck.message}`, true);
146
+ }
147
+ if (loopCheck.kind === 'hard-block') {
148
+ const answer = await callbacks
149
+ .onAskUser(`The model keeps calling ${toolName} with identical arguments. How do you want to proceed?`, [
150
+ { label: 'Pause', description: 'Pause the turn — you can type a new instruction.' },
151
+ { label: 'Continue', description: 'Let the model keep trying; the loop guard stays armed.' },
152
+ ])
153
+ .catch(() => 'Pause');
154
+ if (answer.toLowerCase().startsWith('pause')) {
155
+ // Clear the recent-calls window so the guard doesn't immediately
156
+ // re-trigger on the next turn if the model legitimately retries
157
+ // once with the same args under the user's guidance.
158
+ state.recentToolCalls = [];
159
+ state.messages.push({
160
+ role: 'user',
161
+ content: '[loop-guard] User paused the loop. Wait for further instructions rather than calling more tools.',
162
+ });
163
+ }
164
+ }
165
+ return;
166
+ }
167
+ recordToolCall(state, toolName, input);
126
168
  // ── Permission check for write tools and shell ──
127
169
  if (toolName === 'writeFile' || toolName === 'edit' || toolName === 'shell') {
128
170
  const approved = await checkPermission({ toolCallId, toolName, input }, options.trustMode, callbacks.onAskPermission);
@@ -1 +1 @@
1
- {"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../src/agent/tool-execution.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAE7B,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEjD,6EAA6E;AAC7E,SAAS,gBAAgB,CAAC,OAAe,EAAE,MAAc;IACvD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,GAAG,GAAG,CAAC,CAAA;IACX,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QACnD,KAAK,EAAE,CAAA;QACP,GAAG,IAAI,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,+CAA+C;AAC/C,KAAK,UAAU,gBAAgB,CAAC,QAAgB,EAAE,KAA8B,EAAE,UAAkB;IAClG,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAkB,CAAA;QACzC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAiB,CAAA;QACvC,cAAc,CAAC,UAAU,EAAE,WAAW,QAAQ,EAAE,CAAC,CAAA;QACjD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QACrE,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACjC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;QAC1E,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,iBAAiB,QAAQ,KAAK,SAAS,SAAS,CAAA;QACzD,CAAC;QACD,OAAO,iBAAiB,QAAQ,KAAK,SAAS,SAAS,CAAA;IACzD,CAAC;IAED,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAkB,CAAA;QACzC,MAAM,SAAS,GAAG,KAAK,CAAC,SAAmB,CAAA;QAC3C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAmB,CAAA;QAC3C,MAAM,UAAU,GAAI,KAAK,CAAC,UAAsB,IAAI,KAAK,CAAA;QAEzD,cAAc,CAAC,UAAU,EAAE,WAAW,QAAQ,EAAE,CAAC,CAAA;QACjD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YAClD,IAAI,KAAK,KAAK,CAAC;gBAAE,OAAO,kCAAkC,QAAQ,EAAE,CAAA;YACpE,IAAI,KAAK,GAAG,CAAC;gBACX,OAAO,sCAAsC,QAAQ,WAAW,KAAK,8DAA8D,CAAA;QACvI,CAAC;QAED,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAChH,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;QACjD,OAAO,gBAAgB,QAAQ,EAAE,CAAA;IACnC,CAAC;IAED,OAAO,2BAA2B,CAAA;AACpC,CAAC;AAED,8CAA8C;AAC9C,KAAK,UAAU,YAAY,CACzB,OAAe,EACf,OAAe,EACf,SAAyB,EACzB,UAAkB;IAElB,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,cAAc,EAAE,CAAA;IAEnD,0EAA0E;IAC1E,+EAA+E;IAC/E,0EAA0E;IAC1E,uEAAuE;IACvE,uEAAuE;IACvE,IAAI,IAAI,CAAA;IACR,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACnD,MAAM,KAAK,GAAG,sBAAsB,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,cAAc,GAAG,CAAA;QACtF,IAAI,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE;YACrC,OAAO;YACP,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE;SACnD,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE;YAC3C,OAAO;YACP,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE;SACnD,CAAC,CAAA;IACJ,CAAC;IAED,cAAc,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAA;IAEhD,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE;QAChC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;QAC1B,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;QAC1B,qEAAqE;QACrE,sEAAsE;QACtE,oEAAoE;QACpE,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACjE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACpC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;YACrE,cAAc,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;QACrC,CAAC;IACH,CAAC,CAAA;IAED,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAEhC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAA;IACzB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAA;IAC/E,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,eAAe,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,QAAQ,EAAE,CAAA;QAChG,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IACxC,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;AACrD,CAAC;AAED,qDAAqD;AACrD,SAAS,cAAc,CACrB,KAAgB,EAChB,SAAyB,EACzB,UAAkB,EAClB,QAAgB,EAChB,MAAc,EACd,OAAO,GAAG,KAAK;IAEf,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;IACpE,oEAAoE;IACpE,oEAAoE;IACpE,oEAAoE;IACpE,iEAAiE;IACjE,qBAAqB,CAAC,UAAU,CAAC,CAAA;IACjC,SAAS,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AACrD,CAAC;AAID,kFAAkF;AAClF,KAAK,UAAU,cAAc,CAC3B,EAAY,EACZ,KAAgB,EAChB,OAAqB,EACrB,SAAyB;IAEzB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IAE1C,qBAAqB;IACrB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAkB,CAAA;QACzC,MAAM,WAAW,GAAG,KAAK,CAAC,OAAmD,CAAA;QAC7E,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;QAC/D,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,kBAAkB,MAAM,EAAE,CAAC,CAAA;QAClF,OAAM;IACR,CAAC;IAED,mDAAmD;IACnD,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC5E,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,EAC/B,OAAO,CAAC,SAAS,EACjB,SAAS,CAAC,eAAe,CAC1B,CAAA;QACD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAA;YACpF,OAAM;QACR,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAc,CAAA;IAClB,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,CAAC;QACH,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACpD,MAAM,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;YAC5D,qEAAqE;YACrE,mEAAmE;YACnE,gEAAgE;YAChE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,OAAO,GAAG,IAAI,CAAA;;gBAC1C,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,QAAkB,CAAC,CAAA;QACxD,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,MAAM,OAAO,GAAI,KAAK,CAAC,OAAkB,IAAI,KAAK,CAAA;YAClD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,OAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YAC/F,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;YAC3B,OAAO,GAAG,WAAW,CAAC,OAAO,CAAA;QAC/B,CAAC;aAAM,CAAC;YACN,8EAA8E;YAC9E,OAAM;QACR,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAA;QACrE,OAAO,GAAG,IAAI,CAAA;IAChB,CAAC;IAED,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,CAAA;AAC7F,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAqB,EACrB,KAAgB,EAChB,OAAqB,EACrB,SAAyB;IAEzB,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;IACrD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"tool-execution.js","sourceRoot":"","sources":["../../src/agent/tool-execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ModelMessage } from 'ai';
2
+ /**
3
+ * Walk `messages` in place and truncate any oversized tool-result parts. Only
4
+ * mutates the `output.value` field; the rest of the message structure is
5
+ * preserved exactly as the provider returned it.
6
+ */
7
+ export declare function truncateToolResultsInMessages(messages: ModelMessage[]): void;
8
+ //# sourceMappingURL=tool-result-sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-result-sanitize.d.ts","sourceRoot":"","sources":["../../src/agent/tool-result-sanitize.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AAgCtC;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI,CAmC5E"}
@@ -0,0 +1,77 @@
1
+ // @x-code-cli/core — Truncate tool-result parts inside ModelMessage arrays
2
+ //
3
+ // AI SDK auto-executed tools (readFile / grep / glob / listDir / webFetch /
4
+ // webSearch) return their results inside `response.messages` as tool-result
5
+ // parts. The manual tool path in `tool-execution.ts` runs every output
6
+ // through `truncateToolResult`, but auto-executed results bypass that path
7
+ // and land in `state.messages` at full size. This module walks the messages
8
+ // produced by a completed stream and applies the same per-tool truncation
9
+ // policy in-place before they persist into the conversation state.
10
+ //
11
+ // Policy is per-tool:
12
+ // - shell / edit / writeFile: manual path already truncated
13
+ // - readFile: head-tail (preserve file start + file end)
14
+ // - grep / glob / listDir: head-only (lexical order is meaningful; the tail
15
+ // carries no additional signal once the head is representative)
16
+ // - webFetch: head-tail (pages often have navigation cruft at top + bottom,
17
+ // but the meaningful content is usually the middle. head-tail still beats
18
+ // head-only because it preserves the final anchors)
19
+ // - default: head-tail
20
+ import { truncateToolResult } from '../tools/truncate.js';
21
+ const PER_TOOL_POLICY = {
22
+ readFile: { direction: 'head-tail' },
23
+ grep: { direction: 'head', maxLines: 500 },
24
+ glob: { direction: 'head', maxLines: 500 },
25
+ listDir: { direction: 'head', maxLines: 500 },
26
+ webFetch: { direction: 'head-tail' },
27
+ webSearch: { direction: 'head-tail' },
28
+ shell: { direction: 'head' },
29
+ };
30
+ function policyFor(toolName) {
31
+ if (!toolName)
32
+ return { direction: 'head-tail' };
33
+ return PER_TOOL_POLICY[toolName] ?? { direction: 'head-tail' };
34
+ }
35
+ /**
36
+ * Walk `messages` in place and truncate any oversized tool-result parts. Only
37
+ * mutates the `output.value` field; the rest of the message structure is
38
+ * preserved exactly as the provider returned it.
39
+ */
40
+ export function truncateToolResultsInMessages(messages) {
41
+ for (const msg of messages) {
42
+ if (msg.role !== 'tool')
43
+ continue;
44
+ if (!Array.isArray(msg.content))
45
+ continue;
46
+ for (const part of msg.content) {
47
+ if (part?.type !== 'tool-result')
48
+ continue;
49
+ const output = part.output;
50
+ if (!output)
51
+ continue;
52
+ // Text output: `{ type: 'text', value: string }`
53
+ if (output.type === 'text' && typeof output.value === 'string') {
54
+ const truncated = truncateToolResult(output.value, policyFor(part.toolName));
55
+ if (truncated.length !== output.value.length) {
56
+ output.value = truncated;
57
+ }
58
+ continue;
59
+ }
60
+ // Content output: `{ type: 'content', value: Array<{ type: string, text?: string, ... }> }`
61
+ // Only the text entries are mutable — image-data / file-data / file-url
62
+ // are binary payloads that the provider-compat layer handles elsewhere.
63
+ if (output.type === 'content' && Array.isArray(output.value)) {
64
+ const entries = output.value;
65
+ for (const entry of entries) {
66
+ if (entry?.type === 'text' && typeof entry.text === 'string') {
67
+ const truncated = truncateToolResult(entry.text, policyFor(part.toolName));
68
+ if (truncated.length !== entry.text.length) {
69
+ entry.text = truncated;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ //# sourceMappingURL=tool-result-sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-result-sanitize.js","sourceRoot":"","sources":["../../src/agent/tool-result-sanitize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface VisionProvider {
2
+ /** Provider id, e.g. "google" / "zhipu". */
3
+ provider: string;
4
+ /** Full <provider>:<model> id passed to the AI SDK registry. */
5
+ modelId: string;
6
+ /** Short label for UI notices ("Gemini 2.5 Flash"). */
7
+ label: string;
8
+ }
9
+ /**
10
+ * Pick the best available vision sub-agent given the keys the user has
11
+ * configured. Returns null if no vision-capable provider has a key —
12
+ * caller should fall back to local OCR.
13
+ */
14
+ export declare function pickVisionProvider(): VisionProvider | null;
15
+ /**
16
+ * Generate a textual description of an image via the chosen sub-agent.
17
+ * The prompt asks for both verbatim text AND visual elements (layout,
18
+ * colors, components) — OCR alone misses the latter, so we want the
19
+ * caption to subsume what OCR would have produced.
20
+ */
21
+ export declare function captionImage(filePath: string, sub: VisionProvider): Promise<string>;
22
+ //# sourceMappingURL=vision-fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vision-fallback.d.ts","sourceRoot":"","sources":["../../src/agent/vision-fallback.ts"],"names":[],"mappings":"AAwBA,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAA;IACf,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAA;CACd;AA0BD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,GAAG,IAAI,CAS1D;AAuBD;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCzF"}
@@ -0,0 +1,127 @@
1
+ // @x-code-cli/core — Vision sub-agent for text-only providers
2
+ //
3
+ // When the user attaches an image but the active model can't natively see
4
+ // images (DeepSeek today, custom by default), automatically borrow any
5
+ // other configured provider that DOES have a vision model and use it as
6
+ // a caption sub-agent. The caption is injected as a TextPart into the
7
+ // user message so the main model sees a description without ever
8
+ // receiving the binary.
9
+ //
10
+ // Why this exists: DeepSeek users were stuck with local tesseract OCR,
11
+ // which is fine for code screenshots but useless for UI mockups, diagrams,
12
+ // or photos. Most users who set up DeepSeek also have a key for at least
13
+ // one free-tier provider (Gemini or GLM-4V-Flash); detecting that and
14
+ // reusing it removes the need for a manual /model switch every time the
15
+ // user pastes a screenshot.
16
+ import fs from 'node:fs/promises';
17
+ import path from 'node:path';
18
+ import { generateText } from 'ai';
19
+ import { getAvailableProviders } from '../config/index.js';
20
+ import { createModelRegistry } from '../providers/registry.js';
21
+ import { debugLog } from '../utils.js';
22
+ /** Vision-capable model id + display label per provider. Models picked to
23
+ * favor cheap / free-tier offerings — the goal is a quick caption, not
24
+ * deep analysis. */
25
+ const VISION_MODELS = {
26
+ google: { modelId: 'google:gemini-2.5-flash', label: 'Gemini 2.5 Flash' },
27
+ zhipu: { modelId: 'zhipu:glm-4v-flash', label: 'GLM-4V Flash' },
28
+ alibaba: { modelId: 'alibaba:qwen-vl-plus', label: 'Qwen-VL Plus' },
29
+ openai: { modelId: 'openai:gpt-4o-mini', label: 'GPT-4o Mini' },
30
+ anthropic: { modelId: 'anthropic:claude-haiku-4-5', label: 'Claude Haiku 4.5' },
31
+ moonshotai: {
32
+ modelId: 'moonshotai:moonshot-v1-32k-vision-preview',
33
+ label: 'Moonshot Vision Preview',
34
+ },
35
+ xai: { modelId: 'xai:grok-2-vision-1212', label: 'Grok 2 Vision' },
36
+ };
37
+ /** Order in which we try providers when picking a vision sub-agent.
38
+ * Free tiers and cheap-per-image models go first; heavier flagships
39
+ * last. Gemini 2.5 Flash leads because its free tier is the most
40
+ * generous (1500/day) and the model is also the strongest at the
41
+ * free price point. GLM-4V-Flash is second because it's truly free
42
+ * and reachable from China without a proxy. */
43
+ const VISION_PRIORITY = ['google', 'zhipu', 'alibaba', 'openai', 'anthropic', 'moonshotai', 'xai'];
44
+ /**
45
+ * Pick the best available vision sub-agent given the keys the user has
46
+ * configured. Returns null if no vision-capable provider has a key —
47
+ * caller should fall back to local OCR.
48
+ */
49
+ export function pickVisionProvider() {
50
+ const available = new Set(getAvailableProviders());
51
+ for (const provider of VISION_PRIORITY) {
52
+ if (!available.has(provider))
53
+ continue;
54
+ const model = VISION_MODELS[provider];
55
+ if (!model)
56
+ continue;
57
+ return { provider, modelId: model.modelId, label: model.label };
58
+ }
59
+ return null;
60
+ }
61
+ /** Same media-type mapping as file-ingest.ts uses for ImagePart hints. */
62
+ function mediaTypeFor(filePath) {
63
+ const ext = path.extname(filePath).toLowerCase();
64
+ if (ext === '.jpg' || ext === '.jpeg')
65
+ return 'image/jpeg';
66
+ if (ext === '.webp')
67
+ return 'image/webp';
68
+ if (ext === '.gif')
69
+ return 'image/gif';
70
+ if (ext === '.bmp')
71
+ return 'image/bmp';
72
+ return 'image/png';
73
+ }
74
+ /** In-memory cache so re-attaching the same image (or the same image across
75
+ * multiple submits in one session) doesn't re-burn tokens on the sub-agent.
76
+ * Keyed by `${providerId}:${file size}:${first-64-bytes-base64}` — same
77
+ * cheap collision-resistant key strategy provider-compat.ts uses for OCR. */
78
+ const captionCache = new Map();
79
+ async function cacheKey(filePath, providerModelId) {
80
+ const buffer = await fs.readFile(filePath);
81
+ return `${providerModelId}:${buffer.length}:${buffer.subarray(0, 64).toString('base64')}`;
82
+ }
83
+ /**
84
+ * Generate a textual description of an image via the chosen sub-agent.
85
+ * The prompt asks for both verbatim text AND visual elements (layout,
86
+ * colors, components) — OCR alone misses the latter, so we want the
87
+ * caption to subsume what OCR would have produced.
88
+ */
89
+ export async function captionImage(filePath, sub) {
90
+ const key = await cacheKey(filePath, sub.modelId);
91
+ const cached = captionCache.get(key);
92
+ if (cached != null) {
93
+ debugLog('vision-fallback.cache-hit', `${sub.modelId} ${path.basename(filePath)}`);
94
+ return cached;
95
+ }
96
+ const buffer = await fs.readFile(filePath);
97
+ const registry = createModelRegistry();
98
+ // The registry's languageModel() type is `${string}:${string}` but our
99
+ // VISION_MODELS entries are typed as plain string. Cast at the boundary —
100
+ // we control both ends and every entry is of the form "provider:model".
101
+ const model = registry.languageModel(sub.modelId);
102
+ debugLog('vision-fallback.caption', `${sub.modelId} ${path.basename(filePath)} ${buffer.length}B`);
103
+ const { text } = await generateText({
104
+ model,
105
+ messages: [
106
+ {
107
+ role: 'user',
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: 'Describe this image in detail so a text-only AI can act on it. ' +
112
+ 'Include: (1) any visible text transcribed verbatim, ' +
113
+ '(2) UI elements, layout, and visual hierarchy, ' +
114
+ '(3) colors, icons, shapes, and other visual details, ' +
115
+ '(4) inferred purpose or context. ' +
116
+ 'Be thorough and specific. Output plain text only — no markdown formatting.',
117
+ },
118
+ { type: 'image', image: buffer, mediaType: mediaTypeFor(filePath) },
119
+ ],
120
+ },
121
+ ],
122
+ });
123
+ const caption = text.trim();
124
+ captionCache.set(key, caption);
125
+ return caption;
126
+ }
127
+ //# sourceMappingURL=vision-fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vision-fallback.js","sourceRoot":"","sources":["../../src/agent/vision-fallback.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -8,12 +8,21 @@ export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
8
8
  export type { LoopState } from './agent/loop.js';
9
9
  export { buildSystemPrompt } from './agent/system-prompt.js';
10
10
  export { classifyApiError } from './agent/api-errors.js';
11
+ export { buildUserContent, extractFileReferences, ingestFile, classifyFile } from './agent/file-ingest.js';
12
+ export type { FileKind, FileReference, IngestedPart } from './agent/file-ingest.js';
13
+ export { captionImage, pickVisionProvider } from './agent/vision-fallback.js';
14
+ export type { VisionProvider } from './agent/vision-fallback.js';
15
+ export { capabilitiesOf, providerOf } from './providers/capabilities.js';
16
+ export type { ProviderCapabilities } from './providers/capabilities.js';
11
17
  export { toolRegistry, truncateToolResult } from './tools/index.js';
12
- export { getShellConfig } from './tools/shell-utils.js';
18
+ export { getShellProvider } from './tools/shell-provider.js';
19
+ export type { ShellProvider, ShellType } from './tools/shell-provider.js';
13
20
  export { checkPermission, getPermissionLevel } from './permissions/index.js';
14
21
  export { GLOBAL_XCODE_DIR, XCODE_DIR, debugLog } from './utils.js';
15
22
  export { buildKnowledgeContext } from './knowledge/loader.js';
16
23
  export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
17
24
  export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
25
+ export { loadLatestUsageSnapshot, listSessionUsageSnapshots } from './knowledge/session-usage.js';
26
+ export type { SessionUsageSnapshot } from './knowledge/session-usage.js';
18
27
  export { initProject } from './knowledge/init.js';
19
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9G,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGrD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACxH,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAG7D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGxD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAGvD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAG5E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY,EACV,eAAe,EACf,UAAU,EACV,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,aAAa,GACd,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC9G,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGrD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACxH,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAG7D,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAC1G,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC7E,YAAY,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAGhE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxE,YAAY,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAGvE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAGzE,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAG5E,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAA;AACjG,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
package/dist/index.js CHANGED
@@ -8,9 +8,13 @@ export { createModelRegistry } from './providers/registry.js';
8
8
  export { agentLoop, saveSession, compressMessages } from './agent/loop.js';
9
9
  export { buildSystemPrompt } from './agent/system-prompt.js';
10
10
  export { classifyApiError } from './agent/api-errors.js';
11
+ export { buildUserContent, extractFileReferences, ingestFile, classifyFile } from './agent/file-ingest.js';
12
+ export { captionImage, pickVisionProvider } from './agent/vision-fallback.js';
13
+ // Provider capabilities
14
+ export { capabilitiesOf, providerOf } from './providers/capabilities.js';
11
15
  // Tools
12
16
  export { toolRegistry, truncateToolResult } from './tools/index.js';
13
- export { getShellConfig } from './tools/shell-utils.js';
17
+ export { getShellProvider } from './tools/shell-provider.js';
14
18
  // Permissions
15
19
  export { checkPermission, getPermissionLevel } from './permissions/index.js';
16
20
  // Utils
@@ -19,5 +23,6 @@ export { GLOBAL_XCODE_DIR, XCODE_DIR, debugLog } from './utils.js';
19
23
  export { buildKnowledgeContext } from './knowledge/loader.js';
20
24
  export { getAutoMemory, initMemories } from './knowledge/auto-memory.js';
21
25
  export { loadLatestSession, saveSessionSummary, formatSessionForPrompt } from './knowledge/session.js';
26
+ export { loadLatestUsageSnapshot, listSessionUsageSnapshots } from './knowledge/session-usage.js';
22
27
  export { initProject } from './knowledge/init.js';
23
28
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAiBxC,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG9G,SAAS;AACT,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGxH,oBAAoB;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExD,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvD,cAAc;AACd,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE5E,QAAQ;AACR,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAElE,YAAY;AACZ,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAiBxC,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAG9G,SAAS;AACT,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGxH,oBAAoB;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAE1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1G,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAG7E,wBAAwB;AACxB,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAGxE,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAG5D,cAAc;AACd,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE5E,QAAQ;AACR,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAElE,YAAY;AACZ,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACtG,OAAO,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAA;AAEjG,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,24 @@
1
+ import type { LoopState } from '../agent/loop-state.js';
2
+ import type { TokenUsage } from '../types/index.js';
3
+ export interface SessionUsageSnapshot {
4
+ id: string;
5
+ modelId: string;
6
+ startedAt: string;
7
+ updatedAt: string;
8
+ turnCount: number;
9
+ usage: TokenUsage;
10
+ }
11
+ /** Write the current usage state to disk. Fire-and-forget from the loop —
12
+ * callers should `void` this; failures are swallowed so a transient FS error
13
+ * never aborts the agent turn. */
14
+ export declare function persistUsageSnapshot(state: LoopState, modelId: string): Promise<void>;
15
+ /** Read the most recent usage snapshot for the current project (cwd). Returns
16
+ * null when no session has run here yet. /usage prefers in-memory state for
17
+ * the live session and only hits this on a fresh process. */
18
+ export declare function loadLatestUsageSnapshot(): Promise<SessionUsageSnapshot | null>;
19
+ /** Enumerate every per-session usage snapshot in this project, newest first.
20
+ * Used by `/usage history` — purely project-local, never traverses other
21
+ * cwds. Skips `latest.usage.json` since it's a duplicate pointer. Silently
22
+ * drops malformed JSON files instead of failing the whole listing. */
23
+ export declare function listSessionUsageSnapshots(): Promise<SessionUsageSnapshot[]>;
24
+ //# sourceMappingURL=session-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-usage.d.ts","sourceRoot":"","sources":["../../src/knowledge/session-usage.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,UAAU,CAAA;CAClB;AAgBD;;mCAEmC;AACnC,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB3F;AAED;;8DAE8D;AAC9D,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAOpF;AAED;;;uEAGuE;AACvE,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAqBjF"}
@@ -0,0 +1,86 @@
1
+ // @x-code-cli/core — Per-session token usage persistence.
2
+ //
3
+ // Writes a small JSON snapshot to .x-code/sessions/{sessionId}.usage.json on
4
+ // every assistant turn so that /usage works after a restart and so the user
5
+ // can grep/diff usage across sessions in the project. Scope is intentionally
6
+ // per-cwd (project-local) — there's no cross-project aggregation.
7
+ //
8
+ // Kept separate from session.ts (which writes the LLM-generated SessionSummary
9
+ // at exit/compact) because the two write at different cadences and would
10
+ // clobber each other if they shared a file.
11
+ import fs from 'node:fs/promises';
12
+ import path from 'node:path';
13
+ import { XCODE_DIR } from '../utils.js';
14
+ const SESSIONS_DIR = `${XCODE_DIR}/sessions`;
15
+ function getSessionsDir() {
16
+ return path.join(process.cwd(), SESSIONS_DIR);
17
+ }
18
+ function getUsagePath(sessionId) {
19
+ return path.join(getSessionsDir(), `${sessionId}.usage.json`);
20
+ }
21
+ function getLatestUsagePath() {
22
+ return path.join(getSessionsDir(), 'latest.usage.json');
23
+ }
24
+ /** Write the current usage state to disk. Fire-and-forget from the loop —
25
+ * callers should `void` this; failures are swallowed so a transient FS error
26
+ * never aborts the agent turn. */
27
+ export async function persistUsageSnapshot(state, modelId) {
28
+ const snapshot = {
29
+ id: state.sessionId,
30
+ modelId,
31
+ startedAt: state.startedAt,
32
+ updatedAt: new Date().toISOString(),
33
+ turnCount: state.turnCount,
34
+ usage: { ...state.tokenUsage },
35
+ };
36
+ try {
37
+ await fs.mkdir(getSessionsDir(), { recursive: true });
38
+ const json = JSON.stringify(snapshot, null, 2);
39
+ await Promise.all([
40
+ fs.writeFile(getUsagePath(state.sessionId), json, 'utf-8'),
41
+ fs.writeFile(getLatestUsagePath(), json, 'utf-8'),
42
+ ]);
43
+ }
44
+ catch {
45
+ // Persistence is best-effort; never block the agent loop on FS errors.
46
+ }
47
+ }
48
+ /** Read the most recent usage snapshot for the current project (cwd). Returns
49
+ * null when no session has run here yet. /usage prefers in-memory state for
50
+ * the live session and only hits this on a fresh process. */
51
+ export async function loadLatestUsageSnapshot() {
52
+ try {
53
+ const raw = await fs.readFile(getLatestUsagePath(), 'utf-8');
54
+ return JSON.parse(raw);
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ /** Enumerate every per-session usage snapshot in this project, newest first.
61
+ * Used by `/usage history` — purely project-local, never traverses other
62
+ * cwds. Skips `latest.usage.json` since it's a duplicate pointer. Silently
63
+ * drops malformed JSON files instead of failing the whole listing. */
64
+ export async function listSessionUsageSnapshots() {
65
+ let entries;
66
+ try {
67
+ entries = await fs.readdir(getSessionsDir());
68
+ }
69
+ catch {
70
+ return [];
71
+ }
72
+ const usageFiles = entries.filter((f) => f.endsWith('.usage.json') && f !== 'latest.usage.json');
73
+ const snapshots = await Promise.all(usageFiles.map(async (f) => {
74
+ try {
75
+ const raw = await fs.readFile(path.join(getSessionsDir(), f), 'utf-8');
76
+ return JSON.parse(raw);
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }));
82
+ return snapshots
83
+ .filter((s) => s !== null)
84
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
85
+ }
86
+ //# sourceMappingURL=session-usage.js.map