pybao-cli 1.5.11 → 1.5.13

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 (162) hide show
  1. package/dist/REPL-4ET7DK5F.js +50 -0
  2. package/dist/{acp-NSVRKFDR.js → acp-6D6QDJQY.js} +31 -31
  3. package/dist/{agentsValidate-J4WH47PD.js → agentsValidate-XFP3HZ4H.js} +7 -7
  4. package/dist/{ask-TIOWV5TX.js → ask-6CZRJCSZ.js} +30 -30
  5. package/dist/{autoUpdater-35O63ORK.js → autoUpdater-VCCPGPDD.js} +3 -3
  6. package/dist/{chunk-5MFIJREB.js → chunk-2L7XKUEG.js} +7 -1
  7. package/dist/chunk-2L7XKUEG.js.map +7 -0
  8. package/dist/{chunk-2TZLPLK6.js → chunk-2YIYRACC.js} +1 -1
  9. package/dist/{chunk-LTHUAMIE.js → chunk-4CTIJSGF.js} +1 -1
  10. package/dist/{chunk-NXGI34H4.js → chunk-4V637EWT.js} +35 -15
  11. package/dist/chunk-4V637EWT.js.map +7 -0
  12. package/dist/{chunk-EV3W3WLB.js → chunk-5AZPIB3O.js} +3 -3
  13. package/dist/{chunk-YV7Q3VHM.js → chunk-5SB6YYVT.js} +1 -1
  14. package/dist/chunk-5ZAXW6YC.js.map +7 -0
  15. package/dist/{chunk-TEGHHNGC.js → chunk-62DRY4WE.js} +4 -4
  16. package/dist/{chunk-PFYRLJXN.js → chunk-6Z7VRZE3.js} +2 -2
  17. package/dist/{chunk-E4QA2SMS.js → chunk-CLDFSJRX.js} +20 -6
  18. package/dist/{chunk-E4QA2SMS.js.map → chunk-CLDFSJRX.js.map} +2 -2
  19. package/dist/{chunk-7BZ3TT3E.js → chunk-DFQUXY7J.js} +10 -9
  20. package/dist/chunk-DFQUXY7J.js.map +7 -0
  21. package/dist/{chunk-M3EVWIF3.js → chunk-DYRNDVME.js} +3 -3
  22. package/dist/{chunk-U6JIGJB4.js → chunk-EN3EFAIN.js} +1728 -952
  23. package/dist/chunk-EN3EFAIN.js.map +7 -0
  24. package/dist/{chunk-L5RH454O.js → chunk-FEEOL2BF.js} +2 -2
  25. package/dist/{chunk-QMMOGZ7N.js → chunk-GKLF5SMX.js} +4 -4
  26. package/dist/{chunk-WDCDJPYN.js → chunk-HBFOODQT.js} +1 -1
  27. package/dist/{chunk-4SQ6LXYG.js → chunk-IKZOQVSC.js} +3 -3
  28. package/dist/{chunk-S7PU3TNH.js → chunk-IZKGIVR5.js} +4 -4
  29. package/dist/{chunk-5P4P5CFA.js → chunk-KDWAOC2Y.js} +2 -2
  30. package/dist/{chunk-6N43IM3F.js → chunk-KHCVAV26.js} +1 -1
  31. package/dist/{chunk-33QWSQC4.js → chunk-LHETO2A7.js} +2 -2
  32. package/dist/{chunk-IYPL6KOG.js → chunk-LXKU7CVC.js} +1 -1
  33. package/dist/{chunk-IC6XUDKC.js → chunk-MP2Z2WPA.js} +3 -3
  34. package/dist/{chunk-YJ3HLVKX.js → chunk-NMV2Y2OE.js} +2 -2
  35. package/dist/{chunk-Q3DXXYPX.js → chunk-PF2W6HQJ.js} +3 -3
  36. package/dist/{chunk-MQONPL2D.js → chunk-PH2OZGKF.js} +1 -1
  37. package/dist/{chunk-YKCKLLMA.js → chunk-PMBP2S7T.js} +2 -2
  38. package/dist/{chunk-BQWG5WFV.js → chunk-R5KHOF4Q.js} +1 -1
  39. package/dist/{chunk-EZ5IMWVJ.js → chunk-SQZQF7FX.js} +1 -1
  40. package/dist/{chunk-VH3IQXUR.js → chunk-USAN2W2G.js} +1 -1
  41. package/dist/{chunk-KUQZLTIW.js → chunk-UYEP4HDV.js} +4 -1
  42. package/dist/{chunk-KUQZLTIW.js.map → chunk-UYEP4HDV.js.map} +2 -2
  43. package/dist/{chunk-HOGROHYP.js → chunk-V6HDC2AS.js} +4 -4
  44. package/dist/{chunk-I7FH3MBS.js → chunk-VLE3RIPA.js} +3 -3
  45. package/dist/{cli-TIOLFD3Q.js → cli-2YA4LC5A.js} +92 -92
  46. package/dist/commands-GZ2R547K.js +54 -0
  47. package/dist/{config-BPAZ2QW2.js → config-NLO656A6.js} +4 -4
  48. package/dist/{context-UXBFAE6U.js → context-B5OAVYCB.js} +6 -6
  49. package/dist/{conversationPersistence-S5Y54OEJ.js → conversationPersistence-U3JD7OG2.js} +3 -3
  50. package/dist/{conversationTracker-EPTEVBKG.js → conversationTracker-XMFEBWHY.js} +4 -4
  51. package/dist/{customCommands-LJEKRKH7.js → customCommands-MP2IC4VW.js} +4 -4
  52. package/dist/{env-ZKDJ63EH.js → env-IWFZNFTP.js} +2 -2
  53. package/dist/{file-62N53R4I.js → file-NKAAAB74.js} +4 -4
  54. package/dist/index.js +3 -3
  55. package/dist/{llm-257Z7WOJ.js → llm-VL7SVIXR.js} +32 -32
  56. package/dist/{llmLazy-766Y5JWG.js → llmLazy-JXN5R32R.js} +1 -1
  57. package/dist/{loader-IC2B4I4J.js → loader-QO3E224E.js} +4 -4
  58. package/dist/{lsp-ARSWURXF.js → lsp-3KQLSDLC.js} +6 -6
  59. package/dist/{lspAnchor-5N3KECK7.js → lspAnchor-56RDVJJK.js} +6 -6
  60. package/dist/{mcp-6LNALW65.js → mcp-QYGOVXNU.js} +7 -7
  61. package/dist/{mentionProcessor-LQ6WNIKV.js → mentionProcessor-M5UL6TT6.js} +5 -5
  62. package/dist/{messages-GNEQQA27.js → messages-IR7NEQMR.js} +1 -1
  63. package/dist/{model-F7IYXNO5.js → model-JVW7GWZF.js} +5 -5
  64. package/dist/{openai-HTXVPLAS.js → openai-JJWBAQ7K.js} +5 -5
  65. package/dist/{outputStyles-IEUFSMMK.js → outputStyles-NNT6NWAK.js} +4 -4
  66. package/dist/{pluginRuntime-4AI2VGR6.js → pluginRuntime-5ZYXGIUZ.js} +6 -6
  67. package/dist/{pluginValidation-VM4W42FR.js → pluginValidation-6OLPIUNW.js} +6 -6
  68. package/dist/prompts-ITAM2QAA.js +56 -0
  69. package/dist/{pybAgentSessionLoad-A3OZD3FR.js → pybAgentSessionLoad-HN6WOHQP.js} +4 -4
  70. package/dist/{pybAgentSessionResume-T6XFQUGW.js → pybAgentSessionResume-KEUXFVVT.js} +4 -4
  71. package/dist/{pybAgentStreamJsonSession-J6TKWFS5.js → pybAgentStreamJsonSession-V24MOW3E.js} +1 -1
  72. package/dist/{pybHooks-QXTF2XWB.js → pybHooks-OEASV3O6.js} +4 -4
  73. package/dist/query-4YMUBJ3B.js +56 -0
  74. package/dist/{registry-N7W2DT2O.js → registry-WDNZOTS2.js} +5 -5
  75. package/dist/{ripgrep-4YX3ALXH.js → ripgrep-YEEECTEY.js} +3 -3
  76. package/dist/{skillMarketplace-BHPBAIS5.js → skillMarketplace-N2W7WTS3.js} +3 -3
  77. package/dist/{state-BAYDHBR6.js → state-IB4ZDFMG.js} +2 -2
  78. package/dist/{theme-5WK7OBSE.js → theme-5AY4LKLW.js} +5 -5
  79. package/dist/{toolPermissionSettings-KHCHXARB.js → toolPermissionSettings-J5VPVYUK.js} +6 -6
  80. package/dist/tools-VLTX3RMF.js +55 -0
  81. package/dist/{userInput-I5VZDN77.js → userInput-YJI6VWIU.js} +32 -32
  82. package/package.json +7 -1
  83. package/scripts/session-behavior-invariant-gate.mjs +86 -0
  84. package/scripts/session-contract-gate.mjs +107 -0
  85. package/dist/REPL-TGEVVUGU.js +0 -50
  86. package/dist/chunk-5MFIJREB.js.map +0 -7
  87. package/dist/chunk-7BZ3TT3E.js.map +0 -7
  88. package/dist/chunk-NXGI34H4.js.map +0 -7
  89. package/dist/chunk-OC5CZWBQ.js.map +0 -7
  90. package/dist/chunk-U6JIGJB4.js.map +0 -7
  91. package/dist/commands-T7TKHXOU.js +0 -54
  92. package/dist/prompts-EJTGSKLG.js +0 -56
  93. package/dist/query-ONI2G7VA.js +0 -58
  94. package/dist/tools-LTGCAA7X.js +0 -55
  95. /package/dist/{REPL-TGEVVUGU.js.map → REPL-4ET7DK5F.js.map} +0 -0
  96. /package/dist/{acp-NSVRKFDR.js.map → acp-6D6QDJQY.js.map} +0 -0
  97. /package/dist/{agentsValidate-J4WH47PD.js.map → agentsValidate-XFP3HZ4H.js.map} +0 -0
  98. /package/dist/{ask-TIOWV5TX.js.map → ask-6CZRJCSZ.js.map} +0 -0
  99. /package/dist/{autoUpdater-35O63ORK.js.map → autoUpdater-VCCPGPDD.js.map} +0 -0
  100. /package/dist/{chunk-2TZLPLK6.js.map → chunk-2YIYRACC.js.map} +0 -0
  101. /package/dist/{chunk-LTHUAMIE.js.map → chunk-4CTIJSGF.js.map} +0 -0
  102. /package/dist/{chunk-EV3W3WLB.js.map → chunk-5AZPIB3O.js.map} +0 -0
  103. /package/dist/{chunk-YV7Q3VHM.js.map → chunk-5SB6YYVT.js.map} +0 -0
  104. /package/dist/{chunk-OC5CZWBQ.js → chunk-5ZAXW6YC.js} +0 -0
  105. /package/dist/{chunk-TEGHHNGC.js.map → chunk-62DRY4WE.js.map} +0 -0
  106. /package/dist/{chunk-PFYRLJXN.js.map → chunk-6Z7VRZE3.js.map} +0 -0
  107. /package/dist/{chunk-M3EVWIF3.js.map → chunk-DYRNDVME.js.map} +0 -0
  108. /package/dist/{chunk-L5RH454O.js.map → chunk-FEEOL2BF.js.map} +0 -0
  109. /package/dist/{chunk-QMMOGZ7N.js.map → chunk-GKLF5SMX.js.map} +0 -0
  110. /package/dist/{chunk-WDCDJPYN.js.map → chunk-HBFOODQT.js.map} +0 -0
  111. /package/dist/{chunk-4SQ6LXYG.js.map → chunk-IKZOQVSC.js.map} +0 -0
  112. /package/dist/{chunk-S7PU3TNH.js.map → chunk-IZKGIVR5.js.map} +0 -0
  113. /package/dist/{chunk-5P4P5CFA.js.map → chunk-KDWAOC2Y.js.map} +0 -0
  114. /package/dist/{chunk-6N43IM3F.js.map → chunk-KHCVAV26.js.map} +0 -0
  115. /package/dist/{chunk-33QWSQC4.js.map → chunk-LHETO2A7.js.map} +0 -0
  116. /package/dist/{chunk-IYPL6KOG.js.map → chunk-LXKU7CVC.js.map} +0 -0
  117. /package/dist/{chunk-IC6XUDKC.js.map → chunk-MP2Z2WPA.js.map} +0 -0
  118. /package/dist/{chunk-YJ3HLVKX.js.map → chunk-NMV2Y2OE.js.map} +0 -0
  119. /package/dist/{chunk-Q3DXXYPX.js.map → chunk-PF2W6HQJ.js.map} +0 -0
  120. /package/dist/{chunk-MQONPL2D.js.map → chunk-PH2OZGKF.js.map} +0 -0
  121. /package/dist/{chunk-YKCKLLMA.js.map → chunk-PMBP2S7T.js.map} +0 -0
  122. /package/dist/{chunk-BQWG5WFV.js.map → chunk-R5KHOF4Q.js.map} +0 -0
  123. /package/dist/{chunk-EZ5IMWVJ.js.map → chunk-SQZQF7FX.js.map} +0 -0
  124. /package/dist/{chunk-VH3IQXUR.js.map → chunk-USAN2W2G.js.map} +0 -0
  125. /package/dist/{chunk-HOGROHYP.js.map → chunk-V6HDC2AS.js.map} +0 -0
  126. /package/dist/{chunk-I7FH3MBS.js.map → chunk-VLE3RIPA.js.map} +0 -0
  127. /package/dist/{cli-TIOLFD3Q.js.map → cli-2YA4LC5A.js.map} +0 -0
  128. /package/dist/{commands-T7TKHXOU.js.map → commands-GZ2R547K.js.map} +0 -0
  129. /package/dist/{config-BPAZ2QW2.js.map → config-NLO656A6.js.map} +0 -0
  130. /package/dist/{context-UXBFAE6U.js.map → context-B5OAVYCB.js.map} +0 -0
  131. /package/dist/{conversationPersistence-S5Y54OEJ.js.map → conversationPersistence-U3JD7OG2.js.map} +0 -0
  132. /package/dist/{conversationTracker-EPTEVBKG.js.map → conversationTracker-XMFEBWHY.js.map} +0 -0
  133. /package/dist/{customCommands-LJEKRKH7.js.map → customCommands-MP2IC4VW.js.map} +0 -0
  134. /package/dist/{env-ZKDJ63EH.js.map → env-IWFZNFTP.js.map} +0 -0
  135. /package/dist/{file-62N53R4I.js.map → file-NKAAAB74.js.map} +0 -0
  136. /package/dist/{llm-257Z7WOJ.js.map → llm-VL7SVIXR.js.map} +0 -0
  137. /package/dist/{llmLazy-766Y5JWG.js.map → llmLazy-JXN5R32R.js.map} +0 -0
  138. /package/dist/{loader-IC2B4I4J.js.map → loader-QO3E224E.js.map} +0 -0
  139. /package/dist/{lsp-ARSWURXF.js.map → lsp-3KQLSDLC.js.map} +0 -0
  140. /package/dist/{lspAnchor-5N3KECK7.js.map → lspAnchor-56RDVJJK.js.map} +0 -0
  141. /package/dist/{mcp-6LNALW65.js.map → mcp-QYGOVXNU.js.map} +0 -0
  142. /package/dist/{mentionProcessor-LQ6WNIKV.js.map → mentionProcessor-M5UL6TT6.js.map} +0 -0
  143. /package/dist/{messages-GNEQQA27.js.map → messages-IR7NEQMR.js.map} +0 -0
  144. /package/dist/{model-F7IYXNO5.js.map → model-JVW7GWZF.js.map} +0 -0
  145. /package/dist/{openai-HTXVPLAS.js.map → openai-JJWBAQ7K.js.map} +0 -0
  146. /package/dist/{outputStyles-IEUFSMMK.js.map → outputStyles-NNT6NWAK.js.map} +0 -0
  147. /package/dist/{pluginRuntime-4AI2VGR6.js.map → pluginRuntime-5ZYXGIUZ.js.map} +0 -0
  148. /package/dist/{pluginValidation-VM4W42FR.js.map → pluginValidation-6OLPIUNW.js.map} +0 -0
  149. /package/dist/{prompts-EJTGSKLG.js.map → prompts-ITAM2QAA.js.map} +0 -0
  150. /package/dist/{pybAgentSessionLoad-A3OZD3FR.js.map → pybAgentSessionLoad-HN6WOHQP.js.map} +0 -0
  151. /package/dist/{pybAgentSessionResume-T6XFQUGW.js.map → pybAgentSessionResume-KEUXFVVT.js.map} +0 -0
  152. /package/dist/{pybAgentStreamJsonSession-J6TKWFS5.js.map → pybAgentStreamJsonSession-V24MOW3E.js.map} +0 -0
  153. /package/dist/{pybHooks-QXTF2XWB.js.map → pybHooks-OEASV3O6.js.map} +0 -0
  154. /package/dist/{query-ONI2G7VA.js.map → query-4YMUBJ3B.js.map} +0 -0
  155. /package/dist/{registry-N7W2DT2O.js.map → registry-WDNZOTS2.js.map} +0 -0
  156. /package/dist/{ripgrep-4YX3ALXH.js.map → ripgrep-YEEECTEY.js.map} +0 -0
  157. /package/dist/{skillMarketplace-BHPBAIS5.js.map → skillMarketplace-N2W7WTS3.js.map} +0 -0
  158. /package/dist/{state-BAYDHBR6.js.map → state-IB4ZDFMG.js.map} +0 -0
  159. /package/dist/{theme-5WK7OBSE.js.map → theme-5AY4LKLW.js.map} +0 -0
  160. /package/dist/{toolPermissionSettings-KHCHXARB.js.map → toolPermissionSettings-J5VPVYUK.js.map} +0 -0
  161. /package/dist/{tools-LTGCAA7X.js.map → tools-VLTX3RMF.js.map} +0 -0
  162. /package/dist/{userInput-I5VZDN77.js.map → userInput-YJI6VWIU.js.map} +0 -0
@@ -2,18 +2,18 @@ import { createRequire as __pybCreateRequire } from "node:module";
2
2
  const require = __pybCreateRequire(import.meta.url);
3
3
  import {
4
4
  loadPybAgentSessionMessages
5
- } from "./chunk-EZ5IMWVJ.js";
5
+ } from "./chunk-SQZQF7FX.js";
6
6
  import {
7
7
  listPybAgentSessions
8
- } from "./chunk-2TZLPLK6.js";
8
+ } from "./chunk-2YIYRACC.js";
9
9
  import {
10
10
  appendSessionCustomTitleRecord,
11
11
  appendSessionTagRecord
12
- } from "./chunk-YV7Q3VHM.js";
12
+ } from "./chunk-5SB6YYVT.js";
13
13
  import {
14
14
  formatValidationResult,
15
15
  validatePluginOrMarketplacePath
16
- } from "./chunk-I7FH3MBS.js";
16
+ } from "./chunk-VLE3RIPA.js";
17
17
  import {
18
18
  ConversationTracker,
19
19
  appendFinishState,
@@ -21,10 +21,10 @@ import {
21
21
  getConversationTrackerForContext,
22
22
  isFinishComplete,
23
23
  mapFinishReason
24
- } from "./chunk-BQWG5WFV.js";
24
+ } from "./chunk-R5KHOF4Q.js";
25
25
  import {
26
26
  FileSystemConversationPersistence
27
- } from "./chunk-6N43IM3F.js";
27
+ } from "./chunk-KHCVAV26.js";
28
28
  import {
29
29
  beginReplSessionScope
30
30
  } from "./chunk-F4AXICO7.js";
@@ -39,7 +39,7 @@ import {
39
39
  runStopHooks,
40
40
  runUserPromptSubmitHooks,
41
41
  updateHookTranscriptForMessages
42
- } from "./chunk-E4QA2SMS.js";
42
+ } from "./chunk-CLDFSJRX.js";
43
43
  import {
44
44
  DEFAULT_OUTPUT_STYLE,
45
45
  getAvailableOutputStyles,
@@ -48,11 +48,11 @@ import {
48
48
  getOutputStyleSystemPromptAdditions,
49
49
  resolveOutputStyleName,
50
50
  setCurrentOutputStyle
51
- } from "./chunk-5P4P5CFA.js";
51
+ } from "./chunk-KDWAOC2Y.js";
52
52
  import {
53
53
  fetchCustomModels,
54
54
  getModelFeatures
55
- } from "./chunk-YKCKLLMA.js";
55
+ } from "./chunk-PMBP2S7T.js";
56
56
  import {
57
57
  getSessionState
58
58
  } from "./chunk-XKYHFZEC.js";
@@ -60,7 +60,7 @@ import {
60
60
  queryLLM,
61
61
  queryQuick,
62
62
  verifyApiKey
63
- } from "./chunk-QMMOGZ7N.js";
63
+ } from "./chunk-GKLF5SMX.js";
64
64
  import {
65
65
  DEFAULT_TIMEOUT_MS,
66
66
  FallbackToolUseRejectedMessage,
@@ -74,7 +74,7 @@ import {
74
74
  listMCPServers,
75
75
  loadMergedSettings,
76
76
  normalizeSandboxRuntimeConfigFromSettings
77
- } from "./chunk-S7PU3TNH.js";
77
+ } from "./chunk-IZKGIVR5.js";
78
78
  import {
79
79
  addMarketplace,
80
80
  disableSkillPlugin,
@@ -87,11 +87,11 @@ import {
87
87
  refreshMarketplaceAsync,
88
88
  removeMarketplace,
89
89
  uninstallSkillPlugin
90
- } from "./chunk-VH3IQXUR.js";
90
+ } from "./chunk-USAN2W2G.js";
91
91
  import {
92
92
  loadToolPermissionContextFromDisk,
93
93
  persistToolPermissionUpdateToDisk
94
- } from "./chunk-M3EVWIF3.js";
94
+ } from "./chunk-DYRNDVME.js";
95
95
  import {
96
96
  applyToolPermissionContextUpdate,
97
97
  applyToolPermissionContextUpdates,
@@ -102,13 +102,13 @@ import {
102
102
  generateSystemReminders,
103
103
  resetReminderSession,
104
104
  systemReminderService
105
- } from "./chunk-YJ3HLVKX.js";
105
+ } from "./chunk-NMV2Y2OE.js";
106
106
  import {
107
107
  clearAgentCache,
108
108
  getActiveAgents,
109
109
  getAgentByType,
110
110
  getAllAgents
111
- } from "./chunk-33QWSQC4.js";
111
+ } from "./chunk-LHETO2A7.js";
112
112
  import {
113
113
  API_ERROR_MESSAGE_PREFIX,
114
114
  CANCEL_MESSAGE,
@@ -145,7 +145,7 @@ import {
145
145
  reorderMessages,
146
146
  resetAutoCompactTelemetry,
147
147
  stripSystemMessages
148
- } from "./chunk-KUQZLTIW.js";
148
+ } from "./chunk-UYEP4HDV.js";
149
149
  import {
150
150
  getRequestStatus,
151
151
  setRequestStatus,
@@ -175,7 +175,7 @@ import {
175
175
  normalizeFilePath,
176
176
  readTextContent,
177
177
  writeTextContent
178
- } from "./chunk-PFYRLJXN.js";
178
+ } from "./chunk-6Z7VRZE3.js";
179
179
  import {
180
180
  parseBlockEdits
181
181
  } from "./chunk-QWIBSCDN.js";
@@ -185,18 +185,18 @@ import {
185
185
  ParserRegistry,
186
186
  initParser,
187
187
  loadLanguage
188
- } from "./chunk-HOGROHYP.js";
188
+ } from "./chunk-V6HDC2AS.js";
189
189
  import {
190
190
  getSettingsFileCandidates,
191
191
  loadSettingsWithLegacyFallback,
192
192
  readSettingsFile
193
- } from "./chunk-IYPL6KOG.js";
193
+ } from "./chunk-LXKU7CVC.js";
194
194
  import {
195
195
  getCustomCommandDirectories,
196
196
  hasCustomCommands,
197
197
  loadCustomCommands,
198
198
  reloadCustomCommands
199
- } from "./chunk-L5RH454O.js";
199
+ } from "./chunk-FEEOL2BF.js";
200
200
  import {
201
201
  getSessionPlugins
202
202
  } from "./chunk-BJSWTHRM.js";
@@ -205,7 +205,7 @@ import {
205
205
  buildModelProfileKey,
206
206
  getModelManager,
207
207
  isDefaultSlowAndCapableModel
208
- } from "./chunk-EV3W3WLB.js";
208
+ } from "./chunk-5AZPIB3O.js";
209
209
  import {
210
210
  getCodeStyle,
211
211
  getContext,
@@ -213,16 +213,16 @@ import {
213
213
  getIsGit,
214
214
  getProjectDocs,
215
215
  getProjectStructureStatisticsBlock
216
- } from "./chunk-TEGHHNGC.js";
216
+ } from "./chunk-62DRY4WE.js";
217
217
  import {
218
218
  getRipgrepPath,
219
219
  getRipgrepPolicyMode,
220
220
  resolveRipgrepPolicy,
221
221
  ripGrep
222
- } from "./chunk-LTHUAMIE.js";
222
+ } from "./chunk-4CTIJSGF.js";
223
223
  import {
224
224
  getTheme
225
- } from "./chunk-MQONPL2D.js";
225
+ } from "./chunk-PH2OZGKF.js";
226
226
  import {
227
227
  DEFAULT_GLOBAL_CONFIG,
228
228
  enableConfigs,
@@ -235,7 +235,7 @@ import {
235
235
  saveGlobalConfig,
236
236
  setAllPointersToModel,
237
237
  setModelPointer
238
- } from "./chunk-4SQ6LXYG.js";
238
+ } from "./chunk-IKZOQVSC.js";
239
239
  import {
240
240
  AbortError
241
241
  } from "./chunk-RQVLBMP7.js";
@@ -244,7 +244,7 @@ import {
244
244
  getCurrentRequest,
245
245
  logUserFriendly,
246
246
  markPhase
247
- } from "./chunk-WDCDJPYN.js";
247
+ } from "./chunk-HBFOODQT.js";
248
248
  import {
249
249
  ASCII_LOGO,
250
250
  BunShell,
@@ -285,10 +285,10 @@ import {
285
285
  setCwd,
286
286
  shouldApplyToolOutputTruncation,
287
287
  truncateToolOutput
288
- } from "./chunk-7BZ3TT3E.js";
288
+ } from "./chunk-DFQUXY7J.js";
289
289
  import {
290
290
  MACRO
291
- } from "./chunk-5MFIJREB.js";
291
+ } from "./chunk-2L7XKUEG.js";
292
292
  import {
293
293
  __export
294
294
  } from "./chunk-I3J4JYES.js";
@@ -469,7 +469,7 @@ var getCommandSubcommandPrefix = memoize(
469
469
  var getCommandPrefix = memoize(
470
470
  async (command4, abortSignal) => {
471
471
  const { systemPrompt, userPrompt } = buildBashCommandPrefixDetectionPrompt(command4);
472
- const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-257Z7WOJ.js");
472
+ const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryQuick: queryQuick2 } = await import("./llm-VL7SVIXR.js");
473
473
  const response = await queryQuick2({
474
474
  systemPrompt,
475
475
  userPrompt,
@@ -4271,7 +4271,7 @@ function formatParseError(error) {
4271
4271
  return error instanceof Error ? error.message : String(error);
4272
4272
  }
4273
4273
  async function defaultGateQuery(args) {
4274
- const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-257Z7WOJ.js");
4274
+ const { API_ERROR_MESSAGE_PREFIX: API_ERROR_MESSAGE_PREFIX2, queryLLM: queryLLM2 } = await import("./llm-VL7SVIXR.js");
4275
4275
  const queryLLMFn = args.queryLLMOverride ?? queryLLM2;
4276
4276
  const messages = [
4277
4277
  {
@@ -4679,7 +4679,7 @@ Usage notes:
4679
4679
  - The URL must be a fully-formed valid URL
4680
4680
  - HTTP URLs will be automatically upgraded to HTTPS
4681
4681
  - The prompt should describe what information you want to extract from the page
4682
- - Format options: "markdown", "text", or "html" (choose based on your intent)
4682
+ - Format options: "text" (default, recommended), "markdown", or "html" (choose based on your intent)
4683
4683
  - Timeout is optional and defaults to 30 seconds
4684
4684
  - This tool is read-only and does not modify any files
4685
4685
  - Results may be summarized if the content is very large
@@ -4695,16 +4695,16 @@ Requested Format Behavior Examples:
4695
4695
  </article>
4696
4696
  --html
4697
4697
 
4698
- 1\uFF1Aformat: "markdown" \u2192 preserves structure (headings/lists/links) for readable summaries and structured quoting:
4699
- # Title
4700
- Hello [link](https://example.com)
4701
- - One
4702
- - Two
4703
- 2\uFF1Aformat: "text" \u2192 plain text only, removes all markup and links to minimize noise:
4698
+ 1\uFF1Aformat: "text" (default, recommended) \u2192 plain text only, removes all markup and links to minimize noise:
4704
4699
  Title
4705
4700
  Hello link
4706
4701
  One
4707
4702
  Two
4703
+ 2\uFF1Aformat: "markdown" \u2192 preserves structure (headings/lists/links) for readable summaries and structured quoting:
4704
+ # Title
4705
+ Hello [link](https://example.com)
4706
+ - One
4707
+ - Two
4708
4708
  3\uFF1Aformat: "html" \u2192 cleaned HTML, keeps tags but removes scripts/styles/extra chrome:
4709
4709
  <article><h1>Title</h1><p>Hello <a href="https://example.com">link</a></p><ul><li>One</li><li>Two</li></ul></article>
4710
4710
  `.trim();
@@ -4797,13 +4797,14 @@ var urlCache = new URLCache();
4797
4797
  var inputSchema = z.strictObject({
4798
4798
  url: z.string().url().describe("The URL to fetch content from"),
4799
4799
  prompt: z.string().optional().describe("Optional prompt to run on the fetched content"),
4800
- format: z.enum(["markdown", "html", "text"]).optional().describe("Output format (default: markdown)"),
4800
+ format: z.enum(["markdown", "html", "text"]).optional().describe("Output format (default: text)"),
4801
4801
  timeout: z.number().optional().describe("Timeout in seconds (default: 30)")
4802
4802
  });
4803
4803
  var FETCH_TIMEOUT_MS = 3e4;
4804
4804
  var CONNECT_TIMEOUT_MS = 5e3;
4805
4805
  var ANALYSIS_TIMEOUT_MS = 15e3;
4806
4806
  var MAX_TIMEOUT_MS = 12e4;
4807
+ var READ_CHUNK_TIMEOUT_MS = 2e4;
4807
4808
  var MAX_URL_LENGTH = 2e3;
4808
4809
  var MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
4809
4810
  var MAX_CONTENT_CHARS = 1e5;
@@ -4880,12 +4881,15 @@ function createTimeoutSignal(parent, timeoutMs, onTimeout) {
4880
4881
  }
4881
4882
  };
4882
4883
  }
4883
- async function readResponseTextLimited(response, maxBytes, signal) {
4884
+ async function readResponseTextLimited(response, maxBytes, signal, chunkTimeoutMs = READ_CHUNK_TIMEOUT_MS) {
4884
4885
  if (!response.body) return { text: "", bytes: 0 };
4885
4886
  const reader = response.body.getReader();
4886
4887
  const chunks = [];
4887
4888
  let bytes = 0;
4888
4889
  const abortError = new Error("Response reading aborted");
4890
+ const chunkTimeoutError = new Error(
4891
+ `Response chunk read timeout (${chunkTimeoutMs / 1e3}s)`
4892
+ );
4889
4893
  let onAbort = null;
4890
4894
  let abortPromise = null;
4891
4895
  if (signal) {
@@ -4900,20 +4904,39 @@ async function readResponseTextLimited(response, maxBytes, signal) {
4900
4904
  try {
4901
4905
  while (true) {
4902
4906
  const readPromise = reader.read();
4903
- const { value, done } = abortPromise ? await Promise.race([readPromise, abortPromise]) : await readPromise;
4904
- if (done) break;
4905
- if (!value) continue;
4906
- bytes += value.byteLength;
4907
- if (bytes > maxBytes) {
4908
- try {
4909
- await reader.cancel();
4910
- } catch {
4907
+ let chunkTimeoutId = null;
4908
+ const chunkTimeoutPromise = new Promise((_, reject) => {
4909
+ chunkTimeoutId = setTimeout(() => {
4910
+ reject(chunkTimeoutError);
4911
+ }, chunkTimeoutMs);
4912
+ });
4913
+ const racePromises = abortPromise ? [readPromise, abortPromise, chunkTimeoutPromise] : [readPromise, chunkTimeoutPromise];
4914
+ try {
4915
+ const { value, done } = await Promise.race(racePromises);
4916
+ if (chunkTimeoutId) {
4917
+ clearTimeout(chunkTimeoutId);
4918
+ chunkTimeoutId = null;
4919
+ }
4920
+ if (done) break;
4921
+ if (!value) continue;
4922
+ bytes += value.byteLength;
4923
+ if (bytes > maxBytes) {
4924
+ try {
4925
+ await reader.cancel();
4926
+ } catch {
4927
+ }
4928
+ throw new Error(
4929
+ `Response exceeded maximum allowed size (${maxBytes} bytes)`
4930
+ );
4911
4931
  }
4912
- throw new Error(
4913
- `Response exceeded maximum allowed size (${maxBytes} bytes)`
4914
- );
4932
+ chunks.push(value);
4933
+ } catch (error) {
4934
+ if (chunkTimeoutId) {
4935
+ clearTimeout(chunkTimeoutId);
4936
+ chunkTimeoutId = null;
4937
+ }
4938
+ throw error;
4915
4939
  }
4916
- chunks.push(value);
4917
4940
  }
4918
4941
  } catch (error) {
4919
4942
  if (signal?.aborted) {
@@ -4923,6 +4946,13 @@ async function readResponseTextLimited(response, maxBytes, signal) {
4923
4946
  }
4924
4947
  throw abortError;
4925
4948
  }
4949
+ if (error === chunkTimeoutError) {
4950
+ try {
4951
+ await reader.cancel();
4952
+ } catch {
4953
+ }
4954
+ throw chunkTimeoutError;
4955
+ }
4926
4956
  throw error;
4927
4957
  } finally {
4928
4958
  try {
@@ -5200,7 +5230,7 @@ To complete your request, I need to fetch content from the redirected URL. Pleas
5200
5230
  contentType
5201
5231
  });
5202
5232
  }
5203
- const outputFormat = format3 ?? "markdown";
5233
+ const outputFormat = format3 ?? "text";
5204
5234
  const formatted = truncateFetchedContent(
5205
5235
  applyFormat(rawContent, contentType, outputFormat)
5206
5236
  );
@@ -6634,7 +6664,7 @@ var FileEditTool = {
6634
6664
  const originalFileContent = currentFileContent;
6635
6665
  let totalPatch = [];
6636
6666
  const { SmartEdit } = await import("./smart-edit-AWHJDSU6.js");
6637
- const { findLspAnchor } = await import("./lspAnchor-5N3KECK7.js");
6667
+ const { findLspAnchor } = await import("./lspAnchor-56RDVJJK.js");
6638
6668
  for (const op of editOperations) {
6639
6669
  const normalizedSearch = normalizeLineEndings(op.search);
6640
6670
  const normalizedReplace = normalizeLineEndings(op.replace);
@@ -8142,6 +8172,10 @@ var DESCRIPTION4 = `Fast file pattern matching tool that works with any codebase
8142
8172
  - Example: \`src/*\` lists immediate children of src/ (like src/index.ts, src/components/, src/utils/)
8143
8173
  - Example: \`src/components/*\` lists immediate children of src/components/
8144
8174
  - Use this instead of bash \`ls\` command for directory exploration
8175
+ - **Pattern variations for one-level listing**:
8176
+ - \`dir/*\` matches both files and directories at one level (most common)
8177
+ - \`dir/*.ts\` matches only .ts files at one level
8178
+ - \`dir/*/\` matches only directories at one level (trailing slash filters to directories)
8145
8179
 
8146
8180
  ## Search Strategy
8147
8181
  - **Broad-to-Narrow Pattern**: Start with a broad pattern, then narrow based on results.
@@ -8171,6 +8205,10 @@ var DESCRIPTION4 = `Fast file pattern matching tool that works with any codebase
8171
8205
  - Search ignores .gitignore rules and includes hidden files by default.
8172
8206
  - **Empty Results**: When no files are found, try broader patterns (e.g., src/**/*) or verify path exists.
8173
8207
  - **Error Handling**: Returns error if \`path\` does not exist or is not a valid directory.
8208
+ - **Truncated Results**: When results are truncated (limited to 100 files), narrow down using:
8209
+ 1. Add a more specific path: \`src/core/**/*.ts\` instead of \`**/*.ts\`
8210
+ 2. Use file extension filter: \`src/**/*.test.ts\` instead of \`src/**/*.ts\`
8211
+ 3. Use \`dir/*\` first to understand structure, then target specific directories
8174
8212
 
8175
8213
  ## Typical Usage Examples
8176
8214
 
@@ -8357,9 +8395,9 @@ var GlobTool = {
8357
8395
  renderResultForAssistant(output) {
8358
8396
  let result = output.filenames.join("\n");
8359
8397
  if (output.filenames.length === 0) {
8360
- result = "No files found\nSuggestion: use LS to confirm directory structure, then use a broader path or a broader glob (e.g., src/**/*), and check ignore rules if needed.";
8398
+ result = 'No files found\nSuggestion: Use Glob with pattern "dir/*" to confirm directory structure, then try a broader pattern (e.g., src/**/*) or verify the path exists.';
8361
8399
  } else if (output.truncated) {
8362
- result += "\n(Results are truncated. Consider using a more specific path or pattern.)";
8400
+ result += '\n(Results truncated to 100 files. Narrow down: 1) Add specific path like "src/core/**/*" 2) Filter by extension like "*.test.ts" 3) Use "dir/*" first to explore structure.)';
8363
8401
  }
8364
8402
  if (output.semanticNotice) {
8365
8403
  return `${result}
@@ -8633,14 +8671,14 @@ var GrepTool = {
8633
8671
 
8634
8672
  ${result.semanticNotice}` : base;
8635
8673
  if (result.mode === "content") {
8636
- const base = result.content && result.content.length > 0 ? truncateToCharBudget(result.content) : "No matches found\nSuggestion: confirm search scope (use LS/Glob), then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again.";
8674
+ const base = result.content && result.content.length > 0 ? truncateToCharBudget(result.content) : 'No matches found\nSuggestion: Use Glob "dir/*" to confirm directory structure and search scope, then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again.';
8637
8675
  const withPagination = pagination ? `${base}
8638
8676
 
8639
8677
  [Showing results with pagination = ${pagination}]` : base;
8640
8678
  return appendNotice(withPagination);
8641
8679
  }
8642
8680
  if (result.mode === "count") {
8643
- const base = result.content && result.content.length > 0 ? truncateToCharBudget(result.content) : "No matches found\nSuggestion: confirm search scope (use LS/Glob), then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again.";
8681
+ const base = result.content && result.content.length > 0 ? truncateToCharBudget(result.content) : 'No matches found\nSuggestion: Use Glob "dir/*" to confirm directory structure and search scope, then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again.';
8644
8682
  const numMatches = result.numMatches ?? 0;
8645
8683
  const numFiles = result.numFiles ?? 0;
8646
8684
  const summary = base + `
@@ -8650,7 +8688,7 @@ Found ${numMatches} total ${numMatches === 1 ? "occurrence" : "occurrences"} acr
8650
8688
  }
8651
8689
  if (result.numFiles === 0) {
8652
8690
  return appendNotice(
8653
- "No files found\nSuggestion: confirm search scope (use LS/Glob), then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again."
8691
+ 'No files found\nSuggestion: Use Glob "dir/*" to confirm directory structure and search scope, then broaden matching conditions (case/regex/keyword variants, semantic=true), and if needed switch to content mode or expand the file set before searching again.'
8654
8692
  );
8655
8693
  }
8656
8694
  const header = `Found ${result.numFiles} file${result.numFiles === 1 ? "" : "s"}${pagination ? ` ${pagination}` : ""}
@@ -12111,7 +12149,7 @@ async function createAndStoreApiKey(accessToken) {
12111
12149
  }
12112
12150
  saveGlobalConfig(config2);
12113
12151
  try {
12114
- const { resetAnthropicClient } = await import("./llm-257Z7WOJ.js");
12152
+ const { resetAnthropicClient } = await import("./llm-VL7SVIXR.js");
12115
12153
  resetAnthropicClient();
12116
12154
  } catch {
12117
12155
  }
@@ -16535,7 +16573,7 @@ async function refreshPluginRuntimeFromInstalls() {
16535
16573
  const existingRoots = getSessionPlugins().map((p) => p.rootDir);
16536
16574
  const dirs = Array.from(/* @__PURE__ */ new Set([...existingRoots, ...installedRoots]));
16537
16575
  if (dirs.length === 0) return [];
16538
- const { configureSessionPlugins } = await import("./pluginRuntime-4AI2VGR6.js");
16576
+ const { configureSessionPlugins } = await import("./pluginRuntime-5ZYXGIUZ.js");
16539
16577
  const { errors } = await configureSessionPlugins({ pluginDirs: dirs });
16540
16578
  return errors;
16541
16579
  }
@@ -17210,7 +17248,7 @@ async function call(onDone, context) {
17210
17248
  ModelConfig,
17211
17249
  {
17212
17250
  onClose: () => {
17213
- import("./model-F7IYXNO5.js").then(({ reloadModelManager: reloadModelManager2 }) => {
17251
+ import("./model-JVW7GWZF.js").then(({ reloadModelManager: reloadModelManager2 }) => {
17214
17252
  reloadModelManager2();
17215
17253
  triggerModelConfigChange();
17216
17254
  onDone();
@@ -19052,6 +19090,13 @@ function toConcurrentGroupMeta(toolUseID, messages) {
19052
19090
  if (groupIDs.length <= 1) {
19053
19091
  return null;
19054
19092
  }
19093
+ const groupIDSet = new Set(groupIDs);
19094
+ const hasBash = messages.some(
19095
+ (message) => message.type === "assistant" && message.message.content[0]?.type === "tool_use" && groupIDSet.has(message.message.content[0].id) && resolveToolNameAlias(message.message.content[0].name).resolvedName === "Bash"
19096
+ );
19097
+ if (hasBash) {
19098
+ return null;
19099
+ }
19055
19100
  return {
19056
19101
  groupIDs,
19057
19102
  isLeader: groupIDs[0] === toolUseID
@@ -19071,9 +19116,7 @@ function buildConcurrentSummary(args) {
19071
19116
  const readCount = countByName.get("Read") ?? 0;
19072
19117
  const grepCount = countByName.get("Grep") ?? 0;
19073
19118
  const globCount = countByName.get("Glob") ?? 0;
19074
- const lsCount = countByName.get("LS") ?? 0;
19075
- const bashCount = countByName.get("Bash") ?? 0;
19076
- const knownCount = readCount + grepCount + globCount + lsCount + bashCount;
19119
+ const knownCount = readCount + grepCount + globCount;
19077
19120
  const otherCount = Math.max(groupIDs.length - knownCount, 0);
19078
19121
  const parts = [];
19079
19122
  if (readCount > 0) {
@@ -19085,12 +19128,6 @@ function buildConcurrentSummary(args) {
19085
19128
  if (globCount > 0) {
19086
19129
  parts.push(`matched ${globCount} glob${globCount === 1 ? "" : "s"}`);
19087
19130
  }
19088
- if (lsCount > 0) {
19089
- parts.push(`listed ${lsCount} dir${lsCount === 1 ? "" : "s"}`);
19090
- }
19091
- if (bashCount > 0) {
19092
- parts.push(`ran ${bashCount} command${bashCount === 1 ? "" : "s"}`);
19093
- }
19094
19131
  if (otherCount > 0) {
19095
19132
  parts.push(`ran ${otherCount} other tool${otherCount === 1 ? "" : "s"}`);
19096
19133
  }
@@ -25520,7 +25557,7 @@ function useStatusLine() {
25520
25557
  // src/ui/components/PromptInput.tsx
25521
25558
  async function interpretHashCommand(input) {
25522
25559
  try {
25523
- const { queryQuick: queryQuick2 } = await import("./llm-257Z7WOJ.js");
25560
+ const { queryQuick: queryQuick2 } = await import("./llm-VL7SVIXR.js");
25524
25561
  const systemPrompt = [
25525
25562
  "You're helping the user structure notes that will be added to their PYB.md file.",
25526
25563
  "Format the user's input into a well-structured note that will be useful for later reference.",
@@ -25833,7 +25870,7 @@ function PromptInput({
25833
25870
  if (messages2.length) {
25834
25871
  if (mode === "bash") {
25835
25872
  onQuery(messages2, newAbortController).then(async () => {
25836
- const { getCwd: getCwd2 } = await import("./state-BAYDHBR6.js");
25873
+ const { getCwd: getCwd2 } = await import("./state-IB4ZDFMG.js");
25837
25874
  setCurrentPwd(getCwd2());
25838
25875
  });
25839
25876
  } else {
@@ -26009,7 +26046,7 @@ function PromptInput({
26009
26046
  borderRight: false,
26010
26047
  borderColor: mode === "bash" ? theme.bashBorder : mode === "pyb" ? theme.notingBorder : theme.inputBorder,
26011
26048
  borderDimColor: false,
26012
- borderStyle: "classic",
26049
+ borderStyle: "round",
26013
26050
  marginTop: 1,
26014
26051
  width: "100%"
26015
26052
  },
@@ -27088,10 +27125,46 @@ function startWatchingTaskList(listId) {
27088
27125
  startFallbackWatcher(entry);
27089
27126
  }
27090
27127
 
27091
- // src/services/ai/streamTyped/partStore.ts
27092
- import { existsSync as existsSync17, mkdirSync as mkdirSync7 } from "fs";
27093
- import { dirname as dirname9 } from "path";
27094
- import { createRequire as createRequire2 } from "node:module";
27128
+ // src/utils/session/fileRecoveryCore.ts
27129
+ var MAX_FILES_TO_RECOVER = 5;
27130
+ var MAX_TOKENS_PER_FILE = 1e4;
27131
+ var MAX_TOTAL_FILE_TOKENS = 5e4;
27132
+ async function selectAndReadFiles() {
27133
+ const importantFiles = fileFreshnessService.getImportantFiles(MAX_FILES_TO_RECOVER);
27134
+ const results = [];
27135
+ let totalTokens = 0;
27136
+ for (const fileInfo of importantFiles) {
27137
+ try {
27138
+ const { content } = readTextContent(fileInfo.path);
27139
+ const estimatedTokens = Math.ceil(content.length * 0.25);
27140
+ let finalContent = content;
27141
+ let truncated = false;
27142
+ if (estimatedTokens > MAX_TOKENS_PER_FILE) {
27143
+ const maxChars = Math.floor(MAX_TOKENS_PER_FILE / 0.25);
27144
+ finalContent = content.substring(0, maxChars);
27145
+ truncated = true;
27146
+ }
27147
+ const finalTokens = Math.min(estimatedTokens, MAX_TOKENS_PER_FILE);
27148
+ if (totalTokens + finalTokens > MAX_TOTAL_FILE_TOKENS) {
27149
+ break;
27150
+ }
27151
+ totalTokens += finalTokens;
27152
+ results.push({
27153
+ path: fileInfo.path,
27154
+ content: finalContent,
27155
+ tokens: finalTokens,
27156
+ truncated
27157
+ });
27158
+ } catch (error) {
27159
+ logError(error);
27160
+ debug.warn("FILE_RECOVERY_READ_FAILED", {
27161
+ path: fileInfo.path,
27162
+ error: error instanceof Error ? error.message : String(error)
27163
+ });
27164
+ }
27165
+ }
27166
+ return results;
27167
+ }
27095
27168
 
27096
27169
  // src/services/ai/streamTyped/partTypes.ts
27097
27170
  import { z as z11 } from "zod";
@@ -27460,201 +27533,6 @@ function createSystemEventPart(input) {
27460
27533
  });
27461
27534
  }
27462
27535
 
27463
- // src/services/ai/streamTyped/partStore.ts
27464
- var requireForSqlite = createRequire2(import.meta.url);
27465
- var cachedDatabaseCtor;
27466
- function getDatabaseCtor() {
27467
- if (cachedDatabaseCtor !== void 0) return cachedDatabaseCtor;
27468
- try {
27469
- const mod = requireForSqlite("bun:sqlite");
27470
- if (typeof mod?.Database === "function") {
27471
- cachedDatabaseCtor = mod.Database;
27472
- return cachedDatabaseCtor;
27473
- }
27474
- } catch {
27475
- }
27476
- cachedDatabaseCtor = null;
27477
- return null;
27478
- }
27479
- function getDatabaseCtorOrThrow() {
27480
- const Database = getDatabaseCtor();
27481
- if (Database) return Database;
27482
- const error = new Error(
27483
- "PYB_TYPED_SQL_UNAVAILABLE: bun:sqlite is unavailable for stream typed storage"
27484
- );
27485
- error.code = "PYB_TYPED_SQL_UNAVAILABLE";
27486
- throw error;
27487
- }
27488
- function getStreamTypedDbFilePath() {
27489
- const envPath = String(process.env.PYB_STREAM_TYPED_DB_FILE_PATH ?? "").trim();
27490
- if (envPath) return envPath;
27491
- return resolveXdgCachePath("telemetry/stream-typed-parts.db");
27492
- }
27493
- function validateTypedPartRecord(record) {
27494
- return streamTypedPartSchema.safeParse(record).success;
27495
- }
27496
- function applyRuntimePragmas(db) {
27497
- db.exec(`PRAGMA journal_mode=WAL;`);
27498
- db.exec(`PRAGMA synchronous=NORMAL;`);
27499
- db.exec(`PRAGMA busy_timeout=5000;`);
27500
- db.exec(`PRAGMA foreign_keys=ON;`);
27501
- db.exec(`PRAGMA cache_size=-20000;`);
27502
- }
27503
- function ensureDbSchema(db) {
27504
- applyRuntimePragmas(db);
27505
- db.exec(`
27506
- CREATE TABLE IF NOT EXISTS message (
27507
- message_id TEXT PRIMARY KEY,
27508
- request_id TEXT NOT NULL,
27509
- updated_at INTEGER NOT NULL
27510
- );
27511
- `);
27512
- db.exec(`
27513
- CREATE TABLE IF NOT EXISTS part (
27514
- id TEXT PRIMARY KEY,
27515
- message_id TEXT NOT NULL,
27516
- request_id TEXT NOT NULL,
27517
- part_type TEXT NOT NULL,
27518
- source TEXT NOT NULL,
27519
- timestamp INTEGER NOT NULL,
27520
- data_json TEXT NOT NULL,
27521
- updated_at INTEGER NOT NULL
27522
- );
27523
- `);
27524
- db.exec(`
27525
- CREATE INDEX IF NOT EXISTS idx_part_request_timestamp
27526
- ON part(request_id, timestamp, id);
27527
- `);
27528
- }
27529
- function upsertTypedPartsToDb(options) {
27530
- if (!Array.isArray(options.parts) || options.parts.length === 0) {
27531
- return { upserted: 0 };
27532
- }
27533
- if (!existsSync17(dirname9(options.dbFilePath))) {
27534
- mkdirSync7(dirname9(options.dbFilePath), { recursive: true });
27535
- }
27536
- const Database = getDatabaseCtorOrThrow();
27537
- const db = new Database(options.dbFilePath, { create: true });
27538
- ensureDbSchema(db);
27539
- const now = Date.now();
27540
- const upsertMessage = db.prepare(`
27541
- INSERT INTO message (message_id, request_id, updated_at)
27542
- VALUES (?1, ?2, ?3)
27543
- ON CONFLICT(message_id) DO UPDATE SET
27544
- request_id = excluded.request_id,
27545
- updated_at = excluded.updated_at
27546
- `);
27547
- const upsertPart = db.prepare(`
27548
- INSERT INTO part (
27549
- id, message_id, request_id, part_type, source, timestamp, data_json, updated_at
27550
- )
27551
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)
27552
- ON CONFLICT(id) DO UPDATE SET
27553
- message_id = excluded.message_id,
27554
- request_id = excluded.request_id,
27555
- part_type = excluded.part_type,
27556
- source = excluded.source,
27557
- timestamp = excluded.timestamp,
27558
- data_json = excluded.data_json,
27559
- updated_at = excluded.updated_at
27560
- `);
27561
- const tx = db.transaction((parts) => {
27562
- for (const part of parts) {
27563
- upsertMessage.run(part.requestId, part.requestId, now);
27564
- upsertPart.run(
27565
- part.id,
27566
- part.requestId,
27567
- part.requestId,
27568
- part.partType,
27569
- part.source,
27570
- part.timestamp,
27571
- JSON.stringify(part),
27572
- now
27573
- );
27574
- }
27575
- });
27576
- tx(options.parts);
27577
- db.close();
27578
- return { upserted: options.parts.length };
27579
- }
27580
- function appendTypedParts(options) {
27581
- if (!Array.isArray(options.parts) || options.parts.length === 0) {
27582
- return { appended: 0 };
27583
- }
27584
- const validParts = options.parts.filter((item) => validateTypedPartRecord(item));
27585
- if (validParts.length === 0) {
27586
- return { appended: 0 };
27587
- }
27588
- const dbFilePath = options.dbFilePath ?? getStreamTypedDbFilePath();
27589
- const dbResult = upsertTypedPartsToDb({
27590
- dbFilePath,
27591
- parts: validParts
27592
- });
27593
- return { appended: validParts.length, dbUpserted: dbResult.upserted };
27594
- }
27595
- function readTypedPartsByRequest(options) {
27596
- return readTypedPartsByRequestFromDb({
27597
- dbFilePath: options.dbFilePath,
27598
- requestId: options.requestId
27599
- });
27600
- }
27601
- function isLifecycleStepPart(part) {
27602
- return part.partType === "step_start" || part.partType === "step_finish";
27603
- }
27604
- function readStepTypedPartsByRequest(options) {
27605
- const parts = readTypedPartsByRequest(options);
27606
- return parts.filter(isLifecycleStepPart);
27607
- }
27608
- function readTypedPartsByRequestFromDb(options) {
27609
- const dbFilePath = options.dbFilePath ?? getStreamTypedDbFilePath();
27610
- if (!existsSync17(dbFilePath)) return [];
27611
- const Database = getDatabaseCtorOrThrow();
27612
- const db = new Database(dbFilePath);
27613
- ensureDbSchema(db);
27614
- const statement = options.requestId ? db.prepare(`
27615
- SELECT data_json
27616
- FROM part
27617
- WHERE request_id = ?1
27618
- ORDER BY timestamp ASC, id ASC
27619
- `) : db.prepare(`
27620
- SELECT data_json
27621
- FROM part
27622
- ORDER BY timestamp ASC, id ASC
27623
- `);
27624
- const rows = options.requestId ? statement.all(options.requestId) : statement.all();
27625
- const parts = [];
27626
- for (const row of rows) {
27627
- try {
27628
- const parsed = JSON.parse(String(row.data_json ?? ""));
27629
- if (!validateTypedPartRecord(parsed)) continue;
27630
- parts.push(parsed);
27631
- } catch {
27632
- continue;
27633
- }
27634
- }
27635
- db.close();
27636
- return parts;
27637
- }
27638
-
27639
- // src/services/ai/streamTyped/index.ts
27640
- var streamTypedBuffer = /* @__PURE__ */ new Map();
27641
- function emitTypedPart(event) {
27642
- const requestId = String(event.requestId || "").trim();
27643
- if (!requestId) return;
27644
- const current = streamTypedBuffer.get(requestId) ?? [];
27645
- current.push(event.part);
27646
- streamTypedBuffer.set(requestId, current);
27647
- }
27648
- function flushTypedPartBuffer(options) {
27649
- const requestId = String(options.requestId || "").trim();
27650
- if (!requestId) return { appended: 0 };
27651
- const parts = streamTypedBuffer.get(requestId) ?? [];
27652
- streamTypedBuffer.delete(requestId);
27653
- return appendTypedParts({
27654
- parts
27655
- });
27656
- }
27657
-
27658
27536
  // src/services/ai/streamTyped/eventAssembler.ts
27659
27537
  function createAssemblerState(requestId, source = "auto_compact") {
27660
27538
  return {
@@ -27753,310 +27631,202 @@ function flushTypedParts(state) {
27753
27631
  return parts;
27754
27632
  }
27755
27633
 
27756
- // src/services/ai/streamTyped/projector.ts
27757
- function supportsRichToolResultByProvider(provider) {
27758
- return String(provider ?? "").trim().toLowerCase() === "anthropic";
27634
+ // src/services/ai/streamTyped/partStore.ts
27635
+ import { existsSync as existsSync17, mkdirSync as mkdirSync7 } from "fs";
27636
+ import { dirname as dirname9 } from "path";
27637
+ import { createRequire as createRequire2 } from "node:module";
27638
+ var requireForSqlite = createRequire2(import.meta.url);
27639
+ var cachedDatabaseCtor;
27640
+ function getDatabaseCtor() {
27641
+ if (cachedDatabaseCtor !== void 0) return cachedDatabaseCtor;
27642
+ try {
27643
+ const mod = requireForSqlite("bun:sqlite");
27644
+ if (typeof mod?.Database === "function") {
27645
+ cachedDatabaseCtor = mod.Database;
27646
+ return cachedDatabaseCtor;
27647
+ }
27648
+ } catch {
27649
+ }
27650
+ cachedDatabaseCtor = null;
27651
+ return null;
27759
27652
  }
27760
- function extractToolResultText(content) {
27761
- if (typeof content === "string") return { text: content, hasNonTextBlock: false };
27762
- if (!Array.isArray(content)) return { text: "", hasNonTextBlock: false };
27763
- let hasNonTextBlock = false;
27764
- const text = content.filter((block) => {
27765
- if (!block || typeof block !== "object") return false;
27766
- if (block.type === "text") return true;
27767
- hasNonTextBlock = true;
27768
- return false;
27769
- }).map((block) => String(block.text ?? "")).join("\n");
27770
- return { text, hasNonTextBlock };
27653
+ function getDatabaseCtorOrThrow() {
27654
+ const Database = getDatabaseCtor();
27655
+ if (Database) return Database;
27656
+ const error = new Error(
27657
+ "PYB_TYPED_SQL_UNAVAILABLE: bun:sqlite is unavailable for stream typed storage"
27658
+ );
27659
+ error.code = "PYB_TYPED_SQL_UNAVAILABLE";
27660
+ throw error;
27771
27661
  }
27772
- function extractTaggedText(text, tagName) {
27773
- const normalized = String(text ?? "").trim();
27774
- if (!normalized.startsWith(`<${tagName}>`)) return null;
27775
- const pattern = new RegExp(`<${tagName}>([\\s\\S]*?)<\\/${tagName}>`, "i");
27776
- const match = normalized.match(pattern);
27777
- const content = String(match?.[1] ?? "").trim();
27778
- return content.length > 0 ? content : null;
27662
+ function getStreamTypedDbFilePath() {
27663
+ const envPath = String(process.env.PYB_STREAM_TYPED_DB_FILE_PATH ?? "").trim();
27664
+ if (envPath) return envPath;
27665
+ return resolveXdgCachePath("telemetry/stream-typed-parts.db");
27779
27666
  }
27780
- function projectAssistantMessage(state, message) {
27781
- const content = message?.message?.content;
27782
- if (!Array.isArray(content)) return;
27783
- for (let i = 0; i < content.length; i += 1) {
27784
- const block = content[i];
27785
- if (!block || typeof block !== "object") continue;
27786
- const type3 = String(block.type ?? "");
27787
- if (type3 === "text") {
27788
- const text = String(block.text ?? "");
27789
- const toolProgressText = extractTaggedText(text, "tool-progress");
27790
- if (toolProgressText) {
27791
- state.parts.push(
27792
- createSystemEventPart({
27793
- requestId: state.requestId,
27794
- eventType: "tool_progress",
27795
- text: toolProgressText,
27796
- source: state.source
27797
- })
27798
- );
27799
- }
27800
- const localStdoutText = extractTaggedText(text, "local-command-stdout");
27801
- if (localStdoutText) {
27802
- state.parts.push(
27803
- createSystemEventPart({
27804
- requestId: state.requestId,
27805
- eventType: "local_command_stdout",
27806
- text: localStdoutText,
27807
- source: state.source
27808
- })
27809
- );
27810
- }
27811
- const localStderrText = extractTaggedText(text, "local-command-stderr");
27812
- if (localStderrText) {
27813
- state.parts.push(
27814
- createSystemEventPart({
27815
- requestId: state.requestId,
27816
- eventType: "local_command_stderr",
27817
- text: localStderrText,
27818
- source: state.source
27819
- })
27820
- );
27821
- }
27822
- onTextStart({ textId: `text-${i}` }, state);
27823
- onTextDelta({ textId: `text-${i}`, text }, state);
27824
- onTextEnd({ textId: `text-${i}` }, state);
27825
- continue;
27826
- }
27827
- if (type3 === "thinking" || type3 === "reasoning") {
27828
- const text = String(block.thinking ?? block.reasoning ?? "");
27829
- onReasoningStart({ reasoningId: `reasoning-${i}` }, state);
27830
- onReasoningDelta({ reasoningId: `reasoning-${i}`, text }, state);
27831
- onReasoningEnd({ reasoningId: `reasoning-${i}` }, state);
27832
- continue;
27833
- }
27834
- if (type3 === "tool_use" || type3 === "server_tool_use" || type3 === "mcp_tool_use") {
27835
- const toolCallId = String(block.id ?? `tool-${i}`);
27836
- const toolName = String(block.name ?? "unknown");
27837
- onToolCall({ toolCallId, toolName }, state);
27838
- }
27839
- }
27667
+ function validateTypedPartRecord(record) {
27668
+ return streamTypedPartSchema.safeParse(record).success;
27840
27669
  }
27841
- function projectUserToolResult(projector, message) {
27842
- const state = projector.state;
27843
- const content = message?.message?.content;
27844
- if (!Array.isArray(content)) return;
27845
- for (let i = 0; i < content.length; i += 1) {
27846
- const block = content[i];
27847
- if (!block || typeof block !== "object") continue;
27848
- if (block.type !== "tool_result") continue;
27849
- const toolCallId = String(block.tool_use_id ?? `tool-${i}`);
27850
- const extracted = extractToolResultText(block.content);
27851
- if (extracted.hasNonTextBlock) {
27852
- projector.richToolResultBlockCount += 1;
27853
- if (!projector.supportsRichToolResult) {
27854
- projector.downgradedToolResultCount += 1;
27855
- }
27856
- }
27857
- onToolResult(
27858
- {
27859
- toolCallId,
27860
- status: block.is_error ? "failed" : "completed",
27861
- outputText: extracted.text
27862
- },
27863
- state
27670
+ function applyRuntimePragmas(db) {
27671
+ db.exec(`PRAGMA journal_mode=WAL;`);
27672
+ db.exec(`PRAGMA synchronous=NORMAL;`);
27673
+ db.exec(`PRAGMA busy_timeout=5000;`);
27674
+ db.exec(`PRAGMA foreign_keys=ON;`);
27675
+ db.exec(`PRAGMA cache_size=-20000;`);
27676
+ }
27677
+ function ensureDbSchema(db) {
27678
+ applyRuntimePragmas(db);
27679
+ db.exec(`
27680
+ CREATE TABLE IF NOT EXISTS message (
27681
+ message_id TEXT PRIMARY KEY,
27682
+ request_id TEXT NOT NULL,
27683
+ updated_at INTEGER NOT NULL
27864
27684
  );
27685
+ `);
27686
+ db.exec(`
27687
+ CREATE TABLE IF NOT EXISTS part (
27688
+ id TEXT PRIMARY KEY,
27689
+ message_id TEXT NOT NULL,
27690
+ request_id TEXT NOT NULL,
27691
+ part_type TEXT NOT NULL,
27692
+ source TEXT NOT NULL,
27693
+ timestamp INTEGER NOT NULL,
27694
+ data_json TEXT NOT NULL,
27695
+ updated_at INTEGER NOT NULL
27696
+ );
27697
+ `);
27698
+ db.exec(`
27699
+ CREATE INDEX IF NOT EXISTS idx_part_request_timestamp
27700
+ ON part(request_id, timestamp, id);
27701
+ `);
27702
+ }
27703
+ function upsertTypedPartsToDb(options) {
27704
+ if (!Array.isArray(options.parts) || options.parts.length === 0) {
27705
+ return { upserted: 0 };
27706
+ }
27707
+ if (!existsSync17(dirname9(options.dbFilePath))) {
27708
+ mkdirSync7(dirname9(options.dbFilePath), { recursive: true });
27865
27709
  }
27710
+ const Database = getDatabaseCtorOrThrow();
27711
+ const db = new Database(options.dbFilePath, { create: true });
27712
+ ensureDbSchema(db);
27713
+ const now = Date.now();
27714
+ const upsertMessage = db.prepare(`
27715
+ INSERT INTO message (message_id, request_id, updated_at)
27716
+ VALUES (?1, ?2, ?3)
27717
+ ON CONFLICT(message_id) DO UPDATE SET
27718
+ request_id = excluded.request_id,
27719
+ updated_at = excluded.updated_at
27720
+ `);
27721
+ const upsertPart = db.prepare(`
27722
+ INSERT INTO part (
27723
+ id, message_id, request_id, part_type, source, timestamp, data_json, updated_at
27724
+ )
27725
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)
27726
+ ON CONFLICT(id) DO UPDATE SET
27727
+ message_id = excluded.message_id,
27728
+ request_id = excluded.request_id,
27729
+ part_type = excluded.part_type,
27730
+ source = excluded.source,
27731
+ timestamp = excluded.timestamp,
27732
+ data_json = excluded.data_json,
27733
+ updated_at = excluded.updated_at
27734
+ `);
27735
+ const tx = db.transaction((parts) => {
27736
+ for (const part of parts) {
27737
+ upsertMessage.run(part.requestId, part.requestId, now);
27738
+ upsertPart.run(
27739
+ part.id,
27740
+ part.requestId,
27741
+ part.requestId,
27742
+ part.partType,
27743
+ part.source,
27744
+ part.timestamp,
27745
+ JSON.stringify(part),
27746
+ now
27747
+ );
27748
+ }
27749
+ });
27750
+ tx(options.parts);
27751
+ db.close();
27752
+ return { upserted: options.parts.length };
27866
27753
  }
27867
- function projectProgressMessage(state, message) {
27868
- const toolCallId = String(message?.toolUseID ?? "").trim();
27869
- if (!toolCallId) return;
27870
- const content = String(
27871
- message?.content?.message?.content?.find?.((block) => block?.type === "text")?.text ?? ""
27872
- );
27873
- const extractedProgressText = extractTaggedText(content, "tool-progress");
27874
- const normalizedContent = content.trim();
27875
- const toolProgressText = extractedProgressText ?? (normalizedContent.length > 0 ? normalizedContent : void 0);
27876
- if (toolProgressText) {
27877
- state.parts.push(
27878
- createSystemEventPart({
27879
- requestId: state.requestId,
27880
- eventType: "tool_progress",
27881
- text: toolProgressText,
27882
- toolCallId,
27883
- source: state.source
27884
- })
27885
- );
27754
+ function appendTypedParts(options) {
27755
+ if (!Array.isArray(options.parts) || options.parts.length === 0) {
27756
+ return { appended: 0 };
27886
27757
  }
27887
- onToolResult(
27888
- {
27889
- toolCallId,
27890
- status: "running",
27891
- outputText: content || void 0
27892
- },
27893
- state
27894
- );
27758
+ const validParts = options.parts.filter((item) => validateTypedPartRecord(item));
27759
+ if (validParts.length === 0) {
27760
+ return { appended: 0 };
27761
+ }
27762
+ const dbFilePath = options.dbFilePath ?? getStreamTypedDbFilePath();
27763
+ const dbResult = upsertTypedPartsToDb({
27764
+ dbFilePath,
27765
+ parts: validParts
27766
+ });
27767
+ return { appended: validParts.length, dbUpserted: dbResult.upserted };
27895
27768
  }
27896
- function createStreamTypedProjector(options) {
27897
- const provider = String(options.provider ?? "").trim().toLowerCase();
27898
- return {
27899
- state: createAssemblerState(options.requestId, options.source ?? "query_main"),
27900
- provider,
27901
- supportsRichToolResult: typeof options.supportsRichToolResult === "boolean" ? options.supportsRichToolResult : supportsRichToolResultByProvider(provider),
27902
- richToolResultBlockCount: 0,
27903
- downgradedToolResultCount: 0
27904
- };
27769
+ function readTypedPartsByRequest(options) {
27770
+ return readTypedPartsByRequestFromDb({
27771
+ dbFilePath: options.dbFilePath,
27772
+ requestId: options.requestId
27773
+ });
27905
27774
  }
27906
- function consumeProjectorCompatibilityMetrics(projector) {
27907
- const snapshot = {
27908
- provider: projector.provider || "unknown",
27909
- supportsRichToolResult: projector.supportsRichToolResult,
27910
- richToolResultBlockCount: projector.richToolResultBlockCount,
27911
- downgradedToolResultCount: projector.downgradedToolResultCount
27912
- };
27913
- projector.richToolResultBlockCount = 0;
27914
- projector.downgradedToolResultCount = 0;
27915
- return snapshot;
27775
+ function isLifecycleStepPart(part) {
27776
+ return part.partType === "step_start" || part.partType === "step_finish";
27916
27777
  }
27917
- function projectMessageToTypedParts(projector, message) {
27918
- if (!message || typeof message !== "object") return [];
27919
- if (message.type === "assistant") {
27920
- projectAssistantMessage(projector.state, message);
27921
- } else if (message.type === "user") {
27922
- projectUserToolResult(projector, message);
27923
- } else if (message.type === "progress") {
27924
- projectProgressMessage(projector.state, message);
27925
- }
27926
- return flushTypedParts(projector.state);
27778
+ function readStepTypedPartsByRequest(options) {
27779
+ const parts = readTypedPartsByRequest(options);
27780
+ return parts.filter(isLifecycleStepPart);
27927
27781
  }
27928
- function projectLifecycleEventsToTypedParts(projector, events) {
27929
- if (!Array.isArray(events) || events.length === 0) return [];
27782
+ function readTypedPartsByRequestFromDb(options) {
27783
+ const dbFilePath = options.dbFilePath ?? getStreamTypedDbFilePath();
27784
+ if (!existsSync17(dbFilePath)) return [];
27785
+ const Database = getDatabaseCtorOrThrow();
27786
+ const db = new Database(dbFilePath);
27787
+ ensureDbSchema(db);
27788
+ const statement = options.requestId ? db.prepare(`
27789
+ SELECT data_json
27790
+ FROM part
27791
+ WHERE request_id = ?1
27792
+ ORDER BY timestamp ASC, id ASC
27793
+ `) : db.prepare(`
27794
+ SELECT data_json
27795
+ FROM part
27796
+ ORDER BY timestamp ASC, id ASC
27797
+ `);
27798
+ const rows = options.requestId ? statement.all(options.requestId) : statement.all();
27930
27799
  const parts = [];
27931
- for (const event of events) {
27932
- if (!event || typeof event !== "object") continue;
27933
- if (event.eventType === "start-step") {
27934
- parts.push(
27935
- createStepStartPart({
27936
- requestId: projector.state.requestId,
27937
- stepId: event.stepId,
27938
- timeStart: event.timestamp,
27939
- source: projector.state.source
27940
- })
27941
- );
27800
+ for (const row of rows) {
27801
+ try {
27802
+ const parsed = JSON.parse(String(row.data_json ?? ""));
27803
+ if (!validateTypedPartRecord(parsed)) continue;
27804
+ parts.push(parsed);
27805
+ } catch {
27942
27806
  continue;
27943
27807
  }
27944
- if (event.eventType === "finish-step") {
27945
- parts.push(
27946
- createStepFinishPart({
27947
- requestId: projector.state.requestId,
27948
- stepId: event.stepId,
27949
- reason: event.reason,
27950
- completedAt: event.completedAt,
27951
- costUSD: event.costUSD,
27952
- ...event.tokens ? { tokens: event.tokens } : {},
27953
- source: projector.state.source
27954
- })
27955
- );
27956
- }
27957
27808
  }
27809
+ db.close();
27958
27810
  return parts;
27959
27811
  }
27960
27812
 
27961
- // src/services/ai/streamTyped/skeletonReader.ts
27962
- function pushText(parts, value) {
27963
- const text = String(value ?? "").trim();
27964
- if (!text) return;
27965
- parts.push({ type: "text", text });
27966
- }
27967
- function getToolState(part) {
27968
- if (part.partType !== "tool") return null;
27969
- const payload = part.payload;
27970
- return payload?.state ?? null;
27971
- }
27972
- function buildSkeletonBlocksFromTypedParts(input) {
27973
- const result = [];
27974
- for (const part of input.parts) {
27975
- if (!part || typeof part !== "object") continue;
27976
- if (part.partType === "text") {
27977
- pushText(result, part.payload?.text);
27978
- continue;
27979
- }
27980
- if (part.partType === "reasoning" && input.role === "assistant") {
27981
- const reasoning = String(part.payload?.text ?? "").trim();
27982
- if (!reasoning) continue;
27983
- result.push({ type: "reasoning", reasoning });
27984
- continue;
27985
- }
27986
- if (part.partType !== "tool") continue;
27987
- const payload = part.payload;
27988
- const state = getToolState(part);
27989
- const status = String(
27990
- state?.status ?? payload?.status ?? ""
27991
- ).toLowerCase();
27992
- const toolName = String(payload?.toolName ?? "").trim();
27993
- const toolCallId = String(payload?.toolCallId ?? "").trim();
27994
- if (!toolCallId) continue;
27995
- if (input.role === "assistant") {
27996
- if (status !== "pending") continue;
27997
- result.push({
27998
- type: "tool_use",
27999
- id: toolCallId,
28000
- name: toolName || "unknown",
28001
- input: state?.input && typeof state.input === "object" ? state.input : payload?.input && typeof payload.input === "object" ? payload.input : {}
28002
- });
28003
- continue;
28004
- }
28005
- if (status !== "completed" && status !== "failed" && status !== "interrupted") {
28006
- continue;
28007
- }
28008
- const content = String(
28009
- state?.output ?? state?.error ?? state?.reason ?? payload?.outputText ?? ""
28010
- ).trim();
28011
- result.push({
28012
- type: "tool_result",
28013
- tool_use_id: toolCallId,
28014
- content,
28015
- ...status === "failed" ? { is_error: true } : {}
28016
- });
28017
- }
28018
- return result;
27813
+ // src/services/ai/streamTyped/index.ts
27814
+ var streamTypedBuffer = /* @__PURE__ */ new Map();
27815
+ function emitTypedPart(event) {
27816
+ const requestId = String(event.requestId || "").trim();
27817
+ if (!requestId) return;
27818
+ const current = streamTypedBuffer.get(requestId) ?? [];
27819
+ current.push(event.part);
27820
+ streamTypedBuffer.set(requestId, current);
28019
27821
  }
28020
-
28021
- // src/utils/session/fileRecoveryCore.ts
28022
- var MAX_FILES_TO_RECOVER = 5;
28023
- var MAX_TOKENS_PER_FILE = 1e4;
28024
- var MAX_TOTAL_FILE_TOKENS = 5e4;
28025
- async function selectAndReadFiles() {
28026
- const importantFiles = fileFreshnessService.getImportantFiles(MAX_FILES_TO_RECOVER);
28027
- const results = [];
28028
- let totalTokens = 0;
28029
- for (const fileInfo of importantFiles) {
28030
- try {
28031
- const { content } = readTextContent(fileInfo.path);
28032
- const estimatedTokens = Math.ceil(content.length * 0.25);
28033
- let finalContent = content;
28034
- let truncated = false;
28035
- if (estimatedTokens > MAX_TOKENS_PER_FILE) {
28036
- const maxChars = Math.floor(MAX_TOKENS_PER_FILE / 0.25);
28037
- finalContent = content.substring(0, maxChars);
28038
- truncated = true;
28039
- }
28040
- const finalTokens = Math.min(estimatedTokens, MAX_TOKENS_PER_FILE);
28041
- if (totalTokens + finalTokens > MAX_TOTAL_FILE_TOKENS) {
28042
- break;
28043
- }
28044
- totalTokens += finalTokens;
28045
- results.push({
28046
- path: fileInfo.path,
28047
- content: finalContent,
28048
- tokens: finalTokens,
28049
- truncated
28050
- });
28051
- } catch (error) {
28052
- logError(error);
28053
- debug.warn("FILE_RECOVERY_READ_FAILED", {
28054
- path: fileInfo.path,
28055
- error: error instanceof Error ? error.message : String(error)
28056
- });
28057
- }
28058
- }
28059
- return results;
27822
+ function flushTypedPartBuffer(options) {
27823
+ const requestId = String(options.requestId || "").trim();
27824
+ if (!requestId) return { appended: 0 };
27825
+ const parts = streamTypedBuffer.get(requestId) ?? [];
27826
+ streamTypedBuffer.delete(requestId);
27827
+ return appendTypedParts({
27828
+ parts
27829
+ });
28060
27830
  }
28061
27831
 
28062
27832
  // src/services/ai/streamTyped/replay.ts
@@ -28795,7 +28565,7 @@ function getSummaryContentDiagnostics(content) {
28795
28565
  value: content
28796
28566
  };
28797
28567
  }
28798
- function extractToolResultText2(content) {
28568
+ function extractToolResultText(content) {
28799
28569
  if (typeof content === "string") return content;
28800
28570
  if (!Array.isArray(content)) return "";
28801
28571
  return content.filter((block) => block && typeof block === "object" && block.type === "text").map((block) => String(block.text ?? "")).join("\n");
@@ -28913,7 +28683,7 @@ function emitStreamTypedPartsFromContent(content, requestId) {
28913
28683
  }
28914
28684
  if (type3 === "tool_result") {
28915
28685
  const toolCallId = String(block.tool_use_id ?? `tool-${i}`);
28916
- const outputText = extractToolResultText2(block.content);
28686
+ const outputText = extractToolResultText(block.content);
28917
28687
  onToolResult(
28918
28688
  {
28919
28689
  toolCallId,
@@ -30031,42 +29801,6 @@ function applyToolOutputLifecycle(messages, options) {
30031
29801
  };
30032
29802
  }
30033
29803
 
30034
- // src/utils/session/singleFactLayer.ts
30035
- function toTextBlockContent(content) {
30036
- if (typeof content !== "string") return content;
30037
- return [
30038
- {
30039
- type: "text",
30040
- text: content
30041
- }
30042
- ];
30043
- }
30044
- function normalizeMessagesForSingleFactLayer(messages) {
30045
- if (!Array.isArray(messages) || messages.length === 0) return messages;
30046
- return messages.map((message) => {
30047
- if (!message || typeof message !== "object") return message;
30048
- if (message.type !== "user" && message.type !== "assistant") return message;
30049
- const currentContent = message?.message?.content;
30050
- const nextContent = toTextBlockContent(currentContent);
30051
- const shouldUpdateUserOptions = message.type === "user";
30052
- const hasChanges = nextContent !== currentContent || shouldUpdateUserOptions && message?.options?.contentInputPath !== "blocks";
30053
- if (!hasChanges) return message;
30054
- return {
30055
- ...message,
30056
- message: {
30057
- ...message.message ?? {},
30058
- content: nextContent
30059
- },
30060
- ...shouldUpdateUserOptions ? {
30061
- options: {
30062
- ...message.options ?? {},
30063
- contentInputPath: "blocks"
30064
- }
30065
- } : {}
30066
- };
30067
- });
30068
- }
30069
-
30070
29804
  // src/utils/session/toolOutputLifecycleMetricsDraft.ts
30071
29805
  function safeRate(numerator, denominator) {
30072
29806
  if (!Number.isFinite(numerator) || !Number.isFinite(denominator) || denominator <= 0) {
@@ -30353,7 +30087,686 @@ function createQueryLifecycleEvents(options) {
30353
30087
  };
30354
30088
  }
30355
30089
 
30356
- // src/app/query.ts
30090
+ // src/app/sessionContext.ts
30091
+ var SessionContext = class {
30092
+ state = "idle";
30093
+ interrupted = false;
30094
+ inFlightToolUseIDs = /* @__PURE__ */ new Set();
30095
+ setRunning() {
30096
+ if (this.state !== "closed") {
30097
+ this.state = "running";
30098
+ }
30099
+ }
30100
+ setIdle() {
30101
+ if (this.state !== "closed") {
30102
+ this.state = "idle";
30103
+ this.interrupted = false;
30104
+ }
30105
+ }
30106
+ setInterrupted() {
30107
+ if (this.state !== "closed") {
30108
+ this.state = "interrupted";
30109
+ this.interrupted = true;
30110
+ }
30111
+ }
30112
+ setErrored() {
30113
+ if (this.state !== "closed") {
30114
+ this.state = "errored";
30115
+ }
30116
+ }
30117
+ setClosed() {
30118
+ this.state = "closed";
30119
+ this.inFlightToolUseIDs.clear();
30120
+ }
30121
+ startTool(toolUseID) {
30122
+ if (toolUseID) this.inFlightToolUseIDs.add(toolUseID);
30123
+ }
30124
+ finishTool(toolUseID) {
30125
+ if (toolUseID) this.inFlightToolUseIDs.delete(toolUseID);
30126
+ }
30127
+ getSnapshot() {
30128
+ return {
30129
+ state: this.state,
30130
+ inFlightToolUseIDs: [...this.inFlightToolUseIDs],
30131
+ interrupted: this.interrupted
30132
+ };
30133
+ }
30134
+ };
30135
+
30136
+ // src/app/sessionEngine.ts
30137
+ var DefaultSessionEngine = class _DefaultSessionEngine {
30138
+ constructor(runner, initialInput) {
30139
+ this.runner = runner;
30140
+ this.currentInput = initialInput;
30141
+ }
30142
+ state = "idle";
30143
+ currentInput;
30144
+ generator;
30145
+ async send(input) {
30146
+ if (this.state === "closed") {
30147
+ throw new Error("invalid_transition: closed -> send");
30148
+ }
30149
+ this.currentInput = input;
30150
+ this.generator = this.runner(input);
30151
+ this.state = "running";
30152
+ }
30153
+ async *stream() {
30154
+ if (!this.generator) {
30155
+ return;
30156
+ }
30157
+ try {
30158
+ for await (const message of this.generator) {
30159
+ yield message;
30160
+ }
30161
+ if (this.state === "running") {
30162
+ this.state = "idle";
30163
+ }
30164
+ } catch (error) {
30165
+ this.state = "errored";
30166
+ throw error;
30167
+ }
30168
+ }
30169
+ async resume(input) {
30170
+ if (this.state === "closed") {
30171
+ throw new Error("invalid_transition: closed -> resume");
30172
+ }
30173
+ if (input !== void 0) {
30174
+ this.currentInput = input;
30175
+ }
30176
+ if (this.currentInput === void 0) {
30177
+ throw new Error("invalid_transition: missing_input -> resume");
30178
+ }
30179
+ this.generator = this.runner(this.currentInput);
30180
+ this.state = "running";
30181
+ }
30182
+ fork() {
30183
+ return new _DefaultSessionEngine(this.runner, this.currentInput);
30184
+ }
30185
+ async interrupt() {
30186
+ if (this.state === "running") {
30187
+ this.state = "interrupted";
30188
+ }
30189
+ }
30190
+ async close() {
30191
+ this.state = "closed";
30192
+ }
30193
+ getState() {
30194
+ return this.state;
30195
+ }
30196
+ };
30197
+ function createSession(args) {
30198
+ return new DefaultSessionEngine(args.runner, args.initialInput);
30199
+ }
30200
+ async function* runSessionWithEngine(args) {
30201
+ args.sessionContext?.setRunning();
30202
+ const session = createSession({
30203
+ runner: args.runner
30204
+ });
30205
+ await session.send(args.input);
30206
+ try {
30207
+ yield* session.stream();
30208
+ args.sessionContext?.setIdle();
30209
+ } catch (error) {
30210
+ args.sessionContext?.setErrored();
30211
+ throw error;
30212
+ } finally {
30213
+ await session.close();
30214
+ }
30215
+ }
30216
+ function logQuerySessionRolloutApplied(args) {
30217
+ args.logUserFriendly("THREE_LAYER_ROLLOUT_APPLIED", {
30218
+ enabled: args.featureFlags.rolloutEnabled,
30219
+ stage: args.featureFlags.rolloutStage,
30220
+ decision: args.featureFlags.rolloutDecision,
30221
+ reason: args.featureFlags.rolloutReason,
30222
+ percent: args.featureFlags.rolloutPercent,
30223
+ bucket: args.featureFlags.rolloutBucket,
30224
+ typedSessionWriteEnabled: args.featureFlags.typedSessionWriteEnabled,
30225
+ compactionBoundaryEnabled: args.featureFlags.compactionBoundaryEnabled,
30226
+ toolOutputLifecycleEnabled: args.featureFlags.toolOutputLifecycleEnabled,
30227
+ singleFactLayerReadEnabled: args.featureFlags.singleFactLayerReadEnabled
30228
+ });
30229
+ }
30230
+ function createQuerySessionPrimaryPolicyCoordinator(args) {
30231
+ let currentRequestId = args.initialRequestId ?? "";
30232
+ return {
30233
+ setRequestId: (requestId) => {
30234
+ currentRequestId = requestId;
30235
+ },
30236
+ policy: {
30237
+ onRolloutApplied: (featureFlags) => {
30238
+ logQuerySessionRolloutApplied({
30239
+ featureFlags,
30240
+ logUserFriendly: args.logUserFriendly
30241
+ });
30242
+ },
30243
+ onSkeletonRebuilt: (stats) => {
30244
+ args.logUserFriendly("SINGLE_FACT_LAYER_SKELETON_REBUILT", {
30245
+ role: stats.role,
30246
+ typedPartCount: stats.typedPartCount,
30247
+ skeletonBlockCount: stats.skeletonBlockCount,
30248
+ mapperMode: "rollback_only"
30249
+ });
30250
+ },
30251
+ onCompatibilityMetrics: (compatibilityMetrics) => {
30252
+ args.logUserFriendly("STREAM_TYPED_PROVIDER_COMPATIBILITY", {
30253
+ requestId: currentRequestId,
30254
+ provider: compatibilityMetrics.provider,
30255
+ supportsRichToolResult: compatibilityMetrics.supportsRichToolResult,
30256
+ richToolResultBlockCount: compatibilityMetrics.richToolResultBlockCount,
30257
+ downgradedToolResultCount: compatibilityMetrics.downgradedToolResultCount
30258
+ });
30259
+ }
30260
+ }
30261
+ };
30262
+ }
30263
+ function resolveQuerySessionFeatureFlags() {
30264
+ return {
30265
+ typedSessionWriteEnabled: true,
30266
+ compactionBoundaryEnabled: false,
30267
+ toolOutputLifecycleEnabled: false,
30268
+ singleFactLayerReadEnabled: true,
30269
+ rolloutEnabled: false,
30270
+ rolloutPercent: 100,
30271
+ rolloutBucket: 0,
30272
+ rolloutStage: "stage_100",
30273
+ rolloutDecision: "keep",
30274
+ rolloutReason: "rollout_disabled"
30275
+ };
30276
+ }
30277
+ function buildQueryTypedRequestId(args) {
30278
+ if (args.currentRequestId) return `query_${args.currentRequestId}`;
30279
+ if (args.fallbackQueryId) return `query_${args.fallbackQueryId}`;
30280
+ const now = args.now ?? Date.now();
30281
+ const randomSuffix = args.randomSuffix ?? Math.random().toString(36).slice(2, 10);
30282
+ return `query_${now}_${randomSuffix}`;
30283
+ }
30284
+ function prepareQueryTypedProjector(args) {
30285
+ const modelPointer = args.modelPointer || "main";
30286
+ const modelResolution = args.resolveModelWithInfo(modelPointer);
30287
+ const typedProvider = modelResolution.success ? String(modelResolution.profile?.provider ?? "").trim().toLowerCase() : "unknown";
30288
+ const typedProjector = args.createStreamTypedProjector({
30289
+ requestId: args.requestId,
30290
+ source: "query_main",
30291
+ provider: typedProvider
30292
+ });
30293
+ return { typedProvider, typedProjector };
30294
+ }
30295
+ function findLatestValue(args) {
30296
+ for (let index = args.items.length - 1; index >= 0; index -= 1) {
30297
+ const value = args.selectValue(args.items[index]);
30298
+ if (value !== void 0 && value !== null) {
30299
+ return value;
30300
+ }
30301
+ }
30302
+ return void 0;
30303
+ }
30304
+ function prepareQuerySessionExecution(args) {
30305
+ args.onRolloutApplied(args.featureFlags);
30306
+ if (typeof args.toolUseContext.compactionBoundaryEnabled !== "boolean") {
30307
+ args.toolUseContext.compactionBoundaryEnabled = args.featureFlags.compactionBoundaryEnabled;
30308
+ }
30309
+ if (typeof args.toolUseContext.toolOutputLifecycleEnabled !== "boolean") {
30310
+ args.toolUseContext.toolOutputLifecycleEnabled = args.featureFlags.toolOutputLifecycleEnabled;
30311
+ }
30312
+ if (typeof args.toolUseContext.singleFactLayerReadEnabled !== "boolean") {
30313
+ args.toolUseContext.singleFactLayerReadEnabled = args.featureFlags.singleFactLayerReadEnabled;
30314
+ }
30315
+ const messages = args.featureFlags.singleFactLayerReadEnabled ? args.normalizeMessagesForSingleFactLayer(args.messages) : args.messages;
30316
+ return {
30317
+ messages,
30318
+ shouldPersistTypedSession: args.shouldPersistSession && args.featureFlags.typedSessionWriteEnabled,
30319
+ shouldBuildSingleFactSkeleton: args.featureFlags.singleFactLayerReadEnabled
30320
+ };
30321
+ }
30322
+ function prepareQuerySessionPrimaryPlan(args) {
30323
+ const shouldPersistSession = args.toolUseContext.options?.persistSession !== false && !args.isTestEnv;
30324
+ const fallbackQueryId = findLatestValue({
30325
+ items: args.messages,
30326
+ selectValue: args.extractUserQueryId
30327
+ });
30328
+ const typedRequestId = buildQueryTypedRequestId({
30329
+ currentRequestId: args.currentRequestId,
30330
+ fallbackQueryId
30331
+ });
30332
+ args.policyCoordinator?.setRequestId(typedRequestId);
30333
+ const { typedProjector } = prepareQueryTypedProjector({
30334
+ requestId: typedRequestId,
30335
+ modelPointer: args.toolUseContext.options?.model,
30336
+ resolveModelWithInfo: args.resolveModelWithInfo,
30337
+ createStreamTypedProjector: args.createStreamTypedProjector
30338
+ });
30339
+ const rolloutFlags = resolveQuerySessionFeatureFlags();
30340
+ const {
30341
+ messages: preparedMessages,
30342
+ shouldPersistTypedSession,
30343
+ shouldBuildSingleFactSkeleton
30344
+ } = prepareQuerySessionExecution({
30345
+ featureFlags: rolloutFlags,
30346
+ shouldPersistSession,
30347
+ toolUseContext: args.toolUseContext,
30348
+ messages: args.messages,
30349
+ normalizeMessagesForSingleFactLayer: args.normalizeMessagesForSingleFactLayer,
30350
+ onRolloutApplied: args.policyCoordinator?.policy.onRolloutApplied ?? args.policy?.onRolloutApplied ?? args.onRolloutApplied ?? (() => void 0)
30351
+ });
30352
+ return {
30353
+ preparedMessages,
30354
+ typedRequestId,
30355
+ typedProjector,
30356
+ shouldPersistTypedSession,
30357
+ shouldBuildSingleFactSkeleton
30358
+ };
30359
+ }
30360
+ async function* runQuerySessionPrimaryStream(args) {
30361
+ const activePolicy = args.policyCoordinator?.policy ?? args.policy;
30362
+ const lifecycleBinding = bindQueryLifecycleBuffer({
30363
+ onQueryLifecycleEvent: args.onQueryLifecycleEvent,
30364
+ setOnQueryLifecycleEvent: args.setOnQueryLifecycleEvent
30365
+ });
30366
+ try {
30367
+ for await (const message of withSessionRunning({
30368
+ sessionContext: args.sessionContext,
30369
+ stream: args.stream
30370
+ })) {
30371
+ processQuerySessionTypedOutput({
30372
+ message,
30373
+ lifecycleEventBuffer: lifecycleBinding.lifecycleEventBuffer,
30374
+ typedProjector: args.typedProjector,
30375
+ shouldPersistTypedSession: args.shouldPersistTypedSession,
30376
+ shouldBuildSingleFactSkeleton: args.shouldBuildSingleFactSkeleton,
30377
+ requestId: args.requestId,
30378
+ projectLifecycleEventsToTypedParts: args.projectLifecycleEventsToTypedParts,
30379
+ projectMessageToTypedParts: args.projectMessageToTypedParts,
30380
+ emitTypedPart: args.emitTypedPart,
30381
+ buildSkeletonBlocksFromTypedParts: args.buildSkeletonBlocksFromTypedParts,
30382
+ onSkeletonRebuilt: activePolicy?.onSkeletonRebuilt ?? args.onSkeletonRebuilt ?? (() => void 0)
30383
+ });
30384
+ yield message;
30385
+ }
30386
+ } finally {
30387
+ lifecycleBinding.dispose();
30388
+ finalizeQuerySessionTypedOutput({
30389
+ shouldPersistTypedSession: args.shouldPersistTypedSession,
30390
+ requestId: args.requestId,
30391
+ typedProjector: args.typedProjector,
30392
+ flushTypedPartBuffer: args.flushTypedPartBuffer,
30393
+ consumeProjectorCompatibilityMetrics: args.consumeProjectorCompatibilityMetrics,
30394
+ onCompatibilityMetrics: activePolicy?.onCompatibilityMetrics ?? args.onCompatibilityMetrics ?? (() => void 0)
30395
+ });
30396
+ }
30397
+ }
30398
+ async function* runQuerySessionPrimary(args) {
30399
+ const policyCoordinator = createQuerySessionPrimaryPolicyCoordinator({
30400
+ logUserFriendly: args.logUserFriendly
30401
+ });
30402
+ const {
30403
+ preparedMessages,
30404
+ typedRequestId,
30405
+ typedProjector,
30406
+ shouldPersistTypedSession,
30407
+ shouldBuildSingleFactSkeleton
30408
+ } = prepareQuerySessionPrimaryPlan({
30409
+ messages: args.messages,
30410
+ toolUseContext: args.toolUseContext,
30411
+ currentRequestId: args.currentRequestId,
30412
+ isTestEnv: args.isTestEnv,
30413
+ resolveModelWithInfo: args.resolveModelWithInfo,
30414
+ createStreamTypedProjector: args.createStreamTypedProjector,
30415
+ normalizeMessagesForSingleFactLayer: args.normalizeMessagesForSingleFactLayer,
30416
+ extractUserQueryId: args.extractUserQueryId,
30417
+ policyCoordinator
30418
+ });
30419
+ yield* runQuerySessionPrimaryStream({
30420
+ sessionContext: args.sessionContext,
30421
+ onQueryLifecycleEvent: args.onQueryLifecycleEvent,
30422
+ setOnQueryLifecycleEvent: args.setOnQueryLifecycleEvent,
30423
+ stream: () => args.stream(preparedMessages),
30424
+ typedProjector,
30425
+ shouldPersistTypedSession,
30426
+ shouldBuildSingleFactSkeleton,
30427
+ requestId: typedRequestId,
30428
+ projectLifecycleEventsToTypedParts: args.projectLifecycleEventsToTypedParts,
30429
+ projectMessageToTypedParts: args.projectMessageToTypedParts,
30430
+ emitTypedPart: args.emitTypedPart,
30431
+ buildSkeletonBlocksFromTypedParts: args.buildSkeletonBlocksFromTypedParts,
30432
+ flushTypedPartBuffer: args.flushTypedPartBuffer,
30433
+ consumeProjectorCompatibilityMetrics: args.consumeProjectorCompatibilityMetrics,
30434
+ policyCoordinator
30435
+ });
30436
+ }
30437
+ function createQuerySessionPrimaryAdapterInput(args) {
30438
+ return {
30439
+ messages: args.messages,
30440
+ toolUseContext: args.toolUseContext,
30441
+ currentRequestId: args.currentRequestId,
30442
+ isTestEnv: args.isTestEnv,
30443
+ resolveModelWithInfo: args.hooks.resolveModelWithInfo,
30444
+ createStreamTypedProjector: args.hooks.createStreamTypedProjector,
30445
+ normalizeMessagesForSingleFactLayer: args.hooks.normalizeMessagesForSingleFactLayer,
30446
+ extractUserQueryId: args.extractUserQueryId ?? ((message) => message?.type === "user" ? message.queryId : void 0),
30447
+ logUserFriendly: args.logUserFriendly,
30448
+ sessionContext: args.sessionContext ?? ensureSessionContext(args.toolUseContext),
30449
+ onQueryLifecycleEvent: args.toolUseContext.onQueryLifecycleEvent,
30450
+ setOnQueryLifecycleEvent: (handler) => {
30451
+ args.toolUseContext.onQueryLifecycleEvent = handler;
30452
+ },
30453
+ stream: args.stream,
30454
+ projectLifecycleEventsToTypedParts: args.hooks.projectLifecycleEventsToTypedParts,
30455
+ projectMessageToTypedParts: args.hooks.projectMessageToTypedParts,
30456
+ emitTypedPart: args.hooks.emitTypedPart,
30457
+ buildSkeletonBlocksFromTypedParts: args.hooks.buildSkeletonBlocksFromTypedParts,
30458
+ flushTypedPartBuffer: args.hooks.flushTypedPartBuffer,
30459
+ consumeProjectorCompatibilityMetrics: args.hooks.consumeProjectorCompatibilityMetrics
30460
+ };
30461
+ }
30462
+ async function* runQuerySessionPrimaryAdapter(args) {
30463
+ const primaryArgs = "hooks" in args ? createQuerySessionPrimaryAdapterInput(args) : args;
30464
+ yield* runSessionWithEngine({
30465
+ input: primaryArgs,
30466
+ runner: runQuerySessionPrimary
30467
+ });
30468
+ }
30469
+ async function* runQuerySessionCompatAdapter(args) {
30470
+ const primaryInput = createQuerySessionPrimaryAdapterInput(args);
30471
+ yield* runSessionCompatStreams({
30472
+ routingContext: args.routingContext,
30473
+ primaryInput,
30474
+ primaryRunner: runQuerySessionPrimaryAdapter,
30475
+ fallbackInput: args.fallbackInput,
30476
+ fallbackRunner: args.fallbackRunner,
30477
+ toolUseContext: args.toolUseContext
30478
+ });
30479
+ }
30480
+ async function* runQuerySessionLegacyCompatAdapter(args) {
30481
+ const streamRunner = args.stream;
30482
+ yield* runQuerySessionCompatAdapter({
30483
+ ...args,
30484
+ routingContext: {
30485
+ sessionId: args.toolUseContext.sessionId,
30486
+ agentId: args.toolUseContext.agentId,
30487
+ requestId: args.requestId
30488
+ },
30489
+ fallbackInput: args.messages,
30490
+ fallbackRunner: streamRunner
30491
+ });
30492
+ }
30493
+ function processQuerySessionTypedOutput(args) {
30494
+ if (!args.shouldPersistTypedSession && !args.shouldBuildSingleFactSkeleton) {
30495
+ return;
30496
+ }
30497
+ const lifecycleParts = args.projectLifecycleEventsToTypedParts(
30498
+ args.typedProjector,
30499
+ args.lifecycleEventBuffer.splice(0)
30500
+ );
30501
+ const parts = [
30502
+ ...lifecycleParts,
30503
+ ...args.projectMessageToTypedParts(args.typedProjector, args.message)
30504
+ ];
30505
+ if (args.shouldPersistTypedSession) {
30506
+ for (const part of parts) {
30507
+ args.emitTypedPart({ requestId: args.requestId, part });
30508
+ }
30509
+ }
30510
+ if (args.shouldBuildSingleFactSkeleton && (args.message.type === "assistant" || args.message.type === "user")) {
30511
+ const skeletonBlocks = args.buildSkeletonBlocksFromTypedParts({
30512
+ role: args.message.type,
30513
+ parts
30514
+ });
30515
+ args.onSkeletonRebuilt({
30516
+ role: args.message.type,
30517
+ typedPartCount: parts.length,
30518
+ skeletonBlockCount: skeletonBlocks.length
30519
+ });
30520
+ }
30521
+ }
30522
+ function finalizeQuerySessionTypedOutput(args) {
30523
+ if (!args.shouldPersistTypedSession) {
30524
+ return;
30525
+ }
30526
+ args.flushTypedPartBuffer({ requestId: args.requestId });
30527
+ const compatibilityMetrics = args.consumeProjectorCompatibilityMetrics(args.typedProjector);
30528
+ args.onCompatibilityMetrics(compatibilityMetrics);
30529
+ }
30530
+ function bindQueryLifecycleBuffer(args) {
30531
+ const lifecycleEventBuffer = [];
30532
+ const previousOnQueryLifecycleEvent = args.onQueryLifecycleEvent;
30533
+ args.setOnQueryLifecycleEvent((event) => {
30534
+ previousOnQueryLifecycleEvent?.(event);
30535
+ lifecycleEventBuffer.push(event);
30536
+ });
30537
+ return {
30538
+ lifecycleEventBuffer,
30539
+ dispose: () => {
30540
+ args.setOnQueryLifecycleEvent(previousOnQueryLifecycleEvent);
30541
+ }
30542
+ };
30543
+ }
30544
+ function ensureSessionContext(carrier) {
30545
+ const sessionContext = carrier.sessionContext ?? new SessionContext();
30546
+ carrier.sessionContext = sessionContext;
30547
+ return sessionContext;
30548
+ }
30549
+ async function* withSessionRunning(args) {
30550
+ args.sessionContext.setRunning();
30551
+ try {
30552
+ yield* args.stream();
30553
+ args.sessionContext.setIdle();
30554
+ } catch (error) {
30555
+ args.sessionContext.setErrored();
30556
+ throw error;
30557
+ }
30558
+ }
30559
+ function resolveSessionAdapterControls(replaySeed) {
30560
+ return {
30561
+ enabled: resolveSessionEngineEnabledForCutover(),
30562
+ rolloutPercent: resolveSessionEngineRolloutPercent(),
30563
+ replaySample: resolveSessionEngineReplaySample(replaySeed),
30564
+ forceFallback: resolveSessionEngineForceFallback()
30565
+ };
30566
+ }
30567
+ async function* runSessionOrchestrator(args) {
30568
+ const controls = resolveSessionAdapterControls(args.replaySeed);
30569
+ const selectedRunner = shouldUseSessionEngineByRollout({
30570
+ enabled: controls.enabled,
30571
+ rolloutPercent: controls.rolloutPercent,
30572
+ replaySample: controls.replaySample,
30573
+ forceFallback: controls.forceFallback
30574
+ }) ? args.sessionRunner : args.fallbackRunner;
30575
+ yield* runSessionWithEngine({
30576
+ input: args.input,
30577
+ runner: selectedRunner
30578
+ });
30579
+ }
30580
+ function createSessionReplaySeed(context) {
30581
+ return `${context.sessionId ?? ""}:${context.agentId ?? ""}:${context.requestId ?? ""}`;
30582
+ }
30583
+ async function* runSessionOrchestratorWithContext(args) {
30584
+ const replaySeed = createSessionReplaySeed(args.routingContext);
30585
+ yield* runSessionOrchestrator({
30586
+ input: args.input,
30587
+ replaySeed,
30588
+ sessionRunner: args.sessionRunner,
30589
+ fallbackRunner: args.fallbackRunner
30590
+ });
30591
+ }
30592
+ async function* runSessionOrchestratorStreams(args) {
30593
+ yield* runSessionOrchestratorWithContext({
30594
+ input: void 0,
30595
+ routingContext: args.routingContext,
30596
+ sessionRunner: async function* () {
30597
+ yield* args.sessionStream();
30598
+ },
30599
+ fallbackRunner: async function* () {
30600
+ yield* args.fallbackStream();
30601
+ }
30602
+ });
30603
+ }
30604
+ async function* runSessionCompatStreams(args) {
30605
+ const sessionContext = ensureSessionContext(args.toolUseContext);
30606
+ yield* runSessionOrchestratorStreams({
30607
+ routingContext: args.routingContext,
30608
+ sessionStream: async function* () {
30609
+ yield* args.primaryRunner(args.primaryInput);
30610
+ },
30611
+ fallbackStream: async function* () {
30612
+ yield* runSessionWithEngine({
30613
+ input: args.fallbackInput,
30614
+ sessionContext,
30615
+ runner: args.fallbackRunner
30616
+ });
30617
+ }
30618
+ });
30619
+ }
30620
+ function resolveSessionEngineEnabled() {
30621
+ return process.env.PYB_SESSION_ENGINE_ENABLED === "true";
30622
+ }
30623
+ function resolveSessionEngineDefaultOn() {
30624
+ return process.env.PYB_SESSION_ENGINE_DEFAULT_ON === "true";
30625
+ }
30626
+ function resolveSessionEngineEnabledForCutover() {
30627
+ return resolveSessionEngineEnabled() || resolveSessionEngineDefaultOn();
30628
+ }
30629
+ function resolveSessionEngineForceFallback() {
30630
+ return process.env.PYB_SESSION_ENGINE_FORCE_FALLBACK === "true";
30631
+ }
30632
+ function resolveSessionEngineRolloutPercent() {
30633
+ const raw = process.env.PYB_SESSION_ENGINE_ROLLOUT_PERCENT;
30634
+ if (!raw) return 0;
30635
+ const parsed = Number(raw);
30636
+ if (!Number.isFinite(parsed)) return 0;
30637
+ if (parsed < 0) return 0;
30638
+ if (parsed > 100) return 100;
30639
+ return Math.floor(parsed);
30640
+ }
30641
+ function shouldUseSessionEngineByRollout(args) {
30642
+ if (!args.enabled) return false;
30643
+ if (args.forceFallback) return false;
30644
+ const percent = Math.max(0, Math.min(100, Math.floor(args.rolloutPercent)));
30645
+ const sample2 = Math.max(0, Math.min(99, Math.floor(args.replaySample)));
30646
+ return sample2 < percent;
30647
+ }
30648
+ function resolveSessionEngineReplaySample(replaySeed) {
30649
+ let hash = 0;
30650
+ for (let index = 0; index < replaySeed.length; index += 1) {
30651
+ hash = hash * 31 + replaySeed.charCodeAt(index) >>> 0;
30652
+ }
30653
+ return hash % 100;
30654
+ }
30655
+
30656
+ // src/app/queryRuntime/errorMapping.ts
30657
+ var ERROR_CLASS_BY_CODE = {
30658
+ ENOENT: "soft",
30659
+ EISDIR: "soft",
30660
+ EACCES: "retryable",
30661
+ EPERM: "retryable",
30662
+ EMFILE: "retryable",
30663
+ ENFILE: "retryable",
30664
+ EIO: "fatal",
30665
+ ENODEV: "fatal",
30666
+ EBUSY: "fatal"
30667
+ };
30668
+ function formatError(error) {
30669
+ if (!(error instanceof Error)) {
30670
+ return String(error);
30671
+ }
30672
+ const parts = [error.message];
30673
+ if ("stderr" in error && typeof error.stderr === "string") {
30674
+ parts.push(error.stderr);
30675
+ }
30676
+ if ("stdout" in error && typeof error.stdout === "string") {
30677
+ parts.push(error.stdout);
30678
+ }
30679
+ const fullMessage = parts.filter(Boolean).join("\n");
30680
+ if (fullMessage.length <= 1e4) {
30681
+ return fullMessage;
30682
+ }
30683
+ const halfLength = 5e3;
30684
+ const start = fullMessage.slice(0, halfLength);
30685
+ const end = fullMessage.slice(-halfLength);
30686
+ return `${start}
30687
+
30688
+ ... [${fullMessage.length - 1e4} characters truncated] ...
30689
+
30690
+ ${end}`;
30691
+ }
30692
+ function extractErrorCode(error) {
30693
+ if (!error || typeof error !== "object") {
30694
+ return void 0;
30695
+ }
30696
+ if ("code" in error && typeof error.code === "string") {
30697
+ return error.code;
30698
+ }
30699
+ return void 0;
30700
+ }
30701
+ function summarizeError(detail) {
30702
+ const line = detail.split("\n").map((part) => part.trim()).find((part) => part.length > 0);
30703
+ const summary = line ?? detail.trim();
30704
+ return summary.length > 200 ? summary.slice(0, 200) : summary;
30705
+ }
30706
+ function getErrorClassFromCode(errorCode) {
30707
+ if (!errorCode) return "soft";
30708
+ return ERROR_CLASS_BY_CODE[errorCode] ?? "soft";
30709
+ }
30710
+ function createErrorToolResultBlock(args) {
30711
+ const detail = typeof args.errorDetail === "string" ? args.errorDetail : typeof args.content === "string" ? args.content : JSON.stringify(args.content);
30712
+ const errorCode = args.errorCode;
30713
+ const errorClass = args.errorClass ?? getErrorClassFromCode(errorCode);
30714
+ const summary = detail ? summarizeError(detail) : "";
30715
+ return {
30716
+ type: "tool_result",
30717
+ content: args.content,
30718
+ is_error: true,
30719
+ tool_use_id: args.toolUseId,
30720
+ error_class: errorClass,
30721
+ ...errorCode ? { error_code: errorCode } : {},
30722
+ ...summary ? { error_summary: summary } : {},
30723
+ ...detail ? { error_detail: detail } : {},
30724
+ ...args.rootToolUseId ? { root_tool_use_id: args.rootToolUseId } : {}
30725
+ };
30726
+ }
30727
+
30728
+ // src/app/queryRuntime/toolInput.ts
30729
+ function normalizeToolInput(tool, input) {
30730
+ switch (tool) {
30731
+ case BashTool: {
30732
+ const parsed = BashTool.inputSchema.parse(input);
30733
+ const {
30734
+ command: command4,
30735
+ timeout,
30736
+ description: description3,
30737
+ run_in_background,
30738
+ dangerouslyDisableSandbox
30739
+ } = parsed;
30740
+ return {
30741
+ command: command4.replace(`cd ${getCwd()} && `, "").replace(/\\\\;/g, "\\;"),
30742
+ ...timeout !== void 0 ? { timeout } : {},
30743
+ ...description3 ? { description: description3 } : {},
30744
+ ...run_in_background ? { run_in_background } : {},
30745
+ ...dangerouslyDisableSandbox ? { dangerouslyDisableSandbox } : {}
30746
+ };
30747
+ }
30748
+ default:
30749
+ return input;
30750
+ }
30751
+ }
30752
+ function buildRetryEntryKey(parts) {
30753
+ return parts.map((part) => typeof part === "string" ? part.trim() : "").filter((part) => part.length > 0).join(":");
30754
+ }
30755
+ function preprocessToolInput(tool, input) {
30756
+ if (tool.name === "TaskOutput") {
30757
+ const task_id = typeof input.task_id === "string" && input.task_id || typeof input.agentId === "string" && String(input.agentId) || typeof input.bash_id === "string" && String(input.bash_id) || "";
30758
+ const block = typeof input.block === "boolean" ? input.block : true;
30759
+ const timeout = typeof input.timeout === "number" ? input.timeout : typeof input.wait_up_to === "number" ? Number(input.wait_up_to) * 1e3 : void 0;
30760
+ return {
30761
+ task_id,
30762
+ block,
30763
+ ...timeout !== void 0 ? { timeout } : {}
30764
+ };
30765
+ }
30766
+ return input;
30767
+ }
30768
+
30769
+ // src/app/queryRuntime/lifecycle.ts
30357
30770
  var TOOL_PROGRESS_OPEN_TAG = ["<tool", "-progress>"].join("");
30358
30771
  var TOOL_PROGRESS_CLOSE_TAG = ["</tool", "-progress>"].join("");
30359
30772
  function inferIsNewSessionForAutoCompact(messages) {
@@ -30365,6 +30778,565 @@ function inferIsNewSessionForAutoCompact(messages) {
30365
30778
  );
30366
30779
  return !hasCompactionMarker && naturalMessages.length <= 2;
30367
30780
  }
30781
+
30782
+ // src/services/ai/streamTyped/projector.ts
30783
+ function supportsRichToolResultByProvider(provider) {
30784
+ return String(provider ?? "").trim().toLowerCase() === "anthropic";
30785
+ }
30786
+ function extractToolResultText2(content) {
30787
+ if (typeof content === "string") return { text: content, hasNonTextBlock: false };
30788
+ if (!Array.isArray(content)) return { text: "", hasNonTextBlock: false };
30789
+ let hasNonTextBlock = false;
30790
+ const text = content.filter((block) => {
30791
+ if (!block || typeof block !== "object") return false;
30792
+ if (block.type === "text") return true;
30793
+ hasNonTextBlock = true;
30794
+ return false;
30795
+ }).map((block) => String(block.text ?? "")).join("\n");
30796
+ return { text, hasNonTextBlock };
30797
+ }
30798
+ function extractTaggedText(text, tagName) {
30799
+ const normalized = String(text ?? "").trim();
30800
+ if (!normalized.startsWith(`<${tagName}>`)) return null;
30801
+ const pattern = new RegExp(`<${tagName}>([\\s\\S]*?)<\\/${tagName}>`, "i");
30802
+ const match = normalized.match(pattern);
30803
+ const content = String(match?.[1] ?? "").trim();
30804
+ return content.length > 0 ? content : null;
30805
+ }
30806
+ function projectAssistantMessage(state, message) {
30807
+ const content = message?.message?.content;
30808
+ if (!Array.isArray(content)) return;
30809
+ for (let i = 0; i < content.length; i += 1) {
30810
+ const block = content[i];
30811
+ if (!block || typeof block !== "object") continue;
30812
+ const type3 = String(block.type ?? "");
30813
+ if (type3 === "text") {
30814
+ const text = String(block.text ?? "");
30815
+ const toolProgressText = extractTaggedText(text, "tool-progress");
30816
+ if (toolProgressText) {
30817
+ state.parts.push(
30818
+ createSystemEventPart({
30819
+ requestId: state.requestId,
30820
+ eventType: "tool_progress",
30821
+ text: toolProgressText,
30822
+ source: state.source
30823
+ })
30824
+ );
30825
+ }
30826
+ const localStdoutText = extractTaggedText(text, "local-command-stdout");
30827
+ if (localStdoutText) {
30828
+ state.parts.push(
30829
+ createSystemEventPart({
30830
+ requestId: state.requestId,
30831
+ eventType: "local_command_stdout",
30832
+ text: localStdoutText,
30833
+ source: state.source
30834
+ })
30835
+ );
30836
+ }
30837
+ const localStderrText = extractTaggedText(text, "local-command-stderr");
30838
+ if (localStderrText) {
30839
+ state.parts.push(
30840
+ createSystemEventPart({
30841
+ requestId: state.requestId,
30842
+ eventType: "local_command_stderr",
30843
+ text: localStderrText,
30844
+ source: state.source
30845
+ })
30846
+ );
30847
+ }
30848
+ onTextStart({ textId: `text-${i}` }, state);
30849
+ onTextDelta({ textId: `text-${i}`, text }, state);
30850
+ onTextEnd({ textId: `text-${i}` }, state);
30851
+ continue;
30852
+ }
30853
+ if (type3 === "thinking" || type3 === "reasoning") {
30854
+ const text = String(block.thinking ?? block.reasoning ?? "");
30855
+ onReasoningStart({ reasoningId: `reasoning-${i}` }, state);
30856
+ onReasoningDelta({ reasoningId: `reasoning-${i}`, text }, state);
30857
+ onReasoningEnd({ reasoningId: `reasoning-${i}` }, state);
30858
+ continue;
30859
+ }
30860
+ if (type3 === "tool_use" || type3 === "server_tool_use" || type3 === "mcp_tool_use") {
30861
+ const toolCallId = String(block.id ?? `tool-${i}`);
30862
+ const toolName = String(block.name ?? "unknown");
30863
+ onToolCall({ toolCallId, toolName }, state);
30864
+ }
30865
+ }
30866
+ }
30867
+ function projectUserToolResult(projector, message) {
30868
+ const state = projector.state;
30869
+ const content = message?.message?.content;
30870
+ if (!Array.isArray(content)) return;
30871
+ for (let i = 0; i < content.length; i += 1) {
30872
+ const block = content[i];
30873
+ if (!block || typeof block !== "object") continue;
30874
+ if (block.type !== "tool_result") continue;
30875
+ const toolCallId = String(block.tool_use_id ?? `tool-${i}`);
30876
+ const extracted = extractToolResultText2(block.content);
30877
+ if (extracted.hasNonTextBlock) {
30878
+ projector.richToolResultBlockCount += 1;
30879
+ if (!projector.supportsRichToolResult) {
30880
+ projector.downgradedToolResultCount += 1;
30881
+ }
30882
+ }
30883
+ onToolResult(
30884
+ {
30885
+ toolCallId,
30886
+ status: block.is_error ? "failed" : "completed",
30887
+ outputText: extracted.text
30888
+ },
30889
+ state
30890
+ );
30891
+ }
30892
+ }
30893
+ function projectProgressMessage(state, message) {
30894
+ const toolCallId = String(message?.toolUseID ?? "").trim();
30895
+ if (!toolCallId) return;
30896
+ const content = String(
30897
+ message?.content?.message?.content?.find?.((block) => block?.type === "text")?.text ?? ""
30898
+ );
30899
+ const extractedProgressText = extractTaggedText(content, "tool-progress");
30900
+ const normalizedContent = content.trim();
30901
+ const toolProgressText = extractedProgressText ?? (normalizedContent.length > 0 ? normalizedContent : void 0);
30902
+ if (toolProgressText) {
30903
+ state.parts.push(
30904
+ createSystemEventPart({
30905
+ requestId: state.requestId,
30906
+ eventType: "tool_progress",
30907
+ text: toolProgressText,
30908
+ toolCallId,
30909
+ source: state.source
30910
+ })
30911
+ );
30912
+ }
30913
+ onToolResult(
30914
+ {
30915
+ toolCallId,
30916
+ status: "running",
30917
+ outputText: content || void 0
30918
+ },
30919
+ state
30920
+ );
30921
+ }
30922
+ function createStreamTypedProjector(options) {
30923
+ const provider = String(options.provider ?? "").trim().toLowerCase();
30924
+ return {
30925
+ state: createAssemblerState(options.requestId, options.source ?? "query_main"),
30926
+ provider,
30927
+ supportsRichToolResult: typeof options.supportsRichToolResult === "boolean" ? options.supportsRichToolResult : supportsRichToolResultByProvider(provider),
30928
+ richToolResultBlockCount: 0,
30929
+ downgradedToolResultCount: 0
30930
+ };
30931
+ }
30932
+ function consumeProjectorCompatibilityMetrics(projector) {
30933
+ const snapshot = {
30934
+ provider: projector.provider || "unknown",
30935
+ supportsRichToolResult: projector.supportsRichToolResult,
30936
+ richToolResultBlockCount: projector.richToolResultBlockCount,
30937
+ downgradedToolResultCount: projector.downgradedToolResultCount
30938
+ };
30939
+ projector.richToolResultBlockCount = 0;
30940
+ projector.downgradedToolResultCount = 0;
30941
+ return snapshot;
30942
+ }
30943
+ function projectMessageToTypedParts(projector, message) {
30944
+ if (!message || typeof message !== "object") return [];
30945
+ if (message.type === "assistant") {
30946
+ projectAssistantMessage(projector.state, message);
30947
+ } else if (message.type === "user") {
30948
+ projectUserToolResult(projector, message);
30949
+ } else if (message.type === "progress") {
30950
+ projectProgressMessage(projector.state, message);
30951
+ }
30952
+ return flushTypedParts(projector.state);
30953
+ }
30954
+ function projectLifecycleEventsToTypedParts(projector, events) {
30955
+ if (!Array.isArray(events) || events.length === 0) return [];
30956
+ const parts = [];
30957
+ for (const event of events) {
30958
+ if (!event || typeof event !== "object") continue;
30959
+ if (event.eventType === "start-step") {
30960
+ parts.push(
30961
+ createStepStartPart({
30962
+ requestId: projector.state.requestId,
30963
+ stepId: event.stepId,
30964
+ timeStart: event.timestamp,
30965
+ source: projector.state.source
30966
+ })
30967
+ );
30968
+ continue;
30969
+ }
30970
+ if (event.eventType === "finish-step") {
30971
+ parts.push(
30972
+ createStepFinishPart({
30973
+ requestId: projector.state.requestId,
30974
+ stepId: event.stepId,
30975
+ reason: event.reason,
30976
+ completedAt: event.completedAt,
30977
+ costUSD: event.costUSD,
30978
+ ...event.tokens ? { tokens: event.tokens } : {},
30979
+ source: projector.state.source
30980
+ })
30981
+ );
30982
+ }
30983
+ }
30984
+ return parts;
30985
+ }
30986
+
30987
+ // src/services/ai/streamTyped/skeletonReader.ts
30988
+ function pushText(parts, value) {
30989
+ const text = String(value ?? "").trim();
30990
+ if (!text) return;
30991
+ parts.push({ type: "text", text });
30992
+ }
30993
+ function getToolState(part) {
30994
+ if (part.partType !== "tool") return null;
30995
+ const payload = part.payload;
30996
+ return payload?.state ?? null;
30997
+ }
30998
+ function buildSkeletonBlocksFromTypedParts(input) {
30999
+ const result = [];
31000
+ for (const part of input.parts) {
31001
+ if (!part || typeof part !== "object") continue;
31002
+ if (part.partType === "text") {
31003
+ pushText(result, part.payload?.text);
31004
+ continue;
31005
+ }
31006
+ if (part.partType === "reasoning" && input.role === "assistant") {
31007
+ const reasoning = String(part.payload?.text ?? "").trim();
31008
+ if (!reasoning) continue;
31009
+ result.push({ type: "reasoning", reasoning });
31010
+ continue;
31011
+ }
31012
+ if (part.partType !== "tool") continue;
31013
+ const payload = part.payload;
31014
+ const state = getToolState(part);
31015
+ const status = String(
31016
+ state?.status ?? payload?.status ?? ""
31017
+ ).toLowerCase();
31018
+ const toolName = String(payload?.toolName ?? "").trim();
31019
+ const toolCallId = String(payload?.toolCallId ?? "").trim();
31020
+ if (!toolCallId) continue;
31021
+ if (input.role === "assistant") {
31022
+ if (status !== "pending") continue;
31023
+ result.push({
31024
+ type: "tool_use",
31025
+ id: toolCallId,
31026
+ name: toolName || "unknown",
31027
+ input: state?.input && typeof state.input === "object" ? state.input : payload?.input && typeof payload.input === "object" ? payload.input : {}
31028
+ });
31029
+ continue;
31030
+ }
31031
+ if (status !== "completed" && status !== "failed" && status !== "interrupted") {
31032
+ continue;
31033
+ }
31034
+ const content = String(
31035
+ state?.output ?? state?.error ?? state?.reason ?? payload?.outputText ?? ""
31036
+ ).trim();
31037
+ result.push({
31038
+ type: "tool_result",
31039
+ tool_use_id: toolCallId,
31040
+ content,
31041
+ ...status === "failed" ? { is_error: true } : {}
31042
+ });
31043
+ }
31044
+ return result;
31045
+ }
31046
+
31047
+ // src/utils/session/singleFactLayer.ts
31048
+ function toTextBlockContent(content) {
31049
+ if (typeof content !== "string") return content;
31050
+ return [
31051
+ {
31052
+ type: "text",
31053
+ text: content
31054
+ }
31055
+ ];
31056
+ }
31057
+ function normalizeMessagesForSingleFactLayer(messages) {
31058
+ if (!Array.isArray(messages) || messages.length === 0) return messages;
31059
+ return messages.map((message) => {
31060
+ if (!message || typeof message !== "object") return message;
31061
+ if (message.type !== "user" && message.type !== "assistant") return message;
31062
+ const currentContent = message?.message?.content;
31063
+ const nextContent = toTextBlockContent(currentContent);
31064
+ const shouldUpdateUserOptions = message.type === "user";
31065
+ const hasChanges = nextContent !== currentContent || shouldUpdateUserOptions && message?.options?.contentInputPath !== "blocks";
31066
+ if (!hasChanges) return message;
31067
+ return {
31068
+ ...message,
31069
+ message: {
31070
+ ...message.message ?? {},
31071
+ content: nextContent
31072
+ },
31073
+ ...shouldUpdateUserOptions ? {
31074
+ options: {
31075
+ ...message.options ?? {},
31076
+ contentInputPath: "blocks"
31077
+ }
31078
+ } : {}
31079
+ };
31080
+ });
31081
+ }
31082
+
31083
+ // src/app/queryRuntime/sessionAdapterHooks.ts
31084
+ var querySessionPrimaryAdapterHooksInline = {
31085
+ resolveModelWithInfo: (modelPointer) => getModelManager().resolveModelWithInfo(modelPointer),
31086
+ createStreamTypedProjector,
31087
+ normalizeMessagesForSingleFactLayer,
31088
+ projectLifecycleEventsToTypedParts,
31089
+ projectMessageToTypedParts,
31090
+ emitTypedPart,
31091
+ buildSkeletonBlocksFromTypedParts,
31092
+ flushTypedPartBuffer,
31093
+ consumeProjectorCompatibilityMetrics
31094
+ };
31095
+
31096
+ // src/app/queryRuntime/toolExecution.ts
31097
+ function buildToolHookBaseArgs(context, toolUseId) {
31098
+ return {
31099
+ retryEntryKey: buildRetryEntryKey([
31100
+ context.sessionId,
31101
+ context.parentSessionId,
31102
+ context.childSessionId,
31103
+ context.agentId,
31104
+ toolUseId
31105
+ ]),
31106
+ retryAttempt: 0,
31107
+ sessionId: context.sessionId,
31108
+ parentSessionId: context.parentSessionId,
31109
+ childSessionId: context.childSessionId,
31110
+ agentId: context.agentId,
31111
+ permissionMode: context.options?.toolPermissionContext?.mode,
31112
+ cwd: getCwd(),
31113
+ transcriptPath: getHookTranscriptPath(context),
31114
+ safeMode: context.options?.safeMode ?? false,
31115
+ signal: context.abortController.signal
31116
+ };
31117
+ }
31118
+ function applyHookOutcomeSideEffects(context, hookOutcome) {
31119
+ if (hookOutcome.systemMessages && hookOutcome.systemMessages.length > 0) {
31120
+ queueHookSystemMessages(context, hookOutcome.systemMessages);
31121
+ }
31122
+ if (hookOutcome.additionalContexts && hookOutcome.additionalContexts.length > 0) {
31123
+ queueHookAdditionalContexts(context, hookOutcome.additionalContexts);
31124
+ }
31125
+ }
31126
+ function resolvePermissionExecutionPlan(args) {
31127
+ const effectiveShouldSkipPermissionCheck = args.hookPermissionDecision === "allow" ? true : args.hookPermissionDecision === "ask" ? false : args.shouldSkipPermissionCheck;
31128
+ const permissionContextForCall = args.hookPermissionDecision === "ask" && args.context.options?.toolPermissionContext && args.context.options.toolPermissionContext.mode !== "default" ? {
31129
+ ...args.context,
31130
+ options: {
31131
+ ...args.context.options,
31132
+ toolPermissionContext: {
31133
+ ...args.context.options.toolPermissionContext,
31134
+ mode: "default"
31135
+ }
31136
+ }
31137
+ } : args.context;
31138
+ return {
31139
+ effectiveShouldSkipPermissionCheck,
31140
+ permissionContextForCall
31141
+ };
31142
+ }
31143
+ function resolveToolResultAssistantContent(args) {
31144
+ const rawContent = args.resultForAssistant ?? args.renderResultForAssistant(args.resultData);
31145
+ const shouldTruncate = typeof rawContent === "string" && shouldApplyToolOutputTruncation(args.resultData);
31146
+ return typeof rawContent === "string" && shouldTruncate ? truncateToolOutput(rawContent, {
31147
+ permissionMode: args.permissionMode
31148
+ }).content : rawContent;
31149
+ }
31150
+ function toStructuredToolResultMessages(newMessages) {
31151
+ if (!Array.isArray(newMessages)) {
31152
+ return [];
31153
+ }
31154
+ return newMessages.filter(
31155
+ (message) => Boolean(message) && typeof message === "object" && "type" in message
31156
+ );
31157
+ }
31158
+ function buildToolResultEnvelope(args) {
31159
+ return {
31160
+ blocks: [
31161
+ {
31162
+ type: "tool_result",
31163
+ content: args.content,
31164
+ tool_use_id: args.toolUseId
31165
+ }
31166
+ ],
31167
+ toolUseResult: {
31168
+ data: args.resultData,
31169
+ resultForAssistant: args.content,
31170
+ ...Array.isArray(args.newMessages) ? { newMessages: args.newMessages } : {},
31171
+ ...args.contextModifier ? { contextModifier: args.contextModifier } : {}
31172
+ }
31173
+ };
31174
+ }
31175
+ function createToolExecutionErrorBlock(args) {
31176
+ const content = args.mode === "full" ? formatError(args.error) : `Tool execution failed: ${args.error instanceof Error ? args.error.message : String(args.error)}`;
31177
+ return createErrorToolResultBlock({
31178
+ toolUseId: args.toolUseId,
31179
+ content,
31180
+ errorCode: extractErrorCode(args.error)
31181
+ });
31182
+ }
31183
+ function resolveWarningText(warnings) {
31184
+ if (!Array.isArray(warnings) || warnings.length === 0) {
31185
+ return void 0;
31186
+ }
31187
+ const normalized = warnings.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
31188
+ if (normalized.length === 0) {
31189
+ return void 0;
31190
+ }
31191
+ return normalized.join("\n");
31192
+ }
31193
+ function normalizeProgressPayload(args) {
31194
+ return {
31195
+ normalizedMessages: Array.isArray(args.normalizedMessages) ? args.normalizedMessages : [],
31196
+ tools: Array.isArray(args.tools) ? args.tools : []
31197
+ };
31198
+ }
31199
+ function resolveInitialInputValidationMessage(args) {
31200
+ if (args.toolName === "Read" && Object.keys(args.preprocessedInput).length === 0) {
31201
+ return `Error: The Read tool requires a 'file_path' parameter to specify which file to read. Please provide the absolute path to the file you want to read. For example: {"file_path": "/path/to/file.txt"}`;
31202
+ }
31203
+ return `InputValidationError: ${args.validationMessage}`;
31204
+ }
31205
+ function createInputValidationErrorBlock(args) {
31206
+ return createErrorToolResultBlock({
31207
+ toolUseId: args.toolUseId,
31208
+ content: args.content,
31209
+ errorCode: "INPUT_VALIDATION",
31210
+ errorClass: "soft"
31211
+ });
31212
+ }
31213
+ function createHookBlockedErrorBlock(args) {
31214
+ return createErrorToolResultBlock({
31215
+ toolUseId: args.toolUseId,
31216
+ content: args.content,
31217
+ errorCode: "HOOK_BLOCKED",
31218
+ errorClass: "soft"
31219
+ });
31220
+ }
31221
+ function createPermissionDeniedErrorBlock(args) {
31222
+ return createErrorToolResultBlock({
31223
+ toolUseId: args.toolUseId,
31224
+ content: args.content,
31225
+ errorCode: "PERMISSION_DENIED",
31226
+ errorClass: "soft"
31227
+ });
31228
+ }
31229
+ async function resolveHookUpdatedInput(args) {
31230
+ if (!args.updatedInput) {
31231
+ return { kind: "unchanged", normalizedInput: args.normalizedInput };
31232
+ }
31233
+ const merged = { ...args.normalizedInput, ...args.updatedInput };
31234
+ const parsed = args.tool.inputSchema.safeParse(merged);
31235
+ if (!parsed.success) {
31236
+ return {
31237
+ kind: "invalid",
31238
+ message: `Hook updatedInput failed validation: ${parsed.error.message}`
31239
+ };
31240
+ }
31241
+ const normalizedInput = parsed.data;
31242
+ const isValidUpdate = await args.tool.validateInput?.(
31243
+ normalizedInput,
31244
+ args.context
31245
+ );
31246
+ if (isValidUpdate?.result === false) {
31247
+ return { kind: "invalid", message: isValidUpdate.message };
31248
+ }
31249
+ return { kind: "updated", normalizedInput };
31250
+ }
31251
+ function buildResultDispatchItems(args) {
31252
+ const items = [];
31253
+ const warningText = resolveWarningText(args.postWarnings);
31254
+ if (warningText) {
31255
+ items.push({
31256
+ kind: "warning_progress",
31257
+ warningText,
31258
+ tools: args.defaultTools
31259
+ });
31260
+ }
31261
+ const userMessage = buildToolResultEnvelope({
31262
+ toolUseId: args.toolUseId,
31263
+ content: args.content,
31264
+ resultData: args.resultData,
31265
+ newMessages: args.newMessages,
31266
+ contextModifier: args.contextModifier
31267
+ });
31268
+ items.push({
31269
+ kind: "user_message",
31270
+ blocks: userMessage.blocks,
31271
+ toolUseResult: userMessage.toolUseResult
31272
+ });
31273
+ const structuredMessages = toStructuredToolResultMessages(args.newMessages);
31274
+ for (const message of structuredMessages) {
31275
+ items.push({
31276
+ kind: "structured_message",
31277
+ message
31278
+ });
31279
+ }
31280
+ return items;
31281
+ }
31282
+ function buildRunningProgressPayload(args) {
31283
+ const normalizedPayload = normalizeProgressPayload({
31284
+ normalizedMessages: args.normalizedMessages,
31285
+ tools: args.tools
31286
+ });
31287
+ return {
31288
+ content: args.content,
31289
+ normalizedMessages: normalizedPayload.normalizedMessages,
31290
+ tools: normalizedPayload.tools.length > 0 ? normalizedPayload.tools : args.defaultTools
31291
+ };
31292
+ }
31293
+ function buildWarningDispatchItems(args) {
31294
+ const warningText = resolveWarningText(args.warnings);
31295
+ if (!warningText) {
31296
+ return [];
31297
+ }
31298
+ return [
31299
+ {
31300
+ kind: "warning_progress",
31301
+ warningText,
31302
+ tools: args.defaultTools
31303
+ }
31304
+ ];
31305
+ }
31306
+ async function resolvePermissionResult(args) {
31307
+ if (args.effectiveShouldSkipPermissionCheck) {
31308
+ return { result: true };
31309
+ }
31310
+ return args.canUseTool(
31311
+ args.tool,
31312
+ args.normalizedInput,
31313
+ { ...args.permissionContextForCall, toolUseId: args.toolUseId },
31314
+ args.assistantMessage
31315
+ );
31316
+ }
31317
+ async function resolvePermissionCheckOutcome(args) {
31318
+ const { effectiveShouldSkipPermissionCheck, permissionContextForCall } = resolvePermissionExecutionPlan({
31319
+ context: args.context,
31320
+ hookPermissionDecision: args.hookPermissionDecision,
31321
+ shouldSkipPermissionCheck: args.shouldSkipPermissionCheck
31322
+ });
31323
+ const permissionResult = await resolvePermissionResult({
31324
+ effectiveShouldSkipPermissionCheck,
31325
+ canUseTool: args.canUseTool,
31326
+ tool: args.tool,
31327
+ normalizedInput: args.normalizedInput,
31328
+ permissionContextForCall,
31329
+ toolUseId: args.toolUseId,
31330
+ assistantMessage: args.assistantMessage
31331
+ });
31332
+ return {
31333
+ effectiveShouldSkipPermissionCheck,
31334
+ permissionContextForCall,
31335
+ permissionResult
31336
+ };
31337
+ }
31338
+
31339
+ // src/app/query.ts
30368
31340
  function isToolUseLikeBlock(block) {
30369
31341
  return block && typeof block === "object" && (block.type === "tool_use" || block.type === "server_tool_use" || block.type === "mcp_tool_use");
30370
31342
  }
@@ -30638,121 +31610,28 @@ async function queryWithBinaryFeedback(toolUseContext, getAssistantResponse, get
30638
31610
  return await getBinaryFeedbackResponse(m1, m2);
30639
31611
  }
30640
31612
  async function* query(messages, systemPrompt, context, canUseTool, toolUseContext, getBinaryFeedbackResponse) {
30641
- const shouldPersistSession = toolUseContext.options?.persistSession !== false && process.env.NODE_ENV !== "test";
30642
- const typedRequestId = (() => {
30643
- const currentRequestId = getCurrentRequest()?.id;
30644
- if (currentRequestId) return `query_${currentRequestId}`;
30645
- const lastUser = [...messages].reverse().find((item) => item?.type === "user" && item?.queryId);
30646
- const fallbackQueryId = lastUser?.queryId;
30647
- if (fallbackQueryId) return `query_${fallbackQueryId}`;
30648
- return `query_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
30649
- })();
30650
- const modelPointer = toolUseContext.options.model || "main";
30651
- const modelResolution = getModelManager().resolveModelWithInfo(modelPointer);
30652
- const typedProvider = modelResolution.success ? String(modelResolution.profile?.provider ?? "").trim().toLowerCase() : "unknown";
30653
- const typedProjector = createStreamTypedProjector({
30654
- requestId: typedRequestId,
30655
- source: "query_main",
30656
- provider: typedProvider
30657
- });
30658
- const rolloutFlags = {
30659
- typedSessionWriteEnabled: true,
30660
- compactionBoundaryEnabled: false,
30661
- toolOutputLifecycleEnabled: false,
30662
- singleFactLayerReadEnabled: true,
30663
- rolloutEnabled: false,
30664
- rolloutPercent: 100,
30665
- rolloutBucket: 0,
30666
- rolloutStage: "stage_100",
30667
- rolloutDecision: "keep",
30668
- rolloutReason: "rollout_disabled"
30669
- };
30670
- const shouldPersistTypedSession = shouldPersistSession && rolloutFlags.typedSessionWriteEnabled;
30671
- const shouldBuildSingleFactSkeleton = rolloutFlags.singleFactLayerReadEnabled;
30672
- logUserFriendly("THREE_LAYER_ROLLOUT_APPLIED", {
30673
- enabled: rolloutFlags.rolloutEnabled,
30674
- stage: rolloutFlags.rolloutStage,
30675
- decision: rolloutFlags.rolloutDecision,
30676
- reason: rolloutFlags.rolloutReason,
30677
- percent: rolloutFlags.rolloutPercent,
30678
- bucket: rolloutFlags.rolloutBucket,
30679
- typedSessionWriteEnabled: rolloutFlags.typedSessionWriteEnabled,
30680
- compactionBoundaryEnabled: rolloutFlags.compactionBoundaryEnabled,
30681
- toolOutputLifecycleEnabled: rolloutFlags.toolOutputLifecycleEnabled,
30682
- singleFactLayerReadEnabled: rolloutFlags.singleFactLayerReadEnabled
30683
- });
30684
- if (typeof toolUseContext.compactionBoundaryEnabled !== "boolean") {
30685
- toolUseContext.compactionBoundaryEnabled = rolloutFlags.compactionBoundaryEnabled;
30686
- }
30687
- if (typeof toolUseContext.toolOutputLifecycleEnabled !== "boolean") {
30688
- toolUseContext.toolOutputLifecycleEnabled = rolloutFlags.toolOutputLifecycleEnabled;
30689
- }
30690
- if (typeof toolUseContext.singleFactLayerReadEnabled !== "boolean") {
30691
- toolUseContext.singleFactLayerReadEnabled = rolloutFlags.singleFactLayerReadEnabled;
30692
- }
30693
- if (rolloutFlags.singleFactLayerReadEnabled) {
30694
- messages = normalizeMessagesForSingleFactLayer(messages);
30695
- }
30696
- const lifecycleEventBuffer = [];
30697
- const previousOnQueryLifecycleEvent = toolUseContext.onQueryLifecycleEvent;
30698
- toolUseContext.onQueryLifecycleEvent = (event) => {
30699
- previousOnQueryLifecycleEvent?.(event);
30700
- lifecycleEventBuffer.push(event);
30701
- };
30702
- try {
30703
- for await (const message of queryCore(
30704
- messages,
30705
- systemPrompt,
30706
- context,
30707
- canUseTool,
30708
- toolUseContext,
30709
- getBinaryFeedbackResponse
30710
- )) {
30711
- if (shouldPersistTypedSession || shouldBuildSingleFactSkeleton) {
30712
- const lifecycleParts = projectLifecycleEventsToTypedParts(
30713
- typedProjector,
30714
- lifecycleEventBuffer.splice(0)
30715
- );
30716
- const parts = [
30717
- ...lifecycleParts,
30718
- ...projectMessageToTypedParts(typedProjector, message)
30719
- ];
30720
- for (const part of parts) {
30721
- if (shouldPersistTypedSession) {
30722
- emitTypedPart({ requestId: typedRequestId, part });
30723
- }
30724
- }
30725
- if (shouldBuildSingleFactSkeleton && (message?.type === "assistant" || message?.type === "user")) {
30726
- const skeletonBlocks = buildSkeletonBlocksFromTypedParts({
30727
- role: message.type,
30728
- parts
30729
- });
30730
- logUserFriendly("SINGLE_FACT_LAYER_SKELETON_REBUILT", {
30731
- role: message.type,
30732
- typedPartCount: parts.length,
30733
- skeletonBlockCount: skeletonBlocks.length,
30734
- mapperMode: "rollback_only"
30735
- });
30736
- }
30737
- }
30738
- yield message;
30739
- }
30740
- } finally {
30741
- toolUseContext.onQueryLifecycleEvent = previousOnQueryLifecycleEvent;
30742
- if (shouldPersistTypedSession) {
30743
- flushTypedPartBuffer({ requestId: typedRequestId });
30744
- const compatibilityMetrics = consumeProjectorCompatibilityMetrics(typedProjector);
30745
- logUserFriendly("STREAM_TYPED_PROVIDER_COMPATIBILITY", {
30746
- requestId: typedRequestId,
30747
- provider: compatibilityMetrics.provider,
30748
- supportsRichToolResult: compatibilityMetrics.supportsRichToolResult,
30749
- richToolResultBlockCount: compatibilityMetrics.richToolResultBlockCount,
30750
- downgradedToolResultCount: compatibilityMetrics.downgradedToolResultCount
30751
- });
31613
+ yield* runQuerySessionLegacyCompatAdapter({
31614
+ messages,
31615
+ toolUseContext,
31616
+ requestId: context.requestId,
31617
+ currentRequestId: getCurrentRequest()?.id,
31618
+ isTestEnv: process.env.NODE_ENV === "test",
31619
+ hooks: querySessionPrimaryAdapterHooksInline,
31620
+ logUserFriendly,
31621
+ stream: async function* (preparedMessages) {
31622
+ yield* queryCore(
31623
+ preparedMessages,
31624
+ systemPrompt,
31625
+ context,
31626
+ canUseTool,
31627
+ toolUseContext,
31628
+ getBinaryFeedbackResponse
31629
+ );
30752
31630
  }
30753
- }
31631
+ });
30754
31632
  }
30755
31633
  async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseContext, getBinaryFeedbackResponse, hookState) {
31634
+ const sessionContext = toolUseContext.sessionContext;
30756
31635
  setRequestStatus({ kind: "thinking" });
30757
31636
  try {
30758
31637
  let getAssistantResponse = function() {
@@ -30791,9 +31670,21 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
30791
31670
  source: "inferred"
30792
31671
  };
30793
31672
  }
31673
+ emitAutoCompactTelemetryEvent("COMPACTION_HOOK_TURN_END", {
31674
+ trigger: "turn_end",
31675
+ messageCount: messages.length,
31676
+ sessionId: toolUseContext.sessionId,
31677
+ agentId: toolUseContext.agentId
31678
+ });
30794
31679
  const { messages: processedMessages, wasCompacted } = await checkAutoCompact(messages, toolUseContext);
30795
31680
  if (wasCompacted) {
30796
31681
  messages = processedMessages;
31682
+ emitAutoCompactTelemetryEvent("COMPACTION_HOOK_OVERFLOW_DETECTED", {
31683
+ trigger: "overflow_detected",
31684
+ messageCount: messages.length,
31685
+ sessionId: toolUseContext.sessionId,
31686
+ agentId: toolUseContext.agentId
31687
+ });
30797
31688
  }
30798
31689
  const boundaryConfig = resolveCompactionBoundaryConfig(toolUseContext);
30799
31690
  const boundaryResult = filterAfterCompactionBoundary(messages, {
@@ -30976,6 +31867,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
30976
31867
  );
30977
31868
  if (promptOutcome.decision === "block") {
30978
31869
  yield createAssistantMessage(promptOutcome.message);
31870
+ sessionContext?.setIdle();
30979
31871
  return;
30980
31872
  }
30981
31873
  }
@@ -31092,6 +31984,12 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31092
31984
  }
31093
31985
  }
31094
31986
  }
31987
+ emitAutoCompactTelemetryEvent("COMPACTION_HOOK_PRE_NEXT_TURN", {
31988
+ trigger: "pre_next_turn",
31989
+ messageCount: messages.length,
31990
+ sessionId: toolUseContext.sessionId,
31991
+ agentId: toolUseContext.agentId
31992
+ });
31095
31993
  markPhase("LLM_PREPARATION");
31096
31994
  const result = await queryWithBinaryFeedback(
31097
31995
  toolUseContext,
@@ -31105,6 +32003,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31105
32003
  timestamp: Date.now()
31106
32004
  });
31107
32005
  if (toolUseContext.abortController.signal.aborted) {
32006
+ sessionContext?.setInterrupted();
31108
32007
  lifecycleEvents.finishStep({
31109
32008
  stepId,
31110
32009
  requestId,
@@ -31117,6 +32016,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31117
32016
  return;
31118
32017
  }
31119
32018
  if (result.message === null) {
32019
+ sessionContext?.setInterrupted();
31120
32020
  lifecycleEvents.finishStep({
31121
32021
  stepId,
31122
32022
  requestId,
@@ -31156,6 +32056,17 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31156
32056
  const stopOutcome = await runStopHooks({
31157
32057
  hookEvent: stopHookEvent,
31158
32058
  reason: String(stopReason ?? ""),
32059
+ retryEntryKey: buildRetryEntryKey([
32060
+ toolUseContext.sessionId,
32061
+ toolUseContext.parentSessionId,
32062
+ toolUseContext.childSessionId,
32063
+ toolUseContext.agentId,
32064
+ String(stopReason ?? "")
32065
+ ]),
32066
+ retryAttempt: stopHookAttempts,
32067
+ sessionId: toolUseContext.sessionId,
32068
+ parentSessionId: toolUseContext.parentSessionId,
32069
+ childSessionId: toolUseContext.childSessionId,
31159
32070
  agentId: toolUseContext.agentId,
31160
32071
  permissionMode: toolUseContext.options?.toolPermissionContext?.mode,
31161
32072
  cwd: getCwd(),
@@ -31194,6 +32105,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31194
32105
  }
31195
32106
  }
31196
32107
  if (!parentUserMessage?.uuid) {
32108
+ sessionContext?.setIdle();
31197
32109
  yield assistantMessage;
31198
32110
  return;
31199
32111
  }
@@ -31214,6 +32126,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31214
32126
  }
31215
32127
  }
31216
32128
  yield enrichedAssistantMessage;
32129
+ sessionContext?.setIdle();
31217
32130
  return;
31218
32131
  }
31219
32132
  if (!parentUserMessage?.uuid) {
@@ -31254,6 +32167,7 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31254
32167
  }
31255
32168
  toolUseContext = toolQueue.getUpdatedContext();
31256
32169
  if (toolUseContext.abortController.signal.aborted) {
32170
+ sessionContext?.setInterrupted();
31257
32171
  yield createAssistantMessage(INTERRUPT_MESSAGE_FOR_TOOL_USE);
31258
32172
  return;
31259
32173
  }
@@ -31273,6 +32187,9 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31273
32187
  } catch (error) {
31274
32188
  throw error;
31275
32189
  }
32190
+ } catch (error) {
32191
+ sessionContext?.setErrored();
32192
+ throw error;
31276
32193
  } finally {
31277
32194
  const currentRequest = getCurrentRequest();
31278
32195
  const telemetryRecord = flushAutoCompactTelemetrySnapshot({
@@ -31290,9 +32207,14 @@ async function* queryCore(messages, systemPrompt, context, canUseTool, toolUseCo
31290
32207
  });
31291
32208
  }
31292
32209
  setRequestStatus({ kind: "idle" });
32210
+ if (sessionContext?.getSnapshot().state !== "closed") {
32211
+ sessionContext?.setIdle();
32212
+ }
31293
32213
  }
31294
32214
  }
31295
32215
  async function* runToolUse(toolUse, siblingToolUseIDs, assistantMessage, canUseTool, toolUseContext, shouldSkipPermissionCheck) {
32216
+ const sessionContext = toolUseContext.sessionContext;
32217
+ sessionContext?.startTool(toolUse.id);
31296
32218
  const currentRequest = getCurrentRequest();
31297
32219
  const aliasResolution = resolveToolNameAlias(toolUse.name);
31298
32220
  setRequestStatus({ kind: "tool", detail: aliasResolution.resolvedName });
@@ -31330,6 +32252,7 @@ async function* runToolUse(toolUse, siblingToolUseIDs, assistantMessage, canUseT
31330
32252
  errorClass: "soft"
31331
32253
  })
31332
32254
  ]);
32255
+ sessionContext?.finishTool(toolUse.id);
31333
32256
  return;
31334
32257
  }
31335
32258
  const toolInput = toolUse.input;
@@ -31355,65 +32278,30 @@ async function* runToolUse(toolUse, siblingToolUseIDs, assistantMessage, canUseT
31355
32278
  } catch (e) {
31356
32279
  logError(e);
31357
32280
  const errorMessage = createUserMessageFromBlocks([
31358
- createErrorToolResultBlock({
32281
+ createToolExecutionErrorBlock({
31359
32282
  toolUseId: toolUse.id,
31360
- content: `Tool execution failed: ${e instanceof Error ? e.message : String(e)}`,
31361
- errorCode: extractErrorCode(e)
32283
+ error: e,
32284
+ mode: "summary"
31362
32285
  })
31363
32286
  ]);
31364
32287
  yield errorMessage;
32288
+ } finally {
32289
+ sessionContext?.finishTool(toolUse.id);
31365
32290
  }
31366
32291
  }
31367
- function normalizeToolInput(tool, input) {
31368
- switch (tool) {
31369
- case BashTool: {
31370
- const parsed = BashTool.inputSchema.parse(input);
31371
- const {
31372
- command: command4,
31373
- timeout,
31374
- description: description3,
31375
- run_in_background,
31376
- dangerouslyDisableSandbox
31377
- } = parsed;
31378
- return {
31379
- command: command4.replace(`cd ${getCwd()} && `, "").replace(/\\\\;/g, "\\;"),
31380
- ...timeout !== void 0 ? { timeout } : {},
31381
- ...description3 ? { description: description3 } : {},
31382
- ...run_in_background ? { run_in_background } : {},
31383
- ...dangerouslyDisableSandbox ? { dangerouslyDisableSandbox } : {}
31384
- };
31385
- }
31386
- default:
31387
- return input;
31388
- }
31389
- }
31390
- function preprocessToolInput(tool, input) {
31391
- if (tool.name === "TaskOutput") {
31392
- const task_id = typeof input.task_id === "string" && input.task_id || typeof input.agentId === "string" && String(input.agentId) || typeof input.bash_id === "string" && String(input.bash_id) || "";
31393
- const block = typeof input.block === "boolean" ? input.block : true;
31394
- const timeout = typeof input.timeout === "number" ? input.timeout : typeof input.wait_up_to === "number" ? Number(input.wait_up_to) * 1e3 : void 0;
31395
- return {
31396
- task_id,
31397
- block,
31398
- ...timeout !== void 0 ? { timeout } : {}
31399
- };
31400
- }
31401
- return input;
31402
- }
31403
32292
  async function* checkPermissionsAndCallTool(tool, toolUseID, siblingToolUseIDs, input, context, canUseTool, assistantMessage, shouldSkipPermissionCheck) {
31404
32293
  const preprocessedInput = preprocessToolInput(tool, input);
31405
32294
  const isValidInput = tool.inputSchema.safeParse(preprocessedInput);
31406
32295
  if (!isValidInput.success) {
31407
- let errorMessage = `InputValidationError: ${isValidInput.error.message}`;
31408
- if (tool.name === "Read" && Object.keys(preprocessedInput).length === 0) {
31409
- errorMessage = `Error: The Read tool requires a 'file_path' parameter to specify which file to read. Please provide the absolute path to the file you want to read. For example: {"file_path": "/path/to/file.txt"}`;
31410
- }
32296
+ const errorMessage = resolveInitialInputValidationMessage({
32297
+ toolName: tool.name,
32298
+ preprocessedInput,
32299
+ validationMessage: isValidInput.error.message
32300
+ });
31411
32301
  yield createUserMessageFromBlocks([
31412
- createErrorToolResultBlock({
32302
+ createInputValidationErrorBlock({
31413
32303
  toolUseId: toolUseID,
31414
- content: errorMessage,
31415
- errorCode: "INPUT_VALIDATION",
31416
- errorClass: "soft"
32304
+ content: errorMessage
31417
32305
  })
31418
32306
  ]);
31419
32307
  return;
@@ -31425,11 +32313,9 @@ async function* checkPermissionsAndCallTool(tool, toolUseID, siblingToolUseIDs,
31425
32313
  );
31426
32314
  if (isValidCall?.result === false) {
31427
32315
  yield createUserMessageFromBlocks([
31428
- createErrorToolResultBlock({
32316
+ createInputValidationErrorBlock({
31429
32317
  toolUseId: toolUseID,
31430
- content: isValidCall.message,
31431
- errorCode: "INPUT_VALIDATION",
31432
- errorClass: "soft"
32318
+ content: isValidCall.message
31433
32319
  })
31434
32320
  ]);
31435
32321
  return;
@@ -31438,96 +32324,66 @@ async function* checkPermissionsAndCallTool(tool, toolUseID, siblingToolUseIDs,
31438
32324
  toolName: tool.name,
31439
32325
  toolInput: normalizedInput,
31440
32326
  toolUseId: toolUseID,
31441
- permissionMode: context.options?.toolPermissionContext?.mode,
31442
- cwd: getCwd(),
31443
- transcriptPath: getHookTranscriptPath(context),
31444
- safeMode: context.options?.safeMode ?? false,
31445
- signal: context.abortController.signal
32327
+ ...buildToolHookBaseArgs(context, toolUseID)
31446
32328
  });
31447
32329
  if (hookOutcome.kind === "block") {
31448
32330
  yield createUserMessageFromBlocks([
31449
- createErrorToolResultBlock({
32331
+ createHookBlockedErrorBlock({
31450
32332
  toolUseId: toolUseID,
31451
- content: hookOutcome.message,
31452
- errorCode: "HOOK_BLOCKED",
31453
- errorClass: "soft"
32333
+ content: hookOutcome.message
31454
32334
  })
31455
32335
  ]);
31456
32336
  return;
31457
32337
  }
31458
- if (hookOutcome.warnings.length > 0) {
31459
- const warningText = hookOutcome.warnings.join("\n");
32338
+ const preWarningDispatchItems = buildWarningDispatchItems({
32339
+ warnings: hookOutcome.warnings,
32340
+ defaultTools: context.options?.tools ?? []
32341
+ });
32342
+ for (const dispatchItem of preWarningDispatchItems) {
31460
32343
  yield createProgressMessage(
31461
32344
  toolUseID,
31462
32345
  siblingToolUseIDs,
31463
- createAssistantMessage(warningText),
32346
+ createAssistantMessage(dispatchItem.warningText),
31464
32347
  [],
31465
- context.options?.tools ?? [],
32348
+ dispatchItem.tools,
31466
32349
  { progressState: "running" }
31467
32350
  );
31468
32351
  }
31469
- if (hookOutcome.systemMessages && hookOutcome.systemMessages.length > 0) {
31470
- queueHookSystemMessages(context, hookOutcome.systemMessages);
31471
- }
31472
- if (hookOutcome.additionalContexts && hookOutcome.additionalContexts.length > 0) {
31473
- queueHookAdditionalContexts(context, hookOutcome.additionalContexts);
32352
+ applyHookOutcomeSideEffects(context, hookOutcome);
32353
+ const updatedInputResult = await resolveHookUpdatedInput({
32354
+ tool,
32355
+ normalizedInput,
32356
+ updatedInput: hookOutcome.updatedInput,
32357
+ context
32358
+ });
32359
+ if (updatedInputResult.kind === "invalid") {
32360
+ yield createUserMessageFromBlocks([
32361
+ createInputValidationErrorBlock({
32362
+ toolUseId: toolUseID,
32363
+ content: updatedInputResult.message
32364
+ })
32365
+ ]);
32366
+ return;
31474
32367
  }
31475
- if (hookOutcome.updatedInput) {
31476
- const merged = { ...normalizedInput, ...hookOutcome.updatedInput };
31477
- const parsed = tool.inputSchema.safeParse(merged);
31478
- if (!parsed.success) {
31479
- yield createUserMessageFromBlocks([
31480
- createErrorToolResultBlock({
31481
- toolUseId: toolUseID,
31482
- content: `Hook updatedInput failed validation: ${parsed.error.message}`,
31483
- errorCode: "INPUT_VALIDATION",
31484
- errorClass: "soft"
31485
- })
31486
- ]);
31487
- return;
31488
- }
31489
- normalizedInput = normalizeToolInput(tool, parsed.data);
31490
- const isValidUpdate = await tool.validateInput?.(
31491
- normalizedInput,
31492
- context
31493
- );
31494
- if (isValidUpdate?.result === false) {
31495
- yield createUserMessageFromBlocks([
31496
- createErrorToolResultBlock({
31497
- toolUseId: toolUseID,
31498
- content: isValidUpdate.message,
31499
- errorCode: "INPUT_VALIDATION",
31500
- errorClass: "soft"
31501
- })
31502
- ]);
31503
- return;
31504
- }
32368
+ if (updatedInputResult.kind === "updated") {
32369
+ normalizedInput = normalizeToolInput(tool, updatedInputResult.normalizedInput);
31505
32370
  }
31506
32371
  const hookPermissionDecision = hookOutcome.kind === "allow" ? hookOutcome.permissionDecision : void 0;
31507
- const effectiveShouldSkipPermissionCheck = hookPermissionDecision === "allow" ? true : hookPermissionDecision === "ask" ? false : shouldSkipPermissionCheck;
31508
- const permissionContextForCall = hookPermissionDecision === "ask" && context.options?.toolPermissionContext && context.options.toolPermissionContext.mode !== "default" ? {
31509
- ...context,
31510
- options: {
31511
- ...context.options,
31512
- toolPermissionContext: {
31513
- ...context.options.toolPermissionContext,
31514
- mode: "default"
31515
- }
31516
- }
31517
- } : context;
31518
- const permissionResult = effectiveShouldSkipPermissionCheck ? { result: true } : await canUseTool(
32372
+ const { permissionResult } = await resolvePermissionCheckOutcome({
32373
+ context,
32374
+ hookPermissionDecision,
32375
+ shouldSkipPermissionCheck,
32376
+ canUseTool,
31519
32377
  tool,
31520
32378
  normalizedInput,
31521
- { ...permissionContextForCall, toolUseId: toolUseID },
32379
+ toolUseId: toolUseID,
31522
32380
  assistantMessage
31523
- );
32381
+ });
31524
32382
  if (permissionResult.result === false) {
31525
32383
  yield createUserMessageFromBlocks([
31526
- createErrorToolResultBlock({
32384
+ createPermissionDeniedErrorBlock({
31527
32385
  toolUseId: toolUseID,
31528
- content: permissionResult.message,
31529
- errorCode: "PERMISSION_DENIED",
31530
- errorClass: "soft"
32386
+ content: permissionResult.message
31531
32387
  })
31532
32388
  ]);
31533
32389
  return;
@@ -31541,160 +32397,81 @@ async function* checkPermissionsAndCallTool(tool, toolUseID, siblingToolUseIDs,
31541
32397
  switch (result.type) {
31542
32398
  case "result":
31543
32399
  {
31544
- const rawContent = result.resultForAssistant ?? tool.renderResultForAssistant(result.data);
31545
- const shouldTruncate = typeof rawContent === "string" && shouldApplyToolOutputTruncation(result.data);
31546
- const content = typeof rawContent === "string" && shouldTruncate ? truncateToolOutput(rawContent, {
32400
+ const content = resolveToolResultAssistantContent({
32401
+ resultForAssistant: result.resultForAssistant,
32402
+ resultData: result.data,
32403
+ renderResultForAssistant: (data) => tool.renderResultForAssistant(data),
31547
32404
  permissionMode: context.options?.toolPermissionContext?.mode
31548
- }).content : rawContent;
32405
+ });
31549
32406
  const postOutcome = await runPostToolUseHooks({
31550
32407
  toolName: tool.name,
31551
32408
  toolInput: normalizedInput,
31552
32409
  toolResult: result.data,
31553
32410
  toolUseId: toolUseID,
31554
- permissionMode: context.options?.toolPermissionContext?.mode,
31555
- cwd: getCwd(),
31556
- transcriptPath: getHookTranscriptPath(context),
31557
- safeMode: context.options?.safeMode ?? false,
31558
- signal: context.abortController.signal
32411
+ ...buildToolHookBaseArgs(context, toolUseID)
31559
32412
  });
31560
- if (postOutcome.systemMessages.length > 0) {
31561
- queueHookSystemMessages(context, postOutcome.systemMessages);
31562
- }
31563
- if (postOutcome.additionalContexts.length > 0) {
31564
- queueHookAdditionalContexts(
31565
- context,
31566
- postOutcome.additionalContexts
31567
- );
31568
- }
31569
- if (postOutcome.warnings.length > 0) {
31570
- const warningText = postOutcome.warnings.join("\n");
31571
- yield createProgressMessage(
31572
- toolUseID,
31573
- siblingToolUseIDs,
31574
- createAssistantMessage(warningText),
31575
- [],
31576
- context.options?.tools ?? [],
31577
- { progressState: "running" }
31578
- );
31579
- }
31580
- yield createUserMessageFromBlocks(
31581
- [
31582
- {
31583
- type: "tool_result",
31584
- content,
31585
- tool_use_id: toolUseID
31586
- }
31587
- ],
31588
- {
31589
- data: result.data,
31590
- resultForAssistant: content,
31591
- ...Array.isArray(result.newMessages) ? { newMessages: result.newMessages } : {},
31592
- ...result.contextModifier ? { contextModifier: result.contextModifier } : {}
32413
+ applyHookOutcomeSideEffects(context, postOutcome);
32414
+ const dispatchItems = buildResultDispatchItems({
32415
+ toolUseId: toolUseID,
32416
+ content,
32417
+ resultData: result.data,
32418
+ newMessages: result.newMessages,
32419
+ contextModifier: result.contextModifier,
32420
+ defaultTools: context.options?.tools ?? [],
32421
+ postWarnings: postOutcome.warnings
32422
+ });
32423
+ for (const dispatchItem of dispatchItems) {
32424
+ if (dispatchItem.kind === "warning_progress") {
32425
+ yield createProgressMessage(
32426
+ toolUseID,
32427
+ siblingToolUseIDs,
32428
+ createAssistantMessage(dispatchItem.warningText),
32429
+ [],
32430
+ dispatchItem.tools,
32431
+ { progressState: "running" }
32432
+ );
32433
+ continue;
31593
32434
  }
31594
- );
31595
- if (Array.isArray(result.newMessages)) {
31596
- for (const message of result.newMessages) {
31597
- if (message && typeof message === "object" && "type" in message) {
31598
- yield message;
31599
- }
32435
+ if (dispatchItem.kind === "user_message") {
32436
+ yield createUserMessageFromBlocks(
32437
+ dispatchItem.blocks,
32438
+ dispatchItem.toolUseResult
32439
+ );
32440
+ continue;
31600
32441
  }
32442
+ yield dispatchItem.message;
31601
32443
  }
31602
32444
  }
31603
32445
  return;
31604
32446
  case "progress":
32447
+ const progressPayload = buildRunningProgressPayload({
32448
+ content: result.content,
32449
+ normalizedMessages: result.normalizedMessages,
32450
+ tools: result.tools,
32451
+ defaultTools: context.options?.tools ?? []
32452
+ });
31605
32453
  yield createProgressMessage(
31606
32454
  toolUseID,
31607
32455
  siblingToolUseIDs,
31608
- result.content,
31609
- result.normalizedMessages || [],
31610
- result.tools || [],
32456
+ progressPayload.content,
32457
+ progressPayload.normalizedMessages,
32458
+ progressPayload.tools,
31611
32459
  { progressState: "running" }
31612
32460
  );
31613
32461
  break;
31614
32462
  }
31615
32463
  }
31616
32464
  } catch (error) {
31617
- const content = formatError(error);
31618
32465
  logError(error);
31619
32466
  yield createUserMessageFromBlocks([
31620
- createErrorToolResultBlock({
32467
+ createToolExecutionErrorBlock({
31621
32468
  toolUseId: toolUseID,
31622
- content,
31623
- errorCode: extractErrorCode(error)
32469
+ error,
32470
+ mode: "full"
31624
32471
  })
31625
32472
  ]);
31626
32473
  }
31627
32474
  }
31628
- function formatError(error) {
31629
- if (!(error instanceof Error)) {
31630
- return String(error);
31631
- }
31632
- const parts = [error.message];
31633
- if ("stderr" in error && typeof error.stderr === "string") {
31634
- parts.push(error.stderr);
31635
- }
31636
- if ("stdout" in error && typeof error.stdout === "string") {
31637
- parts.push(error.stdout);
31638
- }
31639
- const fullMessage = parts.filter(Boolean).join("\n");
31640
- if (fullMessage.length <= 1e4) {
31641
- return fullMessage;
31642
- }
31643
- const halfLength = 5e3;
31644
- const start = fullMessage.slice(0, halfLength);
31645
- const end = fullMessage.slice(-halfLength);
31646
- return `${start}
31647
-
31648
- ... [${fullMessage.length - 1e4} characters truncated] ...
31649
-
31650
- ${end}`;
31651
- }
31652
- var ERROR_CLASS_BY_CODE = {
31653
- ENOENT: "soft",
31654
- EISDIR: "soft",
31655
- EACCES: "retryable",
31656
- EPERM: "retryable",
31657
- EMFILE: "retryable",
31658
- ENFILE: "retryable",
31659
- EIO: "fatal",
31660
- ENODEV: "fatal",
31661
- EBUSY: "fatal"
31662
- };
31663
- function extractErrorCode(error) {
31664
- if (!error || typeof error !== "object") {
31665
- return void 0;
31666
- }
31667
- if ("code" in error && typeof error.code === "string") {
31668
- return error.code;
31669
- }
31670
- return void 0;
31671
- }
31672
- function summarizeError(detail) {
31673
- const line = detail.split("\n").map((part) => part.trim()).find((part) => part.length > 0);
31674
- const summary = line ?? detail.trim();
31675
- return summary.length > 200 ? summary.slice(0, 200) : summary;
31676
- }
31677
- function getErrorClassFromCode(errorCode) {
31678
- if (!errorCode) return "soft";
31679
- return ERROR_CLASS_BY_CODE[errorCode] ?? "soft";
31680
- }
31681
- function createErrorToolResultBlock(args) {
31682
- const detail = typeof args.errorDetail === "string" ? args.errorDetail : typeof args.content === "string" ? args.content : JSON.stringify(args.content);
31683
- const errorCode = args.errorCode;
31684
- const errorClass = args.errorClass ?? getErrorClassFromCode(errorCode);
31685
- const summary = detail ? summarizeError(detail) : "";
31686
- return {
31687
- type: "tool_result",
31688
- content: args.content,
31689
- is_error: true,
31690
- tool_use_id: args.toolUseId,
31691
- error_class: errorClass,
31692
- ...errorCode ? { error_code: errorCode } : {},
31693
- ...summary ? { error_summary: summary } : {},
31694
- ...detail ? { error_detail: detail } : {},
31695
- ...args.rootToolUseId ? { root_tool_use_id: args.rootToolUseId } : {}
31696
- };
31697
- }
31698
32475
 
31699
32476
  // src/ui/components/binary-feedback/BinaryFeedback.tsx
31700
32477
  import { default as React96, useCallback as useCallback15 } from "react";
@@ -32870,7 +33647,7 @@ import { homedir as homedir8 } from "os";
32870
33647
  // src/commands/agents/generation.ts
32871
33648
  import { randomUUID as randomUUID6 } from "crypto";
32872
33649
  async function generateAgentWithClaude(prompt) {
32873
- const { queryModel } = await import("./llm-257Z7WOJ.js");
33650
+ const { queryModel } = await import("./llm-VL7SVIXR.js");
32874
33651
  const systemPrompt = `You are an expert at creating AI agent configurations. Based on the user's description, generate a specialized agent configuration.
32875
33652
 
32876
33653
  Return your response as a JSON object with exactly these fields:
@@ -35876,7 +36653,7 @@ var BashTool = {
35876
36653
  result: false,
35877
36654
  message: `Security Policy: Do not use 'ls' for simple file listing.
35878
36655
  - To find files: Use the 'Glob' tool.
35879
- - To view directory structure: Use the 'LS' tool.
36656
+ - To list directory contents: Use Glob with pattern "dir/*" (e.g., Glob pattern="src/*").
35880
36657
  - To check permissions/metadata: Use 'ls -l' (allowed).`
35881
36658
  };
35882
36659
  }
@@ -36707,7 +37484,6 @@ export {
36707
37484
  __ToolUseQueueForTests,
36708
37485
  query,
36709
37486
  runToolUse,
36710
- normalizeToolInput,
36711
37487
  createConversationTrackerPersistenceTelemetryEmitter,
36712
37488
  REPL,
36713
37489
  ResumeConversation,