nolo-cli 0.54.0-alpha.2 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{_executeModel-ANY4SIAS.js → _executeModel-OPTKYHJA.js} +48 -42
- package/{action-Q4W5JPI5.js → action-ORXWW2ZG.js} +8 -8
- package/{addContentAction-O25HFR37.js → addContentAction-53BZ34AE.js} +8 -7
- package/{addDialogAgentAction-GH7AUPPB.js → addDialogAgentAction-JRYUS54Y.js} +10 -9
- package/{agentDeleteCommand-JWIKNWWI.js → agentDeleteCommand-FJIWU2BS.js} +30 -28
- package/{agentEmailCommands-PL22BEU5.js → agentEmailCommands-CE32L43B.js} +57 -52
- package/{agentListCommands-6NR7AQEK.js → agentListCommands-VJNKULIK.js} +42 -33
- package/{agentMachineCommands-TASPU6OA.js → agentMachineCommands-HCJ3WQXL.js} +30 -28
- package/{agentRecordCommands-Z64TA63M.js → agentRecordCommands-QFWERED4.js} +55 -50
- package/{agentRunCommand-4QJQLPRW.js → agentRunCommand-G3GQMUNN.js} +65 -53
- package/{agentRunControl-4GHHSXFZ.js → agentRunControl-INKFDXDA.js} +3 -1
- package/{agentRuntimeLocal-PCJJ56J2.js → agentRuntimeLocal-K327ELSL.js} +30 -26
- package/{agentSlice-KYLDUSNN.js → agentSlice-ODKF4J6M.js} +8 -8
- package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-5AR3DKNN.js} +2 -2
- package/{appDeleteCommands-WLHMJAVT.js → appDeleteCommands-XUXMFDI4.js} +31 -29
- package/{appDeployCommands-CKON7N2E.js → appDeployCommands-37F4GPCU.js} +31 -29
- package/{appDeployStatusCommands-PXRLDASH.js → appDeployStatusCommands-WSPU7TUK.js} +31 -29
- package/{appGetCommands-RAB5RM4M.js → appGetCommands-YLOBA3EM.js} +31 -29
- package/{appListCommands-GU57FB62.js → appListCommands-UD62R5ME.js} +31 -29
- package/{authCommand-QOPOEYEK.js → authCommand-OK6HLHGS.js} +13 -13
- package/{authCommands-SBQVTD6V.js → authCommands-2DUIUEMT.js} +2 -2
- package/{chatQueueReduxAdapter-5O2WLITN.js → chatQueueReduxAdapter-TV2TUOQS.js} +26 -23
- package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
- package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
- package/{chunk-VULELK4T.js → chunk-2WBFJHQA.js} +4 -26
- package/{chunk-IKTHA3JH.js → chunk-3LKZRP7E.js} +2 -2
- package/{chunk-INXBNYCG.js → chunk-3Y2K5O2R.js} +64 -6
- package/{chunk-VRZIH5JO.js → chunk-3ZTR7ZO4.js} +1 -1
- package/{chunk-GV35EHNA.js → chunk-5FCIPEKT.js} +262 -96
- package/{chunk-RTLJUGQH.js → chunk-5UAYZEXO.js} +2 -2
- package/{chunk-TI5BCZCH.js → chunk-6COJEAYH.js} +32 -101
- package/{chunk-Y7LNKP32.js → chunk-6HDYSFLO.js} +4 -6
- package/chunk-6IGD47IC.js +19 -0
- package/chunk-6YTOJY35.js +352 -0
- package/{chunk-6FGXGFAH.js → chunk-75MSWWUE.js} +1 -1
- package/{chunk-3Z3DXZBD.js → chunk-7FAS3NEF.js} +16 -16
- package/{chunk-AV6KQCM5.js → chunk-7NYDJAQ7.js} +19 -14
- package/{chunk-CVT7L2WZ.js → chunk-A65UV3M5.js} +4 -4
- package/{chunk-7APQB6R6.js → chunk-AUVFJGPC.js} +3 -3
- package/{chunk-H4RYESI6.js → chunk-BBTN4NQD.js} +4 -4
- package/{chunk-757BGY6Y.js → chunk-BG7J6Y5X.js} +1 -1
- package/chunk-BY2FF2C4.js +526 -0
- package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
- package/chunk-BYXBJQAS.js +0 -0
- package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
- package/{chunk-UITMHBVK.js → chunk-EA5OYZVD.js} +1 -1
- package/{chunk-4NN3EK7H.js → chunk-EICIFHVS.js} +1 -1
- package/chunk-EJE33XNR.js +19059 -0
- package/{chunk-6SZ52ORL.js → chunk-FJHMLRDQ.js} +9 -9
- package/{chunk-RU5D3B22.js → chunk-GRFK2XP4.js} +2 -2
- package/{chunk-J3UALFHL.js → chunk-HJTAGT3W.js} +1 -1
- package/{chunk-WL3UOGYO.js → chunk-HPW5MNDQ.js} +38 -98
- package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
- package/{chunk-OYNDYVSE.js → chunk-JON2PHYT.js} +1 -1
- package/{chunk-7K5VMB4Q.js → chunk-JXIP6ZWH.js} +7 -7
- package/{chunk-KUUTWU4I.js → chunk-K4NISKOR.js} +46 -8
- package/{chunk-SP3DPVBH.js → chunk-KLIBF3BY.js} +2 -2
- package/chunk-LRGKOI5Y.js +297 -0
- package/{chunk-LN3OQJGG.js → chunk-MLEZPE3U.js} +2 -2
- package/{chunk-FGEYVPPR.js → chunk-MYMBBB6Q.js} +5 -64
- package/{chunk-VRJUIUIY.js → chunk-N4JKMCY3.js} +2 -2
- package/{chunk-U5Z7LFZF.js → chunk-NFLA6GSU.js} +4 -4
- package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
- package/{chunk-56W233KG.js → chunk-NJUQBYFJ.js} +3 -1
- package/{chunk-Q24S4NDF.js → chunk-Q4XZVZPN.js} +1 -1
- package/{chunk-UW4INMD2.js → chunk-RHMDMTDK.js} +2 -2
- package/{chunk-MFI4FGHX.js → chunk-SAJSBPI2.js} +1 -1
- package/{chunk-WHVQA7PJ.js → chunk-SSXTSPSG.js} +27 -6
- package/{chunk-2BWU4ORW.js → chunk-SUEIAK5N.js} +1 -1
- package/{chunk-3QJTD6DO.js → chunk-SVC3GGUA.js} +5 -5
- package/{chunk-QDHZCAH3.js → chunk-SVDMVX4G.js} +118 -2
- package/{chunk-GBADO3SM.js → chunk-SWJGJMTW.js} +1 -1
- package/{chunk-DQLYEGP7.js → chunk-SYYUU7EV.js} +2 -2
- package/{chunk-U2A47SVI.js → chunk-TC6P4NDR.js} +7 -7
- package/{chunk-V4KZGLOI.js → chunk-TR4DXUYX.js} +1983 -447
- package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
- package/chunk-UAD2WT54.js +64 -0
- package/{chunk-PAHILFNT.js → chunk-UGBHDMHI.js} +4 -4
- package/{chunk-6FQ2552G.js → chunk-UOWXD4VN.js} +799 -956
- package/{chunk-5WADL4O7.js → chunk-UR66XPVF.js} +3 -3
- package/{chunk-6BYAXNH5.js → chunk-VZMUOPYG.js} +12 -2
- package/{chunk-LA4IDAK7.js → chunk-WQHGJHAL.js} +440 -2981
- package/{chunk-GLGD2JGY.js → chunk-XIJZOCSP.js} +7 -7
- package/{chunk-BJLYCOZK.js → chunk-YBFJQC2M.js} +93 -776
- package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
- package/{chunk-32I5RVMY.js → chunk-YLCUU3WM.js} +3 -3
- package/{chunk-D3JQPONH.js → chunk-YQBXOHE6.js} +1 -1
- package/chunk-ZJ7UHBJS.js +89 -0
- package/{chunk-TNPCQNGQ.js → chunk-ZVOHVJI3.js} +4 -9
- package/contentThunks-KNI6VXLT.js +71 -0
- package/{createAgentAutomationAction-UJLNFFFC.js → createAgentAutomationAction-OK4L33KF.js} +27 -23
- package/{createDialogAction-TJCX6GUE.js → createDialogAction-JDSMY4AY.js} +28 -24
- package/{createPageAction-N3IYABHV.js → createPageAction-T7RA3HCG.js} +29 -24
- package/{dbSlice-D5CNGWPD.js → dbSlice-TVX6SN2T.js} +6 -6
- package/{deleteFile-44TUM34Y.js → deleteFile-JYKRT7C3.js} +3 -3
- package/{dialogCommands-35M6RBAC.js → dialogCommands-UQZYWOOV.js} +32 -30
- package/{dialogSlice-KO7ADD7H.js → dialogSlice-TYW2G7IL.js} +26 -23
- package/{docCreateCommands-VXHZWQ3P.js → docCreateCommands-OA6HZBWO.js} +34 -32
- package/{docDeleteCommands-4WFAJR6A.js → docDeleteCommands-KBB3YQI2.js} +31 -29
- package/{docReadCommands-OYREEFAR.js → docReadCommands-ZLMFVC67.js} +30 -28
- package/{docStore-5BU76DFK.js → docStore-2URPBVCS.js} +8 -33
- package/{docUpdateCommands-A7QERSME.js → docUpdateCommands-HMH5KUON.js} +34 -32
- package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
- package/{getPricing-HAU62AFM.js → getPricing-RFOPUWHY.js} +4 -4
- package/{handleSendMessageAction-OSGQJQ45.js → handleSendMessageAction-GO53TY7U.js} +28 -25
- package/index.js +56 -56
- package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
- package/{machineCommands-J43U3TX5.js → machineCommands-RK6L7ZWL.js} +59 -54
- package/{machineWsRunDispatch-Z2Z6STXZ.js → machineWsRunDispatch-3X64DW2Z.js} +54 -49
- package/memberThunks-THZYZFSN.js +638 -0
- package/{models-4QF4BJVY.js → models-JVKUEER5.js} +2 -2
- package/package.json +1 -1
- package/{read-RGNPI5H2.js → read-K4JU4MQC.js} +3 -3
- package/{readDocTool-6ESWKTXD.js → readDocTool-LQGR6FUN.js} +1 -1
- package/{readlineWorkspace-YRPV6JPN.js → readlineWorkspace-XUFJV3RS.js} +604 -263
- package/{removeDialogAgentAction-JYT73FU2.js → removeDialogAgentAction-ECHCFB7N.js} +12 -11
- package/{runAgentClientLoop-5YM5WMAY.js → runAgentClientLoop-24GQ2AW6.js} +46 -40
- package/{setDialogExtraReferencesAction-D564LMYQ.js → setDialogExtraReferencesAction-KCVJNGMB.js} +9 -8
- package/{setPrimaryDialogAgentAction-ACY3BLYA.js → setPrimaryDialogAgentAction-VDOBOMKC.js} +12 -11
- package/{settingSlice-MKI3MNZJ.js → settingSlice-VR2IJSXC.js} +7 -7
- package/{skillDiscovery-GPUDHDTZ.js → skillDiscovery-2QTZINON.js} +3 -3
- package/{spaceCommands-MY26V52L.js → spaceCommands-S5YJJXL7.js} +30 -28
- package/{streamAgentChatTurn-XV5X5TNQ.js → streamAgentChatTurn-QHKP3ABO.js} +77 -64
- package/{switchDialogAgentAction-CJ5H6SAR.js → switchDialogAgentAction-5L4UP7VI.js} +10 -9
- package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
- package/{tools-MIMELA2Y.js → tools-SSXSTC3O.js} +37 -32
- package/{tuiSummaryLlmCaller-XJ5BKNNS.js → tuiSummaryLlmCaller-URFJHFC5.js} +17 -15
- package/{updateDialogTitleAction-EIZUSWHR.js → updateDialogTitleAction-YFYAEW3T.js} +28 -24
- package/chunk-6BGAQ3KR.js +0 -7081
- package/chunk-YBV6QJKM.js +0 -441
- package/spaceSlice-JUIXC365.js +0 -127
- package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
- package/{chunk-PYKV6FSC.js → chunk-XOJRZUPF.js} +3 -3
|
@@ -3,11 +3,12 @@ import {
|
|
|
3
3
|
normalizeDialogRecord,
|
|
4
4
|
readDialogSnapshot,
|
|
5
5
|
sortDialogs
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XIJZOCSP.js";
|
|
7
7
|
import {
|
|
8
8
|
ANSI_ESCAPE_REGEX,
|
|
9
9
|
COLLAPSED_PASTE_PLACEHOLDER_RE,
|
|
10
10
|
THEME_PALETTES,
|
|
11
|
+
TUI_TREE_MARKER,
|
|
11
12
|
allocateCollapsedPaste,
|
|
12
13
|
applyDetectedBackground,
|
|
13
14
|
applyTerminalOutputToText,
|
|
@@ -24,12 +25,15 @@ import {
|
|
|
24
25
|
findCollapsedPasteSpanAt,
|
|
25
26
|
fitAnsiLine,
|
|
26
27
|
formatAssistantDisplay,
|
|
28
|
+
formatCreditsChip,
|
|
27
29
|
formatTokenCount,
|
|
28
30
|
getActiveThemeMode,
|
|
29
31
|
getActiveThemeName,
|
|
30
32
|
isBalanceExhaustedError,
|
|
31
|
-
normalizeToolDisplayMode,
|
|
32
33
|
padOrTruncateToWidth,
|
|
34
|
+
polishBreathInsertsBlankBetween,
|
|
35
|
+
readAgentsMdLayerFromDisk,
|
|
36
|
+
redactSecrets,
|
|
33
37
|
releaseCollapsedPaste,
|
|
34
38
|
releaseCollapsedPasteReferences,
|
|
35
39
|
renderSurfaceLine,
|
|
@@ -62,30 +66,32 @@ import {
|
|
|
62
66
|
wrapTextToLines,
|
|
63
67
|
wrapTranscriptLine,
|
|
64
68
|
wrapTranscriptLineWithLayout
|
|
65
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-UOWXD4VN.js";
|
|
70
|
+
import "./chunk-S7Z2HMCN.js";
|
|
71
|
+
import "./chunk-LYGNQHUW.js";
|
|
72
|
+
import "./chunk-ESHYE7WU.js";
|
|
66
73
|
import {
|
|
67
74
|
listFavoriteAgentIdsAcrossServers,
|
|
68
75
|
listLocalCachedAgents,
|
|
69
76
|
listRemoteAgents,
|
|
70
77
|
listRemoteAgentsAcrossServers,
|
|
71
78
|
normalizeListedAgent
|
|
72
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-UR66XPVF.js";
|
|
73
80
|
import "./chunk-ID4G2MAR.js";
|
|
74
81
|
import {
|
|
75
82
|
listUserRecordsFromServers,
|
|
76
83
|
readLiveDbRecordAfterTombstoneMerge
|
|
77
|
-
} from "./chunk-
|
|
78
|
-
import "./chunk-J3UALFHL.js";
|
|
79
|
-
import "./chunk-LYGNQHUW.js";
|
|
84
|
+
} from "./chunk-Q4XZVZPN.js";
|
|
80
85
|
import {
|
|
86
|
+
RUN_WAKE_CHANNEL_ENV,
|
|
81
87
|
createCliLocalRuntimeAdapter,
|
|
82
88
|
initCliLocale,
|
|
83
89
|
parseCliLocale,
|
|
84
90
|
readTimestamp,
|
|
85
91
|
setCliLocale,
|
|
86
92
|
t
|
|
87
|
-
} from "./chunk-
|
|
88
|
-
import "./chunk-
|
|
93
|
+
} from "./chunk-5FCIPEKT.js";
|
|
94
|
+
import "./chunk-NFLA6GSU.js";
|
|
89
95
|
import "./chunk-EADNWBAZ.js";
|
|
90
96
|
import "./chunk-NI2BS6UD.js";
|
|
91
97
|
import {
|
|
@@ -95,37 +101,46 @@ import {
|
|
|
95
101
|
deleteDbRecord,
|
|
96
102
|
queryUserRecords,
|
|
97
103
|
readDbRecord
|
|
98
|
-
} from "./chunk-
|
|
99
|
-
import "./chunk-
|
|
104
|
+
} from "./chunk-SYYUU7EV.js";
|
|
105
|
+
import "./chunk-JON2PHYT.js";
|
|
100
106
|
import {
|
|
101
107
|
NOLO_DEFAULT_AGENT_KEY,
|
|
102
108
|
resolveCliAgentKeyInput
|
|
103
109
|
} from "./chunk-EKLRRZIN.js";
|
|
110
|
+
import "./chunk-HJTAGT3W.js";
|
|
111
|
+
import {
|
|
112
|
+
createChatQueueRuntime,
|
|
113
|
+
createTurnRequest,
|
|
114
|
+
normalizeRunCompletionShape
|
|
115
|
+
} from "./chunk-YPREESF4.js";
|
|
104
116
|
import "./chunk-JDSUTNYY.js";
|
|
117
|
+
import "./chunk-JBTJAPUF.js";
|
|
105
118
|
import {
|
|
119
|
+
backfillRunRecordParentDialog,
|
|
106
120
|
checkStaleRun,
|
|
107
121
|
isRunRecordClaimed,
|
|
108
122
|
listRunRecords,
|
|
109
123
|
readRunRecord
|
|
110
|
-
} from "./chunk-
|
|
111
|
-
import "./chunk-ESHYE7WU.js";
|
|
112
|
-
import "./chunk-JBTJAPUF.js";
|
|
124
|
+
} from "./chunk-SSXTSPSG.js";
|
|
113
125
|
import "./chunk-LTRXGFMS.js";
|
|
114
|
-
import "./chunk-
|
|
126
|
+
import "./chunk-EICIFHVS.js";
|
|
115
127
|
import "./chunk-ATNTHIZI.js";
|
|
116
128
|
import "./chunk-JEXVIMYZ.js";
|
|
117
129
|
import {
|
|
118
130
|
prepareTools
|
|
119
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-RHMDMTDK.js";
|
|
132
|
+
import {
|
|
133
|
+
buildResponseGuidelines
|
|
134
|
+
} from "./chunk-6IGD47IC.js";
|
|
120
135
|
import "./chunk-HS7MLR74.js";
|
|
121
|
-
import "./chunk-
|
|
122
|
-
import "./chunk-
|
|
136
|
+
import "./chunk-BG7J6Y5X.js";
|
|
137
|
+
import "./chunk-TR4DXUYX.js";
|
|
123
138
|
import "./chunk-5XTOKQLW.js";
|
|
124
139
|
import "./chunk-NF64D32W.js";
|
|
125
140
|
import "./chunk-3L2WKC3W.js";
|
|
126
|
-
import "./chunk-
|
|
141
|
+
import "./chunk-GRFK2XP4.js";
|
|
127
142
|
import "./chunk-KQHGZWSV.js";
|
|
128
|
-
import "./chunk-
|
|
143
|
+
import "./chunk-3ZTR7ZO4.js";
|
|
129
144
|
import {
|
|
130
145
|
clipText,
|
|
131
146
|
formatDuration,
|
|
@@ -137,39 +152,38 @@ import {
|
|
|
137
152
|
runShowsLogTail,
|
|
138
153
|
shortRunId
|
|
139
154
|
} from "./chunk-KXKQO4Q6.js";
|
|
155
|
+
import "./chunk-LRGKOI5Y.js";
|
|
156
|
+
import "./chunk-TY3ADTX5.js";
|
|
157
|
+
import "./chunk-UGBHDMHI.js";
|
|
140
158
|
import "./chunk-INZZJSQF.js";
|
|
141
|
-
import "./chunk-Y7LNKP32.js";
|
|
142
|
-
import "./chunk-BANYWEYY.js";
|
|
143
|
-
import "./chunk-PAHILFNT.js";
|
|
144
159
|
import "./chunk-MEYIRKDN.js";
|
|
145
160
|
import "./chunk-63W5N6P3.js";
|
|
146
161
|
import "./chunk-VF4K2QE6.js";
|
|
162
|
+
import "./chunk-6HDYSFLO.js";
|
|
163
|
+
import "./chunk-FJHMLRDQ.js";
|
|
164
|
+
import "./chunk-WQHGJHAL.js";
|
|
165
|
+
import "./chunk-ZJ7UHBJS.js";
|
|
147
166
|
import {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
} from "./chunk-YPREESF4.js";
|
|
152
|
-
import "./chunk-6SZ52ORL.js";
|
|
153
|
-
import "./chunk-LA4IDAK7.js";
|
|
154
|
-
import {
|
|
155
|
-
extractReferenceKeysFromMessage
|
|
156
|
-
} from "./chunk-BJLYCOZK.js";
|
|
167
|
+
extractReferenceKeysFromMessage,
|
|
168
|
+
normalizeUsage
|
|
169
|
+
} from "./chunk-YBFJQC2M.js";
|
|
157
170
|
import "./chunk-EVBFYPDC.js";
|
|
158
|
-
import "./chunk-
|
|
171
|
+
import "./chunk-HQUORJTM.js";
|
|
159
172
|
import "./chunk-YYLHWIW6.js";
|
|
160
|
-
import "./chunk-U2A47SVI.js";
|
|
161
173
|
import "./chunk-AGGIDPCZ.js";
|
|
162
|
-
import "./chunk-
|
|
174
|
+
import "./chunk-TC6P4NDR.js";
|
|
175
|
+
import "./chunk-YLCUU3WM.js";
|
|
163
176
|
import "./chunk-5RGU3J7P.js";
|
|
177
|
+
import "./chunk-6YTOJY35.js";
|
|
164
178
|
import "./chunk-M76ECQRD.js";
|
|
165
|
-
import "./chunk-
|
|
179
|
+
import "./chunk-YDH3FDFQ.js";
|
|
166
180
|
import "./chunk-URMS4XY2.js";
|
|
167
181
|
import "./chunk-IA3A5373.js";
|
|
168
182
|
import "./chunk-GLKOYSRU.js";
|
|
169
183
|
import {
|
|
170
184
|
buildSkillDiscoveryContextBlock,
|
|
171
185
|
buildSkillDiscoveryContextLayer
|
|
172
|
-
} from "./chunk-
|
|
186
|
+
} from "./chunk-SUEIAK5N.js";
|
|
173
187
|
import "./chunk-AA564GBL.js";
|
|
174
188
|
import {
|
|
175
189
|
expandEnabledPacks
|
|
@@ -180,23 +194,23 @@ import {
|
|
|
180
194
|
buildLocalWorkspaceToolset,
|
|
181
195
|
getProcessRegistry,
|
|
182
196
|
readCommandActionGatePayload
|
|
183
|
-
} from "./chunk-
|
|
184
|
-
import "./chunk-INXBNYCG.js";
|
|
197
|
+
} from "./chunk-EJE33XNR.js";
|
|
185
198
|
import "./chunk-ZNFJWEN4.js";
|
|
186
|
-
import "./chunk-
|
|
187
|
-
import "./chunk-
|
|
199
|
+
import "./chunk-3Y2K5O2R.js";
|
|
200
|
+
import "./chunk-A65UV3M5.js";
|
|
201
|
+
import "./chunk-2QDDKFG5.js";
|
|
188
202
|
import "./chunk-N7J63Q6C.js";
|
|
189
203
|
import {
|
|
190
204
|
buildCurrentTimeBlock,
|
|
191
205
|
buildIdentityBlock,
|
|
192
206
|
buildRuntimeGuidanceBlocks,
|
|
193
207
|
resolveToolGuidedSections
|
|
194
|
-
} from "./chunk-
|
|
195
|
-
import "./chunk-
|
|
208
|
+
} from "./chunk-BY2FF2C4.js";
|
|
209
|
+
import "./chunk-VZMUOPYG.js";
|
|
196
210
|
import {
|
|
197
211
|
resolvePlatformAuthToken
|
|
198
|
-
} from "./chunk-
|
|
199
|
-
import "./chunk-
|
|
212
|
+
} from "./chunk-KLIBF3BY.js";
|
|
213
|
+
import "./chunk-ZVOHVJI3.js";
|
|
200
214
|
import {
|
|
201
215
|
isQuotaExhaustedError
|
|
202
216
|
} from "./chunk-IWUMSAQF.js";
|
|
@@ -204,7 +218,7 @@ import "./chunk-2MBTWINN.js";
|
|
|
204
218
|
import {
|
|
205
219
|
DEFAULT_CONTEXT_WINDOW,
|
|
206
220
|
getModelContextWindow
|
|
207
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-K4NISKOR.js";
|
|
208
222
|
import {
|
|
209
223
|
buildCompactionMetricsFromPlan,
|
|
210
224
|
buildCompactionUserContent,
|
|
@@ -215,32 +229,32 @@ import {
|
|
|
215
229
|
formatMessagesForSummaryWithTruncation,
|
|
216
230
|
planCompression,
|
|
217
231
|
serializeMessageContent
|
|
218
|
-
} from "./chunk-
|
|
219
|
-
import "./chunk-
|
|
220
|
-
import "./chunk-
|
|
221
|
-
import "./chunk-
|
|
222
|
-
import "./chunk-QDHZCAH3.js";
|
|
232
|
+
} from "./chunk-BBTN4NQD.js";
|
|
233
|
+
import "./chunk-N4JKMCY3.js";
|
|
234
|
+
import "./chunk-BYXBJQAS.js";
|
|
235
|
+
import "./chunk-SVDMVX4G.js";
|
|
223
236
|
import {
|
|
224
237
|
compactWhitespace
|
|
225
238
|
} from "./chunk-DWLEOOGR.js";
|
|
239
|
+
import "./chunk-CS6TCJ7E.js";
|
|
240
|
+
import "./chunk-FD36SCCD.js";
|
|
226
241
|
import "./chunk-ZHXJ6M7T.js";
|
|
227
242
|
import {
|
|
228
243
|
toErrorMessage
|
|
229
244
|
} from "./chunk-HNMXYYJR.js";
|
|
230
245
|
import {
|
|
231
|
-
buildAgentsMdLayer,
|
|
232
246
|
buildMemoryOverlayLayer,
|
|
233
247
|
buildMemoryUseGuidanceLayer,
|
|
234
248
|
partitionScopedBlocks,
|
|
235
249
|
renderTurnContextBlocksWithScope
|
|
236
|
-
} from "./chunk-
|
|
250
|
+
} from "./chunk-DVINR3PL.js";
|
|
237
251
|
import {
|
|
238
252
|
buildUserResponseLanguageContext
|
|
239
|
-
} from "./chunk-
|
|
253
|
+
} from "./chunk-2GRGFCF6.js";
|
|
240
254
|
import {
|
|
241
255
|
canonicalizeToolNames
|
|
242
256
|
} from "./chunk-O6OSWFZQ.js";
|
|
243
|
-
import "./chunk-
|
|
257
|
+
import "./chunk-BYEJ7K2Z.js";
|
|
244
258
|
import {
|
|
245
259
|
checkForCliUpdate,
|
|
246
260
|
runSelfUpdateDetailed
|
|
@@ -265,19 +279,20 @@ import {
|
|
|
265
279
|
import {
|
|
266
280
|
DEFAULT_NOLO_SERVER_URL
|
|
267
281
|
} from "./chunk-OLZBQWZU.js";
|
|
268
|
-
import "./chunk-
|
|
269
|
-
import "./chunk-
|
|
270
|
-
import "./chunk-
|
|
271
|
-
import "./chunk-
|
|
282
|
+
import "./chunk-NJUQBYFJ.js";
|
|
283
|
+
import "./chunk-HPW5MNDQ.js";
|
|
284
|
+
import "./chunk-AUVFJGPC.js";
|
|
285
|
+
import "./chunk-SVC3GGUA.js";
|
|
272
286
|
import "./chunk-Y5GCAMGP.js";
|
|
273
287
|
import "./chunk-UZ6XXCVR.js";
|
|
274
288
|
import "./chunk-KX6YBIHG.js";
|
|
275
|
-
import "./chunk-
|
|
276
|
-
import "./chunk-
|
|
277
|
-
import "./chunk-
|
|
289
|
+
import "./chunk-MYMBBB6Q.js";
|
|
290
|
+
import "./chunk-UAD2WT54.js";
|
|
291
|
+
import "./chunk-7NYDJAQ7.js";
|
|
292
|
+
import "./chunk-NHRQCXIQ.js";
|
|
278
293
|
import "./chunk-WWC7I6TA.js";
|
|
279
294
|
import "./chunk-I42VC5KR.js";
|
|
280
|
-
import "./chunk-
|
|
295
|
+
import "./chunk-SAJSBPI2.js";
|
|
281
296
|
import {
|
|
282
297
|
asTrimmedLowercaseString
|
|
283
298
|
} from "./chunk-QSJ3HFEF.js";
|
|
@@ -286,18 +301,18 @@ import {
|
|
|
286
301
|
BUILTIN_NOLO_AGENT_MODEL,
|
|
287
302
|
BUILTIN_NOLO_AGENT_NAME,
|
|
288
303
|
builtinAgentCatalogEntryById
|
|
289
|
-
} from "./chunk-
|
|
304
|
+
} from "./chunk-2WBFJHQA.js";
|
|
290
305
|
import {
|
|
291
306
|
extractCustomId,
|
|
292
307
|
parsePublicAgentId
|
|
293
308
|
} from "./chunk-BJIRLHJR.js";
|
|
294
|
-
import "./chunk-
|
|
309
|
+
import "./chunk-XOJRZUPF.js";
|
|
295
310
|
import "./chunk-QOKAKDPE.js";
|
|
296
311
|
import "./chunk-OW765XBU.js";
|
|
297
312
|
import "./chunk-GBRG75BQ.js";
|
|
298
|
-
import "./chunk-KUG52IAP.js";
|
|
299
313
|
import "./chunk-3EUW3WEO.js";
|
|
300
314
|
import "./chunk-U6VC4MU4.js";
|
|
315
|
+
import "./chunk-KUG52IAP.js";
|
|
301
316
|
import "./chunk-LCBAMY2M.js";
|
|
302
317
|
import "./chunk-4SN6J65J.js";
|
|
303
318
|
import "./chunk-CF7PE763.js";
|
|
@@ -1222,7 +1237,81 @@ function appendLocalTurn(history, command, output) {
|
|
|
1222
1237
|
trimHistoryToBudget(history);
|
|
1223
1238
|
resetStreamingTurnCache();
|
|
1224
1239
|
}
|
|
1240
|
+
var TOOL_SUCCESS_LINE_RE = /^(▸ .*?)(?: ×(\d+))?( ✓)$/;
|
|
1241
|
+
function applyTreeRewrite(text, chunk) {
|
|
1242
|
+
if (!chunk.startsWith(TUI_TREE_MARKER)) return null;
|
|
1243
|
+
const payload = chunk.slice(TUI_TREE_MARKER.length).replace(/\u0002\n?$/, "");
|
|
1244
|
+
const tree = `\u2022 ${payload}`;
|
|
1245
|
+
const hadTrailingNewline = text.endsWith("\n");
|
|
1246
|
+
const body = hadTrailingNewline ? text.slice(0, -1) : text;
|
|
1247
|
+
const bodyLines = body.split("\n");
|
|
1248
|
+
const plainLines = bodyLines.map((line) => stripAnsi(line));
|
|
1249
|
+
const tail = plainLines.at(-1) ?? "";
|
|
1250
|
+
let prefix;
|
|
1251
|
+
if (tail.trimStart().startsWith("\u25B8 ")) {
|
|
1252
|
+
prefix = bodyLines.length < 2 ? "" : `${bodyLines.slice(0, -1).join("\n")}
|
|
1253
|
+
`;
|
|
1254
|
+
} else if (tail.trimStart().startsWith("\u2514\u2500\u2500 ")) {
|
|
1255
|
+
const headerIndex = plainLines.findLastIndex((line) => line.trimStart().startsWith("\u2022 "));
|
|
1256
|
+
if (headerIndex < 0) return null;
|
|
1257
|
+
prefix = `${bodyLines.slice(0, headerIndex).join("\n")}${headerIndex > 0 ? "\n" : ""}`;
|
|
1258
|
+
} else return null;
|
|
1259
|
+
return `${prefix}${tree}
|
|
1260
|
+
`;
|
|
1261
|
+
}
|
|
1262
|
+
function foldToolSuccessLine(text, chunk) {
|
|
1263
|
+
const plain = stripAnsi(chunk).replace(/\n+$/, "");
|
|
1264
|
+
if (!plain || plain.includes("\n") || !TOOL_SUCCESS_LINE_RE.test(plain)) return null;
|
|
1265
|
+
const hadTrailingNewline = text.endsWith("\n");
|
|
1266
|
+
const body = hadTrailingNewline ? text.slice(0, -1) : text;
|
|
1267
|
+
const newlineAt = body.lastIndexOf("\n");
|
|
1268
|
+
const tail = newlineAt === -1 ? body : body.slice(newlineAt + 1);
|
|
1269
|
+
const match = TOOL_SUCCESS_LINE_RE.exec(stripAnsi(tail));
|
|
1270
|
+
if (!match || `${match[1]}${match[3]}` !== plain) return null;
|
|
1271
|
+
const count = (match[2] ? Number(match[2]) : 1) + 1;
|
|
1272
|
+
const anchor = tail.lastIndexOf(" ");
|
|
1273
|
+
if (anchor < 0) return null;
|
|
1274
|
+
const head = tail.slice(0, anchor).replace(/\s×\d+$/, "");
|
|
1275
|
+
const merged = `${head} \xD7${count}${tail.slice(anchor)}`;
|
|
1276
|
+
const prefix = newlineAt === -1 ? "" : body.slice(0, newlineAt + 1);
|
|
1277
|
+
return `${prefix}${merged}${hadTrailingNewline ? "\n" : ""}`;
|
|
1278
|
+
}
|
|
1225
1279
|
function applyOutputChunkToCurrentTurn(history, chunk, kind = "assistant") {
|
|
1280
|
+
if (kind === "tool") {
|
|
1281
|
+
if (chunk.startsWith(TUI_TREE_MARKER)) {
|
|
1282
|
+
const rewrittenTree = applyTreeRewrite(history.currentContent, chunk);
|
|
1283
|
+
if (rewrittenTree === null) {
|
|
1284
|
+
const safe = chunk.slice(TUI_TREE_MARKER.length).replace(/\u0002/g, "");
|
|
1285
|
+
const leaves = safe.split("\n").filter((line) => /^(?:├── |└── )/.test(line));
|
|
1286
|
+
const newest = leaves.at(-1)?.replace(/^(?:├── |└── )/, "\u25B8 ") ?? "";
|
|
1287
|
+
if (!newest) return false;
|
|
1288
|
+
const flat = `${newest}
|
|
1289
|
+
`;
|
|
1290
|
+
history.currentContent = applyTerminalOutputToText(history.currentContent, flat);
|
|
1291
|
+
appendCurrentBlock(history, kind, flat);
|
|
1292
|
+
return false;
|
|
1293
|
+
}
|
|
1294
|
+
const treeContent = rewrittenTree;
|
|
1295
|
+
history.currentContent = treeContent;
|
|
1296
|
+
const lastBlock = history.currentBlocks.at(-1);
|
|
1297
|
+
const treeLines = treeContent.split("\n");
|
|
1298
|
+
const treeHeaderIndex = treeLines.findIndex((line) => line.trimStart().startsWith("\u2022 "));
|
|
1299
|
+
const treeBlock = treeHeaderIndex >= 0 ? treeLines.slice(treeHeaderIndex).join("\n") : treeContent;
|
|
1300
|
+
if (lastBlock?.kind === "tool") lastBlock.content = lastBlock.content.replace(/[^\n]*$/, "") + treeBlock;
|
|
1301
|
+
else history.currentBlocks.push({ kind: "tool", content: treeBlock });
|
|
1302
|
+
return true;
|
|
1303
|
+
}
|
|
1304
|
+
const foldedContent = foldToolSuccessLine(history.currentContent, chunk);
|
|
1305
|
+
if (foldedContent !== null) {
|
|
1306
|
+
history.currentContent = foldedContent;
|
|
1307
|
+
const lastBlock = history.currentBlocks.at(-1);
|
|
1308
|
+
if (lastBlock?.kind === "tool") {
|
|
1309
|
+
const foldedBlock = foldToolSuccessLine(lastBlock.content, chunk);
|
|
1310
|
+
if (foldedBlock !== null) lastBlock.content = foldedBlock;
|
|
1311
|
+
}
|
|
1312
|
+
return true;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1226
1315
|
const next = applyTerminalOutputToText(history.currentContent, chunk);
|
|
1227
1316
|
if (next === history.currentContent) return false;
|
|
1228
1317
|
history.currentContent = next;
|
|
@@ -1405,6 +1494,40 @@ var streamingTurnCache = null;
|
|
|
1405
1494
|
function resetStreamingTurnCache() {
|
|
1406
1495
|
streamingTurnCache = null;
|
|
1407
1496
|
}
|
|
1497
|
+
function countFenceFlips(text) {
|
|
1498
|
+
const matches = text.match(/^[ \t]*```/gm);
|
|
1499
|
+
return matches ? matches.length : 0;
|
|
1500
|
+
}
|
|
1501
|
+
var HEADING_LIKE_RE = /^#{1,3} /;
|
|
1502
|
+
function isPipeRowLike(line) {
|
|
1503
|
+
const trimmed = line.trim();
|
|
1504
|
+
return trimmed.length > 0 && trimmed.startsWith("|");
|
|
1505
|
+
}
|
|
1506
|
+
function isSuspiciousAppend(newTail, fenceParityEven) {
|
|
1507
|
+
if (!fenceParityEven) return true;
|
|
1508
|
+
if (newTail.includes("\r")) return true;
|
|
1509
|
+
if (newTail.includes("```")) return true;
|
|
1510
|
+
if (newTail.includes("$$") || newTail.includes("\\[") || newTail.includes("\\]")) {
|
|
1511
|
+
return true;
|
|
1512
|
+
}
|
|
1513
|
+
if (/\n{4,}/.test(newTail)) return true;
|
|
1514
|
+
if (newTail.includes("\0")) return true;
|
|
1515
|
+
return hasPipeRowLine(newTail);
|
|
1516
|
+
}
|
|
1517
|
+
function hasPipeRowLine(text) {
|
|
1518
|
+
const lines = text.split("\n");
|
|
1519
|
+
return lines.some((line) => isPipeRowLike(line));
|
|
1520
|
+
}
|
|
1521
|
+
function isSuspiciousBoundary(committedLastLine, newTail) {
|
|
1522
|
+
const newlineIdx = newTail.indexOf("\n");
|
|
1523
|
+
const firstLine = newlineIdx === -1 ? newTail : newTail.slice(0, newlineIdx);
|
|
1524
|
+
if (HEADING_LIKE_RE.test(firstLine) && committedLastLine !== "") return true;
|
|
1525
|
+
if (HEADING_LIKE_RE.test(committedLastLine) && firstLine !== "") return true;
|
|
1526
|
+
if (isPipeRowLike(firstLine) || isPipeRowLike(committedLastLine)) {
|
|
1527
|
+
return true;
|
|
1528
|
+
}
|
|
1529
|
+
return polishBreathInsertsBlankBetween(committedLastLine, firstLine);
|
|
1530
|
+
}
|
|
1408
1531
|
function renderPrefixTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
1409
1532
|
content = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1410
1533
|
if (role === "user") {
|
|
@@ -1447,62 +1570,94 @@ function renderTailTurnBlock(role, content, contentWidth, colorEnabled) {
|
|
|
1447
1570
|
}
|
|
1448
1571
|
}
|
|
1449
1572
|
function getStreamingTurnLines(role, content, contentWidth, colorEnabled, themeFingerprint) {
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
if (!
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1573
|
+
const forceValidate = process.env.NOLO_TUI_RENDER_VALIDATE === "1";
|
|
1574
|
+
let cache = streamingTurnCache;
|
|
1575
|
+
const geometryChanged = !cache || cache.role !== role || cache.contentWidth !== contentWidth || cache.colorEnabled !== colorEnabled || cache.themeFingerprint !== themeFingerprint;
|
|
1576
|
+
if (geometryChanged || !content.startsWith(cache.fullContent)) {
|
|
1577
|
+
return rebuildStreamingCache(content, role, contentWidth, colorEnabled, themeFingerprint);
|
|
1578
|
+
}
|
|
1579
|
+
if (content === cache.fullContent && cache.lastResult) {
|
|
1580
|
+
return cache.lastResult;
|
|
1581
|
+
}
|
|
1582
|
+
const suffix = content.slice(cache.fullContent.length);
|
|
1583
|
+
if (suffix === "") {
|
|
1584
|
+
return cache.lastResult ?? cache.committedLines;
|
|
1585
|
+
}
|
|
1586
|
+
const renderFull = () => {
|
|
1587
|
+
const lines = renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
1588
|
+
cache.fullContent = content;
|
|
1589
|
+
cache.fenceFlips = countFenceFlips(content);
|
|
1590
|
+
const lastNewline = content.lastIndexOf("\n");
|
|
1591
|
+
cache.completeContentLength = lastNewline + 1;
|
|
1592
|
+
cache.committedLines = lastNewline === -1 ? [] : renderTurnBlock(role, content.slice(0, lastNewline), contentWidth, colorEnabled);
|
|
1593
|
+
cache.pendingTail = content.slice(lastNewline + 1);
|
|
1594
|
+
cache.committedLastLine = lastNewline === -1 ? "" : lastLogicalLineOf(content.slice(0, lastNewline + 1));
|
|
1595
|
+
cache.lastResult = lines;
|
|
1596
|
+
return lines;
|
|
1597
|
+
};
|
|
1598
|
+
const newTail = cache.pendingTail + suffix;
|
|
1599
|
+
if (!cache.fastPathEnabled || isSuspiciousAppend(newTail, cache.fenceFlips % 2 === 0) || isSuspiciousBoundary(cache.committedLastLine, newTail)) {
|
|
1600
|
+
return renderFull();
|
|
1601
|
+
}
|
|
1602
|
+
const tailRenderer = cache.completeContentLength === 0 ? renderPrefixTurnBlock : renderTailTurnBlock;
|
|
1603
|
+
const tailLines = tailRenderer(role, newTail, contentWidth, colorEnabled);
|
|
1604
|
+
const composed = cache.completeContentLength === 0 ? tailLines : [...cache.committedLines, ...tailLines];
|
|
1605
|
+
if (!cache.spliceValidated || forceValidate) {
|
|
1606
|
+
const full = renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
1607
|
+
cache.spliceValidated = true;
|
|
1608
|
+
if (composed.length === full.length && composed.every((line, index) => line === full[index])) {
|
|
1609
|
+
commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled);
|
|
1610
|
+
cache.lastResult = composed;
|
|
1611
|
+
return composed;
|
|
1612
|
+
}
|
|
1613
|
+
cache.fastPathEnabled = false;
|
|
1614
|
+
return renderFull();
|
|
1615
|
+
}
|
|
1616
|
+
commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled);
|
|
1617
|
+
cache.lastResult = composed;
|
|
1618
|
+
return composed;
|
|
1619
|
+
}
|
|
1620
|
+
function lastLogicalLineOf(content) {
|
|
1621
|
+
const trimmed = content.replace(/\n$/, "");
|
|
1622
|
+
const idx = trimmed.lastIndexOf("\n");
|
|
1623
|
+
return idx === -1 ? trimmed : trimmed.slice(idx + 1);
|
|
1624
|
+
}
|
|
1625
|
+
function rebuildStreamingCache(content, role, contentWidth, colorEnabled, themeFingerprint) {
|
|
1626
|
+
const lines = renderTurnBlock(role, content, contentWidth, colorEnabled);
|
|
1627
|
+
const lastNewline = content.lastIndexOf("\n");
|
|
1628
|
+
streamingTurnCache = {
|
|
1629
|
+
role,
|
|
1630
|
+
contentWidth,
|
|
1631
|
+
colorEnabled,
|
|
1632
|
+
themeFingerprint,
|
|
1633
|
+
fullContent: content,
|
|
1634
|
+
// committed 渲染源剥掉段尾 \n(幽灵空行修正,见 renderFull 注释)。
|
|
1635
|
+
committedLines: lastNewline === -1 ? [] : renderTurnBlock(role, content.slice(0, lastNewline), contentWidth, colorEnabled),
|
|
1636
|
+
completeContentLength: lastNewline + 1,
|
|
1637
|
+
pendingTail: content.slice(lastNewline + 1),
|
|
1638
|
+
fenceFlips: countFenceFlips(content),
|
|
1639
|
+
committedLastLine: lastNewline === -1 ? "" : lastLogicalLineOf(content.slice(0, lastNewline + 1)),
|
|
1640
|
+
fastPathEnabled: true,
|
|
1641
|
+
spliceValidated: false,
|
|
1642
|
+
lastResult: lines
|
|
1643
|
+
};
|
|
1644
|
+
return lines;
|
|
1645
|
+
}
|
|
1646
|
+
function commitCompletedTail(cache, content, newTail, role, contentWidth, colorEnabled) {
|
|
1647
|
+
const lastNewline = newTail.lastIndexOf("\n");
|
|
1648
|
+
if (lastNewline !== -1) {
|
|
1649
|
+
const completePart = newTail.slice(0, lastNewline + 1);
|
|
1650
|
+
const renderSource = completePart.slice(0, -1);
|
|
1651
|
+
const renderer = cache.completeContentLength === 0 ? renderPrefixTurnBlock : renderTailTurnBlock;
|
|
1652
|
+
cache.committedLines.push(
|
|
1653
|
+
...renderer(role, renderSource, contentWidth, colorEnabled)
|
|
1654
|
+
);
|
|
1655
|
+
cache.completeContentLength += completePart.length;
|
|
1656
|
+
cache.fenceFlips += countFenceFlips(completePart);
|
|
1657
|
+
cache.committedLastLine = lastLogicalLineOf(completePart);
|
|
1658
|
+
cache.pendingTail = newTail.slice(lastNewline + 1);
|
|
1502
1659
|
}
|
|
1503
|
-
|
|
1504
|
-
const tailLines = renderTailTurnBlock(role, tailContent, contentWidth, colorEnabled);
|
|
1505
|
-
return [...streamingTurnCache.prefixLines, ...tailLines];
|
|
1660
|
+
cache.fullContent = content;
|
|
1506
1661
|
}
|
|
1507
1662
|
function countTurnLines(role, content, contentWidth, command) {
|
|
1508
1663
|
return layoutTurnRows(role, content, contentWidth, false, command).length;
|
|
@@ -1737,6 +1892,7 @@ function createHistoryOutputStream(history, onUpdate) {
|
|
|
1737
1892
|
const stream = {
|
|
1738
1893
|
isTTY: true,
|
|
1739
1894
|
assistantLabelManaged: true,
|
|
1895
|
+
tuiTrees: true,
|
|
1740
1896
|
write(chunk) {
|
|
1741
1897
|
const text = typeof chunk === "string" ? chunk : chunk.toString();
|
|
1742
1898
|
if (applyOutputChunkToCurrentTurn(history, text)) {
|
|
@@ -1745,9 +1901,9 @@ function createHistoryOutputStream(history, onUpdate) {
|
|
|
1745
1901
|
return true;
|
|
1746
1902
|
},
|
|
1747
1903
|
writeToolBlock(chunk) {
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1904
|
+
const applied = applyOutputChunkToCurrentTurn(history, chunk, "tool");
|
|
1905
|
+
if (applied) onUpdate();
|
|
1906
|
+
return applied;
|
|
1751
1907
|
}
|
|
1752
1908
|
};
|
|
1753
1909
|
return stream;
|
|
@@ -1810,6 +1966,14 @@ function resolveDialogBottomRow(args) {
|
|
|
1810
1966
|
return Math.max(1, resolveTtyRows(args.output) - args.inputLines);
|
|
1811
1967
|
}
|
|
1812
1968
|
function createDialogHost(args) {
|
|
1969
|
+
let keyboardClaimed = false;
|
|
1970
|
+
const claimKeyboard = () => {
|
|
1971
|
+
keyboardClaimed = true;
|
|
1972
|
+
};
|
|
1973
|
+
const releaseKeyboard = () => {
|
|
1974
|
+
args.drainDecoder?.();
|
|
1975
|
+
keyboardClaimed = false;
|
|
1976
|
+
};
|
|
1813
1977
|
return {
|
|
1814
1978
|
async run(body) {
|
|
1815
1979
|
const anchor = {
|
|
@@ -1819,14 +1983,25 @@ function createDialogHost(args) {
|
|
|
1819
1983
|
inputLines: args.composer.getInputLines()
|
|
1820
1984
|
})
|
|
1821
1985
|
};
|
|
1986
|
+
claimKeyboard();
|
|
1822
1987
|
args.composer.pause();
|
|
1823
1988
|
try {
|
|
1824
1989
|
return await body(anchor);
|
|
1825
1990
|
} finally {
|
|
1826
1991
|
resetHistoryFrameDiffCache(args.output);
|
|
1827
1992
|
args.composer.resumeFromDialog();
|
|
1993
|
+
releaseKeyboard();
|
|
1828
1994
|
}
|
|
1829
|
-
}
|
|
1995
|
+
},
|
|
1996
|
+
async withKeyboard(body) {
|
|
1997
|
+
claimKeyboard();
|
|
1998
|
+
try {
|
|
1999
|
+
return await body();
|
|
2000
|
+
} finally {
|
|
2001
|
+
releaseKeyboard();
|
|
2002
|
+
}
|
|
2003
|
+
},
|
|
2004
|
+
isKeyboardClaimed: () => keyboardClaimed
|
|
1830
2005
|
};
|
|
1831
2006
|
}
|
|
1832
2007
|
|
|
@@ -1852,13 +2027,14 @@ function formatUnassignedFact(snapshot) {
|
|
|
1852
2027
|
}
|
|
1853
2028
|
function sanitizeRunSnapshotForNormal(snapshot) {
|
|
1854
2029
|
const clean = (value) => stripAnsi(value).replace(/[\r\n]+/g, " ").replace(/\s+/g, " ").trim();
|
|
2030
|
+
const errorMessage = snapshot.errorMessage?.trim() ? redactSecrets(clean(snapshot.errorMessage)) : void 0;
|
|
1855
2031
|
return {
|
|
1856
2032
|
...snapshot,
|
|
1857
2033
|
agentName: snapshot.agentName ? clean(snapshot.agentName) : snapshot.agentName,
|
|
1858
2034
|
taskPreview: snapshot.taskPreview ? clean(snapshot.taskPreview) : snapshot.taskPreview,
|
|
1859
2035
|
lastAssistantText: snapshot.lastAssistantText ? clean(snapshot.lastAssistantText) : snapshot.lastAssistantText,
|
|
1860
2036
|
lastToolNames: snapshot.lastToolNames?.map(clean).filter(Boolean),
|
|
1861
|
-
errorMessage
|
|
2037
|
+
errorMessage,
|
|
1862
2038
|
logLines: void 0
|
|
1863
2039
|
};
|
|
1864
2040
|
}
|
|
@@ -1899,9 +2075,10 @@ function formatAgentRunPanelLines(snapshot, colorEnabled, now = Date.now()) {
|
|
|
1899
2075
|
const progressPart = formatPanelProgress(snapshot, now);
|
|
1900
2076
|
const age = formatTerminalRunAge(snapshot, now);
|
|
1901
2077
|
const agePart = age ? ` \xB7 ${age}` : "";
|
|
2078
|
+
const creditsPart = typeof snapshot.credits === "number" && Number.isFinite(snapshot.credits) ? ` \xB7 ${formatCreditsChip(snapshot.credits)}` : "";
|
|
1902
2079
|
if (!colorEnabled) {
|
|
1903
2080
|
lines.push(
|
|
1904
|
-
`\u{1F916} Sub-Agent: ${name}${runId} \xB7 ${statusSymbol} ${status}${unassignedPart}${agePart}${progressPart}${errPart}`
|
|
2081
|
+
`\u{1F916} Sub-Agent: ${name}${runId} \xB7 ${statusSymbol} ${status}${unassignedPart}${agePart}${progressPart}${creditsPart}${errPart}`
|
|
1905
2082
|
);
|
|
1906
2083
|
} else {
|
|
1907
2084
|
const botIcon = themeText("\u{1F916}", "accent", true);
|
|
@@ -1911,8 +2088,9 @@ function formatAgentRunPanelLines(snapshot, colorEnabled, now = Date.now()) {
|
|
|
1911
2088
|
const unassignedText = unassignedPart ? themeText(unassignedPart, "muted") : "";
|
|
1912
2089
|
const ageText = agePart ? themeText(agePart, "chrome") : "";
|
|
1913
2090
|
const progressText = progressPart ? themeText(progressPart, "chrome") : "";
|
|
2091
|
+
const creditsText = creditsPart ? themeText(creditsPart, "muted") : "";
|
|
1914
2092
|
const errorText = errPart ? themeText(errPart, "danger") : "";
|
|
1915
|
-
lines.push(`${botIcon}${labelText}${nameText}${statusText}${unassignedText}${ageText}${progressText}${errorText}`);
|
|
2093
|
+
lines.push(`${botIcon}${labelText}${nameText}${statusText}${unassignedText}${ageText}${progressText}${creditsText}${errorText}`);
|
|
1916
2094
|
}
|
|
1917
2095
|
const detail = formatPanelDetail(snapshot);
|
|
1918
2096
|
if (detail) {
|
|
@@ -2036,8 +2214,7 @@ function createRunDock(deps) {
|
|
|
2036
2214
|
const ordered = orderedEntries();
|
|
2037
2215
|
if (ordered.length === 0) return [];
|
|
2038
2216
|
const at = now();
|
|
2039
|
-
const
|
|
2040
|
-
const displaySnapshots = mode === "normal" || mode === "hide" ? ordered.map((entry) => sanitizeRunSnapshotForNormal(entry.snapshot)) : ordered.map((entry) => entry.snapshot);
|
|
2217
|
+
const displaySnapshots = ordered.map((entry) => sanitizeRunSnapshotForNormal(entry.snapshot));
|
|
2041
2218
|
if (displaySnapshots.length === 1) {
|
|
2042
2219
|
return formatAgentRunPanelLines(displaySnapshots[0], colorEnabled, at);
|
|
2043
2220
|
}
|
|
@@ -2109,6 +2286,9 @@ function formatRunDockRow(snapshot, colorEnabled, now) {
|
|
|
2109
2286
|
if (typeof snapshot.toolCallCount === "number" && Number.isFinite(snapshot.toolCallCount)) {
|
|
2110
2287
|
facts.push(`${snapshot.toolCallCount} tools`);
|
|
2111
2288
|
}
|
|
2289
|
+
if (typeof snapshot.credits === "number" && Number.isFinite(snapshot.credits)) {
|
|
2290
|
+
facts.push(formatCreditsChip(snapshot.credits, { compact: true }));
|
|
2291
|
+
}
|
|
2112
2292
|
const inFlight = activeInFlight(snapshot);
|
|
2113
2293
|
if (inFlight) {
|
|
2114
2294
|
facts.push(formatInFlightFact(inFlight, now));
|
|
@@ -2211,8 +2391,7 @@ function createActivityIndicator(deps) {
|
|
|
2211
2391
|
onRepaint: deps.onRepaint,
|
|
2212
2392
|
now,
|
|
2213
2393
|
setIntervalFn,
|
|
2214
|
-
clearIntervalFn
|
|
2215
|
-
displayMode: deps.displayMode
|
|
2394
|
+
clearIntervalFn
|
|
2216
2395
|
});
|
|
2217
2396
|
const updateAgentRun = (snapshot) => {
|
|
2218
2397
|
runDock.update(snapshot);
|
|
@@ -2296,6 +2475,8 @@ function snapshotFromRunRecord(record, now) {
|
|
|
2296
2475
|
...startedAt !== void 0 ? { startedAt } : {},
|
|
2297
2476
|
...endedAt !== void 0 ? { finishedAt: endedAt } : {},
|
|
2298
2477
|
...typeof counters?.toolCalls === "number" ? { toolCallCount: counters.toolCalls } : {},
|
|
2478
|
+
// 收尾自报的平台积分 → dock 行「⚡ x.xx 积分」。
|
|
2479
|
+
...typeof record.credits === "number" && Number.isFinite(record.credits) ? { credits: record.credits } : {},
|
|
2299
2480
|
// note 在终态时是死因("orphaned: process gone…"),非终态时只是备注。
|
|
2300
2481
|
...record.note && isAgentRunTerminalStatus(record.status) ? { errorMessage: record.note } : {},
|
|
2301
2482
|
inFlight,
|
|
@@ -2310,6 +2491,7 @@ function fingerprint(snapshot) {
|
|
|
2310
2491
|
snapshot.toolCallCount ?? -1,
|
|
2311
2492
|
snapshot.errorMessage ?? "",
|
|
2312
2493
|
snapshot.finishedAt ?? 0,
|
|
2494
|
+
snapshot.credits ?? -1,
|
|
2313
2495
|
snapshot.inFlight ? [snapshot.inFlight.kind, snapshot.inFlight.name, snapshot.inFlight.startedAt] : null
|
|
2314
2496
|
]);
|
|
2315
2497
|
}
|
|
@@ -3726,6 +3908,12 @@ function renderComposerTokenChip(tokens, fallbackContextWindow, estimatedContext
|
|
|
3726
3908
|
const pctText = pct > 0 && pct < 10 ? pct.toFixed(1) : Math.round(pct).toString();
|
|
3727
3909
|
return `context: ${pctText}% (${formatTokenCount(used)}/${formatTokenCount(cw)})`;
|
|
3728
3910
|
}
|
|
3911
|
+
function resolveStatusLineCredits(state) {
|
|
3912
|
+
const base = state.dialogCreditsBase;
|
|
3913
|
+
const session = state.sessionCredits;
|
|
3914
|
+
if (base === void 0 && session === void 0) return void 0;
|
|
3915
|
+
return (base ?? 0) + (session ?? 0);
|
|
3916
|
+
}
|
|
3729
3917
|
function renderStatusLine(state, maxWidth) {
|
|
3730
3918
|
const colorEnabled = resolveCliColorEnabled();
|
|
3731
3919
|
const sep = themeText(" \xB7 ", "chrome", colorEnabled);
|
|
@@ -3742,18 +3930,19 @@ function renderStatusLine(state, maxWidth) {
|
|
|
3742
3930
|
const untrackedText = untracked > 0 ? ` ${themeText(`?${untracked}`, "muted", colorEnabled)}` : "";
|
|
3743
3931
|
parts.push(`${branchText}${modifiedText}${untrackedText}`);
|
|
3744
3932
|
}
|
|
3745
|
-
const credits = state
|
|
3746
|
-
const creditsSuffix = credits !== void 0 && credits > 0 ? ` \xB7 \u26A1 ${credits.toFixed(2)} \u79EF\u5206` : "";
|
|
3933
|
+
const credits = resolveStatusLineCredits(state);
|
|
3747
3934
|
const tokenSegment = themeText(
|
|
3748
3935
|
renderComposerTokenChip(
|
|
3749
3936
|
state.turnTokens,
|
|
3750
3937
|
state.contextWindow,
|
|
3751
3938
|
state.estimatedContextTokens
|
|
3752
|
-
)
|
|
3939
|
+
),
|
|
3753
3940
|
"muted",
|
|
3754
3941
|
colorEnabled
|
|
3755
3942
|
);
|
|
3943
|
+
const creditsSegment = credits !== void 0 && credits > 0 ? themeText(formatCreditsChip(credits), "muted", colorEnabled) : "";
|
|
3756
3944
|
parts.push(tokenSegment);
|
|
3945
|
+
if (creditsSegment) parts.push(creditsSegment);
|
|
3757
3946
|
const runningTaskCount = getProcessRegistry().listBackground().filter((p) => p.status === "running").length;
|
|
3758
3947
|
if (runningTaskCount > 0) {
|
|
3759
3948
|
parts.push(themeText(`\u2699 ${runningTaskCount} running`, "info", colorEnabled));
|
|
@@ -3764,7 +3953,8 @@ function renderStatusLine(state, maxWidth) {
|
|
|
3764
3953
|
let visibleParts = parts;
|
|
3765
3954
|
if (maxWidth && maxWidth > 0) {
|
|
3766
3955
|
const widthOf = (segments) => displayWidth(stripAnsi(segments.join(" \xB7 "))) + 2;
|
|
3767
|
-
for (const optional of [
|
|
3956
|
+
for (const optional of [cwdSegment, agentSegment, tokenSegment, creditsSegment]) {
|
|
3957
|
+
if (!optional) continue;
|
|
3768
3958
|
if (widthOf(visibleParts) <= maxWidth) break;
|
|
3769
3959
|
visibleParts = visibleParts.filter((part) => part !== optional);
|
|
3770
3960
|
}
|
|
@@ -3797,6 +3987,9 @@ function renderStatusLine(state, maxWidth) {
|
|
|
3797
3987
|
colorEnabled
|
|
3798
3988
|
));
|
|
3799
3989
|
}
|
|
3990
|
+
if (creditsSegment) {
|
|
3991
|
+
emergency.push(themeText(formatCreditsChip(credits ?? 0, { compact: true }), "muted", colorEnabled));
|
|
3992
|
+
}
|
|
3800
3993
|
visibleParts = [emergency.join(" ")];
|
|
3801
3994
|
}
|
|
3802
3995
|
}
|
|
@@ -3927,6 +4120,20 @@ function renderTuiHelp(colorEnabled = resolveCliColorEnabled()) {
|
|
|
3927
4120
|
return themeText(line, "muted", colorEnabled);
|
|
3928
4121
|
}).join("\n");
|
|
3929
4122
|
}
|
|
4123
|
+
function renderCreditsDebug(state, colorEnabled = resolveCliColorEnabled()) {
|
|
4124
|
+
const credits = resolveStatusLineCredits(state);
|
|
4125
|
+
const lines = [
|
|
4126
|
+
"[credits debug] \u79EF\u5206\u94FE\u8DEF\u771F\u503C",
|
|
4127
|
+
`\u2022 dialogCreditsBase : ${state.dialogCreditsBase?.toFixed(4) ?? "undefined\uFF08\u670D\u52A1\u7AEF\u57FA\u6570\u672A seed\u2014\u2014/pick \u540E\u9996\u6B21\u8BFB\u53D6\u5931\u8D25\u6216\u670D\u52A1\u7AEF\u672A\u5199 totalCost\uFF09"}`,
|
|
4128
|
+
`\u2022 sessionCredits : ${state.sessionCredits?.toFixed(4) ?? "undefined\uFF08\u672C\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u5E73\u53F0\u8BA1\u8D39\u8F6E\uFF09"}`,
|
|
4129
|
+
`\u2022 \u72B6\u6001\u884C\u663E\u793A : ${credits !== void 0 && credits > 0 ? formatCreditsChip(credits) : "\uFF08\u65E0 \u26A1\u2014\u2014\u4E24\u6BB5\u5408\u8BA1\u4E3A 0/undefined\uFF09"}`,
|
|
4130
|
+
`\u2022 turnTokens.credits: ${state.turnTokens?.credits?.toFixed(4) ?? "undefined"}\uFF08\u672C\u8F6E\u6700\u540E\u4E00\u6B21\u8C03\u7528\u7684\u6298\u7B97\u503C\uFF0C\u4EC5\u4F9B\u53C2\u8003\uFF0C\u4E0D\u8FDB\u72B6\u6001\u884C\uFF09`,
|
|
4131
|
+
`\u2022 contextWindow : ${state.contextWindow ?? "unknown"}`,
|
|
4132
|
+
'\u2022 \u5224\u5B9A\u53E3\u5F84\uFF1A\u53EA\u6709 billing_unit === "credits" \u7684\u5E73\u53F0\u8BA1\u8D39\u5E27\u624D\u7D2F\u8BA1\uFF1B\u81EA\u6709 API / \u8BA2\u9605\u5236\u6052\u4E3A undefined\u3002',
|
|
4133
|
+
"\u2022 \u82E5\u521A\u8DD1\u5B8C\u5E73\u53F0\u8BA1\u8D39\u8F6E\u4ECD\u65E0 \u26A1\uFF1A\u68C0\u67E5 runAgentTurn \u8FD4\u56DE\u662F\u5426\u5E26 turnCredits\uFF08foldLocalResultForTui \u767D\u540D\u5355\uFF09\u3002"
|
|
4134
|
+
];
|
|
4135
|
+
return lines.map((line) => colorEnabled ? themeText(line, "chrome") : line).join("\n");
|
|
4136
|
+
}
|
|
3930
4137
|
function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
|
|
3931
4138
|
const docs = state.attachedDocs.length ? state.attachedDocs.join(", ") : "none";
|
|
3932
4139
|
const skills = state.attachedSkills.length ? state.attachedSkills.join(", ") : "none";
|
|
@@ -3938,7 +4145,6 @@ function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
|
|
|
3938
4145
|
t("contextFieldSkills"),
|
|
3939
4146
|
t("contextFieldProfile"),
|
|
3940
4147
|
t("contextFieldRuntime"),
|
|
3941
|
-
t("contextFieldTools"),
|
|
3942
4148
|
t("contextFieldServer")
|
|
3943
4149
|
];
|
|
3944
4150
|
let maxW = 0;
|
|
@@ -3968,8 +4174,7 @@ function renderContextPanel(state, colorEnabled = resolveCliColorEnabled()) {
|
|
|
3968
4174
|
field(labels[4], skills),
|
|
3969
4175
|
field(labels[5], state.profileName),
|
|
3970
4176
|
field(labels[6], state.runtimeMode),
|
|
3971
|
-
field(labels[7], state.
|
|
3972
|
-
field(labels[8], state.serverUrl),
|
|
4177
|
+
field(labels[7], state.serverUrl),
|
|
3973
4178
|
"",
|
|
3974
4179
|
themeText(t("contextNext"), "chrome", colorEnabled),
|
|
3975
4180
|
next("/agents ", ` ${t("contextNextAgents")}`),
|
|
@@ -4226,6 +4431,7 @@ var SLASH_COMMANDS = [
|
|
|
4226
4431
|
"/theme",
|
|
4227
4432
|
"/context",
|
|
4228
4433
|
"/ctx",
|
|
4434
|
+
"/credits",
|
|
4229
4435
|
"/cd",
|
|
4230
4436
|
"/runtime",
|
|
4231
4437
|
"/auto",
|
|
@@ -4395,7 +4601,6 @@ async function runAgentPicker(args) {
|
|
|
4395
4601
|
name: selected.name,
|
|
4396
4602
|
key: selected.key,
|
|
4397
4603
|
model: selected.model,
|
|
4398
|
-
apiSource: selected.apiSource ?? (selected.kind === "platform" ? "platform" : void 0),
|
|
4399
4604
|
entries
|
|
4400
4605
|
};
|
|
4401
4606
|
}
|
|
@@ -4407,10 +4612,7 @@ function resolveAgentSwitchTarget(rawTarget, catalogEntries = []) {
|
|
|
4407
4612
|
return {
|
|
4408
4613
|
name: aliasEntry?.name ?? asTrimmedLowercaseString(target),
|
|
4409
4614
|
key: resolvedKey,
|
|
4410
|
-
...aliasEntry?.model ? { model: aliasEntry.model } : {}
|
|
4411
|
-
...aliasEntry ? {
|
|
4412
|
-
...aliasEntry.apiSource ? { apiSource: aliasEntry.apiSource } : aliasEntry.kind === "platform" ? { apiSource: "platform" } : {}
|
|
4413
|
-
} : {}
|
|
4615
|
+
...aliasEntry?.model ? { model: aliasEntry.model } : {}
|
|
4414
4616
|
};
|
|
4415
4617
|
}
|
|
4416
4618
|
return findAgentCatalogEntry(catalogEntries, rawTarget);
|
|
@@ -4528,7 +4730,6 @@ function createInitialTuiState(env = process.env) {
|
|
|
4528
4730
|
modeLabel: asOptionalTrimmedString(env.NOLO_CLI_STATUS_MODE) ?? runtimeMode,
|
|
4529
4731
|
userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
|
|
4530
4732
|
gitStatus: void 0,
|
|
4531
|
-
toolDisplay: normalizeToolDisplayMode(env.NOLO_CLI_TOOLS ?? env.NOLO_TOOLS, "normal"),
|
|
4532
4733
|
thinkingDisplay: resolveThinkingDisplayMode(env),
|
|
4533
4734
|
contextWindow: resolveAgentContextWindow({ agentKey, agentName }),
|
|
4534
4735
|
estimatedContextTokens: estimateDefaultCliContextTokens({
|
|
@@ -4536,8 +4737,7 @@ function createInitialTuiState(env = process.env) {
|
|
|
4536
4737
|
agentKey,
|
|
4537
4738
|
userLanguage: asOptionalTrimmedString(env.NOLO_LANG),
|
|
4538
4739
|
...resolveAgentModelIdentity({ agentKey, agentName })
|
|
4539
|
-
})
|
|
4540
|
-
apiSource: PLATFORM_AGENTS.some((entry) => entry.key === agentKey) ? "platform" : void 0
|
|
4740
|
+
})
|
|
4541
4741
|
};
|
|
4542
4742
|
}
|
|
4543
4743
|
function applyAgentSwitch(state, target) {
|
|
@@ -4558,8 +4758,7 @@ function applyAgentSwitch(state, target) {
|
|
|
4558
4758
|
agentName: target.name,
|
|
4559
4759
|
model: target.model,
|
|
4560
4760
|
userLanguage: state.userLanguage
|
|
4561
|
-
})
|
|
4562
|
-
apiSource: target.apiSource
|
|
4761
|
+
})
|
|
4563
4762
|
},
|
|
4564
4763
|
output: `Switched to ${target.name}. ${state.dialogId ? `Dialog kept: ${state.dialogId}` : "Dialog kept: new"}`
|
|
4565
4764
|
};
|
|
@@ -4703,6 +4902,8 @@ ${t("cdUsage")}`
|
|
|
4703
4902
|
case "/context":
|
|
4704
4903
|
case "/ctx":
|
|
4705
4904
|
return { nextState: state, output: renderContextPanel(state) };
|
|
4905
|
+
case "/credits":
|
|
4906
|
+
return { nextState: state, output: renderCreditsDebug(state) };
|
|
4706
4907
|
case "/runtime": {
|
|
4707
4908
|
if (argText !== "auto" && argText !== "local" && argText !== "server") {
|
|
4708
4909
|
return {
|
|
@@ -5199,9 +5400,106 @@ function detectSystemBrightness(env = process.env, options = {}) {
|
|
|
5199
5400
|
return null;
|
|
5200
5401
|
}
|
|
5201
5402
|
|
|
5202
|
-
// packages/cli/tui/
|
|
5203
|
-
|
|
5403
|
+
// packages/cli/tui/turnInjectionInbox.ts
|
|
5404
|
+
function appendStreamSafeNotice(history, text, deps) {
|
|
5405
|
+
const wasStreamingAssistant = history.currentRole === "assistant";
|
|
5406
|
+
if (wasStreamingAssistant && !history.currentContent) {
|
|
5407
|
+
history.currentRole = null;
|
|
5408
|
+
history.currentBlocks = [];
|
|
5409
|
+
}
|
|
5410
|
+
deps.appendLocalTurn(history, "", text);
|
|
5411
|
+
if (wasStreamingAssistant) deps.startTurn(history, "assistant");
|
|
5412
|
+
}
|
|
5413
|
+
function createTurnInjectionInbox() {
|
|
5414
|
+
let pending = [];
|
|
5415
|
+
let closed = false;
|
|
5416
|
+
return {
|
|
5417
|
+
push(entry) {
|
|
5418
|
+
if (closed) return false;
|
|
5419
|
+
if (!entry || typeof entry.text !== "string" || !entry.text.trim()) return false;
|
|
5420
|
+
pending.push(entry);
|
|
5421
|
+
return true;
|
|
5422
|
+
},
|
|
5423
|
+
drain() {
|
|
5424
|
+
if (pending.length === 0) return [];
|
|
5425
|
+
const taken = pending;
|
|
5426
|
+
pending = [];
|
|
5427
|
+
return taken.map((entry) => entry.text);
|
|
5428
|
+
},
|
|
5429
|
+
close() {
|
|
5430
|
+
closed = true;
|
|
5431
|
+
const remaining = pending;
|
|
5432
|
+
pending = [];
|
|
5433
|
+
return remaining;
|
|
5434
|
+
},
|
|
5435
|
+
get size() {
|
|
5436
|
+
return pending.length;
|
|
5437
|
+
},
|
|
5438
|
+
get closed() {
|
|
5439
|
+
return closed;
|
|
5440
|
+
}
|
|
5441
|
+
};
|
|
5442
|
+
}
|
|
5443
|
+
|
|
5444
|
+
// packages/cli/client/turnBillingAudit.ts
|
|
5445
|
+
import { appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
5446
|
+
import { homedir as homedir4 } from "node:os";
|
|
5204
5447
|
import { join as join3 } from "node:path";
|
|
5448
|
+
function projectUsageForAudit(usage) {
|
|
5449
|
+
if (!usage || typeof usage !== "object") return null;
|
|
5450
|
+
const normalized = normalizeUsage(usage);
|
|
5451
|
+
const projected = {
|
|
5452
|
+
input_tokens: normalized.input_tokens,
|
|
5453
|
+
output_tokens: normalized.output_tokens,
|
|
5454
|
+
cache_read_input_tokens: normalized.cache_read_input_tokens,
|
|
5455
|
+
cache_creation_input_tokens: normalized.cache_creation_input_tokens
|
|
5456
|
+
};
|
|
5457
|
+
if (typeof usage.cost === "number" && Number.isFinite(usage.cost)) {
|
|
5458
|
+
projected.cost = usage.cost;
|
|
5459
|
+
}
|
|
5460
|
+
if (typeof usage.billing_unit === "string" && usage.billing_unit.trim()) {
|
|
5461
|
+
projected.billing_unit = usage.billing_unit;
|
|
5462
|
+
}
|
|
5463
|
+
if (typeof usage.provider_call_id === "string" && usage.provider_call_id.trim()) {
|
|
5464
|
+
projected.provider_call_id = usage.provider_call_id.trim();
|
|
5465
|
+
}
|
|
5466
|
+
return projected;
|
|
5467
|
+
}
|
|
5468
|
+
function resolveTurnBillingAuditLogPath(env = process.env) {
|
|
5469
|
+
const noloHome = env.NOLO_HOME?.trim() || join3(homedir4(), ".nolo");
|
|
5470
|
+
return join3(noloHome, "logs", "turn-billing.jsonl");
|
|
5471
|
+
}
|
|
5472
|
+
function appendTurnBillingAudit(input) {
|
|
5473
|
+
try {
|
|
5474
|
+
if (process.env.NOLO_TURN_BILLING_AUDIT === "0") return;
|
|
5475
|
+
const calls = (input.usageRecords ?? []).map((record) => {
|
|
5476
|
+
const usage = projectUsageForAudit(record?.usage);
|
|
5477
|
+
if (!usage) return null;
|
|
5478
|
+
return {
|
|
5479
|
+
...record?.callId ? { callId: record.callId } : {},
|
|
5480
|
+
...record?.model ? { model: record.model } : {},
|
|
5481
|
+
...record?.provider ? { provider: record.provider } : {},
|
|
5482
|
+
...usage
|
|
5483
|
+
};
|
|
5484
|
+
}).filter((call) => call !== null);
|
|
5485
|
+
if (calls.length === 0 && (input.turnCredits === void 0 || input.turnCredits === null)) {
|
|
5486
|
+
return;
|
|
5487
|
+
}
|
|
5488
|
+
const row = {
|
|
5489
|
+
ts: Date.now(),
|
|
5490
|
+
...input.dialogId ? { dialogId: input.dialogId } : {},
|
|
5491
|
+
...input.agentKey ? { agentKey: input.agentKey } : {},
|
|
5492
|
+
...input.turnCredits !== void 0 && input.turnCredits !== null ? { turnCredits: input.turnCredits } : {},
|
|
5493
|
+
...input.aborted ? { aborted: true } : {},
|
|
5494
|
+
calls
|
|
5495
|
+
};
|
|
5496
|
+
const logPath = resolveTurnBillingAuditLogPath();
|
|
5497
|
+
mkdirSync2(join3(logPath, ".."), { recursive: true });
|
|
5498
|
+
appendFileSync(logPath, `${JSON.stringify(row)}
|
|
5499
|
+
`);
|
|
5500
|
+
} catch {
|
|
5501
|
+
}
|
|
5502
|
+
}
|
|
5205
5503
|
|
|
5206
5504
|
// packages/ai/tools/askChoiceState.ts
|
|
5207
5505
|
function normalizeAskChoiceArgs(args) {
|
|
@@ -5980,24 +6278,6 @@ function emitTerminalBell(output) {
|
|
|
5980
6278
|
}
|
|
5981
6279
|
|
|
5982
6280
|
// packages/cli/tui/tuiTurnRunner.ts
|
|
5983
|
-
var AGENTS_MD_MAX_BYTES = 8192;
|
|
5984
|
-
function readAgentsMdLayer(cwd) {
|
|
5985
|
-
for (const name of ["AGENTS.md", "CLAUDE.md"]) {
|
|
5986
|
-
const filePath = join3(cwd, name);
|
|
5987
|
-
if (existsSync3(filePath)) {
|
|
5988
|
-
try {
|
|
5989
|
-
let content = readFileSync3(filePath, "utf8").trim();
|
|
5990
|
-
if (!content) continue;
|
|
5991
|
-
if (Buffer.byteLength(content, "utf8") > AGENTS_MD_MAX_BYTES) {
|
|
5992
|
-
content = Buffer.from(content, "utf8").subarray(0, AGENTS_MD_MAX_BYTES).toString("utf8") + "\n\n<!-- AGENTS.md truncated -->";
|
|
5993
|
-
}
|
|
5994
|
-
return buildAgentsMdLayer(content, name);
|
|
5995
|
-
} catch {
|
|
5996
|
-
}
|
|
5997
|
-
}
|
|
5998
|
-
}
|
|
5999
|
-
return null;
|
|
6000
|
-
}
|
|
6001
6281
|
async function runAgentChat(scriptDir, state, message, env, output, agentRunner = runAgentTurn, options = {}) {
|
|
6002
6282
|
const effectiveAgentKey = state.agentKey;
|
|
6003
6283
|
const effectiveAgentName = state.agentName;
|
|
@@ -6042,12 +6322,16 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
6042
6322
|
}
|
|
6043
6323
|
}
|
|
6044
6324
|
const layers = [
|
|
6045
|
-
|
|
6325
|
+
readAgentsMdLayerFromDisk(state.cwd),
|
|
6046
6326
|
// Skill discovery: scan conventional skill dirs for SKILL.md and inject an
|
|
6047
6327
|
// index layer so the model knows what skills exist and can readFile them
|
|
6048
6328
|
// on-demand. Mirrors agentRunCommand.ts and desktopAgentRuntimeTurnService.
|
|
6049
6329
|
buildSkillDiscoveryContextLayer(state.cwd)
|
|
6050
6330
|
];
|
|
6331
|
+
const responseGuidelinesBlock = {
|
|
6332
|
+
content: buildResponseGuidelines(true),
|
|
6333
|
+
cacheScope: "session"
|
|
6334
|
+
};
|
|
6051
6335
|
let memoryPromptBlock = state.cachedMemoryOverlay;
|
|
6052
6336
|
if (memoryPromptBlock === void 0) {
|
|
6053
6337
|
memoryPromptBlock = await resolveCliMemory({
|
|
@@ -6063,6 +6347,7 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
6063
6347
|
const cwdNoticeBlocks = state.pendingCwdNotice ? [{ content: state.pendingCwdNotice, cacheScope: "turn" }] : [];
|
|
6064
6348
|
const contextBlockScopes = partitionScopedBlocks([
|
|
6065
6349
|
...renderTurnContextBlocksWithScope(layers),
|
|
6350
|
+
responseGuidelinesBlock,
|
|
6066
6351
|
...renderTurnContextBlocksWithScope([memoryUseGuidanceLayer]),
|
|
6067
6352
|
// Attached skill bodies are already self-contained sections built by
|
|
6068
6353
|
// buildSkillContextBlocks; they stay turn-scope because the user can
|
|
@@ -6071,6 +6356,7 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
6071
6356
|
...renderTurnContextBlocksWithScope([memoryOverlayLayer]),
|
|
6072
6357
|
...cwdNoticeBlocks
|
|
6073
6358
|
]);
|
|
6359
|
+
const spawnedRunsMissingParent = [];
|
|
6074
6360
|
const result = await agentRunner({
|
|
6075
6361
|
agentName: effectiveAgentName,
|
|
6076
6362
|
agentKey: effectiveAgentKey,
|
|
@@ -6088,10 +6374,12 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
6088
6374
|
scriptDir,
|
|
6089
6375
|
env: {
|
|
6090
6376
|
...env,
|
|
6091
|
-
NOLO_LANG: state.userLanguage
|
|
6092
|
-
|
|
6377
|
+
NOLO_LANG: state.userLanguage
|
|
6378
|
+
},
|
|
6379
|
+
output: {
|
|
6380
|
+
...output,
|
|
6381
|
+
tuiTrees: output.tuiTrees === true && typeof output.writeToolBlock === "function"
|
|
6093
6382
|
},
|
|
6094
|
-
output,
|
|
6095
6383
|
showThinking: state.thinkingDisplay === "show",
|
|
6096
6384
|
...options.imageUrls && options.imageUrls.length > 0 ? { imageUrls: options.imageUrls } : {},
|
|
6097
6385
|
...options.actionGateHandler ? { actionGateHandler: options.actionGateHandler } : {},
|
|
@@ -6115,15 +6403,28 @@ async function runAgentChat(scriptDir, state, message, env, output, agentRunner
|
|
|
6115
6403
|
// run-completion watcher can attribute terminal-state wakes to this
|
|
6116
6404
|
// conversation.
|
|
6117
6405
|
...state.dialogId ? { parentDialogId: state.dialogId } : {},
|
|
6406
|
+
// 首轮无 dialogId 时的兜底:收集失归属的 spawn,turn 结束回填。
|
|
6407
|
+
onBackgroundRunSpawned: (runId) => {
|
|
6408
|
+
spawnedRunsMissingParent.push(runId);
|
|
6409
|
+
},
|
|
6118
6410
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {}
|
|
6119
6411
|
}),
|
|
6120
6412
|
...options.activityReporter ? { activityReporter: options.activityReporter } : {},
|
|
6121
6413
|
// 转发 dock 订阅:runAgentTurn 的输出层靠它判断「有面板」从而抑制
|
|
6122
6414
|
// transcript 的进展卡片;dock 本身也靠它接收模型轮询带回来的快照。
|
|
6123
6415
|
...options.onAgentRunStatus ? { onAgentRunStatus: options.onAgentRunStatus } : {},
|
|
6416
|
+
...options.drainInjections ? { drainInjections: options.drainInjections } : {},
|
|
6124
6417
|
...skillAllowedTools !== void 0 ? { allowedToolNames: skillAllowedTools } : {},
|
|
6125
6418
|
...contextBlockScopes.length > 0 ? { contextBlockScopes } : {}
|
|
6126
6419
|
});
|
|
6420
|
+
if (result.dialogId && spawnedRunsMissingParent.length > 0) {
|
|
6421
|
+
for (const runId of spawnedRunsMissingParent) {
|
|
6422
|
+
try {
|
|
6423
|
+
backfillRunRecordParentDialog(runId, result.dialogId, { env });
|
|
6424
|
+
} catch {
|
|
6425
|
+
}
|
|
6426
|
+
}
|
|
6427
|
+
}
|
|
6127
6428
|
return {
|
|
6128
6429
|
...result,
|
|
6129
6430
|
contextWindow: resolveAgentContextWindow({
|
|
@@ -6366,19 +6667,21 @@ async function resolveActionGate(gate, deps) {
|
|
|
6366
6667
|
);
|
|
6367
6668
|
return approved ? buildGateConfirmedResult(gate) : buildGateCancelledResult(gate, "confirmation declined");
|
|
6368
6669
|
}
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6670
|
+
return deps.dialogHost.withKeyboard(async () => {
|
|
6671
|
+
let subprocessRan = false;
|
|
6672
|
+
deps.pauseComposer();
|
|
6673
|
+
try {
|
|
6674
|
+
return await waitForRawActionGate(deps.input, deps.output, gate, deps.spawnRunner, {
|
|
6675
|
+
beforeSubprocess: () => {
|
|
6676
|
+
subprocessRan = true;
|
|
6677
|
+
},
|
|
6678
|
+
afterSubprocess: deps.resumeComposerFromSubprocess,
|
|
6679
|
+
registerToken: deps.registerToken
|
|
6680
|
+
});
|
|
6681
|
+
} finally {
|
|
6682
|
+
if (!subprocessRan) deps.resumeComposerFromDialog();
|
|
6683
|
+
}
|
|
6684
|
+
});
|
|
6382
6685
|
}
|
|
6383
6686
|
async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, confirmDestructiveAction) {
|
|
6384
6687
|
const scheduleTitlePatchSync = (runResult) => {
|
|
@@ -6451,7 +6754,6 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6451
6754
|
ctx.scheduleRender();
|
|
6452
6755
|
}) : ctx.output;
|
|
6453
6756
|
const requestUserChoice = isInteractiveInput(ctx.input) && ctx.dialogHost ? async (choiceReq) => {
|
|
6454
|
-
ctx.modalOwnsKeyboard = true;
|
|
6455
6757
|
try {
|
|
6456
6758
|
return await ctx.dialogHost.run(
|
|
6457
6759
|
(anchor) => runAskChoiceDialog({
|
|
@@ -6463,12 +6765,11 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6463
6765
|
);
|
|
6464
6766
|
} catch {
|
|
6465
6767
|
return { kind: "cancelled" };
|
|
6466
|
-
} finally {
|
|
6467
|
-
ctx.composerDecoderDrain?.();
|
|
6468
|
-
ctx.modalOwnsKeyboard = false;
|
|
6469
6768
|
}
|
|
6470
6769
|
} : void 0;
|
|
6471
6770
|
ctx.runRegistryPoller.beginHold();
|
|
6771
|
+
const injectionInbox = createTurnInjectionInbox();
|
|
6772
|
+
ctx.turnInjectionInbox = injectionInbox;
|
|
6472
6773
|
try {
|
|
6473
6774
|
ctx.activeTurnAbort = new AbortController();
|
|
6474
6775
|
ctx.activeTurnEpoch = myEpoch;
|
|
@@ -6485,6 +6786,7 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6485
6786
|
...confirmDestructiveAction ? { confirmDestructiveAction } : {},
|
|
6486
6787
|
...requestUserChoice ? { requestUserChoice } : {},
|
|
6487
6788
|
abortSignal: ctx.activeTurnAbort.signal,
|
|
6789
|
+
drainInjections: () => injectionInbox.drain(),
|
|
6488
6790
|
pastedTextStore: ctx.pasteStore,
|
|
6489
6791
|
activityReporter: ctx.activityReporter,
|
|
6490
6792
|
onAgentRunStatus: (snapshot) => {
|
|
@@ -6514,10 +6816,14 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6514
6816
|
// 本轮已发起 agent 调用(消息已注入),消费切换通知。
|
|
6515
6817
|
pendingCwdNotice: void 0
|
|
6516
6818
|
};
|
|
6517
|
-
if (runResult.dialogId && nextDialogKey) {
|
|
6518
|
-
ctx.refreshDialogTotalCredits(runResult.dialogId, nextDialogKey);
|
|
6519
|
-
}
|
|
6520
6819
|
}
|
|
6820
|
+
ctx.accumulateSessionCredits(runResult.turnCredits);
|
|
6821
|
+
appendTurnBillingAudit({
|
|
6822
|
+
dialogId: runResult.dialogId ?? null,
|
|
6823
|
+
turnCredits: runResult.turnCredits ?? null,
|
|
6824
|
+
usageRecords: runResult.usageRecords,
|
|
6825
|
+
aborted: true
|
|
6826
|
+
});
|
|
6521
6827
|
scheduleTitlePatchSync(runResult);
|
|
6522
6828
|
return { ok: false, aborted: true };
|
|
6523
6829
|
}
|
|
@@ -6566,10 +6872,16 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6566
6872
|
// 而非纯 child-run-completed 事件短路)时才清除。
|
|
6567
6873
|
pendingCwdNotice: void 0
|
|
6568
6874
|
};
|
|
6569
|
-
if (runResult.dialogId && nextDialogKey) {
|
|
6570
|
-
ctx.refreshDialogTotalCredits(runResult.dialogId, nextDialogKey);
|
|
6571
|
-
}
|
|
6572
6875
|
}
|
|
6876
|
+
ctx.accumulateSessionCredits(runResult.turnCredits);
|
|
6877
|
+
appendTurnBillingAudit({
|
|
6878
|
+
dialogId: runResult.dialogId ?? null,
|
|
6879
|
+
turnCredits: runResult.turnCredits ?? null,
|
|
6880
|
+
usageRecords: runResult.usageRecords,
|
|
6881
|
+
// 普通中断(Esc)同样属于「账照记、轮未正常收尾」,审计行标注出来,
|
|
6882
|
+
// 与 1028 行 forceStop 路径及正常完成轮区分开。
|
|
6883
|
+
...wasAborted || runResult.streamInterrupted ? { aborted: true } : {}
|
|
6884
|
+
});
|
|
6573
6885
|
scheduleTitlePatchSync(runResult);
|
|
6574
6886
|
if (!wasAborted && runResult.exitCode !== 0) {
|
|
6575
6887
|
if (isBalanceExhaustedError(runResult.localError) && runResult.dialogId) {
|
|
@@ -6587,6 +6899,21 @@ async function runOneAgentTurn(ctx, inputMsg, imageUrls, actionGateHandler, conf
|
|
|
6587
6899
|
ctx.runRegistryPoller.endHold();
|
|
6588
6900
|
ctx.activityIndicator.stop();
|
|
6589
6901
|
ctx.activeTurnAbort = null;
|
|
6902
|
+
if (ctx.turnInjectionInbox === injectionInbox) ctx.turnInjectionInbox = null;
|
|
6903
|
+
const leftover = injectionInbox.close();
|
|
6904
|
+
if (leftover.length > 0) {
|
|
6905
|
+
const binding = ensureChatQueueBinding(
|
|
6906
|
+
ctx,
|
|
6907
|
+
actionGateHandler,
|
|
6908
|
+
confirmDestructiveAction
|
|
6909
|
+
);
|
|
6910
|
+
for (const entry of leftover) {
|
|
6911
|
+
try {
|
|
6912
|
+
binding.enqueue(entry.fallback);
|
|
6913
|
+
} catch {
|
|
6914
|
+
}
|
|
6915
|
+
}
|
|
6916
|
+
}
|
|
6590
6917
|
}
|
|
6591
6918
|
}
|
|
6592
6919
|
function ensureChatQueueBinding(ctx, actionGateHandler, confirmDestructiveAction) {
|
|
@@ -7659,7 +7986,7 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
7659
7986
|
emitCommandOutput,
|
|
7660
7987
|
renderHistoryToOutput,
|
|
7661
7988
|
scheduleRender,
|
|
7662
|
-
|
|
7989
|
+
seedDialogCreditsBase,
|
|
7663
7990
|
persistExplicitAgentSwitch,
|
|
7664
7991
|
persistAgentSelection: persistAgentSelection2,
|
|
7665
7992
|
writeClipboard: writeClipboard2,
|
|
@@ -7707,8 +8034,10 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
7707
8034
|
host.state = {
|
|
7708
8035
|
...host.state,
|
|
7709
8036
|
turnTokens: void 0,
|
|
7710
|
-
//
|
|
7711
|
-
|
|
8037
|
+
// 新对话的积分累计从 0 重新开始:既清掉旧对话的本会话累加,也清掉旧对话
|
|
8038
|
+
// 的历史基数(新对话没有历史)。
|
|
8039
|
+
sessionCredits: void 0,
|
|
8040
|
+
dialogCreditsBase: void 0,
|
|
7712
8041
|
cachedMemoryOverlay: void 0,
|
|
7713
8042
|
// 新对话重新加载记忆
|
|
7714
8043
|
estimatedContextTokens: estimateDefaultCliContextTokens({
|
|
@@ -7758,9 +8087,10 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
7758
8087
|
// composer chip falls back to the default CLI surface estimate and
|
|
7759
8088
|
// the context percentage visibly drops. Mirrors the /clear reset.
|
|
7760
8089
|
turnTokens: void 0,
|
|
7761
|
-
// compact fork 出新的官方 dialog
|
|
7762
|
-
//
|
|
7763
|
-
|
|
8090
|
+
// compact fork 出新的官方 dialog,计费从新记录开始累计;新 dialog 没有
|
|
8091
|
+
// 历史基数,本会话累加也随之归零。
|
|
8092
|
+
sessionCredits: void 0,
|
|
8093
|
+
dialogCreditsBase: void 0,
|
|
7764
8094
|
cachedMemoryOverlay: void 0,
|
|
7765
8095
|
// compact 创建新 dialog,重新加载记忆
|
|
7766
8096
|
estimatedContextTokens: estimateDefaultCliContextTokens({
|
|
@@ -7875,7 +8205,6 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
7875
8205
|
model: pickResult.model,
|
|
7876
8206
|
userLanguage: host.state.userLanguage
|
|
7877
8207
|
}),
|
|
7878
|
-
...pickResult.apiSource ? { apiSource: pickResult.apiSource } : {},
|
|
7879
8208
|
cachedMemoryOverlay: void 0
|
|
7880
8209
|
// 切换 agent 后重新加载记忆
|
|
7881
8210
|
};
|
|
@@ -7992,13 +8321,14 @@ async function runSubmittedSlashLine(line, host, actionGateHandler, confirmDestr
|
|
|
7992
8321
|
dialogLabel: pickResult.dialog.title || pickResult.dialog.id,
|
|
7993
8322
|
dialogTitle: pickResult.dialog.title,
|
|
7994
8323
|
turnTokens: void 0,
|
|
7995
|
-
//
|
|
8324
|
+
// 切换对话先清空上一个对话的积分,等下面异步 seed 成功后回填历史基数;
|
|
7996
8325
|
// 若读取失败也不至于把旧对话的累计值残留显示在状态行。
|
|
7997
|
-
|
|
8326
|
+
sessionCredits: void 0,
|
|
8327
|
+
dialogCreditsBase: void 0,
|
|
7998
8328
|
cachedMemoryOverlay: void 0
|
|
7999
8329
|
// 切换对话后重新加载记忆
|
|
8000
8330
|
};
|
|
8001
|
-
|
|
8331
|
+
seedDialogCreditsBase(pickResult.dialog.id, pickResult.dialog.dbKey);
|
|
8002
8332
|
clearCollapsedPasteStore(pasteStore);
|
|
8003
8333
|
emitCommandOutput(
|
|
8004
8334
|
`${t("resumedDialogPrefix")}: ${pickResult.dialog.title} (${pickResult.dialog.id})`
|
|
@@ -8275,7 +8605,6 @@ async function runTuiWorkspace(options) {
|
|
|
8275
8605
|
isTurnActive: () => activeTurnAbort !== null,
|
|
8276
8606
|
fallbackLabel: () => `${state.agentName} -> working`,
|
|
8277
8607
|
stoppingLabel: () => t("turnStopping"),
|
|
8278
|
-
displayMode: () => state.toolDisplay,
|
|
8279
8608
|
onRepaint: () => {
|
|
8280
8609
|
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
8281
8610
|
output.write("\x1B[?2026h\x1B[?25l");
|
|
@@ -8319,7 +8648,14 @@ async function runTuiWorkspace(options) {
|
|
|
8319
8648
|
getInputLines: () => fixedInput.getInputLines(),
|
|
8320
8649
|
isPaused: () => fixedInput.isPaused()
|
|
8321
8650
|
},
|
|
8322
|
-
output
|
|
8651
|
+
output,
|
|
8652
|
+
// The decoder-drain hook is only bound once the interactive raw-mode
|
|
8653
|
+
// composer installs its decoder (inside the `isInteractiveInput` block
|
|
8654
|
+
// below); the non-raw readline path never binds it, so this stays a
|
|
8655
|
+
// no-op there — which is correct, that path has no raw decoder to drain.
|
|
8656
|
+
drainDecoder: () => {
|
|
8657
|
+
if (composerDecoderDrain) composerDecoderDrain();
|
|
8658
|
+
}
|
|
8323
8659
|
});
|
|
8324
8660
|
let sessionEnded = false;
|
|
8325
8661
|
const selectionState = createSelectionState();
|
|
@@ -8348,7 +8684,7 @@ async function runTuiWorkspace(options) {
|
|
|
8348
8684
|
const repaintBanner = () => {
|
|
8349
8685
|
if (!output.isTTY) return;
|
|
8350
8686
|
if (fixedInput.isPaused()) return;
|
|
8351
|
-
if (
|
|
8687
|
+
if (dialogHost.isKeyboardClaimed()) return;
|
|
8352
8688
|
const currentColumns = output.columns ?? 80;
|
|
8353
8689
|
const welcome = renderWelcome(state, 0, 0, currentColumns);
|
|
8354
8690
|
const lines = welcome.split("\n");
|
|
@@ -8397,9 +8733,8 @@ async function runTuiWorkspace(options) {
|
|
|
8397
8733
|
selectionState.anchor = null;
|
|
8398
8734
|
selectionState.head = null;
|
|
8399
8735
|
};
|
|
8400
|
-
let modalOwnsKeyboard = false;
|
|
8401
8736
|
let rawActionGateTokenHandler = null;
|
|
8402
|
-
const
|
|
8737
|
+
const seedDialogCreditsBase = (dialogId, dialogKey) => {
|
|
8403
8738
|
const env = options.env ?? process.env;
|
|
8404
8739
|
const authToken = resolvePlatformAuthToken(env);
|
|
8405
8740
|
if (!authToken) return;
|
|
@@ -8411,14 +8746,19 @@ async function runTuiWorkspace(options) {
|
|
|
8411
8746
|
}).then((record) => {
|
|
8412
8747
|
if (sessionEnded) return;
|
|
8413
8748
|
if (state.dialogId !== dialogId) return;
|
|
8749
|
+
if (state.sessionCredits !== void 0) return;
|
|
8414
8750
|
const recordObj = record && typeof record === "object" ? record : null;
|
|
8415
8751
|
const totalCost = recordObj ? Number(recordObj?.totalCost) : NaN;
|
|
8416
8752
|
if (Number.isFinite(totalCost) && totalCost >= 0) {
|
|
8417
|
-
state = { ...state,
|
|
8753
|
+
state = { ...state, dialogCreditsBase: totalCost };
|
|
8418
8754
|
}
|
|
8419
8755
|
}).catch(() => {
|
|
8420
8756
|
});
|
|
8421
8757
|
};
|
|
8758
|
+
const accumulateSessionCredits = (credits) => {
|
|
8759
|
+
if (credits === void 0 || !Number.isFinite(credits)) return;
|
|
8760
|
+
state = { ...state, sessionCredits: (state.sessionCredits ?? 0) + credits };
|
|
8761
|
+
};
|
|
8422
8762
|
let composerDecoderDrain = null;
|
|
8423
8763
|
const emitCommandOutput = (text, command = "") => {
|
|
8424
8764
|
if (!text) return;
|
|
@@ -8433,6 +8773,7 @@ async function runTuiWorkspace(options) {
|
|
|
8433
8773
|
if (fixedInput.active) fixedInput.repaint(buffer, cursorPos);
|
|
8434
8774
|
};
|
|
8435
8775
|
let chatQueueBinding = null;
|
|
8776
|
+
let turnInjectionInbox = null;
|
|
8436
8777
|
const turnCtx = {
|
|
8437
8778
|
get state() {
|
|
8438
8779
|
return state;
|
|
@@ -8470,24 +8811,18 @@ async function runTuiWorkspace(options) {
|
|
|
8470
8811
|
set activeTurnEpoch(v) {
|
|
8471
8812
|
activeTurnEpoch = v;
|
|
8472
8813
|
},
|
|
8473
|
-
get modalOwnsKeyboard() {
|
|
8474
|
-
return modalOwnsKeyboard;
|
|
8475
|
-
},
|
|
8476
|
-
set modalOwnsKeyboard(v) {
|
|
8477
|
-
modalOwnsKeyboard = v;
|
|
8478
|
-
},
|
|
8479
|
-
get composerDecoderDrain() {
|
|
8480
|
-
return composerDecoderDrain;
|
|
8481
|
-
},
|
|
8482
|
-
set composerDecoderDrain(v) {
|
|
8483
|
-
composerDecoderDrain = v;
|
|
8484
|
-
},
|
|
8485
8814
|
get chatQueueBinding() {
|
|
8486
8815
|
return chatQueueBinding;
|
|
8487
8816
|
},
|
|
8488
8817
|
set chatQueueBinding(v) {
|
|
8489
8818
|
chatQueueBinding = v;
|
|
8490
8819
|
},
|
|
8820
|
+
get turnInjectionInbox() {
|
|
8821
|
+
return turnInjectionInbox;
|
|
8822
|
+
},
|
|
8823
|
+
set turnInjectionInbox(v) {
|
|
8824
|
+
turnInjectionInbox = v;
|
|
8825
|
+
},
|
|
8491
8826
|
get sessionEnded() {
|
|
8492
8827
|
return sessionEnded;
|
|
8493
8828
|
},
|
|
@@ -8515,7 +8850,8 @@ async function runTuiWorkspace(options) {
|
|
|
8515
8850
|
renderHistoryToOutput,
|
|
8516
8851
|
scheduleRender,
|
|
8517
8852
|
flushPendingRender,
|
|
8518
|
-
|
|
8853
|
+
seedDialogCreditsBase,
|
|
8854
|
+
accumulateSessionCredits,
|
|
8519
8855
|
emitCommandOutput
|
|
8520
8856
|
};
|
|
8521
8857
|
const persistExplicitAgentSwitch = (previousAgentKey) => {
|
|
@@ -8554,7 +8890,7 @@ async function runTuiWorkspace(options) {
|
|
|
8554
8890
|
emitCommandOutput,
|
|
8555
8891
|
renderHistoryToOutput,
|
|
8556
8892
|
scheduleRender,
|
|
8557
|
-
|
|
8893
|
+
seedDialogCreditsBase,
|
|
8558
8894
|
persistExplicitAgentSwitch,
|
|
8559
8895
|
persistAgentSelection,
|
|
8560
8896
|
writeClipboard: writeClipboard2,
|
|
@@ -8669,47 +9005,33 @@ async function runTuiWorkspace(options) {
|
|
|
8669
9005
|
input.setRawMode?.(false);
|
|
8670
9006
|
};
|
|
8671
9007
|
const buildInteractiveTurnHandlers = () => {
|
|
8672
|
-
const releaseKeyboardToComposer = () => {
|
|
8673
|
-
onData.destroy();
|
|
8674
|
-
modalOwnsKeyboard = false;
|
|
8675
|
-
};
|
|
8676
9008
|
const actionGateHandler = async (gate) => {
|
|
8677
9009
|
if (state.autoConfirm && isAutoConfirmableFileWriteGate(gate)) {
|
|
8678
9010
|
return buildGateConfirmedResult(gate);
|
|
8679
9011
|
}
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
|
|
8693
|
-
});
|
|
8694
|
-
} finally {
|
|
8695
|
-
releaseKeyboardToComposer();
|
|
8696
|
-
}
|
|
9012
|
+
return await resolveActionGate(gate, {
|
|
9013
|
+
dialogHost,
|
|
9014
|
+
input,
|
|
9015
|
+
output,
|
|
9016
|
+
spawnRunner,
|
|
9017
|
+
registerToken: (handler) => {
|
|
9018
|
+
rawActionGateTokenHandler = handler;
|
|
9019
|
+
},
|
|
9020
|
+
pauseComposer: () => fixedInput.pause(),
|
|
9021
|
+
resumeComposerFromSubprocess: () => fixedInput.resumeFromSubprocess(),
|
|
9022
|
+
resumeComposerFromDialog: () => fixedInput.resumeFromDialog()
|
|
9023
|
+
});
|
|
8697
9024
|
};
|
|
8698
9025
|
const confirmDestructiveAction = async (request) => {
|
|
8699
9026
|
if (state.autoConfirm) return true;
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
})
|
|
8709
|
-
);
|
|
8710
|
-
} finally {
|
|
8711
|
-
releaseKeyboardToComposer();
|
|
8712
|
-
}
|
|
9027
|
+
return await dialogHost.run(
|
|
9028
|
+
(anchor) => runConfirmDialog({
|
|
9029
|
+
request,
|
|
9030
|
+
input,
|
|
9031
|
+
output,
|
|
9032
|
+
...anchor
|
|
9033
|
+
})
|
|
9034
|
+
);
|
|
8713
9035
|
};
|
|
8714
9036
|
return { actionGateHandler, confirmDestructiveAction };
|
|
8715
9037
|
};
|
|
@@ -8742,11 +9064,30 @@ ${err.message}` : ""}`
|
|
|
8742
9064
|
flushPendingRender();
|
|
8743
9065
|
fixedInput.exitOutputMode(buffer, cursorPos);
|
|
8744
9066
|
};
|
|
9067
|
+
(options.env ?? process.env)[RUN_WAKE_CHANNEL_ENV] = "1";
|
|
8745
9068
|
runWakeHandler = (event) => {
|
|
8746
9069
|
if (done) return;
|
|
8747
9070
|
if (busy || fixedInput.isPaused()) {
|
|
8748
|
-
const
|
|
8749
|
-
|
|
9071
|
+
const text = typeof event === "string" ? event : event.text;
|
|
9072
|
+
const injected = !!turnInjectionInbox && turnInjectionInbox.push({ text, fallback: event });
|
|
9073
|
+
if (injected) {
|
|
9074
|
+
const displayText = typeof event !== "string" && event.kind === "child-run-completed" ? event.displayText ?? event.text : text;
|
|
9075
|
+
const noticeLine = dimCliText(displayText, resolveCliColorEnabled());
|
|
9076
|
+
if (!isInteractiveInput(input)) {
|
|
9077
|
+
output.write(`${noticeLine}
|
|
9078
|
+
`);
|
|
9079
|
+
} else {
|
|
9080
|
+
history.followBottom = true;
|
|
9081
|
+
appendStreamSafeNotice(history, noticeLine, {
|
|
9082
|
+
appendLocalTurn,
|
|
9083
|
+
startTurn
|
|
9084
|
+
});
|
|
9085
|
+
renderHistoryToOutput();
|
|
9086
|
+
}
|
|
9087
|
+
} else {
|
|
9088
|
+
const { actionGateHandler, confirmDestructiveAction } = buildInteractiveTurnHandlers();
|
|
9089
|
+
ensureChatQueueBinding(turnCtx, actionGateHandler, confirmDestructiveAction).enqueue(event);
|
|
9090
|
+
}
|
|
8750
9091
|
if (fixedInput.active && !fixedInput.isPaused()) {
|
|
8751
9092
|
fixedInput.repaint(buffer, cursorPos);
|
|
8752
9093
|
}
|
|
@@ -8924,7 +9265,7 @@ ${hint}` : hint;
|
|
|
8924
9265
|
};
|
|
8925
9266
|
const handleInputToken = async (sequence) => {
|
|
8926
9267
|
if (done) return;
|
|
8927
|
-
if (
|
|
9268
|
+
if (dialogHost.isKeyboardClaimed()) {
|
|
8928
9269
|
rawActionGateTokenHandler?.(sequence);
|
|
8929
9270
|
return;
|
|
8930
9271
|
}
|