@joeytheman/gemini-mcp-tool 1.3.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/README.md +127 -35
  2. package/dist/__tests__/agyModelSteps.test.d.ts +2 -0
  3. package/dist/__tests__/agyModelSteps.test.d.ts.map +1 -0
  4. package/dist/__tests__/agyModelSteps.test.js +58 -0
  5. package/dist/__tests__/agyModelSteps.test.js.map +1 -0
  6. package/dist/__tests__/ask-gemini.test.js +99 -37
  7. package/dist/__tests__/ask-gemini.test.js.map +1 -1
  8. package/dist/__tests__/capture-script.chromium.test.d.ts +2 -0
  9. package/dist/__tests__/capture-script.chromium.test.d.ts.map +1 -0
  10. package/dist/__tests__/capture-script.chromium.test.js +235 -0
  11. package/dist/__tests__/capture-script.chromium.test.js.map +1 -0
  12. package/dist/__tests__/layout-snippet.chromium.test.d.ts +2 -0
  13. package/dist/__tests__/layout-snippet.chromium.test.d.ts.map +1 -0
  14. package/dist/__tests__/layout-snippet.chromium.test.js +333 -0
  15. package/dist/__tests__/layout-snippet.chromium.test.js.map +1 -0
  16. package/dist/__tests__/layout-snippet.test.d.ts +2 -0
  17. package/dist/__tests__/layout-snippet.test.d.ts.map +1 -0
  18. package/dist/__tests__/layout-snippet.test.js +12 -0
  19. package/dist/__tests__/layout-snippet.test.js.map +1 -0
  20. package/dist/__tests__/live-pass.test.d.ts +2 -0
  21. package/dist/__tests__/live-pass.test.d.ts.map +1 -0
  22. package/dist/__tests__/live-pass.test.js +1249 -0
  23. package/dist/__tests__/live-pass.test.js.map +1 -0
  24. package/dist/__tests__/screen-review.test.d.ts +2 -0
  25. package/dist/__tests__/screen-review.test.d.ts.map +1 -0
  26. package/dist/__tests__/screen-review.test.js +553 -0
  27. package/dist/__tests__/screen-review.test.js.map +1 -0
  28. package/dist/__tests__/server-progress.test.d.ts +2 -0
  29. package/dist/__tests__/server-progress.test.d.ts.map +1 -0
  30. package/dist/__tests__/server-progress.test.js +63 -0
  31. package/dist/__tests__/server-progress.test.js.map +1 -0
  32. package/dist/__tests__/server.test.js +17 -19
  33. package/dist/__tests__/server.test.js.map +1 -1
  34. package/dist/__tests__/simple-tools.test.d.ts +2 -0
  35. package/dist/__tests__/simple-tools.test.d.ts.map +1 -0
  36. package/dist/__tests__/simple-tools.test.js +30 -0
  37. package/dist/__tests__/simple-tools.test.js.map +1 -0
  38. package/dist/__tests__/tools.test.js +91 -0
  39. package/dist/__tests__/tools.test.js.map +1 -1
  40. package/dist/__tests__/utils/agyExecutor.test.d.ts +2 -0
  41. package/dist/__tests__/utils/agyExecutor.test.d.ts.map +1 -0
  42. package/dist/__tests__/utils/agyExecutor.test.js +731 -0
  43. package/dist/__tests__/utils/agyExecutor.test.js.map +1 -0
  44. package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts +2 -0
  45. package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts.map +1 -0
  46. package/dist/__tests__/utils/agyTranscriptRecovery.test.js +127 -0
  47. package/dist/__tests__/utils/agyTranscriptRecovery.test.js.map +1 -0
  48. package/dist/__tests__/utils/chunkCache.test.js +26 -2
  49. package/dist/__tests__/utils/chunkCache.test.js.map +1 -1
  50. package/dist/__tests__/utils/commandExecutor.test.js +185 -7
  51. package/dist/__tests__/utils/commandExecutor.test.js.map +1 -1
  52. package/dist/__tests__/utils/fileReferences.test.d.ts +2 -0
  53. package/dist/__tests__/utils/fileReferences.test.d.ts.map +1 -0
  54. package/dist/__tests__/utils/fileReferences.test.js +87 -0
  55. package/dist/__tests__/utils/fileReferences.test.js.map +1 -0
  56. package/dist/__tests__/utils/gitStatusGuard.test.d.ts +2 -0
  57. package/dist/__tests__/utils/gitStatusGuard.test.d.ts.map +1 -0
  58. package/dist/__tests__/utils/gitStatusGuard.test.js +106 -0
  59. package/dist/__tests__/utils/gitStatusGuard.test.js.map +1 -0
  60. package/dist/__tests__/utils/progressUpdates.test.d.ts +2 -0
  61. package/dist/__tests__/utils/progressUpdates.test.d.ts.map +1 -0
  62. package/dist/__tests__/utils/progressUpdates.test.js +62 -0
  63. package/dist/__tests__/utils/progressUpdates.test.js.map +1 -0
  64. package/dist/__tests__/utils/responseCache.test.js +31 -11
  65. package/dist/__tests__/utils/responseCache.test.js.map +1 -1
  66. package/dist/__tests__/utils/test-helpers.d.ts +4 -0
  67. package/dist/__tests__/utils/test-helpers.d.ts.map +1 -1
  68. package/dist/__tests__/utils/test-helpers.js +16 -0
  69. package/dist/__tests__/utils/test-helpers.js.map +1 -1
  70. package/dist/constants.d.ts +91 -26
  71. package/dist/constants.d.ts.map +1 -1
  72. package/dist/constants.js +101 -28
  73. package/dist/constants.js.map +1 -1
  74. package/dist/index.js +20 -95
  75. package/dist/index.js.map +1 -1
  76. package/dist/layoutCheckSnippet.generated.d.ts +2 -0
  77. package/dist/layoutCheckSnippet.generated.d.ts.map +1 -0
  78. package/dist/layoutCheckSnippet.generated.js +3 -0
  79. package/dist/layoutCheckSnippet.generated.js.map +1 -0
  80. package/dist/tools/ask-gemini.tool.d.ts +34 -0
  81. package/dist/tools/ask-gemini.tool.d.ts.map +1 -1
  82. package/dist/tools/ask-gemini.tool.js +40 -23
  83. package/dist/tools/ask-gemini.tool.js.map +1 -1
  84. package/dist/tools/brainstorm.tool.d.ts.map +1 -1
  85. package/dist/tools/brainstorm.tool.js +7 -5
  86. package/dist/tools/brainstorm.tool.js.map +1 -1
  87. package/dist/tools/index.d.ts.map +1 -1
  88. package/dist/tools/index.js +3 -1
  89. package/dist/tools/index.js.map +1 -1
  90. package/dist/tools/live-pass.tool.d.ts +206 -0
  91. package/dist/tools/live-pass.tool.d.ts.map +1 -0
  92. package/dist/tools/live-pass.tool.js +670 -0
  93. package/dist/tools/live-pass.tool.js.map +1 -0
  94. package/dist/tools/registry.d.ts +6 -4
  95. package/dist/tools/registry.d.ts.map +1 -1
  96. package/dist/tools/registry.js +14 -11
  97. package/dist/tools/registry.js.map +1 -1
  98. package/dist/tools/screen-review.tool.d.ts +124 -0
  99. package/dist/tools/screen-review.tool.d.ts.map +1 -0
  100. package/dist/tools/screen-review.tool.js +449 -0
  101. package/dist/tools/screen-review.tool.js.map +1 -0
  102. package/dist/tools/simple-tools.d.ts.map +1 -1
  103. package/dist/tools/simple-tools.js +9 -3
  104. package/dist/tools/simple-tools.js.map +1 -1
  105. package/dist/utils/agyExecutor.d.ts +76 -0
  106. package/dist/utils/agyExecutor.d.ts.map +1 -0
  107. package/dist/utils/agyExecutor.js +449 -0
  108. package/dist/utils/agyExecutor.js.map +1 -0
  109. package/dist/utils/agyModelSteps.d.ts +5 -0
  110. package/dist/utils/agyModelSteps.d.ts.map +1 -0
  111. package/dist/utils/agyModelSteps.js +33 -0
  112. package/dist/utils/agyModelSteps.js.map +1 -0
  113. package/dist/utils/agyReport.d.ts +19 -0
  114. package/dist/utils/agyReport.d.ts.map +1 -0
  115. package/dist/utils/agyReport.js +62 -0
  116. package/dist/utils/agyReport.js.map +1 -0
  117. package/dist/utils/agyTranscriptRecovery.d.ts +16 -0
  118. package/dist/utils/agyTranscriptRecovery.d.ts.map +1 -0
  119. package/dist/utils/agyTranscriptRecovery.js +149 -0
  120. package/dist/utils/agyTranscriptRecovery.js.map +1 -0
  121. package/dist/utils/artifactFile.d.ts +6 -0
  122. package/dist/utils/artifactFile.d.ts.map +1 -0
  123. package/dist/utils/artifactFile.js +55 -0
  124. package/dist/utils/artifactFile.js.map +1 -0
  125. package/dist/utils/captureScript.d.ts +24 -0
  126. package/dist/utils/captureScript.d.ts.map +1 -0
  127. package/dist/utils/captureScript.js +83 -0
  128. package/dist/utils/captureScript.js.map +1 -0
  129. package/dist/utils/chunkCache.d.ts.map +1 -1
  130. package/dist/utils/chunkCache.js +19 -5
  131. package/dist/utils/chunkCache.js.map +1 -1
  132. package/dist/utils/commandExecutor.d.ts +7 -1
  133. package/dist/utils/commandExecutor.d.ts.map +1 -1
  134. package/dist/utils/commandExecutor.js +162 -22
  135. package/dist/utils/commandExecutor.js.map +1 -1
  136. package/dist/utils/fileReferences.d.ts +45 -0
  137. package/dist/utils/fileReferences.d.ts.map +1 -0
  138. package/dist/utils/fileReferences.js +169 -0
  139. package/dist/utils/fileReferences.js.map +1 -0
  140. package/dist/utils/gitCheckout.d.ts +14 -0
  141. package/dist/utils/gitCheckout.d.ts.map +1 -0
  142. package/dist/utils/gitCheckout.js +36 -0
  143. package/dist/utils/gitCheckout.js.map +1 -0
  144. package/dist/utils/gitStatusGuard.d.ts +35 -0
  145. package/dist/utils/gitStatusGuard.d.ts.map +1 -0
  146. package/dist/utils/gitStatusGuard.js +82 -0
  147. package/dist/utils/gitStatusGuard.js.map +1 -0
  148. package/dist/utils/layoutCheck.d.ts +58 -0
  149. package/dist/utils/layoutCheck.d.ts.map +1 -0
  150. package/dist/utils/layoutCheck.js +84 -0
  151. package/dist/utils/layoutCheck.js.map +1 -0
  152. package/dist/utils/logger.d.ts +0 -1
  153. package/dist/utils/logger.d.ts.map +1 -1
  154. package/dist/utils/logger.js +0 -6
  155. package/dist/utils/logger.js.map +1 -1
  156. package/dist/utils/progressUpdates.d.ts +14 -0
  157. package/dist/utils/progressUpdates.d.ts.map +1 -0
  158. package/dist/utils/progressUpdates.js +40 -0
  159. package/dist/utils/progressUpdates.js.map +1 -0
  160. package/dist/utils/responseCache.d.ts +3 -3
  161. package/dist/utils/responseCache.d.ts.map +1 -1
  162. package/dist/utils/responseCache.js +11 -6
  163. package/dist/utils/responseCache.js.map +1 -1
  164. package/package.json +19 -16
  165. package/dist/__tests__/utils/geminiExecutor.test.d.ts +0 -2
  166. package/dist/__tests__/utils/geminiExecutor.test.d.ts.map +0 -1
  167. package/dist/__tests__/utils/geminiExecutor.test.js +0 -337
  168. package/dist/__tests__/utils/geminiExecutor.test.js.map +0 -1
  169. package/dist/utils/geminiExecutor.d.ts +0 -17
  170. package/dist/utils/geminiExecutor.d.ts.map +0 -1
  171. package/dist/utils/geminiExecutor.js +0 -238
  172. package/dist/utils/geminiExecutor.js.map +0 -1
@@ -0,0 +1,449 @@
1
+ import { z } from 'zod';
2
+ import { executeCommand } from './commandExecutor.js';
3
+ import { Logger } from './logger.js';
4
+ import { ERROR_MESSAGES, MODELS, CLI, AGY_INTERNAL, LIVE_PASS, AGY_LIMITS } from '../constants.js';
5
+ import { parseChangeModeOutput, validateChangeModeEdits } from './changeModeParser.js';
6
+ import { formatChangeModeResponse, summarizeChangeModeEdits } from './changeModeTranslator.js';
7
+ import { chunkChangeModeEdits } from './changeModeChunker.js';
8
+ import { cacheChunks, getChunks } from './chunkCache.js';
9
+ import { generateCacheKey, getCachedResponse, cacheResponse, isCacheEnabled } from './responseCache.js';
10
+ import { normalizeList, resolveFileReferences, isFilesystemRoot } from './fileReferences.js';
11
+ const DURATION_TERM = /(\d+(?:\.\d+)?)(ms|h|m|s)/g;
12
+ const DURATION_UNIT_MS = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 };
13
+ const PRINT_TIMEOUT_PATTERN = new RegExp(`^(?:0|(?:${DURATION_TERM.source})+)$`);
14
+ export const printTimeoutSchema = z.string().regex(PRINT_TIMEOUT_PATTERN, ERROR_MESSAGES.INVALID_PRINT_TIMEOUT);
15
+ /** Milliseconds (0 is agy's "no limit"), or undefined for a value printTimeoutSchema rejects. */
16
+ function printTimeoutMs(printTimeout) {
17
+ if (!PRINT_TIMEOUT_PATTERN.test(printTimeout))
18
+ return undefined;
19
+ return [...printTimeout.matchAll(DURATION_TERM)].reduce((total, [, amount, unit]) => total + Number(amount) * DURATION_UNIT_MS[unit], 0);
20
+ }
21
+ /**
22
+ * How long an agy process may run: its print timeout plus a margin, or the
23
+ * default ceiling when there is no positive timeout.
24
+ */
25
+ export function agyKillAfterMs(printTimeout) {
26
+ const timeoutMs = printTimeoutMs(printTimeout ?? '') ?? 0;
27
+ return timeoutMs > 0 && timeoutMs <= Number.MAX_SAFE_INTEGER - AGY_LIMITS.CEILING_MARGIN_MS
28
+ ? timeoutMs + AGY_LIMITS.CEILING_MARGIN_MS
29
+ : AGY_LIMITS.DEFAULT_CEILING_MS;
30
+ }
31
+ const AGY_STATUS_SUCCESS = 'SUCCESS';
32
+ const AGY_STATUS_ERROR = 'ERROR';
33
+ const PARSE_EXCERPT_CHARS = 200;
34
+ function isYoloEnabled(opts) {
35
+ return Boolean(opts.yolo) || opts.approvalMode === CLI.DEFAULTS.APPROVAL_MODE_YOLO;
36
+ }
37
+ function isJsonMode(opts) {
38
+ return opts.outputFormat === CLI.DEFAULTS.OUTPUT_FORMAT_JSON;
39
+ }
40
+ function validateAgyOptions(opts) {
41
+ const unsupported = [];
42
+ if (opts.debug)
43
+ unsupported.push('debug');
44
+ if (opts.promptInteractive)
45
+ unsupported.push('promptInteractive');
46
+ if (opts.extensions)
47
+ unsupported.push('extensions');
48
+ if (opts.approvalMode && opts.approvalMode !== CLI.DEFAULTS.APPROVAL_MODE_YOLO) {
49
+ unsupported.push(`approvalMode:${opts.approvalMode}`);
50
+ }
51
+ if (unsupported.length > 0) {
52
+ throw new Error(`${ERROR_MESSAGES.UNSUPPORTED_AGY_OPTIONS}: ${unsupported.join(', ')}. ` +
53
+ `The Antigravity CLI headless path supports model, sandbox, yolo, includeDirectories, printTimeout, ` +
54
+ `resume, conversationId, outputFormat, jsonSchema, effort, and workingDirectory.`);
55
+ }
56
+ if (opts.outputFormat &&
57
+ opts.outputFormat !== CLI.DEFAULTS.OUTPUT_FORMAT_TEXT &&
58
+ opts.outputFormat !== CLI.DEFAULTS.OUTPUT_FORMAT_JSON) {
59
+ throw new Error(`${ERROR_MESSAGES.UNSUPPORTED_OUTPUT_FORMAT} Received '${opts.outputFormat}'.`);
60
+ }
61
+ if (opts.jsonSchema && !isJsonMode(opts)) {
62
+ throw new Error(ERROR_MESSAGES.JSON_SCHEMA_REQUIRES_JSON);
63
+ }
64
+ // Passthrough only: agy rejects --effort for tiered Gemini names and that
65
+ // error is surfaced verbatim. We only guard the shape.
66
+ if (opts.effort && !CLI.DEFAULTS.EFFORT_LEVELS.includes(opts.effort)) {
67
+ throw new Error(`${ERROR_MESSAGES.INVALID_EFFORT} Received '${opts.effort}'.`);
68
+ }
69
+ if (opts.changeMode && isJsonMode(opts)) {
70
+ throw new Error(`${ERROR_MESSAGES.UNSUPPORTED_AGY_OPTIONS}: changeMode with outputFormat 'json'. ` +
71
+ `changeMode returns OLD/NEW text, not a JSON envelope.`);
72
+ }
73
+ if (opts.conversationId !== undefined && !opts.conversationId.trim()) {
74
+ throw new Error(ERROR_MESSAGES.INVALID_CONVERSATION_ID);
75
+ }
76
+ // Refuse yolo (skip-permissions) from a filesystem root, which would grant agy
77
+ // unrestricted access to the whole drive. Check the effective cwd: when
78
+ // workingDirectory is omitted, agy inherits the server's process.cwd().
79
+ if (isYoloEnabled(opts) && isFilesystemRoot(opts.cwd || process.cwd())) {
80
+ throw new Error(ERROR_MESSAGES.UNSAFE_ROOT_YOLO);
81
+ }
82
+ }
83
+ function resolveResumeArgs(resume) {
84
+ if (resume === undefined || resume === false)
85
+ return [];
86
+ const normalized = String(resume).trim();
87
+ const lower = normalized.toLowerCase();
88
+ if (lower === CLI.DEFAULTS.BOOLEAN_FALSE)
89
+ return [];
90
+ if (normalized === '') {
91
+ throw new Error(ERROR_MESSAGES.INVALID_RESUME);
92
+ }
93
+ if (resume === true ||
94
+ lower === CLI.DEFAULTS.BOOLEAN_TRUE ||
95
+ lower === CLI.DEFAULTS.RESUME_LATEST ||
96
+ lower === CLI.DEFAULTS.RESUME_CONTINUE) {
97
+ return [CLI.FLAGS.CONTINUE];
98
+ }
99
+ return [CLI.FLAGS.CONVERSATION, normalized];
100
+ }
101
+ /**
102
+ * The conversation this call asked agy to resume, if any. `resume` with a bare
103
+ * ID maps to the same `--conversation` flag as `conversationId`, so both must be
104
+ * checked against what agy actually returned.
105
+ */
106
+ export function requestedConversationId(opts) {
107
+ const explicit = opts.conversationId?.trim();
108
+ if (explicit)
109
+ return explicit;
110
+ const args = resolveResumeArgs(opts.resume);
111
+ return args[0] === CLI.FLAGS.CONVERSATION ? args[1] : undefined;
112
+ }
113
+ /** An explicit conversationId wins over `resume`. */
114
+ function resolveConversationArgs(opts) {
115
+ const explicit = opts.conversationId?.trim();
116
+ if (explicit)
117
+ return [CLI.FLAGS.CONVERSATION, explicit];
118
+ return resolveResumeArgs(opts.resume);
119
+ }
120
+ function buildAgyArgs(opts, prompt, refDirs) {
121
+ const args = [];
122
+ const model = opts.model || MODELS.DEFAULT;
123
+ args.push(CLI.FLAGS.MODEL, model);
124
+ if (opts.effort) {
125
+ args.push(CLI.FLAGS.EFFORT, opts.effort);
126
+ }
127
+ if (opts.sandbox) {
128
+ args.push(CLI.FLAGS.SANDBOX);
129
+ }
130
+ if (isYoloEnabled(opts)) {
131
+ args.push(CLI.FLAGS.YOLO);
132
+ }
133
+ // Explicit includeDirectories plus the directories resolved from @file
134
+ // references, deduped.
135
+ for (const dir of new Set([...normalizeList(opts.includeDirectories), ...refDirs])) {
136
+ args.push(CLI.FLAGS.ADD_DIR, dir);
137
+ }
138
+ if (opts.printTimeout) {
139
+ args.push(CLI.FLAGS.PRINT_TIMEOUT, opts.printTimeout);
140
+ }
141
+ // Every call reads its answer from the JSON envelope, whatever the caller asked for.
142
+ args.push(CLI.FLAGS.OUTPUT_FORMAT, CLI.DEFAULTS.OUTPUT_FORMAT_JSON);
143
+ // The schema is passed inline (~2 KB); agy takes it as a flag value.
144
+ if (opts.jsonSchema) {
145
+ args.push(CLI.FLAGS.JSON_SCHEMA, opts.jsonSchema);
146
+ }
147
+ args.push(...resolveConversationArgs(opts));
148
+ args.push(CLI.FLAGS.PRINT, prompt);
149
+ return args;
150
+ }
151
+ const CONTROL_ESCAPES = { '\n': '\\n', '\r': '\\r', '\t': '\\t' };
152
+ /** Escape raw newlines/tabs that appear INSIDE JSON string literals, which JSON.parse rejects. */
153
+ function escapeControlCharsInStrings(raw) {
154
+ let out = '';
155
+ let inString = false;
156
+ let escaped = false;
157
+ for (const ch of raw) {
158
+ if (inString && escaped) {
159
+ out += ch;
160
+ escaped = false;
161
+ continue;
162
+ }
163
+ if (inString && ch === '\\') {
164
+ out += ch;
165
+ escaped = true;
166
+ continue;
167
+ }
168
+ if (ch === '"') {
169
+ inString = !inString;
170
+ out += ch;
171
+ continue;
172
+ }
173
+ out += (inString && CONTROL_ESCAPES[ch]) ? CONTROL_ESCAPES[ch] : ch;
174
+ }
175
+ return out;
176
+ }
177
+ /**
178
+ * Parse the JSON envelope out of `agy --output-format json` stdout. agy may
179
+ * print progress lines first, so the envelope is whatever starts at the last
180
+ * line beginning with `{`.
181
+ */
182
+ /**
183
+ * An agy envelope, not merely any JSON object: `{}` must read as a parse
184
+ * failure rather than a verified, cacheable, empty success.
185
+ */
186
+ function isAgyEnvelope(value) {
187
+ if (!value || typeof value !== 'object' || Array.isArray(value))
188
+ return false;
189
+ const candidate = value;
190
+ if (candidate.status === AGY_STATUS_ERROR)
191
+ return true;
192
+ // An ERROR can arrive before agy has a conversation, so only a SUCCESS is
193
+ // required to carry the id. Either way a bare `{}` is a parse failure, not an
194
+ // empty success.
195
+ return candidate.status === AGY_STATUS_SUCCESS && typeof candidate.conversation_id === 'string';
196
+ }
197
+ function tryParseEnvelope(candidate) {
198
+ for (const text of [candidate, escapeControlCharsInStrings(candidate)]) {
199
+ try {
200
+ const parsed = JSON.parse(text);
201
+ if (isAgyEnvelope(parsed))
202
+ return parsed;
203
+ }
204
+ catch {
205
+ // Try the next form.
206
+ }
207
+ }
208
+ return null;
209
+ }
210
+ export function parseAgyJsonEnvelope(stdout) {
211
+ const lines = stdout.split('\n');
212
+ // The envelope is the last JSON object agy printed, so start from the last
213
+ // `{` line and walk backwards: when that line turns out to sit INSIDE the
214
+ // envelope's own `response` (raw newlines plus quoted JSON), the earlier real
215
+ // start line still parses. Progress lines printed before it are never reached.
216
+ for (let index = lines.length - 1; index >= 0; index--) {
217
+ if (!lines[index].trimStart().startsWith('{'))
218
+ continue;
219
+ const envelope = tryParseEnvelope(lines.slice(index).join('\n').trim());
220
+ if (envelope)
221
+ return envelope;
222
+ }
223
+ throw new Error(`${ERROR_MESSAGES.AGY_JSON_PARSE}. Output began: ${stdout.trim().slice(0, PARSE_EXCERPT_CHARS)}`);
224
+ }
225
+ /** Human-readable "DisplayName (action)" list of the actions agy refused to run. */
226
+ export function deniedActionsSummary(envelope) {
227
+ return (envelope.denied_actions ?? [])
228
+ .map(denied => `${denied.display_name || denied.action || 'unknown'} (${denied.action || 'unknown'})`)
229
+ .join(', ');
230
+ }
231
+ export function formatAgyUsageLine(envelope) {
232
+ const usage = envelope.usage ?? {};
233
+ return `Usage: ${envelope.num_turns ?? '?'} turns · ${envelope.duration_seconds ?? '?'}s · tokens in ` +
234
+ `${usage.input_tokens ?? 0} / out ${usage.output_tokens ?? 0} / thinking ${usage.thinking_tokens ?? 0} / ` +
235
+ `cache ${usage.cache_read_tokens ?? 0} / total ${usage.total_tokens ?? 0}`;
236
+ }
237
+ /**
238
+ * Render an envelope for a human reader. A resumed turn replays the PREVIOUS
239
+ * turn's structured_output, so it is only trusted when this call passed a schema.
240
+ */
241
+ export function renderAgyJsonEnvelope(envelope, opts = {}) {
242
+ if (opts.hadSchema && envelope.structured_output !== undefined && envelope.structured_output !== null) {
243
+ return JSON.stringify(envelope.structured_output, null, 2);
244
+ }
245
+ return envelope.response ?? '';
246
+ }
247
+ export function formatConversationLine(conversationId) {
248
+ return `${LIVE_PASS.CONVERSATION_LINE_PREFIX}${conversationId}]`;
249
+ }
250
+ /** A zod schema as the JSON Schema agy's `--json-schema` accepts (no `$schema` key). */
251
+ export function toAgyJsonSchema(schema) {
252
+ const { $schema, ...rest } = z.toJSONSchema(schema);
253
+ return rest;
254
+ }
255
+ /**
256
+ * A resumed turn replays the previous turn's structured_output, so it only
257
+ * counts as this call's answer when this call passed a schema.
258
+ */
259
+ function hasAnswer(envelope, opts) {
260
+ const hasStructuredAnswer = Boolean(opts.jsonSchema) &&
261
+ envelope.structured_output !== undefined && envelope.structured_output !== null;
262
+ return Boolean(envelope.response?.trim()) || hasStructuredAnswer;
263
+ }
264
+ /**
265
+ * Validate a run before it is cached or returned. Throws for every failure
266
+ * mode agy signals inside an exit-0 envelope.
267
+ */
268
+ function verifyJsonEnvelope(stdout, opts) {
269
+ if (stdout.trim() === AGY_INTERNAL.TIMEOUT_SENTINEL) {
270
+ throw new Error(ERROR_MESSAGES.AGY_NO_OUTPUT);
271
+ }
272
+ const envelope = parseAgyJsonEnvelope(stdout);
273
+ if (envelope.status === AGY_STATUS_ERROR) {
274
+ throw new Error(`${ERROR_MESSAGES.AGY_STATUS_ERROR}: ${envelope.error || 'no error text'}`);
275
+ }
276
+ // A stale or unknown ID only warns on stderr and silently starts a NEW
277
+ // conversation with status SUCCESS, so compare what came back.
278
+ const requested = requestedConversationId(opts);
279
+ if (requested && envelope.conversation_id !== requested) {
280
+ throw new Error(`${ERROR_MESSAGES.CONVERSATION_NOT_RESUMED} ${requested}; it returned ` +
281
+ `${envelope.conversation_id || '(none)'}. The ID is unknown to this machine or workspace.`);
282
+ }
283
+ const denied = deniedActionsSummary(envelope);
284
+ if (!hasAnswer(envelope, opts) && denied) {
285
+ // changeMode asks for edits back, so yolo (letting Gemini write the files) is the wrong remedy.
286
+ const message = opts.changeMode ? ERROR_MESSAGES.CHANGEMODE_DENIED_ACTIONS : ERROR_MESSAGES.AGY_DENIED_ACTIONS;
287
+ throw new Error(`${message}: ${denied}`);
288
+ }
289
+ return envelope;
290
+ }
291
+ export async function executeAgyCLI(prompt, options, onProgress) {
292
+ const opts = typeof options === 'string'
293
+ ? { model: options }
294
+ : options || {};
295
+ validateAgyOptions(opts);
296
+ // Cache key (computed once) is only used when caching is enabled and the call
297
+ // is repeatable: changeMode, resumed turns and opt-outs are never cached
298
+ // because their answer depends on conversation state, not just the prompt.
299
+ const cacheable = isCacheEnabled() && !opts.changeMode && !opts.resume &&
300
+ !opts.conversationId && !opts.noCache;
301
+ const cacheKey = cacheable ? generateCacheKey(prompt, opts) : undefined;
302
+ if (cacheKey) {
303
+ const cached = getCachedResponse(cacheKey);
304
+ if (cached) {
305
+ Logger.debug('Returning cached response');
306
+ return cached;
307
+ }
308
+ }
309
+ // Normalize file references and register the directories of any reference
310
+ // that resolves to a real file under a trusted root, so agy can read them (a
311
+ // bare @file outside an added dir makes agy hang). Unresolved references are
312
+ // passed through untouched.
313
+ const { prompt: resolvedPrompt, addDirs: refDirs } = resolveFileReferences(prompt, { cwd: opts.cwd, includeDirectories: opts.includeDirectories });
314
+ let processedPrompt = resolvedPrompt;
315
+ if (opts.changeMode) {
316
+ const changeModeInstructions = `
317
+ [CHANGEMODE INSTRUCTIONS]
318
+ You are generating code modifications that will be processed by an automated system. The output format is critical because it enables programmatic application of changes without human intervention.
319
+
320
+ INSTRUCTIONS:
321
+ 1. Analyze each provided file thoroughly
322
+ 2. Identify locations requiring changes based on the user request
323
+ 3. For each change, output in the exact format specified
324
+ 4. The OLD section must be EXACTLY what appears in the file (copy-paste exact match)
325
+ 5. Provide complete, directly replacing code blocks
326
+ 6. Verify line numbers are accurate
327
+
328
+ CRITICAL REQUIREMENTS:
329
+ 1. Output edits in the EXACT format specified below - no deviations
330
+ 2. The OLD string MUST be findable with Ctrl+F - it must be a unique, exact match
331
+ 3. Include enough surrounding lines to make the OLD string unique
332
+ 4. If a string appears multiple times (like </div>), include enough context lines above and below to make it unique
333
+ 5. Copy the OLD content EXACTLY as it appears - including all whitespace, indentation, line breaks
334
+ 6. Never use partial lines - always include complete lines from start to finish
335
+
336
+ OUTPUT FORMAT (follow exactly):
337
+ **FILE: [filename]:[line_number]**
338
+ \`\`\`
339
+ OLD:
340
+ [exact code to be replaced - must match file content precisely]
341
+ NEW:
342
+ [new code to insert - complete and functional]
343
+ \`\`\`
344
+
345
+ EXAMPLE 1 - Simple unique match:
346
+ **FILE: src/utils/helper.js:100**
347
+ \`\`\`
348
+ OLD:
349
+ function getMessage() {
350
+ return "Hello World";
351
+ }
352
+ NEW:
353
+ function getMessage() {
354
+ return "Hello Universe!";
355
+ }
356
+ \`\`\`
357
+
358
+ EXAMPLE 2 - Common tag needing context:
359
+ **FILE: index.html:245**
360
+ \`\`\`
361
+ OLD:
362
+ </div>
363
+ </div>
364
+ </section>
365
+ NEW:
366
+ </div>
367
+ </footer>
368
+ </section>
369
+ \`\`\`
370
+
371
+ IMPORTANT: The OLD section must be an EXACT copy from the file that can be found with Ctrl+F!
372
+
373
+ USER REQUEST:
374
+ ${processedPrompt}
375
+ `;
376
+ processedPrompt = changeModeInstructions;
377
+ }
378
+ const args = buildAgyArgs(opts, processedPrompt, refDirs);
379
+ try {
380
+ const result = await executeCommand(CLI.COMMANDS.AGY, args, onProgress, opts.cwd, {
381
+ killAfterMs: agyKillAfterMs(opts.printTimeout),
382
+ signal: opts.signal,
383
+ });
384
+ const envelope = verifyJsonEnvelope(result, opts);
385
+ if (isJsonMode(opts)) {
386
+ if (cacheKey && hasAnswer(envelope, opts))
387
+ cacheResponse(cacheKey, result);
388
+ return result;
389
+ }
390
+ const answer = (envelope.response ?? '').trim();
391
+ if (!answer) {
392
+ throw new Error(`${ERROR_MESSAGES.AGY_EMPTY_ANSWER} ${formatConversationLine(envelope.conversation_id ?? '')}`);
393
+ }
394
+ if (cacheKey)
395
+ cacheResponse(cacheKey, answer);
396
+ return answer;
397
+ }
398
+ catch (error) {
399
+ const errorMessage = error instanceof Error ? error.message : String(error);
400
+ if (errorMessage.includes('ENOENT') || errorMessage.includes('command not found')) {
401
+ throw new Error(ERROR_MESSAGES.AGY_NOT_FOUND);
402
+ }
403
+ throw error;
404
+ }
405
+ }
406
+ /** Run agy in json mode and return the parsed envelope. */
407
+ export async function executeAgyJson(prompt, options = {}, onProgress) {
408
+ const raw = await executeAgyCLI(prompt, { ...options, outputFormat: CLI.DEFAULTS.OUTPUT_FORMAT_JSON }, onProgress);
409
+ return parseAgyJsonEnvelope(raw);
410
+ }
411
+ export async function processChangeModeOutput(rawResult, chunkIndex, chunkCacheKey, prompt) {
412
+ if (chunkIndex && chunkCacheKey) {
413
+ const cachedChunks = getChunks(chunkCacheKey);
414
+ if (cachedChunks && chunkIndex > 0 && chunkIndex <= cachedChunks.length) {
415
+ Logger.debug(`Using cached chunk ${chunkIndex} of ${cachedChunks.length}`);
416
+ const chunk = cachedChunks[chunkIndex - 1];
417
+ let result = formatChangeModeResponse(chunk.edits, { current: chunkIndex, total: cachedChunks.length, cacheKey: chunkCacheKey });
418
+ if (chunkIndex === 1 && chunk.edits.length > 5) {
419
+ const allEdits = cachedChunks.flatMap(c => c.edits);
420
+ result = summarizeChangeModeEdits(allEdits) + '\n\n' + result;
421
+ }
422
+ return result;
423
+ }
424
+ Logger.debug(`Cache miss or invalid chunk index, processing new result`);
425
+ }
426
+ const edits = parseChangeModeOutput(rawResult);
427
+ if (edits.length === 0) {
428
+ return `No edits found in Gemini's response. Please ensure Gemini uses the OLD/NEW format. \n\n+ ${rawResult}`;
429
+ }
430
+ const validation = validateChangeModeEdits(edits);
431
+ if (!validation.valid) {
432
+ return `Edit validation failed:\n${validation.errors.join('\n')}`;
433
+ }
434
+ const chunks = chunkChangeModeEdits(edits);
435
+ let cacheKey;
436
+ if (chunks.length > 1 && prompt) {
437
+ cacheKey = cacheChunks(prompt, chunks);
438
+ Logger.debug(`Cached ${chunks.length} chunks with key: ${cacheKey}`);
439
+ }
440
+ const returnChunkIndex = (chunkIndex && chunkIndex > 0 && chunkIndex <= chunks.length) ? chunkIndex : 1;
441
+ const returnChunk = chunks[returnChunkIndex - 1];
442
+ let result = formatChangeModeResponse(returnChunk.edits, chunks.length > 1 ? { current: returnChunkIndex, total: chunks.length, cacheKey } : undefined);
443
+ if (returnChunkIndex === 1 && edits.length > 5) {
444
+ result = summarizeChangeModeEdits(edits, chunks.length > 1) + '\n\n' + result;
445
+ }
446
+ Logger.debug(`ChangeMode: Parsed ${edits.length} edits, ${chunks.length} chunks, returning chunk ${returnChunkIndex}`);
447
+ return result;
448
+ }
449
+ //# sourceMappingURL=agyExecutor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyExecutor.js","sourceRoot":"","sources":["../../src/utils/agyExecutor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAgB,MAAM,KAAK,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,cAAc,EACd,MAAM,EACN,GAAG,EACH,YAAY,EACZ,SAAS,EACT,UAAU,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAkD7F,MAAM,aAAa,GAAG,4BAA4B,CAAC;AACnD,MAAM,gBAAgB,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAW,CAAC;AAC9E,MAAM,qBAAqB,GAAG,IAAI,MAAM,CAAC,YAAY,aAAa,CAAC,MAAM,MAAM,CAAC,CAAC;AAEjF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,qBAAqB,EAAE,cAAc,CAAC,qBAAqB,CAAC,CAAC;AAEhH,iGAAiG;AACjG,SAAS,cAAc,CAAC,YAAoB;IAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,CAAC,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CACrD,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAqC,CAAC,EAC7G,CAAC,CACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,YAAqB;IAClD,MAAM,SAAS,GAAG,cAAc,CAAC,YAAY,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;IAC1D,OAAO,SAAS,GAAG,CAAC,IAAI,SAAS,IAAI,MAAM,CAAC,gBAAgB,GAAG,UAAU,CAAC,iBAAiB;QACzF,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,iBAAiB;QAC1C,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC;AACpC,CAAC;AAED,MAAM,kBAAkB,GAAG,SAAS,CAAC;AACrC,MAAM,gBAAgB,GAAG,OAAO,CAAC;AACjC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC,SAAS,aAAa,CAAC,IAAmB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC;AACrF,CAAC;AAED,SAAS,UAAU,CAAC,IAAmB;IACrC,OAAO,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC;AAC/D,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAmB;IAC7C,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,IAAI,IAAI,CAAC,KAAK;QAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,IAAI,CAAC,iBAAiB;QAAE,WAAW,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAClE,IAAI,IAAI,CAAC,UAAU;QAAE,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QAC/E,WAAW,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,GAAG,cAAc,CAAC,uBAAuB,KAAK,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACxE,qGAAqG;YACrG,iFAAiF,CAClF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,YAAY;QACnB,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,QAAQ,CAAC,kBAAkB;QACrD,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,CAAC,yBAAyB,cAAc,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;IAClG,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC;IAC5D,CAAC;IAED,0EAA0E;IAC1E,uDAAuD;IACvD,IAAI,IAAI,CAAC,MAAM,IAAI,CAAE,GAAG,CAAC,QAAQ,CAAC,aAAmC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,CAAC,cAAc,cAAc,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,GAAG,cAAc,CAAC,uBAAuB,yCAAyC;YAClF,uDAAuD,CACxD,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,uBAAuB,CAAC,CAAC;IAC1D,CAAC;IAED,+EAA+E;IAC/E,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAyB;IAClD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,EAAE,CAAC;IAExD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAEvC,IAAI,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC;IACpD,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,MAAM,KAAK,IAAI;QACjB,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,YAAY;QACnC,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,aAAa;QACpC,KAAK,KAAK,GAAG,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAmB;IACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClE,CAAC;AAED,qDAAqD;AACrD,SAAS,uBAAuB,CAAC,IAAmB;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,QAAQ;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACxD,OAAO,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,IAAmB,EAAE,MAAc,EAAE,OAAiB;IAC1E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC;IAE3C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAElC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,uEAAuE;IACvE,uBAAuB;IACvB,KAAK,MAAM,GAAG,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;QACnF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;IAED,qFAAqF;IACrF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACpE,qEAAqE;IACrE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC;IAE5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,eAAe,GAA2B,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAE1F,kGAAkG;AAClG,SAAS,2BAA2B,CAAC,GAAW;IAC9C,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YAAC,GAAG,IAAI,EAAE,CAAC;YAAC,OAAO,GAAG,KAAK,CAAC;YAAC,SAAS;QAAC,CAAC;QAClE,IAAI,QAAQ,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAAC,GAAG,IAAI,EAAE,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QACrE,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC;YAAC,GAAG,IAAI,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9D,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9E,MAAM,SAAS,GAAG,KAAwB,CAAC;IAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,gBAAgB;QAAE,OAAO,IAAI,CAAC;IACvD,0EAA0E;IAC1E,8EAA8E;IAC9E,iBAAiB;IACjB,OAAO,SAAS,CAAC,MAAM,KAAK,kBAAkB,IAAI,OAAO,SAAS,CAAC,eAAe,KAAK,QAAQ,CAAC;AAClG,CAAC;AAED,SAAS,gBAAgB,CAAC,SAAiB;IACzC,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACvE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;YAC3C,IAAI,aAAa,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,qBAAqB;QACvB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,2EAA2E;IAC3E,0EAA0E;IAC1E,8EAA8E;IAC9E,+EAA+E;IAC/E,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACxD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;IAChC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,GAAG,cAAc,CAAC,cAAc,mBAAmB,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,EAAE,CACjG,CAAC;AACJ,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,oBAAoB,CAAC,QAAyB;IAC5D,OAAO,CAAC,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;SACnC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS,KAAK,MAAM,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC;SACrG,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAyB;IAC1D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;IACnC,OAAO,UAAU,QAAQ,CAAC,SAAS,IAAI,GAAG,YAAY,QAAQ,CAAC,gBAAgB,IAAI,GAAG,gBAAgB;QACpG,GAAG,KAAK,CAAC,YAAY,IAAI,CAAC,UAAU,KAAK,CAAC,aAAa,IAAI,CAAC,eAAe,KAAK,CAAC,eAAe,IAAI,CAAC,KAAK;QAC1G,SAAS,KAAK,CAAC,iBAAiB,IAAI,CAAC,YAAY,KAAK,CAAC,YAAY,IAAI,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAyB,EAAE,OAAgC,EAAE;IACjG,IAAI,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,iBAAiB,KAAK,SAAS,IAAI,QAAQ,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;QACtG,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,cAAsB;IAC3D,OAAO,GAAG,SAAS,CAAC,wBAAwB,GAAG,cAAc,GAAG,CAAC;AACnE,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC,MAAM,CAA4B,CAAC;IAC/E,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,QAAyB,EAAE,IAAmB;IAC/D,MAAM,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;QAClD,QAAQ,CAAC,iBAAiB,KAAK,SAAS,IAAI,QAAQ,CAAC,iBAAiB,KAAK,IAAI,CAAC;IAClF,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,IAAI,mBAAmB,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,MAAc,EAAE,IAAmB;IAC7D,IAAI,MAAM,CAAC,IAAI,EAAE,KAAK,YAAY,CAAC,gBAAgB,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,QAAQ,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE9C,IAAI,QAAQ,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,CAAC,gBAAgB,KAAK,QAAQ,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;IAC9F,CAAC;IAED,uEAAuE;IACvE,+DAA+D;IAC/D,MAAM,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,SAAS,IAAI,QAAQ,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,GAAG,cAAc,CAAC,wBAAwB,IAAI,SAAS,gBAAgB;YACvE,GAAG,QAAQ,CAAC,eAAe,IAAI,QAAQ,mDAAmD,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;QACzC,gGAAgG;QAChG,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC,CAAC,cAAc,CAAC,kBAAkB,CAAC;QAC/G,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,KAAK,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,OAA+B,EAC/B,UAAwC;IAExC,MAAM,IAAI,GAAkB,OAAO,OAAO,KAAK,QAAQ;QACrD,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE;QACpB,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IAElB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,8EAA8E;IAC9E,yEAAyE;IACzE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,MAAM;QACpE,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC1C,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,qBAAqB,CACxE,MAAM,EACN,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE,CAC/D,CAAC;IACF,IAAI,eAAe,GAAG,cAAc,CAAC;IAErC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DjC,eAAe;CAChB,CAAC;QACE,eAAe,GAAG,sBAAsB,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YAChF,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC;YAC9C,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAElD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,IAAI,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC;gBAAE,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC3E,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,GAAG,cAAc,CAAC,gBAAgB,IAAI,sBAAsB,CAAC,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAClH,CAAC;QACD,IAAI,QAAQ;YAAE,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5E,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,UAAyB,EAAE,EAC3B,UAAwC;IAExC,MAAM,GAAG,GAAG,MAAM,aAAa,CAC7B,MAAM,EACN,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAC7D,UAAU,CACX,CAAC;IACF,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAAiB,EACjB,UAAmB,EACnB,aAAsB,EACtB,MAAe;IAEf,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;QAChC,MAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,YAAY,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;YACxE,MAAM,CAAC,KAAK,CAAC,sBAAsB,UAAU,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3E,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;YAC3C,IAAI,MAAM,GAAG,wBAAwB,CACnC,KAAK,CAAC,KAAK,EACX,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,CAC7E,CAAC;YAEF,IAAI,UAAU,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/C,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACpD,MAAM,GAAG,wBAAwB,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;YAChE,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,KAAK,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAE/C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,4FAA4F,SAAS,EAAE,CAAC;IACjH,CAAC;IAED,MAAM,UAAU,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,4BAA4B,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACpE,CAAC;IAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE3C,IAAI,QAA4B,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC;QAChC,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,MAAM,qBAAqB,QAAQ,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,gBAAgB,GAAG,CAAC,UAAU,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC;IAEjD,IAAI,MAAM,GAAG,wBAAwB,CACnC,WAAW,CAAC,KAAK,EACjB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAC9F,CAAC;IAEF,IAAI,gBAAgB,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,GAAG,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;IAChF,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,sBAAsB,KAAK,CAAC,MAAM,WAAW,MAAM,CAAC,MAAM,4BAA4B,gBAAgB,EAAE,CAAC,CAAC;IACvH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function agyConversationStore(conversationId: string, root?: string): string;
2
+ /** How many model steps Gemini took in a conversation, or null when agy's step store can't be read. */
3
+ export declare function countAgyModelSteps(conversationId: string, root?: string): Promise<number | null>;
4
+ export declare function formatModelSteps(steps: number | null, frameCount?: number): string;
5
+ //# sourceMappingURL=agyModelSteps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyModelSteps.d.ts","sourceRoot":"","sources":["../../src/utils/agyModelSteps.ts"],"names":[],"mappings":"AAQA,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,SAAyD,GAAG,MAAM,CAElI;AAED,uGAAuG;AACvG,wBAAsB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAatG;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlF"}
@@ -0,0 +1,33 @@
1
+ import { execFile } from 'child_process';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+ import { promisify } from 'util';
5
+ import { AGY_INTERNAL } from '../constants.js';
6
+ const execFileAsync = promisify(execFile);
7
+ export function agyConversationStore(conversationId, root = path.join(os.homedir(), ...AGY_INTERNAL.ROOT_SEGMENTS)) {
8
+ return path.join(root, AGY_INTERNAL.CONVERSATIONS_DIR, `${conversationId}${AGY_INTERNAL.CONVERSATION_STORE_EXT}`);
9
+ }
10
+ /** How many model steps Gemini took in a conversation, or null when agy's step store can't be read. */
11
+ export async function countAgyModelSteps(conversationId, root) {
12
+ if (!/^[0-9a-f-]+$/i.test(conversationId))
13
+ return null;
14
+ try {
15
+ const { stdout } = await execFileAsync('sqlite3', [`file:${encodeURI(agyConversationStore(conversationId, root))}?immutable=1`, `select count(*) from steps where step_type = ${AGY_INTERNAL.MODEL_STEP_TYPE};`], { timeout: 10_000 });
16
+ const count = Number.parseInt(stdout.trim(), 10);
17
+ return Number.isNaN(count) ? null : count;
18
+ }
19
+ catch {
20
+ return null;
21
+ }
22
+ }
23
+ export function formatModelSteps(steps, frameCount) {
24
+ if (steps === null)
25
+ return "Gemini steps: ? (agy's step store was unreadable)";
26
+ if (frameCount === undefined)
27
+ return `Gemini steps: ${steps}`;
28
+ if (frameCount === 0)
29
+ return `Gemini steps: ${steps}, no frames`;
30
+ const perFrame = Math.round((steps / frameCount) * 10) / 10;
31
+ return `Gemini steps: ${steps} (${perFrame} per frame, ${frameCount} frame${frameCount === 1 ? '' : 's'})`;
32
+ }
33
+ //# sourceMappingURL=agyModelSteps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyModelSteps.js","sourceRoot":"","sources":["../../src/utils/agyModelSteps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,UAAU,oBAAoB,CAAC,cAAsB,EAAE,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,YAAY,CAAC,aAAa,CAAC;IACxH,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,iBAAiB,EAAE,GAAG,cAAc,GAAG,YAAY,CAAC,sBAAsB,EAAE,CAAC,CAAC;AACpH,CAAC;AAED,uGAAuG;AACvG,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,cAAsB,EAAE,IAAa;IAC5E,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CACpC,SAAS,EACT,CAAC,QAAQ,SAAS,CAAC,oBAAoB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,cAAc,EAAE,gDAAgD,YAAY,CAAC,eAAe,GAAG,CAAC,EAC9J,EAAE,OAAO,EAAE,MAAM,EAAE,CACpB,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACjD,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAoB,EAAE,UAAmB;IACxE,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,mDAAmD,CAAC;IAC/E,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,iBAAiB,KAAK,EAAE,CAAC;IAC9D,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,iBAAiB,KAAK,aAAa,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAC5D,OAAO,iBAAiB,KAAK,KAAK,QAAQ,eAAe,UAAU,SAAS,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC7G,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { type AgyJsonEnvelope } from './agyExecutor.js';
2
+ import type { WorkingTreeDiff } from './gitStatusGuard.js';
3
+ export declare function bulletList(items: string[]): string;
4
+ export declare function section(title: string, body: string): string;
5
+ /**
6
+ * The uninvited-edit warning, or '' when the working tree did not change.
7
+ * Every path that hands Gemini a shell must render this, including the ones
8
+ * that bail out early.
9
+ */
10
+ export declare function formatWorkingTreeSection(diff: WorkingTreeDiff): string;
11
+ /**
12
+ * Rethrow an agy failure with any uninvited edits appended. A run that timed
13
+ * out or exited non-zero may still have used its shell first, and that warning
14
+ * must not be lost with the error.
15
+ */
16
+ export declare function failWithWorkingTree(error: unknown, diff: WorkingTreeDiff): never;
17
+ /** Report for an envelope whose structured_output did not match the tool's result schema. */
18
+ export declare function renderUnparsableEnvelope(envelope: AgyJsonEnvelope, headline: string, issues: string[], subtitle?: string): string;
19
+ //# sourceMappingURL=agyReport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyReport.d.ts","sourceRoot":"","sources":["../../src/utils/agyReport.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAElD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAkBtE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,GAAG,KAAK,CAIhF;AAED,6FAA6F;AAC7F,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAcR"}
@@ -0,0 +1,62 @@
1
+ import { formatAgyUsageLine, formatConversationLine } from './agyExecutor.js';
2
+ /**
3
+ * Markdown rendering shared by the tools that turn an agy JSON envelope into a
4
+ * report. Everything here is text only: no image data ever reaches the caller.
5
+ */
6
+ const UNPARSABLE_EXCERPT_CHARS = 2000;
7
+ export function bulletList(items) {
8
+ return items.length > 0 ? items.map(item => `- ${item}`).join('\n') : '- none';
9
+ }
10
+ export function section(title, body) {
11
+ return `## ${title}\n${body}`;
12
+ }
13
+ /**
14
+ * The uninvited-edit warning, or '' when the working tree did not change.
15
+ * Every path that hands Gemini a shell must render this, including the ones
16
+ * that bail out early.
17
+ */
18
+ export function formatWorkingTreeSection(diff) {
19
+ const modified = diff.modified ?? [];
20
+ const changed = diff.added.length > 0 || diff.removed.length > 0 || modified.length > 0;
21
+ // A capped run must still say so: "nothing to report" and "we could not look
22
+ // at everything" are different answers, and silence would conflate them.
23
+ if (!changed && !diff.truncated)
24
+ return '';
25
+ return section('Working tree', [
26
+ changed
27
+ ? '- WARNING: the working tree changed during this run.'
28
+ : '- No change detected in the files that were checked.',
29
+ ...diff.added.map(line => `- added: ${line}`),
30
+ ...diff.removed.map(line => `- removed: ${line}`),
31
+ // A file that was already dirty before the run keeps its status line, so
32
+ // only its content hash reveals that it was rewritten.
33
+ ...modified.map(file => `- modified during run: ${file}`),
34
+ ...(diff.truncated ? ['- NOTE: too many dirty files to hash them all; content changes may be under-reported.'] : []),
35
+ ].join('\n'));
36
+ }
37
+ /**
38
+ * Rethrow an agy failure with any uninvited edits appended. A run that timed
39
+ * out or exited non-zero may still have used its shell first, and that warning
40
+ * must not be lost with the error.
41
+ */
42
+ export function failWithWorkingTree(error, diff) {
43
+ const warning = formatWorkingTreeSection(diff);
44
+ const message = error instanceof Error ? error.message : String(error);
45
+ throw warning ? new Error(`${message}\n\n${warning}`) : (error instanceof Error ? error : new Error(message));
46
+ }
47
+ /** Report for an envelope whose structured_output did not match the tool's result schema. */
48
+ export function renderUnparsableEnvelope(envelope, headline, issues, subtitle) {
49
+ const raw = envelope.structured_output !== undefined && envelope.structured_output !== null
50
+ ? JSON.stringify(envelope.structured_output)
51
+ : (envelope.response ?? '');
52
+ return [
53
+ envelope.conversation_id ? formatConversationLine(envelope.conversation_id) : '',
54
+ headline,
55
+ subtitle ?? '',
56
+ formatAgyUsageLine(envelope),
57
+ section('Why', '- Gemini did not return a result matching the schema this tool requested.'),
58
+ section('Schema issues', bulletList(issues)),
59
+ section('Raw answer (truncated)', raw.slice(0, UNPARSABLE_EXCERPT_CHARS)),
60
+ ].filter(Boolean).join('\n\n');
61
+ }
62
+ //# sourceMappingURL=agyReport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyReport.js","sourceRoot":"","sources":["../../src/utils/agyReport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Output that should trigger transcript recovery: empty or the timeout sentinel. */
2
+ export declare function isRecoverableEmptyOutput(stdout: string): boolean;
3
+ /**
4
+ * Recover the latest model response for `conversationId` (or, absent one, for
5
+ * `cwd`) if it was produced after
6
+ * `runStartMs`. Returns the recovered text, or `null` if recovery is disabled,
7
+ * the cwd has no known conversation, the transcript is stale/missing, or any
8
+ * access fails. There is intentionally NO global "newest transcript" fallback —
9
+ * that could return another project's or session's answer.
10
+ */
11
+ export declare function recoverFromTranscript(opts: {
12
+ cwd?: string;
13
+ conversationId?: string;
14
+ runStartMs: number;
15
+ }): string | null;
16
+ //# sourceMappingURL=agyTranscriptRecovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agyTranscriptRecovery.d.ts","sourceRoot":"","sources":["../../src/utils/agyTranscriptRecovery.ts"],"names":[],"mappings":"AAmCA,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGhE;AA8ED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAClE,MAAM,GAAG,IAAI,CA8Bf"}