@console-agent/agent 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +345 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -2
- package/dist/index.d.ts +39 -2
- package/dist/index.js +345 -25
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var google = require('@ai-sdk/google');
|
|
4
4
|
var ai = require('ai');
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var path = require('path');
|
|
5
7
|
var chalk = require('chalk');
|
|
6
8
|
var ora = require('ora');
|
|
7
9
|
|
|
@@ -10,6 +12,13 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
12
|
var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
11
13
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
12
14
|
|
|
15
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
16
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
+
}) : x)(function(x) {
|
|
18
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
+
});
|
|
21
|
+
|
|
13
22
|
// src/personas/debugger.ts
|
|
14
23
|
var debuggerPersona = {
|
|
15
24
|
name: "debugger",
|
|
@@ -210,6 +219,168 @@ function detectPersona(prompt, defaultPersona) {
|
|
|
210
219
|
function getPersona(name) {
|
|
211
220
|
return personas[name];
|
|
212
221
|
}
|
|
222
|
+
|
|
223
|
+
// src/tools/file-analysis.ts
|
|
224
|
+
function prepareFileContent(fileData, mimeType) {
|
|
225
|
+
const base64 = Buffer.from(fileData).toString("base64");
|
|
226
|
+
return {
|
|
227
|
+
type: "file",
|
|
228
|
+
data: base64,
|
|
229
|
+
mimeType
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// src/tools/index.ts
|
|
234
|
+
var TOOLS_MIN_TIMEOUT = 3e4;
|
|
235
|
+
function resolveTools(tools, google) {
|
|
236
|
+
const resolved = {};
|
|
237
|
+
for (const tool of tools) {
|
|
238
|
+
const name = typeof tool === "string" ? tool : tool.type;
|
|
239
|
+
const config2 = typeof tool === "object" ? tool.config : void 0;
|
|
240
|
+
switch (name) {
|
|
241
|
+
case "google_search":
|
|
242
|
+
resolved["google_search"] = google.tools.googleSearch(config2 ?? {});
|
|
243
|
+
break;
|
|
244
|
+
case "code_execution":
|
|
245
|
+
resolved["code_execution"] = google.tools.codeExecution(config2 ?? {});
|
|
246
|
+
break;
|
|
247
|
+
case "url_context":
|
|
248
|
+
resolved["url_context"] = google.tools.urlContext({});
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return resolved;
|
|
253
|
+
}
|
|
254
|
+
function hasExplicitTools(options) {
|
|
255
|
+
return !!(options?.tools && options.tools.length > 0);
|
|
256
|
+
}
|
|
257
|
+
var MAX_FILE_SIZE = 100 * 1024;
|
|
258
|
+
var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
259
|
+
".ts",
|
|
260
|
+
".tsx",
|
|
261
|
+
".js",
|
|
262
|
+
".jsx",
|
|
263
|
+
".mjs",
|
|
264
|
+
".cjs",
|
|
265
|
+
".py",
|
|
266
|
+
".rb",
|
|
267
|
+
".go",
|
|
268
|
+
".rs",
|
|
269
|
+
".java",
|
|
270
|
+
".kt",
|
|
271
|
+
".c",
|
|
272
|
+
".cpp",
|
|
273
|
+
".h",
|
|
274
|
+
".hpp",
|
|
275
|
+
".cs",
|
|
276
|
+
".swift",
|
|
277
|
+
".vue",
|
|
278
|
+
".svelte",
|
|
279
|
+
".astro",
|
|
280
|
+
".json",
|
|
281
|
+
".yaml",
|
|
282
|
+
".yml",
|
|
283
|
+
".toml",
|
|
284
|
+
".env",
|
|
285
|
+
".sql",
|
|
286
|
+
".graphql",
|
|
287
|
+
".gql",
|
|
288
|
+
".md",
|
|
289
|
+
".txt",
|
|
290
|
+
".html",
|
|
291
|
+
".css",
|
|
292
|
+
".scss"
|
|
293
|
+
]);
|
|
294
|
+
var INTERNAL_PATTERNS = [
|
|
295
|
+
"/console-agent/",
|
|
296
|
+
"/console_agent/",
|
|
297
|
+
"@console-agent/",
|
|
298
|
+
"/node_modules/",
|
|
299
|
+
"node:internal/",
|
|
300
|
+
"node:async_hooks",
|
|
301
|
+
"<anonymous>"
|
|
302
|
+
];
|
|
303
|
+
function parseStackFrames(stack) {
|
|
304
|
+
const frames = [];
|
|
305
|
+
const lines = stack.split("\n");
|
|
306
|
+
for (const line of lines) {
|
|
307
|
+
const match = line.match(/at\s+(?:.*?\s+)?\(?([^()]+):(\d+):(\d+)\)?/);
|
|
308
|
+
if (match) {
|
|
309
|
+
frames.push({
|
|
310
|
+
file: match[1],
|
|
311
|
+
line: parseInt(match[2], 10),
|
|
312
|
+
column: parseInt(match[3], 10)
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return frames;
|
|
317
|
+
}
|
|
318
|
+
function isInternalFrame(filePath) {
|
|
319
|
+
return INTERNAL_PATTERNS.some((pattern) => filePath.includes(pattern));
|
|
320
|
+
}
|
|
321
|
+
function isSourceFile(filePath) {
|
|
322
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
323
|
+
return SOURCE_EXTENSIONS.has(ext);
|
|
324
|
+
}
|
|
325
|
+
function getCallerFile(skipFrames = 0) {
|
|
326
|
+
const err = new Error();
|
|
327
|
+
if (!err.stack) return null;
|
|
328
|
+
const frames = parseStackFrames(err.stack);
|
|
329
|
+
for (const frame of frames) {
|
|
330
|
+
if (isInternalFrame(frame.file)) continue;
|
|
331
|
+
if (!isSourceFile(frame.file)) continue;
|
|
332
|
+
return readSourceFile(frame.file, frame.line, frame.column);
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
336
|
+
function getErrorSourceFile(error) {
|
|
337
|
+
if (!error.stack) return null;
|
|
338
|
+
const frames = parseStackFrames(error.stack);
|
|
339
|
+
for (const frame of frames) {
|
|
340
|
+
if (frame.file.includes("node:internal/") || frame.file.includes("<anonymous>")) continue;
|
|
341
|
+
if (!isSourceFile(frame.file)) continue;
|
|
342
|
+
return readSourceFile(frame.file, frame.line, frame.column);
|
|
343
|
+
}
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
function readSourceFile(filePath, line, column) {
|
|
347
|
+
try {
|
|
348
|
+
const resolvedPath = path.resolve(filePath);
|
|
349
|
+
if (!fs.existsSync(resolvedPath)) return null;
|
|
350
|
+
const { statSync } = __require("fs");
|
|
351
|
+
const stats = statSync(resolvedPath);
|
|
352
|
+
if (stats.size > MAX_FILE_SIZE) {
|
|
353
|
+
const content2 = fs.readFileSync(resolvedPath, "utf-8").substring(0, MAX_FILE_SIZE);
|
|
354
|
+
return {
|
|
355
|
+
filePath: resolvedPath,
|
|
356
|
+
fileName: path.basename(resolvedPath),
|
|
357
|
+
line,
|
|
358
|
+
column,
|
|
359
|
+
content: content2 + "\n\n// [TRUNCATED \u2014 file exceeds 100KB limit]"
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
const content = fs.readFileSync(resolvedPath, "utf-8");
|
|
363
|
+
return {
|
|
364
|
+
filePath: resolvedPath,
|
|
365
|
+
fileName: path.basename(resolvedPath),
|
|
366
|
+
line,
|
|
367
|
+
column,
|
|
368
|
+
content
|
|
369
|
+
};
|
|
370
|
+
} catch {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function formatSourceForContext(source) {
|
|
375
|
+
const lines = source.content.split("\n");
|
|
376
|
+
const numbered = lines.map((line, i) => {
|
|
377
|
+
const lineNum = i + 1;
|
|
378
|
+
const marker = lineNum === source.line ? " \u2192 " : " ";
|
|
379
|
+
return `${marker}${String(lineNum).padStart(4)} | ${line}`;
|
|
380
|
+
});
|
|
381
|
+
return `--- Source File: ${source.fileName} (line ${source.line}) ---
|
|
382
|
+
${numbered.join("\n")}`;
|
|
383
|
+
}
|
|
213
384
|
var currentLogLevel = "info";
|
|
214
385
|
function setLogLevel(level) {
|
|
215
386
|
currentLogLevel = level;
|
|
@@ -218,8 +389,9 @@ function shouldLog(level) {
|
|
|
218
389
|
const levels = ["silent", "errors", "info", "debug"];
|
|
219
390
|
return levels.indexOf(currentLogLevel) >= levels.indexOf(level);
|
|
220
391
|
}
|
|
221
|
-
function startSpinner(persona, prompt) {
|
|
392
|
+
function startSpinner(persona, prompt, verbose = false) {
|
|
222
393
|
if (!shouldLog("info")) return null;
|
|
394
|
+
if (!verbose) return null;
|
|
223
395
|
const truncated = prompt.length > 60 ? prompt.substring(0, 57) + "..." : prompt;
|
|
224
396
|
const spinner = ora__default.default({
|
|
225
397
|
text: chalk__default.default.cyan(`${persona.icon} ${persona.label}... `) + chalk__default.default.dim(truncated),
|
|
@@ -235,8 +407,29 @@ function stopSpinner(spinner, success) {
|
|
|
235
407
|
spinner.fail();
|
|
236
408
|
}
|
|
237
409
|
}
|
|
238
|
-
function formatResult(result, persona) {
|
|
410
|
+
function formatResult(result, persona, verbose = false) {
|
|
239
411
|
if (!shouldLog("info")) return;
|
|
412
|
+
if (!verbose) {
|
|
413
|
+
formatResultQuiet(result);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
formatResultVerbose(result, persona);
|
|
417
|
+
}
|
|
418
|
+
function formatResultQuiet(result) {
|
|
419
|
+
console.log("");
|
|
420
|
+
console.log(result.summary);
|
|
421
|
+
const dataEntries = Object.entries(result.data);
|
|
422
|
+
const hasMeaningfulData = dataEntries.length > 0 && !(dataEntries.length === 1 && dataEntries[0][0] === "raw");
|
|
423
|
+
if (hasMeaningfulData) {
|
|
424
|
+
for (const [key, value] of dataEntries) {
|
|
425
|
+
if (key === "raw") continue;
|
|
426
|
+
const displayValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
427
|
+
console.log(`${chalk__default.default.dim(key + ":")} ${displayValue}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
console.log("");
|
|
431
|
+
}
|
|
432
|
+
function formatResultVerbose(result, persona) {
|
|
240
433
|
const prefix = chalk__default.default.gray("[AGENT]");
|
|
241
434
|
const confidenceColor = result.confidence >= 0.8 ? chalk__default.default.green : result.confidence >= 0.5 ? chalk__default.default.yellow : chalk__default.default.red;
|
|
242
435
|
const statusIcon = result.success ? chalk__default.default.green("\u2713") : chalk__default.default.red("\u2717");
|
|
@@ -266,12 +459,20 @@ function formatResult(result, persona) {
|
|
|
266
459
|
const confidence = confidenceColor(`confidence: ${result.confidence.toFixed(2)}`);
|
|
267
460
|
const latency = chalk__default.default.dim(`${result.metadata.latencyMs}ms`);
|
|
268
461
|
const tokens = chalk__default.default.dim(`${result.metadata.tokensUsed} tokens`);
|
|
462
|
+
const model = chalk__default.default.dim(`model: ${result.metadata.model}`);
|
|
269
463
|
const cached = result.metadata.cached ? chalk__default.default.green(" (cached)") : "";
|
|
270
|
-
|
|
464
|
+
const toolNames = result.metadata.toolCalls.length > 0 ? chalk__default.default.dim(` | tools: ${result.metadata.toolCalls.map((t) => t.name).join(", ")}`) : "";
|
|
465
|
+
console.log(`${prefix} \u2514\u2500 ${confidence} | ${latency} | ${tokens} | ${model}${cached}${toolNames}`);
|
|
271
466
|
console.log("");
|
|
272
467
|
}
|
|
273
|
-
function formatError(error, persona) {
|
|
468
|
+
function formatError(error, persona, verbose = false) {
|
|
274
469
|
if (!shouldLog("errors")) return;
|
|
470
|
+
if (!verbose) {
|
|
471
|
+
console.log("");
|
|
472
|
+
console.log(chalk__default.default.red(`Error: ${error.message}`));
|
|
473
|
+
console.log("");
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
275
476
|
const prefix = chalk__default.default.gray("[AGENT]");
|
|
276
477
|
console.log("");
|
|
277
478
|
console.log(`${prefix} ${persona.icon} ${chalk__default.default.red("Error:")} ${error.message}`);
|
|
@@ -280,18 +481,32 @@ function formatError(error, persona) {
|
|
|
280
481
|
}
|
|
281
482
|
console.log("");
|
|
282
483
|
}
|
|
283
|
-
function formatBudgetWarning(reason) {
|
|
484
|
+
function formatBudgetWarning(reason, verbose = false) {
|
|
284
485
|
if (!shouldLog("errors")) return;
|
|
486
|
+
if (!verbose) {
|
|
487
|
+
console.log(chalk__default.default.yellow(`Budget limit: ${reason}`));
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
285
490
|
const prefix = chalk__default.default.gray("[AGENT]");
|
|
286
491
|
console.log(`${prefix} ${chalk__default.default.yellow("\u26A0 Budget limit:")} ${reason}`);
|
|
287
492
|
}
|
|
288
|
-
function formatRateLimitWarning() {
|
|
493
|
+
function formatRateLimitWarning(verbose = false) {
|
|
289
494
|
if (!shouldLog("errors")) return;
|
|
495
|
+
if (!verbose) {
|
|
496
|
+
console.log(chalk__default.default.yellow("Rate limited: Too many calls. Try again later."));
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
290
499
|
const prefix = chalk__default.default.gray("[AGENT]");
|
|
291
500
|
console.log(`${prefix} ${chalk__default.default.yellow("\u26A0 Rate limited:")} Too many calls. Try again later.`);
|
|
292
501
|
}
|
|
293
|
-
function formatDryRun(prompt, persona, context) {
|
|
502
|
+
function formatDryRun(prompt, persona, context, verbose = false) {
|
|
294
503
|
if (!shouldLog("info")) return;
|
|
504
|
+
if (!verbose) {
|
|
505
|
+
console.log("");
|
|
506
|
+
console.log(chalk__default.default.magenta("[DRY RUN]") + ` Would execute with ${persona.name} persona`);
|
|
507
|
+
console.log("");
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
295
510
|
const prefix = chalk__default.default.gray("[AGENT]");
|
|
296
511
|
console.log("");
|
|
297
512
|
console.log(`${prefix} ${chalk__default.default.magenta("DRY RUN")} ${persona.icon} ${persona.label}`);
|
|
@@ -334,7 +549,37 @@ var agentOutputSchema = ai.jsonSchema({
|
|
|
334
549
|
required: ["success", "summary", "data", "actions", "confidence"],
|
|
335
550
|
additionalProperties: false
|
|
336
551
|
});
|
|
337
|
-
|
|
552
|
+
var JSON_RESPONSE_INSTRUCTION = `
|
|
553
|
+
|
|
554
|
+
IMPORTANT: You MUST respond with ONLY a valid JSON object (no markdown, no code fences, no extra text).
|
|
555
|
+
Use this exact format:
|
|
556
|
+
{"success": true, "summary": "one-line conclusion", "reasoning": "your thought process", "data": {"result": "primary finding"}, "actions": ["tools/steps used"], "confidence": 0.95}`;
|
|
557
|
+
function buildMessages(prompt, context, sourceFile, files) {
|
|
558
|
+
const parts = [];
|
|
559
|
+
parts.push({ type: "text", text: prompt });
|
|
560
|
+
if (context) {
|
|
561
|
+
parts.push({ type: "text", text: `
|
|
562
|
+
--- Context ---
|
|
563
|
+
${context}` });
|
|
564
|
+
}
|
|
565
|
+
if (sourceFile) {
|
|
566
|
+
const formatted = formatSourceForContext(sourceFile);
|
|
567
|
+
parts.push({ type: "text", text: `
|
|
568
|
+
${formatted}` });
|
|
569
|
+
}
|
|
570
|
+
if (files && files.length > 0) {
|
|
571
|
+
for (const file of files) {
|
|
572
|
+
const prepared = prepareFileContent(file.data, file.mediaType);
|
|
573
|
+
if (file.fileName) {
|
|
574
|
+
parts.push({ type: "text", text: `
|
|
575
|
+
--- Attached File: ${file.fileName} ---` });
|
|
576
|
+
}
|
|
577
|
+
parts.push(prepared);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
return [{ role: "user", content: parts }];
|
|
581
|
+
}
|
|
582
|
+
async function callGoogle(prompt, context, persona, config2, options, sourceFile, files) {
|
|
338
583
|
const startTime = Date.now();
|
|
339
584
|
const modelName = options?.model ?? config2.model;
|
|
340
585
|
logDebug(`Using model: ${modelName}`);
|
|
@@ -355,14 +600,69 @@ async function callGoogle(prompt, context, persona, config2, options) {
|
|
|
355
600
|
if (Object.keys(googleOpts).length > 0) {
|
|
356
601
|
providerOptions["google"] = googleOpts;
|
|
357
602
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
logDebug(
|
|
603
|
+
const useTools = hasExplicitTools(options) && !config2.localOnly;
|
|
604
|
+
if (useTools) {
|
|
605
|
+
logDebug("Tools requested \u2014 using generateText path (no structured output)");
|
|
606
|
+
return callWithTools(prompt, context, persona, config2, options, google$1, modelName, startTime, providerOptions, sourceFile, files);
|
|
361
607
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
608
|
+
logDebug("No tools \u2014 using ToolLoopAgent with structured output");
|
|
609
|
+
return callWithStructuredOutput(prompt, context, persona, config2, options, google$1, modelName, startTime, providerOptions, sourceFile, files);
|
|
610
|
+
}
|
|
611
|
+
async function callWithTools(prompt, context, persona, config2, options, google, modelName, startTime, providerOptions, sourceFile, files) {
|
|
612
|
+
const resolvedTools = resolveTools(options.tools, google);
|
|
613
|
+
const toolNames = Object.keys(resolvedTools);
|
|
614
|
+
logDebug(`Tools enabled: ${toolNames.join(", ")}`);
|
|
615
|
+
const effectiveTimeout = Math.max(config2.timeout, TOOLS_MIN_TIMEOUT);
|
|
616
|
+
const messages = buildMessages(prompt, context, sourceFile, files);
|
|
617
|
+
const result = await ai.generateText({
|
|
618
|
+
model: google(modelName),
|
|
619
|
+
system: persona.systemPrompt + JSON_RESPONSE_INSTRUCTION,
|
|
620
|
+
messages,
|
|
621
|
+
tools: resolvedTools,
|
|
622
|
+
stopWhen: ai.stepCountIs(5),
|
|
623
|
+
// Allow multi-step: tool invocation → response
|
|
624
|
+
maxOutputTokens: config2.budget.maxTokensPerCall,
|
|
625
|
+
providerOptions: Object.keys(providerOptions).length > 0 ? providerOptions : void 0,
|
|
626
|
+
abortSignal: AbortSignal.timeout(effectiveTimeout)
|
|
627
|
+
});
|
|
628
|
+
const latencyMs = Date.now() - startTime;
|
|
629
|
+
const tokensUsed = result.usage?.totalTokens ?? 0;
|
|
630
|
+
logDebug(`Response received (tools path): ${latencyMs}ms, ${tokensUsed} tokens`);
|
|
631
|
+
const collectedToolCalls = [];
|
|
632
|
+
if (result.steps) {
|
|
633
|
+
for (const step of result.steps) {
|
|
634
|
+
if (step.toolCalls) {
|
|
635
|
+
for (const tc of step.toolCalls) {
|
|
636
|
+
collectedToolCalls.push({
|
|
637
|
+
name: tc.toolName,
|
|
638
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
639
|
+
args: tc.args ?? {},
|
|
640
|
+
result: tc.toolName
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
logDebug(`Tool calls collected: ${collectedToolCalls.length}`);
|
|
647
|
+
const parsed = parseResponse(result.text);
|
|
648
|
+
return {
|
|
649
|
+
success: parsed?.success ?? true,
|
|
650
|
+
summary: parsed?.summary ?? result.text.substring(0, 200),
|
|
651
|
+
reasoning: parsed?.reasoning,
|
|
652
|
+
data: parsed?.data ?? { raw: result.text },
|
|
653
|
+
actions: parsed?.actions ?? collectedToolCalls.map((tc) => tc.name),
|
|
654
|
+
confidence: parsed?.confidence ?? 0.5,
|
|
655
|
+
metadata: {
|
|
656
|
+
model: modelName,
|
|
657
|
+
tokensUsed,
|
|
658
|
+
latencyMs,
|
|
659
|
+
toolCalls: collectedToolCalls,
|
|
660
|
+
cached: false
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
async function callWithStructuredOutput(prompt, context, persona, config2, options, google, modelName, startTime, providerOptions, sourceFile, files) {
|
|
665
|
+
const messages = buildMessages(prompt, context, sourceFile, files);
|
|
366
666
|
const collectedToolCalls = [];
|
|
367
667
|
const useCustomSchema = !!(options?.schema || options?.responseFormat);
|
|
368
668
|
let outputConfig;
|
|
@@ -379,7 +679,7 @@ ${context}` : prompt;
|
|
|
379
679
|
outputConfig = ai.Output.object({ schema: agentOutputSchema });
|
|
380
680
|
}
|
|
381
681
|
const agent = new ai.ToolLoopAgent({
|
|
382
|
-
model: google
|
|
682
|
+
model: google(modelName),
|
|
383
683
|
instructions: useCustomSchema ? `${persona.systemPrompt}
|
|
384
684
|
|
|
385
685
|
IMPORTANT: You must respond with structured data matching the requested output schema. Do not include AgentResult wrapper fields \u2014 just return the data matching the schema.` : persona.systemPrompt,
|
|
@@ -401,7 +701,7 @@ IMPORTANT: You must respond with structured data matching the requested output s
|
|
|
401
701
|
}
|
|
402
702
|
});
|
|
403
703
|
const result = await agent.generate({
|
|
404
|
-
|
|
704
|
+
messages,
|
|
405
705
|
timeout: config2.timeout
|
|
406
706
|
});
|
|
407
707
|
const latencyMs = Date.now() - startTime;
|
|
@@ -696,7 +996,9 @@ var DEFAULT_CONFIG = {
|
|
|
696
996
|
localOnly: false,
|
|
697
997
|
dryRun: false,
|
|
698
998
|
logLevel: "info",
|
|
699
|
-
|
|
999
|
+
verbose: false,
|
|
1000
|
+
safetySettings: [],
|
|
1001
|
+
includeCallerSource: true
|
|
700
1002
|
};
|
|
701
1003
|
var config = { ...DEFAULT_CONFIG };
|
|
702
1004
|
var rateLimiter = new RateLimiter(config.budget.maxCallsPerDay);
|
|
@@ -715,18 +1017,19 @@ function getConfig() {
|
|
|
715
1017
|
async function executeAgent(prompt, context, options) {
|
|
716
1018
|
const personaName = options?.persona ?? config.persona;
|
|
717
1019
|
const persona = options?.persona ? getPersona(options.persona) : detectPersona(prompt, personaName);
|
|
1020
|
+
const verbose = options?.verbose ?? config.verbose;
|
|
718
1021
|
logDebug(`Selected persona: ${persona.name} (${persona.icon})`);
|
|
719
1022
|
if (config.dryRun) {
|
|
720
|
-
formatDryRun(prompt, persona, context);
|
|
1023
|
+
formatDryRun(prompt, persona, context, verbose);
|
|
721
1024
|
return createDryRunResult(persona.name);
|
|
722
1025
|
}
|
|
723
1026
|
if (!rateLimiter.tryConsume()) {
|
|
724
|
-
formatRateLimitWarning();
|
|
1027
|
+
formatRateLimitWarning(verbose);
|
|
725
1028
|
return createErrorResult("Rate limited \u2014 too many calls. Try again later.");
|
|
726
1029
|
}
|
|
727
1030
|
const budgetCheck = budgetTracker.canMakeCall();
|
|
728
1031
|
if (!budgetCheck.allowed) {
|
|
729
|
-
formatBudgetWarning(budgetCheck.reason);
|
|
1032
|
+
formatBudgetWarning(budgetCheck.reason, verbose);
|
|
730
1033
|
return createErrorResult(budgetCheck.reason);
|
|
731
1034
|
}
|
|
732
1035
|
let contextStr = "";
|
|
@@ -748,10 +1051,27 @@ async function executeAgent(prompt, context, options) {
|
|
|
748
1051
|
}
|
|
749
1052
|
}
|
|
750
1053
|
const processedPrompt = config.anonymize ? anonymizeValue(prompt) : prompt;
|
|
751
|
-
const
|
|
1054
|
+
const shouldIncludeSource = options?.includeCallerSource ?? config.includeCallerSource;
|
|
1055
|
+
let sourceFile = null;
|
|
1056
|
+
if (shouldIncludeSource) {
|
|
1057
|
+
if (context instanceof Error) {
|
|
1058
|
+
sourceFile = getErrorSourceFile(context);
|
|
1059
|
+
if (sourceFile) {
|
|
1060
|
+
logDebug(`Auto-detected error source file: ${sourceFile.fileName} (line ${sourceFile.line})`);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
if (!sourceFile) {
|
|
1064
|
+
sourceFile = getCallerFile();
|
|
1065
|
+
if (sourceFile) {
|
|
1066
|
+
logDebug(`Auto-detected caller file: ${sourceFile.fileName} (line ${sourceFile.line})`);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
const files = options?.files;
|
|
1071
|
+
const spinner = startSpinner(persona, processedPrompt, verbose);
|
|
752
1072
|
try {
|
|
753
1073
|
const result = await Promise.race([
|
|
754
|
-
callGoogle(processedPrompt, contextStr, persona, config, options),
|
|
1074
|
+
callGoogle(processedPrompt, contextStr, persona, config, options, sourceFile, files),
|
|
755
1075
|
createTimeout(config.timeout)
|
|
756
1076
|
]);
|
|
757
1077
|
budgetTracker.recordUsage(
|
|
@@ -759,12 +1079,12 @@ async function executeAgent(prompt, context, options) {
|
|
|
759
1079
|
estimateCost(result.metadata.tokensUsed, result.metadata.model)
|
|
760
1080
|
);
|
|
761
1081
|
stopSpinner(spinner, result.success);
|
|
762
|
-
formatResult(result, persona);
|
|
1082
|
+
formatResult(result, persona, verbose);
|
|
763
1083
|
return result;
|
|
764
1084
|
} catch (error) {
|
|
765
1085
|
stopSpinner(spinner, false);
|
|
766
1086
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
767
|
-
formatError(err, persona);
|
|
1087
|
+
formatError(err, persona, verbose);
|
|
768
1088
|
return createErrorResult(err.message);
|
|
769
1089
|
}
|
|
770
1090
|
}
|