@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.
- package/README.md +127 -35
- package/dist/__tests__/agyModelSteps.test.d.ts +2 -0
- package/dist/__tests__/agyModelSteps.test.d.ts.map +1 -0
- package/dist/__tests__/agyModelSteps.test.js +58 -0
- package/dist/__tests__/agyModelSteps.test.js.map +1 -0
- package/dist/__tests__/ask-gemini.test.js +99 -37
- package/dist/__tests__/ask-gemini.test.js.map +1 -1
- package/dist/__tests__/capture-script.chromium.test.d.ts +2 -0
- package/dist/__tests__/capture-script.chromium.test.d.ts.map +1 -0
- package/dist/__tests__/capture-script.chromium.test.js +235 -0
- package/dist/__tests__/capture-script.chromium.test.js.map +1 -0
- package/dist/__tests__/layout-snippet.chromium.test.d.ts +2 -0
- package/dist/__tests__/layout-snippet.chromium.test.d.ts.map +1 -0
- package/dist/__tests__/layout-snippet.chromium.test.js +333 -0
- package/dist/__tests__/layout-snippet.chromium.test.js.map +1 -0
- package/dist/__tests__/layout-snippet.test.d.ts +2 -0
- package/dist/__tests__/layout-snippet.test.d.ts.map +1 -0
- package/dist/__tests__/layout-snippet.test.js +12 -0
- package/dist/__tests__/layout-snippet.test.js.map +1 -0
- package/dist/__tests__/live-pass.test.d.ts +2 -0
- package/dist/__tests__/live-pass.test.d.ts.map +1 -0
- package/dist/__tests__/live-pass.test.js +1249 -0
- package/dist/__tests__/live-pass.test.js.map +1 -0
- package/dist/__tests__/screen-review.test.d.ts +2 -0
- package/dist/__tests__/screen-review.test.d.ts.map +1 -0
- package/dist/__tests__/screen-review.test.js +553 -0
- package/dist/__tests__/screen-review.test.js.map +1 -0
- package/dist/__tests__/server-progress.test.d.ts +2 -0
- package/dist/__tests__/server-progress.test.d.ts.map +1 -0
- package/dist/__tests__/server-progress.test.js +63 -0
- package/dist/__tests__/server-progress.test.js.map +1 -0
- package/dist/__tests__/server.test.js +17 -19
- package/dist/__tests__/server.test.js.map +1 -1
- package/dist/__tests__/simple-tools.test.d.ts +2 -0
- package/dist/__tests__/simple-tools.test.d.ts.map +1 -0
- package/dist/__tests__/simple-tools.test.js +30 -0
- package/dist/__tests__/simple-tools.test.js.map +1 -0
- package/dist/__tests__/tools.test.js +91 -0
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/__tests__/utils/agyExecutor.test.d.ts +2 -0
- package/dist/__tests__/utils/agyExecutor.test.d.ts.map +1 -0
- package/dist/__tests__/utils/agyExecutor.test.js +731 -0
- package/dist/__tests__/utils/agyExecutor.test.js.map +1 -0
- package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts +2 -0
- package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts.map +1 -0
- package/dist/__tests__/utils/agyTranscriptRecovery.test.js +127 -0
- package/dist/__tests__/utils/agyTranscriptRecovery.test.js.map +1 -0
- package/dist/__tests__/utils/chunkCache.test.js +26 -2
- package/dist/__tests__/utils/chunkCache.test.js.map +1 -1
- package/dist/__tests__/utils/commandExecutor.test.js +185 -7
- package/dist/__tests__/utils/commandExecutor.test.js.map +1 -1
- package/dist/__tests__/utils/fileReferences.test.d.ts +2 -0
- package/dist/__tests__/utils/fileReferences.test.d.ts.map +1 -0
- package/dist/__tests__/utils/fileReferences.test.js +87 -0
- package/dist/__tests__/utils/fileReferences.test.js.map +1 -0
- package/dist/__tests__/utils/gitStatusGuard.test.d.ts +2 -0
- package/dist/__tests__/utils/gitStatusGuard.test.d.ts.map +1 -0
- package/dist/__tests__/utils/gitStatusGuard.test.js +106 -0
- package/dist/__tests__/utils/gitStatusGuard.test.js.map +1 -0
- package/dist/__tests__/utils/progressUpdates.test.d.ts +2 -0
- package/dist/__tests__/utils/progressUpdates.test.d.ts.map +1 -0
- package/dist/__tests__/utils/progressUpdates.test.js +62 -0
- package/dist/__tests__/utils/progressUpdates.test.js.map +1 -0
- package/dist/__tests__/utils/responseCache.test.js +31 -11
- package/dist/__tests__/utils/responseCache.test.js.map +1 -1
- package/dist/__tests__/utils/test-helpers.d.ts +4 -0
- package/dist/__tests__/utils/test-helpers.d.ts.map +1 -1
- package/dist/__tests__/utils/test-helpers.js +16 -0
- package/dist/__tests__/utils/test-helpers.js.map +1 -1
- package/dist/constants.d.ts +91 -26
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +101 -28
- package/dist/constants.js.map +1 -1
- package/dist/index.js +20 -95
- package/dist/index.js.map +1 -1
- package/dist/layoutCheckSnippet.generated.d.ts +2 -0
- package/dist/layoutCheckSnippet.generated.d.ts.map +1 -0
- package/dist/layoutCheckSnippet.generated.js +3 -0
- package/dist/layoutCheckSnippet.generated.js.map +1 -0
- package/dist/tools/ask-gemini.tool.d.ts +34 -0
- package/dist/tools/ask-gemini.tool.d.ts.map +1 -1
- package/dist/tools/ask-gemini.tool.js +40 -23
- package/dist/tools/ask-gemini.tool.js.map +1 -1
- package/dist/tools/brainstorm.tool.d.ts.map +1 -1
- package/dist/tools/brainstorm.tool.js +7 -5
- package/dist/tools/brainstorm.tool.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/live-pass.tool.d.ts +206 -0
- package/dist/tools/live-pass.tool.d.ts.map +1 -0
- package/dist/tools/live-pass.tool.js +670 -0
- package/dist/tools/live-pass.tool.js.map +1 -0
- package/dist/tools/registry.d.ts +6 -4
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +14 -11
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/screen-review.tool.d.ts +124 -0
- package/dist/tools/screen-review.tool.d.ts.map +1 -0
- package/dist/tools/screen-review.tool.js +449 -0
- package/dist/tools/screen-review.tool.js.map +1 -0
- package/dist/tools/simple-tools.d.ts.map +1 -1
- package/dist/tools/simple-tools.js +9 -3
- package/dist/tools/simple-tools.js.map +1 -1
- package/dist/utils/agyExecutor.d.ts +76 -0
- package/dist/utils/agyExecutor.d.ts.map +1 -0
- package/dist/utils/agyExecutor.js +449 -0
- package/dist/utils/agyExecutor.js.map +1 -0
- package/dist/utils/agyModelSteps.d.ts +5 -0
- package/dist/utils/agyModelSteps.d.ts.map +1 -0
- package/dist/utils/agyModelSteps.js +33 -0
- package/dist/utils/agyModelSteps.js.map +1 -0
- package/dist/utils/agyReport.d.ts +19 -0
- package/dist/utils/agyReport.d.ts.map +1 -0
- package/dist/utils/agyReport.js +62 -0
- package/dist/utils/agyReport.js.map +1 -0
- package/dist/utils/agyTranscriptRecovery.d.ts +16 -0
- package/dist/utils/agyTranscriptRecovery.d.ts.map +1 -0
- package/dist/utils/agyTranscriptRecovery.js +149 -0
- package/dist/utils/agyTranscriptRecovery.js.map +1 -0
- package/dist/utils/artifactFile.d.ts +6 -0
- package/dist/utils/artifactFile.d.ts.map +1 -0
- package/dist/utils/artifactFile.js +55 -0
- package/dist/utils/artifactFile.js.map +1 -0
- package/dist/utils/captureScript.d.ts +24 -0
- package/dist/utils/captureScript.d.ts.map +1 -0
- package/dist/utils/captureScript.js +83 -0
- package/dist/utils/captureScript.js.map +1 -0
- package/dist/utils/chunkCache.d.ts.map +1 -1
- package/dist/utils/chunkCache.js +19 -5
- package/dist/utils/chunkCache.js.map +1 -1
- package/dist/utils/commandExecutor.d.ts +7 -1
- package/dist/utils/commandExecutor.d.ts.map +1 -1
- package/dist/utils/commandExecutor.js +162 -22
- package/dist/utils/commandExecutor.js.map +1 -1
- package/dist/utils/fileReferences.d.ts +45 -0
- package/dist/utils/fileReferences.d.ts.map +1 -0
- package/dist/utils/fileReferences.js +169 -0
- package/dist/utils/fileReferences.js.map +1 -0
- package/dist/utils/gitCheckout.d.ts +14 -0
- package/dist/utils/gitCheckout.d.ts.map +1 -0
- package/dist/utils/gitCheckout.js +36 -0
- package/dist/utils/gitCheckout.js.map +1 -0
- package/dist/utils/gitStatusGuard.d.ts +35 -0
- package/dist/utils/gitStatusGuard.d.ts.map +1 -0
- package/dist/utils/gitStatusGuard.js +82 -0
- package/dist/utils/gitStatusGuard.js.map +1 -0
- package/dist/utils/layoutCheck.d.ts +58 -0
- package/dist/utils/layoutCheck.d.ts.map +1 -0
- package/dist/utils/layoutCheck.js +84 -0
- package/dist/utils/layoutCheck.js.map +1 -0
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +0 -6
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/progressUpdates.d.ts +14 -0
- package/dist/utils/progressUpdates.d.ts.map +1 -0
- package/dist/utils/progressUpdates.js +40 -0
- package/dist/utils/progressUpdates.js.map +1 -0
- package/dist/utils/responseCache.d.ts +3 -3
- package/dist/utils/responseCache.d.ts.map +1 -1
- package/dist/utils/responseCache.js +11 -6
- package/dist/utils/responseCache.js.map +1 -1
- package/package.json +19 -16
- package/dist/__tests__/utils/geminiExecutor.test.d.ts +0 -2
- package/dist/__tests__/utils/geminiExecutor.test.d.ts.map +0 -1
- package/dist/__tests__/utils/geminiExecutor.test.js +0 -337
- package/dist/__tests__/utils/geminiExecutor.test.js.map +0 -1
- package/dist/utils/geminiExecutor.d.ts +0 -17
- package/dist/utils/geminiExecutor.d.ts.map +0 -1
- package/dist/utils/geminiExecutor.js +0 -238
- 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":"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"}
|
|
@@ -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"}
|