@protolabsai/proto 0.48.1 → 0.49.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/cli.js +168 -8
- package/package.json +2 -2
package/cli.js
CHANGED
|
@@ -19092,7 +19092,7 @@ function parseResponseData(error40) {
|
|
|
19092
19092
|
}
|
|
19093
19093
|
return error40.response?.data;
|
|
19094
19094
|
}
|
|
19095
|
-
var FatalError, FatalAuthenticationError, FatalInputError, FatalSandboxError, FatalConfigError, FatalTurnLimitedError, FatalToolExecutionError, FatalCancellationError, ForbiddenError, UnauthorizedError, BadRequestError;
|
|
19095
|
+
var FatalError, FatalAuthenticationError, FatalInputError, FatalSandboxError, FatalConfigError, FatalTurnLimitedError, FatalToolExecutionError, FatalBudgetExceededError, FatalCancellationError, ForbiddenError, UnauthorizedError, BadRequestError;
|
|
19096
19096
|
var init_errors = __esm({
|
|
19097
19097
|
"packages/core/dist/src/utils/errors.js"() {
|
|
19098
19098
|
"use strict";
|
|
@@ -19160,6 +19160,14 @@ var init_errors = __esm({
|
|
|
19160
19160
|
super(message, 54);
|
|
19161
19161
|
}
|
|
19162
19162
|
};
|
|
19163
|
+
FatalBudgetExceededError = class extends FatalError {
|
|
19164
|
+
static {
|
|
19165
|
+
__name(this, "FatalBudgetExceededError");
|
|
19166
|
+
}
|
|
19167
|
+
constructor(message) {
|
|
19168
|
+
super(message, 55);
|
|
19169
|
+
}
|
|
19170
|
+
};
|
|
19163
19171
|
FatalCancellationError = class extends FatalError {
|
|
19164
19172
|
static {
|
|
19165
19173
|
__name(this, "FatalCancellationError");
|
|
@@ -168676,7 +168684,7 @@ __export(geminiContentGenerator_exports, {
|
|
|
168676
168684
|
createGeminiContentGenerator: () => createGeminiContentGenerator
|
|
168677
168685
|
});
|
|
168678
168686
|
function createGeminiContentGenerator(config2, gcConfig) {
|
|
168679
|
-
const version2 = "0.
|
|
168687
|
+
const version2 = "0.49.0";
|
|
168680
168688
|
const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
|
|
168681
168689
|
const baseHeaders = {
|
|
168682
168690
|
"User-Agent": userAgent2
|
|
@@ -275236,6 +275244,7 @@ var init_config3 = __esm({
|
|
|
275236
275244
|
folderTrust;
|
|
275237
275245
|
ideMode;
|
|
275238
275246
|
maxSessionTurns;
|
|
275247
|
+
maxToolCalls;
|
|
275239
275248
|
sessionTokenLimit;
|
|
275240
275249
|
listExtensions;
|
|
275241
275250
|
overrideExtensions;
|
|
@@ -275348,6 +275357,7 @@ var init_config3 = __esm({
|
|
|
275348
275357
|
this.fileDiscoveryService = params.fileDiscoveryService ?? null;
|
|
275349
275358
|
this.bugCommand = params.bugCommand;
|
|
275350
275359
|
this.maxSessionTurns = params.maxSessionTurns ?? -1;
|
|
275360
|
+
this.maxToolCalls = params.maxToolCalls ?? -1;
|
|
275351
275361
|
this.sessionTokenLimit = params.sessionTokenLimit ?? -1;
|
|
275352
275362
|
this.experimentalZedIntegration = params.experimentalZedIntegration ?? false;
|
|
275353
275363
|
this.cronEnabled = params.cronEnabled ?? false;
|
|
@@ -275776,6 +275786,9 @@ var init_config3 = __esm({
|
|
|
275776
275786
|
getMaxSessionTurns() {
|
|
275777
275787
|
return this.maxSessionTurns;
|
|
275778
275788
|
}
|
|
275789
|
+
getMaxToolCalls() {
|
|
275790
|
+
return this.maxToolCalls;
|
|
275791
|
+
}
|
|
275779
275792
|
getSessionTokenLimit() {
|
|
275780
275793
|
return this.sessionTokenLimit;
|
|
275781
275794
|
}
|
|
@@ -288111,6 +288124,7 @@ __export(dist_exports, {
|
|
|
288111
288124
|
ExtensionUpdateState: () => ExtensionUpdateState,
|
|
288112
288125
|
FILE_MUTATING_TOOLS: () => FILE_MUTATING_TOOLS,
|
|
288113
288126
|
FatalAuthenticationError: () => FatalAuthenticationError,
|
|
288127
|
+
FatalBudgetExceededError: () => FatalBudgetExceededError,
|
|
288114
288128
|
FatalCancellationError: () => FatalCancellationError,
|
|
288115
288129
|
FatalConfigError: () => FatalConfigError,
|
|
288116
288130
|
FatalError: () => FatalError,
|
|
@@ -405844,6 +405858,15 @@ var SETTINGS_SCHEMA = {
|
|
|
405844
405858
|
description: "Maximum number of user/model/tool turns to keep in a session. -1 means unlimited.",
|
|
405845
405859
|
showInDialog: false
|
|
405846
405860
|
},
|
|
405861
|
+
maxToolCalls: {
|
|
405862
|
+
type: "number",
|
|
405863
|
+
label: "Max Tool Calls",
|
|
405864
|
+
category: "Model",
|
|
405865
|
+
requiresRestart: false,
|
|
405866
|
+
default: -1,
|
|
405867
|
+
description: "Maximum number of tool calls for a headless run before aborting (exit code 55). -1 means unlimited.",
|
|
405868
|
+
showInDialog: false
|
|
405869
|
+
},
|
|
405847
405870
|
chatCompression: {
|
|
405848
405871
|
type: "object",
|
|
405849
405872
|
label: "Chat Compression",
|
|
@@ -408902,6 +408925,17 @@ function handleMaxTurnsExceededError(config2) {
|
|
|
408902
408925
|
}
|
|
408903
408926
|
}
|
|
408904
408927
|
__name(handleMaxTurnsExceededError, "handleMaxTurnsExceededError");
|
|
408928
|
+
function handleBudgetExceededError(config2, exceeded) {
|
|
408929
|
+
const budgetError = new FatalBudgetExceededError(exceeded.message);
|
|
408930
|
+
if (config2.getOutputFormat() === OutputFormat.JSON) {
|
|
408931
|
+
const formatter = new JsonFormatter();
|
|
408932
|
+
writeStderrLine(formatter.formatError(budgetError, budgetError.exitCode));
|
|
408933
|
+
} else {
|
|
408934
|
+
writeStderrLine(budgetError.message);
|
|
408935
|
+
}
|
|
408936
|
+
process.exit(budgetError.exitCode);
|
|
408937
|
+
}
|
|
408938
|
+
__name(handleBudgetExceededError, "handleBudgetExceededError");
|
|
408905
408939
|
|
|
408906
408940
|
// packages/cli/src/commands/extensions/consent.ts
|
|
408907
408941
|
init_esbuild_shims();
|
|
@@ -415376,6 +415410,7 @@ async function handleQwenAuth(command2, options2) {
|
|
|
415376
415410
|
resume: void 0,
|
|
415377
415411
|
sessionId: void 0,
|
|
415378
415412
|
maxSessionTurns: void 0,
|
|
415413
|
+
maxToolCalls: void 0,
|
|
415379
415414
|
coreTools: void 0,
|
|
415380
415415
|
excludeTools: void 0,
|
|
415381
415416
|
disabledSlashCommands: void 0,
|
|
@@ -416526,7 +416561,7 @@ __name(getPackageJson, "getPackageJson");
|
|
|
416526
416561
|
// packages/cli/src/utils/version.ts
|
|
416527
416562
|
async function getCliVersion() {
|
|
416528
416563
|
const pkgJson = await getPackageJson();
|
|
416529
|
-
return "0.
|
|
416564
|
+
return "0.49.0";
|
|
416530
416565
|
}
|
|
416531
416566
|
__name(getCliVersion, "getCliVersion");
|
|
416532
416567
|
|
|
@@ -420634,6 +420669,104 @@ function buildWebSearchConfig(argv, settings2, authType) {
|
|
|
420634
420669
|
}
|
|
420635
420670
|
__name(buildWebSearchConfig, "buildWebSearchConfig");
|
|
420636
420671
|
|
|
420672
|
+
// packages/cli/src/utils/runBudget.ts
|
|
420673
|
+
init_esbuild_shims();
|
|
420674
|
+
var SECOND = 1e3;
|
|
420675
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
420676
|
+
var MAX_WALL_TIME_SECONDS = Math.floor(MAX_TIMEOUT_MS / SECOND);
|
|
420677
|
+
var MAX_TOOL_CALLS = 1e6;
|
|
420678
|
+
function validateMaxToolCalls(value) {
|
|
420679
|
+
if (value === -1) return -1;
|
|
420680
|
+
if (!Number.isFinite(value)) {
|
|
420681
|
+
throw new Error(`maxToolCalls must be a finite number; got ${value}.`);
|
|
420682
|
+
}
|
|
420683
|
+
if (!Number.isInteger(value)) {
|
|
420684
|
+
throw new Error(
|
|
420685
|
+
`maxToolCalls must be an integer (or -1 for unlimited); got ${value}.`
|
|
420686
|
+
);
|
|
420687
|
+
}
|
|
420688
|
+
if (value < 0) {
|
|
420689
|
+
throw new Error(
|
|
420690
|
+
`maxToolCalls must be >= 0 (or -1 for unlimited); got ${value}. Use -1 to disable, not a negative number.`
|
|
420691
|
+
);
|
|
420692
|
+
}
|
|
420693
|
+
if (value > MAX_TOOL_CALLS) {
|
|
420694
|
+
throw new Error(
|
|
420695
|
+
`maxToolCalls ${value} exceeds the supported ceiling (${MAX_TOOL_CALLS}). Likely a typo \u2014 use a smaller value or -1 for unlimited.`
|
|
420696
|
+
);
|
|
420697
|
+
}
|
|
420698
|
+
return value;
|
|
420699
|
+
}
|
|
420700
|
+
__name(validateMaxToolCalls, "validateMaxToolCalls");
|
|
420701
|
+
var RunBudgetEnforcer = class {
|
|
420702
|
+
static {
|
|
420703
|
+
__name(this, "RunBudgetEnforcer");
|
|
420704
|
+
}
|
|
420705
|
+
maxWallTimeSeconds;
|
|
420706
|
+
maxToolCalls;
|
|
420707
|
+
abortController;
|
|
420708
|
+
wallTimer = null;
|
|
420709
|
+
toolCallCount = 0;
|
|
420710
|
+
exceeded = null;
|
|
420711
|
+
constructor(opts, abortController) {
|
|
420712
|
+
this.maxWallTimeSeconds = opts.maxWallTimeSeconds ?? -1;
|
|
420713
|
+
this.maxToolCalls = opts.maxToolCalls ?? -1;
|
|
420714
|
+
this.abortController = abortController;
|
|
420715
|
+
}
|
|
420716
|
+
/**
|
|
420717
|
+
* Starts the wall-clock timer (if configured). Idempotent so callers
|
|
420718
|
+
* don't need to thread "did I already start?" state.
|
|
420719
|
+
*/
|
|
420720
|
+
start() {
|
|
420721
|
+
if (this.wallTimer !== null) return;
|
|
420722
|
+
if (this.maxWallTimeSeconds <= 0) return;
|
|
420723
|
+
this.wallTimer = setTimeout(() => {
|
|
420724
|
+
this.markExceeded({
|
|
420725
|
+
kind: "wall-time",
|
|
420726
|
+
limit: this.maxWallTimeSeconds,
|
|
420727
|
+
observed: this.maxWallTimeSeconds,
|
|
420728
|
+
message: `Run aborted: wall-clock budget of ${this.maxWallTimeSeconds}s exceeded (--max-wall-time).`
|
|
420729
|
+
});
|
|
420730
|
+
}, this.maxWallTimeSeconds * SECOND);
|
|
420731
|
+
this.wallTimer.unref?.();
|
|
420732
|
+
}
|
|
420733
|
+
/** Records one tool execution and enforces `maxToolCalls`. */
|
|
420734
|
+
tickToolCall() {
|
|
420735
|
+
this.toolCallCount += 1;
|
|
420736
|
+
if (this.maxToolCalls >= 0 && this.toolCallCount > this.maxToolCalls) {
|
|
420737
|
+
this.markExceeded({
|
|
420738
|
+
kind: "tool-calls",
|
|
420739
|
+
limit: this.maxToolCalls,
|
|
420740
|
+
observed: this.toolCallCount,
|
|
420741
|
+
message: `Run aborted: tool-call budget of ${this.maxToolCalls} exceeded (--max-tool-calls); observed ${this.toolCallCount}.`
|
|
420742
|
+
});
|
|
420743
|
+
}
|
|
420744
|
+
}
|
|
420745
|
+
/**
|
|
420746
|
+
* Returns the budget-exceeded record if one fired, else null. The
|
|
420747
|
+
* non-interactive loop checks this after `abortController.signal`
|
|
420748
|
+
* fires to distinguish "budget abort" from "user SIGINT" so it can
|
|
420749
|
+
* emit a structured-error envelope with the right reason.
|
|
420750
|
+
*/
|
|
420751
|
+
getExceeded() {
|
|
420752
|
+
return this.exceeded;
|
|
420753
|
+
}
|
|
420754
|
+
/** Cancels the wall-clock timer. Safe to call multiple times. */
|
|
420755
|
+
stop() {
|
|
420756
|
+
if (this.wallTimer !== null) {
|
|
420757
|
+
clearTimeout(this.wallTimer);
|
|
420758
|
+
this.wallTimer = null;
|
|
420759
|
+
}
|
|
420760
|
+
}
|
|
420761
|
+
markExceeded(record2) {
|
|
420762
|
+
if (this.exceeded !== null) return;
|
|
420763
|
+
if (this.abortController.signal.aborted) return;
|
|
420764
|
+
this.exceeded = record2;
|
|
420765
|
+
this.stop();
|
|
420766
|
+
this.abortController.abort();
|
|
420767
|
+
}
|
|
420768
|
+
};
|
|
420769
|
+
|
|
420637
420770
|
// packages/cli/src/config/config.ts
|
|
420638
420771
|
var SESSION_ID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}(-agent-[a-zA-Z0-9_.-]+)?$/i;
|
|
420639
420772
|
function isValidSessionId(value) {
|
|
@@ -420913,6 +421046,9 @@ async function parseArguments() {
|
|
|
420913
421046
|
}).option("max-session-turns", {
|
|
420914
421047
|
type: "number",
|
|
420915
421048
|
description: "Maximum number of session turns"
|
|
421049
|
+
}).option("max-tool-calls", {
|
|
421050
|
+
type: "number",
|
|
421051
|
+
description: "Maximum number of tool calls for a headless run before aborting (exit code 55). Defaults to unlimited."
|
|
420916
421052
|
}).option("core-tools", {
|
|
420917
421053
|
type: "array",
|
|
420918
421054
|
string: true,
|
|
@@ -421308,6 +421444,9 @@ async function loadCliConfig(settings2, argv, cwd6 = process.cwd(), overrideExte
|
|
|
421308
421444
|
outputLanguageFilePath,
|
|
421309
421445
|
sessionTokenLimit: settings2.model?.sessionTokenLimit ?? -1,
|
|
421310
421446
|
maxSessionTurns: argv.maxSessionTurns ?? settings2.model?.maxSessionTurns ?? -1,
|
|
421447
|
+
maxToolCalls: validateMaxToolCalls(
|
|
421448
|
+
argv.maxToolCalls ?? settings2.model?.maxToolCalls ?? -1
|
|
421449
|
+
),
|
|
421311
421450
|
experimentalZedIntegration: argv.acp || argv.experimentalAcp || false,
|
|
421312
421451
|
cronEnabled: settings2.experimental?.cron ?? false,
|
|
421313
421452
|
listExtensions: argv.listExtensions || false,
|
|
@@ -424540,7 +424679,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
|
|
|
424540
424679
|
|
|
424541
424680
|
// packages/cli/src/generated/git-commit.ts
|
|
424542
424681
|
init_esbuild_shims();
|
|
424543
|
-
var GIT_COMMIT_INFO = "
|
|
424682
|
+
var GIT_COMMIT_INFO = "58b119575";
|
|
424544
424683
|
|
|
424545
424684
|
// packages/cli/src/utils/systemInfo.ts
|
|
424546
424685
|
async function getNpmVersion() {
|
|
@@ -436700,6 +436839,17 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
436700
436839
|
}, "stdoutErrorHandler");
|
|
436701
436840
|
const geminiClient = config2.getGeminiClient();
|
|
436702
436841
|
const abortController = options2.abortController ?? new AbortController();
|
|
436842
|
+
const budgetEnforcer = new RunBudgetEnforcer(
|
|
436843
|
+
{ maxToolCalls: config2.getMaxToolCalls() },
|
|
436844
|
+
abortController
|
|
436845
|
+
);
|
|
436846
|
+
const routeAbort = /* @__PURE__ */ __name(() => {
|
|
436847
|
+
const exceeded = budgetEnforcer.getExceeded();
|
|
436848
|
+
if (exceeded) {
|
|
436849
|
+
handleBudgetExceededError(config2, exceeded);
|
|
436850
|
+
}
|
|
436851
|
+
handleCancellationError(config2);
|
|
436852
|
+
}, "routeAbort");
|
|
436703
436853
|
const authError = await checkAuthPreflight(config2);
|
|
436704
436854
|
if (authError) {
|
|
436705
436855
|
if (outputFormat === OutputFormat.JSON || outputFormat === OutputFormat.STREAM_JSON) {
|
|
@@ -436809,6 +436959,7 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
436809
436959
|
}
|
|
436810
436960
|
const initialParts = normalizePartList(initialPartList);
|
|
436811
436961
|
let currentMessages = [{ role: "user", parts: initialParts }];
|
|
436962
|
+
budgetEnforcer.start();
|
|
436812
436963
|
let isFirstTurn = true;
|
|
436813
436964
|
while (true) {
|
|
436814
436965
|
turnCount++;
|
|
@@ -436829,7 +436980,7 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
436829
436980
|
adapter.startAssistantMessage();
|
|
436830
436981
|
for await (const event of responseStream) {
|
|
436831
436982
|
if (abortController.signal.aborted) {
|
|
436832
|
-
|
|
436983
|
+
routeAbort();
|
|
436833
436984
|
}
|
|
436834
436985
|
adapter.processEvent(event);
|
|
436835
436986
|
if (event.type === GeminiEventType.ToolCallRequest) {
|
|
@@ -436862,6 +437013,10 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
436862
437013
|
finalRequestInfo.callId,
|
|
436863
437014
|
adapter
|
|
436864
437015
|
) : createToolProgressHandler(finalRequestInfo, adapter);
|
|
437016
|
+
budgetEnforcer.tickToolCall();
|
|
437017
|
+
if (abortController.signal.aborted) {
|
|
437018
|
+
routeAbort();
|
|
437019
|
+
}
|
|
436865
437020
|
const toolResponse = await executeToolCall(
|
|
436866
437021
|
config2,
|
|
436867
437022
|
finalRequestInfo,
|
|
@@ -436950,6 +437105,10 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
436950
437105
|
requestInfo.callId,
|
|
436951
437106
|
adapter
|
|
436952
437107
|
) : createToolProgressHandler(requestInfo, adapter);
|
|
437108
|
+
budgetEnforcer.tickToolCall();
|
|
437109
|
+
if (abortController.signal.aborted) {
|
|
437110
|
+
routeAbort();
|
|
437111
|
+
}
|
|
436953
437112
|
const toolResponse = await executeToolCall(
|
|
436954
437113
|
config2,
|
|
436955
437114
|
requestInfo,
|
|
@@ -437028,6 +437187,7 @@ async function runNonInteractive(config2, settings2, input, prompt_id, options2
|
|
|
437028
437187
|
});
|
|
437029
437188
|
handleError(error40, config2);
|
|
437030
437189
|
} finally {
|
|
437190
|
+
budgetEnforcer.stop();
|
|
437031
437191
|
process.stdout.removeListener("error", stdoutErrorHandler);
|
|
437032
437192
|
process.removeListener("SIGINT", shutdownHandler);
|
|
437033
437193
|
process.removeListener("SIGTERM", shutdownHandler);
|
|
@@ -461455,7 +461615,7 @@ var getStatusText = /* @__PURE__ */ __name((status) => {
|
|
|
461455
461615
|
return "Unknown";
|
|
461456
461616
|
}
|
|
461457
461617
|
}, "getStatusText");
|
|
461458
|
-
var
|
|
461618
|
+
var MAX_TOOL_CALLS2 = 5;
|
|
461459
461619
|
var MAX_VERBOSE_TOOL_CALLS = 12;
|
|
461460
461620
|
var MAX_TASK_PROMPT_LINES = 5;
|
|
461461
461621
|
var DEFAULT_DETAIL_HEIGHT = 18;
|
|
@@ -461510,7 +461670,7 @@ var AgentExecutionDisplay = /* @__PURE__ */ __name(({
|
|
|
461510
461670
|
Math.floor((renderableBudget - promptBudget) / ROWS_PER_TOOL_CALL)
|
|
461511
461671
|
);
|
|
461512
461672
|
const maxTaskPromptLines = displayMode === "verbose" ? Math.min(8, promptBudget) : Math.min(MAX_TASK_PROMPT_LINES, promptBudget);
|
|
461513
|
-
const maxToolCalls = displayMode === "verbose" ? Math.min(MAX_VERBOSE_TOOL_CALLS, toolBudget) : Math.min(
|
|
461673
|
+
const maxToolCalls = displayMode === "verbose" ? Math.min(MAX_VERBOSE_TOOL_CALLS, toolBudget) : Math.min(MAX_TOOL_CALLS2, toolBudget);
|
|
461514
461674
|
const agentColor = (0, import_react62.useMemo)(() => {
|
|
461515
461675
|
const colorOption = COLOR_OPTIONS.find(
|
|
461516
461676
|
(option2) => option2.name === data.subagentColor
|
|
@@ -493287,7 +493447,7 @@ var QwenAgent = class {
|
|
|
493287
493447
|
async initialize(args2) {
|
|
493288
493448
|
this.clientCapabilities = args2.clientCapabilities;
|
|
493289
493449
|
const authMethods = buildAuthMethods();
|
|
493290
|
-
const version2 = "0.
|
|
493450
|
+
const version2 = "0.49.0";
|
|
493291
493451
|
return {
|
|
493292
493452
|
protocolVersion: PROTOCOL_VERSION,
|
|
493293
493453
|
agentInfo: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protolabsai/proto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
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.
|
|
24
|
+
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.49.0"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {},
|
|
27
27
|
"optionalDependencies": {
|