@google/gemini-cli-a2a-server 0.15.0-preview.0 → 0.16.0-nightly.20251112.c961f274
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/a2a-server.mjs +279 -175
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/a2a-server.mjs
CHANGED
|
@@ -293122,16 +293122,14 @@ var CodeAssistServer = class {
|
|
|
293122
293122
|
});
|
|
293123
293123
|
let bufferedLines = [];
|
|
293124
293124
|
for await (const line of rl) {
|
|
293125
|
-
if (line
|
|
293125
|
+
if (line.startsWith("data: ")) {
|
|
293126
|
+
bufferedLines.push(line.slice(6).trim());
|
|
293127
|
+
} else if (line === "") {
|
|
293126
293128
|
if (bufferedLines.length === 0) {
|
|
293127
293129
|
continue;
|
|
293128
293130
|
}
|
|
293129
293131
|
yield JSON.parse(bufferedLines.join("\n"));
|
|
293130
293132
|
bufferedLines = [];
|
|
293131
|
-
} else if (line.startsWith("data: ")) {
|
|
293132
|
-
bufferedLines.push(line.slice(6).trim());
|
|
293133
|
-
} else {
|
|
293134
|
-
throw new Error(`Unexpected line format in response: ${line}`);
|
|
293135
293133
|
}
|
|
293136
293134
|
}
|
|
293137
293135
|
}();
|
|
@@ -293643,7 +293641,7 @@ function hasCycleInSchema(schema) {
|
|
|
293643
293641
|
}
|
|
293644
293642
|
if ("$ref" in node && typeof node.$ref === "string") {
|
|
293645
293643
|
const ref = node.$ref;
|
|
293646
|
-
if (ref === "#/" || pathRefs.has(ref)) {
|
|
293644
|
+
if (ref === "#" || ref === "#/" || pathRefs.has(ref)) {
|
|
293647
293645
|
return true;
|
|
293648
293646
|
}
|
|
293649
293647
|
if (visitedRefs.has(ref)) {
|
|
@@ -295263,23 +295261,29 @@ var LoopDetectedEvent = class {
|
|
|
295263
295261
|
"event.timestamp";
|
|
295264
295262
|
loop_type;
|
|
295265
295263
|
prompt_id;
|
|
295266
|
-
|
|
295264
|
+
confirmed_by_model;
|
|
295265
|
+
constructor(loop_type, prompt_id, confirmed_by_model) {
|
|
295267
295266
|
this["event.name"] = "loop_detected";
|
|
295268
295267
|
this["event.timestamp"] = (/* @__PURE__ */ new Date()).toISOString();
|
|
295269
295268
|
this.loop_type = loop_type;
|
|
295270
295269
|
this.prompt_id = prompt_id;
|
|
295270
|
+
this.confirmed_by_model = confirmed_by_model;
|
|
295271
295271
|
}
|
|
295272
295272
|
toOpenTelemetryAttributes(config2) {
|
|
295273
|
-
|
|
295273
|
+
const attributes = {
|
|
295274
295274
|
...getCommonAttributes(config2),
|
|
295275
295275
|
"event.name": this["event.name"],
|
|
295276
295276
|
"event.timestamp": this["event.timestamp"],
|
|
295277
295277
|
loop_type: this.loop_type,
|
|
295278
295278
|
prompt_id: this.prompt_id
|
|
295279
295279
|
};
|
|
295280
|
+
if (this.confirmed_by_model) {
|
|
295281
|
+
attributes["confirmed_by_model"] = this.confirmed_by_model;
|
|
295282
|
+
}
|
|
295283
|
+
return attributes;
|
|
295280
295284
|
}
|
|
295281
295285
|
toLogBody() {
|
|
295282
|
-
return `Loop detected. Type: ${this.loop_type}
|
|
295286
|
+
return `Loop detected. Type: ${this.loop_type}.${this.confirmed_by_model ? ` Confirmed by: ${this.confirmed_by_model}` : ""}`;
|
|
295283
295287
|
}
|
|
295284
295288
|
};
|
|
295285
295289
|
var LoopDetectionDisabledEvent = class {
|
|
@@ -295569,6 +295573,37 @@ var ToolOutputTruncatedEvent = class {
|
|
|
295569
295573
|
return `Tool output truncated for ${this.tool_name}.`;
|
|
295570
295574
|
}
|
|
295571
295575
|
};
|
|
295576
|
+
var EVENT_LLM_LOOP_CHECK = "gemini_cli.llm_loop_check";
|
|
295577
|
+
var LlmLoopCheckEvent = class {
|
|
295578
|
+
"event.name";
|
|
295579
|
+
"event.timestamp";
|
|
295580
|
+
prompt_id;
|
|
295581
|
+
flash_confidence;
|
|
295582
|
+
main_model;
|
|
295583
|
+
main_model_confidence;
|
|
295584
|
+
constructor(prompt_id, flash_confidence, main_model, main_model_confidence) {
|
|
295585
|
+
this["event.name"] = "llm_loop_check";
|
|
295586
|
+
this["event.timestamp"] = (/* @__PURE__ */ new Date()).toISOString();
|
|
295587
|
+
this.prompt_id = prompt_id;
|
|
295588
|
+
this.flash_confidence = flash_confidence;
|
|
295589
|
+
this.main_model = main_model;
|
|
295590
|
+
this.main_model_confidence = main_model_confidence;
|
|
295591
|
+
}
|
|
295592
|
+
toOpenTelemetryAttributes(config2) {
|
|
295593
|
+
return {
|
|
295594
|
+
...getCommonAttributes(config2),
|
|
295595
|
+
"event.name": EVENT_LLM_LOOP_CHECK,
|
|
295596
|
+
"event.timestamp": this["event.timestamp"],
|
|
295597
|
+
prompt_id: this.prompt_id,
|
|
295598
|
+
flash_confidence: this.flash_confidence,
|
|
295599
|
+
main_model: this.main_model,
|
|
295600
|
+
main_model_confidence: this.main_model_confidence
|
|
295601
|
+
};
|
|
295602
|
+
}
|
|
295603
|
+
toLogBody() {
|
|
295604
|
+
return this.main_model_confidence === -1 ? `LLM loop check. Flash confidence: ${this.flash_confidence.toFixed(2)}. Main model (${this.main_model}) check skipped` : `LLM loop check. Flash confidence: ${this.flash_confidence.toFixed(2)}. Main model (${this.main_model}) confidence: ${this.main_model_confidence.toFixed(2)}`;
|
|
295605
|
+
}
|
|
295606
|
+
};
|
|
295572
295607
|
var EVENT_SMART_EDIT_STRATEGY = "gemini_cli.smart_edit_strategy";
|
|
295573
295608
|
var SmartEditStrategyEvent = class {
|
|
295574
295609
|
"event.name";
|
|
@@ -295874,6 +295909,10 @@ var EventMetadataKey;
|
|
|
295874
295909
|
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_AGENT_RECOVERY_DURATION_MS"] = 123] = "GEMINI_CLI_AGENT_RECOVERY_DURATION_MS";
|
|
295875
295910
|
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_AGENT_RECOVERY_SUCCESS"] = 124] = "GEMINI_CLI_AGENT_RECOVERY_SUCCESS";
|
|
295876
295911
|
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_INTERACTIVE"] = 125] = "GEMINI_CLI_INTERACTIVE";
|
|
295912
|
+
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_LLM_LOOP_CHECK_FLASH_CONFIDENCE"] = 126] = "GEMINI_CLI_LLM_LOOP_CHECK_FLASH_CONFIDENCE";
|
|
295913
|
+
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL"] = 127] = "GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL";
|
|
295914
|
+
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL_CONFIDENCE"] = 128] = "GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL_CONFIDENCE";
|
|
295915
|
+
EventMetadataKey2[EventMetadataKey2["GEMINI_CLI_LOOP_DETECTED_CONFIRMED_BY_MODEL"] = 129] = "GEMINI_CLI_LOOP_DETECTED_CONFIRMED_BY_MODEL";
|
|
295877
295916
|
})(EventMetadataKey || (EventMetadataKey = {}));
|
|
295878
295917
|
|
|
295879
295918
|
// node_modules/mnemonist/index.mjs
|
|
@@ -295899,8 +295938,8 @@ var Float64Vector = import_vector.default.Float64Vector;
|
|
|
295899
295938
|
var PointerVector = import_vector.default.PointerVector;
|
|
295900
295939
|
|
|
295901
295940
|
// packages/core/dist/src/generated/git-commit.js
|
|
295902
|
-
var GIT_COMMIT_INFO = "
|
|
295903
|
-
var CLI_VERSION = "0.
|
|
295941
|
+
var GIT_COMMIT_INFO = "c961f274";
|
|
295942
|
+
var CLI_VERSION = "0.16.0-nightly.20251112.c961f274";
|
|
295904
295943
|
|
|
295905
295944
|
// packages/core/dist/src/ide/detect-ide.js
|
|
295906
295945
|
var IDE_DEFINITIONS = {
|
|
@@ -296003,6 +296042,7 @@ var EventNames;
|
|
|
296003
296042
|
EventNames2["AGENT_FINISH"] = "agent_finish";
|
|
296004
296043
|
EventNames2["RECOVERY_ATTEMPT"] = "recovery_attempt";
|
|
296005
296044
|
EventNames2["WEB_FETCH_FALLBACK_ATTEMPT"] = "web_fetch_fallback_attempt";
|
|
296045
|
+
EventNames2["LLM_LOOP_CHECK"] = "llm_loop_check";
|
|
296006
296046
|
})(EventNames || (EventNames = {}));
|
|
296007
296047
|
function determineSurface() {
|
|
296008
296048
|
if (process.env["SURFACE"]) {
|
|
@@ -296494,6 +296534,12 @@ var ClearcutLogger = class _ClearcutLogger {
|
|
|
296494
296534
|
value: JSON.stringify(event.loop_type)
|
|
296495
296535
|
}
|
|
296496
296536
|
];
|
|
296537
|
+
if (event.confirmed_by_model) {
|
|
296538
|
+
data.push({
|
|
296539
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_LOOP_DETECTED_CONFIRMED_BY_MODEL,
|
|
296540
|
+
value: event.confirmed_by_model
|
|
296541
|
+
});
|
|
296542
|
+
}
|
|
296497
296543
|
this.enqueueLogEvent(this.createLogEvent(EventNames.LOOP_DETECTED, data));
|
|
296498
296544
|
this.flushIfNeeded();
|
|
296499
296545
|
}
|
|
@@ -296929,6 +296975,28 @@ var ClearcutLogger = class _ClearcutLogger {
|
|
|
296929
296975
|
this.enqueueLogEvent(this.createLogEvent(EventNames.WEB_FETCH_FALLBACK_ATTEMPT, data));
|
|
296930
296976
|
this.flushIfNeeded();
|
|
296931
296977
|
}
|
|
296978
|
+
logLlmLoopCheckEvent(event) {
|
|
296979
|
+
const data = [
|
|
296980
|
+
{
|
|
296981
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
|
|
296982
|
+
value: event.prompt_id
|
|
296983
|
+
},
|
|
296984
|
+
{
|
|
296985
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_LLM_LOOP_CHECK_FLASH_CONFIDENCE,
|
|
296986
|
+
value: event.flash_confidence.toString()
|
|
296987
|
+
},
|
|
296988
|
+
{
|
|
296989
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL,
|
|
296990
|
+
value: event.main_model
|
|
296991
|
+
},
|
|
296992
|
+
{
|
|
296993
|
+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_LLM_LOOP_CHECK_MAIN_MODEL_CONFIDENCE,
|
|
296994
|
+
value: event.main_model_confidence.toString()
|
|
296995
|
+
}
|
|
296996
|
+
];
|
|
296997
|
+
this.enqueueLogEvent(this.createLogEvent(EventNames.LLM_LOOP_CHECK, data));
|
|
296998
|
+
this.flushIfNeeded();
|
|
296999
|
+
}
|
|
296932
297000
|
/**
|
|
296933
297001
|
* Adds default fields to data, and returns a new data array. This fields
|
|
296934
297002
|
* should exist on all log events.
|
|
@@ -298363,6 +298431,17 @@ function logWebFetchFallbackAttempt(config2, event) {
|
|
|
298363
298431
|
};
|
|
298364
298432
|
logger6.emit(logRecord);
|
|
298365
298433
|
}
|
|
298434
|
+
function logLlmLoopCheck(config2, event) {
|
|
298435
|
+
ClearcutLogger.getInstance(config2)?.logLlmLoopCheckEvent(event);
|
|
298436
|
+
if (!isTelemetrySdkInitialized())
|
|
298437
|
+
return;
|
|
298438
|
+
const logger6 = import_api_logs.logs.getLogger(SERVICE_NAME);
|
|
298439
|
+
const logRecord = {
|
|
298440
|
+
body: event.toLogBody(),
|
|
298441
|
+
attributes: event.toOpenTelemetryAttributes(config2)
|
|
298442
|
+
};
|
|
298443
|
+
logger6.emit(logRecord);
|
|
298444
|
+
}
|
|
298366
298445
|
|
|
298367
298446
|
// packages/core/dist/src/utils/quotaErrorDetection.js
|
|
298368
298447
|
function isApiError(error) {
|
|
@@ -298705,7 +298784,7 @@ async function createContentGenerator(config2, gcConfig, sessionId2) {
|
|
|
298705
298784
|
if (gcConfig.fakeResponses) {
|
|
298706
298785
|
return FakeContentGenerator.fromFile(gcConfig.fakeResponses);
|
|
298707
298786
|
}
|
|
298708
|
-
const version3 = "0.
|
|
298787
|
+
const version3 = "0.16.0-nightly.20251112.c961f274";
|
|
298709
298788
|
const userAgent = `GeminiCLI/${version3} (${process.platform}; ${process.arch})`;
|
|
298710
298789
|
const baseHeaders = {
|
|
298711
298790
|
"User-Agent": userAgent
|
|
@@ -300911,7 +300990,7 @@ var MemoryToolInvocation = class _MemoryToolInvocation extends BaseToolInvocatio
|
|
|
300911
300990
|
var MemoryTool = class _MemoryTool extends BaseDeclarativeTool {
|
|
300912
300991
|
static Name = MEMORY_TOOL_NAME;
|
|
300913
300992
|
constructor(messageBus) {
|
|
300914
|
-
super(_MemoryTool.Name, "
|
|
300993
|
+
super(_MemoryTool.Name, "SaveMemory", memoryToolDescription, Kind.Think, memoryToolSchemaData.parametersJsonSchema, true, false, messageBus);
|
|
300915
300994
|
}
|
|
300916
300995
|
validateToolParamValues(params) {
|
|
300917
300996
|
if (params.fact.trim() === "") {
|
|
@@ -320614,83 +320693,61 @@ async function ensureRgPath() {
|
|
|
320614
320693
|
}
|
|
320615
320694
|
throw new Error("Cannot use ripgrep.");
|
|
320616
320695
|
}
|
|
320696
|
+
function resolveAndValidatePath(config2, relativePath) {
|
|
320697
|
+
if (!relativePath) {
|
|
320698
|
+
return null;
|
|
320699
|
+
}
|
|
320700
|
+
const targetDir = config2.getTargetDir();
|
|
320701
|
+
const targetPath = path33.resolve(targetDir, relativePath);
|
|
320702
|
+
const workspaceContext = config2.getWorkspaceContext();
|
|
320703
|
+
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
320704
|
+
const directories = workspaceContext.getDirectories();
|
|
320705
|
+
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
320706
|
+
}
|
|
320707
|
+
try {
|
|
320708
|
+
const stats = fs31.statSync(targetPath);
|
|
320709
|
+
if (!stats.isDirectory() && !stats.isFile()) {
|
|
320710
|
+
throw new Error(`Path is not a valid directory or file: ${targetPath} (CWD: ${targetDir})`);
|
|
320711
|
+
}
|
|
320712
|
+
} catch (error) {
|
|
320713
|
+
if (isNodeError(error) && error.code === "ENOENT") {
|
|
320714
|
+
throw new Error(`Path does not exist: ${targetPath} (CWD: ${targetDir})`);
|
|
320715
|
+
}
|
|
320716
|
+
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
320717
|
+
}
|
|
320718
|
+
return targetPath;
|
|
320719
|
+
}
|
|
320617
320720
|
var GrepToolInvocation2 = class extends BaseToolInvocation {
|
|
320618
320721
|
config;
|
|
320619
320722
|
constructor(config2, params, messageBus, _toolName, _toolDisplayName) {
|
|
320620
320723
|
super(params, messageBus, _toolName, _toolDisplayName);
|
|
320621
320724
|
this.config = config2;
|
|
320622
320725
|
}
|
|
320623
|
-
/**
|
|
320624
|
-
* Checks if a path is within the root directory and resolves it.
|
|
320625
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
320626
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
320627
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
320628
|
-
*/
|
|
320629
|
-
resolveAndValidatePath(relativePath) {
|
|
320630
|
-
if (!relativePath) {
|
|
320631
|
-
return null;
|
|
320632
|
-
}
|
|
320633
|
-
const targetPath = path33.resolve(this.config.getTargetDir(), relativePath);
|
|
320634
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
320635
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
320636
|
-
const directories = workspaceContext.getDirectories();
|
|
320637
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
320638
|
-
}
|
|
320639
|
-
try {
|
|
320640
|
-
const stats = fs31.statSync(targetPath);
|
|
320641
|
-
if (!stats.isDirectory()) {
|
|
320642
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
320643
|
-
}
|
|
320644
|
-
} catch (error) {
|
|
320645
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
320646
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
320647
|
-
}
|
|
320648
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
320649
|
-
}
|
|
320650
|
-
return targetPath;
|
|
320651
|
-
}
|
|
320652
320726
|
async execute(signal) {
|
|
320653
320727
|
try {
|
|
320654
|
-
const
|
|
320655
|
-
const searchDirAbs =
|
|
320656
|
-
const searchDirDisplay =
|
|
320657
|
-
let searchDirectories;
|
|
320658
|
-
if (searchDirAbs === null) {
|
|
320659
|
-
searchDirectories = workspaceContext.getDirectories();
|
|
320660
|
-
} else {
|
|
320661
|
-
searchDirectories = [searchDirAbs];
|
|
320662
|
-
}
|
|
320663
|
-
let allMatches = [];
|
|
320728
|
+
const pathParam = this.params.dir_path || ".";
|
|
320729
|
+
const searchDirAbs = resolveAndValidatePath(this.config, pathParam);
|
|
320730
|
+
const searchDirDisplay = pathParam;
|
|
320664
320731
|
const totalMaxMatches = DEFAULT_TOTAL_MAX_MATCHES;
|
|
320665
320732
|
if (this.config.getDebugMode()) {
|
|
320666
320733
|
debugLogger.log(`[GrepTool] Total result limit: ${totalMaxMatches}`);
|
|
320667
320734
|
}
|
|
320668
|
-
|
|
320669
|
-
|
|
320670
|
-
|
|
320671
|
-
|
|
320672
|
-
|
|
320673
|
-
|
|
320674
|
-
|
|
320675
|
-
|
|
320676
|
-
|
|
320677
|
-
|
|
320678
|
-
|
|
320679
|
-
|
|
320680
|
-
|
|
320681
|
-
allMatches = allMatches.
|
|
320682
|
-
if (allMatches.length >= totalMaxMatches) {
|
|
320683
|
-
allMatches = allMatches.slice(0, totalMaxMatches);
|
|
320684
|
-
break;
|
|
320685
|
-
}
|
|
320686
|
-
}
|
|
320687
|
-
let searchLocationDescription;
|
|
320688
|
-
if (searchDirAbs === null) {
|
|
320689
|
-
const numDirs = workspaceContext.getDirectories().length;
|
|
320690
|
-
searchLocationDescription = numDirs > 1 ? `across ${numDirs} workspace directories` : `in the workspace directory`;
|
|
320691
|
-
} else {
|
|
320692
|
-
searchLocationDescription = `in path "${searchDirDisplay}"`;
|
|
320735
|
+
let allMatches = await this.performRipgrepSearch({
|
|
320736
|
+
pattern: this.params.pattern,
|
|
320737
|
+
path: searchDirAbs,
|
|
320738
|
+
include: this.params.include,
|
|
320739
|
+
case_sensitive: this.params.case_sensitive,
|
|
320740
|
+
fixed_strings: this.params.fixed_strings,
|
|
320741
|
+
context: this.params.context,
|
|
320742
|
+
after: this.params.after,
|
|
320743
|
+
before: this.params.before,
|
|
320744
|
+
no_ignore: this.params.no_ignore,
|
|
320745
|
+
signal
|
|
320746
|
+
});
|
|
320747
|
+
if (allMatches.length >= totalMaxMatches) {
|
|
320748
|
+
allMatches = allMatches.slice(0, totalMaxMatches);
|
|
320693
320749
|
}
|
|
320750
|
+
const searchLocationDescription = `in path "${searchDirDisplay}"`;
|
|
320694
320751
|
if (allMatches.length === 0) {
|
|
320695
320752
|
const noMatchMsg = `No matches found for pattern "${this.params.pattern}" ${searchLocationDescription}${this.params.include ? ` (filter: "${this.params.include}")` : ""}.`;
|
|
320696
320753
|
return { llmContent: noMatchMsg, returnDisplay: `No matches found` };
|
|
@@ -320770,24 +320827,43 @@ var GrepToolInvocation2 = class extends BaseToolInvocation {
|
|
|
320770
320827
|
return results;
|
|
320771
320828
|
}
|
|
320772
320829
|
async performRipgrepSearch(options2) {
|
|
320773
|
-
const { pattern, path: absolutePath, include } = options2;
|
|
320774
|
-
const rgArgs = ["--json"
|
|
320830
|
+
const { pattern, path: absolutePath, include, case_sensitive, fixed_strings, context: context2, after, before, no_ignore } = options2;
|
|
320831
|
+
const rgArgs = ["--json"];
|
|
320832
|
+
if (!case_sensitive) {
|
|
320833
|
+
rgArgs.push("--ignore-case");
|
|
320834
|
+
}
|
|
320835
|
+
if (fixed_strings) {
|
|
320836
|
+
rgArgs.push("--fixed-strings");
|
|
320837
|
+
rgArgs.push(pattern);
|
|
320838
|
+
} else {
|
|
320839
|
+
rgArgs.push("--regexp", pattern);
|
|
320840
|
+
}
|
|
320841
|
+
if (context2) {
|
|
320842
|
+
rgArgs.push("--context", context2.toString());
|
|
320843
|
+
}
|
|
320844
|
+
if (after) {
|
|
320845
|
+
rgArgs.push("--after-context", after.toString());
|
|
320846
|
+
}
|
|
320847
|
+
if (before) {
|
|
320848
|
+
rgArgs.push("--before-context", before.toString());
|
|
320849
|
+
}
|
|
320850
|
+
if (no_ignore) {
|
|
320851
|
+
rgArgs.push("--no-ignore");
|
|
320852
|
+
}
|
|
320775
320853
|
if (include) {
|
|
320776
320854
|
rgArgs.push("--glob", include);
|
|
320777
320855
|
}
|
|
320778
|
-
|
|
320779
|
-
|
|
320780
|
-
|
|
320781
|
-
|
|
320782
|
-
|
|
320783
|
-
|
|
320784
|
-
|
|
320785
|
-
|
|
320786
|
-
|
|
320787
|
-
|
|
320788
|
-
|
|
320789
|
-
rgArgs.push("--glob", `!${exclude}`);
|
|
320790
|
-
});
|
|
320856
|
+
if (!no_ignore) {
|
|
320857
|
+
const fileExclusions = new FileExclusions(this.config);
|
|
320858
|
+
const excludes = fileExclusions.getGlobExcludes([
|
|
320859
|
+
...COMMON_DIRECTORY_EXCLUDES,
|
|
320860
|
+
"*.log",
|
|
320861
|
+
"*.tmp"
|
|
320862
|
+
]);
|
|
320863
|
+
excludes.forEach((exclude) => {
|
|
320864
|
+
rgArgs.push("--glob", `!${exclude}`);
|
|
320865
|
+
});
|
|
320866
|
+
}
|
|
320791
320867
|
rgArgs.push("--threads", "4");
|
|
320792
320868
|
rgArgs.push(absolutePath);
|
|
320793
320869
|
try {
|
|
@@ -320839,20 +320915,13 @@ var GrepToolInvocation2 = class extends BaseToolInvocation {
|
|
|
320839
320915
|
if (this.params.include) {
|
|
320840
320916
|
description += ` in ${this.params.include}`;
|
|
320841
320917
|
}
|
|
320842
|
-
|
|
320843
|
-
|
|
320844
|
-
|
|
320845
|
-
|
|
320846
|
-
} else {
|
|
320847
|
-
const relativePath = makeRelative(resolvedPath, this.config.getTargetDir());
|
|
320848
|
-
description += ` within ${shortenPath(relativePath)}`;
|
|
320849
|
-
}
|
|
320918
|
+
const pathParam = this.params.dir_path || ".";
|
|
320919
|
+
const resolvedPath = path33.resolve(this.config.getTargetDir(), pathParam);
|
|
320920
|
+
if (resolvedPath === this.config.getTargetDir() || pathParam === ".") {
|
|
320921
|
+
description += ` within ./`;
|
|
320850
320922
|
} else {
|
|
320851
|
-
const
|
|
320852
|
-
|
|
320853
|
-
if (directories.length > 1) {
|
|
320854
|
-
description += ` across all workspace directories`;
|
|
320855
|
-
}
|
|
320923
|
+
const relativePath = makeRelative(resolvedPath, this.config.getTargetDir());
|
|
320924
|
+
description += ` within ${shortenPath(relativePath)}`;
|
|
320856
320925
|
}
|
|
320857
320926
|
return description;
|
|
320858
320927
|
}
|
|
@@ -320864,21 +320933,45 @@ var RipGrepTool = class _RipGrepTool extends BaseDeclarativeTool {
|
|
|
320864
320933
|
super(
|
|
320865
320934
|
_RipGrepTool.Name,
|
|
320866
320935
|
"SearchText",
|
|
320867
|
-
|
|
320936
|
+
'FAST, optimized search powered by `ripgrep`. PREFERRED over standard `run_shell_command("grep ...")` due to better performance and automatic output limiting (max 20k matches).',
|
|
320868
320937
|
Kind.Search,
|
|
320869
320938
|
{
|
|
320870
320939
|
properties: {
|
|
320871
320940
|
pattern: {
|
|
320872
|
-
description: "The
|
|
320941
|
+
description: "The pattern to search for. By default, treated as a Rust-flavored regular expression. Use '\\b' for precise symbol matching (e.g., '\\bMatchMe\\b').",
|
|
320873
320942
|
type: "string"
|
|
320874
320943
|
},
|
|
320875
320944
|
dir_path: {
|
|
320876
|
-
description: "
|
|
320945
|
+
description: "Directory or file to search. Directories are searched recursively. Relative paths are resolved against current working directory. Defaults to current working directory ('.') if omitted.",
|
|
320877
320946
|
type: "string"
|
|
320878
320947
|
},
|
|
320879
320948
|
include: {
|
|
320880
|
-
description: "
|
|
320949
|
+
description: "Glob pattern to filter files (e.g., '*.ts', 'src/**'). Recommended for large repositories to reduce noise. Defaults to all files if omitted.",
|
|
320881
320950
|
type: "string"
|
|
320951
|
+
},
|
|
320952
|
+
case_sensitive: {
|
|
320953
|
+
description: "If true, search is case-sensitive. Defaults to false (ignore case) if omitted.",
|
|
320954
|
+
type: "boolean"
|
|
320955
|
+
},
|
|
320956
|
+
fixed_strings: {
|
|
320957
|
+
description: "If true, treats the `pattern` as a literal string instead of a regular expression. Defaults to false (basic regex) if omitted.",
|
|
320958
|
+
type: "boolean"
|
|
320959
|
+
},
|
|
320960
|
+
context: {
|
|
320961
|
+
description: "Show this many lines of context around each match (equivalent to grep -C). Defaults to 0 if omitted.",
|
|
320962
|
+
type: "integer"
|
|
320963
|
+
},
|
|
320964
|
+
after: {
|
|
320965
|
+
description: "Show this many lines after each match (equivalent to grep -A). Defaults to 0 if omitted.",
|
|
320966
|
+
type: "integer"
|
|
320967
|
+
},
|
|
320968
|
+
before: {
|
|
320969
|
+
description: "Show this many lines before each match (equivalent to grep -B). Defaults to 0 if omitted.",
|
|
320970
|
+
type: "integer"
|
|
320971
|
+
},
|
|
320972
|
+
no_ignore: {
|
|
320973
|
+
description: "If true, searches all files including those usually ignored (like in .gitignore, build/, dist/, etc). Defaults to false if omitted.",
|
|
320974
|
+
type: "boolean"
|
|
320882
320975
|
}
|
|
320883
320976
|
},
|
|
320884
320977
|
required: ["pattern"],
|
|
@@ -320892,35 +320985,6 @@ var RipGrepTool = class _RipGrepTool extends BaseDeclarativeTool {
|
|
|
320892
320985
|
);
|
|
320893
320986
|
this.config = config2;
|
|
320894
320987
|
}
|
|
320895
|
-
/**
|
|
320896
|
-
* Checks if a path is within the root directory and resolves it.
|
|
320897
|
-
* @param relativePath Path relative to the root directory (or undefined for root).
|
|
320898
|
-
* @returns The absolute path if valid and exists, or null if no path specified (to search all directories).
|
|
320899
|
-
* @throws {Error} If path is outside root, doesn't exist, or isn't a directory.
|
|
320900
|
-
*/
|
|
320901
|
-
resolveAndValidatePath(relativePath) {
|
|
320902
|
-
if (!relativePath) {
|
|
320903
|
-
return null;
|
|
320904
|
-
}
|
|
320905
|
-
const targetPath = path33.resolve(this.config.getTargetDir(), relativePath);
|
|
320906
|
-
const workspaceContext = this.config.getWorkspaceContext();
|
|
320907
|
-
if (!workspaceContext.isPathWithinWorkspace(targetPath)) {
|
|
320908
|
-
const directories = workspaceContext.getDirectories();
|
|
320909
|
-
throw new Error(`Path validation failed: Attempted path "${relativePath}" resolves outside the allowed workspace directories: ${directories.join(", ")}`);
|
|
320910
|
-
}
|
|
320911
|
-
try {
|
|
320912
|
-
const stats = fs31.statSync(targetPath);
|
|
320913
|
-
if (!stats.isDirectory()) {
|
|
320914
|
-
throw new Error(`Path is not a directory: ${targetPath}`);
|
|
320915
|
-
}
|
|
320916
|
-
} catch (error) {
|
|
320917
|
-
if (isNodeError(error) && error.code !== "ENOENT") {
|
|
320918
|
-
throw new Error(`Path does not exist: ${targetPath}`);
|
|
320919
|
-
}
|
|
320920
|
-
throw new Error(`Failed to access path stats for ${targetPath}: ${error}`);
|
|
320921
|
-
}
|
|
320922
|
-
return targetPath;
|
|
320923
|
-
}
|
|
320924
320988
|
/**
|
|
320925
320989
|
* Validates the parameters for the tool
|
|
320926
320990
|
* @param params Parameters to validate
|
|
@@ -320933,7 +320997,7 @@ var RipGrepTool = class _RipGrepTool extends BaseDeclarativeTool {
|
|
|
320933
320997
|
}
|
|
320934
320998
|
if (params.dir_path) {
|
|
320935
320999
|
try {
|
|
320936
|
-
this.
|
|
321000
|
+
resolveAndValidatePath(this.config, params.dir_path);
|
|
320937
321001
|
} catch (error) {
|
|
320938
321002
|
return getErrorMessage(error);
|
|
320939
321003
|
}
|
|
@@ -345309,7 +345373,7 @@ ${todoListString}` : "Successfully cleared the todo list.";
|
|
|
345309
345373
|
var WriteTodosTool = class _WriteTodosTool extends BaseDeclarativeTool {
|
|
345310
345374
|
static Name = WRITE_TODOS_TOOL_NAME;
|
|
345311
345375
|
constructor() {
|
|
345312
|
-
super(_WriteTodosTool.Name, "
|
|
345376
|
+
super(_WriteTodosTool.Name, "WriteTodos", WRITE_TODOS_DESCRIPTION, Kind.Other, {
|
|
345313
345377
|
type: "object",
|
|
345314
345378
|
properties: {
|
|
345315
345379
|
todos: {
|
|
@@ -345777,6 +345841,8 @@ var LLM_CHECK_AFTER_TURNS = 30;
|
|
|
345777
345841
|
var DEFAULT_LLM_CHECK_INTERVAL = 3;
|
|
345778
345842
|
var MIN_LLM_CHECK_INTERVAL = 5;
|
|
345779
345843
|
var MAX_LLM_CHECK_INTERVAL = 15;
|
|
345844
|
+
var LLM_CONFIDENCE_THRESHOLD = 0.9;
|
|
345845
|
+
var DOUBLE_CHECK_MODEL_ALIAS = "loop-detection-double-check";
|
|
345780
345846
|
var LOOP_DETECTION_SYSTEM_PROMPT = `You are a sophisticated AI diagnostic agent specializing in identifying when a conversational AI is stuck in an unproductive state. Your task is to analyze the provided conversation history and determine if the assistant has ceased to make meaningful progress.
|
|
345781
345847
|
|
|
345782
345848
|
An unproductive state is characterized by one or more of the following patterns over the last 5 or more assistant turns:
|
|
@@ -345787,6 +345853,20 @@ Cognitive Loop: The assistant seems unable to determine the next logical step. I
|
|
|
345787
345853
|
|
|
345788
345854
|
Crucially, differentiate between a true unproductive state and legitimate, incremental progress.
|
|
345789
345855
|
For example, a series of 'tool_A' or 'tool_B' tool calls that make small, distinct changes to the same file (like adding docstrings to functions one by one) is considered forward progress and is NOT a loop. A loop would be repeatedly replacing the same text with the same content, or cycling between a small set of files with no net change.`;
|
|
345856
|
+
var LOOP_DETECTION_SCHEMA = {
|
|
345857
|
+
type: "object",
|
|
345858
|
+
properties: {
|
|
345859
|
+
unproductive_state_analysis: {
|
|
345860
|
+
type: "string",
|
|
345861
|
+
description: "Your reasoning on if the conversation is looping without forward progress."
|
|
345862
|
+
},
|
|
345863
|
+
unproductive_state_confidence: {
|
|
345864
|
+
type: "number",
|
|
345865
|
+
description: "A number between 0.0 and 1.0 representing your confidence that the conversation is in an unproductive state."
|
|
345866
|
+
}
|
|
345867
|
+
},
|
|
345868
|
+
required: ["unproductive_state_analysis", "unproductive_state_confidence"]
|
|
345869
|
+
};
|
|
345790
345870
|
var LoopDetectionService = class {
|
|
345791
345871
|
config;
|
|
345792
345872
|
promptId = "";
|
|
@@ -346014,49 +346094,67 @@ var LoopDetectionService = class {
|
|
|
346014
346094
|
parts: [{ text: "Recent conversation history:" }]
|
|
346015
346095
|
});
|
|
346016
346096
|
}
|
|
346017
|
-
const
|
|
346018
|
-
|
|
346019
|
-
|
|
346020
|
-
|
|
346021
|
-
|
|
346022
|
-
|
|
346023
|
-
|
|
346024
|
-
|
|
346025
|
-
|
|
346026
|
-
|
|
346027
|
-
|
|
346028
|
-
|
|
346029
|
-
|
|
346030
|
-
|
|
346031
|
-
|
|
346032
|
-
|
|
346033
|
-
|
|
346034
|
-
|
|
346097
|
+
const flashResult = await this.queryLoopDetectionModel("loop-detection", contents, signal);
|
|
346098
|
+
if (!flashResult) {
|
|
346099
|
+
return false;
|
|
346100
|
+
}
|
|
346101
|
+
const flashConfidence = flashResult["unproductive_state_confidence"];
|
|
346102
|
+
const doubleCheckModelName = this.config.modelConfigService.getResolvedConfig({
|
|
346103
|
+
model: DOUBLE_CHECK_MODEL_ALIAS
|
|
346104
|
+
}).model;
|
|
346105
|
+
if (flashConfidence < LLM_CONFIDENCE_THRESHOLD) {
|
|
346106
|
+
logLlmLoopCheck(this.config, new LlmLoopCheckEvent(this.promptId, flashConfidence, doubleCheckModelName, -1));
|
|
346107
|
+
this.updateCheckInterval(flashConfidence);
|
|
346108
|
+
return false;
|
|
346109
|
+
}
|
|
346110
|
+
if (this.config.isInFallbackMode()) {
|
|
346111
|
+
const flashModelName = this.config.modelConfigService.getResolvedConfig({
|
|
346112
|
+
model: "loop-detection"
|
|
346113
|
+
}).model;
|
|
346114
|
+
this.handleConfirmedLoop(flashResult, flashModelName);
|
|
346115
|
+
return true;
|
|
346116
|
+
}
|
|
346117
|
+
const mainModelResult = await this.queryLoopDetectionModel(DOUBLE_CHECK_MODEL_ALIAS, contents, signal);
|
|
346118
|
+
const mainModelConfidence = mainModelResult ? mainModelResult["unproductive_state_confidence"] : 0;
|
|
346119
|
+
logLlmLoopCheck(this.config, new LlmLoopCheckEvent(this.promptId, flashConfidence, doubleCheckModelName, mainModelConfidence));
|
|
346120
|
+
if (mainModelResult) {
|
|
346121
|
+
if (mainModelConfidence >= LLM_CONFIDENCE_THRESHOLD) {
|
|
346122
|
+
this.handleConfirmedLoop(mainModelResult, doubleCheckModelName);
|
|
346123
|
+
return true;
|
|
346124
|
+
} else {
|
|
346125
|
+
this.updateCheckInterval(mainModelConfidence);
|
|
346126
|
+
}
|
|
346127
|
+
}
|
|
346128
|
+
return false;
|
|
346129
|
+
}
|
|
346130
|
+
async queryLoopDetectionModel(model, contents, signal) {
|
|
346035
346131
|
try {
|
|
346036
|
-
result = await this.config.getBaseLlmClient().generateJson({
|
|
346037
|
-
modelConfigKey: { model
|
|
346132
|
+
const result = await this.config.getBaseLlmClient().generateJson({
|
|
346133
|
+
modelConfigKey: { model },
|
|
346038
346134
|
contents,
|
|
346039
|
-
schema,
|
|
346135
|
+
schema: LOOP_DETECTION_SCHEMA,
|
|
346040
346136
|
systemInstruction: LOOP_DETECTION_SYSTEM_PROMPT,
|
|
346041
346137
|
abortSignal: signal,
|
|
346042
|
-
promptId: this.promptId
|
|
346138
|
+
promptId: this.promptId,
|
|
346139
|
+
maxAttempts: 2
|
|
346043
346140
|
});
|
|
346141
|
+
if (result && typeof result["unproductive_state_confidence"] === "number") {
|
|
346142
|
+
return result;
|
|
346143
|
+
}
|
|
346144
|
+
return null;
|
|
346044
346145
|
} catch (e2) {
|
|
346045
346146
|
this.config.getDebugMode() ? debugLogger.warn(e2) : debugLogger.debug(e2);
|
|
346046
|
-
return
|
|
346147
|
+
return null;
|
|
346047
346148
|
}
|
|
346048
|
-
|
|
346049
|
-
|
|
346050
|
-
|
|
346051
|
-
|
|
346052
|
-
}
|
|
346053
|
-
logLoopDetected(this.config, new LoopDetectedEvent(LoopType.LLM_DETECTED_LOOP, this.promptId));
|
|
346054
|
-
return true;
|
|
346055
|
-
} else {
|
|
346056
|
-
this.llmCheckInterval = Math.round(MIN_LLM_CHECK_INTERVAL + (MAX_LLM_CHECK_INTERVAL - MIN_LLM_CHECK_INTERVAL) * (1 - result["unproductive_state_confidence"]));
|
|
346057
|
-
}
|
|
346149
|
+
}
|
|
346150
|
+
handleConfirmedLoop(result, modelName) {
|
|
346151
|
+
if (typeof result["unproductive_state_analysis"] === "string" && result["unproductive_state_analysis"]) {
|
|
346152
|
+
debugLogger.warn(result["unproductive_state_analysis"]);
|
|
346058
346153
|
}
|
|
346059
|
-
|
|
346154
|
+
logLoopDetected(this.config, new LoopDetectedEvent(LoopType.LLM_DETECTED_LOOP, this.promptId, modelName));
|
|
346155
|
+
}
|
|
346156
|
+
updateCheckInterval(unproductive_state_confidence) {
|
|
346157
|
+
this.llmCheckInterval = Math.round(MIN_LLM_CHECK_INTERVAL + (MAX_LLM_CHECK_INTERVAL - MIN_LLM_CHECK_INTERVAL) * (1 - unproductive_state_confidence));
|
|
346060
346158
|
}
|
|
346061
346159
|
/**
|
|
346062
346160
|
* Resets all loop detection state.
|
|
@@ -352121,6 +352219,12 @@ var DEFAULT_MODEL_CONFIGS = {
|
|
|
352121
352219
|
extends: "gemini-2.5-flash-base",
|
|
352122
352220
|
modelConfig: {}
|
|
352123
352221
|
},
|
|
352222
|
+
"loop-detection-double-check": {
|
|
352223
|
+
extends: "base",
|
|
352224
|
+
modelConfig: {
|
|
352225
|
+
model: "gemini-2.5-pro"
|
|
352226
|
+
}
|
|
352227
|
+
},
|
|
352124
352228
|
"llm-edit-fixer": {
|
|
352125
352229
|
extends: "gemini-2.5-flash-base",
|
|
352126
352230
|
modelConfig: {}
|
|
@@ -354973,7 +355077,7 @@ async function getClientMetadata() {
|
|
|
354973
355077
|
if (!clientMetadataPromise) {
|
|
354974
355078
|
clientMetadataPromise = (async () => ({
|
|
354975
355079
|
ideName: "GEMINI_CLI",
|
|
354976
|
-
ideVersion: "0.
|
|
355080
|
+
ideVersion: "0.16.0-nightly.20251112.c961f274",
|
|
354977
355081
|
platform: getPlatform(),
|
|
354978
355082
|
updateChannel: await getReleaseChannel(__dirname5)
|
|
354979
355083
|
}))();
|