nolo-cli 0.54.0-alpha.2 → 0.61.0-alpha.2
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/README.md +3 -3
- package/{_executeModel-ANY4SIAS.js → _executeModel-CKT6RGTL.js} +58 -49
- package/{action-Q4W5JPI5.js → action-76JX3JX3.js} +9 -8
- package/{addContentAction-O25HFR37.js → addContentAction-V3NAZRTJ.js} +9 -7
- package/{addDialogAgentAction-GH7AUPPB.js → addDialogAgentAction-RZOAF46K.js} +11 -9
- package/{agentDeleteCommand-JWIKNWWI.js → agentDeleteCommand-VN7NPXQ4.js} +37 -32
- package/{agentEmailCommands-PL22BEU5.js → agentEmailCommands-F2TNAV4A.js} +73 -65
- package/{agentGrantCommands-2LEZDADN.js → agentGrantCommands-R3VQEZJR.js} +1 -1
- package/{agentListCommands-6NR7AQEK.js → agentListCommands-OSM2ANI3.js} +78 -39
- package/{agentMachineCommands-TASPU6OA.js → agentMachineCommands-MTPWYVRV.js} +38 -33
- package/{agentPullCommand-M552CYSI.js → agentPullCommand-N7L2CT7L.js} +2 -2
- package/agentRecordCommands-VWAWTVVC.js +122 -0
- package/agentRunCommand-PLZOBNVK.js +149 -0
- package/{agentRunControl-4GHHSXFZ.js → agentRunControl-WECMOO6O.js} +13 -6
- package/{agentRuntimeLocal-PCJJ56J2.js → agentRuntimeLocal-XCJLRWQE.js} +35 -28
- package/{agentSlice-KYLDUSNN.js → agentSlice-F6DOP4IW.js} +10 -9
- package/{appDeleteCommands-WLHMJAVT.js → appDeleteCommands-3BCFTRFJ.js} +37 -32
- package/{appDeployCommands-CKON7N2E.js → appDeployCommands-B4GMHCYA.js} +37 -32
- package/{appDeployStatusCommands-PXRLDASH.js → appDeployStatusCommands-4MN36WIG.js} +37 -32
- package/{appGetCommands-RAB5RM4M.js → appGetCommands-4GJIEUAX.js} +37 -32
- package/{appListCommands-GU57FB62.js → appListCommands-CHU53GSX.js} +37 -32
- package/{authCommand-QOPOEYEK.js → authCommand-WOTWLJNF.js} +38 -32
- package/{authCommands-SBQVTD6V.js → authCommands-ILTBI6JV.js} +8 -6
- package/{chatQueueReduxAdapter-5O2WLITN.js → chatQueueReduxAdapter-HNSQXNIR.js} +29 -24
- package/{chunk-WL3UOGYO.js → chunk-22BTGNSP.js} +151 -155
- package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
- package/{chunk-V4KZGLOI.js → chunk-2HPRMEEZ.js} +3059 -1079
- package/{chunk-UNZDCI3O.js → chunk-2KDR4CWE.js} +35 -4
- package/{chunk-VRZIH5JO.js → chunk-2PGGC63K.js} +1 -1
- package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
- package/{chunk-7K5VMB4Q.js → chunk-37QVS7BU.js} +21 -8
- package/{chunk-UITMHBVK.js → chunk-37XDGCY7.js} +1 -1
- package/chunk-3BLB7QKO.js +433 -0
- package/{chunk-NQ4N4IGO.js → chunk-3JQ2NRYU.js} +33 -10
- package/{chunk-UW4INMD2.js → chunk-3JWKQDA4.js} +2 -2
- package/{chunk-IKTHA3JH.js → chunk-3QGUVVX5.js} +2 -2
- package/{chunk-WHVQA7PJ.js → chunk-45YO6H7P.js} +97 -35
- package/chunk-4C4ST2YE.js +20015 -0
- package/{chunk-32I5RVMY.js → chunk-4NJEIGBQ.js} +5 -5
- package/{chunk-KUUTWU4I.js → chunk-5ZYA4JJ3.js} +90 -22
- package/chunk-6YTOJY35.js +352 -0
- package/{chunk-INXBNYCG.js → chunk-7A3RRUCQ.js} +155 -12
- package/{chunk-GV35EHNA.js → chunk-7O7KH4X5.js} +1262 -971
- package/{chunk-Y7LNKP32.js → chunk-7UF7CQ6B.js} +4 -6
- package/{chunk-2BWU4ORW.js → chunk-AQMVUA7N.js} +2 -1
- package/{chunk-LA4IDAK7.js → chunk-AVE2YR4F.js} +1056 -3591
- package/{chunk-TI5BCZCH.js → chunk-B7DXRX7F.js} +59 -121
- package/chunk-BFU6C242.js +66 -0
- package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
- package/chunk-BYXBJQAS.js +0 -0
- package/{chunk-IA3A5373.js → chunk-C3FZR5EC.js} +1 -1
- package/{chunk-IWUMSAQF.js → chunk-CJCJF5XB.js} +26 -3
- package/{chunk-PAHILFNT.js → chunk-CP7VIDZ7.js} +4 -4
- package/{chunk-OYNDYVSE.js → chunk-CTCW7U7N.js} +1 -1
- package/{chunk-BJLYCOZK.js → chunk-D5XKNNUV.js} +135 -795
- package/{chunk-AV6KQCM5.js → chunk-DNNSCSA2.js} +19 -14
- package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
- package/{chunk-NI2BS6UD.js → chunk-DWUCB2A3.js} +1 -1
- package/{chunk-AA564GBL.js → chunk-DZZL7UBV.js} +1 -1
- package/{chunk-6FGXGFAH.js → chunk-E6RGHPDR.js} +6 -4
- package/chunk-EDKF7RX4.js +30 -0
- package/{chunk-6SZ52ORL.js → chunk-ES6CVKVD.js} +24 -30
- package/{chunk-DQLYEGP7.js → chunk-FHAGENAS.js} +3 -4
- package/{chunk-56W233KG.js → chunk-FKFMIBTT.js} +5 -1
- package/{chunk-INZZJSQF.js → chunk-FZGV4FGK.js} +24 -12
- package/{chunk-D3JQPONH.js → chunk-GAL47RNP.js} +1 -1
- package/{chunk-6FQ2552G.js → chunk-HBPV76EK.js} +1085 -1150
- package/{chunk-LN3OQJGG.js → chunk-HLU5Q2GV.js} +4 -4
- package/{chunk-U2A47SVI.js → chunk-HQP7HJDL.js} +7 -7
- package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
- package/{chunk-3Z3DXZBD.js → chunk-IYCUMIYS.js} +24 -20
- package/{chunk-7APQB6R6.js → chunk-JX5PJCWS.js} +8 -6
- package/{chunk-LYGNQHUW.js → chunk-JYYZCK2Z.js} +2 -4
- package/{chunk-PYKV6FSC.js → chunk-KWSQR2KK.js} +16 -31
- package/{chunk-VULELK4T.js → chunk-L7B47JXR.js} +37 -64
- package/{chunk-4NN3EK7H.js → chunk-LAFC3B2I.js} +1 -1
- package/{chunk-VRJUIUIY.js → chunk-LJKICKVC.js} +2 -2
- package/chunk-M3JEW6N6.js +193 -0
- package/chunk-MBOEV4L2.js +301 -0
- package/{chunk-QDHZCAH3.js → chunk-MMZ6ZTVO.js} +229 -74
- package/{chunk-JDSUTNYY.js → chunk-MP64VFGD.js} +2 -2
- package/{chunk-U5Z7LFZF.js → chunk-MXUDQZXQ.js} +47 -8
- package/chunk-N4G4PKQ6.js +23 -0
- package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
- package/{chunk-KXKQO4Q6.js → chunk-NTW5GWDM.js} +58 -1
- package/chunk-ONXOABJR.js +215 -0
- package/{chunk-BANYWEYY.js → chunk-OZX2IPKM.js} +8 -3
- package/{chunk-Q24S4NDF.js → chunk-P7OOB7QP.js} +1 -1
- package/{chunk-GLGD2JGY.js → chunk-PEZJEQAO.js} +7 -7
- package/{chunk-GBADO3SM.js → chunk-PQDIDWGX.js} +1 -1
- package/chunk-PSCNXBYA.js +11 -0
- package/chunk-QEFJJS2I.js +508 -0
- package/{chunk-757BGY6Y.js → chunk-QEW2MFDQ.js} +1 -1
- package/{chunk-SP3DPVBH.js → chunk-RDBARW6T.js} +8 -3
- package/{chunk-TNPCQNGQ.js → chunk-RJ2SAFB5.js} +83 -41
- package/{chunk-FGEYVPPR.js → chunk-RVWRKFUB.js} +8 -65
- package/{chunk-43CXXVJD.js → chunk-RXX4GDIH.js} +1 -1
- package/chunk-SEJ5OS6F.js +49 -0
- package/{chunk-MFI4FGHX.js → chunk-SOJM57FX.js} +5 -2
- package/{chunk-EKLRRZIN.js → chunk-SPAQ4PVV.js} +0 -5
- package/{chunk-L7NG2M6H.js → chunk-TRV2MIDW.js} +89 -74
- package/chunk-UAD2WT54.js +64 -0
- package/{chunk-RTLJUGQH.js → chunk-UZPQSVM6.js} +2 -2
- package/{chunk-3QJTD6DO.js → chunk-VMWYBIXG.js} +9 -7
- package/{chunk-ZHXJ6M7T.js → chunk-W7XHHYWM.js} +4 -0
- package/{chunk-5WADL4O7.js → chunk-XAVSS3KE.js} +21 -3
- package/{chunk-CVT7L2WZ.js → chunk-XOKOSO35.js} +13 -22
- package/{chunk-6BYAXNH5.js → chunk-XTJTN3RW.js} +57 -4
- package/{chunk-T5HJEUQN.js → chunk-YCDWJX45.js} +1 -1
- package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
- package/{chunk-H4RYESI6.js → chunk-Z4QSJILV.js} +85 -13
- package/chunk-ZJ7UHBJS.js +89 -0
- package/{chunk-O5FLGN2L.js → chunk-ZRSJ3JEH.js} +6 -2
- package/{cliExecutor-BBUVQU4L.js → cliExecutor-HG3S345O.js} +1 -1
- package/{codingSkills-BCQXRZOI.js → codingSkills-VDXQYWX4.js} +2 -2
- package/contentThunks-7YG2ZYQC.js +73 -0
- package/{cooldownCommands-GI5NNWGL.js → cooldownCommands-BSCH2W7P.js} +2 -2
- package/{createAgentAutomationAction-UJLNFFFC.js → createAgentAutomationAction-PJQSCAIO.js} +32 -26
- package/createDialogAction-SFEJX6SP.js +64 -0
- package/{createPageAction-N3IYABHV.js → createPageAction-B7WRHOQO.js} +35 -28
- package/{dbSlice-D5CNGWPD.js → dbSlice-IBVOBVMS.js} +7 -6
- package/{deleteFile-44TUM34Y.js → deleteFile-FWP2PSBG.js} +4 -3
- package/{dialogCommands-35M6RBAC.js → dialogCommands-VL2X22QC.js} +38 -33
- package/{dialogSlice-KO7ADD7H.js → dialogSlice-ANMACABO.js} +29 -24
- package/{docCreateCommands-VXHZWQ3P.js → docCreateCommands-ITLGZ5YI.js} +40 -35
- package/{docDeleteCommands-4WFAJR6A.js → docDeleteCommands-LH3YNL4C.js} +37 -32
- package/{docReadCommands-OYREEFAR.js → docReadCommands-YAJ77F36.js} +36 -31
- package/{docStore-5BU76DFK.js → docStore-D4HGHPWI.js} +9 -33
- package/{docUpdateCommands-A7QERSME.js → docUpdateCommands-DQBOMH2G.js} +40 -35
- package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
- package/{getPricing-HAU62AFM.js → getPricing-NM3NUTAS.js} +5 -5
- package/handleSendMessageAction-DF2OABGW.js +675 -0
- package/index.js +79 -88
- package/{lib-2ZTNRXR4.js → lib-FRRS27KN.js} +63 -28
- package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
- package/{localRuntimeAuthority-KQDAE64E.js → localRuntimeAuthority-R5UBODT3.js} +6 -4
- package/{localRuntimeDb-PF7CFKDL.js → localRuntimeDb-P37ZTX55.js} +1 -1
- package/{machineCommands-J43U3TX5.js → machineCommands-JXDYQ5LB.js} +309 -87
- package/{machineWsRunDispatch-Z2Z6STXZ.js → machineWsRunDispatch-3QHI7JX5.js} +67 -59
- package/memberThunks-VZI6G7YZ.js +640 -0
- package/{models-4QF4BJVY.js → models-FAMINFZ7.js} +2 -2
- package/package.json +3 -2
- package/{read-RGNPI5H2.js → read-2BYWW7AA.js} +4 -3
- package/{readDocTool-6ESWKTXD.js → readDocTool-LC3A7QTB.js} +1 -1
- package/{readlineWorkspace-YRPV6JPN.js → readlineWorkspace-KVZTEAHB.js} +4609 -2698
- package/{removeDialogAgentAction-JYT73FU2.js → removeDialogAgentAction-SFYZXHNK.js} +14 -12
- package/{runAgentClientLoop-5YM5WMAY.js → runAgentClientLoop-KGTEL7ZP.js} +60 -50
- package/{runtimeDoctorCommands-JKTTN723.js → runtimeDoctorCommands-CROTMULY.js} +7 -5
- package/{setDialogExtraReferencesAction-D564LMYQ.js → setDialogExtraReferencesAction-Q32RGFTA.js} +10 -8
- package/{setPrimaryDialogAgentAction-ACY3BLYA.js → setPrimaryDialogAgentAction-BFYJHUJS.js} +14 -12
- package/{settingSlice-MKI3MNZJ.js → settingSlice-IRUU4VFB.js} +8 -7
- package/{skillDiscovery-GPUDHDTZ.js → skillDiscovery-NTRLM6KP.js} +3 -3
- package/{spaceCommands-MY26V52L.js → spaceCommands-KNAYWMCZ.js} +40 -220
- package/{streamAgentChatTurn-XV5X5TNQ.js → streamAgentChatTurn-FLYPTXKZ.js} +140 -95
- package/{switchDialogAgentAction-CJ5H6SAR.js → switchDialogAgentAction-L2KOKCGG.js} +11 -9
- package/{tableCommands-R6WFRDYF.js → tableCommands-SUNTHAYX.js} +1 -1
- package/{toolApiClient-B2MFXMEG.js → toolApiClient-VGYUB4P5.js} +4 -2
- package/{tools-MIMELA2Y.js → tools-CVLUXK6P.js} +46 -38
- package/{tuiSummaryLlmCaller-XJ5BKNNS.js → tuiSummaryLlmCaller-F3DPFFZM.js} +20 -16
- package/{updateCommands-IYKLF3JX.js → updateCommands-AJYSD73Y.js} +2 -2
- package/{updateDialogTitleAction-EIZUSWHR.js → updateDialogTitleAction-HWJIZEIV.js} +33 -27
- package/agentRecordCommands-Z64TA63M.js +0 -114
- package/agentRunCommand-4QJQLPRW.js +0 -134
- package/agentSuperviseCommands-VB6BUS5H.js +0 -640
- package/chunk-6BGAQ3KR.js +0 -7081
- package/chunk-FD36SCCD.js +0 -105
- package/chunk-J3UALFHL.js +0 -370
- package/chunk-RU5D3B22.js +0 -230
- package/chunk-YBV6QJKM.js +0 -441
- package/createDialogAction-TJCX6GUE.js +0 -58
- package/handleSendMessageAction-OSGQJQ45.js +0 -406
- package/spaceSlice-JUIXC365.js +0 -127
|
@@ -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,
|
|
@@ -9,40 +9,51 @@ import {
|
|
|
9
9
|
resolveRawAgentInput,
|
|
10
10
|
resolveServerUrl,
|
|
11
11
|
writeUsage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JYYZCK2Z.js";
|
|
13
13
|
import {
|
|
14
14
|
agentRunCardLabels,
|
|
15
15
|
createCliLocalRuntimeAdapter,
|
|
16
|
+
detectCurrentMachineId,
|
|
16
17
|
getCliLocale,
|
|
17
18
|
isBuiltinNoloAgentRef,
|
|
19
|
+
isCliProviderAgentConfig,
|
|
20
|
+
isLiveAgentRunObservation,
|
|
21
|
+
isMachineBoundLocalhostCustomProvider,
|
|
18
22
|
isSubtaskRun,
|
|
19
23
|
parseAgentRunEvent,
|
|
24
|
+
resolveAuthToken as resolveAuthToken2,
|
|
25
|
+
resolveBoundMachineId,
|
|
26
|
+
resolveFileWriteGateEnabled,
|
|
27
|
+
resolveLocalUserId,
|
|
20
28
|
t,
|
|
21
29
|
toolLabel
|
|
22
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-7O7KH4X5.js";
|
|
31
|
+
import {
|
|
32
|
+
createRunActivityTracker,
|
|
33
|
+
popSingleQueueMessage,
|
|
34
|
+
readRunRecord,
|
|
35
|
+
resolveRunQueuePath,
|
|
36
|
+
settleRunTerminalAuthoritatively,
|
|
37
|
+
spawnLocalBackgroundRun
|
|
38
|
+
} from "./chunk-45YO6H7P.js";
|
|
39
|
+
import {
|
|
40
|
+
readCredentialEntry,
|
|
41
|
+
recordCredentialProbe,
|
|
42
|
+
resolveCredentialKeyWithFallback
|
|
43
|
+
} from "./chunk-DWUCB2A3.js";
|
|
23
44
|
import {
|
|
24
45
|
getReadableCliDb
|
|
25
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-RXX4GDIH.js";
|
|
26
47
|
import {
|
|
27
|
-
normalizeAgentHandle,
|
|
28
48
|
readDbRecord,
|
|
29
49
|
resolveAgentRecordFromHybridStore
|
|
30
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-FHAGENAS.js";
|
|
31
51
|
import {
|
|
32
|
-
NOLO_PROJECT_MANAGER_AGENT_KEY,
|
|
33
52
|
isLocalCliAgentKey
|
|
34
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-SPAQ4PVV.js";
|
|
35
54
|
import {
|
|
36
55
|
CliProviderQuotaError
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import {
|
|
39
|
-
createRunActivityTracker,
|
|
40
|
-
finalizeRunRecord,
|
|
41
|
-
popSingleQueueMessage,
|
|
42
|
-
readRunRecord,
|
|
43
|
-
resolveRunQueuePath,
|
|
44
|
-
spawnLocalBackgroundRun
|
|
45
|
-
} from "./chunk-WHVQA7PJ.js";
|
|
56
|
+
} from "./chunk-MP64VFGD.js";
|
|
46
57
|
import {
|
|
47
58
|
resolveMachineId
|
|
48
59
|
} from "./chunk-ESHYE7WU.js";
|
|
@@ -52,7 +63,7 @@ import {
|
|
|
52
63
|
} from "./chunk-LTRXGFMS.js";
|
|
53
64
|
import {
|
|
54
65
|
formatAgentListCard
|
|
55
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-2HPRMEEZ.js";
|
|
56
67
|
import {
|
|
57
68
|
isTransientFetchError
|
|
58
69
|
} from "./chunk-5XTOKQLW.js";
|
|
@@ -66,26 +77,33 @@ import {
|
|
|
66
77
|
formatStartRunCard,
|
|
67
78
|
formatStatusRunCard,
|
|
68
79
|
formatStopRunCard,
|
|
69
|
-
isAgentRunTerminalStatus
|
|
70
|
-
|
|
71
|
-
} from "./chunk-KXKQO4Q6.js";
|
|
80
|
+
isAgentRunTerminalStatus
|
|
81
|
+
} from "./chunk-NTW5GWDM.js";
|
|
72
82
|
import {
|
|
73
83
|
buildMemorySubjectsForAgent,
|
|
74
84
|
chooseMemoryOwners,
|
|
75
85
|
loadMemoryCandidatesFromDb,
|
|
76
86
|
resolveAgentMemoryPolicy
|
|
77
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-ES6CVKVD.js";
|
|
78
88
|
import {
|
|
79
89
|
API_REPORTED_COST_MULTIPLIER,
|
|
80
90
|
normalizeUsage,
|
|
81
91
|
parseUiAskChoiceContent
|
|
82
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-D5XKNNUV.js";
|
|
93
|
+
import {
|
|
94
|
+
isOAuthApiKeyRef
|
|
95
|
+
} from "./chunk-YYLHWIW6.js";
|
|
96
|
+
import {
|
|
97
|
+
isCliAuthorityBrokerProtocolError,
|
|
98
|
+
isCliAuthorityBrokerTimeoutError,
|
|
99
|
+
isCliAuthorityBrokerUnavailableError
|
|
100
|
+
} from "./chunk-TRV2MIDW.js";
|
|
83
101
|
import {
|
|
84
102
|
getDefaultCliLocalRuntimeDb
|
|
85
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-C3FZR5EC.js";
|
|
86
104
|
import {
|
|
87
105
|
buildSkillDiscoveryContextLayer
|
|
88
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-AQMVUA7N.js";
|
|
89
107
|
import {
|
|
90
108
|
parseExternalSkillMarkdown,
|
|
91
109
|
parseSkillDocProtocol
|
|
@@ -93,34 +111,38 @@ import {
|
|
|
93
111
|
import {
|
|
94
112
|
LOCAL_AGENT_CONFIG_MISSING_CODE,
|
|
95
113
|
LOCAL_TURN_ABORTED_CODE,
|
|
96
|
-
readActionGate
|
|
97
|
-
|
|
98
|
-
} from "./chunk-6BGAQ3KR.js";
|
|
114
|
+
readActionGate
|
|
115
|
+
} from "./chunk-4C4ST2YE.js";
|
|
99
116
|
import {
|
|
100
117
|
resolveAgentRuntimeConfigFromRecord
|
|
101
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-XOKOSO35.js";
|
|
102
119
|
import {
|
|
103
120
|
createThinkParserState,
|
|
104
121
|
flushThinkParser,
|
|
105
122
|
processThinkChunk
|
|
106
123
|
} from "./chunk-N7J63Q6C.js";
|
|
107
124
|
import {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
125
|
+
isAntigravityOAuthAgent
|
|
126
|
+
} from "./chunk-QEW2MFDQ.js";
|
|
127
|
+
import {
|
|
128
|
+
resolveClientVersion
|
|
129
|
+
} from "./chunk-RDBARW6T.js";
|
|
111
130
|
import {
|
|
112
|
-
isQuotaExhaustedError
|
|
113
|
-
|
|
131
|
+
isQuotaExhaustedError,
|
|
132
|
+
isQuotaLimited403Body,
|
|
133
|
+
mergeAvailabilityDeadline,
|
|
134
|
+
resolveCooldownGate
|
|
135
|
+
} from "./chunk-CJCJF5XB.js";
|
|
114
136
|
import {
|
|
115
137
|
DEFAULT_CONTEXT_WINDOW,
|
|
116
138
|
getModelContextWindow
|
|
117
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-5ZYA4JJ3.js";
|
|
118
140
|
import {
|
|
119
141
|
clipCompactText
|
|
120
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-Z4QSJILV.js";
|
|
121
143
|
import {
|
|
122
144
|
findModelConfig
|
|
123
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-MMZ6ZTVO.js";
|
|
124
146
|
import {
|
|
125
147
|
compactWhitespace
|
|
126
148
|
} from "./chunk-DWLEOOGR.js";
|
|
@@ -133,7 +155,7 @@ import {
|
|
|
133
155
|
buildMemoryUseGuidanceLayer,
|
|
134
156
|
partitionScopedBlocks,
|
|
135
157
|
renderTurnContextBlocksWithScope
|
|
136
|
-
} from "./chunk-
|
|
158
|
+
} from "./chunk-DVINR3PL.js";
|
|
137
159
|
import {
|
|
138
160
|
readPipeText,
|
|
139
161
|
spawnProcess
|
|
@@ -145,13 +167,13 @@ import {
|
|
|
145
167
|
CLIENT_VERSION_TOO_OLD_CODE,
|
|
146
168
|
NOLO_CLIENT_VERSION_HEADER,
|
|
147
169
|
buildClientVersionUpgradeMessage
|
|
148
|
-
} from "./chunk-
|
|
170
|
+
} from "./chunk-22BTGNSP.js";
|
|
149
171
|
import {
|
|
150
172
|
parsePositiveFiniteNumberOrFallback
|
|
151
173
|
} from "./chunk-Y5GCAMGP.js";
|
|
152
174
|
import {
|
|
153
175
|
createMemoryKey
|
|
154
|
-
} from "./chunk-
|
|
176
|
+
} from "./chunk-NHRQCXIQ.js";
|
|
155
177
|
import {
|
|
156
178
|
asTrimmedLowercaseString
|
|
157
179
|
} from "./chunk-QSJ3HFEF.js";
|
|
@@ -159,21 +181,19 @@ import {
|
|
|
159
181
|
BUILTIN_NOLO_AGENT_KEY,
|
|
160
182
|
BUILTIN_NOLO_AGENT_NAME,
|
|
161
183
|
builtinAgentCatalogEntryById
|
|
162
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-L7B47JXR.js";
|
|
163
185
|
import {
|
|
164
186
|
parsePublicAgentId
|
|
165
187
|
} from "./chunk-BJIRLHJR.js";
|
|
166
188
|
import {
|
|
167
189
|
asTrimmedString
|
|
168
190
|
} from "./chunk-3EUW3WEO.js";
|
|
169
|
-
import {
|
|
170
|
-
isLoopbackUrl
|
|
171
|
-
} from "./chunk-4SN6J65J.js";
|
|
172
191
|
import {
|
|
173
192
|
asOptionalTrimmedString
|
|
174
193
|
} from "./chunk-G3SUCT4W.js";
|
|
175
194
|
|
|
176
195
|
// packages/cli/client/tokenUsage.ts
|
|
196
|
+
var PLATFORM_CREDIT_UNIT = "credits";
|
|
177
197
|
var isUsableModelId = (model) => {
|
|
178
198
|
const raw = model?.trim();
|
|
179
199
|
return Boolean(raw) && raw !== "-" && raw !== "auto";
|
|
@@ -245,7 +265,7 @@ function buildTurnTokenUsage(usage, model) {
|
|
|
245
265
|
const contextWindow = resolveContextWindow(model);
|
|
246
266
|
const remaining = contextWindow && parsed.input > 0 ? Math.max(0, contextWindow - parsed.input) : void 0;
|
|
247
267
|
const rawCost = typeof usage?.cost === "number" ? usage.cost : void 0;
|
|
248
|
-
const isPlatformBilled = usage?.billing_unit ===
|
|
268
|
+
const isPlatformBilled = usage?.billing_unit === PLATFORM_CREDIT_UNIT;
|
|
249
269
|
const credits = rawCost !== void 0 && rawCost > 0 ? isPlatformBilled ? rawCost : rawCost * API_REPORTED_COST_MULTIPLIER : void 0;
|
|
250
270
|
return {
|
|
251
271
|
...parsed,
|
|
@@ -254,6 +274,31 @@ function buildTurnTokenUsage(usage, model) {
|
|
|
254
274
|
...credits !== void 0 ? { credits } : {}
|
|
255
275
|
};
|
|
256
276
|
}
|
|
277
|
+
function sumPlatformCredits(records) {
|
|
278
|
+
if (!records?.length) return void 0;
|
|
279
|
+
let total = 0;
|
|
280
|
+
let sawPlatformCall = false;
|
|
281
|
+
for (const record of records) {
|
|
282
|
+
const credits = platformCreditsFromUsage(record?.usage);
|
|
283
|
+
if (credits === void 0) continue;
|
|
284
|
+
sawPlatformCall = true;
|
|
285
|
+
total += credits;
|
|
286
|
+
}
|
|
287
|
+
return sawPlatformCall ? total : void 0;
|
|
288
|
+
}
|
|
289
|
+
function platformCreditsFromUsage(usage) {
|
|
290
|
+
if (!usage || usage.billing_unit !== PLATFORM_CREDIT_UNIT) return void 0;
|
|
291
|
+
const cost = typeof usage.cost === "number" ? usage.cost : 0;
|
|
292
|
+
return Number.isFinite(cost) && cost > 0 ? cost : 0;
|
|
293
|
+
}
|
|
294
|
+
function withTurnCredits(tokens, credits) {
|
|
295
|
+
if (!tokens) return tokens;
|
|
296
|
+
if (credits === void 0) return tokens;
|
|
297
|
+
return { ...tokens, credits };
|
|
298
|
+
}
|
|
299
|
+
function formatCreditsChip(credits, options) {
|
|
300
|
+
return options?.compact ? `\u26A1${credits.toFixed(2)}` : `\u26A1 ${credits.toFixed(2)} \u79EF\u5206`;
|
|
301
|
+
}
|
|
257
302
|
function formatTokenCount(value) {
|
|
258
303
|
if (!Number.isFinite(value) || value < 0) return "\u2014";
|
|
259
304
|
if (value < 1e3) return String(Math.round(value));
|
|
@@ -1098,7 +1143,7 @@ var THEME_PALETTES = {
|
|
|
1098
1143
|
// denser slate — 687584 read too blue in dense prose (inline code/tool labels); 5E6A78 pulls blue down while staying darker than the old value
|
|
1099
1144
|
},
|
|
1100
1145
|
dark: {
|
|
1101
|
-
accent: { hex: "5BA3D9", ansiFallback: "\x1B[
|
|
1146
|
+
accent: { hex: "5BA3D9", ansiFallback: "\x1B[94m" },
|
|
1102
1147
|
// trail dark primary (was wrongly copied from catppuccin 89B4FA)
|
|
1103
1148
|
chrome: { hex: "6C7086", ansiFallback: "\x1B[90m" },
|
|
1104
1149
|
success: { hex: "5CB87A", ansiFallback: "\x1B[32m" },
|
|
@@ -1124,7 +1169,7 @@ var THEME_PALETTES = {
|
|
|
1124
1169
|
muted: { hex: "6E7781", ansiFallback: "\x1B[90m" }
|
|
1125
1170
|
},
|
|
1126
1171
|
dark: {
|
|
1127
|
-
accent: { hex: "89B4FA", ansiFallback: "\x1B[
|
|
1172
|
+
accent: { hex: "89B4FA", ansiFallback: "\x1B[94m" },
|
|
1128
1173
|
// Catppuccin Mocha Blue
|
|
1129
1174
|
chrome: { hex: "6C7086", ansiFallback: "\x1B[90m" },
|
|
1130
1175
|
success: { hex: "A6E3A1", ansiFallback: "\x1B[32m" },
|
|
@@ -1146,7 +1191,7 @@ var THEME_PALETTES = {
|
|
|
1146
1191
|
muted: { hex: "716E61", ansiFallback: "\x1B[90m" }
|
|
1147
1192
|
},
|
|
1148
1193
|
dark: {
|
|
1149
|
-
accent: { hex: "7E9CD8", ansiFallback: "\x1B[
|
|
1194
|
+
accent: { hex: "7E9CD8", ansiFallback: "\x1B[94m" },
|
|
1150
1195
|
// crystalBlue
|
|
1151
1196
|
chrome: { hex: "727169", ansiFallback: "\x1B[90m" },
|
|
1152
1197
|
success: { hex: "98BB6C", ansiFallback: "\x1B[32m" },
|
|
@@ -1167,7 +1212,7 @@ var THEME_PALETTES = {
|
|
|
1167
1212
|
muted: { hex: "6E6A8A", ansiFallback: "\x1B[90m" }
|
|
1168
1213
|
},
|
|
1169
1214
|
dark: {
|
|
1170
|
-
accent: { hex: "8B9CF4", ansiFallback: "\x1B[
|
|
1215
|
+
accent: { hex: "8B9CF4", ansiFallback: "\x1B[94m" },
|
|
1171
1216
|
chrome: { hex: "5A5772", ansiFallback: "\x1B[90m" },
|
|
1172
1217
|
success: { hex: "26BD6C", ansiFallback: "\x1B[32m" },
|
|
1173
1218
|
warning: { hex: "F5A623", ansiFallback: "\x1B[33m" },
|
|
@@ -1187,7 +1232,7 @@ var THEME_PALETTES = {
|
|
|
1187
1232
|
muted: { hex: "797593", ansiFallback: "\x1B[90m" }
|
|
1188
1233
|
},
|
|
1189
1234
|
dark: {
|
|
1190
|
-
accent: { hex: "EB6F92", ansiFallback: "\x1B[
|
|
1235
|
+
accent: { hex: "EB6F92", ansiFallback: "\x1B[95m" },
|
|
1191
1236
|
chrome: { hex: "6E6A86", ansiFallback: "\x1B[90m" },
|
|
1192
1237
|
success: { hex: "9CCFD8", ansiFallback: "\x1B[32m" },
|
|
1193
1238
|
warning: { hex: "F6C177", ansiFallback: "\x1B[33m" },
|
|
@@ -1271,6 +1316,9 @@ function detectSystemBrightnessFromEnv(env = process.env) {
|
|
|
1271
1316
|
return null;
|
|
1272
1317
|
}
|
|
1273
1318
|
function resolveTuiBrightness(env = process.env) {
|
|
1319
|
+
return resolveTuiBrightnessSignal(env) ?? "dark";
|
|
1320
|
+
}
|
|
1321
|
+
function resolveTuiBrightnessSignal(env = process.env) {
|
|
1274
1322
|
const explicit = (env.NOLO_TUI_THEME ?? "").trim().toLowerCase();
|
|
1275
1323
|
if (explicit === "light") return "light";
|
|
1276
1324
|
if (explicit === "dark") return "dark";
|
|
@@ -1283,9 +1331,7 @@ function resolveTuiBrightness(env = process.env) {
|
|
|
1283
1331
|
if (!Number.isNaN(bg) && bg >= 0 && bg <= 6) return "dark";
|
|
1284
1332
|
if (!Number.isNaN(bg) && bg >= 7 && bg <= 15) return "light";
|
|
1285
1333
|
}
|
|
1286
|
-
|
|
1287
|
-
if (sys) return sys;
|
|
1288
|
-
return "dark";
|
|
1334
|
+
return detectSystemBrightnessFromEnv(env);
|
|
1289
1335
|
}
|
|
1290
1336
|
function resolveTuiThemeMode(env = process.env, fallback = activeThemeMode) {
|
|
1291
1337
|
const explicit = (env.NOLO_TUI_THEME ?? "").trim().toLowerCase();
|
|
@@ -2908,6 +2954,14 @@ function normalizeListLine(line) {
|
|
|
2908
2954
|
}
|
|
2909
2955
|
return line;
|
|
2910
2956
|
}
|
|
2957
|
+
function isPolishListLikeLine(line) {
|
|
2958
|
+
return LIST_LIKE_RE_FOR_GUARD.test(normalizeListLine(line));
|
|
2959
|
+
}
|
|
2960
|
+
var LIST_LIKE_RE_FOR_GUARD = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2961
|
+
function polishBreathInsertsBlankBetween(cur, next) {
|
|
2962
|
+
if (cur === "" || next === "") return false;
|
|
2963
|
+
return isPolishListLikeLine(cur) !== isPolishListLikeLine(next);
|
|
2964
|
+
}
|
|
2911
2965
|
function convertMarkdownTablesForTerminal(text) {
|
|
2912
2966
|
const lines = text.split("\n");
|
|
2913
2967
|
const out = [];
|
|
@@ -2975,7 +3029,7 @@ function polishAssistantStructure(text, options = {}) {
|
|
|
2975
3029
|
return line;
|
|
2976
3030
|
});
|
|
2977
3031
|
const afterHeading = maskedLines.join("\n").replace(/([^\n])\n(#{1,3} )/g, "$1\n\n$2").replace(/^(#{1,3} .+)\n(?!\n)/gm, "$1\n\n").replace(/\n{4,}/g, "\n\n\n");
|
|
2978
|
-
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]/;
|
|
3032
|
+
const LIST_LIKE = /^\s*(?:•|☐|☑|\d+\.)\s|^\s*[\u2460-\u2473]|^\s*[├└]──\s/;
|
|
2979
3033
|
const headingLines = afterHeading.split("\n");
|
|
2980
3034
|
const breathed = [];
|
|
2981
3035
|
for (let i = 0; i < headingLines.length; i++) {
|
|
@@ -3333,130 +3387,16 @@ function formatAssistantTextForCli(text) {
|
|
|
3333
3387
|
return text.replace(/\u003cthink\u003e[\s\S]*?\u003c\/think\u003e\s*/gi, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
3334
3388
|
}
|
|
3335
3389
|
|
|
3336
|
-
// packages/cli/
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
}
|
|
3347
|
-
return path.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
3348
|
-
}
|
|
3349
|
-
|
|
3350
|
-
// packages/cli/client/formatReadPathTree.ts
|
|
3351
|
-
function clipPathAware(value, max = 72) {
|
|
3352
|
-
const compact = compactWhitespace(value);
|
|
3353
|
-
if (compact.length <= max) return compact;
|
|
3354
|
-
if (compact.includes(" ") || !compact.includes("/") && !compact.includes("\\")) {
|
|
3355
|
-
return clipCompactText(value, max, "\u2026");
|
|
3356
|
-
}
|
|
3357
|
-
const segments = compact.split(/[/\\]/);
|
|
3358
|
-
const filename = segments[segments.length - 1];
|
|
3359
|
-
if (filename.length >= max) {
|
|
3360
|
-
return clipCompactText(value, max, "\u2026");
|
|
3361
|
-
}
|
|
3362
|
-
const ELISION = "/\u2026/";
|
|
3363
|
-
let prefix = "";
|
|
3364
|
-
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3365
|
-
const candidate = segments.slice(0, i + 1).join("/");
|
|
3366
|
-
if (candidate.length + ELISION.length + filename.length > max) break;
|
|
3367
|
-
prefix = candidate;
|
|
3368
|
-
}
|
|
3369
|
-
if (prefix) return `${prefix}${ELISION}${filename}`;
|
|
3370
|
-
const filenameOnly = `\u2026/${filename}`;
|
|
3371
|
-
if (filenameOnly.length <= max) return filenameOnly;
|
|
3372
|
-
return clipCompactText(value, max, "\u2026");
|
|
3373
|
-
}
|
|
3374
|
-
function formatHomePath(path, customHomedir) {
|
|
3375
|
-
if (!path) return "";
|
|
3376
|
-
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
3377
|
-
return foldHomePath(path, home);
|
|
3378
|
-
}
|
|
3379
|
-
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
3380
|
-
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
3381
|
-
let formattedPath = formatHomePath(inputPath, customHomedir);
|
|
3382
|
-
if (!formattedPath) return "file";
|
|
3383
|
-
let rangePart = "";
|
|
3384
|
-
const match = formattedPath.match(/(:[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*)$/);
|
|
3385
|
-
if (match) {
|
|
3386
|
-
rangePart = match[1];
|
|
3387
|
-
formattedPath = formattedPath.slice(0, -rangePart.length);
|
|
3388
|
-
} else if (metadata && typeof metadata.startLine === "number" && typeof metadata.endLine === "number" && typeof metadata.totalLines === "number") {
|
|
3389
|
-
const { startLine, endLine, totalLines, truncated } = metadata;
|
|
3390
|
-
if (truncated || startLine !== 1 || endLine !== totalLines) {
|
|
3391
|
-
rangePart = `:${startLine}-${endLine}`;
|
|
3392
|
-
}
|
|
3393
|
-
}
|
|
3394
|
-
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3395
|
-
return `${clippedPath}${rangePart}`;
|
|
3396
|
-
}
|
|
3397
|
-
function formatReadTreeLines(items, customHomedir) {
|
|
3398
|
-
const count = items.length;
|
|
3399
|
-
const header = `Read (${count})`;
|
|
3400
|
-
const lines = items.map((item, index) => {
|
|
3401
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3402
|
-
const pathWithRange = formatReadItemPath(item.path, item.metadata, customHomedir);
|
|
3403
|
-
return { connector, pathWithRange };
|
|
3404
|
-
});
|
|
3405
|
-
return { header, count, lines };
|
|
3406
|
-
}
|
|
3407
|
-
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3408
|
-
let text = (query || "").trim();
|
|
3409
|
-
if (path) {
|
|
3410
|
-
const formattedPath = formatHomePath(path, customHomedir);
|
|
3411
|
-
if (formattedPath) {
|
|
3412
|
-
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
3413
|
-
}
|
|
3414
|
-
}
|
|
3415
|
-
if (!text) return "search";
|
|
3416
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3417
|
-
}
|
|
3418
|
-
function formatSearchTreeLines(items, customHomedir) {
|
|
3419
|
-
const count = items.length;
|
|
3420
|
-
const header = `Search (${count})`;
|
|
3421
|
-
const lines = items.map((item, index) => {
|
|
3422
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3423
|
-
const queryText = formatSearchItemQuery(item.query, item.path, customHomedir);
|
|
3424
|
-
return { connector, queryText };
|
|
3425
|
-
});
|
|
3426
|
-
return { header, count, lines };
|
|
3427
|
-
}
|
|
3428
|
-
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3429
|
-
let text = compactWhitespace(command || "");
|
|
3430
|
-
if (!text) text = "command";
|
|
3431
|
-
text = text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3432
|
-
if (timedOut) return `${text} (timed out)`;
|
|
3433
|
-
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3434
|
-
return text;
|
|
3435
|
-
}
|
|
3436
|
-
function formatRunTreeLines(items) {
|
|
3437
|
-
const count = items.length;
|
|
3438
|
-
const header = `Run (${count})`;
|
|
3439
|
-
const lines = items.map((item, index) => {
|
|
3440
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3441
|
-
const commandText = formatRunItemCommand(item.command, item.exitCode, item.timedOut);
|
|
3442
|
-
return { connector, commandText };
|
|
3443
|
-
});
|
|
3444
|
-
return { header, count, lines };
|
|
3445
|
-
}
|
|
3446
|
-
function formatFetchItemUrl(url) {
|
|
3447
|
-
const text = (url || "").trim();
|
|
3448
|
-
if (!text) return "webpage";
|
|
3449
|
-
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3450
|
-
}
|
|
3451
|
-
function formatFetchTreeLines(items) {
|
|
3452
|
-
const count = items.length;
|
|
3453
|
-
const header = `Fetch (${count})`;
|
|
3454
|
-
const lines = items.map((item, index) => {
|
|
3455
|
-
const connector = index === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
3456
|
-
const urlText = formatFetchItemUrl(item.url);
|
|
3457
|
-
return { connector, urlText };
|
|
3458
|
-
});
|
|
3459
|
-
return { header, count, lines };
|
|
3390
|
+
// packages/cli/tui/redactSecrets.ts
|
|
3391
|
+
var REDACTED = "\u27E8redacted\u27E9";
|
|
3392
|
+
function redactSecrets(text) {
|
|
3393
|
+
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(
|
|
3394
|
+
/\b((?:api[_-]?key|apikey|access[_-]?token|auth[_-]?token|token|secret|password|passwd|credential)s?\s*[=:]\s*["']?)[^\s"',;]{8,}/gi,
|
|
3395
|
+
`$1${REDACTED}`
|
|
3396
|
+
).replace(
|
|
3397
|
+
/\b((?:--[a-z-]*(?:token|key|secret|password|credential)[a-z-]*)\s+)[^\s"']{8,}/gi,
|
|
3398
|
+
`$1${REDACTED}`
|
|
3399
|
+
);
|
|
3460
3400
|
}
|
|
3461
3401
|
|
|
3462
3402
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -3709,186 +3649,110 @@ function tokenize(value, options) {
|
|
|
3709
3649
|
return retLines;
|
|
3710
3650
|
}
|
|
3711
3651
|
|
|
3712
|
-
// packages/cli/client/
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3652
|
+
// packages/cli/client/formatReadPathTree.ts
|
|
3653
|
+
import { homedir as osHomedir } from "node:os";
|
|
3654
|
+
|
|
3655
|
+
// packages/core/foldHomePath.ts
|
|
3656
|
+
function foldHomePath(path, home) {
|
|
3657
|
+
if (!path) return path;
|
|
3658
|
+
if (home) {
|
|
3659
|
+
const cleanHome = home.endsWith("/") ? home.slice(0, -1) : home;
|
|
3660
|
+
if (path === cleanHome) return "~";
|
|
3661
|
+
if (path.startsWith(cleanHome + "/")) return `~${path.slice(cleanHome.length)}`;
|
|
3717
3662
|
}
|
|
3718
|
-
|
|
3719
|
-
|
|
3663
|
+
return path.replace(/^(\/Users\/[^/]+|\/home\/[^/]+)(\/|$)/, "~$2");
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
// packages/cli/client/formatReadPathTree.ts
|
|
3667
|
+
function clipPathAware(value, max = 72) {
|
|
3668
|
+
const compact = compactWhitespace(value);
|
|
3669
|
+
if (compact.length <= max) return compact;
|
|
3670
|
+
if (compact.includes(" ") || !compact.includes("/") && !compact.includes("\\")) {
|
|
3671
|
+
return clipCompactText(value, max, "\u2026");
|
|
3720
3672
|
}
|
|
3721
|
-
|
|
3722
|
-
|
|
3673
|
+
const segments = compact.split(/[/\\]/);
|
|
3674
|
+
const filename = segments[segments.length - 1];
|
|
3675
|
+
if (filename.length >= max) {
|
|
3676
|
+
return clipCompactText(value, max, "\u2026");
|
|
3723
3677
|
}
|
|
3724
|
-
|
|
3725
|
-
|
|
3678
|
+
const ELISION = "/\u2026/";
|
|
3679
|
+
let prefix = "";
|
|
3680
|
+
for (let i = 0; i < segments.length - 1; i += 1) {
|
|
3681
|
+
const candidate = segments.slice(0, i + 1).join("/");
|
|
3682
|
+
if (candidate.length + ELISION.length + filename.length > max) break;
|
|
3683
|
+
prefix = candidate;
|
|
3726
3684
|
}
|
|
3727
|
-
return
|
|
3685
|
+
if (prefix) return `${prefix}${ELISION}${filename}`;
|
|
3686
|
+
const filenameOnly = `\u2026/${filename}`;
|
|
3687
|
+
if (filenameOnly.length <= max) return filenameOnly;
|
|
3688
|
+
return clipCompactText(value, max, "\u2026");
|
|
3689
|
+
}
|
|
3690
|
+
function formatHomePath(path, customHomedir) {
|
|
3691
|
+
if (!path) return "";
|
|
3692
|
+
const home = customHomedir || (typeof process !== "undefined" ? process.env?.HOME : void 0) || (typeof osHomedir === "function" ? osHomedir() : "");
|
|
3693
|
+
return foldHomePath(path, home);
|
|
3728
3694
|
}
|
|
3729
|
-
function
|
|
3730
|
-
const
|
|
3731
|
-
|
|
3732
|
-
|
|
3695
|
+
function formatReadItemPath(rawPath, metadata, customHomedir) {
|
|
3696
|
+
const inputPath = rawPath || (typeof metadata?.path === "string" ? metadata.path : void 0) || (typeof metadata?.filePath === "string" ? metadata.filePath : void 0) || "file";
|
|
3697
|
+
let formattedPath = formatHomePath(inputPath, customHomedir);
|
|
3698
|
+
if (!formattedPath) return "file";
|
|
3699
|
+
let rangePart = "";
|
|
3700
|
+
const match = formattedPath.match(/(:[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*)$/);
|
|
3701
|
+
if (match) {
|
|
3702
|
+
rangePart = match[1];
|
|
3703
|
+
formattedPath = formattedPath.slice(0, -rangePart.length);
|
|
3704
|
+
} else if (metadata && typeof metadata.startLine === "number" && typeof metadata.endLine === "number" && typeof metadata.totalLines === "number") {
|
|
3705
|
+
const { startLine, endLine, totalLines, truncated } = metadata;
|
|
3706
|
+
if (truncated || startLine !== 1 || endLine !== totalLines) {
|
|
3707
|
+
rangePart = `:${startLine}-${endLine}`;
|
|
3708
|
+
}
|
|
3733
3709
|
}
|
|
3734
|
-
|
|
3735
|
-
|
|
3710
|
+
const clippedPath = clipPathAware(formattedPath, 72);
|
|
3711
|
+
return `${clippedPath}${rangePart}`;
|
|
3712
|
+
}
|
|
3713
|
+
function formatSearchItemQuery(query, path, customHomedir) {
|
|
3714
|
+
let text = (query || "").trim();
|
|
3715
|
+
if (path) {
|
|
3716
|
+
const formattedPath = formatHomePath(path, customHomedir);
|
|
3717
|
+
if (formattedPath) {
|
|
3718
|
+
text = text ? `${text} in ${formattedPath}` : formattedPath;
|
|
3719
|
+
}
|
|
3736
3720
|
}
|
|
3737
|
-
|
|
3721
|
+
if (!text) return "search";
|
|
3722
|
+
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3723
|
+
}
|
|
3724
|
+
function formatRunItemCommand(command, exitCode, timedOut) {
|
|
3725
|
+
let text = compactWhitespace(command || "");
|
|
3726
|
+
if (!text) text = "command";
|
|
3727
|
+
text = text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3728
|
+
if (timedOut) return `${text} (timed out)`;
|
|
3729
|
+
if (typeof exitCode === "number" && exitCode !== 0) return `${text} (exit ${exitCode})`;
|
|
3730
|
+
return text;
|
|
3738
3731
|
}
|
|
3739
|
-
function
|
|
3740
|
-
|
|
3732
|
+
function formatFetchItemUrl(url) {
|
|
3733
|
+
const text = (url || "").trim();
|
|
3734
|
+
if (!text) return "webpage";
|
|
3735
|
+
return text.length > 80 ? `${text.slice(0, 79)}\u2026` : text;
|
|
3741
3736
|
}
|
|
3737
|
+
|
|
3738
|
+
// packages/cli/client/toolOutput.ts
|
|
3742
3739
|
function clip(value, max = 72) {
|
|
3743
3740
|
return clipCompactText(value, max, "\u2026");
|
|
3744
3741
|
}
|
|
3745
|
-
function formatActiveToolLabel(event) {
|
|
3746
|
-
const toolName = event.toolName || "tool";
|
|
3747
|
-
const args = clipPathAware(event.argumentsPreview ?? "");
|
|
3748
|
-
const label = toolLabel(toolName);
|
|
3749
|
-
return args ? `${label} ${args}` : label;
|
|
3750
|
-
}
|
|
3751
3742
|
function formatConservativeActiveToolLabel(event) {
|
|
3752
3743
|
return toolLabel(event.toolName || "tool");
|
|
3753
3744
|
}
|
|
3754
|
-
function
|
|
3755
|
-
|
|
3756
|
-
if (gate) {
|
|
3757
|
-
const commandPayload = gate.kind === "handoff" ? readCommandActionGatePayload(gate.payload) : null;
|
|
3758
|
-
const command = commandPayload?.displayCommand ?? commandPayload?.command.join(" ") ?? "";
|
|
3759
|
-
const detail = command.trim() ? command : gate.title;
|
|
3760
|
-
return { inline: `${t("toolNeedsAction")}: ${clip(detail, 120)}` };
|
|
3761
|
-
}
|
|
3762
|
-
if (event.metadata?.timedOut) return { inline: t("toolTimedOut") };
|
|
3763
|
-
if (event.toolName === "readFile" && event.metadata) {
|
|
3764
|
-
const range = readReadFileRange(event.metadata);
|
|
3765
|
-
if (range) return { inline: range };
|
|
3766
|
-
}
|
|
3767
|
-
if (event.toolName === "editFile" && event.metadata) {
|
|
3768
|
-
const res = formatEditFileSnippet(event.metadata);
|
|
3769
|
-
if (res) {
|
|
3770
|
-
const stats = [];
|
|
3771
|
-
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
3772
|
-
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
3773
|
-
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
3774
|
-
return { inline, detail: res.lines };
|
|
3775
|
-
}
|
|
3776
|
-
}
|
|
3777
|
-
if (event.toolName === "writeFile" && event.metadata) {
|
|
3778
|
-
const totalLines = event.metadata.totalLines ?? event.metadata.lines;
|
|
3779
|
-
if (typeof totalLines === "number" && totalLines > 0) {
|
|
3780
|
-
return { inline: `(+${totalLines})` };
|
|
3781
|
-
}
|
|
3782
|
-
}
|
|
3783
|
-
const summary = event.summary;
|
|
3784
|
-
if (!summary) return { inline: "" };
|
|
3785
|
-
const exitMatch = summary.match(/exit=(\d+)/);
|
|
3786
|
-
if (exitMatch && exitMatch[1] !== "0") return { inline: `${t("toolExitCode")} ${exitMatch[1]}` };
|
|
3787
|
-
return { inline: "" };
|
|
3788
|
-
}
|
|
3789
|
-
function readReadFileRange(metadata) {
|
|
3790
|
-
const startLine = metadata.startLine;
|
|
3791
|
-
const endLine = metadata.endLine;
|
|
3792
|
-
const totalLines = metadata.totalLines;
|
|
3793
|
-
const truncated = metadata.truncated;
|
|
3794
|
-
if (typeof startLine !== "number" || typeof endLine !== "number" || typeof totalLines !== "number") {
|
|
3795
|
-
return void 0;
|
|
3796
|
-
}
|
|
3797
|
-
if (!truncated && startLine === 1 && endLine === totalLines) return void 0;
|
|
3798
|
-
return `${startLine}-${endLine}/${totalLines}`;
|
|
3799
|
-
}
|
|
3800
|
-
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
3801
|
-
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
3802
|
-
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
3803
|
-
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
3804
|
-
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
3805
|
-
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
3806
|
-
}
|
|
3807
|
-
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
3808
|
-
if (cols > 0) {
|
|
3809
|
-
return Math.max(80, Math.min(160, cols - 8));
|
|
3810
|
-
}
|
|
3811
|
-
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
3745
|
+
function isRunToolName(name) {
|
|
3746
|
+
return name === "execShell" || name === "runCommand" || name === "launchProcess";
|
|
3812
3747
|
}
|
|
3813
|
-
function
|
|
3814
|
-
|
|
3815
|
-
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
3816
|
-
if (!oldSnippet && !newSnippet) return void 0;
|
|
3817
|
-
const maxWidth = resolveEditSnippetMaxWidth();
|
|
3818
|
-
if (oldSnippet && !newSnippet) {
|
|
3819
|
-
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
3820
|
-
return { lines, addedCount: 0, removedCount: lines.length };
|
|
3821
|
-
}
|
|
3822
|
-
if (newSnippet && !oldSnippet) {
|
|
3823
|
-
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
3824
|
-
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
3825
|
-
}
|
|
3826
|
-
const parts = diffLines(oldSnippet, newSnippet);
|
|
3827
|
-
const all = [];
|
|
3828
|
-
let addedCount = 0;
|
|
3829
|
-
let removedCount = 0;
|
|
3830
|
-
for (const part of parts) {
|
|
3831
|
-
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
3832
|
-
const raw = part.value.split("\n");
|
|
3833
|
-
if (raw.length > 0 && raw[raw.length - 1] === "") raw.pop();
|
|
3834
|
-
for (const line of raw) {
|
|
3835
|
-
if (kind === "added") addedCount++;
|
|
3836
|
-
if (kind === "removed") removedCount++;
|
|
3837
|
-
all.push(buildEditLine(kind, line, maxWidth));
|
|
3838
|
-
}
|
|
3839
|
-
}
|
|
3840
|
-
const changeCount = all.filter((l) => l.kind !== "context").length;
|
|
3841
|
-
if (changeCount === 0) return void 0;
|
|
3842
|
-
return {
|
|
3843
|
-
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
3844
|
-
addedCount,
|
|
3845
|
-
removedCount
|
|
3846
|
-
};
|
|
3748
|
+
function isReadToolName(name) {
|
|
3749
|
+
return name === "readFile";
|
|
3847
3750
|
}
|
|
3848
|
-
function
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
return
|
|
3853
|
-
}
|
|
3854
|
-
function snippetLinesWithKind(snippet, kind, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
3855
|
-
const lines = snippet.split(/\r?\n/).filter((line) => line.length > 0);
|
|
3856
|
-
return lines.slice(0, EDIT_SNIPPET_MAX_LINES).map((line) => buildEditLine(kind, line, maxWidth));
|
|
3857
|
-
}
|
|
3858
|
-
function truncateByDisplayWidth(line, maxWidth) {
|
|
3859
|
-
if (displayWidth(line) <= maxWidth) return line;
|
|
3860
|
-
let width = 0;
|
|
3861
|
-
let kept = "";
|
|
3862
|
-
for (const char of line) {
|
|
3863
|
-
const w = displayWidth(char);
|
|
3864
|
-
if (width + w + 1 > maxWidth) break;
|
|
3865
|
-
kept += char;
|
|
3866
|
-
width += w;
|
|
3867
|
-
}
|
|
3868
|
-
return `${kept}\u2026`;
|
|
3869
|
-
}
|
|
3870
|
-
function windowAndTruncate(lines, maxLines) {
|
|
3871
|
-
if (lines.length <= maxLines) return lines;
|
|
3872
|
-
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
3873
|
-
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
3874
|
-
const half = Math.floor(maxLines / 2);
|
|
3875
|
-
let start = Math.max(0, firstChange - half);
|
|
3876
|
-
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
3877
|
-
const kept = lines.slice(start, start + maxLines);
|
|
3878
|
-
const omitted = lines.length - kept.length;
|
|
3879
|
-
if (omitted > 0) {
|
|
3880
|
-
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
3881
|
-
}
|
|
3882
|
-
return kept;
|
|
3883
|
-
}
|
|
3884
|
-
function isFailedToolResult(event) {
|
|
3885
|
-
const exitCode = event.metadata?.exitCode;
|
|
3886
|
-
if (event.metadata?.actionGate) return false;
|
|
3887
|
-
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3888
|
-
return Boolean(event.metadata?.timedOut);
|
|
3889
|
-
}
|
|
3890
|
-
function isNeedsActionToolResult(event) {
|
|
3891
|
-
return Boolean(event.metadata?.actionGate);
|
|
3751
|
+
function isFailedToolResult(event) {
|
|
3752
|
+
const exitCode = event.metadata?.exitCode;
|
|
3753
|
+
if (event.metadata?.actionGate) return false;
|
|
3754
|
+
if (typeof exitCode === "number" && exitCode !== 0) return true;
|
|
3755
|
+
return Boolean(event.metadata?.timedOut);
|
|
3892
3756
|
}
|
|
3893
3757
|
function parseUiAskChoiceForCli(event) {
|
|
3894
3758
|
if (event.toolName !== "ask_user" && !event.metadata?.uiAskChoice) {
|
|
@@ -4006,7 +3870,10 @@ function renderRunCard(snapshot, opts) {
|
|
|
4006
3870
|
lastToolNames: snapshot.lastToolNames?.map(cleanUserText)
|
|
4007
3871
|
} : snapshot;
|
|
4008
3872
|
const hadError = safe && Boolean(source.errorMessage?.trim());
|
|
4009
|
-
const errorFields = safe ? {
|
|
3873
|
+
const errorFields = safe ? {
|
|
3874
|
+
errorMessage: hadError ? clip(redactSecrets(cleanUserText(source.errorMessage)), 160) : void 0,
|
|
3875
|
+
logLines: void 0
|
|
3876
|
+
} : { errorMessage: source.errorMessage, logLines: source.logLines };
|
|
4010
3877
|
const body = isAgentRunTerminalStatus(snapshot.status) ? formatFinishedRunCard(name, snapshot.status, {
|
|
4011
3878
|
runId: snapshot.runId,
|
|
4012
3879
|
toolCallCount: source.toolCallCount,
|
|
@@ -4026,8 +3893,7 @@ function renderRunCard(snapshot, opts) {
|
|
|
4026
3893
|
...opts?.includeLogTail !== void 0 ? { includeLogTail: opts.includeLogTail } : {},
|
|
4027
3894
|
labels
|
|
4028
3895
|
});
|
|
4029
|
-
return
|
|
4030
|
-
error ${t("runDiagnosticsHidden")}` : body;
|
|
3896
|
+
return body;
|
|
4031
3897
|
}
|
|
4032
3898
|
function recoverOrchestrationCard(event, toolName, opts) {
|
|
4033
3899
|
const safe = opts?.safe === true;
|
|
@@ -4073,10 +3939,6 @@ function recoverOrchestrationCard(event, toolName, opts) {
|
|
|
4073
3939
|
if (kind === "stop") return formatStopRunCard(snapshot.status, labels);
|
|
4074
3940
|
return renderRunCard(snapshot, opts);
|
|
4075
3941
|
}
|
|
4076
|
-
function parseControlAgentRunStatusEvent(event) {
|
|
4077
|
-
const parsed = parseAgentRunEvent(event);
|
|
4078
|
-
return parsed?.kind === "status" ? parsed.snapshot : null;
|
|
4079
|
-
}
|
|
4080
3942
|
function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
4081
3943
|
const safe = opts?.safe === true;
|
|
4082
3944
|
const rawLabel = toolLabel(toolName);
|
|
@@ -4084,8 +3946,8 @@ function formatOrchestrationCardBlock(event, toolName, colorEnabled, opts) {
|
|
|
4084
3946
|
const rawDataStr = recoverOrchestrationCard(event, toolName, { safe }) || bakedCard || (typeof event.content === "string" ? event.content : "");
|
|
4085
3947
|
const failed = event.type === "tool-error" || isFailedToolResult(event) || Boolean(event.metadata?.failed) || /^Error:/i.test(rawDataStr.trim());
|
|
4086
3948
|
if (failed) {
|
|
4087
|
-
const firstLine =
|
|
4088
|
-
const message = clip(firstLine, 96);
|
|
3949
|
+
const firstLine = stripAnsi2(rawDataStr.trim().split("\n")[0] || event.summary || event.message || t("toolFailed"));
|
|
3950
|
+
const message = clip(redactSecrets(firstLine), 96);
|
|
4089
3951
|
if (!colorEnabled) {
|
|
4090
3952
|
return `\u2717 ${rawLabel} ${message}
|
|
4091
3953
|
`;
|
|
@@ -4127,7 +3989,7 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4127
3989
|
break;
|
|
4128
3990
|
}
|
|
4129
3991
|
if (/^\s*error\b/i.test(line)) {
|
|
4130
|
-
out.push(
|
|
3992
|
+
out.push(clip(redactSecrets(stripAnsi2(line)), 160));
|
|
4131
3993
|
errorIndent = line.length - line.trimStart().length;
|
|
4132
3994
|
continue;
|
|
4133
3995
|
}
|
|
@@ -4146,59 +4008,207 @@ function sanitizeRunCardForNormal(lines) {
|
|
|
4146
4008
|
}
|
|
4147
4009
|
return out;
|
|
4148
4010
|
}
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
logLines: next.logLines ?? previous.logLines,
|
|
4155
|
-
logKey: next.logKey || previous.logKey,
|
|
4156
|
-
toolCallCount: next.toolCallCount ?? previous.toolCallCount,
|
|
4157
|
-
lastToolNames: next.lastToolNames ?? previous.lastToolNames,
|
|
4158
|
-
lastAssistantText: next.lastAssistantText ?? previous.lastAssistantText,
|
|
4159
|
-
startedAt: next.startedAt ?? previous.startedAt,
|
|
4160
|
-
finishedAt: next.finishedAt ?? previous.finishedAt
|
|
4161
|
-
};
|
|
4011
|
+
var NORMAL_TOOL_GIST_MAX = 28;
|
|
4012
|
+
function gistClip(value, max = NORMAL_TOOL_GIST_MAX) {
|
|
4013
|
+
const oneLine = value.replace(/\s+/g, " ").trim();
|
|
4014
|
+
if (!oneLine) return "";
|
|
4015
|
+
return oneLine.length <= max ? oneLine : `${oneLine.slice(0, max - 1)}\u2026`;
|
|
4162
4016
|
}
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
);
|
|
4017
|
+
var DEFAULT_RUN_GIST_MAX = 96;
|
|
4018
|
+
function normalRunGistMaxWidth(env = process.env, columns) {
|
|
4019
|
+
const pinned = parseInt(env.NOLO_TEST_RUN_GIST_WIDTH ?? "", 10);
|
|
4020
|
+
if (!Number.isNaN(pinned) && pinned > 0) return pinned;
|
|
4021
|
+
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
4022
|
+
if (cols > 0) {
|
|
4023
|
+
return Math.max(48, Math.min(160, cols - 32));
|
|
4024
|
+
}
|
|
4025
|
+
return DEFAULT_RUN_GIST_MAX;
|
|
4026
|
+
}
|
|
4027
|
+
function commandFullGist(command, max) {
|
|
4028
|
+
const oneLine = command.replace(/\s+/g, " ").trim();
|
|
4029
|
+
if (!oneLine) return "";
|
|
4030
|
+
return truncateByDisplayWidth(redactSecrets(oneLine), max);
|
|
4177
4031
|
}
|
|
4178
|
-
function
|
|
4179
|
-
const
|
|
4180
|
-
const
|
|
4181
|
-
|
|
4182
|
-
|
|
4032
|
+
function pathBasenameGist(path) {
|
|
4033
|
+
const segments = path.split(/[\\/]/).filter((segment) => segment.length > 0);
|
|
4034
|
+
const base = segments.pop();
|
|
4035
|
+
return base ? gistClip(base) : "";
|
|
4036
|
+
}
|
|
4037
|
+
var EDIT_SNIPPET_MAX_LINES = 24;
|
|
4038
|
+
var DEFAULT_EDIT_SNIPPET_MAX_WIDTH = 96;
|
|
4039
|
+
function resolveEditSnippetMaxWidth(env = process.env, columns) {
|
|
4040
|
+
if (env.NOLO_TEST_DIFF_WIDTH) {
|
|
4041
|
+
const parsed = parseInt(env.NOLO_TEST_DIFF_WIDTH, 10);
|
|
4042
|
+
if (!Number.isNaN(parsed) && parsed > 0) return parsed;
|
|
4183
4043
|
}
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
return
|
|
4187
|
-
`[nolo:tool] #${round} !! ${event.toolName}${elapsed2}: ${event.message ?? "failed"}`,
|
|
4188
|
-
colorEnabled,
|
|
4189
|
-
"error"
|
|
4190
|
-
);
|
|
4044
|
+
const cols = typeof columns === "number" ? columns : typeof process !== "undefined" && typeof process.stdout?.columns === "number" ? process.stdout.columns : 0;
|
|
4045
|
+
if (cols > 0) {
|
|
4046
|
+
return Math.max(80, Math.min(160, cols - 8));
|
|
4191
4047
|
}
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4048
|
+
return DEFAULT_EDIT_SNIPPET_MAX_WIDTH;
|
|
4049
|
+
}
|
|
4050
|
+
function prefixFor(kind) {
|
|
4051
|
+
return kind === "added" ? "+ " : kind === "removed" ? "- " : " ";
|
|
4052
|
+
}
|
|
4053
|
+
function buildEditLine(kind, body, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
4054
|
+
return { kind, text: prefixFor(kind) + truncateByDisplayWidth(body, maxWidth) };
|
|
4055
|
+
}
|
|
4056
|
+
function snippetLinesWithKind(snippet, kind, maxWidth = resolveEditSnippetMaxWidth()) {
|
|
4057
|
+
const lines = snippet.split(/\r?\n/);
|
|
4058
|
+
if (lines.at(-1) === "") lines.pop();
|
|
4059
|
+
return lines.slice(0, EDIT_SNIPPET_MAX_LINES).map((line) => buildEditLine(kind, line, maxWidth));
|
|
4060
|
+
}
|
|
4061
|
+
function truncateByDisplayWidth(line, maxWidth) {
|
|
4062
|
+
if (displayWidth(line) <= maxWidth) return line;
|
|
4063
|
+
let width = 0;
|
|
4064
|
+
let kept = "";
|
|
4065
|
+
for (const char of line) {
|
|
4066
|
+
const w = displayWidth(char);
|
|
4067
|
+
if (width + w + 1 > maxWidth) break;
|
|
4068
|
+
kept += char;
|
|
4069
|
+
width += w;
|
|
4196
4070
|
}
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
);
|
|
4071
|
+
return `${kept}\u2026`;
|
|
4072
|
+
}
|
|
4073
|
+
function windowAndTruncate(lines, maxLines) {
|
|
4074
|
+
if (lines.length <= maxLines) return lines;
|
|
4075
|
+
const firstChange = lines.findIndex((l) => l.kind !== "context");
|
|
4076
|
+
if (firstChange === -1) return lines.slice(0, maxLines);
|
|
4077
|
+
const half = Math.floor(maxLines / 2);
|
|
4078
|
+
let start = Math.max(0, firstChange - half);
|
|
4079
|
+
if (start + maxLines > lines.length) start = Math.max(0, lines.length - maxLines);
|
|
4080
|
+
const kept = lines.slice(start, start + maxLines);
|
|
4081
|
+
const omitted = lines.length - kept.length;
|
|
4082
|
+
if (omitted > 0) {
|
|
4083
|
+
kept.push({ kind: "context", text: ` \u2026 +${omitted} more lines` });
|
|
4084
|
+
}
|
|
4085
|
+
return kept;
|
|
4086
|
+
}
|
|
4087
|
+
function formatEditFileSnippet(metadata) {
|
|
4088
|
+
const oldSnippet = typeof metadata.oldSnippet === "string" ? metadata.oldSnippet : void 0;
|
|
4089
|
+
const newSnippet = typeof metadata.newSnippet === "string" ? metadata.newSnippet : void 0;
|
|
4090
|
+
if (!oldSnippet && !newSnippet) return void 0;
|
|
4091
|
+
const maxWidth = resolveEditSnippetMaxWidth();
|
|
4092
|
+
if (oldSnippet && !newSnippet) {
|
|
4093
|
+
const lines = snippetLinesWithKind(oldSnippet, "removed", maxWidth);
|
|
4094
|
+
return { lines, addedCount: 0, removedCount: lines.length };
|
|
4095
|
+
}
|
|
4096
|
+
if (newSnippet && !oldSnippet) {
|
|
4097
|
+
const lines = snippetLinesWithKind(newSnippet, "added", maxWidth);
|
|
4098
|
+
return { lines, addedCount: lines.length, removedCount: 0 };
|
|
4099
|
+
}
|
|
4100
|
+
const parts = diffLines(oldSnippet, newSnippet);
|
|
4101
|
+
const all = [];
|
|
4102
|
+
let addedCount = 0;
|
|
4103
|
+
let removedCount = 0;
|
|
4104
|
+
for (const part of parts) {
|
|
4105
|
+
const kind = part.added ? "added" : part.removed ? "removed" : "context";
|
|
4106
|
+
const bodyLines = part.value.replace(/\n$/, "").split("\n");
|
|
4107
|
+
for (const line of bodyLines) {
|
|
4108
|
+
if (kind === "added") addedCount++;
|
|
4109
|
+
if (kind === "removed") removedCount++;
|
|
4110
|
+
all.push(buildEditLine(kind, line, maxWidth));
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
return {
|
|
4114
|
+
lines: windowAndTruncate(all, EDIT_SNIPPET_MAX_LINES),
|
|
4115
|
+
addedCount,
|
|
4116
|
+
removedCount
|
|
4117
|
+
};
|
|
4118
|
+
}
|
|
4119
|
+
function editFileResultHint(event) {
|
|
4120
|
+
if (event.toolName !== "editFile" || !event.metadata) return null;
|
|
4121
|
+
const res = formatEditFileSnippet(event.metadata);
|
|
4122
|
+
if (!res) return null;
|
|
4123
|
+
const stats = [];
|
|
4124
|
+
if (res.addedCount > 0) stats.push(`+${res.addedCount}`);
|
|
4125
|
+
if (res.removedCount > 0) stats.push(`-${res.removedCount}`);
|
|
4126
|
+
const inline = stats.length > 0 ? `(${stats.join(", ")})` : "";
|
|
4127
|
+
return { inline, detail: res.lines };
|
|
4128
|
+
}
|
|
4129
|
+
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4130
|
+
if (!colorEnabled) {
|
|
4131
|
+
return lines.map((line) => ` ${line.text}
|
|
4132
|
+
`).join("");
|
|
4133
|
+
}
|
|
4134
|
+
const isTruecolor = supportsTruecolor(env);
|
|
4135
|
+
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4136
|
+
const brightness = resolveTuiBrightness(env);
|
|
4137
|
+
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4138
|
+
return lines.map((line) => ` ${renderDiffLine({
|
|
4139
|
+
kind: line.kind,
|
|
4140
|
+
text: line.text,
|
|
4141
|
+
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4142
|
+
padTo,
|
|
4143
|
+
colorEnabled: true,
|
|
4144
|
+
env
|
|
4145
|
+
})}
|
|
4146
|
+
`).join("");
|
|
4147
|
+
}
|
|
4148
|
+
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4149
|
+
if (!isTruecolor || lang === "unknown") return false;
|
|
4150
|
+
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4151
|
+
return line.text.length >= 2;
|
|
4152
|
+
}
|
|
4153
|
+
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4154
|
+
const prefix = line.text.slice(0, 2);
|
|
4155
|
+
const body = line.text.slice(2);
|
|
4156
|
+
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4157
|
+
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4158
|
+
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4159
|
+
return `${coloredPrefix}${highlightedBody}`;
|
|
4160
|
+
}
|
|
4161
|
+
function normalToolGistRaw(event) {
|
|
4162
|
+
const metadata = event.metadata ?? {};
|
|
4163
|
+
const toolName = event.toolName || "";
|
|
4164
|
+
if (toolName === "readFile") {
|
|
4165
|
+
const path2 = typeof metadata.path === "string" ? metadata.path : typeof metadata.filePath === "string" ? metadata.filePath : "";
|
|
4166
|
+
if (path2) return gistClip(formatReadItemPath(path2, metadata), 52);
|
|
4167
|
+
}
|
|
4168
|
+
if (toolName === "fetchWebpage") {
|
|
4169
|
+
const url = typeof metadata.url === "string" ? metadata.url : "";
|
|
4170
|
+
if (url) return formatFetchItemUrl(url);
|
|
4171
|
+
}
|
|
4172
|
+
if (toolName === "exa_search") {
|
|
4173
|
+
const query2 = typeof metadata.query === "string" ? metadata.query : typeof metadata.pattern === "string" ? metadata.pattern : "";
|
|
4174
|
+
const path2 = typeof metadata.path === "string" ? metadata.path : void 0;
|
|
4175
|
+
if (query2 || path2) return formatSearchItemQuery(query2, path2);
|
|
4176
|
+
}
|
|
4177
|
+
if (isRunToolName(toolName)) {
|
|
4178
|
+
const command2 = typeof metadata.command === "string" ? metadata.command : "";
|
|
4179
|
+
if (command2) {
|
|
4180
|
+
return commandFullGist(command2, normalRunGistMaxWidth());
|
|
4181
|
+
}
|
|
4182
|
+
}
|
|
4183
|
+
const path = typeof metadata.path === "string" ? metadata.path : "";
|
|
4184
|
+
if (path) return pathBasenameGist(path);
|
|
4185
|
+
const command = typeof metadata.command === "string" ? metadata.command : "";
|
|
4186
|
+
if (command) return commandFullGist(command, normalRunGistMaxWidth());
|
|
4187
|
+
const query = typeof metadata.query === "string" ? metadata.query : "";
|
|
4188
|
+
if (query) return clipCompactText(query, 64, "\u2026");
|
|
4189
|
+
const remembered = event.toolName === "rememberMemory" && typeof metadata.content === "string" ? metadata.content : "";
|
|
4190
|
+
if (remembered) return clipCompactText(redactSecrets(remembered), 64, "\u2026");
|
|
4191
|
+
return "";
|
|
4192
|
+
}
|
|
4193
|
+
var NORMAL_GIST_SECRET_PATTERNS = [
|
|
4194
|
+
/\bbearer\s+[A-Za-z0-9._~+/=-]{8,}/i,
|
|
4195
|
+
/\bsk-(?:ant-)?(?:api)?[0-9a-zA-Z-]{10,}/,
|
|
4196
|
+
/\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{10,}/,
|
|
4197
|
+
/\bxox[baprs]-[A-Za-z0-9-]{10,}/
|
|
4198
|
+
];
|
|
4199
|
+
function withholdIfSecretLike(gist) {
|
|
4200
|
+
if (!gist) return "";
|
|
4201
|
+
if (findPotentialSecrets(gist).length > 0) return "";
|
|
4202
|
+
if (NORMAL_GIST_SECRET_PATTERNS.some((pattern) => pattern.test(gist))) return "";
|
|
4203
|
+
return gist;
|
|
4204
|
+
}
|
|
4205
|
+
function normalToolGist(event) {
|
|
4206
|
+
return withholdIfSecretLike(normalToolGistRaw(event));
|
|
4207
|
+
}
|
|
4208
|
+
function formatNormalToolDuration(elapsedMs) {
|
|
4209
|
+
if (typeof elapsedMs !== "number" || !Number.isFinite(elapsedMs) || elapsedMs <= 500) return "";
|
|
4210
|
+
if (elapsedMs < 1e3) return `${Math.round(elapsedMs)}ms`;
|
|
4211
|
+
return `${(elapsedMs / 1e3).toFixed(1)}s`;
|
|
4202
4212
|
}
|
|
4203
4213
|
function formatNormalToolLine(event, pending, colorEnabled) {
|
|
4204
4214
|
if (event.type === "tool-call") return "";
|
|
@@ -4220,158 +4230,42 @@ function formatNormalToolLine(event, pending, colorEnabled) {
|
|
|
4220
4230
|
return formatToolTraceLine(`\u25B8 ${label} ! ${t("toolNeedsAction")}`, colorEnabled, "error");
|
|
4221
4231
|
}
|
|
4222
4232
|
if (event.type === "tool-error") {
|
|
4223
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4233
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${toolFailureReason(event) || t("toolFailed")}`, colorEnabled, "error");
|
|
4224
4234
|
}
|
|
4225
4235
|
if (event.metadata?.timedOut) {
|
|
4226
4236
|
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolTimedOut")}`, colorEnabled, "error");
|
|
4227
4237
|
}
|
|
4228
4238
|
if (isFailedToolResult(event)) {
|
|
4229
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${t("toolFailed")}`, colorEnabled, "error");
|
|
4230
|
-
}
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
}
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
const titleText = toolLabel("codeSearch");
|
|
4260
|
-
if (!colorEnabled) {
|
|
4261
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4262
|
-
`;
|
|
4263
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4264
|
-
return `${headerLine2}${treeLines2}
|
|
4265
|
-
`;
|
|
4266
|
-
}
|
|
4267
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4268
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4269
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4270
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4271
|
-
`;
|
|
4272
|
-
const treeLines = lines.map((l) => {
|
|
4273
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4274
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4275
|
-
return `${connector}${queryText}`;
|
|
4276
|
-
}).join("\n");
|
|
4277
|
-
return `${headerLine}${treeLines}
|
|
4278
|
-
`;
|
|
4279
|
-
}
|
|
4280
|
-
function formatReadTreeBlockForCli(items, colorEnabled) {
|
|
4281
|
-
if (items.length === 0) return "";
|
|
4282
|
-
const { count, lines } = formatReadTreeLines(items);
|
|
4283
|
-
const titleText = toolLabel("readFile");
|
|
4284
|
-
if (!colorEnabled) {
|
|
4285
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4286
|
-
`;
|
|
4287
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.pathWithRange}`).join("\n");
|
|
4288
|
-
return `${headerLine2}${treeLines2}
|
|
4289
|
-
`;
|
|
4290
|
-
}
|
|
4291
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4292
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4293
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4294
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4295
|
-
`;
|
|
4296
|
-
const treeLines = lines.map((l) => {
|
|
4297
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4298
|
-
const pathText = themeText(l.pathWithRange, "muted", true);
|
|
4299
|
-
return `${connector}${pathText}`;
|
|
4300
|
-
}).join("\n");
|
|
4301
|
-
return `${headerLine}${treeLines}
|
|
4302
|
-
`;
|
|
4303
|
-
}
|
|
4304
|
-
function formatRunTreeBlockForCli(items, colorEnabled) {
|
|
4305
|
-
if (items.length === 0) return "";
|
|
4306
|
-
const { count, lines } = formatRunTreeLines(items);
|
|
4307
|
-
const titleText = toolLabel("execShell");
|
|
4308
|
-
if (!colorEnabled) {
|
|
4309
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4310
|
-
`;
|
|
4311
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.commandText}`).join("\n");
|
|
4312
|
-
return `${headerLine2}${treeLines2}
|
|
4313
|
-
`;
|
|
4314
|
-
}
|
|
4315
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4316
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4317
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4318
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4319
|
-
`;
|
|
4320
|
-
const treeLines = lines.map((l) => {
|
|
4321
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4322
|
-
const commandText = themeText(l.commandText, "muted", true);
|
|
4323
|
-
return `${connector}${commandText}`;
|
|
4324
|
-
}).join("\n");
|
|
4325
|
-
return `${headerLine}${treeLines}
|
|
4326
|
-
`;
|
|
4327
|
-
}
|
|
4328
|
-
function formatWebSearchTreeBlockForCli(items, colorEnabled) {
|
|
4329
|
-
if (items.length === 0) return "";
|
|
4330
|
-
const { count, lines } = formatSearchTreeLines(items);
|
|
4331
|
-
const titleText = toolLabel("exa_search");
|
|
4332
|
-
if (!colorEnabled) {
|
|
4333
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4334
|
-
`;
|
|
4335
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.queryText}`).join("\n");
|
|
4336
|
-
return `${headerLine2}${treeLines2}
|
|
4337
|
-
`;
|
|
4338
|
-
}
|
|
4339
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4340
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4341
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4342
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4343
|
-
`;
|
|
4344
|
-
const treeLines = lines.map((l) => {
|
|
4345
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4346
|
-
const queryText = themeText(l.queryText, "muted", true);
|
|
4347
|
-
return `${connector}${queryText}`;
|
|
4348
|
-
}).join("\n");
|
|
4349
|
-
return `${headerLine}${treeLines}
|
|
4350
|
-
`;
|
|
4351
|
-
}
|
|
4352
|
-
function formatFetchTreeBlockForCli(items, colorEnabled) {
|
|
4353
|
-
if (items.length === 0) return "";
|
|
4354
|
-
const { count, lines } = formatFetchTreeLines(items);
|
|
4355
|
-
const titleText = toolLabel("fetchWebpage");
|
|
4356
|
-
if (!colorEnabled) {
|
|
4357
|
-
const headerLine2 = `\u2022 ${titleText} (${count})
|
|
4358
|
-
`;
|
|
4359
|
-
const treeLines2 = lines.map((l) => ` ${l.connector}${l.urlText}`).join("\n");
|
|
4360
|
-
return `${headerLine2}${treeLines2}
|
|
4361
|
-
`;
|
|
4362
|
-
}
|
|
4363
|
-
const bullet = themeText("\u2022", "chrome", true);
|
|
4364
|
-
const title = styleCliText(titleText, "bold", true);
|
|
4365
|
-
const countText = themeText(`(${count})`, "muted", true);
|
|
4366
|
-
const headerLine = `${bullet} ${title} ${countText}
|
|
4367
|
-
`;
|
|
4368
|
-
const treeLines = lines.map((l) => {
|
|
4369
|
-
const connector = themeText(` ${l.connector}`, "chrome", true);
|
|
4370
|
-
const urlText = themeText(l.urlText, "muted", true);
|
|
4371
|
-
return `${connector}${urlText}`;
|
|
4372
|
-
}).join("\n");
|
|
4373
|
-
return `${headerLine}${treeLines}
|
|
4374
|
-
`;
|
|
4239
|
+
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${toolFailureReason(event) || t("toolFailed")}`, colorEnabled, "error");
|
|
4240
|
+
}
|
|
4241
|
+
const gist = normalToolGist(event);
|
|
4242
|
+
const hint = editFileResultHint(event);
|
|
4243
|
+
const statsInline = hint?.inline ? ` ${hint.inline}` : "";
|
|
4244
|
+
const durationInline = formatNormalToolDuration(event.elapsedMs);
|
|
4245
|
+
const tail = durationInline ? ` \u2713 ${durationInline}` : " \u2713";
|
|
4246
|
+
const mainLine = formatToolTraceLine(
|
|
4247
|
+
gist ? `\u25B8 ${label} \xB7 ${gist}${statsInline}${tail}` : `\u25B8 ${label}${statsInline}${tail}`,
|
|
4248
|
+
colorEnabled
|
|
4249
|
+
);
|
|
4250
|
+
if (hint?.detail?.length) {
|
|
4251
|
+
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4252
|
+
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4253
|
+
}
|
|
4254
|
+
return mainLine;
|
|
4255
|
+
}
|
|
4256
|
+
function toolFailureReason(event) {
|
|
4257
|
+
const metadata = event.metadata ?? {};
|
|
4258
|
+
const rawError = metadata.error ?? metadata.errorMessage;
|
|
4259
|
+
const raw = typeof rawError === "string" && rawError.trim() || event.message?.trim() || typeof event.content === "string" && event.content.trim() || event.summary?.trim() || "";
|
|
4260
|
+
const lines = raw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
|
|
4261
|
+
const sectionLines = (section) => {
|
|
4262
|
+
const start = lines.findIndex((line) => new RegExp(`^${section}\\s*:$`, "i").test(line));
|
|
4263
|
+
if (start < 0) return [];
|
|
4264
|
+
const end = lines.findIndex((line, index) => index > start && /^(stdout|stderr|exitCode)\s*:/i.test(line));
|
|
4265
|
+
return lines.slice(start + 1, end < 0 ? lines.length : end);
|
|
4266
|
+
};
|
|
4267
|
+
const reasonLine = sectionLines("stderr")[0] ?? sectionLines("stdout")[0] ?? lines.find((line) => !/^(stdout|stderr|exitCode)\s*:/i.test(line)) ?? lines[0] ?? "";
|
|
4268
|
+
return reasonLine ? clip(redactSecrets(stripAnsi2(reasonLine)), 96) : "";
|
|
4375
4269
|
}
|
|
4376
4270
|
function resolveLoadSkillName(event) {
|
|
4377
4271
|
const metaName = typeof event.metadata?.name === "string" ? event.metadata.name : void 0;
|
|
@@ -4436,326 +4330,74 @@ function formatLoadSkillBlock(event, colorEnabled, opts) {
|
|
|
4436
4330
|
return `${star} ${labelPart}: ${namePart}
|
|
4437
4331
|
`;
|
|
4438
4332
|
}
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
if (todoBlock) return todoBlock;
|
|
4443
|
-
if (isReadToolName(toolName) && event.type === "tool-result") {
|
|
4444
|
-
const rawPath = (typeof event.metadata?.path === "string" ? event.metadata.path : void 0) || (typeof event.metadata?.filePath === "string" ? event.metadata.filePath : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4445
|
-
return formatReadTreeBlockForCli([{ path: rawPath, metadata: event.metadata }], colorEnabled);
|
|
4446
|
-
}
|
|
4447
|
-
if (isSearchToolName(toolName) && event.type === "tool-result") {
|
|
4448
|
-
const rawQuery = (typeof event.metadata?.query === "string" ? event.metadata.query : void 0) || (typeof event.metadata?.pattern === "string" ? event.metadata.pattern : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4449
|
-
const rawPath = typeof event.metadata?.path === "string" ? event.metadata.path : void 0;
|
|
4450
|
-
return formatSearchTreeBlockForCli([{ query: rawQuery, path: rawPath }], colorEnabled);
|
|
4451
|
-
}
|
|
4452
|
-
if (isFetchToolName(toolName) && event.type === "tool-result") {
|
|
4453
|
-
const rawUrl = (typeof event.metadata?.url === "string" ? event.metadata.url : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4454
|
-
return formatFetchTreeBlockForCli([{ url: rawUrl }], colorEnabled);
|
|
4455
|
-
}
|
|
4456
|
-
if (isRunToolName(toolName) && event.type === "tool-result" && isRunResultFoldable(event)) {
|
|
4457
|
-
const rawCommand = (typeof event.metadata?.command === "string" ? event.metadata.command : void 0) || event.argumentsPreview || pending?.argumentsPreview || "";
|
|
4458
|
-
const exitCode = typeof event.metadata?.exitCode === "number" ? event.metadata.exitCode : void 0;
|
|
4459
|
-
const timedOut = Boolean(event.metadata?.timedOut);
|
|
4460
|
-
return formatRunTreeBlockForCli([{ command: rawCommand, exitCode, timedOut }], colorEnabled);
|
|
4461
|
-
}
|
|
4462
|
-
const rawArgs = clipPathAware(event.argumentsPreview || pending?.argumentsPreview || "", 72);
|
|
4463
|
-
const rawLabel = toolLabel(toolName);
|
|
4464
|
-
const label = rawArgs ? `${rawLabel} ${rawArgs}` : rawLabel;
|
|
4465
|
-
if (event.type === "tool-error") {
|
|
4466
|
-
const message = clip(event.message ?? t("toolFailed"), 96);
|
|
4467
|
-
return formatToolTraceLine(`\u25B8 ${label} \u2717 ${message}`, colorEnabled, "error");
|
|
4468
|
-
}
|
|
4469
|
-
const loadSkillBlock = formatLoadSkillBlock(event, colorEnabled);
|
|
4470
|
-
if (loadSkillBlock) return loadSkillBlock;
|
|
4471
|
-
if (event.type === "tool-result" && (toolName === "listAgents" || toolName === "startAgentRun" || toolName === "controlAgentRun")) {
|
|
4472
|
-
return formatOrchestrationCardBlock(event, toolName, colorEnabled);
|
|
4473
|
-
}
|
|
4474
|
-
if (event.type === "tool-result" && (event.toolName === "ask_user" || event.metadata?.uiAskChoice)) {
|
|
4475
|
-
const block = formatUiAskChoiceBlock(event, colorEnabled);
|
|
4476
|
-
if (block) return block;
|
|
4477
|
-
}
|
|
4478
|
-
const hint = compactResultHint(event);
|
|
4479
|
-
const suffix = hint.inline ? ` ${hint.inline}` : "";
|
|
4480
|
-
const failed = isFailedToolResult(event);
|
|
4481
|
-
const marker = failed ? "\u2717" : isNeedsActionToolResult(event) ? "!" : "\u2713";
|
|
4482
|
-
let mainLine;
|
|
4483
|
-
if (!colorEnabled) {
|
|
4484
|
-
mainLine = `\u25B8 ${label} ${marker}${suffix}
|
|
4485
|
-
`;
|
|
4486
|
-
} else {
|
|
4487
|
-
const chromePointer = themeText("\u25B8", "chrome", true);
|
|
4488
|
-
const mutedLabel = themeText(rawLabel, "muted", true);
|
|
4489
|
-
const argsPart = rawArgs ? ` ${dimCliText(rawArgs, true)}` : "";
|
|
4490
|
-
const statusToken = failed ? themeText("\u2717", "danger", true) : isNeedsActionToolResult(event) ? themeText("!", "warning", true) : themeText("\u2713", "success", true);
|
|
4491
|
-
const suffixPart = hint.inline ? ` ${dimCliText(hint.inline, true)}` : "";
|
|
4492
|
-
mainLine = `${chromePointer} ${mutedLabel}${argsPart} ${statusToken}${suffixPart}
|
|
4493
|
-
`;
|
|
4494
|
-
}
|
|
4495
|
-
if (!hint.detail?.length) return mainLine;
|
|
4496
|
-
const filePath = typeof event.metadata?.path === "string" ? event.metadata.path : event.argumentsPreview;
|
|
4497
|
-
return `${mainLine}${formatEditDetailBlock(hint.detail, colorEnabled, filePath)}`;
|
|
4498
|
-
}
|
|
4499
|
-
function formatEditDetailBlock(lines, colorEnabled, filePath, env = process.env) {
|
|
4500
|
-
if (!colorEnabled) {
|
|
4501
|
-
return lines.map((line) => ` ${line.text}
|
|
4502
|
-
`).join("");
|
|
4503
|
-
}
|
|
4504
|
-
const isTruecolor = supportsTruecolor(env);
|
|
4505
|
-
const lang = isTruecolor ? detectCodeLangFromPath(filePath) : "unknown";
|
|
4506
|
-
const brightness = resolveTuiBrightness(env);
|
|
4507
|
-
const padTo = Math.max(...lines.map((line) => displayWidth(line.text))) + 1;
|
|
4508
|
-
return lines.map((line) => ` ${renderDiffLine({
|
|
4509
|
-
kind: line.kind,
|
|
4510
|
-
text: line.text,
|
|
4511
|
-
highlightedText: shouldHighlightEditLine(line, lang, isTruecolor) ? buildHighlightedEditLine(line, lang, brightness, env) : void 0,
|
|
4512
|
-
padTo,
|
|
4513
|
-
colorEnabled: true,
|
|
4514
|
-
env
|
|
4515
|
-
})}
|
|
4516
|
-
`).join("");
|
|
4517
|
-
}
|
|
4518
|
-
function shouldHighlightEditLine(line, lang, isTruecolor) {
|
|
4519
|
-
if (!isTruecolor || lang === "unknown") return false;
|
|
4520
|
-
if (line.text.startsWith(" \u2026") || line.text.startsWith("\u2026")) return false;
|
|
4521
|
-
return line.text.length >= 2;
|
|
4522
|
-
}
|
|
4523
|
-
function buildHighlightedEditLine(line, lang, brightness, env) {
|
|
4524
|
-
const prefix = line.text.slice(0, 2);
|
|
4525
|
-
const body = line.text.slice(2);
|
|
4526
|
-
const prefixToken = line.kind === "added" ? "success" : line.kind === "removed" ? "danger" : "chrome";
|
|
4527
|
-
const coloredPrefix = themeText(prefix, prefixToken, true, env);
|
|
4528
|
-
const highlightedBody = highlightCodeLine(body, lang, brightness);
|
|
4529
|
-
return `${coloredPrefix}${highlightedBody}`;
|
|
4530
|
-
}
|
|
4531
|
-
function createToolEventFormatter(mode, colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4532
|
-
const suppressRunProgressCards = opts.suppressRunProgressCards === true;
|
|
4333
|
+
var TUI_TREE_MARKER = "TUI_TREE\n";
|
|
4334
|
+
var TUI_TREE_END = "";
|
|
4335
|
+
function createToolEventFormatter(colorEnabled = resolveCliColorEnabled(), opts = {}) {
|
|
4533
4336
|
const pending = /* @__PURE__ */ new Map();
|
|
4534
|
-
let
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
const
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
snapshot.errorMessage ?? "",
|
|
4548
|
-
snapshot.logKey
|
|
4549
|
-
]);
|
|
4550
|
-
const flushStatusFold = () => {
|
|
4551
|
-
if (!statusFold) return "";
|
|
4552
|
-
const fold = statusFold;
|
|
4553
|
-
statusFold = null;
|
|
4554
|
-
const substance = cardSubstance(fold);
|
|
4555
|
-
if (lastPrintedCardByRunId.get(fold.runId) === substance) return "";
|
|
4556
|
-
const prevLog = lastEmittedLogByRunId.get(fold.runId);
|
|
4557
|
-
const changed = Boolean(fold.logKey) && fold.logKey !== prevLog;
|
|
4558
|
-
if (suppressRunProgressCards) {
|
|
4559
|
-
const terminal = isAgentRunTerminalStatus(fold.status);
|
|
4560
|
-
if (!terminal && !fold.errorMessage && !changed) {
|
|
4561
|
-
lastPrintedCardByRunId.set(fold.runId, substance);
|
|
4562
|
-
return "";
|
|
4563
|
-
}
|
|
4337
|
+
let tree = null;
|
|
4338
|
+
const treeKind = (name) => isRunToolName(name) ? "Run" : isReadToolName(name) ? "Read" : name === "exa_search" ? "Search" : name === "fetchWebpage" ? "Fetch" : null;
|
|
4339
|
+
const treeLine = (kind, items) => {
|
|
4340
|
+
const label = kind === "Run" ? toolLabel("execShell") : kind === "Read" ? toolLabel("readFile") : kind === "Fetch" ? toolLabel("fetchWebpage") : toolLabel("exa_search");
|
|
4341
|
+
return `${TUI_TREE_MARKER}${label} (${items.length})
|
|
4342
|
+
${items.map((item, i) => `${i === items.length - 1 ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 "}${item} \u2713`).join("\n")}${TUI_TREE_END}
|
|
4343
|
+
`;
|
|
4344
|
+
};
|
|
4345
|
+
const formatTreeEvent = (event, call) => {
|
|
4346
|
+
if (!opts.tuiTrees || event.type !== "tool-result") return null;
|
|
4347
|
+
if (isFailedToolResult(event) || event.metadata?.failed || event.metadata?.timedOut || readActionGate(event.metadata?.actionGate)) {
|
|
4348
|
+
tree = null;
|
|
4349
|
+
return null;
|
|
4564
4350
|
}
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4351
|
+
const name = event.toolName || call?.toolName || "tool";
|
|
4352
|
+
const kind = treeKind(name);
|
|
4353
|
+
if (!kind) {
|
|
4354
|
+
tree = null;
|
|
4355
|
+
return null;
|
|
4568
4356
|
}
|
|
4569
|
-
|
|
4357
|
+
let item = "";
|
|
4358
|
+
const m = event.metadata ?? {};
|
|
4359
|
+
if (kind === "Run") {
|
|
4360
|
+
const command = typeof m.command === "string" ? m.command : "";
|
|
4361
|
+
item = command ? formatRunItemCommand(command, typeof m.exitCode === "number" ? m.exitCode : void 0, Boolean(m.timedOut)) : "command";
|
|
4362
|
+
}
|
|
4363
|
+
if (kind === "Read") item = formatReadItemPath(typeof m.path === "string" ? m.path : typeof m.filePath === "string" ? m.filePath : "file", m);
|
|
4364
|
+
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);
|
|
4365
|
+
if (kind === "Fetch") item = formatFetchItemUrl(typeof m.url === "string" ? m.url : "webpage");
|
|
4366
|
+
item = withholdIfSecretLike(item) || toolLabel(name);
|
|
4367
|
+
if (tree?.kind !== kind) tree = { kind, items: [] };
|
|
4368
|
+
tree.items.push(item);
|
|
4369
|
+
if (tree.items.length < 2) return formatNormalToolLine(event, call, colorEnabled);
|
|
4370
|
+
return treeLine(kind, tree.items);
|
|
4570
4371
|
};
|
|
4571
|
-
const
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
const rawPath = (typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0) || (typeof evt.metadata?.filePath === "string" ? evt.metadata.filePath : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4577
|
-
return { path: rawPath, metadata: evt.metadata };
|
|
4578
|
-
});
|
|
4579
|
-
for (const evt of readBuffer) pending.delete(evt.toolCallId);
|
|
4580
|
-
readBuffer = [];
|
|
4581
|
-
out += formatReadTreeBlockForCli(items, colorEnabled);
|
|
4582
|
-
}
|
|
4583
|
-
if (searchBuffer.length > 0) {
|
|
4584
|
-
const items = searchBuffer.map((evt) => {
|
|
4585
|
-
const call = pending.get(evt.toolCallId);
|
|
4586
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4587
|
-
const rawPath = typeof evt.metadata?.path === "string" ? evt.metadata.path : void 0;
|
|
4588
|
-
return { query: rawQuery, path: rawPath };
|
|
4589
|
-
});
|
|
4590
|
-
for (const evt of searchBuffer) pending.delete(evt.toolCallId);
|
|
4591
|
-
searchBuffer = [];
|
|
4592
|
-
out += formatSearchTreeBlockForCli(items, colorEnabled);
|
|
4593
|
-
}
|
|
4594
|
-
if (runBuffer.length > 0) {
|
|
4595
|
-
const items = runBuffer.map((evt) => {
|
|
4596
|
-
const call = pending.get(evt.toolCallId);
|
|
4597
|
-
const rawCommand = (typeof evt.metadata?.command === "string" ? evt.metadata.command : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4598
|
-
const exitCode = typeof evt.metadata?.exitCode === "number" ? evt.metadata.exitCode : void 0;
|
|
4599
|
-
const timedOut = Boolean(evt.metadata?.timedOut);
|
|
4600
|
-
return { command: rawCommand, exitCode, timedOut };
|
|
4601
|
-
});
|
|
4602
|
-
for (const evt of runBuffer) pending.delete(evt.toolCallId);
|
|
4603
|
-
runBuffer = [];
|
|
4604
|
-
out += formatRunTreeBlockForCli(items, colorEnabled);
|
|
4605
|
-
}
|
|
4606
|
-
if (fetchBuffer.length > 0) {
|
|
4607
|
-
const items = fetchBuffer.map((evt) => {
|
|
4608
|
-
const call = pending.get(evt.toolCallId);
|
|
4609
|
-
const rawUrl = (typeof evt.metadata?.url === "string" ? evt.metadata.url : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4610
|
-
return { url: rawUrl };
|
|
4611
|
-
});
|
|
4612
|
-
for (const evt of fetchBuffer) pending.delete(evt.toolCallId);
|
|
4613
|
-
fetchBuffer = [];
|
|
4614
|
-
out += formatFetchTreeBlockForCli(items, colorEnabled);
|
|
4615
|
-
}
|
|
4616
|
-
if (webSearchBuffer.length > 0) {
|
|
4617
|
-
const items = webSearchBuffer.map((evt) => {
|
|
4618
|
-
const call = pending.get(evt.toolCallId);
|
|
4619
|
-
const rawQuery = (typeof evt.metadata?.query === "string" ? evt.metadata.query : void 0) || (typeof evt.metadata?.pattern === "string" ? evt.metadata.pattern : void 0) || evt.argumentsPreview || call?.argumentsPreview || "";
|
|
4620
|
-
return { query: rawQuery };
|
|
4372
|
+
const format = (event) => {
|
|
4373
|
+
if (event.type === "tool-call") {
|
|
4374
|
+
pending.set(event.toolCallId, {
|
|
4375
|
+
toolName: event.toolName,
|
|
4376
|
+
argumentsPreview: event.argumentsPreview
|
|
4621
4377
|
});
|
|
4622
|
-
|
|
4623
|
-
webSearchBuffer = [];
|
|
4624
|
-
out += formatWebSearchTreeBlockForCli(items, colorEnabled);
|
|
4378
|
+
return "";
|
|
4625
4379
|
}
|
|
4626
|
-
|
|
4380
|
+
const call = pending.get(event.toolCallId);
|
|
4381
|
+
pending.delete(event.toolCallId);
|
|
4382
|
+
const treeOutput = formatTreeEvent(event, call);
|
|
4383
|
+
if (treeOutput !== null) return treeOutput;
|
|
4384
|
+
return formatNormalToolLine(event, call, colorEnabled);
|
|
4627
4385
|
};
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
const flushed = flushStatusFold();
|
|
4631
|
-
buffer.push(event);
|
|
4632
|
-
return flushed;
|
|
4386
|
+
format.reset = () => {
|
|
4387
|
+
tree = null;
|
|
4633
4388
|
};
|
|
4634
|
-
|
|
4635
|
-
if (mode === "hide") return "";
|
|
4636
|
-
if (mode === "verbose") return formatVerboseToolEvent(event, colorEnabled);
|
|
4637
|
-
if (mode === "normal") {
|
|
4638
|
-
if (event.type === "tool-call") {
|
|
4639
|
-
pending.set(event.toolCallId, {
|
|
4640
|
-
toolName: event.toolName,
|
|
4641
|
-
argumentsPreview: event.argumentsPreview
|
|
4642
|
-
});
|
|
4643
|
-
return "";
|
|
4644
|
-
}
|
|
4645
|
-
const call2 = pending.get(event.toolCallId);
|
|
4646
|
-
pending.delete(event.toolCallId);
|
|
4647
|
-
return formatNormalToolLine(event, call2, colorEnabled);
|
|
4648
|
-
}
|
|
4649
|
-
if (event.toolName === "controlAgentRun") {
|
|
4650
|
-
if (event.type === "tool-call") {
|
|
4651
|
-
pending.set(event.toolCallId, {
|
|
4652
|
-
toolName: event.toolName,
|
|
4653
|
-
argumentsPreview: event.argumentsPreview
|
|
4654
|
-
});
|
|
4655
|
-
return "";
|
|
4656
|
-
}
|
|
4657
|
-
if (event.type === "tool-result") {
|
|
4658
|
-
const snapshot = parseControlAgentRunStatusEvent(event);
|
|
4659
|
-
if (snapshot) {
|
|
4660
|
-
let out = flushToolBuffers();
|
|
4661
|
-
const open = statusFold;
|
|
4662
|
-
const sameRun = open?.runId === snapshot.runId;
|
|
4663
|
-
if (open && (!sameRun || open.status !== snapshot.status)) {
|
|
4664
|
-
out += flushStatusFold();
|
|
4665
|
-
}
|
|
4666
|
-
statusFold = open && sameRun ? mergeRunSnapshot(open, snapshot) : snapshot;
|
|
4667
|
-
pending.delete(event.toolCallId);
|
|
4668
|
-
if (isAgentRunTerminalStatus(snapshot.status)) {
|
|
4669
|
-
out += flushBuffers();
|
|
4670
|
-
}
|
|
4671
|
-
return out;
|
|
4672
|
-
}
|
|
4673
|
-
const flushed2 = flushBuffers();
|
|
4674
|
-
const call2 = pending.get(event.toolCallId);
|
|
4675
|
-
pending.delete(event.toolCallId);
|
|
4676
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4677
|
-
}
|
|
4678
|
-
}
|
|
4679
|
-
if (isReadToolName(event.toolName)) {
|
|
4680
|
-
if (event.type === "tool-call") {
|
|
4681
|
-
pending.set(event.toolCallId, {
|
|
4682
|
-
toolName: event.toolName,
|
|
4683
|
-
argumentsPreview: event.argumentsPreview
|
|
4684
|
-
});
|
|
4685
|
-
return "";
|
|
4686
|
-
}
|
|
4687
|
-
if (event.type === "tool-result") {
|
|
4688
|
-
return bufferToolResult(readBuffer, event);
|
|
4689
|
-
}
|
|
4690
|
-
}
|
|
4691
|
-
if (isSearchToolName(event.toolName)) {
|
|
4692
|
-
if (event.type === "tool-call") {
|
|
4693
|
-
pending.set(event.toolCallId, {
|
|
4694
|
-
toolName: event.toolName,
|
|
4695
|
-
argumentsPreview: event.argumentsPreview
|
|
4696
|
-
});
|
|
4697
|
-
return "";
|
|
4698
|
-
}
|
|
4699
|
-
if (event.type === "tool-result") {
|
|
4700
|
-
return bufferToolResult(searchBuffer, event);
|
|
4701
|
-
}
|
|
4702
|
-
}
|
|
4703
|
-
if (isRunToolName(event.toolName)) {
|
|
4704
|
-
if (event.type === "tool-result" && !isRunResultFoldable(event)) {
|
|
4705
|
-
const flushed2 = flushBuffers();
|
|
4706
|
-
const call2 = pending.get(event.toolCallId);
|
|
4707
|
-
pending.delete(event.toolCallId);
|
|
4708
|
-
return `${flushed2}${formatCompactToolLine(event, call2, colorEnabled)}`;
|
|
4709
|
-
}
|
|
4710
|
-
if (event.type === "tool-call") {
|
|
4711
|
-
pending.set(event.toolCallId, {
|
|
4712
|
-
toolName: event.toolName,
|
|
4713
|
-
argumentsPreview: event.argumentsPreview
|
|
4714
|
-
});
|
|
4715
|
-
return "";
|
|
4716
|
-
}
|
|
4717
|
-
if (event.type === "tool-result") {
|
|
4718
|
-
return bufferToolResult(runBuffer, event);
|
|
4719
|
-
}
|
|
4720
|
-
}
|
|
4721
|
-
if (isFetchToolName(event.toolName)) {
|
|
4722
|
-
if (event.type === "tool-call") {
|
|
4723
|
-
pending.set(event.toolCallId, {
|
|
4724
|
-
toolName: event.toolName,
|
|
4725
|
-
argumentsPreview: event.argumentsPreview
|
|
4726
|
-
});
|
|
4727
|
-
return "";
|
|
4728
|
-
}
|
|
4729
|
-
if (event.type === "tool-result") {
|
|
4730
|
-
return bufferToolResult(fetchBuffer, event);
|
|
4731
|
-
}
|
|
4732
|
-
}
|
|
4733
|
-
if (isWebSearchToolName(event.toolName)) {
|
|
4734
|
-
if (event.type === "tool-call") {
|
|
4735
|
-
pending.set(event.toolCallId, {
|
|
4736
|
-
toolName: event.toolName,
|
|
4737
|
-
argumentsPreview: event.argumentsPreview
|
|
4738
|
-
});
|
|
4739
|
-
return "";
|
|
4740
|
-
}
|
|
4741
|
-
if (event.type === "tool-result") {
|
|
4742
|
-
return bufferToolResult(webSearchBuffer, event);
|
|
4743
|
-
}
|
|
4744
|
-
}
|
|
4745
|
-
const flushed = flushBuffers();
|
|
4389
|
+
format.consume = (event) => {
|
|
4746
4390
|
if (event.type === "tool-call") {
|
|
4747
4391
|
pending.set(event.toolCallId, {
|
|
4748
4392
|
toolName: event.toolName,
|
|
4749
4393
|
argumentsPreview: event.argumentsPreview
|
|
4750
4394
|
});
|
|
4751
|
-
return
|
|
4395
|
+
return;
|
|
4752
4396
|
}
|
|
4753
|
-
const call = pending.get(event.toolCallId);
|
|
4754
4397
|
pending.delete(event.toolCallId);
|
|
4755
|
-
|
|
4398
|
+
tree = null;
|
|
4756
4399
|
};
|
|
4757
|
-
|
|
4758
|
-
return formatter;
|
|
4400
|
+
return format;
|
|
4759
4401
|
}
|
|
4760
4402
|
function createSseToolEventAdapter(onEvent) {
|
|
4761
4403
|
let round = 0;
|
|
@@ -4923,6 +4565,13 @@ ${this.text}
|
|
|
4923
4565
|
|
|
4924
4566
|
// packages/cli/client/agentRunOutput.ts
|
|
4925
4567
|
var IDENTITY_LABEL_SEPARATOR = " > ";
|
|
4568
|
+
var THINKING_PREVIEW_BUFFER_LIMIT = 512;
|
|
4569
|
+
function appendThinkingPreview(current, chunk, limit = THINKING_PREVIEW_BUFFER_LIMIT) {
|
|
4570
|
+
if (limit <= 0) return "";
|
|
4571
|
+
const combined = current + chunk;
|
|
4572
|
+
if (combined.length <= limit) return combined;
|
|
4573
|
+
return combined.slice(combined.length - limit);
|
|
4574
|
+
}
|
|
4926
4575
|
function formatCompactionSummaryLine(event) {
|
|
4927
4576
|
if (!event) return "";
|
|
4928
4577
|
const action = event.reason === "tool_stub" ? "stub \u5DE5\u5177\u8F93\u51FA" : "\u751F\u6210\u5386\u53F2\u6458\u8981";
|
|
@@ -4973,10 +4622,8 @@ function createCliTurnOutput(params) {
|
|
|
4973
4622
|
const { options } = params;
|
|
4974
4623
|
const workingLabel = params.workingLabel ?? `${options.agentName} -> working`;
|
|
4975
4624
|
const spinner = params.spinner ?? new Spinner(options.output, workingLabel, Boolean(options.activityReporter));
|
|
4976
|
-
const
|
|
4977
|
-
|
|
4978
|
-
const formatToolEvent = createToolEventFormatter(toolDisplayMode, void 0, {
|
|
4979
|
-
suppressRunProgressCards: typeof options.onAgentRunStatus === "function"
|
|
4625
|
+
const formatToolEvent = createToolEventFormatter(void 0, {
|
|
4626
|
+
tuiTrees: options.output.tuiTrees === true
|
|
4980
4627
|
});
|
|
4981
4628
|
const eventMode = resolveAgentEventMode(options);
|
|
4982
4629
|
const showThinking = options.showThinking !== false;
|
|
@@ -4985,25 +4632,42 @@ function createCliTurnOutput(params) {
|
|
|
4985
4632
|
let printedAssistantLabel = false;
|
|
4986
4633
|
let thinkState = createThinkParserState();
|
|
4987
4634
|
let thinkingFirstAt = null;
|
|
4988
|
-
let
|
|
4989
|
-
const
|
|
4990
|
-
|
|
4991
|
-
if (
|
|
4992
|
-
|
|
4635
|
+
let thinkingPreview = "";
|
|
4636
|
+
const markThinkingDelta = (chunk) => {
|
|
4637
|
+
if (!showThinking) return;
|
|
4638
|
+
if (streamedAssistantText) return;
|
|
4639
|
+
if (thinkingFirstAt === null) {
|
|
4640
|
+
thinkingFirstAt = Date.now();
|
|
4641
|
+
thinkingPreview = "";
|
|
4642
|
+
}
|
|
4643
|
+
thinkingPreview = appendThinkingPreview(thinkingPreview, chunk);
|
|
4644
|
+
spinner.setThinkingHint(thinkingPreview);
|
|
4645
|
+
reportThinkingProgress();
|
|
4646
|
+
};
|
|
4647
|
+
const reportThinkingProgress = () => {
|
|
4648
|
+
if (!showThinking) return;
|
|
4649
|
+
const preview = truncateThinkingHint(thinkingPreview, 60);
|
|
4650
|
+
const label = preview ? t("thinkingActivePreview", preview) : t("thinkingActive");
|
|
4651
|
+
options.activityReporter?.(label);
|
|
4993
4652
|
};
|
|
4994
|
-
const
|
|
4653
|
+
const endThinkingPhase = () => {
|
|
4995
4654
|
if (thinkingFirstAt === null) return;
|
|
4996
|
-
const seconds = Math.max(0, Math.round((
|
|
4655
|
+
const seconds = Math.max(0, Math.round((Date.now() - thinkingFirstAt) / 1e3));
|
|
4997
4656
|
thinkingFirstAt = null;
|
|
4998
|
-
|
|
4657
|
+
thinkingPreview = "";
|
|
4658
|
+
spinner.stop();
|
|
4659
|
+
options.activityReporter?.(null);
|
|
4660
|
+
if (seconds >= 1) {
|
|
4661
|
+
options.output.write(`${dimCliText(t("thinkingTraceLine", formatElapsed(seconds)))}
|
|
4999
4662
|
`);
|
|
4663
|
+
}
|
|
5000
4664
|
};
|
|
5001
4665
|
let compactionEvent = null;
|
|
5002
4666
|
const assistantLabelManaged = options.output.assistantLabelManaged === true;
|
|
5003
4667
|
const writeToolOutput = (chunk) => {
|
|
5004
4668
|
if (!chunk) return;
|
|
5005
4669
|
if (typeof options.output.writeToolBlock === "function") {
|
|
5006
|
-
options.output.writeToolBlock(chunk);
|
|
4670
|
+
if (!options.output.writeToolBlock(chunk)) formatToolEvent.reset?.();
|
|
5007
4671
|
} else {
|
|
5008
4672
|
options.output.write(chunk);
|
|
5009
4673
|
}
|
|
@@ -5013,17 +4677,15 @@ function createCliTurnOutput(params) {
|
|
|
5013
4677
|
});
|
|
5014
4678
|
const writeVisibleAssistantChunk = (chunk) => {
|
|
5015
4679
|
if (!chunk) return;
|
|
4680
|
+
formatToolEvent.reset?.();
|
|
5016
4681
|
const parsed = processThinkChunk(chunk, thinkState);
|
|
5017
4682
|
thinkState = parsed.state;
|
|
5018
4683
|
if (!parsed.content && !parsed.reasoning) return;
|
|
5019
|
-
if (
|
|
5020
|
-
|
|
5021
|
-
spinner.setThinkingHint(parsed.reasoning);
|
|
4684
|
+
if (parsed.reasoning) {
|
|
4685
|
+
markThinkingDelta(parsed.reasoning);
|
|
5022
4686
|
}
|
|
5023
4687
|
if (!parsed.content) return;
|
|
5024
|
-
|
|
5025
|
-
spinner.stop();
|
|
5026
|
-
options.activityReporter?.(null);
|
|
4688
|
+
endThinkingPhase();
|
|
5027
4689
|
if (!printedAssistantLabel) {
|
|
5028
4690
|
if (!assistantLabelManaged) {
|
|
5029
4691
|
options.output.write(`
|
|
@@ -5036,55 +4698,53 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5036
4698
|
renderWriter.push(parsed.content);
|
|
5037
4699
|
};
|
|
5038
4700
|
const handleToolEvent = (event) => {
|
|
5039
|
-
if (!traceLocalTools) return;
|
|
5040
|
-
const chunk = eventMode === "jsonl" ? formatToolJsonEvent(event) : formatToolEvent(event);
|
|
5041
4701
|
if (eventMode === "jsonl") {
|
|
5042
|
-
|
|
4702
|
+
const chunk2 = formatToolJsonEvent(event);
|
|
4703
|
+
options.output.write(chunk2);
|
|
4704
|
+
if (options.onAgentRunStatus) {
|
|
4705
|
+
const parsed = parseAgentRunEvent(event);
|
|
4706
|
+
if (parsed) {
|
|
4707
|
+
options.onAgentRunStatus(parsed.snapshot);
|
|
4708
|
+
}
|
|
4709
|
+
}
|
|
5043
4710
|
return;
|
|
5044
4711
|
}
|
|
5045
4712
|
if (event.type === "tool-call") {
|
|
5046
4713
|
renderWriter.flush();
|
|
4714
|
+
formatToolEvent(event);
|
|
4715
|
+
endThinkingPhase();
|
|
4716
|
+
if (streamedAssistantText) {
|
|
4717
|
+
options.output.write("\n");
|
|
4718
|
+
streamedAssistantText = false;
|
|
4719
|
+
}
|
|
4720
|
+
const activeLabel = formatConservativeActiveToolLabel(event);
|
|
4721
|
+
spinner.show(activeLabel);
|
|
4722
|
+
options.activityReporter?.(activeLabel);
|
|
4723
|
+
return;
|
|
4724
|
+
}
|
|
4725
|
+
const parsedRunEvent = parseAgentRunEvent(event);
|
|
4726
|
+
if (options.onAgentRunStatus && parsedRunEvent) {
|
|
4727
|
+
options.onAgentRunStatus(parsedRunEvent.snapshot);
|
|
5047
4728
|
}
|
|
5048
4729
|
spinner.stop();
|
|
5049
4730
|
options.activityReporter?.(null);
|
|
5050
|
-
if (event
|
|
5051
|
-
|
|
5052
|
-
|
|
4731
|
+
if (isLiveAgentRunObservation(event, parsedRunEvent)) {
|
|
4732
|
+
formatToolEvent.consume?.(event);
|
|
4733
|
+
return;
|
|
5053
4734
|
}
|
|
4735
|
+
const chunk = formatToolEvent(event);
|
|
5054
4736
|
if (chunk) {
|
|
5055
4737
|
writeToolOutput(chunk);
|
|
5056
4738
|
}
|
|
5057
|
-
if ((toolDisplayMode === "compact" || toolDisplayMode === "pro" || toolDisplayMode === "normal") && event.type === "tool-call") {
|
|
5058
|
-
const activeLabel = toolDisplayMode === "normal" ? formatConservativeActiveToolLabel(event) : formatActiveToolLabel(event);
|
|
5059
|
-
spinner.show(activeLabel);
|
|
5060
|
-
options.activityReporter?.(activeLabel);
|
|
5061
|
-
}
|
|
5062
|
-
if (options.onAgentRunStatus) {
|
|
5063
|
-
const parsed = parseAgentRunEvent(event);
|
|
5064
|
-
if (parsed) {
|
|
5065
|
-
options.onAgentRunStatus(parsed.snapshot);
|
|
5066
|
-
}
|
|
5067
|
-
}
|
|
5068
4739
|
};
|
|
5069
4740
|
return {
|
|
5070
4741
|
spinner,
|
|
5071
|
-
toolDisplayMode,
|
|
5072
|
-
traceLocalTools,
|
|
5073
4742
|
eventMode,
|
|
5074
4743
|
pushText(chunk) {
|
|
5075
|
-
if (eventMode !== "jsonl" && formatToolEvent.flush) {
|
|
5076
|
-
const pendingToolOutput = formatToolEvent.flush();
|
|
5077
|
-
if (pendingToolOutput) {
|
|
5078
|
-
writeToolOutput(pendingToolOutput);
|
|
5079
|
-
}
|
|
5080
|
-
}
|
|
5081
4744
|
writeVisibleAssistantChunk(chunk);
|
|
5082
4745
|
},
|
|
5083
4746
|
pushThinking(chunk) {
|
|
5084
|
-
|
|
5085
|
-
markThinkingActivity();
|
|
5086
|
-
spinner.setThinkingHint(chunk);
|
|
5087
|
-
}
|
|
4747
|
+
markThinkingDelta(chunk);
|
|
5088
4748
|
},
|
|
5089
4749
|
handleToolEvent,
|
|
5090
4750
|
/** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
|
|
@@ -5097,18 +4757,14 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
|
|
|
5097
4757
|
options.activityReporter?.(activeLabel);
|
|
5098
4758
|
},
|
|
5099
4759
|
finish(fallbackContent) {
|
|
5100
|
-
spinner.stop();
|
|
5101
|
-
options.activityReporter?.(null);
|
|
5102
|
-
writeThinkingTrace();
|
|
5103
4760
|
const flushedThink = flushThinkParser(thinkState);
|
|
5104
4761
|
thinkState = flushedThink.state;
|
|
5105
4762
|
if (flushedThink.content) {
|
|
5106
4763
|
writeVisibleAssistantChunk(flushedThink.content);
|
|
5107
4764
|
}
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
}
|
|
4765
|
+
endThinkingPhase();
|
|
4766
|
+
spinner.stop();
|
|
4767
|
+
options.activityReporter?.(null);
|
|
5112
4768
|
if (streamedAssistantText) {
|
|
5113
4769
|
renderWriter.flush();
|
|
5114
4770
|
options.output.write("\n");
|
|
@@ -5309,58 +4965,15 @@ ${describeClientVersionTooOldFailure(message, error)}`);
|
|
|
5309
4965
|
if (usageText && shouldShowUsage(options.env))
|
|
5310
4966
|
options.output.write(`${usageText}
|
|
5311
4967
|
`);
|
|
4968
|
+
const turnCredits = platformCreditsFromUsage(usage);
|
|
5312
4969
|
return {
|
|
5313
4970
|
exitCode: 0,
|
|
5314
4971
|
...dialogId ? { dialogId } : {},
|
|
5315
|
-
turnTokens: buildTurnTokenUsage(usage, options.agentKey)
|
|
4972
|
+
turnTokens: buildTurnTokenUsage(usage, options.agentKey),
|
|
4973
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
5316
4974
|
};
|
|
5317
4975
|
}
|
|
5318
4976
|
|
|
5319
|
-
// packages/cli/client/agentRunTypes.ts
|
|
5320
|
-
function resolveAuthToken2(env) {
|
|
5321
|
-
return resolvePlatformAuthToken(env);
|
|
5322
|
-
}
|
|
5323
|
-
function resolveFileWriteGateEnabled(env) {
|
|
5324
|
-
const raw = (env.NOLO_CLI_WRITE_GATE ?? "").trim().toLowerCase();
|
|
5325
|
-
return raw !== "off" && raw !== "0" && raw !== "false";
|
|
5326
|
-
}
|
|
5327
|
-
function isMachineBoundLocalhostCustomProvider(agentConfig) {
|
|
5328
|
-
const machineId = agentConfig?.runtimeBinding && typeof agentConfig.runtimeBinding === "object" ? String(agentConfig.runtimeBinding.machineId ?? "").trim() : "";
|
|
5329
|
-
const providerUrl = asTrimmedString(agentConfig?.customProviderUrl);
|
|
5330
|
-
if (!machineId || !providerUrl) return false;
|
|
5331
|
-
return isLoopbackUrl(providerUrl);
|
|
5332
|
-
}
|
|
5333
|
-
function resolveBoundMachineId(agentConfig) {
|
|
5334
|
-
return agentConfig?.runtimeBinding && typeof agentConfig.runtimeBinding === "object" ? String(agentConfig.runtimeBinding.machineId ?? "").trim() : "";
|
|
5335
|
-
}
|
|
5336
|
-
var CLI_PROVIDER_NAMES = /* @__PURE__ */ new Set([
|
|
5337
|
-
"agy",
|
|
5338
|
-
"claude",
|
|
5339
|
-
"codex",
|
|
5340
|
-
"copilot",
|
|
5341
|
-
"gemini",
|
|
5342
|
-
"grok",
|
|
5343
|
-
"kimi",
|
|
5344
|
-
"opencode",
|
|
5345
|
-
"qoder"
|
|
5346
|
-
]);
|
|
5347
|
-
function isCliProviderAgentConfig(agentConfig) {
|
|
5348
|
-
const cliProvider = asTrimmedLowercaseString(agentConfig?.cliProvider);
|
|
5349
|
-
const provider = asTrimmedLowercaseString(agentConfig?.provider);
|
|
5350
|
-
return Boolean(cliProvider) || CLI_PROVIDER_NAMES.has(provider);
|
|
5351
|
-
}
|
|
5352
|
-
async function detectCurrentMachineId(env) {
|
|
5353
|
-
const fromEnv = (env.NOLO_CURRENT_MACHINE_ID || env.NOLO_MACHINE_ID || "").trim();
|
|
5354
|
-
if (fromEnv) return fromEnv;
|
|
5355
|
-
try {
|
|
5356
|
-
const { detectMachineInfo } = await import("./machineInfo-66ZFUMLE.js");
|
|
5357
|
-
const machine = await detectMachineInfo({ probeLaunchable: true });
|
|
5358
|
-
return asOptionalTrimmedString(machine?.machineId);
|
|
5359
|
-
} catch {
|
|
5360
|
-
return void 0;
|
|
5361
|
-
}
|
|
5362
|
-
}
|
|
5363
|
-
|
|
5364
4977
|
// packages/cli/client/agentRunPlatformTools.ts
|
|
5365
4978
|
var SERVER_PLATFORM_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
5366
4979
|
"addTableRow",
|
|
@@ -5370,28 +4983,6 @@ var SERVER_PLATFORM_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
|
5370
4983
|
"updateTableRow",
|
|
5371
4984
|
"updateTableRows"
|
|
5372
4985
|
]);
|
|
5373
|
-
var KNOWN_SERVER_PLATFORM_AGENT_KEYS = /* @__PURE__ */ new Set([NOLO_PROJECT_MANAGER_AGENT_KEY]);
|
|
5374
|
-
var KNOWN_SERVER_PLATFORM_AGENT_ALIASES = /* @__PURE__ */ new Set([
|
|
5375
|
-
"code-review",
|
|
5376
|
-
"frontend",
|
|
5377
|
-
"frontend-agent",
|
|
5378
|
-
"frontend-implementer",
|
|
5379
|
-
"full-stack",
|
|
5380
|
-
"fullstack",
|
|
5381
|
-
"nolo code review",
|
|
5382
|
-
"nolo fullstack",
|
|
5383
|
-
"nolo project manager",
|
|
5384
|
-
"nolo reviewer",
|
|
5385
|
-
"nolo-code-review",
|
|
5386
|
-
"nolo-fullstack",
|
|
5387
|
-
"nolo-pm",
|
|
5388
|
-
"nolo-project-manager",
|
|
5389
|
-
"nolo-reviewer",
|
|
5390
|
-
"pm",
|
|
5391
|
-
"project-manager",
|
|
5392
|
-
"review",
|
|
5393
|
-
"reviewer"
|
|
5394
|
-
]);
|
|
5395
4986
|
function findServerPlatformTools(toolNames) {
|
|
5396
4987
|
if (!Array.isArray(toolNames)) return [];
|
|
5397
4988
|
return toolNames.filter(
|
|
@@ -5404,13 +4995,6 @@ function resolveServerPlatformToolNames(agentConfig) {
|
|
|
5404
4995
|
...Array.isArray(agentConfig?.runtimeToolPolicy?.agentTools) ? agentConfig.runtimeToolPolicy.agentTools : []
|
|
5405
4996
|
]);
|
|
5406
4997
|
}
|
|
5407
|
-
function isKnownServerPlatformAgent(options) {
|
|
5408
|
-
if (KNOWN_SERVER_PLATFORM_AGENT_KEYS.has(options.agentKey)) return true;
|
|
5409
|
-
const normalizedKey = normalizeAgentHandle(options.agentKey);
|
|
5410
|
-
return Boolean(
|
|
5411
|
-
normalizedKey && KNOWN_SERVER_PLATFORM_AGENT_ALIASES.has(normalizedKey)
|
|
5412
|
-
);
|
|
5413
|
-
}
|
|
5414
4998
|
|
|
5415
4999
|
// packages/core/collapsedPaste.ts
|
|
5416
5000
|
var COLLAPSE_PASTE_MIN_LINES = 8;
|
|
@@ -5592,10 +5176,14 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
|
|
|
5592
5176
|
// packages/cli/client/agentRun.ts
|
|
5593
5177
|
import { ulid } from "ulid";
|
|
5594
5178
|
async function loadRunLocalAgentTurn() {
|
|
5595
|
-
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-
|
|
5179
|
+
const { runLocalAgentTurn } = await import("./agentRuntimeLocal-XCJLRWQE.js");
|
|
5596
5180
|
return runLocalAgentTurn;
|
|
5597
5181
|
}
|
|
5598
5182
|
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();
|
|
5183
|
+
var pickEmptyAssistantFlags = (result) => ({
|
|
5184
|
+
...result.emptyAssistantFallbackReason ? { emptyAssistantFallbackReason: result.emptyAssistantFallbackReason } : {},
|
|
5185
|
+
...result.emptyAssistantOutputUsable ? { emptyAssistantOutputUsable: true } : {}
|
|
5186
|
+
});
|
|
5599
5187
|
function extractEmbeddedErrorMessage(message) {
|
|
5600
5188
|
const match = /"message"\s*:\s*"((?:[^"\\]|\\.)*)"/.exec(message);
|
|
5601
5189
|
if (!match) return void 0;
|
|
@@ -5710,25 +5298,44 @@ function wrapLoadAgentConfigWithModelOverride(adapter, targetAgentKey, override)
|
|
|
5710
5298
|
}
|
|
5711
5299
|
};
|
|
5712
5300
|
}
|
|
5301
|
+
var oauthChannelSkipReportedOutputs = /* @__PURE__ */ new WeakSet();
|
|
5302
|
+
function resolveOAuthChannelOwnerSkip(agentConfig, options) {
|
|
5303
|
+
if (!agentConfig) return null;
|
|
5304
|
+
const apiKeyRef = typeof agentConfig.apiKeyRef === "string" ? agentConfig.apiKeyRef : void 0;
|
|
5305
|
+
if (!isOAuthApiKeyRef(apiKeyRef) && !isAntigravityOAuthAgent(agentConfig)) {
|
|
5306
|
+
return null;
|
|
5307
|
+
}
|
|
5308
|
+
const rawRecord = agentConfig.rawRecord ?? {};
|
|
5309
|
+
const ownerUserId = asOptionalTrimmedString(rawRecord.userId) ?? asOptionalTrimmedString(rawRecord.ownerUserId);
|
|
5310
|
+
if (!ownerUserId) return null;
|
|
5311
|
+
const localUserId = resolveLocalUserId(options.env);
|
|
5312
|
+
if (ownerUserId === localUserId) return null;
|
|
5313
|
+
return `[nolo] auto runtime: skipping local runtime because ${options.agentKey} runs on its owner's OAuth subscription channel (owner ${ownerUserId}, this machine runs as ${localUserId}). Use --local explicitly to force this machine's own subscription.
|
|
5314
|
+
`;
|
|
5315
|
+
}
|
|
5713
5316
|
async function shouldSkipAutoLocalForServerPlatformTools(options) {
|
|
5714
5317
|
if (isBuiltinNoloAgentRef(options.agentKey)) return false;
|
|
5715
|
-
|
|
5318
|
+
const adapter = resolveLocalRuntimeAdapter(options);
|
|
5319
|
+
if (!adapter) {
|
|
5716
5320
|
return false;
|
|
5717
5321
|
}
|
|
5718
|
-
const knownServerPlatformAgent = isKnownServerPlatformAgent(options);
|
|
5719
|
-
const adapter = resolveLocalRuntimeAdapter(options);
|
|
5720
|
-
if (!adapter) return knownServerPlatformAgent;
|
|
5721
5322
|
let agentConfig;
|
|
5722
5323
|
try {
|
|
5723
5324
|
agentConfig = await adapter.loadAgentConfig(options.agentKey);
|
|
5724
5325
|
} catch {
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5326
|
+
return false;
|
|
5327
|
+
}
|
|
5328
|
+
const oauthChannelOwnerSkip = resolveOAuthChannelOwnerSkip(agentConfig, options);
|
|
5329
|
+
if (oauthChannelOwnerSkip) {
|
|
5330
|
+
if (!options.output || typeof options.output !== "object" || !oauthChannelSkipReportedOutputs.has(options.output)) {
|
|
5331
|
+
if (options.output && typeof options.output === "object") {
|
|
5332
|
+
oauthChannelSkipReportedOutputs.add(options.output);
|
|
5333
|
+
}
|
|
5334
|
+
options.output.write(oauthChannelOwnerSkip);
|
|
5731
5335
|
}
|
|
5336
|
+
return true;
|
|
5337
|
+
}
|
|
5338
|
+
if (options.localRuntimeCwd) {
|
|
5732
5339
|
return false;
|
|
5733
5340
|
}
|
|
5734
5341
|
if (isCliProviderAgentConfig(agentConfig)) {
|
|
@@ -5741,10 +5348,12 @@ async function shouldSkipAutoLocalForServerPlatformTools(options) {
|
|
|
5741
5348
|
);
|
|
5742
5349
|
return true;
|
|
5743
5350
|
}
|
|
5744
|
-
if (
|
|
5351
|
+
if (resolveBoundMachineId(agentConfig)) {
|
|
5352
|
+
const currentMachineId = (await resolveCurrentMachineId(options))?.trim() || "";
|
|
5353
|
+
const boundMachineId = resolveBoundMachineId(agentConfig);
|
|
5354
|
+
if (currentMachineId && currentMachineId === boundMachineId) return false;
|
|
5745
5355
|
options.output.write(
|
|
5746
|
-
`[nolo] auto runtime: skipping local runtime because ${options.agentKey} is a
|
|
5747
|
-
`
|
|
5356
|
+
`[nolo] auto runtime: skipping local runtime because ${options.agentKey} is a platform agent bound to machine ${boundMachineId}` + (currentMachineId ? ` (this machine is ${currentMachineId}).` : ".") + " The server will dispatch it to the bound machine connector.\n"
|
|
5748
5357
|
);
|
|
5749
5358
|
return true;
|
|
5750
5359
|
}
|
|
@@ -5822,9 +5431,12 @@ function classifyLocalRunError(message) {
|
|
|
5822
5431
|
if (!m) return { kind: "generic" };
|
|
5823
5432
|
const status = Number(m[2]);
|
|
5824
5433
|
const transport = PLATFORM_TRANSPORT_RE.test(message) ? "platform" : "local";
|
|
5825
|
-
if (status === 401
|
|
5434
|
+
if (status === 401) {
|
|
5826
5435
|
return { kind: "auth", transport, status };
|
|
5827
5436
|
}
|
|
5437
|
+
if (status === 403) {
|
|
5438
|
+
return isQuotaLimited403Body(message) ? { kind: "rate-limit", transport, status } : { kind: "auth", transport, status };
|
|
5439
|
+
}
|
|
5828
5440
|
if (status === 400 || status === 422) {
|
|
5829
5441
|
return { kind: "rejected-payload", transport, status };
|
|
5830
5442
|
}
|
|
@@ -5841,10 +5453,14 @@ var RUN_UNAVAILABLE_PREFIX = "[nolo] auto runtime: local run unavailable";
|
|
|
5841
5453
|
var NO_FALLBACK = "Not falling back to server.";
|
|
5842
5454
|
var SERVER_FALLBACK_HINT = "or use --server to run on the server explicitly.";
|
|
5843
5455
|
function buildAuthFailure(ctx) {
|
|
5844
|
-
const
|
|
5456
|
+
const platformNoToken = ctx.where === "server chat proxy" && isAuthNoTokenBody(ctx.message);
|
|
5457
|
+
const fix = platformNoToken ? `This install is not logged in \u2014 run \`nolo login\`, or set AUTH_TOKEN / NOLO_SERVER` : ctx.where === "server chat proxy" ? `Check the agent's provider/api-key settings on nolo.chat` : `Fix the local credential/config and retry`;
|
|
5845
5458
|
return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, auth rejected). Detail: ${ctx.message} ${NO_FALLBACK} ${fix}, ${SERVER_FALLBACK_HINT}.
|
|
5846
5459
|
`;
|
|
5847
5460
|
}
|
|
5461
|
+
function isAuthNoTokenBody(message) {
|
|
5462
|
+
return /"authCode"\s*:\s*"AUTH_NO_TOKEN"/i.test(message) || /no authentication token provided/i.test(message);
|
|
5463
|
+
}
|
|
5848
5464
|
function buildRejectedPayloadFailure(ctx) {
|
|
5849
5465
|
const looksLikeHistoryReplay = HISTORY_REPLAY_REJECTION_RE.test(ctx.message);
|
|
5850
5466
|
const cause = looksLikeHistoryReplay ? ` This usually happens when the dialog history contains tool_calls or reasoning produced by a different model/provider (e.g. after /switch); the new provider rejects that history. Start a fresh dialog, or clean the offending history.` : "";
|
|
@@ -5873,6 +5489,9 @@ var FAILURE_BUILDERS = {
|
|
|
5873
5489
|
upstream: buildUpstreamFailure
|
|
5874
5490
|
};
|
|
5875
5491
|
function describeLocalRunFailure(message, rawError) {
|
|
5492
|
+
if (rawError && typeof rawError === "object" && "code" in rawError && rawError.code === "PLATFORM_STREAM_INTERRUPTED") {
|
|
5493
|
+
return "[nolo] The platform LLM stream was interrupted before the turn completed. Your conversation was preserved. Send another message to continue.\n";
|
|
5494
|
+
}
|
|
5876
5495
|
if (isClientVersionTooOldFailure(message, rawError)) {
|
|
5877
5496
|
return describeClientVersionTooOldFailure(message, rawError);
|
|
5878
5497
|
}
|
|
@@ -5903,6 +5522,26 @@ function describeLocalRunFailure(message, rawError) {
|
|
|
5903
5522
|
balanceDetails.current
|
|
5904
5523
|
) : extractEmbeddedErrorMessage(cleanedMessage) ?? fallback;
|
|
5905
5524
|
return `[nolo] ${shownMessage}
|
|
5525
|
+
`;
|
|
5526
|
+
}
|
|
5527
|
+
if (isCliAuthorityBrokerTimeoutError(rawError) || /CLI authority broker .* timed out/i.test(message)) {
|
|
5528
|
+
const cleaned = stripDebugNoise(message);
|
|
5529
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker timed out and did not respond in time (an existing broker process may be unresponsive). Check the local broker process or retry, ${SERVER_FALLBACK_HINT}.
|
|
5530
|
+
`;
|
|
5531
|
+
}
|
|
5532
|
+
if (/CLI authority broker could not attach or take ownership/i.test(message)) {
|
|
5533
|
+
const cleaned = stripDebugNoise(message);
|
|
5534
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local runtime could not attach to an existing broker or take database ownership. Check running broker processes holding the local authority store or retry, ${SERVER_FALLBACK_HINT}.
|
|
5535
|
+
`;
|
|
5536
|
+
}
|
|
5537
|
+
if (isCliAuthorityBrokerUnavailableError(rawError) || /CLI authority broker unavailable at/i.test(message)) {
|
|
5538
|
+
const cleaned = stripDebugNoise(message);
|
|
5539
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker is unavailable. Start or restart the local authority broker and retry, ${SERVER_FALLBACK_HINT}.
|
|
5540
|
+
`;
|
|
5541
|
+
}
|
|
5542
|
+
if (isCliAuthorityBrokerProtocolError(rawError) || /CLI authority broker protocol|CLI authority broker .* returned malformed response/i.test(message)) {
|
|
5543
|
+
const cleaned = stripDebugNoise(message);
|
|
5544
|
+
return `${RUN_UNAVAILABLE_PREFIX} (${cleaned}). ${NO_FALLBACK} The local authority broker returned a protocol or malformed response error. Check the running broker process and retry, ${SERVER_FALLBACK_HINT}.
|
|
5906
5545
|
`;
|
|
5907
5546
|
}
|
|
5908
5547
|
const cls = classifyLocalRunError(message);
|
|
@@ -5947,7 +5586,7 @@ function shouldAttemptAutoLocal(options) {
|
|
|
5947
5586
|
if (options.env.NOLO_DISABLE_CLI_WORKSPACE_TOOLS !== "1" && isBuiltinNoloAgentRef(options.agentKey) && resolveAuthToken2(options.env)) {
|
|
5948
5587
|
return true;
|
|
5949
5588
|
}
|
|
5950
|
-
if (options.env.NOLO_DISABLE_CLI_WORKSPACE_TOOLS !== "1" && resolveAuthToken2(options.env)
|
|
5589
|
+
if (options.env.NOLO_DISABLE_CLI_WORKSPACE_TOOLS !== "1" && resolveAuthToken2(options.env)) {
|
|
5951
5590
|
return true;
|
|
5952
5591
|
}
|
|
5953
5592
|
return Boolean(
|
|
@@ -5989,9 +5628,6 @@ async function runHttpAgentTurn(options, authToken) {
|
|
|
5989
5628
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
5990
5629
|
const clientVersionHeader = resolveClientVersion(options.env ?? {});
|
|
5991
5630
|
const subjectRefs = buildSubjectRefs(options);
|
|
5992
|
-
const allowedChildAgentKeys = options.allowedChildAgentKeys?.filter(
|
|
5993
|
-
(key) => key.trim()
|
|
5994
|
-
);
|
|
5995
5631
|
const allowedToolNames = options.allowedToolNames?.filter(
|
|
5996
5632
|
(name) => name.trim()
|
|
5997
5633
|
);
|
|
@@ -6015,9 +5651,8 @@ async function runHttpAgentTurn(options, authToken) {
|
|
|
6015
5651
|
capabilities: ["text-io", "streaming", "slash-commands"],
|
|
6016
5652
|
...options.dialogAgentMode ? { dialogAgentMode: options.dialogAgentMode } : {},
|
|
6017
5653
|
...subjectRefs ? { subjectRefs } : {},
|
|
6018
|
-
...
|
|
6019
|
-
...
|
|
6020
|
-
...allowedToolNames?.length ? { allowedToolNames } : {}
|
|
5654
|
+
...blockedToolNames !== void 0 ? { blockedToolNames } : {},
|
|
5655
|
+
...allowedToolNames !== void 0 ? { allowedToolNames } : {}
|
|
6021
5656
|
},
|
|
6022
5657
|
...options.continueDialogId ? { continueDialogId: options.continueDialogId } : {},
|
|
6023
5658
|
...options.spaceId ? { spaceId: options.spaceId } : {},
|
|
@@ -6133,13 +5768,17 @@ ${options.agentName} > (no text response)
|
|
|
6133
5768
|
const usage = formatUsage(data?.usage, data?.dialogId);
|
|
6134
5769
|
if (usage && shouldShowUsage(options.env)) options.output.write(`${usage}
|
|
6135
5770
|
`);
|
|
5771
|
+
const turnCredits = platformCreditsFromUsage(
|
|
5772
|
+
data?.usage
|
|
5773
|
+
);
|
|
6136
5774
|
return {
|
|
6137
5775
|
exitCode: 0,
|
|
6138
5776
|
...typeof data?.dialogId === "string" && data.dialogId ? { dialogId: data.dialogId } : {},
|
|
6139
5777
|
turnTokens: buildTurnTokenUsage(
|
|
6140
5778
|
data?.usage,
|
|
6141
5779
|
typeof data?.model === "string" ? data.model : options.agentKey
|
|
6142
|
-
)
|
|
5780
|
+
),
|
|
5781
|
+
...turnCredits !== void 0 ? { turnCredits } : {}
|
|
6143
5782
|
};
|
|
6144
5783
|
}
|
|
6145
5784
|
async function runInjectedLocalAgentTurn(options) {
|
|
@@ -6169,21 +5808,17 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6169
5808
|
return { exitCode: 1 };
|
|
6170
5809
|
}
|
|
6171
5810
|
const subjectRefs = buildSubjectRefs(options);
|
|
6172
|
-
const allowedChildAgentKeys = options.allowedChildAgentKeys?.filter(
|
|
6173
|
-
(key) => key.trim()
|
|
6174
|
-
);
|
|
6175
5811
|
const allowedToolNames = options.allowedToolNames?.filter(
|
|
6176
5812
|
(name) => name.trim()
|
|
6177
5813
|
);
|
|
6178
5814
|
const blockedToolNames = options.blockedToolNames?.filter(
|
|
6179
5815
|
(name) => name.trim()
|
|
6180
5816
|
);
|
|
6181
|
-
const runtimeContext = subjectRefs ||
|
|
5817
|
+
const runtimeContext = subjectRefs || allowedToolNames !== void 0 || blockedToolNames !== void 0 || options.parentWakeOnTerminal || options.dialogAgentMode ? {
|
|
6182
5818
|
...subjectRefs ? { subjectRefs } : {},
|
|
6183
5819
|
...options.dialogAgentMode ? { dialogAgentMode: options.dialogAgentMode } : {},
|
|
6184
|
-
...
|
|
6185
|
-
...
|
|
6186
|
-
...blockedToolNames?.length ? { blockedToolNames } : {},
|
|
5820
|
+
...allowedToolNames !== void 0 ? { allowedToolNames } : {},
|
|
5821
|
+
...blockedToolNames !== void 0 ? { blockedToolNames } : {},
|
|
6187
5822
|
...options.parentWakeOnTerminal ? { parentWakeOnTerminal: true } : {},
|
|
6188
5823
|
...options.parentDialogId ? { parentThreadId: options.parentDialogId } : {}
|
|
6189
5824
|
} : void 0;
|
|
@@ -6223,6 +5858,8 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6223
5858
|
category: options.category,
|
|
6224
5859
|
inheritedFromDialogKey: options.inheritedFromDialogKey,
|
|
6225
5860
|
parentDialogId: options.parentDialogId,
|
|
5861
|
+
runtimeContext,
|
|
5862
|
+
runKind: options.env.NOLO_AGENT_RUN_CHILD === "1" ? "subtask" : "interactive",
|
|
6226
5863
|
background: options.background,
|
|
6227
5864
|
noStream: options.noStream,
|
|
6228
5865
|
...runtimeContext ? { runtimeContext } : {},
|
|
@@ -6235,7 +5872,7 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6235
5872
|
}
|
|
6236
5873
|
if (event.kind === "image-downgraded") {
|
|
6237
5874
|
options.output.write(
|
|
6238
|
-
"[nolo] \u5F53\u524D agent \u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF0C\u5DF2\u7528\u5360\u4F4D\u6587\u672C\u66FF\u4EE3\u3002\
|
|
5875
|
+
"[nolo] \u5F53\u524D agent \u88AB\u914D\u7F6E\u4E3A\u4E0D\u652F\u6301\u56FE\u7247\u8F93\u5165\uFF0C\u56FE\u7247\u5DF2\u7528\u5360\u4F4D\u6587\u672C\u66FF\u4EE3\u3002\u8BF7\u68C0\u67E5\u6A21\u578B\u7684\u56FE\u7247\u80FD\u529B\u914D\u7F6E\uFF0C\u6216\u7528 /switch \u9009\u62E9\u652F\u6301\u56FE\u7247\u7684 agent \u540E\u91CD\u65B0\u53D1\u9001\u56FE\u7247\u3002\n"
|
|
6239
5876
|
);
|
|
6240
5877
|
}
|
|
6241
5878
|
if (event.kind === "compaction") {
|
|
@@ -6244,11 +5881,13 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6244
5881
|
options.onLoopEvent?.(event);
|
|
6245
5882
|
},
|
|
6246
5883
|
...options.abortSignal ? { abortSignal: options.abortSignal } : {},
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
5884
|
+
// 回合内注入(TUI 后台 run 唤醒直投):透传给 local loop。
|
|
5885
|
+
...options.drainInjections ? { drainInjections: options.drainInjections } : {},
|
|
5886
|
+
// tool-gist-fold 后 onToolEvent 无条件挂载(不再受 traceLocalTools 开关
|
|
5887
|
+
// 控制,显示模式合并为单一 gist/折叠通道)——保留 alpha 的新形态。
|
|
5888
|
+
onToolEvent: (event) => {
|
|
5889
|
+
turnOutput.handleToolEvent(event);
|
|
5890
|
+
},
|
|
6252
5891
|
...!options.noStream ? {
|
|
6253
5892
|
onTextDelta: (chunk) => {
|
|
6254
5893
|
turnOutput.pushText(chunk);
|
|
@@ -6259,24 +5898,35 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6259
5898
|
} : {}
|
|
6260
5899
|
});
|
|
6261
5900
|
turnOutput.finish(result.content);
|
|
5901
|
+
const turnCredits = sumPlatformCredits(result.usageRecords);
|
|
6262
5902
|
return {
|
|
6263
5903
|
exitCode: 0,
|
|
6264
5904
|
dialogId: result.dialogId,
|
|
6265
5905
|
title: result.title,
|
|
6266
5906
|
...result.titlePatchPromise ? { titlePatchPromise: result.titlePatchPromise } : {},
|
|
6267
|
-
...result
|
|
6268
|
-
|
|
5907
|
+
...pickEmptyAssistantFlags(result),
|
|
5908
|
+
// 积分口径按「全轮」而非「最后一次调用」:result.usage 只是收尾那次
|
|
5909
|
+
// provider 调用的 usage,本轮前面 N-1 次工具循环调用(以及自动压缩摘要)
|
|
5910
|
+
// 的 cost 都只存在于 usageRecords 里。token 字段仍取 result.usage——
|
|
5911
|
+
// 上下文占用本来就该看最后一次调用的累计输入,不是各次相加。
|
|
5912
|
+
turnTokens: withTurnCredits(buildTurnTokenUsage(result.usage, result.model), turnCredits),
|
|
5913
|
+
...turnCredits !== void 0 ? { turnCredits } : {},
|
|
5914
|
+
...result.usageRecords?.length ? { usageRecords: result.usageRecords } : {}
|
|
6269
5915
|
};
|
|
6270
5916
|
} catch (error) {
|
|
6271
5917
|
turnOutput.spinner.stop();
|
|
6272
5918
|
const savedDialogId = error?.dialogId;
|
|
5919
|
+
const abortedUsageRecords = error?.usageRecords;
|
|
5920
|
+
const abortedTurnCredits = sumPlatformCredits(abortedUsageRecords);
|
|
6273
5921
|
if (error?.code === LOCAL_TURN_ABORTED_CODE || options.abortSignal?.aborted) {
|
|
6274
5922
|
const pendingToolName = error?.pendingToolName;
|
|
6275
5923
|
return {
|
|
6276
5924
|
exitCode: 0,
|
|
6277
5925
|
streamInterrupted: true,
|
|
6278
5926
|
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
6279
|
-
...pendingToolName ? { pendingToolName } : {}
|
|
5927
|
+
...pendingToolName ? { pendingToolName } : {},
|
|
5928
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5929
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6280
5930
|
};
|
|
6281
5931
|
}
|
|
6282
5932
|
const cooldownUntil = await markStartupRateLimitCooldown(
|
|
@@ -6302,10 +5952,76 @@ async function runLocalAgentTurnForCli(options, settings) {
|
|
|
6302
5952
|
return {
|
|
6303
5953
|
exitCode: 1,
|
|
6304
5954
|
localError: error,
|
|
6305
|
-
...savedDialogId ? { dialogId: savedDialogId } : {}
|
|
5955
|
+
...savedDialogId ? { dialogId: savedDialogId } : {},
|
|
5956
|
+
...abortedTurnCredits !== void 0 ? { turnCredits: abortedTurnCredits } : {},
|
|
5957
|
+
...abortedUsageRecords?.length ? { usageRecords: abortedUsageRecords } : {}
|
|
6306
5958
|
};
|
|
6307
5959
|
}
|
|
6308
5960
|
}
|
|
5961
|
+
async function checkLocalAvailabilityBeforeHttpDispatch(options) {
|
|
5962
|
+
const adapter = resolveLocalRuntimeAdapter(options);
|
|
5963
|
+
if (!adapter || typeof adapter.loadAgentConfig !== "function") return null;
|
|
5964
|
+
let config;
|
|
5965
|
+
try {
|
|
5966
|
+
config = await adapter.loadAgentConfig(options.agentKey);
|
|
5967
|
+
} catch {
|
|
5968
|
+
return null;
|
|
5969
|
+
}
|
|
5970
|
+
if (!config || typeof config !== "object") return null;
|
|
5971
|
+
const baseRecord = config.rawRecord ?? config;
|
|
5972
|
+
let credentialKey = resolveCredentialKeyWithFallback(baseRecord);
|
|
5973
|
+
if (credentialKey && resolveOAuthChannelOwnerSkip(
|
|
5974
|
+
config,
|
|
5975
|
+
options
|
|
5976
|
+
)) {
|
|
5977
|
+
credentialKey = void 0;
|
|
5978
|
+
}
|
|
5979
|
+
const agentLevelAt = baseRecord.nextAvailableAt;
|
|
5980
|
+
const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
|
|
5981
|
+
if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
|
|
5982
|
+
const env = options.env;
|
|
5983
|
+
const now = Date.now();
|
|
5984
|
+
const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
|
|
5985
|
+
const entryAt = entry?.nextAvailableAt;
|
|
5986
|
+
const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
|
|
5987
|
+
if (typeof effectiveNextAvailableAt !== "number") return null;
|
|
5988
|
+
const gateDecision = resolveCooldownGate(
|
|
5989
|
+
{ nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
|
|
5990
|
+
now
|
|
5991
|
+
);
|
|
5992
|
+
if (gateDecision === "probe" && credentialKey) {
|
|
5993
|
+
await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
|
|
5994
|
+
return null;
|
|
5995
|
+
}
|
|
5996
|
+
if (gateDecision !== "blocked") return null;
|
|
5997
|
+
options.output.write(
|
|
5998
|
+
`[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
|
|
5999
|
+
Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
|
|
6000
|
+
`
|
|
6001
|
+
);
|
|
6002
|
+
return { exitCode: 1 };
|
|
6003
|
+
}
|
|
6004
|
+
function foldLocalResultForTui(localResult) {
|
|
6005
|
+
return {
|
|
6006
|
+
exitCode: localResult.exitCode,
|
|
6007
|
+
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6008
|
+
title: localResult.title,
|
|
6009
|
+
...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
|
|
6010
|
+
// 空 assistant 兜底成因必须随行:后台 run 的结算(resolveRunOutcome 的
|
|
6011
|
+
// isStalledOrTruncated)靠它把截断轮判成 stalled 而不是 clean 失败。
|
|
6012
|
+
...pickEmptyAssistantFlags(localResult),
|
|
6013
|
+
...localResult.turnTokens ? { turnTokens: localResult.turnTokens } : {},
|
|
6014
|
+
// 平台积分必须随行:runLocalAgentTurnForCli 里 sumPlatformCredits 已按
|
|
6015
|
+
// 「全轮逐次求和」算好(只认 billing_unit === "credits" 的平台计费帧)。
|
|
6016
|
+
...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
|
|
6017
|
+
// 逐帧用量明细必须随行:cli-local 计费走 fail-open 客户端记账,服务端没有
|
|
6018
|
+
// 逐帧记录,TUI 计费审计(appendTurnBillingAudit)要靠它对账。白名单历史上
|
|
6019
|
+
// 漏过 turnCredits(fix/tui-session-credits),usageRecords 是同坑位新字段。
|
|
6020
|
+
...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {},
|
|
6021
|
+
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
6022
|
+
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
6023
|
+
};
|
|
6024
|
+
}
|
|
6309
6025
|
async function runAgentTurn(options) {
|
|
6310
6026
|
const authToken = resolveAuthToken2(options.env);
|
|
6311
6027
|
const runtimeMode = resolveRequestedRuntimeMode(options);
|
|
@@ -6319,15 +6035,7 @@ async function runAgentTurn(options) {
|
|
|
6319
6035
|
reportFailure: false
|
|
6320
6036
|
});
|
|
6321
6037
|
if (localResult.exitCode === 0) {
|
|
6322
|
-
return
|
|
6323
|
-
exitCode: localResult.exitCode,
|
|
6324
|
-
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6325
|
-
title: localResult.title,
|
|
6326
|
-
...localResult.titlePatchPromise ? { titlePatchPromise: localResult.titlePatchPromise } : {},
|
|
6327
|
-
...localResult.turnTokens ? { turnTokens: localResult.turnTokens } : {},
|
|
6328
|
-
...localResult.streamInterrupted ? { streamInterrupted: localResult.streamInterrupted } : {},
|
|
6329
|
-
...localResult.pendingToolName ? { pendingToolName: localResult.pendingToolName } : {}
|
|
6330
|
-
};
|
|
6038
|
+
return foldLocalResultForTui(localResult);
|
|
6331
6039
|
}
|
|
6332
6040
|
if (isMissingLocalAgentConfigError(localResult.localError, options.agentKey)) {
|
|
6333
6041
|
options.output.write(
|
|
@@ -6341,13 +6049,7 @@ async function runAgentTurn(options) {
|
|
|
6341
6049
|
reportFailure: false
|
|
6342
6050
|
});
|
|
6343
6051
|
if (retriedLocalResult.exitCode === 0) {
|
|
6344
|
-
return
|
|
6345
|
-
exitCode: retriedLocalResult.exitCode,
|
|
6346
|
-
...retriedLocalResult.dialogId ? { dialogId: retriedLocalResult.dialogId } : {},
|
|
6347
|
-
title: retriedLocalResult.title,
|
|
6348
|
-
...retriedLocalResult.titlePatchPromise ? { titlePatchPromise: retriedLocalResult.titlePatchPromise } : {},
|
|
6349
|
-
...retriedLocalResult.turnTokens ? { turnTokens: retriedLocalResult.turnTokens } : {}
|
|
6350
|
-
};
|
|
6052
|
+
return foldLocalResultForTui(retriedLocalResult);
|
|
6351
6053
|
}
|
|
6352
6054
|
}
|
|
6353
6055
|
} catch {
|
|
@@ -6360,7 +6062,11 @@ async function runAgentTurn(options) {
|
|
|
6360
6062
|
...localResult.dialogId ? { dialogId: localResult.dialogId } : {},
|
|
6361
6063
|
// Keep localError so TUI can show balance/quota/dialog-preserved hints
|
|
6362
6064
|
// instead of only the raw auto-runtime line.
|
|
6363
|
-
...localResult.localError ? { localError: localResult.localError } : {}
|
|
6065
|
+
...localResult.localError ? { localError: localResult.localError } : {},
|
|
6066
|
+
// 失败轮同样可能已发生平台计费(abort/失败照样扣费):turnCredits 与
|
|
6067
|
+
// 逐帧明细一起随行,否则审计日志在 auto 失败路径上缺账。
|
|
6068
|
+
...localResult.turnCredits !== void 0 ? { turnCredits: localResult.turnCredits } : {},
|
|
6069
|
+
...localResult.usageRecords?.length ? { usageRecords: localResult.usageRecords } : {}
|
|
6364
6070
|
};
|
|
6365
6071
|
}
|
|
6366
6072
|
}
|
|
@@ -6370,26 +6076,107 @@ async function runAgentTurn(options) {
|
|
|
6370
6076
|
);
|
|
6371
6077
|
return { exitCode: 1 };
|
|
6372
6078
|
}
|
|
6079
|
+
const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
|
|
6080
|
+
if (localBlock) {
|
|
6081
|
+
return { exitCode: localBlock.exitCode };
|
|
6082
|
+
}
|
|
6373
6083
|
return runHttpAgentTurn(options, authToken);
|
|
6374
6084
|
}
|
|
6375
6085
|
|
|
6376
6086
|
// packages/cli/agentRunCommand.ts
|
|
6377
6087
|
import * as nodeFs from "node:fs";
|
|
6378
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
6379
|
-
import { join as join2 } from "node:path";
|
|
6380
6088
|
|
|
6381
6089
|
// packages/cli/client/autoModelRouter.ts
|
|
6382
6090
|
var CLI_AUTO_ROUTE_AGENT_KEY = BUILTIN_NOLO_AGENT_KEY;
|
|
6383
6091
|
|
|
6092
|
+
// packages/agent-runtime/agentsMd.ts
|
|
6093
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6094
|
+
import { join } from "node:path";
|
|
6095
|
+
var AGENTS_MD_MAX_BYTES = 8192;
|
|
6096
|
+
var AGENTS_MD_CANDIDATES = ["AGENTS.md", "CLAUDE.md"];
|
|
6097
|
+
function readAgentsMdLayerFromDisk(cwd) {
|
|
6098
|
+
for (const name of AGENTS_MD_CANDIDATES) {
|
|
6099
|
+
const filePath = join(cwd, name);
|
|
6100
|
+
if (!existsSync(filePath)) continue;
|
|
6101
|
+
try {
|
|
6102
|
+
let content = readFileSync(filePath, "utf8").trim();
|
|
6103
|
+
if (!content) continue;
|
|
6104
|
+
if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
|
|
6105
|
+
content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
6106
|
+
}
|
|
6107
|
+
return buildAgentsMdLayer(content, name);
|
|
6108
|
+
} catch {
|
|
6109
|
+
}
|
|
6110
|
+
}
|
|
6111
|
+
return null;
|
|
6112
|
+
}
|
|
6113
|
+
|
|
6114
|
+
// packages/cli/agentRunDoD.ts
|
|
6115
|
+
import { spawnSync as nodeSpawnSync } from "node:child_process";
|
|
6116
|
+
var DOD_COMMAND_TIMEOUT_MS = 12e4;
|
|
6117
|
+
function extractTailLines(text, count) {
|
|
6118
|
+
if (!text) return [];
|
|
6119
|
+
const lines = String(text).split("\n");
|
|
6120
|
+
while (lines.length > 0 && lines[lines.length - 1].trim() === "") lines.pop();
|
|
6121
|
+
return lines.slice(-count);
|
|
6122
|
+
}
|
|
6123
|
+
function executeDoDCommand(cmd, cwd, deps = {}) {
|
|
6124
|
+
const spawnSync = deps.spawnSync ?? nodeSpawnSync;
|
|
6125
|
+
try {
|
|
6126
|
+
const res = spawnSync(cmd, {
|
|
6127
|
+
shell: true,
|
|
6128
|
+
cwd: cwd || process.cwd(),
|
|
6129
|
+
timeout: DOD_COMMAND_TIMEOUT_MS,
|
|
6130
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
6131
|
+
encoding: "utf8"
|
|
6132
|
+
});
|
|
6133
|
+
if (res.error) {
|
|
6134
|
+
const errCode = res.error.code;
|
|
6135
|
+
const timedOut = errCode === "ETIMEDOUT" || res.signal === "SIGTERM" || res.signal === "SIGKILL";
|
|
6136
|
+
return {
|
|
6137
|
+
command: cmd,
|
|
6138
|
+
exitCode: timedOut ? "timeout" : "error",
|
|
6139
|
+
stdoutTail: extractTailLines(res.stdout, 20),
|
|
6140
|
+
stderrTail: extractTailLines(res.stderr || res.error.message, 10)
|
|
6141
|
+
};
|
|
6142
|
+
}
|
|
6143
|
+
if (res.status === null && (res.signal === "SIGTERM" || res.signal === "SIGKILL")) {
|
|
6144
|
+
return {
|
|
6145
|
+
command: cmd,
|
|
6146
|
+
exitCode: "timeout",
|
|
6147
|
+
stdoutTail: extractTailLines(res.stdout, 20),
|
|
6148
|
+
stderrTail: extractTailLines(res.stderr, 10)
|
|
6149
|
+
};
|
|
6150
|
+
}
|
|
6151
|
+
return {
|
|
6152
|
+
command: cmd,
|
|
6153
|
+
exitCode: typeof res.status === "number" ? res.status : "error",
|
|
6154
|
+
stdoutTail: extractTailLines(res.stdout, 20),
|
|
6155
|
+
stderrTail: extractTailLines(res.stderr, 10)
|
|
6156
|
+
};
|
|
6157
|
+
} catch (err) {
|
|
6158
|
+
return {
|
|
6159
|
+
command: cmd,
|
|
6160
|
+
exitCode: "error",
|
|
6161
|
+
stdoutTail: [],
|
|
6162
|
+
stderrTail: extractTailLines(err instanceof Error ? err.message : String(err), 10)
|
|
6163
|
+
};
|
|
6164
|
+
}
|
|
6165
|
+
}
|
|
6166
|
+
function runDoDCommands(commands, cwd, deps = {}) {
|
|
6167
|
+
if (!commands || commands.length === 0) return void 0;
|
|
6168
|
+
return commands.map((cmd) => executeDoDCommand(cmd, cwd, deps));
|
|
6169
|
+
}
|
|
6170
|
+
|
|
6384
6171
|
// packages/cli/agentRunPrompts.ts
|
|
6385
|
-
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
6386
|
-
import { dirname, extname, isAbsolute, join, relative as relativePath, resolve, sep } from "node:path";
|
|
6172
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
|
|
6173
|
+
import { dirname, extname, isAbsolute, join as join2, relative as relativePath, resolve, sep } from "node:path";
|
|
6387
6174
|
function workflowRefToCandidatePath(cwd, ref) {
|
|
6388
6175
|
const normalized = ref.trim();
|
|
6389
6176
|
if (!normalized) return "";
|
|
6390
6177
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6391
6178
|
const directPath = resolve(cwd, normalized);
|
|
6392
|
-
if (
|
|
6179
|
+
if (existsSync2(directPath)) return directPath;
|
|
6393
6180
|
}
|
|
6394
6181
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6395
6182
|
return resolve(cwd, "docs", "workflows", `${fileName}.md`);
|
|
@@ -6402,21 +6189,21 @@ function skillRefToCandidatePath(cwd, ref) {
|
|
|
6402
6189
|
if (!normalized) return "";
|
|
6403
6190
|
if (normalized.endsWith(".md") || normalized.includes("/") || normalized.includes("\\")) {
|
|
6404
6191
|
const directPath = resolve(cwd, normalized);
|
|
6405
|
-
if (
|
|
6192
|
+
if (existsSync2(directPath)) return directPath;
|
|
6406
6193
|
}
|
|
6407
6194
|
const fileName = normalized.replace(/[^a-zA-Z0-9一-鿿]+/g, "-").replace(/^-+|-+$/g, "");
|
|
6408
6195
|
for (const dir of SKILL_SEARCH_DIRS) {
|
|
6409
6196
|
const skillMdPath = resolve(cwd, dir, fileName, "SKILL.md");
|
|
6410
|
-
if (
|
|
6197
|
+
if (existsSync2(skillMdPath)) return skillMdPath;
|
|
6411
6198
|
}
|
|
6412
6199
|
return resolve(cwd, ".agents", "skills", fileName, "SKILL.md");
|
|
6413
6200
|
}
|
|
6414
6201
|
async function resolveWorkflowReference(ref, cwd = process.cwd()) {
|
|
6415
6202
|
const path = workflowRefToCandidatePath(cwd, ref);
|
|
6416
|
-
if (!path || !
|
|
6203
|
+
if (!path || !existsSync2(path)) {
|
|
6417
6204
|
throw new Error(`Workflow reference not found: ${ref}`);
|
|
6418
6205
|
}
|
|
6419
|
-
const markdown =
|
|
6206
|
+
const markdown = readFileSync2(path, "utf8");
|
|
6420
6207
|
const parsed = parseSkillDocProtocol(markdown);
|
|
6421
6208
|
return {
|
|
6422
6209
|
ref,
|
|
@@ -6433,8 +6220,8 @@ function inlineRelativeRefs(body, skillDir) {
|
|
|
6433
6220
|
const absPath = resolve(skillDir, cleaned);
|
|
6434
6221
|
const relative = relativePath(normalizedSkillDir, absPath);
|
|
6435
6222
|
if (relative.startsWith("..") || isAbsolute(relative)) return match;
|
|
6436
|
-
if (!
|
|
6437
|
-
const refContent =
|
|
6223
|
+
if (!existsSync2(absPath) || !absPath.endsWith(".md")) return match;
|
|
6224
|
+
const refContent = readFileSync2(absPath, "utf8");
|
|
6438
6225
|
return `
|
|
6439
6226
|
|
|
6440
6227
|
### ${label}
|
|
@@ -6445,8 +6232,8 @@ ${refContent}
|
|
|
6445
6232
|
});
|
|
6446
6233
|
}
|
|
6447
6234
|
function listSkillScripts(skillDir) {
|
|
6448
|
-
const scriptsDir =
|
|
6449
|
-
if (!
|
|
6235
|
+
const scriptsDir = join2(skillDir, "scripts");
|
|
6236
|
+
if (!existsSync2(scriptsDir) || !statSync(scriptsDir).isDirectory()) return null;
|
|
6450
6237
|
const entries = readdirSync(scriptsDir).filter((e) => !e.startsWith("."));
|
|
6451
6238
|
if (entries.length === 0) return null;
|
|
6452
6239
|
return [
|
|
@@ -6473,10 +6260,10 @@ async function resolveSkillReference(ref, options = {}) {
|
|
|
6473
6260
|
} else {
|
|
6474
6261
|
const cwd = options.cwd ?? process.cwd();
|
|
6475
6262
|
const path = skillRefToCandidatePath(cwd, ref);
|
|
6476
|
-
if (!path || !
|
|
6263
|
+
if (!path || !existsSync2(path)) {
|
|
6477
6264
|
throw new Error(`Skill reference not found: ${ref}`);
|
|
6478
6265
|
}
|
|
6479
|
-
markdown =
|
|
6266
|
+
markdown = readFileSync2(path, "utf8");
|
|
6480
6267
|
filePath = path;
|
|
6481
6268
|
skillDir = dirname(path);
|
|
6482
6269
|
}
|
|
@@ -6581,8 +6368,8 @@ function prependSubjectDialogMarker(message, subjectDialogKey) {
|
|
|
6581
6368
|
function normalizeCliImageInput(input) {
|
|
6582
6369
|
if (/^(https?:|data:|file:)/i.test(input)) return input;
|
|
6583
6370
|
const absolutePath = resolve(input);
|
|
6584
|
-
if (!
|
|
6585
|
-
const base64 =
|
|
6371
|
+
if (!existsSync2(absolutePath)) return input;
|
|
6372
|
+
const base64 = readFileSync2(absolutePath).toString("base64");
|
|
6586
6373
|
return `data:${imageMimeTypeForPath(absolutePath)};base64,${base64}`;
|
|
6587
6374
|
}
|
|
6588
6375
|
function imageMimeTypeForPath(path) {
|
|
@@ -6649,14 +6436,16 @@ ${args.inspection.status.trim()}`] : [],
|
|
|
6649
6436
|
}
|
|
6650
6437
|
|
|
6651
6438
|
// packages/ai/memory/storeShared.ts
|
|
6439
|
+
var retrievalCountOf = (item) => item.activationCount ?? 0;
|
|
6652
6440
|
var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).toISOString()) => {
|
|
6653
6441
|
if (items.length === 0) return;
|
|
6654
6442
|
const batch = db.batch();
|
|
6655
6443
|
for (const item of items) {
|
|
6656
6444
|
batch.put(createMemoryKey(item.ownerType, item.ownerId, item.id), {
|
|
6657
6445
|
...item,
|
|
6446
|
+
// retrieval bookkeeping on legacy storage names — see doc comment above
|
|
6658
6447
|
lastActivatedAt: now,
|
|
6659
|
-
activationCount: (item
|
|
6448
|
+
activationCount: retrievalCountOf(item) + 1
|
|
6660
6449
|
});
|
|
6661
6450
|
}
|
|
6662
6451
|
await batch.write();
|
|
@@ -6665,6 +6454,19 @@ var touchMemoryItemsInDb = async (db, items, now = (/* @__PURE__ */ new Date()).
|
|
|
6665
6454
|
// packages/ai/memory/constants.ts
|
|
6666
6455
|
var EXPLICIT_REMEMBER_PREFIX_REGEX = /^(你要记住|请记住|以后记住|记住)[,,。.\s::]*/u;
|
|
6667
6456
|
|
|
6457
|
+
// packages/ai/memory/source.ts
|
|
6458
|
+
var getMemorySourceKind = (item) => {
|
|
6459
|
+
if (item.sourceKind) return item.sourceKind;
|
|
6460
|
+
if (item.patternKey === "explicit-remember") return "explicit-user-directive";
|
|
6461
|
+
if (item.patternKey === "agent-remember" || item.patternKey === "procedural-runbook")
|
|
6462
|
+
return "agent-tool";
|
|
6463
|
+
if (item.patternKey?.startsWith("dialog-learning:"))
|
|
6464
|
+
return "dialog-learning";
|
|
6465
|
+
if (item.tags?.includes("understanding-memory"))
|
|
6466
|
+
return "inferred-understanding";
|
|
6467
|
+
return "agent-tool";
|
|
6468
|
+
};
|
|
6469
|
+
|
|
6668
6470
|
// packages/ai/memory/overlay.ts
|
|
6669
6471
|
var KIND_TITLES = {
|
|
6670
6472
|
episodic: "Episodic",
|
|
@@ -6698,6 +6500,8 @@ var FACET_DISPLAY = {
|
|
|
6698
6500
|
style: { label: "\u66F4\u504F\u597D", strip: "\u66F4\u559C\u6B22" },
|
|
6699
6501
|
goal: { label: "\u60F3\u63A8\u8FDB", strip: "\u60F3\u63A8\u8FDB" }
|
|
6700
6502
|
};
|
|
6503
|
+
var INFERRED_SOURCE_KINDS = /* @__PURE__ */ new Set(["inferred-understanding", "dialog-learning"]);
|
|
6504
|
+
var isInferredMemory = (item) => INFERRED_SOURCE_KINDS.has(getMemorySourceKind(item));
|
|
6701
6505
|
var formatFacetContent = (facet, normalized, prefix) => {
|
|
6702
6506
|
const { label, strip } = FACET_DISPLAY[facet];
|
|
6703
6507
|
const stripped = normalized.startsWith(strip) ? normalized.slice(strip.length).trim() : normalized;
|
|
@@ -6719,9 +6523,79 @@ var normalizeDisplayContent = (item) => {
|
|
|
6719
6523
|
}
|
|
6720
6524
|
return normalized;
|
|
6721
6525
|
};
|
|
6526
|
+
var pickWithinKind = (list, perKindLimit) => {
|
|
6527
|
+
if (perKindLimit <= 0) return [];
|
|
6528
|
+
const head = list.slice(0, perKindLimit);
|
|
6529
|
+
if (head.length < perKindLimit) return head;
|
|
6530
|
+
if (head.some((item) => item.subjectType === "user")) return head;
|
|
6531
|
+
const firstUserSubject = list.find((item) => item.subjectType === "user");
|
|
6532
|
+
if (!firstUserSubject) return head;
|
|
6533
|
+
return [...head.slice(0, perKindLimit - 1), firstUserSubject];
|
|
6534
|
+
};
|
|
6535
|
+
var DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET = 3200;
|
|
6536
|
+
var MIN_TRUNCATED_TOKENS = 20;
|
|
6537
|
+
var TRUNCATED_SUFFIX = "\u2026\uFF08\u672C\u6761\u5DF2\u622A\u65AD\uFF09";
|
|
6538
|
+
var truncateLineToTokens = (lineText, budgetTokens) => {
|
|
6539
|
+
if (budgetTokens < MIN_TRUNCATED_TOKENS) return null;
|
|
6540
|
+
const suffixTokens = estimateTokens(TRUNCATED_SUFFIX);
|
|
6541
|
+
const bodyBudget = budgetTokens - suffixTokens;
|
|
6542
|
+
if (bodyBudget < MIN_TRUNCATED_TOKENS / 2) return null;
|
|
6543
|
+
let used = 0;
|
|
6544
|
+
let cut = 0;
|
|
6545
|
+
for (const ch of lineText) {
|
|
6546
|
+
const chTokens = estimateTokens(ch);
|
|
6547
|
+
if (used + chTokens > bodyBudget) break;
|
|
6548
|
+
used += chTokens;
|
|
6549
|
+
cut += ch.length;
|
|
6550
|
+
}
|
|
6551
|
+
if (cut <= 2) return null;
|
|
6552
|
+
return `${lineText.slice(0, cut).trimEnd()}${TRUNCATED_SUFFIX}`;
|
|
6553
|
+
};
|
|
6554
|
+
var fitLinesToBudget = (allLines, remainingBudget) => {
|
|
6555
|
+
let usedTokens = 0;
|
|
6556
|
+
const keptByKind = {};
|
|
6557
|
+
let truncatedCount = 0;
|
|
6558
|
+
let droppedCount = 0;
|
|
6559
|
+
const pushLine = (kind, lineText) => {
|
|
6560
|
+
if (!keptByKind[kind]) keptByKind[kind] = [];
|
|
6561
|
+
keptByKind[kind].push(lineText);
|
|
6562
|
+
};
|
|
6563
|
+
for (const candidate of allLines) {
|
|
6564
|
+
const remaining = remainingBudget - usedTokens;
|
|
6565
|
+
if (remaining <= 0) {
|
|
6566
|
+
droppedCount += 1;
|
|
6567
|
+
continue;
|
|
6568
|
+
}
|
|
6569
|
+
if (candidate.lineTokens <= remaining) {
|
|
6570
|
+
usedTokens += candidate.lineTokens;
|
|
6571
|
+
pushLine(candidate.kind, candidate.lineText);
|
|
6572
|
+
continue;
|
|
6573
|
+
}
|
|
6574
|
+
const truncated = truncateLineToTokens(candidate.lineText, remaining);
|
|
6575
|
+
if (!truncated) {
|
|
6576
|
+
droppedCount += 1;
|
|
6577
|
+
continue;
|
|
6578
|
+
}
|
|
6579
|
+
usedTokens += estimateTokens(truncated);
|
|
6580
|
+
pushLine(candidate.kind, truncated);
|
|
6581
|
+
truncatedCount += 1;
|
|
6582
|
+
}
|
|
6583
|
+
return { keptByKind, truncatedCount, droppedCount };
|
|
6584
|
+
};
|
|
6585
|
+
var buildBudgetFooter = (fit) => {
|
|
6586
|
+
const notices = [];
|
|
6587
|
+
if (fit.truncatedCount > 0) {
|
|
6588
|
+
notices.push(`${fit.truncatedCount} \u6761\u56E0\u9884\u7B97\u88AB\u622A\u65AD`);
|
|
6589
|
+
}
|
|
6590
|
+
if (fit.droppedCount > 0) {
|
|
6591
|
+
notices.push(`${fit.droppedCount} \u6761\u672A\u663E\u793A`);
|
|
6592
|
+
}
|
|
6593
|
+
if (notices.length === 0) return [];
|
|
6594
|
+
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`];
|
|
6595
|
+
};
|
|
6722
6596
|
var buildMemoryOverlay = (items, options) => {
|
|
6723
6597
|
if (items.length === 0) return null;
|
|
6724
|
-
const maxTokens = options?.maxTokens ??
|
|
6598
|
+
const maxTokens = options?.maxTokens ?? DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6725
6599
|
const perKindLimit = options?.perKindLimit ?? 3;
|
|
6726
6600
|
const byKind = {
|
|
6727
6601
|
episodic: [],
|
|
@@ -6736,19 +6610,15 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6736
6610
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6737
6611
|
}
|
|
6738
6612
|
const allLines = Object.entries(byKind).filter(([, list]) => list.length > 0).flatMap(
|
|
6739
|
-
([kind, list]) => list
|
|
6740
|
-
const lineText = `- ${normalizeDisplayContent(item)}`;
|
|
6613
|
+
([kind, list]) => pickWithinKind(list, perKindLimit).map((item) => {
|
|
6614
|
+
const lineText = `- ${isInferredMemory(item) ? "\uFF08\u63A8\u65AD\uFF09" : ""}${normalizeDisplayContent(item)}`;
|
|
6741
6615
|
return { kind, lineText, lineTokens: estimateTokens(lineText) };
|
|
6742
6616
|
})
|
|
6743
6617
|
).sort((a, b) => (KIND_PRIORITY[a.kind] ?? 99) - (KIND_PRIORITY[b.kind] ?? 99));
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
usedTokens += candidate.lineTokens;
|
|
6749
|
-
if (!keptByKind[candidate.kind]) keptByKind[candidate.kind] = [];
|
|
6750
|
-
keptByKind[candidate.kind].push(candidate.lineText);
|
|
6751
|
-
}
|
|
6618
|
+
const { keptByKind, truncatedCount, droppedCount } = fitLinesToBudget(
|
|
6619
|
+
allLines,
|
|
6620
|
+
remainingBudget
|
|
6621
|
+
);
|
|
6752
6622
|
const kindOrder = ["semantic", "procedural", "episodic"];
|
|
6753
6623
|
const sections = kindOrder.filter((kind) => keptByKind[kind] && keptByKind[kind].length > 0).map((kind) => {
|
|
6754
6624
|
return [`[${KIND_TITLES[kind]}]`, ...keptByKind[kind]].join("\n");
|
|
@@ -6756,7 +6626,7 @@ var buildMemoryOverlay = (items, options) => {
|
|
|
6756
6626
|
if (sections.length === 0) {
|
|
6757
6627
|
return OVERLAY_HEADER_LINES.join("\n");
|
|
6758
6628
|
}
|
|
6759
|
-
return [...OVERLAY_HEADER_LINES, ...sections].join("\n");
|
|
6629
|
+
return [...OVERLAY_HEADER_LINES, ...sections, ...buildBudgetFooter({ keptByKind, truncatedCount, droppedCount })].join("\n");
|
|
6760
6630
|
};
|
|
6761
6631
|
|
|
6762
6632
|
// packages/ai/memory/rank.ts
|
|
@@ -6803,13 +6673,28 @@ var identifierScore = (query, item) => {
|
|
|
6803
6673
|
).length;
|
|
6804
6674
|
return matches / identifiers.length;
|
|
6805
6675
|
};
|
|
6806
|
-
var
|
|
6807
|
-
|
|
6808
|
-
|
|
6676
|
+
var DAY_MS = 864e5;
|
|
6677
|
+
var UNRETRIEVED_MEMORY_GRACE_DAYS = 3;
|
|
6678
|
+
var MIN_UNRETRIEVED_SCORE_FACTOR = 0.3;
|
|
6679
|
+
var UNRETRIEVED_DECAY_HALF_LIFE_DAYS = 7;
|
|
6680
|
+
var retrievalFrequencyScore = (item, nowMs) => {
|
|
6681
|
+
const lastRetrievedMs = Date.parse(item.lastActivatedAt || item.createdAt);
|
|
6682
|
+
const ageDays = Math.max(0, (nowMs - lastRetrievedMs) / DAY_MS);
|
|
6809
6683
|
const recency = 1 / (1 + ageDays / 7);
|
|
6810
|
-
const
|
|
6811
|
-
return 0.7 * recency + 0.3 *
|
|
6684
|
+
const frequency = Math.min(1, Math.log1p(item.activationCount ?? 0) / 3);
|
|
6685
|
+
return 0.7 * recency + 0.3 * frequency;
|
|
6686
|
+
};
|
|
6687
|
+
var unretrievedDecayFactor = (item, nowMs) => {
|
|
6688
|
+
if ((item.activationCount ?? 0) !== 0) return 1;
|
|
6689
|
+
const createdAgeDays = Math.max(0, (nowMs - Date.parse(item.createdAt)) / DAY_MS);
|
|
6690
|
+
if (createdAgeDays <= UNRETRIEVED_MEMORY_GRACE_DAYS) return 1;
|
|
6691
|
+
const overdue = createdAgeDays - UNRETRIEVED_MEMORY_GRACE_DAYS;
|
|
6692
|
+
return Math.max(
|
|
6693
|
+
MIN_UNRETRIEVED_SCORE_FACTOR,
|
|
6694
|
+
1 / (1 + overdue / UNRETRIEVED_DECAY_HALF_LIFE_DAYS)
|
|
6695
|
+
);
|
|
6812
6696
|
};
|
|
6697
|
+
var retrievalScore = (item, nowMs) => retrievalFrequencyScore(item, nowMs) * unretrievedDecayFactor(item, nowMs);
|
|
6813
6698
|
var creationRecencyScore = (item, nowMs) => {
|
|
6814
6699
|
const createdMs = Date.parse(item.createdAt);
|
|
6815
6700
|
const ageDays = Math.max(0, (nowMs - createdMs) / 864e5);
|
|
@@ -6841,14 +6726,15 @@ var pathScore = (item, context) => {
|
|
|
6841
6726
|
var scoreMemoryItem = (item, query, nowMs = Date.now(), context) => {
|
|
6842
6727
|
const queryMatch = keywordScore(query, item);
|
|
6843
6728
|
const identifierMatch = identifierScore(query, item);
|
|
6844
|
-
const
|
|
6729
|
+
const retrieval = retrievalScore(item, nowMs);
|
|
6845
6730
|
const createdRecency = creationRecencyScore(item, nowMs);
|
|
6846
6731
|
const importance = item.importance ?? 0;
|
|
6847
6732
|
const confidence = item.confidence ?? 0;
|
|
6848
6733
|
const typeFit = typeFitScore(item);
|
|
6849
6734
|
const understanding = understandingScore(item);
|
|
6850
6735
|
const path = pathScore(item, context);
|
|
6851
|
-
return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 * path + 0.09 *
|
|
6736
|
+
return 0.25 * queryMatch + 0.2 * identifierMatch + 0.2 * path + 0.09 * retrieval + // weak retrieval signal, NOT successful-use reinforcement
|
|
6737
|
+
0.16 * createdRecency + 0.06 * importance + 0.03 * confidence + 0.02 * typeFit + 0.01 * understanding;
|
|
6852
6738
|
};
|
|
6853
6739
|
var rankMemoryCandidates = (items, query, context) => {
|
|
6854
6740
|
const nowMs = Date.now();
|
|
@@ -6865,7 +6751,9 @@ var rankMemoryCandidates = (items, query, context) => {
|
|
|
6865
6751
|
|
|
6866
6752
|
// packages/ai/memory/runtime.ts
|
|
6867
6753
|
var COLD_STORAGE_CONFIDENCE = 0.3;
|
|
6868
|
-
var MEMORY_OVERLAY_TOKEN_BUDGET =
|
|
6754
|
+
var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
|
|
6755
|
+
var DEFAULT_MEMORY_RUNTIME_OWNER_LIMIT = 20;
|
|
6756
|
+
var CORROBORATED_PROCEDURAL_RESERVE = 5;
|
|
6869
6757
|
var normalizeSelectedContent = (text) => text.trim().replace(EXPLICIT_REMEMBER_PREFIX_REGEX, "").replace(/[。!?!?]+$/u, "").trim();
|
|
6870
6758
|
var STACK_TERMS = [
|
|
6871
6759
|
"typescript",
|
|
@@ -6967,6 +6855,7 @@ var selectRuntimeMemoryItems = (items, context, userInput = "") => {
|
|
|
6967
6855
|
);
|
|
6968
6856
|
add(unique.find((item) => item.ownerType === "user"));
|
|
6969
6857
|
add(unique.find((item) => item.ownerType === "space"));
|
|
6858
|
+
add(unique.find((item) => item.subjectType === "user"));
|
|
6970
6859
|
add(unique.find((item) => item.kind === "procedural"));
|
|
6971
6860
|
for (const item of unique) {
|
|
6972
6861
|
add(item);
|
|
@@ -6992,8 +6881,9 @@ var resolveMemoryRuntime = async (input) => {
|
|
|
6992
6881
|
policy
|
|
6993
6882
|
}),
|
|
6994
6883
|
kinds: ["episodic", "semantic", "procedural"],
|
|
6995
|
-
ownerLimit:
|
|
6996
|
-
ownerFallback: policy.ownerFallback
|
|
6884
|
+
ownerLimit: input.ownerLimit ?? DEFAULT_MEMORY_RUNTIME_OWNER_LIMIT,
|
|
6885
|
+
ownerFallback: policy.ownerFallback,
|
|
6886
|
+
corroboratedProceduralReserve: input.corroboratedProceduralReserve ?? CORROBORATED_PROCEDURAL_RESERVE
|
|
6997
6887
|
});
|
|
6998
6888
|
const rankContext = {
|
|
6999
6889
|
currentOwner: input.spaceId ? { ownerType: "space", ownerId: input.spaceId } : input.userId ? { ownerType: "user", ownerId: input.userId } : null,
|
|
@@ -7086,6 +6976,36 @@ var resolveCliMemory = async (input) => {
|
|
|
7086
6976
|
function resolvePositiveMs(value, fallback) {
|
|
7087
6977
|
return parsePositiveFiniteNumberOrFallback(value, fallback);
|
|
7088
6978
|
}
|
|
6979
|
+
function resolveRunOutcome(input) {
|
|
6980
|
+
switch (input.kind) {
|
|
6981
|
+
case "stall":
|
|
6982
|
+
return { status: "failed", exitCode: 1 };
|
|
6983
|
+
case "timeout":
|
|
6984
|
+
return { status: "timeout", exitCode: 124 };
|
|
6985
|
+
case "result": {
|
|
6986
|
+
const failed = input.isStalledOrTruncated || input.exitCode !== 0;
|
|
6987
|
+
if (!failed) {
|
|
6988
|
+
return { status: "done", exitCode: 0 };
|
|
6989
|
+
}
|
|
6990
|
+
return { status: "failed", exitCode: input.exitCode !== 0 ? input.exitCode : 1 };
|
|
6991
|
+
}
|
|
6992
|
+
}
|
|
6993
|
+
}
|
|
6994
|
+
var FAILED_EMPTY_ASSISTANT_REASONS = /* @__PURE__ */ new Set([
|
|
6995
|
+
"length_truncated",
|
|
6996
|
+
"stream_truncated",
|
|
6997
|
+
"repetition_loop",
|
|
6998
|
+
"stagnant_tool_calls"
|
|
6999
|
+
]);
|
|
7000
|
+
var isRunResultStalledOrTruncated = (result) => !result.emptyAssistantOutputUsable && FAILED_EMPTY_ASSISTANT_REASONS.has(result.emptyAssistantFallbackReason ?? "");
|
|
7001
|
+
var resolveRunSettlementNote = (result) => {
|
|
7002
|
+
const reason = result.emptyAssistantFallbackReason;
|
|
7003
|
+
if (!reason || !FAILED_EMPTY_ASSISTANT_REASONS.has(reason)) return {};
|
|
7004
|
+
if (result.emptyAssistantOutputUsable) {
|
|
7005
|
+
return { note: `output complete but stream lacked finish frame: ${reason}` };
|
|
7006
|
+
}
|
|
7007
|
+
return { note: `empty assistant output: ${reason}` };
|
|
7008
|
+
};
|
|
7089
7009
|
async function resolveAgentRunAgentKey(args) {
|
|
7090
7010
|
if (!args.agentInput.trim() || args.agentInput.startsWith("agent-")) {
|
|
7091
7011
|
return void 0;
|
|
@@ -7121,11 +7041,14 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7121
7041
|
deps.stallTimeoutMs ?? env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS,
|
|
7122
7042
|
5 * 6e4
|
|
7123
7043
|
);
|
|
7044
|
+
const stallEnvExplicitlySet = typeof env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS === "string" && env.NOLO_LOCAL_RUN_STALL_TIMEOUT_MS.trim().length > 0;
|
|
7045
|
+
const armStallWatchdog = hasRegistry || stallEnvExplicitlySet;
|
|
7046
|
+
const armTimeoutWatchdog = typeof parsed.timeoutMs === "number" && parsed.timeoutMs > 0;
|
|
7124
7047
|
let timedOut = false;
|
|
7125
7048
|
let stalled = false;
|
|
7126
7049
|
let timeoutTimer;
|
|
7127
7050
|
let stallTimer;
|
|
7128
|
-
const activityTracker =
|
|
7051
|
+
const activityTracker = armStallWatchdog ? createRunActivityTracker(childRunId ?? "__foreground__", {
|
|
7129
7052
|
env,
|
|
7130
7053
|
homedir: deps.homedir,
|
|
7131
7054
|
fs: deps.fs,
|
|
@@ -7138,7 +7061,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7138
7061
|
activityTracker?.dispose();
|
|
7139
7062
|
};
|
|
7140
7063
|
let rejectOnWatchdogFailure;
|
|
7141
|
-
const watchdogFailure =
|
|
7064
|
+
const watchdogFailure = armStallWatchdog || armTimeoutWatchdog ? new Promise((_, reject) => {
|
|
7142
7065
|
rejectOnWatchdogFailure = reject;
|
|
7143
7066
|
}) : void 0;
|
|
7144
7067
|
const raceWithWatchdog = (work) => watchdogFailure ? Promise.race([work, watchdogFailure]) : work;
|
|
@@ -7148,8 +7071,18 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7148
7071
|
} catch {
|
|
7149
7072
|
}
|
|
7150
7073
|
};
|
|
7151
|
-
|
|
7152
|
-
|
|
7074
|
+
const finalizeWatchdogOutcome = async (outcome, note) => {
|
|
7075
|
+
if (!hasRegistry) return;
|
|
7076
|
+
await settleRunTerminalAuthoritatively(
|
|
7077
|
+
childRunId,
|
|
7078
|
+
{ status: outcome.status, exitCode: outcome.exitCode, note },
|
|
7079
|
+
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now, sleep: deps.sleep },
|
|
7080
|
+
// Test seam: stubbed transitions keep their single-attempt semantics.
|
|
7081
|
+
deps.transitionRunToTerminal
|
|
7082
|
+
);
|
|
7083
|
+
};
|
|
7084
|
+
if (armStallWatchdog) {
|
|
7085
|
+
stallTimer = setInterval(async () => {
|
|
7153
7086
|
if (timedOut || stalled) return;
|
|
7154
7087
|
const activity = activityTracker?.getActivity();
|
|
7155
7088
|
const lastEventAtMs = activity ? new Date(activity.lastEventAt).getTime() : nowMs();
|
|
@@ -7166,31 +7099,25 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7166
7099
|
const note = `stalled: no progress for ${stallTimeoutMs}ms`;
|
|
7167
7100
|
output.write(`[nolo] local run ${note}
|
|
7168
7101
|
`);
|
|
7169
|
-
(
|
|
7170
|
-
|
|
7171
|
-
{ status: "failed", note },
|
|
7172
|
-
{ env, homedir: deps.homedir, fs: deps.fs, now: deps.now }
|
|
7173
|
-
);
|
|
7102
|
+
const outcome = resolveRunOutcome({ kind: "stall" });
|
|
7103
|
+
await finalizeWatchdogOutcome(outcome, note);
|
|
7174
7104
|
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7175
|
-
exitFromWatchdog(
|
|
7105
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7176
7106
|
}
|
|
7177
7107
|
}, Math.min(stallTimeoutMs, 1e4));
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7182
|
-
|
|
7183
|
-
|
|
7108
|
+
}
|
|
7109
|
+
if (armTimeoutWatchdog) {
|
|
7110
|
+
timeoutTimer = setTimeout(async () => {
|
|
7111
|
+
timedOut = true;
|
|
7112
|
+
clearWatchdogs();
|
|
7113
|
+
const note = `timed out after ${parsed.timeoutMs}ms`;
|
|
7114
|
+
output.write(`[nolo] local run ${note}
|
|
7184
7115
|
`);
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7191
|
-
exitFromWatchdog(124);
|
|
7192
|
-
}, parsed.timeoutMs);
|
|
7193
|
-
}
|
|
7116
|
+
const outcome = resolveRunOutcome({ kind: "timeout" });
|
|
7117
|
+
await finalizeWatchdogOutcome(outcome, note);
|
|
7118
|
+
rejectOnWatchdogFailure?.(new Error(`[nolo] local run ${note}`));
|
|
7119
|
+
exitFromWatchdog(outcome.exitCode);
|
|
7120
|
+
}, parsed.timeoutMs);
|
|
7194
7121
|
}
|
|
7195
7122
|
const wantsFallbackSuggestions = parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0;
|
|
7196
7123
|
const rawAgentInput = resolveRawAgentInput(args, deps.commandPath) ?? parsed.agentKey;
|
|
@@ -7286,7 +7213,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7286
7213
|
(acc, tools) => acc.filter((t2) => tools.includes(t2))
|
|
7287
7214
|
);
|
|
7288
7215
|
if (skillAllowed.length === 0) {
|
|
7289
|
-
output.write(`[nolo] warning: attached skills declare incompatible allowed-tools;
|
|
7216
|
+
output.write(`[nolo] warning: attached skills declare incompatible allowed-tools; this run has no tools
|
|
7290
7217
|
`);
|
|
7291
7218
|
}
|
|
7292
7219
|
skillAllowedToolOverride = parsed.allowedToolNames?.length ? parsed.allowedToolNames.filter((t2) => skillAllowed.includes(t2)) : skillAllowed;
|
|
@@ -7345,22 +7272,8 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7345
7272
|
let memoryOverlayLayer = null;
|
|
7346
7273
|
let memoryUseGuidanceLayer = null;
|
|
7347
7274
|
if (!isSubtask) {
|
|
7348
|
-
const
|
|
7349
|
-
|
|
7350
|
-
const agentsMdPath = join2(cliCwd, name);
|
|
7351
|
-
if (existsSync2(agentsMdPath)) {
|
|
7352
|
-
try {
|
|
7353
|
-
let mdContent = readFileSync2(agentsMdPath, "utf8").trim();
|
|
7354
|
-
if (!mdContent) continue;
|
|
7355
|
-
if (Buffer.byteLength(mdContent, "utf8") > AGENTS_MD_MAX) {
|
|
7356
|
-
mdContent = Buffer.from(mdContent, "utf8").subarray(0, AGENTS_MD_MAX).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
7357
|
-
}
|
|
7358
|
-
scopedLayers.push(buildAgentsMdLayer(mdContent, name));
|
|
7359
|
-
break;
|
|
7360
|
-
} catch {
|
|
7361
|
-
}
|
|
7362
|
-
}
|
|
7363
|
-
}
|
|
7275
|
+
const agentsMdLayer = readAgentsMdLayerFromDisk(cliCwd);
|
|
7276
|
+
if (agentsMdLayer) scopedLayers.push(agentsMdLayer);
|
|
7364
7277
|
skillContentBlocks.push(...buildSkillContextBlocks(skillReferences));
|
|
7365
7278
|
scopedLayers.push(buildSkillDiscoveryContextLayer(cliCwd));
|
|
7366
7279
|
if (!deps.memoryRecallDisabled) {
|
|
@@ -7421,7 +7334,6 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7421
7334
|
...parsed.parentWakeOnTerminal ? { parentWakeOnTerminal: true } : {},
|
|
7422
7335
|
...parsed.subjectDialogKey ? { subjectDialogKey: parsed.subjectDialogKey } : {},
|
|
7423
7336
|
...parsed.subjectRefs?.length ? { subjectRefs: parsed.subjectRefs } : {},
|
|
7424
|
-
...parsed.allowedChildAgentKeys?.length ? { allowedChildAgentKeys: parsed.allowedChildAgentKeys } : {},
|
|
7425
7337
|
...skillAllowedToolOverride !== void 0 ? { allowedToolNames: skillAllowedToolOverride } : parsed.allowedToolNames?.length ? { allowedToolNames: parsed.allowedToolNames } : {},
|
|
7426
7338
|
...parsed.blockedToolNames?.length ? { blockedToolNames: parsed.blockedToolNames } : {},
|
|
7427
7339
|
...activityTracker ? { onLoopEvent: activityTracker.onLoopEvent } : {},
|
|
@@ -7441,6 +7353,7 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7441
7353
|
})
|
|
7442
7354
|
);
|
|
7443
7355
|
clearWatchdogs();
|
|
7356
|
+
let runCreditsTotal = result.turnCredits;
|
|
7444
7357
|
if (result.exitCode !== 0 && isQuotaExhaustedError(result.localError) && isLocalRun && parsed.fallbackAgentKeys && parsed.fallbackAgentKeys.length > 0) {
|
|
7445
7358
|
const fallbackAgentKey = parsed.fallbackAgentKeys[0];
|
|
7446
7359
|
output.write(
|
|
@@ -7456,7 +7369,11 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7456
7369
|
clearWatchdogs();
|
|
7457
7370
|
if (fallbackResult.exitCode === 0) {
|
|
7458
7371
|
result = fallbackResult;
|
|
7459
|
-
}
|
|
7372
|
+
}
|
|
7373
|
+
if (fallbackResult.turnCredits !== void 0) {
|
|
7374
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + fallbackResult.turnCredits;
|
|
7375
|
+
}
|
|
7376
|
+
if (fallbackResult.exitCode !== 0) {
|
|
7460
7377
|
result = {
|
|
7461
7378
|
...fallbackResult,
|
|
7462
7379
|
...fallbackResult.dialogId || result.dialogId ? { dialogId: fallbackResult.dialogId ?? result.dialogId } : {}
|
|
@@ -7499,6 +7416,9 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7499
7416
|
);
|
|
7500
7417
|
clearWatchdogs();
|
|
7501
7418
|
result = turnResult;
|
|
7419
|
+
if (turnResult.turnCredits !== void 0) {
|
|
7420
|
+
runCreditsTotal = (runCreditsTotal ?? 0) + turnResult.turnCredits;
|
|
7421
|
+
}
|
|
7502
7422
|
if (result.exitCode !== 0) {
|
|
7503
7423
|
break;
|
|
7504
7424
|
}
|
|
@@ -7549,41 +7469,48 @@ async function runAgentRunCommand(args, deps) {
|
|
|
7549
7469
|
}
|
|
7550
7470
|
}
|
|
7551
7471
|
if (typeof childRunId === "string" && childRunId.length > 0) {
|
|
7552
|
-
const
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
7472
|
+
const childRecordForDoD = (deps.readRunRecord ?? readRunRecord)(childRunId, {
|
|
7473
|
+
env,
|
|
7474
|
+
homedir: deps.homedir,
|
|
7475
|
+
fs: deps.fs
|
|
7476
|
+
});
|
|
7477
|
+
const isStalledOrTruncated = isRunResultStalledOrTruncated(result);
|
|
7478
|
+
const truncationNote = resolveRunSettlementNote(result);
|
|
7479
|
+
const outcome = resolveRunOutcome({
|
|
7480
|
+
kind: "result",
|
|
7481
|
+
exitCode: result.exitCode,
|
|
7482
|
+
isStalledOrTruncated
|
|
7483
|
+
});
|
|
7484
|
+
let dodResults;
|
|
7485
|
+
try {
|
|
7486
|
+
dodResults = (deps.runDoDCommands ?? runDoDCommands)(
|
|
7487
|
+
childRecordForDoD?.dodCommands,
|
|
7488
|
+
childRecordForDoD?.cwd
|
|
7489
|
+
);
|
|
7490
|
+
} catch (dodError) {
|
|
7491
|
+
console.warn(`[nolo] DoD verification failed to run for ${childRunId}:`, dodError);
|
|
7492
|
+
}
|
|
7493
|
+
await settleRunTerminalAuthoritatively(
|
|
7556
7494
|
childRunId,
|
|
7557
7495
|
{
|
|
7558
|
-
status:
|
|
7559
|
-
exitCode:
|
|
7496
|
+
status: outcome.status,
|
|
7497
|
+
exitCode: outcome.exitCode,
|
|
7560
7498
|
dialogId: result.dialogId,
|
|
7499
|
+
...dodResults ? { dodResults } : {},
|
|
7500
|
+
// run 级累计的平台积分(主轮 + fallback + drain 轮):dock 行据此显示
|
|
7501
|
+
// 「⚡ x.xx」,让派发任务的消耗可见。undefined = 全程无平台计费。
|
|
7502
|
+
...runCreditsTotal !== void 0 ? { credits: runCreditsTotal } : {},
|
|
7561
7503
|
...truncationNote
|
|
7562
7504
|
},
|
|
7563
7505
|
{
|
|
7564
7506
|
env,
|
|
7565
7507
|
homedir: deps.homedir,
|
|
7566
7508
|
fs: deps.fs,
|
|
7567
|
-
now: deps.now
|
|
7568
|
-
|
|
7509
|
+
now: deps.now,
|
|
7510
|
+
sleep: deps.sleep
|
|
7511
|
+
},
|
|
7512
|
+
deps.transitionRunToTerminal
|
|
7569
7513
|
);
|
|
7570
|
-
try {
|
|
7571
|
-
const record = (deps.readRunRecord ?? readRunRecord)(childRunId, {
|
|
7572
|
-
env,
|
|
7573
|
-
homedir: deps.homedir,
|
|
7574
|
-
fs: deps.fs
|
|
7575
|
-
});
|
|
7576
|
-
if (record) {
|
|
7577
|
-
await (deps.generateRunReport ?? generateRunReport)(record, {
|
|
7578
|
-
env,
|
|
7579
|
-
homedir: deps.homedir,
|
|
7580
|
-
fs: deps.fs,
|
|
7581
|
-
now: deps.now
|
|
7582
|
-
});
|
|
7583
|
-
}
|
|
7584
|
-
} catch (reportError) {
|
|
7585
|
-
console.warn(`[nolo] failed to generate run report for ${childRunId}:`, reportError);
|
|
7586
|
-
}
|
|
7587
7514
|
}
|
|
7588
7515
|
return result.exitCode;
|
|
7589
7516
|
}
|
|
@@ -7602,6 +7529,8 @@ function isBalanceExhaustedError(error) {
|
|
|
7602
7529
|
export {
|
|
7603
7530
|
resolveAgentModelIdentity,
|
|
7604
7531
|
resolveAgentContextWindow,
|
|
7532
|
+
platformCreditsFromUsage,
|
|
7533
|
+
formatCreditsChip,
|
|
7605
7534
|
formatTokenCount,
|
|
7606
7535
|
renderTokenStatus,
|
|
7607
7536
|
resolveCliColorEnabled,
|
|
@@ -7629,7 +7558,7 @@ export {
|
|
|
7629
7558
|
setActiveThemeMode,
|
|
7630
7559
|
setActiveBrightness,
|
|
7631
7560
|
detectSystemBrightnessFromEnv,
|
|
7632
|
-
|
|
7561
|
+
resolveTuiBrightnessSignal,
|
|
7633
7562
|
resolveTuiThemeMode,
|
|
7634
7563
|
resetWorkspaceThemeState,
|
|
7635
7564
|
applyDetectedBackground,
|
|
@@ -7640,8 +7569,10 @@ export {
|
|
|
7640
7569
|
themeText,
|
|
7641
7570
|
tuiRenderThemeFingerprint,
|
|
7642
7571
|
setMathRenderingEnabled,
|
|
7572
|
+
polishBreathInsertsBlankBetween,
|
|
7643
7573
|
formatAssistantDisplay,
|
|
7644
|
-
|
|
7574
|
+
redactSecrets,
|
|
7575
|
+
TUI_TREE_MARKER,
|
|
7645
7576
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
7646
7577
|
shouldCollapsePaste,
|
|
7647
7578
|
createCollapsedPasteStore,
|
|
@@ -7653,6 +7584,7 @@ export {
|
|
|
7653
7584
|
expandRangeToCollapsedPasteChips,
|
|
7654
7585
|
findCollapsedPasteSpanAt,
|
|
7655
7586
|
runAgentTurn,
|
|
7587
|
+
readAgentsMdLayerFromDisk,
|
|
7656
7588
|
resolveWorkflowReference,
|
|
7657
7589
|
resolveSkillReference,
|
|
7658
7590
|
buildSkillContextBlocks,
|
|
@@ -7660,6 +7592,9 @@ export {
|
|
|
7660
7592
|
normalizeCliImageInput,
|
|
7661
7593
|
inspectLocalRunWorkspace,
|
|
7662
7594
|
resolveCliMemory,
|
|
7595
|
+
resolveRunOutcome,
|
|
7596
|
+
isRunResultStalledOrTruncated,
|
|
7597
|
+
resolveRunSettlementNote,
|
|
7663
7598
|
runAgentRunCommand,
|
|
7664
7599
|
isBalanceExhaustedError
|
|
7665
7600
|
};
|