0sec-cli 0.22.0 → 0.22.4
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/0.js +56 -45
- package/README.md +12 -0
- package/chunks/{adapt-loop-7I57LXXR.js → adapt-loop-3CCOWE43.js} +4 -4
- package/chunks/{artifact-scraper-PYZ3RU3O.js → artifact-scraper-Z4UUIOH3.js} +2 -2
- package/chunks/{assumption-mining-MFLF43IR.js → assumption-mining-2UAKQB6V.js} +18 -14
- package/chunks/{chunk-RE5EZDG2.js → chunk-2WWAPKAW.js} +126 -1089
- package/chunks/{chunk-LPTRPRZR.js → chunk-3BPX75OR.js} +1 -1
- package/chunks/chunk-4ZYYX5GY.js +74 -0
- package/chunks/{chunk-RSIUX3RW.js → chunk-5JNTMWPK.js} +2 -2
- package/chunks/{chunk-RRD4XXPU.js → chunk-5WAJGLCW.js} +3 -3
- package/chunks/{chunk-76KSBWOQ.js → chunk-6KFB6AYN.js} +515 -20
- package/chunks/{chunk-HR2TU42B.js → chunk-6WQDXWQC.js} +169 -15
- package/chunks/chunk-6YZE552K.js +5603 -0
- package/chunks/chunk-BGX53365.js +309 -0
- package/chunks/{chunk-7DEHG7YT.js → chunk-C6JPA32H.js} +1 -1
- package/chunks/chunk-CF3MNS3O.js +990 -0
- package/chunks/{chunk-4VGLO2YS.js → chunk-CPCHLL6A.js} +5 -2
- package/chunks/{chunk-DM5C5L5D.js → chunk-DPUXXMJW.js} +1 -1
- package/chunks/{chunk-LYUAM3TG.js → chunk-E3OOBVOK.js} +30 -12
- package/chunks/{chunk-HUNAPTKV.js → chunk-E74LXQFY.js} +1 -1
- package/chunks/{chunk-UU7PQP6N.js → chunk-ELI3BVIK.js} +3 -3
- package/chunks/chunk-FFHRANYC.js +547 -0
- package/chunks/{chunk-IO7R7WBM.js → chunk-G2BE2FC7.js} +1 -1
- package/chunks/chunk-GQ3DGHWE.js +1659 -0
- package/chunks/{chunk-V36HVTUL.js → chunk-GVY3S5E5.js} +21 -18
- package/chunks/{chunk-UV5QWZGE.js → chunk-H4DH7COV.js} +192 -40
- package/chunks/{chunk-SJBCK2EI.js → chunk-H6Q2QAIY.js} +23475 -22747
- package/chunks/{chunk-VMRRNRMR.js → chunk-IHPTOTLL.js} +1 -1
- package/chunks/chunk-IXAHQICR.js +31 -0
- package/chunks/{chunk-TH2LW437.js → chunk-KCA35IL3.js} +2 -190
- package/chunks/{chunk-VNRY6AWF.js → chunk-L2CCO4KE.js} +282 -34
- package/chunks/{chunk-6YNKRUMC.js → chunk-NJLKFC66.js} +321 -5
- package/chunks/{chunk-W6UWZFKL.js → chunk-O6KPVYOI.js} +100 -5
- package/chunks/{chunk-EGZGZFAH.js → chunk-OAS5SAVZ.js} +6768 -2100
- package/chunks/chunk-PS5E7LUQ.js +277 -0
- package/chunks/{chunk-2GV4HQKE.js → chunk-QVIRWJ45.js} +257 -145
- package/chunks/{chunk-OWLJYJ5O.js → chunk-QWK4R3DB.js} +9 -9
- package/chunks/{chunk-XFCTUKXR.js → chunk-RCRTSKQN.js} +1 -1
- package/chunks/chunk-RS4MAN3Q.js +73 -0
- package/chunks/{chunk-7UFUALR2.js → chunk-RTBZ36BD.js} +8 -274
- package/chunks/{chunk-TZFIAMWZ.js → chunk-SCWWLABR.js} +1 -1
- package/chunks/chunk-VDOWARMJ.js +63 -0
- package/chunks/{chunk-5MWAG3FT.js → chunk-WBRGXCU2.js} +79 -18
- package/chunks/{chunk-LCRTAQN2.js → chunk-WHUAUFSX.js} +1 -1
- package/chunks/{chunk-YIQSGNAA.js → chunk-XODDLNBI.js} +1535 -1306
- package/chunks/chunk-YAZARMJY.js +355 -0
- package/chunks/{chunk-OAYUPGF6.js → chunk-YED25PA4.js} +1 -1
- package/chunks/{codex-models-7TLJSY3L.js → codex-models-Z43V3427.js} +9 -3
- package/chunks/{commands-NEI7L3QA.js → commands-EUGF4FUZ.js} +5844 -4095
- package/chunks/{db-5AP3JB4W.js → db-NVAW4WWR.js} +3 -3
- package/chunks/{dist-3FNZIBB4.js → dist-27BNG6WD.js} +195 -112
- package/chunks/{dist-5YHYNLI3.js → dist-7RUOKPRJ.js} +12 -2
- package/chunks/{dist-KEULE5IQ.js → dist-LNXGATR2.js} +2 -2
- package/chunks/{dist-XZB53PS5.js → dist-M2X367VW.js} +2 -2
- package/chunks/{dist-DD4H6HMQ.js → dist-NG2HT5XU.js} +27 -1
- package/chunks/{eval-runner-43BO2C4T.js → eval-runner-6Q3H52SP.js} +13 -9
- package/chunks/{exploit-agent-N4A5ELBK.js → exploit-agent-FCCR2HYX.js} +1 -1
- package/chunks/{exploit-autoclimb-N7P6KIF5.js → exploit-autoclimb-X5ZS5FAO.js} +1 -1
- package/chunks/{exploit-climb-WNEJUB5W.js → exploit-climb-3JHGEO36.js} +2 -2
- package/chunks/{fix-Z452M4EC.js → fix-NSNPU33B.js} +12 -6
- package/chunks/{harness-QJJJVSG4.js → harness-KXQOVIDQ.js} +3 -3
- package/chunks/{hunt-scan-K6D2V3PX.js → hunt-scan-ELTKGKC4.js} +16 -12
- package/chunks/{kernel-primitive-TKUACPKD.js → kernel-primitive-MT7YZSIG.js} +2 -2
- package/chunks/{kernel-vm-runner-RAAO2PGT.js → kernel-vm-runner-YFRHYC6G.js} +2 -2
- package/chunks/{native-loop-2ZRJENZ3.js → native-loop-OFJDRHPI.js} +18 -8
- package/chunks/orchestrate-DRZ2SVCP.js +62 -0
- package/chunks/{prepare-KYHGFWCJ.js → prepare-72GWTRVI.js} +6 -2
- package/chunks/{process-N245QIQG.js → process-MJYJ2K5E.js} +2 -1
- package/chunks/{run-U3XU4CTC.js → run-WTJCZZHV.js} +3091 -6037
- package/chunks/{runtime-G75TEWQY.js → runtime-FCKOUB7V.js} +10 -4
- package/chunks/{runtime-XFWJTBUO.js → runtime-LCJ4XSKE.js} +5 -1
- package/chunks/{scan-stream-BMOCPKQX.js → scan-stream-GT6GKQ3U.js} +7 -1
- package/chunks/{scope-WXI46UHJ.js → scope-E5QZUOOH.js} +2 -2
- package/chunks/service-plugins-MSK2EQP6.js +62 -0
- package/chunks/{session-store-27L3ZU73.js → session-store-H3Q7KCYG.js} +6 -4
- package/chunks/{variant-candidates-YWZORZMK.js → variant-candidates-SZKDCOLK.js} +9 -3
- package/chunks/{web-recon-prepass-YVMFXCIK.js → web-recon-prepass-IO3GXQMW.js} +11 -6
- package/dashboard/apple-touch-icon.png +0 -0
- package/dashboard/assets/operations-BvB5Qpmk.css +1 -0
- package/dashboard/assets/operations-D8Ii01SV.js +114 -0
- package/dashboard/assets/zero-peek-Dzm3MT3X.png +0 -0
- package/dashboard/favicon.ico +0 -0
- package/dashboard/favicon.svg +10 -0
- package/dashboard/index.html +5 -3
- package/package.json +1 -1
- package/chunks/chunk-6GHSR47F.js +0 -147
- package/chunks/chunk-CAYANSH6.js +0 -3524
- package/chunks/chunk-GHWODZMR.js +0 -16
- package/chunks/chunk-MICHDTBK.js +0 -193
- package/chunks/orchestrate-2GWGNTBF.js +0 -58
- package/dashboard/assets/bot-Bg1Tp9_d.js +0 -1
- package/dashboard/assets/dist-B_dDCPbu.js +0 -1
- package/dashboard/assets/findings-page-mayGhNx6.js +0 -5
- package/dashboard/assets/format--susmHX7.js +0 -1
- package/dashboard/assets/input-TuVPR3Zl.js +0 -1
- package/dashboard/assets/jsx-runtime-MGseXjj5.js +0 -3
- package/dashboard/assets/live-page-HWWHX99U.js +0 -1
- package/dashboard/assets/meta-tile-ckHo-w7k.js +0 -1
- package/dashboard/assets/operations-BxZ0OoXO.js +0 -10
- package/dashboard/assets/operations-CMFVrXEe.css +0 -2
- package/dashboard/assets/operations-app-D3d35rgo.js +0 -46
- package/dashboard/assets/overview-page-W_4IteEr.js +0 -1
- package/dashboard/assets/page-header-Bw9AJgBV.js +0 -1
- package/dashboard/assets/scans-page-CgzVXHnn.js +0 -1
- package/dashboard/assets/siren-KQj8QAnJ.js +0 -1
- package/dashboard/assets/table-8EDklulN.js +0 -1
- package/dashboard/assets/tabs-CFHPOwg8.js +0 -1
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
isAdmittedSmolvmWorkbench
|
|
6
|
+
} from "./chunk-2WWAPKAW.js";
|
|
7
|
+
import {
|
|
8
|
+
MESSAGE_CACHE_BREAKPOINTS,
|
|
9
|
+
planMessageBreakpoints,
|
|
10
|
+
providerSupportsPromptCache,
|
|
11
|
+
readCacheUsage,
|
|
12
|
+
withCacheControl
|
|
13
|
+
} from "./chunk-RS4MAN3Q.js";
|
|
4
14
|
import {
|
|
5
15
|
VERSION
|
|
6
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-6KFB6AYN.js";
|
|
7
17
|
|
|
8
18
|
// packages/core/dist/agent/feature-presets.js
|
|
9
19
|
var FP_MOAT_FLAGS = [
|
|
@@ -1029,66 +1039,25 @@ import { appendFileSync, existsSync, readFileSync, renameSync, writeFileSync } f
|
|
|
1029
1039
|
import { homedir } from "node:os";
|
|
1030
1040
|
import { join } from "node:path";
|
|
1031
1041
|
|
|
1032
|
-
// packages/core/dist/runtime/
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
var BREAKPOINT_SPACING_BLOCKS = 15;
|
|
1036
|
-
var NATIVE_CACHE_PROVIDERS = /* @__PURE__ */ new Set(["anthropic"]);
|
|
1037
|
-
var OPT_IN_CACHE_PROVIDERS = /* @__PURE__ */ new Set(["z-ai", "kimi"]);
|
|
1038
|
-
function providerSupportsPromptCache(provider) {
|
|
1039
|
-
if (NATIVE_CACHE_PROVIDERS.has(provider))
|
|
1040
|
-
return true;
|
|
1041
|
-
if (!OPT_IN_CACHE_PROVIDERS.has(provider))
|
|
1042
|
-
return false;
|
|
1043
|
-
return readExtraCacheProviders().has(provider);
|
|
1044
|
-
}
|
|
1045
|
-
function readExtraCacheProviders() {
|
|
1046
|
-
const raw = process.env["ZERO_PROMPT_CACHE_EXTRA_PROVIDERS"];
|
|
1042
|
+
// packages/core/dist/runtime/workbench-provider-proxy.js
|
|
1043
|
+
function resolveWorkbenchProviderProxy(env2) {
|
|
1044
|
+
const raw = env2.ZERO_WORKBENCH_PROVIDER_PROXY;
|
|
1047
1045
|
if (!raw)
|
|
1048
|
-
return /* @__PURE__ */ new Set();
|
|
1049
|
-
return new Set(raw.split(",").map((entry) => entry.trim().toLowerCase()).filter((entry) => entry.length > 0));
|
|
1050
|
-
}
|
|
1051
|
-
function planMessageBreakpoints(messages, budget = MESSAGE_CACHE_BREAKPOINTS) {
|
|
1052
|
-
if (messages.length === 0 || budget <= 0)
|
|
1053
|
-
return [];
|
|
1054
|
-
const lastIndex = messages.length - 1;
|
|
1055
|
-
const picks = /* @__PURE__ */ new Set([lastIndex]);
|
|
1056
|
-
const rollingBudget = Math.max(1, budget - 1);
|
|
1057
|
-
let blocksSincePick = blockCount(messages[lastIndex]);
|
|
1058
|
-
for (let i = lastIndex - 1; i >= 0 && picks.size < rollingBudget; i--) {
|
|
1059
|
-
if (blocksSincePick >= BREAKPOINT_SPACING_BLOCKS) {
|
|
1060
|
-
picks.add(i);
|
|
1061
|
-
blocksSincePick = 0;
|
|
1062
|
-
}
|
|
1063
|
-
blocksSincePick += blockCount(messages[i]);
|
|
1064
|
-
}
|
|
1065
|
-
if (picks.size < budget)
|
|
1066
|
-
picks.add(0);
|
|
1067
|
-
return [...picks].sort((a, b) => a - b).slice(0, budget);
|
|
1068
|
-
}
|
|
1069
|
-
function blockCount(message) {
|
|
1070
|
-
return message?.content.length ?? 0;
|
|
1071
|
-
}
|
|
1072
|
-
function withCacheControl(block) {
|
|
1073
|
-
return { ...block, cache_control: { type: "ephemeral" } };
|
|
1074
|
-
}
|
|
1075
|
-
function readCacheUsage(raw) {
|
|
1076
|
-
if (typeof raw !== "object" || raw === null)
|
|
1077
1046
|
return void 0;
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
return
|
|
1047
|
+
if (!isAdmittedSmolvmWorkbench())
|
|
1048
|
+
throw new Error("Provider proxy requires authenticated SmolVM workbench admission");
|
|
1049
|
+
let url;
|
|
1050
|
+
try {
|
|
1051
|
+
url = new URL(raw);
|
|
1052
|
+
} catch {
|
|
1053
|
+
throw new Error("Invalid guest provider proxy address");
|
|
1054
|
+
}
|
|
1055
|
+
if (url.protocol !== "http:" || url.hostname !== "127.0.0.1" || !url.port || url.pathname !== "/provider/request" || url.username || url.password || url.search || url.hash)
|
|
1056
|
+
throw new Error("Provider proxy must be the fixed guest loopback route");
|
|
1057
|
+
const model = env2.ZERO_WORKBENCH_PROVIDER_MODEL;
|
|
1058
|
+
if (!model || !/^[A-Za-z0-9._-]{1,128}$/.test(model))
|
|
1059
|
+
throw new Error("Missing exact workbench provider model");
|
|
1060
|
+
return { url: url.href, model };
|
|
1092
1061
|
}
|
|
1093
1062
|
|
|
1094
1063
|
// packages/core/dist/runtime/llm-api.js
|
|
@@ -1098,6 +1067,31 @@ function readResponsesCachedTokens(usage) {
|
|
|
1098
1067
|
const cached = Number(details?.cached_tokens ?? 0);
|
|
1099
1068
|
return Number.isFinite(cached) && cached > 0 ? { cachedInputTokens: cached } : {};
|
|
1100
1069
|
}
|
|
1070
|
+
function readChatUsage(raw) {
|
|
1071
|
+
if (!raw || typeof raw !== "object")
|
|
1072
|
+
return void 0;
|
|
1073
|
+
const usage = raw;
|
|
1074
|
+
if (usage.prompt_tokens === void 0 && usage.completion_tokens === void 0)
|
|
1075
|
+
return void 0;
|
|
1076
|
+
return {
|
|
1077
|
+
inputTokens: Number(usage.prompt_tokens ?? 0),
|
|
1078
|
+
outputTokens: Number(usage.completion_tokens ?? 0),
|
|
1079
|
+
...readResponsesCachedTokens({ input_tokens_details: usage.prompt_tokens_details })
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
function readGoogleUsage(raw) {
|
|
1083
|
+
if (!raw || typeof raw !== "object")
|
|
1084
|
+
return void 0;
|
|
1085
|
+
const usage = raw;
|
|
1086
|
+
if (usage.promptTokenCount === void 0 && usage.candidatesTokenCount === void 0)
|
|
1087
|
+
return void 0;
|
|
1088
|
+
const cached = Number(usage.cachedContentTokenCount ?? 0);
|
|
1089
|
+
return {
|
|
1090
|
+
inputTokens: Number(usage.promptTokenCount ?? 0),
|
|
1091
|
+
outputTokens: Number(usage.candidatesTokenCount ?? 0) + Number(usage.thoughtsTokenCount ?? 0),
|
|
1092
|
+
...cached > 0 ? { cachedInputTokens: cached } : {}
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1101
1095
|
function safeParseJson(raw) {
|
|
1102
1096
|
if (!raw)
|
|
1103
1097
|
return {};
|
|
@@ -1107,6 +1101,18 @@ function safeParseJson(raw) {
|
|
|
1107
1101
|
return { _raw: raw };
|
|
1108
1102
|
}
|
|
1109
1103
|
}
|
|
1104
|
+
function parseResponsesFunctionCall(item) {
|
|
1105
|
+
if (item.status !== void 0 && item.status !== "completed" || typeof item.call_id !== "string" || !item.call_id.trim() || typeof item.name !== "string" || !item.name.trim() || typeof item.arguments !== "string")
|
|
1106
|
+
return void 0;
|
|
1107
|
+
try {
|
|
1108
|
+
const input = JSON.parse(item.arguments);
|
|
1109
|
+
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
1110
|
+
return void 0;
|
|
1111
|
+
return { type: "tool_use", id: item.call_id, name: item.name, input };
|
|
1112
|
+
} catch {
|
|
1113
|
+
return void 0;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1110
1116
|
function isWireBlockArray(blocks) {
|
|
1111
1117
|
return blocks.every((block) => block !== null && typeof block === "object" && !Array.isArray(block) && typeof block.type === "string");
|
|
1112
1118
|
}
|
|
@@ -2187,6 +2193,13 @@ var DEFAULT_PROVIDER_MODELS = {
|
|
|
2187
2193
|
};
|
|
2188
2194
|
var AUTO_MODEL_SENTINEL = "auto";
|
|
2189
2195
|
function detectProvider(configApiKey, preferredModel, env2, configProvider) {
|
|
2196
|
+
const proxy = resolveWorkbenchProviderProxy(env2);
|
|
2197
|
+
if (proxy) {
|
|
2198
|
+
if ([configProvider, env2.ZERO_SELECTED_PROVIDER, env2.ZERO_FORCE_PROVIDER].some((provider) => provider && provider !== "chatgpt-codex")) {
|
|
2199
|
+
throw new Error("Workbench provider broker supports chatgpt-codex only; no fallback is permitted");
|
|
2200
|
+
}
|
|
2201
|
+
return { provider: "chatgpt-codex", apiKey: "", baseUrl: proxy.url, defaultModel: proxy.model, wireApi: "responses" };
|
|
2202
|
+
}
|
|
2190
2203
|
if (configProvider !== void 0 && !Object.hasOwn(DEFAULT_PROVIDER_MODELS, configProvider)) {
|
|
2191
2204
|
throw new Error(`RuntimeConfig.provider is unsupported: ${configProvider}`);
|
|
2192
2205
|
}
|
|
@@ -2204,8 +2217,10 @@ function detectProvider(configApiKey, preferredModel, env2, configProvider) {
|
|
|
2204
2217
|
throw new Error(`${source} is unsupported: ${pinnedProviderRaw}`);
|
|
2205
2218
|
}
|
|
2206
2219
|
const provider = pinnedProviderRaw;
|
|
2207
|
-
const model = preferredModel ?? env2["ZERO_MODEL"] ?? (configProvider !== void 0 ? DEFAULT_PROVIDER_MODELS[provider] : void 0);
|
|
2220
|
+
const model = preferredModel ?? env2["ZERO_MODEL"] ?? (provider === "azure" ? env2.AZURE_OPENAI_MODEL ?? parseCodexAzureConfig(env2).model : void 0) ?? (configProvider !== void 0 ? DEFAULT_PROVIDER_MODELS[provider] : void 0);
|
|
2208
2221
|
if (model === void 0 || model === "") {
|
|
2222
|
+
if (provider === "azure")
|
|
2223
|
+
throw new Error("Choose an Azure deployment model in Connections to finish setup.");
|
|
2209
2224
|
throw new Error(`${source} requires an explicit model`);
|
|
2210
2225
|
}
|
|
2211
2226
|
if (configApiKey && provider === "chatgpt-codex") {
|
|
@@ -2520,6 +2535,7 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2520
2535
|
// Not readonly: a live provider switch re-freezes env from the new account.
|
|
2521
2536
|
env;
|
|
2522
2537
|
codexAuthState;
|
|
2538
|
+
workbenchProviderProxy;
|
|
2523
2539
|
geminiAuthState;
|
|
2524
2540
|
provider;
|
|
2525
2541
|
apiKey;
|
|
@@ -2552,6 +2568,7 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2552
2568
|
timeout: Math.min(timeout, inherited.config.timeout || 12e4)
|
|
2553
2569
|
};
|
|
2554
2570
|
this.env = inherited.env;
|
|
2571
|
+
this.workbenchProviderProxy = inherited.workbenchProviderProxy;
|
|
2555
2572
|
this.provider = inherited.provider;
|
|
2556
2573
|
this.apiKey = inherited.apiKey;
|
|
2557
2574
|
this.baseUrl = inherited.baseUrl;
|
|
@@ -2591,8 +2608,9 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2591
2608
|
...config.agentModels ? { agentModels: Object.freeze({ ...config.agentModels }) } : {}
|
|
2592
2609
|
};
|
|
2593
2610
|
this.env = Object.freeze({ ...process.env, ...config.env });
|
|
2611
|
+
this.workbenchProviderProxy = resolveWorkbenchProviderProxy(this.env);
|
|
2594
2612
|
this.azureConfig = parseCodexAzureConfig(this.env);
|
|
2595
|
-
this.fallbackChain = getFallbackChain(this.env).map((entry) => ({
|
|
2613
|
+
this.fallbackChain = (this.workbenchProviderProxy ? [] : getFallbackChain(this.env)).map((entry) => ({
|
|
2596
2614
|
...entry,
|
|
2597
2615
|
credentials: resolveFailoverProvider(entry.provider, entry.model, this.env)
|
|
2598
2616
|
}));
|
|
@@ -2603,7 +2621,7 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2603
2621
|
this.baseUrl = detected.baseUrl;
|
|
2604
2622
|
this.wireApi = detected.wireApi;
|
|
2605
2623
|
this.codexAuthState = void 0;
|
|
2606
|
-
if (this.provider === "chatgpt-codex" || this.fallbackChain.some((entry) => entry.provider === "chatgpt-codex")) {
|
|
2624
|
+
if (!this.workbenchProviderProxy && (this.provider === "chatgpt-codex" || this.fallbackChain.some((entry) => entry.provider === "chatgpt-codex"))) {
|
|
2607
2625
|
if (readChatGptCodexEnv(this.env) || readChatGptCodexAuthFile(this.env)) {
|
|
2608
2626
|
this.codexAuthState = resolveChatGptCodexAuthState(this.env);
|
|
2609
2627
|
}
|
|
@@ -2661,14 +2679,50 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2661
2679
|
}
|
|
2662
2680
|
return createHash("sha256").update(JSON.stringify(identity)).digest("hex");
|
|
2663
2681
|
}
|
|
2682
|
+
/** Documented effort controls only on routes which send Responses reasoning. */
|
|
2683
|
+
reasoningConfiguration() {
|
|
2684
|
+
if (this.wireApi !== "responses" || !["openai", "azure", "chatgpt-codex"].includes(this.provider))
|
|
2685
|
+
return null;
|
|
2686
|
+
const model = this.model.replace(/^openai\//, "");
|
|
2687
|
+
let options;
|
|
2688
|
+
if (/^gpt-(?:6-astra|6\.1-sol)(?:-20\d\d-\d\d-\d\d)?$/.test(model))
|
|
2689
|
+
options = ["low", "medium", "high", "xhigh", "max"];
|
|
2690
|
+
else if (/^gpt-(?:6-sol|6-luna|5\.6(?:-sol|-terra|-luna)?)(?:-20\d\d-\d\d-\d\d)?$/.test(model))
|
|
2691
|
+
options = ["none", "low", "medium", "high", "xhigh", "max"];
|
|
2692
|
+
else
|
|
2693
|
+
return null;
|
|
2694
|
+
const effort = this.reasoningEffort ?? defaultReasoningEffort(this.model) ?? "medium";
|
|
2695
|
+
return options.includes(effort) ? { effort, options } : null;
|
|
2696
|
+
}
|
|
2697
|
+
/** Apply an effort for subsequent requests and same-model worker forks. */
|
|
2698
|
+
setReasoningEffort(effort) {
|
|
2699
|
+
const configuration = this.reasoningConfiguration();
|
|
2700
|
+
if (!configuration || !configuration.options.includes(effort))
|
|
2701
|
+
throw new Error("This reasoning effort is not supported by the selected model and connection.");
|
|
2702
|
+
this.reasoningEffort = effort;
|
|
2703
|
+
}
|
|
2664
2704
|
/** Discover models using this runtime's captured account, including after a separate login changes. */
|
|
2665
2705
|
async codexModelCatalog(signal) {
|
|
2706
|
+
if (this.workbenchProviderProxy) {
|
|
2707
|
+
signal?.throwIfAborted();
|
|
2708
|
+
return [{ id: this.workbenchProviderProxy.model }];
|
|
2709
|
+
}
|
|
2666
2710
|
const state = this.codexAuthState;
|
|
2667
2711
|
if (this.provider !== "chatgpt-codex" || !state)
|
|
2668
2712
|
throw new Error("No active Codex subscription");
|
|
2669
|
-
const { loadCodexModelCatalog } = await import("./codex-models-
|
|
2713
|
+
const { loadCodexModelCatalog } = await import("./codex-models-Z43V3427.js");
|
|
2670
2714
|
return loadCodexModelCatalog({ signal, resolveCredentials: () => refreshChatGptCodexAuthState(state) });
|
|
2671
2715
|
}
|
|
2716
|
+
/** Host-only inference grant bound to this captured account, including after
|
|
2717
|
+
* later logins or runtime reconfiguration. Never serialize the closure or
|
|
2718
|
+
* its result into guest admission, workspace files or environment. */
|
|
2719
|
+
workbenchCredentialResolver() {
|
|
2720
|
+
const state = this.codexAuthState;
|
|
2721
|
+
if (this.workbenchProviderProxy || this.provider !== "chatgpt-codex" || !state) {
|
|
2722
|
+
throw new Error("Host workbench credential broker requires a captured chatgpt-codex account");
|
|
2723
|
+
}
|
|
2724
|
+
return () => refreshChatGptCodexAuthState(state);
|
|
2725
|
+
}
|
|
2672
2726
|
/**
|
|
2673
2727
|
* Mutate the live selection in place so the NEXT turn (the engine reads
|
|
2674
2728
|
* `config.runtime` per turn) and the NEXT `forkForSubagent` pick up the new
|
|
@@ -2685,6 +2739,7 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2685
2739
|
model: sel.model,
|
|
2686
2740
|
...sel.agentModels !== void 0 ? { agentModels: sel.agentModels } : {},
|
|
2687
2741
|
...sel.singleModel !== void 0 ? { singleModel: sel.singleModel } : {},
|
|
2742
|
+
...sel.autoRoute !== void 0 ? { autoRoute: sel.autoRoute } : {},
|
|
2688
2743
|
...sel.env !== void 0 ? { env: sel.env } : {}
|
|
2689
2744
|
};
|
|
2690
2745
|
this.applyConfiguration(merged);
|
|
@@ -2696,6 +2751,9 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2696
2751
|
if (sel.singleModel !== void 0) {
|
|
2697
2752
|
this.config = { ...this.config, singleModel: sel.singleModel };
|
|
2698
2753
|
}
|
|
2754
|
+
if (sel.autoRoute !== void 0) {
|
|
2755
|
+
this.config = { ...this.config, autoRoute: sel.autoRoute };
|
|
2756
|
+
}
|
|
2699
2757
|
if (sel.model !== void 0) {
|
|
2700
2758
|
const model = this.provider === "opencode" ? opencodeModelId(sel.model) : this.provider === "copilot" ? copilotModelId(sel.model) : sel.model;
|
|
2701
2759
|
if (model !== this.model) {
|
|
@@ -2727,6 +2785,8 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2727
2785
|
* failover chain uses — including auth-only providers (chatgpt-codex OAuth).
|
|
2728
2786
|
*/
|
|
2729
2787
|
accessibleProviders() {
|
|
2788
|
+
if (this.workbenchProviderProxy)
|
|
2789
|
+
return ["chatgpt-codex"];
|
|
2730
2790
|
const out = [];
|
|
2731
2791
|
for (const provider of Object.keys(DEFAULT_PROVIDER_MODELS)) {
|
|
2732
2792
|
const probeModel = DEFAULT_PROVIDER_MODELS[provider] || "probe";
|
|
@@ -2743,6 +2803,8 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2743
2803
|
* provider has creds, so this is a helpful starting set, not the whole bound.
|
|
2744
2804
|
*/
|
|
2745
2805
|
accessibleModels() {
|
|
2806
|
+
if (this.workbenchProviderProxy)
|
|
2807
|
+
return [this.workbenchProviderProxy.model];
|
|
2746
2808
|
const models = /* @__PURE__ */ new Set();
|
|
2747
2809
|
if (this.model)
|
|
2748
2810
|
models.add(this.model);
|
|
@@ -2760,6 +2822,8 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2760
2822
|
* accessible defaults as a fallback for ids the router does not pattern-match.
|
|
2761
2823
|
*/
|
|
2762
2824
|
isModelAccessible(model) {
|
|
2825
|
+
if (this.workbenchProviderProxy)
|
|
2826
|
+
return this.accessibleModels().includes(model);
|
|
2763
2827
|
if (providerForModel(model, this.env) !== void 0)
|
|
2764
2828
|
return true;
|
|
2765
2829
|
return this.accessibleModels().includes(model);
|
|
@@ -2849,6 +2913,17 @@ var LlmApiRuntime = class _LlmApiRuntime {
|
|
|
2849
2913
|
resolvedModel() {
|
|
2850
2914
|
return this.model;
|
|
2851
2915
|
}
|
|
2916
|
+
/** JSON-safe routing policy, not the runtime's private environment or configuration. */
|
|
2917
|
+
modelSelection() {
|
|
2918
|
+
return {
|
|
2919
|
+
agentModels: { ...this.config.agentModels },
|
|
2920
|
+
singleModel: this.config.singleModel === true,
|
|
2921
|
+
autoRoute: this.config.autoRoute === true
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
resolvedProvider() {
|
|
2925
|
+
return this.provider;
|
|
2926
|
+
}
|
|
2852
2927
|
/** Price discovered IDs on their actual route without changing the wire model. */
|
|
2853
2928
|
resolvedPricingModel() {
|
|
2854
2929
|
if (this.provider === "chatgpt-codex" || this.provider === "copilot" || this.provider === "google")
|
|
@@ -3252,7 +3327,13 @@ Missing: ${missing.join("; ")}
|
|
|
3252
3327
|
abort?.throwIfCancelled();
|
|
3253
3328
|
let res;
|
|
3254
3329
|
try {
|
|
3255
|
-
res = await fetch(this.
|
|
3330
|
+
res = this.workbenchProviderProxy ? await fetch(this.workbenchProviderProxy.url, {
|
|
3331
|
+
method: "POST",
|
|
3332
|
+
redirect: "error",
|
|
3333
|
+
headers: { "Content-Type": "application/json" },
|
|
3334
|
+
body: JSON.stringify({ provider: this.provider, model: this.model, body: bodyFactory() }),
|
|
3335
|
+
signal
|
|
3336
|
+
}) : await fetch(this.buildUrl(), {
|
|
3256
3337
|
method: "POST",
|
|
3257
3338
|
headers: await this.ensureFreshHeaders(),
|
|
3258
3339
|
body: bodyFactory(),
|
|
@@ -3377,6 +3458,22 @@ Missing: ${missing.join("; ")}
|
|
|
3377
3458
|
// ── Legacy Runtime interface (single-prompt) ──
|
|
3378
3459
|
async execute(prompt, context) {
|
|
3379
3460
|
const start = Date.now();
|
|
3461
|
+
if (context?.signal?.aborted) {
|
|
3462
|
+
return { output: "", exitCode: null, timedOut: false, durationMs: 0, error: "API execution cancelled." };
|
|
3463
|
+
}
|
|
3464
|
+
if (this.workbenchProviderProxy) {
|
|
3465
|
+
const result = await this.executeNative(context?.systemPrompt ?? "", [
|
|
3466
|
+
{ role: "user", content: [{ type: "text", text: prompt }] }
|
|
3467
|
+
], [], void 0, context?.signal);
|
|
3468
|
+
return {
|
|
3469
|
+
output: result.content.filter((block) => block.type === "text").map((block) => block.text).join("\n"),
|
|
3470
|
+
exitCode: result.cancelled ? null : result.stopReason === "error" ? 1 : 0,
|
|
3471
|
+
timedOut: false,
|
|
3472
|
+
durationMs: Date.now() - start,
|
|
3473
|
+
usage: result.usage,
|
|
3474
|
+
error: result.error
|
|
3475
|
+
};
|
|
3476
|
+
}
|
|
3380
3477
|
if (!this.apiKey && this.provider !== "chatgpt-codex" && this.provider !== "google") {
|
|
3381
3478
|
return {
|
|
3382
3479
|
output: "",
|
|
@@ -3389,9 +3486,11 @@ Missing: ${missing.join("; ")}
|
|
|
3389
3486
|
const systemPrompt = context?.systemPrompt ?? "";
|
|
3390
3487
|
const controller = new AbortController();
|
|
3391
3488
|
const timer = setTimeout(() => controller.abort(), this.config.timeout || 12e4);
|
|
3489
|
+
const abort = composeCallAbort(controller.signal, context?.signal);
|
|
3392
3490
|
try {
|
|
3393
3491
|
let res;
|
|
3394
3492
|
do {
|
|
3493
|
+
abort.throwIfCancelled();
|
|
3395
3494
|
if (this.isOpenAICompat && this.wireApi === "chat_completions") {
|
|
3396
3495
|
const messages = [];
|
|
3397
3496
|
if (systemPrompt) {
|
|
@@ -3404,7 +3503,7 @@ Missing: ${missing.join("; ")}
|
|
|
3404
3503
|
messages,
|
|
3405
3504
|
// See executeNative: explicit reasoning_effort passthrough only.
|
|
3406
3505
|
...this.reasoningEffort ? { reasoning_effort: this.reasoningEffort } : {}
|
|
3407
|
-
}),
|
|
3506
|
+
}), abort.signal, abort);
|
|
3408
3507
|
} else if (this.isOpenAICompat && this.wireApi === "responses") {
|
|
3409
3508
|
const input = [];
|
|
3410
3509
|
if (systemPrompt) {
|
|
@@ -3422,7 +3521,7 @@ Missing: ${missing.join("; ")}
|
|
|
3422
3521
|
model: this.model,
|
|
3423
3522
|
input,
|
|
3424
3523
|
...isCodex ? { store: false } : { max_output_tokens: NATIVE_COMPLETION_TOKEN_LIMIT }
|
|
3425
|
-
}),
|
|
3524
|
+
}), abort.signal, abort);
|
|
3426
3525
|
} else if (this.isGeminiCodeAssist) {
|
|
3427
3526
|
const request = {
|
|
3428
3527
|
...systemPrompt ? { systemInstruction: { parts: [{ text: systemPrompt }] } } : {},
|
|
@@ -3430,13 +3529,13 @@ Missing: ${missing.join("; ")}
|
|
|
3430
3529
|
generationConfig: { maxOutputTokens: NATIVE_COMPLETION_TOKEN_LIMIT }
|
|
3431
3530
|
};
|
|
3432
3531
|
const geminiBody = await this.wrapGeminiCodeAssistBody(request);
|
|
3433
|
-
res = await this.postWithRetry(() => JSON.stringify(geminiBody),
|
|
3532
|
+
res = await this.postWithRetry(() => JSON.stringify(geminiBody), abort.signal, abort);
|
|
3434
3533
|
} else if (this.isGoogleWire) {
|
|
3435
3534
|
res = await this.postWithRetry(() => JSON.stringify({
|
|
3436
3535
|
...systemPrompt ? { systemInstruction: { parts: [{ text: systemPrompt }] } } : {},
|
|
3437
3536
|
contents: [{ role: "user", parts: [{ text: prompt }] }],
|
|
3438
3537
|
generationConfig: { maxOutputTokens: NATIVE_COMPLETION_TOKEN_LIMIT }
|
|
3439
|
-
}),
|
|
3538
|
+
}), abort.signal, abort);
|
|
3440
3539
|
} else if (this.isAnthropicWire) {
|
|
3441
3540
|
res = await this.postWithRetry(() => JSON.stringify({
|
|
3442
3541
|
model: this.model,
|
|
@@ -3444,12 +3543,11 @@ Missing: ${missing.join("; ")}
|
|
|
3444
3543
|
...this.anthropicThinkingField(),
|
|
3445
3544
|
...systemPrompt ? { system: systemPrompt } : {},
|
|
3446
3545
|
messages: [{ role: "user", content: prompt }]
|
|
3447
|
-
}),
|
|
3546
|
+
}), abort.signal, abort);
|
|
3448
3547
|
} else {
|
|
3449
3548
|
throw new Error(`execute: provider ${this.provider} is not mapped to a wire`);
|
|
3450
3549
|
}
|
|
3451
3550
|
} while (!res);
|
|
3452
|
-
clearTimeout(timer);
|
|
3453
3551
|
const body = await res.text();
|
|
3454
3552
|
if (!res.ok) {
|
|
3455
3553
|
appendNativeTrace({
|
|
@@ -3483,12 +3581,9 @@ Missing: ${missing.join("; ")}
|
|
|
3483
3581
|
if (this.isAnthropicWire) {
|
|
3484
3582
|
usage = readCacheUsage(json.usage);
|
|
3485
3583
|
} else if ((this.isGoogleWire || this.isGeminiCodeAssist) && json.usageMetadata) {
|
|
3486
|
-
usage =
|
|
3487
|
-
inputTokens: json.usageMetadata.promptTokenCount ?? 0,
|
|
3488
|
-
outputTokens: json.usageMetadata.candidatesTokenCount ?? 0
|
|
3489
|
-
};
|
|
3584
|
+
usage = readGoogleUsage(json.usageMetadata);
|
|
3490
3585
|
} else if (this.isOpenAICompat && json.usage) {
|
|
3491
|
-
usage = this.wireApi === "chat_completions" ?
|
|
3586
|
+
usage = this.wireApi === "chat_completions" ? readChatUsage(json.usage) : { inputTokens: json.usage.input_tokens ?? 0, outputTokens: json.usage.output_tokens ?? 0, ...readResponsesCachedTokens(json.usage) };
|
|
3492
3587
|
}
|
|
3493
3588
|
return {
|
|
3494
3589
|
output: text,
|
|
@@ -3499,6 +3594,9 @@ Missing: ${missing.join("; ")}
|
|
|
3499
3594
|
};
|
|
3500
3595
|
} catch (err) {
|
|
3501
3596
|
clearTimeout(timer);
|
|
3597
|
+
if (abort.operatorAborted()) {
|
|
3598
|
+
return { output: "", exitCode: null, timedOut: false, durationMs: Date.now() - start, error: "API execution cancelled." };
|
|
3599
|
+
}
|
|
3502
3600
|
if (err instanceof QuotaExhaustedError) {
|
|
3503
3601
|
return {
|
|
3504
3602
|
output: "",
|
|
@@ -3517,6 +3615,9 @@ Missing: ${missing.join("; ")}
|
|
|
3517
3615
|
durationMs: Date.now() - start,
|
|
3518
3616
|
error: timedOut ? `${this.providerLabel} API request timed out` : `${this.providerLabel} API error: ${msg}`
|
|
3519
3617
|
};
|
|
3618
|
+
} finally {
|
|
3619
|
+
clearTimeout(timer);
|
|
3620
|
+
abort.dispose();
|
|
3520
3621
|
}
|
|
3521
3622
|
}
|
|
3522
3623
|
// ── Native Runtime interface (structured messages + tool_use) ──
|
|
@@ -3903,62 +4004,7 @@ Missing: ${missing.join("; ")}
|
|
|
3903
4004
|
const finishReason = choice?.finish_reason;
|
|
3904
4005
|
stopReason = finishReason === "tool_calls" || finishReason === "function_call" ? "tool_use" : finishReason === "length" ? "max_tokens" : "end_turn";
|
|
3905
4006
|
if (json.usage) {
|
|
3906
|
-
usage =
|
|
3907
|
-
inputTokens: json.usage.prompt_tokens ?? 0,
|
|
3908
|
-
outputTokens: json.usage.completion_tokens ?? 0
|
|
3909
|
-
};
|
|
3910
|
-
}
|
|
3911
|
-
} else if (this.isOpenAICompat && this.wireApi === "responses") {
|
|
3912
|
-
content = [];
|
|
3913
|
-
const reasoningSummaries = [];
|
|
3914
|
-
const rawOutput = json.output ?? [];
|
|
3915
|
-
if (rawOutput.length > 0) {
|
|
3916
|
-
providerRaw = {
|
|
3917
|
-
provider: this.provider,
|
|
3918
|
-
model: this.model,
|
|
3919
|
-
wireApi: this.wireApi,
|
|
3920
|
-
output: rawOutput
|
|
3921
|
-
};
|
|
3922
|
-
}
|
|
3923
|
-
for (const item of json.output ?? []) {
|
|
3924
|
-
if (item.type === "function_call") {
|
|
3925
|
-
content.push({
|
|
3926
|
-
type: "tool_use",
|
|
3927
|
-
id: item.call_id,
|
|
3928
|
-
name: item.name,
|
|
3929
|
-
input: safeParseJson(item.arguments)
|
|
3930
|
-
});
|
|
3931
|
-
continue;
|
|
3932
|
-
}
|
|
3933
|
-
if (item.type === "reasoning") {
|
|
3934
|
-
const summaryParts = Array.isArray(item.summary) ? item.summary.map((block) => typeof block.text === "string" ? block.text : "").filter((text) => text.trim().length > 0) : [];
|
|
3935
|
-
const reasoningText = summaryParts.join("\n").trim();
|
|
3936
|
-
if (reasoningText)
|
|
3937
|
-
reasoningSummaries.push(reasoningText);
|
|
3938
|
-
continue;
|
|
3939
|
-
}
|
|
3940
|
-
for (const block of item.content ?? []) {
|
|
3941
|
-
if (block.type === "output_text") {
|
|
3942
|
-
content.push({ type: "text", text: block.text });
|
|
3943
|
-
} else if (block.type === "summary_text" || block.type === "reasoning_text") {
|
|
3944
|
-
const text = typeof block.text === "string" ? block.text : "";
|
|
3945
|
-
if (text.trim())
|
|
3946
|
-
reasoningSummaries.push(text);
|
|
3947
|
-
}
|
|
3948
|
-
}
|
|
3949
|
-
}
|
|
3950
|
-
if (callbacks?.onThinking && reasoningSummaries.length > 0) {
|
|
3951
|
-
callbacks.onThinking(reasoningSummaries.join("\n"));
|
|
3952
|
-
}
|
|
3953
|
-
stopReason = content.some((block) => block.type === "tool_use") ? "tool_use" : "end_turn";
|
|
3954
|
-
if (json.usage) {
|
|
3955
|
-
usage = {
|
|
3956
|
-
inputTokens: json.usage.input_tokens ?? 0,
|
|
3957
|
-
outputTokens: json.usage.output_tokens ?? 0,
|
|
3958
|
-
// Responses `input_tokens` already includes the cached span, so
|
|
3959
|
-
// this is instrumentation only — see the streaming path.
|
|
3960
|
-
...readResponsesCachedTokens(json.usage)
|
|
3961
|
-
};
|
|
4007
|
+
usage = readChatUsage(json.usage);
|
|
3962
4008
|
}
|
|
3963
4009
|
} else if (this.isGoogleWire || this.isGeminiCodeAssist) {
|
|
3964
4010
|
const candidate = json.candidates?.[0];
|
|
@@ -3990,10 +4036,7 @@ Missing: ${missing.join("; ")}
|
|
|
3990
4036
|
const finishReason = String(candidate?.finishReason ?? "").toUpperCase();
|
|
3991
4037
|
stopReason = content.some((block) => block.type === "tool_use") ? "tool_use" : finishReason === "MAX_TOKENS" ? "max_tokens" : "end_turn";
|
|
3992
4038
|
if (json.usageMetadata) {
|
|
3993
|
-
usage =
|
|
3994
|
-
inputTokens: json.usageMetadata.promptTokenCount ?? 0,
|
|
3995
|
-
outputTokens: json.usageMetadata.candidatesTokenCount ?? 0
|
|
3996
|
-
};
|
|
4039
|
+
usage = readGoogleUsage(json.usageMetadata);
|
|
3997
4040
|
}
|
|
3998
4041
|
} else {
|
|
3999
4042
|
const rawBlocks = json.content ?? [];
|
|
@@ -4135,6 +4178,9 @@ Missing: ${missing.join("; ")}
|
|
|
4135
4178
|
const eventTypes = /* @__PURE__ */ new Set();
|
|
4136
4179
|
const identifier = (value) => typeof value === "string" && /^[A-Za-z0-9_.:-]{1,96}$/.test(value) ? value : null;
|
|
4137
4180
|
let completedResponse = null;
|
|
4181
|
+
let outputCapResponse;
|
|
4182
|
+
let assistantText = "";
|
|
4183
|
+
const pendingFunctionCalls = /* @__PURE__ */ new Set();
|
|
4138
4184
|
let streamFailure;
|
|
4139
4185
|
let responseUsage;
|
|
4140
4186
|
const streamedOutputItems = [];
|
|
@@ -4239,9 +4285,13 @@ Missing: ${missing.join("; ")}
|
|
|
4239
4285
|
};
|
|
4240
4286
|
callbacks?.onUsage?.(responseUsage);
|
|
4241
4287
|
}
|
|
4288
|
+
const incomplete = response?.incomplete_details;
|
|
4289
|
+
if (type === "response.incomplete" && response?.status === "incomplete" && incomplete?.reason === "max_output_tokens" && response.error == null && event.error == null && event.code == null && !completedResponse && malformedEvents === 0) {
|
|
4290
|
+
outputCapResponse = response;
|
|
4291
|
+
break responses;
|
|
4292
|
+
}
|
|
4242
4293
|
if (!terminal || !response || response.error != null || (type === "response.done" || response.status !== void 0) && response.status !== "completed") {
|
|
4243
4294
|
const error = response?.error ?? event.error;
|
|
4244
|
-
const incomplete = response?.incomplete_details;
|
|
4245
4295
|
streamFailure = {
|
|
4246
4296
|
event: type,
|
|
4247
4297
|
status: identifier(response?.status),
|
|
@@ -4257,6 +4307,7 @@ Missing: ${missing.join("; ")}
|
|
|
4257
4307
|
if (type === "response.output_text.delta" || this.provider === "openrouter" && type === "response.content_part.delta") {
|
|
4258
4308
|
const delta = typeof event.delta === "string" ? event.delta : "";
|
|
4259
4309
|
if (delta) {
|
|
4310
|
+
assistantText += delta;
|
|
4260
4311
|
callbacks?.onDelta?.("assistant_response", delta);
|
|
4261
4312
|
}
|
|
4262
4313
|
continue;
|
|
@@ -4278,9 +4329,18 @@ Missing: ${missing.join("; ")}
|
|
|
4278
4329
|
}
|
|
4279
4330
|
continue;
|
|
4280
4331
|
}
|
|
4332
|
+
if (type === "response.output_item.added") {
|
|
4333
|
+
const item = event.item;
|
|
4334
|
+
if (item?.type === "function_call") {
|
|
4335
|
+
pendingFunctionCalls.add(String(item.id ?? item.call_id ?? event.output_index ?? pendingFunctionCalls.size));
|
|
4336
|
+
}
|
|
4337
|
+
continue;
|
|
4338
|
+
}
|
|
4281
4339
|
if (type === "response.output_item.done") {
|
|
4282
4340
|
const item = event.item;
|
|
4283
4341
|
if (item && typeof item.type === "string") {
|
|
4342
|
+
if (item.type === "function_call")
|
|
4343
|
+
pendingFunctionCalls.add(String(item.id ?? item.call_id ?? event.output_index ?? pendingFunctionCalls.size));
|
|
4284
4344
|
streamedOutputItems.push(item);
|
|
4285
4345
|
}
|
|
4286
4346
|
continue;
|
|
@@ -4288,6 +4348,46 @@ Missing: ${missing.join("; ")}
|
|
|
4288
4348
|
}
|
|
4289
4349
|
}
|
|
4290
4350
|
emitThinking(true);
|
|
4351
|
+
if (outputCapResponse) {
|
|
4352
|
+
void reader.cancel().catch(() => {
|
|
4353
|
+
});
|
|
4354
|
+
const finalOutput = Array.isArray(outputCapResponse.output) ? outputCapResponse.output : [];
|
|
4355
|
+
const output = finalOutput.length > 0 ? finalOutput : streamedOutputItems;
|
|
4356
|
+
let finalText = "";
|
|
4357
|
+
for (const item of output) {
|
|
4358
|
+
if (item.type === "function_call")
|
|
4359
|
+
pendingFunctionCalls.add(String(item.id ?? item.call_id ?? pendingFunctionCalls.size));
|
|
4360
|
+
if (!Array.isArray(item.content))
|
|
4361
|
+
continue;
|
|
4362
|
+
for (const block of item.content) {
|
|
4363
|
+
if (block.type === "output_text" && typeof block.text === "string")
|
|
4364
|
+
finalText += block.text;
|
|
4365
|
+
}
|
|
4366
|
+
}
|
|
4367
|
+
const text = finalText.startsWith(assistantText) ? finalText : assistantText || finalText;
|
|
4368
|
+
if (operatorSignal?.aborted) {
|
|
4369
|
+
return { ...this.cancelledResult(start), content: [{ type: "text", text }], usage: responseUsage };
|
|
4370
|
+
}
|
|
4371
|
+
const checkpoint = {
|
|
4372
|
+
reason: "max_output_tokens",
|
|
4373
|
+
...identifier(outputCapResponse.id) ? { responseId: String(outputCapResponse.id) } : {},
|
|
4374
|
+
discardedToolCalls: pendingFunctionCalls.size
|
|
4375
|
+
};
|
|
4376
|
+
appendNativeTrace({
|
|
4377
|
+
kind: "native-response-checkpoint",
|
|
4378
|
+
provider: this.providerLabel,
|
|
4379
|
+
wireApi: this.wireApi,
|
|
4380
|
+
checkpoint,
|
|
4381
|
+
usage: responseUsage ?? null
|
|
4382
|
+
});
|
|
4383
|
+
return {
|
|
4384
|
+
content: [{ type: "text", text }],
|
|
4385
|
+
stopReason: "max_tokens",
|
|
4386
|
+
checkpoint,
|
|
4387
|
+
usage: responseUsage,
|
|
4388
|
+
durationMs: Date.now() - start
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4291
4391
|
if (!completedResponse || streamFailure) {
|
|
4292
4392
|
if (streamFailure) {
|
|
4293
4393
|
void reader.cancel().catch(() => {
|
|
@@ -4333,18 +4433,25 @@ Missing: ${missing.join("; ")}
|
|
|
4333
4433
|
})),
|
|
4334
4434
|
topLevelKeys: Object.keys(completedResponse)
|
|
4335
4435
|
});
|
|
4336
|
-
const completedOutput = completedResponse.output
|
|
4337
|
-
const outputItems =
|
|
4436
|
+
const completedOutput = Array.isArray(completedResponse.output) ? completedResponse.output : [];
|
|
4437
|
+
const outputItems = completedOutput.length > 0 ? completedOutput : streamedOutputItems;
|
|
4338
4438
|
const content = [];
|
|
4339
4439
|
const reasoningSummaries = [];
|
|
4440
|
+
const callIds = /* @__PURE__ */ new Set();
|
|
4340
4441
|
for (const item of outputItems) {
|
|
4341
4442
|
if (item.type === "function_call") {
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4443
|
+
const call = parseResponsesFunctionCall(item);
|
|
4444
|
+
if (!call || callIds.has(call.id) || malformedEvents > 0) {
|
|
4445
|
+
return {
|
|
4446
|
+
content: [{ type: "text", text: assistantText }],
|
|
4447
|
+
stopReason: "error",
|
|
4448
|
+
usage: responseUsage,
|
|
4449
|
+
durationMs: Date.now() - start,
|
|
4450
|
+
error: `${this.providerLabel} API error: Responses completed with an incomplete or malformed function call`
|
|
4451
|
+
};
|
|
4452
|
+
}
|
|
4453
|
+
callIds.add(call.id);
|
|
4454
|
+
content.push(call);
|
|
4348
4455
|
continue;
|
|
4349
4456
|
}
|
|
4350
4457
|
if (item.type === "reasoning") {
|
|
@@ -4360,6 +4467,9 @@ Missing: ${missing.join("; ")}
|
|
|
4360
4467
|
}
|
|
4361
4468
|
}
|
|
4362
4469
|
}
|
|
4470
|
+
const observedTextFallback = !!assistantText && !content.some((block) => block.type === "text");
|
|
4471
|
+
if (observedTextFallback)
|
|
4472
|
+
content.unshift({ type: "text", text: assistantText });
|
|
4363
4473
|
if (lastThinkingEmit === 0 && reasoningSummaries.length > 0) {
|
|
4364
4474
|
thinkingText = reasoningSummaries.join("\n");
|
|
4365
4475
|
emitThinking(true);
|
|
@@ -4373,7 +4483,7 @@ Missing: ${missing.join("; ")}
|
|
|
4373
4483
|
// reasoning items with their `encrypted_content` still attached, each
|
|
4374
4484
|
// immediately followed by the item it produced. Handing it back lets the
|
|
4375
4485
|
// next turn replay it verbatim instead of re-deriving the reasoning.
|
|
4376
|
-
|
|
4486
|
+
...!observedTextFallback && outputItems.length > 0 ? {
|
|
4377
4487
|
providerRaw: {
|
|
4378
4488
|
provider: this.provider,
|
|
4379
4489
|
model: this.model,
|
|
@@ -4384,6 +4494,8 @@ Missing: ${missing.join("; ")}
|
|
|
4384
4494
|
};
|
|
4385
4495
|
}
|
|
4386
4496
|
async isAvailable() {
|
|
4497
|
+
if (this.workbenchProviderProxy)
|
|
4498
|
+
return true;
|
|
4387
4499
|
if (this.provider === "chatgpt-codex") {
|
|
4388
4500
|
return this.codexAuthState !== void 0;
|
|
4389
4501
|
}
|