nolo-cli 0.16.0 → 0.18.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-AVCA2NAV.js → _executeModel-X5PCIZN6.js} +50 -44
- package/{action-F5JACQBG.js → action-LT7BRFLK.js} +10 -9
- package/{addContentAction-AQXEYRBE.js → addContentAction-PL3KKBDH.js} +9 -8
- package/{addDialogAgentAction-EJHHJZWW.js → addDialogAgentAction-FCMSKYAF.js} +8 -7
- package/{agentDeleteCommand-QW5PUMDQ.js → agentDeleteCommand-2BZDQV36.js} +32 -29
- package/{agentEmailCommands-4ORVLGVQ.js → agentEmailCommands-2QJDGRMB.js} +62 -56
- package/{agentListCommands-YWBYRTYC.js → agentListCommands-6VEPTKBI.js} +31 -28
- package/{agentMachineCommands-JSQW4FOA.js → agentMachineCommands-NVVHNWYI.js} +30 -27
- package/{agentPullCommand-6HWUT3SW.js → agentPullCommand-ZZGU5KOY.js} +4 -4
- package/{agentRecordCommands-AASIWOBT.js → agentRecordCommands-4GGRDMD4.js} +57 -51
- package/{agentRunCommand-TB5BHXUH.js → agentRunCommand-XOLQNKBZ.js} +63 -54
- package/{agentRunControl-6ADXVYMR.js → agentRunControl-Y5AFH5PQ.js} +24 -1
- package/{agentRuntimeLocal-QNPNJRVH.js → agentRuntimeLocal-7WYWCGL4.js} +25 -22
- package/{agentSlice-RUNXC62Y.js → agentSlice-EAXPGEYV.js} +9 -8
- package/appDeleteCommands-77KR2RJ4.js +127 -0
- package/appDeployCommands-K7CAHGBI.js +166 -0
- package/appDeployStatusCommands-4OEKLTBT.js +147 -0
- package/appGetCommands-VM2WDLAZ.js +122 -0
- package/appListCommands-GX6BBA6U.js +125 -0
- package/{authCommand-YFTR3347.js → authCommand-DY6UUL6O.js} +16 -9
- package/{authCommands-YXGOXNBZ.js → authCommands-XTBV7OFZ.js} +6 -5
- package/{chunk-DPAB4FQ7.js → chunk-23FZYPLC.js} +1608 -212
- package/{chunk-LPEUV5RE.js → chunk-34WPV75U.js} +23 -2
- package/{chunk-XPC5C7BK.js → chunk-3ND52WIL.js} +2 -2
- package/{chunk-SOTZ6RDN.js → chunk-3Q7WHGCB.js} +1 -1
- package/{chunk-3OIRVWXA.js → chunk-3ZX7PERL.js} +10 -1
- package/{chunk-KKY4B2Q2.js → chunk-4PWB7JRR.js} +4 -1
- package/{chunk-6N4KODMN.js → chunk-4T5F7YZQ.js} +1 -1
- package/chunk-7BUYEZ6U.js +671 -0
- package/{chunk-AS3ZQ3O2.js → chunk-7OBMZCRD.js} +1 -1
- package/{chunk-IGXREZW2.js → chunk-AHCY2S2I.js} +1 -1
- package/{chunk-QLUFR47U.js → chunk-AL2V7U3E.js} +1 -1
- package/{chunk-MTU75CZ2.js → chunk-B5TOXZAK.js} +1 -1
- package/{chunk-AUURUT6L.js → chunk-BV4VEE3W.js} +264 -424
- package/{chunk-FRV6A633.js → chunk-CZ6NYQTV.js} +13 -4
- package/{chunk-PCTUYVUM.js → chunk-DFCFMCY6.js} +10 -3
- package/{chunk-JTMNCCWF.js → chunk-DKZFOK24.js} +16 -87
- package/chunk-DL6EPNIK.js +50 -0
- package/{chunk-ZQBL7LIC.js → chunk-EDV7EBOI.js} +317 -216
- package/{chunk-IWLUTMYX.js → chunk-ELT65PZW.js} +2 -2
- package/chunk-FQZZLA3C.js +223 -0
- package/{chunk-55NSNCFM.js → chunk-FXUSIQC2.js} +1 -1
- package/{chunk-MR6ISAGB.js → chunk-G5U6LDLG.js} +6 -6
- package/chunk-GFUIQ4RY.js +136 -0
- package/{chunk-NVEWUJVX.js → chunk-HEGV7BH3.js} +1 -1
- package/{chunk-BEBNFWDU.js → chunk-HWW2M4SN.js} +3 -3
- package/{chunk-4L2OJPCU.js → chunk-I2ZJKTG5.js} +58 -8
- package/{chunk-Z5JQNBNY.js → chunk-IYEXFJPC.js} +34 -15
- package/{setDialogExtraReferencesAction-LR6MSIXO.js → chunk-JLA4FXYC.js} +2 -17
- package/chunk-KFEVY3ST.js +255 -0
- package/{chunk-4FX6NVDW.js → chunk-L4F3I4SR.js} +3 -136
- package/{chunk-XBS2WYJ2.js → chunk-LLWKHDG4.js} +1 -1
- package/{chunk-3WGLLTK4.js → chunk-LSFAWXKC.js} +100 -3
- package/{chunk-6EVITP2G.js → chunk-MHSGJW4Z.js} +2 -251
- package/{chunk-O6W2O2DA.js → chunk-MKA6QE5E.js} +6 -2
- package/{chunk-DGEYDWEZ.js → chunk-MPVYDS7I.js} +3 -3
- package/{chunk-KFHN5NGJ.js → chunk-MVQ4TBSD.js} +1 -1
- package/{chunk-AVVZUXXC.js → chunk-N54HIJVJ.js} +34 -13
- package/{chunk-EHLHSX7R.js → chunk-OK6YSWLH.js} +9 -2
- package/{chunk-33BJUVK4.js → chunk-PIZYJVHQ.js} +5 -5
- package/{chunk-RLCXU7A5.js → chunk-PJSV3IZ5.js} +1 -1
- package/{chunk-7UKFVQ5W.js → chunk-R35XMF6F.js} +126 -41
- package/{chunk-OOSFSFMA.js → chunk-R5V5G73M.js} +2 -0
- package/{chunk-S2LXHNHG.js → chunk-REA4JLBH.js} +6 -6
- package/chunk-RQN4SEKL.js +107 -0
- package/{chunk-EABWT43X.js → chunk-RVOUXDFU.js} +5 -5
- package/{chunk-NSCHQQPU.js → chunk-SCTYAHYK.js} +470 -325
- package/{chunk-JTINRTBT.js → chunk-SKDNBYZK.js} +2 -2
- package/{chunk-M43KDE25.js → chunk-SWDPIPOY.js} +2 -8
- package/{chunk-KMQPSTMJ.js → chunk-TRT4I4UD.js} +2 -2
- package/{chunk-66X4VSRC.js → chunk-UAIVG4J6.js} +42 -2
- package/{chunk-3663CXZN.js → chunk-UBHAWFQ6.js} +143 -31
- package/{chunk-YJKXGHJ6.js → chunk-UGUW3FHG.js} +4 -4
- package/{chunk-P3RIAYGG.js → chunk-V3ED5AWK.js} +3 -3
- package/chunk-V5R4NZP2.js +78 -0
- package/{chunk-4IJYA27C.js → chunk-VDXCXCXH.js} +1 -1
- package/{chunk-MYMMNKYL.js → chunk-VNAEBGDK.js} +156 -6
- package/{chunk-FY233ZFU.js → chunk-VYHDJEQD.js} +110 -192
- package/{chunk-W4NVOSFF.js → chunk-WFHXMLHZ.js} +1 -1
- package/{chunk-H33743XH.js → chunk-WJRJDX2W.js} +1 -1
- package/chunk-X4Q4UZEY.js +26 -0
- package/{chunk-RPDGJO4D.js → chunk-XHG22OEX.js} +4 -4
- package/{chunk-DVRHHFEA.js → chunk-XMLRJUU5.js} +1 -1
- package/{chunk-3S2VOMIF.js → chunk-XRZJGPFI.js} +7 -7
- package/{chunk-GSINCD4P.js → chunk-YGW4G5W5.js} +25 -12
- package/chunk-ZZ2MH7LE.js +84 -0
- package/{cliExecutor-K3F7DMRO.js → cliExecutor-DNE7TCC4.js} +2 -2
- package/codingSkills-36KN5NQT.js +48 -0
- package/{createAgentAutomationAction-FNHPSKKO.js → createAgentAutomationAction-GNFF524X.js} +20 -19
- package/{createDialogAction-TZCVQ3NU.js → createDialogAction-RB55KCLO.js} +22 -21
- package/{createPageAction-EIGZ3BKT.js → createPageAction-Y7343GLU.js} +26 -25
- package/{db-HCJ5PRB5.js → db-W3O47YGF.js} +38 -12
- package/{dbSlice-7KQH6GOU.js → dbSlice-CGSRFJN3.js} +8 -7
- package/{deleteFile-WPWVZE4B.js → deleteFile-WDZ3VM7B.js} +3 -3
- package/{dialogCommands-FO77J5DQ.js → dialogCommands-IAZK6YHQ.js} +30 -27
- package/{dialogSlice-MM5U4KE2.js → dialogSlice-UQAXF23P.js} +20 -19
- package/{docCreateCommands-I3BS3AZI.js → docCreateCommands-I2EWZGCI.js} +33 -28
- package/{docDeleteCommands-Q2OPV52P.js → docDeleteCommands-IZ45UZKG.js} +32 -27
- package/{docReadCommands-YOOFACYZ.js → docReadCommands-R6Z4QJYU.js} +31 -26
- package/{docStore-NGYQ2JTR.js → docStore-5HOJ4D7D.js} +21 -20
- package/{docUpdateCommands-2B32ITHN.js → docUpdateCommands-2LRBKQPY.js} +32 -27
- package/{fetchMessages-KTNM7QAR.js → fetchMessages-BMGVZVSE.js} +4 -3
- package/{getPricing-P4XRJRZB.js → getPricing-G7DLAST6.js} +3 -3
- package/{handleSendMessageAction-JRZWWBKP.js → handleSendMessageAction-Q4HY35WX.js} +21 -20
- package/index.js +95 -64
- package/{localDialogRead-2VRI24F4.js → localDialogRead-4H3QJFLW.js} +2 -2
- package/{localRuntimeDb-LGDF6FQP.js → localRuntimeDb-THJZGAOJ.js} +1 -1
- package/{machineCommands-WRWF2ICZ.js → machineCommands-PKBPQKTY.js} +63 -57
- package/{machineWsRunDispatch-ZX7Q3TWZ.js → machineWsRunDispatch-UZAW4OXJ.js} +55 -49
- package/{models-WQ5N4OJM.js → models-DJFSJ7SW.js} +2 -2
- package/package.json +1 -1
- package/queryRunOverlay-O4LOMMPO.js +161 -0
- package/{read-CN3TNXIP.js → read-3FMPZPER.js} +3 -3
- package/{readDocTool-WF3675ED.js → readDocTool-VSYHKK3V.js} +1 -1
- package/{readlineWorkspace-ZTGRGW46.js → readlineWorkspace-Y2RDOFZG.js} +762 -218
- package/{removeDialogAgentAction-YDHBFEGI.js → removeDialogAgentAction-OAGA2G3U.js} +10 -9
- package/{runAgentClientLoop-JZCOP7LG.js → runAgentClientLoop-NBPIKJ6J.js} +44 -38
- package/runOverlayPresentation-ZO4VCWEU.js +11 -0
- package/{runtimeDoctorCommands-THIHX2SY.js → runtimeDoctorCommands-E2OUORHK.js} +6 -6
- package/setDialogExtraReferencesAction-JZEXA5SL.js +27 -0
- package/{setPrimaryDialogAgentAction-IIVDCY5C.js → setPrimaryDialogAgentAction-4ZUQQKDG.js} +26 -17
- package/{settingSlice-O23YDK2O.js → settingSlice-7MNKHZ6R.js} +9 -8
- package/{skillDiscovery-6M2BZUFN.js → skillDiscovery-KJWT7JBU.js} +3 -3
- package/{spaceCommands-VV4GTPQK.js → spaceCommands-DHCZ7J5I.js} +31 -28
- package/{spaceSlice-DRWWZJP7.js → spaceSlice-ZXLLG3CR.js} +20 -19
- package/{streamAgentChatTurn-Y6WGATQR.js → streamAgentChatTurn-L3YW6LSB.js} +98 -57
- package/{tableCommands-3P7MJ3PF.js → tableCommands-BEQAGE4I.js} +1 -1
- package/{tools-PUNBY3AH.js → tools-ECGXR5QF.js} +33 -28
- package/{tuiSummaryLlmCaller-F64WLSAF.js → tuiSummaryLlmCaller-OMSCNHXA.js} +6 -5
- package/types-ZSTJ7MPR.js +7 -0
- package/{updateDialogTitleAction-YSR4TCMB.js → updateDialogTitleAction-HQ2EUDFT.js} +23 -22
- package/{chunk-O4BU24WZ.js → chunk-6Y7A3OQQ.js} +3 -3
- package/{chunk-CMKUBIGW.js → chunk-X7W4TNB4.js} +3 -3
- package/{localRuntimeAuthority-TEGCOWX4.js → localRuntimeAuthority-4IXJCHZ7.js} +3 -3
|
@@ -3,12 +3,11 @@ import {
|
|
|
3
3
|
refreshAntigravityOAuthToken,
|
|
4
4
|
refreshOpenAiCodexToken,
|
|
5
5
|
refreshXaiOAuthToken
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-OK6YSWLH.js";
|
|
7
7
|
import {
|
|
8
8
|
buildLocalAgentLookupKeys,
|
|
9
|
-
normalizeAgentHandle,
|
|
10
9
|
shouldReadAgentKeyRemotely
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-SWDPIPOY.js";
|
|
12
11
|
import {
|
|
13
12
|
LOCAL_CODEX_AGENT_ID,
|
|
14
13
|
LOCAL_CODEX_AGENT_KEY,
|
|
@@ -17,17 +16,17 @@ import {
|
|
|
17
16
|
} from "./chunk-VHBWHNVT.js";
|
|
18
17
|
import {
|
|
19
18
|
inferCaptureIntent
|
|
20
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-MVQ4TBSD.js";
|
|
21
20
|
import {
|
|
22
21
|
inlineImageUrlsForCustomProvider,
|
|
23
22
|
prepareTools
|
|
24
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-CZ6NYQTV.js";
|
|
25
24
|
import {
|
|
26
25
|
getAntigravityUserAgent,
|
|
27
26
|
isAntigravityOAuthAgent,
|
|
28
27
|
readAntigravityProjectId,
|
|
29
28
|
resolveAntigravityCloudCodeBaseUrl
|
|
30
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FXUSIQC2.js";
|
|
31
30
|
import {
|
|
32
31
|
FORCED_TOOLS,
|
|
33
32
|
addDefaultLightWebToolsForConfiguredAgents,
|
|
@@ -36,19 +35,13 @@ import {
|
|
|
36
35
|
applyDisabledTools,
|
|
37
36
|
applySystemBuiltinSkillFilter,
|
|
38
37
|
expandEnabledPacks,
|
|
39
|
-
formatListRunsCard,
|
|
40
|
-
formatNotFoundRunCard,
|
|
41
|
-
formatStartRunCard,
|
|
42
|
-
formatStatusRunCard,
|
|
43
|
-
formatStopRunCard,
|
|
44
38
|
readXPostFunc,
|
|
45
39
|
readXPostFunctionSchema,
|
|
46
40
|
readXhsProfileFunc,
|
|
47
41
|
readXhsProfileFunctionSchema,
|
|
48
42
|
rememberMemoryFunctionSchema,
|
|
49
|
-
resolveEffectiveEnabledPacks
|
|
50
|
-
|
|
51
|
-
} from "./chunk-ZQBL7LIC.js";
|
|
43
|
+
resolveEffectiveEnabledPacks
|
|
44
|
+
} from "./chunk-EDV7EBOI.js";
|
|
52
45
|
import {
|
|
53
46
|
createDrainExhaustedResponse,
|
|
54
47
|
isCoreDrainingBody,
|
|
@@ -58,15 +51,18 @@ import {
|
|
|
58
51
|
import {
|
|
59
52
|
normalizeDialogTitle
|
|
60
53
|
} from "./chunk-OWOHNGCN.js";
|
|
54
|
+
import {
|
|
55
|
+
getDefaultCliLocalRuntimeDb
|
|
56
|
+
} from "./chunk-WJRJDX2W.js";
|
|
61
57
|
import {
|
|
62
58
|
prepareTokenUsageData
|
|
63
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-SCTYAHYK.js";
|
|
64
60
|
import {
|
|
65
61
|
BUILTIN_TITLE_LLM_CONFIG
|
|
66
62
|
} from "./chunk-XOIF2TNF.js";
|
|
67
63
|
import {
|
|
68
64
|
fetchServerSyncedCredential
|
|
69
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-REA4JLBH.js";
|
|
70
66
|
import {
|
|
71
67
|
buildAgentRuntimeDialogWritePlan,
|
|
72
68
|
buildLocalWorkspaceOpenAiTools,
|
|
@@ -77,9 +73,10 @@ import {
|
|
|
77
73
|
executeLocalToolWithPolicy,
|
|
78
74
|
executeOpenAiCompatibleChatCompletion,
|
|
79
75
|
parseSseDataLineJson,
|
|
76
|
+
parseSseDataLineObject,
|
|
80
77
|
readOpenAiCompatibleSseCompletion,
|
|
81
78
|
resolveOpenAiCompatibleProviderConfig
|
|
82
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-R35XMF6F.js";
|
|
83
80
|
import {
|
|
84
81
|
buildPlatformChatCompletionRequest,
|
|
85
82
|
canUsePlatformChatProvider,
|
|
@@ -88,25 +85,27 @@ import {
|
|
|
88
85
|
readSseDataValues,
|
|
89
86
|
resolvePlatformChatProviderConfig,
|
|
90
87
|
shouldUsePlatformChatProvider
|
|
91
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-N54HIJVJ.js";
|
|
92
89
|
import {
|
|
93
90
|
resolveAgentRuntimeConfigFromRecord
|
|
94
91
|
} from "./chunk-OIQPORYI.js";
|
|
95
92
|
import {
|
|
96
|
-
parseToolArgumentsJson,
|
|
97
93
|
summarizeToolArguments
|
|
98
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-YGW4G5W5.js";
|
|
95
|
+
import {
|
|
96
|
+
convertMessagesToResponsesInput,
|
|
97
|
+
toResponsesTools
|
|
98
|
+
} from "./chunk-KFEVY3ST.js";
|
|
99
99
|
import {
|
|
100
100
|
resolvePlatformAuthToken
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-MHSGJW4Z.js";
|
|
102
102
|
import {
|
|
103
103
|
buildLoadSkillExecutor,
|
|
104
104
|
buildNoloWorkspaceCliToolExecutors,
|
|
105
105
|
buildNoloWorkspaceOpenAiTools,
|
|
106
|
-
canonicalizeToolNames,
|
|
107
106
|
parseNoloWorkspaceToolArguments,
|
|
108
107
|
resolveRuntimeToolSurfaceForAgent
|
|
109
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-DKZFOK24.js";
|
|
110
109
|
import {
|
|
111
110
|
clipCompactText
|
|
112
111
|
} from "./chunk-5MMAK75Q.js";
|
|
@@ -122,6 +121,15 @@ import {
|
|
|
122
121
|
readOAuthCredential,
|
|
123
122
|
resolveFreshAccessToken
|
|
124
123
|
} from "./chunk-JZPBVBIY.js";
|
|
124
|
+
import {
|
|
125
|
+
isAdaptiveThinkingModelId
|
|
126
|
+
} from "./chunk-UAIVG4J6.js";
|
|
127
|
+
import {
|
|
128
|
+
toErrorMessage
|
|
129
|
+
} from "./chunk-HNMXYYJR.js";
|
|
130
|
+
import {
|
|
131
|
+
canonicalizeToolNames
|
|
132
|
+
} from "./chunk-ZZ2MH7LE.js";
|
|
125
133
|
import {
|
|
126
134
|
compactWhitespace
|
|
127
135
|
} from "./chunk-DWLEOOGR.js";
|
|
@@ -129,22 +137,29 @@ import {
|
|
|
129
137
|
checkStaleRun,
|
|
130
138
|
finalizeRunRecord,
|
|
131
139
|
findRunRecord,
|
|
132
|
-
|
|
140
|
+
gcRunRecords,
|
|
141
|
+
queryRunRecords,
|
|
133
142
|
spawnLocalBackgroundRun
|
|
134
|
-
} from "./chunk-
|
|
143
|
+
} from "./chunk-VNAEBGDK.js";
|
|
144
|
+
import {
|
|
145
|
+
TASK_PREVIEW_MAX,
|
|
146
|
+
formatListRunsCard,
|
|
147
|
+
formatNotFoundRunCard,
|
|
148
|
+
formatStartRunCard,
|
|
149
|
+
formatStatusRunCard,
|
|
150
|
+
formatStopRunCard,
|
|
151
|
+
isAgentNameFallback,
|
|
152
|
+
isAgentRunTerminalStatus,
|
|
153
|
+
resolveRunLabel,
|
|
154
|
+
shortRunId
|
|
155
|
+
} from "./chunk-FQZZLA3C.js";
|
|
135
156
|
import {
|
|
136
157
|
CliProviderQuotaError,
|
|
137
158
|
executeCli
|
|
138
|
-
} from "./chunk-
|
|
159
|
+
} from "./chunk-X7W4TNB4.js";
|
|
139
160
|
import {
|
|
140
161
|
buildCliPrompt
|
|
141
162
|
} from "./chunk-ATNTHIZI.js";
|
|
142
|
-
import {
|
|
143
|
-
toErrorMessage
|
|
144
|
-
} from "./chunk-HNMXYYJR.js";
|
|
145
|
-
import {
|
|
146
|
-
getDefaultCliLocalRuntimeDb
|
|
147
|
-
} from "./chunk-H33743XH.js";
|
|
148
163
|
import {
|
|
149
164
|
isCompiledBinary,
|
|
150
165
|
parseUserIdFromAuthToken
|
|
@@ -152,27 +167,27 @@ import {
|
|
|
152
167
|
import {
|
|
153
168
|
DEFAULT_NOLO_SERVER_URL
|
|
154
169
|
} from "./chunk-OLZBQWZU.js";
|
|
155
|
-
import {
|
|
156
|
-
asRecordOrEmpty
|
|
157
|
-
} from "./chunk-KX6YBIHG.js";
|
|
158
170
|
import {
|
|
159
171
|
createTokenKey,
|
|
160
172
|
createUserKey,
|
|
161
173
|
dialogMessageRange
|
|
162
|
-
} from "./chunk-
|
|
174
|
+
} from "./chunk-6Y7A3OQQ.js";
|
|
175
|
+
import {
|
|
176
|
+
asOptionalFiniteNumber
|
|
177
|
+
} from "./chunk-WWC7I6TA.js";
|
|
163
178
|
import {
|
|
164
179
|
asTrimmedNonEmptyStringArray
|
|
165
180
|
} from "./chunk-I42VC5KR.js";
|
|
166
181
|
import {
|
|
167
|
-
|
|
168
|
-
} from "./chunk-
|
|
182
|
+
asTrimmedLowercaseString
|
|
183
|
+
} from "./chunk-QSJ3HFEF.js";
|
|
169
184
|
import {
|
|
170
185
|
BUILTIN_NOLO_AGENT_KEY,
|
|
171
186
|
PUBLIC_DEEPSEEK_V4_FLASH_AGENT_KEY,
|
|
172
187
|
PUBLIC_DEEPSEEK_V4_PRO_AGENT_KEY,
|
|
173
188
|
PUBLIC_GLM_52_AGENT_KEY,
|
|
174
189
|
PUBLIC_KIMI_K26_IMAGE_AGENT_KEY
|
|
175
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-3ND52WIL.js";
|
|
176
191
|
import {
|
|
177
192
|
asTrimmedString
|
|
178
193
|
} from "./chunk-3EUW3WEO.js";
|
|
@@ -262,6 +277,10 @@ var STRINGS = {
|
|
|
262
277
|
en: "Cleared current dialog messages.",
|
|
263
278
|
zh: "\u5DF2\u6E05\u9664\u5F53\u524D\u5BF9\u8BDD\u6D88\u606F\u3002"
|
|
264
279
|
},
|
|
280
|
+
persistentProcessesLeft: {
|
|
281
|
+
en: "{0} persistent process(es) left running in the background.",
|
|
282
|
+
zh: "\u4ECD\u6709 {0} \u4E2A\u5E38\u9A7B\u540E\u53F0\u8FDB\u7A0B\u5728\u540E\u53F0\u7EE7\u7EED\u8FD0\u884C\u3002"
|
|
283
|
+
},
|
|
265
284
|
clearNoDialog: {
|
|
266
285
|
en: "No current dialog messages to clear.",
|
|
267
286
|
zh: "\u5F53\u524D\u6CA1\u6709\u53EF\u6E05\u9664\u7684\u5BF9\u8BDD\u6D88\u606F\u3002"
|
|
@@ -294,6 +313,10 @@ var STRINGS = {
|
|
|
294
313
|
en: "Agent switch cancelled.",
|
|
295
314
|
zh: "\u5DF2\u53D6\u6D88\u5207\u6362 agent\u3002"
|
|
296
315
|
},
|
|
316
|
+
agentPickerLoading: {
|
|
317
|
+
en: "Loading agents\u2026",
|
|
318
|
+
zh: "\u6B63\u5728\u52A0\u8F7D agent \u5217\u8868\u2026"
|
|
319
|
+
},
|
|
297
320
|
historyPickerTitle: {
|
|
298
321
|
en: "Resume dialog (\u2191\u2193 Enter Esc)",
|
|
299
322
|
zh: "\u6062\u590D\u5BF9\u8BDD\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
|
|
@@ -458,6 +481,10 @@ var STRINGS = {
|
|
|
458
481
|
en: "Run stopped",
|
|
459
482
|
zh: "\u8FD0\u884C\u5DF2\u505C\u6B62"
|
|
460
483
|
},
|
|
484
|
+
runFinishedLabel: {
|
|
485
|
+
en: "Run finished",
|
|
486
|
+
zh: "\u8FD0\u884C\u5DF2\u7ED3\u675F"
|
|
487
|
+
},
|
|
461
488
|
runLogTailLabel: {
|
|
462
489
|
en: "Log tail:",
|
|
463
490
|
zh: "\u65E5\u5FD7\u5C3E\u90E8\uFF1A"
|
|
@@ -492,6 +519,10 @@ var STRINGS = {
|
|
|
492
519
|
en: "selected",
|
|
493
520
|
zh: "\u5DF2\u9009"
|
|
494
521
|
},
|
|
522
|
+
dialogMultiSelectRequired: {
|
|
523
|
+
en: "Pick at least one option to submit",
|
|
524
|
+
zh: "\u81F3\u5C11\u9009\u62E9\u4E00\u9879\u624D\u80FD\u63D0\u4EA4"
|
|
525
|
+
},
|
|
495
526
|
dialogConfirmHint: {
|
|
496
527
|
en: "(\u2191\u2193 move \xB7 Enter choose \xB7 Esc cancel)",
|
|
497
528
|
zh: "\uFF08\u2191\u2193 \u79FB\u52A8 \xB7 Enter \u9009\u62E9 \xB7 Esc \u53D6\u6D88\uFF09"
|
|
@@ -532,7 +563,7 @@ var STRINGS = {
|
|
|
532
563
|
en: "abort the operation",
|
|
533
564
|
zh: "\u4E2D\u6B62\u64CD\u4F5C"
|
|
534
565
|
},
|
|
535
|
-
// --- Ask choice (
|
|
566
|
+
// --- Ask choice (ask_user) ------------------------------------------
|
|
536
567
|
askChoiceTitle: {
|
|
537
568
|
en: "question",
|
|
538
569
|
zh: "\u95EE\u9898"
|
|
@@ -613,10 +644,6 @@ var STRINGS = {
|
|
|
613
644
|
en: "tools",
|
|
614
645
|
zh: "\u5DE5\u5177"
|
|
615
646
|
},
|
|
616
|
-
contextFieldThinking: {
|
|
617
|
-
en: "thinking",
|
|
618
|
-
zh: "\u601D\u8003"
|
|
619
|
-
},
|
|
620
647
|
contextFieldServer: {
|
|
621
648
|
en: "server",
|
|
622
649
|
zh: "\u670D\u52A1\u7AEF"
|
|
@@ -654,7 +681,6 @@ var STRINGS = {
|
|
|
654
681
|
" /context Show workspace context and next actions",
|
|
655
682
|
" /runtime <mode> Use auto, local, or server runtime",
|
|
656
683
|
" /tools <mode> Control tool trace: hide, compact, verbose",
|
|
657
|
-
" /thinking <mode> Control thinking output: hide, marker, show",
|
|
658
684
|
" /switch Pick an agent interactively (\u2191\u2193, Enter)",
|
|
659
685
|
" /switch list List agents as text",
|
|
660
686
|
" /switch <name> Switch directly by name, alias, or key (alias: /agent)",
|
|
@@ -691,7 +717,6 @@ var STRINGS = {
|
|
|
691
717
|
" /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
|
|
692
718
|
" /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
|
|
693
719
|
" /tools <mode> \u5DE5\u5177\u8F68\u8FF9\u663E\u793A\uFF1Ahide\u3001compact\u3001verbose",
|
|
694
|
-
" /thinking <mode> \u601D\u8003\u8FC7\u7A0B\u663E\u793A\uFF1Ahide\u3001marker\u3001show",
|
|
695
720
|
" /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
|
|
696
721
|
" /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
|
|
697
722
|
" /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
|
|
@@ -736,12 +761,6 @@ var STRINGS = {
|
|
|
736
761
|
},
|
|
737
762
|
toolsUsage: { en: "Usage: /tools <hide|compact|verbose>", zh: "\u7528\u6CD5\uFF1A/tools <hide|compact|verbose>" },
|
|
738
763
|
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}" },
|
|
745
764
|
tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
|
|
746
765
|
tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
|
|
747
766
|
tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
|
|
@@ -935,11 +954,191 @@ function agentRunCardLabels() {
|
|
|
935
954
|
runStatus: t("runStatusLabel"),
|
|
936
955
|
runStarted: t("runStartedLabel"),
|
|
937
956
|
runStopped: t("runStoppedLabel"),
|
|
957
|
+
runFinished: t("runFinishedLabel"),
|
|
938
958
|
logTail: t("runLogTailLabel"),
|
|
939
959
|
runs: (count) => t("runsListLabel", String(count))
|
|
940
960
|
};
|
|
941
961
|
}
|
|
942
962
|
|
|
963
|
+
// packages/ai/tools/agent/quotaCircuitBreaker.ts
|
|
964
|
+
var QUOTA_ERROR_PATTERNS = [
|
|
965
|
+
/429/,
|
|
966
|
+
/quota/i,
|
|
967
|
+
/rate\s*limit/i,
|
|
968
|
+
/too\s*many\s*requests/i,
|
|
969
|
+
/额度/,
|
|
970
|
+
/上限/,
|
|
971
|
+
/用尽/,
|
|
972
|
+
/CliProviderQuotaError/i
|
|
973
|
+
];
|
|
974
|
+
var AGENT_NOT_FOUND_PATTERNS = [
|
|
975
|
+
/agent[^\n]{0,80}not\s+found/i,
|
|
976
|
+
/agent[^\n]{0,80}not\s+exist/i,
|
|
977
|
+
/agent[^\n]{0,80}不存在/i,
|
|
978
|
+
/agent[^\n]{0,80}未找到/i,
|
|
979
|
+
/AGENT_NOT_FOUND/
|
|
980
|
+
];
|
|
981
|
+
var AUTH_ERROR_PATTERNS = [
|
|
982
|
+
/401/,
|
|
983
|
+
/403/,
|
|
984
|
+
/unauthori[sz]ed/i,
|
|
985
|
+
/authentication\s+failed/i,
|
|
986
|
+
/invalid\s+(api[-\s]?key|token|credential)/i,
|
|
987
|
+
/api[-\s]?key\s+(invalid|missing|not\s+found)/i,
|
|
988
|
+
/token\s*(invalid|expired|失效|过期)/i,
|
|
989
|
+
/未授权/,
|
|
990
|
+
/认证失败/,
|
|
991
|
+
/凭证/
|
|
992
|
+
];
|
|
993
|
+
var NETWORK_ERROR_PATTERNS = [
|
|
994
|
+
/ECONNREFUSED|ECONNRESET|ETIMEDOUT|ENOTFOUND|EHOSTUNREACH|EPIPE/i,
|
|
995
|
+
/getaddrinfo|DNS\s+(error|fail)/i,
|
|
996
|
+
/fetch\s+failed/i,
|
|
997
|
+
/network\s+(error|unreachable|down|disconnected)/i,
|
|
998
|
+
/socket\s+(hang|closed|error)/i,
|
|
999
|
+
/连接失败/,
|
|
1000
|
+
/网络错误|网络异常|无法连接/
|
|
1001
|
+
];
|
|
1002
|
+
function findActiveBreaker(now, table, target) {
|
|
1003
|
+
if (!Number.isFinite(now)) return void 0;
|
|
1004
|
+
for (const entry of table) {
|
|
1005
|
+
if (entry.target !== target) continue;
|
|
1006
|
+
if (typeof entry.until === "number" && entry.until > now) return entry;
|
|
1007
|
+
}
|
|
1008
|
+
return void 0;
|
|
1009
|
+
}
|
|
1010
|
+
function isCliProviderQuotaErrorShape(error) {
|
|
1011
|
+
if (!error || typeof error !== "object") return false;
|
|
1012
|
+
const e = error;
|
|
1013
|
+
return e.name === "CliProviderQuotaError" || typeof e.message === "string" && e.message.startsWith("[QUOTA_LIMITED:");
|
|
1014
|
+
}
|
|
1015
|
+
function isQuotaExhaustedError(error) {
|
|
1016
|
+
if (!error) return false;
|
|
1017
|
+
if (isCliProviderQuotaErrorShape(error)) return true;
|
|
1018
|
+
if (error instanceof Error) {
|
|
1019
|
+
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error.message));
|
|
1020
|
+
}
|
|
1021
|
+
if (typeof error === "string") {
|
|
1022
|
+
return QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(error));
|
|
1023
|
+
}
|
|
1024
|
+
const maybeStatus = error.status;
|
|
1025
|
+
if (typeof maybeStatus === "number" && maybeStatus === 429) return true;
|
|
1026
|
+
const maybeStatusCode = error.statusCode;
|
|
1027
|
+
if (typeof maybeStatusCode === "number" && maybeStatusCode === 429) return true;
|
|
1028
|
+
return false;
|
|
1029
|
+
}
|
|
1030
|
+
function isAgentNotFoundError(error) {
|
|
1031
|
+
if (!error) return false;
|
|
1032
|
+
const e = error;
|
|
1033
|
+
if (e.code === "AGENT_NOT_FOUND") return true;
|
|
1034
|
+
const message = typeof e.message === "string" ? e.message : typeof error === "string" ? error : "";
|
|
1035
|
+
if (AGENT_NOT_FOUND_PATTERNS.some((pattern) => pattern.test(message))) return true;
|
|
1036
|
+
if ((e.status === 404 || e.statusCode === 404) && /agent|不存在|未找到/i.test(message)) {
|
|
1037
|
+
return true;
|
|
1038
|
+
}
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
function extractMessage(error) {
|
|
1042
|
+
if (typeof error === "string") return error;
|
|
1043
|
+
if (error instanceof Error) return error.message;
|
|
1044
|
+
if (error && typeof error === "object") {
|
|
1045
|
+
const m = error.message;
|
|
1046
|
+
return typeof m === "string" ? m : "";
|
|
1047
|
+
}
|
|
1048
|
+
return "";
|
|
1049
|
+
}
|
|
1050
|
+
function extractStatus(error) {
|
|
1051
|
+
if (!error || typeof error !== "object") return void 0;
|
|
1052
|
+
const e = error;
|
|
1053
|
+
const s = typeof e.status === "number" ? e.status : void 0;
|
|
1054
|
+
const sc = typeof e.statusCode === "number" ? e.statusCode : void 0;
|
|
1055
|
+
return s ?? sc;
|
|
1056
|
+
}
|
|
1057
|
+
function parseResetsInMs(text) {
|
|
1058
|
+
if (!text) return void 0;
|
|
1059
|
+
const unitMs = (n, unit) => {
|
|
1060
|
+
if (/^d/.test(unit)) return n * 24 * 3600 * 1e3;
|
|
1061
|
+
if (/^h/.test(unit)) return n * 3600 * 1e3;
|
|
1062
|
+
if (/^m/.test(unit)) return n * 60 * 1e3;
|
|
1063
|
+
if (/^s/.test(unit)) return n * 1e3;
|
|
1064
|
+
return NaN;
|
|
1065
|
+
};
|
|
1066
|
+
const re = /(\d+)\s*(d(?:ay|ays)?|h(?:r|rs|our|ours)?|m(?:in|ins|inute|inutes)?|s(?:ec|ecs|econd|econds)?)/gi;
|
|
1067
|
+
let totalMs = 0;
|
|
1068
|
+
let matched = false;
|
|
1069
|
+
let m;
|
|
1070
|
+
while ((m = re.exec(text)) !== null) {
|
|
1071
|
+
const ms = unitMs(Number(m[1]), m[2]);
|
|
1072
|
+
if (!Number.isFinite(ms)) continue;
|
|
1073
|
+
totalMs += ms;
|
|
1074
|
+
matched = true;
|
|
1075
|
+
}
|
|
1076
|
+
return matched ? totalMs : void 0;
|
|
1077
|
+
}
|
|
1078
|
+
function extractProvider(error) {
|
|
1079
|
+
if (!error || typeof error !== "object") return void 0;
|
|
1080
|
+
const p = error.provider;
|
|
1081
|
+
if (typeof p === "string" && p.length > 0) return p;
|
|
1082
|
+
const message = extractMessage(error);
|
|
1083
|
+
const tag = /\[QUOTA_LIMITED:([^\]]+)\]/i.exec(message);
|
|
1084
|
+
if (tag?.[1]) return tag[1];
|
|
1085
|
+
return void 0;
|
|
1086
|
+
}
|
|
1087
|
+
function extractRetryAfterHeader(error) {
|
|
1088
|
+
if (!error || typeof error !== "object") return void 0;
|
|
1089
|
+
const headers = error.headers;
|
|
1090
|
+
if (!headers || typeof headers !== "object") return void 0;
|
|
1091
|
+
const raw = headers["retry-after"];
|
|
1092
|
+
if (typeof raw !== "string" && typeof raw !== "number") return void 0;
|
|
1093
|
+
const secs = Number(raw);
|
|
1094
|
+
return Number.isFinite(secs) && secs > 0 ? secs * 1e3 : void 0;
|
|
1095
|
+
}
|
|
1096
|
+
function classifyRunFailure(error) {
|
|
1097
|
+
const message = extractMessage(error);
|
|
1098
|
+
const status = extractStatus(error);
|
|
1099
|
+
const retryAfterMs = extractRetryAfterHeader(error) ?? parseResetsInMs(message);
|
|
1100
|
+
if (isQuotaExhaustedError(error)) {
|
|
1101
|
+
return {
|
|
1102
|
+
reason: "quota",
|
|
1103
|
+
provider: extractProvider(error),
|
|
1104
|
+
// 纯函数不取时钟:resetsAt 由调用方用 now + retryAfterMs 计算后补齐
|
|
1105
|
+
retryAfterMs,
|
|
1106
|
+
message
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
if (isAgentNotFoundError(error)) {
|
|
1110
|
+
return { reason: "agent-not-found", message };
|
|
1111
|
+
}
|
|
1112
|
+
if (isAuthError(error)) {
|
|
1113
|
+
return { reason: "auth", message };
|
|
1114
|
+
}
|
|
1115
|
+
if (isNetworkError(error)) {
|
|
1116
|
+
return { reason: "network", message };
|
|
1117
|
+
}
|
|
1118
|
+
return { reason: "other", message };
|
|
1119
|
+
}
|
|
1120
|
+
function isAuthError(error) {
|
|
1121
|
+
const message = extractMessage(error);
|
|
1122
|
+
const status = extractStatus(error);
|
|
1123
|
+
if (status === 401 || status === 403) return true;
|
|
1124
|
+
return AUTH_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
1125
|
+
}
|
|
1126
|
+
function isNetworkError(error) {
|
|
1127
|
+
const message = extractMessage(error);
|
|
1128
|
+
return NETWORK_ERROR_PATTERNS.some((pattern) => pattern.test(message));
|
|
1129
|
+
}
|
|
1130
|
+
var DEFAULT_QUOTA_BREAKER_MS = 6 * 3600 * 1e3;
|
|
1131
|
+
var DEFAULT_AGENT_NOT_FOUND_BREAKER_MS = 15 * 60 * 1e3;
|
|
1132
|
+
function buildBreakerEntry(now, target, kind, retryAfterMs) {
|
|
1133
|
+
const ttl = kind === "quota" ? typeof retryAfterMs === "number" && retryAfterMs > 0 ? retryAfterMs : DEFAULT_QUOTA_BREAKER_MS : DEFAULT_AGENT_NOT_FOUND_BREAKER_MS;
|
|
1134
|
+
return {
|
|
1135
|
+
target,
|
|
1136
|
+
kind,
|
|
1137
|
+
until: now + ttl,
|
|
1138
|
+
...kind === "quota" && typeof retryAfterMs === "number" ? { resetsAt: now + retryAfterMs } : {}
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
|
|
943
1142
|
// packages/cli/client/localRuntimeDiagnostics.ts
|
|
944
1143
|
import { ulid } from "ulid";
|
|
945
1144
|
var preparedAgentRuntimeCache = /* @__PURE__ */ new Map();
|
|
@@ -979,7 +1178,7 @@ function summarizeOpenAiToolNames(tools) {
|
|
|
979
1178
|
}
|
|
980
1179
|
|
|
981
1180
|
// packages/cli/client/localRuntimeAdapter.ts
|
|
982
|
-
import { dirname, extname, join } from "node:path";
|
|
1181
|
+
import { dirname as dirname2, extname, join as join2 } from "node:path";
|
|
983
1182
|
import { fileURLToPath } from "node:url";
|
|
984
1183
|
|
|
985
1184
|
// packages/core/summarizeEndpoint.ts
|
|
@@ -1130,6 +1329,11 @@ async function fetchWithTransientRetry(fetchImpl, input, init, options = {}) {
|
|
|
1130
1329
|
const attemptBudget = coreDraining ? coreDrainingMaxAttempts : maxAttempts;
|
|
1131
1330
|
if (attempt < attemptBudget) {
|
|
1132
1331
|
const delayMs = await resolveRetryAfterMs(response, attempt);
|
|
1332
|
+
options.onRetry?.({
|
|
1333
|
+
attempt: attempt + 1,
|
|
1334
|
+
maxAttempts: attemptBudget,
|
|
1335
|
+
delayMs
|
|
1336
|
+
});
|
|
1133
1337
|
await (options.sleep ?? defaultSleep)(delayMs);
|
|
1134
1338
|
continue;
|
|
1135
1339
|
}
|
|
@@ -1143,7 +1347,13 @@ async function fetchWithTransientRetry(fetchImpl, input, init, options = {}) {
|
|
|
1143
1347
|
if (!isTransientFetchError(error)) throw error;
|
|
1144
1348
|
lastError = error;
|
|
1145
1349
|
if (attempt < maxAttempts) {
|
|
1146
|
-
|
|
1350
|
+
const delayMs = transientFetchRetryDelayMs(attempt);
|
|
1351
|
+
options.onRetry?.({
|
|
1352
|
+
attempt: attempt + 1,
|
|
1353
|
+
maxAttempts,
|
|
1354
|
+
delayMs
|
|
1355
|
+
});
|
|
1356
|
+
await (options.sleep ?? defaultSleep)(delayMs);
|
|
1147
1357
|
}
|
|
1148
1358
|
}
|
|
1149
1359
|
}
|
|
@@ -1590,23 +1800,6 @@ async function readAgentFromStore(args) {
|
|
|
1590
1800
|
if (!record || typeof record !== "object") continue;
|
|
1591
1801
|
return resolveAgentRuntimeConfigFromRecord(key, record);
|
|
1592
1802
|
}
|
|
1593
|
-
const normalizedRef = normalizeAgentHandle(args.agentRef);
|
|
1594
|
-
if (!normalizedRef) {
|
|
1595
|
-
return resolveBuiltinPlatformAgentConfig(args.agentRef);
|
|
1596
|
-
}
|
|
1597
|
-
try {
|
|
1598
|
-
const iterator = args.store.iterator({
|
|
1599
|
-
gte: "agent-",
|
|
1600
|
-
lte: "agent-\uFFFF"
|
|
1601
|
-
});
|
|
1602
|
-
for await (const [key, record] of iterator) {
|
|
1603
|
-
if (!record || typeof record !== "object") continue;
|
|
1604
|
-
const handle = normalizeAgentHandle(record.handle);
|
|
1605
|
-
if (handle !== normalizedRef) continue;
|
|
1606
|
-
return resolveAgentRuntimeConfigFromRecord(key, record);
|
|
1607
|
-
}
|
|
1608
|
-
} catch {
|
|
1609
|
-
}
|
|
1610
1803
|
return resolveBuiltinPlatformAgentConfig(args.agentRef);
|
|
1611
1804
|
}
|
|
1612
1805
|
async function readDialogMessages(args) {
|
|
@@ -1765,7 +1958,10 @@ var LOCAL_SERVER_WEB_TOOL_NAMES = ["fetchWebpage", "exa_search"];
|
|
|
1765
1958
|
var LOCAL_SERVER_WEB_TOOL_NAME_SET = new Set(
|
|
1766
1959
|
LOCAL_SERVER_WEB_TOOL_NAMES
|
|
1767
1960
|
);
|
|
1768
|
-
var LOCAL_SERVER_MEMORY_TOOL_NAMES = [
|
|
1961
|
+
var LOCAL_SERVER_MEMORY_TOOL_NAMES = [
|
|
1962
|
+
"queryMemory",
|
|
1963
|
+
"rememberMemory"
|
|
1964
|
+
];
|
|
1769
1965
|
var LOCAL_SERVER_MEMORY_TOOL_NAME_SET = new Set(
|
|
1770
1966
|
LOCAL_SERVER_MEMORY_TOOL_NAMES
|
|
1771
1967
|
);
|
|
@@ -1997,6 +2193,25 @@ function buildServerPlatformToolExecutors(args) {
|
|
|
1997
2193
|
}
|
|
1998
2194
|
])
|
|
1999
2195
|
);
|
|
2196
|
+
const queryMemory = async (call) => {
|
|
2197
|
+
const parsed = parseNoloWorkspaceToolArguments(call.arguments);
|
|
2198
|
+
const query = typeof parsed.query === "string" ? parsed.query.trim() : "";
|
|
2199
|
+
if (!query) {
|
|
2200
|
+
return {
|
|
2201
|
+
content: JSON.stringify({ error: "queryMemory \u9700\u8981\u975E\u7A7A query\u3002" }),
|
|
2202
|
+
metadata: { serverPlatformTool: true, memoryRead: false }
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
const body = { userInput: query };
|
|
2206
|
+
if (args.agentKey) body.agentKey = args.agentKey;
|
|
2207
|
+
const raw = await postServer("/api/memory/query", body, {
|
|
2208
|
+
retryTransient: true
|
|
2209
|
+
});
|
|
2210
|
+
return {
|
|
2211
|
+
content: raw,
|
|
2212
|
+
metadata: { serverPlatformTool: true, memoryRead: true }
|
|
2213
|
+
};
|
|
2214
|
+
};
|
|
2000
2215
|
const rememberMemory = async (call) => {
|
|
2001
2216
|
const parsed = parseNoloWorkspaceToolArguments(call.arguments);
|
|
2002
2217
|
const content = typeof parsed.content === "string" ? parsed.content.trim() : "";
|
|
@@ -2023,11 +2238,368 @@ function buildServerPlatformToolExecutors(args) {
|
|
|
2023
2238
|
metadata: { serverPlatformTool: true, memoryWrite: true }
|
|
2024
2239
|
};
|
|
2025
2240
|
};
|
|
2026
|
-
return { ...tableExecutors, ...webExecutors, rememberMemory };
|
|
2241
|
+
return { ...tableExecutors, ...webExecutors, queryMemory, rememberMemory };
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
// packages/cli/client/cliAgentRunToolExecutors.ts
|
|
2245
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
2246
|
+
|
|
2247
|
+
// packages/cli/client/agentRunSnapshot.ts
|
|
2248
|
+
function readString(value) {
|
|
2249
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
2250
|
+
}
|
|
2251
|
+
function readLogLines(parsed) {
|
|
2252
|
+
if (Array.isArray(parsed.logLines)) return parsed.logLines;
|
|
2253
|
+
const tail = readString(parsed.logTail);
|
|
2254
|
+
return tail ? tail.split("\n") : void 0;
|
|
2255
|
+
}
|
|
2256
|
+
function readTimestamp(value) {
|
|
2257
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
|
|
2258
|
+
if (typeof value === "string" && value.trim()) {
|
|
2259
|
+
const parsed = Date.parse(value);
|
|
2260
|
+
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
2261
|
+
}
|
|
2262
|
+
return void 0;
|
|
2263
|
+
}
|
|
2264
|
+
function readToolNames(value) {
|
|
2265
|
+
if (!Array.isArray(value)) return void 0;
|
|
2266
|
+
const names = value.filter((n) => typeof n === "string" && Boolean(n.trim()));
|
|
2267
|
+
return names.length > 0 ? names : void 0;
|
|
2268
|
+
}
|
|
2269
|
+
function buildSnapshot(parsed, event) {
|
|
2270
|
+
const runId = readString(parsed.runId) ?? readString(event.metadata?.runId) ?? "";
|
|
2271
|
+
const label = resolveRunLabel({
|
|
2272
|
+
agentName: parsed.agentName,
|
|
2273
|
+
name: parsed.name,
|
|
2274
|
+
agentKey: parsed.agentKey
|
|
2275
|
+
});
|
|
2276
|
+
const logLines = readLogLines(parsed);
|
|
2277
|
+
const taskPreview = readString(parsed.taskPreview);
|
|
2278
|
+
const lastToolNames = readToolNames(parsed.lastToolNames);
|
|
2279
|
+
const lastAssistantText = readString(parsed.lastAssistantText);
|
|
2280
|
+
const errorMessage = readString(parsed.errorMessage);
|
|
2281
|
+
const startedAt = readTimestamp(parsed.startedAt);
|
|
2282
|
+
const finishedAt = readTimestamp(parsed.finishedAt) ?? readTimestamp(parsed.endedAt);
|
|
2283
|
+
return {
|
|
2284
|
+
runId,
|
|
2285
|
+
status: readString(parsed.status) ?? "running",
|
|
2286
|
+
// The literal `agent` fallback is dropped here rather than at each render
|
|
2287
|
+
// site: an unnamed run should render no name row, not the word "agent".
|
|
2288
|
+
...isAgentNameFallback(label) ? {} : { agentName: label },
|
|
2289
|
+
...taskPreview ? { taskPreview } : {},
|
|
2290
|
+
...typeof parsed.toolCallCount === "number" && Number.isFinite(parsed.toolCallCount) ? { toolCallCount: parsed.toolCallCount } : {},
|
|
2291
|
+
...lastToolNames ? { lastToolNames } : {},
|
|
2292
|
+
...lastAssistantText ? { lastAssistantText } : {},
|
|
2293
|
+
...errorMessage ? { errorMessage } : {},
|
|
2294
|
+
...startedAt !== void 0 ? { startedAt } : {},
|
|
2295
|
+
...finishedAt !== void 0 ? { finishedAt } : {},
|
|
2296
|
+
...logLines ? { logLines } : {},
|
|
2297
|
+
logKey: logLines && logLines.length > 0 ? logLines.join("\n") : ""
|
|
2298
|
+
};
|
|
2299
|
+
}
|
|
2300
|
+
var STOP_STATUSES = /* @__PURE__ */ new Set(["killed", "cancelled", "cancelling"]);
|
|
2301
|
+
function parseAgentRunEvent(event) {
|
|
2302
|
+
if (event.type !== "tool-result") return null;
|
|
2303
|
+
if (event.toolName !== "startAgentRun" && event.toolName !== "controlAgentRun") {
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
const raw = typeof event.content === "string" ? event.content.trim() : "";
|
|
2307
|
+
if (!raw.startsWith("{")) return null;
|
|
2308
|
+
let parsed;
|
|
2309
|
+
try {
|
|
2310
|
+
parsed = JSON.parse(raw);
|
|
2311
|
+
} catch {
|
|
2312
|
+
return null;
|
|
2313
|
+
}
|
|
2314
|
+
if (Array.isArray(parsed.runs)) return null;
|
|
2315
|
+
const snapshot = buildSnapshot(parsed, event);
|
|
2316
|
+
const status = readString(parsed.status);
|
|
2317
|
+
if (event.toolName === "startAgentRun") {
|
|
2318
|
+
if (!snapshot.runId) return null;
|
|
2319
|
+
return { kind: "start", snapshot };
|
|
2320
|
+
}
|
|
2321
|
+
if (parsed.found === false || status === "not_found") {
|
|
2322
|
+
return { kind: "gone", snapshot: { ...snapshot, status: "not_found" } };
|
|
2323
|
+
}
|
|
2324
|
+
if (status && STOP_STATUSES.has(status)) {
|
|
2325
|
+
return { kind: "stop", snapshot };
|
|
2326
|
+
}
|
|
2327
|
+
if (!status) return null;
|
|
2328
|
+
if (!snapshot.runId) return null;
|
|
2329
|
+
return { kind: "status", snapshot };
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
// packages/ai/tools/agent/batchAggregation.ts
|
|
2333
|
+
var DEFAULT_BATCH_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
2334
|
+
var MAX_ERROR_SUMMARY_CHARS = 120;
|
|
2335
|
+
var MAX_FAILURE_LINES = 10;
|
|
2336
|
+
function isFailureStatus(status) {
|
|
2337
|
+
return isAgentRunTerminalStatus(status) && status !== "done";
|
|
2338
|
+
}
|
|
2339
|
+
function isOrphanedStatus(status) {
|
|
2340
|
+
return status === "orphaned";
|
|
2341
|
+
}
|
|
2342
|
+
function toEpochMs(iso) {
|
|
2343
|
+
if (!iso) return void 0;
|
|
2344
|
+
const ms = Date.parse(iso);
|
|
2345
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
2346
|
+
}
|
|
2347
|
+
function isOverTimeout(run, nowMs, timeoutMs) {
|
|
2348
|
+
const startedMs = toEpochMs(run.startedAt);
|
|
2349
|
+
if (startedMs === void 0) return false;
|
|
2350
|
+
return nowMs - startedMs >= timeoutMs;
|
|
2351
|
+
}
|
|
2352
|
+
function truncateErrorSummary(text, max = MAX_ERROR_SUMMARY_CHARS) {
|
|
2353
|
+
if (!text) return "";
|
|
2354
|
+
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
2355
|
+
if (collapsed.length <= max) return collapsed;
|
|
2356
|
+
return `${collapsed.slice(0, max - 1)}\u2026`;
|
|
2357
|
+
}
|
|
2358
|
+
function formatFailureLine(run) {
|
|
2359
|
+
const label = shortRunId(run.runId);
|
|
2360
|
+
const agent = run.agentName ? ` (${run.agentName})` : "";
|
|
2361
|
+
const error = truncateErrorSummary(run.errorSummary);
|
|
2362
|
+
return error ? `\u5931\u8D25: ${label}${agent} \u2014 ${error}` : `\u5931\u8D25: ${label}${agent}`;
|
|
2363
|
+
}
|
|
2364
|
+
function formatBatchSummary(batchId, counts, runs, reason) {
|
|
2365
|
+
const failures = runs.filter((r) => isFailureStatus(r.status));
|
|
2366
|
+
const unfinished = runs.filter((r) => !isAgentRunTerminalStatus(r.status));
|
|
2367
|
+
if (reason === "timeout") {
|
|
2368
|
+
const lines2 = [
|
|
2369
|
+
`\u6279\u6B21 ${batchId}: \u8D85\u65F6\u672A\u6536\u655B \u2014 ${counts.running} \u4E2A\u672A\u5B8C\u6210`
|
|
2370
|
+
];
|
|
2371
|
+
for (const run of unfinished.slice(0, MAX_FAILURE_LINES)) {
|
|
2372
|
+
const agent = run.agentName ? ` (${run.agentName})` : "";
|
|
2373
|
+
lines2.push(`\u672A\u5B8C\u6210: ${shortRunId(run.runId)}${agent}`);
|
|
2374
|
+
}
|
|
2375
|
+
const rest2 = unfinished.length - MAX_FAILURE_LINES;
|
|
2376
|
+
if (rest2 > 0) lines2.push(`\u2026 \u53CA\u53E6\u5916 ${rest2} \u4E2A\u672A\u5B8C\u6210`);
|
|
2377
|
+
return lines2.join("\n");
|
|
2378
|
+
}
|
|
2379
|
+
const tail = counts.running > 0 ? `, ${counts.running} \u4ECD\u5728\u8DD1` : "";
|
|
2380
|
+
const lines = [
|
|
2381
|
+
`\u6279\u6B21 ${batchId}: ${counts.success + counts.failed}/${counts.total} \u5B8C\u6210 \u2014 ${counts.success} \u6210\u529F, ${counts.failed} \u5931\u8D25${tail}`
|
|
2382
|
+
];
|
|
2383
|
+
for (const run of failures.slice(0, MAX_FAILURE_LINES)) {
|
|
2384
|
+
lines.push(formatFailureLine(run));
|
|
2385
|
+
}
|
|
2386
|
+
const rest = failures.length - MAX_FAILURE_LINES;
|
|
2387
|
+
if (rest > 0) lines.push(`\u2026 \u53CA\u53E6\u5916 ${rest} \u4E2A\u5931\u8D25`);
|
|
2388
|
+
return lines.join("\n");
|
|
2389
|
+
}
|
|
2390
|
+
function aggregateBatch(input) {
|
|
2391
|
+
const { batchId, runs, now } = input;
|
|
2392
|
+
const timeoutMs = input.timeoutMs ?? DEFAULT_BATCH_TIMEOUT_MS;
|
|
2393
|
+
const notified = new Set(input.notifiedReasons ?? []);
|
|
2394
|
+
const nowMs = toEpochMs(now) ?? 0;
|
|
2395
|
+
let success = 0;
|
|
2396
|
+
let failed = 0;
|
|
2397
|
+
let orphaned = 0;
|
|
2398
|
+
let running = 0;
|
|
2399
|
+
const unfinished = [];
|
|
2400
|
+
let timedOut = false;
|
|
2401
|
+
for (const run of runs) {
|
|
2402
|
+
if (isAgentRunTerminalStatus(run.status)) {
|
|
2403
|
+
if (run.status === "done") success += 1;
|
|
2404
|
+
else {
|
|
2405
|
+
failed += 1;
|
|
2406
|
+
if (isOrphanedStatus(run.status)) orphaned += 1;
|
|
2407
|
+
}
|
|
2408
|
+
} else {
|
|
2409
|
+
running += 1;
|
|
2410
|
+
unfinished.push(run.runId);
|
|
2411
|
+
if (isOverTimeout(run, nowMs, timeoutMs)) timedOut = true;
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
const converged = running === 0;
|
|
2415
|
+
let newWakeReasons = [];
|
|
2416
|
+
if (failed > 0 && !notified.has("failure")) {
|
|
2417
|
+
newWakeReasons = ["failure"];
|
|
2418
|
+
} else if (converged && !notified.has("converged")) {
|
|
2419
|
+
newWakeReasons = ["converged"];
|
|
2420
|
+
} else if (timedOut && !notified.has("timeout")) {
|
|
2421
|
+
newWakeReasons = ["timeout"];
|
|
2422
|
+
}
|
|
2423
|
+
const counts = {
|
|
2424
|
+
total: runs.length,
|
|
2425
|
+
success,
|
|
2426
|
+
failed,
|
|
2427
|
+
orphaned,
|
|
2428
|
+
running
|
|
2429
|
+
};
|
|
2430
|
+
const summary = newWakeReasons.length > 0 ? formatBatchSummary(batchId, counts, runs, newWakeReasons[0]) : "";
|
|
2431
|
+
return {
|
|
2432
|
+
batchId,
|
|
2433
|
+
converged,
|
|
2434
|
+
timedOut,
|
|
2435
|
+
counts,
|
|
2436
|
+
newWakeReasons,
|
|
2437
|
+
unfinished,
|
|
2438
|
+
summary
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
// packages/ai/tools/agent/runtimeTodo.ts
|
|
2443
|
+
var TODO_REVIEW_BLOCK = "BLOCK";
|
|
2444
|
+
function deriveTodoStatus(input) {
|
|
2445
|
+
const { todo, runs } = input;
|
|
2446
|
+
if (todo.status === "abandoned") {
|
|
2447
|
+
return { status: "abandoned" };
|
|
2448
|
+
}
|
|
2449
|
+
if (runs.length === 0) {
|
|
2450
|
+
return { status: todo.status };
|
|
2451
|
+
}
|
|
2452
|
+
if (runs.some((r) => !isAgentRunTerminalStatus(r.status))) {
|
|
2453
|
+
return { status: "running", latestRun: latestRun(runs) };
|
|
2454
|
+
}
|
|
2455
|
+
const latest = latestRun(runs);
|
|
2456
|
+
if (latest?.reviewVerdict === TODO_REVIEW_BLOCK) {
|
|
2457
|
+
return {
|
|
2458
|
+
status: "blocked",
|
|
2459
|
+
latestRun: latest,
|
|
2460
|
+
blockedReason: clipSummary(latest.reviewReason, MAX_ERROR_SUMMARY_CHARS)
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2463
|
+
if (latest?.status === "done") {
|
|
2464
|
+
return { status: "done", latestRun: latest };
|
|
2465
|
+
}
|
|
2466
|
+
return { status: "pending", latestRun: latest };
|
|
2467
|
+
}
|
|
2468
|
+
function toEpochMs2(iso) {
|
|
2469
|
+
if (!iso) return void 0;
|
|
2470
|
+
const ms = Date.parse(iso);
|
|
2471
|
+
return Number.isFinite(ms) ? ms : void 0;
|
|
2472
|
+
}
|
|
2473
|
+
function latestRun(runs) {
|
|
2474
|
+
let latest;
|
|
2475
|
+
let latestScore = -1;
|
|
2476
|
+
for (const run of runs) {
|
|
2477
|
+
const score = toEpochMs2(run.finishedAt) ?? toEpochMs2(run.startedAt) ?? -1;
|
|
2478
|
+
if (latest === void 0 || score >= latestScore) {
|
|
2479
|
+
latest = run;
|
|
2480
|
+
latestScore = score;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return latest;
|
|
2484
|
+
}
|
|
2485
|
+
function clipSummary(text, max) {
|
|
2486
|
+
if (!text) return void 0;
|
|
2487
|
+
const folded = text.replace(/\s+/g, " ").trim();
|
|
2488
|
+
if (folded.length === 0) return void 0;
|
|
2489
|
+
return folded.length > max ? `${folded.slice(0, max - 1)}\u2026` : folded;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
// packages/cli/client/fileSystemStores.ts
|
|
2493
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2494
|
+
import { homedir as nodeHomedir } from "node:os";
|
|
2495
|
+
import { dirname, join } from "node:path";
|
|
2496
|
+
var nodeFs = {
|
|
2497
|
+
mkdirSync,
|
|
2498
|
+
writeFileSync,
|
|
2499
|
+
readFileSync,
|
|
2500
|
+
existsSync
|
|
2501
|
+
};
|
|
2502
|
+
function resolveNoloHome(env, homedir) {
|
|
2503
|
+
const custom = env?.NOLO_HOME;
|
|
2504
|
+
if (custom && custom.trim()) return custom.trim();
|
|
2505
|
+
return join(homedir(), ".nolo");
|
|
2506
|
+
}
|
|
2507
|
+
function ensureDir(dir, fs) {
|
|
2508
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
2509
|
+
}
|
|
2510
|
+
function readJson(path, fs) {
|
|
2511
|
+
if (!fs.existsSync(path)) return void 0;
|
|
2512
|
+
try {
|
|
2513
|
+
const raw = fs.readFileSync(path, "utf8");
|
|
2514
|
+
return JSON.parse(String(raw));
|
|
2515
|
+
} catch {
|
|
2516
|
+
return void 0;
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2519
|
+
function writeJson(path, data, fs) {
|
|
2520
|
+
fs.writeFileSync(path, JSON.stringify(data, null, 2));
|
|
2521
|
+
}
|
|
2522
|
+
function createFileSystemCircuitBreakerStore(opts = {}) {
|
|
2523
|
+
const env = opts.env ?? process.env;
|
|
2524
|
+
const homedir = opts.homedir ?? nodeHomedir;
|
|
2525
|
+
const fs = opts.fs ?? nodeFs;
|
|
2526
|
+
const filePath = opts.filePath ?? join(resolveNoloHome(env, homedir), "breakers.json");
|
|
2527
|
+
const loadMap = () => {
|
|
2528
|
+
const data = readJson(filePath, fs);
|
|
2529
|
+
const map = /* @__PURE__ */ new Map();
|
|
2530
|
+
if (data?.entries) {
|
|
2531
|
+
for (const entry of data.entries) {
|
|
2532
|
+
if (entry && typeof entry.target === "string") map.set(entry.target, entry);
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
return map;
|
|
2536
|
+
};
|
|
2537
|
+
const persist = (map) => {
|
|
2538
|
+
ensureDir(dirname(filePath), fs);
|
|
2539
|
+
writeJson(filePath, { entries: [...map.values()] }, fs);
|
|
2540
|
+
};
|
|
2541
|
+
return {
|
|
2542
|
+
get(target) {
|
|
2543
|
+
return loadMap().get(target);
|
|
2544
|
+
},
|
|
2545
|
+
set(entry) {
|
|
2546
|
+
const map = loadMap();
|
|
2547
|
+
map.set(entry.target, entry);
|
|
2548
|
+
persist(map);
|
|
2549
|
+
},
|
|
2550
|
+
clear(target) {
|
|
2551
|
+
const map = loadMap();
|
|
2552
|
+
map.delete(target);
|
|
2553
|
+
persist(map);
|
|
2554
|
+
},
|
|
2555
|
+
clearAll() {
|
|
2556
|
+
persist(/* @__PURE__ */ new Map());
|
|
2557
|
+
}
|
|
2558
|
+
};
|
|
2559
|
+
}
|
|
2560
|
+
function createFileSystemTodoStore(opts = {}) {
|
|
2561
|
+
const env = opts.env ?? process.env;
|
|
2562
|
+
const homedir = opts.homedir ?? nodeHomedir;
|
|
2563
|
+
const fs = opts.fs ?? nodeFs;
|
|
2564
|
+
const filePath = opts.filePath ?? join(resolveNoloHome(env, homedir), "todos.json");
|
|
2565
|
+
const loadMap = () => {
|
|
2566
|
+
const data = readJson(filePath, fs);
|
|
2567
|
+
const map = /* @__PURE__ */ new Map();
|
|
2568
|
+
if (data?.todos) {
|
|
2569
|
+
for (const todo of data.todos) {
|
|
2570
|
+
if (todo && typeof todo.id === "string") map.set(todo.id, todo);
|
|
2571
|
+
}
|
|
2572
|
+
}
|
|
2573
|
+
return map;
|
|
2574
|
+
};
|
|
2575
|
+
const persist = (map) => {
|
|
2576
|
+
ensureDir(dirname(filePath), fs);
|
|
2577
|
+
writeJson(filePath, { todos: [...map.values()] }, fs);
|
|
2578
|
+
};
|
|
2579
|
+
return {
|
|
2580
|
+
async getTodo(id) {
|
|
2581
|
+
return loadMap().get(id);
|
|
2582
|
+
},
|
|
2583
|
+
async listTodos(filter) {
|
|
2584
|
+
const all = [...loadMap().values()];
|
|
2585
|
+
if (!filter?.statuses || filter.statuses.length === 0) return all;
|
|
2586
|
+
const wanted = new Set(filter.statuses);
|
|
2587
|
+
return all.filter((t2) => wanted.has(t2.status));
|
|
2588
|
+
},
|
|
2589
|
+
async putTodo(todo) {
|
|
2590
|
+
const map = loadMap();
|
|
2591
|
+
map.set(todo.id, todo);
|
|
2592
|
+
persist(map);
|
|
2593
|
+
},
|
|
2594
|
+
async deleteTodo(id) {
|
|
2595
|
+
const map = loadMap();
|
|
2596
|
+
map.delete(id);
|
|
2597
|
+
persist(map);
|
|
2598
|
+
}
|
|
2599
|
+
};
|
|
2027
2600
|
}
|
|
2028
2601
|
|
|
2029
2602
|
// packages/cli/client/cliAgentRunToolExecutors.ts
|
|
2030
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2031
2603
|
var noopOutput = { write: () => {
|
|
2032
2604
|
} };
|
|
2033
2605
|
var parseCallArgs = (call) => {
|
|
@@ -2037,7 +2609,7 @@ var parseCallArgs = (call) => {
|
|
|
2037
2609
|
return {};
|
|
2038
2610
|
}
|
|
2039
2611
|
};
|
|
2040
|
-
var resolveFs = (deps) => deps.fs ?? { existsSync, readFileSync };
|
|
2612
|
+
var resolveFs = (deps) => deps.fs ?? { existsSync: existsSync2, readFileSync: readFileSync2 };
|
|
2041
2613
|
var tailFile = (logPath, tailLines, fs) => {
|
|
2042
2614
|
if (!fs.existsSync(logPath)) return void 0;
|
|
2043
2615
|
try {
|
|
@@ -2049,6 +2621,27 @@ var tailFile = (logPath, tailLines, fs) => {
|
|
|
2049
2621
|
return void 0;
|
|
2050
2622
|
}
|
|
2051
2623
|
};
|
|
2624
|
+
var resolveBreakerStore = (deps) => deps.breakerStore ?? createFileSystemCircuitBreakerStore({ env: deps.env, homedir: deps.homedir, fs: deps.fs });
|
|
2625
|
+
var resolveTodoStore = (deps) => deps.todoStore ?? createFileSystemTodoStore({ env: deps.env, homedir: deps.homedir, fs: deps.fs });
|
|
2626
|
+
var resolveNowMs = (deps) => typeof deps.nowMs === "function" ? deps.nowMs() : Date.now();
|
|
2627
|
+
var resolveTarget = (deps, agentKey) => typeof deps.resolveProviderTarget === "function" ? deps.resolveProviderTarget(agentKey) : agentKey;
|
|
2628
|
+
function buildProgressField(record, nowMs) {
|
|
2629
|
+
const activity = record.activity;
|
|
2630
|
+
if (!activity || isAgentRunTerminalStatus(record.status)) return {};
|
|
2631
|
+
const lastEventAt = Date.parse(activity.lastEventAt ?? "");
|
|
2632
|
+
const inFlight = activity.inFlight;
|
|
2633
|
+
const progress = {
|
|
2634
|
+
toolCalls: activity.counters?.toolCalls ?? 0,
|
|
2635
|
+
llmCalls: activity.counters?.llmCalls ?? 0,
|
|
2636
|
+
fileEdits: activity.counters?.fileEdits ?? 0,
|
|
2637
|
+
...Number.isFinite(lastEventAt) ? { idleMs: Math.max(0, nowMs - lastEventAt) } : {}
|
|
2638
|
+
};
|
|
2639
|
+
if (inFlight) {
|
|
2640
|
+
progress.inFlight = inFlight.name ? `${inFlight.kind}:${inFlight.name}` : inFlight.kind;
|
|
2641
|
+
if (Number.isFinite(inFlight.sinceMs)) progress.inFlightMs = Math.max(0, inFlight.sinceMs);
|
|
2642
|
+
}
|
|
2643
|
+
return { progress };
|
|
2644
|
+
}
|
|
2052
2645
|
function createCliStartAgentRunExecutor(deps = {}) {
|
|
2053
2646
|
return async (call) => {
|
|
2054
2647
|
const args = parseCallArgs(call);
|
|
@@ -2056,6 +2649,29 @@ function createCliStartAgentRunExecutor(deps = {}) {
|
|
|
2056
2649
|
const task = typeof args.task === "string" ? args.task.trim() : "";
|
|
2057
2650
|
if (!agentKey) throw new Error("startAgentRun: \u7F3A\u5C11 agentKey \u53C2\u6570\u3002");
|
|
2058
2651
|
if (!task) throw new Error("startAgentRun: \u7F3A\u5C11\u6709\u6548\u7684 task \u6587\u672C\u63CF\u8FF0\u3002");
|
|
2652
|
+
const breakerStore = resolveBreakerStore(deps);
|
|
2653
|
+
const target = resolveTarget(deps, agentKey);
|
|
2654
|
+
const nowMs = resolveNowMs(deps);
|
|
2655
|
+
const activeBreaker = findActiveBreaker(
|
|
2656
|
+
nowMs,
|
|
2657
|
+
[breakerStore.get(target)].filter(Boolean),
|
|
2658
|
+
target
|
|
2659
|
+
);
|
|
2660
|
+
if (activeBreaker) {
|
|
2661
|
+
const resetsAt = activeBreaker.resetsAt;
|
|
2662
|
+
return {
|
|
2663
|
+
content: JSON.stringify({
|
|
2664
|
+
rejected: true,
|
|
2665
|
+
reason: "quota",
|
|
2666
|
+
provider: target,
|
|
2667
|
+
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
2668
|
+
message: `provider ${target} \u5904\u4E8E\u7194\u65AD\u671F\uFF08\u914D\u989D\u8017\u5C3D\uFF09\uFF0C\u5EFA\u8BAE\u6539\u6D3E\u5176\u5B83 provider\u3002`
|
|
2669
|
+
}),
|
|
2670
|
+
metadata: {
|
|
2671
|
+
displayData: `Run rejected \xB7 quota breaker active on ${target}`
|
|
2672
|
+
}
|
|
2673
|
+
};
|
|
2674
|
+
}
|
|
2059
2675
|
const message = typeof args.input === "undefined" ? task : `${task}
|
|
2060
2676
|
|
|
2061
2677
|
--- \u9644\u52A0\u8F93\u5165 ---
|
|
@@ -2071,13 +2687,16 @@ ${JSON.stringify(args.input)}`;
|
|
|
2071
2687
|
...args.ephemeral === true ? ["--ephemeral"] : []
|
|
2072
2688
|
];
|
|
2073
2689
|
const agentName = typeof args.agentName === "string" && args.agentName.trim() ? args.agentName.trim() : typeof args.name === "string" && args.name.trim() ? args.name.trim() : void 0;
|
|
2074
|
-
const
|
|
2690
|
+
const batchId = typeof args.batchId === "string" && args.batchId.trim() ? args.batchId.trim() : void 0;
|
|
2691
|
+
const { runId, batchId: resolvedBatchId } = await spawnLocalBackgroundRun(
|
|
2075
2692
|
{
|
|
2076
2693
|
rawArgs,
|
|
2077
2694
|
commandPath: ["agent", "run"],
|
|
2078
2695
|
cliEntrypointPath: deps.cliEntrypoint,
|
|
2079
2696
|
agentKey,
|
|
2080
2697
|
...agentName ? { agentName } : {},
|
|
2698
|
+
...batchId ? { batchId } : {},
|
|
2699
|
+
...typeof args.parentDialogId === "string" && args.parentDialogId.trim() ? { parentDialogId: args.parentDialogId.trim() } : {},
|
|
2081
2700
|
cwd: deps.cwd ?? process.cwd(),
|
|
2082
2701
|
message,
|
|
2083
2702
|
output: noopOutput
|
|
@@ -2086,14 +2705,49 @@ ${JSON.stringify(args.input)}`;
|
|
|
2086
2705
|
);
|
|
2087
2706
|
const displayName = resolveRunLabel({ agentName, agentKey, runId });
|
|
2088
2707
|
const labels = agentRunCardLabels();
|
|
2708
|
+
const taskPreview = typeof args.task === "string" ? args.task.replace(/\s+/g, " ").trim().slice(0, TASK_PREVIEW_MAX) : "";
|
|
2709
|
+
const trackTodo = typeof args.trackTodo === "boolean" ? args.trackTodo : Boolean(resolvedBatchId);
|
|
2710
|
+
if (trackTodo) {
|
|
2711
|
+
try {
|
|
2712
|
+
const todoStore = resolveTodoStore(deps);
|
|
2713
|
+
const todoId = `todo-${resolvedBatchId}`;
|
|
2714
|
+
const existing = await todoStore.getTodo(todoId);
|
|
2715
|
+
const nowIso = new Date(nowMs).toISOString();
|
|
2716
|
+
const runIds = existing?.runIds ?? [];
|
|
2717
|
+
if (!runIds.includes(runId)) runIds.push(runId);
|
|
2718
|
+
const todo = {
|
|
2719
|
+
id: todoId,
|
|
2720
|
+
title: taskPreview || task.slice(0, 100),
|
|
2721
|
+
status: existing?.status ?? "pending",
|
|
2722
|
+
...existing?.specPath ? { specPath: existing.specPath } : {},
|
|
2723
|
+
...existing?.worktree ? { worktree: existing.worktree } : {},
|
|
2724
|
+
...existing?.branch ? { branch: existing.branch } : {},
|
|
2725
|
+
...deps.cwd ? { worktree: deps.cwd } : {},
|
|
2726
|
+
runIds,
|
|
2727
|
+
deps: existing?.deps ?? [],
|
|
2728
|
+
createdAt: existing?.createdAt ?? nowIso,
|
|
2729
|
+
updatedAt: nowIso
|
|
2730
|
+
};
|
|
2731
|
+
await todoStore.putTodo(todo);
|
|
2732
|
+
} catch {
|
|
2733
|
+
}
|
|
2734
|
+
}
|
|
2089
2735
|
return {
|
|
2090
2736
|
content: JSON.stringify({
|
|
2091
2737
|
runId,
|
|
2092
2738
|
status: "running",
|
|
2093
|
-
|
|
2739
|
+
// batchId is always returned so the caller can later filter by it —
|
|
2740
|
+
// even when the caller didn't supply one, a fresh id was generated.
|
|
2741
|
+
batchId: resolvedBatchId,
|
|
2742
|
+
...agentName ? { agentName } : {},
|
|
2743
|
+
...taskPreview ? { taskPreview } : {}
|
|
2094
2744
|
}),
|
|
2095
2745
|
metadata: {
|
|
2096
|
-
displayData: formatStartRunCard(displayName, "running",
|
|
2746
|
+
displayData: formatStartRunCard(displayName, "running", {
|
|
2747
|
+
task: taskPreview,
|
|
2748
|
+
runId,
|
|
2749
|
+
labels
|
|
2750
|
+
})
|
|
2097
2751
|
}
|
|
2098
2752
|
};
|
|
2099
2753
|
};
|
|
@@ -2104,26 +2758,103 @@ function createCliControlAgentRunExecutor(deps = {}) {
|
|
|
2104
2758
|
const action = typeof args.action === "string" ? args.action : "";
|
|
2105
2759
|
const tailLines = typeof args.tailLines === "number" ? args.tailLines : 0;
|
|
2106
2760
|
if (action === "list") {
|
|
2107
|
-
|
|
2761
|
+
gcRunRecords(deps);
|
|
2762
|
+
const { runs: records, total, hasMore } = queryRunRecords(
|
|
2763
|
+
{
|
|
2764
|
+
...typeof args.batchId === "string" && args.batchId.trim() ? { batchId: args.batchId.trim() } : {},
|
|
2765
|
+
...typeof args.status === "string" && args.status.trim() ? { status: args.status.trim() } : typeof args.statusFilter === "string" && args.statusFilter.trim() ? { status: args.statusFilter.trim() } : {},
|
|
2766
|
+
...typeof args.limit === "number" ? { limit: args.limit } : {},
|
|
2767
|
+
...typeof args.offset === "number" ? { offset: args.offset } : {}
|
|
2768
|
+
},
|
|
2769
|
+
deps
|
|
2770
|
+
);
|
|
2108
2771
|
const runs = records.map((record2) => {
|
|
2109
|
-
const reconciled = checkStaleRun(record2.runId, deps) ?? record2;
|
|
2110
2772
|
return {
|
|
2111
|
-
runId:
|
|
2112
|
-
status:
|
|
2113
|
-
agentKey:
|
|
2114
|
-
...
|
|
2115
|
-
|
|
2116
|
-
|
|
2773
|
+
runId: record2.runId,
|
|
2774
|
+
status: record2.status,
|
|
2775
|
+
agentKey: record2.agentKey,
|
|
2776
|
+
...record2.agentName ? { agentName: record2.agentName } : {},
|
|
2777
|
+
...record2.batchId ? { batchId: record2.batchId } : {},
|
|
2778
|
+
pid: record2.pid ?? null,
|
|
2779
|
+
startedAt: record2.startedAt
|
|
2117
2780
|
};
|
|
2118
2781
|
});
|
|
2119
2782
|
const labels2 = agentRunCardLabels();
|
|
2783
|
+
const batchIdArg = typeof args.batchId === "string" && args.batchId.trim() ? args.batchId.trim() : void 0;
|
|
2784
|
+
let batchSummary;
|
|
2785
|
+
if (batchIdArg && records.length > 0) {
|
|
2786
|
+
const batchRuns = records.map((r) => ({
|
|
2787
|
+
runId: r.runId,
|
|
2788
|
+
status: r.status,
|
|
2789
|
+
startedAt: r.startedAt,
|
|
2790
|
+
...r.agentName ? { agentName: r.agentName } : {}
|
|
2791
|
+
}));
|
|
2792
|
+
batchSummary = aggregateBatch({
|
|
2793
|
+
batchId: batchIdArg,
|
|
2794
|
+
runs: batchRuns,
|
|
2795
|
+
now: new Date(resolveNowMs(deps)).toISOString()
|
|
2796
|
+
});
|
|
2797
|
+
}
|
|
2120
2798
|
return {
|
|
2121
|
-
content: JSON.stringify({
|
|
2799
|
+
content: JSON.stringify({
|
|
2800
|
+
runs,
|
|
2801
|
+
count: runs.length,
|
|
2802
|
+
total,
|
|
2803
|
+
hasMore,
|
|
2804
|
+
...batchSummary?.summary ? { batchSummary: batchSummary.summary } : {}
|
|
2805
|
+
}),
|
|
2122
2806
|
metadata: {
|
|
2123
2807
|
displayData: formatListRunsCard(runs, labels2)
|
|
2124
2808
|
}
|
|
2125
2809
|
};
|
|
2126
2810
|
}
|
|
2811
|
+
if (action === "todo") {
|
|
2812
|
+
const todoStore = resolveTodoStore(deps);
|
|
2813
|
+
const statusesRaw = typeof args.status === "string" ? args.status.trim() : void 0;
|
|
2814
|
+
const filter = statusesRaw && statusesRaw !== "all" ? { statuses: statusesRaw.split(",").map((s) => s.trim()).filter(Boolean) } : void 0;
|
|
2815
|
+
const todos = await todoStore.listTodos(filter);
|
|
2816
|
+
const enriched = await Promise.all(
|
|
2817
|
+
todos.map(async (todo) => {
|
|
2818
|
+
const runSummaries = [];
|
|
2819
|
+
for (const rid of todo.runIds) {
|
|
2820
|
+
const rec = findRunRecord(rid, deps);
|
|
2821
|
+
if (!rec) continue;
|
|
2822
|
+
runSummaries.push({
|
|
2823
|
+
runId: rec.runId,
|
|
2824
|
+
status: rec.status,
|
|
2825
|
+
startedAt: rec.startedAt,
|
|
2826
|
+
...rec.agentName ? { agentName: rec.agentName } : {}
|
|
2827
|
+
});
|
|
2828
|
+
}
|
|
2829
|
+
const derived = deriveTodoStatus({
|
|
2830
|
+
todo: { id: todo.id, status: todo.status },
|
|
2831
|
+
runs: runSummaries,
|
|
2832
|
+
now: new Date(resolveNowMs(deps)).toISOString()
|
|
2833
|
+
});
|
|
2834
|
+
return {
|
|
2835
|
+
id: todo.id,
|
|
2836
|
+
title: todo.title,
|
|
2837
|
+
status: derived.status,
|
|
2838
|
+
runIds: todo.runIds,
|
|
2839
|
+
...derived.blockedReason ? { blockedReason: derived.blockedReason } : {},
|
|
2840
|
+
...derived.latestRun ? { latestRunId: derived.latestRun.runId, latestRunStatus: derived.latestRun.status } : {},
|
|
2841
|
+
updatedAt: todo.updatedAt
|
|
2842
|
+
};
|
|
2843
|
+
})
|
|
2844
|
+
);
|
|
2845
|
+
return {
|
|
2846
|
+
content: JSON.stringify({ todos: enriched, count: enriched.length }),
|
|
2847
|
+
metadata: {
|
|
2848
|
+
displayData: formatListRunsCard(
|
|
2849
|
+
enriched.map((t2) => ({
|
|
2850
|
+
agentName: t2.title,
|
|
2851
|
+
status: t2.status
|
|
2852
|
+
})),
|
|
2853
|
+
agentRunCardLabels()
|
|
2854
|
+
)
|
|
2855
|
+
}
|
|
2856
|
+
};
|
|
2857
|
+
}
|
|
2127
2858
|
if (action !== "status" && action !== "stop") {
|
|
2128
2859
|
throw new Error(`controlAgentRun: \u672A\u77E5 action "${action}"\u3002`);
|
|
2129
2860
|
}
|
|
@@ -2142,6 +2873,25 @@ function createCliControlAgentRunExecutor(deps = {}) {
|
|
|
2142
2873
|
const name = resolveRunLabel(reconciled);
|
|
2143
2874
|
const logLines = logTail ? logTail.split("\n") : void 0;
|
|
2144
2875
|
const labels2 = agentRunCardLabels();
|
|
2876
|
+
if (reconciled.status === "failed" || reconciled.status === "orphaned") {
|
|
2877
|
+
try {
|
|
2878
|
+
const failureSource = logTail ?? reconciled.note ?? "";
|
|
2879
|
+
const failureInfo = classifyRunFailure(
|
|
2880
|
+
failureSource || reconciled.status
|
|
2881
|
+
);
|
|
2882
|
+
if (failureInfo.reason === "quota") {
|
|
2883
|
+
const t2 = resolveTarget(deps, reconciled.agentKey);
|
|
2884
|
+
const entry = buildBreakerEntry(
|
|
2885
|
+
resolveNowMs(deps),
|
|
2886
|
+
t2,
|
|
2887
|
+
"quota",
|
|
2888
|
+
failureInfo.retryAfterMs
|
|
2889
|
+
);
|
|
2890
|
+
resolveBreakerStore(deps).set(entry);
|
|
2891
|
+
}
|
|
2892
|
+
} catch {
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2145
2895
|
return {
|
|
2146
2896
|
content: JSON.stringify({
|
|
2147
2897
|
runId: reconciled.runId,
|
|
@@ -2162,11 +2912,26 @@ function createCliControlAgentRunExecutor(deps = {}) {
|
|
|
2162
2912
|
// indistinguishable from a hung run without this field. Surfacing
|
|
2163
2913
|
// dialogId gives the caller a reliable way to fetch the result.
|
|
2164
2914
|
...reconciled.dialogId ? { dialogId: reconciled.dialogId } : {},
|
|
2915
|
+
// Progress is what makes tailLines:0 an actual answer to "is it
|
|
2916
|
+
// stuck?". Without it a poll returns `running` and a pid, so the only
|
|
2917
|
+
// way to tell a working run from a wedged one was to pull 30 lines of
|
|
2918
|
+
// log — the exact thing the orchestration prompt tells the model not
|
|
2919
|
+
// to do. The registry has been recording this all along and `nolo
|
|
2920
|
+
// agent status` has been printing it; only the tool was blind.
|
|
2921
|
+
...buildProgressField(reconciled, resolveNowMs(deps)),
|
|
2165
2922
|
...logTail !== void 0 ? { logTail } : {},
|
|
2166
2923
|
...logLines ? { logLines } : {}
|
|
2167
2924
|
}),
|
|
2168
2925
|
metadata: {
|
|
2169
|
-
displayData: formatStatusRunCard(name, reconciled.status, {
|
|
2926
|
+
displayData: formatStatusRunCard(name, reconciled.status, {
|
|
2927
|
+
runId: reconciled.runId,
|
|
2928
|
+
timing: {
|
|
2929
|
+
startedAt: readTimestamp(reconciled.startedAt),
|
|
2930
|
+
finishedAt: readTimestamp(reconciled.endedAt)
|
|
2931
|
+
},
|
|
2932
|
+
logLines,
|
|
2933
|
+
labels: labels2
|
|
2934
|
+
})
|
|
2170
2935
|
}
|
|
2171
2936
|
};
|
|
2172
2937
|
}
|
|
@@ -2304,7 +3069,7 @@ function buildLocalToolExecutors(args) {
|
|
|
2304
3069
|
}
|
|
2305
3070
|
};
|
|
2306
3071
|
},
|
|
2307
|
-
|
|
3072
|
+
ask_user: async (call) => {
|
|
2308
3073
|
const parsedArgs = (() => {
|
|
2309
3074
|
try {
|
|
2310
3075
|
return JSON.parse(call.arguments || "{}");
|
|
@@ -2320,8 +3085,8 @@ function buildLocalToolExecutors(args) {
|
|
|
2320
3085
|
if (!hasQuestions && (!question || choices.length === 0)) {
|
|
2321
3086
|
return {
|
|
2322
3087
|
content: JSON.stringify({
|
|
2323
|
-
error: "
|
|
2324
|
-
detail: "
|
|
3088
|
+
error: "ask_user",
|
|
3089
|
+
detail: "ask_user \u9700\u8981 question+choices \u6216 questions\u3002"
|
|
2325
3090
|
}),
|
|
2326
3091
|
metadata: { uiAskChoice: true, error: true }
|
|
2327
3092
|
};
|
|
@@ -2337,7 +3102,7 @@ function buildLocalToolExecutors(args) {
|
|
|
2337
3102
|
if (result.kind === "multi-submitted") {
|
|
2338
3103
|
return {
|
|
2339
3104
|
content: JSON.stringify({
|
|
2340
|
-
type: "
|
|
3105
|
+
type: "ask_user",
|
|
2341
3106
|
question,
|
|
2342
3107
|
choices,
|
|
2343
3108
|
blocking,
|
|
@@ -2354,7 +3119,7 @@ function buildLocalToolExecutors(args) {
|
|
|
2354
3119
|
if (result.kind === "selected") {
|
|
2355
3120
|
return {
|
|
2356
3121
|
content: JSON.stringify({
|
|
2357
|
-
type: "
|
|
3122
|
+
type: "ask_user",
|
|
2358
3123
|
question,
|
|
2359
3124
|
choices,
|
|
2360
3125
|
blocking,
|
|
@@ -2369,7 +3134,7 @@ function buildLocalToolExecutors(args) {
|
|
|
2369
3134
|
}
|
|
2370
3135
|
return {
|
|
2371
3136
|
content: JSON.stringify({
|
|
2372
|
-
type: "
|
|
3137
|
+
type: "ask_user",
|
|
2373
3138
|
question,
|
|
2374
3139
|
choices,
|
|
2375
3140
|
blocking,
|
|
@@ -2384,7 +3149,7 @@ function buildLocalToolExecutors(args) {
|
|
|
2384
3149
|
}
|
|
2385
3150
|
return {
|
|
2386
3151
|
content: JSON.stringify({
|
|
2387
|
-
type: "
|
|
3152
|
+
type: "ask_user",
|
|
2388
3153
|
question,
|
|
2389
3154
|
choices,
|
|
2390
3155
|
blocking,
|
|
@@ -2448,19 +3213,22 @@ function resolveAntigravityWireModel(logicalModelId) {
|
|
|
2448
3213
|
return { wireModelId: id };
|
|
2449
3214
|
}
|
|
2450
3215
|
|
|
2451
|
-
// packages/agent-runtime/
|
|
2452
|
-
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
3216
|
+
// packages/agent-runtime/geminiNativeShared.ts
|
|
2453
3217
|
var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
|
|
2454
|
-
function
|
|
3218
|
+
function isGemini3Model(modelId) {
|
|
2455
3219
|
return modelId.includes("gemini-3");
|
|
2456
3220
|
}
|
|
2457
3221
|
function messageText(content) {
|
|
2458
3222
|
if (typeof content === "string") return content;
|
|
2459
3223
|
if (!Array.isArray(content)) return "";
|
|
2460
|
-
return content.filter(
|
|
3224
|
+
return content.filter(
|
|
3225
|
+
(part) => part?.type === "text"
|
|
3226
|
+
).map((part) => part.text).join("\n").trim();
|
|
2461
3227
|
}
|
|
2462
3228
|
function parseDataUrlToInlineData(url) {
|
|
2463
|
-
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
3229
|
+
const match = /^data:([A-Za-z0-9.+-]+\/[A-Za-z0-9.+-]+);base64,([A-Za-z0-9+/=]*)$/.exec(
|
|
3230
|
+
url
|
|
3231
|
+
);
|
|
2464
3232
|
if (!match) return null;
|
|
2465
3233
|
return { mimeType: match[1], data: match[2] };
|
|
2466
3234
|
}
|
|
@@ -2477,7 +3245,7 @@ function extractInlineDataParts(content) {
|
|
|
2477
3245
|
}
|
|
2478
3246
|
return parts;
|
|
2479
3247
|
}
|
|
2480
|
-
function
|
|
3248
|
+
function convertOpenAiMessagesToGemini(messages, options) {
|
|
2481
3249
|
const contents = [];
|
|
2482
3250
|
const systemTexts = [];
|
|
2483
3251
|
const toolNamesById = /* @__PURE__ */ new Map();
|
|
@@ -2493,9 +3261,11 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2493
3261
|
};
|
|
2494
3262
|
const flushPendingFunctionCalls = () => {
|
|
2495
3263
|
if (pendingFunctionCalls.length === 0) return;
|
|
2496
|
-
const dummyResponses = pendingFunctionCalls.map(
|
|
2497
|
-
|
|
2498
|
-
|
|
3264
|
+
const dummyResponses = pendingFunctionCalls.map(
|
|
3265
|
+
({ name }) => ({
|
|
3266
|
+
functionResponse: { name, response: { output: "{}" } }
|
|
3267
|
+
})
|
|
3268
|
+
);
|
|
2499
3269
|
pendingFunctionCalls = [];
|
|
2500
3270
|
pushOrMergeContent("user", dummyResponses);
|
|
2501
3271
|
};
|
|
@@ -2504,13 +3274,17 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2504
3274
|
const role = String(raw.role);
|
|
2505
3275
|
const content = "content" in raw ? raw.content : null;
|
|
2506
3276
|
if (role === "system") {
|
|
2507
|
-
const text = messageText(
|
|
3277
|
+
const text = messageText(
|
|
3278
|
+
content
|
|
3279
|
+
);
|
|
2508
3280
|
if (text) systemTexts.push(text);
|
|
2509
3281
|
continue;
|
|
2510
3282
|
}
|
|
2511
3283
|
if (role === "user") {
|
|
2512
3284
|
flushPendingFunctionCalls();
|
|
2513
|
-
const text = messageText(
|
|
3285
|
+
const text = messageText(
|
|
3286
|
+
content
|
|
3287
|
+
);
|
|
2514
3288
|
const imageParts = extractInlineDataParts(
|
|
2515
3289
|
content
|
|
2516
3290
|
);
|
|
@@ -2524,7 +3298,9 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2524
3298
|
if (role === "assistant") {
|
|
2525
3299
|
flushPendingFunctionCalls();
|
|
2526
3300
|
const parts = [];
|
|
2527
|
-
const text = messageText(
|
|
3301
|
+
const text = messageText(
|
|
3302
|
+
content
|
|
3303
|
+
);
|
|
2528
3304
|
if (text) parts.push({ text });
|
|
2529
3305
|
const toolCalls = "tool_calls" in raw && Array.isArray(raw.tool_calls) ? raw.tool_calls ?? [] : [];
|
|
2530
3306
|
for (const call of toolCalls) {
|
|
@@ -2534,17 +3310,20 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2534
3310
|
toolNamesById.set(id, name);
|
|
2535
3311
|
pendingFunctionCalls.push({ name, id });
|
|
2536
3312
|
const realSignature = typeof call.thought_signature === "string" && call.thought_signature ? call.thought_signature : void 0;
|
|
2537
|
-
const isFirstFunctionCallPart = !parts.some(
|
|
2538
|
-
|
|
3313
|
+
const isFirstFunctionCallPart = !parts.some(
|
|
3314
|
+
(p) => "functionCall" in p
|
|
3315
|
+
);
|
|
3316
|
+
const signature = realSignature ?? (options.attachSkipThoughtSignature && isFirstFunctionCallPart ? SKIP_THOUGHT_SIGNATURE : void 0);
|
|
3317
|
+
const part = {
|
|
2539
3318
|
functionCall: {
|
|
2540
3319
|
name,
|
|
2541
|
-
args:
|
|
2542
|
-
id
|
|
3320
|
+
args: parseToolArgs(call.function?.arguments),
|
|
3321
|
+
...id ? { id } : {}
|
|
2543
3322
|
},
|
|
2544
|
-
...
|
|
2545
|
-
}
|
|
3323
|
+
...signature ? { thoughtSignature: signature } : {}
|
|
3324
|
+
};
|
|
3325
|
+
parts.push(part);
|
|
2546
3326
|
}
|
|
2547
|
-
if (parts.length === 0) continue;
|
|
2548
3327
|
pushOrMergeContent("model", parts);
|
|
2549
3328
|
continue;
|
|
2550
3329
|
}
|
|
@@ -2562,14 +3341,39 @@ function convertOpenAiMessagesToCca(messages, options) {
|
|
|
2562
3341
|
}
|
|
2563
3342
|
const output = messageText(content) || "{}";
|
|
2564
3343
|
pushOrMergeContent("user", [
|
|
2565
|
-
{
|
|
3344
|
+
{
|
|
3345
|
+
functionResponse: {
|
|
3346
|
+
name,
|
|
3347
|
+
response: { output },
|
|
3348
|
+
// 保留 OpenAI tool_call_id:antigravity Cloud Code Assist 网关把
|
|
3349
|
+
// Gemini contents 转成 Claude messages 时需要 functionResponse →
|
|
3350
|
+
// tool_result 的 tool_use_id;缺 id 时网关报
|
|
3351
|
+
// "tool_result.tool_use_id: Field required"(HTTP 400)。
|
|
3352
|
+
...toolCallId ? { id: toolCallId } : {}
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
2566
3355
|
]);
|
|
2567
3356
|
}
|
|
2568
3357
|
}
|
|
2569
3358
|
flushPendingFunctionCalls();
|
|
2570
3359
|
return { contents, systemTexts };
|
|
2571
3360
|
}
|
|
2572
|
-
function
|
|
3361
|
+
function parseToolArgs(raw) {
|
|
3362
|
+
if (typeof raw === "string") {
|
|
3363
|
+
try {
|
|
3364
|
+
const parsed = JSON.parse(raw);
|
|
3365
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3366
|
+
return parsed;
|
|
3367
|
+
}
|
|
3368
|
+
} catch {
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
3372
|
+
return raw;
|
|
3373
|
+
}
|
|
3374
|
+
return {};
|
|
3375
|
+
}
|
|
3376
|
+
function convertOpenAiToolsToGemini(tools) {
|
|
2573
3377
|
if (!Array.isArray(tools) || tools.length === 0) return void 0;
|
|
2574
3378
|
const declarations = [];
|
|
2575
3379
|
for (const tool of tools) {
|
|
@@ -2586,79 +3390,7 @@ function convertOpenAiTools(tools) {
|
|
|
2586
3390
|
if (declarations.length === 0) return void 0;
|
|
2587
3391
|
return [{ functionDeclarations: declarations }];
|
|
2588
3392
|
}
|
|
2589
|
-
function
|
|
2590
|
-
const projectId = readAntigravityProjectId(args.metadata);
|
|
2591
|
-
if (!projectId) {
|
|
2592
|
-
throw new Error(
|
|
2593
|
-
"Antigravity OAuth credential is missing metadata.projectId. Re-run `nolo auth antigravity`."
|
|
2594
|
-
);
|
|
2595
|
-
}
|
|
2596
|
-
const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
|
|
2597
|
-
const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
|
|
2598
|
-
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
2599
|
-
const { contents, systemTexts } = convertOpenAiMessagesToCca(rawMessages, {
|
|
2600
|
-
attachSkipThoughtSignature: isGemini3WireModel(model)
|
|
2601
|
-
});
|
|
2602
|
-
if (contents.length === 0) {
|
|
2603
|
-
throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
|
|
2604
|
-
}
|
|
2605
|
-
const prompt = args.agentConfig.prompt?.trim();
|
|
2606
|
-
if (prompt) systemTexts.unshift(prompt);
|
|
2607
|
-
const request = { contents };
|
|
2608
|
-
if (systemTexts.length > 0) {
|
|
2609
|
-
request.systemInstruction = {
|
|
2610
|
-
role: "user",
|
|
2611
|
-
parts: systemTexts.map((text) => ({ text }))
|
|
2612
|
-
};
|
|
2613
|
-
}
|
|
2614
|
-
const tools = convertOpenAiTools(
|
|
2615
|
-
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
2616
|
-
);
|
|
2617
|
-
if (tools) {
|
|
2618
|
-
request.tools = tools;
|
|
2619
|
-
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
2620
|
-
}
|
|
2621
|
-
const generationConfig = {};
|
|
2622
|
-
if (profile?.maxOutputTokens) {
|
|
2623
|
-
generationConfig.maxOutputTokens = profile.maxOutputTokens;
|
|
2624
|
-
} else if (typeof args.agentConfig.max_tokens === "number" && args.agentConfig.max_tokens > 0) {
|
|
2625
|
-
generationConfig.maxOutputTokens = args.agentConfig.max_tokens;
|
|
2626
|
-
}
|
|
2627
|
-
if (typeof args.agentConfig.temperature === "number") {
|
|
2628
|
-
generationConfig.temperature = args.agentConfig.temperature;
|
|
2629
|
-
}
|
|
2630
|
-
if (Object.keys(generationConfig).length > 0) {
|
|
2631
|
-
request.generationConfig = generationConfig;
|
|
2632
|
-
}
|
|
2633
|
-
const agentId = randomUUID();
|
|
2634
|
-
const trajectoryId = randomUUID();
|
|
2635
|
-
const step = 2;
|
|
2636
|
-
const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
|
|
2637
|
-
const isClaude = model.toLowerCase().includes("claude");
|
|
2638
|
-
const labels = {
|
|
2639
|
-
trajectory_id: trajectoryId,
|
|
2640
|
-
last_step_index: String(step - 1),
|
|
2641
|
-
used_claude: String(isClaude),
|
|
2642
|
-
used_claude_conservative: String(isClaude)
|
|
2643
|
-
};
|
|
2644
|
-
if (profile?.modelEnum) {
|
|
2645
|
-
labels.model_enum = profile.modelEnum;
|
|
2646
|
-
}
|
|
2647
|
-
request.labels = labels;
|
|
2648
|
-
request.sessionId = `-${Math.floor(Math.random() * 9e15)}`;
|
|
2649
|
-
return {
|
|
2650
|
-
url: `${resolveAntigravityCloudCodeBaseUrl(args.agentConfig.customProviderUrl)}${STREAM_PATH}`,
|
|
2651
|
-
envelope: {
|
|
2652
|
-
project: projectId,
|
|
2653
|
-
model,
|
|
2654
|
-
request,
|
|
2655
|
-
requestId,
|
|
2656
|
-
requestType: "agent",
|
|
2657
|
-
userAgent: "antigravity"
|
|
2658
|
-
}
|
|
2659
|
-
};
|
|
2660
|
-
}
|
|
2661
|
-
function accumulateCcaChunks(chunks) {
|
|
3393
|
+
function accumulateGeminiChunks(chunks) {
|
|
2662
3394
|
let text = "";
|
|
2663
3395
|
const toolCalls = [];
|
|
2664
3396
|
let usage;
|
|
@@ -2679,11 +3411,10 @@ function accumulateCcaChunks(chunks) {
|
|
|
2679
3411
|
}
|
|
2680
3412
|
const candidates = Array.isArray(response.candidates) ? response.candidates : [];
|
|
2681
3413
|
for (const candidate of candidates) {
|
|
2682
|
-
if (!candidate || typeof candidate !== "object"
|
|
2683
|
-
const
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
if (!Array.isArray(parts)) continue;
|
|
3414
|
+
if (!candidate || typeof candidate !== "object") continue;
|
|
3415
|
+
const parts = Array.isArray(
|
|
3416
|
+
candidate.content?.parts
|
|
3417
|
+
) ? candidate.content.parts : [];
|
|
2687
3418
|
for (const part of parts) {
|
|
2688
3419
|
if (!part || typeof part !== "object") continue;
|
|
2689
3420
|
const partSignature = part.thoughtSignature;
|
|
@@ -2700,7 +3431,7 @@ function accumulateCcaChunks(chunks) {
|
|
|
2700
3431
|
const call = part.functionCall;
|
|
2701
3432
|
const name = typeof call.name === "string" ? call.name : "tool";
|
|
2702
3433
|
const id = typeof call.id === "string" ? call.id : `${name}_${toolCalls.length}`;
|
|
2703
|
-
const argsObj =
|
|
3434
|
+
const argsObj = call.args && typeof call.args === "object" ? call.args : {};
|
|
2704
3435
|
const resolvedSignature = typeof partSignature === "string" && partSignature ? partSignature : pendingThoughtSignature;
|
|
2705
3436
|
pendingThoughtSignature = void 0;
|
|
2706
3437
|
toolCalls.push({
|
|
@@ -2713,7 +3444,114 @@ function accumulateCcaChunks(chunks) {
|
|
|
2713
3444
|
}
|
|
2714
3445
|
}
|
|
2715
3446
|
}
|
|
2716
|
-
return { text, toolCalls, usage };
|
|
3447
|
+
return { text, toolCalls, usage };
|
|
3448
|
+
}
|
|
3449
|
+
function shouldUseGeminiNativeToolRoute(provider, model, tools, isImageModel) {
|
|
3450
|
+
return provider === "google" && !isImageModel(model) && isGemini3Model(model) && Array.isArray(tools) && tools.length > 0;
|
|
3451
|
+
}
|
|
3452
|
+
function buildGeminiGenerateContentRequest(args) {
|
|
3453
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(
|
|
3454
|
+
args.messages,
|
|
3455
|
+
{ attachSkipThoughtSignature: args.attachSkipThoughtSignature }
|
|
3456
|
+
);
|
|
3457
|
+
const request = { contents };
|
|
3458
|
+
if (systemTexts.length > 0) {
|
|
3459
|
+
request.systemInstruction = {
|
|
3460
|
+
role: "user",
|
|
3461
|
+
parts: systemTexts.map((text) => ({ text }))
|
|
3462
|
+
};
|
|
3463
|
+
}
|
|
3464
|
+
const toolsResult = convertOpenAiToolsToGemini(args.tools);
|
|
3465
|
+
if (toolsResult) {
|
|
3466
|
+
request.tools = toolsResult;
|
|
3467
|
+
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
3468
|
+
}
|
|
3469
|
+
const generationConfig = {};
|
|
3470
|
+
if (typeof args.maxTokens === "number" && args.maxTokens > 0) {
|
|
3471
|
+
generationConfig.maxOutputTokens = args.maxTokens;
|
|
3472
|
+
}
|
|
3473
|
+
if (typeof args.temperature === "number") {
|
|
3474
|
+
generationConfig.temperature = args.temperature;
|
|
3475
|
+
}
|
|
3476
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
3477
|
+
request.generationConfig = generationConfig;
|
|
3478
|
+
}
|
|
3479
|
+
return request;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
// packages/agent-runtime/antigravityCloudCodeProvider.ts
|
|
3483
|
+
var STREAM_PATH = "/v1internal:streamGenerateContent?alt=sse";
|
|
3484
|
+
function buildCloudCodeAssistPayload(args) {
|
|
3485
|
+
const projectId = readAntigravityProjectId(args.metadata);
|
|
3486
|
+
if (!projectId) {
|
|
3487
|
+
throw new Error(
|
|
3488
|
+
"Antigravity OAuth credential is missing metadata.projectId. Re-run `nolo auth antigravity`."
|
|
3489
|
+
);
|
|
3490
|
+
}
|
|
3491
|
+
const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
|
|
3492
|
+
const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
|
|
3493
|
+
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
3494
|
+
const isClaude = model.toLowerCase().includes("claude");
|
|
3495
|
+
const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
|
|
3496
|
+
attachSkipThoughtSignature: isGemini3Model(model)
|
|
3497
|
+
});
|
|
3498
|
+
if (contents.length === 0) {
|
|
3499
|
+
throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
|
|
3500
|
+
}
|
|
3501
|
+
const prompt = args.agentConfig.prompt?.trim();
|
|
3502
|
+
if (prompt) systemTexts.unshift(prompt);
|
|
3503
|
+
const request = { contents };
|
|
3504
|
+
if (systemTexts.length > 0) {
|
|
3505
|
+
request.systemInstruction = {
|
|
3506
|
+
role: "user",
|
|
3507
|
+
parts: systemTexts.map((text) => ({ text }))
|
|
3508
|
+
};
|
|
3509
|
+
}
|
|
3510
|
+
const tools = convertOpenAiToolsToGemini(
|
|
3511
|
+
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
3512
|
+
);
|
|
3513
|
+
if (tools) {
|
|
3514
|
+
request.tools = tools;
|
|
3515
|
+
request.toolConfig = { functionCallingConfig: { mode: "VALIDATED" } };
|
|
3516
|
+
}
|
|
3517
|
+
const generationConfig = {};
|
|
3518
|
+
if (profile?.maxOutputTokens) {
|
|
3519
|
+
generationConfig.maxOutputTokens = profile.maxOutputTokens;
|
|
3520
|
+
} else if (typeof args.agentConfig.max_tokens === "number" && args.agentConfig.max_tokens > 0) {
|
|
3521
|
+
generationConfig.maxOutputTokens = args.agentConfig.max_tokens;
|
|
3522
|
+
}
|
|
3523
|
+
if (typeof args.agentConfig.temperature === "number") {
|
|
3524
|
+
generationConfig.temperature = args.agentConfig.temperature;
|
|
3525
|
+
}
|
|
3526
|
+
if (Object.keys(generationConfig).length > 0) {
|
|
3527
|
+
request.generationConfig = generationConfig;
|
|
3528
|
+
}
|
|
3529
|
+
const agentId = randomUUID();
|
|
3530
|
+
const trajectoryId = randomUUID();
|
|
3531
|
+
const step = 2;
|
|
3532
|
+
const requestId = `agent/${agentId}/${Date.now()}/${trajectoryId}/${step}`;
|
|
3533
|
+
const labels = {
|
|
3534
|
+
trajectory_id: trajectoryId,
|
|
3535
|
+
last_step_index: String(step - 1),
|
|
3536
|
+
used_claude: String(isClaude),
|
|
3537
|
+
used_claude_conservative: String(isClaude)
|
|
3538
|
+
};
|
|
3539
|
+
if (profile?.modelEnum) {
|
|
3540
|
+
labels.model_enum = profile.modelEnum;
|
|
3541
|
+
}
|
|
3542
|
+
request.labels = labels;
|
|
3543
|
+
request.sessionId = `-${Math.floor(Math.random() * 9e15)}`;
|
|
3544
|
+
return {
|
|
3545
|
+
url: `${resolveAntigravityCloudCodeBaseUrl(args.agentConfig.customProviderUrl)}${STREAM_PATH}`,
|
|
3546
|
+
envelope: {
|
|
3547
|
+
project: projectId,
|
|
3548
|
+
model,
|
|
3549
|
+
request,
|
|
3550
|
+
requestId,
|
|
3551
|
+
requestType: "agent",
|
|
3552
|
+
userAgent: "antigravity"
|
|
3553
|
+
}
|
|
3554
|
+
};
|
|
2717
3555
|
}
|
|
2718
3556
|
async function readSseJsonChunks(response) {
|
|
2719
3557
|
return readSseDataValues(response, parseSseDataLineJson);
|
|
@@ -2739,7 +3577,7 @@ async function fetchAntigravityCloudCodeCompletion(args) {
|
|
|
2739
3577
|
};
|
|
2740
3578
|
}
|
|
2741
3579
|
const chunks = await readSseJsonChunks(response);
|
|
2742
|
-
const { text, toolCalls, usage } =
|
|
3580
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
2743
3581
|
const message = {
|
|
2744
3582
|
role: "assistant",
|
|
2745
3583
|
content: text || null
|
|
@@ -2775,9 +3613,67 @@ var CLAUDE_CODE_IDENTITY_PATTERNS = [
|
|
|
2775
3613
|
CLAUDE_CODE_SYSTEM_INSTRUCTION,
|
|
2776
3614
|
"You are Claude Code"
|
|
2777
3615
|
];
|
|
3616
|
+
var REASONING_EFFORT_TO_BUDGET = {
|
|
3617
|
+
minimal: 2048,
|
|
3618
|
+
low: 4096,
|
|
3619
|
+
medium: 8192,
|
|
3620
|
+
high: 16384,
|
|
3621
|
+
xhigh: 32e3,
|
|
3622
|
+
max: 32e3
|
|
3623
|
+
};
|
|
3624
|
+
function resolveThinkingBudget(effort) {
|
|
3625
|
+
if (!effort) return void 0;
|
|
3626
|
+
const normalized = effort.toLowerCase();
|
|
3627
|
+
if (normalized === "none" || normalized === "off") return void 0;
|
|
3628
|
+
return REASONING_EFFORT_TO_BUDGET[normalized];
|
|
3629
|
+
}
|
|
3630
|
+
var DEFAULT_THINKING_EFFORT = "medium";
|
|
3631
|
+
var DEFAULT_ENABLED_BUDGET = 8192;
|
|
3632
|
+
var DEFAULT_ENABLE_THINKING_BUDGET = 8e3;
|
|
3633
|
+
var ANTHROPIC_EFFORT_ALIASES = { minimal: "low" };
|
|
3634
|
+
function resolveThinkingSpec(input) {
|
|
3635
|
+
const { model, maxTokens } = input;
|
|
3636
|
+
const normalizedEffort = input.reasoningEffort?.toLowerCase();
|
|
3637
|
+
const effortDisabled = normalizedEffort === "none" || normalizedEffort === "off";
|
|
3638
|
+
const effectiveEffort = normalizedEffort !== void 0 && !effortDisabled ? ANTHROPIC_EFFORT_ALIASES[normalizedEffort] ?? normalizedEffort : DEFAULT_THINKING_EFFORT;
|
|
3639
|
+
let thinkingBlock;
|
|
3640
|
+
let outputConfig;
|
|
3641
|
+
let finalMaxTokens = maxTokens;
|
|
3642
|
+
let finalTemperature = input.temperature;
|
|
3643
|
+
if (isAdaptiveThinkingModelId(model)) {
|
|
3644
|
+
if (effortDisabled) {
|
|
3645
|
+
thinkingBlock = { type: "disabled" };
|
|
3646
|
+
} else {
|
|
3647
|
+
thinkingBlock = { type: "adaptive", display: "summarized" };
|
|
3648
|
+
outputConfig = { effort: effectiveEffort };
|
|
3649
|
+
}
|
|
3650
|
+
} else {
|
|
3651
|
+
const injected = input.injectedThinking;
|
|
3652
|
+
const injectedBudget = injected?.type === "enabled" && typeof injected.budget_tokens === "number" ? injected.budget_tokens : void 0;
|
|
3653
|
+
const effortBudget = resolveThinkingBudget(input.reasoningEffort);
|
|
3654
|
+
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;
|
|
3655
|
+
const thinkingBudget = effortBudget ?? fallbackBudget;
|
|
3656
|
+
if (thinkingBudget !== void 0) {
|
|
3657
|
+
thinkingBlock = { type: "enabled", budget_tokens: thinkingBudget };
|
|
3658
|
+
finalMaxTokens = Math.max(maxTokens, thinkingBudget + 1);
|
|
3659
|
+
finalTemperature = 1;
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
return {
|
|
3663
|
+
thinkingBlock,
|
|
3664
|
+
outputConfig,
|
|
3665
|
+
maxTokens: finalMaxTokens,
|
|
3666
|
+
temperature: finalTemperature
|
|
3667
|
+
};
|
|
3668
|
+
}
|
|
2778
3669
|
function stringValue(value) {
|
|
2779
3670
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2780
3671
|
}
|
|
3672
|
+
function isCacheControl(value) {
|
|
3673
|
+
return Boolean(
|
|
3674
|
+
value && typeof value === "object" && !Array.isArray(value) && typeof value.type === "string"
|
|
3675
|
+
);
|
|
3676
|
+
}
|
|
2781
3677
|
function toAnthropicContent(content) {
|
|
2782
3678
|
if (typeof content === "string") {
|
|
2783
3679
|
return content.length > 0 ? [{ type: "text", text: content }] : [];
|
|
@@ -2788,17 +3684,23 @@ function toAnthropicContent(content) {
|
|
|
2788
3684
|
if (!raw || typeof raw !== "object") continue;
|
|
2789
3685
|
const part = raw;
|
|
2790
3686
|
if ((part.type === "text" || part.type === "input_text") && typeof part.text === "string") {
|
|
2791
|
-
if (part.text.length > 0)
|
|
3687
|
+
if (part.text.length > 0) {
|
|
3688
|
+
const block2 = { type: "text", text: part.text };
|
|
3689
|
+
if (isCacheControl(part.cache_control)) block2.cache_control = part.cache_control;
|
|
3690
|
+
blocks.push(block2);
|
|
3691
|
+
}
|
|
2792
3692
|
continue;
|
|
2793
3693
|
}
|
|
2794
3694
|
if (part.type !== "image_url") continue;
|
|
2795
3695
|
const imageUrl = typeof part.image_url === "string" ? part.image_url : stringValue(part.image_url?.url);
|
|
2796
3696
|
if (!imageUrl) continue;
|
|
2797
3697
|
const dataMatch = imageUrl.match(/^data:([^;,]+);base64,(.+)$/s);
|
|
2798
|
-
|
|
3698
|
+
const block = {
|
|
2799
3699
|
type: "image",
|
|
2800
3700
|
source: dataMatch ? { type: "base64", media_type: dataMatch[1], data: dataMatch[2] } : { type: "url", url: imageUrl }
|
|
2801
|
-
}
|
|
3701
|
+
};
|
|
3702
|
+
if (isCacheControl(part.cache_control)) block.cache_control = part.cache_control;
|
|
3703
|
+
blocks.push(block);
|
|
2802
3704
|
}
|
|
2803
3705
|
return blocks;
|
|
2804
3706
|
}
|
|
@@ -2832,7 +3734,15 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2832
3734
|
const message = raw;
|
|
2833
3735
|
const role = String(message.role ?? "");
|
|
2834
3736
|
if (role === "system" || role === "developer") {
|
|
2835
|
-
|
|
3737
|
+
const stablePrefixChars = Number(message.stable_prefix_chars);
|
|
3738
|
+
if (typeof message.content === "string" && Number.isFinite(stablePrefixChars) && stablePrefixChars > 0 && stablePrefixChars <= message.content.length) {
|
|
3739
|
+
const stable = message.content.slice(0, stablePrefixChars);
|
|
3740
|
+
const dynamic = message.content.slice(stablePrefixChars);
|
|
3741
|
+
system.push({ type: "text", text: stable, cache_control: { type: "ephemeral" } });
|
|
3742
|
+
if (dynamic) system.push({ type: "text", text: dynamic });
|
|
3743
|
+
} else {
|
|
3744
|
+
system.push(...toAnthropicContent(message.content));
|
|
3745
|
+
}
|
|
2836
3746
|
continue;
|
|
2837
3747
|
}
|
|
2838
3748
|
if (role === "tool") {
|
|
@@ -2874,6 +3784,9 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2874
3784
|
if (!hasClaudeCodeIdentity(system)) {
|
|
2875
3785
|
system.unshift({ type: "text", text: CLAUDE_CODE_SYSTEM_INSTRUCTION });
|
|
2876
3786
|
}
|
|
3787
|
+
if (system.length > 0 && !system.some((block) => isCacheControl(block.cache_control))) {
|
|
3788
|
+
system[system.length - 1].cache_control = { type: "ephemeral" };
|
|
3789
|
+
}
|
|
2877
3790
|
const tools = Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools.flatMap((raw) => {
|
|
2878
3791
|
if (!raw || typeof raw !== "object") return [];
|
|
2879
3792
|
const fn = raw.function;
|
|
@@ -2888,14 +3801,39 @@ function buildAnthropicMessagesBody(args) {
|
|
|
2888
3801
|
const model = stringValue(args.openAiBody.model) ?? args.agentConfig.model ?? "claude-sonnet-5";
|
|
2889
3802
|
const maxTokensRaw = args.openAiBody.max_completion_tokens ?? args.openAiBody.max_tokens ?? args.agentConfig.max_tokens;
|
|
2890
3803
|
const maxTokens = typeof maxTokensRaw === "number" && Number.isFinite(maxTokensRaw) ? Math.max(1, Math.floor(maxTokensRaw)) : 8192;
|
|
3804
|
+
const reasoningEffort = stringValue(args.openAiBody.reasoning_effort) ?? stringValue(args.agentConfig.reasoning_effort);
|
|
3805
|
+
const spec = resolveThinkingSpec({
|
|
3806
|
+
model,
|
|
3807
|
+
reasoningEffort,
|
|
3808
|
+
maxTokens,
|
|
3809
|
+
temperature: typeof args.openAiBody.temperature === "number" ? args.openAiBody.temperature : args.agentConfig.temperature,
|
|
3810
|
+
injectedThinking: args.openAiBody.thinking,
|
|
3811
|
+
enableThinking: args.agentConfig.enableThinking,
|
|
3812
|
+
thinkingBudget: args.agentConfig.thinkingBudget
|
|
3813
|
+
});
|
|
3814
|
+
const { thinkingBlock, outputConfig } = spec;
|
|
3815
|
+
const finalMaxTokens = spec.maxTokens;
|
|
3816
|
+
const finalTemperature = spec.temperature;
|
|
3817
|
+
if (messages.length > 0) {
|
|
3818
|
+
const lastMessage = messages[messages.length - 1];
|
|
3819
|
+
const content = Array.isArray(lastMessage.content) ? lastMessage.content : [];
|
|
3820
|
+
if (content.length > 0) {
|
|
3821
|
+
const lastBlock = content[content.length - 1];
|
|
3822
|
+
if (!isCacheControl(lastBlock.cache_control)) {
|
|
3823
|
+
lastBlock.cache_control = { type: "ephemeral" };
|
|
3824
|
+
}
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
2891
3827
|
return {
|
|
2892
3828
|
model,
|
|
2893
3829
|
messages,
|
|
2894
|
-
max_tokens:
|
|
3830
|
+
max_tokens: finalMaxTokens,
|
|
2895
3831
|
stream: false,
|
|
3832
|
+
...thinkingBlock ? { thinking: thinkingBlock } : {},
|
|
3833
|
+
...outputConfig ? { output_config: outputConfig } : {},
|
|
2896
3834
|
...system.length > 0 ? { system } : {},
|
|
2897
3835
|
...tools.length > 0 ? { tools } : {},
|
|
2898
|
-
...typeof
|
|
3836
|
+
...typeof finalTemperature === "number" ? { temperature: finalTemperature } : {},
|
|
2899
3837
|
...typeof args.openAiBody.top_p === "number" ? { top_p: args.openAiBody.top_p } : {}
|
|
2900
3838
|
};
|
|
2901
3839
|
}
|
|
@@ -2919,6 +3857,8 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
2919
3857
|
}
|
|
2920
3858
|
const usage = payload.usage ?? {};
|
|
2921
3859
|
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);
|
|
3860
|
+
const cacheCreationInputTokens = typeof usage.cache_creation_input_tokens === "number" ? usage.cache_creation_input_tokens : 0;
|
|
3861
|
+
const cacheReadInputTokens = typeof usage.cache_read_input_tokens === "number" ? usage.cache_read_input_tokens : 0;
|
|
2922
3862
|
const outputTokens = typeof usage.output_tokens === "number" ? usage.output_tokens : 0;
|
|
2923
3863
|
const stopReason = String(payload.stop_reason ?? "");
|
|
2924
3864
|
const message = { role: "assistant", content: text || null };
|
|
@@ -2934,9 +3874,16 @@ function mapAnthropicMessageToOpenAi(payload) {
|
|
|
2934
3874
|
finish_reason: toolCalls.length > 0 || stopReason === "tool_use" ? "tool_calls" : stopReason === "max_tokens" ? "length" : "stop"
|
|
2935
3875
|
}],
|
|
2936
3876
|
usage: {
|
|
3877
|
+
// prompt_tokens/input_tokens are total input, including cache read/write.
|
|
3878
|
+
// Preserve Anthropic's components so normalization and billing can apply
|
|
3879
|
+
// the correct cache prices without double-counting them.
|
|
2937
3880
|
prompt_tokens: inputTokens,
|
|
3881
|
+
input_tokens: inputTokens,
|
|
2938
3882
|
completion_tokens: outputTokens,
|
|
2939
|
-
|
|
3883
|
+
output_tokens: outputTokens,
|
|
3884
|
+
total_tokens: inputTokens + outputTokens,
|
|
3885
|
+
cache_creation_input_tokens: cacheCreationInputTokens,
|
|
3886
|
+
cache_read_input_tokens: cacheReadInputTokens
|
|
2940
3887
|
}
|
|
2941
3888
|
};
|
|
2942
3889
|
}
|
|
@@ -9011,6 +9958,262 @@ function isCursorOAuthAgent(agent) {
|
|
|
9011
9958
|
return agent.apiKeyRef?.trim().toLowerCase() === "cursor";
|
|
9012
9959
|
}
|
|
9013
9960
|
|
|
9961
|
+
// packages/agent-runtime/codexResponsesProvider.ts
|
|
9962
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
9963
|
+
var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
|
|
9964
|
+
var CODEX_CLIENT_VERSION = "0.144.1";
|
|
9965
|
+
var CODEX_ORIGINATOR = "codex_cli_rs";
|
|
9966
|
+
var CODEX_OPENAI_BETA = "responses=experimental";
|
|
9967
|
+
var OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
|
|
9968
|
+
var CODEX_INSTALLATION_ID = randomUUID4();
|
|
9969
|
+
function decodeCodexAccountId(accessToken) {
|
|
9970
|
+
const parts = accessToken.split(".");
|
|
9971
|
+
if (parts.length < 2) return void 0;
|
|
9972
|
+
try {
|
|
9973
|
+
const payload = JSON.parse(
|
|
9974
|
+
Buffer.from(parts[1], "base64").toString("utf8")
|
|
9975
|
+
);
|
|
9976
|
+
const claim = payload[OPENAI_AUTH_CLAIM];
|
|
9977
|
+
const value = claim && typeof claim === "object" ? claim.chatgpt_account_id : void 0;
|
|
9978
|
+
return typeof value === "string" && value ? value : void 0;
|
|
9979
|
+
} catch {
|
|
9980
|
+
return void 0;
|
|
9981
|
+
}
|
|
9982
|
+
}
|
|
9983
|
+
function createCodexRequestIdentity(installationId = CODEX_INSTALLATION_ID) {
|
|
9984
|
+
const sessionId = randomUUID4();
|
|
9985
|
+
const threadId = randomUUID4();
|
|
9986
|
+
const windowId = randomUUID4();
|
|
9987
|
+
const turnId = randomUUID4();
|
|
9988
|
+
const turnMetadata = {
|
|
9989
|
+
installation_id: installationId,
|
|
9990
|
+
session_id: sessionId,
|
|
9991
|
+
thread_id: threadId,
|
|
9992
|
+
turn_id: turnId,
|
|
9993
|
+
window_id: windowId,
|
|
9994
|
+
request_kind: "turn",
|
|
9995
|
+
turn_started_at_unix_ms: Date.now()
|
|
9996
|
+
};
|
|
9997
|
+
const turnMetadataJson = JSON.stringify(turnMetadata);
|
|
9998
|
+
return {
|
|
9999
|
+
sessionId,
|
|
10000
|
+
threadId,
|
|
10001
|
+
windowId,
|
|
10002
|
+
turnId,
|
|
10003
|
+
turnMetadataJson,
|
|
10004
|
+
clientMetadata: {
|
|
10005
|
+
"x-codex-installation-id": installationId,
|
|
10006
|
+
session_id: sessionId,
|
|
10007
|
+
thread_id: threadId,
|
|
10008
|
+
"x-codex-window-id": windowId,
|
|
10009
|
+
turn_id: turnId,
|
|
10010
|
+
"x-codex-turn-metadata": turnMetadataJson
|
|
10011
|
+
}
|
|
10012
|
+
};
|
|
10013
|
+
}
|
|
10014
|
+
function buildCodexCompatibilityHeaders(identity, accountId) {
|
|
10015
|
+
return {
|
|
10016
|
+
Authorization: "",
|
|
10017
|
+
// filled by caller with bearer token
|
|
10018
|
+
"Content-Type": "application/json",
|
|
10019
|
+
Accept: "text/event-stream",
|
|
10020
|
+
"chatgpt-account-id": accountId,
|
|
10021
|
+
"OpenAI-Beta": CODEX_OPENAI_BETA,
|
|
10022
|
+
originator: CODEX_ORIGINATOR,
|
|
10023
|
+
version: CODEX_CLIENT_VERSION,
|
|
10024
|
+
session_id: identity.sessionId,
|
|
10025
|
+
conversation_id: identity.sessionId,
|
|
10026
|
+
"x-client-request-id": identity.sessionId,
|
|
10027
|
+
"session-id": identity.sessionId,
|
|
10028
|
+
"thread-id": identity.threadId,
|
|
10029
|
+
"x-codex-window-id": identity.windowId,
|
|
10030
|
+
"x-codex-turn-metadata": identity.turnMetadataJson
|
|
10031
|
+
};
|
|
10032
|
+
}
|
|
10033
|
+
function collectInstructions(messages, agentPrompt) {
|
|
10034
|
+
const systemTexts = [];
|
|
10035
|
+
const prompt = agentPrompt?.trim();
|
|
10036
|
+
if (prompt) systemTexts.push(prompt);
|
|
10037
|
+
for (const raw of messages) {
|
|
10038
|
+
if (!raw || typeof raw !== "object") continue;
|
|
10039
|
+
const role = String(raw.role ?? "");
|
|
10040
|
+
if (role !== "system" && role !== "developer") continue;
|
|
10041
|
+
const content = raw.content;
|
|
10042
|
+
const stringContent = asOptionalTrimmedString(content);
|
|
10043
|
+
if (stringContent) {
|
|
10044
|
+
systemTexts.push(stringContent);
|
|
10045
|
+
} else if (Array.isArray(content)) {
|
|
10046
|
+
const text = content.filter(
|
|
10047
|
+
(p) => !!p && p.type === "text"
|
|
10048
|
+
).map((p) => p.text).join("\n").trim();
|
|
10049
|
+
if (text) systemTexts.push(text);
|
|
10050
|
+
}
|
|
10051
|
+
}
|
|
10052
|
+
return systemTexts.join("\n\n");
|
|
10053
|
+
}
|
|
10054
|
+
function collectStableInstructions(messages, fallbackPrompt) {
|
|
10055
|
+
const systemTexts = [];
|
|
10056
|
+
if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
|
|
10057
|
+
for (const raw of messages) {
|
|
10058
|
+
if (!raw || typeof raw !== "object") continue;
|
|
10059
|
+
const message = raw;
|
|
10060
|
+
const role = String(message.role ?? "");
|
|
10061
|
+
if (role !== "system" && role !== "developer") continue;
|
|
10062
|
+
if (typeof message.content === "string") {
|
|
10063
|
+
const boundary = Number(message.stable_prefix_chars);
|
|
10064
|
+
const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
|
|
10065
|
+
if (text.trim()) systemTexts.push(text.trim());
|
|
10066
|
+
}
|
|
10067
|
+
}
|
|
10068
|
+
return systemTexts.join("\n\n");
|
|
10069
|
+
}
|
|
10070
|
+
function stablePromptCacheKey(parts) {
|
|
10071
|
+
const value = JSON.stringify(parts);
|
|
10072
|
+
let hash = 2166136261;
|
|
10073
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
10074
|
+
hash ^= value.charCodeAt(index);
|
|
10075
|
+
hash = Math.imul(hash, 16777619) >>> 0;
|
|
10076
|
+
}
|
|
10077
|
+
return `nolo-codex-${hash.toString(16).padStart(8, "0")}`;
|
|
10078
|
+
}
|
|
10079
|
+
function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
|
|
10080
|
+
const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
|
|
10081
|
+
const nonSystem = rawMessages.filter((m) => {
|
|
10082
|
+
const role = m && typeof m === "object" ? String(m.role) : "";
|
|
10083
|
+
return role !== "system" && role !== "developer";
|
|
10084
|
+
});
|
|
10085
|
+
const input = convertMessagesToResponsesInput(nonSystem);
|
|
10086
|
+
const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
|
|
10087
|
+
const stableInstructions = collectStableInstructions(rawMessages, args.agentConfig.prompt);
|
|
10088
|
+
const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
|
|
10089
|
+
const tools = toResponsesTools(
|
|
10090
|
+
Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
|
|
10091
|
+
);
|
|
10092
|
+
const body = {
|
|
10093
|
+
model,
|
|
10094
|
+
input,
|
|
10095
|
+
stream: true,
|
|
10096
|
+
store: false,
|
|
10097
|
+
// Keep routing stable across turns and request UUIDs. Growing input/history
|
|
10098
|
+
// is intentionally excluded; only stable request-prefix material belongs.
|
|
10099
|
+
prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []]),
|
|
10100
|
+
client_metadata: identity.clientMetadata
|
|
10101
|
+
};
|
|
10102
|
+
if (instructions) body.instructions = instructions;
|
|
10103
|
+
if (tools && tools.length > 0) {
|
|
10104
|
+
body.tools = tools;
|
|
10105
|
+
body.tool_choice = "auto";
|
|
10106
|
+
body.parallel_tool_calls = true;
|
|
10107
|
+
}
|
|
10108
|
+
return body;
|
|
10109
|
+
}
|
|
10110
|
+
function aggregateResponsesStream(events) {
|
|
10111
|
+
let text = "";
|
|
10112
|
+
const toolCalls = [];
|
|
10113
|
+
let usage;
|
|
10114
|
+
for (const ev of events) {
|
|
10115
|
+
const type = String(ev.type ?? "");
|
|
10116
|
+
if (type === "response.output_text.delta" && typeof ev.delta === "string") {
|
|
10117
|
+
text += ev.delta;
|
|
10118
|
+
continue;
|
|
10119
|
+
}
|
|
10120
|
+
if (type === "response.output_item.done") {
|
|
10121
|
+
const item = ev.item;
|
|
10122
|
+
if (item && item.type === "function_call") {
|
|
10123
|
+
const name = typeof item.name === "string" ? item.name : "";
|
|
10124
|
+
if (name) {
|
|
10125
|
+
toolCalls.push({
|
|
10126
|
+
id: typeof item.call_id === "string" && item.call_id ? item.call_id : `${name}_${toolCalls.length}`,
|
|
10127
|
+
type: "function",
|
|
10128
|
+
function: {
|
|
10129
|
+
name,
|
|
10130
|
+
arguments: typeof item.arguments === "string" ? item.arguments : "{}"
|
|
10131
|
+
}
|
|
10132
|
+
});
|
|
10133
|
+
}
|
|
10134
|
+
}
|
|
10135
|
+
continue;
|
|
10136
|
+
}
|
|
10137
|
+
if (type === "response.completed") {
|
|
10138
|
+
const response = ev.response;
|
|
10139
|
+
const u = response?.usage;
|
|
10140
|
+
if (u) {
|
|
10141
|
+
const prompt = typeof u.input_tokens === "number" ? u.input_tokens : 0;
|
|
10142
|
+
const completion = typeof u.output_tokens === "number" ? u.output_tokens : 0;
|
|
10143
|
+
const total = typeof u.total_tokens === "number" ? u.total_tokens : prompt + completion;
|
|
10144
|
+
usage = {
|
|
10145
|
+
prompt_tokens: prompt,
|
|
10146
|
+
completion_tokens: completion,
|
|
10147
|
+
total_tokens: total
|
|
10148
|
+
};
|
|
10149
|
+
}
|
|
10150
|
+
}
|
|
10151
|
+
}
|
|
10152
|
+
return { text, toolCalls, usage };
|
|
10153
|
+
}
|
|
10154
|
+
async function readSseEvents(response) {
|
|
10155
|
+
return readSseDataValues(response, (line) => {
|
|
10156
|
+
const ev = parseSseDataLineObject(line);
|
|
10157
|
+
return ev && !Array.isArray(ev) ? ev : null;
|
|
10158
|
+
});
|
|
10159
|
+
}
|
|
10160
|
+
async function fetchCodexResponsesCompletion(args) {
|
|
10161
|
+
const fetchImpl = args.fetchImpl ?? fetch;
|
|
10162
|
+
const accountId = args.accountId?.trim() || decodeCodexAccountId(args.accessToken);
|
|
10163
|
+
if (!accountId) {
|
|
10164
|
+
return {
|
|
10165
|
+
status: 401,
|
|
10166
|
+
body: {
|
|
10167
|
+
error: {
|
|
10168
|
+
message: "ChatGPT Codex credential is missing chatgpt_account_id. Re-run `nolo auth chatgpt`."
|
|
10169
|
+
}
|
|
10170
|
+
}
|
|
10171
|
+
};
|
|
10172
|
+
}
|
|
10173
|
+
const identity = createCodexRequestIdentity();
|
|
10174
|
+
const body = buildCodexRequestBody(args, identity);
|
|
10175
|
+
const headers = buildCodexCompatibilityHeaders(identity, accountId);
|
|
10176
|
+
headers.Authorization = `Bearer ${args.accessToken}`;
|
|
10177
|
+
const response = await fetchImpl(CODEX_RESPONSES_URL, {
|
|
10178
|
+
method: "POST",
|
|
10179
|
+
headers,
|
|
10180
|
+
body: JSON.stringify(body),
|
|
10181
|
+
signal: args.signal
|
|
10182
|
+
});
|
|
10183
|
+
if (!response.ok) {
|
|
10184
|
+
const errorText = await response.text();
|
|
10185
|
+
return {
|
|
10186
|
+
status: response.status,
|
|
10187
|
+
body: { error: { message: errorText || response.statusText } }
|
|
10188
|
+
};
|
|
10189
|
+
}
|
|
10190
|
+
const events = await readSseEvents(response);
|
|
10191
|
+
const { text, toolCalls, usage } = aggregateResponsesStream(events);
|
|
10192
|
+
const message = {
|
|
10193
|
+
role: "assistant",
|
|
10194
|
+
content: text || null
|
|
10195
|
+
};
|
|
10196
|
+
if (toolCalls.length > 0) message.tool_calls = toolCalls;
|
|
10197
|
+
return {
|
|
10198
|
+
status: 200,
|
|
10199
|
+
body: {
|
|
10200
|
+
choices: [
|
|
10201
|
+
{
|
|
10202
|
+
index: 0,
|
|
10203
|
+
message,
|
|
10204
|
+
finish_reason: toolCalls.length > 0 ? "tool_calls" : "stop"
|
|
10205
|
+
}
|
|
10206
|
+
],
|
|
10207
|
+
...usage ? { usage } : {}
|
|
10208
|
+
}
|
|
10209
|
+
};
|
|
10210
|
+
}
|
|
10211
|
+
function isCodexOAuthAgent(agentConfig) {
|
|
10212
|
+
if (!agentConfig) return false;
|
|
10213
|
+
const apiKeyRef = asTrimmedLowercaseString(agentConfig.apiKeyRef);
|
|
10214
|
+
return apiKeyRef === "chatgpt";
|
|
10215
|
+
}
|
|
10216
|
+
|
|
9014
10217
|
// packages/agent-runtime/oauthProviders.ts
|
|
9015
10218
|
var XAI_ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
|
|
9016
10219
|
var decodeBase64 = (s) => Buffer.from(s, "base64").toString("utf8");
|
|
@@ -9504,7 +10707,7 @@ function buildOpenAiTools(args) {
|
|
|
9504
10707
|
const toolset = buildLocalWorkspaceToolsetForEnv(args);
|
|
9505
10708
|
const toolNameSet = new Set(args.toolNames ?? []);
|
|
9506
10709
|
const callAgentTools = toolNameSet.has("callAgent") ? prepareTools(["callAgent"]) : [];
|
|
9507
|
-
const uiAskChoiceTools = toolNameSet.has("
|
|
10710
|
+
const uiAskChoiceTools = toolNameSet.has("ask_user") ? prepareTools(["ask_user"]) : [];
|
|
9508
10711
|
const readPastedTextTools = toolNameSet.has("readPastedText") ? [
|
|
9509
10712
|
{
|
|
9510
10713
|
type: "function",
|
|
@@ -9564,10 +10767,10 @@ function buildOpenAiTools(args) {
|
|
|
9564
10767
|
var CLI_DEFAULT_TOOLS = ["exa_search", "fetchWebpage"];
|
|
9565
10768
|
function addDefaultCliCoreTools(toolNames, env, options) {
|
|
9566
10769
|
const declaredOnly = env && shouldUseDeclaredOnlyLocalWorkspaceTools(env);
|
|
9567
|
-
const forcedTools = options?.hasUserChoice === true ? FORCED_TOOLS : FORCED_TOOLS.filter((name) => name !== "
|
|
10770
|
+
const forcedTools = options?.hasUserChoice === true ? FORCED_TOOLS : FORCED_TOOLS.filter((name) => name !== "ask_user");
|
|
9568
10771
|
const injected = declaredOnly ? [...forcedTools] : [...forcedTools, ...CLI_DEFAULT_TOOLS];
|
|
9569
10772
|
const combined = [...toolNames, ...injected];
|
|
9570
|
-
const filtered = options?.hasUserChoice === true ? combined : combined.filter((name) => name !== "
|
|
10773
|
+
const filtered = options?.hasUserChoice === true ? combined : combined.filter((name) => name !== "ask_user");
|
|
9571
10774
|
return [...new Set(filtered)];
|
|
9572
10775
|
}
|
|
9573
10776
|
function resolveCliEffectiveEnabledPacks(args) {
|
|
@@ -9860,9 +11063,9 @@ function createCliCallAgentToolExecutor(deps, ctx) {
|
|
|
9860
11063
|
// packages/cli/client/localRuntimeAdapter.ts
|
|
9861
11064
|
var currentMetaFile = fileURLToPath(import.meta.url);
|
|
9862
11065
|
var isJsBundle = extname(currentMetaFile) === ".js";
|
|
9863
|
-
var SOURCE_CLI_DIR = isJsBundle ?
|
|
9864
|
-
var CLI_DIR = isCompiledBinary() ?
|
|
9865
|
-
var CLI_ENTRYPOINT = isCompiledBinary() ? process.execPath : isJsBundle ? currentMetaFile :
|
|
11066
|
+
var SOURCE_CLI_DIR = isJsBundle ? dirname2(currentMetaFile) : dirname2(dirname2(currentMetaFile));
|
|
11067
|
+
var CLI_DIR = isCompiledBinary() ? dirname2(process.execPath) : SOURCE_CLI_DIR;
|
|
11068
|
+
var CLI_ENTRYPOINT = isCompiledBinary() ? process.execPath : isJsBundle ? currentMetaFile : join2(SOURCE_CLI_DIR, "index.ts");
|
|
9866
11069
|
function createCliLocalRuntimeAdapter(deps) {
|
|
9867
11070
|
const now = deps.now ?? Date.now;
|
|
9868
11071
|
const createId = deps.createId ?? createFallbackId;
|
|
@@ -10208,6 +11411,74 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10208
11411
|
}
|
|
10209
11412
|
};
|
|
10210
11413
|
}
|
|
11414
|
+
if (isCodexOAuthAgent(agentConfig)) {
|
|
11415
|
+
const accessToken = await apiKeyRefResolver("chatgpt");
|
|
11416
|
+
if (!accessToken) {
|
|
11417
|
+
throw new Error(
|
|
11418
|
+
'OAuth credential for "chatgpt" not found locally. Run `nolo auth chatgpt`.'
|
|
11419
|
+
);
|
|
11420
|
+
}
|
|
11421
|
+
const credential = readOAuthCredential("chatgpt");
|
|
11422
|
+
const accountId = credential?.accountId;
|
|
11423
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
11424
|
+
agentConfig,
|
|
11425
|
+
deps.env,
|
|
11426
|
+
buildProviderOpenAiTools,
|
|
11427
|
+
additionalToolNames,
|
|
11428
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
11429
|
+
);
|
|
11430
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
11431
|
+
agentKey: agentConfig.key,
|
|
11432
|
+
transport: "codex-responses",
|
|
11433
|
+
provider: "openai",
|
|
11434
|
+
model: agentConfig.model ?? "gpt-5.6-sol",
|
|
11435
|
+
hasApiKey: true
|
|
11436
|
+
});
|
|
11437
|
+
return {
|
|
11438
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
11439
|
+
complete: async (messages, options) => {
|
|
11440
|
+
const result = await fetchCodexResponsesCompletion({
|
|
11441
|
+
agentConfig,
|
|
11442
|
+
accessToken,
|
|
11443
|
+
...accountId ? { accountId } : {},
|
|
11444
|
+
openAiBody: {
|
|
11445
|
+
model: agentConfig.model || "gpt-5.6-sol",
|
|
11446
|
+
messages,
|
|
11447
|
+
stream: false,
|
|
11448
|
+
...tools2.length > 0 ? { tools: tools2 } : {}
|
|
11449
|
+
},
|
|
11450
|
+
fetchImpl: (url, init) => fetchWithTransientRetry(fetchImpl, url, init, {
|
|
11451
|
+
sleep: deps.sleep,
|
|
11452
|
+
loopbackRequest
|
|
11453
|
+
})
|
|
11454
|
+
});
|
|
11455
|
+
if (result.status < 200 || result.status >= 300) {
|
|
11456
|
+
const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
|
|
11457
|
+
throw new Error(
|
|
11458
|
+
`local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
|
|
11459
|
+
);
|
|
11460
|
+
}
|
|
11461
|
+
const choice = Array.isArray(result.body.choices) ? result.body.choices[0] : void 0;
|
|
11462
|
+
const message = choice?.message ?? {};
|
|
11463
|
+
const content = typeof message.content === "string" ? message.content : "";
|
|
11464
|
+
const tool_calls = Array.isArray(message.tool_calls) ? message.tool_calls : void 0;
|
|
11465
|
+
if (content && options?.onTextDelta) options.onTextDelta(content);
|
|
11466
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
11467
|
+
agentKey: agentConfig.key,
|
|
11468
|
+
transport: "codex-responses",
|
|
11469
|
+
ok: true,
|
|
11470
|
+
contentChars: content.length,
|
|
11471
|
+
toolCallCount: tool_calls?.length ?? 0,
|
|
11472
|
+
requestedToolNames: requestedToolNames2
|
|
11473
|
+
});
|
|
11474
|
+
return {
|
|
11475
|
+
content,
|
|
11476
|
+
...tool_calls ? { tool_calls } : {},
|
|
11477
|
+
trace: messages
|
|
11478
|
+
};
|
|
11479
|
+
}
|
|
11480
|
+
};
|
|
11481
|
+
}
|
|
10211
11482
|
if (isCursorOAuthAgent(agentConfig)) {
|
|
10212
11483
|
const accessToken = await apiKeyRefResolver("cursor");
|
|
10213
11484
|
if (!accessToken) {
|
|
@@ -10277,6 +11548,101 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10277
11548
|
}
|
|
10278
11549
|
};
|
|
10279
11550
|
}
|
|
11551
|
+
if (shouldUsePlatformChatProvider(deps.env, agentConfig) && isGemini3Model(agentConfig.model ?? "") && agentConfig.provider === "google") {
|
|
11552
|
+
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
11553
|
+
agentConfig,
|
|
11554
|
+
env: deps.env,
|
|
11555
|
+
apiKeyRefResolver,
|
|
11556
|
+
credentialBroker,
|
|
11557
|
+
syncFetcher
|
|
11558
|
+
});
|
|
11559
|
+
const { requestedToolNames: requestedToolNames2, tools: tools2 } = resolveProviderOpenAiToolBundle(
|
|
11560
|
+
agentConfig,
|
|
11561
|
+
deps.env,
|
|
11562
|
+
buildProviderOpenAiTools,
|
|
11563
|
+
additionalToolNames,
|
|
11564
|
+
{ hasUserChoice: Boolean(deps.requestUserChoice) }
|
|
11565
|
+
);
|
|
11566
|
+
if (tools2.length > 0 && providerConfig2.apiKey && shouldUseGeminiNativeToolRoute(
|
|
11567
|
+
agentConfig.provider ?? "",
|
|
11568
|
+
agentConfig.model ?? "",
|
|
11569
|
+
tools2,
|
|
11570
|
+
() => false
|
|
11571
|
+
// CLI 端不区分 image 模型
|
|
11572
|
+
)) {
|
|
11573
|
+
logLocalRuntimeDiagnostic("provider.selected", {
|
|
11574
|
+
agentKey: agentConfig.key,
|
|
11575
|
+
transport: "gemini-native-tool",
|
|
11576
|
+
apiSource: agentConfig.apiSource ?? null,
|
|
11577
|
+
provider: providerConfig2.provider,
|
|
11578
|
+
model: providerConfig2.model,
|
|
11579
|
+
hasApiKey: Boolean(providerConfig2.apiKey)
|
|
11580
|
+
});
|
|
11581
|
+
return {
|
|
11582
|
+
model: providerConfig2.model,
|
|
11583
|
+
complete: async (messages, options) => {
|
|
11584
|
+
const requestBody = buildGeminiGenerateContentRequest({
|
|
11585
|
+
messages,
|
|
11586
|
+
tools: tools2,
|
|
11587
|
+
maxTokens: typeof agentConfig.max_tokens === "number" ? agentConfig.max_tokens : void 0,
|
|
11588
|
+
temperature: typeof agentConfig.temperature === "number" ? agentConfig.temperature : void 0,
|
|
11589
|
+
attachSkipThoughtSignature: true
|
|
11590
|
+
});
|
|
11591
|
+
const model = providerConfig2.model;
|
|
11592
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:streamGenerateContent?alt=sse`;
|
|
11593
|
+
logLocalRuntimeDiagnostic("provider.request.start", {
|
|
11594
|
+
agentKey: agentConfig.key,
|
|
11595
|
+
transport: "gemini-native-tool",
|
|
11596
|
+
model,
|
|
11597
|
+
messageCount: messages.length,
|
|
11598
|
+
toolCount: tools2.length,
|
|
11599
|
+
requestedToolNames: requestedToolNames2
|
|
11600
|
+
});
|
|
11601
|
+
const res = await fetchImpl(url, {
|
|
11602
|
+
method: "POST",
|
|
11603
|
+
headers: {
|
|
11604
|
+
"Content-Type": "application/json",
|
|
11605
|
+
"x-goog-api-key": providerConfig2.apiKey ?? ""
|
|
11606
|
+
},
|
|
11607
|
+
body: JSON.stringify(requestBody),
|
|
11608
|
+
signal: AbortSignal.timeout(12e4)
|
|
11609
|
+
});
|
|
11610
|
+
if (!res.ok) {
|
|
11611
|
+
const errText = await res.text();
|
|
11612
|
+
logLocalRuntimeDiagnostic("provider.request.failed", {
|
|
11613
|
+
agentKey: agentConfig.key,
|
|
11614
|
+
transport: "gemini-native-tool",
|
|
11615
|
+
status: res.status,
|
|
11616
|
+
error: errText.slice(0, 200)
|
|
11617
|
+
});
|
|
11618
|
+
throw new Error(
|
|
11619
|
+
`gemini native tool provider failed: HTTP ${res.status} ${errText.slice(0, 500)}`
|
|
11620
|
+
);
|
|
11621
|
+
}
|
|
11622
|
+
const chunks = await readSseDataValues(res, parseSseDataLineJson);
|
|
11623
|
+
const { text, toolCalls, usage } = accumulateGeminiChunks(chunks);
|
|
11624
|
+
if (text && options?.onTextDelta) {
|
|
11625
|
+
options.onTextDelta(text);
|
|
11626
|
+
}
|
|
11627
|
+
const result = {
|
|
11628
|
+
content: text,
|
|
11629
|
+
model,
|
|
11630
|
+
tool_calls: toolCalls.length > 0 ? toolCalls : void 0,
|
|
11631
|
+
...usage ? { usage } : {},
|
|
11632
|
+
trace: messages
|
|
11633
|
+
};
|
|
11634
|
+
logLocalRuntimeDiagnostic("provider.request.result", {
|
|
11635
|
+
agentKey: agentConfig.key,
|
|
11636
|
+
transport: "gemini-native-tool",
|
|
11637
|
+
ok: true,
|
|
11638
|
+
contentChars: text.length,
|
|
11639
|
+
toolCallCount: toolCalls.length
|
|
11640
|
+
});
|
|
11641
|
+
return result;
|
|
11642
|
+
}
|
|
11643
|
+
};
|
|
11644
|
+
}
|
|
11645
|
+
}
|
|
10280
11646
|
if (shouldUsePlatformChatProvider(deps.env, agentConfig)) {
|
|
10281
11647
|
const providerConfig2 = await resolvePlatformChatProviderConfig({
|
|
10282
11648
|
agentConfig,
|
|
@@ -10337,7 +11703,16 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10337
11703
|
},
|
|
10338
11704
|
{
|
|
10339
11705
|
sleep: deps.sleep,
|
|
10340
|
-
loopbackRequest
|
|
11706
|
+
loopbackRequest,
|
|
11707
|
+
// auto 档位转发 nolo.chat 时,网关层 502(server: Caddy、空 body)
|
|
11708
|
+
// 意味着请求根本没到 Bun 上游,provider 未受理,重试安全。
|
|
11709
|
+
// 与 429/503 同口径:不会重复计费/重复生成。
|
|
11710
|
+
retryableStatuses: /* @__PURE__ */ new Set([429, 502, 503]),
|
|
11711
|
+
onRetry: deps.activityReporter ? ({ attempt, maxAttempts, delayMs }) => {
|
|
11712
|
+
deps.activityReporter(
|
|
11713
|
+
`\u81EA\u52A8\u91CD\u8BD5 ${attempt}/${maxAttempts} \xB7 ${Math.ceil(delayMs / 1e3)}s`
|
|
11714
|
+
);
|
|
11715
|
+
} : void 0
|
|
10341
11716
|
}
|
|
10342
11717
|
);
|
|
10343
11718
|
if (!res.ok) {
|
|
@@ -10493,6 +11868,23 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10493
11868
|
};
|
|
10494
11869
|
},
|
|
10495
11870
|
executeTool: async (call, opts) => {
|
|
11871
|
+
const contextualCall = opts?.runtimeContext ? { ...call, runtimeContext: opts.runtimeContext } : call;
|
|
11872
|
+
let injectedCall = contextualCall;
|
|
11873
|
+
if (contextualCall.name === "startAgentRun" && deps.parentDialogId && typeof contextualCall.arguments === "string") {
|
|
11874
|
+
try {
|
|
11875
|
+
const args = JSON.parse(contextualCall.arguments);
|
|
11876
|
+
if (!args.parentDialogId) {
|
|
11877
|
+
injectedCall = {
|
|
11878
|
+
...contextualCall,
|
|
11879
|
+
arguments: JSON.stringify({
|
|
11880
|
+
...args,
|
|
11881
|
+
parentDialogId: deps.parentDialogId
|
|
11882
|
+
})
|
|
11883
|
+
};
|
|
11884
|
+
}
|
|
11885
|
+
} catch {
|
|
11886
|
+
}
|
|
11887
|
+
}
|
|
10496
11888
|
assertWithinLocalToolBudget({
|
|
10497
11889
|
toolName: call.name,
|
|
10498
11890
|
budgets: localToolBudgets,
|
|
@@ -10501,7 +11893,7 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10501
11893
|
const result = await executeLocalToolWithPolicy({
|
|
10502
11894
|
env: deps.env,
|
|
10503
11895
|
agentToolNames: activeAgentToolNames,
|
|
10504
|
-
call,
|
|
11896
|
+
call: injectedCall,
|
|
10505
11897
|
executors: localToolExecutors,
|
|
10506
11898
|
abortSignal: opts?.abortSignal,
|
|
10507
11899
|
detachMs: resolveExecShellDetachMs(deps.env),
|
|
@@ -10522,6 +11914,8 @@ function createCliLocalRuntimeAdapter(deps) {
|
|
|
10522
11914
|
export {
|
|
10523
11915
|
summarizeEndpoint,
|
|
10524
11916
|
isBuiltinNoloAgentRef,
|
|
11917
|
+
readTimestamp,
|
|
11918
|
+
parseAgentRunEvent,
|
|
10525
11919
|
parseCliLocale,
|
|
10526
11920
|
getCliLocale,
|
|
10527
11921
|
setCliLocale,
|
|
@@ -10529,6 +11923,8 @@ export {
|
|
|
10529
11923
|
t,
|
|
10530
11924
|
toolLabel,
|
|
10531
11925
|
agentRunCardLabels,
|
|
11926
|
+
QUOTA_ERROR_PATTERNS,
|
|
11927
|
+
isQuotaExhaustedError,
|
|
10532
11928
|
clearCliLocalRuntimePreparedAgentCache,
|
|
10533
11929
|
createCliCallAgentToolExecutor,
|
|
10534
11930
|
createCliLocalRuntimeAdapter
|