@protolabsai/proto 0.55.0 → 0.55.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cli.js +229 -40
  2. package/package.json +2 -2
package/cli.js CHANGED
@@ -168684,7 +168684,7 @@ __export(geminiContentGenerator_exports, {
168684
168684
  createGeminiContentGenerator: () => createGeminiContentGenerator
168685
168685
  });
168686
168686
  function createGeminiContentGenerator(config2, gcConfig) {
168687
- const version2 = "0.55.0";
168687
+ const version2 = "0.55.2";
168688
168688
  const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
168689
168689
  const baseHeaders = {
168690
168690
  "User-Agent": userAgent2
@@ -175339,10 +175339,10 @@ function parseRule(raw2) {
175339
175339
  const normalized2 = trimmed2.replace(/:(\*)/, " $1");
175340
175340
  const openParen = normalized2.indexOf("(");
175341
175341
  if (openParen === -1) {
175342
- const canonicalName2 = resolveToolName(normalized2);
175342
+ const canonicalName3 = resolveToolName(normalized2);
175343
175343
  return {
175344
175344
  raw: trimmed2,
175345
- toolName: canonicalName2
175345
+ toolName: canonicalName3
175346
175346
  };
175347
175347
  }
175348
175348
  const toolPart = normalized2.substring(0, openParen).trim();
@@ -175350,11 +175350,11 @@ function parseRule(raw2) {
175350
175350
  return { raw: trimmed2, toolName: resolveToolName(toolPart), invalid: true };
175351
175351
  }
175352
175352
  const specifier = normalized2.substring(openParen + 1, normalized2.length - 1);
175353
- const canonicalName = resolveToolName(toolPart);
175354
- const specifierKind = specifier ? getSpecifierKind(canonicalName) : void 0;
175353
+ const canonicalName2 = resolveToolName(toolPart);
175354
+ const specifierKind = specifier ? getSpecifierKind(canonicalName2) : void 0;
175355
175355
  return {
175356
175356
  raw: trimmed2,
175357
- toolName: canonicalName,
175357
+ toolName: canonicalName2,
175358
175358
  specifier,
175359
175359
  specifierKind
175360
175360
  };
@@ -175371,9 +175371,9 @@ function getRuleDisplayName(canonicalToolName) {
175371
175371
  return CANONICAL_TO_RULE_DISPLAY[canonicalToolName] ?? canonicalToolName;
175372
175372
  }
175373
175373
  function buildPermissionRules(ctx) {
175374
- const canonicalName = resolveToolName(ctx.toolName);
175375
- const displayName = getRuleDisplayName(canonicalName);
175376
- const kind2 = getSpecifierKind(canonicalName);
175374
+ const canonicalName2 = resolveToolName(ctx.toolName);
175375
+ const displayName = getRuleDisplayName(canonicalName2);
175376
+ const kind2 = getSpecifierKind(canonicalName2);
175377
175377
  switch (kind2) {
175378
175378
  case "command":
175379
175379
  if (ctx.command) {
@@ -175382,7 +175382,7 @@ function buildPermissionRules(ctx) {
175382
175382
  return [displayName];
175383
175383
  case "path":
175384
175384
  if (ctx.filePath) {
175385
- const dirPath = FILE_TARGETED_TOOLS.has(canonicalName) ? path21.dirname(ctx.filePath) : ctx.filePath;
175385
+ const dirPath = FILE_TARGETED_TOOLS.has(canonicalName2) ? path21.dirname(ctx.filePath) : ctx.filePath;
175386
175386
  const specifier = dirPath.startsWith("/") ? `/${dirPath}/**` : `${dirPath}/**`;
175387
175387
  return [`${displayName}(${specifier})`];
175388
175388
  }
@@ -175425,8 +175425,8 @@ function buildHumanReadableRuleLabel(rules) {
175425
175425
  const displayName = rule.substring(0, parenIdx);
175426
175426
  const specifier = rule.substring(parenIdx + 1, rule.length - 1);
175427
175427
  const verb = DISPLAY_NAME_TO_VERB[displayName] ?? displayName.toLowerCase();
175428
- const canonicalName = Object.entries(CANONICAL_TO_RULE_DISPLAY).find(([, v2]) => v2 === displayName)?.[0];
175429
- const kind2 = canonicalName ? getSpecifierKind(canonicalName) : "literal";
175428
+ const canonicalName2 = Object.entries(CANONICAL_TO_RULE_DISPLAY).find(([, v2]) => v2 === displayName)?.[0];
175429
+ const kind2 = canonicalName2 ? getSpecifierKind(canonicalName2) : "literal";
175430
175430
  switch (kind2) {
175431
175431
  case "path": {
175432
175432
  const cleanPath = cleanPathSpecifier(specifier);
@@ -176637,14 +176637,14 @@ var init_tool_utils = __esm({
176637
176637
  set2.add(normalizeIdentifier(alias));
176638
176638
  }, "addAlias");
176639
176639
  for (const key of toolNameKeys) {
176640
- const canonicalName = ToolNames[key];
176640
+ const canonicalName2 = ToolNames[key];
176641
176641
  const displayName = ToolDisplayNames[key];
176642
176642
  const aliases = /* @__PURE__ */ new Set();
176643
- addAlias(aliases, canonicalName);
176643
+ addAlias(aliases, canonicalName2);
176644
176644
  addAlias(aliases, displayName);
176645
176645
  addAlias(aliases, `${displayName}Tool`);
176646
176646
  for (const [legacyName, mappedName] of Object.entries(ToolNamesMigration)) {
176647
- if (mappedName === canonicalName) {
176647
+ if (mappedName === canonicalName2) {
176648
176648
  addAlias(aliases, legacyName);
176649
176649
  }
176650
176650
  }
@@ -176653,7 +176653,7 @@ var init_tool_utils = __esm({
176653
176653
  addAlias(aliases, legacyDisplay);
176654
176654
  }
176655
176655
  }
176656
- map3.set(canonicalName, aliases);
176656
+ map3.set(canonicalName2, aliases);
176657
176657
  }
176658
176658
  return map3;
176659
176659
  })();
@@ -190243,9 +190243,9 @@ Digest teammate findings thoroughly. Cite file paths and line numbers. NEVER wri
190243
190243
 
190244
190244
  ## Task Decomposition
190245
190245
  When given a complex task:
190246
- 1. Break it into independent subtasks using ${ToolNames.TASK_CREATE}
190246
+ 1. Break it into independent subtasks using ${ToolNames.TASK_CREATE} and track their status with ${ToolNames.TASK_UPDATE}
190247
190247
  2. Identify which can run in parallel vs which have dependencies
190248
- 3. Launch parallel agents using ${ToolNames.AGENT} with run_in_background=true
190248
+ 3. Delegate each subtask to a teammate via your team channel, briefing it per the Delegation Rules above
190249
190249
  4. Monitor completion notifications and synthesize results
190250
190250
  5. Run dependent tasks after prerequisites complete
190251
190251
 
@@ -190258,13 +190258,17 @@ Before reporting completion:
190258
190258
  Notes:
190259
190259
  - Agent threads always have their cwd reset between bash calls, as a result please only use absolute file paths.
190260
190260
  - For clear communication, avoid using emojis.`,
190261
+ // NOTE: ToolNames.AGENT is intentionally NOT listed here. The runtime
190262
+ // strips the agent tool from every subagent to prevent recursion
190263
+ // (see agent-core.ts `excludedFromSubagents`), so listing it would only
190264
+ // tell the model about a tool it can't actually call. The coordinator
190265
+ // delegates to teammates via the team channel when run as a team lead.
190261
190266
  tools: [
190262
190267
  ToolNames.READ_FILE,
190263
190268
  ToolNames.GREP,
190264
190269
  ToolNames.GLOB,
190265
190270
  ToolNames.SHELL,
190266
190271
  ToolNames.LS,
190267
- ToolNames.AGENT,
190268
190272
  ToolNames.TASK_CREATE,
190269
190273
  ToolNames.TASK_LIST,
190270
190274
  ToolNames.TASK_UPDATE,
@@ -197083,12 +197087,13 @@ var init_completion_checker = __esm({
197083
197087
  });
197084
197088
 
197085
197089
  // packages/core/dist/src/goal/types.js
197086
- var MAX_GOAL_CONDITION_LENGTH, GOAL_CLEAR_ALIASES;
197090
+ var MAX_GOAL_CONDITION_LENGTH, GOAL_STALL_LIMIT, GOAL_CLEAR_ALIASES;
197087
197091
  var init_types10 = __esm({
197088
197092
  "packages/core/dist/src/goal/types.js"() {
197089
197093
  "use strict";
197090
197094
  init_esbuild_shims();
197091
197095
  MAX_GOAL_CONDITION_LENGTH = 4e3;
197096
+ GOAL_STALL_LIMIT = 3;
197092
197097
  GOAL_CLEAR_ALIASES = [
197093
197098
  "clear",
197094
197099
  "stop",
@@ -197104,6 +197109,17 @@ var init_types10 = __esm({
197104
197109
  function truncate2(s5, max) {
197105
197110
  return s5.length <= max ? s5 : `${s5.slice(0, max - 1)}\u2026`;
197106
197111
  }
197112
+ function normalizeReason(reason) {
197113
+ const collapsed = reason.trim().toLowerCase().replace(/\s+/g, " ");
197114
+ let end = collapsed.length;
197115
+ while (end > 0 && isTrailingPunctuation(collapsed[end - 1])) {
197116
+ end -= 1;
197117
+ }
197118
+ return collapsed.slice(0, end);
197119
+ }
197120
+ function isTrailingPunctuation(ch) {
197121
+ return ch === "." || ch === "!" || ch === "?";
197122
+ }
197107
197123
  var debugLogger39, GoalManager;
197108
197124
  var init_GoalManager = __esm({
197109
197125
  "packages/core/dist/src/goal/GoalManager.js"() {
@@ -197119,6 +197135,10 @@ var init_GoalManager = __esm({
197119
197135
  active;
197120
197136
  lastAchieved;
197121
197137
  lastFailed;
197138
+ /** Normalized text of the last not-met reason, for stall detection. */
197139
+ lastReasonNormalized;
197140
+ /** Consecutive not-met evaluations repeating `lastReasonNormalized`. */
197141
+ repeatedReasonCount = 0;
197122
197142
  /**
197123
197143
  * Set a new goal. Replaces any active goal. Returns the created state.
197124
197144
  * Throws if the condition is empty or exceeds the length limit.
@@ -197140,6 +197160,7 @@ var init_GoalManager = __esm({
197140
197160
  turnCount: 0,
197141
197161
  tokensSpent: 0
197142
197162
  };
197163
+ this.resetStall();
197143
197164
  return { ...this.active };
197144
197165
  }
197145
197166
  /**
@@ -197151,6 +197172,7 @@ var init_GoalManager = __esm({
197151
197172
  return void 0;
197152
197173
  const cleared = { ...this.active };
197153
197174
  this.active = void 0;
197175
+ this.resetStall();
197154
197176
  debugLogger39.info(`Cleared goal "${truncate2(cleared.condition, 60)}" after ${cleared.turnCount} turns.`);
197155
197177
  return cleared;
197156
197178
  }
@@ -197167,6 +197189,7 @@ var init_GoalManager = __esm({
197167
197189
  };
197168
197190
  this.lastAchieved = achieved;
197169
197191
  this.active = void 0;
197192
+ this.resetStall();
197170
197193
  debugLogger39.info(`Goal achieved after ${achieved.turnCount} turns: "${truncate2(achieved.condition, 60)}".`);
197171
197194
  return achieved;
197172
197195
  }
@@ -197185,6 +197208,7 @@ var init_GoalManager = __esm({
197185
197208
  };
197186
197209
  this.lastFailed = failed;
197187
197210
  this.active = void 0;
197211
+ this.resetStall();
197188
197212
  debugLogger39.info(`Goal abandoned as impossible after ${failed.turnCount} turns: "${truncate2(failed.condition, 60)}" (${truncate2(reason, 80)}).`);
197189
197213
  return failed;
197190
197214
  }
@@ -197194,15 +197218,30 @@ var init_GoalManager = __esm({
197194
197218
  this.active = { ...this.active, turnCount: this.active.turnCount + 1 };
197195
197219
  }
197196
197220
  }
197197
- /** Record the result of an evaluation against the active goal. */
197221
+ /**
197222
+ * Record the result of an evaluation against the active goal. Returns the
197223
+ * number of consecutive not-met evaluations that have repeated the same
197224
+ * reason -- the stall signal a caller compares against {@link GOAL_STALL_LIMIT}.
197225
+ * A converging goal sees the reason change as different pieces complete; a
197226
+ * stuck goal repeats one complaint while the agent churns. Returns 0 when the
197227
+ * goal is met or no goal is active.
197228
+ */
197198
197229
  recordEvaluation(result) {
197199
197230
  if (!this.active)
197200
- return;
197231
+ return 0;
197201
197232
  this.active = {
197202
197233
  ...this.active,
197203
197234
  lastReason: result.reason,
197204
197235
  tokensSpent: this.active.tokensSpent + result.tokensUsed
197205
197236
  };
197237
+ if (result.met) {
197238
+ this.resetStall();
197239
+ return 0;
197240
+ }
197241
+ const norm = normalizeReason(result.reason);
197242
+ this.repeatedReasonCount = norm === this.lastReasonNormalized ? this.repeatedReasonCount + 1 : 1;
197243
+ this.lastReasonNormalized = norm;
197244
+ return this.repeatedReasonCount;
197206
197245
  }
197207
197246
  hasActiveGoal() {
197208
197247
  return this.active !== void 0;
@@ -197221,9 +197260,17 @@ var init_GoalManager = __esm({
197221
197260
  this.active = void 0;
197222
197261
  this.lastAchieved = void 0;
197223
197262
  this.lastFailed = void 0;
197263
+ this.resetStall();
197264
+ }
197265
+ /** Clear stall-detection bookkeeping. */
197266
+ resetStall() {
197267
+ this.lastReasonNormalized = void 0;
197268
+ this.repeatedReasonCount = 0;
197224
197269
  }
197225
197270
  };
197226
197271
  __name(truncate2, "truncate");
197272
+ __name(normalizeReason, "normalizeReason");
197273
+ __name(isTrailingPunctuation, "isTrailingPunctuation");
197227
197274
  }
197228
197275
  });
197229
197276
 
@@ -197272,7 +197319,7 @@ function buildEvaluatorPrompt(context2) {
197272
197319
  "Condition:",
197273
197320
  context2.condition,
197274
197321
  "",
197275
- "Recent tool calls:",
197322
+ "Tool activity so far (repeats collapsed; actions are state-changing, inspections are read-only):",
197276
197323
  context2.toolCallSummary || "(none)",
197277
197324
  "",
197278
197325
  "Final assistant message:",
@@ -197367,9 +197414,9 @@ Respond ONLY with valid JSON matching one of these shapes:
197367
197414
  {"met": false, "impossible": true, "reason": "one short sentence on why it can never be satisfied"}
197368
197415
 
197369
197416
  Rules:
197370
- - Set "met": true only when the condition is clearly demonstrated by the visible evidence (a test output, an exit code, a file count, an empty queue, etc.).
197371
- - If the assistant only claims the work is done without showing evidence, set "met": false and ask for the missing evidence in "reason".
197372
- - If the condition cannot be verified from what is shown, set "met": false and explain what would prove it in "reason".
197417
+ - Set "met": true when the visible evidence shows the condition is satisfied. Evidence can be a command result (a test output, an exit code, a count, an empty queue) OR the requested artifact itself (files created or edited, content written, a result documented, output shown in the transcript). The existence of the deliverable the condition asked for IS evidence -- do not demand a test or an exit code for a goal that does not call for one.
197418
+ - Judge the condition exactly as written. If it asks to create, write, explore, or document something and the transcript shows that artifact exists, set "met": true. Do not invent acceptance criteria stricter than what the user stated.
197419
+ - Set "met": false only when the condition is genuinely unsatisfied, or when the assistant asserts success with nothing in the transcript backing it. When false, name the specific missing piece in "reason".
197373
197420
  - Only set "impossible": true when the condition is genuinely unachievable in this session: it is self-contradictory, depends on an unavailable resource or capability, or the assistant has exhausted reasonable approaches and the transcript confirms there is no path forward. The assistant claiming the goal is impossible is evidence, not proof -- independently confirm it rather than deferring to the assistant's self-assessment. Do NOT set it just because progress is slow or evidence is currently missing. When in doubt, return {"met": false} without "impossible".
197374
197421
  - "impossible" is only meaningful alongside "met": false. Never set it when "met" is true.
197375
197422
  - Keep "reason" to one short sentence. It will be shown to the assistant as guidance for the next turn.`;
@@ -197382,6 +197429,139 @@ Rules:
197382
197429
  }
197383
197430
  });
197384
197431
 
197432
+ // packages/core/dist/src/goal/toolCallSummary.js
197433
+ function summarizeToolCallsForGoal(records) {
197434
+ if (records.length === 0)
197435
+ return "";
197436
+ const byKey = /* @__PURE__ */ new Map();
197437
+ records.forEach((record2, index) => {
197438
+ const name4 = canonicalName(record2.name);
197439
+ const target = extractTarget(record2.input);
197440
+ const key = `${name4} ${target}`;
197441
+ const existing = byKey.get(key);
197442
+ if (existing) {
197443
+ existing.count += 1;
197444
+ existing.lastIndex = index;
197445
+ if (record2.success)
197446
+ existing.okCount += 1;
197447
+ else
197448
+ existing.failCount += 1;
197449
+ } else {
197450
+ byKey.set(key, {
197451
+ name: name4,
197452
+ target,
197453
+ readOnly: READ_ONLY_TOOLS.has(name4),
197454
+ count: 1,
197455
+ okCount: record2.success ? 1 : 0,
197456
+ failCount: record2.success ? 0 : 1,
197457
+ lastIndex: index
197458
+ });
197459
+ }
197460
+ });
197461
+ const distinct = [...byKey.values()].sort((a2, b2) => a2.lastIndex - b2.lastIndex);
197462
+ const actions = distinct.filter((c4) => !c4.readOnly);
197463
+ const reads = distinct.filter((c4) => c4.readOnly);
197464
+ const sections = [];
197465
+ const actionSection = renderSection("Actions taken (most recent last)", actions, MAX_ACTION_LINES);
197466
+ if (actionSection)
197467
+ sections.push(actionSection);
197468
+ const readSection = renderSection("Inspections / reads (most recent last)", reads, MAX_READ_LINES);
197469
+ if (readSection)
197470
+ sections.push(readSection);
197471
+ return sections.join("\n");
197472
+ }
197473
+ function canonicalName(name4) {
197474
+ const migrated = ToolNamesMigration[name4];
197475
+ return migrated ?? name4;
197476
+ }
197477
+ function extractTarget(input) {
197478
+ if (!input)
197479
+ return "";
197480
+ for (const key of TARGET_KEYS) {
197481
+ const value = input[key];
197482
+ if (typeof value === "string" && value.trim().length > 0) {
197483
+ return truncateTarget(value);
197484
+ }
197485
+ }
197486
+ return "";
197487
+ }
197488
+ function truncateTarget(value) {
197489
+ const collapsed = value.replace(/\s+/g, " ").trim();
197490
+ return collapsed.length <= MAX_TARGET_LEN ? collapsed : `${collapsed.slice(0, MAX_TARGET_LEN - 3)}...`;
197491
+ }
197492
+ function renderSection(label, entries, limit2) {
197493
+ if (entries.length === 0)
197494
+ return "";
197495
+ const kept = entries.length > limit2 ? entries.slice(-limit2) : entries;
197496
+ const omitted = entries.length - kept.length;
197497
+ const header = omitted > 0 ? `${label}; ${omitted} earlier omitted:` : `${label}:`;
197498
+ const lines = kept.map((c4) => `- ${renderLine(c4)}`);
197499
+ return [header, ...lines].join("\n");
197500
+ }
197501
+ function renderLine(call) {
197502
+ const target = call.target ? ` ${call.target}` : "";
197503
+ const status = renderStatus(call);
197504
+ const repeat = call.count > 1 ? ` (x${call.count})` : "";
197505
+ return `${call.name}${target} ${status}${repeat}`;
197506
+ }
197507
+ function renderStatus(call) {
197508
+ if (call.failCount === 0)
197509
+ return "[ok]";
197510
+ if (call.okCount === 0)
197511
+ return "[failed]";
197512
+ return `[${call.okCount} ok, ${call.failCount} failed]`;
197513
+ }
197514
+ var MAX_ACTION_LINES, MAX_READ_LINES, MAX_TARGET_LEN, READ_ONLY_TOOLS, TARGET_KEYS;
197515
+ var init_toolCallSummary = __esm({
197516
+ "packages/core/dist/src/goal/toolCallSummary.js"() {
197517
+ "use strict";
197518
+ init_esbuild_shims();
197519
+ init_tool_names();
197520
+ MAX_ACTION_LINES = 30;
197521
+ MAX_READ_LINES = 12;
197522
+ MAX_TARGET_LEN = 120;
197523
+ READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
197524
+ ToolNames.READ_FILE,
197525
+ ToolNames.GREP,
197526
+ ToolNames.GLOB,
197527
+ ToolNames.LS,
197528
+ ToolNames.WEB_FETCH,
197529
+ ToolNames.WEB_SEARCH,
197530
+ ToolNames.LSP,
197531
+ ToolNames.REPO_MAP,
197532
+ ToolNames.TASK_GET,
197533
+ ToolNames.TASK_LIST,
197534
+ ToolNames.TASK_OUTPUT,
197535
+ ToolNames.TASK_READY,
197536
+ // Real read-only tools without a ToolNames entry:
197537
+ "read_many_files"
197538
+ ]);
197539
+ TARGET_KEYS = [
197540
+ "file_path",
197541
+ "absolute_path",
197542
+ "notebook_path",
197543
+ "path",
197544
+ "command",
197545
+ "pattern",
197546
+ "url",
197547
+ "query",
197548
+ "prompt",
197549
+ "description",
197550
+ "skill",
197551
+ "fact",
197552
+ "title",
197553
+ "task_id"
197554
+ ];
197555
+ __name(summarizeToolCallsForGoal, "summarizeToolCallsForGoal");
197556
+ __name(canonicalName, "canonicalName");
197557
+ __name(extractTarget, "extractTarget");
197558
+ __name(truncateTarget, "truncateTarget");
197559
+ __name(renderSection, "renderSection");
197560
+ __name(renderLine, "renderLine");
197561
+ __name(renderStatus, "renderStatus");
197562
+ }
197563
+ });
197564
+
197385
197565
  // packages/core/dist/src/goal/index.js
197386
197566
  var init_goal = __esm({
197387
197567
  "packages/core/dist/src/goal/index.js"() {
@@ -197389,6 +197569,7 @@ var init_goal = __esm({
197389
197569
  init_esbuild_shims();
197390
197570
  init_GoalManager();
197391
197571
  init_goalEvaluator();
197572
+ init_toolCallSummary();
197392
197573
  init_types10();
197393
197574
  }
197394
197575
  });
@@ -197988,11 +198169,7 @@ Please address these issues before finishing.`;
197988
198169
  const active = goalManager.getActiveGoal();
197989
198170
  if (active) {
197990
198171
  goalManager.recordTurn();
197991
- const toolCallSummary = goalToolCalls.slice(-20).map((t5) => {
197992
- const status = t5.success ? "ok" : "failed";
197993
- const cmd = typeof t5.input?.["command"] === "string" ? `: ${t5.input["command"].slice(0, 200)}` : "";
197994
- return `- ${t5.name} [${status}]${cmd}`;
197995
- }).join("\n");
198172
+ const toolCallSummary = summarizeToolCallsForGoal(goalToolCalls);
197996
198173
  let evalResult;
197997
198174
  try {
197998
198175
  evalResult = await evaluateGoal(this.getContentGeneratorOrFail(), this.config.getModel(), {
@@ -198004,12 +198181,20 @@ Please address these issues before finishing.`;
198004
198181
  this.config.getDebugLogger().warn(`[goal] evaluator threw for condition "${active.condition.slice(0, 60)}": ${err3 instanceof Error ? err3.message : String(err3)}`);
198005
198182
  }
198006
198183
  if (evalResult) {
198007
- goalManager.recordEvaluation(evalResult);
198184
+ const repeatedReason = goalManager.recordEvaluation(evalResult);
198008
198185
  if (evalResult.met) {
198009
198186
  goalManager.markAchieved();
198010
198187
  } else if (evalResult.impossible) {
198011
198188
  goalManager.markImpossible(evalResult.reason);
198012
198189
  this.config.getDebugLogger().info(`[goal] abandoned as impossible: ${evalResult.reason.slice(0, 120)}`);
198190
+ } else if (repeatedReason >= GOAL_STALL_LIMIT) {
198191
+ goalManager.clearGoal();
198192
+ const stallReason = `Stopping the /goal loop: the completion check returned the same unmet verdict ${repeatedReason} turns in a row without converging ("${evalResult.reason}"). The goal "${active.condition}" is now cleared. Briefly tell the user where things stand and what they should decide or check next, then stop.`;
198193
+ const stallRequest = [{ text: stallReason }];
198194
+ const stallResult = yield* this.sendMessageStream(stallRequest, signal, prompt_id, { type: SendMessageType.GoalContinuation }, boundedTurns - 1);
198195
+ if (ownsTurnSpan)
198196
+ endTurnSpan("ok");
198197
+ return stallResult;
198013
198198
  } else {
198014
198199
  const continueReason = `Goal not yet met. Evaluator: ${evalResult.reason}
198015
198200
 
@@ -250735,13 +250920,13 @@ var init_permission_manager = __esm({
250735
250920
  * deny specific invocations at runtime.
250736
250921
  */
250737
250922
  async isToolEnabled(toolName) {
250738
- const canonicalName = resolveToolName(toolName);
250923
+ const canonicalName2 = resolveToolName(toolName);
250739
250924
  if (this.coreToolsAllowList !== null && this.coreToolsAllowList.size > 0) {
250740
- if (!this.coreToolsAllowList.has(canonicalName)) {
250925
+ if (!this.coreToolsAllowList.has(canonicalName2)) {
250741
250926
  return false;
250742
250927
  }
250743
250928
  }
250744
- const decision = await this.evaluate({ toolName: canonicalName });
250929
+ const decision = await this.evaluate({ toolName: canonicalName2 });
250745
250930
  return decision !== "deny";
250746
250931
  }
250747
250932
  /**
@@ -288356,6 +288541,7 @@ __export(dist_exports, {
288356
288541
  FlashFallbackEvent: () => FlashFallbackEvent,
288357
288542
  ForbiddenError: () => ForbiddenError,
288358
288543
  GOAL_CLEAR_ALIASES: () => GOAL_CLEAR_ALIASES,
288544
+ GOAL_STALL_LIMIT: () => GOAL_STALL_LIMIT,
288359
288545
  GOOGLE_ACCOUNTS_FILENAME: () => GOOGLE_ACCOUNTS_FILENAME,
288360
288546
  GeminiChat: () => GeminiChat,
288361
288547
  GeminiClient: () => GeminiClient,
@@ -288409,9 +288595,11 @@ __export(dist_exports, {
288409
288595
  LspServerManager: () => LspServerManager,
288410
288596
  LspTool: () => LspTool,
288411
288597
  MAINLINE_CODER_MODEL: () => MAINLINE_CODER_MODEL,
288598
+ MAX_ACTION_LINES: () => MAX_ACTION_LINES,
288412
288599
  MAX_ENTRYPOINT_BYTES: () => MAX_ENTRYPOINT_BYTES,
288413
288600
  MAX_ENTRYPOINT_LINES: () => MAX_ENTRYPOINT_LINES,
288414
288601
  MAX_GOAL_CONDITION_LENGTH: () => MAX_GOAL_CONDITION_LENGTH,
288602
+ MAX_READ_LINES: () => MAX_READ_LINES,
288415
288603
  MCPDiscoveryState: () => MCPDiscoveryState,
288416
288604
  MCPOAuthProvider: () => MCPOAuthProvider,
288417
288605
  MCPOAuthTokenStorage: () => MCPOAuthTokenStorage,
@@ -288963,6 +289151,7 @@ __export(dist_exports, {
288963
289151
  stripStartupContext: () => stripStartupContext,
288964
289152
  subagentGenerator: () => subagentGenerator,
288965
289153
  substituteHookVariables: () => substituteHookVariables,
289154
+ summarizeToolCallsForGoal: () => summarizeToolCallsForGoal,
288966
289155
  teamRegistry: () => teamRegistry,
288967
289156
  templateString: () => templateString,
288968
289157
  tildeifyPath: () => tildeifyPath,
@@ -416785,7 +416974,7 @@ __name(getPackageJson, "getPackageJson");
416785
416974
  // packages/cli/src/utils/version.ts
416786
416975
  async function getCliVersion() {
416787
416976
  const pkgJson = await getPackageJson();
416788
- return "0.55.0";
416977
+ return "0.55.2";
416789
416978
  }
416790
416979
  __name(getCliVersion, "getCliVersion");
416791
416980
 
@@ -424985,7 +425174,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
424985
425174
 
424986
425175
  // packages/cli/src/generated/git-commit.ts
424987
425176
  init_esbuild_shims();
424988
- var GIT_COMMIT_INFO = "c2271eacc";
425177
+ var GIT_COMMIT_INFO = "c065df84f";
424989
425178
 
424990
425179
  // packages/cli/src/utils/systemInfo.ts
424991
425180
  async function getNpmVersion() {
@@ -475728,7 +475917,7 @@ var BaseTextInput = /* @__PURE__ */ __name(({
475728
475917
  borderColor,
475729
475918
  topRightLabel,
475730
475919
  isActive = true,
475731
- renderLine = defaultRenderLine
475920
+ renderLine: renderLine2 = defaultRenderLine
475732
475921
  }) => {
475733
475922
  const handleKey = (0, import_react116.useCallback)(
475734
475923
  (key) => {
@@ -475820,7 +476009,7 @@ var BaseTextInput = /* @__PURE__ */ __name(({
475820
476009
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(Text3, { color: theme.text.secondary, children: placeholder }) : linesToRender.map((lineText, idx) => {
475821
476010
  const absoluteVisualIndex = scrollVisualRow + idx;
475822
476011
  const isOnCursorLine = absoluteVisualIndex === cursorVisualRow;
475823
- return /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(Box_default, { height: 1, children: renderLine({
476012
+ return /* @__PURE__ */ (0, import_jsx_runtime114.jsx)(Box_default, { height: 1, children: renderLine2({
475824
476013
  lineText,
475825
476014
  isOnCursorLine,
475826
476015
  cursorCol: cursorVisualCol,
@@ -493874,7 +494063,7 @@ var QwenAgent = class {
493874
494063
  async initialize(args2) {
493875
494064
  this.clientCapabilities = args2.clientCapabilities;
493876
494065
  const authMethods = buildAuthMethods();
493877
- const version2 = "0.55.0";
494066
+ const version2 = "0.55.2";
493878
494067
  return {
493879
494068
  protocolVersion: PROTOCOL_VERSION,
493880
494069
  agentInfo: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@protolabsai/proto",
3
- "version": "0.55.0",
3
+ "version": "0.55.2",
4
4
  "description": "proto - AI-powered coding agent",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,7 @@
21
21
  "bundled"
22
22
  ],
23
23
  "config": {
24
- "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.55.0"
24
+ "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.55.2"
25
25
  },
26
26
  "dependencies": {},
27
27
  "optionalDependencies": {