@verboo/code 0.15.16 → 0.15.17
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/cli.mjs +987 -452
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -17973,7 +17973,7 @@ function getOauthConfig() {
|
|
|
17973
17973
|
}
|
|
17974
17974
|
return config;
|
|
17975
17975
|
}
|
|
17976
|
-
var CLAUDE_AI_INFERENCE_SCOPE = "user:inference", CLAUDE_AI_PROFILE_SCOPE = "user:profile", CONSOLE_SCOPE = "org:create_api_key", OAUTH_BETA_HEADER = "oauth-2025-04-20", CONSOLE_OAUTH_SCOPES, CLAUDE_AI_OAUTH_SCOPES, ALL_OAUTH_SCOPES, VERBOO_API_BASE_URL = "https://code.verboo.ai", VERBOO_FRONT_BASE_URL = "https://code.verboo.ai", VERBOO_ROUTER_URL = "https://code.verboo.ai/router/v1", VERBOO_OAUTH_SCOPES, PROD_OAUTH_CONFIG, MCP_CLIENT_METADATA_URL = "https://
|
|
17976
|
+
var CLAUDE_AI_INFERENCE_SCOPE = "user:inference", CLAUDE_AI_PROFILE_SCOPE = "user:profile", CONSOLE_SCOPE = "org:create_api_key", OAUTH_BETA_HEADER = "oauth-2025-04-20", CONSOLE_OAUTH_SCOPES, CLAUDE_AI_OAUTH_SCOPES, ALL_OAUTH_SCOPES, VERBOO_API_BASE_URL = "https://code.verboo.ai", VERBOO_FRONT_BASE_URL = "https://code.verboo.ai", VERBOO_ROUTER_URL = "https://code.verboo.ai/router/v1", VERBOO_OAUTH_SCOPES, PROD_OAUTH_CONFIG, MCP_CLIENT_METADATA_URL = "https://code.verboo.ai/.well-known/oauth-client/verboo-code", STAGING_OAUTH_CONFIG, ALLOWED_OAUTH_BASE_URLS;
|
|
17977
17977
|
var init_oauth = __esm(() => {
|
|
17978
17978
|
init_envUtils();
|
|
17979
17979
|
CONSOLE_OAUTH_SCOPES = [
|
|
@@ -118686,7 +118686,7 @@ function getClaudeCodeUserAgent() {
|
|
|
118686
118686
|
return `claude-code/${"99.0.0"}`;
|
|
118687
118687
|
}
|
|
118688
118688
|
function getVerbooCodeUserAgent() {
|
|
118689
|
-
const version2 = "0.15.
|
|
118689
|
+
const version2 = "0.15.17";
|
|
118690
118690
|
return `verboo-code/${version2}`;
|
|
118691
118691
|
}
|
|
118692
118692
|
|
|
@@ -152401,9 +152401,17 @@ function resolveToolNameByUniquePrefix(toolNames, name) {
|
|
|
152401
152401
|
const uniqueToolNames = [...new Set(toolNames)];
|
|
152402
152402
|
if (uniqueToolNames.includes(name))
|
|
152403
152403
|
return name;
|
|
152404
|
-
|
|
152404
|
+
const caseInsensitiveExactMatches = uniqueToolNames.filter((toolName) => toolName.toLowerCase() === name.toLowerCase());
|
|
152405
|
+
if (caseInsensitiveExactMatches.length === 1) {
|
|
152406
|
+
return caseInsensitiveExactMatches[0];
|
|
152407
|
+
}
|
|
152408
|
+
const normalizedName = name.toLowerCase();
|
|
152409
|
+
if (name.length < 3)
|
|
152405
152410
|
return;
|
|
152406
|
-
const prefixMatches = uniqueToolNames.filter((toolName) =>
|
|
152411
|
+
const prefixMatches = uniqueToolNames.filter((toolName) => {
|
|
152412
|
+
const normalizedToolName = toolName.toLowerCase();
|
|
152413
|
+
return !normalizedToolName.startsWith("mcp__") && normalizedToolName.startsWith(normalizedName);
|
|
152414
|
+
});
|
|
152407
152415
|
const oneCharacterCompletions = prefixMatches.filter((toolName) => toolName.length === name.length + 1);
|
|
152408
152416
|
if (oneCharacterCompletions.length === 1) {
|
|
152409
152417
|
return oneCharacterCompletions[0];
|
|
@@ -191380,7 +191388,7 @@ async function fetchPortalUrl(accessToken) {
|
|
|
191380
191388
|
throw apiError;
|
|
191381
191389
|
}
|
|
191382
191390
|
}
|
|
191383
|
-
var subscriptionSchema, subscriptionsSchema, portalSchema;
|
|
191391
|
+
var subscriptionSourceSchema, subscriptionSchema, subscriptionsSchema, portalSchema;
|
|
191384
191392
|
var init_verbooSubscriptions = __esm(() => {
|
|
191385
191393
|
init_axios2();
|
|
191386
191394
|
init_zod();
|
|
@@ -191388,6 +191396,17 @@ var init_verbooSubscriptions = __esm(() => {
|
|
|
191388
191396
|
init_debug();
|
|
191389
191397
|
init_log3();
|
|
191390
191398
|
init_verbooApiError();
|
|
191399
|
+
subscriptionSourceSchema = exports_external2.union([
|
|
191400
|
+
exports_external2.enum([
|
|
191401
|
+
"stripe",
|
|
191402
|
+
"manual",
|
|
191403
|
+
"trial",
|
|
191404
|
+
"stripe_trial",
|
|
191405
|
+
"woovi",
|
|
191406
|
+
"managed_seat"
|
|
191407
|
+
]),
|
|
191408
|
+
exports_external2.string().min(1)
|
|
191409
|
+
]);
|
|
191391
191410
|
subscriptionSchema = exports_external2.object({
|
|
191392
191411
|
id: exports_external2.string().uuid(),
|
|
191393
191412
|
groupId: exports_external2.string().uuid(),
|
|
@@ -191401,7 +191420,7 @@ var init_verbooSubscriptions = __esm(() => {
|
|
|
191401
191420
|
status: exports_external2.string(),
|
|
191402
191421
|
models: exports_external2.array(exports_external2.string()).optional()
|
|
191403
191422
|
}).passthrough().optional(),
|
|
191404
|
-
source:
|
|
191423
|
+
source: subscriptionSourceSchema.optional(),
|
|
191405
191424
|
status: exports_external2.string().min(1),
|
|
191406
191425
|
wooviSubscriptionId: exports_external2.string().optional(),
|
|
191407
191426
|
currentPeriodStart: exports_external2.string().datetime({ offset: true }).optional(),
|
|
@@ -192809,6 +192828,102 @@ var init_openaiSchemaSanitizer = __esm(() => {
|
|
|
192809
192828
|
});
|
|
192810
192829
|
|
|
192811
192830
|
// src/services/api/codexShim.ts
|
|
192831
|
+
function maxBufferedToolArgumentChars() {
|
|
192832
|
+
const raw = process.env.VERBOO_MAX_BUFFERED_TOOL_ARGUMENT_CHARS;
|
|
192833
|
+
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
|
192834
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS;
|
|
192835
|
+
}
|
|
192836
|
+
function parseCompletedCodexTool(item) {
|
|
192837
|
+
if (typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.arguments.length > maxBufferedToolArgumentChars()) {
|
|
192838
|
+
throw new Error("Codex completed response contained a malformed tool call; no tool was committed");
|
|
192839
|
+
}
|
|
192840
|
+
for (const key of ["id", "call_id"]) {
|
|
192841
|
+
const value = item[key];
|
|
192842
|
+
if (value != null && (typeof value !== "string" || !value.trim())) {
|
|
192843
|
+
throw new Error("Codex completed response contained a malformed tool call ID; no tool was committed");
|
|
192844
|
+
}
|
|
192845
|
+
}
|
|
192846
|
+
const rawToolUseId = item.call_id ?? item.id;
|
|
192847
|
+
if (typeof rawToolUseId !== "string" || !rawToolUseId.trim()) {
|
|
192848
|
+
throw new Error("Codex completed response omitted its tool call ID; no tool was committed");
|
|
192849
|
+
}
|
|
192850
|
+
let input;
|
|
192851
|
+
try {
|
|
192852
|
+
input = JSON.parse(item.arguments);
|
|
192853
|
+
} catch {
|
|
192854
|
+
throw new Error("Codex completed response contained invalid tool arguments; no tool was committed");
|
|
192855
|
+
}
|
|
192856
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) {
|
|
192857
|
+
throw new Error("Codex completed response contained non-object tool arguments; no tool was committed");
|
|
192858
|
+
}
|
|
192859
|
+
return {
|
|
192860
|
+
input,
|
|
192861
|
+
toolUseId: rawToolUseId
|
|
192862
|
+
};
|
|
192863
|
+
}
|
|
192864
|
+
function parseCodexSseEventChunk(chunk) {
|
|
192865
|
+
const lines = chunk.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
192866
|
+
if (lines.length === 0)
|
|
192867
|
+
return;
|
|
192868
|
+
const eventLine = lines.find((line) => line.startsWith("event:"));
|
|
192869
|
+
const dataLines = lines.filter((line) => line.startsWith("data:"));
|
|
192870
|
+
if (dataLines.length === 0)
|
|
192871
|
+
return;
|
|
192872
|
+
const rawData = dataLines.map((line) => line.slice("data:".length).trimStart()).join(`
|
|
192873
|
+
`);
|
|
192874
|
+
if (rawData === "[DONE]")
|
|
192875
|
+
return;
|
|
192876
|
+
let data;
|
|
192877
|
+
try {
|
|
192878
|
+
const parsed = JSON.parse(rawData);
|
|
192879
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
192880
|
+
throw new Error("Codex SSE data was not a JSON object");
|
|
192881
|
+
}
|
|
192882
|
+
data = parsed;
|
|
192883
|
+
} catch (error41) {
|
|
192884
|
+
throw new Error("Codex SSE emitted invalid JSON; the response was not committed", { cause: error41 });
|
|
192885
|
+
}
|
|
192886
|
+
const framedEvent = eventLine?.slice("event:".length).trim() ?? "";
|
|
192887
|
+
const payloadEvent = typeof data.type === "string" ? data.type : "";
|
|
192888
|
+
if (framedEvent && payloadEvent && framedEvent !== payloadEvent) {
|
|
192889
|
+
throw new Error("Codex SSE event name contradicted its payload type; no tool was committed");
|
|
192890
|
+
}
|
|
192891
|
+
const event = framedEvent || payloadEvent;
|
|
192892
|
+
if (!event) {
|
|
192893
|
+
throw new Error("Codex SSE data omitted its event type; the response was not committed");
|
|
192894
|
+
}
|
|
192895
|
+
return { event, data };
|
|
192896
|
+
}
|
|
192897
|
+
function completedCodexVisibleText(response) {
|
|
192898
|
+
const output = Array.isArray(response.output) ? response.output : [];
|
|
192899
|
+
let visible = "";
|
|
192900
|
+
for (const item of output) {
|
|
192901
|
+
if (item?.type !== "message" || !Array.isArray(item.content))
|
|
192902
|
+
continue;
|
|
192903
|
+
for (const part of item.content) {
|
|
192904
|
+
if (part?.type === "output_text" && typeof part.text === "string") {
|
|
192905
|
+
visible += stripThinkTags(part.text);
|
|
192906
|
+
}
|
|
192907
|
+
}
|
|
192908
|
+
}
|
|
192909
|
+
return visible;
|
|
192910
|
+
}
|
|
192911
|
+
function requireCodexTerminalResponse(payload, expectedStatus) {
|
|
192912
|
+
const response = payload?.response;
|
|
192913
|
+
if (!response || typeof response !== "object" || Array.isArray(response)) {
|
|
192914
|
+
throw new Error(`Codex response.${expectedStatus} omitted its response object; the response was not committed`);
|
|
192915
|
+
}
|
|
192916
|
+
if (response.status !== expectedStatus) {
|
|
192917
|
+
throw new Error(`Codex response.${expectedStatus} carried a missing or contradictory status; the response was not committed`);
|
|
192918
|
+
}
|
|
192919
|
+
if (typeof response.id !== "string" || !response.id.trim()) {
|
|
192920
|
+
throw new Error(`Codex response.${expectedStatus} omitted its response ID; the response was not committed`);
|
|
192921
|
+
}
|
|
192922
|
+
if (!Array.isArray(response.output)) {
|
|
192923
|
+
throw new Error(`Codex response.${expectedStatus} omitted its output array; the response was not committed`);
|
|
192924
|
+
}
|
|
192925
|
+
return response;
|
|
192926
|
+
}
|
|
192812
192927
|
function makeUsage(usage) {
|
|
192813
192928
|
return buildAnthropicUsageFromRawUsage(usage);
|
|
192814
192929
|
}
|
|
@@ -193171,80 +193286,110 @@ async function performCodexRequest(options2) {
|
|
|
193171
193286
|
return response;
|
|
193172
193287
|
}
|
|
193173
193288
|
async function* readSseEvents(response, signal) {
|
|
193174
|
-
const
|
|
193175
|
-
if (!
|
|
193289
|
+
const responseBody = response.body;
|
|
193290
|
+
if (!responseBody)
|
|
193176
193291
|
return;
|
|
193292
|
+
const reader = responseBody.getReader();
|
|
193177
193293
|
const decoder = new TextDecoder;
|
|
193178
193294
|
let buffer = "";
|
|
193179
|
-
const STREAM_IDLE_TIMEOUT_MS =
|
|
193295
|
+
const STREAM_IDLE_TIMEOUT_MS = (() => {
|
|
193296
|
+
const raw = process.env.VERBOO_STREAM_IDLE_TIMEOUT_MS;
|
|
193297
|
+
const parsed = raw ? parseInt(raw, 10) : NaN;
|
|
193298
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : 120000;
|
|
193299
|
+
})();
|
|
193180
193300
|
let lastDataTime = Date.now();
|
|
193301
|
+
let pendingReaderCancellation;
|
|
193302
|
+
let reachedEOF = false;
|
|
193303
|
+
const cancelReader = (reason) => {
|
|
193304
|
+
if (pendingReaderCancellation)
|
|
193305
|
+
return;
|
|
193306
|
+
pendingReaderCancellation = reader.cancel(reason).then(() => {
|
|
193307
|
+
return;
|
|
193308
|
+
}, () => {
|
|
193309
|
+
return;
|
|
193310
|
+
});
|
|
193311
|
+
};
|
|
193181
193312
|
async function readWithTimeout() {
|
|
193182
193313
|
return new Promise((resolve19, reject) => {
|
|
193314
|
+
let settled = false;
|
|
193315
|
+
let abortCleanup;
|
|
193316
|
+
const cleanup = () => {
|
|
193317
|
+
clearTimeout(timeoutId);
|
|
193318
|
+
if (signal && abortCleanup)
|
|
193319
|
+
signal.removeEventListener("abort", abortCleanup);
|
|
193320
|
+
};
|
|
193321
|
+
const resolveOnce = (result) => {
|
|
193322
|
+
if (settled)
|
|
193323
|
+
return;
|
|
193324
|
+
settled = true;
|
|
193325
|
+
cleanup();
|
|
193326
|
+
if (result.value)
|
|
193327
|
+
lastDataTime = Date.now();
|
|
193328
|
+
resolve19(result);
|
|
193329
|
+
};
|
|
193330
|
+
const rejectOnce = (error41) => {
|
|
193331
|
+
if (settled)
|
|
193332
|
+
return;
|
|
193333
|
+
settled = true;
|
|
193334
|
+
cleanup();
|
|
193335
|
+
reject(error41);
|
|
193336
|
+
};
|
|
193183
193337
|
const timeoutId = setTimeout(() => {
|
|
193184
193338
|
const elapsed = Math.round((Date.now() - lastDataTime) / 1000);
|
|
193185
|
-
|
|
193339
|
+
const timeoutError = new Error(`Codex SSE stream idle for ${elapsed}s (limit: ${STREAM_IDLE_TIMEOUT_MS / 1000}s). Connection likely dropped.`);
|
|
193340
|
+
cancelReader(timeoutError);
|
|
193341
|
+
rejectOnce(timeoutError);
|
|
193186
193342
|
}, STREAM_IDLE_TIMEOUT_MS);
|
|
193187
|
-
let abortCleanup;
|
|
193188
193343
|
if (signal) {
|
|
193189
193344
|
abortCleanup = () => {
|
|
193190
|
-
|
|
193345
|
+
const abortError = signal.reason instanceof Error ? signal.reason : Object.assign(new Error("The operation was aborted"), {
|
|
193346
|
+
name: "AbortError"
|
|
193347
|
+
});
|
|
193348
|
+
cancelReader(abortError);
|
|
193349
|
+
rejectOnce(abortError);
|
|
193191
193350
|
};
|
|
193351
|
+
if (signal.aborted) {
|
|
193352
|
+
abortCleanup();
|
|
193353
|
+
return;
|
|
193354
|
+
}
|
|
193192
193355
|
signal.addEventListener("abort", abortCleanup, { once: true });
|
|
193193
193356
|
}
|
|
193194
|
-
reader.read().then(
|
|
193195
|
-
clearTimeout(timeoutId);
|
|
193196
|
-
if (signal && abortCleanup)
|
|
193197
|
-
signal.removeEventListener("abort", abortCleanup);
|
|
193198
|
-
if (result.value)
|
|
193199
|
-
lastDataTime = Date.now();
|
|
193200
|
-
resolve19(result);
|
|
193201
|
-
}, (err2) => {
|
|
193202
|
-
clearTimeout(timeoutId);
|
|
193203
|
-
if (signal && abortCleanup)
|
|
193204
|
-
signal.removeEventListener("abort", abortCleanup);
|
|
193205
|
-
reject(err2);
|
|
193206
|
-
});
|
|
193357
|
+
reader.read().then(resolveOnce, rejectOnce);
|
|
193207
193358
|
});
|
|
193208
193359
|
}
|
|
193209
|
-
|
|
193210
|
-
|
|
193211
|
-
|
|
193212
|
-
|
|
193213
|
-
|
|
193214
|
-
|
|
193215
|
-
|
|
193216
|
-
|
|
193217
|
-
|
|
193218
|
-
|
|
193219
|
-
|
|
193220
|
-
|
|
193221
|
-
|
|
193222
|
-
|
|
193223
|
-
const
|
|
193224
|
-
|
|
193225
|
-
|
|
193226
|
-
|
|
193227
|
-
const event = eventLine.slice(7).trim();
|
|
193228
|
-
const rawData = dataLines.map((line) => line.slice(6)).join(`
|
|
193229
|
-
`);
|
|
193230
|
-
if (rawData === "[DONE]")
|
|
193231
|
-
continue;
|
|
193232
|
-
let data;
|
|
193233
|
-
try {
|
|
193234
|
-
const parsed = JSON.parse(rawData);
|
|
193235
|
-
if (!parsed || typeof parsed !== "object")
|
|
193236
|
-
continue;
|
|
193237
|
-
data = parsed;
|
|
193238
|
-
} catch {
|
|
193239
|
-
continue;
|
|
193360
|
+
try {
|
|
193361
|
+
while (true) {
|
|
193362
|
+
const { done, value } = await readWithTimeout();
|
|
193363
|
+
if (done) {
|
|
193364
|
+
reachedEOF = true;
|
|
193365
|
+
buffer += decoder.decode();
|
|
193366
|
+
const finalEvent = parseCodexSseEventChunk(buffer);
|
|
193367
|
+
if (finalEvent)
|
|
193368
|
+
yield finalEvent;
|
|
193369
|
+
break;
|
|
193370
|
+
}
|
|
193371
|
+
buffer += decoder.decode(value, { stream: true });
|
|
193372
|
+
const chunks = buffer.split(/\r?\n\r?\n/);
|
|
193373
|
+
buffer = chunks.pop() ?? "";
|
|
193374
|
+
for (const chunk of chunks) {
|
|
193375
|
+
const event = parseCodexSseEventChunk(chunk);
|
|
193376
|
+
if (event)
|
|
193377
|
+
yield event;
|
|
193240
193378
|
}
|
|
193241
|
-
yield { event, data };
|
|
193242
193379
|
}
|
|
193380
|
+
} finally {
|
|
193381
|
+
if (!reachedEOF) {
|
|
193382
|
+
cancelReader("Codex SSE consumer completed before transport EOF");
|
|
193383
|
+
}
|
|
193384
|
+
await pendingReaderCancellation;
|
|
193385
|
+
try {
|
|
193386
|
+
reader.releaseLock();
|
|
193387
|
+
} catch {}
|
|
193243
193388
|
}
|
|
193244
193389
|
}
|
|
193245
193390
|
function determineStopReason(response, sawToolUse) {
|
|
193246
193391
|
const output = Array.isArray(response?.output) ? response.output : [];
|
|
193247
|
-
if (sawToolUse || output.some((item) => item?.type === "function_call")) {
|
|
193392
|
+
if (response?.status !== "incomplete" && (sawToolUse || output.some((item) => item?.type === "function_call"))) {
|
|
193248
193393
|
return "tool_use";
|
|
193249
193394
|
}
|
|
193250
193395
|
const incompleteReason = response?.incomplete_details?.reason;
|
|
@@ -193260,8 +193405,12 @@ async function collectCodexCompletedResponse(response, signal) {
|
|
|
193260
193405
|
const msg = event.data?.response?.error?.message ?? event.data?.error?.message ?? "Codex response failed";
|
|
193261
193406
|
throw APIError.generate(500, undefined, msg, new Headers);
|
|
193262
193407
|
}
|
|
193263
|
-
if (event.event === "response.completed"
|
|
193264
|
-
completedResponse = event.data
|
|
193408
|
+
if (event.event === "response.completed") {
|
|
193409
|
+
completedResponse = requireCodexTerminalResponse(event.data, "completed");
|
|
193410
|
+
break;
|
|
193411
|
+
}
|
|
193412
|
+
if (event.event === "response.incomplete") {
|
|
193413
|
+
completedResponse = requireCodexTerminalResponse(event.data, "incomplete");
|
|
193265
193414
|
break;
|
|
193266
193415
|
}
|
|
193267
193416
|
}
|
|
@@ -193274,18 +193423,26 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193274
193423
|
const messageId = makeMessageId();
|
|
193275
193424
|
const toolBlocksByItemId = new Map;
|
|
193276
193425
|
let activeTextBlockIndex = null;
|
|
193426
|
+
let emittedVisibleText = "";
|
|
193277
193427
|
const thinkFilter = createThinkTagFilter();
|
|
193278
193428
|
let nextContentBlockIndex = 0;
|
|
193279
193429
|
let sawToolUse = false;
|
|
193280
193430
|
let finalResponse;
|
|
193431
|
+
let terminalEvent;
|
|
193432
|
+
let terminalErrorMessage;
|
|
193433
|
+
let totalBufferedToolArgumentChars = 0;
|
|
193434
|
+
const toolArgumentCharsLimit = maxBufferedToolArgumentChars();
|
|
193281
193435
|
const closeActiveTextBlock = async function* () {
|
|
193282
193436
|
if (activeTextBlockIndex === null)
|
|
193283
193437
|
return;
|
|
193438
|
+
const textBlockIndex = activeTextBlockIndex;
|
|
193439
|
+
activeTextBlockIndex = null;
|
|
193284
193440
|
const tail = thinkFilter.flush();
|
|
193285
193441
|
if (tail) {
|
|
193442
|
+
emittedVisibleText += tail;
|
|
193286
193443
|
yield {
|
|
193287
193444
|
type: "content_block_delta",
|
|
193288
|
-
index:
|
|
193445
|
+
index: textBlockIndex,
|
|
193289
193446
|
delta: {
|
|
193290
193447
|
type: "text_delta",
|
|
193291
193448
|
text: tail
|
|
@@ -193294,9 +193451,8 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193294
193451
|
}
|
|
193295
193452
|
yield {
|
|
193296
193453
|
type: "content_block_stop",
|
|
193297
|
-
index:
|
|
193454
|
+
index: textBlockIndex
|
|
193298
193455
|
};
|
|
193299
|
-
activeTextBlockIndex = null;
|
|
193300
193456
|
};
|
|
193301
193457
|
const startTextBlockIfNeeded = async function* () {
|
|
193302
193458
|
if (activeTextBlockIndex !== null)
|
|
@@ -193308,6 +193464,21 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193308
193464
|
content_block: { type: "text", text: "" }
|
|
193309
193465
|
};
|
|
193310
193466
|
};
|
|
193467
|
+
const replaceToolArguments = (toolBlock, nextArguments) => {
|
|
193468
|
+
const nextTotal = totalBufferedToolArgumentChars - toolBlock.argumentsBuffer.length + nextArguments.length;
|
|
193469
|
+
if (nextArguments.length > toolArgumentCharsLimit || nextTotal > toolArgumentCharsLimit) {
|
|
193470
|
+
throw new Error("Codex tool arguments exceeded the configured safety limit; no tool was committed");
|
|
193471
|
+
}
|
|
193472
|
+
toolBlock.argumentsBuffer = nextArguments;
|
|
193473
|
+
totalBufferedToolArgumentChars = nextTotal;
|
|
193474
|
+
};
|
|
193475
|
+
const appendToolArguments = (toolBlock, delta) => {
|
|
193476
|
+
if (toolBlock.argumentsBuffer.length + delta.length > toolArgumentCharsLimit || totalBufferedToolArgumentChars + delta.length > toolArgumentCharsLimit) {
|
|
193477
|
+
throw new Error("Codex tool arguments exceeded the configured safety limit; no tool was committed");
|
|
193478
|
+
}
|
|
193479
|
+
toolBlock.argumentsBuffer += delta;
|
|
193480
|
+
totalBufferedToolArgumentChars += delta.length;
|
|
193481
|
+
};
|
|
193311
193482
|
const findToolBlockEntry = (item) => {
|
|
193312
193483
|
for (const candidate of [item.id, item.call_id]) {
|
|
193313
193484
|
if (candidate == null)
|
|
@@ -193316,12 +193487,18 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193316
193487
|
const toolBlock = toolBlocksByItemId.get(itemId);
|
|
193317
193488
|
if (toolBlock)
|
|
193318
193489
|
return [itemId, toolBlock];
|
|
193490
|
+
for (const entry of toolBlocksByItemId) {
|
|
193491
|
+
if (entry[0] === itemId || entry[1].toolUseId === itemId)
|
|
193492
|
+
return entry;
|
|
193493
|
+
}
|
|
193319
193494
|
}
|
|
193320
193495
|
return;
|
|
193321
193496
|
};
|
|
193322
|
-
const toolNameMayBeIncomplete = (name) => Boolean(name) && !advertisedToolNames.includes(name) && advertisedToolNames.some((toolName) => toolName.startsWith(name));
|
|
193323
193497
|
const canonicalizeFinalToolName = (toolBlock) => {
|
|
193324
193498
|
const resolvedName = resolveToolNameByUniquePrefix(advertisedToolNames, toolBlock.name);
|
|
193499
|
+
if (advertisedToolNames.length > 0 && !resolvedName) {
|
|
193500
|
+
throw new Error("Codex completed response selected an unadvertised tool; no tool was committed");
|
|
193501
|
+
}
|
|
193325
193502
|
if (resolvedName)
|
|
193326
193503
|
toolBlock.name = resolvedName;
|
|
193327
193504
|
};
|
|
@@ -193329,8 +193506,11 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193329
193506
|
if (typeof item.name === "string" && item.name) {
|
|
193330
193507
|
toolBlock.name = item.name;
|
|
193331
193508
|
}
|
|
193332
|
-
if (typeof item.arguments === "string"
|
|
193333
|
-
toolBlock
|
|
193509
|
+
if (typeof item.arguments === "string") {
|
|
193510
|
+
replaceToolArguments(toolBlock, item.arguments);
|
|
193511
|
+
}
|
|
193512
|
+
if (item.call_id != null || item.id != null) {
|
|
193513
|
+
toolBlock.toolUseId = String(item.call_id ?? item.id);
|
|
193334
193514
|
}
|
|
193335
193515
|
canonicalizeFinalToolName(toolBlock);
|
|
193336
193516
|
};
|
|
@@ -193348,14 +193528,10 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193348
193528
|
};
|
|
193349
193529
|
toolBlock.emittedArgumentsLength = toolBlock.argumentsBuffer.length;
|
|
193350
193530
|
};
|
|
193351
|
-
const startToolBlock = async function* (toolBlock
|
|
193531
|
+
const startToolBlock = async function* (toolBlock) {
|
|
193352
193532
|
if (toolBlock.hasStarted)
|
|
193353
193533
|
return;
|
|
193354
|
-
|
|
193355
|
-
return;
|
|
193356
|
-
}
|
|
193357
|
-
if (force)
|
|
193358
|
-
canonicalizeFinalToolName(toolBlock);
|
|
193534
|
+
canonicalizeFinalToolName(toolBlock);
|
|
193359
193535
|
toolBlock.hasStarted = true;
|
|
193360
193536
|
toolBlock.startedName = toolBlock.name || "tool";
|
|
193361
193537
|
yield {
|
|
@@ -193370,45 +193546,47 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193370
193546
|
};
|
|
193371
193547
|
yield* emitPendingToolArguments(toolBlock);
|
|
193372
193548
|
};
|
|
193373
|
-
const flushToolBlocks = async function* (
|
|
193549
|
+
const flushToolBlocks = async function* () {
|
|
193374
193550
|
const orderedBlocks = [...toolBlocksByItemId.values()].sort((a2, b) => a2.index - b.index);
|
|
193375
193551
|
for (const toolBlock of orderedBlocks) {
|
|
193376
193552
|
if (toolBlock.hasStopped)
|
|
193377
193553
|
continue;
|
|
193378
193554
|
if (!toolBlock.hasStarted) {
|
|
193379
|
-
|
|
193555
|
+
if (!toolBlock.isDone)
|
|
193556
|
+
break;
|
|
193557
|
+
yield* startToolBlock(toolBlock);
|
|
193380
193558
|
if (!toolBlock.hasStarted)
|
|
193381
193559
|
break;
|
|
193382
193560
|
}
|
|
193383
|
-
if (toolBlock.isDone && toolBlock.startedName !== (toolBlock.name || "tool")) {
|
|
193384
|
-
toolBlock.startedName = toolBlock.name || "tool";
|
|
193385
|
-
yield {
|
|
193386
|
-
type: "content_block_start",
|
|
193387
|
-
index: toolBlock.index,
|
|
193388
|
-
content_block: {
|
|
193389
|
-
type: "tool_use",
|
|
193390
|
-
id: toolBlock.toolUseId,
|
|
193391
|
-
name: toolBlock.startedName,
|
|
193392
|
-
input: {}
|
|
193393
|
-
}
|
|
193394
|
-
};
|
|
193395
|
-
}
|
|
193396
193561
|
yield* emitPendingToolArguments(toolBlock);
|
|
193397
193562
|
if (toolBlock.isDone) {
|
|
193563
|
+
toolBlock.hasStopped = true;
|
|
193398
193564
|
yield {
|
|
193399
193565
|
type: "content_block_stop",
|
|
193400
193566
|
index: toolBlock.index
|
|
193401
193567
|
};
|
|
193402
|
-
toolBlock.hasStopped = true;
|
|
193403
193568
|
}
|
|
193404
193569
|
}
|
|
193405
193570
|
};
|
|
193406
193571
|
const removeStoppedToolBlocks = () => {
|
|
193407
193572
|
for (const [itemId, toolBlock] of toolBlocksByItemId) {
|
|
193408
|
-
if (toolBlock.hasStopped)
|
|
193573
|
+
if (toolBlock.hasStopped) {
|
|
193574
|
+
totalBufferedToolArgumentChars -= toolBlock.argumentsBuffer.length;
|
|
193409
193575
|
toolBlocksByItemId.delete(itemId);
|
|
193576
|
+
}
|
|
193410
193577
|
}
|
|
193411
193578
|
};
|
|
193579
|
+
const closeOpenBlocksForFailure = async function* () {
|
|
193580
|
+
yield* closeActiveTextBlock();
|
|
193581
|
+
const orderedBlocks = [...new Set(toolBlocksByItemId.values())].sort((a2, b) => a2.index - b.index);
|
|
193582
|
+
for (const toolBlock of orderedBlocks) {
|
|
193583
|
+
if (!toolBlock.hasStarted || toolBlock.hasStopped)
|
|
193584
|
+
continue;
|
|
193585
|
+
toolBlock.hasStopped = true;
|
|
193586
|
+
yield { type: "content_block_stop", index: toolBlock.index };
|
|
193587
|
+
}
|
|
193588
|
+
toolBlocksByItemId.clear();
|
|
193589
|
+
};
|
|
193412
193590
|
yield {
|
|
193413
193591
|
type: "message_start",
|
|
193414
193592
|
message: {
|
|
@@ -193422,116 +193600,244 @@ async function* codexStreamToAnthropic(response, model2, signal, advertisedToolN
|
|
|
193422
193600
|
usage: makeUsage()
|
|
193423
193601
|
}
|
|
193424
193602
|
};
|
|
193425
|
-
|
|
193426
|
-
const
|
|
193427
|
-
|
|
193428
|
-
|
|
193429
|
-
|
|
193430
|
-
|
|
193603
|
+
try {
|
|
193604
|
+
for await (const event of readSseEvents(response, signal)) {
|
|
193605
|
+
const payload = event.data;
|
|
193606
|
+
if (event.event === "response.output_item.added") {
|
|
193607
|
+
const item = payload.item;
|
|
193608
|
+
if (item?.type === "function_call") {
|
|
193609
|
+
yield* closeActiveTextBlock();
|
|
193610
|
+
const blockIndex = nextContentBlockIndex++;
|
|
193611
|
+
const toolUseId = item.call_id ?? item.id ?? `call_${blockIndex}`;
|
|
193612
|
+
const toolBlock = {
|
|
193613
|
+
index: blockIndex,
|
|
193614
|
+
toolUseId,
|
|
193615
|
+
name: typeof item.name === "string" ? item.name : "",
|
|
193616
|
+
argumentsBuffer: "",
|
|
193617
|
+
emittedArgumentsLength: 0,
|
|
193618
|
+
hasStarted: false,
|
|
193619
|
+
isDone: false,
|
|
193620
|
+
hasStopped: false
|
|
193621
|
+
};
|
|
193622
|
+
if (typeof item.arguments === "string") {
|
|
193623
|
+
replaceToolArguments(toolBlock, item.arguments);
|
|
193624
|
+
}
|
|
193625
|
+
const itemKey = String(item.id ?? toolUseId);
|
|
193626
|
+
if (toolBlocksByItemId.has(itemKey)) {
|
|
193627
|
+
throw new Error("Codex stream repeated a tool item ID; no tool was committed");
|
|
193628
|
+
}
|
|
193629
|
+
toolBlocksByItemId.set(itemKey, toolBlock);
|
|
193630
|
+
}
|
|
193631
|
+
continue;
|
|
193632
|
+
}
|
|
193633
|
+
if (event.event === "response.content_part.added") {
|
|
193634
|
+
if (payload.part?.type === "output_text") {
|
|
193635
|
+
if (toolBlocksByItemId.size > 0) {
|
|
193636
|
+
throw new Error("Codex emitted text after a reserved tool block; the out-of-order response was not committed");
|
|
193637
|
+
}
|
|
193638
|
+
yield* startTextBlockIfNeeded();
|
|
193639
|
+
}
|
|
193640
|
+
continue;
|
|
193641
|
+
}
|
|
193642
|
+
if (event.event === "response.output_text.delta") {
|
|
193643
|
+
if (toolBlocksByItemId.size > 0) {
|
|
193644
|
+
throw new Error("Codex emitted text after a reserved tool block; the out-of-order response was not committed");
|
|
193645
|
+
}
|
|
193646
|
+
yield* startTextBlockIfNeeded();
|
|
193647
|
+
if (activeTextBlockIndex !== null) {
|
|
193648
|
+
const visible = thinkFilter.feed(payload.delta ?? "");
|
|
193649
|
+
if (visible) {
|
|
193650
|
+
emittedVisibleText += visible;
|
|
193651
|
+
yield {
|
|
193652
|
+
type: "content_block_delta",
|
|
193653
|
+
index: activeTextBlockIndex,
|
|
193654
|
+
delta: {
|
|
193655
|
+
type: "text_delta",
|
|
193656
|
+
text: visible
|
|
193657
|
+
}
|
|
193658
|
+
};
|
|
193659
|
+
}
|
|
193660
|
+
}
|
|
193661
|
+
continue;
|
|
193662
|
+
}
|
|
193663
|
+
if (event.event === "response.function_call_arguments.delta") {
|
|
193664
|
+
const toolBlock = toolBlocksByItemId.get(String(payload.item_id ?? ""));
|
|
193665
|
+
if (toolBlock) {
|
|
193666
|
+
if (typeof payload.delta === "string") {
|
|
193667
|
+
appendToolArguments(toolBlock, payload.delta);
|
|
193668
|
+
}
|
|
193669
|
+
}
|
|
193670
|
+
continue;
|
|
193671
|
+
}
|
|
193672
|
+
if (event.event === "response.output_item.done") {
|
|
193673
|
+
const item = payload.item;
|
|
193674
|
+
if (item?.type === "function_call") {
|
|
193675
|
+
const toolBlockEntry = findToolBlockEntry(item);
|
|
193676
|
+
if (toolBlockEntry) {
|
|
193677
|
+
const [, toolBlock] = toolBlockEntry;
|
|
193678
|
+
applyFinalToolItem(toolBlock, item);
|
|
193679
|
+
toolBlock.isDone = true;
|
|
193680
|
+
}
|
|
193681
|
+
} else if (item?.type === "message") {
|
|
193682
|
+
yield* closeActiveTextBlock();
|
|
193683
|
+
}
|
|
193684
|
+
continue;
|
|
193685
|
+
}
|
|
193686
|
+
if (event.event === "response.completed") {
|
|
193687
|
+
terminalEvent = "completed";
|
|
193688
|
+
finalResponse = requireCodexTerminalResponse(payload, "completed");
|
|
193689
|
+
break;
|
|
193690
|
+
}
|
|
193691
|
+
if (event.event === "response.incomplete") {
|
|
193692
|
+
terminalEvent = "incomplete";
|
|
193693
|
+
finalResponse = requireCodexTerminalResponse(payload, "incomplete");
|
|
193694
|
+
break;
|
|
193695
|
+
}
|
|
193696
|
+
if (event.event === "response.failed") {
|
|
193697
|
+
terminalEvent = "failed";
|
|
193698
|
+
terminalErrorMessage = payload?.response?.error?.message ?? payload?.error?.message ?? "Codex response failed";
|
|
193699
|
+
break;
|
|
193700
|
+
}
|
|
193701
|
+
}
|
|
193702
|
+
yield* closeActiveTextBlock();
|
|
193703
|
+
if (terminalEvent === "failed") {
|
|
193704
|
+
toolBlocksByItemId.clear();
|
|
193705
|
+
throw APIError.generate(500, undefined, terminalErrorMessage ?? "Codex response failed", new Headers);
|
|
193706
|
+
}
|
|
193707
|
+
if (!terminalEvent || !finalResponse) {
|
|
193708
|
+
toolBlocksByItemId.clear();
|
|
193709
|
+
throw APIError.generate(500, undefined, "Codex response ended without a terminal payload", new Headers);
|
|
193710
|
+
}
|
|
193711
|
+
const finalVisibleText = completedCodexVisibleText(finalResponse);
|
|
193712
|
+
let missingSuffix = "";
|
|
193713
|
+
if (!emittedVisibleText) {
|
|
193714
|
+
missingSuffix = finalVisibleText;
|
|
193715
|
+
} else if (finalVisibleText.startsWith(emittedVisibleText)) {
|
|
193716
|
+
missingSuffix = finalVisibleText.slice(emittedVisibleText.length);
|
|
193717
|
+
} else if (finalVisibleText !== emittedVisibleText) {
|
|
193718
|
+
throw APIError.generate(500, undefined, "Codex completed text contradicted streamed text; response was not committed", new Headers);
|
|
193719
|
+
}
|
|
193720
|
+
if (missingSuffix && toolBlocksByItemId.size > 0) {
|
|
193721
|
+
toolBlocksByItemId.clear();
|
|
193722
|
+
throw APIError.generate(500, undefined, "Codex completed text arrived after a reserved tool block; the out-of-order response was not committed", new Headers);
|
|
193723
|
+
}
|
|
193724
|
+
if (missingSuffix) {
|
|
193725
|
+
yield* startTextBlockIfNeeded();
|
|
193726
|
+
if (activeTextBlockIndex !== null) {
|
|
193727
|
+
emittedVisibleText += missingSuffix;
|
|
193728
|
+
yield {
|
|
193729
|
+
type: "content_block_delta",
|
|
193730
|
+
index: activeTextBlockIndex,
|
|
193731
|
+
delta: { type: "text_delta", text: missingSuffix }
|
|
193732
|
+
};
|
|
193733
|
+
}
|
|
193734
|
+
yield* closeActiveTextBlock();
|
|
193735
|
+
}
|
|
193736
|
+
if (terminalEvent === "incomplete") {
|
|
193737
|
+
toolBlocksByItemId.clear();
|
|
193738
|
+
yield {
|
|
193739
|
+
type: "message_delta",
|
|
193740
|
+
delta: {
|
|
193741
|
+
stop_reason: determineStopReason(finalResponse, false),
|
|
193742
|
+
stop_sequence: null
|
|
193743
|
+
},
|
|
193744
|
+
usage: makeUsage(finalResponse.usage)
|
|
193745
|
+
};
|
|
193746
|
+
yield { type: "message_stop" };
|
|
193747
|
+
return;
|
|
193748
|
+
}
|
|
193749
|
+
const finalOutput = Array.isArray(finalResponse?.output) ? finalResponse.output : [];
|
|
193750
|
+
const reservedToolIndices = [...toolBlocksByItemId.values()].map((toolBlock) => toolBlock.index);
|
|
193751
|
+
const firstFinalToolIndex = reservedToolIndices.length > 0 ? Math.min(...reservedToolIndices) : nextContentBlockIndex;
|
|
193752
|
+
const completedToolBlocks = new Set;
|
|
193753
|
+
const completedToolCallIds = new Set;
|
|
193754
|
+
for (const item of finalOutput) {
|
|
193755
|
+
if (item?.type !== "function_call")
|
|
193756
|
+
continue;
|
|
193757
|
+
try {
|
|
193758
|
+
parseCompletedCodexTool(item);
|
|
193759
|
+
} catch (error41) {
|
|
193760
|
+
toolBlocksByItemId.clear();
|
|
193761
|
+
throw APIError.generate(500, undefined, error41 instanceof Error ? error41.message : "Invalid Codex tool call", new Headers);
|
|
193762
|
+
}
|
|
193763
|
+
let toolBlockEntry = findToolBlockEntry(item);
|
|
193764
|
+
if (!toolBlockEntry) {
|
|
193431
193765
|
const blockIndex = nextContentBlockIndex++;
|
|
193432
|
-
const toolUseId = item
|
|
193766
|
+
const { toolUseId } = parseCompletedCodexTool(item);
|
|
193433
193767
|
const toolBlock = {
|
|
193434
193768
|
index: blockIndex,
|
|
193435
193769
|
toolUseId,
|
|
193436
|
-
name:
|
|
193437
|
-
argumentsBuffer:
|
|
193770
|
+
name: "",
|
|
193771
|
+
argumentsBuffer: "",
|
|
193438
193772
|
emittedArgumentsLength: 0,
|
|
193439
193773
|
hasStarted: false,
|
|
193440
193774
|
isDone: false,
|
|
193441
193775
|
hasStopped: false
|
|
193442
193776
|
};
|
|
193443
|
-
|
|
193444
|
-
|
|
193445
|
-
|
|
193777
|
+
const itemKey = String(item.id ?? item.call_id ?? toolUseId);
|
|
193778
|
+
toolBlocksByItemId.set(itemKey, toolBlock);
|
|
193779
|
+
toolBlockEntry = [itemKey, toolBlock];
|
|
193446
193780
|
}
|
|
193447
|
-
|
|
193448
|
-
|
|
193449
|
-
|
|
193450
|
-
if (payload.part?.type === "output_text") {
|
|
193451
|
-
yield* startTextBlockIfNeeded();
|
|
193781
|
+
if (completedToolBlocks.has(toolBlockEntry[1])) {
|
|
193782
|
+
toolBlocksByItemId.clear();
|
|
193783
|
+
throw APIError.generate(500, undefined, "Codex completed response repeated a tool call; no tool was committed", new Headers);
|
|
193452
193784
|
}
|
|
193453
|
-
|
|
193454
|
-
|
|
193455
|
-
|
|
193456
|
-
|
|
193457
|
-
if (activeTextBlockIndex !== null) {
|
|
193458
|
-
const visible = thinkFilter.feed(payload.delta ?? "");
|
|
193459
|
-
if (visible) {
|
|
193460
|
-
yield {
|
|
193461
|
-
type: "content_block_delta",
|
|
193462
|
-
index: activeTextBlockIndex,
|
|
193463
|
-
delta: {
|
|
193464
|
-
type: "text_delta",
|
|
193465
|
-
text: visible
|
|
193466
|
-
}
|
|
193467
|
-
};
|
|
193468
|
-
}
|
|
193785
|
+
applyFinalToolItem(toolBlockEntry[1], item);
|
|
193786
|
+
if (completedToolCallIds.has(toolBlockEntry[1].toolUseId)) {
|
|
193787
|
+
toolBlocksByItemId.clear();
|
|
193788
|
+
throw APIError.generate(500, undefined, "Codex completed response reused a tool call ID; no tool was committed", new Headers);
|
|
193469
193789
|
}
|
|
193470
|
-
|
|
193790
|
+
completedToolCallIds.add(toolBlockEntry[1].toolUseId);
|
|
193791
|
+
toolBlockEntry[1].isDone = true;
|
|
193792
|
+
completedToolBlocks.add(toolBlockEntry[1]);
|
|
193471
193793
|
}
|
|
193472
|
-
|
|
193473
|
-
|
|
193474
|
-
|
|
193475
|
-
if (typeof payload.delta === "string") {
|
|
193476
|
-
toolBlock.argumentsBuffer += payload.delta;
|
|
193477
|
-
}
|
|
193478
|
-
yield* flushToolBlocks();
|
|
193479
|
-
}
|
|
193480
|
-
continue;
|
|
193794
|
+
let authoritativeToolOffset = 0;
|
|
193795
|
+
for (const toolBlock of completedToolBlocks) {
|
|
193796
|
+
toolBlock.index = firstFinalToolIndex + authoritativeToolOffset++;
|
|
193481
193797
|
}
|
|
193482
|
-
if (
|
|
193483
|
-
|
|
193484
|
-
if (item?.type === "function_call") {
|
|
193485
|
-
const toolBlockEntry = findToolBlockEntry(item);
|
|
193486
|
-
if (toolBlockEntry) {
|
|
193487
|
-
const [, toolBlock] = toolBlockEntry;
|
|
193488
|
-
applyFinalToolItem(toolBlock, item);
|
|
193489
|
-
toolBlock.isDone = true;
|
|
193490
|
-
yield* flushToolBlocks();
|
|
193491
|
-
removeStoppedToolBlocks();
|
|
193492
|
-
}
|
|
193493
|
-
} else if (item?.type === "message") {
|
|
193494
|
-
yield* closeActiveTextBlock();
|
|
193495
|
-
}
|
|
193496
|
-
continue;
|
|
193798
|
+
if (completedToolBlocks.size > 0) {
|
|
193799
|
+
nextContentBlockIndex = firstFinalToolIndex + completedToolBlocks.size;
|
|
193497
193800
|
}
|
|
193498
|
-
|
|
193499
|
-
|
|
193500
|
-
|
|
193501
|
-
|
|
193502
|
-
|
|
193503
|
-
const msg = payload?.response?.error?.message ?? payload?.error?.message ?? "Codex response failed";
|
|
193504
|
-
throw APIError.generate(500, undefined, msg, new Headers);
|
|
193801
|
+
for (const [itemId, toolBlock] of toolBlocksByItemId) {
|
|
193802
|
+
if (!completedToolBlocks.has(toolBlock)) {
|
|
193803
|
+
totalBufferedToolArgumentChars -= toolBlock.argumentsBuffer.length;
|
|
193804
|
+
toolBlocksByItemId.delete(itemId);
|
|
193805
|
+
}
|
|
193505
193806
|
}
|
|
193807
|
+
sawToolUse = completedToolBlocks.size > 0;
|
|
193808
|
+
yield* flushToolBlocks();
|
|
193809
|
+
removeStoppedToolBlocks();
|
|
193810
|
+
yield {
|
|
193811
|
+
type: "message_delta",
|
|
193812
|
+
delta: {
|
|
193813
|
+
stop_reason: determineStopReason(finalResponse, sawToolUse),
|
|
193814
|
+
stop_sequence: null
|
|
193815
|
+
},
|
|
193816
|
+
usage: makeUsage(finalResponse?.usage)
|
|
193817
|
+
};
|
|
193818
|
+
yield { type: "message_stop" };
|
|
193819
|
+
} catch (error41) {
|
|
193820
|
+
yield* closeOpenBlocksForFailure();
|
|
193821
|
+
throw error41;
|
|
193506
193822
|
}
|
|
193507
|
-
yield* closeActiveTextBlock();
|
|
193508
|
-
const finalOutput = Array.isArray(finalResponse?.output) ? finalResponse.output : [];
|
|
193509
|
-
for (const item of finalOutput) {
|
|
193510
|
-
if (item?.type !== "function_call")
|
|
193511
|
-
continue;
|
|
193512
|
-
const toolBlockEntry = findToolBlockEntry(item);
|
|
193513
|
-
if (!toolBlockEntry)
|
|
193514
|
-
continue;
|
|
193515
|
-
applyFinalToolItem(toolBlockEntry[1], item);
|
|
193516
|
-
}
|
|
193517
|
-
for (const toolBlock of toolBlocksByItemId.values()) {
|
|
193518
|
-
toolBlock.isDone = true;
|
|
193519
|
-
}
|
|
193520
|
-
yield* flushToolBlocks(true);
|
|
193521
|
-
removeStoppedToolBlocks();
|
|
193522
|
-
yield {
|
|
193523
|
-
type: "message_delta",
|
|
193524
|
-
delta: {
|
|
193525
|
-
stop_reason: determineStopReason(finalResponse, sawToolUse),
|
|
193526
|
-
stop_sequence: null
|
|
193527
|
-
},
|
|
193528
|
-
usage: makeUsage(finalResponse?.usage)
|
|
193529
|
-
};
|
|
193530
|
-
yield { type: "message_stop" };
|
|
193531
193823
|
}
|
|
193532
193824
|
function convertCodexResponseToAnthropicMessage(data, model2, advertisedToolNames = []) {
|
|
193533
193825
|
const content = [];
|
|
193534
193826
|
const output = Array.isArray(data.output) ? data.output : [];
|
|
193827
|
+
if (data.status == null) {
|
|
193828
|
+
throw new Error("Codex response omitted its terminal status; the response was not committed");
|
|
193829
|
+
}
|
|
193830
|
+
if (data.status === "failed") {
|
|
193831
|
+
const failureMessage = typeof data.error?.message === "string" ? `: ${data.error.message}` : "";
|
|
193832
|
+
throw new Error(`Codex response failed${failureMessage}`);
|
|
193833
|
+
}
|
|
193834
|
+
if (data.status !== "completed" && data.status !== "incomplete") {
|
|
193835
|
+
throw new Error(`Codex response carried non-terminal status "${String(data.status)}"; the response was not committed`);
|
|
193836
|
+
}
|
|
193837
|
+
const mayCommitTools = data.status === "completed";
|
|
193838
|
+
const completedToolCallIds = new Set;
|
|
193839
|
+
let completedToolArgumentChars = 0;
|
|
193840
|
+
const toolArgumentCharsLimit = maxBufferedToolArgumentChars();
|
|
193535
193841
|
for (const item of output) {
|
|
193536
193842
|
if (item?.type === "message" && Array.isArray(item.content)) {
|
|
193537
193843
|
for (const part of item.content) {
|
|
@@ -193544,17 +193850,23 @@ function convertCodexResponseToAnthropicMessage(data, model2, advertisedToolName
|
|
|
193544
193850
|
}
|
|
193545
193851
|
continue;
|
|
193546
193852
|
}
|
|
193547
|
-
if (item?.type === "function_call") {
|
|
193853
|
+
if (item?.type === "function_call" && mayCommitTools) {
|
|
193854
|
+
const { input, toolUseId } = parseCompletedCodexTool(item);
|
|
193855
|
+
completedToolArgumentChars += item.arguments.length;
|
|
193856
|
+
if (completedToolArgumentChars > toolArgumentCharsLimit) {
|
|
193857
|
+
throw new Error("Codex tool arguments exceeded the configured safety limit; no tool was committed");
|
|
193858
|
+
}
|
|
193859
|
+
if (completedToolCallIds.has(toolUseId)) {
|
|
193860
|
+
throw new Error("Codex completed response reused a tool call ID; no tool was committed");
|
|
193861
|
+
}
|
|
193862
|
+
completedToolCallIds.add(toolUseId);
|
|
193548
193863
|
const toolName = resolveToolNameByUniquePrefix(advertisedToolNames, item.name ?? "") ?? item.name ?? "tool";
|
|
193549
|
-
|
|
193550
|
-
|
|
193551
|
-
input = JSON.parse(item.arguments ?? "{}");
|
|
193552
|
-
} catch {
|
|
193553
|
-
input = { raw: item.arguments ?? "" };
|
|
193864
|
+
if (advertisedToolNames.length > 0 && !resolveToolNameByUniquePrefix(advertisedToolNames, item.name ?? "")) {
|
|
193865
|
+
throw new Error("Codex completed response selected an unadvertised tool; no tool was committed");
|
|
193554
193866
|
}
|
|
193555
193867
|
content.push({
|
|
193556
193868
|
type: "tool_use",
|
|
193557
|
-
id:
|
|
193869
|
+
id: toolUseId,
|
|
193558
193870
|
name: toolName,
|
|
193559
193871
|
input
|
|
193560
193872
|
});
|
|
@@ -193571,6 +193883,7 @@ function convertCodexResponseToAnthropicMessage(data, model2, advertisedToolName
|
|
|
193571
193883
|
usage: makeUsage(data.usage)
|
|
193572
193884
|
};
|
|
193573
193885
|
}
|
|
193886
|
+
var DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS;
|
|
193574
193887
|
var init_codexShim = __esm(() => {
|
|
193575
193888
|
init_sdk();
|
|
193576
193889
|
init_Tool();
|
|
@@ -193579,6 +193892,7 @@ var init_codexShim = __esm(() => {
|
|
|
193579
193892
|
init_fetchWithProxyRetry();
|
|
193580
193893
|
init_openaiSchemaSanitizer();
|
|
193581
193894
|
init_thinkTagSanitizer();
|
|
193895
|
+
DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS = 64 * 1024 * 1024;
|
|
193582
193896
|
});
|
|
193583
193897
|
|
|
193584
193898
|
// src/services/api/visionDelegate.ts
|
|
@@ -194820,29 +195134,84 @@ function convertChunkUsage(usage) {
|
|
|
194820
195134
|
return;
|
|
194821
195135
|
return buildAnthropicUsageFromRawUsage(usage);
|
|
194822
195136
|
}
|
|
194823
|
-
function
|
|
195137
|
+
function hasInvalidToolArguments(raw, toolName) {
|
|
195138
|
+
const trimmed2 = raw.trim();
|
|
195139
|
+
if (!hasToolFieldMapping(toolName)) {
|
|
195140
|
+
try {
|
|
195141
|
+
const parsed = JSON.parse(raw);
|
|
195142
|
+
return parsed === null || typeof parsed !== "object" || Array.isArray(parsed);
|
|
195143
|
+
} catch {
|
|
195144
|
+
return true;
|
|
195145
|
+
}
|
|
195146
|
+
}
|
|
195147
|
+
if (!trimmed2.startsWith("{"))
|
|
195148
|
+
return false;
|
|
194824
195149
|
try {
|
|
194825
|
-
|
|
194826
|
-
return
|
|
195150
|
+
JSON.parse(raw);
|
|
195151
|
+
return false;
|
|
194827
195152
|
} catch {
|
|
194828
|
-
|
|
194829
|
-
|
|
194830
|
-
|
|
194831
|
-
|
|
194832
|
-
|
|
194833
|
-
|
|
194834
|
-
|
|
194835
|
-
|
|
195153
|
+
return !(toolName.toLowerCase() === "bash" && /^\{\s*[^{}]*;\s*\}$/.test(trimmed2));
|
|
195154
|
+
}
|
|
195155
|
+
}
|
|
195156
|
+
function maxBufferedToolArgumentChars2() {
|
|
195157
|
+
const raw = process.env.VERBOO_MAX_BUFFERED_TOOL_ARGUMENT_CHARS;
|
|
195158
|
+
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
|
195159
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS2;
|
|
195160
|
+
}
|
|
195161
|
+
function mergeOpaqueMetadata(current, next) {
|
|
195162
|
+
const merged = Object.fromEntries(Object.entries(current ?? {}));
|
|
195163
|
+
for (const [key, nextValue] of Object.entries(next)) {
|
|
195164
|
+
const currentValue = merged[key];
|
|
195165
|
+
if (currentValue !== null && nextValue !== null && typeof currentValue === "object" && typeof nextValue === "object" && !Array.isArray(currentValue) && !Array.isArray(nextValue)) {
|
|
195166
|
+
Object.defineProperty(merged, key, {
|
|
195167
|
+
value: mergeOpaqueMetadata(currentValue, nextValue),
|
|
195168
|
+
enumerable: true,
|
|
195169
|
+
configurable: true,
|
|
195170
|
+
writable: true
|
|
195171
|
+
});
|
|
195172
|
+
} else {
|
|
195173
|
+
Object.defineProperty(merged, key, {
|
|
195174
|
+
value: nextValue,
|
|
195175
|
+
enumerable: true,
|
|
195176
|
+
configurable: true,
|
|
195177
|
+
writable: true
|
|
195178
|
+
});
|
|
194836
195179
|
}
|
|
194837
|
-
return null;
|
|
194838
195180
|
}
|
|
195181
|
+
return merged;
|
|
194839
195182
|
}
|
|
194840
|
-
function
|
|
194841
|
-
|
|
194842
|
-
|
|
194843
|
-
if (
|
|
194844
|
-
return
|
|
194845
|
-
|
|
195183
|
+
function resolveStreamedToolName(advertisedToolNames, fragments) {
|
|
195184
|
+
const nonEmpty = fragments.filter(Boolean);
|
|
195185
|
+
const concatenated = nonEmpty.join("");
|
|
195186
|
+
if (advertisedToolNames.length === 0) {
|
|
195187
|
+
return { name: concatenated, ambiguous: false };
|
|
195188
|
+
}
|
|
195189
|
+
const candidates = new Set([concatenated]);
|
|
195190
|
+
let cumulative = "";
|
|
195191
|
+
for (const fragment of nonEmpty) {
|
|
195192
|
+
if (!cumulative) {
|
|
195193
|
+
cumulative = fragment;
|
|
195194
|
+
continue;
|
|
195195
|
+
}
|
|
195196
|
+
const currentFolded = cumulative.toLowerCase();
|
|
195197
|
+
const fragmentFolded = fragment.toLowerCase();
|
|
195198
|
+
if (fragmentFolded.startsWith(currentFolded)) {
|
|
195199
|
+
cumulative = fragment;
|
|
195200
|
+
} else if (!currentFolded.startsWith(fragmentFolded)) {
|
|
195201
|
+
cumulative += fragment;
|
|
195202
|
+
}
|
|
195203
|
+
}
|
|
195204
|
+
candidates.add(cumulative);
|
|
195205
|
+
const resolved = new Set;
|
|
195206
|
+
for (const candidate of candidates) {
|
|
195207
|
+
const toolName = resolveToolNameByUniquePrefix(advertisedToolNames, candidate);
|
|
195208
|
+
if (toolName)
|
|
195209
|
+
resolved.add(toolName);
|
|
195210
|
+
}
|
|
195211
|
+
if (resolved.size === 1) {
|
|
195212
|
+
return { name: [...resolved][0], ambiguous: false };
|
|
195213
|
+
}
|
|
195214
|
+
return { name: concatenated, ambiguous: true };
|
|
194846
195215
|
}
|
|
194847
195216
|
function getAdvertisedToolNames(params) {
|
|
194848
195217
|
return (params.tools ?? []).flatMap((tool) => typeof tool.name === "string" && tool.name && tool.name !== "ToolSearchTool" ? [tool.name] : []);
|
|
@@ -194923,7 +195292,11 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
194923
195292
|
let lastStopReason = null;
|
|
194924
195293
|
let hasEmittedFinalUsage = false;
|
|
194925
195294
|
let hasProcessedFinishReason = false;
|
|
195295
|
+
let sawDoneMarker = false;
|
|
194926
195296
|
const streamState = createStreamState();
|
|
195297
|
+
let nextSyntheticProtocolIndex = -2;
|
|
195298
|
+
let totalBufferedToolArgumentChars = 0;
|
|
195299
|
+
const toolArgumentCharsLimit = maxBufferedToolArgumentChars2();
|
|
194927
195300
|
yield {
|
|
194928
195301
|
type: "message_start",
|
|
194929
195302
|
message: {
|
|
@@ -194942,9 +195315,11 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
194942
195315
|
}
|
|
194943
195316
|
}
|
|
194944
195317
|
};
|
|
194945
|
-
const
|
|
194946
|
-
if (!
|
|
194947
|
-
|
|
195318
|
+
const responseBody = response.body;
|
|
195319
|
+
if (!responseBody) {
|
|
195320
|
+
throw new Error("Upstream SSE response had no readable body");
|
|
195321
|
+
}
|
|
195322
|
+
const reader = responseBody.getReader();
|
|
194948
195323
|
const decoder = new TextDecoder;
|
|
194949
195324
|
let buffer = "";
|
|
194950
195325
|
const STREAM_IDLE_TIMEOUT_MS = (() => {
|
|
@@ -194954,32 +195329,61 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
194954
195329
|
})();
|
|
194955
195330
|
let lastDataTime = Date.now();
|
|
194956
195331
|
const streamStartedAt = Date.now();
|
|
195332
|
+
let pendingReaderCancellation;
|
|
195333
|
+
const cancelReader = (reason) => {
|
|
195334
|
+
pendingReaderCancellation = reader.cancel(reason).then(() => {
|
|
195335
|
+
return;
|
|
195336
|
+
}, () => {
|
|
195337
|
+
return;
|
|
195338
|
+
});
|
|
195339
|
+
};
|
|
194957
195340
|
async function readWithTimeout() {
|
|
194958
195341
|
return new Promise((resolve19, reject) => {
|
|
195342
|
+
let settled = false;
|
|
195343
|
+
let abortCleanup;
|
|
195344
|
+
const cleanup = () => {
|
|
195345
|
+
clearTimeout(timeoutId);
|
|
195346
|
+
if (signal && abortCleanup) {
|
|
195347
|
+
signal.removeEventListener("abort", abortCleanup);
|
|
195348
|
+
}
|
|
195349
|
+
};
|
|
195350
|
+
const resolveOnce = (result) => {
|
|
195351
|
+
if (settled)
|
|
195352
|
+
return;
|
|
195353
|
+
settled = true;
|
|
195354
|
+
cleanup();
|
|
195355
|
+
if (result.value)
|
|
195356
|
+
lastDataTime = Date.now();
|
|
195357
|
+
resolve19(result);
|
|
195358
|
+
};
|
|
195359
|
+
const rejectOnce = (error41) => {
|
|
195360
|
+
if (settled)
|
|
195361
|
+
return;
|
|
195362
|
+
settled = true;
|
|
195363
|
+
cleanup();
|
|
195364
|
+
reject(error41);
|
|
195365
|
+
};
|
|
194959
195366
|
const timeoutId = setTimeout(() => {
|
|
194960
195367
|
const elapsed = Math.round((Date.now() - lastDataTime) / 1000);
|
|
194961
|
-
|
|
195368
|
+
const timeoutError = new Error(`OpenAI/Gemini SSE stream idle for ${elapsed}s (limit: ${STREAM_IDLE_TIMEOUT_MS / 1000}s). Connection likely dropped.`);
|
|
195369
|
+
cancelReader(timeoutError);
|
|
195370
|
+
rejectOnce(timeoutError);
|
|
194962
195371
|
}, STREAM_IDLE_TIMEOUT_MS);
|
|
194963
|
-
let abortCleanup;
|
|
194964
195372
|
if (signal) {
|
|
194965
195373
|
abortCleanup = () => {
|
|
194966
|
-
|
|
195374
|
+
const abortError = signal.reason instanceof Error ? signal.reason : Object.assign(new Error("The operation was aborted"), {
|
|
195375
|
+
name: "AbortError"
|
|
195376
|
+
});
|
|
195377
|
+
cancelReader(abortError);
|
|
195378
|
+
rejectOnce(abortError);
|
|
194967
195379
|
};
|
|
195380
|
+
if (signal.aborted) {
|
|
195381
|
+
abortCleanup();
|
|
195382
|
+
return;
|
|
195383
|
+
}
|
|
194968
195384
|
signal.addEventListener("abort", abortCleanup, { once: true });
|
|
194969
195385
|
}
|
|
194970
|
-
reader.read().then(
|
|
194971
|
-
clearTimeout(timeoutId);
|
|
194972
|
-
if (signal && abortCleanup)
|
|
194973
|
-
signal.removeEventListener("abort", abortCleanup);
|
|
194974
|
-
if (result.value)
|
|
194975
|
-
lastDataTime = Date.now();
|
|
194976
|
-
resolve19(result);
|
|
194977
|
-
}, (err2) => {
|
|
194978
|
-
clearTimeout(timeoutId);
|
|
194979
|
-
if (signal && abortCleanup)
|
|
194980
|
-
signal.removeEventListener("abort", abortCleanup);
|
|
194981
|
-
reject(err2);
|
|
194982
|
-
});
|
|
195386
|
+
reader.read().then(resolveOnce, rejectOnce);
|
|
194983
195387
|
});
|
|
194984
195388
|
}
|
|
194985
195389
|
const closeActiveContentBlock = async function* () {
|
|
@@ -195000,25 +195404,38 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195000
195404
|
contentBlockIndex++;
|
|
195001
195405
|
hasEmittedContentStart = false;
|
|
195002
195406
|
};
|
|
195003
|
-
const
|
|
195004
|
-
|
|
195005
|
-
|
|
195006
|
-
|
|
195007
|
-
|
|
195407
|
+
const finalizeToolCall = (toolCall) => {
|
|
195408
|
+
const distinctIds = [...new Set(toolCall.idFragments.filter(Boolean))];
|
|
195409
|
+
if (distinctIds.length > 1) {
|
|
195410
|
+
return "conflicting_tool_call_ids";
|
|
195411
|
+
}
|
|
195412
|
+
if (distinctIds.length === 1)
|
|
195413
|
+
toolCall.id = distinctIds[0];
|
|
195414
|
+
const resolvedName = resolveStreamedToolName(advertisedToolNames, toolCall.nameFragments);
|
|
195415
|
+
toolCall.name = resolvedName.name;
|
|
195416
|
+
if (resolvedName.ambiguous)
|
|
195417
|
+
return "ambiguous_tool_name_fragments";
|
|
195418
|
+
if (!toolCall.id.trim())
|
|
195419
|
+
return "missing_tool_call_id";
|
|
195420
|
+
if (!toolCall.name.trim())
|
|
195421
|
+
return "missing_tool_name";
|
|
195422
|
+
if (toolCall.ambiguousArgumentFraming) {
|
|
195423
|
+
return "ambiguous_tool_argument_fragments";
|
|
195424
|
+
}
|
|
195425
|
+
if (hasInvalidToolArguments(toolCall.jsonBuffer, toolCall.name)) {
|
|
195426
|
+
return "malformed_structured_tool_arguments";
|
|
195427
|
+
}
|
|
195428
|
+
return null;
|
|
195008
195429
|
};
|
|
195009
|
-
const startToolCall = async function* (toolCall
|
|
195010
|
-
if (toolCall.hasStarted || !toolCall.id || !toolCall.name)
|
|
195430
|
+
const startToolCall = async function* (toolCall) {
|
|
195431
|
+
if (toolCall.hasStarted || toolCall.index === null || !toolCall.id || !toolCall.name)
|
|
195011
195432
|
return;
|
|
195012
|
-
|
|
195013
|
-
return;
|
|
195014
|
-
if (force)
|
|
195015
|
-
canonicalizeFinalToolName(toolCall);
|
|
195433
|
+
const blockIndex = toolCall.index;
|
|
195016
195434
|
toolCall.normalizeAtStop = hasToolFieldMapping(toolCall.name);
|
|
195017
195435
|
toolCall.hasStarted = true;
|
|
195018
|
-
toolCall.startedName = toolCall.name;
|
|
195019
195436
|
yield {
|
|
195020
195437
|
type: "content_block_start",
|
|
195021
|
-
index:
|
|
195438
|
+
index: blockIndex,
|
|
195022
195439
|
content_block: {
|
|
195023
195440
|
type: "tool_use",
|
|
195024
195441
|
id: toolCall.id,
|
|
@@ -195033,7 +195450,7 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195033
195450
|
if (!toolCall.normalizeAtStop && toolCall.jsonBuffer) {
|
|
195034
195451
|
yield {
|
|
195035
195452
|
type: "content_block_delta",
|
|
195036
|
-
index:
|
|
195453
|
+
index: blockIndex,
|
|
195037
195454
|
delta: {
|
|
195038
195455
|
type: "input_json_delta",
|
|
195039
195456
|
partial_json: toolCall.jsonBuffer
|
|
@@ -195042,20 +195459,28 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195042
195459
|
toolCall.emittedJsonLength = toolCall.jsonBuffer.length;
|
|
195043
195460
|
}
|
|
195044
195461
|
};
|
|
195045
|
-
const
|
|
195046
|
-
|
|
195047
|
-
for (const toolCall of
|
|
195462
|
+
const orderedActiveToolCalls = () => [...activeToolCalls.entries()].sort(([leftProtocolIndex], [rightProtocolIndex]) => leftProtocolIndex - rightProtocolIndex).map(([, toolCall]) => toolCall);
|
|
195463
|
+
const flushReadyToolCalls = async function* () {
|
|
195464
|
+
for (const toolCall of orderedActiveToolCalls()) {
|
|
195465
|
+
if (toolCall.index === null) {
|
|
195466
|
+
toolCall.index = contentBlockIndex++;
|
|
195467
|
+
}
|
|
195048
195468
|
if (!toolCall.hasStarted) {
|
|
195049
|
-
|
|
195050
|
-
break;
|
|
195051
|
-
yield* startToolCall(toolCall, force);
|
|
195469
|
+
yield* startToolCall(toolCall);
|
|
195052
195470
|
if (!toolCall.hasStarted) {
|
|
195053
|
-
if (!force)
|
|
195054
|
-
break;
|
|
195055
195471
|
continue;
|
|
195056
195472
|
}
|
|
195057
195473
|
}
|
|
195058
|
-
if (
|
|
195474
|
+
if (toolCall.normalizeAtStop) {
|
|
195475
|
+
yield {
|
|
195476
|
+
type: "content_block_delta",
|
|
195477
|
+
index: toolCall.index,
|
|
195478
|
+
delta: {
|
|
195479
|
+
type: "input_json_delta",
|
|
195480
|
+
partial_json: JSON.stringify(normalizeToolArguments(toolCall.name, toolCall.jsonBuffer))
|
|
195481
|
+
}
|
|
195482
|
+
};
|
|
195483
|
+
} else if (toolCall.emittedJsonLength < toolCall.jsonBuffer.length) {
|
|
195059
195484
|
yield {
|
|
195060
195485
|
type: "content_block_delta",
|
|
195061
195486
|
index: toolCall.index,
|
|
@@ -195066,7 +195491,61 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195066
195491
|
};
|
|
195067
195492
|
toolCall.emittedJsonLength = toolCall.jsonBuffer.length;
|
|
195068
195493
|
}
|
|
195494
|
+
toolCall.hasStopped = true;
|
|
195495
|
+
yield { type: "content_block_stop", index: toolCall.index };
|
|
195496
|
+
}
|
|
195497
|
+
};
|
|
195498
|
+
const discardActiveToolCalls = (reason) => {
|
|
195499
|
+
if (activeToolCalls.size > 0) {
|
|
195500
|
+
logForDebugging(JSON.stringify({
|
|
195501
|
+
type: "discarded_uncommitted_tool_calls",
|
|
195502
|
+
model: model2,
|
|
195503
|
+
reason,
|
|
195504
|
+
count: activeToolCalls.size
|
|
195505
|
+
}), { level: "warn" });
|
|
195506
|
+
}
|
|
195507
|
+
activeToolCalls.clear();
|
|
195508
|
+
};
|
|
195509
|
+
const closeOpenBlocksForFailure = async function* () {
|
|
195510
|
+
if (hasEmittedContentStart) {
|
|
195511
|
+
yield* closeActiveContentBlock();
|
|
195512
|
+
}
|
|
195513
|
+
if (hasEmittedThinkingStart && !hasClosedThinking) {
|
|
195514
|
+
const thinkingBlockIndex = contentBlockIndex;
|
|
195515
|
+
hasClosedThinking = true;
|
|
195516
|
+
contentBlockIndex++;
|
|
195517
|
+
yield { type: "content_block_stop", index: thinkingBlockIndex };
|
|
195518
|
+
}
|
|
195519
|
+
for (const toolCall of orderedActiveToolCalls()) {
|
|
195520
|
+
if (!toolCall.hasStarted || toolCall.hasStopped || toolCall.index === null)
|
|
195521
|
+
continue;
|
|
195522
|
+
toolCall.hasStopped = true;
|
|
195523
|
+
yield { type: "content_block_stop", index: toolCall.index };
|
|
195524
|
+
}
|
|
195525
|
+
discardActiveToolCalls("stream_exception");
|
|
195526
|
+
};
|
|
195527
|
+
const resolveProtocolIndex = (toolCall, batchSize) => {
|
|
195528
|
+
if (Number.isInteger(toolCall.index))
|
|
195529
|
+
return toolCall.index;
|
|
195530
|
+
if (typeof toolCall.id === "string" && toolCall.id) {
|
|
195531
|
+
const matches = [...activeToolCalls.entries()].filter(([, active]) => active.idFragments.includes(toolCall.id));
|
|
195532
|
+
if (matches.length === 1)
|
|
195533
|
+
return matches[0][0];
|
|
195534
|
+
if (matches.length > 1) {
|
|
195535
|
+
throw new Error("Upstream omitted tool index and reused an ambiguous tool call ID; no tool was committed.");
|
|
195536
|
+
}
|
|
195537
|
+
if (activeToolCalls.size === 1 && batchSize === 1) {
|
|
195538
|
+
return activeToolCalls.keys().next().value;
|
|
195539
|
+
}
|
|
195540
|
+
return nextSyntheticProtocolIndex--;
|
|
195541
|
+
}
|
|
195542
|
+
if (batchSize === 1 && activeToolCalls.size === 1) {
|
|
195543
|
+
return activeToolCalls.keys().next().value;
|
|
195069
195544
|
}
|
|
195545
|
+
if (batchSize === 1 && activeToolCalls.size === 0) {
|
|
195546
|
+
return nextSyntheticProtocolIndex--;
|
|
195547
|
+
}
|
|
195548
|
+
throw new Error("Upstream omitted tool indices for parallel calls; no tool was committed.");
|
|
195070
195549
|
};
|
|
195071
195550
|
try {
|
|
195072
195551
|
while (true) {
|
|
@@ -195081,18 +195560,7 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195081
195560
|
duration_ms: Date.now() - streamStartedAt,
|
|
195082
195561
|
had_content: hasEmittedContentStart || hasEmittedThinkingStart
|
|
195083
195562
|
}), { level: "error" });
|
|
195084
|
-
|
|
195085
|
-
yield* closeActiveContentBlock();
|
|
195086
|
-
}
|
|
195087
|
-
if (hasEmittedThinkingStart && !hasClosedThinking) {
|
|
195088
|
-
yield { type: "content_block_stop", index: contentBlockIndex };
|
|
195089
|
-
}
|
|
195090
|
-
for (const [, toolCall] of activeToolCalls) {
|
|
195091
|
-
if (toolCall.hasStarted) {
|
|
195092
|
-
yield { type: "content_block_stop", index: toolCall.index };
|
|
195093
|
-
}
|
|
195094
|
-
}
|
|
195095
|
-
activeToolCalls.clear();
|
|
195563
|
+
discardActiveToolCalls("premature_eof");
|
|
195096
195564
|
throw new Error(`Upstream stream closed without finish_reason after ${elapsedSec}s — likely a guard_proxy/vLLM disconnect. The session was interrupted, not completed.`);
|
|
195097
195565
|
}
|
|
195098
195566
|
break;
|
|
@@ -195103,15 +195571,23 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195103
195571
|
buffer = lines.pop() ?? "";
|
|
195104
195572
|
for (const line of lines) {
|
|
195105
195573
|
const trimmed2 = line.trim();
|
|
195106
|
-
if (!trimmed2
|
|
195574
|
+
if (!trimmed2)
|
|
195107
195575
|
continue;
|
|
195576
|
+
if (trimmed2 === "data: [DONE]") {
|
|
195577
|
+
if (!hasProcessedFinishReason) {
|
|
195578
|
+
throw new Error("Upstream SSE emitted [DONE] without finish_reason; the response was not committed.");
|
|
195579
|
+
}
|
|
195580
|
+
sawDoneMarker = true;
|
|
195581
|
+
cancelReader("OpenAI SSE completed");
|
|
195582
|
+
break;
|
|
195583
|
+
}
|
|
195108
195584
|
if (!trimmed2.startsWith("data: "))
|
|
195109
195585
|
continue;
|
|
195110
195586
|
let chunk;
|
|
195111
195587
|
try {
|
|
195112
195588
|
chunk = JSON.parse(trimmed2.slice(6));
|
|
195113
195589
|
} catch {
|
|
195114
|
-
|
|
195590
|
+
throw new Error("Upstream emitted invalid SSE JSON; the response was not committed.");
|
|
195115
195591
|
}
|
|
195116
195592
|
const routerStatus = chunk.router_status;
|
|
195117
195593
|
if (typeof routerStatus === "string") {
|
|
@@ -195123,18 +195599,7 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195123
195599
|
const inStreamError = chunk.error;
|
|
195124
195600
|
if (inStreamError && typeof inStreamError === "object") {
|
|
195125
195601
|
const message = typeof inStreamError.message === "string" ? inStreamError.message : "Provider returned an in-stream error";
|
|
195126
|
-
|
|
195127
|
-
yield* closeActiveContentBlock();
|
|
195128
|
-
}
|
|
195129
|
-
if (hasEmittedThinkingStart && !hasClosedThinking) {
|
|
195130
|
-
yield { type: "content_block_stop", index: contentBlockIndex };
|
|
195131
|
-
}
|
|
195132
|
-
for (const [, toolCall] of activeToolCalls) {
|
|
195133
|
-
if (toolCall.hasStarted) {
|
|
195134
|
-
yield { type: "content_block_stop", index: toolCall.index };
|
|
195135
|
-
}
|
|
195136
|
-
}
|
|
195137
|
-
activeToolCalls.clear();
|
|
195602
|
+
discardActiveToolCalls("in_stream_error");
|
|
195138
195603
|
const errorPayload = {
|
|
195139
195604
|
error: {
|
|
195140
195605
|
message,
|
|
@@ -195146,8 +195611,33 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195146
195611
|
}
|
|
195147
195612
|
const chunkUsage = convertChunkUsage(chunk.usage);
|
|
195148
195613
|
for (const choice of chunk.choices ?? []) {
|
|
195149
|
-
const delta = choice.delta;
|
|
195614
|
+
const delta = choice.delta ?? {};
|
|
195615
|
+
if (choice.finish_reason != null && (typeof choice.finish_reason !== "string" || !choice.finish_reason.trim())) {
|
|
195616
|
+
throw new Error("Upstream emitted a malformed finish_reason; the response was not committed.");
|
|
195617
|
+
}
|
|
195618
|
+
if (hasProcessedFinishReason) {
|
|
195619
|
+
const hasLateOutput = Object.entries(delta).some(([key, value2]) => {
|
|
195620
|
+
if (key === "role" || value2 == null || value2 === "")
|
|
195621
|
+
return false;
|
|
195622
|
+
if (Array.isArray(value2))
|
|
195623
|
+
return value2.length > 0;
|
|
195624
|
+
if (typeof value2 === "object") {
|
|
195625
|
+
return Object.keys(value2).length > 0;
|
|
195626
|
+
}
|
|
195627
|
+
return true;
|
|
195628
|
+
});
|
|
195629
|
+
if (hasLateOutput) {
|
|
195630
|
+
throw new Error("Upstream emitted assistant output after finish_reason; the late output was not committed.");
|
|
195631
|
+
}
|
|
195632
|
+
continue;
|
|
195633
|
+
}
|
|
195634
|
+
if (activeToolCalls.size > 0 && (delta.reasoning_content != null && delta.reasoning_content !== "" || delta.content != null && delta.content !== "")) {
|
|
195635
|
+
throw new Error("Upstream emitted text after a reserved tool block; the out-of-order response was not committed.");
|
|
195636
|
+
}
|
|
195150
195637
|
if (delta.reasoning_content != null && delta.reasoning_content !== "") {
|
|
195638
|
+
if (hasClosedThinking || hasEmittedContentStart) {
|
|
195639
|
+
throw new Error("Upstream emitted reasoning after visible text; the out-of-order delta was not committed.");
|
|
195640
|
+
}
|
|
195151
195641
|
if (!hasEmittedThinkingStart) {
|
|
195152
195642
|
yield {
|
|
195153
195643
|
type: "content_block_start",
|
|
@@ -195158,7 +195648,7 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195158
195648
|
}
|
|
195159
195649
|
yield {
|
|
195160
195650
|
type: "content_block_delta",
|
|
195161
|
-
index:
|
|
195651
|
+
index: contentBlockIndex,
|
|
195162
195652
|
delta: {
|
|
195163
195653
|
type: "thinking_delta",
|
|
195164
195654
|
thinking: delta.reasoning_content
|
|
@@ -195189,9 +195679,31 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195189
195679
|
}
|
|
195190
195680
|
processStreamChunk(streamState, delta.content);
|
|
195191
195681
|
}
|
|
195192
|
-
|
|
195193
|
-
|
|
195194
|
-
|
|
195682
|
+
const streamedToolCalls = [
|
|
195683
|
+
...delta.tool_calls ?? []
|
|
195684
|
+
];
|
|
195685
|
+
if (delta.function_call) {
|
|
195686
|
+
streamedToolCalls.push({
|
|
195687
|
+
index: -1,
|
|
195688
|
+
id: `${messageId}_function_call`,
|
|
195689
|
+
type: "function",
|
|
195690
|
+
function: delta.function_call
|
|
195691
|
+
});
|
|
195692
|
+
}
|
|
195693
|
+
if (streamedToolCalls.length > 0) {
|
|
195694
|
+
for (const tc of streamedToolCalls) {
|
|
195695
|
+
if (tc.id != null && typeof tc.id !== "string" || tc.function?.name != null && typeof tc.function.name !== "string" || tc.function?.arguments != null && typeof tc.function.arguments !== "string") {
|
|
195696
|
+
discardActiveToolCalls("malformed_tool_call_delta");
|
|
195697
|
+
throw new Error("Upstream returned malformed tool call fields; no tool was committed.");
|
|
195698
|
+
}
|
|
195699
|
+
let protocolIndex;
|
|
195700
|
+
try {
|
|
195701
|
+
protocolIndex = resolveProtocolIndex(tc, streamedToolCalls.length);
|
|
195702
|
+
} catch (error41) {
|
|
195703
|
+
discardActiveToolCalls("ambiguous_missing_tool_index");
|
|
195704
|
+
throw error41;
|
|
195705
|
+
}
|
|
195706
|
+
let active = activeToolCalls.get(protocolIndex);
|
|
195195
195707
|
if (!active) {
|
|
195196
195708
|
if (hasEmittedThinkingStart && !hasClosedThinking) {
|
|
195197
195709
|
yield {
|
|
@@ -195207,40 +195719,52 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195207
195719
|
active = {
|
|
195208
195720
|
id: "",
|
|
195209
195721
|
name: "",
|
|
195210
|
-
|
|
195722
|
+
idFragments: [],
|
|
195723
|
+
nameFragments: [],
|
|
195724
|
+
index: null,
|
|
195211
195725
|
jsonBuffer: "",
|
|
195726
|
+
ambiguousArgumentFraming: false,
|
|
195212
195727
|
emittedJsonLength: 0,
|
|
195213
195728
|
normalizeAtStop: false,
|
|
195214
195729
|
hasStarted: false,
|
|
195215
|
-
|
|
195730
|
+
hasStopped: false
|
|
195216
195731
|
};
|
|
195217
|
-
activeToolCalls.set(
|
|
195732
|
+
activeToolCalls.set(protocolIndex, active);
|
|
195218
195733
|
}
|
|
195219
|
-
if (tc.id
|
|
195220
|
-
active.
|
|
195734
|
+
if (tc.id) {
|
|
195735
|
+
active.idFragments.push(tc.id);
|
|
195221
195736
|
}
|
|
195222
195737
|
const nameFragment = tc.function?.name;
|
|
195223
195738
|
if (nameFragment) {
|
|
195224
|
-
active.
|
|
195739
|
+
active.nameFragments.push(nameFragment);
|
|
195225
195740
|
}
|
|
195226
195741
|
const argumentFragment = tc.function?.arguments;
|
|
195227
195742
|
if (typeof argumentFragment === "string") {
|
|
195743
|
+
if (argumentFragment.length > 0 && active.jsonBuffer.length > 0 && argumentFragment.startsWith(active.jsonBuffer)) {
|
|
195744
|
+
active.ambiguousArgumentFraming = true;
|
|
195745
|
+
}
|
|
195746
|
+
if (active.jsonBuffer.length + argumentFragment.length > toolArgumentCharsLimit || totalBufferedToolArgumentChars + argumentFragment.length > toolArgumentCharsLimit) {
|
|
195747
|
+
discardActiveToolCalls("tool_arguments_limit_exceeded");
|
|
195748
|
+
throw new Error("Upstream tool arguments exceeded the configured safety limit; no tool was committed.");
|
|
195749
|
+
}
|
|
195228
195750
|
active.jsonBuffer += argumentFragment;
|
|
195751
|
+
totalBufferedToolArgumentChars += argumentFragment.length;
|
|
195229
195752
|
processStreamChunk(streamState, argumentFragment);
|
|
195230
195753
|
}
|
|
195231
195754
|
const thoughtSignature = tc.thought_signature;
|
|
195232
|
-
|
|
195233
|
-
if (
|
|
195234
|
-
|
|
195235
|
-
|
|
195236
|
-
...extraContent
|
|
195755
|
+
let extraContent;
|
|
195756
|
+
if (typeof thoughtSignature === "string" && thoughtSignature) {
|
|
195757
|
+
extraContent = {
|
|
195758
|
+
google: { thought_signature: thoughtSignature }
|
|
195237
195759
|
};
|
|
195238
195760
|
}
|
|
195239
|
-
if (
|
|
195240
|
-
|
|
195761
|
+
if (tc.extra_content) {
|
|
195762
|
+
extraContent = mergeOpaqueMetadata(extraContent, tc.extra_content);
|
|
195763
|
+
}
|
|
195764
|
+
if (extraContent) {
|
|
195765
|
+
active.extra_content = mergeOpaqueMetadata(active.extra_content, extraContent);
|
|
195241
195766
|
}
|
|
195242
195767
|
}
|
|
195243
|
-
yield* flushReadyToolCalls();
|
|
195244
195768
|
}
|
|
195245
195769
|
if (choice.finish_reason && !hasProcessedFinishReason) {
|
|
195246
195770
|
hasProcessedFinishReason = true;
|
|
@@ -195252,97 +195776,32 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195252
195776
|
if (hasEmittedContentStart) {
|
|
195253
195777
|
yield* closeActiveContentBlock();
|
|
195254
195778
|
}
|
|
195255
|
-
|
|
195256
|
-
|
|
195257
|
-
|
|
195258
|
-
|
|
195259
|
-
|
|
195260
|
-
|
|
195261
|
-
|
|
195262
|
-
|
|
195263
|
-
|
|
195264
|
-
|
|
195265
|
-
|
|
195266
|
-
|
|
195267
|
-
|
|
195268
|
-
if (wasStarted && (tc.extra_content || tc.startedName !== tc.name)) {
|
|
195269
|
-
yield {
|
|
195270
|
-
type: "content_block_start",
|
|
195271
|
-
index: tc.index,
|
|
195272
|
-
content_block: {
|
|
195273
|
-
type: "tool_use",
|
|
195274
|
-
id: tc.id,
|
|
195275
|
-
name: tc.name,
|
|
195276
|
-
input: {},
|
|
195277
|
-
...tc.extra_content ? { extra_content: tc.extra_content } : {},
|
|
195278
|
-
...tc.extra_content?.google?.thought_signature ? {
|
|
195279
|
-
signature: (tc.extra_content?.google).thought_signature
|
|
195280
|
-
} : {}
|
|
195281
|
-
}
|
|
195282
|
-
};
|
|
195283
|
-
}
|
|
195284
|
-
if (tc.normalizeAtStop) {
|
|
195285
|
-
let partialJson;
|
|
195286
|
-
if (choice.finish_reason === "length") {
|
|
195287
|
-
partialJson = tc.jsonBuffer;
|
|
195288
|
-
} else {
|
|
195289
|
-
const repairedStructuredJson = repairPossiblyTruncatedObjectJson(tc.jsonBuffer);
|
|
195290
|
-
if (repairedStructuredJson) {
|
|
195291
|
-
partialJson = repairedStructuredJson;
|
|
195292
|
-
} else {
|
|
195293
|
-
partialJson = JSON.stringify(normalizeToolArguments(tc.name, tc.jsonBuffer));
|
|
195294
|
-
}
|
|
195295
|
-
}
|
|
195296
|
-
yield {
|
|
195297
|
-
type: "content_block_delta",
|
|
195298
|
-
index: tc.index,
|
|
195299
|
-
delta: {
|
|
195300
|
-
type: "input_json_delta",
|
|
195301
|
-
partial_json: partialJson
|
|
195302
|
-
}
|
|
195303
|
-
};
|
|
195304
|
-
yield { type: "content_block_stop", index: tc.index };
|
|
195305
|
-
continue;
|
|
195306
|
-
}
|
|
195307
|
-
if (tc.emittedJsonLength < tc.jsonBuffer.length) {
|
|
195308
|
-
yield {
|
|
195309
|
-
type: "content_block_delta",
|
|
195310
|
-
index: tc.index,
|
|
195311
|
-
delta: {
|
|
195312
|
-
type: "input_json_delta",
|
|
195313
|
-
partial_json: tc.jsonBuffer.slice(tc.emittedJsonLength)
|
|
195314
|
-
}
|
|
195315
|
-
};
|
|
195316
|
-
tc.emittedJsonLength = tc.jsonBuffer.length;
|
|
195317
|
-
}
|
|
195318
|
-
let suffixToAdd = "";
|
|
195319
|
-
if (tc.jsonBuffer) {
|
|
195320
|
-
try {
|
|
195321
|
-
JSON.parse(tc.jsonBuffer);
|
|
195322
|
-
} catch {
|
|
195323
|
-
const str = tc.jsonBuffer.trimEnd();
|
|
195324
|
-
for (const combo of JSON_REPAIR_SUFFIXES) {
|
|
195325
|
-
try {
|
|
195326
|
-
JSON.parse(str + combo);
|
|
195327
|
-
suffixToAdd = combo;
|
|
195328
|
-
break;
|
|
195329
|
-
} catch {}
|
|
195779
|
+
const isToolFinish = choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call";
|
|
195780
|
+
if (!isToolFinish) {
|
|
195781
|
+
discardActiveToolCalls(`finish_reason:${choice.finish_reason}`);
|
|
195782
|
+
} else {
|
|
195783
|
+
const invalidReasons = [];
|
|
195784
|
+
const finalizedToolCallIds = new Set;
|
|
195785
|
+
for (const toolCall of activeToolCalls.values()) {
|
|
195786
|
+
const invalidReason = finalizeToolCall(toolCall);
|
|
195787
|
+
if (invalidReason)
|
|
195788
|
+
invalidReasons.push(invalidReason);
|
|
195789
|
+
if (toolCall.id) {
|
|
195790
|
+
if (finalizedToolCallIds.has(toolCall.id)) {
|
|
195791
|
+
invalidReasons.push("duplicate_tool_call_id_across_indices");
|
|
195330
195792
|
}
|
|
195793
|
+
finalizedToolCallIds.add(toolCall.id);
|
|
195331
195794
|
}
|
|
195795
|
+
toolCall.normalizeAtStop = hasToolFieldMapping(toolCall.name);
|
|
195332
195796
|
}
|
|
195333
|
-
if (
|
|
195334
|
-
|
|
195335
|
-
|
|
195336
|
-
index: tc.index,
|
|
195337
|
-
delta: {
|
|
195338
|
-
type: "input_json_delta",
|
|
195339
|
-
partial_json: suffixToAdd
|
|
195340
|
-
}
|
|
195341
|
-
};
|
|
195797
|
+
if (activeToolCalls.size === 0 || invalidReasons.length > 0) {
|
|
195798
|
+
discardActiveToolCalls(invalidReasons.length > 0 ? invalidReasons.join(",") : "tool_finish_without_tool_call");
|
|
195799
|
+
throw new Error(`Upstream returned ${choice.finish_reason} with an incomplete or ambiguous tool call; no tool was committed.`);
|
|
195342
195800
|
}
|
|
195343
|
-
yield
|
|
195801
|
+
yield* flushReadyToolCalls();
|
|
195802
|
+
activeToolCalls.clear();
|
|
195344
195803
|
}
|
|
195345
|
-
const stopReason = choice.finish_reason === "tool_calls" ? "tool_use" : choice.finish_reason === "length" ? "max_tokens" : "end_turn";
|
|
195804
|
+
const stopReason = choice.finish_reason === "tool_calls" || choice.finish_reason === "function_call" ? "tool_use" : choice.finish_reason === "length" ? "max_tokens" : "end_turn";
|
|
195346
195805
|
if (choice.finish_reason === "content_filter" || choice.finish_reason === "safety") {
|
|
195347
195806
|
if (!hasEmittedContentStart) {
|
|
195348
195807
|
yield {
|
|
@@ -195382,6 +195841,9 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195382
195841
|
}
|
|
195383
195842
|
};
|
|
195384
195843
|
}
|
|
195844
|
+
if (hasEmittedContentStart) {
|
|
195845
|
+
yield* closeActiveContentBlock();
|
|
195846
|
+
}
|
|
195385
195847
|
lastStopReason = stopReason;
|
|
195386
195848
|
yield {
|
|
195387
195849
|
type: "message_delta",
|
|
@@ -195402,9 +195864,19 @@ async function* openaiStreamToAnthropic(response, model2, signal, warmingHint, a
|
|
|
195402
195864
|
hasEmittedFinalUsage = true;
|
|
195403
195865
|
}
|
|
195404
195866
|
}
|
|
195867
|
+
if (sawDoneMarker)
|
|
195868
|
+
break;
|
|
195405
195869
|
}
|
|
195870
|
+
} catch (error41) {
|
|
195871
|
+
yield* closeOpenBlocksForFailure();
|
|
195872
|
+
throw error41;
|
|
195406
195873
|
} finally {
|
|
195407
|
-
|
|
195874
|
+
await pendingReaderCancellation;
|
|
195875
|
+
try {
|
|
195876
|
+
reader.releaseLock();
|
|
195877
|
+
} catch (releaseError) {
|
|
195878
|
+
logForDebugging(`Failed to release OpenAI stream reader after cancellation: ${releaseError instanceof Error ? releaseError.message : String(releaseError)}`, { level: "warn" });
|
|
195879
|
+
}
|
|
195408
195880
|
}
|
|
195409
195881
|
const stats = getStreamStats(streamState);
|
|
195410
195882
|
if (stats.totalChunks > 0) {
|
|
@@ -196010,6 +196482,10 @@ class OpenAIShimMessages {
|
|
|
196010
196482
|
}
|
|
196011
196483
|
_convertNonStreamingResponse(data, model2, advertisedToolNames = []) {
|
|
196012
196484
|
const choice = data.choices?.[0];
|
|
196485
|
+
const toolArgumentCharsLimit = maxBufferedToolArgumentChars2();
|
|
196486
|
+
if (!choice || typeof choice.finish_reason !== "string" || !choice.finish_reason.trim()) {
|
|
196487
|
+
throw new Error("Upstream non-streaming response ended without a terminal choice; no output was committed.");
|
|
196488
|
+
}
|
|
196013
196489
|
const content = [];
|
|
196014
196490
|
const reasoningText = choice?.message?.reasoning_content;
|
|
196015
196491
|
if (typeof reasoningText === "string" && reasoningText) {
|
|
@@ -196037,8 +196513,34 @@ class OpenAIShimMessages {
|
|
|
196037
196513
|
});
|
|
196038
196514
|
}
|
|
196039
196515
|
}
|
|
196040
|
-
|
|
196041
|
-
|
|
196516
|
+
const isToolFinish = choice?.finish_reason === "tool_calls" || choice?.finish_reason === "function_call";
|
|
196517
|
+
const completedToolCalls = [
|
|
196518
|
+
...choice?.message?.tool_calls ?? [],
|
|
196519
|
+
...choice?.message?.function_call ? [
|
|
196520
|
+
{
|
|
196521
|
+
id: `${data.id ?? makeMessageId2()}_function_call`,
|
|
196522
|
+
function: choice.message.function_call
|
|
196523
|
+
}
|
|
196524
|
+
] : []
|
|
196525
|
+
];
|
|
196526
|
+
if (isToolFinish) {
|
|
196527
|
+
if (completedToolCalls.length === 0) {
|
|
196528
|
+
throw new Error("Upstream returned a tool finish reason without a tool call; no tool was committed.");
|
|
196529
|
+
}
|
|
196530
|
+
const completedToolCallIds = new Set;
|
|
196531
|
+
let completedToolArgumentChars = 0;
|
|
196532
|
+
for (const tc of completedToolCalls) {
|
|
196533
|
+
const resolvedToolName = typeof tc.function?.name === "string" ? resolveToolNameByUniquePrefix(advertisedToolNames, tc.function.name) : undefined;
|
|
196534
|
+
if (typeof tc.id !== "string" || !tc.id.trim() || typeof tc.function?.name !== "string" || !tc.function.name.trim() || typeof tc.function?.arguments !== "string" || tc.function.arguments.length > toolArgumentCharsLimit || advertisedToolNames.length > 0 && !resolvedToolName || hasInvalidToolArguments(tc.function.arguments, resolvedToolName ?? tc.function.name) || completedToolCallIds.has(tc.id)) {
|
|
196535
|
+
throw new Error("Upstream returned malformed, incomplete, or duplicate tool calls; no tool was committed.");
|
|
196536
|
+
}
|
|
196537
|
+
completedToolArgumentChars += tc.function.arguments.length;
|
|
196538
|
+
if (completedToolArgumentChars > toolArgumentCharsLimit) {
|
|
196539
|
+
throw new Error("Upstream tool arguments exceeded the configured safety limit; no tool was committed.");
|
|
196540
|
+
}
|
|
196541
|
+
completedToolCallIds.add(tc.id);
|
|
196542
|
+
}
|
|
196543
|
+
for (const tc of completedToolCalls) {
|
|
196042
196544
|
const toolName = resolveToolNameByUniquePrefix(advertisedToolNames, tc.function.name) ?? tc.function.name;
|
|
196043
196545
|
const input = normalizeToolArguments(toolName, tc.function.arguments);
|
|
196044
196546
|
content.push({
|
|
@@ -196047,11 +196549,20 @@ class OpenAIShimMessages {
|
|
|
196047
196549
|
name: toolName,
|
|
196048
196550
|
input,
|
|
196049
196551
|
...tc.extra_content ? { extra_content: tc.extra_content } : {},
|
|
196050
|
-
...tc.extra_content?.google?.thought_signature ? {
|
|
196552
|
+
...tc.extra_content?.google?.thought_signature ? {
|
|
196553
|
+
signature: (tc.extra_content?.google).thought_signature
|
|
196554
|
+
} : {}
|
|
196051
196555
|
});
|
|
196052
196556
|
}
|
|
196557
|
+
} else if (completedToolCalls.length > 0) {
|
|
196558
|
+
logForDebugging(JSON.stringify({
|
|
196559
|
+
type: "discarded_uncommitted_tool_calls",
|
|
196560
|
+
model: model2,
|
|
196561
|
+
reason: `finish_reason:${choice?.finish_reason ?? "missing"}`,
|
|
196562
|
+
count: completedToolCalls.length
|
|
196563
|
+
}), { level: "warn" });
|
|
196053
196564
|
}
|
|
196054
|
-
const stopReason = choice?.finish_reason === "tool_calls" ? "tool_use" : choice?.finish_reason === "length" ? "max_tokens" : "end_turn";
|
|
196565
|
+
const stopReason = choice?.finish_reason === "tool_calls" || choice?.finish_reason === "function_call" ? "tool_use" : choice?.finish_reason === "length" ? "max_tokens" : "end_turn";
|
|
196055
196566
|
if (choice?.finish_reason === "content_filter" || choice?.finish_reason === "safety") {
|
|
196056
196567
|
content.push({
|
|
196057
196568
|
type: "text",
|
|
@@ -196093,7 +196604,7 @@ function createOpenAIShimClient(options2) {
|
|
|
196093
196604
|
messages: beta.messages
|
|
196094
196605
|
};
|
|
196095
196606
|
}
|
|
196096
|
-
var GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, GEMINI_API_HOST = "generativelanguage.googleapis.com", VERBOO_SESSION_HEADER = "X-Verboo-Session-Id", COPILOT_HEADERS2,
|
|
196607
|
+
var GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, GEMINI_API_HOST = "generativelanguage.googleapis.com", VERBOO_SESSION_HEADER = "X-Verboo-Session-Id", COPILOT_HEADERS2, DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS2, routerStatusHandler = null, routerStatusHandlerGeneration = 0, activeWarmingHints, OpenAIShimStream;
|
|
196097
196608
|
var init_openaiShim = __esm(() => {
|
|
196098
196609
|
init_sdk();
|
|
196099
196610
|
init_Tool();
|
|
@@ -196127,18 +196638,7 @@ var init_openaiShim = __esm(() => {
|
|
|
196127
196638
|
"Editor-Plugin-Version": "copilot-chat/0.26.7",
|
|
196128
196639
|
"Copilot-Integration-Id": "vscode-chat"
|
|
196129
196640
|
};
|
|
196130
|
-
|
|
196131
|
-
"}",
|
|
196132
|
-
'"}',
|
|
196133
|
-
"]}",
|
|
196134
|
-
'"]}',
|
|
196135
|
-
"}}",
|
|
196136
|
-
'"}}',
|
|
196137
|
-
"]}}",
|
|
196138
|
-
'"]}}',
|
|
196139
|
-
'"]}]}',
|
|
196140
|
-
"}]}"
|
|
196141
|
-
];
|
|
196641
|
+
DEFAULT_MAX_BUFFERED_TOOL_ARGUMENT_CHARS2 = 64 * 1024 * 1024;
|
|
196142
196642
|
activeWarmingHints = new Set;
|
|
196143
196643
|
OpenAIShimStream = class OpenAIShimStream {
|
|
196144
196644
|
generator;
|
|
@@ -391284,7 +391784,7 @@ function getAnthropicEnvMetadata() {
|
|
|
391284
391784
|
function getBuildAgeMinutes() {
|
|
391285
391785
|
if (false)
|
|
391286
391786
|
;
|
|
391287
|
-
const buildTime = new Date("2026-08-
|
|
391787
|
+
const buildTime = new Date("2026-08-25T17:16:19.335Z").getTime();
|
|
391288
391788
|
if (isNaN(buildTime))
|
|
391289
391789
|
return;
|
|
391290
391790
|
return Math.floor((Date.now() - buildTime) / 60000);
|
|
@@ -405590,7 +406090,7 @@ function normalizeContentFromAPI(contentBlocks, tools, agentId) {
|
|
|
405590
406090
|
normalizedInput = contentBlock.input;
|
|
405591
406091
|
}
|
|
405592
406092
|
const resolvedTool = findToolByNameOrUniquePrefix(tools, contentBlock.name);
|
|
405593
|
-
const normalizedToolName = resolvedTool && resolvedTool.name !== contentBlock.name && !resolvedTool.aliases?.includes(contentBlock.name) && resolvedTool.name.startsWith(contentBlock.name) ? resolvedTool.name : contentBlock.name;
|
|
406093
|
+
const normalizedToolName = resolvedTool && resolvedTool.name !== contentBlock.name && !resolvedTool.aliases?.includes(contentBlock.name) && resolvedTool.name.toLowerCase().startsWith(contentBlock.name.toLowerCase()) ? resolvedTool.name : contentBlock.name;
|
|
405594
406094
|
if (typeof normalizedInput === "object" && normalizedInput !== null) {
|
|
405595
406095
|
if (resolvedTool) {
|
|
405596
406096
|
try {
|
|
@@ -405766,6 +406266,7 @@ function handleMessageFromStream(message, onMessage2, onUpdateLength, onSetStrea
|
|
|
405766
406266
|
}
|
|
405767
406267
|
if (isSyntheticApiErrorMessage(message)) {
|
|
405768
406268
|
onSetStreamMode("tool-use");
|
|
406269
|
+
onStreamingToolUses(() => []);
|
|
405769
406270
|
}
|
|
405770
406271
|
}
|
|
405771
406272
|
onStreamingText?.(() => null);
|
|
@@ -405777,6 +406278,7 @@ function handleMessageFromStream(message, onMessage2, onUpdateLength, onSetStrea
|
|
|
405777
406278
|
return;
|
|
405778
406279
|
}
|
|
405779
406280
|
if (message.event.type === "message_start") {
|
|
406281
|
+
onStreamingToolUses(() => []);
|
|
405780
406282
|
if (message.ttftMs != null) {
|
|
405781
406283
|
onApiMetrics?.({ ttftMs: message.ttftMs });
|
|
405782
406284
|
}
|
|
@@ -405802,14 +406304,28 @@ function handleMessageFromStream(message, onMessage2, onUpdateLength, onSetStrea
|
|
|
405802
406304
|
onSetStreamMode("tool-input");
|
|
405803
406305
|
const contentBlock = message.event.content_block;
|
|
405804
406306
|
const index = message.event.index;
|
|
405805
|
-
onStreamingToolUses((
|
|
405806
|
-
|
|
405807
|
-
{
|
|
405808
|
-
|
|
405809
|
-
|
|
405810
|
-
|
|
406307
|
+
onStreamingToolUses((current) => {
|
|
406308
|
+
const exactMatchIndex = current.findIndex((toolUse) => toolUse.index === index && toolUse.contentBlock.id === contentBlock.id);
|
|
406309
|
+
if (exactMatchIndex !== -1) {
|
|
406310
|
+
return current.map((toolUse, currentIndex) => currentIndex === exactMatchIndex ? { ...toolUse, contentBlock } : toolUse);
|
|
406311
|
+
}
|
|
406312
|
+
const reusedIndex = current.findIndex((toolUse) => toolUse.index === index);
|
|
406313
|
+
if (reusedIndex !== -1) {
|
|
406314
|
+
return current.map((toolUse, currentIndex) => currentIndex === reusedIndex ? {
|
|
406315
|
+
index,
|
|
406316
|
+
contentBlock,
|
|
406317
|
+
unparsedToolInput: ""
|
|
406318
|
+
} : toolUse);
|
|
405811
406319
|
}
|
|
405812
|
-
|
|
406320
|
+
return [
|
|
406321
|
+
...current,
|
|
406322
|
+
{
|
|
406323
|
+
index,
|
|
406324
|
+
contentBlock,
|
|
406325
|
+
unparsedToolInput: ""
|
|
406326
|
+
}
|
|
406327
|
+
];
|
|
406328
|
+
});
|
|
405813
406329
|
return;
|
|
405814
406330
|
}
|
|
405815
406331
|
case "server_tool_use":
|
|
@@ -405844,13 +406360,10 @@ function handleMessageFromStream(message, onMessage2, onUpdateLength, onSetStrea
|
|
|
405844
406360
|
if (!element) {
|
|
405845
406361
|
return _;
|
|
405846
406362
|
}
|
|
405847
|
-
return
|
|
405848
|
-
...
|
|
405849
|
-
|
|
405850
|
-
|
|
405851
|
-
unparsedToolInput: element.unparsedToolInput + delta
|
|
405852
|
-
}
|
|
405853
|
-
];
|
|
406363
|
+
return _.map((toolUse) => toolUse === element ? {
|
|
406364
|
+
...toolUse,
|
|
406365
|
+
unparsedToolInput: toolUse.unparsedToolInput + delta
|
|
406366
|
+
} : toolUse);
|
|
405854
406367
|
});
|
|
405855
406368
|
return;
|
|
405856
406369
|
}
|
|
@@ -410827,6 +411340,15 @@ import { mkdir as mkdir26 } from "fs/promises";
|
|
|
410827
411340
|
import { createServer as createServer4 } from "http";
|
|
410828
411341
|
import { join as join100 } from "path";
|
|
410829
411342
|
import { parse as parse13 } from "url";
|
|
411343
|
+
function getRefreshCredentialInvalidationScope(error42) {
|
|
411344
|
+
if (error42 instanceof InvalidClientError || error42 instanceof UnauthorizedClientError) {
|
|
411345
|
+
return "all";
|
|
411346
|
+
}
|
|
411347
|
+
if (error42 instanceof InvalidGrantError) {
|
|
411348
|
+
return "tokens";
|
|
411349
|
+
}
|
|
411350
|
+
return;
|
|
411351
|
+
}
|
|
410830
411352
|
function redactSensitiveUrlParams(url3) {
|
|
410831
411353
|
try {
|
|
410832
411354
|
const parsedUrl = new URL(url3);
|
|
@@ -411633,7 +412155,7 @@ class ClaudeAuthProvider {
|
|
|
411633
412155
|
const storage3 = getSecureStorage();
|
|
411634
412156
|
const data = await storage3.readAsync();
|
|
411635
412157
|
const serverKey = getServerKey(this.serverName, this.serverConfig);
|
|
411636
|
-
|
|
412158
|
+
let tokenData = data?.mcpOAuth?.[serverKey];
|
|
411637
412159
|
if (isXaaEnabled() && this.serverConfig.oauth?.xaa && !tokenData?.refreshToken && (!tokenData?.accessToken || (tokenData.expiresAt - Date.now()) / 1000 <= 300)) {
|
|
411638
412160
|
if (!this._refreshInProgress) {
|
|
411639
412161
|
logMCPDebug(this.serverName, tokenData ? `XAA: access_token expiring, attempting silent exchange` : `XAA: no access_token yet, attempting silent exchange`);
|
|
@@ -411678,22 +412200,31 @@ class ClaudeAuthProvider {
|
|
|
411678
412200
|
logMCPDebug(this.serverName, `Token refreshed successfully`);
|
|
411679
412201
|
return refreshed;
|
|
411680
412202
|
}
|
|
411681
|
-
logMCPDebug(this.serverName, `Token refresh
|
|
412203
|
+
logMCPDebug(this.serverName, `Token refresh did not return new tokens; checking stored credentials`);
|
|
412204
|
+
tokenData = (await storage3.readAsync())?.mcpOAuth?.[serverKey];
|
|
412205
|
+
if (!tokenData?.accessToken) {
|
|
412206
|
+
logMCPDebug(this.serverName, `Refresh invalidated stored credentials; authorization required`);
|
|
412207
|
+
return;
|
|
412208
|
+
}
|
|
411682
412209
|
} catch (error42) {
|
|
411683
412210
|
logMCPDebug(this.serverName, `Token refresh error: ${errorMessage(error42)}`);
|
|
411684
412211
|
}
|
|
411685
412212
|
}
|
|
412213
|
+
if (!tokenData) {
|
|
412214
|
+
return;
|
|
412215
|
+
}
|
|
412216
|
+
const currentExpiresIn = (tokenData.expiresAt - Date.now()) / 1000;
|
|
411686
412217
|
const tokens = {
|
|
411687
412218
|
access_token: tokenData.accessToken,
|
|
411688
412219
|
refresh_token: needsStepUp ? undefined : tokenData.refreshToken,
|
|
411689
|
-
expires_in:
|
|
412220
|
+
expires_in: currentExpiresIn,
|
|
411690
412221
|
scope: tokenData.scope,
|
|
411691
412222
|
token_type: "Bearer"
|
|
411692
412223
|
};
|
|
411693
412224
|
logMCPDebug(this.serverName, `Returning tokens`);
|
|
411694
412225
|
logMCPDebug(this.serverName, `Token length: ${tokens.access_token?.length}`);
|
|
411695
412226
|
logMCPDebug(this.serverName, `Has refresh token: ${!!tokens.refresh_token}`);
|
|
411696
|
-
logMCPDebug(this.serverName, `Expires in: ${Math.floor(
|
|
412227
|
+
logMCPDebug(this.serverName, `Expires in: ${Math.floor(currentExpiresIn)}s`);
|
|
411697
412228
|
return tokens;
|
|
411698
412229
|
}
|
|
411699
412230
|
async saveTokens(tokens) {
|
|
@@ -412070,8 +412601,10 @@ class ClaudeAuthProvider {
|
|
|
412070
412601
|
emitRefreshEvent("failure", "no_tokens_returned");
|
|
412071
412602
|
return;
|
|
412072
412603
|
} catch (error42) {
|
|
412073
|
-
|
|
412074
|
-
|
|
412604
|
+
const invalidationScope = getRefreshCredentialInvalidationScope(error42);
|
|
412605
|
+
if (invalidationScope) {
|
|
412606
|
+
const clientRegistrationInvalid = invalidationScope === "all";
|
|
412607
|
+
logMCPDebug(this.serverName, clientRegistrationInvalid ? `Token refresh rejected the OAuth client (${error42 instanceof OAuthError ? error42.errorCode : "invalid_client"}): ${errorMessage(error42)}` : `Token refresh failed with invalid_grant: ${errorMessage(error42)}`);
|
|
412075
412608
|
clearKeychainCache();
|
|
412076
412609
|
const storage3 = getSecureStorage();
|
|
412077
412610
|
const data = storage3.read();
|
|
@@ -412090,9 +412623,9 @@ class ClaudeAuthProvider {
|
|
|
412090
412623
|
};
|
|
412091
412624
|
}
|
|
412092
412625
|
}
|
|
412093
|
-
logMCPDebug(this.serverName, `No valid tokens in storage, clearing stored tokens`);
|
|
412094
|
-
await this.invalidateCredentials(
|
|
412095
|
-
emitRefreshEvent("failure", "invalid_grant");
|
|
412626
|
+
logMCPDebug(this.serverName, clientRegistrationInvalid ? `No valid tokens in storage, clearing the stale OAuth client registration` : `No valid tokens in storage, clearing stored tokens`);
|
|
412627
|
+
await this.invalidateCredentials(invalidationScope);
|
|
412628
|
+
emitRefreshEvent("failure", clientRegistrationInvalid ? "invalid_client" : "invalid_grant");
|
|
412096
412629
|
return;
|
|
412097
412630
|
}
|
|
412098
412631
|
const isTimeoutError = error42 instanceof Error && /timeout|timed out|etimedout|econnreset/i.test(error42.message);
|
|
@@ -433087,7 +433620,7 @@ function buildPrimarySection() {
|
|
|
433087
433620
|
});
|
|
433088
433621
|
return [{
|
|
433089
433622
|
label: "Version",
|
|
433090
|
-
value: "0.15.
|
|
433623
|
+
value: "0.15.17"
|
|
433091
433624
|
}, {
|
|
433092
433625
|
label: "Session name",
|
|
433093
433626
|
value: nameValue
|
|
@@ -447017,7 +447550,7 @@ function getReleaseTagUrl(version2 = publicBuildVersion) {
|
|
|
447017
447550
|
return `${VERBOO_RELEASES_URL}/tag/v${normalizePublicVersion(version2)}`;
|
|
447018
447551
|
}
|
|
447019
447552
|
function getPublicBuildVersion() {
|
|
447020
|
-
return "0.15.
|
|
447553
|
+
return "0.15.17";
|
|
447021
447554
|
}
|
|
447022
447555
|
var import_semver10, VERBOO_RELEASES_URL = "https://github.com/verbeux-ai/code/releases", fallbackBuildVersion, publicBuildVersion;
|
|
447023
447556
|
var init_version = __esm(() => {
|
|
@@ -474015,7 +474548,7 @@ var import_react_compiler_runtime198, React97, import_react155, jsx_runtime267,
|
|
|
474015
474548
|
const msg_1 = createAssistantMessage({
|
|
474016
474549
|
content: [streamingToolUse.contentBlock]
|
|
474017
474550
|
});
|
|
474018
|
-
msg_1.uuid = deriveUUID(streamingToolUse.contentBlock.id,
|
|
474551
|
+
msg_1.uuid = deriveUUID(streamingToolUse.contentBlock.id, streamingToolUse.index);
|
|
474019
474552
|
return normalizeMessages([msg_1]);
|
|
474020
474553
|
}), [streamingToolUsesWithoutInProgress]);
|
|
474021
474554
|
const isTranscriptMode = screen === "transcript";
|
|
@@ -498411,7 +498944,7 @@ var init_bridge_kick = __esm(() => {
|
|
|
498411
498944
|
var call66 = async () => {
|
|
498412
498945
|
return {
|
|
498413
498946
|
type: "text",
|
|
498414
|
-
value: `${"99.0.0"} (built ${"2026-08-
|
|
498947
|
+
value: `${"99.0.0"} (built ${"2026-08-25T17:16:19.335Z"})`
|
|
498415
498948
|
};
|
|
498416
498949
|
}, version2, version_default;
|
|
498417
498950
|
var init_version2 = __esm(() => {
|
|
@@ -500233,6 +500766,8 @@ var init_verbooInChrome = __esm(() => {
|
|
|
500233
500766
|
VERBOO_IN_CHROME_TOOL_NAMES = [
|
|
500234
500767
|
"navigate",
|
|
500235
500768
|
"read_page",
|
|
500769
|
+
"find",
|
|
500770
|
+
"extract_page_content",
|
|
500236
500771
|
"structured_extract",
|
|
500237
500772
|
"click",
|
|
500238
500773
|
"type",
|
|
@@ -522147,7 +522682,7 @@ function printStartupScreen(modelOverride) {
|
|
|
522147
522682
|
const home = process.env.HOME || process.env.USERPROFILE || "";
|
|
522148
522683
|
const cwd2 = process.cwd();
|
|
522149
522684
|
const displayCwd = home && cwd2.startsWith(home) ? `~${cwd2.slice(home.length)}` : cwd2;
|
|
522150
|
-
const version3 = "0.15.
|
|
522685
|
+
const version3 = "0.15.17";
|
|
522151
522686
|
const columns = process.stdout.columns ?? STARTUP_DEFAULT_COLUMNS;
|
|
522152
522687
|
process.stdout.write(renderStartupScreen(p, version3, displayCwd, columns));
|
|
522153
522688
|
}
|
|
@@ -541376,7 +541911,7 @@ var init_routerRateLimitHook = __esm(() => {
|
|
|
541376
541911
|
function getSemverPart(version3) {
|
|
541377
541912
|
return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
|
|
541378
541913
|
}
|
|
541379
|
-
function useUpdateNotification(updatedVersion, initialVersion = "0.15.
|
|
541914
|
+
function useUpdateNotification(updatedVersion, initialVersion = "0.15.17") {
|
|
541380
541915
|
const [lastNotifiedSemver, setLastNotifiedSemver] = import_react226.useState(() => getSemverPart(initialVersion));
|
|
541381
541916
|
const [pendingNotification2, setPendingNotification] = import_react226.useState(null);
|
|
541382
541917
|
if (updatedVersion) {
|
|
@@ -541416,7 +541951,7 @@ function AutoUpdater({
|
|
|
541416
541951
|
return;
|
|
541417
541952
|
}
|
|
541418
541953
|
if (false) {}
|
|
541419
|
-
const currentVersion = "0.15.
|
|
541954
|
+
const currentVersion = "0.15.17";
|
|
541420
541955
|
const channel2 = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
541421
541956
|
let latestVersion = await getLatestVersion(channel2);
|
|
541422
541957
|
const isDisabled = isAutoUpdaterDisabled();
|
|
@@ -541769,17 +542304,17 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
541769
542304
|
const maxVersion = await getMaxVersion();
|
|
541770
542305
|
if (maxVersion && latest && gt(latest, maxVersion)) {
|
|
541771
542306
|
logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
|
|
541772
|
-
if (gte("0.15.
|
|
541773
|
-
logForDebugging(`PackageManagerAutoUpdater: current version ${"0.15.
|
|
542307
|
+
if (gte("0.15.17", maxVersion)) {
|
|
542308
|
+
logForDebugging(`PackageManagerAutoUpdater: current version ${"0.15.17"} is already at or above maxVersion ${maxVersion}, skipping update`);
|
|
541774
542309
|
setUpdateAvailable(false);
|
|
541775
542310
|
return;
|
|
541776
542311
|
}
|
|
541777
542312
|
latest = maxVersion;
|
|
541778
542313
|
}
|
|
541779
|
-
const hasUpdate = latest && !gte("0.15.
|
|
542314
|
+
const hasUpdate = latest && !gte("0.15.17", latest) && !shouldSkipVersion(latest);
|
|
541780
542315
|
setUpdateAvailable(!!hasUpdate);
|
|
541781
542316
|
if (hasUpdate) {
|
|
541782
|
-
logForDebugging(`PackageManagerAutoUpdater: Update available ${"0.15.
|
|
542317
|
+
logForDebugging(`PackageManagerAutoUpdater: Update available ${"0.15.17"} -> ${latest}`);
|
|
541783
542318
|
}
|
|
541784
542319
|
};
|
|
541785
542320
|
$2[0] = t1;
|
|
@@ -541813,7 +542348,7 @@ function PackageManagerAutoUpdater(t0) {
|
|
|
541813
542348
|
wrap: "truncate",
|
|
541814
542349
|
children: [
|
|
541815
542350
|
"currentVersion: ",
|
|
541816
|
-
"0.15.
|
|
542351
|
+
"0.15.17"
|
|
541817
542352
|
]
|
|
541818
542353
|
});
|
|
541819
542354
|
$2[3] = verbose;
|
|
@@ -557503,10 +558038,10 @@ async function autoUpdateCliInBackground() {
|
|
|
557503
558038
|
return;
|
|
557504
558039
|
const channel2 = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
557505
558040
|
const latest = await getLatestVersion(channel2);
|
|
557506
|
-
if (!latest || gte("0.15.
|
|
558041
|
+
if (!latest || gte("0.15.17", latest))
|
|
557507
558042
|
return;
|
|
557508
558043
|
writeToStdout(`
|
|
557509
|
-
Nova versão disponível: ${latest} (atual: ${"0.15.
|
|
558044
|
+
Nova versão disponível: ${latest} (atual: ${"0.15.17"})
|
|
557510
558045
|
`);
|
|
557511
558046
|
writeToStdout(`Atualizando automaticamente...
|
|
557512
558047
|
`);
|
|
@@ -574944,7 +575479,7 @@ var init_ApproveApiKey = __esm(() => {
|
|
|
574944
575479
|
|
|
574945
575480
|
// src/components/LogoV2/WelcomeV2.tsx
|
|
574946
575481
|
function WelcomeV2() {
|
|
574947
|
-
const version3 = "0.15.
|
|
575482
|
+
const version3 = "0.15.17";
|
|
574948
575483
|
return /* @__PURE__ */ jsx_runtime476.jsxs(ThemedBox_default, {
|
|
574949
575484
|
flexDirection: "column",
|
|
574950
575485
|
marginY: 1,
|
|
@@ -593892,7 +594427,7 @@ __export(exports_update, {
|
|
|
593892
594427
|
});
|
|
593893
594428
|
async function update() {
|
|
593894
594429
|
logEvent("tengu_update_check", {});
|
|
593895
|
-
writeToStdout(`Current version: ${"0.15.
|
|
594430
|
+
writeToStdout(`Current version: ${"0.15.17"}
|
|
593896
594431
|
`);
|
|
593897
594432
|
const channel2 = getInitialSettings()?.autoUpdatesChannel ?? "latest";
|
|
593898
594433
|
writeToStdout(`Checking for updates to ${channel2} version...
|
|
@@ -593977,8 +594512,8 @@ async function update() {
|
|
|
593977
594512
|
writeToStdout(`Verboo Code is managed by Homebrew.
|
|
593978
594513
|
`);
|
|
593979
594514
|
const latest = await getLatestVersion(channel2);
|
|
593980
|
-
if (latest && !gte("0.15.
|
|
593981
|
-
writeToStdout(`Update available: ${"0.15.
|
|
594515
|
+
if (latest && !gte("0.15.17", latest)) {
|
|
594516
|
+
writeToStdout(`Update available: ${"0.15.17"} → ${latest}
|
|
593982
594517
|
`);
|
|
593983
594518
|
writeToStdout(`
|
|
593984
594519
|
`);
|
|
@@ -593994,8 +594529,8 @@ async function update() {
|
|
|
593994
594529
|
writeToStdout(`Verboo Code is managed by winget.
|
|
593995
594530
|
`);
|
|
593996
594531
|
const latest = await getLatestVersion(channel2);
|
|
593997
|
-
if (latest && !gte("0.15.
|
|
593998
|
-
writeToStdout(`Update available: ${"0.15.
|
|
594532
|
+
if (latest && !gte("0.15.17", latest)) {
|
|
594533
|
+
writeToStdout(`Update available: ${"0.15.17"} → ${latest}
|
|
593999
594534
|
`);
|
|
594000
594535
|
writeToStdout(`
|
|
594001
594536
|
`);
|
|
@@ -594011,8 +594546,8 @@ async function update() {
|
|
|
594011
594546
|
writeToStdout(`Verboo Code is managed by apk.
|
|
594012
594547
|
`);
|
|
594013
594548
|
const latest = await getLatestVersion(channel2);
|
|
594014
|
-
if (latest && !gte("0.15.
|
|
594015
|
-
writeToStdout(`Update available: ${"0.15.
|
|
594549
|
+
if (latest && !gte("0.15.17", latest)) {
|
|
594550
|
+
writeToStdout(`Update available: ${"0.15.17"} → ${latest}
|
|
594016
594551
|
`);
|
|
594017
594552
|
writeToStdout(`
|
|
594018
594553
|
`);
|
|
@@ -594065,11 +594600,11 @@ async function update() {
|
|
|
594065
594600
|
`);
|
|
594066
594601
|
await gracefulShutdown(1);
|
|
594067
594602
|
}
|
|
594068
|
-
if (result.latestVersion === "0.15.
|
|
594069
|
-
writeToStdout(source_default.green(`Verboo Code is up to date (${"0.15.
|
|
594603
|
+
if (result.latestVersion === "0.15.17") {
|
|
594604
|
+
writeToStdout(source_default.green(`Verboo Code is up to date (${"0.15.17"})`) + `
|
|
594070
594605
|
`);
|
|
594071
594606
|
} else {
|
|
594072
|
-
writeToStdout(source_default.green(`Successfully updated from ${"0.15.
|
|
594607
|
+
writeToStdout(source_default.green(`Successfully updated from ${"0.15.17"} to version ${result.latestVersion}`) + `
|
|
594073
594608
|
`);
|
|
594074
594609
|
await regenerateCompletionCache();
|
|
594075
594610
|
}
|
|
@@ -594129,12 +594664,12 @@ async function update() {
|
|
|
594129
594664
|
`);
|
|
594130
594665
|
await gracefulShutdown(1);
|
|
594131
594666
|
}
|
|
594132
|
-
if (latestVersion === "0.15.
|
|
594133
|
-
writeToStdout(source_default.green(`Verboo Code is up to date (${"0.15.
|
|
594667
|
+
if (latestVersion === "0.15.17") {
|
|
594668
|
+
writeToStdout(source_default.green(`Verboo Code is up to date (${"0.15.17"})`) + `
|
|
594134
594669
|
`);
|
|
594135
594670
|
await gracefulShutdown(0);
|
|
594136
594671
|
}
|
|
594137
|
-
writeToStdout(`New version available: ${latestVersion} (current: ${"0.15.
|
|
594672
|
+
writeToStdout(`New version available: ${latestVersion} (current: ${"0.15.17"})
|
|
594138
594673
|
`);
|
|
594139
594674
|
writeToStdout(`Installing update...
|
|
594140
594675
|
`);
|
|
@@ -594179,7 +594714,7 @@ async function update() {
|
|
|
594179
594714
|
logForDebugging(`update: Installation status: ${status2}`);
|
|
594180
594715
|
switch (status2) {
|
|
594181
594716
|
case "success":
|
|
594182
|
-
writeToStdout(source_default.green(`Successfully updated from ${"0.15.
|
|
594717
|
+
writeToStdout(source_default.green(`Successfully updated from ${"0.15.17"} to version ${latestVersion}`) + `
|
|
594183
594718
|
`);
|
|
594184
594719
|
await regenerateCompletionCache();
|
|
594185
594720
|
break;
|
|
@@ -595518,7 +596053,7 @@ ${chromeSystemPrompt}` : chromeSystemPrompt;
|
|
|
595518
596053
|
is_native_binary: isInBundledMode()
|
|
595519
596054
|
});
|
|
595520
596055
|
logMemoryDiagnostics("start", {
|
|
595521
|
-
version: "0.15.
|
|
596056
|
+
version: "0.15.17",
|
|
595522
596057
|
debug: debug2,
|
|
595523
596058
|
debugToStderr,
|
|
595524
596059
|
print: print ?? false,
|
|
@@ -596329,7 +596864,7 @@ Usage: verboo --remote "your task description"`, () => gracefulShutdown(1));
|
|
|
596329
596864
|
pendingHookMessages
|
|
596330
596865
|
}, renderAndRun);
|
|
596331
596866
|
}
|
|
596332
|
-
}).version(`0.15.
|
|
596867
|
+
}).version(`0.15.17 (${cliDesc})`, "-v, --version", "Output the version number");
|
|
596333
596868
|
program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
|
|
596334
596869
|
program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
|
|
596335
596870
|
if (canUserConfigureAdvisor()) {
|
|
@@ -596944,7 +597479,7 @@ if (false) {}
|
|
|
596944
597479
|
async function main2() {
|
|
596945
597480
|
const args = process.argv.slice(2);
|
|
596946
597481
|
if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
|
|
596947
|
-
console.log(`${"0.15.
|
|
597482
|
+
console.log(`${"0.15.17"} (Verboo Code)`);
|
|
596948
597483
|
return;
|
|
596949
597484
|
}
|
|
596950
597485
|
if (!IS_VERBOO_CLI && args.includes("--provider")) {
|
|
@@ -597118,4 +597653,4 @@ async function main2() {
|
|
|
597118
597653
|
}
|
|
597119
597654
|
main2();
|
|
597120
597655
|
|
|
597121
|
-
//# debugId=
|
|
597656
|
+
//# debugId=5CD1B0C278B044C764756E2164756E21
|