nolo-cli 0.16.0-alpha.5 → 0.16.0-alpha.7
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/{agentDeleteCommand-7AI657MF.js → agentDeleteCommand-X35VSSVM.js} +4 -4
- package/{agentEmailCommands-KJJXDEGM.js → agentEmailCommands-LGMEEMQP.js} +5 -5
- package/{agentListCommands-HPXVKI4Q.js → agentListCommands-LLQHUE4O.js} +5 -5
- package/{agentMachineCommands-N3B2TVPV.js → agentMachineCommands-4Q5PFIKF.js} +4 -4
- package/{agentRecordCommands-M63W7DKA.js → agentRecordCommands-XUYVG7BS.js} +5 -5
- package/{agentRunCommand-JSXYRLUZ.js → agentRunCommand-NORLSA7L.js} +5 -5
- package/{agentRuntimeLocal-BILOZZYS.js → agentRuntimeLocal-N56G2ZJK.js} +1 -1
- package/{appDeleteCommands-NUJOKI4W.js → appDeleteCommands-WHRYDQLZ.js} +5 -5
- package/{appDeployCommands-A6N2FGQI.js → appDeployCommands-USRWBT6T.js} +5 -5
- package/{appDeployStatusCommands-7AM5QF3L.js → appDeployStatusCommands-R632IBVL.js} +5 -5
- package/{appGetCommands-5SKEWQ2M.js → appGetCommands-PKGC2JWH.js} +5 -5
- package/{appListCommands-DO3DRMFF.js → appListCommands-OMRAEOAL.js} +5 -5
- package/{chunk-Z7R7O2YU.js → chunk-2B3BNWPC.js} +1 -1
- package/{chunk-N7Y6Y4WV.js → chunk-6EFJQCL6.js} +545 -87
- package/{chunk-QSUEDDDQ.js → chunk-AKYTMRBP.js} +1 -1
- package/{chunk-4LDZJAM4.js → chunk-BS5STUTA.js} +2 -2
- package/{chunk-GYJSDXGN.js → chunk-C2BYYSAO.js} +5 -0
- package/{chunk-U27RSNNB.js → chunk-EFNMO3YF.js} +1 -1
- package/{chunk-YU3RHZQK.js → chunk-FJHD7FHN.js} +1 -1
- package/{chunk-VWLK6WAB.js → chunk-NY5FDXZL.js} +1 -1
- package/{chunk-QEZOL2ES.js → chunk-QSWWWYGA.js} +1 -1
- package/{chunk-SPNQ52KM.js → chunk-YLVJ7NB4.js} +2 -2
- package/{chunk-NNQCFBSX.js → chunk-YXQA6X6I.js} +5 -5
- package/{chunk-TCFMDZDB.js → chunk-ZRDWHLMQ.js} +1 -1
- package/{dialogCommands-MFSTNUJH.js → dialogCommands-L4LMXQAI.js} +5 -5
- package/{docCreateCommands-3BYOEDE4.js → docCreateCommands-C4HJCM47.js} +4 -4
- package/{docDeleteCommands-7SGOMJJC.js → docDeleteCommands-Y6W6A3W6.js} +5 -5
- package/{docReadCommands-GO2ODL3E.js → docReadCommands-2WUIDAR6.js} +4 -4
- package/{docUpdateCommands-7XUCR5T7.js → docUpdateCommands-XVL2CBKE.js} +4 -4
- package/index.js +40 -40
- package/{machineCommands-H7KTKQAT.js → machineCommands-SXOARUBD.js} +4 -4
- package/{machineWsRunDispatch-5QP2PLA6.js → machineWsRunDispatch-OZQ4WNCE.js} +4 -4
- package/package.json +1 -1
- package/{readlineWorkspace-PGZRQYIR.js → readlineWorkspace-AM2FA7HS.js} +8 -8
- package/{spaceCommands-IQQEG2MG.js → spaceCommands-PYFLKEAW.js} +4 -4
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
buildLocalAgentLookupKeys,
|
|
9
9
|
normalizeAgentHandle,
|
|
10
10
|
shouldReadAgentKeyRemotely
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QSWWWYGA.js";
|
|
12
12
|
import {
|
|
13
13
|
LOCAL_CODEX_AGENT_ID,
|
|
14
14
|
LOCAL_CODEX_AGENT_KEY,
|
|
@@ -76,9 +76,10 @@ import {
|
|
|
76
76
|
executeLocalToolWithPolicy,
|
|
77
77
|
executeOpenAiCompatibleChatCompletion,
|
|
78
78
|
parseSseDataLineJson,
|
|
79
|
+
parseSseDataLineObject,
|
|
79
80
|
readOpenAiCompatibleSseCompletion,
|
|
80
81
|
resolveOpenAiCompatibleProviderConfig
|
|
81
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-C2BYYSAO.js";
|
|
82
83
|
import {
|
|
83
84
|
buildPlatformChatCompletionRequest,
|
|
84
85
|
canUsePlatformChatProvider,
|
|
@@ -93,9 +94,12 @@ import {
|
|
|
93
94
|
resolveAgentRuntimeConfigFromRecord
|
|
94
95
|
} from "./chunk-OIQPORYI.js";
|
|
95
96
|
import {
|
|
96
|
-
parseToolArgumentsJson,
|
|
97
97
|
summarizeToolArguments
|
|
98
98
|
} from "./chunk-ZTRZ2O5B.js";
|
|
99
|
+
import {
|
|
100
|
+
convertMessagesToResponsesInput,
|
|
101
|
+
toResponsesTools
|
|
102
|
+
} from "./chunk-KFEVY3ST.js";
|
|
99
103
|
import {
|
|
100
104
|
resolvePlatformAuthToken
|
|
101
105
|
} from "./chunk-LJIJWXIT.js";
|
|
@@ -152,9 +156,6 @@ import {
|
|
|
152
156
|
import {
|
|
153
157
|
DEFAULT_NOLO_SERVER_URL
|
|
154
158
|
} from "./chunk-OLZBQWZU.js";
|
|
155
|
-
import {
|
|
156
|
-
asRecordOrEmpty
|
|
157
|
-
} from "./chunk-KX6YBIHG.js";
|
|
158
159
|
import {
|
|
159
160
|
createTokenKey,
|
|
160
161
|
createUserKey,
|
|
@@ -166,6 +167,9 @@ import {
|
|
|
166
167
|
import {
|
|
167
168
|
asOptionalFiniteNumber
|
|
168
169
|
} from "./chunk-WWC7I6TA.js";
|
|
170
|
+
import {
|
|
171
|
+
asTrimmedLowercaseString
|
|
172
|
+
} from "./chunk-QSJ3HFEF.js";
|
|
169
173
|
import {
|
|
170
174
|
BUILTIN_NOLO_AGENT_KEY,
|
|
171
175
|
PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
|
|
@@ -2431,19 +2435,22 @@ function resolveAntigravityWireModel(logicalModelId) {
|
|
|
2431
2435
|
return { wireModelId: id };
|
|
2432
2436
|
}
|
|
2433
2437
|
|
|
2434
|
-
// packages/agent-runtime/
|
|
2435
|
-
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2438
|
+
// packages/agent-runtime/geminiNativeShared.ts
|
|
2436
2439
|
var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2437
|
-
function
|
|
2440
|
+
function isGemini3Model(modelId) {
|
|
2438
2441
|
return modelId.includes("gemini-3");
|
|
2439
2442
|
}
|
|
2440
2443
|
function messageText(content) {
|
|
2441
2444
|
if (typeof content === "string") return content;
|
|
2442
2445
|
if (!Array.isArray(content)) return "";
|
|
2443
|
-
return content.filter(
|
|
2446
|
+
return content.filter(
|
|
2447
|
+
(part) => part?.type === "text"
|
|
2448
|
+
).map((part) => part.text).join("\n").trim();
|
|
2444
2449
|
}
|
|
2445
2450
|
function parseDataUrlToInlineData(url) {
|
|
2446
|
-
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
2451
|
+
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
2452
|
+
url
|
|
2453
|
+
);
|
|
2447
2454
|
if (!match) return null;
|
|
2448
2455
|
return { mimeType: match[1], data: match[2] };
|
|
2449
2456
|
}
|
|
@@ -2460,7 +2467,7 @@ function extractInlineDataParts(content) {
|
|
|
2460
2467
|
}
|
|
2461
2468
|
return parts;
|
|
2462
2469
|
}
|
|
2463
|
-
function
|
|
2470
|
+
function convertOpenAiMessagesToGemini(messages, options) {
|
|
2464
2471
|
const contents = [];
|
|
2465
2472
|
const systemTexts = [];
|
|
2466
2473
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
@@ -2476,9 +2483,11 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2476
2483
|
};
|
|
2477
2484
|
const flushPendingFunctionCalls = () => {
|
|
2478
2485
|
if (pendingFunctionCalls.length === 0) return;
|
|
2479
|
-
const dummyResponses = pendingFunctionCalls.map(
|
|
2480
|
-
|
|
2481
|
-
|
|
2486
|
+
const dummyResponses = pendingFunctionCalls.map(
|
|
2487
|
+
({ name }) => ({
|
|
2488
|
+
functionResponse: { name, response: { output: "{}" } }
|
|
2489
|
+
})
|
|
2490
|
+
);
|
|
2482
2491
|
pendingFunctionCalls = [];
|
|
2483
2492
|
pushOrMergeContent("user", dummyResponses);
|
|
2484
2493
|
};
|
|
@@ -2487,13 +2496,17 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2487
2496
|
const role = String(raw.role);
|
|
2488
2497
|
const content = "content" in raw ? raw.content : null;
|
|
2489
2498
|
if (role === "system") {
|
|
2490
|
-
const text = messageText(
|
|
2499
|
+
const text = messageText(
|
|
2500
|
+
content
|
|
2501
|
+
);
|
|
2491
2502
|
if (text) systemTexts.push(text);
|
|
2492
2503
|
continue;
|
|
2493
2504
|
}
|
|
2494
2505
|
if (role === "user") {
|
|
2495
2506
|
flushPendingFunctionCalls();
|
|
2496
|
-
const text = messageText(
|
|
2507
|
+
const text = messageText(
|
|
2508
|
+
content
|
|
2509
|
+
);
|
|
2497
2510
|
const imageParts = extractInlineDataParts(
|
|
2498
2511
|
content
|
|
2499
2512
|
);
|
|
@@ -2507,7 +2520,9 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2507
2520
|
if (role === "assistant") {
|
|
2508
2521
|
flushPendingFunctionCalls();
|
|
2509
2522
|
const parts = [];
|
|
2510
|
-
const text = messageText(
|
|
2523
|
+
const text = messageText(
|
|
2524
|
+
content
|
|
2525
|
+
);
|
|
2511
2526
|
if (text) parts.push({ text });
|
|
2512
2527
|
const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
|
|
2513
2528
|
for (const call of toolCalls) {
|
|
@@ -2517,17 +2532,20 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2517
2532
|
toolNamesById.set(id, name);
|
|
2518
2533
|
pendingFunctionCalls.push({ name, id });
|
|
2519
2534
|
const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
|
|
2520
|
-
const isFirstFunctionCallPart = !parts.some(
|
|
2521
|
-
|
|
2535
|
+
const isFirstFunctionCallPart = !parts.some(
|
|
2536
|
+
(p) => "functionCall" in p
|
|
2537
|
+
);
|
|
2538
|
+
const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
|
|
2539
|
+
const part = {
|
|
2522
2540
|
functionCall: {
|
|
2523
2541
|
name,
|
|
2524
|
-
args:
|
|
2525
|
-
id
|
|
2542
|
+
args: parseToolArgs(call.function?.arguments),
|
|
2543
|
+
...id ? { id } : {}
|
|
2526
2544
|
},
|
|
2527
|
-
...
|
|
2528
|
-
}
|
|
2545
|
+
...signature ? { thoughtSignature: signature } : {}
|
|
2546
|
+
};
|
|
2547
|
+
parts.push(part);
|
|
2529
2548
|
}
|
|
2530
|
-
if (parts.length === 0) continue;
|
|
2531
2549
|
pushOrMergeContent("model", parts);
|
|
2532
2550
|
continue;
|
|
2533
2551
|
}
|
|
@@ -2552,7 +2570,22 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2552
2570
|
flushPendingFunctionCalls();
|
|
2553
2571
|
return { contents, systemTexts };
|
|
2554
2572
|
}
|
|
2555
|
-
function
|
|
2573
|
+
function parseToolArgs(raw) {
|
|
2574
|
+
if (typeof raw === "string") {
|
|
2575
|
+
try {
|
|
2576
|
+
const parsed = JSON.parse(raw);
|
|
2577
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2578
|
+
return parsed;
|
|
2579
|
+
}
|
|
2580
|
+
} catch {
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
2584
|
+
return raw;
|
|
2585
|
+
}
|
|
2586
|
+
return {};
|
|
2587
|
+
}
|
|
2588
|
+
function convertOpenAiToolsToGemini(tools) {
|
|
2556
2589
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
2557
2590
|
const declarations = [];
|
|
2558
2591
|
for (const tool of tools) {
|
|
@@ -2569,6 +2602,97 @@ function convertOpenAiTools(tools) {
|
|
|
2569
2602
|
if (declarations.length === 0) return void 0;
|
|
2570
2603
|
return [{ functionDeclarations: declarations }];
|
|
2571
2604
|
}
|
|
2605
|
+
function accumulateGeminiChunks(chunks) {
|
|
2606
|
+
let text = "";
|
|
2607
|
+
const toolCalls = [];
|
|
2608
|
+
let usage;
|
|
2609
|
+
let pendingThoughtSignature;
|
|
2610
|
+
for (const chunk of chunks) {
|
|
2611
|
+
if (!chunk || typeof chunk !== "object") continue;
|
|
2612
|
+
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2613
|
+
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2614
|
+
const meta = response.usageMetadata;
|
|
2615
|
+
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2616
|
+
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2617
|
+
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2618
|
+
usage = {
|
|
2619
|
+
prompt_tokens: prompt,
|
|
2620
|
+
completion_tokens: candidates2,
|
|
2621
|
+
total_tokens: total
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2625
|
+
for (const candidate of candidates) {
|
|
2626
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
2627
|
+
const parts = Array.isArray(
|
|
2628
|
+
candidate.content?.parts
|
|
2629
|
+
) ? candidate.content.parts : [];
|
|
2630
|
+
for (const part of parts) {
|
|
2631
|
+
if (!part || typeof part !== "object") continue;
|
|
2632
|
+
const partSignature = part.thoughtSignature;
|
|
2633
|
+
if ("text" in part && typeof part.text === "string") {
|
|
2634
|
+
const piece = part.text;
|
|
2635
|
+
if (!part.thought) {
|
|
2636
|
+
text += piece;
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
if (part.thought && typeof partSignature === "string" && partSignature) {
|
|
2640
|
+
pendingThoughtSignature = partSignature;
|
|
2641
|
+
}
|
|
2642
|
+
if ("functionCall" in part && part.functionCall) {
|
|
2643
|
+
const call = part.functionCall;
|
|
2644
|
+
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2645
|
+
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2646
|
+
const argsObj = call.args && typeof call.args === "object" ? call.args : {};
|
|
2647
|
+
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2648
|
+
pendingThoughtSignature = void 0;
|
|
2649
|
+
toolCalls.push({
|
|
2650
|
+
id,
|
|
2651
|
+
type: "function",
|
|
2652
|
+
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2653
|
+
...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
|
|
2654
|
+
});
|
|
2655
|
+
}
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
return { text, toolCalls, usage };
|
|
2660
|
+
}
|
|
2661
|
+
function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
|
|
2662
|
+
return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
|
|
2663
|
+
}
|
|
2664
|
+
function buildGeminiGenerateContentRequest(args) {
|
|
2665
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(
|
|
2666
|
+
args.messages,
|
|
2667
|
+
{ attachSkipThoughtSignature: args.attachSkipThoughtSignature }
|
|
2668
|
+
);
|
|
2669
|
+
const request = { contents };
|
|
2670
|
+
if (systemTexts.length > 0) {
|
|
2671
|
+
request.systemInstruction = {
|
|
2672
|
+
role: "user",
|
|
2673
|
+
parts: systemTexts.map((text) => ({ text }))
|
|
2674
|
+
};
|
|
2675
|
+
}
|
|
2676
|
+
const toolsResult = convertOpenAiToolsToGemini(args.tools);
|
|
2677
|
+
if (toolsResult) {
|
|
2678
|
+
request.tools = toolsResult;
|
|
2679
|
+
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
2680
|
+
}
|
|
2681
|
+
const generationConfig = {};
|
|
2682
|
+
if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
|
|
2683
|
+
generationConfig.maxOutputTokens = args.maxTokens;
|
|
2684
|
+
}
|
|
2685
|
+
if (typeof args.temperature === "number") {
|
|
2686
|
+
generationConfig.temperature = args.temperature;
|
|
2687
|
+
}
|
|
2688
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
2689
|
+
request.generationConfig = generationConfig;
|
|
2690
|
+
}
|
|
2691
|
+
return request;
|
|
2692
|
+
}
|
|
2693
|
+
|
|
2694
|
+
// packages/agent-runtime/antigravityCloudCodeProvider.ts
|
|
2695
|
+
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2572
2696
|
function buildCloudCodeAssistPayload(args) {
|
|
2573
2697
|
const projectId = readAntigravityProjectId(args.metadata);
|
|
2574
2698
|
if (!projectId) {
|
|
@@ -2579,8 +2703,8 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2579
2703
|
const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
|
|
2580
2704
|
const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
|
|
2581
2705
|
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
2582
|
-
const { contents, systemTexts } =
|
|
2583
|
-
attachSkipThoughtSignature:
|
|
2706
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
|
|
2707
|
+
attachSkipThoughtSignature: isGemini3Model(model)
|
|
2584
2708
|
});
|
|
2585
2709
|
if (contents.length === 0) {
|
|
2586
2710
|
throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
|
|
@@ -2594,7 +2718,7 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2594
2718
|
parts: systemTexts.map((text) => ({ text }))
|
|
2595
2719
|
};
|
|
2596
2720
|
}
|
|
2597
|
-
const tools =
|
|
2721
|
+
const tools = convertOpenAiToolsToGemini(
|
|
2598
2722
|
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
2599
2723
|
);
|
|
2600
2724
|
if (tools) {
|
|
@@ -2641,63 +2765,6 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2641
2765
|
}
|
|
2642
2766
|
};
|
|
2643
2767
|
}
|
|
2644
|
-
function accumulateCcaChunks(chunks) {
|
|
2645
|
-
let text = "";
|
|
2646
|
-
const toolCalls = [];
|
|
2647
|
-
let usage;
|
|
2648
|
-
let pendingThoughtSignature;
|
|
2649
|
-
for (const chunk of chunks) {
|
|
2650
|
-
if (!chunk || typeof chunk !== "object") continue;
|
|
2651
|
-
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2652
|
-
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2653
|
-
const meta = response.usageMetadata;
|
|
2654
|
-
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2655
|
-
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2656
|
-
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2657
|
-
usage = {
|
|
2658
|
-
prompt_tokens: prompt,
|
|
2659
|
-
completion_tokens: candidates2,
|
|
2660
|
-
total_tokens: total
|
|
2661
|
-
};
|
|
2662
|
-
}
|
|
2663
|
-
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2664
|
-
for (const candidate of candidates) {
|
|
2665
|
-
if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
|
|
2666
|
-
const content = candidate.content;
|
|
2667
|
-
if (!content || typeof content !== "object" || !("parts" in content)) continue;
|
|
2668
|
-
const parts = content.parts;
|
|
2669
|
-
if (!Array.isArray(parts)) continue;
|
|
2670
|
-
for (const part of parts) {
|
|
2671
|
-
if (!part || typeof part !== "object") continue;
|
|
2672
|
-
const partSignature = part.thoughtSignature;
|
|
2673
|
-
if ("text" in part && typeof part.text === "string") {
|
|
2674
|
-
const piece = part.text;
|
|
2675
|
-
if (!part.thought) {
|
|
2676
|
-
text += piece;
|
|
2677
|
-
}
|
|
2678
|
-
}
|
|
2679
|
-
if (part.thought && typeof partSignature === "string" && partSignature) {
|
|
2680
|
-
pendingThoughtSignature = partSignature;
|
|
2681
|
-
}
|
|
2682
|
-
if ("functionCall" in part && part.functionCall) {
|
|
2683
|
-
const call = part.functionCall;
|
|
2684
|
-
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2685
|
-
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2686
|
-
const argsObj = asRecordOrEmpty(call.args);
|
|
2687
|
-
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2688
|
-
pendingThoughtSignature = void 0;
|
|
2689
|
-
toolCalls.push({
|
|
2690
|
-
id,
|
|
2691
|
-
type: "function",
|
|
2692
|
-
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2693
|
-
...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
|
|
2694
|
-
});
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
return { text, toolCalls, usage };
|
|
2700
|
-
}
|
|
2701
2768
|
async function readSseJsonChunks(response) {
|
|
2702
2769
|
return readSseDataValues(response, parseSseDataLineJson);
|
|
2703
2770
|
}
|
|
@@ -2722,7 +2789,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
|
|
|
2722
2789
|
};
|
|
2723
2790
|
}
|
|
2724
2791
|
const chunks = await readSseJsonChunks(response);
|
|
2725
|
-
const { text, toolCalls, usage } =
|
|
2792
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
2726
2793
|
const message = {
|
|
2727
2794
|
role: "assistant",
|
|
2728
2795
|
content: text || null
|
|
@@ -9021,6 +9088,234 @@ function isCursorOAuthAgent(agent) {
|
|
|
9021
9088
|
return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
|
|
9022
9089
|
}
|
|
9023
9090
|
|
|
9091
|
+
// packages/agent-runtime/codexResponsesProvider.ts
|
|
9092
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
9093
|
+
var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
|
|
9094
|
+
var CODEX_CLIENT_VERSION = "0.144.1";
|
|
9095
|
+
var CODEX_ORIGINATOR = "codex_cli_rs";
|
|
9096
|
+
var CODEX_OPENAI_BETA = "responses=experimental";
|
|
9097
|
+
var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
|
|
9098
|
+
var CODEX_INSTALLATION_ID = randomUUID4();
|
|
9099
|
+
function decodeCodexAccountId(accessToken) {
|
|
9100
|
+
const parts = accessToken.split(".");
|
|
9101
|
+
if (parts.length < 2) return void 0;
|
|
9102
|
+
try {
|
|
9103
|
+
const payload = JSON.parse(
|
|
9104
|
+
Buffer.from(parts[1], "base64").toString("utf8")
|
|
9105
|
+
);
|
|
9106
|
+
const claim = payload[OPENAI_AUTH_CLAIM];
|
|
9107
|
+
const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
|
|
9108
|
+
return typeof value === "string" && value ? value : void 0;
|
|
9109
|
+
} catch {
|
|
9110
|
+
return void 0;
|
|
9111
|
+
}
|
|
9112
|
+
}
|
|
9113
|
+
function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
|
|
9114
|
+
const sessionId = randomUUID4();
|
|
9115
|
+
const threadId = randomUUID4();
|
|
9116
|
+
const windowId = randomUUID4();
|
|
9117
|
+
const turnId = randomUUID4();
|
|
9118
|
+
const turnMetadata = {
|
|
9119
|
+
installation_id: installationId,
|
|
9120
|
+
session_id: sessionId,
|
|
9121
|
+
thread_id: threadId,
|
|
9122
|
+
turn_id: turnId,
|
|
9123
|
+
window_id: windowId,
|
|
9124
|
+
request_kind: "turn",
|
|
9125
|
+
turn_started_at_unix_ms: Date.now()
|
|
9126
|
+
};
|
|
9127
|
+
const turnMetadataJson = JSON.stringify(turnMetadata);
|
|
9128
|
+
return {
|
|
9129
|
+
sessionId,
|
|
9130
|
+
threadId,
|
|
9131
|
+
windowId,
|
|
9132
|
+
turnId,
|
|
9133
|
+
turnMetadataJson,
|
|
9134
|
+
clientMetadata: {
|
|
9135
|
+
"x-codex-installation-id": installationId,
|
|
9136
|
+
session_id: sessionId,
|
|
9137
|
+
thread_id: threadId,
|
|
9138
|
+
"x-codex-window-id": windowId,
|
|
9139
|
+
turn_id: turnId,
|
|
9140
|
+
"x-codex-turn-metadata": turnMetadataJson
|
|
9141
|
+
}
|
|
9142
|
+
};
|
|
9143
|
+
}
|
|
9144
|
+
function buildCodexCompatibilityHeaders(identity, accountId) {
|
|
9145
|
+
return {
|
|
9146
|
+
Authorization: "",
|
|
9147
|
+
// filled by caller with bearer token
|
|
9148
|
+
"Content-Type": "application/json",
|
|
9149
|
+
Accept: "text/event-stream",
|
|
9150
|
+
"chatgpt-account-id": accountId,
|
|
9151
|
+
"OpenAI-Beta": CODEX_OPENAI_BETA,
|
|
9152
|
+
originator: CODEX_ORIGINATOR,
|
|
9153
|
+
version: CODEX_CLIENT_VERSION,
|
|
9154
|
+
session_id: identity.sessionId,
|
|
9155
|
+
conversation_id: identity.sessionId,
|
|
9156
|
+
"x-client-request-id": identity.sessionId,
|
|
9157
|
+
"session-id": identity.sessionId,
|
|
9158
|
+
"thread-id": identity.threadId,
|
|
9159
|
+
"x-codex-window-id": identity.windowId,
|
|
9160
|
+
"x-codex-turn-metadata": identity.turnMetadataJson
|
|
9161
|
+
};
|
|
9162
|
+
}
|
|
9163
|
+
function collectInstructions(messages, agentPrompt) {
|
|
9164
|
+
const systemTexts = [];
|
|
9165
|
+
const prompt = agentPrompt?.trim();
|
|
9166
|
+
if (prompt) systemTexts.push(prompt);
|
|
9167
|
+
for (const raw of messages) {
|
|
9168
|
+
if (!raw || typeof raw !== "object") continue;
|
|
9169
|
+
const role = String(raw.role ?? "");
|
|
9170
|
+
if (role !== "system" && role !== "developer") continue;
|
|
9171
|
+
const content = raw.content;
|
|
9172
|
+
const stringContent = asOptionalTrimmedString(content);
|
|
9173
|
+
if (stringContent) {
|
|
9174
|
+
systemTexts.push(stringContent);
|
|
9175
|
+
} else if (Array.isArray(content)) {
|
|
9176
|
+
const text = content.filter(
|
|
9177
|
+
(p) => !!p && p.type === "text"
|
|
9178
|
+
).map((p) => p.text).join("\n").trim();
|
|
9179
|
+
if (text) systemTexts.push(text);
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
9182
|
+
return systemTexts.join("\n\n");
|
|
9183
|
+
}
|
|
9184
|
+
function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
|
|
9185
|
+
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
9186
|
+
const nonSystem = rawMessages.filter((m) => {
|
|
9187
|
+
const role = m && typeof m === "object" ? String(m.role) : "";
|
|
9188
|
+
return role !== "system" && role !== "developer";
|
|
9189
|
+
});
|
|
9190
|
+
const input = convertMessagesToResponsesInput(nonSystem);
|
|
9191
|
+
const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
|
|
9192
|
+
const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
|
|
9193
|
+
const tools = toResponsesTools(
|
|
9194
|
+
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
9195
|
+
);
|
|
9196
|
+
const body = {
|
|
9197
|
+
model,
|
|
9198
|
+
input,
|
|
9199
|
+
stream: true,
|
|
9200
|
+
store: false,
|
|
9201
|
+
prompt_cache_key: identity.sessionId,
|
|
9202
|
+
client_metadata: identity.clientMetadata
|
|
9203
|
+
};
|
|
9204
|
+
if (instructions) body.instructions = instructions;
|
|
9205
|
+
if (tools && tools.length > 0) {
|
|
9206
|
+
body.tools = tools;
|
|
9207
|
+
body.tool_choice = "auto";
|
|
9208
|
+
body.parallel_tool_calls = true;
|
|
9209
|
+
}
|
|
9210
|
+
return body;
|
|
9211
|
+
}
|
|
9212
|
+
function aggregateResponsesStream(events) {
|
|
9213
|
+
let text = "";
|
|
9214
|
+
const toolCalls = [];
|
|
9215
|
+
let usage;
|
|
9216
|
+
for (const ev of events) {
|
|
9217
|
+
const type = String(ev.type ?? "");
|
|
9218
|
+
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
9219
|
+
text += ev.delta;
|
|
9220
|
+
continue;
|
|
9221
|
+
}
|
|
9222
|
+
if (type === "response.output_item.done") {
|
|
9223
|
+
const item = ev.item;
|
|
9224
|
+
if (item && item.type === "function_call") {
|
|
9225
|
+
const name = typeof item.name === "string" ? item.name : "";
|
|
9226
|
+
if (name) {
|
|
9227
|
+
toolCalls.push({
|
|
9228
|
+
id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
|
|
9229
|
+
type: "function",
|
|
9230
|
+
function: {
|
|
9231
|
+
name,
|
|
9232
|
+
arguments: typeof item.arguments === "string" ? item.arguments : "{}"
|
|
9233
|
+
}
|
|
9234
|
+
});
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
continue;
|
|
9238
|
+
}
|
|
9239
|
+
if (type === "response.completed") {
|
|
9240
|
+
const response = ev.response;
|
|
9241
|
+
const u = response?.usage;
|
|
9242
|
+
if (u) {
|
|
9243
|
+
const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
|
|
9244
|
+
const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
|
|
9245
|
+
const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
|
|
9246
|
+
usage = {
|
|
9247
|
+
prompt_tokens: prompt,
|
|
9248
|
+
completion_tokens: completion,
|
|
9249
|
+
total_tokens: total
|
|
9250
|
+
};
|
|
9251
|
+
}
|
|
9252
|
+
}
|
|
9253
|
+
}
|
|
9254
|
+
return { text, toolCalls, usage };
|
|
9255
|
+
}
|
|
9256
|
+
async function readSseEvents(response) {
|
|
9257
|
+
return readSseDataValues(response, (line) => {
|
|
9258
|
+
const ev = parseSseDataLineObject(line);
|
|
9259
|
+
return ev && !Array.isArray(ev) ? ev : null;
|
|
9260
|
+
});
|
|
9261
|
+
}
|
|
9262
|
+
async function fetchCodexResponsesCompletion(args) {
|
|
9263
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
9264
|
+
const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
|
|
9265
|
+
if (!accountId) {
|
|
9266
|
+
return {
|
|
9267
|
+
status: 401,
|
|
9268
|
+
body: {
|
|
9269
|
+
error: {
|
|
9270
|
+
message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
|
|
9271
|
+
}
|
|
9272
|
+
}
|
|
9273
|
+
};
|
|
9274
|
+
}
|
|
9275
|
+
const identity = createCodexRequestIdentity();
|
|
9276
|
+
const body = buildCodexRequestBody(args, identity);
|
|
9277
|
+
const headers = buildCodexCompatibilityHeaders(identity, accountId);
|
|
9278
|
+
headers.Authorization = `Bearer ${args.accessToken}`;
|
|
9279
|
+
const response = await fetchImpl(CODEX_RESPONSES_URL, {
|
|
9280
|
+
method: "POST",
|
|
9281
|
+
headers,
|
|
9282
|
+
body: JSON.stringify(body),
|
|
9283
|
+
signal: args.signal
|
|
9284
|
+
});
|
|
9285
|
+
if (!response.ok) {
|
|
9286
|
+
const errorText = await response.text();
|
|
9287
|
+
return {
|
|
9288
|
+
status: response.status,
|
|
9289
|
+
body: { error: { message: errorText || response.statusText } }
|
|
9290
|
+
};
|
|
9291
|
+
}
|
|
9292
|
+
const events = await readSseEvents(response);
|
|
9293
|
+
const { text, toolCalls, usage } = aggregateResponsesStream(events);
|
|
9294
|
+
const message = {
|
|
9295
|
+
role: "assistant",
|
|
9296
|
+
content: text || null
|
|
9297
|
+
};
|
|
9298
|
+
if (toolCalls.length > 0) message.tool_calls = toolCalls;
|
|
9299
|
+
return {
|
|
9300
|
+
status: 200,
|
|
9301
|
+
body: {
|
|
9302
|
+
choices: [
|
|
9303
|
+
{
|
|
9304
|
+
index: 0,
|
|
9305
|
+
message,
|
|
9306
|
+
finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
|
|
9307
|
+
}
|
|
9308
|
+
],
|
|
9309
|
+
...usage ? { usage } : {}
|
|
9310
|
+
}
|
|
9311
|
+
};
|
|
9312
|
+
}
|
|
9313
|
+
function isCodexOAuthAgent(agentConfig) {
|
|
9314
|
+
if (!agentConfig) return false;
|
|
9315
|
+
const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
|
|
9316
|
+
return apiKeyRef === "chatgpt";
|
|
9317
|
+
}
|
|
9318
|
+
|
|
9024
9319
|
// packages/agent-runtime/oauthProviders.ts
|
|
9025
9320
|
var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
|
|
9026
9321
|
var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
|
|
@@ -10218,6 +10513,74 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10218
10513
|
}
|
|
10219
10514
|
};
|
|
10220
10515
|
}
|
|
10516
|
+
if (isCodexOAuthAgent(agentConfig)) {
|
|
10517
|
+
const accessToken = await apiKeyRefResolver("chatgpt");
|
|
10518
|
+
if (!accessToken) {
|
|
10519
|
+
throw new Error(
|
|
10520
|
+
'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
|
|
10521
|
+
);
|
|
10522
|
+
}
|
|
10523
|
+
const credential = readOAuthCredential("chatgpt");
|
|
10524
|
+
const accountId = credential?.accountId;
|
|
10525
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10526
|
+
agentConfig,
|
|
10527
|
+
deps.env,
|
|
10528
|
+
buildProviderOpenAiTools,
|
|
10529
|
+
additionalToolNames,
|
|
10530
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10531
|
+
);
|
|
10532
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10533
|
+
agentKey: agentConfig.key,
|
|
10534
|
+
transport: "codex-responses",
|
|
10535
|
+
provider: "openai",
|
|
10536
|
+
model: agentConfig.model ?? "gpt-5.6-sol",
|
|
10537
|
+
hasApiKey: true
|
|
10538
|
+
});
|
|
10539
|
+
return {
|
|
10540
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
10541
|
+
complete: async (messages, options) => {
|
|
10542
|
+
const result = await fetchCodexResponsesCompletion({
|
|
10543
|
+
agentConfig,
|
|
10544
|
+
accessToken,
|
|
10545
|
+
...accountId ? { accountId } : {},
|
|
10546
|
+
openAiBody: {
|
|
10547
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
10548
|
+
messages,
|
|
10549
|
+
stream: false,
|
|
10550
|
+
...tools2.length > 0 ? { tools: tools2 } : {}
|
|
10551
|
+
},
|
|
10552
|
+
fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
|
|
10553
|
+
sleep: deps.sleep,
|
|
10554
|
+
loopbackRequest
|
|
10555
|
+
})
|
|
10556
|
+
});
|
|
10557
|
+
if (result.status < 200 || result.status >= 300) {
|
|
10558
|
+
const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
|
|
10559
|
+
throw new Error(
|
|
10560
|
+
`local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
|
|
10561
|
+
);
|
|
10562
|
+
}
|
|
10563
|
+
const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
|
|
10564
|
+
const message = choice?.message ?? {};
|
|
10565
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
10566
|
+
const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
|
|
10567
|
+
if (content && options?.onTextDelta) options.onTextDelta(content);
|
|
10568
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10569
|
+
agentKey: agentConfig.key,
|
|
10570
|
+
transport: "codex-responses",
|
|
10571
|
+
ok: true,
|
|
10572
|
+
contentChars: content.length,
|
|
10573
|
+
toolCallCount: tool_calls?.length ?? 0,
|
|
10574
|
+
requestedToolNames: requestedToolNames2
|
|
10575
|
+
});
|
|
10576
|
+
return {
|
|
10577
|
+
content,
|
|
10578
|
+
...tool_calls ? { tool_calls } : {},
|
|
10579
|
+
trace: messages
|
|
10580
|
+
};
|
|
10581
|
+
}
|
|
10582
|
+
};
|
|
10583
|
+
}
|
|
10221
10584
|
if (isCursorOAuthAgent(agentConfig)) {
|
|
10222
10585
|
const accessToken = await apiKeyRefResolver("cursor");
|
|
10223
10586
|
if (!accessToken) {
|
|
@@ -10287,6 +10650,101 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10287
10650
|
}
|
|
10288
10651
|
};
|
|
10289
10652
|
}
|
|
10653
|
+
if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
|
|
10654
|
+
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10655
|
+
agentConfig,
|
|
10656
|
+
env: deps.env,
|
|
10657
|
+
apiKeyRefResolver,
|
|
10658
|
+
credentialBroker,
|
|
10659
|
+
syncFetcher
|
|
10660
|
+
});
|
|
10661
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10662
|
+
agentConfig,
|
|
10663
|
+
deps.env,
|
|
10664
|
+
buildProviderOpenAiTools,
|
|
10665
|
+
additionalToolNames,
|
|
10666
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10667
|
+
);
|
|
10668
|
+
if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
|
|
10669
|
+
agentConfig.provider ?? "",
|
|
10670
|
+
agentConfig.model ?? "",
|
|
10671
|
+
tools2,
|
|
10672
|
+
() => false
|
|
10673
|
+
// CLI 端不区分 image 模型
|
|
10674
|
+
)) {
|
|
10675
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10676
|
+
agentKey: agentConfig.key,
|
|
10677
|
+
transport: "gemini-native-tool",
|
|
10678
|
+
apiSource: agentConfig.apiSource ?? null,
|
|
10679
|
+
provider: providerConfig2.provider,
|
|
10680
|
+
model: providerConfig2.model,
|
|
10681
|
+
hasApiKey: Boolean(providerConfig2.apiKey)
|
|
10682
|
+
});
|
|
10683
|
+
return {
|
|
10684
|
+
model: providerConfig2.model,
|
|
10685
|
+
complete: async (messages, options) => {
|
|
10686
|
+
const requestBody = buildGeminiGenerateContentRequest({
|
|
10687
|
+
messages,
|
|
10688
|
+
tools: tools2,
|
|
10689
|
+
maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
|
|
10690
|
+
temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
|
|
10691
|
+
attachSkipThoughtSignature: true
|
|
10692
|
+
});
|
|
10693
|
+
const model = providerConfig2.model;
|
|
10694
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
|
|
10695
|
+
logLocalRuntimeDiagnostic("provider.request.start", {
|
|
10696
|
+
agentKey: agentConfig.key,
|
|
10697
|
+
transport: "gemini-native-tool",
|
|
10698
|
+
model,
|
|
10699
|
+
messageCount: messages.length,
|
|
10700
|
+
toolCount: tools2.length,
|
|
10701
|
+
requestedToolNames: requestedToolNames2
|
|
10702
|
+
});
|
|
10703
|
+
const res = await fetchImpl(url, {
|
|
10704
|
+
method: "POST",
|
|
10705
|
+
headers: {
|
|
10706
|
+
"Content-Type": "application/json",
|
|
10707
|
+
"x-goog-api-key": providerConfig2.apiKey ?? ""
|
|
10708
|
+
},
|
|
10709
|
+
body: JSON.stringify(requestBody),
|
|
10710
|
+
signal: AbortSignal.timeout(12e4)
|
|
10711
|
+
});
|
|
10712
|
+
if (!res.ok) {
|
|
10713
|
+
const errText = await res.text();
|
|
10714
|
+
logLocalRuntimeDiagnostic("provider.request.failed", {
|
|
10715
|
+
agentKey: agentConfig.key,
|
|
10716
|
+
transport: "gemini-native-tool",
|
|
10717
|
+
status: res.status,
|
|
10718
|
+
error: errText.slice(0, 200)
|
|
10719
|
+
});
|
|
10720
|
+
throw new Error(
|
|
10721
|
+
`gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
|
|
10722
|
+
);
|
|
10723
|
+
}
|
|
10724
|
+
const chunks = await readSseDataValues(res, parseSseDataLineJson);
|
|
10725
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
10726
|
+
if (text && options?.onTextDelta) {
|
|
10727
|
+
options.onTextDelta(text);
|
|
10728
|
+
}
|
|
10729
|
+
const result = {
|
|
10730
|
+
content: text,
|
|
10731
|
+
model,
|
|
10732
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
10733
|
+
...usage ? { usage } : {},
|
|
10734
|
+
trace: messages
|
|
10735
|
+
};
|
|
10736
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10737
|
+
agentKey: agentConfig.key,
|
|
10738
|
+
transport: "gemini-native-tool",
|
|
10739
|
+
ok: true,
|
|
10740
|
+
contentChars: text.length,
|
|
10741
|
+
toolCallCount: toolCalls.length
|
|
10742
|
+
});
|
|
10743
|
+
return result;
|
|
10744
|
+
}
|
|
10745
|
+
};
|
|
10746
|
+
}
|
|
10747
|
+
}
|
|
10290
10748
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
10291
10749
|
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10292
10750
|
agentConfig,
|