nolo-cli 0.54.0-alpha.1 → 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-IVEOJ7L6.js → _executeModel-OPTKYHJA.js} +53 -48
- package/{action-IU6ON7ZB.js → action-ORXWW2ZG.js} +9 -9
- package/{addContentAction-5V5CCI3I.js → addContentAction-53BZ34AE.js} +9 -8
- package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-JRYUS54Y.js} +11 -10
- package/{agentDeleteCommand-D7AFLKQN.js → agentDeleteCommand-FJIWU2BS.js} +31 -29
- package/{agentEmailCommands-MXFZGF54.js → agentEmailCommands-CE32L43B.js} +62 -58
- package/{agentListCommands-MP732Q23.js → agentListCommands-VJNKULIK.js} +43 -34
- package/{agentMachineCommands-352JFJX4.js → agentMachineCommands-HCJ3WQXL.js} +31 -29
- package/agentRecordCommands-QFWERED4.js +119 -0
- package/{agentRunCommand-UUWJMH7J.js → agentRunCommand-G3GQMUNN.js} +70 -59
- package/{agentRunControl-4GHHSXFZ.js → agentRunControl-INKFDXDA.js} +3 -1
- package/{agentRuntimeLocal-KWBPJ53H.js → agentRuntimeLocal-K327ELSL.js} +31 -27
- package/{agentSlice-V742SNKC.js → agentSlice-ODKF4J6M.js} +9 -9
- package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-5AR3DKNN.js} +2 -2
- package/{appDeleteCommands-GV4TF52A.js → appDeleteCommands-XUXMFDI4.js} +32 -30
- package/{appDeployCommands-EZMUPNSW.js → appDeployCommands-37F4GPCU.js} +32 -30
- package/{appDeployStatusCommands-AAGELKAN.js → appDeployStatusCommands-WSPU7TUK.js} +32 -30
- package/{appGetCommands-W37KDAON.js → appGetCommands-YLOBA3EM.js} +32 -30
- package/{appListCommands-IFDWBBNV.js → appListCommands-UD62R5ME.js} +32 -30
- package/{authCommand-5HM57KPL.js → authCommand-OK6HLHGS.js} +13 -13
- package/{authCommands-SBQVTD6V.js → authCommands-2DUIUEMT.js} +2 -2
- package/{chatQueueReduxAdapter-ZXXP6E4O.js → chatQueueReduxAdapter-TV2TUOQS.js} +28 -25
- package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
- package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
- package/{chunk-2JYSSXLY.js → chunk-2WBFJHQA.js} +5 -27
- package/{chunk-FZMM2KZC.js → chunk-3LKZRP7E.js} +2 -2
- package/{chunk-WUMYQ2FE.js → chunk-3Y2K5O2R.js} +64 -6
- package/{chunk-5XCW6RQG.js → chunk-3ZTR7ZO4.js} +1 -1
- package/{chunk-W6N3GLUU.js → chunk-5FCIPEKT.js} +327 -149
- package/{chunk-B54WOZ77.js → chunk-5UAYZEXO.js} +2 -2
- package/{chunk-5SXS7T5Q.js → chunk-6COJEAYH.js} +36 -105
- package/{chunk-PEMGYJNS.js → chunk-6HDYSFLO.js} +4 -6
- package/{chunk-6XIE5ZGI.js → chunk-6HIGYUBQ.js} +1 -1
- package/chunk-6IGD47IC.js +19 -0
- package/chunk-6YTOJY35.js +352 -0
- package/{chunk-6FGXGFAH.js → chunk-75MSWWUE.js} +1 -1
- package/{chunk-ALMVQQPG.js → chunk-7FAS3NEF.js} +17 -17
- package/{chunk-76UA7376.js → chunk-7NYDJAQ7.js} +20 -15
- package/{chunk-2T6XO4PK.js → chunk-A65UV3M5.js} +4 -4
- package/{chunk-V2IPBG5U.js → chunk-AA564GBL.js} +2 -2
- package/{chunk-SQTVMYMU.js → chunk-AUVFJGPC.js} +4 -4
- package/{chunk-HR5XDXYM.js → chunk-BBTN4NQD.js} +4 -4
- package/{chunk-CULR4XB4.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-DIQCV4FR.js → chunk-EA5OYZVD.js} +1 -1
- package/{chunk-RO2IUWZE.js → chunk-EICIFHVS.js} +1 -1
- package/chunk-EJE33XNR.js +19059 -0
- package/{chunk-M2CGG6VJ.js → chunk-EVBFYPDC.js} +1 -1
- package/{chunk-KHCLMKZZ.js → chunk-EY7V7REW.js} +280 -6
- package/{chunk-MC66ASS6.js → chunk-FJHMLRDQ.js} +12 -12
- package/{chunk-YFHUQLJF.js → chunk-GRFK2XP4.js} +2 -2
- package/{chunk-J3UALFHL.js → chunk-HJTAGT3W.js} +1 -1
- package/{chunk-J7KVJAUQ.js → chunk-HPW5MNDQ.js} +38 -99
- package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
- package/{chunk-OYNDYVSE.js → chunk-JON2PHYT.js} +1 -1
- package/{chunk-RBJD33HM.js → chunk-JXIP6ZWH.js} +7 -7
- package/{chunk-PTHLNXGY.js → chunk-K4NISKOR.js} +46 -8
- package/{chunk-5Y5G76BJ.js → chunk-KLIBF3BY.js} +2 -2
- package/chunk-LRGKOI5Y.js +297 -0
- package/{chunk-OU7NGN5Y.js → chunk-MLEZPE3U.js} +2 -2
- package/{chunk-4RXXP6WD.js → chunk-MYMBBB6Q.js} +5 -64
- package/{chunk-ET7BXWAW.js → chunk-N4JKMCY3.js} +2 -2
- package/{chunk-45E65JER.js → chunk-NFLA6GSU.js} +4 -4
- package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
- package/{chunk-WJV3G7BM.js → chunk-NJUQBYFJ.js} +3 -1
- package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
- package/{chunk-Q24S4NDF.js → chunk-Q4XZVZPN.js} +1 -1
- package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
- package/{chunk-VM7K5EJL.js → chunk-RHMDMTDK.js} +2 -2
- package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
- package/{chunk-WHVQA7PJ.js → chunk-SSXTSPSG.js} +27 -6
- package/chunk-SUEIAK5N.js +2574 -0
- package/{chunk-X7S7OFUX.js → chunk-SVC3GGUA.js} +6 -6
- package/{chunk-7UFH6THF.js → chunk-SVDMVX4G.js} +118 -2
- package/{chunk-ZMV5PCRS.js → chunk-SWJGJMTW.js} +1 -1
- package/{chunk-DQLYEGP7.js → chunk-SYYUU7EV.js} +2 -2
- package/{chunk-K7CNV7GI.js → chunk-TC6P4NDR.js} +7 -7
- package/{chunk-SUFDWBLV.js → chunk-TR4DXUYX.js} +1988 -452
- package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
- package/chunk-UAD2WT54.js +64 -0
- package/{chunk-HCBQVVFZ.js → chunk-UGBHDMHI.js} +4 -4
- package/{chunk-R63FNYSI.js → chunk-UOWXD4VN.js} +851 -970
- package/{chunk-GBXR3CSM.js → chunk-UR66XPVF.js} +3 -3
- package/{chunk-6BYAXNH5.js → chunk-VZMUOPYG.js} +12 -2
- package/{chunk-RVHPY5PC.js → chunk-WQHGJHAL.js} +441 -2982
- package/chunk-XIJZOCSP.js +1766 -0
- package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
- package/{chunk-BKPUPZ6W.js → chunk-YBFJQC2M.js} +95 -778
- package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
- package/{chunk-SG65C33A.js → chunk-YLCUU3WM.js} +4 -4
- package/{chunk-XXZULHJ7.js → chunk-YQBXOHE6.js} +1 -1
- package/chunk-ZJ7UHBJS.js +89 -0
- package/{chunk-TNPCQNGQ.js → chunk-ZVOHVJI3.js} +4 -9
- package/{codingSkills-BYQI6EPT.js → codingSkills-BCQXRZOI.js} +3 -4
- package/contentThunks-KNI6VXLT.js +71 -0
- package/{createAgentAutomationAction-LE3ZYDT6.js → createAgentAutomationAction-OK4L33KF.js} +29 -25
- package/createDialogAction-JDSMY4AY.js +62 -0
- package/{createPageAction-X4C7K3OD.js → createPageAction-T7RA3HCG.js} +32 -28
- package/{dbSlice-FWF5F4L7.js → dbSlice-TVX6SN2T.js} +7 -7
- package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
- package/{dialogCommands-CP2U44A7.js → dialogCommands-UQZYWOOV.js} +33 -31
- package/{dialogSlice-2SH5636X.js → dialogSlice-TYW2G7IL.js} +28 -25
- package/{docCreateCommands-A2KIJSF7.js → docCreateCommands-OA6HZBWO.js} +37 -36
- package/{docDeleteCommands-NZ7XO4Z4.js → docDeleteCommands-KBB3YQI2.js} +34 -33
- package/{docReadCommands-VWVK4ZAR.js → docReadCommands-ZLMFVC67.js} +33 -32
- package/{docStore-J6GQYKHS.js → docStore-2URPBVCS.js} +9 -34
- package/{docUpdateCommands-YTUEC6PN.js → docUpdateCommands-HMH5KUON.js} +37 -36
- package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
- package/{getPricing-I53UFOPH.js → getPricing-RFOPUWHY.js} +4 -4
- package/{handleSendMessageAction-MD325XZS.js → handleSendMessageAction-GO53TY7U.js} +30 -27
- package/index.js +67 -67
- package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
- package/{machineCommands-TCNZV2DC.js → machineCommands-RK6L7ZWL.js} +64 -60
- package/{machineWsRunDispatch-QSX5IWPH.js → machineWsRunDispatch-3X64DW2Z.js} +59 -55
- package/memberThunks-THZYZFSN.js +638 -0
- package/{models-E2CYP4IB.js → models-JVKUEER5.js} +2 -2
- package/package.json +2 -3
- package/{read-J7RVVCHH.js → read-K4JU4MQC.js} +4 -4
- package/{readDocTool-G2WBM4IH.js → readDocTool-LQGR6FUN.js} +1 -1
- package/{readlineWorkspace-N3RGX7EK.js → readlineWorkspace-XUFJV3RS.js} +1005 -437
- package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-ECHCFB7N.js} +13 -12
- package/{runAgentClientLoop-R3NTOERA.js → runAgentClientLoop-24GQ2AW6.js} +51 -46
- package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-KCVJNGMB.js} +10 -9
- package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-VDOBOMKC.js} +13 -12
- package/{settingSlice-7NN2MI6Y.js → settingSlice-VR2IJSXC.js} +8 -8
- package/{skillDiscovery-COX56OBO.js → skillDiscovery-2QTZINON.js} +3 -4
- package/{spaceCommands-RC7XMYQ7.js → spaceCommands-S5YJJXL7.js} +31 -29
- package/{streamAgentChatTurn-WLWEBWSF.js → streamAgentChatTurn-QHKP3ABO.js} +82 -70
- package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-5L4UP7VI.js} +11 -10
- package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
- package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
- package/{tools-LSLDSUWU.js → tools-SSXSTC3O.js} +42 -38
- package/{tuiSummaryLlmCaller-TPBL4BV2.js → tuiSummaryLlmCaller-URFJHFC5.js} +19 -17
- package/{updateDialogTitleAction-4HJEARM7.js → updateDialogTitleAction-YFYAEW3T.js} +30 -26
- package/agentRecordCommands-G6EFHU3G.js +0 -115
- package/chunk-AETZ7AD6.js +0 -274
- package/chunk-DMCFF4KE.js +0 -435
- package/chunk-EUG45QJR.js +0 -6104
- package/chunk-J4Z6UI4C.js +0 -7076
- package/chunk-OFZPJ3NT.js +0 -114
- package/createDialogAction-2C6SR62D.js +0 -59
- package/spaceSlice-KBVKKO3M.js +0 -127
- package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.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,39 +74,37 @@ 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
|
|
92
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-EY7V7REW.js";
|
|
93
100
|
import {
|
|
94
101
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
95
102
|
LOCAL_TURN_ABORTED_CODE,
|
|
96
|
-
readActionGate
|
|
97
|
-
|
|
98
|
-
} from "./chunk-J4Z6UI4C.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));
|
|
@@ -1240,13 +1274,6 @@ function setActiveThemeMode(mode) {
|
|
|
1240
1274
|
function setActiveBrightness(brightness) {
|
|
1241
1275
|
setActiveThemeMode(brightness ?? "terminal");
|
|
1242
1276
|
}
|
|
1243
|
-
var activeDensity = "spacious";
|
|
1244
|
-
function getActiveDensity() {
|
|
1245
|
-
return activeDensity;
|
|
1246
|
-
}
|
|
1247
|
-
function setActiveDensity(density) {
|
|
1248
|
-
activeDensity = density;
|
|
1249
|
-
}
|
|
1250
1277
|
var TRUECOLOR_TERM_PROGRAMS = /* @__PURE__ */ new Set([
|
|
1251
1278
|
"iterm.app",
|
|
1252
1279
|
"wezterm",
|
|
@@ -2915,6 +2942,14 @@ function normalizeListLine(line) {
|
|
|
2915
2942
|
}
|
|
2916
2943
|
return line;
|
|
2917
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
|
+
}
|
|
2918
2953
|
function convertMarkdownTablesForTerminal(text) {
|
|
2919
2954
|
const lines = text.split("\n");
|
|
2920
2955
|
const out = [];
|
|
@@ -2982,7 +3017,7 @@ function polishAssistantStructure(text, options = {}) {
|
|
|
2982
3017
|
return line;
|
|
2983
3018
|
});
|
|
2984
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");
|
|
2985
|
-
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]/;
|
|
3020
|
+
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2986
3021
|
const headingLines = afterHeading.split("\n");
|
|
2987
3022
|
const breathed = [];
|
|
2988
3023
|
for (let i = 0; i < headingLines.length; i++) {
|
|
@@ -3340,130 +3375,16 @@ function formatAssistantTextForCli(text) {
|
|
|
3340
3375
|
return text.replace(/\u003cthink\u003e[\s\S]*?\u003c\/think\u003e\s*/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
3341
3376
|
}
|
|
3342
3377
|
|
|
3343
|
-
// packages/cli/
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
}
|
|
3354
|
-
return path.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
3355
|
-
}
|
|
3356
|
-
|
|
3357
|
-
// packages/cli/client/formatReadPathTree.ts
|
|
3358
|
-
function clipPathAware(value, max = 72) {
|
|
3359
|
-
const compact = compactWhitespace(value);
|
|
3360
|
-
if (compact.length <= max) return compact;
|
|
3361
|
-
if (compact.includes(" ") || !compact.includes("/") && !compact.includes("\\")) {
|
|
3362
|
-
return clipCompactText(value, max, "\u2026");
|
|
3363
|
-
}
|
|
3364
|
-
const segments = compact.split(/[/\\]/);
|
|
3365
|
-
const filename = segments[segments.length - 1];
|
|
3366
|
-
if (filename.length >= max) {
|
|
3367
|
-
return clipCompactText(value, max, "\u2026");
|
|
3368
|
-
}
|
|
3369
|
-
const ELISION = "/\u2026/";
|
|
3370
|
-
let prefix = "";
|
|
3371
|
-
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3372
|
-
const candidate = segments.slice(0, i + 1).join("/");
|
|
3373
|
-
if (candidate.length + ELISION.length + filename.length > max) break;
|
|
3374
|
-
prefix = candidate;
|
|
3375
|
-
}
|
|
3376
|
-
if (prefix) return `${prefix}${ELISION}${filename}`;
|
|
3377
|
-
const filenameOnly = `\u2026/${filename}`;
|
|
3378
|
-
if (filenameOnly.length <= max) return filenameOnly;
|
|
3379
|
-
return clipCompactText(value, max, "\u2026");
|
|
3380
|
-
}
|
|
3381
|
-
function formatHomePath(path, customHomedir) {
|
|
3382
|
-
if (!path) return "";
|
|
3383
|
-
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
3384
|
-
return foldHomePath(path, home);
|
|
3385
|
-
}
|
|
3386
|
-
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
3387
|
-
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
3388
|
-
let formattedPath = formatHomePath(inputPath, customHomedir);
|
|
3389
|
-
if (!formattedPath) return "file";
|
|
3390
|
-
let rangePart = "";
|
|
3391
|
-
const match = formattedPath.match(/(:[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*)$/);
|
|
3392
|
-
if (match) {
|
|
3393
|
-
rangePart = match[1];
|
|
3394
|
-
formattedPath = formattedPath.slice(0, -rangePart.length);
|
|
3395
|
-
} else if (metadata && typeof metadata.startLine === "number" && typeof metadata.endLine === "number" && typeof metadata.totalLines === "number") {
|
|
3396
|
-
const { startLine, endLine, totalLines, truncated } = metadata;
|
|
3397
|
-
if (truncated || startLine !== 1 || endLine !== totalLines) {
|
|
3398
|
-
rangePart = `:${startLine}-${endLine}`;
|
|
3399
|
-
}
|
|
3400
|
-
}
|
|
3401
|
-
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3402
|
-
return `${clippedPath}${rangePart}`;
|
|
3403
|
-
}
|
|
3404
|
-
function formatReadTreeLines(items, customHomedir) {
|
|
3405
|
-
const count = items.length;
|
|
3406
|
-
const header = `Read (${count})`;
|
|
3407
|
-
const lines = items.map((item, index) => {
|
|
3408
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3409
|
-
const pathWithRange = formatReadItemPath(item.path, item.metadata, customHomedir);
|
|
3410
|
-
return { connector, pathWithRange };
|
|
3411
|
-
});
|
|
3412
|
-
return { header, count, lines };
|
|
3413
|
-
}
|
|
3414
|
-
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3415
|
-
let text = (query || "").trim();
|
|
3416
|
-
if (path) {
|
|
3417
|
-
const formattedPath = formatHomePath(path, customHomedir);
|
|
3418
|
-
if (formattedPath) {
|
|
3419
|
-
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
3420
|
-
}
|
|
3421
|
-
}
|
|
3422
|
-
if (!text) return "search";
|
|
3423
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3424
|
-
}
|
|
3425
|
-
function formatSearchTreeLines(items, customHomedir) {
|
|
3426
|
-
const count = items.length;
|
|
3427
|
-
const header = `Search (${count})`;
|
|
3428
|
-
const lines = items.map((item, index) => {
|
|
3429
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3430
|
-
const queryText = formatSearchItemQuery(item.query, item.path, customHomedir);
|
|
3431
|
-
return { connector, queryText };
|
|
3432
|
-
});
|
|
3433
|
-
return { header, count, lines };
|
|
3434
|
-
}
|
|
3435
|
-
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3436
|
-
let text = compactWhitespace(command || "");
|
|
3437
|
-
if (!text) text = "command";
|
|
3438
|
-
text = text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3439
|
-
if (timedOut) return `${text} (timed out)`;
|
|
3440
|
-
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3441
|
-
return text;
|
|
3442
|
-
}
|
|
3443
|
-
function formatRunTreeLines(items) {
|
|
3444
|
-
const count = items.length;
|
|
3445
|
-
const header = `Run (${count})`;
|
|
3446
|
-
const lines = items.map((item, index) => {
|
|
3447
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3448
|
-
const commandText = formatRunItemCommand(item.command, item.exitCode, item.timedOut);
|
|
3449
|
-
return { connector, commandText };
|
|
3450
|
-
});
|
|
3451
|
-
return { header, count, lines };
|
|
3452
|
-
}
|
|
3453
|
-
function formatFetchItemUrl(url) {
|
|
3454
|
-
const text = (url || "").trim();
|
|
3455
|
-
if (!text) return "webpage";
|
|
3456
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3457
|
-
}
|
|
3458
|
-
function formatFetchTreeLines(items) {
|
|
3459
|
-
const count = items.length;
|
|
3460
|
-
const header = `Fetch (${count})`;
|
|
3461
|
-
const lines = items.map((item, index) => {
|
|
3462
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3463
|
-
const urlText = formatFetchItemUrl(item.url);
|
|
3464
|
-
return { connector, urlText };
|
|
3465
|
-
});
|
|
3466
|
-
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
|
+
);
|
|
3467
3388
|
}
|
|
3468
3389
|
|
|
3469
3390
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -3716,186 +3637,110 @@ function tokenize(value, options) {
|
|
|
3716
3637
|
return retLines;
|
|
3717
3638
|
}
|
|
3718
3639
|
|
|
3719
|
-
// packages/cli/client/
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
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)}`;
|
|
3724
3650
|
}
|
|
3725
|
-
|
|
3726
|
-
|
|
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");
|
|
3727
3660
|
}
|
|
3728
|
-
|
|
3729
|
-
|
|
3661
|
+
const segments = compact.split(/[/\\]/);
|
|
3662
|
+
const filename = segments[segments.length - 1];
|
|
3663
|
+
if (filename.length >= max) {
|
|
3664
|
+
return clipCompactText(value, max, "\u2026");
|
|
3730
3665
|
}
|
|
3731
|
-
|
|
3732
|
-
|
|
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;
|
|
3733
3672
|
}
|
|
3734
|
-
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);
|
|
3735
3682
|
}
|
|
3736
|
-
function
|
|
3737
|
-
const
|
|
3738
|
-
|
|
3739
|
-
|
|
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
|
+
}
|
|
3740
3697
|
}
|
|
3741
|
-
|
|
3742
|
-
|
|
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
|
+
}
|
|
3743
3708
|
}
|
|
3744
|
-
|
|
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;
|
|
3745
3719
|
}
|
|
3746
|
-
function
|
|
3747
|
-
|
|
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;
|
|
3748
3724
|
}
|
|
3725
|
+
|
|
3726
|
+
// packages/cli/client/toolOutput.ts
|
|
3749
3727
|
function clip(value, max = 72) {
|
|
3750
3728
|
return clipCompactText(value, max, "\u2026");
|
|
3751
3729
|
}
|
|
3752
|
-
function formatActiveToolLabel(event) {
|
|
3753
|
-
const toolName = event.toolName || "tool";
|
|
3754
|
-
const args = clipPathAware(event.argumentsPreview ?? "");
|
|
3755
|
-
const label = toolLabel(toolName);
|
|
3756
|
-
return args ? `${label} ${args}` : label;
|
|
3757
|
-
}
|
|
3758
3730
|
function formatConservativeActiveToolLabel(event) {
|
|
3759
3731
|
return toolLabel(event.toolName || "tool");
|
|
3760
3732
|
}
|
|
3761
|
-
function
|
|
3762
|
-
|
|
3763
|
-
if (gate) {
|
|
3764
|
-
const commandPayload = gate.kind === "handoff" ? readCommandActionGatePayload(gate.payload) : null;
|
|
3765
|
-
const command = commandPayload?.displayCommand ?? commandPayload?.command.join(" ") ?? "";
|
|
3766
|
-
const detail = command.trim() ? command : gate.title;
|
|
3767
|
-
return { inline: `${t("toolNeedsAction")}: ${clip(detail, 120)}` };
|
|
3768
|
-
}
|
|
3769
|
-
if (event.metadata?.timedOut) return { inline: t("toolTimedOut") };
|
|
3770
|
-
if (event.toolName === "readFile" && event.metadata) {
|
|
3771
|
-
const range = readReadFileRange(event.metadata);
|
|
3772
|
-
if (range) return { inline: range };
|
|
3773
|
-
}
|
|
3774
|
-
if (event.toolName === "editFile" && event.metadata) {
|
|
3775
|
-
const res = formatEditFileSnippet(event.metadata);
|
|
3776
|
-
if (res) {
|
|
3777
|
-
const stats = [];
|
|
3778
|
-
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
3779
|
-
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
3780
|
-
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
3781
|
-
return { inline, detail: res.lines };
|
|
3782
|
-
}
|
|
3783
|
-
}
|
|
3784
|
-
if (event.toolName === "writeFile" && event.metadata) {
|
|
3785
|
-
const totalLines = event.metadata.totalLines ?? event.metadata.lines;
|
|
3786
|
-
if (typeof totalLines === "number" && totalLines > 0) {
|
|
3787
|
-
return { inline: `(+${totalLines})` };
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
const summary = event.summary;
|
|
3791
|
-
if (!summary) return { inline: "" };
|
|
3792
|
-
const exitMatch = summary.match(/exit=(\d+)/);
|
|
3793
|
-
if (exitMatch && exitMatch[1] !== "0") return { inline: `${t("toolExitCode")} ${exitMatch[1]}` };
|
|
3794
|
-
return { inline: "" };
|
|
3795
|
-
}
|
|
3796
|
-
function readReadFileRange(metadata) {
|
|
3797
|
-
const startLine = metadata.startLine;
|
|
3798
|
-
const endLine = metadata.endLine;
|
|
3799
|
-
const totalLines = metadata.totalLines;
|
|
3800
|
-
const truncated = metadata.truncated;
|
|
3801
|
-
if (typeof startLine !== "number" || typeof endLine !== "number" || typeof totalLines !== "number") {
|
|
3802
|
-
return void 0;
|
|
3803
|
-
}
|
|
3804
|
-
if (!truncated && startLine === 1 && endLine === totalLines) return void 0;
|
|
3805
|
-
return `${startLine}-${endLine}/${totalLines}`;
|
|
3806
|
-
}
|
|
3807
|
-
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
3808
|
-
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
3809
|
-
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
3810
|
-
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
3811
|
-
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
3812
|
-
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
3813
|
-
}
|
|
3814
|
-
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
3815
|
-
if (cols > 0) {
|
|
3816
|
-
return Math.max(80, Math.min(160, cols - 8));
|
|
3817
|
-
}
|
|
3818
|
-
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
3819
|
-
}
|
|
3820
|
-
function formatEditFileSnippet(metadata) {
|
|
3821
|
-
const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
|
|
3822
|
-
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
3823
|
-
if (!oldSnippet && !newSnippet) return void 0;
|
|
3824
|
-
const maxWidth = resolveEditSnippetMaxWidth();
|
|
3825
|
-
if (oldSnippet && !newSnippet) {
|
|
3826
|
-
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
3827
|
-
return { lines, addedCount: 0, removedCount: lines.length };
|
|
3828
|
-
}
|
|
3829
|
-
if (newSnippet && !oldSnippet) {
|
|
3830
|
-
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
3831
|
-
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
3832
|
-
}
|
|
3833
|
-
const parts = diffLines(oldSnippet, newSnippet);
|
|
3834
|
-
const all = [];
|
|
3835
|
-
let addedCount = 0;
|
|
3836
|
-
let removedCount = 0;
|
|
3837
|
-
for (const part of parts) {
|
|
3838
|
-
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
3839
|
-
const raw = part.value.split("\n");
|
|
3840
|
-
if (raw.length > 0 && raw[raw.length - 1] === "") raw.pop();
|
|
3841
|
-
for (const line of raw) {
|
|
3842
|
-
if (kind === "added") addedCount++;
|
|
3843
|
-
if (kind === "removed") removedCount++;
|
|
3844
|
-
all.push(buildEditLine(kind, line, maxWidth));
|
|
3845
|
-
}
|
|
3846
|
-
}
|
|
3847
|
-
const changeCount = all.filter((l) => l.kind !== "context").length;
|
|
3848
|
-
if (changeCount === 0) return void 0;
|
|
3849
|
-
return {
|
|
3850
|
-
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
3851
|
-
addedCount,
|
|
3852
|
-
removedCount
|
|
3853
|
-
};
|
|
3854
|
-
}
|
|
3855
|
-
function prefixFor(kind) {
|
|
3856
|
-
return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
|
|
3733
|
+
function isRunToolName(name) {
|
|
3734
|
+
return name === "execShell" || name === "runCommand" || name === "launchProcess";
|
|
3857
3735
|
}
|
|
3858
|
-
function
|
|
3859
|
-
return
|
|
3736
|
+
function isReadToolName(name) {
|
|
3737
|
+
return name === "readFile";
|
|
3860
3738
|
}
|
|
3861
|
-
function
|
|
3862
|
-
const
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
if (displayWidth(line) <= maxWidth) return line;
|
|
3867
|
-
let width = 0;
|
|
3868
|
-
let kept = "";
|
|
3869
|
-
for (const char of line) {
|
|
3870
|
-
const w = displayWidth(char);
|
|
3871
|
-
if (width + w + 1 > maxWidth) break;
|
|
3872
|
-
kept += char;
|
|
3873
|
-
width += w;
|
|
3874
|
-
}
|
|
3875
|
-
return `${kept}\u2026`;
|
|
3876
|
-
}
|
|
3877
|
-
function windowAndTruncate(lines, maxLines) {
|
|
3878
|
-
if (lines.length <= maxLines) return lines;
|
|
3879
|
-
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
3880
|
-
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
3881
|
-
const half = Math.floor(maxLines / 2);
|
|
3882
|
-
let start = Math.max(0, firstChange - half);
|
|
3883
|
-
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
3884
|
-
const kept = lines.slice(start, start + maxLines);
|
|
3885
|
-
const omitted = lines.length - kept.length;
|
|
3886
|
-
if (omitted > 0) {
|
|
3887
|
-
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
3888
|
-
}
|
|
3889
|
-
return kept;
|
|
3890
|
-
}
|
|
3891
|
-
function isFailedToolResult(event) {
|
|
3892
|
-
const exitCode = event.metadata?.exitCode;
|
|
3893
|
-
if (event.metadata?.actionGate) return false;
|
|
3894
|
-
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3895
|
-
return Boolean(event.metadata?.timedOut);
|
|
3896
|
-
}
|
|
3897
|
-
function isNeedsActionToolResult(event) {
|
|
3898
|
-
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);
|
|
3899
3744
|
}
|
|
3900
3745
|
function parseUiAskChoiceForCli(event) {
|
|
3901
3746
|
if (event.toolName !== "ask_user" && !event.metadata?.uiAskChoice) {
|
|
@@ -4013,7 +3858,10 @@ function renderRunCard(snapshot, opts) {
|
|
|
4013
3858
|
lastToolNames: snapshot.lastToolNames?.map(cleanUserText)
|
|
4014
3859
|
} : snapshot;
|
|
4015
3860
|
const hadError = safe && Boolean(source.errorMessage?.trim());
|
|
4016
|
-
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 };
|
|
4017
3865
|
const body = isAgentRunTerminalStatus(snapshot.status) ? formatFinishedRunCard(name, snapshot.status, {
|
|
4018
3866
|
runId: snapshot.runId,
|
|
4019
3867
|
toolCallCount: source.toolCallCount,
|
|
@@ -4033,8 +3881,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
4033
3881
|
...opts?.includeLogTail !== void 0 ? { includeLogTail: opts.includeLogTail } : {},
|
|
4034
3882
|
labels
|
|
4035
3883
|
});
|
|
4036
|
-
return
|
|
4037
|
-
error ${t("runDiagnosticsHidden")}` : body;
|
|
3884
|
+
return body;
|
|
4038
3885
|
}
|
|
4039
3886
|
function recoverOrchestrationCard(event, toolName, opts) {
|
|
4040
3887
|
const safe = opts?.safe === true;
|
|
@@ -4080,10 +3927,6 @@ function recoverOrchestrationCard(event, toolName, opts) {
|
|
|
4080
3927
|
if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
|
|
4081
3928
|
return renderRunCard(snapshot, opts);
|
|
4082
3929
|
}
|
|
4083
|
-
function parseControlAgentRunStatusEvent(event) {
|
|
4084
|
-
const parsed = parseAgentRunEvent(event);
|
|
4085
|
-
return parsed?.kind === "status" ? parsed.snapshot : null;
|
|
4086
|
-
}
|
|
4087
3930
|
function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
4088
3931
|
const safe = opts?.safe === true;
|
|
4089
3932
|
const rawLabel = toolLabel(toolName);
|
|
@@ -4091,8 +3934,8 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
|
4091
3934
|
const rawDataStr = recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
|
|
4092
3935
|
const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || /^Error:/i.test(rawDataStr.trim());
|
|
4093
3936
|
if (failed) {
|
|
4094
|
-
const firstLine =
|
|
4095
|
-
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);
|
|
4096
3939
|
if (!colorEnabled) {
|
|
4097
3940
|
return `\u2717 ${rawLabel} ${message}
|
|
4098
3941
|
`;
|
|
@@ -4134,7 +3977,7 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4134
3977
|
break;
|
|
4135
3978
|
}
|
|
4136
3979
|
if (/^\s*error\b/i.test(line)) {
|
|
4137
|
-
out.push(
|
|
3980
|
+
out.push(clip(redactSecrets(stripAnsi2(line)), 160));
|
|
4138
3981
|
errorIndent = line.length - line.trimStart().length;
|
|
4139
3982
|
continue;
|
|
4140
3983
|
}
|
|
@@ -4153,59 +3996,207 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4153
3996
|
}
|
|
4154
3997
|
return out;
|
|
4155
3998
|
}
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
logLines: next.logLines ?? previous.logLines,
|
|
4162
|
-
logKey: next.logKey || previous.logKey,
|
|
4163
|
-
toolCallCount: next.toolCallCount ?? previous.toolCallCount,
|
|
4164
|
-
lastToolNames: next.lastToolNames ?? previous.lastToolNames,
|
|
4165
|
-
lastAssistantText: next.lastAssistantText ?? previous.lastAssistantText,
|
|
4166
|
-
startedAt: next.startedAt ?? previous.startedAt,
|
|
4167
|
-
finishedAt: next.finishedAt ?? previous.finishedAt
|
|
4168
|
-
};
|
|
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`;
|
|
4169
4004
|
}
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
metadata: { displayData: body }
|
|
4180
|
-
},
|
|
4181
|
-
"controlAgentRun",
|
|
4182
|
-
colorEnabled
|
|
4183
|
-
);
|
|
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;
|
|
4184
4014
|
}
|
|
4185
|
-
function
|
|
4186
|
-
const
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4015
|
+
function commandFullGist(command, max) {
|
|
4016
|
+
const oneLine = command.replace(/\s+/g, " ").trim();
|
|
4017
|
+
if (!oneLine) return "";
|
|
4018
|
+
return truncateByDisplayWidth(redactSecrets(oneLine), max);
|
|
4019
|
+
}
|
|
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;
|
|
4190
4031
|
}
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
return
|
|
4194
|
-
`[nolo:tool] #${round} !! ${event.toolName}${elapsed2}: ${event.message ?? "failed"}`,
|
|
4195
|
-
colorEnabled,
|
|
4196
|
-
"error"
|
|
4197
|
-
);
|
|
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));
|
|
4198
4035
|
}
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
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;
|
|
4203
4058
|
}
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
);
|
|
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`;
|
|
4209
4200
|
}
|
|
4210
4201
|
function formatNormalToolLine(event, pending, colorEnabled) {
|
|
4211
4202
|
if (event.type === "tool-call") return "";
|
|
@@ -4227,158 +4218,42 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
4227
4218
|
return formatToolTraceLine(`\u25B8 ${label} ! ${t("toolNeedsAction")}`, colorEnabled, "error");
|
|
4228
4219
|
}
|
|
4229
4220
|
if (event.type === "tool-error") {
|
|
4230
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4221
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${toolFailureReason(event) || t("toolFailed")}`, colorEnabled, "error");
|
|
4231
4222
|
}
|
|
4232
4223
|
if (event.metadata?.timedOut) {
|
|
4233
4224
|
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolTimedOut")}`, colorEnabled, "error");
|
|
4234
4225
|
}
|
|
4235
4226
|
if (isFailedToolResult(event)) {
|
|
4236
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4237
|
-
}
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
}
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
const titleText = toolLabel("codeSearch");
|
|
4267
|
-
if (!colorEnabled) {
|
|
4268
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4269
|
-
`;
|
|
4270
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4271
|
-
return `${headerLine2}${treeLines2}
|
|
4272
|
-
`;
|
|
4273
|
-
}
|
|
4274
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4275
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4276
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4277
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4278
|
-
`;
|
|
4279
|
-
const treeLines = lines.map((l) => {
|
|
4280
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4281
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4282
|
-
return `${connector}${queryText}`;
|
|
4283
|
-
}).join("\n");
|
|
4284
|
-
return `${headerLine}${treeLines}
|
|
4285
|
-
`;
|
|
4286
|
-
}
|
|
4287
|
-
function formatReadTreeBlockForCli(items, colorEnabled) {
|
|
4288
|
-
if (items.length === 0) return "";
|
|
4289
|
-
const { count, lines } = formatReadTreeLines(items);
|
|
4290
|
-
const titleText = toolLabel("readFile");
|
|
4291
|
-
if (!colorEnabled) {
|
|
4292
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4293
|
-
`;
|
|
4294
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.pathWithRange}`).join("\n");
|
|
4295
|
-
return `${headerLine2}${treeLines2}
|
|
4296
|
-
`;
|
|
4297
|
-
}
|
|
4298
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4299
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4300
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4301
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4302
|
-
`;
|
|
4303
|
-
const treeLines = lines.map((l) => {
|
|
4304
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4305
|
-
const pathText = themeText(l.pathWithRange, "muted", true);
|
|
4306
|
-
return `${connector}${pathText}`;
|
|
4307
|
-
}).join("\n");
|
|
4308
|
-
return `${headerLine}${treeLines}
|
|
4309
|
-
`;
|
|
4310
|
-
}
|
|
4311
|
-
function formatRunTreeBlockForCli(items, colorEnabled) {
|
|
4312
|
-
if (items.length === 0) return "";
|
|
4313
|
-
const { count, lines } = formatRunTreeLines(items);
|
|
4314
|
-
const titleText = toolLabel("execShell");
|
|
4315
|
-
if (!colorEnabled) {
|
|
4316
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4317
|
-
`;
|
|
4318
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.commandText}`).join("\n");
|
|
4319
|
-
return `${headerLine2}${treeLines2}
|
|
4320
|
-
`;
|
|
4321
|
-
}
|
|
4322
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4323
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4324
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4325
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4326
|
-
`;
|
|
4327
|
-
const treeLines = lines.map((l) => {
|
|
4328
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4329
|
-
const commandText = themeText(l.commandText, "muted", true);
|
|
4330
|
-
return `${connector}${commandText}`;
|
|
4331
|
-
}).join("\n");
|
|
4332
|
-
return `${headerLine}${treeLines}
|
|
4333
|
-
`;
|
|
4334
|
-
}
|
|
4335
|
-
function formatWebSearchTreeBlockForCli(items, colorEnabled) {
|
|
4336
|
-
if (items.length === 0) return "";
|
|
4337
|
-
const { count, lines } = formatSearchTreeLines(items);
|
|
4338
|
-
const titleText = toolLabel("exa_search");
|
|
4339
|
-
if (!colorEnabled) {
|
|
4340
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4341
|
-
`;
|
|
4342
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4343
|
-
return `${headerLine2}${treeLines2}
|
|
4344
|
-
`;
|
|
4345
|
-
}
|
|
4346
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4347
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4348
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4349
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4350
|
-
`;
|
|
4351
|
-
const treeLines = lines.map((l) => {
|
|
4352
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4353
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4354
|
-
return `${connector}${queryText}`;
|
|
4355
|
-
}).join("\n");
|
|
4356
|
-
return `${headerLine}${treeLines}
|
|
4357
|
-
`;
|
|
4358
|
-
}
|
|
4359
|
-
function formatFetchTreeBlockForCli(items, colorEnabled) {
|
|
4360
|
-
if (items.length === 0) return "";
|
|
4361
|
-
const { count, lines } = formatFetchTreeLines(items);
|
|
4362
|
-
const titleText = toolLabel("fetchWebpage");
|
|
4363
|
-
if (!colorEnabled) {
|
|
4364
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4365
|
-
`;
|
|
4366
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.urlText}`).join("\n");
|
|
4367
|
-
return `${headerLine2}${treeLines2}
|
|
4368
|
-
`;
|
|
4369
|
-
}
|
|
4370
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4371
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4372
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4373
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4374
|
-
`;
|
|
4375
|
-
const treeLines = lines.map((l) => {
|
|
4376
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4377
|
-
const urlText = themeText(l.urlText, "muted", true);
|
|
4378
|
-
return `${connector}${urlText}`;
|
|
4379
|
-
}).join("\n");
|
|
4380
|
-
return `${headerLine}${treeLines}
|
|
4381
|
-
`;
|
|
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) : "";
|
|
4382
4257
|
}
|
|
4383
4258
|
function resolveLoadSkillName(event) {
|
|
4384
4259
|
const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
|
|
@@ -4443,326 +4318,63 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
|
|
|
4443
4318
|
return `${star} ${labelPart}: ${namePart}
|
|
4444
4319
|
`;
|
|
4445
4320
|
}
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
if (todoBlock) return todoBlock;
|
|
4450
|
-
if (isReadToolName(toolName) && event.type === "tool-result") {
|
|
4451
|
-
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 || "";
|
|
4452
|
-
return formatReadTreeBlockForCli([{ path: rawPath, metadata: event.metadata }], colorEnabled);
|
|
4453
|
-
}
|
|
4454
|
-
if (isSearchToolName(toolName) && event.type === "tool-result") {
|
|
4455
|
-
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 || "";
|
|
4456
|
-
const rawPath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4457
|
-
return formatSearchTreeBlockForCli([{ query: rawQuery, path: rawPath }], colorEnabled);
|
|
4458
|
-
}
|
|
4459
|
-
if (isFetchToolName(toolName) && event.type === "tool-result") {
|
|
4460
|
-
const rawUrl = (typeof event.metadata?.url === "string" ? event.metadata.url : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4461
|
-
return formatFetchTreeBlockForCli([{ url: rawUrl }], colorEnabled);
|
|
4462
|
-
}
|
|
4463
|
-
if (isRunToolName(toolName) && event.type === "tool-result" && isRunResultFoldable(event)) {
|
|
4464
|
-
const rawCommand = (typeof event.metadata?.command === "string" ? event.metadata.command : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4465
|
-
const exitCode = typeof event.metadata?.exitCode === "number" ? event.metadata.exitCode : void 0;
|
|
4466
|
-
const timedOut = Boolean(event.metadata?.timedOut);
|
|
4467
|
-
return formatRunTreeBlockForCli([{ command: rawCommand, exitCode, timedOut }], colorEnabled);
|
|
4468
|
-
}
|
|
4469
|
-
const rawArgs = clipPathAware(event.argumentsPreview || pending?.argumentsPreview || "", 72);
|
|
4470
|
-
const rawLabel = toolLabel(toolName);
|
|
4471
|
-
const label = rawArgs ? `${rawLabel} ${rawArgs}` : rawLabel;
|
|
4472
|
-
if (event.type === "tool-error") {
|
|
4473
|
-
const message = clip(event.message ?? t("toolFailed"), 96);
|
|
4474
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${message}`, colorEnabled, "error");
|
|
4475
|
-
}
|
|
4476
|
-
const loadSkillBlock = formatLoadSkillBlock(event, colorEnabled);
|
|
4477
|
-
if (loadSkillBlock) return loadSkillBlock;
|
|
4478
|
-
if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
|
|
4479
|
-
return formatOrchestrationCardBlock(event, toolName, colorEnabled);
|
|
4480
|
-
}
|
|
4481
|
-
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
4482
|
-
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
4483
|
-
if (block) return block;
|
|
4484
|
-
}
|
|
4485
|
-
const hint = compactResultHint(event);
|
|
4486
|
-
const suffix = hint.inline ? ` ${hint.inline}` : "";
|
|
4487
|
-
const failed = isFailedToolResult(event);
|
|
4488
|
-
const marker = failed ? "\u2717" : isNeedsActionToolResult(event) ? "!" : "\u2713";
|
|
4489
|
-
let mainLine;
|
|
4490
|
-
if (!colorEnabled) {
|
|
4491
|
-
mainLine = `\u25B8 ${label} ${marker}${suffix}
|
|
4492
|
-
`;
|
|
4493
|
-
} else {
|
|
4494
|
-
const chromePointer = themeText("\u25B8", "chrome", true);
|
|
4495
|
-
const mutedLabel = themeText(rawLabel, "muted", true);
|
|
4496
|
-
const argsPart = rawArgs ? ` ${dimCliText(rawArgs, true)}` : "";
|
|
4497
|
-
const statusToken = failed ? themeText("\u2717", "danger", true) : isNeedsActionToolResult(event) ? themeText("!", "warning", true) : themeText("\u2713", "success", true);
|
|
4498
|
-
const suffixPart = hint.inline ? ` ${dimCliText(hint.inline, true)}` : "";
|
|
4499
|
-
mainLine = `${chromePointer} ${mutedLabel}${argsPart} ${statusToken}${suffixPart}
|
|
4500
|
-
`;
|
|
4501
|
-
}
|
|
4502
|
-
if (!hint.detail?.length) return mainLine;
|
|
4503
|
-
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : event.argumentsPreview;
|
|
4504
|
-
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4505
|
-
}
|
|
4506
|
-
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4507
|
-
if (!colorEnabled) {
|
|
4508
|
-
return lines.map((line) => ` ${line.text}
|
|
4509
|
-
`).join("");
|
|
4510
|
-
}
|
|
4511
|
-
const isTruecolor = supportsTruecolor(env);
|
|
4512
|
-
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4513
|
-
const brightness = resolveTuiBrightness(env);
|
|
4514
|
-
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4515
|
-
return lines.map((line) => ` ${renderDiffLine({
|
|
4516
|
-
kind: line.kind,
|
|
4517
|
-
text: line.text,
|
|
4518
|
-
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4519
|
-
padTo,
|
|
4520
|
-
colorEnabled: true,
|
|
4521
|
-
env
|
|
4522
|
-
})}
|
|
4523
|
-
`).join("");
|
|
4524
|
-
}
|
|
4525
|
-
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4526
|
-
if (!isTruecolor || lang === "unknown") return false;
|
|
4527
|
-
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4528
|
-
return line.text.length >= 2;
|
|
4529
|
-
}
|
|
4530
|
-
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4531
|
-
const prefix = line.text.slice(0, 2);
|
|
4532
|
-
const body = line.text.slice(2);
|
|
4533
|
-
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4534
|
-
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4535
|
-
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4536
|
-
return `${coloredPrefix}${highlightedBody}`;
|
|
4537
|
-
}
|
|
4538
|
-
function createToolEventFormatter(mode, colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4539
|
-
const suppressRunProgressCards = opts.suppressRunProgressCards === true;
|
|
4321
|
+
var TUI_TREE_MARKER = "TUI_TREE\n";
|
|
4322
|
+
var TUI_TREE_END = "";
|
|
4323
|
+
function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4540
4324
|
const pending = /* @__PURE__ */ new Map();
|
|
4541
|
-
let
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
const lastPrintedCardByRunId = /* @__PURE__ */ new Map();
|
|
4549
|
-
const cardSubstance = (snapshot) => JSON.stringify([
|
|
4550
|
-
snapshot.status,
|
|
4551
|
-
snapshot.toolCallCount ?? -1,
|
|
4552
|
-
snapshot.lastToolNames ?? [],
|
|
4553
|
-
snapshot.lastAssistantText ?? "",
|
|
4554
|
-
snapshot.errorMessage ?? "",
|
|
4555
|
-
snapshot.logKey
|
|
4556
|
-
]);
|
|
4557
|
-
const flushStatusFold = () => {
|
|
4558
|
-
if (!statusFold) return "";
|
|
4559
|
-
const fold = statusFold;
|
|
4560
|
-
statusFold = null;
|
|
4561
|
-
const substance = cardSubstance(fold);
|
|
4562
|
-
if (lastPrintedCardByRunId.get(fold.runId) === substance) return "";
|
|
4563
|
-
const prevLog = lastEmittedLogByRunId.get(fold.runId);
|
|
4564
|
-
const changed = Boolean(fold.logKey) && fold.logKey !== prevLog;
|
|
4565
|
-
if (suppressRunProgressCards) {
|
|
4566
|
-
const terminal = isAgentRunTerminalStatus(fold.status);
|
|
4567
|
-
if (!terminal && !fold.errorMessage && !changed) {
|
|
4568
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4569
|
-
return "";
|
|
4570
|
-
}
|
|
4571
|
-
}
|
|
4572
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4573
|
-
if (changed && runShowsLogTail(fold.status)) {
|
|
4574
|
-
lastEmittedLogByRunId.set(fold.runId, fold.logKey);
|
|
4575
|
-
}
|
|
4576
|
-
return formatFoldedControlStatusCard({ ...fold, includeLogTail: changed }, colorEnabled);
|
|
4577
|
-
};
|
|
4578
|
-
const flushToolBuffers = () => {
|
|
4579
|
-
let out = "";
|
|
4580
|
-
if (readBuffer.length > 0) {
|
|
4581
|
-
const items = readBuffer.map((evt) => {
|
|
4582
|
-
const call = pending.get(evt.toolCallId);
|
|
4583
|
-
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 || "";
|
|
4584
|
-
return { path: rawPath, metadata: evt.metadata };
|
|
4585
|
-
});
|
|
4586
|
-
for (const evt of readBuffer) pending.delete(evt.toolCallId);
|
|
4587
|
-
readBuffer = [];
|
|
4588
|
-
out += formatReadTreeBlockForCli(items, colorEnabled);
|
|
4589
|
-
}
|
|
4590
|
-
if (searchBuffer.length > 0) {
|
|
4591
|
-
const items = searchBuffer.map((evt) => {
|
|
4592
|
-
const call = pending.get(evt.toolCallId);
|
|
4593
|
-
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 || "";
|
|
4594
|
-
const rawPath = typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0;
|
|
4595
|
-
return { query: rawQuery, path: rawPath };
|
|
4596
|
-
});
|
|
4597
|
-
for (const evt of searchBuffer) pending.delete(evt.toolCallId);
|
|
4598
|
-
searchBuffer = [];
|
|
4599
|
-
out += formatSearchTreeBlockForCli(items, colorEnabled);
|
|
4600
|
-
}
|
|
4601
|
-
if (runBuffer.length > 0) {
|
|
4602
|
-
const items = runBuffer.map((evt) => {
|
|
4603
|
-
const call = pending.get(evt.toolCallId);
|
|
4604
|
-
const rawCommand = (typeof evt.metadata?.command === "string" ? evt.metadata.command : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4605
|
-
const exitCode = typeof evt.metadata?.exitCode === "number" ? evt.metadata.exitCode : void 0;
|
|
4606
|
-
const timedOut = Boolean(evt.metadata?.timedOut);
|
|
4607
|
-
return { command: rawCommand, exitCode, timedOut };
|
|
4608
|
-
});
|
|
4609
|
-
for (const evt of runBuffer) pending.delete(evt.toolCallId);
|
|
4610
|
-
runBuffer = [];
|
|
4611
|
-
out += formatRunTreeBlockForCli(items, colorEnabled);
|
|
4612
|
-
}
|
|
4613
|
-
if (fetchBuffer.length > 0) {
|
|
4614
|
-
const items = fetchBuffer.map((evt) => {
|
|
4615
|
-
const call = pending.get(evt.toolCallId);
|
|
4616
|
-
const rawUrl = (typeof evt.metadata?.url === "string" ? evt.metadata.url : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4617
|
-
return { url: rawUrl };
|
|
4618
|
-
});
|
|
4619
|
-
for (const evt of fetchBuffer) pending.delete(evt.toolCallId);
|
|
4620
|
-
fetchBuffer = [];
|
|
4621
|
-
out += formatFetchTreeBlockForCli(items, colorEnabled);
|
|
4622
|
-
}
|
|
4623
|
-
if (webSearchBuffer.length > 0) {
|
|
4624
|
-
const items = webSearchBuffer.map((evt) => {
|
|
4625
|
-
const call = pending.get(evt.toolCallId);
|
|
4626
|
-
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 || "";
|
|
4627
|
-
return { query: rawQuery };
|
|
4628
|
-
});
|
|
4629
|
-
for (const evt of webSearchBuffer) pending.delete(evt.toolCallId);
|
|
4630
|
-
webSearchBuffer = [];
|
|
4631
|
-
out += formatWebSearchTreeBlockForCli(items, colorEnabled);
|
|
4632
|
-
}
|
|
4633
|
-
return out;
|
|
4634
|
-
};
|
|
4635
|
-
const flushBuffers = () => `${flushStatusFold()}${flushToolBuffers()}`;
|
|
4636
|
-
const bufferToolResult = (buffer, event) => {
|
|
4637
|
-
const flushed = flushStatusFold();
|
|
4638
|
-
buffer.push(event);
|
|
4639
|
-
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
|
+
`;
|
|
4640
4332
|
};
|
|
4641
|
-
const
|
|
4642
|
-
if (
|
|
4643
|
-
if (
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
pending.set(event.toolCallId, {
|
|
4647
|
-
toolName: event.toolName,
|
|
4648
|
-
argumentsPreview: event.argumentsPreview
|
|
4649
|
-
});
|
|
4650
|
-
return "";
|
|
4651
|
-
}
|
|
4652
|
-
const call2 = pending.get(event.toolCallId);
|
|
4653
|
-
pending.delete(event.toolCallId);
|
|
4654
|
-
return formatNormalToolLine(event, call2, colorEnabled);
|
|
4655
|
-
}
|
|
4656
|
-
if (event.toolName === "controlAgentRun") {
|
|
4657
|
-
if (event.type === "tool-call") {
|
|
4658
|
-
pending.set(event.toolCallId, {
|
|
4659
|
-
toolName: event.toolName,
|
|
4660
|
-
argumentsPreview: event.argumentsPreview
|
|
4661
|
-
});
|
|
4662
|
-
return "";
|
|
4663
|
-
}
|
|
4664
|
-
if (event.type === "tool-result") {
|
|
4665
|
-
const snapshot = parseControlAgentRunStatusEvent(event);
|
|
4666
|
-
if (snapshot) {
|
|
4667
|
-
let out = flushToolBuffers();
|
|
4668
|
-
const open = statusFold;
|
|
4669
|
-
const sameRun = open?.runId === snapshot.runId;
|
|
4670
|
-
if (open && (!sameRun || open.status !== snapshot.status)) {
|
|
4671
|
-
out += flushStatusFold();
|
|
4672
|
-
}
|
|
4673
|
-
statusFold = open && sameRun ? mergeRunSnapshot(open, snapshot) : snapshot;
|
|
4674
|
-
pending.delete(event.toolCallId);
|
|
4675
|
-
if (isAgentRunTerminalStatus(snapshot.status)) {
|
|
4676
|
-
out += flushBuffers();
|
|
4677
|
-
}
|
|
4678
|
-
return out;
|
|
4679
|
-
}
|
|
4680
|
-
const flushed2 = flushBuffers();
|
|
4681
|
-
const call2 = pending.get(event.toolCallId);
|
|
4682
|
-
pending.delete(event.toolCallId);
|
|
4683
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4684
|
-
}
|
|
4685
|
-
}
|
|
4686
|
-
if (isReadToolName(event.toolName)) {
|
|
4687
|
-
if (event.type === "tool-call") {
|
|
4688
|
-
pending.set(event.toolCallId, {
|
|
4689
|
-
toolName: event.toolName,
|
|
4690
|
-
argumentsPreview: event.argumentsPreview
|
|
4691
|
-
});
|
|
4692
|
-
return "";
|
|
4693
|
-
}
|
|
4694
|
-
if (event.type === "tool-result") {
|
|
4695
|
-
return bufferToolResult(readBuffer, event);
|
|
4696
|
-
}
|
|
4697
|
-
}
|
|
4698
|
-
if (isSearchToolName(event.toolName)) {
|
|
4699
|
-
if (event.type === "tool-call") {
|
|
4700
|
-
pending.set(event.toolCallId, {
|
|
4701
|
-
toolName: event.toolName,
|
|
4702
|
-
argumentsPreview: event.argumentsPreview
|
|
4703
|
-
});
|
|
4704
|
-
return "";
|
|
4705
|
-
}
|
|
4706
|
-
if (event.type === "tool-result") {
|
|
4707
|
-
return bufferToolResult(searchBuffer, event);
|
|
4708
|
-
}
|
|
4709
|
-
}
|
|
4710
|
-
if (isRunToolName(event.toolName)) {
|
|
4711
|
-
if (event.type === "tool-result" && !isRunResultFoldable(event)) {
|
|
4712
|
-
const flushed2 = flushBuffers();
|
|
4713
|
-
const call2 = pending.get(event.toolCallId);
|
|
4714
|
-
pending.delete(event.toolCallId);
|
|
4715
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4716
|
-
}
|
|
4717
|
-
if (event.type === "tool-call") {
|
|
4718
|
-
pending.set(event.toolCallId, {
|
|
4719
|
-
toolName: event.toolName,
|
|
4720
|
-
argumentsPreview: event.argumentsPreview
|
|
4721
|
-
});
|
|
4722
|
-
return "";
|
|
4723
|
-
}
|
|
4724
|
-
if (event.type === "tool-result") {
|
|
4725
|
-
return bufferToolResult(runBuffer, event);
|
|
4726
|
-
}
|
|
4727
|
-
}
|
|
4728
|
-
if (isFetchToolName(event.toolName)) {
|
|
4729
|
-
if (event.type === "tool-call") {
|
|
4730
|
-
pending.set(event.toolCallId, {
|
|
4731
|
-
toolName: event.toolName,
|
|
4732
|
-
argumentsPreview: event.argumentsPreview
|
|
4733
|
-
});
|
|
4734
|
-
return "";
|
|
4735
|
-
}
|
|
4736
|
-
if (event.type === "tool-result") {
|
|
4737
|
-
return bufferToolResult(fetchBuffer, event);
|
|
4738
|
-
}
|
|
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;
|
|
4739
4338
|
}
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
});
|
|
4746
|
-
return "";
|
|
4747
|
-
}
|
|
4748
|
-
if (event.type === "tool-result") {
|
|
4749
|
-
return bufferToolResult(webSearchBuffer, event);
|
|
4750
|
-
}
|
|
4339
|
+
const name = event.toolName || call?.toolName || "tool";
|
|
4340
|
+
const kind = treeKind(name);
|
|
4341
|
+
if (!kind) {
|
|
4342
|
+
tree = null;
|
|
4343
|
+
return null;
|
|
4751
4344
|
}
|
|
4752
|
-
|
|
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) => {
|
|
4753
4361
|
if (event.type === "tool-call") {
|
|
4754
4362
|
pending.set(event.toolCallId, {
|
|
4755
4363
|
toolName: event.toolName,
|
|
4756
4364
|
argumentsPreview: event.argumentsPreview
|
|
4757
4365
|
});
|
|
4758
|
-
return
|
|
4366
|
+
return "";
|
|
4759
4367
|
}
|
|
4760
4368
|
const call = pending.get(event.toolCallId);
|
|
4761
4369
|
pending.delete(event.toolCallId);
|
|
4762
|
-
|
|
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;
|
|
4763
4376
|
};
|
|
4764
|
-
|
|
4765
|
-
return formatter;
|
|
4377
|
+
return format;
|
|
4766
4378
|
}
|
|
4767
4379
|
function createSseToolEventAdapter(onEvent) {
|
|
4768
4380
|
let round = 0;
|
|
@@ -4923,7 +4535,7 @@ ${this.text}
|
|
|
4923
4535
|
0,
|
|
4924
4536
|
Math.floor((Date.now() - this.startTime) / 1e3)
|
|
4925
4537
|
);
|
|
4926
|
-
const thinkingPart = this.thinkingHint ? `: ${truncateThinkingHint(this.thinkingHint, 60)}` : "";
|
|
4538
|
+
const thinkingPart = this.thinkingHint ? dimCliText(`: ${truncateThinkingHint(this.thinkingHint, 60)}`) : "";
|
|
4927
4539
|
return `${themeColorSequence("accent")}${frame}\x1B[39m ${this.text}${thinkingPart} (${formatElapsed(elapsedSeconds)})`;
|
|
4928
4540
|
}
|
|
4929
4541
|
};
|
|
@@ -4980,10 +4592,8 @@ function createCliTurnOutput(params) {
|
|
|
4980
4592
|
const { options } = params;
|
|
4981
4593
|
const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
|
|
4982
4594
|
const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
|
|
4983
|
-
const
|
|
4984
|
-
|
|
4985
|
-
const formatToolEvent = createToolEventFormatter(toolDisplayMode, void 0, {
|
|
4986
|
-
suppressRunProgressCards: typeof options.onAgentRunStatus === "function"
|
|
4595
|
+
const formatToolEvent = createToolEventFormatter(void 0, {
|
|
4596
|
+
tuiTrees: options.output.tuiTrees === true
|
|
4987
4597
|
});
|
|
4988
4598
|
const eventMode = resolveAgentEventMode(options);
|
|
4989
4599
|
const showThinking = options.showThinking !== false;
|
|
@@ -4991,12 +4601,27 @@ function createCliTurnOutput(params) {
|
|
|
4991
4601
|
let everStreamedAnyText = false;
|
|
4992
4602
|
let printedAssistantLabel = false;
|
|
4993
4603
|
let thinkState = createThinkParserState();
|
|
4604
|
+
let thinkingFirstAt = null;
|
|
4605
|
+
let thinkingLastAt = 0;
|
|
4606
|
+
const markThinkingActivity = () => {
|
|
4607
|
+
const now = Date.now();
|
|
4608
|
+
if (thinkingFirstAt === null) thinkingFirstAt = now;
|
|
4609
|
+
thinkingLastAt = now;
|
|
4610
|
+
};
|
|
4611
|
+
const writeThinkingTrace = () => {
|
|
4612
|
+
if (thinkingFirstAt === null) return;
|
|
4613
|
+
const seconds = Math.max(0, Math.round((thinkingLastAt - thinkingFirstAt) / 1e3));
|
|
4614
|
+
thinkingFirstAt = null;
|
|
4615
|
+
if (seconds < 1) return;
|
|
4616
|
+
options.output.write(`${dimCliText(t("thinkingTraceLine", formatElapsed(seconds)))}
|
|
4617
|
+
`);
|
|
4618
|
+
};
|
|
4994
4619
|
let compactionEvent = null;
|
|
4995
4620
|
const assistantLabelManaged = options.output.assistantLabelManaged === true;
|
|
4996
4621
|
const writeToolOutput = (chunk) => {
|
|
4997
4622
|
if (!chunk) return;
|
|
4998
4623
|
if (typeof options.output.writeToolBlock === "function") {
|
|
4999
|
-
options.output.writeToolBlock(chunk);
|
|
4624
|
+
if (!options.output.writeToolBlock(chunk)) formatToolEvent.reset?.();
|
|
5000
4625
|
} else {
|
|
5001
4626
|
options.output.write(chunk);
|
|
5002
4627
|
}
|
|
@@ -5006,13 +4631,16 @@ function createCliTurnOutput(params) {
|
|
|
5006
4631
|
});
|
|
5007
4632
|
const writeVisibleAssistantChunk = (chunk) => {
|
|
5008
4633
|
if (!chunk) return;
|
|
4634
|
+
formatToolEvent.reset?.();
|
|
5009
4635
|
const parsed = processThinkChunk(chunk, thinkState);
|
|
5010
4636
|
thinkState = parsed.state;
|
|
5011
4637
|
if (!parsed.content && !parsed.reasoning) return;
|
|
5012
4638
|
if (showThinking && parsed.reasoning) {
|
|
4639
|
+
markThinkingActivity();
|
|
5013
4640
|
spinner.setThinkingHint(parsed.reasoning);
|
|
5014
4641
|
}
|
|
5015
4642
|
if (!parsed.content) return;
|
|
4643
|
+
writeThinkingTrace();
|
|
5016
4644
|
spinner.stop();
|
|
5017
4645
|
options.activityReporter?.(null);
|
|
5018
4646
|
if (!printedAssistantLabel) {
|
|
@@ -5027,7 +4655,6 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5027
4655
|
renderWriter.push(parsed.content);
|
|
5028
4656
|
};
|
|
5029
4657
|
const handleToolEvent = (event) => {
|
|
5030
|
-
if (!traceLocalTools) return;
|
|
5031
4658
|
const chunk = eventMode === "jsonl" ? formatToolJsonEvent(event) : formatToolEvent(event);
|
|
5032
4659
|
if (eventMode === "jsonl") {
|
|
5033
4660
|
options.output.write(chunk);
|
|
@@ -5045,8 +4672,8 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5045
4672
|
if (chunk) {
|
|
5046
4673
|
writeToolOutput(chunk);
|
|
5047
4674
|
}
|
|
5048
|
-
if (
|
|
5049
|
-
const activeLabel =
|
|
4675
|
+
if (event.type === "tool-call") {
|
|
4676
|
+
const activeLabel = formatConservativeActiveToolLabel(event);
|
|
5050
4677
|
spinner.show(activeLabel);
|
|
5051
4678
|
options.activityReporter?.(activeLabel);
|
|
5052
4679
|
}
|
|
@@ -5059,20 +4686,15 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5059
4686
|
};
|
|
5060
4687
|
return {
|
|
5061
4688
|
spinner,
|
|
5062
|
-
toolDisplayMode,
|
|
5063
|
-
traceLocalTools,
|
|
5064
4689
|
eventMode,
|
|
5065
4690
|
pushText(chunk) {
|
|
5066
|
-
if (eventMode !== "jsonl" && formatToolEvent.flush) {
|
|
5067
|
-
const pendingToolOutput = formatToolEvent.flush();
|
|
5068
|
-
if (pendingToolOutput) {
|
|
5069
|
-
writeToolOutput(pendingToolOutput);
|
|
5070
|
-
}
|
|
5071
|
-
}
|
|
5072
4691
|
writeVisibleAssistantChunk(chunk);
|
|
5073
4692
|
},
|
|
5074
4693
|
pushThinking(chunk) {
|
|
5075
|
-
if (showThinking)
|
|
4694
|
+
if (showThinking) {
|
|
4695
|
+
markThinkingActivity();
|
|
4696
|
+
spinner.setThinkingHint(chunk);
|
|
4697
|
+
}
|
|
5076
4698
|
},
|
|
5077
4699
|
handleToolEvent,
|
|
5078
4700
|
/** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
|
|
@@ -5087,15 +4709,12 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5087
4709
|
finish(fallbackContent) {
|
|
5088
4710
|
spinner.stop();
|
|
5089
4711
|
options.activityReporter?.(null);
|
|
4712
|
+
writeThinkingTrace();
|
|
5090
4713
|
const flushedThink = flushThinkParser(thinkState);
|
|
5091
4714
|
thinkState = flushedThink.state;
|
|
5092
4715
|
if (flushedThink.content) {
|
|
5093
4716
|
writeVisibleAssistantChunk(flushedThink.content);
|
|
5094
4717
|
}
|
|
5095
|
-
const pendingToolOutput = formatToolEvent.flush ? formatToolEvent.flush() : "";
|
|
5096
|
-
if (pendingToolOutput) {
|
|
5097
|
-
writeToolOutput(pendingToolOutput);
|
|
5098
|
-
}
|
|
5099
4718
|
if (streamedAssistantText) {
|
|
5100
4719
|
renderWriter.flush();
|
|
5101
4720
|
options.output.write("\n");
|
|
@@ -5296,10 +4915,12 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
5296
4915
|
if (usageText && shouldShowUsage(options.env))
|
|
5297
4916
|
options.output.write(`${usageText}
|
|
5298
4917
|
`);
|
|
4918
|
+
const turnCredits = platformCreditsFromUsage(usage);
|
|
5299
4919
|
return {
|
|
5300
4920
|
exitCode: 0,
|
|
5301
4921
|
...dialogId ? { dialogId } : {},
|
|
5302
|
-
turnTokens: buildTurnTokenUsage(usage, options.agentKey)
|
|
4922
|
+
turnTokens: buildTurnTokenUsage(usage, options.agentKey),
|
|
4923
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
5303
4924
|
};
|
|
5304
4925
|
}
|
|
5305
4926
|
|
|
@@ -5307,6 +4928,10 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
5307
4928
|
function resolveAuthToken2(env) {
|
|
5308
4929
|
return resolvePlatformAuthToken(env);
|
|
5309
4930
|
}
|
|
4931
|
+
function resolveFileWriteGateEnabled(env) {
|
|
4932
|
+
const raw = (env.NOLO_CLI_WRITE_GATE ?? "").trim().toLowerCase();
|
|
4933
|
+
return raw !== "off" && raw !== "0" && raw !== "false";
|
|
4934
|
+
}
|
|
5310
4935
|
function isMachineBoundLocalhostCustomProvider(agentConfig) {
|
|
5311
4936
|
const machineId = agentConfig?.runtimeBinding && typeof agentConfig.runtimeBinding === "object" ? String(agentConfig.runtimeBinding.machineId ?? "").trim() : "";
|
|
5312
4937
|
const providerUrl = asTrimmedString(agentConfig?.customProviderUrl);
|
|
@@ -5398,7 +5023,16 @@ function isKnownServerPlatformAgent(options) {
|
|
|
5398
5023
|
// packages/core/collapsedPaste.ts
|
|
5399
5024
|
var COLLAPSE_PASTE_MIN_LINES = 8;
|
|
5400
5025
|
var COLLAPSE_PASTE_MIN_CHARS = 400;
|
|
5401
|
-
var COLLAPSED_PASTE_PLACEHOLDER_RE =
|
|
5026
|
+
var COLLAPSED_PASTE_PLACEHOLDER_RE = (
|
|
5027
|
+
// 兼容两种格式:旧 `[paste #N · L lines]` 与新 `[paste #N · L lines · preview]`。
|
|
5028
|
+
// preview 段用负向先行断言排除模型引用(`…; full content available via
|
|
5029
|
+
// readPastedText(pasteId=N)`):legacy 无 scope 的模型引用与新 chip 形状重叠,
|
|
5030
|
+
// 若被当作 chip 匹配,跨会话残留的引用会被错误展开/替换(破坏 durable
|
|
5031
|
+
// fallback 语义)。preview 与模型引用尾段在生成时都不会包含该标记原文之外
|
|
5032
|
+
// 的歧义,此处按"完整模型引用尾段"精确排除。
|
|
5033
|
+
/\[paste #(\d+) · (\d+) lines(?: · (?![^\]]*; full content available via readPastedText\(pasteId=\d+\))([^\]]*))?\]/g
|
|
5034
|
+
);
|
|
5035
|
+
var COLLAPSED_PASTE_PREVIEW_MAX_CHARS = 24;
|
|
5402
5036
|
var COLLAPSED_PASTE_MODEL_REFERENCE_RE = /\[paste #(\d+)(?: scope:([a-zA-Z0-9_-]+))? · [^\]]+; full content available via readPastedText\(pasteId=(\d+)\)\]/g;
|
|
5403
5037
|
function countTextLines(text) {
|
|
5404
5038
|
if (text.length === 0) return 0;
|
|
@@ -5438,9 +5072,22 @@ function estimatePasteBytes(text) {
|
|
|
5438
5072
|
}
|
|
5439
5073
|
return bytes;
|
|
5440
5074
|
}
|
|
5075
|
+
function buildCollapsedPastePreview(text) {
|
|
5076
|
+
const firstNonEmptyLine = text.split(/\r\n|\r|\n/).find((line) => line.trim().length > 0) ?? "";
|
|
5077
|
+
let preview = compactWhitespace(firstNonEmptyLine);
|
|
5078
|
+
preview = preview.replace(new RegExp("\\]|\\p{C}", "gu"), "").trim();
|
|
5079
|
+
if (preview.length === 0) return "";
|
|
5080
|
+
const chars = Array.from(preview);
|
|
5081
|
+
if (chars.length > COLLAPSED_PASTE_PREVIEW_MAX_CHARS) {
|
|
5082
|
+
return chars.slice(0, COLLAPSED_PASTE_PREVIEW_MAX_CHARS).join("") + "\u2026";
|
|
5083
|
+
}
|
|
5084
|
+
return preview;
|
|
5085
|
+
}
|
|
5441
5086
|
function formatCollapsedPastePlaceholder(id, text) {
|
|
5442
5087
|
const lines = countTextLines(text);
|
|
5443
|
-
|
|
5088
|
+
const preview = buildCollapsedPastePreview(text);
|
|
5089
|
+
if (!preview) return `[paste #${id} \xB7 ${lines} lines]`;
|
|
5090
|
+
return `[paste #${id} \xB7 ${lines} lines \xB7 ${preview}]`;
|
|
5444
5091
|
}
|
|
5445
5092
|
function generatePasteScope() {
|
|
5446
5093
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -5553,10 +5200,14 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
|
|
|
5553
5200
|
// packages/cli/client/agentRun.ts
|
|
5554
5201
|
import { ulid } from "ulid";
|
|
5555
5202
|
async function loadRunLocalAgentTurn() {
|
|
5556
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
5203
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-K327ELSL.js");
|
|
5557
5204
|
return runLocalAgentTurn;
|
|
5558
5205
|
}
|
|
5559
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
|
+
});
|
|
5560
5211
|
function extractEmbeddedErrorMessage(message) {
|
|
5561
5212
|
const match = /"message"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(message);
|
|
5562
5213
|
if (!match) return void 0;
|
|
@@ -6094,13 +5745,17 @@ ${options.agentName} > (no text response)
|
|
|
6094
5745
|
const usage = formatUsage(data?.usage, data?.dialogId);
|
|
6095
5746
|
if (usage && shouldShowUsage(options.env)) options.output.write(`${usage}
|
|
6096
5747
|
`);
|
|
5748
|
+
const turnCredits = platformCreditsFromUsage(
|
|
5749
|
+
data?.usage
|
|
5750
|
+
);
|
|
6097
5751
|
return {
|
|
6098
5752
|
exitCode: 0,
|
|
6099
5753
|
...typeof data?.dialogId === "string" && data.dialogId ? { dialogId: data.dialogId } : {},
|
|
6100
5754
|
turnTokens: buildTurnTokenUsage(
|
|
6101
5755
|
data?.usage,
|
|
6102
5756
|
typeof data?.model === "string" ? data.model : options.agentKey
|
|
6103
|
-
)
|
|
5757
|
+
),
|
|
5758
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
6104
5759
|
};
|
|
6105
5760
|
}
|
|
6106
5761
|
async function runInjectedLocalAgentTurn(options) {
|
|
@@ -6179,6 +5834,7 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6179
5834
|
} : {},
|
|
6180
5835
|
continueDialogId: currentDialogId,
|
|
6181
5836
|
fileWriteSessionId: currentDialogId,
|
|
5837
|
+
fileWriteGateEnabled: resolveFileWriteGateEnabled(options.env),
|
|
6182
5838
|
spaceId: options.spaceId,
|
|
6183
5839
|
category: options.category,
|
|
6184
5840
|
inheritedFromDialogKey: options.inheritedFromDialogKey,
|
|
@@ -6204,11 +5860,13 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6204
5860
|
options.onLoopEvent?.(event);
|
|
6205
5861
|
},
|
|
6206
5862
|
...options.abortSignal ? { abortSignal: options.abortSignal } : {},
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
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
|
+
},
|
|
6212
5870
|
...!options.noStream ? {
|
|
6213
5871
|
onTextDelta: (chunk) => {
|
|
6214
5872
|
turnOutput.pushText(chunk);
|
|
@@ -6219,24 +5877,35 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6219
5877
|
} : {}
|
|
6220
5878
|
});
|
|
6221
5879
|
turnOutput.finish(result.content);
|
|
5880
|
+
const turnCredits = sumPlatformCredits(result.usageRecords);
|
|
6222
5881
|
return {
|
|
6223
5882
|
exitCode: 0,
|
|
6224
5883
|
dialogId: result.dialogId,
|
|
6225
5884
|
title: result.title,
|
|
6226
5885
|
...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
|
|
6227
|
-
...result
|
|
6228
|
-
|
|
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 } : {}
|
|
6229
5894
|
};
|
|
6230
5895
|
} catch (error) {
|
|
6231
5896
|
turnOutput.spinner.stop();
|
|
6232
5897
|
const savedDialogId = error?.dialogId;
|
|
5898
|
+
const abortedUsageRecords = error?.usageRecords;
|
|
5899
|
+
const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
|
|
6233
5900
|
if (error?.code === LOCAL_TURN_ABORTED_CODE || options.abortSignal?.aborted) {
|
|
6234
5901
|
const pendingToolName = error?.pendingToolName;
|
|
6235
5902
|
return {
|
|
6236
5903
|
exitCode: 0,
|
|
6237
5904
|
streamInterrupted: true,
|
|
6238
5905
|
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
6239
|
-
...pendingToolName ? { pendingToolName } : {}
|
|
5906
|
+
...pendingToolName ? { pendingToolName } : {},
|
|
5907
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5908
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6240
5909
|
};
|
|
6241
5910
|
}
|
|
6242
5911
|
const cooldownUntil = await markStartupRateLimitCooldown(
|
|
@@ -6262,10 +5931,70 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6262
5931
|
return {
|
|
6263
5932
|
exitCode: 1,
|
|
6264
5933
|
localError: error,
|
|
6265
|
-
...savedDialogId ? { dialogId: savedDialogId } : {}
|
|
5934
|
+
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
5935
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5936
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6266
5937
|
};
|
|
6267
5938
|
}
|
|
6268
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
|
+
}
|
|
6269
5998
|
async function runAgentTurn(options) {
|
|
6270
5999
|
const authToken = resolveAuthToken2(options.env);
|
|
6271
6000
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
@@ -6279,15 +6008,7 @@ async function runAgentTurn(options) {
|
|
|
6279
6008
|
reportFailure: false
|
|
6280
6009
|
});
|
|
6281
6010
|
if (localResult.exitCode === 0) {
|
|
6282
|
-
return
|
|
6283
|
-
exitCode: localResult.exitCode,
|
|
6284
|
-
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6285
|
-
title: localResult.title,
|
|
6286
|
-
...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
|
|
6287
|
-
...localResult.turnTokens ? { turnTokens: localResult.turnTokens } : {},
|
|
6288
|
-
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
6289
|
-
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
6290
|
-
};
|
|
6011
|
+
return foldLocalResultForTui(localResult);
|
|
6291
6012
|
}
|
|
6292
6013
|
if (isMissingLocalAgentConfigError(localResult.localError, options.agentKey)) {
|
|
6293
6014
|
options.output.write(
|
|
@@ -6301,13 +6022,7 @@ async function runAgentTurn(options) {
|
|
|
6301
6022
|
reportFailure: false
|
|
6302
6023
|
});
|
|
6303
6024
|
if (retriedLocalResult.exitCode === 0) {
|
|
6304
|
-
return
|
|
6305
|
-
exitCode: retriedLocalResult.exitCode,
|
|
6306
|
-
...retriedLocalResult.dialogId ? { dialogId: retriedLocalResult.dialogId } : {},
|
|
6307
|
-
title: retriedLocalResult.title,
|
|
6308
|
-
...retriedLocalResult.titlePatchPromise ? { titlePatchPromise: retriedLocalResult.titlePatchPromise } : {},
|
|
6309
|
-
...retriedLocalResult.turnTokens ? { turnTokens: retriedLocalResult.turnTokens } : {}
|
|
6310
|
-
};
|
|
6025
|
+
return foldLocalResultForTui(retriedLocalResult);
|
|
6311
6026
|
}
|
|
6312
6027
|
}
|
|
6313
6028
|
} catch {
|
|
@@ -6320,7 +6035,11 @@ async function runAgentTurn(options) {
|
|
|
6320
6035
|
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6321
6036
|
// Keep localError so TUI can show balance/quota/dialog-preserved hints
|
|
6322
6037
|
// instead of only the raw auto-runtime line.
|
|
6323
|
-
...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 } : {}
|
|
6324
6043
|
};
|
|
6325
6044
|
}
|
|
6326
6045
|
}
|
|
@@ -6330,26 +6049,50 @@ async function runAgentTurn(options) {
|
|
|
6330
6049
|
);
|
|
6331
6050
|
return { exitCode: 1 };
|
|
6332
6051
|
}
|
|
6052
|
+
const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
|
|
6053
|
+
if (localBlock) {
|
|
6054
|
+
return { exitCode: localBlock.exitCode };
|
|
6055
|
+
}
|
|
6333
6056
|
return runHttpAgentTurn(options, authToken);
|
|
6334
6057
|
}
|
|
6335
6058
|
|
|
6336
6059
|
// packages/cli/agentRunCommand.ts
|
|
6337
6060
|
import * as nodeFs from "node:fs";
|
|
6338
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6339
|
-
import { join as join2 } from "node:path";
|
|
6340
6061
|
|
|
6341
6062
|
// packages/cli/client/autoModelRouter.ts
|
|
6342
6063
|
var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
|
|
6343
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
|
+
|
|
6344
6087
|
// packages/cli/agentRunPrompts.ts
|
|
6345
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6346
|
-
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";
|
|
6347
6090
|
function workflowRefToCandidatePath(cwd, ref) {
|
|
6348
6091
|
const normalized = ref.trim();
|
|
6349
6092
|
if (!normalized) return "";
|
|
6350
6093
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6351
6094
|
const directPath = resolve(cwd, normalized);
|
|
6352
|
-
if (
|
|
6095
|
+
if (existsSync2(directPath)) return directPath;
|
|
6353
6096
|
}
|
|
6354
6097
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6355
6098
|
return resolve(cwd, "docs", "workflows", `${fileName}.md`);
|
|
@@ -6362,21 +6105,21 @@ function skillRefToCandidatePath(cwd, ref) {
|
|
|
6362
6105
|
if (!normalized) return "";
|
|
6363
6106
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6364
6107
|
const directPath = resolve(cwd, normalized);
|
|
6365
|
-
if (
|
|
6108
|
+
if (existsSync2(directPath)) return directPath;
|
|
6366
6109
|
}
|
|
6367
6110
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6368
6111
|
for (const dir of SKILL_SEARCH_DIRS) {
|
|
6369
6112
|
const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
|
|
6370
|
-
if (
|
|
6113
|
+
if (existsSync2(skillMdPath)) return skillMdPath;
|
|
6371
6114
|
}
|
|
6372
6115
|
return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
|
|
6373
6116
|
}
|
|
6374
6117
|
async function resolveWorkflowReference(ref, cwd = process.cwd()) {
|
|
6375
6118
|
const path = workflowRefToCandidatePath(cwd, ref);
|
|
6376
|
-
if (!path || !
|
|
6119
|
+
if (!path || !existsSync2(path)) {
|
|
6377
6120
|
throw new Error(`Workflow reference not found: ${ref}`);
|
|
6378
6121
|
}
|
|
6379
|
-
const markdown =
|
|
6122
|
+
const markdown = readFileSync2(path, "utf8");
|
|
6380
6123
|
const parsed = parseSkillDocProtocol(markdown);
|
|
6381
6124
|
return {
|
|
6382
6125
|
ref,
|
|
@@ -6393,8 +6136,8 @@ function inlineRelativeRefs(body, skillDir) {
|
|
|
6393
6136
|
const absPath = resolve(skillDir, cleaned);
|
|
6394
6137
|
const relative = relativePath(normalizedSkillDir, absPath);
|
|
6395
6138
|
if (relative.startsWith("..") || isAbsolute(relative)) return match;
|
|
6396
|
-
if (!
|
|
6397
|
-
const refContent =
|
|
6139
|
+
if (!existsSync2(absPath) || !absPath.endsWith(".md")) return match;
|
|
6140
|
+
const refContent = readFileSync2(absPath, "utf8");
|
|
6398
6141
|
return `
|
|
6399
6142
|
|
|
6400
6143
|
### ${label}
|
|
@@ -6405,8 +6148,8 @@ ${refContent}
|
|
|
6405
6148
|
});
|
|
6406
6149
|
}
|
|
6407
6150
|
function listSkillScripts(skillDir) {
|
|
6408
|
-
const scriptsDir =
|
|
6409
|
-
if (!
|
|
6151
|
+
const scriptsDir = join2(skillDir, "scripts");
|
|
6152
|
+
if (!existsSync2(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
|
|
6410
6153
|
const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
|
|
6411
6154
|
if (entries.length === 0) return null;
|
|
6412
6155
|
return [
|
|
@@ -6433,10 +6176,10 @@ async function resolveSkillReference(ref, options = {}) {
|
|
|
6433
6176
|
} else {
|
|
6434
6177
|
const cwd = options.cwd ?? process.cwd();
|
|
6435
6178
|
const path = skillRefToCandidatePath(cwd, ref);
|
|
6436
|
-
if (!path || !
|
|
6179
|
+
if (!path || !existsSync2(path)) {
|
|
6437
6180
|
throw new Error(`Skill reference not found: ${ref}`);
|
|
6438
6181
|
}
|
|
6439
|
-
markdown =
|
|
6182
|
+
markdown = readFileSync2(path, "utf8");
|
|
6440
6183
|
filePath = path;
|
|
6441
6184
|
skillDir = dirname(path);
|
|
6442
6185
|
}
|
|
@@ -6541,8 +6284,8 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
|
|
|
6541
6284
|
function normalizeCliImageInput(input) {
|
|
6542
6285
|
if (/^(https?:|data:|file:)/i.test(input)) return input;
|
|
6543
6286
|
const absolutePath = resolve(input);
|
|
6544
|
-
if (!
|
|
6545
|
-
const base64 =
|
|
6287
|
+
if (!existsSync2(absolutePath)) return input;
|
|
6288
|
+
const base64 = readFileSync2(absolutePath).toString("base64");
|
|
6546
6289
|
return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
|
|
6547
6290
|
}
|
|
6548
6291
|
function imageMimeTypeForPath(path) {
|
|
@@ -6625,6 +6368,19 @@ var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).
|
|
|
6625
6368
|
// packages/ai/memory/constants.ts
|
|
6626
6369
|
var EXPLICIT_REMEMBER_PREFIX_REGEX = /^(你要记住|请记住|以后记住|记住)[,,。.\s::]*/u;
|
|
6627
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
|
+
|
|
6628
6384
|
// packages/ai/memory/overlay.ts
|
|
6629
6385
|
var KIND_TITLES = {
|
|
6630
6386
|
episodic: "Episodic",
|
|
@@ -6658,6 +6414,8 @@ var FACET_DISPLAY = {
|
|
|
6658
6414
|
style: { label: "\u66F4\u504F\u597D", strip: "\u66F4\u559C\u6B22" },
|
|
6659
6415
|
goal: { label: "\u60F3\u63A8\u8FDB", strip: "\u60F3\u63A8\u8FDB" }
|
|
6660
6416
|
};
|
|
6417
|
+
var INFERRED_SOURCE_KINDS = /* @__PURE__ */ new Set(["inferred-understanding", "dialog-learning"]);
|
|
6418
|
+
var isInferredMemory = (item) => INFERRED_SOURCE_KINDS.has(getMemorySourceKind(item));
|
|
6661
6419
|
var formatFacetContent = (facet, normalized, prefix) => {
|
|
6662
6420
|
const { label, strip } = FACET_DISPLAY[facet];
|
|
6663
6421
|
const stripped = normalized.startsWith(strip) ? normalized.slice(strip.length).trim() : normalized;
|
|
@@ -6679,9 +6437,79 @@ var normalizeDisplayContent = (item) => {
|
|
|
6679
6437
|
}
|
|
6680
6438
|
return normalized;
|
|
6681
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
|
+
};
|
|
6682
6510
|
var buildMemoryOverlay = (items, options) => {
|
|
6683
6511
|
if (items.length === 0) return null;
|
|
6684
|
-
const maxTokens = options?.maxTokens ??
|
|
6512
|
+
const maxTokens = options?.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6685
6513
|
const perKindLimit = options?.perKindLimit ?? 3;
|
|
6686
6514
|
const byKind = {
|
|
6687
6515
|
episodic: [],
|
|
@@ -6696,19 +6524,15 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6696
6524
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6697
6525
|
}
|
|
6698
6526
|
const allLines = Object.entries(byKind).filter(([, list]) => list.length > 0).flatMap(
|
|
6699
|
-
([kind, list]) => list
|
|
6700
|
-
const lineText = `- ${normalizeDisplayContent(item)}`;
|
|
6527
|
+
([kind, list]) => pickWithinKind(list, perKindLimit).map((item) => {
|
|
6528
|
+
const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
|
|
6701
6529
|
return { kind, lineText, lineTokens: estimateTokens(lineText) };
|
|
6702
6530
|
})
|
|
6703
6531
|
).sort((a, b) => (KIND_PRIORITY[a.kind] ?? 99) - (KIND_PRIORITY[b.kind] ?? 99));
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
usedTokens += candidate.lineTokens;
|
|
6709
|
-
if (!keptByKind[candidate.kind]) keptByKind[candidate.kind] = [];
|
|
6710
|
-
keptByKind[candidate.kind].push(candidate.lineText);
|
|
6711
|
-
}
|
|
6532
|
+
const { keptByKind, truncatedCount, droppedCount } = fitLinesToBudget(
|
|
6533
|
+
allLines,
|
|
6534
|
+
remainingBudget
|
|
6535
|
+
);
|
|
6712
6536
|
const kindOrder = ["semantic", "procedural", "episodic"];
|
|
6713
6537
|
const sections = kindOrder.filter((kind) => keptByKind[kind] && keptByKind[kind].length > 0).map((kind) => {
|
|
6714
6538
|
return [`[${KIND_TITLES[kind]}]`, ...keptByKind[kind]].join("\n");
|
|
@@ -6716,7 +6540,7 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6716
6540
|
if (sections.length === 0) {
|
|
6717
6541
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6718
6542
|
}
|
|
6719
|
-
return [...OVERLAY_HEADER_LINES, ...sections].join("\n");
|
|
6543
|
+
return [...OVERLAY_HEADER_LINES, ...sections, ...buildBudgetFooter({ keptByKind, truncatedCount, droppedCount })].join("\n");
|
|
6720
6544
|
};
|
|
6721
6545
|
|
|
6722
6546
|
// packages/ai/memory/rank.ts
|
|
@@ -6763,13 +6587,28 @@ var identifierScore = (query, item) => {
|
|
|
6763
6587
|
).length;
|
|
6764
6588
|
return matches / identifiers.length;
|
|
6765
6589
|
};
|
|
6766
|
-
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) => {
|
|
6767
6595
|
const lastActivatedMs = Date.parse(item.lastActivatedAt || item.createdAt);
|
|
6768
|
-
const ageDays = Math.max(0, (nowMs - lastActivatedMs) /
|
|
6596
|
+
const ageDays = Math.max(0, (nowMs - lastActivatedMs) / DAY_MS);
|
|
6769
6597
|
const recency = 1 / (1 + ageDays / 7);
|
|
6770
6598
|
const reinforcement = Math.min(1, Math.log1p(item.activationCount ?? 0) / 3);
|
|
6771
6599
|
return 0.7 * recency + 0.3 * reinforcement;
|
|
6772
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);
|
|
6773
6612
|
var creationRecencyScore = (item, nowMs) => {
|
|
6774
6613
|
const createdMs = Date.parse(item.createdAt);
|
|
6775
6614
|
const ageDays = Math.max(0, (nowMs - createdMs) / 864e5);
|
|
@@ -6825,7 +6664,7 @@ var rankMemoryCandidates = (items, query, context) => {
|
|
|
6825
6664
|
|
|
6826
6665
|
// packages/ai/memory/runtime.ts
|
|
6827
6666
|
var COLD_STORAGE_CONFIDENCE = 0.3;
|
|
6828
|
-
var MEMORY_OVERLAY_TOKEN_BUDGET =
|
|
6667
|
+
var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6829
6668
|
var normalizeSelectedContent = (text) => text.trim().replace(EXPLICIT_REMEMBER_PREFIX_REGEX, "").replace(/[。!?!?]+$/u, "").trim();
|
|
6830
6669
|
var STACK_TERMS = [
|
|
6831
6670
|
"typescript",
|
|
@@ -6927,6 +6766,7 @@ var selectRuntimeMemoryItems = (items, context, userInput = "") => {
|
|
|
6927
6766
|
);
|
|
6928
6767
|
add(unique.find((item) => item.ownerType === "user"));
|
|
6929
6768
|
add(unique.find((item) => item.ownerType === "space"));
|
|
6769
|
+
add(unique.find((item) => item.subjectType === "user"));
|
|
6930
6770
|
add(unique.find((item) => item.kind === "procedural"));
|
|
6931
6771
|
for (const item of unique) {
|
|
6932
6772
|
add(item);
|
|
@@ -7046,6 +6886,36 @@ var resolveCliMemory = async (input) => {
|
|
|
7046
6886
|
function resolvePositiveMs(value, fallback) {
|
|
7047
6887
|
return parsePositiveFiniteNumberOrFallback(value, fallback);
|
|
7048
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
|
+
};
|
|
7049
6919
|
async function resolveAgentRunAgentKey(args) {
|
|
7050
6920
|
if (!args.agentInput.trim() || args.agentInput.startsWith("agent-")) {
|
|
7051
6921
|
return void 0;
|
|
@@ -7081,11 +6951,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7081
6951
|
deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
|
|
7082
6952
|
5 * 6e4
|
|
7083
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;
|
|
7084
6957
|
let timedOut = false;
|
|
7085
6958
|
let stalled = false;
|
|
7086
6959
|
let timeoutTimer;
|
|
7087
6960
|
let stallTimer;
|
|
7088
|
-
const activityTracker =
|
|
6961
|
+
const activityTracker = armStallWatchdog ? createRunActivityTracker(childRunId ?? "__foreground__", {
|
|
7089
6962
|
env,
|
|
7090
6963
|
homedir: deps.homedir,
|
|
7091
6964
|
fs: deps.fs,
|
|
@@ -7098,7 +6971,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7098
6971
|
activityTracker?.dispose();
|
|
7099
6972
|
};
|
|
7100
6973
|
let rejectOnWatchdogFailure;
|
|
7101
|
-
const watchdogFailure =
|
|
6974
|
+
const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
|
|
7102
6975
|
rejectOnWatchdogFailure = reject;
|
|
7103
6976
|
}) : void 0;
|
|
7104
6977
|
const raceWithWatchdog = (work) => watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
|
|
@@ -7108,7 +6981,15 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7108
6981
|
} catch {
|
|
7109
6982
|
}
|
|
7110
6983
|
};
|
|
7111
|
-
|
|
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) {
|
|
7112
6993
|
stallTimer = setInterval(() => {
|
|
7113
6994
|
if (timedOut || stalled) return;
|
|
7114
6995
|
const activity = activityTracker?.getActivity();
|
|
@@ -7126,31 +7007,25 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7126
7007
|
const note = `stalled: no progress for ${stallTimeoutMs}ms`;
|
|
7127
7008
|
output.write(`[nolo] local run ${note}
|
|
7128
7009
|
`);
|
|
7129
|
-
(
|
|
7130
|
-
|
|
7131
|
-
{ status: "failed", note },
|
|
7132
|
-
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
7133
|
-
);
|
|
7010
|
+
const outcome = resolveRunOutcome({ kind: "stall" });
|
|
7011
|
+
finalizeWatchdogOutcome(outcome, note);
|
|
7134
7012
|
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7135
|
-
exitFromWatchdog(
|
|
7013
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7136
7014
|
}
|
|
7137
7015
|
}, Math.min(stallTimeoutMs, 1e4));
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
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}
|
|
7144
7023
|
`);
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7151
|
-
exitFromWatchdog(124);
|
|
7152
|
-
}, parsed.timeoutMs);
|
|
7153
|
-
}
|
|
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);
|
|
7154
7029
|
}
|
|
7155
7030
|
const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
|
|
7156
7031
|
const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
|
|
@@ -7305,22 +7180,8 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7305
7180
|
let memoryOverlayLayer = null;
|
|
7306
7181
|
let memoryUseGuidanceLayer = null;
|
|
7307
7182
|
if (!isSubtask) {
|
|
7308
|
-
const
|
|
7309
|
-
|
|
7310
|
-
const agentsMdPath = join2(cliCwd, name);
|
|
7311
|
-
if (existsSync2(agentsMdPath)) {
|
|
7312
|
-
try {
|
|
7313
|
-
let mdContent = readFileSync2(agentsMdPath, "utf8").trim();
|
|
7314
|
-
if (!mdContent) continue;
|
|
7315
|
-
if (Buffer.byteLength(mdContent, "utf8") > AGENTS_MD_MAX) {
|
|
7316
|
-
mdContent = Buffer.from(mdContent, "utf8").subarray(0, AGENTS_MD_MAX).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
7317
|
-
}
|
|
7318
|
-
scopedLayers.push(buildAgentsMdLayer(mdContent, name));
|
|
7319
|
-
break;
|
|
7320
|
-
} catch {
|
|
7321
|
-
}
|
|
7322
|
-
}
|
|
7323
|
-
}
|
|
7183
|
+
const agentsMdLayer = readAgentsMdLayerFromDisk(cliCwd);
|
|
7184
|
+
if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
|
|
7324
7185
|
skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
|
|
7325
7186
|
scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
|
|
7326
7187
|
if (!deps.memoryRecallDisabled) {
|
|
@@ -7401,6 +7262,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7401
7262
|
})
|
|
7402
7263
|
);
|
|
7403
7264
|
clearWatchdogs();
|
|
7265
|
+
let runCreditsTotal = result.turnCredits;
|
|
7404
7266
|
if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
|
|
7405
7267
|
const fallbackAgentKey = parsed.fallbackAgentKeys[0];
|
|
7406
7268
|
output.write(
|
|
@@ -7416,7 +7278,11 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7416
7278
|
clearWatchdogs();
|
|
7417
7279
|
if (fallbackResult.exitCode === 0) {
|
|
7418
7280
|
result = fallbackResult;
|
|
7419
|
-
}
|
|
7281
|
+
}
|
|
7282
|
+
if (fallbackResult.turnCredits !== void 0) {
|
|
7283
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + fallbackResult.turnCredits;
|
|
7284
|
+
}
|
|
7285
|
+
if (fallbackResult.exitCode !== 0) {
|
|
7420
7286
|
result = {
|
|
7421
7287
|
...fallbackResult,
|
|
7422
7288
|
...fallbackResult.dialogId || result.dialogId ? { dialogId: fallbackResult.dialogId ?? result.dialogId } : {}
|
|
@@ -7459,6 +7325,9 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7459
7325
|
);
|
|
7460
7326
|
clearWatchdogs();
|
|
7461
7327
|
result = turnResult;
|
|
7328
|
+
if (turnResult.turnCredits !== void 0) {
|
|
7329
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
|
|
7330
|
+
}
|
|
7462
7331
|
if (result.exitCode !== 0) {
|
|
7463
7332
|
break;
|
|
7464
7333
|
}
|
|
@@ -7509,15 +7378,22 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7509
7378
|
}
|
|
7510
7379
|
}
|
|
7511
7380
|
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
7512
|
-
const isStalledOrTruncated = result
|
|
7513
|
-
const truncationNote =
|
|
7514
|
-
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
|
+
});
|
|
7515
7388
|
await (deps.finalizeRunRecord ?? finalizeRunRecord)(
|
|
7516
7389
|
childRunId,
|
|
7517
7390
|
{
|
|
7518
|
-
status:
|
|
7519
|
-
exitCode:
|
|
7391
|
+
status: outcome.status,
|
|
7392
|
+
exitCode: outcome.exitCode,
|
|
7520
7393
|
dialogId: result.dialogId,
|
|
7394
|
+
// run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
|
|
7395
|
+
// 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
|
|
7396
|
+
...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
|
|
7521
7397
|
...truncationNote
|
|
7522
7398
|
},
|
|
7523
7399
|
{
|
|
@@ -7562,6 +7438,7 @@ function isBalanceExhaustedError(error) {
|
|
|
7562
7438
|
export {
|
|
7563
7439
|
resolveAgentModelIdentity,
|
|
7564
7440
|
resolveAgentContextWindow,
|
|
7441
|
+
formatCreditsChip,
|
|
7565
7442
|
formatTokenCount,
|
|
7566
7443
|
renderTokenStatus,
|
|
7567
7444
|
resolveCliColorEnabled,
|
|
@@ -7588,8 +7465,6 @@ export {
|
|
|
7588
7465
|
getActiveThemeMode,
|
|
7589
7466
|
setActiveThemeMode,
|
|
7590
7467
|
setActiveBrightness,
|
|
7591
|
-
getActiveDensity,
|
|
7592
|
-
setActiveDensity,
|
|
7593
7468
|
detectSystemBrightnessFromEnv,
|
|
7594
7469
|
resolveTuiBrightness,
|
|
7595
7470
|
resolveTuiThemeMode,
|
|
@@ -7602,8 +7477,10 @@ export {
|
|
|
7602
7477
|
themeText,
|
|
7603
7478
|
tuiRenderThemeFingerprint,
|
|
7604
7479
|
setMathRenderingEnabled,
|
|
7480
|
+
polishBreathInsertsBlankBetween,
|
|
7605
7481
|
formatAssistantDisplay,
|
|
7606
|
-
|
|
7482
|
+
redactSecrets,
|
|
7483
|
+
TUI_TREE_MARKER,
|
|
7607
7484
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
7608
7485
|
shouldCollapsePaste,
|
|
7609
7486
|
createCollapsedPasteStore,
|
|
@@ -7615,6 +7492,7 @@ export {
|
|
|
7615
7492
|
expandRangeToCollapsedPasteChips,
|
|
7616
7493
|
findCollapsedPasteSpanAt,
|
|
7617
7494
|
runAgentTurn,
|
|
7495
|
+
readAgentsMdLayerFromDisk,
|
|
7618
7496
|
resolveWorkflowReference,
|
|
7619
7497
|
resolveSkillReference,
|
|
7620
7498
|
buildSkillContextBlocks,
|
|
@@ -7622,6 +7500,9 @@ export {
|
|
|
7622
7500
|
normalizeCliImageInput,
|
|
7623
7501
|
inspectLocalRunWorkspace,
|
|
7624
7502
|
resolveCliMemory,
|
|
7503
|
+
resolveRunOutcome,
|
|
7504
|
+
isRunResultStalledOrTruncated,
|
|
7505
|
+
resolveRunSettlementNote,
|
|
7625
7506
|
runAgentRunCommand,
|
|
7626
7507
|
isBalanceExhaustedError
|
|
7627
7508
|
};
|