nolo-cli 0.54.0-alpha.2 → 0.54.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-ANY4SIAS.js → _executeModel-OPTKYHJA.js} +48 -42
- package/{action-Q4W5JPI5.js → action-ORXWW2ZG.js} +8 -8
- package/{addContentAction-O25HFR37.js → addContentAction-53BZ34AE.js} +8 -7
- package/{addDialogAgentAction-GH7AUPPB.js → addDialogAgentAction-JRYUS54Y.js} +10 -9
- package/{agentDeleteCommand-JWIKNWWI.js → agentDeleteCommand-FJIWU2BS.js} +30 -28
- package/{agentEmailCommands-PL22BEU5.js → agentEmailCommands-CE32L43B.js} +57 -52
- package/{agentListCommands-6NR7AQEK.js → agentListCommands-VJNKULIK.js} +42 -33
- package/{agentMachineCommands-TASPU6OA.js → agentMachineCommands-HCJ3WQXL.js} +30 -28
- package/{agentRecordCommands-Z64TA63M.js → agentRecordCommands-QFWERED4.js} +55 -50
- package/{agentRunCommand-4QJQLPRW.js → agentRunCommand-G3GQMUNN.js} +65 -53
- package/{agentRunControl-4GHHSXFZ.js → agentRunControl-INKFDXDA.js} +3 -1
- package/{agentRuntimeLocal-PCJJ56J2.js → agentRuntimeLocal-K327ELSL.js} +30 -26
- package/{agentSlice-KYLDUSNN.js → agentSlice-ODKF4J6M.js} +8 -8
- package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-5AR3DKNN.js} +2 -2
- package/{appDeleteCommands-WLHMJAVT.js → appDeleteCommands-XUXMFDI4.js} +31 -29
- package/{appDeployCommands-CKON7N2E.js → appDeployCommands-37F4GPCU.js} +31 -29
- package/{appDeployStatusCommands-PXRLDASH.js → appDeployStatusCommands-WSPU7TUK.js} +31 -29
- package/{appGetCommands-RAB5RM4M.js → appGetCommands-YLOBA3EM.js} +31 -29
- package/{appListCommands-GU57FB62.js → appListCommands-UD62R5ME.js} +31 -29
- package/{authCommand-QOPOEYEK.js → authCommand-OK6HLHGS.js} +13 -13
- package/{authCommands-SBQVTD6V.js → authCommands-2DUIUEMT.js} +2 -2
- package/{chatQueueReduxAdapter-5O2WLITN.js → chatQueueReduxAdapter-TV2TUOQS.js} +26 -23
- package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
- package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
- package/{chunk-VULELK4T.js → chunk-2WBFJHQA.js} +4 -26
- package/{chunk-IKTHA3JH.js → chunk-3LKZRP7E.js} +2 -2
- package/{chunk-INXBNYCG.js → chunk-3Y2K5O2R.js} +64 -6
- package/{chunk-VRZIH5JO.js → chunk-3ZTR7ZO4.js} +1 -1
- package/{chunk-GV35EHNA.js → chunk-5FCIPEKT.js} +262 -96
- package/{chunk-RTLJUGQH.js → chunk-5UAYZEXO.js} +2 -2
- package/{chunk-TI5BCZCH.js → chunk-6COJEAYH.js} +32 -101
- package/{chunk-Y7LNKP32.js → chunk-6HDYSFLO.js} +4 -6
- package/chunk-6IGD47IC.js +19 -0
- package/chunk-6YTOJY35.js +352 -0
- package/{chunk-6FGXGFAH.js → chunk-75MSWWUE.js} +1 -1
- package/{chunk-3Z3DXZBD.js → chunk-7FAS3NEF.js} +16 -16
- package/{chunk-AV6KQCM5.js → chunk-7NYDJAQ7.js} +19 -14
- package/{chunk-CVT7L2WZ.js → chunk-A65UV3M5.js} +4 -4
- package/{chunk-7APQB6R6.js → chunk-AUVFJGPC.js} +3 -3
- package/{chunk-H4RYESI6.js → chunk-BBTN4NQD.js} +4 -4
- package/{chunk-757BGY6Y.js → chunk-BG7J6Y5X.js} +1 -1
- package/chunk-BY2FF2C4.js +526 -0
- package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
- package/chunk-BYXBJQAS.js +0 -0
- package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
- package/{chunk-UITMHBVK.js → chunk-EA5OYZVD.js} +1 -1
- package/{chunk-4NN3EK7H.js → chunk-EICIFHVS.js} +1 -1
- package/chunk-EJE33XNR.js +19059 -0
- package/{chunk-6SZ52ORL.js → chunk-FJHMLRDQ.js} +9 -9
- package/{chunk-RU5D3B22.js → chunk-GRFK2XP4.js} +2 -2
- package/{chunk-J3UALFHL.js → chunk-HJTAGT3W.js} +1 -1
- package/{chunk-WL3UOGYO.js → chunk-HPW5MNDQ.js} +38 -98
- package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
- package/{chunk-OYNDYVSE.js → chunk-JON2PHYT.js} +1 -1
- package/{chunk-7K5VMB4Q.js → chunk-JXIP6ZWH.js} +7 -7
- package/{chunk-KUUTWU4I.js → chunk-K4NISKOR.js} +46 -8
- package/{chunk-SP3DPVBH.js → chunk-KLIBF3BY.js} +2 -2
- package/chunk-LRGKOI5Y.js +297 -0
- package/{chunk-LN3OQJGG.js → chunk-MLEZPE3U.js} +2 -2
- package/{chunk-FGEYVPPR.js → chunk-MYMBBB6Q.js} +5 -64
- package/{chunk-VRJUIUIY.js → chunk-N4JKMCY3.js} +2 -2
- package/{chunk-U5Z7LFZF.js → chunk-NFLA6GSU.js} +4 -4
- package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
- package/{chunk-56W233KG.js → chunk-NJUQBYFJ.js} +3 -1
- package/{chunk-Q24S4NDF.js → chunk-Q4XZVZPN.js} +1 -1
- package/{chunk-UW4INMD2.js → chunk-RHMDMTDK.js} +2 -2
- package/{chunk-MFI4FGHX.js → chunk-SAJSBPI2.js} +1 -1
- package/{chunk-WHVQA7PJ.js → chunk-SSXTSPSG.js} +27 -6
- package/{chunk-2BWU4ORW.js → chunk-SUEIAK5N.js} +1 -1
- package/{chunk-3QJTD6DO.js → chunk-SVC3GGUA.js} +5 -5
- package/{chunk-QDHZCAH3.js → chunk-SVDMVX4G.js} +118 -2
- package/{chunk-GBADO3SM.js → chunk-SWJGJMTW.js} +1 -1
- package/{chunk-DQLYEGP7.js → chunk-SYYUU7EV.js} +2 -2
- package/{chunk-U2A47SVI.js → chunk-TC6P4NDR.js} +7 -7
- package/{chunk-V4KZGLOI.js → chunk-TR4DXUYX.js} +1983 -447
- package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
- package/chunk-UAD2WT54.js +64 -0
- package/{chunk-PAHILFNT.js → chunk-UGBHDMHI.js} +4 -4
- package/{chunk-6FQ2552G.js → chunk-UOWXD4VN.js} +799 -956
- package/{chunk-5WADL4O7.js → chunk-UR66XPVF.js} +3 -3
- package/{chunk-6BYAXNH5.js → chunk-VZMUOPYG.js} +12 -2
- package/{chunk-LA4IDAK7.js → chunk-WQHGJHAL.js} +440 -2981
- package/{chunk-GLGD2JGY.js → chunk-XIJZOCSP.js} +7 -7
- package/{chunk-BJLYCOZK.js → chunk-YBFJQC2M.js} +93 -776
- package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
- package/{chunk-32I5RVMY.js → chunk-YLCUU3WM.js} +3 -3
- package/{chunk-D3JQPONH.js → chunk-YQBXOHE6.js} +1 -1
- package/chunk-ZJ7UHBJS.js +89 -0
- package/{chunk-TNPCQNGQ.js → chunk-ZVOHVJI3.js} +4 -9
- package/contentThunks-KNI6VXLT.js +71 -0
- package/{createAgentAutomationAction-UJLNFFFC.js → createAgentAutomationAction-OK4L33KF.js} +27 -23
- package/{createDialogAction-TJCX6GUE.js → createDialogAction-JDSMY4AY.js} +28 -24
- package/{createPageAction-N3IYABHV.js → createPageAction-T7RA3HCG.js} +29 -24
- package/{dbSlice-D5CNGWPD.js → dbSlice-TVX6SN2T.js} +6 -6
- package/{deleteFile-44TUM34Y.js → deleteFile-JYKRT7C3.js} +3 -3
- package/{dialogCommands-35M6RBAC.js → dialogCommands-UQZYWOOV.js} +32 -30
- package/{dialogSlice-KO7ADD7H.js → dialogSlice-TYW2G7IL.js} +26 -23
- package/{docCreateCommands-VXHZWQ3P.js → docCreateCommands-OA6HZBWO.js} +34 -32
- package/{docDeleteCommands-4WFAJR6A.js → docDeleteCommands-KBB3YQI2.js} +31 -29
- package/{docReadCommands-OYREEFAR.js → docReadCommands-ZLMFVC67.js} +30 -28
- package/{docStore-5BU76DFK.js → docStore-2URPBVCS.js} +8 -33
- package/{docUpdateCommands-A7QERSME.js → docUpdateCommands-HMH5KUON.js} +34 -32
- package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
- package/{getPricing-HAU62AFM.js → getPricing-RFOPUWHY.js} +4 -4
- package/{handleSendMessageAction-OSGQJQ45.js → handleSendMessageAction-GO53TY7U.js} +28 -25
- package/index.js +56 -56
- package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
- package/{machineCommands-J43U3TX5.js → machineCommands-RK6L7ZWL.js} +59 -54
- package/{machineWsRunDispatch-Z2Z6STXZ.js → machineWsRunDispatch-3X64DW2Z.js} +54 -49
- package/memberThunks-THZYZFSN.js +638 -0
- package/{models-4QF4BJVY.js → models-JVKUEER5.js} +2 -2
- package/package.json +1 -1
- package/{read-RGNPI5H2.js → read-K4JU4MQC.js} +3 -3
- package/{readDocTool-6ESWKTXD.js → readDocTool-LQGR6FUN.js} +1 -1
- package/{readlineWorkspace-YRPV6JPN.js → readlineWorkspace-XUFJV3RS.js} +604 -263
- package/{removeDialogAgentAction-JYT73FU2.js → removeDialogAgentAction-ECHCFB7N.js} +12 -11
- package/{runAgentClientLoop-5YM5WMAY.js → runAgentClientLoop-24GQ2AW6.js} +46 -40
- package/{setDialogExtraReferencesAction-D564LMYQ.js → setDialogExtraReferencesAction-KCVJNGMB.js} +9 -8
- package/{setPrimaryDialogAgentAction-ACY3BLYA.js → setPrimaryDialogAgentAction-VDOBOMKC.js} +12 -11
- package/{settingSlice-MKI3MNZJ.js → settingSlice-VR2IJSXC.js} +7 -7
- package/{skillDiscovery-GPUDHDTZ.js → skillDiscovery-2QTZINON.js} +3 -3
- package/{spaceCommands-MY26V52L.js → spaceCommands-S5YJJXL7.js} +30 -28
- package/{streamAgentChatTurn-XV5X5TNQ.js → streamAgentChatTurn-QHKP3ABO.js} +77 -64
- package/{switchDialogAgentAction-CJ5H6SAR.js → switchDialogAgentAction-5L4UP7VI.js} +10 -9
- package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
- package/{tools-MIMELA2Y.js → tools-SSXSTC3O.js} +37 -32
- package/{tuiSummaryLlmCaller-XJ5BKNNS.js → tuiSummaryLlmCaller-URFJHFC5.js} +17 -15
- package/{updateDialogTitleAction-EIZUSWHR.js → updateDialogTitleAction-YFYAEW3T.js} +28 -24
- package/chunk-6BGAQ3KR.js +0 -7081
- package/chunk-YBV6QJKM.js +0 -441
- package/spaceSlice-JUIXC365.js +0 -127
- package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
- package/{chunk-PYKV6FSC.js → chunk-XOJRZUPF.js} +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
findPotentialSecrets
|
|
3
|
+
} from "./chunk-S7Z2HMCN.js";
|
|
4
4
|
import {
|
|
5
5
|
buildLocalRunEnv,
|
|
6
6
|
isFullstackCodingAgentRef,
|
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
resolveServerUrl,
|
|
11
11
|
writeUsage
|
|
12
12
|
} from "./chunk-LYGNQHUW.js";
|
|
13
|
+
import {
|
|
14
|
+
resolveMachineId
|
|
15
|
+
} from "./chunk-ESHYE7WU.js";
|
|
13
16
|
import {
|
|
14
17
|
agentRunCardLabels,
|
|
15
18
|
createCliLocalRuntimeAdapter,
|
|
@@ -19,7 +22,12 @@ import {
|
|
|
19
22
|
parseAgentRunEvent,
|
|
20
23
|
t,
|
|
21
24
|
toolLabel
|
|
22
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-5FCIPEKT.js";
|
|
26
|
+
import {
|
|
27
|
+
readCredentialEntry,
|
|
28
|
+
recordCredentialProbe,
|
|
29
|
+
resolveCredentialKeyWithFallback
|
|
30
|
+
} from "./chunk-NI2BS6UD.js";
|
|
23
31
|
import {
|
|
24
32
|
getReadableCliDb
|
|
25
33
|
} from "./chunk-43CXXVJD.js";
|
|
@@ -27,11 +35,14 @@ import {
|
|
|
27
35
|
normalizeAgentHandle,
|
|
28
36
|
readDbRecord,
|
|
29
37
|
resolveAgentRecordFromHybridStore
|
|
30
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-SYYUU7EV.js";
|
|
31
39
|
import {
|
|
32
40
|
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
33
41
|
isLocalCliAgentKey
|
|
34
42
|
} from "./chunk-EKLRRZIN.js";
|
|
43
|
+
import {
|
|
44
|
+
generateRunReport
|
|
45
|
+
} from "./chunk-HJTAGT3W.js";
|
|
35
46
|
import {
|
|
36
47
|
CliProviderQuotaError
|
|
37
48
|
} from "./chunk-JDSUTNYY.js";
|
|
@@ -42,17 +53,14 @@ import {
|
|
|
42
53
|
readRunRecord,
|
|
43
54
|
resolveRunQueuePath,
|
|
44
55
|
spawnLocalBackgroundRun
|
|
45
|
-
} from "./chunk-
|
|
46
|
-
import {
|
|
47
|
-
resolveMachineId
|
|
48
|
-
} from "./chunk-ESHYE7WU.js";
|
|
56
|
+
} from "./chunk-SSXTSPSG.js";
|
|
49
57
|
import {
|
|
50
58
|
applyModelLayerOverride,
|
|
51
59
|
buildModelLayerOverride
|
|
52
60
|
} from "./chunk-LTRXGFMS.js";
|
|
53
61
|
import {
|
|
54
62
|
formatAgentListCard
|
|
55
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-TR4DXUYX.js";
|
|
56
64
|
import {
|
|
57
65
|
isTransientFetchError
|
|
58
66
|
} from "./chunk-5XTOKQLW.js";
|
|
@@ -66,26 +74,25 @@ import {
|
|
|
66
74
|
formatStartRunCard,
|
|
67
75
|
formatStatusRunCard,
|
|
68
76
|
formatStopRunCard,
|
|
69
|
-
isAgentRunTerminalStatus
|
|
70
|
-
runShowsLogTail
|
|
77
|
+
isAgentRunTerminalStatus
|
|
71
78
|
} from "./chunk-KXKQO4Q6.js";
|
|
72
79
|
import {
|
|
73
80
|
buildMemorySubjectsForAgent,
|
|
74
81
|
chooseMemoryOwners,
|
|
75
82
|
loadMemoryCandidatesFromDb,
|
|
76
83
|
resolveAgentMemoryPolicy
|
|
77
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-FJHMLRDQ.js";
|
|
78
85
|
import {
|
|
79
86
|
API_REPORTED_COST_MULTIPLIER,
|
|
80
87
|
normalizeUsage,
|
|
81
88
|
parseUiAskChoiceContent
|
|
82
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-YBFJQC2M.js";
|
|
83
90
|
import {
|
|
84
91
|
getDefaultCliLocalRuntimeDb
|
|
85
92
|
} from "./chunk-IA3A5373.js";
|
|
86
93
|
import {
|
|
87
94
|
buildSkillDiscoveryContextLayer
|
|
88
|
-
} from "./chunk-
|
|
95
|
+
} from "./chunk-SUEIAK5N.js";
|
|
89
96
|
import {
|
|
90
97
|
parseExternalSkillMarkdown,
|
|
91
98
|
parseSkillDocProtocol
|
|
@@ -93,12 +100,11 @@ import {
|
|
|
93
100
|
import {
|
|
94
101
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
95
102
|
LOCAL_TURN_ABORTED_CODE,
|
|
96
|
-
readActionGate
|
|
97
|
-
|
|
98
|
-
} from "./chunk-6BGAQ3KR.js";
|
|
103
|
+
readActionGate
|
|
104
|
+
} from "./chunk-EJE33XNR.js";
|
|
99
105
|
import {
|
|
100
106
|
resolveAgentRuntimeConfigFromRecord
|
|
101
|
-
} from "./chunk-
|
|
107
|
+
} from "./chunk-A65UV3M5.js";
|
|
102
108
|
import {
|
|
103
109
|
createThinkParserState,
|
|
104
110
|
flushThinkParser,
|
|
@@ -107,20 +113,22 @@ import {
|
|
|
107
113
|
import {
|
|
108
114
|
resolveClientVersion,
|
|
109
115
|
resolvePlatformAuthToken
|
|
110
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-KLIBF3BY.js";
|
|
111
117
|
import {
|
|
112
|
-
isQuotaExhaustedError
|
|
118
|
+
isQuotaExhaustedError,
|
|
119
|
+
mergeAvailabilityDeadline,
|
|
120
|
+
resolveCooldownGate
|
|
113
121
|
} from "./chunk-IWUMSAQF.js";
|
|
114
122
|
import {
|
|
115
123
|
DEFAULT_CONTEXT_WINDOW,
|
|
116
124
|
getModelContextWindow
|
|
117
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-K4NISKOR.js";
|
|
118
126
|
import {
|
|
119
127
|
clipCompactText
|
|
120
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-BBTN4NQD.js";
|
|
121
129
|
import {
|
|
122
130
|
findModelConfig
|
|
123
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-SVDMVX4G.js";
|
|
124
132
|
import {
|
|
125
133
|
compactWhitespace
|
|
126
134
|
} from "./chunk-DWLEOOGR.js";
|
|
@@ -133,7 +141,7 @@ import {
|
|
|
133
141
|
buildMemoryUseGuidanceLayer,
|
|
134
142
|
partitionScopedBlocks,
|
|
135
143
|
renderTurnContextBlocksWithScope
|
|
136
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-DVINR3PL.js";
|
|
137
145
|
import {
|
|
138
146
|
readPipeText,
|
|
139
147
|
spawnProcess
|
|
@@ -145,13 +153,13 @@ import {
|
|
|
145
153
|
CLIENT_VERSION_TOO_OLD_CODE,
|
|
146
154
|
NOLO_CLIENT_VERSION_HEADER,
|
|
147
155
|
buildClientVersionUpgradeMessage
|
|
148
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-HPW5MNDQ.js";
|
|
149
157
|
import {
|
|
150
158
|
parsePositiveFiniteNumberOrFallback
|
|
151
159
|
} from "./chunk-Y5GCAMGP.js";
|
|
152
160
|
import {
|
|
153
161
|
createMemoryKey
|
|
154
|
-
} from "./chunk-
|
|
162
|
+
} from "./chunk-NHRQCXIQ.js";
|
|
155
163
|
import {
|
|
156
164
|
asTrimmedLowercaseString
|
|
157
165
|
} from "./chunk-QSJ3HFEF.js";
|
|
@@ -159,7 +167,7 @@ import {
|
|
|
159
167
|
BUILTIN_NOLO_AGENT_KEY,
|
|
160
168
|
BUILTIN_NOLO_AGENT_NAME,
|
|
161
169
|
builtinAgentCatalogEntryById
|
|
162
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-2WBFJHQA.js";
|
|
163
171
|
import {
|
|
164
172
|
parsePublicAgentId
|
|
165
173
|
} from "./chunk-BJIRLHJR.js";
|
|
@@ -174,6 +182,7 @@ import {
|
|
|
174
182
|
} from "./chunk-G3SUCT4W.js";
|
|
175
183
|
|
|
176
184
|
// packages/cli/client/tokenUsage.ts
|
|
185
|
+
var PLATFORM_CREDIT_UNIT = "credits";
|
|
177
186
|
var isUsableModelId = (model) => {
|
|
178
187
|
const raw = model?.trim();
|
|
179
188
|
return Boolean(raw) && raw !== "-" && raw !== "auto";
|
|
@@ -245,7 +254,7 @@ function buildTurnTokenUsage(usage, model) {
|
|
|
245
254
|
const contextWindow = resolveContextWindow(model);
|
|
246
255
|
const remaining = contextWindow && parsed.input > 0 ? Math.max(0, contextWindow - parsed.input) : void 0;
|
|
247
256
|
const rawCost = typeof usage?.cost === "number" ? usage.cost : void 0;
|
|
248
|
-
const isPlatformBilled = usage?.billing_unit ===
|
|
257
|
+
const isPlatformBilled = usage?.billing_unit === PLATFORM_CREDIT_UNIT;
|
|
249
258
|
const credits = rawCost !== void 0 && rawCost > 0 ? isPlatformBilled ? rawCost : rawCost * API_REPORTED_COST_MULTIPLIER : void 0;
|
|
250
259
|
return {
|
|
251
260
|
...parsed,
|
|
@@ -254,6 +263,31 @@ function buildTurnTokenUsage(usage, model) {
|
|
|
254
263
|
...credits !== void 0 ? { credits } : {}
|
|
255
264
|
};
|
|
256
265
|
}
|
|
266
|
+
function sumPlatformCredits(records) {
|
|
267
|
+
if (!records?.length) return void 0;
|
|
268
|
+
let total = 0;
|
|
269
|
+
let sawPlatformCall = false;
|
|
270
|
+
for (const record of records) {
|
|
271
|
+
const credits = platformCreditsFromUsage(record?.usage);
|
|
272
|
+
if (credits === void 0) continue;
|
|
273
|
+
sawPlatformCall = true;
|
|
274
|
+
total += credits;
|
|
275
|
+
}
|
|
276
|
+
return sawPlatformCall ? total : void 0;
|
|
277
|
+
}
|
|
278
|
+
function platformCreditsFromUsage(usage) {
|
|
279
|
+
if (!usage || usage.billing_unit !== PLATFORM_CREDIT_UNIT) return void 0;
|
|
280
|
+
const cost = typeof usage.cost === "number" ? usage.cost : 0;
|
|
281
|
+
return Number.isFinite(cost) && cost > 0 ? cost : 0;
|
|
282
|
+
}
|
|
283
|
+
function withTurnCredits(tokens, credits) {
|
|
284
|
+
if (!tokens) return tokens;
|
|
285
|
+
if (credits === void 0) return tokens;
|
|
286
|
+
return { ...tokens, credits };
|
|
287
|
+
}
|
|
288
|
+
function formatCreditsChip(credits, options) {
|
|
289
|
+
return options?.compact ? `\u26A1${credits.toFixed(2)}` : `\u26A1 ${credits.toFixed(2)} \u79EF\u5206`;
|
|
290
|
+
}
|
|
257
291
|
function formatTokenCount(value) {
|
|
258
292
|
if (!Number.isFinite(value) || value < 0) return "\u2014";
|
|
259
293
|
if (value < 1e3) return String(Math.round(value));
|
|
@@ -2908,6 +2942,14 @@ function normalizeListLine(line) {
|
|
|
2908
2942
|
}
|
|
2909
2943
|
return line;
|
|
2910
2944
|
}
|
|
2945
|
+
function isPolishListLikeLine(line) {
|
|
2946
|
+
return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
|
|
2947
|
+
}
|
|
2948
|
+
var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2949
|
+
function polishBreathInsertsBlankBetween(cur, next) {
|
|
2950
|
+
if (cur === "" || next === "") return false;
|
|
2951
|
+
return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
|
|
2952
|
+
}
|
|
2911
2953
|
function convertMarkdownTablesForTerminal(text) {
|
|
2912
2954
|
const lines = text.split("\n");
|
|
2913
2955
|
const out = [];
|
|
@@ -2975,7 +3017,7 @@ function polishAssistantStructure(text, options = {}) {
|
|
|
2975
3017
|
return line;
|
|
2976
3018
|
});
|
|
2977
3019
|
const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,3} )/g, "$1\n\n$2").replace(/^(#{1,3} .+)\n(?!\n)/gm, "$1\n\n").replace(/\n{4,}/g, "\n\n\n");
|
|
2978
|
-
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]/;
|
|
3020
|
+
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2979
3021
|
const headingLines = afterHeading.split("\n");
|
|
2980
3022
|
const breathed = [];
|
|
2981
3023
|
for (let i = 0; i < headingLines.length; i++) {
|
|
@@ -3333,130 +3375,16 @@ function formatAssistantTextForCli(text) {
|
|
|
3333
3375
|
return text.replace(/\u003cthink\u003e[\s\S]*?\u003c\/think\u003e\s*/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
3334
3376
|
}
|
|
3335
3377
|
|
|
3336
|
-
// packages/cli/
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
}
|
|
3347
|
-
return path.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
3348
|
-
}
|
|
3349
|
-
|
|
3350
|
-
// packages/cli/client/formatReadPathTree.ts
|
|
3351
|
-
function clipPathAware(value, max = 72) {
|
|
3352
|
-
const compact = compactWhitespace(value);
|
|
3353
|
-
if (compact.length <= max) return compact;
|
|
3354
|
-
if (compact.includes(" ") || !compact.includes("/") && !compact.includes("\\")) {
|
|
3355
|
-
return clipCompactText(value, max, "\u2026");
|
|
3356
|
-
}
|
|
3357
|
-
const segments = compact.split(/[/\\]/);
|
|
3358
|
-
const filename = segments[segments.length - 1];
|
|
3359
|
-
if (filename.length >= max) {
|
|
3360
|
-
return clipCompactText(value, max, "\u2026");
|
|
3361
|
-
}
|
|
3362
|
-
const ELISION = "/\u2026/";
|
|
3363
|
-
let prefix = "";
|
|
3364
|
-
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3365
|
-
const candidate = segments.slice(0, i + 1).join("/");
|
|
3366
|
-
if (candidate.length + ELISION.length + filename.length > max) break;
|
|
3367
|
-
prefix = candidate;
|
|
3368
|
-
}
|
|
3369
|
-
if (prefix) return `${prefix}${ELISION}${filename}`;
|
|
3370
|
-
const filenameOnly = `\u2026/${filename}`;
|
|
3371
|
-
if (filenameOnly.length <= max) return filenameOnly;
|
|
3372
|
-
return clipCompactText(value, max, "\u2026");
|
|
3373
|
-
}
|
|
3374
|
-
function formatHomePath(path, customHomedir) {
|
|
3375
|
-
if (!path) return "";
|
|
3376
|
-
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
3377
|
-
return foldHomePath(path, home);
|
|
3378
|
-
}
|
|
3379
|
-
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
3380
|
-
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
3381
|
-
let formattedPath = formatHomePath(inputPath, customHomedir);
|
|
3382
|
-
if (!formattedPath) return "file";
|
|
3383
|
-
let rangePart = "";
|
|
3384
|
-
const match = formattedPath.match(/(:[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*)$/);
|
|
3385
|
-
if (match) {
|
|
3386
|
-
rangePart = match[1];
|
|
3387
|
-
formattedPath = formattedPath.slice(0, -rangePart.length);
|
|
3388
|
-
} else if (metadata && typeof metadata.startLine === "number" && typeof metadata.endLine === "number" && typeof metadata.totalLines === "number") {
|
|
3389
|
-
const { startLine, endLine, totalLines, truncated } = metadata;
|
|
3390
|
-
if (truncated || startLine !== 1 || endLine !== totalLines) {
|
|
3391
|
-
rangePart = `:${startLine}-${endLine}`;
|
|
3392
|
-
}
|
|
3393
|
-
}
|
|
3394
|
-
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3395
|
-
return `${clippedPath}${rangePart}`;
|
|
3396
|
-
}
|
|
3397
|
-
function formatReadTreeLines(items, customHomedir) {
|
|
3398
|
-
const count = items.length;
|
|
3399
|
-
const header = `Read (${count})`;
|
|
3400
|
-
const lines = items.map((item, index) => {
|
|
3401
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3402
|
-
const pathWithRange = formatReadItemPath(item.path, item.metadata, customHomedir);
|
|
3403
|
-
return { connector, pathWithRange };
|
|
3404
|
-
});
|
|
3405
|
-
return { header, count, lines };
|
|
3406
|
-
}
|
|
3407
|
-
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3408
|
-
let text = (query || "").trim();
|
|
3409
|
-
if (path) {
|
|
3410
|
-
const formattedPath = formatHomePath(path, customHomedir);
|
|
3411
|
-
if (formattedPath) {
|
|
3412
|
-
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3415
|
-
if (!text) return "search";
|
|
3416
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3417
|
-
}
|
|
3418
|
-
function formatSearchTreeLines(items, customHomedir) {
|
|
3419
|
-
const count = items.length;
|
|
3420
|
-
const header = `Search (${count})`;
|
|
3421
|
-
const lines = items.map((item, index) => {
|
|
3422
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3423
|
-
const queryText = formatSearchItemQuery(item.query, item.path, customHomedir);
|
|
3424
|
-
return { connector, queryText };
|
|
3425
|
-
});
|
|
3426
|
-
return { header, count, lines };
|
|
3427
|
-
}
|
|
3428
|
-
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3429
|
-
let text = compactWhitespace(command || "");
|
|
3430
|
-
if (!text) text = "command";
|
|
3431
|
-
text = text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3432
|
-
if (timedOut) return `${text} (timed out)`;
|
|
3433
|
-
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3434
|
-
return text;
|
|
3435
|
-
}
|
|
3436
|
-
function formatRunTreeLines(items) {
|
|
3437
|
-
const count = items.length;
|
|
3438
|
-
const header = `Run (${count})`;
|
|
3439
|
-
const lines = items.map((item, index) => {
|
|
3440
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3441
|
-
const commandText = formatRunItemCommand(item.command, item.exitCode, item.timedOut);
|
|
3442
|
-
return { connector, commandText };
|
|
3443
|
-
});
|
|
3444
|
-
return { header, count, lines };
|
|
3445
|
-
}
|
|
3446
|
-
function formatFetchItemUrl(url) {
|
|
3447
|
-
const text = (url || "").trim();
|
|
3448
|
-
if (!text) return "webpage";
|
|
3449
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3450
|
-
}
|
|
3451
|
-
function formatFetchTreeLines(items) {
|
|
3452
|
-
const count = items.length;
|
|
3453
|
-
const header = `Fetch (${count})`;
|
|
3454
|
-
const lines = items.map((item, index) => {
|
|
3455
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3456
|
-
const urlText = formatFetchItemUrl(item.url);
|
|
3457
|
-
return { connector, urlText };
|
|
3458
|
-
});
|
|
3459
|
-
return { header, count, lines };
|
|
3378
|
+
// packages/cli/tui/redactSecrets.ts
|
|
3379
|
+
var REDACTED = "\u27E8redacted\u27E9";
|
|
3380
|
+
function redactSecrets(text) {
|
|
3381
|
+
return text.replace(/\b(?:sk|pk)-[A-Za-z0-9_-]{10,}/g, REDACTED).replace(/\b(Bearer\s+)[A-Za-z0-9._~+/=-]{12,}/gi, `$1${REDACTED}`).replace(
|
|
3382
|
+
/\b((?:api[_-]?key|apikey|access[_-]?token|auth[_-]?token|token|secret|password|passwd|credential)s?\s*[=:]\s*["']?)[^\s"',;]{8,}/gi,
|
|
3383
|
+
`$1${REDACTED}`
|
|
3384
|
+
).replace(
|
|
3385
|
+
/\b((?:--[a-z-]*(?:token|key|secret|password|credential)[a-z-]*)\s+)[^\s"']{8,}/gi,
|
|
3386
|
+
`$1${REDACTED}`
|
|
3387
|
+
);
|
|
3460
3388
|
}
|
|
3461
3389
|
|
|
3462
3390
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -3709,186 +3637,110 @@ function tokenize(value, options) {
|
|
|
3709
3637
|
return retLines;
|
|
3710
3638
|
}
|
|
3711
3639
|
|
|
3712
|
-
// packages/cli/client/
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3640
|
+
// packages/cli/client/formatReadPathTree.ts
|
|
3641
|
+
import { homedir as osHomedir } from "node:os";
|
|
3642
|
+
|
|
3643
|
+
// packages/core/foldHomePath.ts
|
|
3644
|
+
function foldHomePath(path, home) {
|
|
3645
|
+
if (!path) return path;
|
|
3646
|
+
if (home) {
|
|
3647
|
+
const cleanHome = home.endsWith("/") ? home.slice(0, -1) : home;
|
|
3648
|
+
if (path === cleanHome) return "~";
|
|
3649
|
+
if (path.startsWith(cleanHome + "/")) return `~${path.slice(cleanHome.length)}`;
|
|
3717
3650
|
}
|
|
3718
|
-
|
|
3719
|
-
|
|
3651
|
+
return path.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
// packages/cli/client/formatReadPathTree.ts
|
|
3655
|
+
function clipPathAware(value, max = 72) {
|
|
3656
|
+
const compact = compactWhitespace(value);
|
|
3657
|
+
if (compact.length <= max) return compact;
|
|
3658
|
+
if (compact.includes(" ") || !compact.includes("/") && !compact.includes("\\")) {
|
|
3659
|
+
return clipCompactText(value, max, "\u2026");
|
|
3720
3660
|
}
|
|
3721
|
-
|
|
3722
|
-
|
|
3661
|
+
const segments = compact.split(/[/\\]/);
|
|
3662
|
+
const filename = segments[segments.length - 1];
|
|
3663
|
+
if (filename.length >= max) {
|
|
3664
|
+
return clipCompactText(value, max, "\u2026");
|
|
3723
3665
|
}
|
|
3724
|
-
|
|
3725
|
-
|
|
3666
|
+
const ELISION = "/\u2026/";
|
|
3667
|
+
let prefix = "";
|
|
3668
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3669
|
+
const candidate = segments.slice(0, i + 1).join("/");
|
|
3670
|
+
if (candidate.length + ELISION.length + filename.length > max) break;
|
|
3671
|
+
prefix = candidate;
|
|
3726
3672
|
}
|
|
3727
|
-
return
|
|
3673
|
+
if (prefix) return `${prefix}${ELISION}${filename}`;
|
|
3674
|
+
const filenameOnly = `\u2026/${filename}`;
|
|
3675
|
+
if (filenameOnly.length <= max) return filenameOnly;
|
|
3676
|
+
return clipCompactText(value, max, "\u2026");
|
|
3677
|
+
}
|
|
3678
|
+
function formatHomePath(path, customHomedir) {
|
|
3679
|
+
if (!path) return "";
|
|
3680
|
+
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
3681
|
+
return foldHomePath(path, home);
|
|
3728
3682
|
}
|
|
3729
|
-
function
|
|
3730
|
-
const
|
|
3731
|
-
|
|
3732
|
-
|
|
3683
|
+
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
3684
|
+
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
3685
|
+
let formattedPath = formatHomePath(inputPath, customHomedir);
|
|
3686
|
+
if (!formattedPath) return "file";
|
|
3687
|
+
let rangePart = "";
|
|
3688
|
+
const match = formattedPath.match(/(:[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*)$/);
|
|
3689
|
+
if (match) {
|
|
3690
|
+
rangePart = match[1];
|
|
3691
|
+
formattedPath = formattedPath.slice(0, -rangePart.length);
|
|
3692
|
+
} else if (metadata && typeof metadata.startLine === "number" && typeof metadata.endLine === "number" && typeof metadata.totalLines === "number") {
|
|
3693
|
+
const { startLine, endLine, totalLines, truncated } = metadata;
|
|
3694
|
+
if (truncated || startLine !== 1 || endLine !== totalLines) {
|
|
3695
|
+
rangePart = `:${startLine}-${endLine}`;
|
|
3696
|
+
}
|
|
3733
3697
|
}
|
|
3734
|
-
|
|
3735
|
-
|
|
3698
|
+
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3699
|
+
return `${clippedPath}${rangePart}`;
|
|
3700
|
+
}
|
|
3701
|
+
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3702
|
+
let text = (query || "").trim();
|
|
3703
|
+
if (path) {
|
|
3704
|
+
const formattedPath = formatHomePath(path, customHomedir);
|
|
3705
|
+
if (formattedPath) {
|
|
3706
|
+
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
3707
|
+
}
|
|
3736
3708
|
}
|
|
3737
|
-
|
|
3709
|
+
if (!text) return "search";
|
|
3710
|
+
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3711
|
+
}
|
|
3712
|
+
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3713
|
+
let text = compactWhitespace(command || "");
|
|
3714
|
+
if (!text) text = "command";
|
|
3715
|
+
text = text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3716
|
+
if (timedOut) return `${text} (timed out)`;
|
|
3717
|
+
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3718
|
+
return text;
|
|
3738
3719
|
}
|
|
3739
|
-
function
|
|
3740
|
-
|
|
3720
|
+
function formatFetchItemUrl(url) {
|
|
3721
|
+
const text = (url || "").trim();
|
|
3722
|
+
if (!text) return "webpage";
|
|
3723
|
+
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3741
3724
|
}
|
|
3725
|
+
|
|
3726
|
+
// packages/cli/client/toolOutput.ts
|
|
3742
3727
|
function clip(value, max = 72) {
|
|
3743
3728
|
return clipCompactText(value, max, "\u2026");
|
|
3744
3729
|
}
|
|
3745
|
-
function formatActiveToolLabel(event) {
|
|
3746
|
-
const toolName = event.toolName || "tool";
|
|
3747
|
-
const args = clipPathAware(event.argumentsPreview ?? "");
|
|
3748
|
-
const label = toolLabel(toolName);
|
|
3749
|
-
return args ? `${label} ${args}` : label;
|
|
3750
|
-
}
|
|
3751
3730
|
function formatConservativeActiveToolLabel(event) {
|
|
3752
3731
|
return toolLabel(event.toolName || "tool");
|
|
3753
3732
|
}
|
|
3754
|
-
function
|
|
3755
|
-
|
|
3756
|
-
if (gate) {
|
|
3757
|
-
const commandPayload = gate.kind === "handoff" ? readCommandActionGatePayload(gate.payload) : null;
|
|
3758
|
-
const command = commandPayload?.displayCommand ?? commandPayload?.command.join(" ") ?? "";
|
|
3759
|
-
const detail = command.trim() ? command : gate.title;
|
|
3760
|
-
return { inline: `${t("toolNeedsAction")}: ${clip(detail, 120)}` };
|
|
3761
|
-
}
|
|
3762
|
-
if (event.metadata?.timedOut) return { inline: t("toolTimedOut") };
|
|
3763
|
-
if (event.toolName === "readFile" && event.metadata) {
|
|
3764
|
-
const range = readReadFileRange(event.metadata);
|
|
3765
|
-
if (range) return { inline: range };
|
|
3766
|
-
}
|
|
3767
|
-
if (event.toolName === "editFile" && event.metadata) {
|
|
3768
|
-
const res = formatEditFileSnippet(event.metadata);
|
|
3769
|
-
if (res) {
|
|
3770
|
-
const stats = [];
|
|
3771
|
-
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
3772
|
-
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
3773
|
-
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
3774
|
-
return { inline, detail: res.lines };
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
if (event.toolName === "writeFile" && event.metadata) {
|
|
3778
|
-
const totalLines = event.metadata.totalLines ?? event.metadata.lines;
|
|
3779
|
-
if (typeof totalLines === "number" && totalLines > 0) {
|
|
3780
|
-
return { inline: `(+${totalLines})` };
|
|
3781
|
-
}
|
|
3782
|
-
}
|
|
3783
|
-
const summary = event.summary;
|
|
3784
|
-
if (!summary) return { inline: "" };
|
|
3785
|
-
const exitMatch = summary.match(/exit=(\d+)/);
|
|
3786
|
-
if (exitMatch && exitMatch[1] !== "0") return { inline: `${t("toolExitCode")} ${exitMatch[1]}` };
|
|
3787
|
-
return { inline: "" };
|
|
3788
|
-
}
|
|
3789
|
-
function readReadFileRange(metadata) {
|
|
3790
|
-
const startLine = metadata.startLine;
|
|
3791
|
-
const endLine = metadata.endLine;
|
|
3792
|
-
const totalLines = metadata.totalLines;
|
|
3793
|
-
const truncated = metadata.truncated;
|
|
3794
|
-
if (typeof startLine !== "number" || typeof endLine !== "number" || typeof totalLines !== "number") {
|
|
3795
|
-
return void 0;
|
|
3796
|
-
}
|
|
3797
|
-
if (!truncated && startLine === 1 && endLine === totalLines) return void 0;
|
|
3798
|
-
return `${startLine}-${endLine}/${totalLines}`;
|
|
3799
|
-
}
|
|
3800
|
-
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
3801
|
-
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
3802
|
-
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
3803
|
-
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
3804
|
-
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
3805
|
-
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
3806
|
-
}
|
|
3807
|
-
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
3808
|
-
if (cols > 0) {
|
|
3809
|
-
return Math.max(80, Math.min(160, cols - 8));
|
|
3810
|
-
}
|
|
3811
|
-
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
3812
|
-
}
|
|
3813
|
-
function formatEditFileSnippet(metadata) {
|
|
3814
|
-
const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
|
|
3815
|
-
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
3816
|
-
if (!oldSnippet && !newSnippet) return void 0;
|
|
3817
|
-
const maxWidth = resolveEditSnippetMaxWidth();
|
|
3818
|
-
if (oldSnippet && !newSnippet) {
|
|
3819
|
-
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
3820
|
-
return { lines, addedCount: 0, removedCount: lines.length };
|
|
3821
|
-
}
|
|
3822
|
-
if (newSnippet && !oldSnippet) {
|
|
3823
|
-
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
3824
|
-
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
3825
|
-
}
|
|
3826
|
-
const parts = diffLines(oldSnippet, newSnippet);
|
|
3827
|
-
const all = [];
|
|
3828
|
-
let addedCount = 0;
|
|
3829
|
-
let removedCount = 0;
|
|
3830
|
-
for (const part of parts) {
|
|
3831
|
-
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
3832
|
-
const raw = part.value.split("\n");
|
|
3833
|
-
if (raw.length > 0 && raw[raw.length - 1] === "") raw.pop();
|
|
3834
|
-
for (const line of raw) {
|
|
3835
|
-
if (kind === "added") addedCount++;
|
|
3836
|
-
if (kind === "removed") removedCount++;
|
|
3837
|
-
all.push(buildEditLine(kind, line, maxWidth));
|
|
3838
|
-
}
|
|
3839
|
-
}
|
|
3840
|
-
const changeCount = all.filter((l) => l.kind !== "context").length;
|
|
3841
|
-
if (changeCount === 0) return void 0;
|
|
3842
|
-
return {
|
|
3843
|
-
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
3844
|
-
addedCount,
|
|
3845
|
-
removedCount
|
|
3846
|
-
};
|
|
3847
|
-
}
|
|
3848
|
-
function prefixFor(kind) {
|
|
3849
|
-
return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
|
|
3733
|
+
function isRunToolName(name) {
|
|
3734
|
+
return name === "execShell" || name === "runCommand" || name === "launchProcess";
|
|
3850
3735
|
}
|
|
3851
|
-
function
|
|
3852
|
-
return
|
|
3736
|
+
function isReadToolName(name) {
|
|
3737
|
+
return name === "readFile";
|
|
3853
3738
|
}
|
|
3854
|
-
function
|
|
3855
|
-
const
|
|
3856
|
-
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
if (displayWidth(line) <= maxWidth) return line;
|
|
3860
|
-
let width = 0;
|
|
3861
|
-
let kept = "";
|
|
3862
|
-
for (const char of line) {
|
|
3863
|
-
const w = displayWidth(char);
|
|
3864
|
-
if (width + w + 1 > maxWidth) break;
|
|
3865
|
-
kept += char;
|
|
3866
|
-
width += w;
|
|
3867
|
-
}
|
|
3868
|
-
return `${kept}\u2026`;
|
|
3869
|
-
}
|
|
3870
|
-
function windowAndTruncate(lines, maxLines) {
|
|
3871
|
-
if (lines.length <= maxLines) return lines;
|
|
3872
|
-
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
3873
|
-
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
3874
|
-
const half = Math.floor(maxLines / 2);
|
|
3875
|
-
let start = Math.max(0, firstChange - half);
|
|
3876
|
-
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
3877
|
-
const kept = lines.slice(start, start + maxLines);
|
|
3878
|
-
const omitted = lines.length - kept.length;
|
|
3879
|
-
if (omitted > 0) {
|
|
3880
|
-
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
3881
|
-
}
|
|
3882
|
-
return kept;
|
|
3883
|
-
}
|
|
3884
|
-
function isFailedToolResult(event) {
|
|
3885
|
-
const exitCode = event.metadata?.exitCode;
|
|
3886
|
-
if (event.metadata?.actionGate) return false;
|
|
3887
|
-
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3888
|
-
return Boolean(event.metadata?.timedOut);
|
|
3889
|
-
}
|
|
3890
|
-
function isNeedsActionToolResult(event) {
|
|
3891
|
-
return Boolean(event.metadata?.actionGate);
|
|
3739
|
+
function isFailedToolResult(event) {
|
|
3740
|
+
const exitCode = event.metadata?.exitCode;
|
|
3741
|
+
if (event.metadata?.actionGate) return false;
|
|
3742
|
+
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3743
|
+
return Boolean(event.metadata?.timedOut);
|
|
3892
3744
|
}
|
|
3893
3745
|
function parseUiAskChoiceForCli(event) {
|
|
3894
3746
|
if (event.toolName !== "ask_user" && !event.metadata?.uiAskChoice) {
|
|
@@ -4006,7 +3858,10 @@ function renderRunCard(snapshot, opts) {
|
|
|
4006
3858
|
lastToolNames: snapshot.lastToolNames?.map(cleanUserText)
|
|
4007
3859
|
} : snapshot;
|
|
4008
3860
|
const hadError = safe && Boolean(source.errorMessage?.trim());
|
|
4009
|
-
const errorFields = safe ? {
|
|
3861
|
+
const errorFields = safe ? {
|
|
3862
|
+
errorMessage: hadError ? clip(redactSecrets(cleanUserText(source.errorMessage)), 160) : void 0,
|
|
3863
|
+
logLines: void 0
|
|
3864
|
+
} : { errorMessage: source.errorMessage, logLines: source.logLines };
|
|
4010
3865
|
const body = isAgentRunTerminalStatus(snapshot.status) ? formatFinishedRunCard(name, snapshot.status, {
|
|
4011
3866
|
runId: snapshot.runId,
|
|
4012
3867
|
toolCallCount: source.toolCallCount,
|
|
@@ -4026,8 +3881,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
4026
3881
|
...opts?.includeLogTail !== void 0 ? { includeLogTail: opts.includeLogTail } : {},
|
|
4027
3882
|
labels
|
|
4028
3883
|
});
|
|
4029
|
-
return
|
|
4030
|
-
error ${t("runDiagnosticsHidden")}` : body;
|
|
3884
|
+
return body;
|
|
4031
3885
|
}
|
|
4032
3886
|
function recoverOrchestrationCard(event, toolName, opts) {
|
|
4033
3887
|
const safe = opts?.safe === true;
|
|
@@ -4073,10 +3927,6 @@ function recoverOrchestrationCard(event, toolName, opts) {
|
|
|
4073
3927
|
if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
|
|
4074
3928
|
return renderRunCard(snapshot, opts);
|
|
4075
3929
|
}
|
|
4076
|
-
function parseControlAgentRunStatusEvent(event) {
|
|
4077
|
-
const parsed = parseAgentRunEvent(event);
|
|
4078
|
-
return parsed?.kind === "status" ? parsed.snapshot : null;
|
|
4079
|
-
}
|
|
4080
3930
|
function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
4081
3931
|
const safe = opts?.safe === true;
|
|
4082
3932
|
const rawLabel = toolLabel(toolName);
|
|
@@ -4084,8 +3934,8 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
|
4084
3934
|
const rawDataStr = recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
|
|
4085
3935
|
const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || /^Error:/i.test(rawDataStr.trim());
|
|
4086
3936
|
if (failed) {
|
|
4087
|
-
const firstLine =
|
|
4088
|
-
const message = clip(firstLine, 96);
|
|
3937
|
+
const firstLine = stripAnsi2(rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
|
|
3938
|
+
const message = clip(redactSecrets(firstLine), 96);
|
|
4089
3939
|
if (!colorEnabled) {
|
|
4090
3940
|
return `\u2717 ${rawLabel} ${message}
|
|
4091
3941
|
`;
|
|
@@ -4127,7 +3977,7 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4127
3977
|
break;
|
|
4128
3978
|
}
|
|
4129
3979
|
if (/^\s*error\b/i.test(line)) {
|
|
4130
|
-
out.push(
|
|
3980
|
+
out.push(clip(redactSecrets(stripAnsi2(line)), 160));
|
|
4131
3981
|
errorIndent = line.length - line.trimStart().length;
|
|
4132
3982
|
continue;
|
|
4133
3983
|
}
|
|
@@ -4146,59 +3996,207 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4146
3996
|
}
|
|
4147
3997
|
return out;
|
|
4148
3998
|
}
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
logLines: next.logLines ?? previous.logLines,
|
|
4155
|
-
logKey: next.logKey || previous.logKey,
|
|
4156
|
-
toolCallCount: next.toolCallCount ?? previous.toolCallCount,
|
|
4157
|
-
lastToolNames: next.lastToolNames ?? previous.lastToolNames,
|
|
4158
|
-
lastAssistantText: next.lastAssistantText ?? previous.lastAssistantText,
|
|
4159
|
-
startedAt: next.startedAt ?? previous.startedAt,
|
|
4160
|
-
finishedAt: next.finishedAt ?? previous.finishedAt
|
|
4161
|
-
};
|
|
3999
|
+
var NORMAL_TOOL_GIST_MAX = 28;
|
|
4000
|
+
function gistClip(value, max = NORMAL_TOOL_GIST_MAX) {
|
|
4001
|
+
const oneLine = value.replace(/\s+/g, " ").trim();
|
|
4002
|
+
if (!oneLine) return "";
|
|
4003
|
+
return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}\u2026`;
|
|
4162
4004
|
}
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
);
|
|
4005
|
+
var DEFAULT_RUN_GIST_MAX = 96;
|
|
4006
|
+
function normalRunGistMaxWidth(env = process.env, columns) {
|
|
4007
|
+
const pinned = parseInt(env.NOLO_TEST_RUN_GIST_WIDTH ?? "", 10);
|
|
4008
|
+
if (!Number.isNaN(pinned) && pinned > 0) return pinned;
|
|
4009
|
+
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
4010
|
+
if (cols > 0) {
|
|
4011
|
+
return Math.max(48, Math.min(160, cols - 32));
|
|
4012
|
+
}
|
|
4013
|
+
return DEFAULT_RUN_GIST_MAX;
|
|
4014
|
+
}
|
|
4015
|
+
function commandFullGist(command, max) {
|
|
4016
|
+
const oneLine = command.replace(/\s+/g, " ").trim();
|
|
4017
|
+
if (!oneLine) return "";
|
|
4018
|
+
return truncateByDisplayWidth(redactSecrets(oneLine), max);
|
|
4177
4019
|
}
|
|
4178
|
-
function
|
|
4179
|
-
const
|
|
4180
|
-
const
|
|
4181
|
-
|
|
4182
|
-
|
|
4020
|
+
function pathBasenameGist(path) {
|
|
4021
|
+
const segments = path.split(/[\\/]/).filter((segment) => segment.length > 0);
|
|
4022
|
+
const base = segments.pop();
|
|
4023
|
+
return base ? gistClip(base) : "";
|
|
4024
|
+
}
|
|
4025
|
+
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
4026
|
+
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
4027
|
+
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
4028
|
+
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
4029
|
+
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
4030
|
+
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
4183
4031
|
}
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
return
|
|
4187
|
-
`[nolo:tool] #${round} !! ${event.toolName}${elapsed2}: ${event.message ?? "failed"}`,
|
|
4188
|
-
colorEnabled,
|
|
4189
|
-
"error"
|
|
4190
|
-
);
|
|
4032
|
+
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
4033
|
+
if (cols > 0) {
|
|
4034
|
+
return Math.max(80, Math.min(160, cols - 8));
|
|
4191
4035
|
}
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4036
|
+
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
4037
|
+
}
|
|
4038
|
+
function prefixFor(kind) {
|
|
4039
|
+
return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
|
|
4040
|
+
}
|
|
4041
|
+
function buildEditLine(kind, body, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
4042
|
+
return { kind, text: prefixFor(kind) + truncateByDisplayWidth(body, maxWidth) };
|
|
4043
|
+
}
|
|
4044
|
+
function snippetLinesWithKind(snippet, kind, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
4045
|
+
const lines = snippet.split(/\r?\n/);
|
|
4046
|
+
if (lines.at(-1) === "") lines.pop();
|
|
4047
|
+
return lines.slice(0, EDIT_SNIPPET_MAX_LINES).map((line) => buildEditLine(kind, line, maxWidth));
|
|
4048
|
+
}
|
|
4049
|
+
function truncateByDisplayWidth(line, maxWidth) {
|
|
4050
|
+
if (displayWidth(line) <= maxWidth) return line;
|
|
4051
|
+
let width = 0;
|
|
4052
|
+
let kept = "";
|
|
4053
|
+
for (const char of line) {
|
|
4054
|
+
const w = displayWidth(char);
|
|
4055
|
+
if (width + w + 1 > maxWidth) break;
|
|
4056
|
+
kept += char;
|
|
4057
|
+
width += w;
|
|
4196
4058
|
}
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
);
|
|
4059
|
+
return `${kept}\u2026`;
|
|
4060
|
+
}
|
|
4061
|
+
function windowAndTruncate(lines, maxLines) {
|
|
4062
|
+
if (lines.length <= maxLines) return lines;
|
|
4063
|
+
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
4064
|
+
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
4065
|
+
const half = Math.floor(maxLines / 2);
|
|
4066
|
+
let start = Math.max(0, firstChange - half);
|
|
4067
|
+
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
4068
|
+
const kept = lines.slice(start, start + maxLines);
|
|
4069
|
+
const omitted = lines.length - kept.length;
|
|
4070
|
+
if (omitted > 0) {
|
|
4071
|
+
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
4072
|
+
}
|
|
4073
|
+
return kept;
|
|
4074
|
+
}
|
|
4075
|
+
function formatEditFileSnippet(metadata) {
|
|
4076
|
+
const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
|
|
4077
|
+
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
4078
|
+
if (!oldSnippet && !newSnippet) return void 0;
|
|
4079
|
+
const maxWidth = resolveEditSnippetMaxWidth();
|
|
4080
|
+
if (oldSnippet && !newSnippet) {
|
|
4081
|
+
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
4082
|
+
return { lines, addedCount: 0, removedCount: lines.length };
|
|
4083
|
+
}
|
|
4084
|
+
if (newSnippet && !oldSnippet) {
|
|
4085
|
+
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
4086
|
+
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
4087
|
+
}
|
|
4088
|
+
const parts = diffLines(oldSnippet, newSnippet);
|
|
4089
|
+
const all = [];
|
|
4090
|
+
let addedCount = 0;
|
|
4091
|
+
let removedCount = 0;
|
|
4092
|
+
for (const part of parts) {
|
|
4093
|
+
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
4094
|
+
const bodyLines = part.value.replace(/\n$/, "").split("\n");
|
|
4095
|
+
for (const line of bodyLines) {
|
|
4096
|
+
if (kind === "added") addedCount++;
|
|
4097
|
+
if (kind === "removed") removedCount++;
|
|
4098
|
+
all.push(buildEditLine(kind, line, maxWidth));
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
return {
|
|
4102
|
+
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
4103
|
+
addedCount,
|
|
4104
|
+
removedCount
|
|
4105
|
+
};
|
|
4106
|
+
}
|
|
4107
|
+
function editFileResultHint(event) {
|
|
4108
|
+
if (event.toolName !== "editFile" || !event.metadata) return null;
|
|
4109
|
+
const res = formatEditFileSnippet(event.metadata);
|
|
4110
|
+
if (!res) return null;
|
|
4111
|
+
const stats = [];
|
|
4112
|
+
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
4113
|
+
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
4114
|
+
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
4115
|
+
return { inline, detail: res.lines };
|
|
4116
|
+
}
|
|
4117
|
+
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4118
|
+
if (!colorEnabled) {
|
|
4119
|
+
return lines.map((line) => ` ${line.text}
|
|
4120
|
+
`).join("");
|
|
4121
|
+
}
|
|
4122
|
+
const isTruecolor = supportsTruecolor(env);
|
|
4123
|
+
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4124
|
+
const brightness = resolveTuiBrightness(env);
|
|
4125
|
+
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4126
|
+
return lines.map((line) => ` ${renderDiffLine({
|
|
4127
|
+
kind: line.kind,
|
|
4128
|
+
text: line.text,
|
|
4129
|
+
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4130
|
+
padTo,
|
|
4131
|
+
colorEnabled: true,
|
|
4132
|
+
env
|
|
4133
|
+
})}
|
|
4134
|
+
`).join("");
|
|
4135
|
+
}
|
|
4136
|
+
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4137
|
+
if (!isTruecolor || lang === "unknown") return false;
|
|
4138
|
+
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4139
|
+
return line.text.length >= 2;
|
|
4140
|
+
}
|
|
4141
|
+
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4142
|
+
const prefix = line.text.slice(0, 2);
|
|
4143
|
+
const body = line.text.slice(2);
|
|
4144
|
+
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4145
|
+
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4146
|
+
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4147
|
+
return `${coloredPrefix}${highlightedBody}`;
|
|
4148
|
+
}
|
|
4149
|
+
function normalToolGistRaw(event) {
|
|
4150
|
+
const metadata = event.metadata ?? {};
|
|
4151
|
+
const toolName = event.toolName || "";
|
|
4152
|
+
if (toolName === "readFile") {
|
|
4153
|
+
const path2 = typeof metadata.path === "string" ? metadata.path : typeof metadata.filePath === "string" ? metadata.filePath : "";
|
|
4154
|
+
if (path2) return gistClip(formatReadItemPath(path2, metadata), 52);
|
|
4155
|
+
}
|
|
4156
|
+
if (toolName === "fetchWebpage") {
|
|
4157
|
+
const url = typeof metadata.url === "string" ? metadata.url : "";
|
|
4158
|
+
if (url) return formatFetchItemUrl(url);
|
|
4159
|
+
}
|
|
4160
|
+
if (toolName === "exa_search") {
|
|
4161
|
+
const query2 = typeof metadata.query === "string" ? metadata.query : typeof metadata.pattern === "string" ? metadata.pattern : "";
|
|
4162
|
+
const path2 = typeof metadata.path === "string" ? metadata.path : void 0;
|
|
4163
|
+
if (query2 || path2) return formatSearchItemQuery(query2, path2);
|
|
4164
|
+
}
|
|
4165
|
+
if (isRunToolName(toolName)) {
|
|
4166
|
+
const command2 = typeof metadata.command === "string" ? metadata.command : "";
|
|
4167
|
+
if (command2) {
|
|
4168
|
+
return commandFullGist(command2, normalRunGistMaxWidth());
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
4171
|
+
const path = typeof metadata.path === "string" ? metadata.path : "";
|
|
4172
|
+
if (path) return pathBasenameGist(path);
|
|
4173
|
+
const command = typeof metadata.command === "string" ? metadata.command : "";
|
|
4174
|
+
if (command) return commandFullGist(command, normalRunGistMaxWidth());
|
|
4175
|
+
const query = typeof metadata.query === "string" ? metadata.query : "";
|
|
4176
|
+
if (query) return clipCompactText(query, 64, "\u2026");
|
|
4177
|
+
const remembered = event.toolName === "rememberMemory" && typeof metadata.content === "string" ? metadata.content : "";
|
|
4178
|
+
if (remembered) return clipCompactText(redactSecrets(remembered), 64, "\u2026");
|
|
4179
|
+
return "";
|
|
4180
|
+
}
|
|
4181
|
+
var NORMAL_GIST_SECRET_PATTERNS = [
|
|
4182
|
+
/\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
|
|
4183
|
+
/\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
|
|
4184
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
|
|
4185
|
+
/\bxox[baprs]-[A-Za-z0-9-]{10,}/
|
|
4186
|
+
];
|
|
4187
|
+
function withholdIfSecretLike(gist) {
|
|
4188
|
+
if (!gist) return "";
|
|
4189
|
+
if (findPotentialSecrets(gist).length > 0) return "";
|
|
4190
|
+
if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
|
|
4191
|
+
return gist;
|
|
4192
|
+
}
|
|
4193
|
+
function normalToolGist(event) {
|
|
4194
|
+
return withholdIfSecretLike(normalToolGistRaw(event));
|
|
4195
|
+
}
|
|
4196
|
+
function formatNormalToolDuration(elapsedMs) {
|
|
4197
|
+
if (typeof elapsedMs !== "number" || !Number.isFinite(elapsedMs) || elapsedMs <= 500) return "";
|
|
4198
|
+
if (elapsedMs < 1e3) return `${Math.round(elapsedMs)}ms`;
|
|
4199
|
+
return `${(elapsedMs / 1e3).toFixed(1)}s`;
|
|
4202
4200
|
}
|
|
4203
4201
|
function formatNormalToolLine(event, pending, colorEnabled) {
|
|
4204
4202
|
if (event.type === "tool-call") return "";
|
|
@@ -4220,158 +4218,42 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
4220
4218
|
return formatToolTraceLine(`\u25B8 ${label} ! ${t("toolNeedsAction")}`, colorEnabled, "error");
|
|
4221
4219
|
}
|
|
4222
4220
|
if (event.type === "tool-error") {
|
|
4223
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4221
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${toolFailureReason(event) || t("toolFailed")}`, colorEnabled, "error");
|
|
4224
4222
|
}
|
|
4225
4223
|
if (event.metadata?.timedOut) {
|
|
4226
4224
|
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolTimedOut")}`, colorEnabled, "error");
|
|
4227
4225
|
}
|
|
4228
4226
|
if (isFailedToolResult(event)) {
|
|
4229
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4230
|
-
}
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
}
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
const titleText = toolLabel("codeSearch");
|
|
4260
|
-
if (!colorEnabled) {
|
|
4261
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4262
|
-
`;
|
|
4263
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4264
|
-
return `${headerLine2}${treeLines2}
|
|
4265
|
-
`;
|
|
4266
|
-
}
|
|
4267
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4268
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4269
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4270
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4271
|
-
`;
|
|
4272
|
-
const treeLines = lines.map((l) => {
|
|
4273
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4274
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4275
|
-
return `${connector}${queryText}`;
|
|
4276
|
-
}).join("\n");
|
|
4277
|
-
return `${headerLine}${treeLines}
|
|
4278
|
-
`;
|
|
4279
|
-
}
|
|
4280
|
-
function formatReadTreeBlockForCli(items, colorEnabled) {
|
|
4281
|
-
if (items.length === 0) return "";
|
|
4282
|
-
const { count, lines } = formatReadTreeLines(items);
|
|
4283
|
-
const titleText = toolLabel("readFile");
|
|
4284
|
-
if (!colorEnabled) {
|
|
4285
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4286
|
-
`;
|
|
4287
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.pathWithRange}`).join("\n");
|
|
4288
|
-
return `${headerLine2}${treeLines2}
|
|
4289
|
-
`;
|
|
4290
|
-
}
|
|
4291
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4292
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4293
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4294
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4295
|
-
`;
|
|
4296
|
-
const treeLines = lines.map((l) => {
|
|
4297
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4298
|
-
const pathText = themeText(l.pathWithRange, "muted", true);
|
|
4299
|
-
return `${connector}${pathText}`;
|
|
4300
|
-
}).join("\n");
|
|
4301
|
-
return `${headerLine}${treeLines}
|
|
4302
|
-
`;
|
|
4303
|
-
}
|
|
4304
|
-
function formatRunTreeBlockForCli(items, colorEnabled) {
|
|
4305
|
-
if (items.length === 0) return "";
|
|
4306
|
-
const { count, lines } = formatRunTreeLines(items);
|
|
4307
|
-
const titleText = toolLabel("execShell");
|
|
4308
|
-
if (!colorEnabled) {
|
|
4309
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4310
|
-
`;
|
|
4311
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.commandText}`).join("\n");
|
|
4312
|
-
return `${headerLine2}${treeLines2}
|
|
4313
|
-
`;
|
|
4314
|
-
}
|
|
4315
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4316
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4317
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4318
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4319
|
-
`;
|
|
4320
|
-
const treeLines = lines.map((l) => {
|
|
4321
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4322
|
-
const commandText = themeText(l.commandText, "muted", true);
|
|
4323
|
-
return `${connector}${commandText}`;
|
|
4324
|
-
}).join("\n");
|
|
4325
|
-
return `${headerLine}${treeLines}
|
|
4326
|
-
`;
|
|
4327
|
-
}
|
|
4328
|
-
function formatWebSearchTreeBlockForCli(items, colorEnabled) {
|
|
4329
|
-
if (items.length === 0) return "";
|
|
4330
|
-
const { count, lines } = formatSearchTreeLines(items);
|
|
4331
|
-
const titleText = toolLabel("exa_search");
|
|
4332
|
-
if (!colorEnabled) {
|
|
4333
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4334
|
-
`;
|
|
4335
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4336
|
-
return `${headerLine2}${treeLines2}
|
|
4337
|
-
`;
|
|
4338
|
-
}
|
|
4339
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4340
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4341
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4342
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4343
|
-
`;
|
|
4344
|
-
const treeLines = lines.map((l) => {
|
|
4345
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4346
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4347
|
-
return `${connector}${queryText}`;
|
|
4348
|
-
}).join("\n");
|
|
4349
|
-
return `${headerLine}${treeLines}
|
|
4350
|
-
`;
|
|
4351
|
-
}
|
|
4352
|
-
function formatFetchTreeBlockForCli(items, colorEnabled) {
|
|
4353
|
-
if (items.length === 0) return "";
|
|
4354
|
-
const { count, lines } = formatFetchTreeLines(items);
|
|
4355
|
-
const titleText = toolLabel("fetchWebpage");
|
|
4356
|
-
if (!colorEnabled) {
|
|
4357
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4358
|
-
`;
|
|
4359
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.urlText}`).join("\n");
|
|
4360
|
-
return `${headerLine2}${treeLines2}
|
|
4361
|
-
`;
|
|
4362
|
-
}
|
|
4363
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4364
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4365
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4366
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4367
|
-
`;
|
|
4368
|
-
const treeLines = lines.map((l) => {
|
|
4369
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4370
|
-
const urlText = themeText(l.urlText, "muted", true);
|
|
4371
|
-
return `${connector}${urlText}`;
|
|
4372
|
-
}).join("\n");
|
|
4373
|
-
return `${headerLine}${treeLines}
|
|
4374
|
-
`;
|
|
4227
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${toolFailureReason(event) || t("toolFailed")}`, colorEnabled, "error");
|
|
4228
|
+
}
|
|
4229
|
+
const gist = normalToolGist(event);
|
|
4230
|
+
const hint = editFileResultHint(event);
|
|
4231
|
+
const statsInline = hint?.inline ? ` ${hint.inline}` : "";
|
|
4232
|
+
const durationInline = formatNormalToolDuration(event.elapsedMs);
|
|
4233
|
+
const tail = durationInline ? ` \u2713 ${durationInline}` : " \u2713";
|
|
4234
|
+
const mainLine = formatToolTraceLine(
|
|
4235
|
+
gist ? `\u25B8 ${label} \xB7 ${gist}${statsInline}${tail}` : `\u25B8 ${label}${statsInline}${tail}`,
|
|
4236
|
+
colorEnabled
|
|
4237
|
+
);
|
|
4238
|
+
if (hint?.detail?.length) {
|
|
4239
|
+
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4240
|
+
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4241
|
+
}
|
|
4242
|
+
return mainLine;
|
|
4243
|
+
}
|
|
4244
|
+
function toolFailureReason(event) {
|
|
4245
|
+
const metadata = event.metadata ?? {};
|
|
4246
|
+
const rawError = metadata.error ?? metadata.errorMessage;
|
|
4247
|
+
const raw = typeof rawError === "string" && rawError.trim() || event.message?.trim() || typeof event.content === "string" && event.content.trim() || event.summary?.trim() || "";
|
|
4248
|
+
const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
4249
|
+
const sectionLines = (section) => {
|
|
4250
|
+
const start = lines.findIndex((line) => new RegExp(`^${section}\\s*:$`, "i").test(line));
|
|
4251
|
+
if (start < 0) return [];
|
|
4252
|
+
const end = lines.findIndex((line, index) => index > start && /^(stdout|stderr|exitCode)\s*:/i.test(line));
|
|
4253
|
+
return lines.slice(start + 1, end < 0 ? lines.length : end);
|
|
4254
|
+
};
|
|
4255
|
+
const reasonLine = sectionLines("stderr")[0] ?? sectionLines("stdout")[0] ?? lines.find((line) => !/^(stdout|stderr|exitCode)\s*:/i.test(line)) ?? lines[0] ?? "";
|
|
4256
|
+
return reasonLine ? clip(redactSecrets(stripAnsi2(reasonLine)), 96) : "";
|
|
4375
4257
|
}
|
|
4376
4258
|
function resolveLoadSkillName(event) {
|
|
4377
4259
|
const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
|
|
@@ -4436,326 +4318,63 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
|
|
|
4436
4318
|
return `${star} ${labelPart}: ${namePart}
|
|
4437
4319
|
`;
|
|
4438
4320
|
}
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
if (todoBlock) return todoBlock;
|
|
4443
|
-
if (isReadToolName(toolName) && event.type === "tool-result") {
|
|
4444
|
-
const rawPath = (typeof event.metadata?.path === "string" ? event.metadata.path : void 0) || (typeof event.metadata?.filePath === "string" ? event.metadata.filePath : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4445
|
-
return formatReadTreeBlockForCli([{ path: rawPath, metadata: event.metadata }], colorEnabled);
|
|
4446
|
-
}
|
|
4447
|
-
if (isSearchToolName(toolName) && event.type === "tool-result") {
|
|
4448
|
-
const rawQuery = (typeof event.metadata?.query === "string" ? event.metadata.query : void 0) || (typeof event.metadata?.pattern === "string" ? event.metadata.pattern : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4449
|
-
const rawPath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4450
|
-
return formatSearchTreeBlockForCli([{ query: rawQuery, path: rawPath }], colorEnabled);
|
|
4451
|
-
}
|
|
4452
|
-
if (isFetchToolName(toolName) && event.type === "tool-result") {
|
|
4453
|
-
const rawUrl = (typeof event.metadata?.url === "string" ? event.metadata.url : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4454
|
-
return formatFetchTreeBlockForCli([{ url: rawUrl }], colorEnabled);
|
|
4455
|
-
}
|
|
4456
|
-
if (isRunToolName(toolName) && event.type === "tool-result" && isRunResultFoldable(event)) {
|
|
4457
|
-
const rawCommand = (typeof event.metadata?.command === "string" ? event.metadata.command : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4458
|
-
const exitCode = typeof event.metadata?.exitCode === "number" ? event.metadata.exitCode : void 0;
|
|
4459
|
-
const timedOut = Boolean(event.metadata?.timedOut);
|
|
4460
|
-
return formatRunTreeBlockForCli([{ command: rawCommand, exitCode, timedOut }], colorEnabled);
|
|
4461
|
-
}
|
|
4462
|
-
const rawArgs = clipPathAware(event.argumentsPreview || pending?.argumentsPreview || "", 72);
|
|
4463
|
-
const rawLabel = toolLabel(toolName);
|
|
4464
|
-
const label = rawArgs ? `${rawLabel} ${rawArgs}` : rawLabel;
|
|
4465
|
-
if (event.type === "tool-error") {
|
|
4466
|
-
const message = clip(event.message ?? t("toolFailed"), 96);
|
|
4467
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${message}`, colorEnabled, "error");
|
|
4468
|
-
}
|
|
4469
|
-
const loadSkillBlock = formatLoadSkillBlock(event, colorEnabled);
|
|
4470
|
-
if (loadSkillBlock) return loadSkillBlock;
|
|
4471
|
-
if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
|
|
4472
|
-
return formatOrchestrationCardBlock(event, toolName, colorEnabled);
|
|
4473
|
-
}
|
|
4474
|
-
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
4475
|
-
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
4476
|
-
if (block) return block;
|
|
4477
|
-
}
|
|
4478
|
-
const hint = compactResultHint(event);
|
|
4479
|
-
const suffix = hint.inline ? ` ${hint.inline}` : "";
|
|
4480
|
-
const failed = isFailedToolResult(event);
|
|
4481
|
-
const marker = failed ? "\u2717" : isNeedsActionToolResult(event) ? "!" : "\u2713";
|
|
4482
|
-
let mainLine;
|
|
4483
|
-
if (!colorEnabled) {
|
|
4484
|
-
mainLine = `\u25B8 ${label} ${marker}${suffix}
|
|
4485
|
-
`;
|
|
4486
|
-
} else {
|
|
4487
|
-
const chromePointer = themeText("\u25B8", "chrome", true);
|
|
4488
|
-
const mutedLabel = themeText(rawLabel, "muted", true);
|
|
4489
|
-
const argsPart = rawArgs ? ` ${dimCliText(rawArgs, true)}` : "";
|
|
4490
|
-
const statusToken = failed ? themeText("\u2717", "danger", true) : isNeedsActionToolResult(event) ? themeText("!", "warning", true) : themeText("\u2713", "success", true);
|
|
4491
|
-
const suffixPart = hint.inline ? ` ${dimCliText(hint.inline, true)}` : "";
|
|
4492
|
-
mainLine = `${chromePointer} ${mutedLabel}${argsPart} ${statusToken}${suffixPart}
|
|
4493
|
-
`;
|
|
4494
|
-
}
|
|
4495
|
-
if (!hint.detail?.length) return mainLine;
|
|
4496
|
-
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : event.argumentsPreview;
|
|
4497
|
-
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4498
|
-
}
|
|
4499
|
-
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4500
|
-
if (!colorEnabled) {
|
|
4501
|
-
return lines.map((line) => ` ${line.text}
|
|
4502
|
-
`).join("");
|
|
4503
|
-
}
|
|
4504
|
-
const isTruecolor = supportsTruecolor(env);
|
|
4505
|
-
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4506
|
-
const brightness = resolveTuiBrightness(env);
|
|
4507
|
-
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4508
|
-
return lines.map((line) => ` ${renderDiffLine({
|
|
4509
|
-
kind: line.kind,
|
|
4510
|
-
text: line.text,
|
|
4511
|
-
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4512
|
-
padTo,
|
|
4513
|
-
colorEnabled: true,
|
|
4514
|
-
env
|
|
4515
|
-
})}
|
|
4516
|
-
`).join("");
|
|
4517
|
-
}
|
|
4518
|
-
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4519
|
-
if (!isTruecolor || lang === "unknown") return false;
|
|
4520
|
-
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4521
|
-
return line.text.length >= 2;
|
|
4522
|
-
}
|
|
4523
|
-
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4524
|
-
const prefix = line.text.slice(0, 2);
|
|
4525
|
-
const body = line.text.slice(2);
|
|
4526
|
-
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4527
|
-
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4528
|
-
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4529
|
-
return `${coloredPrefix}${highlightedBody}`;
|
|
4530
|
-
}
|
|
4531
|
-
function createToolEventFormatter(mode, colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4532
|
-
const suppressRunProgressCards = opts.suppressRunProgressCards === true;
|
|
4321
|
+
var TUI_TREE_MARKER = "TUI_TREE\n";
|
|
4322
|
+
var TUI_TREE_END = "";
|
|
4323
|
+
function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4533
4324
|
const pending = /* @__PURE__ */ new Map();
|
|
4534
|
-
let
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
const lastPrintedCardByRunId = /* @__PURE__ */ new Map();
|
|
4542
|
-
const cardSubstance = (snapshot) => JSON.stringify([
|
|
4543
|
-
snapshot.status,
|
|
4544
|
-
snapshot.toolCallCount ?? -1,
|
|
4545
|
-
snapshot.lastToolNames ?? [],
|
|
4546
|
-
snapshot.lastAssistantText ?? "",
|
|
4547
|
-
snapshot.errorMessage ?? "",
|
|
4548
|
-
snapshot.logKey
|
|
4549
|
-
]);
|
|
4550
|
-
const flushStatusFold = () => {
|
|
4551
|
-
if (!statusFold) return "";
|
|
4552
|
-
const fold = statusFold;
|
|
4553
|
-
statusFold = null;
|
|
4554
|
-
const substance = cardSubstance(fold);
|
|
4555
|
-
if (lastPrintedCardByRunId.get(fold.runId) === substance) return "";
|
|
4556
|
-
const prevLog = lastEmittedLogByRunId.get(fold.runId);
|
|
4557
|
-
const changed = Boolean(fold.logKey) && fold.logKey !== prevLog;
|
|
4558
|
-
if (suppressRunProgressCards) {
|
|
4559
|
-
const terminal = isAgentRunTerminalStatus(fold.status);
|
|
4560
|
-
if (!terminal && !fold.errorMessage && !changed) {
|
|
4561
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4562
|
-
return "";
|
|
4563
|
-
}
|
|
4564
|
-
}
|
|
4565
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4566
|
-
if (changed && runShowsLogTail(fold.status)) {
|
|
4567
|
-
lastEmittedLogByRunId.set(fold.runId, fold.logKey);
|
|
4568
|
-
}
|
|
4569
|
-
return formatFoldedControlStatusCard({ ...fold, includeLogTail: changed }, colorEnabled);
|
|
4570
|
-
};
|
|
4571
|
-
const flushToolBuffers = () => {
|
|
4572
|
-
let out = "";
|
|
4573
|
-
if (readBuffer.length > 0) {
|
|
4574
|
-
const items = readBuffer.map((evt) => {
|
|
4575
|
-
const call = pending.get(evt.toolCallId);
|
|
4576
|
-
const rawPath = (typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0) || (typeof evt.metadata?.filePath === "string" ? evt.metadata.filePath : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4577
|
-
return { path: rawPath, metadata: evt.metadata };
|
|
4578
|
-
});
|
|
4579
|
-
for (const evt of readBuffer) pending.delete(evt.toolCallId);
|
|
4580
|
-
readBuffer = [];
|
|
4581
|
-
out += formatReadTreeBlockForCli(items, colorEnabled);
|
|
4582
|
-
}
|
|
4583
|
-
if (searchBuffer.length > 0) {
|
|
4584
|
-
const items = searchBuffer.map((evt) => {
|
|
4585
|
-
const call = pending.get(evt.toolCallId);
|
|
4586
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4587
|
-
const rawPath = typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0;
|
|
4588
|
-
return { query: rawQuery, path: rawPath };
|
|
4589
|
-
});
|
|
4590
|
-
for (const evt of searchBuffer) pending.delete(evt.toolCallId);
|
|
4591
|
-
searchBuffer = [];
|
|
4592
|
-
out += formatSearchTreeBlockForCli(items, colorEnabled);
|
|
4593
|
-
}
|
|
4594
|
-
if (runBuffer.length > 0) {
|
|
4595
|
-
const items = runBuffer.map((evt) => {
|
|
4596
|
-
const call = pending.get(evt.toolCallId);
|
|
4597
|
-
const rawCommand = (typeof evt.metadata?.command === "string" ? evt.metadata.command : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4598
|
-
const exitCode = typeof evt.metadata?.exitCode === "number" ? evt.metadata.exitCode : void 0;
|
|
4599
|
-
const timedOut = Boolean(evt.metadata?.timedOut);
|
|
4600
|
-
return { command: rawCommand, exitCode, timedOut };
|
|
4601
|
-
});
|
|
4602
|
-
for (const evt of runBuffer) pending.delete(evt.toolCallId);
|
|
4603
|
-
runBuffer = [];
|
|
4604
|
-
out += formatRunTreeBlockForCli(items, colorEnabled);
|
|
4605
|
-
}
|
|
4606
|
-
if (fetchBuffer.length > 0) {
|
|
4607
|
-
const items = fetchBuffer.map((evt) => {
|
|
4608
|
-
const call = pending.get(evt.toolCallId);
|
|
4609
|
-
const rawUrl = (typeof evt.metadata?.url === "string" ? evt.metadata.url : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4610
|
-
return { url: rawUrl };
|
|
4611
|
-
});
|
|
4612
|
-
for (const evt of fetchBuffer) pending.delete(evt.toolCallId);
|
|
4613
|
-
fetchBuffer = [];
|
|
4614
|
-
out += formatFetchTreeBlockForCli(items, colorEnabled);
|
|
4615
|
-
}
|
|
4616
|
-
if (webSearchBuffer.length > 0) {
|
|
4617
|
-
const items = webSearchBuffer.map((evt) => {
|
|
4618
|
-
const call = pending.get(evt.toolCallId);
|
|
4619
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4620
|
-
return { query: rawQuery };
|
|
4621
|
-
});
|
|
4622
|
-
for (const evt of webSearchBuffer) pending.delete(evt.toolCallId);
|
|
4623
|
-
webSearchBuffer = [];
|
|
4624
|
-
out += formatWebSearchTreeBlockForCli(items, colorEnabled);
|
|
4625
|
-
}
|
|
4626
|
-
return out;
|
|
4627
|
-
};
|
|
4628
|
-
const flushBuffers = () => `${flushStatusFold()}${flushToolBuffers()}`;
|
|
4629
|
-
const bufferToolResult = (buffer, event) => {
|
|
4630
|
-
const flushed = flushStatusFold();
|
|
4631
|
-
buffer.push(event);
|
|
4632
|
-
return flushed;
|
|
4325
|
+
let tree = null;
|
|
4326
|
+
const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
|
|
4327
|
+
const treeLine = (kind, items) => {
|
|
4328
|
+
const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
|
|
4329
|
+
return `${TUI_TREE_MARKER}${label} (${items.length})
|
|
4330
|
+
${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${item} \u2713`).join("\n")}${TUI_TREE_END}
|
|
4331
|
+
`;
|
|
4633
4332
|
};
|
|
4634
|
-
const
|
|
4635
|
-
if (
|
|
4636
|
-
if (
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
pending.set(event.toolCallId, {
|
|
4640
|
-
toolName: event.toolName,
|
|
4641
|
-
argumentsPreview: event.argumentsPreview
|
|
4642
|
-
});
|
|
4643
|
-
return "";
|
|
4644
|
-
}
|
|
4645
|
-
const call2 = pending.get(event.toolCallId);
|
|
4646
|
-
pending.delete(event.toolCallId);
|
|
4647
|
-
return formatNormalToolLine(event, call2, colorEnabled);
|
|
4648
|
-
}
|
|
4649
|
-
if (event.toolName === "controlAgentRun") {
|
|
4650
|
-
if (event.type === "tool-call") {
|
|
4651
|
-
pending.set(event.toolCallId, {
|
|
4652
|
-
toolName: event.toolName,
|
|
4653
|
-
argumentsPreview: event.argumentsPreview
|
|
4654
|
-
});
|
|
4655
|
-
return "";
|
|
4656
|
-
}
|
|
4657
|
-
if (event.type === "tool-result") {
|
|
4658
|
-
const snapshot = parseControlAgentRunStatusEvent(event);
|
|
4659
|
-
if (snapshot) {
|
|
4660
|
-
let out = flushToolBuffers();
|
|
4661
|
-
const open = statusFold;
|
|
4662
|
-
const sameRun = open?.runId === snapshot.runId;
|
|
4663
|
-
if (open && (!sameRun || open.status !== snapshot.status)) {
|
|
4664
|
-
out += flushStatusFold();
|
|
4665
|
-
}
|
|
4666
|
-
statusFold = open && sameRun ? mergeRunSnapshot(open, snapshot) : snapshot;
|
|
4667
|
-
pending.delete(event.toolCallId);
|
|
4668
|
-
if (isAgentRunTerminalStatus(snapshot.status)) {
|
|
4669
|
-
out += flushBuffers();
|
|
4670
|
-
}
|
|
4671
|
-
return out;
|
|
4672
|
-
}
|
|
4673
|
-
const flushed2 = flushBuffers();
|
|
4674
|
-
const call2 = pending.get(event.toolCallId);
|
|
4675
|
-
pending.delete(event.toolCallId);
|
|
4676
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4677
|
-
}
|
|
4678
|
-
}
|
|
4679
|
-
if (isReadToolName(event.toolName)) {
|
|
4680
|
-
if (event.type === "tool-call") {
|
|
4681
|
-
pending.set(event.toolCallId, {
|
|
4682
|
-
toolName: event.toolName,
|
|
4683
|
-
argumentsPreview: event.argumentsPreview
|
|
4684
|
-
});
|
|
4685
|
-
return "";
|
|
4686
|
-
}
|
|
4687
|
-
if (event.type === "tool-result") {
|
|
4688
|
-
return bufferToolResult(readBuffer, event);
|
|
4689
|
-
}
|
|
4690
|
-
}
|
|
4691
|
-
if (isSearchToolName(event.toolName)) {
|
|
4692
|
-
if (event.type === "tool-call") {
|
|
4693
|
-
pending.set(event.toolCallId, {
|
|
4694
|
-
toolName: event.toolName,
|
|
4695
|
-
argumentsPreview: event.argumentsPreview
|
|
4696
|
-
});
|
|
4697
|
-
return "";
|
|
4698
|
-
}
|
|
4699
|
-
if (event.type === "tool-result") {
|
|
4700
|
-
return bufferToolResult(searchBuffer, event);
|
|
4701
|
-
}
|
|
4702
|
-
}
|
|
4703
|
-
if (isRunToolName(event.toolName)) {
|
|
4704
|
-
if (event.type === "tool-result" && !isRunResultFoldable(event)) {
|
|
4705
|
-
const flushed2 = flushBuffers();
|
|
4706
|
-
const call2 = pending.get(event.toolCallId);
|
|
4707
|
-
pending.delete(event.toolCallId);
|
|
4708
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4709
|
-
}
|
|
4710
|
-
if (event.type === "tool-call") {
|
|
4711
|
-
pending.set(event.toolCallId, {
|
|
4712
|
-
toolName: event.toolName,
|
|
4713
|
-
argumentsPreview: event.argumentsPreview
|
|
4714
|
-
});
|
|
4715
|
-
return "";
|
|
4716
|
-
}
|
|
4717
|
-
if (event.type === "tool-result") {
|
|
4718
|
-
return bufferToolResult(runBuffer, event);
|
|
4719
|
-
}
|
|
4720
|
-
}
|
|
4721
|
-
if (isFetchToolName(event.toolName)) {
|
|
4722
|
-
if (event.type === "tool-call") {
|
|
4723
|
-
pending.set(event.toolCallId, {
|
|
4724
|
-
toolName: event.toolName,
|
|
4725
|
-
argumentsPreview: event.argumentsPreview
|
|
4726
|
-
});
|
|
4727
|
-
return "";
|
|
4728
|
-
}
|
|
4729
|
-
if (event.type === "tool-result") {
|
|
4730
|
-
return bufferToolResult(fetchBuffer, event);
|
|
4731
|
-
}
|
|
4333
|
+
const formatTreeEvent = (event, call) => {
|
|
4334
|
+
if (!opts.tuiTrees || event.type !== "tool-result") return null;
|
|
4335
|
+
if (isFailedToolResult(event) || event.metadata?.failed || event.metadata?.timedOut || readActionGate(event.metadata?.actionGate)) {
|
|
4336
|
+
tree = null;
|
|
4337
|
+
return null;
|
|
4732
4338
|
}
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
});
|
|
4739
|
-
return "";
|
|
4740
|
-
}
|
|
4741
|
-
if (event.type === "tool-result") {
|
|
4742
|
-
return bufferToolResult(webSearchBuffer, event);
|
|
4743
|
-
}
|
|
4339
|
+
const name = event.toolName || call?.toolName || "tool";
|
|
4340
|
+
const kind = treeKind(name);
|
|
4341
|
+
if (!kind) {
|
|
4342
|
+
tree = null;
|
|
4343
|
+
return null;
|
|
4744
4344
|
}
|
|
4745
|
-
|
|
4345
|
+
let item = "";
|
|
4346
|
+
const m = event.metadata ?? {};
|
|
4347
|
+
if (kind === "Run") {
|
|
4348
|
+
const command = typeof m.command === "string" ? m.command : "";
|
|
4349
|
+
item = command ? formatRunItemCommand(command, typeof m.exitCode === "number" ? m.exitCode : void 0, Boolean(m.timedOut)) : "command";
|
|
4350
|
+
}
|
|
4351
|
+
if (kind === "Read") item = formatReadItemPath(typeof m.path === "string" ? m.path : typeof m.filePath === "string" ? m.filePath : "file", m);
|
|
4352
|
+
if (kind === "Search") item = formatSearchItemQuery(typeof m.query === "string" ? m.query : typeof m.pattern === "string" ? m.pattern : "search", typeof m.path === "string" ? m.path : void 0);
|
|
4353
|
+
if (kind === "Fetch") item = formatFetchItemUrl(typeof m.url === "string" ? m.url : "webpage");
|
|
4354
|
+
item = withholdIfSecretLike(item) || toolLabel(name);
|
|
4355
|
+
if (tree?.kind !== kind) tree = { kind, items: [] };
|
|
4356
|
+
tree.items.push(item);
|
|
4357
|
+
if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
|
|
4358
|
+
return treeLine(kind, tree.items);
|
|
4359
|
+
};
|
|
4360
|
+
const format = (event) => {
|
|
4746
4361
|
if (event.type === "tool-call") {
|
|
4747
4362
|
pending.set(event.toolCallId, {
|
|
4748
4363
|
toolName: event.toolName,
|
|
4749
4364
|
argumentsPreview: event.argumentsPreview
|
|
4750
4365
|
});
|
|
4751
|
-
return
|
|
4366
|
+
return "";
|
|
4752
4367
|
}
|
|
4753
4368
|
const call = pending.get(event.toolCallId);
|
|
4754
4369
|
pending.delete(event.toolCallId);
|
|
4755
|
-
|
|
4370
|
+
const treeOutput = formatTreeEvent(event, call);
|
|
4371
|
+
if (treeOutput !== null) return treeOutput;
|
|
4372
|
+
return formatNormalToolLine(event, call, colorEnabled);
|
|
4373
|
+
};
|
|
4374
|
+
format.reset = () => {
|
|
4375
|
+
tree = null;
|
|
4756
4376
|
};
|
|
4757
|
-
|
|
4758
|
-
return formatter;
|
|
4377
|
+
return format;
|
|
4759
4378
|
}
|
|
4760
4379
|
function createSseToolEventAdapter(onEvent) {
|
|
4761
4380
|
let round = 0;
|
|
@@ -4973,10 +4592,8 @@ function createCliTurnOutput(params) {
|
|
|
4973
4592
|
const { options } = params;
|
|
4974
4593
|
const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
|
|
4975
4594
|
const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
|
|
4976
|
-
const
|
|
4977
|
-
|
|
4978
|
-
const formatToolEvent = createToolEventFormatter(toolDisplayMode, void 0, {
|
|
4979
|
-
suppressRunProgressCards: typeof options.onAgentRunStatus === "function"
|
|
4595
|
+
const formatToolEvent = createToolEventFormatter(void 0, {
|
|
4596
|
+
tuiTrees: options.output.tuiTrees === true
|
|
4980
4597
|
});
|
|
4981
4598
|
const eventMode = resolveAgentEventMode(options);
|
|
4982
4599
|
const showThinking = options.showThinking !== false;
|
|
@@ -4995,6 +4612,7 @@ function createCliTurnOutput(params) {
|
|
|
4995
4612
|
if (thinkingFirstAt === null) return;
|
|
4996
4613
|
const seconds = Math.max(0, Math.round((thinkingLastAt - thinkingFirstAt) / 1e3));
|
|
4997
4614
|
thinkingFirstAt = null;
|
|
4615
|
+
if (seconds < 1) return;
|
|
4998
4616
|
options.output.write(`${dimCliText(t("thinkingTraceLine", formatElapsed(seconds)))}
|
|
4999
4617
|
`);
|
|
5000
4618
|
};
|
|
@@ -5003,7 +4621,7 @@ function createCliTurnOutput(params) {
|
|
|
5003
4621
|
const writeToolOutput = (chunk) => {
|
|
5004
4622
|
if (!chunk) return;
|
|
5005
4623
|
if (typeof options.output.writeToolBlock === "function") {
|
|
5006
|
-
options.output.writeToolBlock(chunk);
|
|
4624
|
+
if (!options.output.writeToolBlock(chunk)) formatToolEvent.reset?.();
|
|
5007
4625
|
} else {
|
|
5008
4626
|
options.output.write(chunk);
|
|
5009
4627
|
}
|
|
@@ -5013,6 +4631,7 @@ function createCliTurnOutput(params) {
|
|
|
5013
4631
|
});
|
|
5014
4632
|
const writeVisibleAssistantChunk = (chunk) => {
|
|
5015
4633
|
if (!chunk) return;
|
|
4634
|
+
formatToolEvent.reset?.();
|
|
5016
4635
|
const parsed = processThinkChunk(chunk, thinkState);
|
|
5017
4636
|
thinkState = parsed.state;
|
|
5018
4637
|
if (!parsed.content && !parsed.reasoning) return;
|
|
@@ -5036,7 +4655,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5036
4655
|
renderWriter.push(parsed.content);
|
|
5037
4656
|
};
|
|
5038
4657
|
const handleToolEvent = (event) => {
|
|
5039
|
-
if (!traceLocalTools) return;
|
|
5040
4658
|
const chunk = eventMode === "jsonl" ? formatToolJsonEvent(event) : formatToolEvent(event);
|
|
5041
4659
|
if (eventMode === "jsonl") {
|
|
5042
4660
|
options.output.write(chunk);
|
|
@@ -5054,8 +4672,8 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5054
4672
|
if (chunk) {
|
|
5055
4673
|
writeToolOutput(chunk);
|
|
5056
4674
|
}
|
|
5057
|
-
if (
|
|
5058
|
-
const activeLabel =
|
|
4675
|
+
if (event.type === "tool-call") {
|
|
4676
|
+
const activeLabel = formatConservativeActiveToolLabel(event);
|
|
5059
4677
|
spinner.show(activeLabel);
|
|
5060
4678
|
options.activityReporter?.(activeLabel);
|
|
5061
4679
|
}
|
|
@@ -5068,16 +4686,8 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5068
4686
|
};
|
|
5069
4687
|
return {
|
|
5070
4688
|
spinner,
|
|
5071
|
-
toolDisplayMode,
|
|
5072
|
-
traceLocalTools,
|
|
5073
4689
|
eventMode,
|
|
5074
4690
|
pushText(chunk) {
|
|
5075
|
-
if (eventMode !== "jsonl" && formatToolEvent.flush) {
|
|
5076
|
-
const pendingToolOutput = formatToolEvent.flush();
|
|
5077
|
-
if (pendingToolOutput) {
|
|
5078
|
-
writeToolOutput(pendingToolOutput);
|
|
5079
|
-
}
|
|
5080
|
-
}
|
|
5081
4691
|
writeVisibleAssistantChunk(chunk);
|
|
5082
4692
|
},
|
|
5083
4693
|
pushThinking(chunk) {
|
|
@@ -5105,10 +4715,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5105
4715
|
if (flushedThink.content) {
|
|
5106
4716
|
writeVisibleAssistantChunk(flushedThink.content);
|
|
5107
4717
|
}
|
|
5108
|
-
const pendingToolOutput = formatToolEvent.flush ? formatToolEvent.flush() : "";
|
|
5109
|
-
if (pendingToolOutput) {
|
|
5110
|
-
writeToolOutput(pendingToolOutput);
|
|
5111
|
-
}
|
|
5112
4718
|
if (streamedAssistantText) {
|
|
5113
4719
|
renderWriter.flush();
|
|
5114
4720
|
options.output.write("\n");
|
|
@@ -5309,10 +4915,12 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
5309
4915
|
if (usageText && shouldShowUsage(options.env))
|
|
5310
4916
|
options.output.write(`${usageText}
|
|
5311
4917
|
`);
|
|
4918
|
+
const turnCredits = platformCreditsFromUsage(usage);
|
|
5312
4919
|
return {
|
|
5313
4920
|
exitCode: 0,
|
|
5314
4921
|
...dialogId ? { dialogId } : {},
|
|
5315
|
-
turnTokens: buildTurnTokenUsage(usage, options.agentKey)
|
|
4922
|
+
turnTokens: buildTurnTokenUsage(usage, options.agentKey),
|
|
4923
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
5316
4924
|
};
|
|
5317
4925
|
}
|
|
5318
4926
|
|
|
@@ -5592,10 +5200,14 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
|
|
|
5592
5200
|
// packages/cli/client/agentRun.ts
|
|
5593
5201
|
import { ulid } from "ulid";
|
|
5594
5202
|
async function loadRunLocalAgentTurn() {
|
|
5595
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
5203
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-K327ELSL.js");
|
|
5596
5204
|
return runLocalAgentTurn;
|
|
5597
5205
|
}
|
|
5598
5206
|
var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
|
|
5207
|
+
var pickEmptyAssistantFlags = (result) => ({
|
|
5208
|
+
...result.emptyAssistantFallbackReason ? { emptyAssistantFallbackReason: result.emptyAssistantFallbackReason } : {},
|
|
5209
|
+
...result.emptyAssistantOutputUsable ? { emptyAssistantOutputUsable: true } : {}
|
|
5210
|
+
});
|
|
5599
5211
|
function extractEmbeddedErrorMessage(message) {
|
|
5600
5212
|
const match = /"message"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(message);
|
|
5601
5213
|
if (!match) return void 0;
|
|
@@ -6133,13 +5745,17 @@ ${options.agentName} > (no text response)
|
|
|
6133
5745
|
const usage = formatUsage(data?.usage, data?.dialogId);
|
|
6134
5746
|
if (usage && shouldShowUsage(options.env)) options.output.write(`${usage}
|
|
6135
5747
|
`);
|
|
5748
|
+
const turnCredits = platformCreditsFromUsage(
|
|
5749
|
+
data?.usage
|
|
5750
|
+
);
|
|
6136
5751
|
return {
|
|
6137
5752
|
exitCode: 0,
|
|
6138
5753
|
...typeof data?.dialogId === "string" && data.dialogId ? { dialogId: data.dialogId } : {},
|
|
6139
5754
|
turnTokens: buildTurnTokenUsage(
|
|
6140
5755
|
data?.usage,
|
|
6141
5756
|
typeof data?.model === "string" ? data.model : options.agentKey
|
|
6142
|
-
)
|
|
5757
|
+
),
|
|
5758
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
6143
5759
|
};
|
|
6144
5760
|
}
|
|
6145
5761
|
async function runInjectedLocalAgentTurn(options) {
|
|
@@ -6244,11 +5860,13 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6244
5860
|
options.onLoopEvent?.(event);
|
|
6245
5861
|
},
|
|
6246
5862
|
...options.abortSignal ? { abortSignal: options.abortSignal } : {},
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
5863
|
+
// 回合内注入(TUI 后台 run 唤醒直投):透传给 local loop。
|
|
5864
|
+
...options.drainInjections ? { drainInjections: options.drainInjections } : {},
|
|
5865
|
+
// tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
|
|
5866
|
+
// 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
|
|
5867
|
+
onToolEvent: (event) => {
|
|
5868
|
+
turnOutput.handleToolEvent(event);
|
|
5869
|
+
},
|
|
6252
5870
|
...!options.noStream ? {
|
|
6253
5871
|
onTextDelta: (chunk) => {
|
|
6254
5872
|
turnOutput.pushText(chunk);
|
|
@@ -6259,24 +5877,35 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6259
5877
|
} : {}
|
|
6260
5878
|
});
|
|
6261
5879
|
turnOutput.finish(result.content);
|
|
5880
|
+
const turnCredits = sumPlatformCredits(result.usageRecords);
|
|
6262
5881
|
return {
|
|
6263
5882
|
exitCode: 0,
|
|
6264
5883
|
dialogId: result.dialogId,
|
|
6265
5884
|
title: result.title,
|
|
6266
5885
|
...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
|
|
6267
|
-
...result
|
|
6268
|
-
|
|
5886
|
+
...pickEmptyAssistantFlags(result),
|
|
5887
|
+
// 积分口径按「全轮」而非「最后一次调用」:result.usage 只是收尾那次
|
|
5888
|
+
// provider 调用的 usage,本轮前面 N-1 次工具循环调用(以及自动压缩摘要)
|
|
5889
|
+
// 的 cost 都只存在于 usageRecords 里。token 字段仍取 result.usage——
|
|
5890
|
+
// 上下文占用本来就该看最后一次调用的累计输入,不是各次相加。
|
|
5891
|
+
turnTokens: withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits),
|
|
5892
|
+
...turnCredits !== void 0 ? { turnCredits } : {},
|
|
5893
|
+
...result.usageRecords?.length ? { usageRecords: result.usageRecords } : {}
|
|
6269
5894
|
};
|
|
6270
5895
|
} catch (error) {
|
|
6271
5896
|
turnOutput.spinner.stop();
|
|
6272
5897
|
const savedDialogId = error?.dialogId;
|
|
5898
|
+
const abortedUsageRecords = error?.usageRecords;
|
|
5899
|
+
const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
|
|
6273
5900
|
if (error?.code === LOCAL_TURN_ABORTED_CODE || options.abortSignal?.aborted) {
|
|
6274
5901
|
const pendingToolName = error?.pendingToolName;
|
|
6275
5902
|
return {
|
|
6276
5903
|
exitCode: 0,
|
|
6277
5904
|
streamInterrupted: true,
|
|
6278
5905
|
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
6279
|
-
...pendingToolName ? { pendingToolName } : {}
|
|
5906
|
+
...pendingToolName ? { pendingToolName } : {},
|
|
5907
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5908
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6280
5909
|
};
|
|
6281
5910
|
}
|
|
6282
5911
|
const cooldownUntil = await markStartupRateLimitCooldown(
|
|
@@ -6302,10 +5931,70 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6302
5931
|
return {
|
|
6303
5932
|
exitCode: 1,
|
|
6304
5933
|
localError: error,
|
|
6305
|
-
...savedDialogId ? { dialogId: savedDialogId } : {}
|
|
5934
|
+
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
5935
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5936
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6306
5937
|
};
|
|
6307
5938
|
}
|
|
6308
5939
|
}
|
|
5940
|
+
async function checkLocalAvailabilityBeforeHttpDispatch(options) {
|
|
5941
|
+
const adapter = resolveLocalRuntimeAdapter(options);
|
|
5942
|
+
if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
|
|
5943
|
+
let config;
|
|
5944
|
+
try {
|
|
5945
|
+
config = await adapter.loadAgentConfig(options.agentKey);
|
|
5946
|
+
} catch {
|
|
5947
|
+
return null;
|
|
5948
|
+
}
|
|
5949
|
+
if (!config || typeof config !== "object") return null;
|
|
5950
|
+
const baseRecord = config.rawRecord ?? config;
|
|
5951
|
+
const credentialKey = resolveCredentialKeyWithFallback(baseRecord);
|
|
5952
|
+
const agentLevelAt = baseRecord.nextAvailableAt;
|
|
5953
|
+
const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
|
|
5954
|
+
if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
|
|
5955
|
+
const env = options.env;
|
|
5956
|
+
const now = Date.now();
|
|
5957
|
+
const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
|
|
5958
|
+
const entryAt = entry?.nextAvailableAt;
|
|
5959
|
+
const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
|
|
5960
|
+
if (typeof effectiveNextAvailableAt !== "number") return null;
|
|
5961
|
+
const gateDecision = resolveCooldownGate(
|
|
5962
|
+
{ nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
|
|
5963
|
+
now
|
|
5964
|
+
);
|
|
5965
|
+
if (gateDecision === "probe" && credentialKey) {
|
|
5966
|
+
await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
|
|
5967
|
+
return null;
|
|
5968
|
+
}
|
|
5969
|
+
if (gateDecision !== "blocked") return null;
|
|
5970
|
+
options.output.write(
|
|
5971
|
+
`[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
|
|
5972
|
+
Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
|
|
5973
|
+
`
|
|
5974
|
+
);
|
|
5975
|
+
return { exitCode: 1 };
|
|
5976
|
+
}
|
|
5977
|
+
function foldLocalResultForTui(localResult) {
|
|
5978
|
+
return {
|
|
5979
|
+
exitCode: localResult.exitCode,
|
|
5980
|
+
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
5981
|
+
title: localResult.title,
|
|
5982
|
+
...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
|
|
5983
|
+
// 空 assistant 兜底成因必须随行:后台 run 的结算(resolveRunOutcome 的
|
|
5984
|
+
// isStalledOrTruncated)靠它把截断轮判成 stalled 而不是 clean 失败。
|
|
5985
|
+
...pickEmptyAssistantFlags(localResult),
|
|
5986
|
+
...localResult.turnTokens ? { turnTokens: localResult.turnTokens } : {},
|
|
5987
|
+
// 平台积分必须随行:runLocalAgentTurnForCli 里 sumPlatformCredits 已按
|
|
5988
|
+
// 「全轮逐次求和」算好(只认 billing_unit === "credits" 的平台计费帧)。
|
|
5989
|
+
...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
|
|
5990
|
+
// 逐帧用量明细必须随行:cli-local 计费走 fail-open 客户端记账,服务端没有
|
|
5991
|
+
// 逐帧记录,TUI 计费审计(appendTurnBillingAudit)要靠它对账。白名单历史上
|
|
5992
|
+
// 漏过 turnCredits(fix/tui-session-credits),usageRecords 是同坑位新字段。
|
|
5993
|
+
...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {},
|
|
5994
|
+
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
5995
|
+
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
5996
|
+
};
|
|
5997
|
+
}
|
|
6309
5998
|
async function runAgentTurn(options) {
|
|
6310
5999
|
const authToken = resolveAuthToken2(options.env);
|
|
6311
6000
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
@@ -6319,15 +6008,7 @@ async function runAgentTurn(options) {
|
|
|
6319
6008
|
reportFailure: false
|
|
6320
6009
|
});
|
|
6321
6010
|
if (localResult.exitCode === 0) {
|
|
6322
|
-
return
|
|
6323
|
-
exitCode: localResult.exitCode,
|
|
6324
|
-
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6325
|
-
title: localResult.title,
|
|
6326
|
-
...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
|
|
6327
|
-
...localResult.turnTokens ? { turnTokens: localResult.turnTokens } : {},
|
|
6328
|
-
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
6329
|
-
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
6330
|
-
};
|
|
6011
|
+
return foldLocalResultForTui(localResult);
|
|
6331
6012
|
}
|
|
6332
6013
|
if (isMissingLocalAgentConfigError(localResult.localError, options.agentKey)) {
|
|
6333
6014
|
options.output.write(
|
|
@@ -6341,13 +6022,7 @@ async function runAgentTurn(options) {
|
|
|
6341
6022
|
reportFailure: false
|
|
6342
6023
|
});
|
|
6343
6024
|
if (retriedLocalResult.exitCode === 0) {
|
|
6344
|
-
return
|
|
6345
|
-
exitCode: retriedLocalResult.exitCode,
|
|
6346
|
-
...retriedLocalResult.dialogId ? { dialogId: retriedLocalResult.dialogId } : {},
|
|
6347
|
-
title: retriedLocalResult.title,
|
|
6348
|
-
...retriedLocalResult.titlePatchPromise ? { titlePatchPromise: retriedLocalResult.titlePatchPromise } : {},
|
|
6349
|
-
...retriedLocalResult.turnTokens ? { turnTokens: retriedLocalResult.turnTokens } : {}
|
|
6350
|
-
};
|
|
6025
|
+
return foldLocalResultForTui(retriedLocalResult);
|
|
6351
6026
|
}
|
|
6352
6027
|
}
|
|
6353
6028
|
} catch {
|
|
@@ -6360,7 +6035,11 @@ async function runAgentTurn(options) {
|
|
|
6360
6035
|
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6361
6036
|
// Keep localError so TUI can show balance/quota/dialog-preserved hints
|
|
6362
6037
|
// instead of only the raw auto-runtime line.
|
|
6363
|
-
...localResult.localError ? { localError: localResult.localError } : {}
|
|
6038
|
+
...localResult.localError ? { localError: localResult.localError } : {},
|
|
6039
|
+
// 失败轮同样可能已发生平台计费(abort/失败照样扣费):turnCredits 与
|
|
6040
|
+
// 逐帧明细一起随行,否则审计日志在 auto 失败路径上缺账。
|
|
6041
|
+
...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
|
|
6042
|
+
...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {}
|
|
6364
6043
|
};
|
|
6365
6044
|
}
|
|
6366
6045
|
}
|
|
@@ -6370,26 +6049,50 @@ async function runAgentTurn(options) {
|
|
|
6370
6049
|
);
|
|
6371
6050
|
return { exitCode: 1 };
|
|
6372
6051
|
}
|
|
6052
|
+
const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
|
|
6053
|
+
if (localBlock) {
|
|
6054
|
+
return { exitCode: localBlock.exitCode };
|
|
6055
|
+
}
|
|
6373
6056
|
return runHttpAgentTurn(options, authToken);
|
|
6374
6057
|
}
|
|
6375
6058
|
|
|
6376
6059
|
// packages/cli/agentRunCommand.ts
|
|
6377
6060
|
import * as nodeFs from "node:fs";
|
|
6378
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6379
|
-
import { join as join2 } from "node:path";
|
|
6380
6061
|
|
|
6381
6062
|
// packages/cli/client/autoModelRouter.ts
|
|
6382
6063
|
var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
|
|
6383
6064
|
|
|
6065
|
+
// packages/agent-runtime/agentsMd.ts
|
|
6066
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6067
|
+
import { join } from "node:path";
|
|
6068
|
+
var AGENTS_MD_MAX_BYTES = 8192;
|
|
6069
|
+
var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
|
|
6070
|
+
function readAgentsMdLayerFromDisk(cwd) {
|
|
6071
|
+
for (const name of AGENTS_MD_CANDIDATES) {
|
|
6072
|
+
const filePath = join(cwd, name);
|
|
6073
|
+
if (!existsSync(filePath)) continue;
|
|
6074
|
+
try {
|
|
6075
|
+
let content = readFileSync(filePath, "utf8").trim();
|
|
6076
|
+
if (!content) continue;
|
|
6077
|
+
if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
|
|
6078
|
+
content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
6079
|
+
}
|
|
6080
|
+
return buildAgentsMdLayer(content, name);
|
|
6081
|
+
} catch {
|
|
6082
|
+
}
|
|
6083
|
+
}
|
|
6084
|
+
return null;
|
|
6085
|
+
}
|
|
6086
|
+
|
|
6384
6087
|
// packages/cli/agentRunPrompts.ts
|
|
6385
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6386
|
-
import { dirname, extname, isAbsolute, join, relative as relativePath, resolve, sep } from "node:path";
|
|
6088
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
|
|
6089
|
+
import { dirname, extname, isAbsolute, join as join2, relative as relativePath, resolve, sep } from "node:path";
|
|
6387
6090
|
function workflowRefToCandidatePath(cwd, ref) {
|
|
6388
6091
|
const normalized = ref.trim();
|
|
6389
6092
|
if (!normalized) return "";
|
|
6390
6093
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6391
6094
|
const directPath = resolve(cwd, normalized);
|
|
6392
|
-
if (
|
|
6095
|
+
if (existsSync2(directPath)) return directPath;
|
|
6393
6096
|
}
|
|
6394
6097
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6395
6098
|
return resolve(cwd, "docs", "workflows", `${fileName}.md`);
|
|
@@ -6402,21 +6105,21 @@ function skillRefToCandidatePath(cwd, ref) {
|
|
|
6402
6105
|
if (!normalized) return "";
|
|
6403
6106
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6404
6107
|
const directPath = resolve(cwd, normalized);
|
|
6405
|
-
if (
|
|
6108
|
+
if (existsSync2(directPath)) return directPath;
|
|
6406
6109
|
}
|
|
6407
6110
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6408
6111
|
for (const dir of SKILL_SEARCH_DIRS) {
|
|
6409
6112
|
const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
|
|
6410
|
-
if (
|
|
6113
|
+
if (existsSync2(skillMdPath)) return skillMdPath;
|
|
6411
6114
|
}
|
|
6412
6115
|
return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
|
|
6413
6116
|
}
|
|
6414
6117
|
async function resolveWorkflowReference(ref, cwd = process.cwd()) {
|
|
6415
6118
|
const path = workflowRefToCandidatePath(cwd, ref);
|
|
6416
|
-
if (!path || !
|
|
6119
|
+
if (!path || !existsSync2(path)) {
|
|
6417
6120
|
throw new Error(`Workflow reference not found: ${ref}`);
|
|
6418
6121
|
}
|
|
6419
|
-
const markdown =
|
|
6122
|
+
const markdown = readFileSync2(path, "utf8");
|
|
6420
6123
|
const parsed = parseSkillDocProtocol(markdown);
|
|
6421
6124
|
return {
|
|
6422
6125
|
ref,
|
|
@@ -6433,8 +6136,8 @@ function inlineRelativeRefs(body, skillDir) {
|
|
|
6433
6136
|
const absPath = resolve(skillDir, cleaned);
|
|
6434
6137
|
const relative = relativePath(normalizedSkillDir, absPath);
|
|
6435
6138
|
if (relative.startsWith("..") || isAbsolute(relative)) return match;
|
|
6436
|
-
if (!
|
|
6437
|
-
const refContent =
|
|
6139
|
+
if (!existsSync2(absPath) || !absPath.endsWith(".md")) return match;
|
|
6140
|
+
const refContent = readFileSync2(absPath, "utf8");
|
|
6438
6141
|
return `
|
|
6439
6142
|
|
|
6440
6143
|
### ${label}
|
|
@@ -6445,8 +6148,8 @@ ${refContent}
|
|
|
6445
6148
|
});
|
|
6446
6149
|
}
|
|
6447
6150
|
function listSkillScripts(skillDir) {
|
|
6448
|
-
const scriptsDir =
|
|
6449
|
-
if (!
|
|
6151
|
+
const scriptsDir = join2(skillDir, "scripts");
|
|
6152
|
+
if (!existsSync2(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
|
|
6450
6153
|
const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
|
|
6451
6154
|
if (entries.length === 0) return null;
|
|
6452
6155
|
return [
|
|
@@ -6473,10 +6176,10 @@ async function resolveSkillReference(ref, options = {}) {
|
|
|
6473
6176
|
} else {
|
|
6474
6177
|
const cwd = options.cwd ?? process.cwd();
|
|
6475
6178
|
const path = skillRefToCandidatePath(cwd, ref);
|
|
6476
|
-
if (!path || !
|
|
6179
|
+
if (!path || !existsSync2(path)) {
|
|
6477
6180
|
throw new Error(`Skill reference not found: ${ref}`);
|
|
6478
6181
|
}
|
|
6479
|
-
markdown =
|
|
6182
|
+
markdown = readFileSync2(path, "utf8");
|
|
6480
6183
|
filePath = path;
|
|
6481
6184
|
skillDir = dirname(path);
|
|
6482
6185
|
}
|
|
@@ -6581,8 +6284,8 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
|
|
|
6581
6284
|
function normalizeCliImageInput(input) {
|
|
6582
6285
|
if (/^(https?:|data:|file:)/i.test(input)) return input;
|
|
6583
6286
|
const absolutePath = resolve(input);
|
|
6584
|
-
if (!
|
|
6585
|
-
const base64 =
|
|
6287
|
+
if (!existsSync2(absolutePath)) return input;
|
|
6288
|
+
const base64 = readFileSync2(absolutePath).toString("base64");
|
|
6586
6289
|
return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
|
|
6587
6290
|
}
|
|
6588
6291
|
function imageMimeTypeForPath(path) {
|
|
@@ -6665,6 +6368,19 @@ var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).
|
|
|
6665
6368
|
// packages/ai/memory/constants.ts
|
|
6666
6369
|
var EXPLICIT_REMEMBER_PREFIX_REGEX = /^(你要记住|请记住|以后记住|记住)[,,。.\s::]*/u;
|
|
6667
6370
|
|
|
6371
|
+
// packages/ai/memory/source.ts
|
|
6372
|
+
var getMemorySourceKind = (item) => {
|
|
6373
|
+
if (item.sourceKind) return item.sourceKind;
|
|
6374
|
+
if (item.patternKey === "explicit-remember") return "explicit-user-directive";
|
|
6375
|
+
if (item.patternKey === "agent-remember" || item.patternKey === "procedural-runbook")
|
|
6376
|
+
return "agent-tool";
|
|
6377
|
+
if (item.patternKey?.startsWith("dialog-learning:"))
|
|
6378
|
+
return "dialog-learning";
|
|
6379
|
+
if (item.tags?.includes("understanding-memory"))
|
|
6380
|
+
return "inferred-understanding";
|
|
6381
|
+
return "agent-tool";
|
|
6382
|
+
};
|
|
6383
|
+
|
|
6668
6384
|
// packages/ai/memory/overlay.ts
|
|
6669
6385
|
var KIND_TITLES = {
|
|
6670
6386
|
episodic: "Episodic",
|
|
@@ -6698,6 +6414,8 @@ var FACET_DISPLAY = {
|
|
|
6698
6414
|
style: { label: "\u66F4\u504F\u597D", strip: "\u66F4\u559C\u6B22" },
|
|
6699
6415
|
goal: { label: "\u60F3\u63A8\u8FDB", strip: "\u60F3\u63A8\u8FDB" }
|
|
6700
6416
|
};
|
|
6417
|
+
var INFERRED_SOURCE_KINDS = /* @__PURE__ */ new Set(["inferred-understanding", "dialog-learning"]);
|
|
6418
|
+
var isInferredMemory = (item) => INFERRED_SOURCE_KINDS.has(getMemorySourceKind(item));
|
|
6701
6419
|
var formatFacetContent = (facet, normalized, prefix) => {
|
|
6702
6420
|
const { label, strip } = FACET_DISPLAY[facet];
|
|
6703
6421
|
const stripped = normalized.startsWith(strip) ? normalized.slice(strip.length).trim() : normalized;
|
|
@@ -6719,9 +6437,79 @@ var normalizeDisplayContent = (item) => {
|
|
|
6719
6437
|
}
|
|
6720
6438
|
return normalized;
|
|
6721
6439
|
};
|
|
6440
|
+
var pickWithinKind = (list, perKindLimit) => {
|
|
6441
|
+
if (perKindLimit <= 0) return [];
|
|
6442
|
+
const head = list.slice(0, perKindLimit);
|
|
6443
|
+
if (head.length < perKindLimit) return head;
|
|
6444
|
+
if (head.some((item) => item.subjectType === "user")) return head;
|
|
6445
|
+
const firstUserSubject = list.find((item) => item.subjectType === "user");
|
|
6446
|
+
if (!firstUserSubject) return head;
|
|
6447
|
+
return [...head.slice(0, perKindLimit - 1), firstUserSubject];
|
|
6448
|
+
};
|
|
6449
|
+
var DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET = 3200;
|
|
6450
|
+
var MIN_TRUNCATED_TOKENS = 20;
|
|
6451
|
+
var TRUNCATED_SUFFIX = "\u2026\uFF08\u672C\u6761\u5DF2\u622A\u65AD\uFF09";
|
|
6452
|
+
var truncateLineToTokens = (lineText, budgetTokens) => {
|
|
6453
|
+
if (budgetTokens < MIN_TRUNCATED_TOKENS) return null;
|
|
6454
|
+
const suffixTokens = estimateTokens(TRUNCATED_SUFFIX);
|
|
6455
|
+
const bodyBudget = budgetTokens - suffixTokens;
|
|
6456
|
+
if (bodyBudget < MIN_TRUNCATED_TOKENS / 2) return null;
|
|
6457
|
+
let used = 0;
|
|
6458
|
+
let cut = 0;
|
|
6459
|
+
for (const ch of lineText) {
|
|
6460
|
+
const chTokens = estimateTokens(ch);
|
|
6461
|
+
if (used + chTokens > bodyBudget) break;
|
|
6462
|
+
used += chTokens;
|
|
6463
|
+
cut += ch.length;
|
|
6464
|
+
}
|
|
6465
|
+
if (cut <= 2) return null;
|
|
6466
|
+
return `${lineText.slice(0, cut).trimEnd()}${TRUNCATED_SUFFIX}`;
|
|
6467
|
+
};
|
|
6468
|
+
var fitLinesToBudget = (allLines, remainingBudget) => {
|
|
6469
|
+
let usedTokens = 0;
|
|
6470
|
+
const keptByKind = {};
|
|
6471
|
+
let truncatedCount = 0;
|
|
6472
|
+
let droppedCount = 0;
|
|
6473
|
+
const pushLine = (kind, lineText) => {
|
|
6474
|
+
if (!keptByKind[kind]) keptByKind[kind] = [];
|
|
6475
|
+
keptByKind[kind].push(lineText);
|
|
6476
|
+
};
|
|
6477
|
+
for (const candidate of allLines) {
|
|
6478
|
+
const remaining = remainingBudget - usedTokens;
|
|
6479
|
+
if (remaining <= 0) {
|
|
6480
|
+
droppedCount += 1;
|
|
6481
|
+
continue;
|
|
6482
|
+
}
|
|
6483
|
+
if (candidate.lineTokens <= remaining) {
|
|
6484
|
+
usedTokens += candidate.lineTokens;
|
|
6485
|
+
pushLine(candidate.kind, candidate.lineText);
|
|
6486
|
+
continue;
|
|
6487
|
+
}
|
|
6488
|
+
const truncated = truncateLineToTokens(candidate.lineText, remaining);
|
|
6489
|
+
if (!truncated) {
|
|
6490
|
+
droppedCount += 1;
|
|
6491
|
+
continue;
|
|
6492
|
+
}
|
|
6493
|
+
usedTokens += estimateTokens(truncated);
|
|
6494
|
+
pushLine(candidate.kind, truncated);
|
|
6495
|
+
truncatedCount += 1;
|
|
6496
|
+
}
|
|
6497
|
+
return { keptByKind, truncatedCount, droppedCount };
|
|
6498
|
+
};
|
|
6499
|
+
var buildBudgetFooter = (fit) => {
|
|
6500
|
+
const notices = [];
|
|
6501
|
+
if (fit.truncatedCount > 0) {
|
|
6502
|
+
notices.push(`${fit.truncatedCount} \u6761\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
|
|
6503
|
+
}
|
|
6504
|
+
if (fit.droppedCount > 0) {
|
|
6505
|
+
notices.push(`${fit.droppedCount} \u6761\u672A\u663E\u793A`);
|
|
6506
|
+
}
|
|
6507
|
+
if (notices.length === 0) return [];
|
|
6508
|
+
return [`\uFF08${notices.join("\u3001")}\uFF1B\u9700\u8981\u5B8C\u6574\u5185\u5BB9\u6216\u66F4\u591A\u76F8\u5173\u8BB0\u5FC6\u65F6\u7528 queryMemory \u68C0\u7D22\uFF09`];
|
|
6509
|
+
};
|
|
6722
6510
|
var buildMemoryOverlay = (items, options) => {
|
|
6723
6511
|
if (items.length === 0) return null;
|
|
6724
|
-
const maxTokens = options?.maxTokens ??
|
|
6512
|
+
const maxTokens = options?.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6725
6513
|
const perKindLimit = options?.perKindLimit ?? 3;
|
|
6726
6514
|
const byKind = {
|
|
6727
6515
|
episodic: [],
|
|
@@ -6736,19 +6524,15 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6736
6524
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6737
6525
|
}
|
|
6738
6526
|
const allLines = Object.entries(byKind).filter(([, list]) => list.length > 0).flatMap(
|
|
6739
|
-
([kind, list]) => list
|
|
6740
|
-
const lineText = `- ${normalizeDisplayContent(item)}`;
|
|
6527
|
+
([kind, list]) => pickWithinKind(list, perKindLimit).map((item) => {
|
|
6528
|
+
const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
|
|
6741
6529
|
return { kind, lineText, lineTokens: estimateTokens(lineText) };
|
|
6742
6530
|
})
|
|
6743
6531
|
).sort((a, b) => (KIND_PRIORITY[a.kind] ?? 99) - (KIND_PRIORITY[b.kind] ?? 99));
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
usedTokens += candidate.lineTokens;
|
|
6749
|
-
if (!keptByKind[candidate.kind]) keptByKind[candidate.kind] = [];
|
|
6750
|
-
keptByKind[candidate.kind].push(candidate.lineText);
|
|
6751
|
-
}
|
|
6532
|
+
const { keptByKind, truncatedCount, droppedCount } = fitLinesToBudget(
|
|
6533
|
+
allLines,
|
|
6534
|
+
remainingBudget
|
|
6535
|
+
);
|
|
6752
6536
|
const kindOrder = ["semantic", "procedural", "episodic"];
|
|
6753
6537
|
const sections = kindOrder.filter((kind) => keptByKind[kind] && keptByKind[kind].length > 0).map((kind) => {
|
|
6754
6538
|
return [`[${KIND_TITLES[kind]}]`, ...keptByKind[kind]].join("\n");
|
|
@@ -6756,7 +6540,7 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6756
6540
|
if (sections.length === 0) {
|
|
6757
6541
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6758
6542
|
}
|
|
6759
|
-
return [...OVERLAY_HEADER_LINES, ...sections].join("\n");
|
|
6543
|
+
return [...OVERLAY_HEADER_LINES, ...sections, ...buildBudgetFooter({ keptByKind, truncatedCount, droppedCount })].join("\n");
|
|
6760
6544
|
};
|
|
6761
6545
|
|
|
6762
6546
|
// packages/ai/memory/rank.ts
|
|
@@ -6803,13 +6587,28 @@ var identifierScore = (query, item) => {
|
|
|
6803
6587
|
).length;
|
|
6804
6588
|
return matches / identifiers.length;
|
|
6805
6589
|
};
|
|
6806
|
-
var
|
|
6590
|
+
var DAY_MS = 864e5;
|
|
6591
|
+
var UNPROVEN_MEMORY_GRACE_DAYS = 3;
|
|
6592
|
+
var MIN_UNPROVEN_SCORE_FACTOR = 0.3;
|
|
6593
|
+
var UNPROVEN_DECAY_HALF_LIFE_DAYS = 7;
|
|
6594
|
+
var provenActivationScore = (item, nowMs) => {
|
|
6807
6595
|
const lastActivatedMs = Date.parse(item.lastActivatedAt || item.createdAt);
|
|
6808
|
-
const ageDays = Math.max(0, (nowMs - lastActivatedMs) /
|
|
6596
|
+
const ageDays = Math.max(0, (nowMs - lastActivatedMs) / DAY_MS);
|
|
6809
6597
|
const recency = 1 / (1 + ageDays / 7);
|
|
6810
6598
|
const reinforcement = Math.min(1, Math.log1p(item.activationCount ?? 0) / 3);
|
|
6811
6599
|
return 0.7 * recency + 0.3 * reinforcement;
|
|
6812
6600
|
};
|
|
6601
|
+
var unprovenDecayFactor = (item, nowMs) => {
|
|
6602
|
+
if ((item.activationCount ?? 0) !== 0) return 1;
|
|
6603
|
+
const createdAgeDays = Math.max(0, (nowMs - Date.parse(item.createdAt)) / DAY_MS);
|
|
6604
|
+
if (createdAgeDays <= UNPROVEN_MEMORY_GRACE_DAYS) return 1;
|
|
6605
|
+
const overdue = createdAgeDays - UNPROVEN_MEMORY_GRACE_DAYS;
|
|
6606
|
+
return Math.max(
|
|
6607
|
+
MIN_UNPROVEN_SCORE_FACTOR,
|
|
6608
|
+
1 / (1 + overdue / UNPROVEN_DECAY_HALF_LIFE_DAYS)
|
|
6609
|
+
);
|
|
6610
|
+
};
|
|
6611
|
+
var activationScore = (item, nowMs) => provenActivationScore(item, nowMs) * unprovenDecayFactor(item, nowMs);
|
|
6813
6612
|
var creationRecencyScore = (item, nowMs) => {
|
|
6814
6613
|
const createdMs = Date.parse(item.createdAt);
|
|
6815
6614
|
const ageDays = Math.max(0, (nowMs - createdMs) / 864e5);
|
|
@@ -6865,7 +6664,7 @@ var rankMemoryCandidates = (items, query, context) => {
|
|
|
6865
6664
|
|
|
6866
6665
|
// packages/ai/memory/runtime.ts
|
|
6867
6666
|
var COLD_STORAGE_CONFIDENCE = 0.3;
|
|
6868
|
-
var MEMORY_OVERLAY_TOKEN_BUDGET =
|
|
6667
|
+
var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6869
6668
|
var normalizeSelectedContent = (text) => text.trim().replace(EXPLICIT_REMEMBER_PREFIX_REGEX, "").replace(/[。!?!?]+$/u, "").trim();
|
|
6870
6669
|
var STACK_TERMS = [
|
|
6871
6670
|
"typescript",
|
|
@@ -6967,6 +6766,7 @@ var selectRuntimeMemoryItems = (items, context, userInput = "") => {
|
|
|
6967
6766
|
);
|
|
6968
6767
|
add(unique.find((item) => item.ownerType === "user"));
|
|
6969
6768
|
add(unique.find((item) => item.ownerType === "space"));
|
|
6769
|
+
add(unique.find((item) => item.subjectType === "user"));
|
|
6970
6770
|
add(unique.find((item) => item.kind === "procedural"));
|
|
6971
6771
|
for (const item of unique) {
|
|
6972
6772
|
add(item);
|
|
@@ -7086,6 +6886,36 @@ var resolveCliMemory = async (input) => {
|
|
|
7086
6886
|
function resolvePositiveMs(value, fallback) {
|
|
7087
6887
|
return parsePositiveFiniteNumberOrFallback(value, fallback);
|
|
7088
6888
|
}
|
|
6889
|
+
function resolveRunOutcome(input) {
|
|
6890
|
+
switch (input.kind) {
|
|
6891
|
+
case "stall":
|
|
6892
|
+
return { status: "failed", exitCode: 1 };
|
|
6893
|
+
case "timeout":
|
|
6894
|
+
return { status: "timeout", exitCode: 124 };
|
|
6895
|
+
case "result": {
|
|
6896
|
+
const failed = input.isStalledOrTruncated || input.exitCode !== 0;
|
|
6897
|
+
if (!failed) {
|
|
6898
|
+
return { status: "done", exitCode: 0 };
|
|
6899
|
+
}
|
|
6900
|
+
return { status: "failed", exitCode: input.exitCode !== 0 ? input.exitCode : 1 };
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
var FAILED_EMPTY_ASSISTANT_REASONS = /* @__PURE__ */ new Set([
|
|
6905
|
+
"length_truncated",
|
|
6906
|
+
"stream_truncated",
|
|
6907
|
+
"repetition_loop",
|
|
6908
|
+
"stagnant_tool_calls"
|
|
6909
|
+
]);
|
|
6910
|
+
var isRunResultStalledOrTruncated = (result) => !result.emptyAssistantOutputUsable && FAILED_EMPTY_ASSISTANT_REASONS.has(result.emptyAssistantFallbackReason ?? "");
|
|
6911
|
+
var resolveRunSettlementNote = (result) => {
|
|
6912
|
+
const reason = result.emptyAssistantFallbackReason;
|
|
6913
|
+
if (!reason || !FAILED_EMPTY_ASSISTANT_REASONS.has(reason)) return {};
|
|
6914
|
+
if (result.emptyAssistantOutputUsable) {
|
|
6915
|
+
return { note: `output complete but stream lacked finish frame: ${reason}` };
|
|
6916
|
+
}
|
|
6917
|
+
return { note: `empty assistant output: ${reason}` };
|
|
6918
|
+
};
|
|
7089
6919
|
async function resolveAgentRunAgentKey(args) {
|
|
7090
6920
|
if (!args.agentInput.trim() || args.agentInput.startsWith("agent-")) {
|
|
7091
6921
|
return void 0;
|
|
@@ -7121,11 +6951,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7121
6951
|
deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
|
|
7122
6952
|
5 * 6e4
|
|
7123
6953
|
);
|
|
6954
|
+
const stallEnvExplicitlySet = typeof env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS === "string" && env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS.trim().length > 0;
|
|
6955
|
+
const armStallWatchdog = hasRegistry || stallEnvExplicitlySet;
|
|
6956
|
+
const armTimeoutWatchdog = typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0;
|
|
7124
6957
|
let timedOut = false;
|
|
7125
6958
|
let stalled = false;
|
|
7126
6959
|
let timeoutTimer;
|
|
7127
6960
|
let stallTimer;
|
|
7128
|
-
const activityTracker =
|
|
6961
|
+
const activityTracker = armStallWatchdog ? createRunActivityTracker(childRunId ?? "__foreground__", {
|
|
7129
6962
|
env,
|
|
7130
6963
|
homedir: deps.homedir,
|
|
7131
6964
|
fs: deps.fs,
|
|
@@ -7138,7 +6971,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7138
6971
|
activityTracker?.dispose();
|
|
7139
6972
|
};
|
|
7140
6973
|
let rejectOnWatchdogFailure;
|
|
7141
|
-
const watchdogFailure =
|
|
6974
|
+
const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
|
|
7142
6975
|
rejectOnWatchdogFailure = reject;
|
|
7143
6976
|
}) : void 0;
|
|
7144
6977
|
const raceWithWatchdog = (work) => watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
|
|
@@ -7148,7 +6981,15 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7148
6981
|
} catch {
|
|
7149
6982
|
}
|
|
7150
6983
|
};
|
|
7151
|
-
|
|
6984
|
+
const finalizeWatchdogOutcome = (outcome, note) => {
|
|
6985
|
+
if (!hasRegistry) return;
|
|
6986
|
+
(deps.finalizeRunRecord ?? finalizeRunRecord)(
|
|
6987
|
+
childRunId,
|
|
6988
|
+
{ status: outcome.status, exitCode: outcome.exitCode, note },
|
|
6989
|
+
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
6990
|
+
);
|
|
6991
|
+
};
|
|
6992
|
+
if (armStallWatchdog) {
|
|
7152
6993
|
stallTimer = setInterval(() => {
|
|
7153
6994
|
if (timedOut || stalled) return;
|
|
7154
6995
|
const activity = activityTracker?.getActivity();
|
|
@@ -7166,31 +7007,25 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7166
7007
|
const note = `stalled: no progress for ${stallTimeoutMs}ms`;
|
|
7167
7008
|
output.write(`[nolo] local run ${note}
|
|
7168
7009
|
`);
|
|
7169
|
-
(
|
|
7170
|
-
|
|
7171
|
-
{ status: "failed", note },
|
|
7172
|
-
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
7173
|
-
);
|
|
7010
|
+
const outcome = resolveRunOutcome({ kind: "stall" });
|
|
7011
|
+
finalizeWatchdogOutcome(outcome, note);
|
|
7174
7012
|
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7175
|
-
exitFromWatchdog(
|
|
7013
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7176
7014
|
}
|
|
7177
7015
|
}, Math.min(stallTimeoutMs, 1e4));
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7016
|
+
}
|
|
7017
|
+
if (armTimeoutWatchdog) {
|
|
7018
|
+
timeoutTimer = setTimeout(() => {
|
|
7019
|
+
timedOut = true;
|
|
7020
|
+
clearWatchdogs();
|
|
7021
|
+
const note = `timed out after ${parsed.timeoutMs}ms`;
|
|
7022
|
+
output.write(`[nolo] local run ${note}
|
|
7184
7023
|
`);
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7191
|
-
exitFromWatchdog(124);
|
|
7192
|
-
}, parsed.timeoutMs);
|
|
7193
|
-
}
|
|
7024
|
+
const outcome = resolveRunOutcome({ kind: "timeout" });
|
|
7025
|
+
finalizeWatchdogOutcome(outcome, note);
|
|
7026
|
+
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7027
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7028
|
+
}, parsed.timeoutMs);
|
|
7194
7029
|
}
|
|
7195
7030
|
const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
|
|
7196
7031
|
const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
|
|
@@ -7345,22 +7180,8 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7345
7180
|
let memoryOverlayLayer = null;
|
|
7346
7181
|
let memoryUseGuidanceLayer = null;
|
|
7347
7182
|
if (!isSubtask) {
|
|
7348
|
-
const
|
|
7349
|
-
|
|
7350
|
-
const agentsMdPath = join2(cliCwd, name);
|
|
7351
|
-
if (existsSync2(agentsMdPath)) {
|
|
7352
|
-
try {
|
|
7353
|
-
let mdContent = readFileSync2(agentsMdPath, "utf8").trim();
|
|
7354
|
-
if (!mdContent) continue;
|
|
7355
|
-
if (Buffer.byteLength(mdContent, "utf8") > AGENTS_MD_MAX) {
|
|
7356
|
-
mdContent = Buffer.from(mdContent, "utf8").subarray(0, AGENTS_MD_MAX).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
7357
|
-
}
|
|
7358
|
-
scopedLayers.push(buildAgentsMdLayer(mdContent, name));
|
|
7359
|
-
break;
|
|
7360
|
-
} catch {
|
|
7361
|
-
}
|
|
7362
|
-
}
|
|
7363
|
-
}
|
|
7183
|
+
const agentsMdLayer = readAgentsMdLayerFromDisk(cliCwd);
|
|
7184
|
+
if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
|
|
7364
7185
|
skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
|
|
7365
7186
|
scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
|
|
7366
7187
|
if (!deps.memoryRecallDisabled) {
|
|
@@ -7441,6 +7262,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7441
7262
|
})
|
|
7442
7263
|
);
|
|
7443
7264
|
clearWatchdogs();
|
|
7265
|
+
let runCreditsTotal = result.turnCredits;
|
|
7444
7266
|
if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
|
|
7445
7267
|
const fallbackAgentKey = parsed.fallbackAgentKeys[0];
|
|
7446
7268
|
output.write(
|
|
@@ -7456,7 +7278,11 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7456
7278
|
clearWatchdogs();
|
|
7457
7279
|
if (fallbackResult.exitCode === 0) {
|
|
7458
7280
|
result = fallbackResult;
|
|
7459
|
-
}
|
|
7281
|
+
}
|
|
7282
|
+
if (fallbackResult.turnCredits !== void 0) {
|
|
7283
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + fallbackResult.turnCredits;
|
|
7284
|
+
}
|
|
7285
|
+
if (fallbackResult.exitCode !== 0) {
|
|
7460
7286
|
result = {
|
|
7461
7287
|
...fallbackResult,
|
|
7462
7288
|
...fallbackResult.dialogId || result.dialogId ? { dialogId: fallbackResult.dialogId ?? result.dialogId } : {}
|
|
@@ -7499,6 +7325,9 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7499
7325
|
);
|
|
7500
7326
|
clearWatchdogs();
|
|
7501
7327
|
result = turnResult;
|
|
7328
|
+
if (turnResult.turnCredits !== void 0) {
|
|
7329
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
|
|
7330
|
+
}
|
|
7502
7331
|
if (result.exitCode !== 0) {
|
|
7503
7332
|
break;
|
|
7504
7333
|
}
|
|
@@ -7549,15 +7378,22 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7549
7378
|
}
|
|
7550
7379
|
}
|
|
7551
7380
|
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
7552
|
-
const isStalledOrTruncated = result
|
|
7553
|
-
const truncationNote =
|
|
7554
|
-
const
|
|
7381
|
+
const isStalledOrTruncated = isRunResultStalledOrTruncated(result);
|
|
7382
|
+
const truncationNote = resolveRunSettlementNote(result);
|
|
7383
|
+
const outcome = resolveRunOutcome({
|
|
7384
|
+
kind: "result",
|
|
7385
|
+
exitCode: result.exitCode,
|
|
7386
|
+
isStalledOrTruncated
|
|
7387
|
+
});
|
|
7555
7388
|
await (deps.finalizeRunRecord ?? finalizeRunRecord)(
|
|
7556
7389
|
childRunId,
|
|
7557
7390
|
{
|
|
7558
|
-
status:
|
|
7559
|
-
exitCode:
|
|
7391
|
+
status: outcome.status,
|
|
7392
|
+
exitCode: outcome.exitCode,
|
|
7560
7393
|
dialogId: result.dialogId,
|
|
7394
|
+
// run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
|
|
7395
|
+
// 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
|
|
7396
|
+
...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
|
|
7561
7397
|
...truncationNote
|
|
7562
7398
|
},
|
|
7563
7399
|
{
|
|
@@ -7602,6 +7438,7 @@ function isBalanceExhaustedError(error) {
|
|
|
7602
7438
|
export {
|
|
7603
7439
|
resolveAgentModelIdentity,
|
|
7604
7440
|
resolveAgentContextWindow,
|
|
7441
|
+
formatCreditsChip,
|
|
7605
7442
|
formatTokenCount,
|
|
7606
7443
|
renderTokenStatus,
|
|
7607
7444
|
resolveCliColorEnabled,
|
|
@@ -7640,8 +7477,10 @@ export {
|
|
|
7640
7477
|
themeText,
|
|
7641
7478
|
tuiRenderThemeFingerprint,
|
|
7642
7479
|
setMathRenderingEnabled,
|
|
7480
|
+
polishBreathInsertsBlankBetween,
|
|
7643
7481
|
formatAssistantDisplay,
|
|
7644
|
-
|
|
7482
|
+
redactSecrets,
|
|
7483
|
+
TUI_TREE_MARKER,
|
|
7645
7484
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
7646
7485
|
shouldCollapsePaste,
|
|
7647
7486
|
createCollapsedPasteStore,
|
|
@@ -7653,6 +7492,7 @@ export {
|
|
|
7653
7492
|
expandRangeToCollapsedPasteChips,
|
|
7654
7493
|
findCollapsedPasteSpanAt,
|
|
7655
7494
|
runAgentTurn,
|
|
7495
|
+
readAgentsMdLayerFromDisk,
|
|
7656
7496
|
resolveWorkflowReference,
|
|
7657
7497
|
resolveSkillReference,
|
|
7658
7498
|
buildSkillContextBlocks,
|
|
@@ -7660,6 +7500,9 @@ export {
|
|
|
7660
7500
|
normalizeCliImageInput,
|
|
7661
7501
|
inspectLocalRunWorkspace,
|
|
7662
7502
|
resolveCliMemory,
|
|
7503
|
+
resolveRunOutcome,
|
|
7504
|
+
isRunResultStalledOrTruncated,
|
|
7505
|
+
resolveRunSettlementNote,
|
|
7663
7506
|
runAgentRunCommand,
|
|
7664
7507
|
isBalanceExhaustedError
|
|
7665
7508
|
};
|