nolo-cli 0.15.0 → 0.16.0-alpha.10
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-QAUS6B7J.js → _executeModel-6BR65FSI.js} +29 -28
- package/{action-GUOZYYGN.js → action-F5JACQBG.js} +4 -4
- package/{addContentAction-QDGHGUBH.js → addContentAction-AQXEYRBE.js} +3 -3
- package/{addDialogAgentAction-Z4YCYZIV.js → addDialogAgentAction-EJHHJZWW.js} +2 -2
- package/{agentDeleteCommand-QDO62EZA.js → agentDeleteCommand-PBIUC4FT.js} +18 -17
- package/{agentEmailCommands-UZ5BKX3P.js → agentEmailCommands-KNZY4HXV.js} +35 -34
- package/{agentListCommands-ZC33UDWT.js → agentListCommands-N64PHBXM.js} +20 -19
- package/{agentMachineCommands-RZGZEZRL.js → agentMachineCommands-2AIPJKFM.js} +18 -17
- package/{agentRecordCommands-DGDXE2VH.js → agentRecordCommands-TB4N7YSB.js} +34 -33
- package/{agentRunCommand-SRZWFOPH.js → agentRunCommand-UVW2ZLKT.js} +34 -33
- package/{agentRuntimeLocal-4YCF6IRF.js → agentRuntimeLocal-T6YECTNF.js} +15 -16
- package/{agentSlice-IVE735EV.js → agentSlice-533PEM4O.js} +3 -3
- package/{appDeleteCommands-7I26L64I.js → appDeleteCommands-D6B6Z4ZQ.js} +19 -18
- package/{appDeployCommands-TZLZNTJN.js → appDeployCommands-YMO5FK4T.js} +19 -18
- package/{appDeployStatusCommands-OPPTLHRW.js → appDeployStatusCommands-EO5DWWPQ.js} +19 -18
- package/{appGetCommands-N2S4HYKY.js → appGetCommands-6SMZ3URQ.js} +19 -18
- package/{appListCommands-OBTPPKUM.js → appListCommands-RZXSWR2G.js} +19 -18
- package/{authCommand-YFTR3347.js → authCommand-MSSBXCQ6.js} +8 -2
- package/{chunk-OQMPU2ML.js → chunk-2OUI4TLC.js} +4 -4
- package/{chunk-SFXYKGK2.js → chunk-3S2VOMIF.js} +3 -3
- package/{chunk-JBKVPAYK.js → chunk-6KBBMW4D.js} +2 -2
- package/{chunk-U7LEGLEB.js → chunk-6N4KODMN.js} +1 -1
- package/{chunk-IZ2QRVEU.js → chunk-A7O4KKLZ.js} +3 -3
- package/{chunk-WA6KZL5V.js → chunk-AAODAAUQ.js} +23 -20
- package/{chunk-K53477EY.js → chunk-C4MMO7W4.js} +1 -1
- package/{chunk-YNHQIXX5.js → chunk-CXM4IIUF.js} +21 -21
- package/{chunk-JKWWVF2I.js → chunk-D3HVJJIA.js} +1 -1
- package/{chunk-XGQZFBO5.js → chunk-DBLHEQH7.js} +148 -175
- package/{chunk-TTGAVETO.js → chunk-EABWT43X.js} +2 -2
- package/{chunk-OKSYPTDZ.js → chunk-F3UOACU4.js} +1 -1
- package/{chunk-VE6XMVKG.js → chunk-G2IQGDQZ.js} +163 -53
- package/{chunk-RKM3K52F.js → chunk-GPELDE6I.js} +2 -2
- package/{chunk-OGGHETUE.js → chunk-HQPG2PIV.js} +62 -19
- package/{chunk-XVP3C2KY.js → chunk-IWLUTMYX.js} +1 -1
- package/{chunk-B4KT7RN2.js → chunk-JTMNCCWF.js} +2 -2
- package/chunk-KFEVY3ST.js +255 -0
- package/{chunk-WNLPAOIT.js → chunk-KFHN5NGJ.js} +1 -1
- package/{chunk-P4MJQWWF.js → chunk-KPD4CEQD.js} +2 -2
- package/{chunk-G2MKOQCB.js → chunk-KPJWHHG4.js} +1 -1
- package/{chunk-ISYE6GZB.js → chunk-L6NVTGI7.js} +1 -1
- package/{chunk-O53CP2QR.js → chunk-LCMAJFAD.js} +3 -3
- package/{chunk-UXKQQ2MR.js → chunk-LO6JNGCT.js} +3 -3
- package/{chunk-472E5RMQ.js → chunk-MSA4JAOZ.js} +1 -1
- package/{chunk-HRQCKQA5.js → chunk-MUCU6ATG.js} +8 -257
- package/{chunk-524BDL33.js → chunk-O6W2O2DA.js} +1 -15
- package/{chunk-4QQFLN5C.js → chunk-OVBVEXZ7.js} +4 -4
- package/{chunk-IOQ7IBPU.js → chunk-PU4LXVAC.js} +1 -1
- package/{chunk-Z24FGIU2.js → chunk-R4L524UB.js} +3 -3
- package/{chunk-4IJYA27C.js → chunk-RG2U2MTJ.js} +1 -1
- package/{chunk-6MHDWKOT.js → chunk-RIF3XLXK.js} +9 -5
- package/{chunk-IKXL2HZ3.js → chunk-RK5NYQEL.js} +1 -1
- package/{chunk-JS33TCQ3.js → chunk-RPDGJO4D.js} +2 -2
- package/{chunk-BFRVXJJJ.js → chunk-SI73WO7P.js} +10 -10
- package/{chunk-WRN5EQT7.js → chunk-T26DWCH5.js} +3 -3
- package/{chunk-EHLHSX7R.js → chunk-UB4RYYNQ.js} +9 -2
- package/{chunk-5VMYGIIL.js → chunk-VHXXRWNL.js} +23 -9
- package/{chunk-OOIN7HSO.js → chunk-XJITGCTM.js} +10 -1
- package/{chunk-AWDOJBHW.js → chunk-XJYXSTBK.js} +883 -174
- package/{chunk-V2J635L5.js → chunk-XOIF2TNF.js} +2 -2
- package/{chunk-VPTJB4HM.js → chunk-XPC5C7BK.js} +0 -3
- package/{chunk-NTC6I2FN.js → chunk-XRSPI6CP.js} +1 -1
- package/{chunk-N5424GSW.js → chunk-YJKXGHJ6.js} +1 -1
- package/chunk-ZHXJ6M7T.js +27 -0
- package/{chunk-6565R2TI.js → chunk-ZOQNJXMS.js} +23 -18
- package/{createAgentAutomationAction-TS6NNZ4X.js → createAgentAutomationAction-OARFMDWU.js} +13 -13
- package/{createDialogAction-5HVQ33EX.js → createDialogAction-4E6ALCDK.js} +14 -14
- package/{createPageAction-4F3ZGQJD.js → createPageAction-RS65DDRX.js} +13 -13
- package/{dbSlice-OP6UPXKA.js → dbSlice-7KQH6GOU.js} +2 -2
- package/{dialogCommands-3GEPXHFB.js → dialogCommands-DFY5HJ6M.js} +19 -18
- package/{dialogSlice-FAWUQDJW.js → dialogSlice-MS7OYWHW.js} +13 -13
- package/{docCreateCommands-ZE3S6BCP.js → docCreateCommands-5L76YTI2.js} +18 -17
- package/{docDeleteCommands-TW6PGTRT.js → docDeleteCommands-3GASP3VR.js} +19 -18
- package/{docReadCommands-LDXL3B6J.js → docReadCommands-ALA77AZM.js} +18 -17
- package/{docStore-2UHVWLTV.js → docStore-KYTKNGMU.js} +14 -14
- package/{docUpdateCommands-GYD6XI5O.js → docUpdateCommands-6AZGXE5M.js} +18 -17
- package/{getPricing-UGDJHI7M.js → getPricing-RYY6OBA4.js} +4 -4
- package/{handleSendMessageAction-LJPUYNOH.js → handleSendMessageAction-LHTGYRMN.js} +201 -15
- package/index.js +47 -47
- package/{machineCommands-OKNDYS3M.js → machineCommands-RDQQBA72.js} +33 -32
- package/{machineWsRunDispatch-ZX5AJ6FJ.js → machineWsRunDispatch-27RCTQQF.js} +33 -32
- package/{models-LSCRJJ6P.js → models-5K5G2CZI.js} +2 -2
- package/package.json +1 -1
- package/{read-HXHAZBKH.js → read-CN3TNXIP.js} +1 -1
- package/{readDocTool-VPBDTO4G.js → readDocTool-WF3675ED.js} +1 -1
- package/{readlineWorkspace-MB3ANKHM.js → readlineWorkspace-BTONC7NW.js} +177 -76
- package/{removeDialogAgentAction-HUFVN35S.js → removeDialogAgentAction-YDHBFEGI.js} +5 -5
- package/{runAgentClientLoop-A75BUU6D.js → runAgentClientLoop-Q4CL22BP.js} +26 -25
- package/{setDialogExtraReferencesAction-2VLGWQKG.js → setDialogExtraReferencesAction-LR6MSIXO.js} +2 -2
- package/{setPrimaryDialogAgentAction-VB4UV2CC.js → setPrimaryDialogAgentAction-IIVDCY5C.js} +5 -5
- package/{settingSlice-7JYPQNAC.js → settingSlice-O23YDK2O.js} +3 -3
- package/{spaceCommands-O3KJNCON.js → spaceCommands-AB2D7A2R.js} +18 -17
- package/{spaceSlice-444MFUP6.js → spaceSlice-XLJ4DRG6.js} +13 -13
- package/{streamAgentChatTurn-DJAE7USZ.js → streamAgentChatTurn-YYAAGLZL.js} +30 -32
- package/{tools-YB6LXSVN.js → tools-5UKY65R3.js} +20 -20
- package/{tuiSummaryLlmCaller-QQL3JA5I.js → tuiSummaryLlmCaller-VUNVBRX3.js} +7 -6
- package/{updateDialogTitleAction-6HGFBM64.js → updateDialogTitleAction-VNSUVPUZ.js} +13 -13
- package/chunk-BYXBJQAS.js +0 -0
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
refreshAntigravityOAuthToken,
|
|
4
4
|
refreshOpenAiCodexToken,
|
|
5
5
|
refreshXaiOAuthToken
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UB4RYYNQ.js";
|
|
7
7
|
import {
|
|
8
8
|
buildLocalAgentLookupKeys,
|
|
9
9
|
normalizeAgentHandle,
|
|
10
10
|
shouldReadAgentKeyRemotely
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-PU4LXVAC.js";
|
|
12
12
|
import {
|
|
13
13
|
LOCAL_CODEX_AGENT_ID,
|
|
14
14
|
LOCAL_CODEX_AGENT_KEY,
|
|
@@ -17,19 +17,20 @@ import {
|
|
|
17
17
|
} from "./chunk-VHBWHNVT.js";
|
|
18
18
|
import {
|
|
19
19
|
inferCaptureIntent
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-KFHN5NGJ.js";
|
|
21
21
|
import {
|
|
22
22
|
inlineImageUrlsForCustomProvider,
|
|
23
23
|
prepareTools
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-T26DWCH5.js";
|
|
25
25
|
import {
|
|
26
26
|
getAntigravityUserAgent,
|
|
27
27
|
isAntigravityOAuthAgent,
|
|
28
28
|
readAntigravityProjectId,
|
|
29
29
|
resolveAntigravityCloudCodeBaseUrl
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-L6NVTGI7.js";
|
|
31
31
|
import {
|
|
32
32
|
FORCED_TOOLS,
|
|
33
|
+
TASK_PREVIEW_MAX,
|
|
33
34
|
addDefaultLightWebToolsForConfiguredAgents,
|
|
34
35
|
addDefaultSystemCapabilityTools,
|
|
35
36
|
appendEnabledPackPromptPatches,
|
|
@@ -41,13 +42,15 @@ import {
|
|
|
41
42
|
formatStartRunCard,
|
|
42
43
|
formatStatusRunCard,
|
|
43
44
|
formatStopRunCard,
|
|
45
|
+
isAgentNameFallback,
|
|
44
46
|
readXPostFunc,
|
|
45
47
|
readXPostFunctionSchema,
|
|
46
48
|
readXhsProfileFunc,
|
|
47
49
|
readXhsProfileFunctionSchema,
|
|
48
50
|
rememberMemoryFunctionSchema,
|
|
49
|
-
resolveEffectiveEnabledPacks
|
|
50
|
-
|
|
51
|
+
resolveEffectiveEnabledPacks,
|
|
52
|
+
resolveRunLabel
|
|
53
|
+
} from "./chunk-G2IQGDQZ.js";
|
|
51
54
|
import {
|
|
52
55
|
createDrainExhaustedResponse,
|
|
53
56
|
isCoreDrainingBody,
|
|
@@ -59,13 +62,13 @@ import {
|
|
|
59
62
|
} from "./chunk-OWOHNGCN.js";
|
|
60
63
|
import {
|
|
61
64
|
prepareTokenUsageData
|
|
62
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-CXM4IIUF.js";
|
|
63
66
|
import {
|
|
64
67
|
BUILTIN_TITLE_LLM_CONFIG
|
|
65
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-XOIF2TNF.js";
|
|
66
69
|
import {
|
|
67
70
|
fetchServerSyncedCredential
|
|
68
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-2OUI4TLC.js";
|
|
69
72
|
import {
|
|
70
73
|
buildAgentRuntimeDialogWritePlan,
|
|
71
74
|
buildLocalWorkspaceOpenAiTools,
|
|
@@ -76,29 +79,32 @@ import {
|
|
|
76
79
|
executeLocalToolWithPolicy,
|
|
77
80
|
executeOpenAiCompatibleChatCompletion,
|
|
78
81
|
parseSseDataLineJson,
|
|
82
|
+
parseSseDataLineObject,
|
|
79
83
|
readOpenAiCompatibleSseCompletion,
|
|
80
84
|
resolveOpenAiCompatibleProviderConfig
|
|
81
|
-
} from "./chunk-
|
|
85
|
+
} from "./chunk-VHXXRWNL.js";
|
|
82
86
|
import {
|
|
83
87
|
buildPlatformChatCompletionRequest,
|
|
84
88
|
canUsePlatformChatProvider,
|
|
85
89
|
parsePlatformChatCompletionData,
|
|
86
90
|
parsePlatformChatCompletionResponse,
|
|
87
91
|
readSseDataValues,
|
|
88
|
-
resolveLegacyDeepSeekProxyChatFallback,
|
|
89
92
|
resolvePlatformChatProviderConfig,
|
|
90
93
|
shouldUsePlatformChatProvider
|
|
91
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-AAODAAUQ.js";
|
|
92
95
|
import {
|
|
93
96
|
resolveAgentRuntimeConfigFromRecord
|
|
94
97
|
} from "./chunk-OIQPORYI.js";
|
|
95
98
|
import {
|
|
96
|
-
parseToolArgumentsJson,
|
|
97
99
|
summarizeToolArguments
|
|
98
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-RIF3XLXK.js";
|
|
101
|
+
import {
|
|
102
|
+
convertMessagesToResponsesInput,
|
|
103
|
+
toResponsesTools
|
|
104
|
+
} from "./chunk-KFEVY3ST.js";
|
|
99
105
|
import {
|
|
100
106
|
resolvePlatformAuthToken
|
|
101
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-MUCU6ATG.js";
|
|
102
108
|
import {
|
|
103
109
|
buildLoadSkillExecutor,
|
|
104
110
|
buildNoloWorkspaceCliToolExecutors,
|
|
@@ -106,10 +112,13 @@ import {
|
|
|
106
112
|
canonicalizeToolNames,
|
|
107
113
|
parseNoloWorkspaceToolArguments,
|
|
108
114
|
resolveRuntimeToolSurfaceForAgent
|
|
109
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-JTMNCCWF.js";
|
|
110
116
|
import {
|
|
111
117
|
clipCompactText
|
|
112
118
|
} from "./chunk-5MMAK75Q.js";
|
|
119
|
+
import {
|
|
120
|
+
isAdaptiveThinkingModelId
|
|
121
|
+
} from "./chunk-HQPG2PIV.js";
|
|
113
122
|
import {
|
|
114
123
|
createFileCredentialBroker,
|
|
115
124
|
resolveCurrentRunRuntimeToolPolicy,
|
|
@@ -152,9 +161,6 @@ import {
|
|
|
152
161
|
import {
|
|
153
162
|
DEFAULT_NOLO_SERVER_URL
|
|
154
163
|
} from "./chunk-OLZBQWZU.js";
|
|
155
|
-
import {
|
|
156
|
-
asRecordOrEmpty
|
|
157
|
-
} from "./chunk-KX6YBIHG.js";
|
|
158
164
|
import {
|
|
159
165
|
createTokenKey,
|
|
160
166
|
createUserKey,
|
|
@@ -166,14 +172,16 @@ import {
|
|
|
166
172
|
import {
|
|
167
173
|
asOptionalFiniteNumber
|
|
168
174
|
} from "./chunk-WWC7I6TA.js";
|
|
175
|
+
import {
|
|
176
|
+
asTrimmedLowercaseString
|
|
177
|
+
} from "./chunk-QSJ3HFEF.js";
|
|
169
178
|
import {
|
|
170
179
|
BUILTIN_NOLO_AGENT_KEY,
|
|
171
180
|
PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
|
|
172
181
|
PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
|
|
173
182
|
PUBLIC_GLM_52_AGENT_KEY,
|
|
174
|
-
PUBLIC_KIMI_K26_IMAGE_AGENT_KEY
|
|
175
|
-
|
|
176
|
-
} from "./chunk-VPTJB4HM.js";
|
|
183
|
+
PUBLIC_KIMI_K26_IMAGE_AGENT_KEY
|
|
184
|
+
} from "./chunk-XPC5C7BK.js";
|
|
177
185
|
import {
|
|
178
186
|
asTrimmedString
|
|
179
187
|
} from "./chunk-3EUW3WEO.js";
|
|
@@ -463,6 +471,10 @@ var STRINGS = {
|
|
|
463
471
|
en: "Run stopped",
|
|
464
472
|
zh: "\u8FD0\u884C\u5DF2\u505C\u6B62"
|
|
465
473
|
},
|
|
474
|
+
runFinishedLabel: {
|
|
475
|
+
en: "Run finished",
|
|
476
|
+
zh: "\u8FD0\u884C\u5DF2\u7ED3\u675F"
|
|
477
|
+
},
|
|
466
478
|
runLogTailLabel: {
|
|
467
479
|
en: "Log tail:",
|
|
468
480
|
zh: "\u65E5\u5FD7\u5C3E\u90E8\uFF1A"
|
|
@@ -764,8 +776,8 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
|
|
|
764
776
|
},
|
|
765
777
|
themeCurrent: { en: "Current theme: {0} \xB7 {1}", zh: "\u5F53\u524D\u4E3B\u9898\uFF1A{0} \xB7 {1}" },
|
|
766
778
|
themeUsage: {
|
|
767
|
-
en: "Usage: /theme <name> | /theme light | /theme dark",
|
|
768
|
-
zh: "\u7528\u6CD5\uFF1A/theme <name> | /theme light | /theme dark"
|
|
779
|
+
en: "Usage: /theme <name> | /theme light | /theme dark | /theme refresh",
|
|
780
|
+
zh: "\u7528\u6CD5\uFF1A/theme <name> | /theme light | /theme dark | /theme refresh"
|
|
769
781
|
},
|
|
770
782
|
themeAvailable: { en: "Available themes: {0}", zh: "\u53EF\u7528\u4E3B\u9898\uFF1A{0}" },
|
|
771
783
|
themeBrightnessSwitched: { en: "Switched to {0} background colors.", zh: "\u5DF2\u5207\u6362\u5230 {0} \u80CC\u666F\u8272\u3002" },
|
|
@@ -773,6 +785,14 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
|
|
|
773
785
|
en: "Background colors follow terminal detection (now: {0}).",
|
|
774
786
|
zh: "\u80CC\u666F\u8272\u8DDF\u968F\u7EC8\u7AEF\u81EA\u52A8\u68C0\u6D4B\uFF08\u5F53\u524D\uFF1A{0}\uFF09\u3002"
|
|
775
787
|
},
|
|
788
|
+
themeRefreshed: {
|
|
789
|
+
en: "Re-detected terminal background: {0}.",
|
|
790
|
+
zh: "\u5DF2\u91CD\u65B0\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF1A{0}\u3002"
|
|
791
|
+
},
|
|
792
|
+
themeRefreshFailed: {
|
|
793
|
+
en: "Could not detect terminal background (not a TTY or no response).",
|
|
794
|
+
zh: "\u65E0\u6CD5\u68C0\u6D4B\u7EC8\u7AEF\u80CC\u666F\uFF08\u975E TTY \u6216\u7EC8\u7AEF\u65E0\u54CD\u5E94\uFF09\u3002"
|
|
795
|
+
},
|
|
776
796
|
themeSwitched: { en: "Switched to theme: {0}", zh: "\u5DF2\u5207\u6362\u5230\u4E3B\u9898\uFF1A{0}" },
|
|
777
797
|
themeUnknown: { en: "Unknown theme: {0}. Available themes: {1}", zh: "\u672A\u77E5\u4E3B\u9898\uFF1A{0}\u3002\u53EF\u7528\u4E3B\u9898\uFF1A{1}" },
|
|
778
798
|
densityCurrent: {
|
|
@@ -920,6 +940,7 @@ function agentRunCardLabels() {
|
|
|
920
940
|
runStatus: t("runStatusLabel"),
|
|
921
941
|
runStarted: t("runStartedLabel"),
|
|
922
942
|
runStopped: t("runStoppedLabel"),
|
|
943
|
+
runFinished: t("runFinishedLabel"),
|
|
923
944
|
logTail: t("runLogTailLabel"),
|
|
924
945
|
runs: (count) => t("runsListLabel", String(count))
|
|
925
946
|
};
|
|
@@ -1115,6 +1136,11 @@ async function fetchWithTransientRetry(fetchImpl, input, init, options = {}) {
|
|
|
1115
1136
|
const attemptBudget = coreDraining ? coreDrainingMaxAttempts : maxAttempts;
|
|
1116
1137
|
if (attempt < attemptBudget) {
|
|
1117
1138
|
const delayMs = await resolveRetryAfterMs(response, attempt);
|
|
1139
|
+
options.onRetry?.({
|
|
1140
|
+
attempt: attempt + 1,
|
|
1141
|
+
maxAttempts: attemptBudget,
|
|
1142
|
+
delayMs
|
|
1143
|
+
});
|
|
1118
1144
|
await (options.sleep ?? defaultSleep)(delayMs);
|
|
1119
1145
|
continue;
|
|
1120
1146
|
}
|
|
@@ -1128,7 +1154,13 @@ async function fetchWithTransientRetry(fetchImpl, input, init, options = {}) {
|
|
|
1128
1154
|
if (!isTransientFetchError(error)) throw error;
|
|
1129
1155
|
lastError = error;
|
|
1130
1156
|
if (attempt < maxAttempts) {
|
|
1131
|
-
|
|
1157
|
+
const delayMs = transientFetchRetryDelayMs(attempt);
|
|
1158
|
+
options.onRetry?.({
|
|
1159
|
+
attempt: attempt + 1,
|
|
1160
|
+
maxAttempts,
|
|
1161
|
+
delayMs
|
|
1162
|
+
});
|
|
1163
|
+
await (options.sleep ?? defaultSleep)(delayMs);
|
|
1132
1164
|
}
|
|
1133
1165
|
}
|
|
1134
1166
|
}
|
|
@@ -1458,14 +1490,14 @@ var BUILTIN_PLATFORM_AGENT_CONFIGS = {
|
|
|
1458
1490
|
[PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY]: {
|
|
1459
1491
|
key: PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
|
|
1460
1492
|
name: "DeepSeek V4 Pro",
|
|
1461
|
-
provider: "
|
|
1493
|
+
provider: "nolo",
|
|
1462
1494
|
model: "deepseek-v4-pro",
|
|
1463
1495
|
apiSource: "platform",
|
|
1464
1496
|
useServerProxy: true,
|
|
1465
1497
|
rawRecord: {
|
|
1466
1498
|
dbKey: PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
|
|
1467
1499
|
isPublic: true,
|
|
1468
|
-
provider: "
|
|
1500
|
+
provider: "nolo",
|
|
1469
1501
|
model: "deepseek-v4-pro",
|
|
1470
1502
|
apiSource: "platform",
|
|
1471
1503
|
useServerProxy: true
|
|
@@ -1503,22 +1535,6 @@ var BUILTIN_PLATFORM_AGENT_CONFIGS = {
|
|
|
1503
1535
|
useServerProxy: true
|
|
1504
1536
|
}
|
|
1505
1537
|
},
|
|
1506
|
-
[PUBLIC_KIMI_K27_CODING_AGENT_KEY]: {
|
|
1507
|
-
key: PUBLIC_KIMI_K27_CODING_AGENT_KEY,
|
|
1508
|
-
name: "Kimi K2.7 Coding",
|
|
1509
|
-
provider: "nolo",
|
|
1510
|
-
model: "kimi-k2.7-code",
|
|
1511
|
-
apiSource: "platform",
|
|
1512
|
-
useServerProxy: true,
|
|
1513
|
-
rawRecord: {
|
|
1514
|
-
dbKey: PUBLIC_KIMI_K27_CODING_AGENT_KEY,
|
|
1515
|
-
isPublic: true,
|
|
1516
|
-
provider: "nolo",
|
|
1517
|
-
model: "kimi-k2.7-code",
|
|
1518
|
-
apiSource: "platform",
|
|
1519
|
-
useServerProxy: true
|
|
1520
|
-
}
|
|
1521
|
-
},
|
|
1522
1538
|
[BUILTIN_NOLO_AGENT_KEY]: {
|
|
1523
1539
|
key: BUILTIN_NOLO_AGENT_KEY,
|
|
1524
1540
|
name: "Nolo",
|
|
@@ -2029,6 +2045,93 @@ function buildServerPlatformToolExecutors(args) {
|
|
|
2029
2045
|
|
|
2030
2046
|
// packages/cli/client/cliAgentRunToolExecutors.ts
|
|
2031
2047
|
import { existsSync, readFileSync } from "node:fs";
|
|
2048
|
+
|
|
2049
|
+
// packages/cli/client/agentRunSnapshot.ts
|
|
2050
|
+
function readString(value) {
|
|
2051
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2052
|
+
}
|
|
2053
|
+
function readLogLines(parsed) {
|
|
2054
|
+
if (Array.isArray(parsed.logLines)) return parsed.logLines;
|
|
2055
|
+
const tail = readString(parsed.logTail);
|
|
2056
|
+
return tail ? tail.split("\n") : void 0;
|
|
2057
|
+
}
|
|
2058
|
+
function readTimestamp(value) {
|
|
2059
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
2060
|
+
if (typeof value === "string" && value.trim()) {
|
|
2061
|
+
const parsed = Date.parse(value);
|
|
2062
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
2063
|
+
}
|
|
2064
|
+
return void 0;
|
|
2065
|
+
}
|
|
2066
|
+
function readToolNames(value) {
|
|
2067
|
+
if (!Array.isArray(value)) return void 0;
|
|
2068
|
+
const names = value.filter((n) => typeof n === "string" && Boolean(n.trim()));
|
|
2069
|
+
return names.length > 0 ? names : void 0;
|
|
2070
|
+
}
|
|
2071
|
+
function buildSnapshot(parsed, event) {
|
|
2072
|
+
const runId = readString(parsed.runId) ?? readString(event.metadata?.runId) ?? "";
|
|
2073
|
+
const label = resolveRunLabel({
|
|
2074
|
+
agentName: parsed.agentName,
|
|
2075
|
+
name: parsed.name,
|
|
2076
|
+
agentKey: parsed.agentKey
|
|
2077
|
+
});
|
|
2078
|
+
const logLines = readLogLines(parsed);
|
|
2079
|
+
const taskPreview = readString(parsed.taskPreview);
|
|
2080
|
+
const lastToolNames = readToolNames(parsed.lastToolNames);
|
|
2081
|
+
const lastAssistantText = readString(parsed.lastAssistantText);
|
|
2082
|
+
const errorMessage = readString(parsed.errorMessage);
|
|
2083
|
+
const startedAt = readTimestamp(parsed.startedAt);
|
|
2084
|
+
const finishedAt = readTimestamp(parsed.finishedAt) ?? readTimestamp(parsed.endedAt);
|
|
2085
|
+
return {
|
|
2086
|
+
runId,
|
|
2087
|
+
status: readString(parsed.status) ?? "running",
|
|
2088
|
+
// The literal `agent` fallback is dropped here rather than at each render
|
|
2089
|
+
// site: an unnamed run should render no name row, not the word "agent".
|
|
2090
|
+
...isAgentNameFallback(label) ? {} : { agentName: label },
|
|
2091
|
+
...taskPreview ? { taskPreview } : {},
|
|
2092
|
+
...typeof parsed.toolCallCount === "number" && Number.isFinite(parsed.toolCallCount) ? { toolCallCount: parsed.toolCallCount } : {},
|
|
2093
|
+
...lastToolNames ? { lastToolNames } : {},
|
|
2094
|
+
...lastAssistantText ? { lastAssistantText } : {},
|
|
2095
|
+
...errorMessage ? { errorMessage } : {},
|
|
2096
|
+
...startedAt !== void 0 ? { startedAt } : {},
|
|
2097
|
+
...finishedAt !== void 0 ? { finishedAt } : {},
|
|
2098
|
+
...logLines ? { logLines } : {},
|
|
2099
|
+
logKey: logLines && logLines.length > 0 ? logLines.join("\n") : ""
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
var STOP_STATUSES = /* @__PURE__ */ new Set(["killed", "cancelled", "cancelling"]);
|
|
2103
|
+
function parseAgentRunEvent(event) {
|
|
2104
|
+
if (event.type !== "tool-result") return null;
|
|
2105
|
+
if (event.toolName !== "startAgentRun" && event.toolName !== "controlAgentRun") {
|
|
2106
|
+
return null;
|
|
2107
|
+
}
|
|
2108
|
+
const raw = typeof event.content === "string" ? event.content.trim() : "";
|
|
2109
|
+
if (!raw.startsWith("{")) return null;
|
|
2110
|
+
let parsed;
|
|
2111
|
+
try {
|
|
2112
|
+
parsed = JSON.parse(raw);
|
|
2113
|
+
} catch {
|
|
2114
|
+
return null;
|
|
2115
|
+
}
|
|
2116
|
+
if (Array.isArray(parsed.runs)) return null;
|
|
2117
|
+
const snapshot = buildSnapshot(parsed, event);
|
|
2118
|
+
const status = readString(parsed.status);
|
|
2119
|
+
if (event.toolName === "startAgentRun") {
|
|
2120
|
+
if (!snapshot.runId) return null;
|
|
2121
|
+
return { kind: "start", snapshot };
|
|
2122
|
+
}
|
|
2123
|
+
if (parsed.found === false || status === "not_found") {
|
|
2124
|
+
return { kind: "gone", snapshot: { ...snapshot, status: "not_found" } };
|
|
2125
|
+
}
|
|
2126
|
+
if (status && STOP_STATUSES.has(status)) {
|
|
2127
|
+
return { kind: "stop", snapshot };
|
|
2128
|
+
}
|
|
2129
|
+
if (!status) return null;
|
|
2130
|
+
if (!snapshot.runId) return null;
|
|
2131
|
+
return { kind: "status", snapshot };
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// packages/cli/client/cliAgentRunToolExecutors.ts
|
|
2032
2135
|
var noopOutput = { write: () => {
|
|
2033
2136
|
} };
|
|
2034
2137
|
var parseCallArgs = (call) => {
|
|
@@ -2061,7 +2164,16 @@ function createCliStartAgentRunExecutor(deps = {}) {
|
|
|
2061
2164
|
|
|
2062
2165
|
--- \u9644\u52A0\u8F93\u5165 ---
|
|
2063
2166
|
${JSON.stringify(args.input)}`;
|
|
2064
|
-
const rawArgs = [
|
|
2167
|
+
const rawArgs = [
|
|
2168
|
+
"--agent",
|
|
2169
|
+
agentKey,
|
|
2170
|
+
"--msg-file",
|
|
2171
|
+
"PLACEHOLDER",
|
|
2172
|
+
"--bg",
|
|
2173
|
+
// 非持久化派发(review 等一次性任务):透传 --ephemeral,run 完成后不留
|
|
2174
|
+
// dialog 记录。与 web 端 runAgentBackground 的 ephemeral: true 对齐。
|
|
2175
|
+
...args.ephemeral === true ? ["--ephemeral"] : []
|
|
2176
|
+
];
|
|
2065
2177
|
const agentName = typeof args.agentName === "string" && args.agentName.trim() ? args.agentName.trim() : typeof args.name === "string" && args.name.trim() ? args.name.trim() : void 0;
|
|
2066
2178
|
const { runId } = await spawnLocalBackgroundRun(
|
|
2067
2179
|
{
|
|
@@ -2076,16 +2188,22 @@ ${JSON.stringify(args.input)}`;
|
|
|
2076
2188
|
},
|
|
2077
2189
|
deps
|
|
2078
2190
|
);
|
|
2079
|
-
const displayName = agentName
|
|
2191
|
+
const displayName = resolveRunLabel({ agentName, agentKey, runId });
|
|
2080
2192
|
const labels = agentRunCardLabels();
|
|
2193
|
+
const taskPreview = typeof args.task === "string" ? args.task.replace(/\s+/g, " ").trim().slice(0, TASK_PREVIEW_MAX) : "";
|
|
2081
2194
|
return {
|
|
2082
2195
|
content: JSON.stringify({
|
|
2083
2196
|
runId,
|
|
2084
2197
|
status: "running",
|
|
2085
|
-
...agentName ? { agentName } : {}
|
|
2198
|
+
...agentName ? { agentName } : {},
|
|
2199
|
+
...taskPreview ? { taskPreview } : {}
|
|
2086
2200
|
}),
|
|
2087
2201
|
metadata: {
|
|
2088
|
-
displayData: formatStartRunCard(displayName, "running",
|
|
2202
|
+
displayData: formatStartRunCard(displayName, "running", {
|
|
2203
|
+
task: taskPreview,
|
|
2204
|
+
runId,
|
|
2205
|
+
labels
|
|
2206
|
+
})
|
|
2089
2207
|
}
|
|
2090
2208
|
};
|
|
2091
2209
|
};
|
|
@@ -2131,7 +2249,7 @@ function createCliControlAgentRunExecutor(deps = {}) {
|
|
|
2131
2249
|
if (action === "status") {
|
|
2132
2250
|
const reconciled = checkStaleRun(record.runId, deps) ?? record;
|
|
2133
2251
|
const logTail = tailLines > 0 ? tailFile(record.logPath, tailLines, resolveFs(deps)) : void 0;
|
|
2134
|
-
const name = reconciled
|
|
2252
|
+
const name = resolveRunLabel(reconciled);
|
|
2135
2253
|
const logLines = logTail ? logTail.split("\n") : void 0;
|
|
2136
2254
|
const labels2 = agentRunCardLabels();
|
|
2137
2255
|
return {
|
|
@@ -2158,7 +2276,15 @@ function createCliControlAgentRunExecutor(deps = {}) {
|
|
|
2158
2276
|
...logLines ? { logLines } : {}
|
|
2159
2277
|
}),
|
|
2160
2278
|
metadata: {
|
|
2161
|
-
displayData: formatStatusRunCard(name, reconciled.status, {
|
|
2279
|
+
displayData: formatStatusRunCard(name, reconciled.status, {
|
|
2280
|
+
runId: reconciled.runId,
|
|
2281
|
+
timing: {
|
|
2282
|
+
startedAt: readTimestamp(reconciled.startedAt),
|
|
2283
|
+
finishedAt: readTimestamp(reconciled.endedAt)
|
|
2284
|
+
},
|
|
2285
|
+
logLines,
|
|
2286
|
+
labels: labels2
|
|
2287
|
+
})
|
|
2162
2288
|
}
|
|
2163
2289
|
};
|
|
2164
2290
|
}
|
|
@@ -2440,19 +2566,22 @@ function resolveAntigravityWireModel(logicalModelId) {
|
|
|
2440
2566
|
return { wireModelId: id };
|
|
2441
2567
|
}
|
|
2442
2568
|
|
|
2443
|
-
// packages/agent-runtime/
|
|
2444
|
-
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2569
|
+
// packages/agent-runtime/geminiNativeShared.ts
|
|
2445
2570
|
var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2446
|
-
function
|
|
2571
|
+
function isGemini3Model(modelId) {
|
|
2447
2572
|
return modelId.includes("gemini-3");
|
|
2448
2573
|
}
|
|
2449
2574
|
function messageText(content) {
|
|
2450
2575
|
if (typeof content === "string") return content;
|
|
2451
2576
|
if (!Array.isArray(content)) return "";
|
|
2452
|
-
return content.filter(
|
|
2577
|
+
return content.filter(
|
|
2578
|
+
(part) => part?.type === "text"
|
|
2579
|
+
).map((part) => part.text).join("\n").trim();
|
|
2453
2580
|
}
|
|
2454
2581
|
function parseDataUrlToInlineData(url) {
|
|
2455
|
-
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
2582
|
+
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
2583
|
+
url
|
|
2584
|
+
);
|
|
2456
2585
|
if (!match) return null;
|
|
2457
2586
|
return { mimeType: match[1], data: match[2] };
|
|
2458
2587
|
}
|
|
@@ -2469,7 +2598,7 @@ function extractInlineDataParts(content) {
|
|
|
2469
2598
|
}
|
|
2470
2599
|
return parts;
|
|
2471
2600
|
}
|
|
2472
|
-
function
|
|
2601
|
+
function convertOpenAiMessagesToGemini(messages, options) {
|
|
2473
2602
|
const contents = [];
|
|
2474
2603
|
const systemTexts = [];
|
|
2475
2604
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
@@ -2485,9 +2614,11 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2485
2614
|
};
|
|
2486
2615
|
const flushPendingFunctionCalls = () => {
|
|
2487
2616
|
if (pendingFunctionCalls.length === 0) return;
|
|
2488
|
-
const dummyResponses = pendingFunctionCalls.map(
|
|
2489
|
-
|
|
2490
|
-
|
|
2617
|
+
const dummyResponses = pendingFunctionCalls.map(
|
|
2618
|
+
({ name }) => ({
|
|
2619
|
+
functionResponse: { name, response: { output: "{}" } }
|
|
2620
|
+
})
|
|
2621
|
+
);
|
|
2491
2622
|
pendingFunctionCalls = [];
|
|
2492
2623
|
pushOrMergeContent("user", dummyResponses);
|
|
2493
2624
|
};
|
|
@@ -2496,13 +2627,17 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2496
2627
|
const role = String(raw.role);
|
|
2497
2628
|
const content = "content" in raw ? raw.content : null;
|
|
2498
2629
|
if (role === "system") {
|
|
2499
|
-
const text = messageText(
|
|
2630
|
+
const text = messageText(
|
|
2631
|
+
content
|
|
2632
|
+
);
|
|
2500
2633
|
if (text) systemTexts.push(text);
|
|
2501
2634
|
continue;
|
|
2502
2635
|
}
|
|
2503
2636
|
if (role === "user") {
|
|
2504
2637
|
flushPendingFunctionCalls();
|
|
2505
|
-
const text = messageText(
|
|
2638
|
+
const text = messageText(
|
|
2639
|
+
content
|
|
2640
|
+
);
|
|
2506
2641
|
const imageParts = extractInlineDataParts(
|
|
2507
2642
|
content
|
|
2508
2643
|
);
|
|
@@ -2516,7 +2651,9 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2516
2651
|
if (role === "assistant") {
|
|
2517
2652
|
flushPendingFunctionCalls();
|
|
2518
2653
|
const parts = [];
|
|
2519
|
-
const text = messageText(
|
|
2654
|
+
const text = messageText(
|
|
2655
|
+
content
|
|
2656
|
+
);
|
|
2520
2657
|
if (text) parts.push({ text });
|
|
2521
2658
|
const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
|
|
2522
2659
|
for (const call of toolCalls) {
|
|
@@ -2526,17 +2663,20 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2526
2663
|
toolNamesById.set(id, name);
|
|
2527
2664
|
pendingFunctionCalls.push({ name, id });
|
|
2528
2665
|
const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
|
|
2529
|
-
const isFirstFunctionCallPart = !parts.some(
|
|
2530
|
-
|
|
2666
|
+
const isFirstFunctionCallPart = !parts.some(
|
|
2667
|
+
(p) => "functionCall" in p
|
|
2668
|
+
);
|
|
2669
|
+
const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
|
|
2670
|
+
const part = {
|
|
2531
2671
|
functionCall: {
|
|
2532
2672
|
name,
|
|
2533
|
-
args:
|
|
2534
|
-
id
|
|
2673
|
+
args: parseToolArgs(call.function?.arguments),
|
|
2674
|
+
...id ? { id } : {}
|
|
2535
2675
|
},
|
|
2536
|
-
...
|
|
2537
|
-
}
|
|
2676
|
+
...signature ? { thoughtSignature: signature } : {}
|
|
2677
|
+
};
|
|
2678
|
+
parts.push(part);
|
|
2538
2679
|
}
|
|
2539
|
-
if (parts.length === 0) continue;
|
|
2540
2680
|
pushOrMergeContent("model", parts);
|
|
2541
2681
|
continue;
|
|
2542
2682
|
}
|
|
@@ -2554,14 +2694,39 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2554
2694
|
}
|
|
2555
2695
|
const output = messageText(content) || "{}";
|
|
2556
2696
|
pushOrMergeContent("user", [
|
|
2557
|
-
{
|
|
2697
|
+
{
|
|
2698
|
+
functionResponse: {
|
|
2699
|
+
name,
|
|
2700
|
+
response: { output },
|
|
2701
|
+
// 保留 OpenAI tool_call_id:antigravity Cloud Code Assist 网关把
|
|
2702
|
+
// Gemini contents 转成 Claude messages 时需要 functionResponse →
|
|
2703
|
+
// tool_result 的 tool_use_id;缺 id 时网关报
|
|
2704
|
+
// "tool_result.tool_use_id: Field required"(HTTP 400)。
|
|
2705
|
+
...toolCallId ? { id: toolCallId } : {}
|
|
2706
|
+
}
|
|
2707
|
+
}
|
|
2558
2708
|
]);
|
|
2559
2709
|
}
|
|
2560
2710
|
}
|
|
2561
2711
|
flushPendingFunctionCalls();
|
|
2562
2712
|
return { contents, systemTexts };
|
|
2563
2713
|
}
|
|
2564
|
-
function
|
|
2714
|
+
function parseToolArgs(raw) {
|
|
2715
|
+
if (typeof raw === "string") {
|
|
2716
|
+
try {
|
|
2717
|
+
const parsed = JSON.parse(raw);
|
|
2718
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2719
|
+
return parsed;
|
|
2720
|
+
}
|
|
2721
|
+
} catch {
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
2725
|
+
return raw;
|
|
2726
|
+
}
|
|
2727
|
+
return {};
|
|
2728
|
+
}
|
|
2729
|
+
function convertOpenAiToolsToGemini(tools) {
|
|
2565
2730
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
2566
2731
|
const declarations = [];
|
|
2567
2732
|
for (const tool of tools) {
|
|
@@ -2578,6 +2743,97 @@ function convertOpenAiTools(tools) {
|
|
|
2578
2743
|
if (declarations.length === 0) return void 0;
|
|
2579
2744
|
return [{ functionDeclarations: declarations }];
|
|
2580
2745
|
}
|
|
2746
|
+
function accumulateGeminiChunks(chunks) {
|
|
2747
|
+
let text = "";
|
|
2748
|
+
const toolCalls = [];
|
|
2749
|
+
let usage;
|
|
2750
|
+
let pendingThoughtSignature;
|
|
2751
|
+
for (const chunk of chunks) {
|
|
2752
|
+
if (!chunk || typeof chunk !== "object") continue;
|
|
2753
|
+
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2754
|
+
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2755
|
+
const meta = response.usageMetadata;
|
|
2756
|
+
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2757
|
+
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2758
|
+
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2759
|
+
usage = {
|
|
2760
|
+
prompt_tokens: prompt,
|
|
2761
|
+
completion_tokens: candidates2,
|
|
2762
|
+
total_tokens: total
|
|
2763
|
+
};
|
|
2764
|
+
}
|
|
2765
|
+
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2766
|
+
for (const candidate of candidates) {
|
|
2767
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
2768
|
+
const parts = Array.isArray(
|
|
2769
|
+
candidate.content?.parts
|
|
2770
|
+
) ? candidate.content.parts : [];
|
|
2771
|
+
for (const part of parts) {
|
|
2772
|
+
if (!part || typeof part !== "object") continue;
|
|
2773
|
+
const partSignature = part.thoughtSignature;
|
|
2774
|
+
if ("text" in part && typeof part.text === "string") {
|
|
2775
|
+
const piece = part.text;
|
|
2776
|
+
if (!part.thought) {
|
|
2777
|
+
text += piece;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
if (part.thought && typeof partSignature === "string" && partSignature) {
|
|
2781
|
+
pendingThoughtSignature = partSignature;
|
|
2782
|
+
}
|
|
2783
|
+
if ("functionCall" in part && part.functionCall) {
|
|
2784
|
+
const call = part.functionCall;
|
|
2785
|
+
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2786
|
+
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2787
|
+
const argsObj = call.args && typeof call.args === "object" ? call.args : {};
|
|
2788
|
+
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2789
|
+
pendingThoughtSignature = void 0;
|
|
2790
|
+
toolCalls.push({
|
|
2791
|
+
id,
|
|
2792
|
+
type: "function",
|
|
2793
|
+
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2794
|
+
...typeof resolvedSignature === "string" && resolvedSignature ? { thought_signature: resolvedSignature } : {}
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
return { text, toolCalls, usage };
|
|
2801
|
+
}
|
|
2802
|
+
function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
|
|
2803
|
+
return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
|
|
2804
|
+
}
|
|
2805
|
+
function buildGeminiGenerateContentRequest(args) {
|
|
2806
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(
|
|
2807
|
+
args.messages,
|
|
2808
|
+
{ attachSkipThoughtSignature: args.attachSkipThoughtSignature }
|
|
2809
|
+
);
|
|
2810
|
+
const request = { contents };
|
|
2811
|
+
if (systemTexts.length > 0) {
|
|
2812
|
+
request.systemInstruction = {
|
|
2813
|
+
role: "user",
|
|
2814
|
+
parts: systemTexts.map((text) => ({ text }))
|
|
2815
|
+
};
|
|
2816
|
+
}
|
|
2817
|
+
const toolsResult = convertOpenAiToolsToGemini(args.tools);
|
|
2818
|
+
if (toolsResult) {
|
|
2819
|
+
request.tools = toolsResult;
|
|
2820
|
+
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
2821
|
+
}
|
|
2822
|
+
const generationConfig = {};
|
|
2823
|
+
if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
|
|
2824
|
+
generationConfig.maxOutputTokens = args.maxTokens;
|
|
2825
|
+
}
|
|
2826
|
+
if (typeof args.temperature === "number") {
|
|
2827
|
+
generationConfig.temperature = args.temperature;
|
|
2828
|
+
}
|
|
2829
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
2830
|
+
request.generationConfig = generationConfig;
|
|
2831
|
+
}
|
|
2832
|
+
return request;
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
// packages/agent-runtime/antigravityCloudCodeProvider.ts
|
|
2836
|
+
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
2581
2837
|
function buildCloudCodeAssistPayload(args) {
|
|
2582
2838
|
const projectId = readAntigravityProjectId(args.metadata);
|
|
2583
2839
|
if (!projectId) {
|
|
@@ -2588,8 +2844,9 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2588
2844
|
const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
|
|
2589
2845
|
const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
|
|
2590
2846
|
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
2591
|
-
const
|
|
2592
|
-
|
|
2847
|
+
const isClaude = model.toLowerCase().includes("claude");
|
|
2848
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
|
|
2849
|
+
attachSkipThoughtSignature: isGemini3Model(model)
|
|
2593
2850
|
});
|
|
2594
2851
|
if (contents.length === 0) {
|
|
2595
2852
|
throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
|
|
@@ -2603,7 +2860,7 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2603
2860
|
parts: systemTexts.map((text) => ({ text }))
|
|
2604
2861
|
};
|
|
2605
2862
|
}
|
|
2606
|
-
const tools =
|
|
2863
|
+
const tools = convertOpenAiToolsToGemini(
|
|
2607
2864
|
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
2608
2865
|
);
|
|
2609
2866
|
if (tools) {
|
|
@@ -2626,7 +2883,6 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2626
2883
|
const trajectoryId = randomUUID();
|
|
2627
2884
|
const step = 2;
|
|
2628
2885
|
const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
|
|
2629
|
-
const isClaude = model.toLowerCase().includes("claude");
|
|
2630
2886
|
const labels = {
|
|
2631
2887
|
trajectory_id: trajectoryId,
|
|
2632
2888
|
last_step_index: String(step - 1),
|
|
@@ -2650,57 +2906,6 @@ function buildCloudCodeAssistPayload(args) {
|
|
|
2650
2906
|
}
|
|
2651
2907
|
};
|
|
2652
2908
|
}
|
|
2653
|
-
function accumulateCcaChunks(chunks) {
|
|
2654
|
-
let text = "";
|
|
2655
|
-
const toolCalls = [];
|
|
2656
|
-
let usage;
|
|
2657
|
-
for (const chunk of chunks) {
|
|
2658
|
-
if (!chunk || typeof chunk !== "object") continue;
|
|
2659
|
-
const response = "response" in chunk && chunk.response && typeof chunk.response === "object" ? chunk.response : chunk;
|
|
2660
|
-
if ("usageMetadata" in response && response.usageMetadata && typeof response.usageMetadata === "object") {
|
|
2661
|
-
const meta = response.usageMetadata;
|
|
2662
|
-
const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
|
|
2663
|
-
const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
|
|
2664
|
-
const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
|
|
2665
|
-
usage = {
|
|
2666
|
-
prompt_tokens: prompt,
|
|
2667
|
-
completion_tokens: candidates2,
|
|
2668
|
-
total_tokens: total
|
|
2669
|
-
};
|
|
2670
|
-
}
|
|
2671
|
-
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2672
|
-
for (const candidate of candidates) {
|
|
2673
|
-
if (!candidate || typeof candidate !== "object" || !("content" in candidate)) continue;
|
|
2674
|
-
const content = candidate.content;
|
|
2675
|
-
if (!content || typeof content !== "object" || !("parts" in content)) continue;
|
|
2676
|
-
const parts = content.parts;
|
|
2677
|
-
if (!Array.isArray(parts)) continue;
|
|
2678
|
-
for (const part of parts) {
|
|
2679
|
-
if (!part || typeof part !== "object") continue;
|
|
2680
|
-
const partSignature = part.thoughtSignature;
|
|
2681
|
-
if ("text" in part && typeof part.text === "string") {
|
|
2682
|
-
const piece = part.text;
|
|
2683
|
-
if (!part.thought) {
|
|
2684
|
-
text += piece;
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
if ("functionCall" in part && part.functionCall) {
|
|
2688
|
-
const call = part.functionCall;
|
|
2689
|
-
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2690
|
-
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2691
|
-
const argsObj = asRecordOrEmpty(call.args);
|
|
2692
|
-
toolCalls.push({
|
|
2693
|
-
id,
|
|
2694
|
-
type: "function",
|
|
2695
|
-
function: { name, arguments: JSON.stringify(argsObj) },
|
|
2696
|
-
...typeof partSignature === "string" && partSignature ? { thought_signature: partSignature } : {}
|
|
2697
|
-
});
|
|
2698
|
-
}
|
|
2699
|
-
}
|
|
2700
|
-
}
|
|
2701
|
-
}
|
|
2702
|
-
return { text, toolCalls, usage };
|
|
2703
|
-
}
|
|
2704
2909
|
async function readSseJsonChunks(response) {
|
|
2705
2910
|
return readSseDataValues(response, parseSseDataLineJson);
|
|
2706
2911
|
}
|
|
@@ -2725,7 +2930,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
|
|
|
2725
2930
|
};
|
|
2726
2931
|
}
|
|
2727
2932
|
const chunks = await readSseJsonChunks(response);
|
|
2728
|
-
const { text, toolCalls, usage } =
|
|
2933
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
2729
2934
|
const message = {
|
|
2730
2935
|
role: "assistant",
|
|
2731
2936
|
content: text || null
|
|
@@ -2761,28 +2966,94 @@ var CLAUDE_CODE_IDENTITY_PATTERNS = [
|
|
|
2761
2966
|
CLAUDE_CODE_SYSTEM_INSTRUCTION,
|
|
2762
2967
|
"You are Claude Code"
|
|
2763
2968
|
];
|
|
2969
|
+
var REASONING_EFFORT_TO_BUDGET = {
|
|
2970
|
+
minimal: 2048,
|
|
2971
|
+
low: 4096,
|
|
2972
|
+
medium: 8192,
|
|
2973
|
+
high: 16384,
|
|
2974
|
+
xhigh: 32e3,
|
|
2975
|
+
max: 32e3
|
|
2976
|
+
};
|
|
2977
|
+
function resolveThinkingBudget(effort) {
|
|
2978
|
+
if (!effort) return void 0;
|
|
2979
|
+
const normalized = effort.toLowerCase();
|
|
2980
|
+
if (normalized === "none" || normalized === "off") return void 0;
|
|
2981
|
+
return REASONING_EFFORT_TO_BUDGET[normalized];
|
|
2982
|
+
}
|
|
2983
|
+
var DEFAULT_THINKING_EFFORT = "medium";
|
|
2984
|
+
var DEFAULT_ENABLED_BUDGET = 8192;
|
|
2985
|
+
var DEFAULT_ENABLE_THINKING_BUDGET = 8e3;
|
|
2986
|
+
var ANTHROPIC_EFFORT_ALIASES = { minimal: "low" };
|
|
2987
|
+
function resolveThinkingSpec(input) {
|
|
2988
|
+
const { model, maxTokens } = input;
|
|
2989
|
+
const normalizedEffort = input.reasoningEffort?.toLowerCase();
|
|
2990
|
+
const effortDisabled = normalizedEffort === "none" || normalizedEffort === "off";
|
|
2991
|
+
const effectiveEffort = normalizedEffort !== void 0 && !effortDisabled ? ANTHROPIC_EFFORT_ALIASES[normalizedEffort] ?? normalizedEffort : DEFAULT_THINKING_EFFORT;
|
|
2992
|
+
let thinkingBlock;
|
|
2993
|
+
let outputConfig;
|
|
2994
|
+
let finalMaxTokens = maxTokens;
|
|
2995
|
+
let finalTemperature = input.temperature;
|
|
2996
|
+
if (isAdaptiveThinkingModelId(model)) {
|
|
2997
|
+
if (effortDisabled) {
|
|
2998
|
+
thinkingBlock = { type: "disabled" };
|
|
2999
|
+
} else {
|
|
3000
|
+
thinkingBlock = { type: "adaptive", display: "summarized" };
|
|
3001
|
+
outputConfig = { effort: effectiveEffort };
|
|
3002
|
+
}
|
|
3003
|
+
} else {
|
|
3004
|
+
const injected = input.injectedThinking;
|
|
3005
|
+
const injectedBudget = injected?.type === "enabled" && typeof injected.budget_tokens === "number" ? injected.budget_tokens : void 0;
|
|
3006
|
+
const effortBudget = resolveThinkingBudget(input.reasoningEffort);
|
|
3007
|
+
const fallbackBudget = input.reasoningEffort === void 0 ? injectedBudget ?? (input.enableThinking === true ? typeof input.thinkingBudget === "number" ? input.thinkingBudget : DEFAULT_ENABLE_THINKING_BUDGET : DEFAULT_ENABLED_BUDGET) : void 0;
|
|
3008
|
+
const thinkingBudget = effortBudget ?? fallbackBudget;
|
|
3009
|
+
if (thinkingBudget !== void 0) {
|
|
3010
|
+
thinkingBlock = { type: "enabled", budget_tokens: thinkingBudget };
|
|
3011
|
+
finalMaxTokens = Math.max(maxTokens, thinkingBudget + 1);
|
|
3012
|
+
finalTemperature = 1;
|
|
3013
|
+
}
|
|
3014
|
+
}
|
|
3015
|
+
return {
|
|
3016
|
+
thinkingBlock,
|
|
3017
|
+
outputConfig,
|
|
3018
|
+
maxTokens: finalMaxTokens,
|
|
3019
|
+
temperature: finalTemperature
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
2764
3022
|
function stringValue(value) {
|
|
2765
3023
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2766
3024
|
}
|
|
3025
|
+
function isCacheControl(value) {
|
|
3026
|
+
return Boolean(
|
|
3027
|
+
value && typeof value === "object" && !Array.isArray(value) && typeof value.type === "string"
|
|
3028
|
+
);
|
|
3029
|
+
}
|
|
2767
3030
|
function toAnthropicContent(content) {
|
|
2768
|
-
if (typeof content === "string")
|
|
3031
|
+
if (typeof content === "string") {
|
|
3032
|
+
return content.length > 0 ? [{ type: "text", text: content }] : [];
|
|
3033
|
+
}
|
|
2769
3034
|
if (!Array.isArray(content)) return [];
|
|
2770
3035
|
const blocks = [];
|
|
2771
3036
|
for (const raw of content) {
|
|
2772
3037
|
if (!raw || typeof raw !== "object") continue;
|
|
2773
3038
|
const part = raw;
|
|
2774
3039
|
if ((part.type === "text" || part.type === "input_text") && typeof part.text === "string") {
|
|
2775
|
-
|
|
3040
|
+
if (part.text.length > 0) {
|
|
3041
|
+
const block2 = { type: "text", text: part.text };
|
|
3042
|
+
if (isCacheControl(part.cache_control)) block2.cache_control = part.cache_control;
|
|
3043
|
+
blocks.push(block2);
|
|
3044
|
+
}
|
|
2776
3045
|
continue;
|
|
2777
3046
|
}
|
|
2778
3047
|
if (part.type !== "image_url") continue;
|
|
2779
3048
|
const imageUrl = typeof part.image_url === "string" ? part.image_url : stringValue(part.image_url?.url);
|
|
2780
3049
|
if (!imageUrl) continue;
|
|
2781
3050
|
const dataMatch = imageUrl.match(/^data:([^;,]+);base64,(.+)$/s);
|
|
2782
|
-
|
|
3051
|
+
const block = {
|
|
2783
3052
|
type: "image",
|
|
2784
3053
|
source: dataMatch ? { type: "base64", media_type: dataMatch[1], data: dataMatch[2] } : { type: "url", url: imageUrl }
|
|
2785
|
-
}
|
|
3054
|
+
};
|
|
3055
|
+
if (isCacheControl(part.cache_control)) block.cache_control = part.cache_control;
|
|
3056
|
+
blocks.push(block);
|
|
2786
3057
|
}
|
|
2787
3058
|
return blocks;
|
|
2788
3059
|
}
|
|
@@ -2816,7 +3087,15 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2816
3087
|
const message = raw;
|
|
2817
3088
|
const role = String(message.role ?? "");
|
|
2818
3089
|
if (role === "system" || role === "developer") {
|
|
2819
|
-
|
|
3090
|
+
const stablePrefixChars = Number(message.stable_prefix_chars);
|
|
3091
|
+
if (typeof message.content === "string" && Number.isFinite(stablePrefixChars) && stablePrefixChars > 0 && stablePrefixChars <= message.content.length) {
|
|
3092
|
+
const stable = message.content.slice(0, stablePrefixChars);
|
|
3093
|
+
const dynamic = message.content.slice(stablePrefixChars);
|
|
3094
|
+
system.push({ type: "text", text: stable, cache_control: { type: "ephemeral" } });
|
|
3095
|
+
if (dynamic) system.push({ type: "text", text: dynamic });
|
|
3096
|
+
} else {
|
|
3097
|
+
system.push(...toAnthropicContent(message.content));
|
|
3098
|
+
}
|
|
2820
3099
|
continue;
|
|
2821
3100
|
}
|
|
2822
3101
|
if (role === "tool") {
|
|
@@ -2858,6 +3137,9 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2858
3137
|
if (!hasClaudeCodeIdentity(system)) {
|
|
2859
3138
|
system.unshift({ type: "text", text: CLAUDE_CODE_SYSTEM_INSTRUCTION });
|
|
2860
3139
|
}
|
|
3140
|
+
if (system.length > 0 && !system.some((block) => isCacheControl(block.cache_control))) {
|
|
3141
|
+
system[system.length - 1].cache_control = { type: "ephemeral" };
|
|
3142
|
+
}
|
|
2861
3143
|
const tools = Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools.flatMap((raw) => {
|
|
2862
3144
|
if (!raw || typeof raw !== "object") return [];
|
|
2863
3145
|
const fn = raw.function;
|
|
@@ -2872,14 +3154,39 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2872
3154
|
const model = stringValue(args.openAiBody.model) ?? args.agentConfig.model ?? "claude-sonnet-5";
|
|
2873
3155
|
const maxTokensRaw = args.openAiBody.max_completion_tokens ?? args.openAiBody.max_tokens ?? args.agentConfig.max_tokens;
|
|
2874
3156
|
const maxTokens = typeof maxTokensRaw === "number" && Number.isFinite(maxTokensRaw) ? Math.max(1, Math.floor(maxTokensRaw)) : 8192;
|
|
3157
|
+
const reasoningEffort = stringValue(args.openAiBody.reasoning_effort) ?? stringValue(args.agentConfig.reasoning_effort);
|
|
3158
|
+
const spec = resolveThinkingSpec({
|
|
3159
|
+
model,
|
|
3160
|
+
reasoningEffort,
|
|
3161
|
+
maxTokens,
|
|
3162
|
+
temperature: typeof args.openAiBody.temperature === "number" ? args.openAiBody.temperature : args.agentConfig.temperature,
|
|
3163
|
+
injectedThinking: args.openAiBody.thinking,
|
|
3164
|
+
enableThinking: args.agentConfig.enableThinking,
|
|
3165
|
+
thinkingBudget: args.agentConfig.thinkingBudget
|
|
3166
|
+
});
|
|
3167
|
+
const { thinkingBlock, outputConfig } = spec;
|
|
3168
|
+
const finalMaxTokens = spec.maxTokens;
|
|
3169
|
+
const finalTemperature = spec.temperature;
|
|
3170
|
+
if (messages.length > 0) {
|
|
3171
|
+
const lastMessage = messages[messages.length - 1];
|
|
3172
|
+
const content = Array.isArray(lastMessage.content) ? lastMessage.content : [];
|
|
3173
|
+
if (content.length > 0) {
|
|
3174
|
+
const lastBlock = content[content.length - 1];
|
|
3175
|
+
if (!isCacheControl(lastBlock.cache_control)) {
|
|
3176
|
+
lastBlock.cache_control = { type: "ephemeral" };
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
2875
3180
|
return {
|
|
2876
3181
|
model,
|
|
2877
3182
|
messages,
|
|
2878
|
-
max_tokens:
|
|
3183
|
+
max_tokens: finalMaxTokens,
|
|
2879
3184
|
stream: false,
|
|
3185
|
+
...thinkingBlock ? { thinking: thinkingBlock } : {},
|
|
3186
|
+
...outputConfig ? { output_config: outputConfig } : {},
|
|
2880
3187
|
...system.length > 0 ? { system } : {},
|
|
2881
3188
|
...tools.length > 0 ? { tools } : {},
|
|
2882
|
-
...typeof
|
|
3189
|
+
...typeof finalTemperature === "number" ? { temperature: finalTemperature } : {},
|
|
2883
3190
|
...typeof args.openAiBody.top_p === "number" ? { top_p: args.openAiBody.top_p } : {}
|
|
2884
3191
|
};
|
|
2885
3192
|
}
|
|
@@ -2903,6 +3210,8 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
2903
3210
|
}
|
|
2904
3211
|
const usage = payload.usage ?? {};
|
|
2905
3212
|
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);
|
|
3213
|
+
const cacheCreationInputTokens = typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0;
|
|
3214
|
+
const cacheReadInputTokens = typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0;
|
|
2906
3215
|
const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : 0;
|
|
2907
3216
|
const stopReason = String(payload.stop_reason ?? "");
|
|
2908
3217
|
const message = { role: "assistant", content: text || null };
|
|
@@ -2918,9 +3227,16 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
2918
3227
|
finish_reason: toolCalls.length > 0 || stopReason === "tool_use" ? "tool_calls" : stopReason === "max_tokens" ? "length" : "stop"
|
|
2919
3228
|
}],
|
|
2920
3229
|
usage: {
|
|
3230
|
+
// prompt_tokens/input_tokens are total input, including cache read/write.
|
|
3231
|
+
// Preserve Anthropic's components so normalization and billing can apply
|
|
3232
|
+
// the correct cache prices without double-counting them.
|
|
2921
3233
|
prompt_tokens: inputTokens,
|
|
3234
|
+
input_tokens: inputTokens,
|
|
2922
3235
|
completion_tokens: outputTokens,
|
|
2923
|
-
|
|
3236
|
+
output_tokens: outputTokens,
|
|
3237
|
+
total_tokens: inputTokens + outputTokens,
|
|
3238
|
+
cache_creation_input_tokens: cacheCreationInputTokens,
|
|
3239
|
+
cache_read_input_tokens: cacheReadInputTokens
|
|
2924
3240
|
}
|
|
2925
3241
|
};
|
|
2926
3242
|
}
|
|
@@ -8995,6 +9311,262 @@ function isCursorOAuthAgent(agent) {
|
|
|
8995
9311
|
return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
|
|
8996
9312
|
}
|
|
8997
9313
|
|
|
9314
|
+
// packages/agent-runtime/codexResponsesProvider.ts
|
|
9315
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
9316
|
+
var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
|
|
9317
|
+
var CODEX_CLIENT_VERSION = "0.144.1";
|
|
9318
|
+
var CODEX_ORIGINATOR = "codex_cli_rs";
|
|
9319
|
+
var CODEX_OPENAI_BETA = "responses=experimental";
|
|
9320
|
+
var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
|
|
9321
|
+
var CODEX_INSTALLATION_ID = randomUUID4();
|
|
9322
|
+
function decodeCodexAccountId(accessToken) {
|
|
9323
|
+
const parts = accessToken.split(".");
|
|
9324
|
+
if (parts.length < 2) return void 0;
|
|
9325
|
+
try {
|
|
9326
|
+
const payload = JSON.parse(
|
|
9327
|
+
Buffer.from(parts[1], "base64").toString("utf8")
|
|
9328
|
+
);
|
|
9329
|
+
const claim = payload[OPENAI_AUTH_CLAIM];
|
|
9330
|
+
const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
|
|
9331
|
+
return typeof value === "string" && value ? value : void 0;
|
|
9332
|
+
} catch {
|
|
9333
|
+
return void 0;
|
|
9334
|
+
}
|
|
9335
|
+
}
|
|
9336
|
+
function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
|
|
9337
|
+
const sessionId = randomUUID4();
|
|
9338
|
+
const threadId = randomUUID4();
|
|
9339
|
+
const windowId = randomUUID4();
|
|
9340
|
+
const turnId = randomUUID4();
|
|
9341
|
+
const turnMetadata = {
|
|
9342
|
+
installation_id: installationId,
|
|
9343
|
+
session_id: sessionId,
|
|
9344
|
+
thread_id: threadId,
|
|
9345
|
+
turn_id: turnId,
|
|
9346
|
+
window_id: windowId,
|
|
9347
|
+
request_kind: "turn",
|
|
9348
|
+
turn_started_at_unix_ms: Date.now()
|
|
9349
|
+
};
|
|
9350
|
+
const turnMetadataJson = JSON.stringify(turnMetadata);
|
|
9351
|
+
return {
|
|
9352
|
+
sessionId,
|
|
9353
|
+
threadId,
|
|
9354
|
+
windowId,
|
|
9355
|
+
turnId,
|
|
9356
|
+
turnMetadataJson,
|
|
9357
|
+
clientMetadata: {
|
|
9358
|
+
"x-codex-installation-id": installationId,
|
|
9359
|
+
session_id: sessionId,
|
|
9360
|
+
thread_id: threadId,
|
|
9361
|
+
"x-codex-window-id": windowId,
|
|
9362
|
+
turn_id: turnId,
|
|
9363
|
+
"x-codex-turn-metadata": turnMetadataJson
|
|
9364
|
+
}
|
|
9365
|
+
};
|
|
9366
|
+
}
|
|
9367
|
+
function buildCodexCompatibilityHeaders(identity, accountId) {
|
|
9368
|
+
return {
|
|
9369
|
+
Authorization: "",
|
|
9370
|
+
// filled by caller with bearer token
|
|
9371
|
+
"Content-Type": "application/json",
|
|
9372
|
+
Accept: "text/event-stream",
|
|
9373
|
+
"chatgpt-account-id": accountId,
|
|
9374
|
+
"OpenAI-Beta": CODEX_OPENAI_BETA,
|
|
9375
|
+
originator: CODEX_ORIGINATOR,
|
|
9376
|
+
version: CODEX_CLIENT_VERSION,
|
|
9377
|
+
session_id: identity.sessionId,
|
|
9378
|
+
conversation_id: identity.sessionId,
|
|
9379
|
+
"x-client-request-id": identity.sessionId,
|
|
9380
|
+
"session-id": identity.sessionId,
|
|
9381
|
+
"thread-id": identity.threadId,
|
|
9382
|
+
"x-codex-window-id": identity.windowId,
|
|
9383
|
+
"x-codex-turn-metadata": identity.turnMetadataJson
|
|
9384
|
+
};
|
|
9385
|
+
}
|
|
9386
|
+
function collectInstructions(messages, agentPrompt) {
|
|
9387
|
+
const systemTexts = [];
|
|
9388
|
+
const prompt = agentPrompt?.trim();
|
|
9389
|
+
if (prompt) systemTexts.push(prompt);
|
|
9390
|
+
for (const raw of messages) {
|
|
9391
|
+
if (!raw || typeof raw !== "object") continue;
|
|
9392
|
+
const role = String(raw.role ?? "");
|
|
9393
|
+
if (role !== "system" && role !== "developer") continue;
|
|
9394
|
+
const content = raw.content;
|
|
9395
|
+
const stringContent = asOptionalTrimmedString(content);
|
|
9396
|
+
if (stringContent) {
|
|
9397
|
+
systemTexts.push(stringContent);
|
|
9398
|
+
} else if (Array.isArray(content)) {
|
|
9399
|
+
const text = content.filter(
|
|
9400
|
+
(p) => !!p && p.type === "text"
|
|
9401
|
+
).map((p) => p.text).join("\n").trim();
|
|
9402
|
+
if (text) systemTexts.push(text);
|
|
9403
|
+
}
|
|
9404
|
+
}
|
|
9405
|
+
return systemTexts.join("\n\n");
|
|
9406
|
+
}
|
|
9407
|
+
function collectStableInstructions(messages, fallbackPrompt) {
|
|
9408
|
+
const systemTexts = [];
|
|
9409
|
+
if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
|
|
9410
|
+
for (const raw of messages) {
|
|
9411
|
+
if (!raw || typeof raw !== "object") continue;
|
|
9412
|
+
const message = raw;
|
|
9413
|
+
const role = String(message.role ?? "");
|
|
9414
|
+
if (role !== "system" && role !== "developer") continue;
|
|
9415
|
+
if (typeof message.content === "string") {
|
|
9416
|
+
const boundary = Number(message.stable_prefix_chars);
|
|
9417
|
+
const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
|
|
9418
|
+
if (text.trim()) systemTexts.push(text.trim());
|
|
9419
|
+
}
|
|
9420
|
+
}
|
|
9421
|
+
return systemTexts.join("\n\n");
|
|
9422
|
+
}
|
|
9423
|
+
function stablePromptCacheKey(parts) {
|
|
9424
|
+
const value = JSON.stringify(parts);
|
|
9425
|
+
let hash = 2166136261;
|
|
9426
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
9427
|
+
hash ^= value.charCodeAt(index);
|
|
9428
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
9429
|
+
}
|
|
9430
|
+
return `nolo-codex-${hash.toString(16).padStart(8, "0")}`;
|
|
9431
|
+
}
|
|
9432
|
+
function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
|
|
9433
|
+
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
9434
|
+
const nonSystem = rawMessages.filter((m) => {
|
|
9435
|
+
const role = m && typeof m === "object" ? String(m.role) : "";
|
|
9436
|
+
return role !== "system" && role !== "developer";
|
|
9437
|
+
});
|
|
9438
|
+
const input = convertMessagesToResponsesInput(nonSystem);
|
|
9439
|
+
const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
|
|
9440
|
+
const stableInstructions = collectStableInstructions(rawMessages, args.agentConfig.prompt);
|
|
9441
|
+
const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
|
|
9442
|
+
const tools = toResponsesTools(
|
|
9443
|
+
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
9444
|
+
);
|
|
9445
|
+
const body = {
|
|
9446
|
+
model,
|
|
9447
|
+
input,
|
|
9448
|
+
stream: true,
|
|
9449
|
+
store: false,
|
|
9450
|
+
// Keep routing stable across turns and request UUIDs. Growing input/history
|
|
9451
|
+
// is intentionally excluded; only stable request-prefix material belongs.
|
|
9452
|
+
prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []]),
|
|
9453
|
+
client_metadata: identity.clientMetadata
|
|
9454
|
+
};
|
|
9455
|
+
if (instructions) body.instructions = instructions;
|
|
9456
|
+
if (tools && tools.length > 0) {
|
|
9457
|
+
body.tools = tools;
|
|
9458
|
+
body.tool_choice = "auto";
|
|
9459
|
+
body.parallel_tool_calls = true;
|
|
9460
|
+
}
|
|
9461
|
+
return body;
|
|
9462
|
+
}
|
|
9463
|
+
function aggregateResponsesStream(events) {
|
|
9464
|
+
let text = "";
|
|
9465
|
+
const toolCalls = [];
|
|
9466
|
+
let usage;
|
|
9467
|
+
for (const ev of events) {
|
|
9468
|
+
const type = String(ev.type ?? "");
|
|
9469
|
+
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
9470
|
+
text += ev.delta;
|
|
9471
|
+
continue;
|
|
9472
|
+
}
|
|
9473
|
+
if (type === "response.output_item.done") {
|
|
9474
|
+
const item = ev.item;
|
|
9475
|
+
if (item && item.type === "function_call") {
|
|
9476
|
+
const name = typeof item.name === "string" ? item.name : "";
|
|
9477
|
+
if (name) {
|
|
9478
|
+
toolCalls.push({
|
|
9479
|
+
id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
|
|
9480
|
+
type: "function",
|
|
9481
|
+
function: {
|
|
9482
|
+
name,
|
|
9483
|
+
arguments: typeof item.arguments === "string" ? item.arguments : "{}"
|
|
9484
|
+
}
|
|
9485
|
+
});
|
|
9486
|
+
}
|
|
9487
|
+
}
|
|
9488
|
+
continue;
|
|
9489
|
+
}
|
|
9490
|
+
if (type === "response.completed") {
|
|
9491
|
+
const response = ev.response;
|
|
9492
|
+
const u = response?.usage;
|
|
9493
|
+
if (u) {
|
|
9494
|
+
const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
|
|
9495
|
+
const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
|
|
9496
|
+
const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
|
|
9497
|
+
usage = {
|
|
9498
|
+
prompt_tokens: prompt,
|
|
9499
|
+
completion_tokens: completion,
|
|
9500
|
+
total_tokens: total
|
|
9501
|
+
};
|
|
9502
|
+
}
|
|
9503
|
+
}
|
|
9504
|
+
}
|
|
9505
|
+
return { text, toolCalls, usage };
|
|
9506
|
+
}
|
|
9507
|
+
async function readSseEvents(response) {
|
|
9508
|
+
return readSseDataValues(response, (line) => {
|
|
9509
|
+
const ev = parseSseDataLineObject(line);
|
|
9510
|
+
return ev && !Array.isArray(ev) ? ev : null;
|
|
9511
|
+
});
|
|
9512
|
+
}
|
|
9513
|
+
async function fetchCodexResponsesCompletion(args) {
|
|
9514
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
9515
|
+
const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
|
|
9516
|
+
if (!accountId) {
|
|
9517
|
+
return {
|
|
9518
|
+
status: 401,
|
|
9519
|
+
body: {
|
|
9520
|
+
error: {
|
|
9521
|
+
message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
|
|
9522
|
+
}
|
|
9523
|
+
}
|
|
9524
|
+
};
|
|
9525
|
+
}
|
|
9526
|
+
const identity = createCodexRequestIdentity();
|
|
9527
|
+
const body = buildCodexRequestBody(args, identity);
|
|
9528
|
+
const headers = buildCodexCompatibilityHeaders(identity, accountId);
|
|
9529
|
+
headers.Authorization = `Bearer ${args.accessToken}`;
|
|
9530
|
+
const response = await fetchImpl(CODEX_RESPONSES_URL, {
|
|
9531
|
+
method: "POST",
|
|
9532
|
+
headers,
|
|
9533
|
+
body: JSON.stringify(body),
|
|
9534
|
+
signal: args.signal
|
|
9535
|
+
});
|
|
9536
|
+
if (!response.ok) {
|
|
9537
|
+
const errorText = await response.text();
|
|
9538
|
+
return {
|
|
9539
|
+
status: response.status,
|
|
9540
|
+
body: { error: { message: errorText || response.statusText } }
|
|
9541
|
+
};
|
|
9542
|
+
}
|
|
9543
|
+
const events = await readSseEvents(response);
|
|
9544
|
+
const { text, toolCalls, usage } = aggregateResponsesStream(events);
|
|
9545
|
+
const message = {
|
|
9546
|
+
role: "assistant",
|
|
9547
|
+
content: text || null
|
|
9548
|
+
};
|
|
9549
|
+
if (toolCalls.length > 0) message.tool_calls = toolCalls;
|
|
9550
|
+
return {
|
|
9551
|
+
status: 200,
|
|
9552
|
+
body: {
|
|
9553
|
+
choices: [
|
|
9554
|
+
{
|
|
9555
|
+
index: 0,
|
|
9556
|
+
message,
|
|
9557
|
+
finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
|
|
9558
|
+
}
|
|
9559
|
+
],
|
|
9560
|
+
...usage ? { usage } : {}
|
|
9561
|
+
}
|
|
9562
|
+
};
|
|
9563
|
+
}
|
|
9564
|
+
function isCodexOAuthAgent(agentConfig) {
|
|
9565
|
+
if (!agentConfig) return false;
|
|
9566
|
+
const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
|
|
9567
|
+
return apiKeyRef === "chatgpt";
|
|
9568
|
+
}
|
|
9569
|
+
|
|
8998
9570
|
// packages/agent-runtime/oauthProviders.ts
|
|
8999
9571
|
var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
|
|
9000
9572
|
var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
|
|
@@ -10192,6 +10764,74 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10192
10764
|
}
|
|
10193
10765
|
};
|
|
10194
10766
|
}
|
|
10767
|
+
if (isCodexOAuthAgent(agentConfig)) {
|
|
10768
|
+
const accessToken = await apiKeyRefResolver("chatgpt");
|
|
10769
|
+
if (!accessToken) {
|
|
10770
|
+
throw new Error(
|
|
10771
|
+
'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
|
|
10772
|
+
);
|
|
10773
|
+
}
|
|
10774
|
+
const credential = readOAuthCredential("chatgpt");
|
|
10775
|
+
const accountId = credential?.accountId;
|
|
10776
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10777
|
+
agentConfig,
|
|
10778
|
+
deps.env,
|
|
10779
|
+
buildProviderOpenAiTools,
|
|
10780
|
+
additionalToolNames,
|
|
10781
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10782
|
+
);
|
|
10783
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10784
|
+
agentKey: agentConfig.key,
|
|
10785
|
+
transport: "codex-responses",
|
|
10786
|
+
provider: "openai",
|
|
10787
|
+
model: agentConfig.model ?? "gpt-5.6-sol",
|
|
10788
|
+
hasApiKey: true
|
|
10789
|
+
});
|
|
10790
|
+
return {
|
|
10791
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
10792
|
+
complete: async (messages, options) => {
|
|
10793
|
+
const result = await fetchCodexResponsesCompletion({
|
|
10794
|
+
agentConfig,
|
|
10795
|
+
accessToken,
|
|
10796
|
+
...accountId ? { accountId } : {},
|
|
10797
|
+
openAiBody: {
|
|
10798
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
10799
|
+
messages,
|
|
10800
|
+
stream: false,
|
|
10801
|
+
...tools2.length > 0 ? { tools: tools2 } : {}
|
|
10802
|
+
},
|
|
10803
|
+
fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
|
|
10804
|
+
sleep: deps.sleep,
|
|
10805
|
+
loopbackRequest
|
|
10806
|
+
})
|
|
10807
|
+
});
|
|
10808
|
+
if (result.status < 200 || result.status >= 300) {
|
|
10809
|
+
const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
|
|
10810
|
+
throw new Error(
|
|
10811
|
+
`local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
|
|
10812
|
+
);
|
|
10813
|
+
}
|
|
10814
|
+
const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
|
|
10815
|
+
const message = choice?.message ?? {};
|
|
10816
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
10817
|
+
const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
|
|
10818
|
+
if (content && options?.onTextDelta) options.onTextDelta(content);
|
|
10819
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10820
|
+
agentKey: agentConfig.key,
|
|
10821
|
+
transport: "codex-responses",
|
|
10822
|
+
ok: true,
|
|
10823
|
+
contentChars: content.length,
|
|
10824
|
+
toolCallCount: tool_calls?.length ?? 0,
|
|
10825
|
+
requestedToolNames: requestedToolNames2
|
|
10826
|
+
});
|
|
10827
|
+
return {
|
|
10828
|
+
content,
|
|
10829
|
+
...tool_calls ? { tool_calls } : {},
|
|
10830
|
+
trace: messages
|
|
10831
|
+
};
|
|
10832
|
+
}
|
|
10833
|
+
};
|
|
10834
|
+
}
|
|
10195
10835
|
if (isCursorOAuthAgent(agentConfig)) {
|
|
10196
10836
|
const accessToken = await apiKeyRefResolver("cursor");
|
|
10197
10837
|
if (!accessToken) {
|
|
@@ -10261,6 +10901,101 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10261
10901
|
}
|
|
10262
10902
|
};
|
|
10263
10903
|
}
|
|
10904
|
+
if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
|
|
10905
|
+
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10906
|
+
agentConfig,
|
|
10907
|
+
env: deps.env,
|
|
10908
|
+
apiKeyRefResolver,
|
|
10909
|
+
credentialBroker,
|
|
10910
|
+
syncFetcher
|
|
10911
|
+
});
|
|
10912
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
10913
|
+
agentConfig,
|
|
10914
|
+
deps.env,
|
|
10915
|
+
buildProviderOpenAiTools,
|
|
10916
|
+
additionalToolNames,
|
|
10917
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
10918
|
+
);
|
|
10919
|
+
if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
|
|
10920
|
+
agentConfig.provider ?? "",
|
|
10921
|
+
agentConfig.model ?? "",
|
|
10922
|
+
tools2,
|
|
10923
|
+
() => false
|
|
10924
|
+
// CLI 端不区分 image 模型
|
|
10925
|
+
)) {
|
|
10926
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
10927
|
+
agentKey: agentConfig.key,
|
|
10928
|
+
transport: "gemini-native-tool",
|
|
10929
|
+
apiSource: agentConfig.apiSource ?? null,
|
|
10930
|
+
provider: providerConfig2.provider,
|
|
10931
|
+
model: providerConfig2.model,
|
|
10932
|
+
hasApiKey: Boolean(providerConfig2.apiKey)
|
|
10933
|
+
});
|
|
10934
|
+
return {
|
|
10935
|
+
model: providerConfig2.model,
|
|
10936
|
+
complete: async (messages, options) => {
|
|
10937
|
+
const requestBody = buildGeminiGenerateContentRequest({
|
|
10938
|
+
messages,
|
|
10939
|
+
tools: tools2,
|
|
10940
|
+
maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
|
|
10941
|
+
temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
|
|
10942
|
+
attachSkipThoughtSignature: true
|
|
10943
|
+
});
|
|
10944
|
+
const model = providerConfig2.model;
|
|
10945
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
|
|
10946
|
+
logLocalRuntimeDiagnostic("provider.request.start", {
|
|
10947
|
+
agentKey: agentConfig.key,
|
|
10948
|
+
transport: "gemini-native-tool",
|
|
10949
|
+
model,
|
|
10950
|
+
messageCount: messages.length,
|
|
10951
|
+
toolCount: tools2.length,
|
|
10952
|
+
requestedToolNames: requestedToolNames2
|
|
10953
|
+
});
|
|
10954
|
+
const res = await fetchImpl(url, {
|
|
10955
|
+
method: "POST",
|
|
10956
|
+
headers: {
|
|
10957
|
+
"Content-Type": "application/json",
|
|
10958
|
+
"x-goog-api-key": providerConfig2.apiKey ?? ""
|
|
10959
|
+
},
|
|
10960
|
+
body: JSON.stringify(requestBody),
|
|
10961
|
+
signal: AbortSignal.timeout(12e4)
|
|
10962
|
+
});
|
|
10963
|
+
if (!res.ok) {
|
|
10964
|
+
const errText = await res.text();
|
|
10965
|
+
logLocalRuntimeDiagnostic("provider.request.failed", {
|
|
10966
|
+
agentKey: agentConfig.key,
|
|
10967
|
+
transport: "gemini-native-tool",
|
|
10968
|
+
status: res.status,
|
|
10969
|
+
error: errText.slice(0, 200)
|
|
10970
|
+
});
|
|
10971
|
+
throw new Error(
|
|
10972
|
+
`gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
|
|
10973
|
+
);
|
|
10974
|
+
}
|
|
10975
|
+
const chunks = await readSseDataValues(res, parseSseDataLineJson);
|
|
10976
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
10977
|
+
if (text && options?.onTextDelta) {
|
|
10978
|
+
options.onTextDelta(text);
|
|
10979
|
+
}
|
|
10980
|
+
const result = {
|
|
10981
|
+
content: text,
|
|
10982
|
+
model,
|
|
10983
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
10984
|
+
...usage ? { usage } : {},
|
|
10985
|
+
trace: messages
|
|
10986
|
+
};
|
|
10987
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
10988
|
+
agentKey: agentConfig.key,
|
|
10989
|
+
transport: "gemini-native-tool",
|
|
10990
|
+
ok: true,
|
|
10991
|
+
contentChars: text.length,
|
|
10992
|
+
toolCallCount: toolCalls.length
|
|
10993
|
+
});
|
|
10994
|
+
return result;
|
|
10995
|
+
}
|
|
10996
|
+
};
|
|
10997
|
+
}
|
|
10998
|
+
}
|
|
10264
10999
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
10265
11000
|
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10266
11001
|
agentConfig,
|
|
@@ -10321,47 +11056,20 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10321
11056
|
},
|
|
10322
11057
|
{
|
|
10323
11058
|
sleep: deps.sleep,
|
|
10324
|
-
loopbackRequest
|
|
11059
|
+
loopbackRequest,
|
|
11060
|
+
// auto 档位转发 nolo.chat 时,网关层 502(server: Caddy、空 body)
|
|
11061
|
+
// 意味着请求根本没到 Bun 上游,provider 未受理,重试安全。
|
|
11062
|
+
// 与 429/503 同口径:不会重复计费/重复生成。
|
|
11063
|
+
retryableStatuses: /* @__PURE__ */ new Set([429, 502, 503]),
|
|
11064
|
+
onRetry: deps.activityReporter ? ({ attempt, maxAttempts, delayMs }) => {
|
|
11065
|
+
deps.activityReporter(
|
|
11066
|
+
`\u81EA\u52A8\u91CD\u8BD5 ${attempt}/${maxAttempts} \xB7 ${Math.ceil(delayMs / 1e3)}s`
|
|
11067
|
+
);
|
|
11068
|
+
} : void 0
|
|
10325
11069
|
}
|
|
10326
11070
|
);
|
|
10327
|
-
let responseProviderConfig = providerConfig2;
|
|
10328
|
-
let firstErrorRaw;
|
|
10329
|
-
if (!res.ok) {
|
|
10330
|
-
firstErrorRaw = await res.text().catch(() => "");
|
|
10331
|
-
const fallbackProviderConfig = resolveLegacyDeepSeekProxyChatFallback({
|
|
10332
|
-
providerConfig: providerConfig2,
|
|
10333
|
-
status: res.status,
|
|
10334
|
-
raw: firstErrorRaw
|
|
10335
|
-
});
|
|
10336
|
-
if (fallbackProviderConfig) {
|
|
10337
|
-
responseProviderConfig = fallbackProviderConfig;
|
|
10338
|
-
const fallbackRequest = buildPlatformChatCompletionRequest({
|
|
10339
|
-
providerConfig: fallbackProviderConfig,
|
|
10340
|
-
messages,
|
|
10341
|
-
tools: tools2,
|
|
10342
|
-
stream: false
|
|
10343
|
-
});
|
|
10344
|
-
logLocalRuntimeDiagnostic("provider.request.compatibility-fallback", {
|
|
10345
|
-
agentKey: agentConfig.key,
|
|
10346
|
-
provider: providerConfig2.provider,
|
|
10347
|
-
fromEndpoint: summarizeEndpoint(providerConfig2.endpoint) ?? null,
|
|
10348
|
-
toEndpoint: summarizeEndpoint(fallbackProviderConfig.endpoint) ?? null,
|
|
10349
|
-
reason: "legacy-proxy-responses-schema"
|
|
10350
|
-
});
|
|
10351
|
-
res = await fetchWithTransientRetry(
|
|
10352
|
-
fetchImpl,
|
|
10353
|
-
fallbackRequest.url,
|
|
10354
|
-
{ ...fallbackRequest.init },
|
|
10355
|
-
{
|
|
10356
|
-
sleep: deps.sleep,
|
|
10357
|
-
loopbackRequest
|
|
10358
|
-
}
|
|
10359
|
-
);
|
|
10360
|
-
firstErrorRaw = void 0;
|
|
10361
|
-
}
|
|
10362
|
-
}
|
|
10363
11071
|
if (!res.ok) {
|
|
10364
|
-
const raw2 =
|
|
11072
|
+
const raw2 = await res.text().catch(() => "");
|
|
10365
11073
|
const data2 = parsePlatformChatCompletionData(raw2);
|
|
10366
11074
|
const rawPreview = raw2.length > 200 ? `${raw2.slice(0, 200)}\u2026(${raw2.length}b)` : raw2;
|
|
10367
11075
|
const gatewayHeaders = [
|
|
@@ -10412,7 +11120,7 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10412
11120
|
});
|
|
10413
11121
|
const data = parsePlatformChatCompletionData(raw);
|
|
10414
11122
|
return parsePlatformChatCompletionResponse({
|
|
10415
|
-
providerConfig:
|
|
11123
|
+
providerConfig: providerConfig2,
|
|
10416
11124
|
data,
|
|
10417
11125
|
trace: messages
|
|
10418
11126
|
});
|
|
@@ -10542,6 +11250,7 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10542
11250
|
export {
|
|
10543
11251
|
summarizeEndpoint,
|
|
10544
11252
|
isBuiltinNoloAgentRef,
|
|
11253
|
+
parseAgentRunEvent,
|
|
10545
11254
|
parseCliLocale,
|
|
10546
11255
|
getCliLocale,
|
|
10547
11256
|
setCliLocale,
|