nolo-cli 0.54.0-alpha.1 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/{_executeModel-IVEOJ7L6.js → _executeModel-OPTKYHJA.js} +53 -48
  2. package/{action-IU6ON7ZB.js → action-ORXWW2ZG.js} +9 -9
  3. package/{addContentAction-5V5CCI3I.js → addContentAction-53BZ34AE.js} +9 -8
  4. package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-JRYUS54Y.js} +11 -10
  5. package/{agentDeleteCommand-D7AFLKQN.js → agentDeleteCommand-FJIWU2BS.js} +31 -29
  6. package/{agentEmailCommands-MXFZGF54.js → agentEmailCommands-CE32L43B.js} +62 -58
  7. package/{agentListCommands-MP732Q23.js → agentListCommands-VJNKULIK.js} +43 -34
  8. package/{agentMachineCommands-352JFJX4.js → agentMachineCommands-HCJ3WQXL.js} +31 -29
  9. package/agentRecordCommands-QFWERED4.js +119 -0
  10. package/{agentRunCommand-UUWJMH7J.js → agentRunCommand-G3GQMUNN.js} +70 -59
  11. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-INKFDXDA.js} +3 -1
  12. package/{agentRuntimeLocal-KWBPJ53H.js → agentRuntimeLocal-K327ELSL.js} +31 -27
  13. package/{agentSlice-V742SNKC.js → agentSlice-ODKF4J6M.js} +9 -9
  14. package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-5AR3DKNN.js} +2 -2
  15. package/{appDeleteCommands-GV4TF52A.js → appDeleteCommands-XUXMFDI4.js} +32 -30
  16. package/{appDeployCommands-EZMUPNSW.js → appDeployCommands-37F4GPCU.js} +32 -30
  17. package/{appDeployStatusCommands-AAGELKAN.js → appDeployStatusCommands-WSPU7TUK.js} +32 -30
  18. package/{appGetCommands-W37KDAON.js → appGetCommands-YLOBA3EM.js} +32 -30
  19. package/{appListCommands-IFDWBBNV.js → appListCommands-UD62R5ME.js} +32 -30
  20. package/{authCommand-5HM57KPL.js → authCommand-OK6HLHGS.js} +13 -13
  21. package/{authCommands-SBQVTD6V.js → authCommands-2DUIUEMT.js} +2 -2
  22. package/{chatQueueReduxAdapter-ZXXP6E4O.js → chatQueueReduxAdapter-TV2TUOQS.js} +28 -25
  23. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  24. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  25. package/{chunk-2JYSSXLY.js → chunk-2WBFJHQA.js} +5 -27
  26. package/{chunk-FZMM2KZC.js → chunk-3LKZRP7E.js} +2 -2
  27. package/{chunk-WUMYQ2FE.js → chunk-3Y2K5O2R.js} +64 -6
  28. package/{chunk-5XCW6RQG.js → chunk-3ZTR7ZO4.js} +1 -1
  29. package/{chunk-W6N3GLUU.js → chunk-5FCIPEKT.js} +327 -149
  30. package/{chunk-B54WOZ77.js → chunk-5UAYZEXO.js} +2 -2
  31. package/{chunk-5SXS7T5Q.js → chunk-6COJEAYH.js} +36 -105
  32. package/{chunk-PEMGYJNS.js → chunk-6HDYSFLO.js} +4 -6
  33. package/{chunk-6XIE5ZGI.js → chunk-6HIGYUBQ.js} +1 -1
  34. package/chunk-6IGD47IC.js +19 -0
  35. package/chunk-6YTOJY35.js +352 -0
  36. package/{chunk-6FGXGFAH.js → chunk-75MSWWUE.js} +1 -1
  37. package/{chunk-ALMVQQPG.js → chunk-7FAS3NEF.js} +17 -17
  38. package/{chunk-76UA7376.js → chunk-7NYDJAQ7.js} +20 -15
  39. package/{chunk-2T6XO4PK.js → chunk-A65UV3M5.js} +4 -4
  40. package/{chunk-V2IPBG5U.js → chunk-AA564GBL.js} +2 -2
  41. package/{chunk-SQTVMYMU.js → chunk-AUVFJGPC.js} +4 -4
  42. package/{chunk-HR5XDXYM.js → chunk-BBTN4NQD.js} +4 -4
  43. package/{chunk-CULR4XB4.js → chunk-BG7J6Y5X.js} +1 -1
  44. package/chunk-BY2FF2C4.js +526 -0
  45. package/{chunk-FA4SY4F5.js → chunk-BYEJ7K2Z.js} +1 -1
  46. package/chunk-BYXBJQAS.js +0 -0
  47. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  48. package/{chunk-DIQCV4FR.js → chunk-EA5OYZVD.js} +1 -1
  49. package/{chunk-RO2IUWZE.js → chunk-EICIFHVS.js} +1 -1
  50. package/chunk-EJE33XNR.js +19059 -0
  51. package/{chunk-M2CGG6VJ.js → chunk-EVBFYPDC.js} +1 -1
  52. package/{chunk-KHCLMKZZ.js → chunk-EY7V7REW.js} +280 -6
  53. package/{chunk-MC66ASS6.js → chunk-FJHMLRDQ.js} +12 -12
  54. package/{chunk-YFHUQLJF.js → chunk-GRFK2XP4.js} +2 -2
  55. package/{chunk-J3UALFHL.js → chunk-HJTAGT3W.js} +1 -1
  56. package/{chunk-J7KVJAUQ.js → chunk-HPW5MNDQ.js} +38 -99
  57. package/{chunk-H2G6JXTR.js → chunk-HQUORJTM.js} +1 -1
  58. package/{chunk-OYNDYVSE.js → chunk-JON2PHYT.js} +1 -1
  59. package/{chunk-RBJD33HM.js → chunk-JXIP6ZWH.js} +7 -7
  60. package/{chunk-PTHLNXGY.js → chunk-K4NISKOR.js} +46 -8
  61. package/{chunk-5Y5G76BJ.js → chunk-KLIBF3BY.js} +2 -2
  62. package/chunk-LRGKOI5Y.js +297 -0
  63. package/{chunk-OU7NGN5Y.js → chunk-MLEZPE3U.js} +2 -2
  64. package/{chunk-4RXXP6WD.js → chunk-MYMBBB6Q.js} +5 -64
  65. package/{chunk-ET7BXWAW.js → chunk-N4JKMCY3.js} +2 -2
  66. package/{chunk-45E65JER.js → chunk-NFLA6GSU.js} +4 -4
  67. package/{chunk-SVEUG45B.js → chunk-NHRQCXIQ.js} +0 -24
  68. package/{chunk-WJV3G7BM.js → chunk-NJUQBYFJ.js} +3 -1
  69. package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
  70. package/{chunk-Q24S4NDF.js → chunk-Q4XZVZPN.js} +1 -1
  71. package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
  72. package/{chunk-VM7K5EJL.js → chunk-RHMDMTDK.js} +2 -2
  73. package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
  74. package/{chunk-WHVQA7PJ.js → chunk-SSXTSPSG.js} +27 -6
  75. package/chunk-SUEIAK5N.js +2574 -0
  76. package/{chunk-X7S7OFUX.js → chunk-SVC3GGUA.js} +6 -6
  77. package/{chunk-7UFH6THF.js → chunk-SVDMVX4G.js} +118 -2
  78. package/{chunk-ZMV5PCRS.js → chunk-SWJGJMTW.js} +1 -1
  79. package/{chunk-DQLYEGP7.js → chunk-SYYUU7EV.js} +2 -2
  80. package/{chunk-K7CNV7GI.js → chunk-TC6P4NDR.js} +7 -7
  81. package/{chunk-SUFDWBLV.js → chunk-TR4DXUYX.js} +1988 -452
  82. package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
  83. package/chunk-UAD2WT54.js +64 -0
  84. package/{chunk-HCBQVVFZ.js → chunk-UGBHDMHI.js} +4 -4
  85. package/{chunk-R63FNYSI.js → chunk-UOWXD4VN.js} +851 -970
  86. package/{chunk-GBXR3CSM.js → chunk-UR66XPVF.js} +3 -3
  87. package/{chunk-6BYAXNH5.js → chunk-VZMUOPYG.js} +12 -2
  88. package/{chunk-RVHPY5PC.js → chunk-WQHGJHAL.js} +441 -2982
  89. package/chunk-XIJZOCSP.js +1766 -0
  90. package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
  91. package/{chunk-BKPUPZ6W.js → chunk-YBFJQC2M.js} +95 -778
  92. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  93. package/{chunk-SG65C33A.js → chunk-YLCUU3WM.js} +4 -4
  94. package/{chunk-XXZULHJ7.js → chunk-YQBXOHE6.js} +1 -1
  95. package/chunk-ZJ7UHBJS.js +89 -0
  96. package/{chunk-TNPCQNGQ.js → chunk-ZVOHVJI3.js} +4 -9
  97. package/{codingSkills-BYQI6EPT.js → codingSkills-BCQXRZOI.js} +3 -4
  98. package/contentThunks-KNI6VXLT.js +71 -0
  99. package/{createAgentAutomationAction-LE3ZYDT6.js → createAgentAutomationAction-OK4L33KF.js} +29 -25
  100. package/createDialogAction-JDSMY4AY.js +62 -0
  101. package/{createPageAction-X4C7K3OD.js → createPageAction-T7RA3HCG.js} +32 -28
  102. package/{dbSlice-FWF5F4L7.js → dbSlice-TVX6SN2T.js} +7 -7
  103. package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
  104. package/{dialogCommands-CP2U44A7.js → dialogCommands-UQZYWOOV.js} +33 -31
  105. package/{dialogSlice-2SH5636X.js → dialogSlice-TYW2G7IL.js} +28 -25
  106. package/{docCreateCommands-A2KIJSF7.js → docCreateCommands-OA6HZBWO.js} +37 -36
  107. package/{docDeleteCommands-NZ7XO4Z4.js → docDeleteCommands-KBB3YQI2.js} +34 -33
  108. package/{docReadCommands-VWVK4ZAR.js → docReadCommands-ZLMFVC67.js} +33 -32
  109. package/{docStore-J6GQYKHS.js → docStore-2URPBVCS.js} +9 -34
  110. package/{docUpdateCommands-YTUEC6PN.js → docUpdateCommands-HMH5KUON.js} +37 -36
  111. package/{fetchMessages-KZQVBXKY.js → fetchMessages-DRABNDPZ.js} +3 -3
  112. package/{getPricing-I53UFOPH.js → getPricing-RFOPUWHY.js} +4 -4
  113. package/{handleSendMessageAction-MD325XZS.js → handleSendMessageAction-GO53TY7U.js} +30 -27
  114. package/index.js +67 -67
  115. package/{localDialogRead-NQ33HBSI.js → localDialogRead-PUQKFI73.js} +1 -1
  116. package/{machineCommands-TCNZV2DC.js → machineCommands-RK6L7ZWL.js} +64 -60
  117. package/{machineWsRunDispatch-QSX5IWPH.js → machineWsRunDispatch-3X64DW2Z.js} +59 -55
  118. package/memberThunks-THZYZFSN.js +638 -0
  119. package/{models-E2CYP4IB.js → models-JVKUEER5.js} +2 -2
  120. package/package.json +2 -3
  121. package/{read-J7RVVCHH.js → read-K4JU4MQC.js} +4 -4
  122. package/{readDocTool-G2WBM4IH.js → readDocTool-LQGR6FUN.js} +1 -1
  123. package/{readlineWorkspace-N3RGX7EK.js → readlineWorkspace-XUFJV3RS.js} +1005 -437
  124. package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-ECHCFB7N.js} +13 -12
  125. package/{runAgentClientLoop-R3NTOERA.js → runAgentClientLoop-24GQ2AW6.js} +51 -46
  126. package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-KCVJNGMB.js} +10 -9
  127. package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-VDOBOMKC.js} +13 -12
  128. package/{settingSlice-7NN2MI6Y.js → settingSlice-VR2IJSXC.js} +8 -8
  129. package/{skillDiscovery-COX56OBO.js → skillDiscovery-2QTZINON.js} +3 -4
  130. package/{spaceCommands-RC7XMYQ7.js → spaceCommands-S5YJJXL7.js} +31 -29
  131. package/{streamAgentChatTurn-WLWEBWSF.js → streamAgentChatTurn-QHKP3ABO.js} +82 -70
  132. package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-5L4UP7VI.js} +11 -10
  133. package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
  134. package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
  135. package/{tools-LSLDSUWU.js → tools-SSXSTC3O.js} +42 -38
  136. package/{tuiSummaryLlmCaller-TPBL4BV2.js → tuiSummaryLlmCaller-URFJHFC5.js} +19 -17
  137. package/{updateDialogTitleAction-4HJEARM7.js → updateDialogTitleAction-YFYAEW3T.js} +30 -26
  138. package/agentRecordCommands-G6EFHU3G.js +0 -115
  139. package/chunk-AETZ7AD6.js +0 -274
  140. package/chunk-DMCFF4KE.js +0 -435
  141. package/chunk-EUG45QJR.js +0 -6104
  142. package/chunk-J4Z6UI4C.js +0 -7076
  143. package/chunk-OFZPJ3NT.js +0 -114
  144. package/createDialogAction-2C6SR62D.js +0 -59
  145. package/spaceSlice-KBVKKO3M.js +0 -127
  146. package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
@@ -4,7 +4,7 @@ import {
4
4
  refreshAntigravityOAuthToken,
5
5
  refreshOpenAiCodexToken,
6
6
  xaiRefresh
7
- } from "./chunk-45E65JER.js";
7
+ } from "./chunk-NFLA6GSU.js";
8
8
  import {
9
9
  defaultLoopbackRequest
10
10
  } from "./chunk-EADNWBAZ.js";
@@ -18,7 +18,7 @@ import {
18
18
  } from "./chunk-NI2BS6UD.js";
19
19
  import {
20
20
  buildLocalAgentLookupKeys
21
- } from "./chunk-OYNDYVSE.js";
21
+ } from "./chunk-JON2PHYT.js";
22
22
  import {
23
23
  LOCAL_CODEX_AGENT_ID,
24
24
  LOCAL_CODEX_AGENT_KEY,
@@ -46,17 +46,17 @@ import {
46
46
  spawnLocalBackgroundRun,
47
47
  terminateRunProcess,
48
48
  withQueueLock
49
- } from "./chunk-WHVQA7PJ.js";
49
+ } from "./chunk-SSXTSPSG.js";
50
50
  import {
51
51
  inferCaptureIntent
52
- } from "./chunk-RO2IUWZE.js";
52
+ } from "./chunk-EICIFHVS.js";
53
53
  import {
54
54
  buildCliPrompt
55
55
  } from "./chunk-ATNTHIZI.js";
56
56
  import {
57
57
  inlineImageUrlsForCustomProvider,
58
58
  prepareTools
59
- } from "./chunk-VM7K5EJL.js";
59
+ } from "./chunk-RHMDMTDK.js";
60
60
  import {
61
61
  getServerProviderSecret
62
62
  } from "./chunk-HS7MLR74.js";
@@ -65,9 +65,13 @@ import {
65
65
  isAntigravityOAuthAgent,
66
66
  readAntigravityProjectId,
67
67
  resolveAntigravityCloudCodeBaseUrl
68
- } from "./chunk-CULR4XB4.js";
68
+ } from "./chunk-BG7J6Y5X.js";
69
69
  import {
70
+ CONTROL_AGENT_RUN_ACTIONS,
71
+ buildControlAgentRunFunctionSchema,
72
+ buildStartAgentRunFunctionSchema,
70
73
  deleteMemoryFunctionSchema,
74
+ queryMemoryFunctionSchema,
71
75
  readXPostFunc,
72
76
  readXPostFunctionSchema,
73
77
  readXhsProfileFunc,
@@ -75,7 +79,7 @@ import {
75
79
  rememberMemoryFunctionSchema,
76
80
  resolveAgentRequiredPackIds,
77
81
  setTodoListFunc
78
- } from "./chunk-SUFDWBLV.js";
82
+ } from "./chunk-TR4DXUYX.js";
79
83
  import {
80
84
  fetchWithTransientRetry,
81
85
  isTransientFetchError
@@ -98,13 +102,13 @@ import {
98
102
  prepareTokenUsageData,
99
103
  resolveBuiltinPlatformAgentConfig,
100
104
  runKeyed
101
- } from "./chunk-BKPUPZ6W.js";
105
+ } from "./chunk-YBFJQC2M.js";
102
106
  import {
103
107
  BUILTIN_TITLE_LLM_CONFIG
104
- } from "./chunk-M2CGG6VJ.js";
108
+ } from "./chunk-EVBFYPDC.js";
105
109
  import {
106
110
  fetchServerSyncedCredential
107
- } from "./chunk-K7CNV7GI.js";
111
+ } from "./chunk-TC6P4NDR.js";
108
112
  import {
109
113
  require_date_fns
110
114
  } from "./chunk-M76ECQRD.js";
@@ -120,8 +124,9 @@ import {
120
124
  applySystemBuiltinSkillFilter,
121
125
  expandEnabledPacks,
122
126
  resolveEffectiveEnabledPacks
123
- } from "./chunk-LGUQHYAL.js";
127
+ } from "./chunk-O5FLGN2L.js";
124
128
  import {
129
+ DEFAULT_HYBRID_READ_TIMEOUT_MS,
125
130
  aggregateResponsesStream,
126
131
  buildLoadSkillExecutor,
127
132
  buildLocalDialogWritePlan,
@@ -131,6 +136,7 @@ import {
131
136
  codexStreamFailureStatus,
132
137
  createHybridRecordStore,
133
138
  createLocalWorkspaceToolExecutors,
139
+ evaluateFileWritePolicy,
134
140
  executeLocalToolWithPolicy,
135
141
  executeOpenAiCompatibleChatCompletion,
136
142
  filterRetainedLedgerRecords,
@@ -143,10 +149,11 @@ import {
143
149
  parseSyncServersEnv,
144
150
  resolveOpenAiCompatibleProviderConfig,
145
151
  summarizeToolArguments
146
- } from "./chunk-J4Z6UI4C.js";
152
+ } from "./chunk-EJE33XNR.js";
147
153
  import {
148
154
  buildPlatformChatCompletionRequest,
149
155
  canUsePlatformChatProvider,
156
+ collectStablePromptPrefix,
150
157
  hasDirectOpenAiCompatibleProvider,
151
158
  parsePlatformChatCompletionData,
152
159
  parsePlatformChatCompletionResponse,
@@ -154,24 +161,25 @@ import {
154
161
  readSseDataValues,
155
162
  resolvePlatformChatProviderConfig,
156
163
  shouldUsePlatformChatProvider,
164
+ stablePromptCacheKey,
157
165
  streamSseDataValues
158
- } from "./chunk-WUMYQ2FE.js";
166
+ } from "./chunk-3Y2K5O2R.js";
159
167
  import {
160
168
  resolveAgentRuntimeConfigFromRecord,
161
169
  resolveHistoricalToolContentCap
162
- } from "./chunk-2T6XO4PK.js";
170
+ } from "./chunk-A65UV3M5.js";
163
171
  import {
164
172
  convertMessagesToResponsesInput,
165
173
  toResponsesTools
166
- } from "./chunk-6BYAXNH5.js";
174
+ } from "./chunk-VZMUOPYG.js";
167
175
  import {
168
176
  resolvePlatformAuthToken
169
- } from "./chunk-5Y5G76BJ.js";
177
+ } from "./chunk-KLIBF3BY.js";
170
178
  import {
171
179
  buildNoloWorkspaceOpenAiTools,
172
180
  parseNoloWorkspaceToolArguments,
173
181
  resolveRuntimeToolSurfaceForAgent
174
- } from "./chunk-TNPCQNGQ.js";
182
+ } from "./chunk-ZVOHVJI3.js";
175
183
  import {
176
184
  mergeAvailabilityDeadline,
177
185
  resolveAvailabilityAction,
@@ -183,25 +191,25 @@ import {
183
191
  } from "./chunk-2MBTWINN.js";
184
192
  import {
185
193
  clipCompactText
186
- } from "./chunk-HR5XDXYM.js";
194
+ } from "./chunk-BBTN4NQD.js";
195
+ import {
196
+ isAdaptiveThinkingModelId
197
+ } from "./chunk-SVDMVX4G.js";
198
+ import {
199
+ compactWhitespace
200
+ } from "./chunk-DWLEOOGR.js";
187
201
  import {
188
202
  createFileCredentialBroker,
189
203
  resolveCurrentRunRuntimeToolPolicy,
190
204
  resolveLocalWorkspaceExecutorOptionsFromPolicy,
191
205
  resolveRequestedRuntimeToolNames
192
- } from "./chunk-NQ4N4IGO.js";
206
+ } from "./chunk-CS6TCJ7E.js";
193
207
  import {
194
208
  createOAuthTokenStore,
195
209
  isTokenExpired,
196
210
  readOAuthCredential,
197
211
  resolveFreshAccessToken
198
212
  } from "./chunk-FD36SCCD.js";
199
- import {
200
- isAdaptiveThinkingModelId
201
- } from "./chunk-7UFH6THF.js";
202
- import {
203
- compactWhitespace
204
- } from "./chunk-DWLEOOGR.js";
205
213
  import {
206
214
  toErrorMessage
207
215
  } from "./chunk-HNMXYYJR.js";
@@ -215,15 +223,12 @@ import {
215
223
  import {
216
224
  DEFAULT_NOLO_SERVER_URL
217
225
  } from "./chunk-OLZBQWZU.js";
218
- import {
219
- PLATFORM_HOSTED_NEMOTRON_35_LIGHTNING_MODEL
220
- } from "./chunk-J7KVJAUQ.js";
221
226
  import {
222
227
  createTokenKey,
223
228
  createTokenStatsKey,
224
229
  createUserKey,
225
230
  dialogMessageRange
226
- } from "./chunk-SVEUG45B.js";
231
+ } from "./chunk-NHRQCXIQ.js";
227
232
  import {
228
233
  asTrimmedNonEmptyStringArray
229
234
  } from "./chunk-I42VC5KR.js";
@@ -232,7 +237,7 @@ import {
232
237
  } from "./chunk-QSJ3HFEF.js";
233
238
  import {
234
239
  isSystemBuiltinTrustedAgentKey
235
- } from "./chunk-2JYSSXLY.js";
240
+ } from "./chunk-2WBFJHQA.js";
236
241
  import {
237
242
  isRecord
238
243
  } from "./chunk-KUG52IAP.js";
@@ -307,6 +312,12 @@ function isSubtaskRun(env) {
307
312
  const value = env.NOLO_AGENT_RUN_CHILD;
308
313
  return typeof value === "string" && value.length > 0 && value !== "0";
309
314
  }
315
+ var RUN_WAKE_CHANNEL_ENV = "NOLO_RUN_WAKE";
316
+ function hasRunWakeChannel(env) {
317
+ if (!env) return false;
318
+ const value = env[RUN_WAKE_CHANNEL_ENV];
319
+ return typeof value === "string" && value.length > 0 && value !== "0";
320
+ }
310
321
  function filterToolNamesForRunKind(toolNames, isSubtask) {
311
322
  if (!isSubtask) return [...toolNames];
312
323
  return toolNames.filter((name) => !SUBTASK_REMOVED_TOOL_NAMES.has(name));
@@ -534,6 +545,11 @@ var STRINGS = {
534
545
  en: "Draft cleared.",
535
546
  zh: "\u8F93\u5165\u8349\u7A3F\u5DF2\u6E05\u7A7A\u3002"
536
547
  },
548
+ // 空草稿按 Backspace 逐个撤销附件(composer 附件条)。
549
+ attachmentRemovedHint: {
550
+ en: "Removed attachment {0}, {1} remaining",
551
+ zh: "\u5DF2\u79FB\u9664\u9644\u4EF6 {0}\uFF0C\u5269\u4F59 {1} \u5F20"
552
+ },
537
553
  historyNoToken: {
538
554
  en: "History requires an auth token. Run `nolo login` or set AUTH_TOKEN.",
539
555
  zh: "\u67E5\u770B\u5386\u53F2\u5BF9\u8BDD\u9700\u8981\u767B\u5F55\u51ED\u8BC1\u3002\u8BF7\u8FD0\u884C `nolo login` \u6216\u8BBE\u7F6E AUTH_TOKEN\u3002"
@@ -601,6 +617,10 @@ var STRINGS = {
601
617
  // --- Tool trace copy ------------------------------------------------------
602
618
  // The compact trace shows only status, never timing or output size: a line
603
619
  // count told the user nothing actionable and the ms figure read as noise.
620
+ thinkingTraceLine: {
621
+ en: "\u273B Thought for {0}",
622
+ zh: "\u273B \u601D\u8003 {0}"
623
+ },
604
624
  toolNeedsAction: {
605
625
  en: "needs action",
606
626
  zh: "\u5F85\u786E\u8BA4"
@@ -644,10 +664,6 @@ var STRINGS = {
644
664
  },
645
665
  // Normal-mode safe projection: the raw errorMessage/logLines of a failed run
646
666
  // stay in pro/verbose; normal mode names the failure and points at pro.
647
- runDiagnosticsHidden: {
648
- en: "run failed \u2014 full diagnostics in pro mode",
649
- zh: "\u8FD0\u884C\u5931\u8D25\u2014\u2014\u5B8C\u6574\u8BCA\u65AD\u89C1 pro \u6A21\u5F0F"
650
- },
651
667
  runsListLabel: {
652
668
  en: "Runs ({0})",
653
669
  zh: "\u8FD0\u884C ({0})"
@@ -803,10 +819,6 @@ var STRINGS = {
803
819
  en: "runtime",
804
820
  zh: "\u8FD0\u884C\u65F6"
805
821
  },
806
- contextFieldTools: {
807
- en: "tools",
808
- zh: "\u5DE5\u5177"
809
- },
810
822
  contextFieldServer: {
811
823
  en: "server",
812
824
  zh: "\u670D\u52A1\u7AEF"
@@ -842,9 +854,8 @@ var STRINGS = {
842
854
  " /new Clear screen and start a fresh dialog",
843
855
  " /compact Compact current dialog and fork a new one",
844
856
  " /context Show workspace context and next actions",
857
+ " /cd <path> Change the working directory (takes effect on the next turn)",
845
858
  " /runtime <mode> Use auto, local, or server runtime",
846
- " /tools <mode> Control tool trace: hide, compact, verbose",
847
- " /thinking <mode> Show or hide live model reasoning",
848
859
  " /switch Pick an agent interactively (\u2191\u2193, Enter)",
849
860
  " /switch list List agents as text",
850
861
  " /switch <name> Switch directly by name, alias, or key (alias: /agent)",
@@ -854,7 +865,7 @@ var STRINGS = {
854
865
  " /lang <zh|en> Switch interface language",
855
866
  ' /copy [all] Copy the last reply (or the full conversation with "all") to the clipboard',
856
867
  " /mouse <on|off> Toggle mouse mode (off = drag to select text)",
857
- " /auto <on|off> Toggle permission auto-approve (skip destructive-shell & external-file confirms)",
868
+ " /auto <on|off> Toggle permission auto-approve (skip destructive-shell, external-file & file-write confirms)",
858
869
  " /math <on|off> Toggle math formula rendering (Unicode transcription)",
859
870
  " /altscreen <on|off> Toggle the terminal alternate screen (default on; off shares shell scrollback)",
860
871
  " Shift+drag Select text natively even while mouse mode is on (terminal bypass)",
@@ -881,9 +892,8 @@ var STRINGS = {
881
892
  " /new \u6E05\u5C4F\u5E76\u5F00\u59CB\u65B0\u5BF9\u8BDD",
882
893
  " /compact \u538B\u7F29\u5F53\u524D\u5BF9\u8BDD\u5E76\u5206\u53C9\u51FA\u65B0\u5BF9\u8BDD",
883
894
  " /context \u67E5\u770B\u5DE5\u4F5C\u533A\u4E0A\u4E0B\u6587\u4E0E\u540E\u7EED\u64CD\u4F5C",
895
+ " /cd <path> \u5207\u6362\u5DE5\u4F5C\u76EE\u5F55\uFF08\u4E0B\u4E2A turn \u751F\u6548\uFF09",
884
896
  " /runtime <mode> \u5207\u6362 runtime\uFF1Aauto\u3001local\u3001server",
885
- " /tools <mode> \u5DE5\u5177\u8F68\u8FF9\u663E\u793A\uFF1Ahide\u3001compact\u3001verbose",
886
- " /thinking <mode> \u663E\u793A\u6216\u9690\u85CF\u6A21\u578B\u7684\u5B9E\u65F6\u601D\u8003\u8FC7\u7A0B",
887
897
  " /switch \u4EA4\u4E92\u5F0F\u9009\u62E9 agent\uFF08\u2191\u2193 \u79FB\u52A8\uFF0CEnter \u786E\u8BA4\uFF09",
888
898
  " /switch list \u4EE5\u6587\u672C\u5217\u51FA\u5168\u90E8 agent",
889
899
  " /switch <name> \u6309\u540D\u79F0\u3001\u522B\u540D\u6216 key \u76F4\u63A5\u5207\u6362\uFF08\u522B\u540D\uFF1A/agent\uFF09",
@@ -893,7 +903,7 @@ var STRINGS = {
893
903
  " /lang <zh|en> \u5207\u6362\u754C\u9762\u8BED\u8A00",
894
904
  " /copy [all] \u590D\u5236\u6700\u540E\u4E00\u6761\u56DE\u590D\u5230\u526A\u8D34\u677F\uFF08\u52A0 all \u590D\u5236\u5B8C\u6574\u5BF9\u8BDD\uFF09",
895
905
  " /mouse <on|off> \u5207\u6362\u9F20\u6807\u6A21\u5F0F\uFF08off \u540E\u53EF\u76F4\u63A5\u62D6\u9009\u6587\u672C\uFF09",
896
- " /auto <on|off> \u5207\u6362\u6743\u9650\u81EA\u52A8\u5316\uFF08\u81EA\u52A8\u653E\u884C\u7834\u574F\u6027 shell \u4E0E\u5916\u90E8\u6587\u4EF6\u786E\u8BA4\uFF09",
906
+ " /auto <on|off> \u5207\u6362\u6743\u9650\u81EA\u52A8\u5316\uFF08\u81EA\u52A8\u653E\u884C\u7834\u574F\u6027 shell\u3001\u5916\u90E8\u6587\u4EF6\u4E0E\u5199\u6587\u4EF6\u786E\u8BA4\uFF09",
897
907
  " /math <on|off> \u5207\u6362\u6570\u5B66\u516C\u5F0F\u6E32\u67D3\uFF08Unicode \u8F6C\u5199\uFF09",
898
908
  " /altscreen <on|off> \u5207\u6362\u7EC8\u7AEF\u5907\u7528\u5C4F\uFF08\u9ED8\u8BA4 on\uFF1Boff \u6539\u4E3A\u4E0E shell \u5171\u7528\u56DE\u6EDA\uFF09",
899
909
  " Shift+\u62D6\u62FD \u9F20\u6807\u6A21\u5F0F\u5F00\u542F\u65F6\u4E5F\u53EF\u539F\u751F\u9009\u4E2D\u6587\u672C\uFF08\u7EC8\u7AEF\u7ED5\u8FC7\u4FEE\u9970\u952E\uFF09",
@@ -924,21 +934,10 @@ var STRINGS = {
924
934
  },
925
935
  runtimeUsage: { en: "Usage: /runtime <auto|local|server>", zh: "\u7528\u6CD5\uFF1A/runtime <auto|local|server>" },
926
936
  runtimeSet: { en: "Runtime: {0}", zh: "\u8FD0\u884C\u6A21\u5F0F\uFF1A{0}" },
927
- toolsCurrent: {
928
- en: "Tool display: {0} (normal | pro | hide | verbose)",
929
- zh: "\u5DE5\u5177\u663E\u793A\uFF1A{0}\uFF08\u666E\u901A normal | \u4E13\u4E1A pro | hide | verbose\uFF09"
930
- },
931
- toolsUsage: { en: "Usage: /tools <normal|pro|hide|verbose>", zh: "\u7528\u6CD5\uFF1A/tools <normal|pro|hide|verbose>" },
932
- toolsSet: { en: "Tool display: {0}", zh: "\u5DE5\u5177\u663E\u793A\uFF1A{0}" },
933
- thinkingCurrent: {
934
- en: "Thinking display: {0} (show | hide)",
935
- zh: "\u601D\u8003\u663E\u793A\uFF1A{0}\uFF08show | hide\uFF09"
936
- },
937
- thinkingUsage: {
938
- en: "Usage: /thinking <show|hide>",
939
- zh: "\u7528\u6CD5\uFF1A/thinking <show|hide>"
937
+ displayFixedHint: {
938
+ en: "The TUI ships a single built-in tool display \u2014 no configuration needed. Thinking process visibility is still controlled independently via NOLO_CLI_THINKING=show|hide (applied on restart).",
939
+ zh: "TUI \u53EA\u6709\u4E00\u5957\u5185\u7F6E\u5DE5\u5177\u663E\u793A\uFF0C\u65E0\u9700\u914D\u7F6E\u3002\u601D\u8003\u8FC7\u7A0B\u4ECD\u53EF\u7528 NOLO_CLI_THINKING=show|hide \u72EC\u7ACB\u63A7\u5236\uFF08\u91CD\u542F\u751F\u6548\uFF09\u3002"
940
940
  },
941
- thinkingSet: { en: "Thinking display: {0}", zh: "\u601D\u8003\u663E\u793A\uFF1A{0}" },
942
941
  tasksRunning: { en: "Running processes ({0}):", zh: "\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\uFF08{0}\uFF09\uFF1A" },
943
942
  tasksStopped: { en: "Stopped/exited ({0}):", zh: "\u5DF2\u505C\u6B62/\u5DF2\u9000\u51FA\uFF08{0}\uFF09\uFF1A" },
944
943
  tasksNone: { en: "No processes.", zh: "\u6CA1\u6709\u8FD0\u884C\u4E2D\u7684\u8FDB\u7A0B\u3002" },
@@ -1011,14 +1010,18 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
1011
1010
  },
1012
1011
  themeSwitched: { en: "Switched to theme: {0}", zh: "\u5DF2\u5207\u6362\u5230\u4E3B\u9898\uFF1A{0}" },
1013
1012
  themeUnknown: { en: "Unknown theme: {0}. Available themes: {1}", zh: "\u672A\u77E5\u4E3B\u9898\uFF1A{0}\u3002\u53EF\u7528\u4E3B\u9898\uFF1A{1}" },
1014
- densityCurrent: {
1015
- en: "Current density: {0}\nUsage: /density <cozy|spacious>",
1016
- zh: "\u5F53\u524D\u5BC6\u5EA6\uFF1A{0}\n\u7528\u6CD5\uFF1A/density <cozy|spacious>"
1017
- },
1018
- densitySwitched: { en: "Switched to layout density: {0}", zh: "\u5DF2\u5207\u6362\u5230\u5E03\u5C40\u5BC6\u5EA6\uFF1A{0}" },
1019
- densityUnknown: {
1020
- en: "Unknown density: {0}. Use 'cozy' or 'spacious'.",
1021
- zh: "\u672A\u77E5\u5BC6\u5EA6\uFF1A{0}\u3002\u8BF7\u4F7F\u7528 cozy \u6216 spacious\u3002"
1013
+ cdUsage: {
1014
+ en: "Usage: /cd <path> (relative, absolute, ~, or -; takes effect on the next turn)",
1015
+ zh: "\u7528\u6CD5\uFF1A/cd <path>\uFF08\u76F8\u5BF9\u3001\u7EDD\u5BF9\u3001~ \u6216 - \u8DEF\u5F84\uFF1B\u4E0B\u4E2A turn \u751F\u6548\uFF09"
1016
+ },
1017
+ cdCurrent: { en: "Current directory: {0}", zh: "\u5F53\u524D\u76EE\u5F55\uFF1A{0}" },
1018
+ cdSwitched: { en: "Working directory: {0}", zh: "\u5DE5\u4F5C\u76EE\u5F55\uFF1A{0}" },
1019
+ cdNotFound: { en: "Directory not found: {0}", zh: "\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A{0}" },
1020
+ cdNotDir: { en: "Not a directory: {0}", zh: "\u4E0D\u662F\u76EE\u5F55\uFF1A{0}" },
1021
+ cdNoPrevious: { en: "No previous directory.", zh: "\u6CA1\u6709\u4E0A\u4E00\u4E2A\u76EE\u5F55\u3002" },
1022
+ cdSwitchedMessage: {
1023
+ en: "Working directory changed: {0} \u2192 {1}. Subsequent tool execution and file operations use the new directory.",
1024
+ zh: "\u5DE5\u4F5C\u76EE\u5F55\u5DF2\u5207\u6362\uFF1A{0} \u2192 {1}\u3002\u540E\u7EED\u5DE5\u5177\u6267\u884C\u4E0E\u6587\u4EF6\u64CD\u4F5C\u4EE5\u65B0\u76EE\u5F55\u4E3A\u51C6\u3002"
1022
1025
  },
1023
1026
  docAttachUsage: { en: "Usage: /doc attach <doc>", zh: "\u7528\u6CD5\uFF1A/doc attach <doc>" },
1024
1027
  docList: { en: "Attached docs: {0}", zh: "\u5DF2\u6302\u8F7D\u6587\u6863\uFF1A{0}" },
@@ -1078,6 +1081,7 @@ Use /switch, /switch list, /switch minimax-m3, or a full agent key.`,
1078
1081
  en: "Press Enter to run it now. Follow any prompts below, or Ctrl+C to cancel.",
1079
1082
  zh: "\u6309 Enter \u7ACB\u5373\u6267\u884C\uFF0C\u6309\u4E0B\u65B9\u63D0\u793A\u64CD\u4F5C\uFF0C\u6216\u6309 Ctrl+C \u53D6\u6D88\u3002"
1080
1083
  },
1084
+ actionGateConfirmHint: { en: "Enter=approve, n=cancel (or type y/yes).", zh: "Enter=\u6279\u51C6\uFF0Cn=\u53D6\u6D88\uFF08\u4E5F\u53EF\u8F93\u5165 y/yes\uFF09\u3002" },
1081
1085
  actionGateInteractiveTitle: {
1082
1086
  en: "This command requires an interactive terminal.",
1083
1087
  zh: "\u8BE5\u547D\u4EE4\u9700\u8981\u4EA4\u4E92\u5F0F\u7EC8\u7AEF"
@@ -1565,11 +1569,32 @@ function buildOpenAiTools(args) {
1565
1569
  }),
1566
1570
  ...buildServerPlatformOpenAiTools({ toolNames: args.toolNames }),
1567
1571
  ...buildNoloWorkspaceOpenAiTools({ toolNames: args.toolNames }),
1568
- ...prepareTools(
1569
- ["startAgentRun", "controlAgentRun"].filter((name) => toolNameSet.has(name))
1570
- )
1572
+ ...buildOrchestrationOpenAiTools({
1573
+ toolNameSet,
1574
+ env: args.env
1575
+ })
1571
1576
  ];
1572
1577
  }
1578
+ function buildOrchestrationOpenAiTools(args) {
1579
+ const names = ["startAgentRun", "controlAgentRun"].filter(
1580
+ (name) => args.toolNameSet.has(name)
1581
+ );
1582
+ if (names.length === 0) return [];
1583
+ const waitCapableActions = CONTROL_AGENT_RUN_ACTIONS.filter(
1584
+ (action) => action !== "wait"
1585
+ );
1586
+ const controlSchema = hasRunWakeChannel(args.env) ? buildControlAgentRunFunctionSchema({ actions: waitCapableActions }) : buildControlAgentRunFunctionSchema();
1587
+ const startSchema = buildStartAgentRunFunctionSchema({ supportsWait: false });
1588
+ return prepareTools(names).map((tool) => {
1589
+ if (tool?.function?.name === "controlAgentRun") {
1590
+ return { ...tool, function: controlSchema };
1591
+ }
1592
+ if (tool?.function?.name === "startAgentRun") {
1593
+ return { ...tool, function: startSchema };
1594
+ }
1595
+ return tool;
1596
+ });
1597
+ }
1573
1598
  var CLI_DEFAULT_TOOLS = ["exa_search", "fetchWebpage", "ask_user"];
1574
1599
  function addDefaultCliCoreTools(toolNames, env) {
1575
1600
  const declaredOnly = env && shouldUseDeclaredOnlyLocalWorkspaceTools(env);
@@ -1686,6 +1711,12 @@ function buildServerPlatformOpenAiTools(args) {
1686
1711
  function: rememberMemoryFunctionSchema
1687
1712
  }
1688
1713
  ] : [],
1714
+ ...toolNameSet.has("queryMemory") ? [
1715
+ {
1716
+ type: "function",
1717
+ function: queryMemoryFunctionSchema
1718
+ }
1719
+ ] : [],
1689
1720
  ...toolNameSet.has("deleteMemory") ? [
1690
1721
  {
1691
1722
  type: "function",
@@ -1751,7 +1782,8 @@ var resolveAnthropicOAuthTransport = async (ctx) => {
1751
1782
  });
1752
1783
  await recordLocalAvailability(result.status, result.body);
1753
1784
  if (result.status < 200 || result.status >= 300) {
1754
- const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
1785
+ const errorObj = result.body?.error;
1786
+ const errMsg = typeof errorObj?.message === "string" ? errorObj.message : JSON.stringify(result.body);
1755
1787
  throw new Error(
1756
1788
  `local Claude OAuth provider failed: HTTP ${result.status} ${errMsg}`
1757
1789
  );
@@ -1813,6 +1845,10 @@ var WIRE_PROFILES = {
1813
1845
  // The UI labels its effort variants (Low/Medium/High), but the literal
1814
1846
  // -medium/-high ids return 404 from streamGenerateContent.
1815
1847
  "gemini-3.7-flash-tiered": { modelEnum: "MODEL_PLACEHOLDER_M301", maxOutputTokens: 65536 },
1848
+ // Gemini 3.8 Flash 沿用 3.7 的 tiered 兼容策略:仓库内暂无 Antigravity discovery
1849
+ // 证据确认 3.8 的 wire modelEnum,禁止虚构,先只声明同档输出上限;enum 待
1850
+ // discovery 证据到位后补齐。
1851
+ "gemini-3.8-flash-tiered": { maxOutputTokens: 65536 },
1816
1852
  "gemini-3.6-flash-low": { maxOutputTokens: 65536 },
1817
1853
  "gemini-3.6-flash-medium": { maxOutputTokens: 65536 },
1818
1854
  "gemini-3.6-flash-high": { maxOutputTokens: 65536 },
@@ -1838,6 +1874,10 @@ function resolveAntigravityWireModel(logicalModelId) {
1838
1874
  const wireModelId = "gemini-3.7-flash-tiered";
1839
1875
  return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
1840
1876
  }
1877
+ if (lower === "gemini-3.8-flash" || ["gemini-3.8-flash-low", "gemini-3.8-flash-medium", "gemini-3.8-flash-high"].includes(lower)) {
1878
+ const wireModelId = "gemini-3.8-flash-tiered";
1879
+ return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
1880
+ }
1841
1881
  if (lower === "gemini-3.6-flash") {
1842
1882
  const wireModelId = "gemini-3.6-flash-low";
1843
1883
  return { wireModelId, profile: WIRE_PROFILES[wireModelId] };
@@ -1854,8 +1894,19 @@ function resolveAntigravityWireModel(logicalModelId) {
1854
1894
 
1855
1895
  // packages/agent-runtime/geminiNativeShared.ts
1856
1896
  var SKIP_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
1897
+ function resolveGeminiModelQuirks(modelId) {
1898
+ const lower = modelId.toLowerCase();
1899
+ const isGemini3 = lower.includes("gemini-3");
1900
+ const isStrictSignatureModel = lower.includes("gemini-3.5") || lower.includes("flash-preview");
1901
+ const isClaude = lower.includes("claude");
1902
+ return {
1903
+ requiresThoughtSignature: isGemini3,
1904
+ allowsThoughtSignatureSentinel: isGemini3 && !isStrictSignatureModel,
1905
+ isClaudeCrossModel: isClaude
1906
+ };
1907
+ }
1857
1908
  function isGemini3Model(modelId) {
1858
- return modelId.includes("gemini-3");
1909
+ return resolveGeminiModelQuirks(modelId).requiresThoughtSignature;
1859
1910
  }
1860
1911
  function messageText(content) {
1861
1912
  if (typeof content === "string") return content;
@@ -2050,10 +2101,15 @@ function applyGeminiChunk(chunk, state, options) {
2050
2101
  const prompt = typeof meta.promptTokenCount === "number" ? meta.promptTokenCount : 0;
2051
2102
  const candidates2 = typeof meta.candidatesTokenCount === "number" ? meta.candidatesTokenCount : 0;
2052
2103
  const total = typeof meta.totalTokenCount === "number" ? meta.totalTokenCount : prompt + candidates2;
2104
+ const cached = typeof meta.cachedContentTokenCount === "number" && Number.isFinite(meta.cachedContentTokenCount) ? (
2105
+ // cached ⊆ prompt;对畸形上游防御性钳位,避免 cache_read > input 破坏归一化与计费
2106
+ Math.min(Math.max(0, Math.floor(meta.cachedContentTokenCount)), prompt)
2107
+ ) : 0;
2053
2108
  state.usage = {
2054
2109
  prompt_tokens: prompt,
2055
2110
  completion_tokens: candidates2,
2056
- total_tokens: total
2111
+ total_tokens: total,
2112
+ ...cached > 0 ? { cache_read_input_tokens: cached } : {}
2057
2113
  };
2058
2114
  }
2059
2115
  const candidates = Array.isArray(response.candidates) ? response.candidates : [];
@@ -2166,9 +2222,10 @@ function buildCloudCodeAssistPayload(args) {
2166
2222
  const logicalModel = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gemini-3.1-pro";
2167
2223
  const { wireModelId: model, profile } = resolveAntigravityWireModel(logicalModel);
2168
2224
  const rawMessages = Array.isArray(args.openAiBody.messages) ? args.openAiBody.messages : [];
2169
- const isClaude = model.toLowerCase().includes("claude");
2225
+ const quirks = resolveGeminiModelQuirks(model);
2226
+ const isClaude = quirks.isClaudeCrossModel;
2170
2227
  const { contents, systemTexts } = convertOpenAiMessagesToGemini(rawMessages, {
2171
- attachSkipThoughtSignature: isGemini3Model(model)
2228
+ attachSkipThoughtSignature: quirks.allowsThoughtSignatureSentinel
2172
2229
  });
2173
2230
  if (contents.length === 0) {
2174
2231
  throw new Error("Antigravity Cloud Code Assist request has no user/model contents.");
@@ -2613,31 +2670,6 @@ function collectInstructions(messages, agentPrompt) {
2613
2670
  }
2614
2671
  return systemTexts.join("\n\n");
2615
2672
  }
2616
- function collectStableInstructions(messages, fallbackPrompt) {
2617
- const systemTexts = [];
2618
- if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
2619
- for (const raw of messages) {
2620
- if (!raw || typeof raw !== "object") continue;
2621
- const message = raw;
2622
- const role = String(message.role ?? "");
2623
- if (role !== "system" && role !== "developer") continue;
2624
- if (typeof message.content === "string") {
2625
- const boundary = Number(message.stable_prefix_chars);
2626
- const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
2627
- if (text.trim()) systemTexts.push(text.trim());
2628
- }
2629
- }
2630
- return systemTexts.join("\n\n");
2631
- }
2632
- function stablePromptCacheKey(parts) {
2633
- const value = JSON.stringify(parts);
2634
- let hash = 2166136261;
2635
- for (let index = 0; index < value.length; index += 1) {
2636
- hash ^= value.charCodeAt(index);
2637
- hash = Math.imul(hash, 16777619) >>> 0;
2638
- }
2639
- return `nolo-codex-${hash.toString(16).padStart(8, "0")}`;
2640
- }
2641
2673
  function convertMessagesToCodexInput(messages) {
2642
2674
  return convertMessagesToResponsesInput(messages).map((item) => {
2643
2675
  if (item.type !== "reasoning") return item;
@@ -2658,7 +2690,7 @@ function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
2658
2690
  });
2659
2691
  const input = convertMessagesToCodexInput(nonSystem);
2660
2692
  const instructions = collectInstructions(rawMessages, args.agentConfig.prompt);
2661
- const stableInstructions = collectStableInstructions(rawMessages, args.agentConfig.prompt);
2693
+ const stableInstructions = collectStablePromptPrefix(rawMessages, args.agentConfig.prompt);
2662
2694
  const model = asOptionalTrimmedString(args.openAiBody.model) ?? asOptionalTrimmedString(args.agentConfig.model) ?? "gpt-5.5";
2663
2695
  const tools = toResponsesTools(
2664
2696
  Array.isArray(args.openAiBody.tools) ? args.openAiBody.tools : void 0
@@ -2670,7 +2702,7 @@ function buildCodexRequestBody(args, identity = createCodexRequestIdentity()) {
2670
2702
  store: false,
2671
2703
  // Keep routing stable across turns and request UUIDs. Growing input/history
2672
2704
  // is intentionally excluded; only stable request-prefix material belongs.
2673
- prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []]),
2705
+ prompt_cache_key: stablePromptCacheKey([model, stableInstructions, tools ?? []], "nolo-codex"),
2674
2706
  client_metadata: identity.clientMetadata
2675
2707
  };
2676
2708
  if (instructions) body.instructions = instructions;
@@ -2818,7 +2850,8 @@ var resolveCodexOAuthTransport = async (ctx) => {
2818
2850
  });
2819
2851
  await recordLocalAvailability(result.status, result.body);
2820
2852
  if (result.status < 200 || result.status >= 300) {
2821
- const errMsg = result.body?.error && typeof result.body.error === "object" && typeof result.body.error.message === "string" ? result.body.error.message : JSON.stringify(result.body);
2853
+ const errorObj = result.body?.error;
2854
+ const errMsg = typeof errorObj?.message === "string" ? errorObj.message : JSON.stringify(result.body);
2822
2855
  throw new Error(
2823
2856
  `local Codex OAuth provider failed: HTTP ${result.status} ${errMsg}`
2824
2857
  );
@@ -2838,6 +2871,8 @@ var resolveCodexOAuthTransport = async (ctx) => {
2838
2871
  });
2839
2872
  return {
2840
2873
  content,
2874
+ model: agentConfig.model || "gpt-5.6-sol",
2875
+ provider: "openai",
2841
2876
  ...tool_calls ? { tool_calls } : {},
2842
2877
  // fetchCodexResponsesCompletion 已把 codex responses 流聚合完毕并归一化成
2843
2878
  // OpenAI chat.completions 形状:choices[0].finish_reason("stop"/"tool_calls")
@@ -7789,6 +7824,7 @@ async function streamCursorChat(messages, options) {
7789
7824
  const execCtx = {
7790
7825
  tools: buildMcpToolDefinitions(options.tools),
7791
7826
  executeTool: options.executeTool,
7827
+ ...options.onActionGate ? { onActionGate: options.onActionGate } : {},
7792
7828
  ...options.searchWorkspace ? { searchWorkspace: options.searchWorkspace } : {},
7793
7829
  ...options.listWorkspaceEntries ? { listWorkspaceEntries: options.listWorkspaceEntries } : {},
7794
7830
  toolCalls,
@@ -8332,6 +8368,23 @@ function decodeMcpArgValue(value) {
8332
8368
  }
8333
8369
  }
8334
8370
  }
8371
+ async function executeCursorTool(ctx, call) {
8372
+ if ((call.name === "writeFile" || call.name === "editFile") && ctx.onActionGate) {
8373
+ let path = "the requested file";
8374
+ try {
8375
+ const parsed = JSON.parse(call.arguments);
8376
+ if (typeof parsed.path === "string" && parsed.path.trim()) path = parsed.path.trim();
8377
+ } catch {
8378
+ }
8379
+ const policy = evaluateFileWritePolicy({ tool: call.name, path, sessionApproved: false });
8380
+ if (policy.permissionDecision !== "ask") return ctx.executeTool ? ctx.executeTool(call) : { content: "tool execution unavailable" };
8381
+ const gate = { ...policy.permissionRequest, kind: "confirm", toolName: call.name, toolCallId: call.id };
8382
+ const result = await ctx.onActionGate(gate);
8383
+ if (result?.metadata?.actionGateResult?.status !== "completed") return result ?? { content: `${call.name} cancelled: file write confirmation was not approved.`, metadata: { cancelled: true, actionGateResult: { gateId: gate.id, status: "cancelled" } } };
8384
+ ctx.onActionGate = void 0;
8385
+ }
8386
+ return ctx.executeTool ? ctx.executeTool(call) : { content: "tool execution unavailable" };
8387
+ }
8335
8388
  async function handleExecServerMessage(execMsg, h2Request, ctx) {
8336
8389
  const execCase = execMsg.message?.case;
8337
8390
  if (execCase === "requestContextArgs") {
@@ -8372,7 +8425,7 @@ async function handleExecServerMessage(execMsg, h2Request, ctx) {
8372
8425
  });
8373
8426
  const startedAt = Date.now();
8374
8427
  try {
8375
- const toolResult = await ctx.executeTool({
8428
+ const toolResult = await executeCursorTool(ctx, {
8376
8429
  id: args.toolCallId,
8377
8430
  name: "readFile",
8378
8431
  arguments: toolCallArgs
@@ -8442,7 +8495,7 @@ async function handleExecServerMessage(execMsg, h2Request, ctx) {
8442
8495
  });
8443
8496
  const startedAt = Date.now();
8444
8497
  try {
8445
- const toolResult = await ctx.executeTool({
8498
+ const toolResult = await executeCursorTool(ctx, {
8446
8499
  id: args.toolCallId,
8447
8500
  name: "execShell",
8448
8501
  arguments: toolCallArgs
@@ -8600,7 +8653,7 @@ async function handleExecServerMessage(execMsg, h2Request, ctx) {
8600
8653
  });
8601
8654
  const startedAt = Date.now();
8602
8655
  try {
8603
- const toolResult = await ctx.executeTool({
8656
+ const toolResult = await executeCursorTool(ctx, {
8604
8657
  id: args.toolCallId,
8605
8658
  name: "writeFile",
8606
8659
  arguments: toolCallArgs
@@ -8662,7 +8715,7 @@ async function handleExecServerMessage(execMsg, h2Request, ctx) {
8662
8715
  });
8663
8716
  const startedAt = Date.now();
8664
8717
  try {
8665
- const toolResult = await ctx.executeTool({
8718
+ const toolResult = await executeCursorTool(ctx, {
8666
8719
  id: args.toolCallId,
8667
8720
  name: "deleteFile",
8668
8721
  arguments: toolCallArgs
@@ -8781,7 +8834,7 @@ async function handleExecServerMessage(execMsg, h2Request, ctx) {
8781
8834
  });
8782
8835
  const startedAt = Date.now();
8783
8836
  try {
8784
- const toolResult = await ctx.executeTool({
8837
+ const toolResult = await executeCursorTool(ctx, {
8785
8838
  id: args.toolCallId,
8786
8839
  name: toolName,
8787
8840
  arguments: toolCallArgs
@@ -8890,6 +8943,7 @@ function createCursorProvider(config) {
8890
8943
  ...options?.onTextDelta ? { onTextDelta: options.onTextDelta } : {},
8891
8944
  ...options?.onReasoningDelta ? { onReasoningDelta: options.onReasoningDelta } : {},
8892
8945
  ...options?.onToolEvent ? { onToolEvent: options.onToolEvent } : {},
8946
+ ...options?.onActionGate ? { onActionGate: options.onActionGate } : {},
8893
8947
  ...typeof options?.toolEventRound === "number" ? { toolEventRound: options.toolEventRound } : {}
8894
8948
  });
8895
8949
  }
@@ -9403,7 +9457,7 @@ async function resolveLocalProvider(ctx) {
9403
9457
  }
9404
9458
 
9405
9459
  // packages/cli/client/localRuntimeAdapter.ts
9406
- import { dirname as dirname2, extname, join as join2 } from "node:path";
9460
+ import { dirname as dirname2, extname, join as join3 } from "node:path";
9407
9461
  import { fileURLToPath } from "node:url";
9408
9462
 
9409
9463
  // packages/cli/client/providerStreamRetry.ts
@@ -9532,6 +9586,11 @@ function clipLocalWakeEvidence(value, max = 1200) {
9532
9586
  const compact = clipCompactText(value, max);
9533
9587
  return compact || void 0;
9534
9588
  }
9589
+ function buildLocalWakeDisplayText(args) {
9590
+ const failed = args.terminalStatus !== "done";
9591
+ const duration = typeof args.durationMs === "number" && args.durationMs >= 0 ? ` \xB7 ${Math.floor(args.durationMs / 6e4)}m${Math.floor(args.durationMs / 1e3) % 60}s` : "";
9592
+ return `1 \u6761\u540E\u53F0 run \u5DF2\u5B8C\u6210 \xB7 ${failed ? "\u2717" : "\u2713"} ${args.label || "\u540E\u53F0 run"}${failed ? ` ${args.terminalStatus}` : ""}${duration}`;
9593
+ }
9535
9594
  function buildLocalParentWakeMessage(args) {
9536
9595
  return [
9537
9596
  "A child agent dialog you started has reached a terminal status.",
@@ -9581,7 +9640,14 @@ async function postRemoteRecord(args) {
9581
9640
  },
9582
9641
  // evidence 写是 customKey 幂等覆盖写(同 key 重写结果相同),
9583
9642
  // 因此 502 重试安全:即便前一次已被服务端处理,重写结果不变。
9584
- { retryableStatuses: /* @__PURE__ */ new Set([429, 502, 503]) }
9643
+ // 402(ledger append conflict)同样幂等可重试:token 记录同 key
9644
+ // 覆盖写 + 扣费幂等键(token:<key>)在 prepare 阶段短路 duplicate,
9645
+ // 重试不会双扣。服务端 chargeTokenUsageWithLedger 内部已带 conflict
9646
+ // 重试,走到 402 说明多重冲突,客户端再退避重试一轮兜底。
9647
+ // Effect v4 迁移锚点:白名单重试 ≈ Effect.retry({ while: res =>
9648
+ // retryableStatuses.has(res.status), schedule: Schedule.exponential }),
9649
+ // 退避/抖动由 Schedule 组合表达,测试用 TestClock 免真实 sleep。
9650
+ { retryableStatuses: /* @__PURE__ */ new Set([402, 429, 502, 503]) }
9585
9651
  );
9586
9652
  if (!response.ok) {
9587
9653
  const text = await response.text().catch(() => "");
@@ -9658,6 +9724,12 @@ async function maybeWakeParentDialogAfterLocalSync(args) {
9658
9724
  host: "terminal",
9659
9725
  runtime: "bun",
9660
9726
  entrypoint: "agent-runtime:parent-child-terminal-wake",
9727
+ wakeChildDialogKey: args.childDialogKey,
9728
+ wakeTerminalStatus: "done",
9729
+ wakeDisplayText: buildLocalWakeDisplayText({
9730
+ label: args.childDialogRecord.taskLabel ?? args.childDialogRecord.title,
9731
+ terminalStatus: "done"
9732
+ }),
9661
9733
  subjectRefs,
9662
9734
  ...allowedChildAgentKeys.length ? { allowedChildAgentKeys } : {},
9663
9735
  ...allowedToolNames.length ? { allowedToolNames } : {},
@@ -10070,7 +10142,8 @@ function buildServerPlatformToolExecutors(args) {
10070
10142
  content,
10071
10143
  metadata: {
10072
10144
  serverPlatformTool: true,
10073
- webTool: toolName
10145
+ webTool: toolName,
10146
+ query: parsed.query
10074
10147
  }
10075
10148
  };
10076
10149
  }
@@ -10092,7 +10165,7 @@ function buildServerPlatformToolExecutors(args) {
10092
10165
  });
10093
10166
  return {
10094
10167
  content: raw,
10095
- metadata: { serverPlatformTool: true, memoryRead: true }
10168
+ metadata: { serverPlatformTool: true, memoryRead: true, query }
10096
10169
  };
10097
10170
  };
10098
10171
  const rememberMemory = async (call) => {
@@ -10112,13 +10185,16 @@ function buildServerPlatformToolExecutors(args) {
10112
10185
  kind: parsed.kind ?? "episodic",
10113
10186
  source: "agent-inferred"
10114
10187
  };
10188
+ if (typeof parsed.recurrenceEvidence === "string" && parsed.recurrenceEvidence.trim()) {
10189
+ body.recurrenceEvidence = parsed.recurrenceEvidence.trim();
10190
+ }
10115
10191
  if (args.agentKey) body.agentKey = args.agentKey;
10116
10192
  const raw = await postServer("/api/memory/remember", body, {
10117
10193
  retryTransient: true
10118
10194
  });
10119
10195
  return {
10120
10196
  content: raw,
10121
- metadata: { serverPlatformTool: true, memoryWrite: true }
10197
+ metadata: { serverPlatformTool: true, memoryWrite: true, content }
10122
10198
  };
10123
10199
  };
10124
10200
  const deleteMemory = async (call) => {
@@ -10169,6 +10245,7 @@ function buildServerPlatformToolExecutors(args) {
10169
10245
  }
10170
10246
 
10171
10247
  // packages/cli/client/cliAgentRunToolExecutors.ts
10248
+ import * as nodeFs2 from "node:fs";
10172
10249
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
10173
10250
 
10174
10251
  // packages/cli/client/agentRunSnapshot.ts
@@ -10217,6 +10294,7 @@ function buildSnapshot(parsed, event) {
10217
10294
  ...typeof parsed.toolCallCount === "number" && Number.isFinite(parsed.toolCallCount) ? { toolCallCount: parsed.toolCallCount } : {},
10218
10295
  ...lastToolNames ? { lastToolNames } : {},
10219
10296
  ...lastAssistantText ? { lastAssistantText } : {},
10297
+ ...typeof parsed.credits === "number" && Number.isFinite(parsed.credits) ? { credits: parsed.credits } : {},
10220
10298
  ...errorMessage ? { errorMessage } : {},
10221
10299
  ...startedAt !== void 0 ? { startedAt } : {},
10222
10300
  ...finishedAt !== void 0 ? { finishedAt } : {},
@@ -10395,18 +10473,18 @@ function deriveAgentRunTodoStatus(input) {
10395
10473
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10396
10474
  import { homedir as nodeHomedir } from "node:os";
10397
10475
  import { dirname, join } from "node:path";
10398
- var nodeFs2 = {
10476
+ var nodeFs = {
10399
10477
  mkdirSync,
10400
10478
  writeFileSync,
10401
10479
  readFileSync,
10402
10480
  existsSync
10403
10481
  };
10404
- function resolveNoloHome(env, homedir) {
10482
+ function resolveNoloHome(env, homedir2) {
10405
10483
  const custom = env?.NOLO_HOME;
10406
10484
  if (custom && custom.trim()) return custom.trim();
10407
10485
  const ambient = process.env.NOLO_HOME?.trim();
10408
10486
  if (ambient) return ambient;
10409
- return join(homedir(), ".nolo");
10487
+ return join(homedir2(), ".nolo");
10410
10488
  }
10411
10489
  function ensureDir(dir, fs) {
10412
10490
  fs.mkdirSync(dir, { recursive: true });
@@ -10425,9 +10503,9 @@ function writeJson(path, data, fs) {
10425
10503
  }
10426
10504
  function createFileSystemTodoStore(opts = {}) {
10427
10505
  const env = opts.env ?? process.env;
10428
- const homedir = opts.homedir ?? nodeHomedir;
10429
- const fs = opts.fs ?? nodeFs2;
10430
- const noloHome = resolveNoloHome(env, homedir);
10506
+ const homedir2 = opts.homedir ?? nodeHomedir;
10507
+ const fs = opts.fs ?? nodeFs;
10508
+ const noloHome = resolveNoloHome(env, homedir2);
10431
10509
  const filePath = opts.filePath ?? join(noloHome, "agent_run_todos.json");
10432
10510
  const oldFilePath = join(noloHome, "todos.json");
10433
10511
  const loadMap = () => {
@@ -10880,7 +10958,7 @@ function createCliControlAgentRunExecutor(deps = {}) {
10880
10958
  if (!ourEntryFound) {
10881
10959
  if (remainingEntries.length > 0) {
10882
10960
  await withQueueLock(queuePath, deps, () => {
10883
- const fs = deps.fs ?? nodeFs;
10961
+ const fs = deps.fs ?? nodeFs2;
10884
10962
  const existing = fs.existsSync(queuePath) ? fs.readFileSync(queuePath, "utf8") : "";
10885
10963
  fs.writeFileSync(queuePath, serializeQueueEntries(remainingEntries) + existing, "utf8");
10886
10964
  });
@@ -11039,6 +11117,7 @@ function createCliControlAgentRunExecutor(deps = {}) {
11039
11117
  // packages/cli/client/cliLocalToolExecutors.ts
11040
11118
  var MAX_PASTED_TEXT_LINES_PER_READ = 200;
11041
11119
  var PASTED_TEXT_EXPLICIT_OVERSHOOT_LINES = 20;
11120
+ var FULLY_DELIVERED_SEGMENT_LINES = MAX_PASTED_TEXT_LINES_PER_READ + PASTED_TEXT_EXPLICIT_OVERSHOOT_LINES;
11042
11121
  var PASTE_LEDGER_MAX_RECORDS = 64;
11043
11122
  function createReadPastedTextExecutor(store) {
11044
11123
  const ledger = /* @__PURE__ */ new Map();
@@ -11106,8 +11185,19 @@ function createReadPastedTextExecutor(store) {
11106
11185
  const clamped = explicitEnd !== void 0 && endLine < explicitEnd && endLine < lines.length;
11107
11186
  const paged = explicitEnd === void 0 && endLine < lines.length;
11108
11187
  const needsFooter = clamped || paged;
11188
+ const nextStartLine = endLine + 1;
11189
+ const remainingLines = lines.length - endLine;
11190
+ const footer = !needsFooter ? void 0 : remainingLines <= FULLY_DELIVERED_SEGMENT_LINES ? `[readPastedText: returned lines ${startLine}-${endLine} of ${lines.length}. Continue with startLine=${nextStartLine}.]` : (() => {
11191
+ const firstEnd = Math.min(
11192
+ nextStartLine + FULLY_DELIVERED_SEGMENT_LINES - 1,
11193
+ lines.length
11194
+ );
11195
+ const secondStart = firstEnd + 1;
11196
+ const secondEnd = Math.min(secondStart + FULLY_DELIVERED_SEGMENT_LINES - 1, lines.length);
11197
+ return `[readPastedText: returned lines ${startLine}-${endLine} of ${lines.length}. Continue with startLine=${nextStartLine}, or fetch the remaining ${remainingLines} lines in one turn with parallel calls (e.g. ${nextStartLine}-${firstEnd}, ${secondStart}-${secondEnd})]`;
11198
+ })();
11109
11199
  const content = needsFooter ? `${delivered}
11110
- [readPastedText: returned lines ${startLine}-${endLine} of ${lines.length}. Continue with startLine=${endLine + 1}.]` : delivered;
11200
+ ${footer}` : delivered;
11111
11201
  const metadata = {
11112
11202
  pasteId,
11113
11203
  startLine,
@@ -11118,7 +11208,7 @@ function createReadPastedTextExecutor(store) {
11118
11208
  // Continuation pointer whenever more content exists, even when an
11119
11209
  // explicit request was honored in full — the schema contract says a
11120
11210
  // truncated read advertises the exact next startLine.
11121
- ...endLine < lines.length ? { nextStartLine: endLine + 1 } : {},
11211
+ ...endLine < lines.length ? { nextStartLine: endLine + 1, remainingLines: lines.length - endLine } : {},
11122
11212
  source: "tui-paste-store"
11123
11213
  };
11124
11214
  const persistedChars = content.length + "\n\n[tool metadata]\n".length + JSON.stringify(metadata).length;
@@ -11364,6 +11454,15 @@ function resolveFallbackServers(env) {
11364
11454
  function resolveAuthToken(env) {
11365
11455
  return resolvePlatformAuthToken(env);
11366
11456
  }
11457
+ function resolveHybridReadTimeoutMs(env = process.env) {
11458
+ const raw = env.NOLO_HYBRID_READ_TIMEOUT_MS?.trim();
11459
+ if (!raw) return DEFAULT_HYBRID_READ_TIMEOUT_MS;
11460
+ const parsed = Number(raw);
11461
+ if (!Number.isFinite(parsed) || parsed < 0) {
11462
+ return DEFAULT_HYBRID_READ_TIMEOUT_MS;
11463
+ }
11464
+ return parsed;
11465
+ }
11367
11466
  function createCliHybridRecordStore(deps) {
11368
11467
  return createHybridRecordStore({
11369
11468
  db: deps.db,
@@ -11372,7 +11471,8 @@ function createCliHybridRecordStore(deps) {
11372
11471
  ),
11373
11472
  fallbackServers: resolveFallbackServers(deps.env),
11374
11473
  authToken: resolveAuthToken(deps.env),
11375
- fetchImpl: deps.fetchImpl
11474
+ fetchImpl: deps.fetchImpl,
11475
+ requestTimeoutMs: resolveHybridReadTimeoutMs(deps.env)
11376
11476
  });
11377
11477
  }
11378
11478
 
@@ -11433,18 +11533,12 @@ async function generateLocalDialogTitle(input) {
11433
11533
  } else if (typeof request.init?.body === "object" && request.init?.body !== null) {
11434
11534
  parsedBody = request.init.body;
11435
11535
  }
11436
- const patchedBody = isNemotronTitleModel() ? {
11536
+ const patchedBody = {
11437
11537
  ...parsedBody,
11438
- // response_format 与 reasoning_effort 同发会被 RunInfra 400 拒绝;
11439
- // json mode 下模型跳过 thinking(实测 completion 16-18 tokens)。
11440
- // 防御:显式置空,防未来 BUILTIN 配置或 requestOptions 残留该字段。
11538
+ // response_format 与 reasoning_effort 同发会被 RunInfra 400 拒绝,
11539
+ // 标题路径统一走 json mode(跳过 thinking,实测 completion 个位数 tokens)。
11441
11540
  response_format: { type: "json_object" },
11442
- max_tokens: 512,
11443
- reasoning_effort: void 0
11444
- } : {
11445
- ...parsedBody,
11446
- reasoning_effort: "low",
11447
- max_tokens: 3072
11541
+ max_tokens: 512
11448
11542
  };
11449
11543
  const res = await input.fetchImpl(request.url, {
11450
11544
  ...request.init,
@@ -11507,9 +11601,10 @@ async function generateLocalDialogTitle(input) {
11507
11601
  { role: "system", content: buildTitleSystemPrompt(input.existingTitle) },
11508
11602
  { role: "user", content: compactTranscript }
11509
11603
  ],
11510
- // Nemotron json mode(跳过 thinking)与其余路径的 reasoning_effort 优化互斥;
11511
- // 严格 OpenAI 兼容服务端若拒绝未知参数会降级到 fallback
11512
- ...isNemotronTitleModel() ? { response_format: { type: "json_object" }, max_tokens: 512 } : { reasoning_effort: "low", max_tokens: 3072 },
11604
+ // 标题路径统一 json mode(跳过 thinking);response_format
11605
+ // reasoning_effort 同发会被 RunInfra 400 拒绝,故不发 reasoning_effort
11606
+ response_format: { type: "json_object" },
11607
+ max_tokens: 512,
11513
11608
  stream: false
11514
11609
  }),
11515
11610
  signal: AbortSignal.timeout(timeoutMs)
@@ -11539,14 +11634,13 @@ function transcriptLength(messages) {
11539
11634
  }
11540
11635
  function buildTitleSystemPrompt(existingTitle) {
11541
11636
  const title = existingTitle?.trim();
11542
- const jsonFormatInstruction = isNemotronTitleModel() ? '\n\u8F93\u51FA\u683C\u5F0F\uFF1A\u8FD4\u56DE JSON \u5BF9\u8C61 {"title": "<\u6807\u9898>"}\uFF0C\u9664\u6B64\u4E4B\u5916\u4E0D\u8981\u6709\u4EFB\u4F55\u5B57\u7B26\u3002' : "";
11543
- const base = `${BUILTIN_TITLE_LLM_CONFIG.prompt}${jsonFormatInstruction}`;
11637
+ const base = `${BUILTIN_TITLE_LLM_CONFIG.prompt}
11638
+ \u8F93\u51FA\u683C\u5F0F\uFF1A\u8FD4\u56DE JSON \u5BF9\u8C61 {"title": "<\u6807\u9898>"}\uFF0C\u9664\u6B64\u4E4B\u5916\u4E0D\u8981\u6709\u4EFB\u4F55\u5B57\u7B26\u3002`;
11544
11639
  return title ? `${base}
11545
11640
  \u5F53\u524D\u6807\u9898\uFF1A${title}\u3002\u5982\u679C\u5BF9\u8BDD\u4ECD\u5728\u8BA8\u8BBA\u540C\u4E00\u4E3B\u9898\uFF0C\u5FC5\u987B\u539F\u6837\u8F93\u51FA\u5F53\u524D\u6807\u9898\uFF0C\u4E0D\u8981\u6539\u5199\uFF1B\u53EA\u6709\u5F53\u5BF9\u8BDD\u660E\u786E\u8F6C\u5411\u4E86\u4E0D\u540C\u4E3B\u9898\u65F6\u624D\u751F\u6210\u65B0\u6807\u9898\u3002` : base;
11546
11641
  }
11547
- var isNemotronTitleModel = () => BUILTIN_TITLE_LLM_CONFIG.model === PLATFORM_HOSTED_NEMOTRON_35_LIGHTNING_MODEL;
11548
11642
  function extractTitleFromLlmContent(raw) {
11549
- if (isNemotronTitleModel() && raw.trim().startsWith("{")) {
11643
+ if (raw.trim().startsWith("{")) {
11550
11644
  try {
11551
11645
  const parsed = JSON.parse(raw);
11552
11646
  if (typeof parsed?.title === "string" && parsed.title.trim()) {
@@ -11603,6 +11697,70 @@ function isRemoteAuthEndpoint(endpoint) {
11603
11697
 
11604
11698
  // packages/cli/client/localRuntimeDialog.ts
11605
11699
  var import_date_fns = __toESM(require_date_fns(), 1);
11700
+ import { appendFileSync, mkdirSync as mkdirSync2 } from "fs";
11701
+ import { homedir } from "os";
11702
+ import { join as join2 } from "path";
11703
+ var RAW_USAGE_SCALARS = [
11704
+ "prompt_tokens",
11705
+ "completion_tokens",
11706
+ "total_tokens",
11707
+ "input_tokens",
11708
+ "output_tokens",
11709
+ "cache_read_input_tokens",
11710
+ "cache_creation_input_tokens",
11711
+ "prompt_cache_hit_tokens",
11712
+ "prompt_cache_miss_tokens",
11713
+ "cost",
11714
+ "cost_in_usd_ticks",
11715
+ "provider_call_id"
11716
+ ];
11717
+ var RAW_USAGE_DETAIL_OBJECTS = [
11718
+ "prompt_tokens_details",
11719
+ "completion_tokens_details",
11720
+ "input_tokens_details",
11721
+ "output_tokens_details",
11722
+ "cost_details"
11723
+ ];
11724
+ function projectRawUsage(usage) {
11725
+ const out = {};
11726
+ for (const key of RAW_USAGE_SCALARS) {
11727
+ const value = usage[key];
11728
+ if (typeof value === "number" && Number.isFinite(value)) {
11729
+ out[key] = value;
11730
+ } else if (key === "provider_call_id" && typeof value === "string" && value.trim()) {
11731
+ out[key] = value;
11732
+ }
11733
+ }
11734
+ for (const key of RAW_USAGE_DETAIL_OBJECTS) {
11735
+ const value = usage[key];
11736
+ if (!value || typeof value !== "object" || Array.isArray(value)) continue;
11737
+ const numericLeaves = Object.fromEntries(
11738
+ Object.entries(value).filter(
11739
+ ([, leaf]) => typeof leaf === "number" && Number.isFinite(leaf)
11740
+ )
11741
+ );
11742
+ if (Object.keys(numericLeaves).length > 0) out[key] = numericLeaves;
11743
+ }
11744
+ return out;
11745
+ }
11746
+ function debugCaptureRawUsage(item) {
11747
+ if (!process.env.NOLO_DEBUG_RAW_USAGE) return;
11748
+ try {
11749
+ const noloHome = process.env.NOLO_HOME?.trim() || join2(homedir(), ".nolo");
11750
+ const dir = join2(noloHome, "logs");
11751
+ mkdirSync2(dir, { recursive: true });
11752
+ appendFileSync(
11753
+ join2(dir, "raw-usage.jsonl"),
11754
+ JSON.stringify({
11755
+ ts: Date.now(),
11756
+ model: item.model,
11757
+ provider: item.provider,
11758
+ usage: projectRawUsage(item.usage)
11759
+ }) + "\n"
11760
+ );
11761
+ } catch {
11762
+ }
11763
+ }
11606
11764
  async function resolveStore(deps) {
11607
11765
  if (deps.store) return deps.store;
11608
11766
  return createCliHybridRecordStore({
@@ -11691,6 +11849,7 @@ async function writeLocalTokenRecord(args) {
11691
11849
  const ops = [];
11692
11850
  for (const item of usageRecords) {
11693
11851
  if (!item.usage || Object.keys(item.usage).length === 0) continue;
11852
+ debugCaptureRawUsage(item);
11694
11853
  const timestamp = args.now();
11695
11854
  const callId = item.callId || typeof item.usage.provider_call_id === "string" && item.usage.provider_call_id.trim() || args.createId();
11696
11855
  const prepared = prepareTokenUsageData({
@@ -11710,7 +11869,11 @@ async function writeLocalTokenRecord(args) {
11710
11869
  agentId: args.input.agentKey,
11711
11870
  dialogId: args.dialogId,
11712
11871
  timestamp,
11713
- entry_path: "cli-local"
11872
+ entry_path: "cli-local",
11873
+ ...item.stablePrefixHash ? {
11874
+ stable_prefix_hash: item.stablePrefixHash,
11875
+ stable_prefix_estimated_tokens: item.stablePrefixEstimatedTokens
11876
+ } : {}
11714
11877
  });
11715
11878
  const recordKey = createTokenKey.recordForStableCall(args.userId, callId);
11716
11879
  const existingToken = await args.store.read(recordKey, { remote: false }).catch(() => null);
@@ -11955,7 +12118,7 @@ var currentMetaFile = fileURLToPath(import.meta.url);
11955
12118
  var isJsBundle = extname(currentMetaFile) === ".js";
11956
12119
  var SOURCE_CLI_DIR = isJsBundle ? dirname2(currentMetaFile) : dirname2(dirname2(currentMetaFile));
11957
12120
  var CLI_DIR = isCompiledBinary() ? dirname2(process.execPath) : SOURCE_CLI_DIR;
11958
- var CLI_ENTRYPOINT = isCompiledBinary() ? process.execPath : isJsBundle ? currentMetaFile : join2(SOURCE_CLI_DIR, "index.ts");
12121
+ var CLI_ENTRYPOINT = isCompiledBinary() ? process.execPath : isJsBundle ? currentMetaFile : join3(SOURCE_CLI_DIR, "index.ts");
11959
12122
  async function recordLocalAvailabilityForAgent(args) {
11960
12123
  const now = args.now ?? Date.now;
11961
12124
  const { deps, status } = args;
@@ -12251,17 +12414,22 @@ function createCliLocalRuntimeAdapter(deps) {
12251
12414
  executeTool: async (call, opts) => {
12252
12415
  const contextualCall = opts?.runtimeContext ? { ...call, runtimeContext: opts.runtimeContext } : call;
12253
12416
  let injectedCall = contextualCall;
12254
- if (contextualCall.name === "startAgentRun" && deps.parentDialogId && typeof contextualCall.arguments === "string") {
12417
+ let spawnedWithoutParent = false;
12418
+ if (contextualCall.name === "startAgentRun" && typeof contextualCall.arguments === "string") {
12255
12419
  try {
12256
12420
  const args = JSON.parse(contextualCall.arguments);
12257
12421
  if (!args.parentDialogId) {
12258
- injectedCall = {
12259
- ...contextualCall,
12260
- arguments: JSON.stringify({
12261
- ...args,
12262
- parentDialogId: deps.parentDialogId
12263
- })
12264
- };
12422
+ if (deps.parentDialogId) {
12423
+ injectedCall = {
12424
+ ...contextualCall,
12425
+ arguments: JSON.stringify({
12426
+ ...args,
12427
+ parentDialogId: deps.parentDialogId
12428
+ })
12429
+ };
12430
+ } else {
12431
+ spawnedWithoutParent = true;
12432
+ }
12265
12433
  }
12266
12434
  } catch {
12267
12435
  }
@@ -12280,6 +12448,15 @@ function createCliLocalRuntimeAdapter(deps) {
12280
12448
  detachMs: resolveExecShellDetachMs(deps.env),
12281
12449
  ...deps.confirmDestructiveAction ? { confirmDestructiveAction: deps.confirmDestructiveAction } : {}
12282
12450
  });
12451
+ if (spawnedWithoutParent && deps.onBackgroundRunSpawned) {
12452
+ try {
12453
+ const payload = JSON.parse(result?.content ?? "");
12454
+ if (payload && typeof payload.runId === "string" && payload.runId) {
12455
+ deps.onBackgroundRunSpawned(payload.runId);
12456
+ }
12457
+ } catch {
12458
+ }
12459
+ }
12283
12460
  return {
12284
12461
  ...result,
12285
12462
  metadata: {
@@ -12318,6 +12495,7 @@ function createCliLocalRuntimeAdapter(deps) {
12318
12495
  export {
12319
12496
  clearCliLocalRuntimePreparedAgentCache,
12320
12497
  isSubtaskRun,
12498
+ RUN_WAKE_CHANNEL_ENV,
12321
12499
  summarizeEndpoint,
12322
12500
  isBuiltinNoloAgentRef,
12323
12501
  readTimestamp,