nolo-cli 0.156.0-alpha.3 → 0.156.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 (164) hide show
  1. package/{_executeModel-5WS2PA62.js → _executeModel-3FMHTHSS.js} +55 -55
  2. package/{accountResolver-7RYB4D2P.js → accountResolver-55EDKEIK.js} +1 -1
  3. package/{action-ZJYUBXFC.js → action-GPPJC5TI.js} +5 -5
  4. package/{addContentAction-TVHB4526.js → addContentAction-XJQEJ4XW.js} +8 -8
  5. package/{addDialogAgentAction-FDPBU6K6.js → addDialogAgentAction-5WZX5CAY.js} +7 -7
  6. package/{agentDeleteCommand-MDC7OS3I.js → agentDeleteCommand-VRHLJZKX.js} +75 -76
  7. package/{agentEmailCommands-WN4EOPKQ.js → agentEmailCommands-YGBQXOL3.js} +78 -79
  8. package/{agentListCommands-G36AMSBR.js → agentListCommands-GOCGOQUB.js} +36 -36
  9. package/{agentMachineCommands-63GXO27A.js → agentMachineCommands-FBAWZYHI.js} +35 -32
  10. package/{agentProviderCommands-X2HQE6HY.js → agentProviderCommands-CXBHNONN.js} +5 -5
  11. package/{agentPullCommand-FA43RBRU.js → agentPullCommand-GXXEDOSA.js} +4 -4
  12. package/{agentRecordCommands-X4WJRHDW.js → agentRecordCommands-KAK2G56H.js} +72 -73
  13. package/{agentRunCommand-4YMIVVHF.js → agentRunCommand-62P3AGJA.js} +75 -75
  14. package/{agentRunControl-2C5GM3BW.js → agentRunControl-XBSNHHZE.js} +7 -7
  15. package/{agentRuntimeLocal-Q7ZOMZC7.js → agentRuntimeLocal-J6I63NZC.js} +21 -19
  16. package/{agentSlice-E3XS5FTQ.js → agentSlice-IZFU3WWH.js} +8 -8
  17. package/{appDeleteCommands-MMWT54BR.js → appDeleteCommands-KKLAK2UR.js} +31 -29
  18. package/{appDeployCommands-OIFXVDOF.js → appDeployCommands-PXWK4FAX.js} +31 -29
  19. package/{appDeployStatusCommands-OTXMSDFB.js → appDeployStatusCommands-3NGWDZTX.js} +31 -29
  20. package/{appGetCommands-JPY36ANL.js → appGetCommands-APWYPEO3.js} +31 -29
  21. package/{appListCommands-IHJGN36O.js → appListCommands-OP7IRALO.js} +31 -29
  22. package/{authCommand-J3XILHWW.js → authCommand-3Z52KJID.js} +22 -302
  23. package/{authCommands-77CHYBGF.js → authCommands-QOCKVPX3.js} +5 -5
  24. package/{builtinSkillRegistry-A6VSPJEJ.js → builtinSkillRegistry-LJV7FHNI.js} +4 -4
  25. package/{chromeCommands-OBBNJCLS.js → chromeCommands-IY4NVSXZ.js} +17 -10
  26. package/{chunk-SW4S4XYB.js → chunk-2AB2HA4M.js} +84 -34
  27. package/{chunk-H4KACZMG.js → chunk-2QQ7D3P5.js} +271 -138
  28. package/{chunk-C5VPAHIU.js → chunk-32ZKZET7.js} +1 -1
  29. package/{chunk-FPWT3RH2.js → chunk-36IWXF25.js} +22 -22
  30. package/{chunk-XPWGOTBQ.js → chunk-3L2WKC3W.js} +1 -8
  31. package/{chunk-3XZKV7QQ.js → chunk-3L5MSPWX.js} +1 -1
  32. package/{chunk-QLQ573SU.js → chunk-3M52COK5.js} +120 -0
  33. package/{chunk-Z6KQDSZW.js → chunk-43OFVLWJ.js} +6 -6
  34. package/{chunk-7A4LJCDR.js → chunk-4FDDVVCE.js} +5 -5
  35. package/{chunk-TJ2VPCBE.js → chunk-4JCAW7TO.js} +2 -2
  36. package/{chunk-6TF64IF2.js → chunk-4L4K6YR7.js} +16 -2
  37. package/{chunk-ZG73GDYU.js → chunk-5E5VB7PS.js} +332 -59
  38. package/{chunk-HKT6QXP3.js → chunk-5IKRTRRR.js} +5 -5
  39. package/{chunk-P5QACQDK.js → chunk-62TBKWTV.js} +1 -1
  40. package/{chunk-TRW43TSC.js → chunk-6EQD4AQL.js} +41 -1
  41. package/{chunk-RUNKPFM5.js → chunk-6QIBWOPT.js} +12 -8
  42. package/{chunk-YLMMECCH.js → chunk-6XIE5ZGI.js} +1 -1
  43. package/{chunk-7GC3EKUG.js → chunk-7PDNSQZC.js} +3 -3
  44. package/{chunk-DW7MGLMG.js → chunk-7YQQXP42.js} +35 -207
  45. package/{chunk-WZ6OU4NX.js → chunk-BAWAKW7X.js} +2 -2
  46. package/{chunk-UUPR3TD7.js → chunk-BL4HFN6L.js} +2 -4
  47. package/{chunk-2GGXHQIW.js → chunk-BLVSFYQ3.js} +4 -2
  48. package/{chunk-HP6O6LTV.js → chunk-CDLP56BS.js} +9 -9
  49. package/{chunk-4LRK5Q2Z.js → chunk-CI6YDDL2.js} +18 -17
  50. package/{chunk-5MM7NNO6.js → chunk-CNWKLQRL.js} +8 -3
  51. package/{chunk-UTIMX333.js → chunk-DJ2BOPJY.js} +1 -1
  52. package/{chunk-36OMEXXR.js → chunk-DLV3H464.js} +8 -8
  53. package/{chunk-X5SUT4CN.js → chunk-EDJND3FK.js} +6 -6
  54. package/{chunk-CE7PIHQD.js → chunk-ESMZW5PE.js} +3 -3
  55. package/{chunk-PSJWPSKS.js → chunk-EWO77ZGF.js} +9 -43
  56. package/{chunk-ZWG3C7VI.js → chunk-F3SOW2EU.js} +81 -1
  57. package/{chunk-FY4SDK2E.js → chunk-FDLDMJTM.js} +1 -1
  58. package/chunk-FTHF2P2I.js +2685 -0
  59. package/{chunk-7KYVUFDG.js → chunk-G3VYRPTV.js} +5 -267
  60. package/{chunk-NQ64VVAI.js → chunk-GXZZOTDM.js} +826 -689
  61. package/{chunk-6MJNEXUU.js → chunk-HGDKT2D6.js} +4 -0
  62. package/{chunk-6KVZAZJA.js → chunk-HRZW3SQN.js} +7 -7
  63. package/{chunk-B2EGWZJG.js → chunk-I7S63QUU.js} +1 -1
  64. package/{chunk-ROPSATAB.js → chunk-IF7V3CBU.js} +1 -1
  65. package/{chunk-T6CBQ6BN.js → chunk-INFHX73M.js} +1 -1
  66. package/{chunk-YBNHPX4S.js → chunk-IW64YHXL.js} +155 -31
  67. package/{chunk-VSOWPETY.js → chunk-JIAZK434.js} +10 -10
  68. package/{chunk-K43ZF2C3.js → chunk-JPPQ3GUO.js} +1 -1
  69. package/{chunk-TZTWMGE3.js → chunk-JWEXJ573.js} +3 -3
  70. package/{chunk-OH2M7WEU.js → chunk-K3N2DWLT.js} +3 -3
  71. package/{chunk-I2ZMGXXF.js → chunk-KFHREHUQ.js} +1 -1
  72. package/{chunk-3C2QLERX.js → chunk-KMDDG73K.js} +1 -1
  73. package/{chunk-EM3YOZJ4.js → chunk-L2JMH4I5.js} +3 -3
  74. package/{chunk-D4OWHT5Y.js → chunk-MAYW6V3E.js} +2 -2
  75. package/{chunk-IPAW7XLD.js → chunk-MFVOJ6KF.js} +2 -2
  76. package/{chunk-CBHGZRCE.js → chunk-MYOH447Z.js} +1 -1
  77. package/{chunk-6MPAEODB.js → chunk-NHEWV5FD.js} +17 -3
  78. package/{chunk-SUKSWFLP.js → chunk-PIG2IUVZ.js} +1 -1
  79. package/{chunk-WP6RXNE6.js → chunk-PNACBSRF.js} +134 -126
  80. package/{chunk-SEJ5OS6F.js → chunk-PXYBUFDB.js} +4 -0
  81. package/{chunk-SKPPKHD3.js → chunk-Q5LVXPGT.js} +2 -2
  82. package/{chunk-2MTE2PEH.js → chunk-QA2C5NKI.js} +5 -739
  83. package/{chunk-XFKZ3MCV.js → chunk-QFL42TMV.js} +251 -77
  84. package/{chunk-L6EQV5OC.js → chunk-QXZH5UDF.js} +3 -3
  85. package/{chunk-TNIX77YM.js → chunk-R5GO3YZP.js} +34 -1
  86. package/{chunk-4Z245KOA.js → chunk-SH3XD4E2.js} +8 -4
  87. package/{chunk-MM3662RS.js → chunk-SNAWGDXT.js} +263 -4
  88. package/{chunk-JGRPBIZZ.js → chunk-SQX235S2.js} +1 -1
  89. package/chunk-TT644UJD.js +188 -0
  90. package/{chunk-IYBIRCQV.js → chunk-U34KT53V.js} +29 -11
  91. package/{chunk-KOB75UNU.js → chunk-U5U4WAFS.js} +19 -3
  92. package/{chunk-ANJTRG52.js → chunk-ULQAD7ZY.js} +18 -43
  93. package/{chunk-FDT27L7S.js → chunk-UUPXTEZA.js} +19 -17
  94. package/{chunk-QDA4Y5O6.js → chunk-V67W64OY.js} +21 -17
  95. package/{chunk-I2RMFLLH.js → chunk-V7PCFWX3.js} +1 -1
  96. package/{chunk-HXHSTRGH.js → chunk-VYNMQ6HW.js} +0 -27
  97. package/{chunk-G47IPDOK.js → chunk-W7FGZRLK.js} +1 -1
  98. package/{chunk-7BSQK2UC.js → chunk-WRCZXJ4N.js} +2 -2
  99. package/{chunk-KX6LPG7W.js → chunk-WYJTNSVL.js} +9 -9
  100. package/chunk-Y5GCAMGP.js +9 -0
  101. package/{chunk-JZX2XLKC.js → chunk-YCRROBDY.js} +1 -1
  102. package/{chunk-SCJD2PNK.js → chunk-YPG7TUQD.js} +3 -3
  103. package/{chunk-YANF2RR4.js → chunk-ZPKUJROL.js} +1 -1
  104. package/{chunk-TYND6RDQ.js → chunk-ZZDVBZOP.js} +74 -3
  105. package/{commandRegistry-NE2JOCQT.js → commandRegistry-2DDDET7G.js} +88 -96
  106. package/{contentThunks-B3FRQGP7.js → contentThunks-5DNEHJ2Z.js} +21 -21
  107. package/{createAgentAutomationAction-T2YFJ6MY.js → createAgentAutomationAction-4SUS2EFX.js} +21 -21
  108. package/{createDialogAction-2NFGFBXW.js → createDialogAction-JSFXX6JE.js} +25 -25
  109. package/{createPageAction-LDAVZDN7.js → createPageAction-37HHOXZ2.js} +24 -25
  110. package/{dbSlice-5QGKMQLO.js → dbSlice-6PVPY44C.js} +7 -7
  111. package/{deleteFile-EW6QNRRT.js → deleteFile-YM6NDPAR.js} +5 -5
  112. package/{dialogCommands-H3K7PTF6.js → dialogCommands-ZJRMCP4S.js} +35 -32
  113. package/{dialogSlice-64S3J6CP.js → dialogSlice-2Z66AWEW.js} +20 -20
  114. package/{dist-NJC2W7I4.js → dist-Q2JSMAKA.js} +7 -361
  115. package/{docCreateCommands-KP64KMVL.js → docCreateCommands-KQHQNLRX.js} +32 -30
  116. package/{docDeleteCommands-C3F4SZSR.js → docDeleteCommands-O3DWFX2W.js} +33 -31
  117. package/{docReadCommands-7H6BDOUR.js → docReadCommands-2U2BUONC.js} +32 -30
  118. package/{docStore-NIP7OO4I.js → docStore-XMTUF3GX.js} +8 -8
  119. package/{docUpdateCommands-JDW4BRBH.js → docUpdateCommands-MF3C52XI.js} +32 -30
  120. package/{getPricing-TX35D7PI.js → getPricing-XQ3N3RBP.js} +2 -2
  121. package/{handleSendMessageAction-TOKA7ED7.js → handleSendMessageAction-4VFVXTF2.js} +43 -39
  122. package/index.js +8 -8
  123. package/{localRuntimeAdapter-OPPDLUG3.js → localRuntimeAdapter-KKIVRYVN.js} +70 -69
  124. package/{localRuntimeAuthority-JDAD7CB6.js → localRuntimeAuthority-BPN5OAQG.js} +2 -2
  125. package/{localRuntimeDb-CVC62PM5.js → localRuntimeDb-QIVAXMUL.js} +1 -1
  126. package/{machineCommands-OPLQR7XY.js → machineCommands-UHQVCOD3.js} +80 -79
  127. package/{machineWsRunDispatch-PTS42QDK.js → machineWsRunDispatch-TX4X7TOJ.js} +70 -71
  128. package/{memberThunks-KRV5YXOB.js → memberThunks-AZINUM4S.js} +10 -10
  129. package/package.json +6 -2
  130. package/{profileConfig-ZGOFORWV.js → profileConfig-KN3N2BLF.js} +7 -1
  131. package/{providerPresetApply-CRZFMQD5.js → providerPresetApply-PKUOHQJT.js} +5 -5
  132. package/{providerRegistry-7IS43D3X.js → providerRegistry-HNQLIFN2.js} +5 -5
  133. package/{read-5KAZHHDM.js → read-7JPIWRBQ.js} +5 -5
  134. package/{readDocTool-5QO34OSX.js → readDocTool-AAQTB2Y3.js} +1 -1
  135. package/{readlineWorkspace-3XC7SEMZ.js → readlineWorkspace-BFVB2ON5.js} +375 -200
  136. package/{removeDialogAgentAction-6X63HMI3.js → removeDialogAgentAction-RMVRILLK.js} +9 -9
  137. package/{runAgentClientLoop-5QIGEALK.js → runAgentClientLoop-HHLHNMBE.js} +59 -54
  138. package/{runtimeDoctorCommands-56NWKNON.js → runtimeDoctorCommands-MMCP4B4U.js} +12 -12
  139. package/{secretCommands-ZXZRLR3R.js → secretCommands-DNY56NSU.js} +11 -1
  140. package/{setDialogExtraReferencesAction-4MAYKKYW.js → setDialogExtraReferencesAction-L3V7JTMG.js} +8 -8
  141. package/{setPrimaryDialogAgentAction-EGBAMREH.js → setPrimaryDialogAgentAction-X52JQGTJ.js} +9 -9
  142. package/settingThunks-N6XFWPOU.js +923 -0
  143. package/{spaceCommands-JQN7D4FE.js → spaceCommands-NDPGHDMD.js} +29 -27
  144. package/{streamAgentChatTurn-456DWXNY.js → streamAgentChatTurn-KNPOLET7.js} +154 -95
  145. package/{switchDialogAgentAction-YBKTD6DO.js → switchDialogAgentAction-ZJ5CGU7J.js} +7 -7
  146. package/{tableCommands-U3QDY4L6.js → tableCommands-IVC5S7Y3.js} +11 -11
  147. package/{toolApiClient-7WSJJJBV.js → toolApiClient-HGNO53TC.js} +2 -2
  148. package/{tools-IWNXKK4Y.js → tools-ULA7XJQT.js} +43 -44
  149. package/{tuiSummaryLlmCaller-KLK6K3Q3.js → tuiSummaryLlmCaller-FESHBDTT.js} +7 -7
  150. package/{updateCommands-NQXAGFM7.js → updateCommands-FJHGWD3Q.js} +5 -3
  151. package/{updateDialogTitleAction-SX53FZWO.js → updateDialogTitleAction-VUIVBDAS.js} +21 -21
  152. package/{workloadLifecycle-36DXRZKU.js → workloadLifecycle-6O6PMISX.js} +2 -2
  153. package/chunk-IA7TRNNR.js +0 -11
  154. package/chunk-UKZX3NHN.js +0 -48
  155. package/chunk-VAZHH6FO.js +0 -7012
  156. package/chunk-W4S6OTSC.js +0 -35
  157. package/clipboardy-GCO3GT3I.js +0 -11793
  158. package/settingThunks-FTDRZNSJ.js +0 -1371
  159. package/{agentGrantCommands-HOJ3JBBQ.js → agentGrantCommands-5DPHYEKP.js} +3 -3
  160. package/{chromeOpsCommands-3Z34RKSE.js → chromeOpsCommands-GZVVK7HU.js} +4 -4
  161. package/{chunk-XETG4RIX.js → chunk-AETZ7AD6.js} +4 -4
  162. package/{chunk-2IXDJNZI.js → chunk-GAGGEA7D.js} +3 -3
  163. package/{memoryCommands-CUNBFRVS.js → memoryCommands-ZS3VQJAL.js} +3 -3
  164. package/{offlineMarxistsAgentCommand-2QTHJCHV.js → offlineMarxistsAgentCommand-3GLX4QQY.js} +3 -3
@@ -2,7 +2,7 @@ import {
2
2
  DEVIN_CONNECT_URL,
3
3
  parseSseDataLineJson,
4
4
  parseSseDataLineObject
5
- } from "./chunk-3C2QLERX.js";
5
+ } from "./chunk-KMDDG73K.js";
6
6
  import {
7
7
  applyChatCompletionDelta,
8
8
  applyResponsesToolEvent,
@@ -11,7 +11,7 @@ import {
11
11
  flushChatCompletionStream,
12
12
  providerHttpFailure,
13
13
  throwIfChatCompletionStreamFailed
14
- } from "./chunk-L6EQV5OC.js";
14
+ } from "./chunk-QXZH5UDF.js";
15
15
  import {
16
16
  readSseFrames
17
17
  } from "./chunk-HNUWUO75.js";
@@ -24,15 +24,14 @@ import {
24
24
  } from "./chunk-PWTNI4N7.js";
25
25
  import {
26
26
  hasImageInRuntimeMessages,
27
- resolveAgentContextWindow,
28
27
  stripImagePartsFromMessages
29
- } from "./chunk-ANJTRG52.js";
28
+ } from "./chunk-ULQAD7ZY.js";
30
29
  import {
31
30
  clipToolText,
32
31
  resolveAgentImageInputSupport,
33
32
  resolveHistoricalToolContentCap,
34
33
  resolveToolOutputProfile
35
- } from "./chunk-IYBIRCQV.js";
34
+ } from "./chunk-U34KT53V.js";
36
35
  import {
37
36
  applyShapingCounts,
38
37
  attachProjectionFacts,
@@ -52,7 +51,9 @@ import {
52
51
  finalizeAccumulatedToolCalls
53
52
  } from "./chunk-56GBUMO5.js";
54
53
  import {
54
+ CREDENTIAL_HYGIENE_RULE,
55
55
  DELETE_SAFETY_RED_LINE,
56
+ DISPATCH_BACKEND_POLICY,
56
57
  PARALLEL_DISPATCH_DEFAULT_RULE,
57
58
  PLATFORM_RISK_CONTROL_RULE,
58
59
  TOOL_GUIDED_SECTION_ORDER,
@@ -63,8 +64,9 @@ import {
63
64
  detectDispatchIntentFromMessages,
64
65
  estimateContextTokens,
65
66
  hashStablePrefixContent,
67
+ resolveResponseGuidelines,
66
68
  resolveToolGuidedSections
67
- } from "./chunk-TYND6RDQ.js";
69
+ } from "./chunk-ZZDVBZOP.js";
68
70
  import {
69
71
  classifyUnparsableToolArgs,
70
72
  collectStablePromptPrefix,
@@ -88,22 +90,26 @@ import {
88
90
  toOpenAiCompatibleMessages,
89
91
  toResponsesTools,
90
92
  transferDowngradedToolTurnOrigin
91
- } from "./chunk-6TF64IF2.js";
93
+ } from "./chunk-4L4K6YR7.js";
92
94
  import {
93
95
  BRIDGE_STREAM_MAX_CHARS,
94
96
  DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS,
97
+ DEFAULT_SUBTASK_MAX_TOOL_CALLS,
98
+ DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS,
95
99
  NOLO_WORKSPACE_TOOL_NAMES,
96
100
  applyToolSurfaceConstraints,
97
101
  buildDialogReadEnvelope,
98
102
  buildNoloWorkspaceCommandArgs,
99
103
  buildNoloWorkspaceOpenAiTools,
104
+ buildSubtaskBudgetExhaustedContent,
100
105
  createStreamingDialogReadProjector,
106
+ createSubtaskBudgetTracker,
101
107
  noloPositiveIntegerString,
102
108
  noloStringArg,
103
109
  parseNoloWorkspaceToolArguments,
104
110
  readTextStreamUpToChars,
105
111
  resolveNoloDialogInput
106
- } from "./chunk-QLQ573SU.js";
112
+ } from "./chunk-3M52COK5.js";
107
113
  import {
108
114
  buildDialogFallbackTitleFromUserInput
109
115
  } from "./chunk-2MBTWINN.js";
@@ -114,10 +120,11 @@ import {
114
120
  normalizeUsage,
115
121
  readCacheCreationInputTokens,
116
122
  readCacheReadInputTokens,
123
+ resolveAgentContextWindow,
117
124
  resolveEmptyAssistantFallbackMessage,
118
125
  resolveEmptyAssistantOutcome,
119
126
  resolveTruncatedReasoningTailLog
120
- } from "./chunk-ZWG3C7VI.js";
127
+ } from "./chunk-F3SOW2EU.js";
121
128
  import {
122
129
  COMPACTION_SUMMARY_SCHEMA_VERSION,
123
130
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
@@ -140,7 +147,7 @@ import {
140
147
  sha256Hex,
141
148
  truncateToolOutputForContext,
142
149
  withProviderCallTimingFields
143
- } from "./chunk-2MTE2PEH.js";
150
+ } from "./chunk-QA2C5NKI.js";
144
151
  import {
145
152
  clipCompactText
146
153
  } from "./chunk-5MMAK75Q.js";
@@ -150,6 +157,12 @@ import {
150
157
  import {
151
158
  isAbortError
152
159
  } from "./chunk-7DPNBQSV.js";
160
+ import {
161
+ buildDialogSummaryLayer
162
+ } from "./chunk-VEA7H5FG.js";
163
+ import {
164
+ buildUserResponseLanguageContext
165
+ } from "./chunk-4VJAC32I.js";
153
166
  import {
154
167
  canonicalizeToolName,
155
168
  canonicalizeToolNames
@@ -164,16 +177,16 @@ import {
164
177
  import {
165
178
  asOptionalPositiveFiniteNumber
166
179
  } from "./chunk-U6VC4MU4.js";
167
- import {
168
- asOptionalFiniteNumber
169
- } from "./chunk-WWC7I6TA.js";
170
180
  import {
171
181
  estimateTokenCount
172
182
  } from "./chunk-PSCNXBYA.js";
183
+ import {
184
+ asOptionalFiniteNumber
185
+ } from "./chunk-WWC7I6TA.js";
173
186
  import {
174
187
  buildProviderAuthHeaders,
175
188
  buildProviderExecutionPlan
176
- } from "./chunk-SUKSWFLP.js";
189
+ } from "./chunk-PIG2IUVZ.js";
177
190
  import {
178
191
  isRecord
179
192
  } from "./chunk-KUG52IAP.js";
@@ -195,12 +208,6 @@ import {
195
208
  import {
196
209
  resolveNoloStateDir
197
210
  } from "./chunk-ZWQUWF6W.js";
198
- import {
199
- buildDialogSummaryLayer
200
- } from "./chunk-VEA7H5FG.js";
201
- import {
202
- buildUserResponseLanguageContext
203
- } from "./chunk-4VJAC32I.js";
204
211
  import {
205
212
  __export
206
213
  } from "./chunk-4VNS5WPM.js";
@@ -14047,8 +14054,11 @@ function detectExecShellSynchronousWarnings(command, shell) {
14047
14054
  }
14048
14055
 
14049
14056
  // packages/agent-runtime/workspaceShell.ts
14050
- import { resolve } from "node:path";
14057
+ import { createWriteStream, mkdirSync as mkdirSync2 } from "node:fs";
14058
+ import { dirname, join as join4, resolve } from "node:path";
14051
14059
  import { spawn as spawnChildProcess } from "node:child_process";
14060
+ import { randomUUID } from "node:crypto";
14061
+ import { tmpdir } from "node:os";
14052
14062
 
14053
14063
  // packages/agent-runtime/runtimeCompat.ts
14054
14064
  import { existsSync as existsSync2, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
@@ -14984,39 +14994,168 @@ function truncateToolOutput(value, limit = 2e4, options) {
14984
14994
  ${tail}`;
14985
14995
  }
14986
14996
  var DEFAULT_MAX_STREAM_BUFFER_BYTES = 5 * 1024 * 1024;
14987
- function readNodeStream(stream, maxBytes = DEFAULT_MAX_STREAM_BUFFER_BYTES) {
14997
+ function readNodeStream(stream, maxBytesOrOptions = DEFAULT_MAX_STREAM_BUFFER_BYTES) {
14988
14998
  if (!stream) return Promise.resolve("");
14999
+ const options = typeof maxBytesOrOptions === "number" ? { maxBytes: maxBytesOrOptions } : maxBytesOrOptions ?? {};
15000
+ const maxBytes = typeof options.maxBytes === "number" && Number.isFinite(options.maxBytes) && options.maxBytes >= 0 ? options.maxBytes : DEFAULT_MAX_STREAM_BUFFER_BYTES;
15001
+ const spillPath = asOptionalTrimmedString(options.spillPath);
15002
+ const createSink = options.spillSinkFactory ?? ((path) => createWriteStream(path));
14989
15003
  return new Promise((resolveStream, rejectStream) => {
14990
15004
  const chunks2 = [];
14991
15005
  let totalBytes = 0;
14992
15006
  let settled = false;
15007
+ let truncated = false;
15008
+ let spillState = spillPath ? "idle" : "disabled";
15009
+ let spillError = null;
15010
+ let spillSink = null;
15011
+ let sourcePausedForSpill = false;
15012
+ let sinkFinished = false;
14993
15013
  const formatLimit = maxBytes >= 1024 * 1024 ? `${Math.round(maxBytes / (1024 * 1024))}MB` : `${Math.round(maxBytes / 1024)}KB`;
14994
- const finalize2 = (truncated = false) => {
15014
+ const resumeSourceIfPaused = () => {
15015
+ if (!sourcePausedForSpill) return;
15016
+ sourcePausedForSpill = false;
15017
+ try {
15018
+ stream.resume?.();
15019
+ } catch {
15020
+ }
15021
+ };
15022
+ const markSpillFailed = (error) => {
15023
+ if (spillState === "failed") return;
15024
+ spillState = "failed";
15025
+ if (!spillError) {
15026
+ spillError = toErrorMessage(error);
15027
+ }
15028
+ const sink = spillSink;
15029
+ spillSink = null;
15030
+ if (sink) {
15031
+ try {
15032
+ sink.destroy?.();
15033
+ } catch {
15034
+ }
15035
+ }
15036
+ resumeSourceIfPaused();
15037
+ };
15038
+ const writeToSink = (buf) => {
15039
+ const sink = spillSink;
15040
+ if (!sink || spillState !== "open") return;
15041
+ if (sink.destroyed === true) {
15042
+ markSpillFailed(new Error("spill writable closed before finish"));
15043
+ return;
15044
+ }
15045
+ let accepted = true;
15046
+ try {
15047
+ accepted = sink.write(buf) !== false;
15048
+ } catch (error) {
15049
+ markSpillFailed(error);
15050
+ return;
15051
+ }
15052
+ if (!accepted && !sourcePausedForSpill) {
15053
+ sourcePausedForSpill = true;
15054
+ try {
15055
+ stream.pause?.();
15056
+ } catch {
15057
+ sourcePausedForSpill = false;
15058
+ }
15059
+ }
15060
+ };
15061
+ const openSpill = (headChunks, crossingChunk) => {
15062
+ if (!spillPath || spillState !== "idle") return;
15063
+ let sink;
15064
+ try {
15065
+ mkdirSync2(dirname(spillPath), { recursive: true });
15066
+ sink = createSink(spillPath);
15067
+ sink.on("error", (error) => markSpillFailed(error));
15068
+ sink.on("drain", () => {
15069
+ if (settled) return;
15070
+ resumeSourceIfPaused();
15071
+ });
15072
+ sink.on("finish", () => {
15073
+ sinkFinished = true;
15074
+ });
15075
+ sink.on("close", () => {
15076
+ if (sinkFinished || spillState !== "open") return;
15077
+ markSpillFailed(new Error("spill writable closed before finish"));
15078
+ });
15079
+ } catch (error) {
15080
+ spillState = "failed";
15081
+ spillError = toErrorMessage(error);
15082
+ spillSink = null;
15083
+ return;
15084
+ }
15085
+ spillSink = sink;
15086
+ spillState = "open";
15087
+ for (const head3 of headChunks) writeToSink(head3);
15088
+ writeToSink(crossingChunk);
15089
+ };
15090
+ const finalize2 = (wasTruncated) => {
14995
15091
  if (settled) return;
14996
15092
  settled = true;
14997
- let text2 = Buffer.concat(chunks2).toString("utf8");
14998
- if (truncated) {
14999
- text2 += `
15093
+ const truncatedNow = wasTruncated || truncated;
15094
+ const baseText = Buffer.concat(chunks2).toString("utf8");
15095
+ const done4 = () => {
15096
+ let text2 = baseText;
15097
+ if (truncatedNow) {
15098
+ const notes = [`output exceeded ${formatLimit} buffer limit`];
15099
+ if (spillState === "ok") {
15100
+ notes.push(`full output: ${spillPath}`);
15101
+ } else if (spillPath) {
15102
+ notes.push(
15103
+ `spill failed${spillError ? ` (${spillError})` : ""}; output incomplete`
15104
+ );
15105
+ }
15106
+ text2 += `
15000
15107
 
15001
- [stream pipe truncated: output exceeded ${formatLimit} buffer limit]`;
15108
+ [stream pipe truncated: ${notes.join("; ")}]`;
15109
+ }
15110
+ resolveStream(text2);
15111
+ };
15112
+ const sink = spillSink;
15113
+ if (!sink || spillState !== "open") {
15114
+ done4();
15115
+ return;
15116
+ }
15117
+ let closed = false;
15118
+ const settleSink = (failed, error) => {
15119
+ if (closed) return;
15120
+ closed = true;
15121
+ if (failed) {
15122
+ markSpillFailed(error ?? new Error("spill write failed"));
15123
+ } else if (spillState === "open") {
15124
+ spillState = "ok";
15125
+ }
15126
+ done4();
15127
+ };
15128
+ if (sink.destroyed === true) {
15129
+ settleSink(true, new Error("spill writable closed before finish"));
15130
+ return;
15131
+ }
15132
+ sink.once("error", (error) => settleSink(true, error));
15133
+ sink.once("finish", () => settleSink(false));
15134
+ sink.once("close", () => {
15135
+ settleSink(!sinkFinished, new Error("spill writable closed before finish"));
15136
+ });
15137
+ try {
15138
+ sink.end?.();
15139
+ } catch (error) {
15140
+ settleSink(true, error);
15002
15141
  }
15003
- resolveStream(text2);
15004
15142
  };
15005
15143
  stream.on("data", (chunk) => {
15006
15144
  if (settled) return;
15007
15145
  const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
15146
+ if (truncated) {
15147
+ writeToSink(buf);
15148
+ return;
15149
+ }
15008
15150
  if (totalBytes + buf.length >= maxBytes) {
15009
15151
  const remaining = Math.max(0, maxBytes - totalBytes);
15152
+ const headChunks = chunks2.slice();
15010
15153
  if (remaining > 0) {
15011
15154
  chunks2.push(buf.subarray(0, remaining));
15012
15155
  }
15013
- try {
15014
- if (typeof stream.destroy === "function") {
15015
- stream.destroy();
15016
- }
15017
- } catch {
15018
- }
15019
- finalize2(true);
15156
+ totalBytes += buf.length;
15157
+ truncated = true;
15158
+ openSpill(headChunks, buf);
15020
15159
  return;
15021
15160
  }
15022
15161
  totalBytes += buf.length;
@@ -15025,6 +15164,19 @@ function readNodeStream(stream, maxBytes = DEFAULT_MAX_STREAM_BUFFER_BYTES) {
15025
15164
  stream.on("error", (error) => {
15026
15165
  if (settled) return;
15027
15166
  settled = true;
15167
+ const sink = spillSink;
15168
+ spillSink = null;
15169
+ if (!spillError) spillError = toErrorMessage(error);
15170
+ if (spillState !== "failed" && spillState !== "disabled") {
15171
+ spillState = "failed";
15172
+ }
15173
+ if (sink) {
15174
+ try {
15175
+ sink.destroy?.();
15176
+ } catch {
15177
+ }
15178
+ }
15179
+ resumeSourceIfPaused();
15028
15180
  rejectStream(error);
15029
15181
  });
15030
15182
  stream.on("end", () => finalize2(false));
@@ -15099,7 +15251,7 @@ async function runWorkspaceCommand(args2) {
15099
15251
  proc.stdin.write(args2.stdin);
15100
15252
  proc.stdin.end();
15101
15253
  }
15102
- const label = deriveLabel(args2.command.join(" "));
15254
+ const label = args2.label?.trim() || deriveLabel(args2.command.join(" "));
15103
15255
  const registry2 = getProcessRegistry();
15104
15256
  if (typeof proc.pid === "number") {
15105
15257
  registry2.add({
@@ -15137,8 +15289,12 @@ async function runWorkspaceCommand(args2) {
15137
15289
  process.removeListener("SIGINT", cleanupChildOnHostSignal);
15138
15290
  };
15139
15291
  exitPromise.then(detachSignalCleanup, detachSignalCleanup);
15140
- const stdoutCapture = stdoutPromiseResult(readNodeStream(proc.stdout));
15141
- const stderrCapture = stdoutPromiseResult(readNodeStream(proc.stderr));
15292
+ const stdoutCapture = stdoutPromiseResult(
15293
+ readNodeStream(proc.stdout, { spillPath: join4(tmpdir(), `nolo-stream-${randomUUID()}.log`) })
15294
+ );
15295
+ const stderrCapture = stdoutPromiseResult(
15296
+ readNodeStream(proc.stderr, { spillPath: join4(tmpdir(), `nolo-stream-${randomUUID()}-stderr.log`) })
15297
+ );
15142
15298
  const killChild = (signal) => {
15143
15299
  if (detached && typeof proc.pid === "number") {
15144
15300
  try {
@@ -15344,6 +15500,10 @@ function buildExecShellToolDefinition(toolName = "execShell") {
15344
15500
  background: {
15345
15501
  type: "boolean",
15346
15502
  description: "Immediately detach this command into a tracked background task (no 120s synchronous wait): returns {detached: true, taskId}, and on completion the platform resumes this conversation with a bounded result capsule (exitCode, duration, stdout/stderr tail). Default false. Use for finite jobs (tests, builds, batch) whose result you need later; NOT for dev servers/watchers \u2014 use launchProcess for those."
15503
+ },
15504
+ label: {
15505
+ type: "string",
15506
+ description: "Optional human-readable label for the resulting background task, shown in the task list and completion notices. Defaults to the command's last token, which is unhelpful for pipelines (e.g. '| tail -25' yields '-25')."
15347
15507
  }
15348
15508
  }
15349
15509
  }
@@ -15392,7 +15552,8 @@ function normalizeExecShellInput(input) {
15392
15552
  ...login !== void 0 ? { login } : {},
15393
15553
  ...activity ? { activity } : {},
15394
15554
  ...record2.input !== void 0 ? { input: record2.input } : {},
15395
- ...background ? { background: true } : {}
15555
+ ...background ? { background: true } : {},
15556
+ ...typeof record2.label === "string" && record2.label.trim() ? { label: record2.label.trim() } : {}
15396
15557
  };
15397
15558
  }
15398
15559
  throw new Error("execShell requires a non-empty command.");
@@ -15457,6 +15618,7 @@ var execShellCapability = {
15457
15618
  abortSignal: ctx.abortSignal,
15458
15619
  detachMs: background ? 0 : isImmediateDetachShellCommand({ command }) ? 0 : ctx.detachMs,
15459
15620
  stdin: typeof normalized.input === "string" ? normalized.input : void 0,
15621
+ label: typeof normalized.label === "string" ? normalized.label : void 0,
15460
15622
  // Ownership of the turn that invoked this command: an auto-detached
15461
15623
  // command keeps its parent dialog so its terminal can resume that
15462
15624
  // conversation (see processOwnership.ts). Absent ctx.owner = unowned.
@@ -15541,11 +15703,11 @@ async function invokeCapability(capabilityOrName, input, ctx = {}) {
15541
15703
  }
15542
15704
 
15543
15705
  // packages/agent-runtime/localWorkspaceTools.ts
15544
- import { existsSync as existsSync3 } from "node:fs";
15706
+ import { existsSync as existsSync4 } from "node:fs";
15545
15707
  import { createHash as createHash4 } from "node:crypto";
15546
15708
  import { lstat, mkdir, readdir as readdir2, readFile as readFile3, realpath, stat as stat3, writeFile } from "node:fs/promises";
15547
15709
  import { homedir } from "node:os";
15548
- import { dirname, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve4, sep } from "node:path";
15710
+ import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve4, sep } from "node:path";
15549
15711
  import { spawn as spawnChildProcess3 } from "node:child_process";
15550
15712
 
15551
15713
  // packages/core/readRangeLedger.ts
@@ -16827,7 +16989,7 @@ function resolveRipgrepBinary(env = process.env) {
16827
16989
  const fromEnv = asOptionalTrimmedString(env.NOLO_BUNDLED_RG);
16828
16990
  if (fromEnv) {
16829
16991
  try {
16830
- if (existsSync3(fromEnv)) return fromEnv;
16992
+ if (existsSync4(fromEnv)) return fromEnv;
16831
16993
  } catch {
16832
16994
  }
16833
16995
  }
@@ -16933,6 +17095,7 @@ ${tail}`,
16933
17095
  };
16934
17096
  }
16935
17097
  var READ_FILE_LEDGER_MAX_RECORDS = 64;
17098
+ var READ_FILE_LEDGER_MAX_KEYS = 256;
16936
17099
  async function readFileTool(args2) {
16937
17100
  const parsed = parseWorkspaceToolArguments(args2.call.arguments);
16938
17101
  const requestedPath = requireWorkspaceToolPath(parsed);
@@ -16971,6 +17134,8 @@ async function readFileTool(args2) {
16971
17134
  const retainedCap = resolveHistoricalToolContentCap("readFile", 0);
16972
17135
  const retained = filterRetainedLedgerRecords(entry.records, retainedCap);
16973
17136
  if (retained.length > 0 && isLineRangeCovered(requestRange, retained)) {
17137
+ ledger.delete(relativePath);
17138
+ ledger.set(relativePath, entry);
16974
17139
  return {
16975
17140
  content: `[readFile] ${relativePath} lines ${requestRange.startLine}-${requestRange.endLine} were already delivered earlier and the file is unchanged; not resending. Pass force:true to refetch.`,
16976
17141
  metadata: {
@@ -17003,10 +17168,16 @@ async function readFileTool(args2) {
17003
17168
  const persistedChars = truncatedRead.content.length + "\n\n[tool metadata]\n".length + JSON.stringify(metadata).length;
17004
17169
  const records = entry?.records ?? [];
17005
17170
  records.push({ ...requestRange, chars: persistedChars });
17171
+ ledger.delete(relativePath);
17006
17172
  ledger.set(relativePath, {
17007
17173
  fingerprint,
17008
17174
  records: records.slice(-READ_FILE_LEDGER_MAX_RECORDS)
17009
17175
  });
17176
+ while (ledger.size > READ_FILE_LEDGER_MAX_KEYS) {
17177
+ const oldestKey = ledger.keys().next().value;
17178
+ if (oldestKey === void 0) break;
17179
+ ledger.delete(oldestKey);
17180
+ }
17010
17181
  }
17011
17182
  return { content: truncatedRead.content, metadata };
17012
17183
  }
@@ -17019,7 +17190,7 @@ async function writeFileTool(args2) {
17019
17190
  requestedPath,
17020
17191
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17021
17192
  });
17022
- await mkdir(dirname(absolutePath), { recursive: true });
17193
+ await mkdir(dirname2(absolutePath), { recursive: true });
17023
17194
  await writeFile(absolutePath, content, "utf8");
17024
17195
  const relativePath = normalizeWorkspaceRelativePath({
17025
17196
  workspaceRoot: resolve4(args2.workspaceRoot),
@@ -17476,7 +17647,7 @@ async function execShellTool(args2) {
17476
17647
  );
17477
17648
  }
17478
17649
  var LAUNCH_PROCESS_STREAM_RING_CHARS = 65536;
17479
- var LAUNCH_PROCESS_STREAM_CAPTURE_MAX_CHARS = 4e6;
17650
+ var LAUNCH_PROCESS_STREAM_CAPTURE_MAX_CHARS = 1e6;
17480
17651
  function createLaunchProcessStreamCapture() {
17481
17652
  let ring = "";
17482
17653
  let full = null;
@@ -18457,7 +18628,11 @@ async function executeToolCall(args2) {
18457
18628
  ...userInputText ? { userInput: userInputText } : {},
18458
18629
  ...input.runtimeContext ? { runtimeContext: input.runtimeContext } : {},
18459
18630
  ...args2.runToolNames ? { runToolNames: args2.runToolNames } : {},
18460
- ...input.abortSignal ? { abortSignal: input.abortSignal } : {}
18631
+ ...input.abortSignal ? { abortSignal: input.abortSignal } : {},
18632
+ // 定档信号:来源只由 turn 输入推导,不让模型/参数层参与。
18633
+ // 三级判据见 plan §10——后台运行优先于子 run(后台派发的子 run 仍是
18634
+ // 无人值守的,按 automation 报更保守)。
18635
+ origin: input.background ? "automation" : input.runKind === "subtask" ? "agent" : "chat"
18461
18636
  }, {
18462
18637
  ...input.abortSignal ? { abortSignal: input.abortSignal } : {},
18463
18638
  ...input.runtimeContext ? { runtimeContext: input.runtimeContext } : {}
@@ -18696,7 +18871,7 @@ var normalizeContextBlockScopes = (legacyBlocks = void 0, scopes = void 0) => {
18696
18871
  };
18697
18872
 
18698
18873
  // packages/agent-runtime/localAutoCompaction.ts
18699
- import { randomUUID } from "node:crypto";
18874
+ import { randomUUID as randomUUID2 } from "node:crypto";
18700
18875
  function toPlanCompressionMessages(history) {
18701
18876
  return history.map((message, index) => ({
18702
18877
  id: typeof message.id === "string" && message.id.length > 0 ? message.id : `local-${index}`,
@@ -18931,7 +19106,7 @@ async function maybeAutoCompactLocalHistory(args2) {
18931
19106
  };
18932
19107
  }
18933
19108
  emitPhase({ kind: "compaction-start" });
18934
- const compactionAttemptId = randomUUID();
19109
+ const compactionAttemptId = randomUUID2();
18935
19110
  let compactionT0 = Date.now();
18936
19111
  let compactionInputTokens;
18937
19112
  let compactionPrevSummaryTokens;
@@ -19611,6 +19786,17 @@ async function runLocalAgentTurn(input) {
19611
19786
  observationBoundary.attachCallbacks(legacyCallbacks);
19612
19787
  }
19613
19788
  const loopTiming = createLoopTiming();
19789
+ const subtaskBudgetClock = input.subtaskBudgetNow ?? (() => Date.now());
19790
+ const subtaskBudgetLimits = {
19791
+ maxToolCalls: input.subtaskMaxToolCalls ?? input.subtaskBudgetLimits?.maxToolCalls ?? DEFAULT_SUBTASK_MAX_TOOL_CALLS,
19792
+ maxWallClockMs: input.subtaskMaxWallClockMs ?? input.subtaskBudgetLimits?.maxWallClockMs ?? DEFAULT_SUBTASK_MAX_WALL_CLOCK_MS
19793
+ };
19794
+ const subtaskBudgetTracker = input.runKind === "subtask" ? createSubtaskBudgetTracker({
19795
+ limits: subtaskBudgetLimits,
19796
+ now: subtaskBudgetClock,
19797
+ // 墙钟从 run 开始计(含 provider 初始化与首轮前的准备)。
19798
+ startedAtMs: subtaskBudgetClock()
19799
+ }) : null;
19614
19800
  try {
19615
19801
  loopTiming.mark("turnStart", 0);
19616
19802
  let agentConfig = await input.adapter.loadAgentConfig(input.agentRef);
@@ -19750,18 +19936,38 @@ async function runLocalAgentTurn(input) {
19750
19936
  input.contextBlocks,
19751
19937
  input.contextBlockScopes
19752
19938
  );
19939
+ const responseGuidelines = resolveResponseGuidelines(
19940
+ input.responseViewport ?? "unknown"
19941
+ );
19942
+ const responseGuidelineScopes = [
19943
+ { content: responseGuidelines.behavior, cacheScope: "session" },
19944
+ ...responseGuidelines.presentation.trim().length > 0 ? [
19945
+ {
19946
+ content: responseGuidelines.presentation,
19947
+ cacheScope: "session"
19948
+ }
19949
+ ] : []
19950
+ ];
19753
19951
  const mergedContextBlockScopes = [
19754
19952
  // 删除安全红线:系统层最高优先级约束,位于所有块之前(含身份信息块),
19755
19953
  // owner 要求常驻「根本提示词」的最顶部(2026-09-26 批量误删事故)。
19756
19954
  { content: DELETE_SAFETY_RED_LINE, cacheScope: "session" },
19955
+ // 凭据纪律:与红线同为系统层固定块,紧随其后(四条装配线同源)。
19956
+ { content: CREDENTIAL_HYGIENE_RULE, cacheScope: "session" },
19757
19957
  // 并行是默认:系统层固定块,紧随红线(localLoop 无 static 作用域,用 session 占位,
19758
19958
  // 「最顶」由数组首位保证——与红线同一约定)。
19759
19959
  { content: PARALLEL_DISPATCH_DEFAULT_RULE, cacheScope: "session" },
19960
+ // 派发落点:并行派发纪律的下一层(派到哪个执行后端),沿用 session 占位约定。
19961
+ { content: DISPATCH_BACKEND_POLICY, cacheScope: "session" },
19760
19962
  // 平台风控纪律:无条件系统层块,沿用 session 占位约定。
19761
19963
  { content: PLATFORM_RISK_CONTROL_RULE, cacheScope: "session" },
19762
19964
  { content: buildConsultationModeBlock(), cacheScope: "session" },
19763
19965
  { content: identityBlock, cacheScope: "session" },
19764
19966
  ...guidanceScopes,
19967
+ // 回复行为准则:local 线(CLI 非交互 / 桌面 / TUI)的唯一注入边界。
19968
+ // 行为段恒注入;排版段只在宿主声明了可确认的展示能力时追加一份
19969
+ // (unknown = 拿不到视口信息,不得猜成宽屏或窄屏)。两块同属 session scope。
19970
+ ...responseGuidelineScopes,
19765
19971
  ...callerScopes
19766
19972
  ];
19767
19973
  loopTiming.mark("buildContextBlocks", 0);
@@ -19826,12 +20032,8 @@ async function runLocalAgentTurn(input) {
19826
20032
  `[nolo] rewrote ${stats.rewrittenToolCalls} tool calls in ${stats.rewrittenAssistantMessages} assistant messages and ${stats.rewrittenToolMessages} tool-result messages (bad arguments: truncated=${stats.badArguments.truncated}, malformed=${stats.badArguments.malformed}); persisted history untouched`
19827
20033
  );
19828
20034
  }
19829
- const supportsImages = resolveAgentImageInputSupport({
19830
- apiSource: agentConfig.apiSource,
19831
- provider: agentConfig.provider,
19832
- model: agentConfig.model,
19833
- hasVision: agentConfig.hasVision
19834
- });
20035
+ const supportsImages = resolveAgentImageInputSupport(agentConfig);
20036
+ let imageDowngradeEmitted = false;
19835
20037
  if (!supportsImages && hasImageInRuntimeMessages(messages)) {
19836
20038
  messages = filterImagePartsFromMessages(messages, false);
19837
20039
  emitLoopEvent(observationBoundary, {
@@ -19839,6 +20041,7 @@ async function runLocalAgentTurn(input) {
19839
20041
  reason: "no-vision",
19840
20042
  atMs: Date.now()
19841
20043
  });
20044
+ imageDowngradeEmitted = true;
19842
20045
  }
19843
20046
  const prefixCount = builtMessages.prefixCount;
19844
20047
  const capToolMessage = (msg) => msg.role === "tool" && typeof msg.content === "string" ? {
@@ -19853,7 +20056,7 @@ async function runLocalAgentTurn(input) {
19853
20056
  });
19854
20057
  const userInputText = extractUserInputText(input.input);
19855
20058
  let toolCallCount = 0;
19856
- let result4;
20059
+ let result4 = { content: "" };
19857
20060
  const usageLedger = createTurnUsageLedger({
19858
20061
  model: agentConfig.model,
19859
20062
  provider: agentConfig.provider,
@@ -19865,12 +20068,36 @@ async function runLocalAgentTurn(input) {
19865
20068
  if (initialCompactionUsage) usageLedger.addCompaction(initialCompactionUsage);
19866
20069
  let loopError;
19867
20070
  let round = 0;
20071
+ let budgetExhaustion = null;
20072
+ const executedToolNameLog = [];
20073
+ const markBudgetExhausted = () => {
20074
+ if (!subtaskBudgetTracker || budgetExhaustion) return;
20075
+ const exhaustion = subtaskBudgetTracker.exhaustion();
20076
+ if (!exhaustion) return;
20077
+ budgetExhaustion = exhaustion;
20078
+ emitLoopEvent(observationBoundary, {
20079
+ kind: "budget-exhausted",
20080
+ limit: exhaustion.limit,
20081
+ atMs: exhaustion.atMs,
20082
+ maxToolCalls: exhaustion.limits.maxToolCalls,
20083
+ maxWallClockMs: exhaustion.limits.maxWallClockMs,
20084
+ toolCallsExecuted: exhaustion.toolCallsExecuted,
20085
+ elapsedMs: exhaustion.elapsedMs,
20086
+ round
20087
+ });
20088
+ };
19868
20089
  let emptyAssistantRepairPending = false;
19869
20090
  let emptyAssistantRepairUsed = false;
19870
20091
  let reasoningEmptyRepairCount = 0;
19871
20092
  let skipFinalAppend = false;
19872
20093
  let partialContent = "";
19873
20094
  const progressGuard = createLocalLoopProgressGuard(input.progressGuardConfig);
20095
+ const budgetAdmissionGate = () => {
20096
+ if (!subtaskBudgetTracker) return true;
20097
+ if (!subtaskBudgetTracker.isExhausted()) return true;
20098
+ markBudgetExhausted();
20099
+ return false;
20100
+ };
19874
20101
  try {
19875
20102
  const provider = await resolveProviderOnce();
19876
20103
  const applyPendingInjections = () => {
@@ -19905,6 +20132,14 @@ async function runLocalAgentTurn(input) {
19905
20132
  roundBudgetWarningInjected = true;
19906
20133
  }
19907
20134
  const preparedMessages = prepareMessagesForProviderCall(transcript.working());
20135
+ if (!supportsImages && hasImageInRuntimeMessages(preparedMessages.messages) && !imageDowngradeEmitted) {
20136
+ emitLoopEvent(observationBoundary, {
20137
+ kind: "image-downgraded",
20138
+ reason: "no-vision",
20139
+ atMs: Date.now()
20140
+ });
20141
+ imageDowngradeEmitted = true;
20142
+ }
19908
20143
  const baseRequestMessages = filterImagePartsFromMessages(
19909
20144
  preparedMessages.messages,
19910
20145
  supportsImages
@@ -19939,6 +20174,9 @@ async function runLocalAgentTurn(input) {
19939
20174
  messages: requestMessages,
19940
20175
  toolsHash: safeToolNamesHash(agentTools)
19941
20176
  });
20177
+ if (!budgetAdmissionGate()) {
20178
+ break;
20179
+ }
19942
20180
  result4 = await runCompleteWithTimeout({
19943
20181
  provider,
19944
20182
  messages: requestMessages,
@@ -20127,6 +20365,11 @@ ${reasoningTailLog}
20127
20365
  const slotResults = new Array(toolCalls.length);
20128
20366
  const runSingleTool = async ({ index, toolCall }) => {
20129
20367
  throwIfAborted(input);
20368
+ if (!budgetAdmissionGate()) {
20369
+ skippedToolCalls.push(toolCall);
20370
+ return;
20371
+ }
20372
+ subtaskBudgetTracker?.recordToolCallExecuted();
20130
20373
  const { toolResult, toolExecMs } = await executeToolCall({
20131
20374
  input,
20132
20375
  toolCall,
@@ -20146,6 +20389,7 @@ ${reasoningTailLog}
20146
20389
  toolResult,
20147
20390
  toolExecMs
20148
20391
  };
20392
+ executedToolNameLog.push(toolCall.function.name);
20149
20393
  };
20150
20394
  const commitSlot = (i) => {
20151
20395
  const toolCall = toolCalls[i];
@@ -20171,6 +20415,7 @@ ${reasoningTailLog}
20171
20415
  ...observedMetadata ? { tool_result_metadata: observedMetadata } : {}
20172
20416
  });
20173
20417
  };
20418
+ const skippedToolCalls = [];
20174
20419
  const batches = partitionToolCallsIntoBatches(toolCalls);
20175
20420
  for (const batch of batches) {
20176
20421
  throwIfAborted(input);
@@ -20194,6 +20439,17 @@ ${reasoningTailLog}
20194
20439
  }
20195
20440
  if (batchError) throw batchError;
20196
20441
  }
20442
+ for (const skipped of skippedToolCalls) {
20443
+ transcript.pushTool({
20444
+ role: "tool",
20445
+ content: "[\u5B50\u4EFB\u52A1\u9884\u7B97\u4E0A\u9650\u5DF2\u89E6\u53D1] \u8BE5\u5DE5\u5177\u8C03\u7528\u672A\u6267\u884C\uFF1A\u5DF2\u8FBE\u5B50\u4EFB\u52A1\u9884\u7B97\u4E0A\u9650\uFF0C\u672C\u8F6E\u4E0D\u518D\u53D1\u8D77\u65B0\u7684\u5DE5\u5177\u8C03\u7528\u3002",
20446
+ tool_call_id: skipped.id,
20447
+ toolName: skipped.function.name
20448
+ });
20449
+ }
20450
+ if (budgetExhaustion) {
20451
+ break;
20452
+ }
20197
20453
  const toolExecutionGuardVerdict = progressGuard.observeToolExecution(
20198
20454
  toolCalls,
20199
20455
  executedToolResults
@@ -20215,12 +20471,29 @@ ${reasoningTailLog}
20215
20471
  break;
20216
20472
  }
20217
20473
  await compaction.maybeCompactInLoop();
20474
+ if (!budgetAdmissionGate()) {
20475
+ break;
20476
+ }
20218
20477
  loopTiming.mark("roundEnd", round);
20219
20478
  round += 1;
20220
20479
  }
20221
20480
  } catch (error) {
20222
20481
  loopError = error;
20223
20482
  }
20483
+ if (budgetExhaustion) {
20484
+ const previousContent = typeof result4?.content === "string" ? result4.content.trim() : "";
20485
+ result4 = {
20486
+ ...result4,
20487
+ content: [
20488
+ previousContent,
20489
+ buildSubtaskBudgetExhaustedContent({
20490
+ exhaustion: budgetExhaustion,
20491
+ roundsCompleted: round,
20492
+ recentToolNames: executedToolNameLog
20493
+ })
20494
+ ].filter((part) => part.length > 0).join("\n\n")
20495
+ };
20496
+ }
20224
20497
  if (loopError) {
20225
20498
  const turnMessages2 = transcript.persisted(
20226
20499
  sanitizedPersistedInput,
@@ -21671,7 +21944,7 @@ function buildLoadSkillExecutor(args2) {
21671
21944
  const { resolveSkillByName } = await import("./skillDiscovery-QC35EQY4.js");
21672
21945
  const resolved = resolveSkillByName(args2.cwd, name);
21673
21946
  if (!resolved) {
21674
- const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-A6VSPJEJ.js");
21947
+ const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-LJV7FHNI.js");
21675
21948
  const builtin = resolveBuiltinSkillByName(name);
21676
21949
  if (builtin) {
21677
21950
  return {
@@ -21749,7 +22022,7 @@ function resolveSessionKey(args2) {
21749
22022
  }
21750
22023
 
21751
22024
  // packages/agent-runtime/devin/devinProvider.ts
21752
- import { randomBytes, randomUUID as randomUUID2 } from "node:crypto";
22025
+ import { randomBytes, randomUUID as randomUUID3 } from "node:crypto";
21753
22026
  var CLIENT_NAME = "chisel";
21754
22027
  var CLIENT_VERSION = "3000.11.3";
21755
22028
  function writeVarint(fieldNum, value) {
@@ -21809,7 +22082,7 @@ function encodeDevinClientMetadata(token) {
21809
22082
  ]);
21810
22083
  }
21811
22084
  function devinId(id, purpose) {
21812
- return id?.sessionKey && isStableSessionIdentityEnabled() ? deriveStableUuid(id.sessionKey, purpose) : randomUUID2();
22085
+ return id?.sessionKey && isStableSessionIdentityEnabled() ? deriveStableUuid(id.sessionKey, purpose) : randomUUID3();
21813
22086
  }
21814
22087
  function encodeDevinChatMessage(msg, identity2, index = 0) {
21815
22088
  const source = msg.role === "assistant" ? 2 : msg.role === "tool" ? 4 : 1;
@@ -21903,7 +22176,7 @@ ${item.text}`;
21903
22176
  const chatMessageBuffers = coalesced.map((m, i) => encodeDevinChatMessage(m, identity2, i));
21904
22177
  const completionConfig = buildCompletionConfig({ temperature });
21905
22178
  const modelConfig = Buffer.concat([
21906
- writeStringField(1, randomUUID2()),
22179
+ writeStringField(1, randomUUID3()),
21907
22180
  writeVarint(2, 1),
21908
22181
  writeVarint(3, 4)
21909
22182
  ]);
@@ -21915,7 +22188,7 @@ ${item.text}`;
21915
22188
  writeMessageField(8, completionConfig),
21916
22189
  ...tools.map((tool) => writeMessageField(10, encodeDevinToolDefinition(tool))),
21917
22190
  writeMessageField(15, modelConfig),
21918
- writeStringField(16, randomUUID2()),
22191
+ writeStringField(16, randomUUID3()),
21919
22192
  writeVarint(20, 1),
21920
22193
  writeStringField(21, model)
21921
22194
  ]);