nolo-cli 0.16.0-alpha.9 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{_executeModel-ABTND4KZ.js → _executeModel-AVCA2NAV.js} +18 -19
- package/{agentDeleteCommand-ARMAV46L.js → agentDeleteCommand-QW5PUMDQ.js} +12 -13
- package/{agentEmailCommands-BKPZP4UP.js → agentEmailCommands-4ORVLGVQ.js} +23 -24
- package/{agentListCommands-5J7RRXUO.js → agentListCommands-YWBYRTYC.js} +14 -15
- package/{agentMachineCommands-VXWJXXPF.js → agentMachineCommands-JSQW4FOA.js} +12 -13
- package/{agentRecordCommands-INDJINPN.js → agentRecordCommands-AASIWOBT.js} +22 -23
- package/{agentRunCommand-KBN6HBY4.js → agentRunCommand-TB5BHXUH.js} +22 -23
- package/{agentRuntimeLocal-AH2RYWGP.js → agentRuntimeLocal-QNPNJRVH.js} +10 -11
- package/{agentSlice-R4PELU57.js → agentSlice-RUNXC62Y.js} +1 -1
- package/{authCommand-QU5BXRBH.js → authCommand-YFTR3347.js} +2 -8
- package/{chunk-ZVC2PCZN.js → chunk-33BJUVK4.js} +2 -2
- package/{chunk-BG7AP3Q7.js → chunk-3663CXZN.js} +11 -38
- package/{chunk-IFPY2BIE.js → chunk-3OIRVWXA.js} +10 -1
- package/{chunk-LSFAWXKC.js → chunk-3WGLLTK4.js} +3 -100
- package/{chunk-5Y5KEB7V.js → chunk-4FX6NVDW.js} +134 -1
- package/{chunk-QLWU2KOT.js → chunk-4IJYA27C.js} +1 -1
- package/{chunk-OELQ67TN.js → chunk-4L2OJPCU.js} +1 -1
- package/{chunk-HSLJ7QER.js → chunk-55NSNCFM.js} +1 -1
- package/{chunk-ZVDRAEZL.js → chunk-6EVITP2G.js} +250 -1
- package/{chunk-AFNJWHKL.js → chunk-7UKFVQ5W.js} +27 -84
- package/{chunk-VK2HVKAO.js → chunk-AUURUT6L.js} +193 -64
- package/{chunk-4N7QA72L.js → chunk-AVVZUXXC.js} +13 -34
- package/{chunk-2XA3QGOH.js → chunk-BEBNFWDU.js} +3 -3
- package/{chunk-4EME3YTO.js → chunk-DGEYDWEZ.js} +3 -3
- package/{chunk-XECKIDGJ.js → chunk-DPAB4FQ7.js} +126 -646
- package/{chunk-J3VQSU5W.js → chunk-EHLHSX7R.js} +2 -9
- package/{chunk-PEDT43JF.js → chunk-FRV6A633.js} +2 -2
- package/{chunk-VAT72PDP.js → chunk-FY233ZFU.js} +12 -13
- package/{chunk-LZYEWFPK.js → chunk-GSINCD4P.js} +4 -8
- package/{chunk-ZPPTWRPT.js → chunk-IGXREZW2.js} +1 -1
- package/{chunk-B4KT7RN2.js → chunk-JTMNCCWF.js} +2 -2
- package/{chunk-ASZ2C44S.js → chunk-LPEUV5RE.js} +2 -2
- package/{chunk-WVDAUR2S.js → chunk-M43KDE25.js} +1 -1
- package/{chunk-GWESD7AS.js → chunk-MR6ISAGB.js} +2 -2
- package/{chunk-LSHKV3S7.js → chunk-NSCHQQPU.js} +9 -9
- package/{chunk-F6JSVFHX.js → chunk-NVEWUJVX.js} +1 -1
- package/{chunk-R6ALN5F5.js → chunk-P3RIAYGG.js} +1 -1
- package/{chunk-FMYTM25W.js → chunk-PCTUYVUM.js} +1 -1
- package/{chunk-BHVBFI6B.js → chunk-S2LXHNHG.js} +3 -3
- package/{chunk-SGRDLYRZ.js → chunk-Z5JQNBNY.js} +1 -1
- package/{chunk-7HECYFOI.js → chunk-ZQBL7LIC.js} +22 -17
- package/{createAgentAutomationAction-3KKRAYGE.js → createAgentAutomationAction-FNHPSKKO.js} +4 -4
- package/{createDialogAction-S7NMQ4TZ.js → createDialogAction-TZCVQ3NU.js} +5 -5
- package/{createPageAction-2EFBT4LQ.js → createPageAction-EIGZ3BKT.js} +4 -4
- package/{dialogCommands-J7XFIQRD.js → dialogCommands-FO77J5DQ.js} +13 -14
- package/{dialogSlice-LNRRBUIC.js → dialogSlice-MM5U4KE2.js} +4 -4
- package/{docCreateCommands-MKO5WB34.js → docCreateCommands-I3BS3AZI.js} +15 -18
- package/{docDeleteCommands-RCBHRKUE.js → docDeleteCommands-Q2OPV52P.js} +14 -17
- package/{docReadCommands-66527P4G.js → docReadCommands-YOOFACYZ.js} +13 -16
- package/{docStore-67MYPX7P.js → docStore-NGYQ2JTR.js} +5 -5
- package/{docUpdateCommands-UT5HSLOJ.js → docUpdateCommands-2B32ITHN.js} +14 -17
- package/{handleSendMessageAction-VZ7226PB.js → handleSendMessageAction-JRZWWBKP.js} +4 -4
- package/index.js +43 -74
- package/{machineCommands-ATA7OSBJ.js → machineCommands-WRWF2ICZ.js} +21 -22
- package/{machineWsRunDispatch-ZDCZ645H.js → machineWsRunDispatch-ZX7Q3TWZ.js} +21 -22
- package/{models-5K5G2CZI.js → models-WQ5N4OJM.js} +1 -1
- package/package.json +1 -1
- package/{readlineWorkspace-UUNABTLB.js → readlineWorkspace-ZTGRGW46.js} +74 -75
- package/{runAgentClientLoop-2A577WBM.js → runAgentClientLoop-JZCOP7LG.js} +14 -15
- package/{spaceCommands-UNZVR2OS.js → spaceCommands-VV4GTPQK.js} +12 -13
- package/{spaceSlice-MC7FYPMZ.js → spaceSlice-DRWWZJP7.js} +4 -4
- package/{streamAgentChatTurn-IEKPNM33.js → streamAgentChatTurn-Y6WGATQR.js} +23 -21
- package/{tools-E6FHKTCF.js → tools-PUNBY3AH.js} +9 -9
- package/{tuiSummaryLlmCaller-QHPDD4WP.js → tuiSummaryLlmCaller-F64WLSAF.js} +3 -4
- package/{updateDialogTitleAction-SQJEEW2K.js → updateDialogTitleAction-YSR4TCMB.js} +4 -4
- package/appDeleteCommands-FRWMPQNS.js +0 -125
- package/appDeployCommands-IRF3T35Z.js +0 -164
- package/appDeployStatusCommands-ADFERYPU.js +0 -145
- package/appGetCommands-FTEOXWMS.js +0 -120
- package/appListCommands-WBY7UWYD.js +0 -123
- package/chunk-G63IH3ZK.js +0 -107
- package/chunk-GFUIQ4RY.js +0 -136
- package/chunk-KFEVY3ST.js +0 -255
- /package/{chunk-RK5NYQEL.js → chunk-XBS2WYJ2.js} +0 -0
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
refreshAntigravityOAuthToken,
|
|
4
4
|
refreshOpenAiCodexToken,
|
|
5
5
|
refreshXaiOAuthToken
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EHLHSX7R.js";
|
|
7
7
|
import {
|
|
8
8
|
buildLocalAgentLookupKeys,
|
|
9
9
|
normalizeAgentHandle,
|
|
10
10
|
shouldReadAgentKeyRemotely
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-M43KDE25.js";
|
|
12
12
|
import {
|
|
13
13
|
LOCAL_CODEX_AGENT_ID,
|
|
14
14
|
LOCAL_CODEX_AGENT_KEY,
|
|
@@ -21,13 +21,13 @@ import {
|
|
|
21
21
|
import {
|
|
22
22
|
inlineImageUrlsForCustomProvider,
|
|
23
23
|
prepareTools
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FRV6A633.js";
|
|
25
25
|
import {
|
|
26
26
|
getAntigravityUserAgent,
|
|
27
27
|
isAntigravityOAuthAgent,
|
|
28
28
|
readAntigravityProjectId,
|
|
29
29
|
resolveAntigravityCloudCodeBaseUrl
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-55NSNCFM.js";
|
|
31
31
|
import {
|
|
32
32
|
FORCED_TOOLS,
|
|
33
33
|
addDefaultLightWebToolsForConfiguredAgents,
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
rememberMemoryFunctionSchema,
|
|
49
49
|
resolveEffectiveEnabledPacks,
|
|
50
50
|
resolveRunLabel
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-ZQBL7LIC.js";
|
|
52
52
|
import {
|
|
53
53
|
createDrainExhaustedResponse,
|
|
54
54
|
isCoreDrainingBody,
|
|
@@ -60,13 +60,13 @@ import {
|
|
|
60
60
|
} from "./chunk-OWOHNGCN.js";
|
|
61
61
|
import {
|
|
62
62
|
prepareTokenUsageData
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-NSCHQQPU.js";
|
|
64
64
|
import {
|
|
65
65
|
BUILTIN_TITLE_LLM_CONFIG
|
|
66
66
|
} from "./chunk-XOIF2TNF.js";
|
|
67
67
|
import {
|
|
68
68
|
fetchServerSyncedCredential
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-S2LXHNHG.js";
|
|
70
70
|
import {
|
|
71
71
|
buildAgentRuntimeDialogWritePlan,
|
|
72
72
|
buildLocalWorkspaceOpenAiTools,
|
|
@@ -77,10 +77,9 @@ import {
|
|
|
77
77
|
executeLocalToolWithPolicy,
|
|
78
78
|
executeOpenAiCompatibleChatCompletion,
|
|
79
79
|
parseSseDataLineJson,
|
|
80
|
-
parseSseDataLineObject,
|
|
81
80
|
readOpenAiCompatibleSseCompletion,
|
|
82
81
|
resolveOpenAiCompatibleProviderConfig
|
|
83
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-7UKFVQ5W.js";
|
|
84
83
|
import {
|
|
85
84
|
buildPlatformChatCompletionRequest,
|
|
86
85
|
canUsePlatformChatProvider,
|
|
@@ -89,20 +88,17 @@ import {
|
|
|
89
88
|
readSseDataValues,
|
|
90
89
|
resolvePlatformChatProviderConfig,
|
|
91
90
|
shouldUsePlatformChatProvider
|
|
92
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-AVVZUXXC.js";
|
|
93
92
|
import {
|
|
94
93
|
resolveAgentRuntimeConfigFromRecord
|
|
95
94
|
} from "./chunk-OIQPORYI.js";
|
|
96
95
|
import {
|
|
96
|
+
parseToolArgumentsJson,
|
|
97
97
|
summarizeToolArguments
|
|
98
|
-
} from "./chunk-
|
|
99
|
-
import {
|
|
100
|
-
convertMessagesToResponsesInput,
|
|
101
|
-
toResponsesTools
|
|
102
|
-
} from "./chunk-KFEVY3ST.js";
|
|
98
|
+
} from "./chunk-GSINCD4P.js";
|
|
103
99
|
import {
|
|
104
100
|
resolvePlatformAuthToken
|
|
105
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-6EVITP2G.js";
|
|
106
102
|
import {
|
|
107
103
|
buildLoadSkillExecutor,
|
|
108
104
|
buildNoloWorkspaceCliToolExecutors,
|
|
@@ -110,7 +106,7 @@ import {
|
|
|
110
106
|
canonicalizeToolNames,
|
|
111
107
|
parseNoloWorkspaceToolArguments,
|
|
112
108
|
resolveRuntimeToolSurfaceForAgent
|
|
113
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-JTMNCCWF.js";
|
|
114
110
|
import {
|
|
115
111
|
clipCompactText
|
|
116
112
|
} from "./chunk-5MMAK75Q.js";
|
|
@@ -156,6 +152,9 @@ import {
|
|
|
156
152
|
import {
|
|
157
153
|
DEFAULT_NOLO_SERVER_URL
|
|
158
154
|
} from "./chunk-OLZBQWZU.js";
|
|
155
|
+
import {
|
|
156
|
+
asRecordOrEmpty
|
|
157
|
+
} from "./chunk-KX6YBIHG.js";
|
|
159
158
|
import {
|
|
160
159
|
createTokenKey,
|
|
161
160
|
createUserKey,
|
|
@@ -167,9 +166,6 @@ import {
|
|
|
167
166
|
import {
|
|
168
167
|
asOptionalFiniteNumber
|
|
169
168
|
} from "./chunk-WWC7I6TA.js";
|
|
170
|
-
import {
|
|
171
|
-
asTrimmedLowercaseString
|
|
172
|
-
} from "./chunk-QSJ3HFEF.js";
|
|
173
169
|
import {
|
|
174
170
|
BUILTIN_NOLO_AGENT_KEY,
|
|
175
171
|
PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
|
|
@@ -298,10 +294,6 @@ var STRINGS = {
|
|
|
298
294
|
en: "Agent switch cancelled.",
|
|
299
295
|
zh: "\u5DF2\u53D6\u6D88\u5207\u6362 agent\u3002"
|
|
300
296
|
},
|
|
301
|
-
agentPickerLoading: {
|
|
302
|
-
en: "Loading agents\u2026",
|
|
303
|
-
zh: "\u6B63\u5728\u52A0\u8F7D agent \u5217\u8868\u2026"
|
|
304
|
-
},
|
|
305
297
|
historyPickerTitle: {
|
|
306
298
|
en: "Resume dialog (\u2191\u2193 Enter Esc)",
|
|
307
299
|
zh: "\u6062\u590D\u5BF9\u8BDD\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
|
|
@@ -621,6 +613,10 @@ var STRINGS = {
|
|
|
621
613
|
en: "tools",
|
|
622
614
|
zh: "\u5DE5\u5177"
|
|
623
615
|
},
|
|
616
|
+
contextFieldThinking: {
|
|
617
|
+
en: "thinking",
|
|
618
|
+
zh: "\u601D\u8003"
|
|
619
|
+
},
|
|
624
620
|
contextFieldServer: {
|
|
625
621
|
en: "server",
|
|
626
622
|
zh: "\u670D\u52A1\u7AEF"
|
|
@@ -658,6 +654,7 @@ var STRINGS = {
|
|
|
658
654
|
" /context Show workspace context and next actions",
|
|
659
655
|
" /runtime <mode> Use auto, local, or server runtime",
|
|
660
656
|
" /tools <mode> Control tool trace: hide, compact, verbose",
|
|
657
|
+
" /thinking <mode> Control thinking output: hide, marker, show",
|
|
661
658
|
" /switch Pick an agent interactively (\u2191\u2193, Enter)",
|
|
662
659
|
" /switch list List agents as text",
|
|
663
660
|
" /switch <name> Switch directly by name, alias, or key (alias: /agent)",
|
|
@@ -694,6 +691,7 @@ var STRINGS = {
|
|
|
694
691
|
" /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
|
|
695
692
|
" /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
|
|
696
693
|
" /tools <mode> \u5DE5\u5177\u8F68\u8FF9\u663E\u793A\uFF1Ahide\u3001compact\u3001verbose",
|
|
694
|
+
" /thinking <mode> \u601D\u8003\u8FC7\u7A0B\u663E\u793A\uFF1Ahide\u3001marker\u3001show",
|
|
697
695
|
" /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
|
|
698
696
|
" /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
|
|
699
697
|
" /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
|
|
@@ -738,6 +736,12 @@ var STRINGS = {
|
|
|
738
736
|
},
|
|
739
737
|
toolsUsage: { en: "Usage: /tools <hide|compact|verbose>", zh: "\u7528\u6CD5\uFF1A/tools <hide|compact|verbose>" },
|
|
740
738
|
toolsSet: { en: "Tool display: {0}", zh: "\u5DE5\u5177\u663E\u793A\uFF1A{0}" },
|
|
739
|
+
thinkingCurrent: {
|
|
740
|
+
en: "Thinking display: {0} (hide | marker | show)",
|
|
741
|
+
zh: "\u601D\u8003\u663E\u793A\uFF1A{0}\uFF08hide | marker | show\uFF09"
|
|
742
|
+
},
|
|
743
|
+
thinkingUsage: { en: "Usage: /thinking <hide|marker|show>", zh: "\u7528\u6CD5\uFF1A/thinking <hide|marker|show>" },
|
|
744
|
+
thinkingSet: { en: "Thinking display: {0}", zh: "\u601D\u8003\u663E\u793A\uFF1A{0}" },
|
|
741
745
|
tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
|
|
742
746
|
tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
|
|
743
747
|
tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
|
|
@@ -2056,7 +2060,16 @@ function createCliStartAgentRunExecutor(deps = {}) {
|
|
|
2056
2060
|
|
|
2057
2061
|
--- \u9644\u52A0\u8F93\u5165 ---
|
|
2058
2062
|
${JSON.stringify(args.input)}`;
|
|
2059
|
-
const rawArgs = [
|
|
2063
|
+
const rawArgs = [
|
|
2064
|
+
"--agent",
|
|
2065
|
+
agentKey,
|
|
2066
|
+
"--msg-file",
|
|
2067
|
+
"PLACEHOLDER",
|
|
2068
|
+
"--bg",
|
|
2069
|
+
// 非持久化派发(review 等一次性任务):透传 --ephemeral,run 完成后不留
|
|
2070
|
+
// dialog 记录。与 web 端 runAgentBackground 的 ephemeral: true 对齐。
|
|
2071
|
+
...args.ephemeral === true ? ["--ephemeral"] : []
|
|
2072
|
+
];
|
|
2060
2073
|
const agentName = typeof args.agentName === "string" && args.agentName.trim() ? args.agentName.trim() : typeof args.name === "string" && args.name.trim() ? args.name.trim() : void 0;
|
|
2061
2074
|
const { runId } = await spawnLocalBackgroundRun(
|
|
2062
2075
|
{
|
|
@@ -2435,22 +2448,19 @@ function resolveAntigravityWireModel(logicalModelId) {
|
|
|
2435
2448
|
return { wireModelId: id };
|
|
2436
2449
|
}
|
|
2437
2450
|
|
|
2438
|
-
// packages/agent-runtime/
|
|
2451
|
+
// packages/agent-runtime/antigravityCloudCodeProvider.ts
|
|
2452
|
+
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2439
2453
|
var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2440
|
-
function
|
|
2454
|
+
function isGemini3WireModel(modelId) {
|
|
2441
2455
|
return modelId.includes("gemini-3");
|
|
2442
2456
|
}
|
|
2443
2457
|
function messageText(content) {
|
|
2444
2458
|
if (typeof content === "string") return content;
|
|
2445
2459
|
if (!Array.isArray(content)) return "";
|
|
2446
|
-
return content.filter(
|
|
2447
|
-
(part) => part?.type === "text"
|
|
2448
|
-
).map((part) => part.text).join("\n").trim();
|
|
2460
|
+
return content.filter((part) => part?.type === "text").map((part) => part.text).join("\n").trim();
|
|
2449
2461
|
}
|
|
2450
2462
|
function parseDataUrlToInlineData(url) {
|
|
2451
|
-
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
2452
|
-
url
|
|
2453
|
-
);
|
|
2463
|
+
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(url);
|
|
2454
2464
|
if (!match) return null;
|
|
2455
2465
|
return { mimeType: match[1], data: match[2] };
|
|
2456
2466
|
}
|
|
@@ -2467,7 +2477,7 @@ function extractInlineDataParts(content) {
|
|
|
2467
2477
|
}
|
|
2468
2478
|
return parts;
|
|
2469
2479
|
}
|
|
2470
|
-
function
|
|
2480
|
+
function convertOpenAiMessagesToCca(messages, options) {
|
|
2471
2481
|
const contents = [];
|
|
2472
2482
|
const systemTexts = [];
|
|
2473
2483
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
@@ -2483,11 +2493,9 @@ function convertOpenAiMessagesToGemini(messages, options) {
|
|
|
2483
2493
|
};
|
|
2484
2494
|
const flushPendingFunctionCalls = () => {
|
|
2485
2495
|
if (pendingFunctionCalls.length === 0) return;
|
|
2486
|
-
const dummyResponses = pendingFunctionCalls.map(
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
})
|
|
2490
|
-
);
|
|
2496
|
+
const dummyResponses = pendingFunctionCalls.map(({ name }) => ({
|
|
2497
|
+
functionResponse: { name, response: { output: "{}" } }
|
|
2498
|
+
}));
|
|
2491
2499
|
pendingFunctionCalls = [];
|
|
2492
2500
|
pushOrMergeContent("user", dummyResponses);
|
|
2493
2501
|
};
|
|
@@ -2496,17 +2504,13 @@ function convertOpenAiMessagesToGemini(messages, options) {
|
|
|
2496
2504
|
const role = String(raw.role);
|
|
2497
2505
|
const content = "content" in raw ? raw.content : null;
|
|
2498
2506
|
if (role === "system") {
|
|
2499
|
-
const text = messageText(
|
|
2500
|
-
content
|
|
2501
|
-
);
|
|
2507
|
+
const text = messageText(content);
|
|
2502
2508
|
if (text) systemTexts.push(text);
|
|
2503
2509
|
continue;
|
|
2504
2510
|
}
|
|
2505
2511
|
if (role === "user") {
|
|
2506
2512
|
flushPendingFunctionCalls();
|
|
2507
|
-
const text = messageText(
|
|
2508
|
-
content
|
|
2509
|
-
);
|
|
2513
|
+
const text = messageText(content);
|
|
2510
2514
|
const imageParts = extractInlineDataParts(
|
|
2511
2515
|
content
|
|
2512
2516
|
);
|
|
@@ -2520,9 +2524,7 @@ function convertOpenAiMessagesToGemini(messages, options) {
|
|
|
2520
2524
|
if (role === "assistant") {
|
|
2521
2525
|
flushPendingFunctionCalls();
|
|
2522
2526
|
const parts = [];
|
|
2523
|
-
const text = messageText(
|
|
2524
|
-
content
|
|
2525
|
-
);
|
|
2527
|
+
const text = messageText(content);
|
|
2526
2528
|
if (text) parts.push({ text });
|
|
2527
2529
|
const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
|
|
2528
2530
|
for (const call of toolCalls) {
|
|
@@ -2532,20 +2534,17 @@ function convertOpenAiMessagesToGemini(messages, options) {
|
|
|
2532
2534
|
toolNamesById.set(id, name);
|
|
2533
2535
|
pendingFunctionCalls.push({ name, id });
|
|
2534
2536
|
const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
|
|
2535
|
-
const isFirstFunctionCallPart = !parts.some(
|
|
2536
|
-
|
|
2537
|
-
);
|
|
2538
|
-
const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
|
|
2539
|
-
const part = {
|
|
2537
|
+
const isFirstFunctionCallPart = !parts.some((p) => "functionCall" in p);
|
|
2538
|
+
parts.push({
|
|
2540
2539
|
functionCall: {
|
|
2541
2540
|
name,
|
|
2542
|
-
args:
|
|
2543
|
-
|
|
2541
|
+
args: parseToolArgumentsJson(call.function?.arguments),
|
|
2542
|
+
id
|
|
2544
2543
|
},
|
|
2545
|
-
...
|
|
2546
|
-
};
|
|
2547
|
-
parts.push(part);
|
|
2544
|
+
...realSignature ? { thoughtSignature: realSignature } : options.attachSkipThoughtSignature && isFirstFunctionCallPart ? { thoughtSignature: SKIP_THOUGHT_SIGNATURE } : {}
|
|
2545
|
+
});
|
|
2548
2546
|
}
|
|
2547
|
+
if (parts.length === 0) continue;
|
|
2549
2548
|
pushOrMergeContent("model", parts);
|
|
2550
2549
|
continue;
|
|
2551
2550
|
}
|
|
@@ -2563,39 +2562,14 @@ function convertOpenAiMessagesToGemini(messages, options) {
|
|
|
2563
2562
|
}
|
|
2564
2563
|
const output = messageText(content) || "{}";
|
|
2565
2564
|
pushOrMergeContent("user", [
|
|
2566
|
-
{
|
|
2567
|
-
functionResponse: {
|
|
2568
|
-
name,
|
|
2569
|
-
response: { output },
|
|
2570
|
-
// 保留 OpenAI tool_call_id:antigravity Cloud Code Assist 网关把
|
|
2571
|
-
// Gemini contents 转成 Claude messages 时需要 functionResponse →
|
|
2572
|
-
// tool_result 的 tool_use_id;缺 id 时网关报
|
|
2573
|
-
// "tool_result.tool_use_id: Field required"(HTTP 400)。
|
|
2574
|
-
...toolCallId ? { id: toolCallId } : {}
|
|
2575
|
-
}
|
|
2576
|
-
}
|
|
2565
|
+
{ functionResponse: { name, response: { output } } }
|
|
2577
2566
|
]);
|
|
2578
2567
|
}
|
|
2579
2568
|
}
|
|
2580
2569
|
flushPendingFunctionCalls();
|
|
2581
2570
|
return { contents, systemTexts };
|
|
2582
2571
|
}
|
|
2583
|
-
function
|
|
2584
|
-
if (typeof raw === "string") {
|
|
2585
|
-
try {
|
|
2586
|
-
const parsed = JSON.parse(raw);
|
|
2587
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2588
|
-
return parsed;
|
|
2589
|
-
}
|
|
2590
|
-
} catch {
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
2594
|
-
return raw;
|
|
2595
|
-
}
|
|
2596
|
-
return {};
|
|
2597
|
-
}
|
|
2598
|
-
function convertOpenAiToolsToGemini(tools) {
|
|
2572
|
+
function convertOpenAiTools(tools) {
|
|
2599
2573
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
2600
2574
|
const declarations = [];
|
|
2601
2575
|
for (const tool of tools) {
|
|
@@ -2612,97 +2586,6 @@ function convertOpenAiToolsToGemini(tools) {
|
|
|
2612
2586
|
if (declarations.length === 0) return void 0;
|
|
2613
2587
|
return [{ functionDeclarations: declarations }];
|
|
2614
2588
|
}
|
|
2615
|
-
function accumulateGeminiChunks(chunks) {
|
|
2616
|
-
let text = "";
|
|
2617
|
-
const toolCalls = [];
|
|
2618
|
-
let usage;
|
|
2619
|
-
let pendingThoughtSignature;
|
|
2620
|
-
for (const chunk of chunks) {
|
|
2621
|
-
if (!chunk || typeof chunk !== "object") continue;
|
|
2622
|
-
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2623
|
-
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2624
|
-
const meta = response.usageMetadata;
|
|
2625
|
-
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2626
|
-
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2627
|
-
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2628
|
-
usage = {
|
|
2629
|
-
prompt_tokens: prompt,
|
|
2630
|
-
completion_tokens: candidates2,
|
|
2631
|
-
total_tokens: total
|
|
2632
|
-
};
|
|
2633
|
-
}
|
|
2634
|
-
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2635
|
-
for (const candidate of candidates) {
|
|
2636
|
-
if (!candidate || typeof candidate !== "object") continue;
|
|
2637
|
-
const parts = Array.isArray(
|
|
2638
|
-
candidate.content?.parts
|
|
2639
|
-
) ? candidate.content.parts : [];
|
|
2640
|
-
for (const part of parts) {
|
|
2641
|
-
if (!part || typeof part !== "object") continue;
|
|
2642
|
-
const partSignature = part.thoughtSignature;
|
|
2643
|
-
if ("text" in part && typeof part.text === "string") {
|
|
2644
|
-
const piece = part.text;
|
|
2645
|
-
if (!part.thought) {
|
|
2646
|
-
text += piece;
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
if (part.thought && typeof partSignature === "string" && partSignature) {
|
|
2650
|
-
pendingThoughtSignature = partSignature;
|
|
2651
|
-
}
|
|
2652
|
-
if ("functionCall" in part && part.functionCall) {
|
|
2653
|
-
const call = part.functionCall;
|
|
2654
|
-
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2655
|
-
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2656
|
-
const argsObj = call.args && typeof call.args === "object" ? call.args : {};
|
|
2657
|
-
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2658
|
-
pendingThoughtSignature = void 0;
|
|
2659
|
-
toolCalls.push({
|
|
2660
|
-
id,
|
|
2661
|
-
type: "function",
|
|
2662
|
-
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2663
|
-
...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
|
|
2664
|
-
});
|
|
2665
|
-
}
|
|
2666
|
-
}
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
return { text, toolCalls, usage };
|
|
2670
|
-
}
|
|
2671
|
-
function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
|
|
2672
|
-
return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
|
|
2673
|
-
}
|
|
2674
|
-
function buildGeminiGenerateContentRequest(args) {
|
|
2675
|
-
const { contents, systemTexts } = convertOpenAiMessagesToGemini(
|
|
2676
|
-
args.messages,
|
|
2677
|
-
{ attachSkipThoughtSignature: args.attachSkipThoughtSignature }
|
|
2678
|
-
);
|
|
2679
|
-
const request = { contents };
|
|
2680
|
-
if (systemTexts.length > 0) {
|
|
2681
|
-
request.systemInstruction = {
|
|
2682
|
-
role: "user",
|
|
2683
|
-
parts: systemTexts.map((text) => ({ text }))
|
|
2684
|
-
};
|
|
2685
|
-
}
|
|
2686
|
-
const toolsResult = convertOpenAiToolsToGemini(args.tools);
|
|
2687
|
-
if (toolsResult) {
|
|
2688
|
-
request.tools = toolsResult;
|
|
2689
|
-
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
2690
|
-
}
|
|
2691
|
-
const generationConfig = {};
|
|
2692
|
-
if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
|
|
2693
|
-
generationConfig.maxOutputTokens = args.maxTokens;
|
|
2694
|
-
}
|
|
2695
|
-
if (typeof args.temperature === "number") {
|
|
2696
|
-
generationConfig.temperature = args.temperature;
|
|
2697
|
-
}
|
|
2698
|
-
if (Object.keys(generationConfig).length > 0) {
|
|
2699
|
-
request.generationConfig = generationConfig;
|
|
2700
|
-
}
|
|
2701
|
-
return request;
|
|
2702
|
-
}
|
|
2703
|
-
|
|
2704
|
-
// packages/agent-runtime/antigravityCloudCodeProvider.ts
|
|
2705
|
-
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2706
2589
|
function buildCloudCodeAssistPayload(args) {
|
|
2707
2590
|
const projectId = readAntigravityProjectId(args.metadata);
|
|
2708
2591
|
if (!projectId) {
|
|
@@ -2713,9 +2596,8 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2713
2596
|
const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
|
|
2714
2597
|
const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
|
|
2715
2598
|
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
2716
|
-
const
|
|
2717
|
-
|
|
2718
|
-
attachSkipThoughtSignature: isGemini3Model(model)
|
|
2599
|
+
const { contents, systemTexts } = convertOpenAiMessagesToCca(rawMessages, {
|
|
2600
|
+
attachSkipThoughtSignature: isGemini3WireModel(model)
|
|
2719
2601
|
});
|
|
2720
2602
|
if (contents.length === 0) {
|
|
2721
2603
|
throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
|
|
@@ -2729,7 +2611,7 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2729
2611
|
parts: systemTexts.map((text) => ({ text }))
|
|
2730
2612
|
};
|
|
2731
2613
|
}
|
|
2732
|
-
const tools =
|
|
2614
|
+
const tools = convertOpenAiTools(
|
|
2733
2615
|
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
2734
2616
|
);
|
|
2735
2617
|
if (tools) {
|
|
@@ -2752,6 +2634,7 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2752
2634
|
const trajectoryId = randomUUID();
|
|
2753
2635
|
const step = 2;
|
|
2754
2636
|
const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
|
|
2637
|
+
const isClaude = model.toLowerCase().includes("claude");
|
|
2755
2638
|
const labels = {
|
|
2756
2639
|
trajectory_id: trajectoryId,
|
|
2757
2640
|
last_step_index: String(step - 1),
|
|
@@ -2775,6 +2658,63 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2775
2658
|
}
|
|
2776
2659
|
};
|
|
2777
2660
|
}
|
|
2661
|
+
function accumulateCcaChunks(chunks) {
|
|
2662
|
+
let text = "";
|
|
2663
|
+
const toolCalls = [];
|
|
2664
|
+
let usage;
|
|
2665
|
+
let pendingThoughtSignature;
|
|
2666
|
+
for (const chunk of chunks) {
|
|
2667
|
+
if (!chunk || typeof chunk !== "object") continue;
|
|
2668
|
+
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2669
|
+
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2670
|
+
const meta = response.usageMetadata;
|
|
2671
|
+
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2672
|
+
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2673
|
+
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2674
|
+
usage = {
|
|
2675
|
+
prompt_tokens: prompt,
|
|
2676
|
+
completion_tokens: candidates2,
|
|
2677
|
+
total_tokens: total
|
|
2678
|
+
};
|
|
2679
|
+
}
|
|
2680
|
+
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2681
|
+
for (const candidate of candidates) {
|
|
2682
|
+
if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
|
|
2683
|
+
const content = candidate.content;
|
|
2684
|
+
if (!content || typeof content !== "object" || !("parts" in content)) continue;
|
|
2685
|
+
const parts = content.parts;
|
|
2686
|
+
if (!Array.isArray(parts)) continue;
|
|
2687
|
+
for (const part of parts) {
|
|
2688
|
+
if (!part || typeof part !== "object") continue;
|
|
2689
|
+
const partSignature = part.thoughtSignature;
|
|
2690
|
+
if ("text" in part && typeof part.text === "string") {
|
|
2691
|
+
const piece = part.text;
|
|
2692
|
+
if (!part.thought) {
|
|
2693
|
+
text += piece;
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
if (part.thought && typeof partSignature === "string" && partSignature) {
|
|
2697
|
+
pendingThoughtSignature = partSignature;
|
|
2698
|
+
}
|
|
2699
|
+
if ("functionCall" in part && part.functionCall) {
|
|
2700
|
+
const call = part.functionCall;
|
|
2701
|
+
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2702
|
+
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2703
|
+
const argsObj = asRecordOrEmpty(call.args);
|
|
2704
|
+
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2705
|
+
pendingThoughtSignature = void 0;
|
|
2706
|
+
toolCalls.push({
|
|
2707
|
+
id,
|
|
2708
|
+
type: "function",
|
|
2709
|
+
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2710
|
+
...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
|
|
2711
|
+
});
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
return { text, toolCalls, usage };
|
|
2717
|
+
}
|
|
2778
2718
|
async function readSseJsonChunks(response) {
|
|
2779
2719
|
return readSseDataValues(response, parseSseDataLineJson);
|
|
2780
2720
|
}
|
|
@@ -2799,7 +2739,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
|
|
|
2799
2739
|
};
|
|
2800
2740
|
}
|
|
2801
2741
|
const chunks = await readSseJsonChunks(response);
|
|
2802
|
-
const { text, toolCalls, usage } =
|
|
2742
|
+
const { text, toolCalls, usage } = accumulateCcaChunks(chunks);
|
|
2803
2743
|
const message = {
|
|
2804
2744
|
role: "assistant",
|
|
2805
2745
|
content: text || null
|
|
@@ -2838,11 +2778,6 @@ var CLAUDE_CODE_IDENTITY_PATTERNS = [
|
|
|
2838
2778
|
function stringValue(value) {
|
|
2839
2779
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2840
2780
|
}
|
|
2841
|
-
function isCacheControl(value) {
|
|
2842
|
-
return Boolean(
|
|
2843
|
-
value && typeof value === "object" && !Array.isArray(value) && typeof value.type === "string"
|
|
2844
|
-
);
|
|
2845
|
-
}
|
|
2846
2781
|
function toAnthropicContent(content) {
|
|
2847
2782
|
if (typeof content === "string") {
|
|
2848
2783
|
return content.length > 0 ? [{ type: "text", text: content }] : [];
|
|
@@ -2853,23 +2788,17 @@ function toAnthropicContent(content) {
|
|
|
2853
2788
|
if (!raw || typeof raw !== "object") continue;
|
|
2854
2789
|
const part = raw;
|
|
2855
2790
|
if ((part.type === "text" || part.type === "input_text") && typeof part.text === "string") {
|
|
2856
|
-
if (part.text.length > 0) {
|
|
2857
|
-
const block2 = { type: "text", text: part.text };
|
|
2858
|
-
if (isCacheControl(part.cache_control)) block2.cache_control = part.cache_control;
|
|
2859
|
-
blocks.push(block2);
|
|
2860
|
-
}
|
|
2791
|
+
if (part.text.length > 0) blocks.push({ type: "text", text: part.text });
|
|
2861
2792
|
continue;
|
|
2862
2793
|
}
|
|
2863
2794
|
if (part.type !== "image_url") continue;
|
|
2864
2795
|
const imageUrl = typeof part.image_url === "string" ? part.image_url : stringValue(part.image_url?.url);
|
|
2865
2796
|
if (!imageUrl) continue;
|
|
2866
2797
|
const dataMatch = imageUrl.match(/^data:([^;,]+);base64,(.+)$/s);
|
|
2867
|
-
|
|
2798
|
+
blocks.push({
|
|
2868
2799
|
type: "image",
|
|
2869
2800
|
source: dataMatch ? { type: "base64", media_type: dataMatch[1], data: dataMatch[2] } : { type: "url", url: imageUrl }
|
|
2870
|
-
};
|
|
2871
|
-
if (isCacheControl(part.cache_control)) block.cache_control = part.cache_control;
|
|
2872
|
-
blocks.push(block);
|
|
2801
|
+
});
|
|
2873
2802
|
}
|
|
2874
2803
|
return blocks;
|
|
2875
2804
|
}
|
|
@@ -2903,15 +2832,7 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2903
2832
|
const message = raw;
|
|
2904
2833
|
const role = String(message.role ?? "");
|
|
2905
2834
|
if (role === "system" || role === "developer") {
|
|
2906
|
-
|
|
2907
|
-
if (typeof message.content === "string" && Number.isFinite(stablePrefixChars) && stablePrefixChars > 0 && stablePrefixChars <= message.content.length) {
|
|
2908
|
-
const stable = message.content.slice(0, stablePrefixChars);
|
|
2909
|
-
const dynamic = message.content.slice(stablePrefixChars);
|
|
2910
|
-
system.push({ type: "text", text: stable, cache_control: { type: "ephemeral" } });
|
|
2911
|
-
if (dynamic) system.push({ type: "text", text: dynamic });
|
|
2912
|
-
} else {
|
|
2913
|
-
system.push(...toAnthropicContent(message.content));
|
|
2914
|
-
}
|
|
2835
|
+
system.push(...toAnthropicContent(message.content));
|
|
2915
2836
|
continue;
|
|
2916
2837
|
}
|
|
2917
2838
|
if (role === "tool") {
|
|
@@ -2953,9 +2874,6 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2953
2874
|
if (!hasClaudeCodeIdentity(system)) {
|
|
2954
2875
|
system.unshift({ type: "text", text: CLAUDE_CODE_SYSTEM_INSTRUCTION });
|
|
2955
2876
|
}
|
|
2956
|
-
if (system.length > 0 && !system.some((block) => isCacheControl(block.cache_control))) {
|
|
2957
|
-
system[system.length - 1].cache_control = { type: "ephemeral" };
|
|
2958
|
-
}
|
|
2959
2877
|
const tools = Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools.flatMap((raw) => {
|
|
2960
2878
|
if (!raw || typeof raw !== "object") return [];
|
|
2961
2879
|
const fn = raw.function;
|
|
@@ -2970,16 +2888,6 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2970
2888
|
const model = stringValue(args.openAiBody.model) ?? args.agentConfig.model ?? "claude-sonnet-5";
|
|
2971
2889
|
const maxTokensRaw = args.openAiBody.max_completion_tokens ?? args.openAiBody.max_tokens ?? args.agentConfig.max_tokens;
|
|
2972
2890
|
const maxTokens = typeof maxTokensRaw === "number" && Number.isFinite(maxTokensRaw) ? Math.max(1, Math.floor(maxTokensRaw)) : 8192;
|
|
2973
|
-
if (messages.length > 0) {
|
|
2974
|
-
const lastMessage = messages[messages.length - 1];
|
|
2975
|
-
const content = Array.isArray(lastMessage.content) ? lastMessage.content : [];
|
|
2976
|
-
if (content.length > 0) {
|
|
2977
|
-
const lastBlock = content[content.length - 1];
|
|
2978
|
-
if (!isCacheControl(lastBlock.cache_control)) {
|
|
2979
|
-
lastBlock.cache_control = { type: "ephemeral" };
|
|
2980
|
-
}
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2983
2891
|
return {
|
|
2984
2892
|
model,
|
|
2985
2893
|
messages,
|
|
@@ -3011,8 +2919,6 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
3011
2919
|
}
|
|
3012
2920
|
const usage = payload.usage ?? {};
|
|
3013
2921
|
const inputTokens = (typeof usage.input_tokens === "number" ? usage.input_tokens : 0) + (typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0) + (typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0);
|
|
3014
|
-
const cacheCreationInputTokens = typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0;
|
|
3015
|
-
const cacheReadInputTokens = typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0;
|
|
3016
2922
|
const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : 0;
|
|
3017
2923
|
const stopReason = String(payload.stop_reason ?? "");
|
|
3018
2924
|
const message = { role: "assistant", content: text || null };
|
|
@@ -3028,16 +2934,9 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
3028
2934
|
finish_reason: toolCalls.length > 0 || stopReason === "tool_use" ? "tool_calls" : stopReason === "max_tokens" ? "length" : "stop"
|
|
3029
2935
|
}],
|
|
3030
2936
|
usage: {
|
|
3031
|
-
// prompt_tokens/input_tokens are total input, including cache read/write.
|
|
3032
|
-
// Preserve Anthropic's components so normalization and billing can apply
|
|
3033
|
-
// the correct cache prices without double-counting them.
|
|
3034
2937
|
prompt_tokens: inputTokens,
|
|
3035
|
-
input_tokens: inputTokens,
|
|
3036
2938
|
completion_tokens: outputTokens,
|
|
3037
|
-
|
|
3038
|
-
total_tokens: inputTokens + outputTokens,
|
|
3039
|
-
cache_creation_input_tokens: cacheCreationInputTokens,
|
|
3040
|
-
cache_read_input_tokens: cacheReadInputTokens
|
|
2939
|
+
total_tokens: inputTokens + outputTokens
|
|
3041
2940
|
}
|
|
3042
2941
|
};
|
|
3043
2942
|
}
|
|
@@ -9112,262 +9011,6 @@ function isCursorOAuthAgent(agent) {
|
|
|
9112
9011
|
return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
|
|
9113
9012
|
}
|
|
9114
9013
|
|
|
9115
|
-
// packages/agent-runtime/codexResponsesProvider.ts
|
|
9116
|
-
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
9117
|
-
var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
|
|
9118
|
-
var CODEX_CLIENT_VERSION = "0.144.1";
|
|
9119
|
-
var CODEX_ORIGINATOR = "codex_cli_rs";
|
|
9120
|
-
var CODEX_OPENAI_BETA = "responses=experimental";
|
|
9121
|
-
var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
|
|
9122
|
-
var CODEX_INSTALLATION_ID = randomUUID4();
|
|
9123
|
-
function decodeCodexAccountId(accessToken) {
|
|
9124
|
-
const parts = accessToken.split(".");
|
|
9125
|
-
if (parts.length < 2) return void 0;
|
|
9126
|
-
try {
|
|
9127
|
-
const payload = JSON.parse(
|
|
9128
|
-
Buffer.from(parts[1], "base64").toString("utf8")
|
|
9129
|
-
);
|
|
9130
|
-
const claim = payload[OPENAI_AUTH_CLAIM];
|
|
9131
|
-
const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
|
|
9132
|
-
return typeof value === "string" && value ? value : void 0;
|
|
9133
|
-
} catch {
|
|
9134
|
-
return void 0;
|
|
9135
|
-
}
|
|
9136
|
-
}
|
|
9137
|
-
function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
|
|
9138
|
-
const sessionId = randomUUID4();
|
|
9139
|
-
const threadId = randomUUID4();
|
|
9140
|
-
const windowId = randomUUID4();
|
|
9141
|
-
const turnId = randomUUID4();
|
|
9142
|
-
const turnMetadata = {
|
|
9143
|
-
installation_id: installationId,
|
|
9144
|
-
session_id: sessionId,
|
|
9145
|
-
thread_id: threadId,
|
|
9146
|
-
turn_id: turnId,
|
|
9147
|
-
window_id: windowId,
|
|
9148
|
-
request_kind: "turn",
|
|
9149
|
-
turn_started_at_unix_ms: Date.now()
|
|
9150
|
-
};
|
|
9151
|
-
const turnMetadataJson = JSON.stringify(turnMetadata);
|
|
9152
|
-
return {
|
|
9153
|
-
sessionId,
|
|
9154
|
-
threadId,
|
|
9155
|
-
windowId,
|
|
9156
|
-
turnId,
|
|
9157
|
-
turnMetadataJson,
|
|
9158
|
-
clientMetadata: {
|
|
9159
|
-
"x-codex-installation-id": installationId,
|
|
9160
|
-
session_id: sessionId,
|
|
9161
|
-
thread_id: threadId,
|
|
9162
|
-
"x-codex-window-id": windowId,
|
|
9163
|
-
turn_id: turnId,
|
|
9164
|
-
"x-codex-turn-metadata": turnMetadataJson
|
|
9165
|
-
}
|
|
9166
|
-
};
|
|
9167
|
-
}
|
|
9168
|
-
function buildCodexCompatibilityHeaders(identity, accountId) {
|
|
9169
|
-
return {
|
|
9170
|
-
Authorization: "",
|
|
9171
|
-
// filled by caller with bearer token
|
|
9172
|
-
"Content-Type": "application/json",
|
|
9173
|
-
Accept: "text/event-stream",
|
|
9174
|
-
"chatgpt-account-id": accountId,
|
|
9175
|
-
"OpenAI-Beta": CODEX_OPENAI_BETA,
|
|
9176
|
-
originator: CODEX_ORIGINATOR,
|
|
9177
|
-
version: CODEX_CLIENT_VERSION,
|
|
9178
|
-
session_id: identity.sessionId,
|
|
9179
|
-
conversation_id: identity.sessionId,
|
|
9180
|
-
"x-client-request-id": identity.sessionId,
|
|
9181
|
-
"session-id": identity.sessionId,
|
|
9182
|
-
"thread-id": identity.threadId,
|
|
9183
|
-
"x-codex-window-id": identity.windowId,
|
|
9184
|
-
"x-codex-turn-metadata": identity.turnMetadataJson
|
|
9185
|
-
};
|
|
9186
|
-
}
|
|
9187
|
-
function collectInstructions(messages, agentPrompt) {
|
|
9188
|
-
const systemTexts = [];
|
|
9189
|
-
const prompt = agentPrompt?.trim();
|
|
9190
|
-
if (prompt) systemTexts.push(prompt);
|
|
9191
|
-
for (const raw of messages) {
|
|
9192
|
-
if (!raw || typeof raw !== "object") continue;
|
|
9193
|
-
const role = String(raw.role ?? "");
|
|
9194
|
-
if (role !== "system" && role !== "developer") continue;
|
|
9195
|
-
const content = raw.content;
|
|
9196
|
-
const stringContent = asOptionalTrimmedString(content);
|
|
9197
|
-
if (stringContent) {
|
|
9198
|
-
systemTexts.push(stringContent);
|
|
9199
|
-
} else if (Array.isArray(content)) {
|
|
9200
|
-
const text = content.filter(
|
|
9201
|
-
(p) => !!p && p.type === "text"
|
|
9202
|
-
).map((p) => p.text).join("\n").trim();
|
|
9203
|
-
if (text) systemTexts.push(text);
|
|
9204
|
-
}
|
|
9205
|
-
}
|
|
9206
|
-
return systemTexts.join("\n\n");
|
|
9207
|
-
}
|
|
9208
|
-
function collectStableInstructions(messages, fallbackPrompt) {
|
|
9209
|
-
const systemTexts = [];
|
|
9210
|
-
if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
|
|
9211
|
-
for (const raw of messages) {
|
|
9212
|
-
if (!raw || typeof raw !== "object") continue;
|
|
9213
|
-
const message = raw;
|
|
9214
|
-
const role = String(message.role ?? "");
|
|
9215
|
-
if (role !== "system" && role !== "developer") continue;
|
|
9216
|
-
if (typeof message.content === "string") {
|
|
9217
|
-
const boundary = Number(message.stable_prefix_chars);
|
|
9218
|
-
const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
|
|
9219
|
-
if (text.trim()) systemTexts.push(text.trim());
|
|
9220
|
-
}
|
|
9221
|
-
}
|
|
9222
|
-
return systemTexts.join("\n\n");
|
|
9223
|
-
}
|
|
9224
|
-
function stablePromptCacheKey(parts) {
|
|
9225
|
-
const value = JSON.stringify(parts);
|
|
9226
|
-
let hash = 2166136261;
|
|
9227
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
9228
|
-
hash ^= value.charCodeAt(index);
|
|
9229
|
-
hash = Math.imul(hash, 16777619) >>> 0;
|
|
9230
|
-
}
|
|
9231
|
-
return `nolo-codex-${hash.toString(16).padStart(8, "0")}`;
|
|
9232
|
-
}
|
|
9233
|
-
function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
|
|
9234
|
-
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
9235
|
-
const nonSystem = rawMessages.filter((m) => {
|
|
9236
|
-
const role = m && typeof m === "object" ? String(m.role) : "";
|
|
9237
|
-
return role !== "system" && role !== "developer";
|
|
9238
|
-
});
|
|
9239
|
-
const input = convertMessagesToResponsesInput(nonSystem);
|
|
9240
|
-
const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
|
|
9241
|
-
const stableInstructions = collectStableInstructions(rawMessages, args.agentConfig.prompt);
|
|
9242
|
-
const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
|
|
9243
|
-
const tools = toResponsesTools(
|
|
9244
|
-
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
9245
|
-
);
|
|
9246
|
-
const body = {
|
|
9247
|
-
model,
|
|
9248
|
-
input,
|
|
9249
|
-
stream: true,
|
|
9250
|
-
store: false,
|
|
9251
|
-
// Keep routing stable across turns and request UUIDs. Growing input/history
|
|
9252
|
-
// is intentionally excluded; only stable request-prefix material belongs.
|
|
9253
|
-
prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []]),
|
|
9254
|
-
client_metadata: identity.clientMetadata
|
|
9255
|
-
};
|
|
9256
|
-
if (instructions) body.instructions = instructions;
|
|
9257
|
-
if (tools && tools.length > 0) {
|
|
9258
|
-
body.tools = tools;
|
|
9259
|
-
body.tool_choice = "auto";
|
|
9260
|
-
body.parallel_tool_calls = true;
|
|
9261
|
-
}
|
|
9262
|
-
return body;
|
|
9263
|
-
}
|
|
9264
|
-
function aggregateResponsesStream(events) {
|
|
9265
|
-
let text = "";
|
|
9266
|
-
const toolCalls = [];
|
|
9267
|
-
let usage;
|
|
9268
|
-
for (const ev of events) {
|
|
9269
|
-
const type = String(ev.type ?? "");
|
|
9270
|
-
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
9271
|
-
text += ev.delta;
|
|
9272
|
-
continue;
|
|
9273
|
-
}
|
|
9274
|
-
if (type === "response.output_item.done") {
|
|
9275
|
-
const item = ev.item;
|
|
9276
|
-
if (item && item.type === "function_call") {
|
|
9277
|
-
const name = typeof item.name === "string" ? item.name : "";
|
|
9278
|
-
if (name) {
|
|
9279
|
-
toolCalls.push({
|
|
9280
|
-
id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
|
|
9281
|
-
type: "function",
|
|
9282
|
-
function: {
|
|
9283
|
-
name,
|
|
9284
|
-
arguments: typeof item.arguments === "string" ? item.arguments : "{}"
|
|
9285
|
-
}
|
|
9286
|
-
});
|
|
9287
|
-
}
|
|
9288
|
-
}
|
|
9289
|
-
continue;
|
|
9290
|
-
}
|
|
9291
|
-
if (type === "response.completed") {
|
|
9292
|
-
const response = ev.response;
|
|
9293
|
-
const u = response?.usage;
|
|
9294
|
-
if (u) {
|
|
9295
|
-
const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
|
|
9296
|
-
const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
|
|
9297
|
-
const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
|
|
9298
|
-
usage = {
|
|
9299
|
-
prompt_tokens: prompt,
|
|
9300
|
-
completion_tokens: completion,
|
|
9301
|
-
total_tokens: total
|
|
9302
|
-
};
|
|
9303
|
-
}
|
|
9304
|
-
}
|
|
9305
|
-
}
|
|
9306
|
-
return { text, toolCalls, usage };
|
|
9307
|
-
}
|
|
9308
|
-
async function readSseEvents(response) {
|
|
9309
|
-
return readSseDataValues(response, (line) => {
|
|
9310
|
-
const ev = parseSseDataLineObject(line);
|
|
9311
|
-
return ev && !Array.isArray(ev) ? ev : null;
|
|
9312
|
-
});
|
|
9313
|
-
}
|
|
9314
|
-
async function fetchCodexResponsesCompletion(args) {
|
|
9315
|
-
const fetchImpl = args.fetchImpl ?? fetch;
|
|
9316
|
-
const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
|
|
9317
|
-
if (!accountId) {
|
|
9318
|
-
return {
|
|
9319
|
-
status: 401,
|
|
9320
|
-
body: {
|
|
9321
|
-
error: {
|
|
9322
|
-
message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
|
|
9323
|
-
}
|
|
9324
|
-
}
|
|
9325
|
-
};
|
|
9326
|
-
}
|
|
9327
|
-
const identity = createCodexRequestIdentity();
|
|
9328
|
-
const body = buildCodexRequestBody(args, identity);
|
|
9329
|
-
const headers = buildCodexCompatibilityHeaders(identity, accountId);
|
|
9330
|
-
headers.Authorization = `Bearer ${args.accessToken}`;
|
|
9331
|
-
const response = await fetchImpl(CODEX_RESPONSES_URL, {
|
|
9332
|
-
method: "POST",
|
|
9333
|
-
headers,
|
|
9334
|
-
body: JSON.stringify(body),
|
|
9335
|
-
signal: args.signal
|
|
9336
|
-
});
|
|
9337
|
-
if (!response.ok) {
|
|
9338
|
-
const errorText = await response.text();
|
|
9339
|
-
return {
|
|
9340
|
-
status: response.status,
|
|
9341
|
-
body: { error: { message: errorText || response.statusText } }
|
|
9342
|
-
};
|
|
9343
|
-
}
|
|
9344
|
-
const events = await readSseEvents(response);
|
|
9345
|
-
const { text, toolCalls, usage } = aggregateResponsesStream(events);
|
|
9346
|
-
const message = {
|
|
9347
|
-
role: "assistant",
|
|
9348
|
-
content: text || null
|
|
9349
|
-
};
|
|
9350
|
-
if (toolCalls.length > 0) message.tool_calls = toolCalls;
|
|
9351
|
-
return {
|
|
9352
|
-
status: 200,
|
|
9353
|
-
body: {
|
|
9354
|
-
choices: [
|
|
9355
|
-
{
|
|
9356
|
-
index: 0,
|
|
9357
|
-
message,
|
|
9358
|
-
finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
|
|
9359
|
-
}
|
|
9360
|
-
],
|
|
9361
|
-
...usage ? { usage } : {}
|
|
9362
|
-
}
|
|
9363
|
-
};
|
|
9364
|
-
}
|
|
9365
|
-
function isCodexOAuthAgent(agentConfig) {
|
|
9366
|
-
if (!agentConfig) return false;
|
|
9367
|
-
const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
|
|
9368
|
-
return apiKeyRef === "chatgpt";
|
|
9369
|
-
}
|
|
9370
|
-
|
|
9371
9014
|
// packages/agent-runtime/oauthProviders.ts
|
|
9372
9015
|
var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
|
|
9373
9016
|
var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
|
|
@@ -10565,74 +10208,6 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10565
10208
|
}
|
|
10566
10209
|
};
|
|
10567
10210
|
}
|
|
10568
|
-
if (isCodexOAuthAgent(agentConfig)) {
|
|
10569
|
-
const accessToken = await apiKeyRefResolver("chatgpt");
|
|
10570
|
-
if (!accessToken) {
|
|
10571
|
-
throw new Error(
|
|
10572
|
-
'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
|
|
10573
|
-
);
|
|
10574
|
-
}
|
|
10575
|
-
const credential = readOAuthCredential("chatgpt");
|
|
10576
|
-
const accountId = credential?.accountId;
|
|
10577
|
-
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10578
|
-
agentConfig,
|
|
10579
|
-
deps.env,
|
|
10580
|
-
buildProviderOpenAiTools,
|
|
10581
|
-
additionalToolNames,
|
|
10582
|
-
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10583
|
-
);
|
|
10584
|
-
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10585
|
-
agentKey: agentConfig.key,
|
|
10586
|
-
transport: "codex-responses",
|
|
10587
|
-
provider: "openai",
|
|
10588
|
-
model: agentConfig.model ?? "gpt-5.6-sol",
|
|
10589
|
-
hasApiKey: true
|
|
10590
|
-
});
|
|
10591
|
-
return {
|
|
10592
|
-
model: agentConfig.model || "gpt-5.6-sol",
|
|
10593
|
-
complete: async (messages, options) => {
|
|
10594
|
-
const result = await fetchCodexResponsesCompletion({
|
|
10595
|
-
agentConfig,
|
|
10596
|
-
accessToken,
|
|
10597
|
-
...accountId ? { accountId } : {},
|
|
10598
|
-
openAiBody: {
|
|
10599
|
-
model: agentConfig.model || "gpt-5.6-sol",
|
|
10600
|
-
messages,
|
|
10601
|
-
stream: false,
|
|
10602
|
-
...tools2.length > 0 ? { tools: tools2 } : {}
|
|
10603
|
-
},
|
|
10604
|
-
fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
|
|
10605
|
-
sleep: deps.sleep,
|
|
10606
|
-
loopbackRequest
|
|
10607
|
-
})
|
|
10608
|
-
});
|
|
10609
|
-
if (result.status < 200 || result.status >= 300) {
|
|
10610
|
-
const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
|
|
10611
|
-
throw new Error(
|
|
10612
|
-
`local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
|
|
10613
|
-
);
|
|
10614
|
-
}
|
|
10615
|
-
const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
|
|
10616
|
-
const message = choice?.message ?? {};
|
|
10617
|
-
const content = typeof message.content === "string" ? message.content : "";
|
|
10618
|
-
const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
|
|
10619
|
-
if (content && options?.onTextDelta) options.onTextDelta(content);
|
|
10620
|
-
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10621
|
-
agentKey: agentConfig.key,
|
|
10622
|
-
transport: "codex-responses",
|
|
10623
|
-
ok: true,
|
|
10624
|
-
contentChars: content.length,
|
|
10625
|
-
toolCallCount: tool_calls?.length ?? 0,
|
|
10626
|
-
requestedToolNames: requestedToolNames2
|
|
10627
|
-
});
|
|
10628
|
-
return {
|
|
10629
|
-
content,
|
|
10630
|
-
...tool_calls ? { tool_calls } : {},
|
|
10631
|
-
trace: messages
|
|
10632
|
-
};
|
|
10633
|
-
}
|
|
10634
|
-
};
|
|
10635
|
-
}
|
|
10636
10211
|
if (isCursorOAuthAgent(agentConfig)) {
|
|
10637
10212
|
const accessToken = await apiKeyRefResolver("cursor");
|
|
10638
10213
|
if (!accessToken) {
|
|
@@ -10702,101 +10277,6 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10702
10277
|
}
|
|
10703
10278
|
};
|
|
10704
10279
|
}
|
|
10705
|
-
if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
|
|
10706
|
-
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10707
|
-
agentConfig,
|
|
10708
|
-
env: deps.env,
|
|
10709
|
-
apiKeyRefResolver,
|
|
10710
|
-
credentialBroker,
|
|
10711
|
-
syncFetcher
|
|
10712
|
-
});
|
|
10713
|
-
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10714
|
-
agentConfig,
|
|
10715
|
-
deps.env,
|
|
10716
|
-
buildProviderOpenAiTools,
|
|
10717
|
-
additionalToolNames,
|
|
10718
|
-
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10719
|
-
);
|
|
10720
|
-
if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
|
|
10721
|
-
agentConfig.provider ?? "",
|
|
10722
|
-
agentConfig.model ?? "",
|
|
10723
|
-
tools2,
|
|
10724
|
-
() => false
|
|
10725
|
-
// CLI 端不区分 image 模型
|
|
10726
|
-
)) {
|
|
10727
|
-
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10728
|
-
agentKey: agentConfig.key,
|
|
10729
|
-
transport: "gemini-native-tool",
|
|
10730
|
-
apiSource: agentConfig.apiSource ?? null,
|
|
10731
|
-
provider: providerConfig2.provider,
|
|
10732
|
-
model: providerConfig2.model,
|
|
10733
|
-
hasApiKey: Boolean(providerConfig2.apiKey)
|
|
10734
|
-
});
|
|
10735
|
-
return {
|
|
10736
|
-
model: providerConfig2.model,
|
|
10737
|
-
complete: async (messages, options) => {
|
|
10738
|
-
const requestBody = buildGeminiGenerateContentRequest({
|
|
10739
|
-
messages,
|
|
10740
|
-
tools: tools2,
|
|
10741
|
-
maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
|
|
10742
|
-
temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
|
|
10743
|
-
attachSkipThoughtSignature: true
|
|
10744
|
-
});
|
|
10745
|
-
const model = providerConfig2.model;
|
|
10746
|
-
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
|
|
10747
|
-
logLocalRuntimeDiagnostic("provider.request.start", {
|
|
10748
|
-
agentKey: agentConfig.key,
|
|
10749
|
-
transport: "gemini-native-tool",
|
|
10750
|
-
model,
|
|
10751
|
-
messageCount: messages.length,
|
|
10752
|
-
toolCount: tools2.length,
|
|
10753
|
-
requestedToolNames: requestedToolNames2
|
|
10754
|
-
});
|
|
10755
|
-
const res = await fetchImpl(url, {
|
|
10756
|
-
method: "POST",
|
|
10757
|
-
headers: {
|
|
10758
|
-
"Content-Type": "application/json",
|
|
10759
|
-
"x-goog-api-key": providerConfig2.apiKey ?? ""
|
|
10760
|
-
},
|
|
10761
|
-
body: JSON.stringify(requestBody),
|
|
10762
|
-
signal: AbortSignal.timeout(12e4)
|
|
10763
|
-
});
|
|
10764
|
-
if (!res.ok) {
|
|
10765
|
-
const errText = await res.text();
|
|
10766
|
-
logLocalRuntimeDiagnostic("provider.request.failed", {
|
|
10767
|
-
agentKey: agentConfig.key,
|
|
10768
|
-
transport: "gemini-native-tool",
|
|
10769
|
-
status: res.status,
|
|
10770
|
-
error: errText.slice(0, 200)
|
|
10771
|
-
});
|
|
10772
|
-
throw new Error(
|
|
10773
|
-
`gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
|
|
10774
|
-
);
|
|
10775
|
-
}
|
|
10776
|
-
const chunks = await readSseDataValues(res, parseSseDataLineJson);
|
|
10777
|
-
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
10778
|
-
if (text && options?.onTextDelta) {
|
|
10779
|
-
options.onTextDelta(text);
|
|
10780
|
-
}
|
|
10781
|
-
const result = {
|
|
10782
|
-
content: text,
|
|
10783
|
-
model,
|
|
10784
|
-
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
10785
|
-
...usage ? { usage } : {},
|
|
10786
|
-
trace: messages
|
|
10787
|
-
};
|
|
10788
|
-
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10789
|
-
agentKey: agentConfig.key,
|
|
10790
|
-
transport: "gemini-native-tool",
|
|
10791
|
-
ok: true,
|
|
10792
|
-
contentChars: text.length,
|
|
10793
|
-
toolCallCount: toolCalls.length
|
|
10794
|
-
});
|
|
10795
|
-
return result;
|
|
10796
|
-
}
|
|
10797
|
-
};
|
|
10798
|
-
}
|
|
10799
|
-
}
|
|
10800
10280
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
10801
10281
|
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10802
10282
|
agentConfig,
|