@ashx-j/lunr 0.2.19 → 0.2.21

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 (259) hide show
  1. package/CHANGELOG.md +36 -1
  2. package/README.md +2 -2
  3. package/dist/builtin-extensions/index.d.ts.map +1 -1
  4. package/dist/builtin-extensions/index.js +0 -2
  5. package/dist/builtin-extensions/index.js.map +1 -1
  6. package/dist/builtin-extensions/lunr-todos.d.ts +6 -5
  7. package/dist/builtin-extensions/lunr-todos.d.ts.map +1 -1
  8. package/dist/builtin-extensions/lunr-todos.js +9 -7
  9. package/dist/builtin-extensions/lunr-todos.js.map +1 -1
  10. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts +6 -4
  11. package/dist/builtin-extensions/pi-intercom/broker/spawn.d.ts.map +1 -1
  12. package/dist/builtin-extensions/pi-intercom/broker/spawn.js +114 -61
  13. package/dist/builtin-extensions/pi-intercom/broker/spawn.js.map +1 -1
  14. package/dist/builtin-extensions/pi-intercom/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-intercom/index.js +360 -351
  16. package/dist/builtin-extensions/pi-intercom/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js +2 -2
  19. package/dist/builtin-extensions/pi-subagents/src/extension/fanout-child.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +8 -6
  21. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  22. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +128 -57
  23. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts +18 -8
  25. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +38 -13
  27. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -3
  29. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  30. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +24 -14
  31. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  32. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts +8 -1
  33. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.d.ts.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js +247 -18
  35. package/dist/builtin-extensions/pi-subagents/src/intercom/native-supervisor-channel.js.map +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts +1 -0
  37. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.d.ts.map +1 -1
  38. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/intercom/result-intercom.js.map +1 -1
  40. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts +29 -0
  41. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.d.ts.map +1 -0
  42. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js +179 -0
  43. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-ask.js.map +1 -0
  44. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts +89 -0
  45. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.d.ts.map +1 -0
  46. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js +541 -0
  47. package/dist/builtin-extensions/pi-subagents/src/intercom/supervisor-questions.js.map +1 -0
  48. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts +11 -1
  49. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js +38 -12
  51. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-execution.js.map +1 -1
  52. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js +3 -2
  54. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-job-tracker.js.map +1 -1
  55. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts +2 -1
  56. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.d.ts.map +1 -1
  57. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js +35 -8
  58. package/dist/builtin-extensions/pi-subagents/src/runs/background/async-resume.js.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts +7 -3
  60. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.d.ts.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js +26 -4
  62. package/dist/builtin-extensions/pi-subagents/src/runs/background/notify.js.map +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts +1 -0
  64. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.d.ts.map +1 -1
  65. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js +55 -38
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/result-watcher.js.map +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +100 -0
  68. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  69. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +46 -31
  70. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  71. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +3 -6
  72. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
  73. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +64 -5
  74. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts +15 -2
  76. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.d.ts.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js +14 -4
  78. package/dist/builtin-extensions/pi-subagents/src/runs/background/top-level-async.js.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  80. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +2 -1
  81. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +21 -8
  84. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts +0 -1
  89. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +71 -25
  91. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  92. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts +2 -0
  93. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js +75 -18
  95. package/dist/builtin-extensions/pi-subagents/src/runs/shared/acceptance.js.map +1 -1
  96. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts +1 -1
  97. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.d.ts.map +1 -1
  98. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js +1 -1
  99. package/dist/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.js.map +1 -1
  100. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts +13 -1
  101. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.d.ts.map +1 -1
  102. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js +67 -11
  103. package/dist/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.js.map +1 -1
  104. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts +1 -0
  105. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.d.ts.map +1 -1
  106. package/dist/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.js.map +1 -1
  107. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts +3 -0
  108. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.d.ts.map +1 -1
  109. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js +7 -2
  110. package/dist/builtin-extensions/pi-subagents/src/runs/shared/pi-args.js.map +1 -1
  111. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
  112. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js +13 -3
  113. package/dist/builtin-extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
  114. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts +2 -2
  115. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.d.ts.map +1 -1
  116. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js +5 -10
  117. package/dist/builtin-extensions/pi-subagents/src/runs/shared/task-intent.js.map +1 -1
  118. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts +2 -0
  119. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.d.ts.map +1 -0
  120. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js +3 -0
  121. package/dist/builtin-extensions/pi-subagents/src/shared/async-guidance.js.map +1 -0
  122. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts +3 -0
  123. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.d.ts.map +1 -1
  124. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js +68 -11
  125. package/dist/builtin-extensions/pi-subagents/src/shared/child-spec.js.map +1 -1
  126. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts +12 -1
  127. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.d.ts.map +1 -1
  128. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js +21 -2
  129. package/dist/builtin-extensions/pi-subagents/src/shared/formatters.js.map +1 -1
  130. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts +21 -4
  131. package/dist/builtin-extensions/pi-subagents/src/shared/types.d.ts.map +1 -1
  132. package/dist/builtin-extensions/pi-subagents/src/shared/types.js +1 -1
  133. package/dist/builtin-extensions/pi-subagents/src/shared/types.js.map +1 -1
  134. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.d.ts.map +1 -1
  135. package/dist/builtin-extensions/pi-subagents/src/slash/delegation-adapters.js.map +1 -1
  136. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts +7 -0
  137. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.d.ts.map +1 -1
  138. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js +11 -7
  139. package/dist/builtin-extensions/pi-subagents/src/slash/prompt-workflows.js.map +1 -1
  140. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +6 -0
  141. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  142. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +46 -29
  143. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  144. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +46 -4
  145. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  146. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +407 -450
  147. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  148. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.d.ts.map +1 -1
  149. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js +1 -1
  150. package/dist/builtin-extensions/pi-subagents/src/watchdog/register-main.js.map +1 -1
  151. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts +2 -13
  152. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.d.ts.map +1 -1
  153. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js +5 -91
  154. package/dist/builtin-extensions/pi-subagents/src/watchdog/tool-actions.js.map +1 -1
  155. package/dist/core/customize.d.ts +2 -0
  156. package/dist/core/customize.d.ts.map +1 -1
  157. package/dist/core/customize.js +3 -0
  158. package/dist/core/customize.js.map +1 -1
  159. package/dist/core/permissions.d.ts +1 -0
  160. package/dist/core/permissions.d.ts.map +1 -1
  161. package/dist/core/permissions.js +8 -4
  162. package/dist/core/permissions.js.map +1 -1
  163. package/dist/core/plan-mode.d.ts.map +1 -1
  164. package/dist/core/plan-mode.js +0 -5
  165. package/dist/core/plan-mode.js.map +1 -1
  166. package/dist/core/runtime-bridges.d.ts.map +1 -1
  167. package/dist/core/runtime-bridges.js +0 -2
  168. package/dist/core/runtime-bridges.js.map +1 -1
  169. package/dist/core/settings-manager.d.ts +4 -0
  170. package/dist/core/settings-manager.d.ts.map +1 -1
  171. package/dist/core/settings-manager.js +11 -0
  172. package/dist/core/settings-manager.js.map +1 -1
  173. package/dist/core/subagent-cancellation.d.ts +21 -0
  174. package/dist/core/subagent-cancellation.d.ts.map +1 -0
  175. package/dist/core/subagent-cancellation.js +53 -0
  176. package/dist/core/subagent-cancellation.js.map +1 -0
  177. package/dist/core/subagent-spinner-setting.d.ts +6 -0
  178. package/dist/core/subagent-spinner-setting.d.ts.map +1 -0
  179. package/dist/core/subagent-spinner-setting.js +12 -0
  180. package/dist/core/subagent-spinner-setting.js.map +1 -0
  181. package/dist/core/subagent-spinner.d.ts +4 -0
  182. package/dist/core/subagent-spinner.d.ts.map +1 -0
  183. package/dist/core/subagent-spinner.js +6 -0
  184. package/dist/core/subagent-spinner.js.map +1 -0
  185. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  186. package/dist/modes/interactive/components/assistant-message.js +12 -18
  187. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  188. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  189. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  190. package/dist/modes/interactive/components/settings-selector.js +73 -1
  191. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  192. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  193. package/dist/modes/interactive/components/tool-execution.js +12 -0
  194. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  195. package/dist/modes/interactive/extension-widget-order.d.ts +8 -0
  196. package/dist/modes/interactive/extension-widget-order.d.ts.map +1 -0
  197. package/dist/modes/interactive/extension-widget-order.js +37 -0
  198. package/dist/modes/interactive/extension-widget-order.js.map +1 -0
  199. package/dist/modes/interactive/interactive-mode.d.ts +1 -0
  200. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  201. package/dist/modes/interactive/interactive-mode.js +44 -22
  202. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  203. package/dist/node-runtime/{agent-session-services-35WNVGMR.js → agent-session-services-C743TYQE.js} +6 -5
  204. package/dist/node-runtime/{builtin-extensions-322XDDEM.js → builtin-extensions-JCOPAAB5.js} +3 -2
  205. package/dist/node-runtime/{chunk-XATUM2HK.js → chunk-25I2BHAA.js} +1 -1
  206. package/dist/node-runtime/{chunk-TXHKBRHZ.js → chunk-2BUAYZ7K.js} +136 -53
  207. package/dist/node-runtime/chunk-5ZH3ZFIZ.js +308 -0
  208. package/dist/node-runtime/{chunk-J26TSGDL.js → chunk-6N22HULO.js} +8 -5
  209. package/dist/node-runtime/chunk-A3KMVBZV.js +60 -0
  210. package/dist/node-runtime/{chunk-4FX25LWP.js → chunk-AWVD5IEY.js} +20 -421
  211. package/dist/node-runtime/{chunk-ZRCBN365.js → chunk-GB2MGFLI.js} +12 -12
  212. package/dist/node-runtime/chunk-LISUTZS3.js +19 -0
  213. package/dist/node-runtime/{chunk-PNJSG3IZ.js → chunk-LTYWTR3V.js} +1 -369
  214. package/dist/node-runtime/{chunk-TFBIJTM3.js → chunk-PDNXVXMD.js} +13 -13
  215. package/dist/node-runtime/{chunk-MCUNIRD5.js → chunk-SY2TFMLO.js} +532 -261
  216. package/dist/node-runtime/{chunk-HQCKFM2O.js → chunk-VGYZ3APQ.js} +3 -0
  217. package/dist/node-runtime/{chunk-4DJ6HEGH.js → chunk-VZR3NCM7.js} +3 -3
  218. package/dist/node-runtime/chunk-W3SILANP.js +24 -0
  219. package/dist/node-runtime/{chunk-CBGB57XT.js → chunk-WLLDXJRT.js} +10 -0
  220. package/dist/node-runtime/{chunk-ATGA2WLC.js → chunk-XI77KVKA.js} +399 -36
  221. package/dist/node-runtime/{chunk-4CSFRBCN.js → chunk-Y5KOEMBH.js} +1 -1
  222. package/dist/node-runtime/{chunk-AROOY4BB.js → chunk-YMEAYRBE.js} +1 -1
  223. package/dist/node-runtime/{command-DWUM5X3U.js → command-P4NYCJ2M.js} +1 -1
  224. package/dist/node-runtime/{customize-XEXL2DGQ.js → customize-LF5VST47.js} +1 -1
  225. package/dist/node-runtime/{gateway-UZXMFGWY.js → gateway-BM6NLOH4.js} +2 -2
  226. package/dist/node-runtime/index.js +16 -13
  227. package/dist/node-runtime/{interactive-mode-QT5IKGQ5.js → interactive-mode-EVVBA64D.js} +11 -8
  228. package/dist/node-runtime/{lunr-cron-QPBTKBGI.js → lunr-cron-4VHP4E4B.js} +2 -2
  229. package/dist/node-runtime/main.js +14 -12
  230. package/dist/node-runtime/{package-manager-cli-7RKSZGEN.js → package-manager-cli-N37546V5.js} +5 -4
  231. package/dist/node-runtime/{pi-intercom-EEMBGQID.js → pi-intercom-NV2LW6X7.js} +108 -87
  232. package/dist/node-runtime/{pi-subagents-7YJ3I4VE.js → pi-subagents-6MUIFNDM.js} +1262 -599
  233. package/dist/node-runtime/rpc-entry.js +14 -12
  234. package/dist/node-runtime/{runtime-bridges-3RKBDLNA.js → runtime-bridges-2VQTLPOZ.js} +3 -5
  235. package/dist/node-runtime/{settings-manager-GHPTUN7R.js → settings-manager-CUGAZWAB.js} +2 -1
  236. package/dist/node-runtime/{subagent-executor-5Q5A4HJ2.js → subagent-executor-MH4A7CCF.js} +181 -294
  237. package/dist/node-runtime/{update-cli-L3JIBH2U.js → update-cli-XTZMZGOL.js} +2 -1
  238. package/docs/features.md +22 -4
  239. package/docs/keybindings.md +3 -1
  240. package/docs/settings.md +3 -2
  241. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  242. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  243. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  244. package/examples/extensions/gondolin/package-lock.json +2 -2
  245. package/examples/extensions/gondolin/package.json +1 -1
  246. package/examples/extensions/sandbox/package-lock.json +2 -2
  247. package/examples/extensions/sandbox/package.json +1 -1
  248. package/examples/extensions/with-deps/package-lock.json +2 -2
  249. package/examples/extensions/with-deps/package.json +1 -1
  250. package/package.json +4 -4
  251. package/dist/builtin-extensions/lunr-settings-tools.d.ts +0 -4
  252. package/dist/builtin-extensions/lunr-settings-tools.d.ts.map +0 -1
  253. package/dist/builtin-extensions/lunr-settings-tools.js +0 -120
  254. package/dist/builtin-extensions/lunr-settings-tools.js.map +0 -1
  255. package/dist/core/settings-tools-bridge.d.ts +0 -35
  256. package/dist/core/settings-tools-bridge.d.ts.map +0 -1
  257. package/dist/core/settings-tools-bridge.js +0 -56
  258. package/dist/core/settings-tools-bridge.js.map +0 -1
  259. package/dist/node-runtime/chunk-3NMWLTPV.js +0 -64
@@ -1 +1 @@
1
- {"version":3,"file":"completion-guard.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAE,6BAA6B,EAAE,CAAC;AAEzC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACvC,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,UAAU;IACV,oBAAoB;CACpB,CAAC,CAAC;AAgBH,MAAM,UAAU,yBAAyB,CAAC,KAA2B,EAAE,cAAoC,EAAW;IACrH,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAAA,CACjE;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAmB,EAAW;IACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;gBAAE,SAAS;YACvC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACnC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC3G,CAAC,CAAC,IAAI,CAAC,SAAoC;gBAC3C,CAAC,CAAC,EAAE,CAAC;YACN,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC1F,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAmC,EAAiC;IACnH,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC;QACpF,CAAC,CAAC,6BAA6B,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;QACxD,CAAC,CAAC,KAAK,CAAC;IACT,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO;QACN,gBAAgB;QAChB,iBAAiB;QACjB,SAAS,EAAE,gBAAgB,IAAI,CAAC,iBAAiB;KACjD,CAAC;AAAA,CACF","sourcesContent":["// @ts-nocheck\nimport type { Message } from \"@ashx-j/lunr-ai\";\nimport { isMutatingBashCommand } from \"./long-running-guard.ts\";\nimport { expectsImplementationMutation } from \"./task-intent.ts\";\n\nexport { expectsImplementationMutation };\n\nconst READ_ONLY_BUILTIN_TOOLS = new Set([\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"web_search\",\n\t\"fetch_content\",\n\t\"get_search_content\",\n\t\"intercom\",\n\t\"contact_supervisor\",\n]);\n\ninterface CompletionMutationGuardInput {\n\tagent: string;\n\ttask: string;\n\tmessages: Message[];\n\ttools?: string[];\n\tmcpDirectTools?: string[];\n}\n\ninterface CompletionMutationGuardResult {\n\texpectedMutation: boolean;\n\tattemptedMutation: boolean;\n\ttriggered: boolean;\n}\n\nexport function hasMutationToolCapability(tools: string[] | undefined, mcpDirectTools: string[] | undefined): boolean {\n\tif (tools === undefined || tools.length === 0 || (mcpDirectTools?.length ?? 0) > 0) return true;\n\treturn !tools.every((tool) => READ_ONLY_BUILTIN_TOOLS.has(tool));\n}\n\nexport function hasMutationToolCall(messages: Message[]): boolean {\n\tfor (const message of messages) {\n\t\tif (message.role !== \"assistant\") continue;\n\t\tfor (const part of message.content) {\n\t\t\tif (part.type !== \"toolCall\") continue;\n\t\t\tif (part.name === \"edit\" || part.name === \"write\") return true;\n\t\t\tif (part.name !== \"bash\") continue;\n\t\t\tconst args = typeof part.arguments === \"object\" && part.arguments !== null && !Array.isArray(part.arguments)\n\t\t\t\t? part.arguments as Record<string, unknown>\n\t\t\t\t: {};\n\t\t\tif (typeof args.command === \"string\" && isMutatingBashCommand(args.command)) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function evaluateCompletionMutationGuard(input: CompletionMutationGuardInput): CompletionMutationGuardResult {\n\tconst expectedMutation = hasMutationToolCapability(input.tools, input.mcpDirectTools)\n\t\t? expectsImplementationMutation(input.agent, input.task)\n\t\t: false;\n\tconst attemptedMutation = hasMutationToolCall(input.messages);\n\treturn {\n\t\texpectedMutation,\n\t\tattemptedMutation,\n\t\ttriggered: expectedMutation && !attemptedMutation,\n\t};\n}\n"]}
1
+ {"version":3,"file":"completion-guard.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/completion-guard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAE,6BAA6B,EAAE,CAAC;AAEzC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACvC,MAAM;IACN,MAAM;IACN,MAAM;IACN,IAAI;IACJ,YAAY;IACZ,eAAe;IACf,oBAAoB;IACpB,UAAU;IACV,oBAAoB;CACpB,CAAC,CAAC;AAgBH,MAAM,UAAU,yBAAyB,CAAC,KAA2B,EAAE,cAAoC,EAAW;IACrH,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAAA,CACjE;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAmB,EAAW;IACjE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU;gBAAE,SAAS;YACvC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;gBAAE,OAAO,IAAI,CAAC;YAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;gBAAE,SAAS;YACnC,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC3G,CAAC,CAAC,IAAI,CAAC,SAAoC;gBAC3C,CAAC,CAAC,EAAE,CAAC;YACN,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC1F,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAmC,EAAiC;IACnH,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC;QACpF,CAAC,CAAC,6BAA6B,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC;QAC9D,CAAC,CAAC,KAAK,CAAC;IACT,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO;QACN,gBAAgB;QAChB,iBAAiB;QACjB,SAAS,EAAE,gBAAgB,IAAI,CAAC,iBAAiB;KACjD,CAAC;AAAA,CACF","sourcesContent":["// @ts-nocheck\nimport type { Message } from \"@ashx-j/lunr-ai\";\nimport { isMutatingBashCommand } from \"./long-running-guard.ts\";\nimport { expectsImplementationMutation } from \"./task-intent.ts\";\n\nexport { expectsImplementationMutation };\n\nconst READ_ONLY_BUILTIN_TOOLS = new Set([\n\t\"read\",\n\t\"grep\",\n\t\"find\",\n\t\"ls\",\n\t\"web_search\",\n\t\"fetch_content\",\n\t\"get_search_content\",\n\t\"intercom\",\n\t\"contact_supervisor\",\n]);\n\ninterface CompletionMutationGuardInput {\n\tpermissions: \"full\" | \"read-only\";\n\ttask: string;\n\tmessages: Message[];\n\ttools?: string[];\n\tmcpDirectTools?: string[];\n}\n\ninterface CompletionMutationGuardResult {\n\texpectedMutation: boolean;\n\tattemptedMutation: boolean;\n\ttriggered: boolean;\n}\n\nexport function hasMutationToolCapability(tools: string[] | undefined, mcpDirectTools: string[] | undefined): boolean {\n\tif (tools === undefined || tools.length === 0 || (mcpDirectTools?.length ?? 0) > 0) return true;\n\treturn !tools.every((tool) => READ_ONLY_BUILTIN_TOOLS.has(tool));\n}\n\nexport function hasMutationToolCall(messages: Message[]): boolean {\n\tfor (const message of messages) {\n\t\tif (message.role !== \"assistant\") continue;\n\t\tfor (const part of message.content) {\n\t\t\tif (part.type !== \"toolCall\") continue;\n\t\t\tif (part.name === \"edit\" || part.name === \"write\") return true;\n\t\t\tif (part.name !== \"bash\") continue;\n\t\t\tconst args = typeof part.arguments === \"object\" && part.arguments !== null && !Array.isArray(part.arguments)\n\t\t\t\t? part.arguments as Record<string, unknown>\n\t\t\t\t: {};\n\t\t\tif (typeof args.command === \"string\" && isMutatingBashCommand(args.command)) return true;\n\t\t}\n\t}\n\treturn false;\n}\n\nexport function evaluateCompletionMutationGuard(input: CompletionMutationGuardInput): CompletionMutationGuardResult {\n\tconst expectedMutation = hasMutationToolCapability(input.tools, input.mcpDirectTools)\n\t\t? expectsImplementationMutation(input.permissions, input.task)\n\t\t: false;\n\tconst attemptedMutation = hasMutationToolCall(input.messages);\n\treturn {\n\t\texpectedMutation,\n\t\tattemptedMutation,\n\t\ttriggered: expectedMutation && !attemptedMutation,\n\t};\n}\n"]}
@@ -9,6 +9,7 @@ interface ModelAttemptSummary {
9
9
  error?: string;
10
10
  usage?: Usage;
11
11
  }
12
+ /** Strip only a known thinking suffix so model ids that contain colons stay intact. */
12
13
  export declare function splitThinkingSuffix(model: string): {
13
14
  baseModel: string;
14
15
  thinkingSuffix: string;
@@ -77,12 +78,23 @@ export declare function resolveRequiredTierModel(tier: unknown, availableModels:
77
78
  /**
78
79
  * Capture how a child model was selected from the original requested params.
79
80
  * Must run before callers replace `model` with a resolved override.
80
- * Explicit model wins; a tier only counts when it actually resolves.
81
+ * Exactly one of tier or model; inherit and both are rejected.
81
82
  */
82
83
  export declare function captureModelSelection(input: {
83
84
  model?: unknown;
84
85
  tier?: unknown;
85
86
  }): ModelSelection;
87
+ /** Resolve and validate an explicit provider/model (+ optional thinking) with no silent fallback. */
88
+ export declare function resolveRequiredExplicitModel(model: unknown, availableModels: AvailableModelInfo[] | undefined, preferredProvider?: string, thinking?: unknown): string;
89
+ /** Resolve the launch model from a captured selection. Tier uses configured thinking; model uses optional explicit thinking. */
90
+ export declare function resolveExecutableChildModel(input: {
91
+ modelSelection?: ModelSelection;
92
+ tier?: unknown;
93
+ model?: unknown;
94
+ thinking?: unknown;
95
+ availableModels?: AvailableModelInfo[];
96
+ preferredProvider?: string;
97
+ }): string;
86
98
  export interface BuildModelCandidatesOptions {
87
99
  /** Fallback models are inherited agent config and warn, rather than error, when out of scope. */
88
100
  scope?: ModelScopeConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"model-fallback.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport type { ModelInfo as AvailableModelInfo } from \"../../shared/model-info.ts\";\nimport type { ChildTier, ModelSelection, Usage } from \"../../shared/types.ts\";\nimport { checkModelScope, type ModelScopeConfig, type ModelScopeViolation, type ModelSource } from \"./model-scope.ts\";\nimport { applyThinkingSuffix } from \"./pi-args.ts\";\n\nexport type { AvailableModelInfo };\n\ninterface ModelAttemptSummary {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\nexport function splitThinkingSuffix(model: string): { baseModel: string; thinkingSuffix: string } {\n\tconst colonIdx = model.lastIndexOf(\":\");\n\tif (colonIdx === -1) return { baseModel: model, thinkingSuffix: \"\" };\n\treturn {\n\t\tbaseModel: model.substring(0, colonIdx),\n\t\tthinkingSuffix: model.substring(colonIdx),\n\t};\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = \"inherit\";\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n\tprovider: string;\n\tid: string;\n}\n\n/**\n * Normalize a model id or provider segment for fuzzy comparison: case-fold,\n * treat dots/underscores as dashes (so `4.5` matches `4-5`), and collapse\n * repeated separators. Pure.\n */\nexport function normalizeModelSegment(segment: string): string {\n\treturn segment\n\t\t.toLowerCase()\n\t\t.replace(/[._]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\nfunction isPlausibleDateStamp(year: string, month: string, day: string): boolean {\n\tconst yyyy = Number(year);\n\tconst mm = Number(month);\n\tconst dd = Number(day);\n\treturn yyyy >= 1900 && yyyy <= 2099 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;\n}\n\n/** Drop a trailing date stamp (`-20251001` or `-2025-10-01`) so dated and undated ids match. Pure. */\nfunction stripTrailingDateStamp(segment: string): string {\n\tconst dashed = /^(.*)-(\\d{4})-(\\d{2})-(\\d{2})$/.exec(segment);\n\tif (dashed && isPlausibleDateStamp(dashed[2]!, dashed[3]!, dashed[4]!)) return dashed[1]!;\n\tconst compact = /^(.*)-(\\d{4})(\\d{2})(\\d{2})$/.exec(segment);\n\tif (compact && isPlausibleDateStamp(compact[2]!, compact[3]!, compact[4]!)) return compact[1]!;\n\treturn segment;\n}\n\nfunction resolveBaseModelCandidate(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (baseModel.includes(\"/\")) {\n\t\tconst exact = availableModels.find((entry) => entry.fullId === baseModel);\n\t\tif (exact) return exact.fullId;\n\t} else {\n\t\tconst exactMatches = availableModels.filter((entry) => entry.id === baseModel);\n\t\tif (preferredProvider) {\n\t\t\tconst preferredMatch = exactMatches.find((entry) => entry.provider === preferredProvider);\n\t\t\tif (preferredMatch) return preferredMatch.fullId;\n\t\t}\n\t\tif (exactMatches.length === 1) return exactMatches[0]!.fullId;\n\t}\n\n\treturn fuzzyResolveModel(baseModel, availableModels, preferredProvider);\n}\n\n/**\n * Fuzzy-resolve a base model id (thinking suffix already stripped) against the\n * registry, tolerating separator, case, and optional date-stamp differences so\n * users do not have to spell provider/model exactly. A qualified `provider/id`\n * query only matches within the named provider — this never silently switches\n * providers for security/cost-sensitive configs. Returns the matched `fullId`,\n * or `undefined` when there is no match or the match is ambiguous across\n * providers (and no `preferredProvider` disambiguates). Pure.\n */\nexport function fuzzyResolveModel(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tlet queryProvider: string | undefined;\n\tlet queryIdRaw = baseModel;\n\tconst slashIdx = baseModel.indexOf(\"/\");\n\tif (slashIdx !== -1) {\n\t\tqueryProvider = normalizeModelSegment(baseModel.slice(0, slashIdx));\n\t\tqueryIdRaw = baseModel.slice(slashIdx + 1);\n\t} else {\n\t\tconst providerSeparators = [\":\", \".\"];\n\t\tfor (const separator of providerSeparators) {\n\t\t\tconst separatorIdx = baseModel.indexOf(separator);\n\t\t\tif (separatorIdx <= 0) continue;\n\t\t\tconst providerPart = normalizeModelSegment(baseModel.slice(0, separatorIdx));\n\t\t\tif (!availableModels.some((entry) => normalizeModelSegment(entry.provider) === providerPart)) continue;\n\t\t\tqueryProvider = providerPart;\n\t\t\tqueryIdRaw = baseModel.slice(separatorIdx + 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst queryId = normalizeModelSegment(queryIdRaw);\n\tconst queryIdNoDate = stripTrailingDateStamp(queryId);\n\n\tconst candidates = availableModels.filter((entry) => {\n\t\tconst entryId = normalizeModelSegment(entry.id);\n\t\tif (entryId !== queryId && stripTrailingDateStamp(entryId) !== queryIdNoDate) return false;\n\t\tif (queryProvider !== undefined && normalizeModelSegment(entry.provider) !== queryProvider) return false;\n\t\treturn true;\n\t});\n\tif (candidates.length === 0) return undefined;\n\tif (preferredProvider) {\n\t\tconst preferredProviderNorm = normalizeModelSegment(preferredProvider);\n\t\tconst preferred = candidates.find((entry) => normalizeModelSegment(entry.provider) === preferredProviderNorm);\n\t\tif (preferred) return preferred.fullId;\n\t}\n\tif (candidates.length === 1) return candidates[0]!.fullId;\n\treturn undefined;\n}\n\n/**\n * Resolve a possibly-loose model id to a canonical `provider/id` (plus any\n * thinking suffix). Exact registry matches win; fuzzy normalization\n * (separator/case/date-stamp via {@link fuzzyResolveModel}) is a fallback so\n * spelling differences still resolve. Never switches providers for a qualified\n * query. Pure.\n */\nexport function resolveModelCandidate(\n\tmodel: string | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (!model) return undefined;\n\tif (!availableModels || availableModels.length === 0) return model;\n\n\tconst resolvedWhole = resolveBaseModelCandidate(model, availableModels, preferredProvider);\n\tif (resolvedWhole) return resolvedWhole;\n\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(model);\n\tif (!thinkingSuffix) return model;\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (resolvedBase) return `${resolvedBase}${thinkingSuffix}`;\n\treturn model;\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n\t/** When set with `enforce: true`, out-of-scope models are rejected. */\n\tscope?: ModelScopeConfig;\n\t/** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n\tsource?: ModelSource;\n\t/** Called for warn-severity violations instead of `console.warn`. */\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nfunction defaultScopeWarn(violation: ModelScopeViolation): void {\n\tconsole.warn(`[pi-subagents] ${violation.message}`);\n}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child must inherit the parent session's *in-memory* model\n * (`provider/id`) instead of being left to resolve its own model. Without an\n * explicit `provider/id`, the child falls back to the global\n * `~/.pi/agent/settings.json` default, which is shared across every open PI\n * session — so a different session that last changed its model in the TUI would\n * silently contaminate this session's subagents (see issue #266). Passing an\n * explicit `provider/id` keeps each session's children isolated to that\n * session's model.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n\trequestedModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n\tconst trimmed = typeof requestedModel === \"string\" ? requestedModel.trim() : \"\";\n\tconst explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n\tlet resolved: string | undefined;\n\tif (explicit === undefined) {\n\t\tresolved = parentModel ? `${parentModel.provider}/${parentModel.id}` : undefined;\n\t} else {\n\t\tresolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n\t}\n\tif (resolved && options?.scope?.enforce) {\n\t\tconst source: ModelSource = explicit === undefined ? \"inherited\" : (options.source ?? \"inherited\");\n\t\tconst violation = checkModelScope(resolved, options.scope, source);\n\t\tif (violation) {\n\t\t\tif (violation.severity === \"error\") throw new Error(violation.message);\n\t\t\t(options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t}\n\treturn resolved;\n}\n\nexport function resolveEffectiveSubagentModel(\n\texplicitModel: string | boolean | undefined,\n\tagentModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: Omit<ResolveSubagentModelOverrideOptions, \"source\">,\n): string | undefined {\n\tconst resolved = resolveSubagentModelOverride(\n\t\texplicitModel ?? agentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: explicitModel !== undefined ? \"explicit\" : \"inherited\" },\n\t);\n\tif (resolved || explicitModel === undefined) return resolved;\n\treturn resolveSubagentModelOverride(\n\t\tagentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: \"inherited\" },\n\t);\n}\n\n// lunr: model tier bridge — every executable child must resolve one configured tier.\nexport function resolveTierModelOverride(tier: unknown): string | undefined {\n\tif (tier !== \"light\" && tier !== \"standard\" && tier !== \"heavy\") {\n\t\tthrow new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\t}\n\tconst tierName = tier.trim();\n\ttry {\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t\t| { getTierModel?: (tier: string) => unknown; isTierModeEnabled?: () => unknown }\n\t\t\t| undefined;\n\t\tif (typeof bridge?.isTierModeEnabled !== \"function\" || typeof bridge?.getTierModel !== \"function\") {\n\t\t\tthrow new Error(\"Model tier settings are unavailable. Reload lunR and try again.\");\n\t\t}\n\t\tif (bridge.isTierModeEnabled() !== true) {\n\t\t\tthrow new Error(\"Model tiers are disabled. Enable them in /settings before launching a subagent.\");\n\t\t}\n\t\tconst model = bridge.getTierModel(tierName);\n\t\tif (typeof model !== \"string\" || !model.trim()) {\n\t\t\tthrow new Error(`Model tier '${tierName}' has no configured model. Configure it in /settings before launching a subagent.`);\n\t\t}\n\t\tconst trimmed = model.trim();\n\t\tconst thinking =\n\t\t\ttypeof bridge.getTierThinking === \"function\" ? bridge.getTierThinking(tierName) : undefined;\n\t\tconst parent = typeof bridge.getParentThinking === \"function\" ? bridge.getParentThinking() : undefined;\n\t\tconst level = (typeof thinking === \"string\" && thinking ? thinking : undefined) ?? (typeof parent === \"string\" && parent ? parent : undefined);\n\t\tif (!level) return trimmed;\n\t\treturn applyThinkingSuffix(trimmed, level, true) ?? trimmed;\n\t} catch (error) {\n\t\tthrow error instanceof Error ? error : new Error(String(error));\n\t}\n}\n\n/** Resolve a required tier and prove its configured model is available to this session. */\nexport function resolveRequiredTierModel(\n\ttier: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string {\n\tconst configured = resolveTierModelOverride(tier);\n\tif (!configured) throw new Error(`Model tier '${String(tier)}' could not be resolved.`);\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model tier '${String(tier)}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(configured);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model tier '${String(tier)}' resolves to '${baseModel}', but that model is unavailable or unauthenticated. Configure an available model in /settings.`,\n\t\t);\n\t}\n\treturn `${resolvedBase}${thinkingSuffix}`;\n}\n\nfunction requestedModelString(model: unknown): string | undefined {\n\treturn typeof model === \"string\" && model.trim() && model.trim() !== INHERIT_MODEL ? model.trim() : undefined;\n}\n\nfunction requestedTier(tier: unknown): ChildTier | undefined {\n\treturn tier === \"light\" || tier === \"standard\" || tier === \"heavy\" ? tier : undefined;\n}\n\n/**\n * Capture how a child model was selected from the original requested params.\n * Must run before callers replace `model` with a resolved override.\n * Explicit model wins; a tier only counts when it actually resolves.\n */\nexport function captureModelSelection(input: { model?: unknown; tier?: unknown }): ModelSelection {\n\tconst tier = requestedTier(input.tier);\n\tif (!tier) throw new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\treturn { kind: \"tier\", tier };\n}\n\nexport interface BuildModelCandidatesOptions {\n\t/** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n\tscope?: ModelScopeConfig;\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nexport function buildModelCandidates(\n\tprimaryModel: string | undefined,\n\tfallbackModels: string[] | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: BuildModelCandidatesOptions,\n): string[] {\n\tconst seen = new Set<string>();\n\tconst candidates: string[] = [];\n\tconst rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n\tfor (let index = 0; index < rawCandidates.length; index++) {\n\t\tconst raw = rawCandidates[index];\n\t\tif (!raw) continue;\n\t\tconst normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n\t\tif (!normalized || seen.has(normalized)) continue;\n\t\tif (index > 0 && options?.scope?.enforce) {\n\t\t\tconst violation = checkModelScope(normalized, options.scope, \"inherited\");\n\t\t\tif (violation) (options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t\tseen.add(normalized);\n\t\tcandidates.push(normalized);\n\t}\n\treturn candidates;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n\t/rate\\s*limit/i,\n\t/too many requests/i,\n\t/\\b429\\b/,\n\t/quota/i,\n\t/billing/i,\n\t/credit/i,\n\t/auth(?:entication)?/i,\n\t/unauthori[sz]ed/i,\n\t/forbidden/i,\n\t/api key/i,\n\t/token expired/i,\n\t/invalid key/i,\n\t/provider.*unavailable/i,\n\t/model.*unavailable/i,\n\t/model.*disabled/i,\n\t/model.*not found/i,\n\t/unknown model/i,\n\t/overloaded/i,\n\t/service unavailable/i,\n\t/temporar(?:ily)? unavailable/i,\n\t/connection refused/i,\n\t/fetch failed/i,\n\t/network error/i,\n\t/socket hang up/i,\n\t/stream ended without finish_reason/i,\n\t/upstream/i,\n\t/timed? out/i,\n\t/timeout/i,\n\t/\\b502\\b/,\n\t/\\b503\\b/,\n\t/\\b504\\b/,\n\t/cold.?start/i,\n\t/empty response/i,\n\t/no output/i,\n\t/model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n\tif (!error) return false;\n\tif (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n\treturn RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n\tconst failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;\n\treturn nextModel\n\t\t? `[fallback] ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n\t\t: `[fallback] ${attempt.model} failed: ${failure}.`;\n}\n"]}
1
+ {"version":3,"file":"model-fallback.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport type { ModelInfo as AvailableModelInfo } from \"../../shared/model-info.ts\";\nimport { getSupportedThinkingLevels, splitKnownThinkingSuffix, THINKING_LEVELS, type ThinkingLevel } from \"../../shared/model-info.ts\";\nimport type { ChildTier, ModelSelection, Usage } from \"../../shared/types.ts\";\nimport { checkModelScope, type ModelScopeConfig, type ModelScopeViolation, type ModelSource } from \"./model-scope.ts\";\nimport { applyThinkingSuffix } from \"./pi-args.ts\";\n\nexport type { AvailableModelInfo };\n\ninterface ModelAttemptSummary {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\n/** Strip only a known thinking suffix so model ids that contain colons stay intact. */\nexport function splitThinkingSuffix(model: string): { baseModel: string; thinkingSuffix: string } {\n\treturn splitKnownThinkingSuffix(model);\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = \"inherit\";\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n\tprovider: string;\n\tid: string;\n}\n\n/**\n * Normalize a model id or provider segment for fuzzy comparison: case-fold,\n * treat dots/underscores as dashes (so `4.5` matches `4-5`), and collapse\n * repeated separators. Pure.\n */\nexport function normalizeModelSegment(segment: string): string {\n\treturn segment\n\t\t.toLowerCase()\n\t\t.replace(/[._]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\nfunction isPlausibleDateStamp(year: string, month: string, day: string): boolean {\n\tconst yyyy = Number(year);\n\tconst mm = Number(month);\n\tconst dd = Number(day);\n\treturn yyyy >= 1900 && yyyy <= 2099 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;\n}\n\n/** Drop a trailing date stamp (`-20251001` or `-2025-10-01`) so dated and undated ids match. Pure. */\nfunction stripTrailingDateStamp(segment: string): string {\n\tconst dashed = /^(.*)-(\\d{4})-(\\d{2})-(\\d{2})$/.exec(segment);\n\tif (dashed && isPlausibleDateStamp(dashed[2]!, dashed[3]!, dashed[4]!)) return dashed[1]!;\n\tconst compact = /^(.*)-(\\d{4})(\\d{2})(\\d{2})$/.exec(segment);\n\tif (compact && isPlausibleDateStamp(compact[2]!, compact[3]!, compact[4]!)) return compact[1]!;\n\treturn segment;\n}\n\nfunction resolveBaseModelCandidate(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (baseModel.includes(\"/\")) {\n\t\tconst exact = availableModels.find((entry) => entry.fullId === baseModel);\n\t\tif (exact) return exact.fullId;\n\t} else {\n\t\tconst exactMatches = availableModels.filter((entry) => entry.id === baseModel);\n\t\tif (preferredProvider) {\n\t\t\tconst preferredMatch = exactMatches.find((entry) => entry.provider === preferredProvider);\n\t\t\tif (preferredMatch) return preferredMatch.fullId;\n\t\t}\n\t\tif (exactMatches.length === 1) return exactMatches[0]!.fullId;\n\t}\n\n\treturn fuzzyResolveModel(baseModel, availableModels, preferredProvider);\n}\n\n/**\n * Fuzzy-resolve a base model id (thinking suffix already stripped) against the\n * registry, tolerating separator, case, and optional date-stamp differences so\n * users do not have to spell provider/model exactly. A qualified `provider/id`\n * query only matches within the named provider — this never silently switches\n * providers for security/cost-sensitive configs. Returns the matched `fullId`,\n * or `undefined` when there is no match or the match is ambiguous across\n * providers (and no `preferredProvider` disambiguates). Pure.\n */\nexport function fuzzyResolveModel(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tlet queryProvider: string | undefined;\n\tlet queryIdRaw = baseModel;\n\tconst slashIdx = baseModel.indexOf(\"/\");\n\tif (slashIdx !== -1) {\n\t\tqueryProvider = normalizeModelSegment(baseModel.slice(0, slashIdx));\n\t\tqueryIdRaw = baseModel.slice(slashIdx + 1);\n\t} else {\n\t\tconst providerSeparators = [\":\", \".\"];\n\t\tfor (const separator of providerSeparators) {\n\t\t\tconst separatorIdx = baseModel.indexOf(separator);\n\t\t\tif (separatorIdx <= 0) continue;\n\t\t\tconst providerPart = normalizeModelSegment(baseModel.slice(0, separatorIdx));\n\t\t\tif (!availableModels.some((entry) => normalizeModelSegment(entry.provider) === providerPart)) continue;\n\t\t\tqueryProvider = providerPart;\n\t\t\tqueryIdRaw = baseModel.slice(separatorIdx + 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst queryId = normalizeModelSegment(queryIdRaw);\n\tconst queryIdNoDate = stripTrailingDateStamp(queryId);\n\n\tconst candidates = availableModels.filter((entry) => {\n\t\tconst entryId = normalizeModelSegment(entry.id);\n\t\tif (entryId !== queryId && stripTrailingDateStamp(entryId) !== queryIdNoDate) return false;\n\t\tif (queryProvider !== undefined && normalizeModelSegment(entry.provider) !== queryProvider) return false;\n\t\treturn true;\n\t});\n\tif (candidates.length === 0) return undefined;\n\tif (preferredProvider) {\n\t\tconst preferredProviderNorm = normalizeModelSegment(preferredProvider);\n\t\tconst preferred = candidates.find((entry) => normalizeModelSegment(entry.provider) === preferredProviderNorm);\n\t\tif (preferred) return preferred.fullId;\n\t}\n\tif (candidates.length === 1) return candidates[0]!.fullId;\n\treturn undefined;\n}\n\n/**\n * Resolve a possibly-loose model id to a canonical `provider/id` (plus any\n * thinking suffix). Exact registry matches win; fuzzy normalization\n * (separator/case/date-stamp via {@link fuzzyResolveModel}) is a fallback so\n * spelling differences still resolve. Never switches providers for a qualified\n * query. Pure.\n */\nexport function resolveModelCandidate(\n\tmodel: string | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (!model) return undefined;\n\tif (!availableModels || availableModels.length === 0) return model;\n\n\tconst resolvedWhole = resolveBaseModelCandidate(model, availableModels, preferredProvider);\n\tif (resolvedWhole) return resolvedWhole;\n\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(model);\n\tif (!thinkingSuffix) return model;\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (resolvedBase) return `${resolvedBase}${thinkingSuffix}`;\n\treturn model;\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n\t/** When set with `enforce: true`, out-of-scope models are rejected. */\n\tscope?: ModelScopeConfig;\n\t/** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n\tsource?: ModelSource;\n\t/** Called for warn-severity violations instead of `console.warn`. */\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nfunction defaultScopeWarn(violation: ModelScopeViolation): void {\n\tconsole.warn(`[pi-subagents] ${violation.message}`);\n}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child must inherit the parent session's *in-memory* model\n * (`provider/id`) instead of being left to resolve its own model. Without an\n * explicit `provider/id`, the child falls back to the global\n * `~/.pi/agent/settings.json` default, which is shared across every open PI\n * session — so a different session that last changed its model in the TUI would\n * silently contaminate this session's subagents (see issue #266). Passing an\n * explicit `provider/id` keeps each session's children isolated to that\n * session's model.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n\trequestedModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n\tconst trimmed = typeof requestedModel === \"string\" ? requestedModel.trim() : \"\";\n\tconst explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n\tlet resolved: string | undefined;\n\tif (explicit === undefined) {\n\t\tresolved = parentModel ? `${parentModel.provider}/${parentModel.id}` : undefined;\n\t} else {\n\t\tresolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n\t}\n\tif (resolved && options?.scope?.enforce) {\n\t\tconst source: ModelSource = explicit === undefined ? \"inherited\" : (options.source ?? \"inherited\");\n\t\tconst violation = checkModelScope(resolved, options.scope, source);\n\t\tif (violation) {\n\t\t\tif (violation.severity === \"error\") throw new Error(violation.message);\n\t\t\t(options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t}\n\treturn resolved;\n}\n\nexport function resolveEffectiveSubagentModel(\n\texplicitModel: string | boolean | undefined,\n\tagentModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: Omit<ResolveSubagentModelOverrideOptions, \"source\">,\n): string | undefined {\n\tconst resolved = resolveSubagentModelOverride(\n\t\texplicitModel ?? agentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: explicitModel !== undefined ? \"explicit\" : \"inherited\" },\n\t);\n\tif (resolved || explicitModel === undefined) return resolved;\n\treturn resolveSubagentModelOverride(\n\t\tagentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: \"inherited\" },\n\t);\n}\n\n// lunr: model tier bridge — every executable child must resolve one configured tier.\nexport function resolveTierModelOverride(tier: unknown): string | undefined {\n\tif (tier !== \"light\" && tier !== \"standard\" && tier !== \"heavy\") {\n\t\tthrow new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\t}\n\tconst tierName = tier.trim();\n\ttry {\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t\t| { getTierModel?: (tier: string) => unknown; isTierModeEnabled?: () => unknown }\n\t\t\t| undefined;\n\t\tif (typeof bridge?.isTierModeEnabled !== \"function\" || typeof bridge?.getTierModel !== \"function\") {\n\t\t\tthrow new Error(\"Model tier settings are unavailable. Reload lunR and try again.\");\n\t\t}\n\t\tif (bridge.isTierModeEnabled() !== true) {\n\t\t\tthrow new Error(\"Model tiers are disabled. Enable them in /settings before launching a subagent.\");\n\t\t}\n\t\tconst model = bridge.getTierModel(tierName);\n\t\tif (typeof model !== \"string\" || !model.trim()) {\n\t\t\tthrow new Error(`Model tier '${tierName}' has no configured model. Configure it in /settings before launching a subagent.`);\n\t\t}\n\t\tconst trimmed = model.trim();\n\t\tconst thinking =\n\t\t\ttypeof bridge.getTierThinking === \"function\" ? bridge.getTierThinking(tierName) : undefined;\n\t\tconst parent = typeof bridge.getParentThinking === \"function\" ? bridge.getParentThinking() : undefined;\n\t\tconst level = (typeof thinking === \"string\" && thinking ? thinking : undefined) ?? (typeof parent === \"string\" && parent ? parent : undefined);\n\t\tif (!level) return trimmed;\n\t\treturn applyThinkingSuffix(trimmed, level, true) ?? trimmed;\n\t} catch (error) {\n\t\tthrow error instanceof Error ? error : new Error(String(error));\n\t}\n}\n\n/** Resolve a required tier and prove its configured model is available to this session. */\nexport function resolveRequiredTierModel(\n\ttier: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string {\n\tconst configured = resolveTierModelOverride(tier);\n\tif (!configured) throw new Error(`Model tier '${String(tier)}' could not be resolved.`);\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model tier '${String(tier)}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(configured);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model tier '${String(tier)}' resolves to '${baseModel}', but that model is unavailable or unauthenticated. Configure an available model in /settings.`,\n\t\t);\n\t}\n\treturn `${resolvedBase}${thinkingSuffix}`;\n}\n\nfunction requestedModelString(model: unknown): string | undefined {\n\treturn typeof model === \"string\" && model.trim() && model.trim() !== INHERIT_MODEL ? model.trim() : undefined;\n}\n\nfunction requestedTier(tier: unknown): ChildTier | undefined {\n\treturn tier === \"light\" || tier === \"standard\" || tier === \"heavy\" ? tier : undefined;\n}\n\nfunction parseExplicitThinking(value: unknown, pathLabel = \"thinking\"): ThinkingLevel | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === false || value === \"off\") return \"off\";\n\tif (typeof value !== \"string\" || !(THINKING_LEVELS as readonly string[]).includes(value)) {\n\t\tthrow new Error(`${pathLabel} must be one of ${THINKING_LEVELS.join(\", \")}.`);\n\t}\n\treturn value as ThinkingLevel;\n}\n\n/**\n * Capture how a child model was selected from the original requested params.\n * Must run before callers replace `model` with a resolved override.\n * Exactly one of tier or model; inherit and both are rejected.\n */\nexport function captureModelSelection(input: { model?: unknown; tier?: unknown }): ModelSelection {\n\tconst model = typeof input.model === \"string\" ? input.model.trim() : \"\";\n\tconst hasModel = Boolean(model);\n\tconst tier = requestedTier(input.tier);\n\tif (hasModel && model === INHERIT_MODEL) {\n\t\tthrow new Error('model \"inherit\" is not supported; choose tier: \"light\", \"standard\", or \"heavy\", or an explicit provider/model.');\n\t}\n\tif (hasModel && tier) {\n\t\tthrow new Error('Choose exactly one of tier or model; do not pass both.');\n\t}\n\tif (hasModel) return { kind: \"model\", model };\n\tif (tier) return { kind: \"tier\", tier };\n\tthrow new Error('Every executable child requires tier: \"light\", \"standard\", or \"heavy\", or an explicit model when the user names one.');\n}\n\n/** Resolve and validate an explicit provider/model (+ optional thinking) with no silent fallback. */\nexport function resolveRequiredExplicitModel(\n\tmodel: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\tthinking?: unknown,\n): string {\n\tconst requested = requestedModelString(model);\n\tif (!requested) {\n\t\tthrow new Error('Explicit model selection requires model as \"provider/id\".');\n\t}\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model '${requested}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(requested);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model '${baseModel}' is unavailable or unauthenticated. Choose an available provider/model or a configured tier.`,\n\t\t);\n\t}\n\tconst fromSuffix = thinkingSuffix ? thinkingSuffix.slice(1) : undefined;\n\tconst fromParam = parseExplicitThinking(thinking);\n\tif (fromSuffix && fromParam && fromSuffix !== fromParam) {\n\t\tthrow new Error(`Conflicting thinking levels '${fromSuffix}' and '${fromParam}' for model '${requested}'.`);\n\t}\n\tconst level = fromParam ?? fromSuffix;\n\tif (!level) return resolvedBase;\n\tconst info = availableModels.find((entry) => entry.fullId === resolvedBase);\n\tconst supported = getSupportedThinkingLevels(info);\n\tif (!supported.includes(level as ThinkingLevel)) {\n\t\tthrow new Error(\n\t\t\t`Thinking level '${level}' is not supported by '${resolvedBase}'. Supported: ${supported.join(\", \") || \"none\"}.`,\n\t\t);\n\t}\n\treturn applyThinkingSuffix(resolvedBase, level, true) ?? resolvedBase;\n}\n\n/** Resolve the launch model from a captured selection. Tier uses configured thinking; model uses optional explicit thinking. */\nexport function resolveExecutableChildModel(input: {\n\tmodelSelection?: ModelSelection;\n\ttier?: unknown;\n\tmodel?: unknown;\n\tthinking?: unknown;\n\tavailableModels?: AvailableModelInfo[];\n\tpreferredProvider?: string;\n}): string {\n\tconst selection = input.modelSelection ?? captureModelSelection({ model: input.model, tier: input.tier });\n\tif (selection.kind === \"tier\") {\n\t\tif (input.thinking !== undefined) {\n\t\t\tthrow new Error('thinking is only valid with an explicit model; tier children use the configured tier thinking level.');\n\t\t}\n\t\treturn resolveRequiredTierModel(selection.tier, input.availableModels, input.preferredProvider);\n\t}\n\treturn resolveRequiredExplicitModel(input.model, input.availableModels, input.preferredProvider, input.thinking);\n}\n\nexport interface BuildModelCandidatesOptions {\n\t/** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n\tscope?: ModelScopeConfig;\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nexport function buildModelCandidates(\n\tprimaryModel: string | undefined,\n\tfallbackModels: string[] | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: BuildModelCandidatesOptions,\n): string[] {\n\tconst seen = new Set<string>();\n\tconst candidates: string[] = [];\n\tconst rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n\tfor (let index = 0; index < rawCandidates.length; index++) {\n\t\tconst raw = rawCandidates[index];\n\t\tif (!raw) continue;\n\t\tconst normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n\t\tif (!normalized || seen.has(normalized)) continue;\n\t\tif (index > 0 && options?.scope?.enforce) {\n\t\t\tconst violation = checkModelScope(normalized, options.scope, \"inherited\");\n\t\t\tif (violation) (options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t\tseen.add(normalized);\n\t\tcandidates.push(normalized);\n\t}\n\treturn candidates;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n\t/rate\\s*limit/i,\n\t/too many requests/i,\n\t/\\b429\\b/,\n\t/quota/i,\n\t/billing/i,\n\t/credit/i,\n\t/auth(?:entication)?/i,\n\t/unauthori[sz]ed/i,\n\t/forbidden/i,\n\t/api key/i,\n\t/token expired/i,\n\t/invalid key/i,\n\t/provider.*unavailable/i,\n\t/model.*unavailable/i,\n\t/model.*disabled/i,\n\t/model.*not found/i,\n\t/unknown model/i,\n\t/overloaded/i,\n\t/service unavailable/i,\n\t/temporar(?:ily)? unavailable/i,\n\t/connection refused/i,\n\t/fetch failed/i,\n\t/network error/i,\n\t/socket hang up/i,\n\t/stream ended without finish_reason/i,\n\t/upstream/i,\n\t/timed? out/i,\n\t/timeout/i,\n\t/\\b502\\b/,\n\t/\\b503\\b/,\n\t/\\b504\\b/,\n\t/cold.?start/i,\n\t/empty response/i,\n\t/no output/i,\n\t/model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n\tif (!error) return false;\n\tif (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n\treturn RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n\tconst failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;\n\treturn nextModel\n\t\t? `[fallback] ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n\t\t: `[fallback] ${attempt.model} failed: ${failure}.`;\n}\n"]}
@@ -1,13 +1,9 @@
1
+ import { getSupportedThinkingLevels, splitKnownThinkingSuffix, THINKING_LEVELS } from "../../shared/model-info.js";
1
2
  import { checkModelScope } from "./model-scope.js";
2
3
  import { applyThinkingSuffix } from "./pi-args.js";
4
+ /** Strip only a known thinking suffix so model ids that contain colons stay intact. */
3
5
  export function splitThinkingSuffix(model) {
4
- const colonIdx = model.lastIndexOf(":");
5
- if (colonIdx === -1)
6
- return { baseModel: model, thinkingSuffix: "" };
7
- return {
8
- baseModel: model.substring(0, colonIdx),
9
- thinkingSuffix: model.substring(colonIdx),
10
- };
6
+ return splitKnownThinkingSuffix(model);
11
7
  }
12
8
  /** Sentinel model value requesting that a subagent inherit the parent session's model. */
13
9
  export const INHERIT_MODEL = "inherit";
@@ -231,16 +227,76 @@ function requestedModelString(model) {
231
227
  function requestedTier(tier) {
232
228
  return tier === "light" || tier === "standard" || tier === "heavy" ? tier : undefined;
233
229
  }
230
+ function parseExplicitThinking(value, pathLabel = "thinking") {
231
+ if (value === undefined)
232
+ return undefined;
233
+ if (value === false || value === "off")
234
+ return "off";
235
+ if (typeof value !== "string" || !THINKING_LEVELS.includes(value)) {
236
+ throw new Error(`${pathLabel} must be one of ${THINKING_LEVELS.join(", ")}.`);
237
+ }
238
+ return value;
239
+ }
234
240
  /**
235
241
  * Capture how a child model was selected from the original requested params.
236
242
  * Must run before callers replace `model` with a resolved override.
237
- * Explicit model wins; a tier only counts when it actually resolves.
243
+ * Exactly one of tier or model; inherit and both are rejected.
238
244
  */
239
245
  export function captureModelSelection(input) {
246
+ const model = typeof input.model === "string" ? input.model.trim() : "";
247
+ const hasModel = Boolean(model);
240
248
  const tier = requestedTier(input.tier);
241
- if (!tier)
242
- throw new Error("Every subagent execution requires tier: \"light\", \"standard\", or \"heavy\".");
243
- return { kind: "tier", tier };
249
+ if (hasModel && model === INHERIT_MODEL) {
250
+ throw new Error('model "inherit" is not supported; choose tier: "light", "standard", or "heavy", or an explicit provider/model.');
251
+ }
252
+ if (hasModel && tier) {
253
+ throw new Error('Choose exactly one of tier or model; do not pass both.');
254
+ }
255
+ if (hasModel)
256
+ return { kind: "model", model };
257
+ if (tier)
258
+ return { kind: "tier", tier };
259
+ throw new Error('Every executable child requires tier: "light", "standard", or "heavy", or an explicit model when the user names one.');
260
+ }
261
+ /** Resolve and validate an explicit provider/model (+ optional thinking) with no silent fallback. */
262
+ export function resolveRequiredExplicitModel(model, availableModels, preferredProvider, thinking) {
263
+ const requested = requestedModelString(model);
264
+ if (!requested) {
265
+ throw new Error('Explicit model selection requires model as "provider/id".');
266
+ }
267
+ if (!availableModels?.length) {
268
+ throw new Error(`Model '${requested}' cannot launch because no authenticated models are available.`);
269
+ }
270
+ const { baseModel, thinkingSuffix } = splitThinkingSuffix(requested);
271
+ const resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);
272
+ if (!resolvedBase) {
273
+ throw new Error(`Model '${baseModel}' is unavailable or unauthenticated. Choose an available provider/model or a configured tier.`);
274
+ }
275
+ const fromSuffix = thinkingSuffix ? thinkingSuffix.slice(1) : undefined;
276
+ const fromParam = parseExplicitThinking(thinking);
277
+ if (fromSuffix && fromParam && fromSuffix !== fromParam) {
278
+ throw new Error(`Conflicting thinking levels '${fromSuffix}' and '${fromParam}' for model '${requested}'.`);
279
+ }
280
+ const level = fromParam ?? fromSuffix;
281
+ if (!level)
282
+ return resolvedBase;
283
+ const info = availableModels.find((entry) => entry.fullId === resolvedBase);
284
+ const supported = getSupportedThinkingLevels(info);
285
+ if (!supported.includes(level)) {
286
+ throw new Error(`Thinking level '${level}' is not supported by '${resolvedBase}'. Supported: ${supported.join(", ") || "none"}.`);
287
+ }
288
+ return applyThinkingSuffix(resolvedBase, level, true) ?? resolvedBase;
289
+ }
290
+ /** Resolve the launch model from a captured selection. Tier uses configured thinking; model uses optional explicit thinking. */
291
+ export function resolveExecutableChildModel(input) {
292
+ const selection = input.modelSelection ?? captureModelSelection({ model: input.model, tier: input.tier });
293
+ if (selection.kind === "tier") {
294
+ if (input.thinking !== undefined) {
295
+ throw new Error('thinking is only valid with an explicit model; tier children use the configured tier thinking level.');
296
+ }
297
+ return resolveRequiredTierModel(selection.tier, input.availableModels, input.preferredProvider);
298
+ }
299
+ return resolveRequiredExplicitModel(input.model, input.availableModels, input.preferredProvider, input.thinking);
244
300
  }
245
301
  export function buildModelCandidates(primaryModel, fallbackModels, availableModels, preferredProvider, options) {
246
302
  const seen = new Set();
@@ -1 +1 @@
1
- {"version":3,"file":"model-fallback.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport type { ModelInfo as AvailableModelInfo } from \"../../shared/model-info.ts\";\nimport type { ChildTier, ModelSelection, Usage } from \"../../shared/types.ts\";\nimport { checkModelScope, type ModelScopeConfig, type ModelScopeViolation, type ModelSource } from \"./model-scope.ts\";\nimport { applyThinkingSuffix } from \"./pi-args.ts\";\n\nexport type { AvailableModelInfo };\n\ninterface ModelAttemptSummary {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\nexport function splitThinkingSuffix(model: string): { baseModel: string; thinkingSuffix: string } {\n\tconst colonIdx = model.lastIndexOf(\":\");\n\tif (colonIdx === -1) return { baseModel: model, thinkingSuffix: \"\" };\n\treturn {\n\t\tbaseModel: model.substring(0, colonIdx),\n\t\tthinkingSuffix: model.substring(colonIdx),\n\t};\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = \"inherit\";\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n\tprovider: string;\n\tid: string;\n}\n\n/**\n * Normalize a model id or provider segment for fuzzy comparison: case-fold,\n * treat dots/underscores as dashes (so `4.5` matches `4-5`), and collapse\n * repeated separators. Pure.\n */\nexport function normalizeModelSegment(segment: string): string {\n\treturn segment\n\t\t.toLowerCase()\n\t\t.replace(/[._]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\nfunction isPlausibleDateStamp(year: string, month: string, day: string): boolean {\n\tconst yyyy = Number(year);\n\tconst mm = Number(month);\n\tconst dd = Number(day);\n\treturn yyyy >= 1900 && yyyy <= 2099 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;\n}\n\n/** Drop a trailing date stamp (`-20251001` or `-2025-10-01`) so dated and undated ids match. Pure. */\nfunction stripTrailingDateStamp(segment: string): string {\n\tconst dashed = /^(.*)-(\\d{4})-(\\d{2})-(\\d{2})$/.exec(segment);\n\tif (dashed && isPlausibleDateStamp(dashed[2]!, dashed[3]!, dashed[4]!)) return dashed[1]!;\n\tconst compact = /^(.*)-(\\d{4})(\\d{2})(\\d{2})$/.exec(segment);\n\tif (compact && isPlausibleDateStamp(compact[2]!, compact[3]!, compact[4]!)) return compact[1]!;\n\treturn segment;\n}\n\nfunction resolveBaseModelCandidate(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (baseModel.includes(\"/\")) {\n\t\tconst exact = availableModels.find((entry) => entry.fullId === baseModel);\n\t\tif (exact) return exact.fullId;\n\t} else {\n\t\tconst exactMatches = availableModels.filter((entry) => entry.id === baseModel);\n\t\tif (preferredProvider) {\n\t\t\tconst preferredMatch = exactMatches.find((entry) => entry.provider === preferredProvider);\n\t\t\tif (preferredMatch) return preferredMatch.fullId;\n\t\t}\n\t\tif (exactMatches.length === 1) return exactMatches[0]!.fullId;\n\t}\n\n\treturn fuzzyResolveModel(baseModel, availableModels, preferredProvider);\n}\n\n/**\n * Fuzzy-resolve a base model id (thinking suffix already stripped) against the\n * registry, tolerating separator, case, and optional date-stamp differences so\n * users do not have to spell provider/model exactly. A qualified `provider/id`\n * query only matches within the named provider — this never silently switches\n * providers for security/cost-sensitive configs. Returns the matched `fullId`,\n * or `undefined` when there is no match or the match is ambiguous across\n * providers (and no `preferredProvider` disambiguates). Pure.\n */\nexport function fuzzyResolveModel(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tlet queryProvider: string | undefined;\n\tlet queryIdRaw = baseModel;\n\tconst slashIdx = baseModel.indexOf(\"/\");\n\tif (slashIdx !== -1) {\n\t\tqueryProvider = normalizeModelSegment(baseModel.slice(0, slashIdx));\n\t\tqueryIdRaw = baseModel.slice(slashIdx + 1);\n\t} else {\n\t\tconst providerSeparators = [\":\", \".\"];\n\t\tfor (const separator of providerSeparators) {\n\t\t\tconst separatorIdx = baseModel.indexOf(separator);\n\t\t\tif (separatorIdx <= 0) continue;\n\t\t\tconst providerPart = normalizeModelSegment(baseModel.slice(0, separatorIdx));\n\t\t\tif (!availableModels.some((entry) => normalizeModelSegment(entry.provider) === providerPart)) continue;\n\t\t\tqueryProvider = providerPart;\n\t\t\tqueryIdRaw = baseModel.slice(separatorIdx + 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst queryId = normalizeModelSegment(queryIdRaw);\n\tconst queryIdNoDate = stripTrailingDateStamp(queryId);\n\n\tconst candidates = availableModels.filter((entry) => {\n\t\tconst entryId = normalizeModelSegment(entry.id);\n\t\tif (entryId !== queryId && stripTrailingDateStamp(entryId) !== queryIdNoDate) return false;\n\t\tif (queryProvider !== undefined && normalizeModelSegment(entry.provider) !== queryProvider) return false;\n\t\treturn true;\n\t});\n\tif (candidates.length === 0) return undefined;\n\tif (preferredProvider) {\n\t\tconst preferredProviderNorm = normalizeModelSegment(preferredProvider);\n\t\tconst preferred = candidates.find((entry) => normalizeModelSegment(entry.provider) === preferredProviderNorm);\n\t\tif (preferred) return preferred.fullId;\n\t}\n\tif (candidates.length === 1) return candidates[0]!.fullId;\n\treturn undefined;\n}\n\n/**\n * Resolve a possibly-loose model id to a canonical `provider/id` (plus any\n * thinking suffix). Exact registry matches win; fuzzy normalization\n * (separator/case/date-stamp via {@link fuzzyResolveModel}) is a fallback so\n * spelling differences still resolve. Never switches providers for a qualified\n * query. Pure.\n */\nexport function resolveModelCandidate(\n\tmodel: string | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (!model) return undefined;\n\tif (!availableModels || availableModels.length === 0) return model;\n\n\tconst resolvedWhole = resolveBaseModelCandidate(model, availableModels, preferredProvider);\n\tif (resolvedWhole) return resolvedWhole;\n\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(model);\n\tif (!thinkingSuffix) return model;\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (resolvedBase) return `${resolvedBase}${thinkingSuffix}`;\n\treturn model;\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n\t/** When set with `enforce: true`, out-of-scope models are rejected. */\n\tscope?: ModelScopeConfig;\n\t/** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n\tsource?: ModelSource;\n\t/** Called for warn-severity violations instead of `console.warn`. */\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nfunction defaultScopeWarn(violation: ModelScopeViolation): void {\n\tconsole.warn(`[pi-subagents] ${violation.message}`);\n}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child must inherit the parent session's *in-memory* model\n * (`provider/id`) instead of being left to resolve its own model. Without an\n * explicit `provider/id`, the child falls back to the global\n * `~/.pi/agent/settings.json` default, which is shared across every open PI\n * session — so a different session that last changed its model in the TUI would\n * silently contaminate this session's subagents (see issue #266). Passing an\n * explicit `provider/id` keeps each session's children isolated to that\n * session's model.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n\trequestedModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n\tconst trimmed = typeof requestedModel === \"string\" ? requestedModel.trim() : \"\";\n\tconst explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n\tlet resolved: string | undefined;\n\tif (explicit === undefined) {\n\t\tresolved = parentModel ? `${parentModel.provider}/${parentModel.id}` : undefined;\n\t} else {\n\t\tresolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n\t}\n\tif (resolved && options?.scope?.enforce) {\n\t\tconst source: ModelSource = explicit === undefined ? \"inherited\" : (options.source ?? \"inherited\");\n\t\tconst violation = checkModelScope(resolved, options.scope, source);\n\t\tif (violation) {\n\t\t\tif (violation.severity === \"error\") throw new Error(violation.message);\n\t\t\t(options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t}\n\treturn resolved;\n}\n\nexport function resolveEffectiveSubagentModel(\n\texplicitModel: string | boolean | undefined,\n\tagentModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: Omit<ResolveSubagentModelOverrideOptions, \"source\">,\n): string | undefined {\n\tconst resolved = resolveSubagentModelOverride(\n\t\texplicitModel ?? agentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: explicitModel !== undefined ? \"explicit\" : \"inherited\" },\n\t);\n\tif (resolved || explicitModel === undefined) return resolved;\n\treturn resolveSubagentModelOverride(\n\t\tagentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: \"inherited\" },\n\t);\n}\n\n// lunr: model tier bridge — every executable child must resolve one configured tier.\nexport function resolveTierModelOverride(tier: unknown): string | undefined {\n\tif (tier !== \"light\" && tier !== \"standard\" && tier !== \"heavy\") {\n\t\tthrow new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\t}\n\tconst tierName = tier.trim();\n\ttry {\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t\t| { getTierModel?: (tier: string) => unknown; isTierModeEnabled?: () => unknown }\n\t\t\t| undefined;\n\t\tif (typeof bridge?.isTierModeEnabled !== \"function\" || typeof bridge?.getTierModel !== \"function\") {\n\t\t\tthrow new Error(\"Model tier settings are unavailable. Reload lunR and try again.\");\n\t\t}\n\t\tif (bridge.isTierModeEnabled() !== true) {\n\t\t\tthrow new Error(\"Model tiers are disabled. Enable them in /settings before launching a subagent.\");\n\t\t}\n\t\tconst model = bridge.getTierModel(tierName);\n\t\tif (typeof model !== \"string\" || !model.trim()) {\n\t\t\tthrow new Error(`Model tier '${tierName}' has no configured model. Configure it in /settings before launching a subagent.`);\n\t\t}\n\t\tconst trimmed = model.trim();\n\t\tconst thinking =\n\t\t\ttypeof bridge.getTierThinking === \"function\" ? bridge.getTierThinking(tierName) : undefined;\n\t\tconst parent = typeof bridge.getParentThinking === \"function\" ? bridge.getParentThinking() : undefined;\n\t\tconst level = (typeof thinking === \"string\" && thinking ? thinking : undefined) ?? (typeof parent === \"string\" && parent ? parent : undefined);\n\t\tif (!level) return trimmed;\n\t\treturn applyThinkingSuffix(trimmed, level, true) ?? trimmed;\n\t} catch (error) {\n\t\tthrow error instanceof Error ? error : new Error(String(error));\n\t}\n}\n\n/** Resolve a required tier and prove its configured model is available to this session. */\nexport function resolveRequiredTierModel(\n\ttier: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string {\n\tconst configured = resolveTierModelOverride(tier);\n\tif (!configured) throw new Error(`Model tier '${String(tier)}' could not be resolved.`);\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model tier '${String(tier)}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(configured);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model tier '${String(tier)}' resolves to '${baseModel}', but that model is unavailable or unauthenticated. Configure an available model in /settings.`,\n\t\t);\n\t}\n\treturn `${resolvedBase}${thinkingSuffix}`;\n}\n\nfunction requestedModelString(model: unknown): string | undefined {\n\treturn typeof model === \"string\" && model.trim() && model.trim() !== INHERIT_MODEL ? model.trim() : undefined;\n}\n\nfunction requestedTier(tier: unknown): ChildTier | undefined {\n\treturn tier === \"light\" || tier === \"standard\" || tier === \"heavy\" ? tier : undefined;\n}\n\n/**\n * Capture how a child model was selected from the original requested params.\n * Must run before callers replace `model` with a resolved override.\n * Explicit model wins; a tier only counts when it actually resolves.\n */\nexport function captureModelSelection(input: { model?: unknown; tier?: unknown }): ModelSelection {\n\tconst tier = requestedTier(input.tier);\n\tif (!tier) throw new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\treturn { kind: \"tier\", tier };\n}\n\nexport interface BuildModelCandidatesOptions {\n\t/** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n\tscope?: ModelScopeConfig;\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nexport function buildModelCandidates(\n\tprimaryModel: string | undefined,\n\tfallbackModels: string[] | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: BuildModelCandidatesOptions,\n): string[] {\n\tconst seen = new Set<string>();\n\tconst candidates: string[] = [];\n\tconst rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n\tfor (let index = 0; index < rawCandidates.length; index++) {\n\t\tconst raw = rawCandidates[index];\n\t\tif (!raw) continue;\n\t\tconst normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n\t\tif (!normalized || seen.has(normalized)) continue;\n\t\tif (index > 0 && options?.scope?.enforce) {\n\t\t\tconst violation = checkModelScope(normalized, options.scope, \"inherited\");\n\t\t\tif (violation) (options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t\tseen.add(normalized);\n\t\tcandidates.push(normalized);\n\t}\n\treturn candidates;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n\t/rate\\s*limit/i,\n\t/too many requests/i,\n\t/\\b429\\b/,\n\t/quota/i,\n\t/billing/i,\n\t/credit/i,\n\t/auth(?:entication)?/i,\n\t/unauthori[sz]ed/i,\n\t/forbidden/i,\n\t/api key/i,\n\t/token expired/i,\n\t/invalid key/i,\n\t/provider.*unavailable/i,\n\t/model.*unavailable/i,\n\t/model.*disabled/i,\n\t/model.*not found/i,\n\t/unknown model/i,\n\t/overloaded/i,\n\t/service unavailable/i,\n\t/temporar(?:ily)? unavailable/i,\n\t/connection refused/i,\n\t/fetch failed/i,\n\t/network error/i,\n\t/socket hang up/i,\n\t/stream ended without finish_reason/i,\n\t/upstream/i,\n\t/timed? out/i,\n\t/timeout/i,\n\t/\\b502\\b/,\n\t/\\b503\\b/,\n\t/\\b504\\b/,\n\t/cold.?start/i,\n\t/empty response/i,\n\t/no output/i,\n\t/model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n\tif (!error) return false;\n\tif (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n\treturn RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n\tconst failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;\n\treturn nextModel\n\t\t? `[fallback] ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n\t\t: `[fallback] ${attempt.model} failed: ${failure}.`;\n}\n"]}
1
+ {"version":3,"file":"model-fallback.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/model-fallback.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nimport type { ModelInfo as AvailableModelInfo } from \"../../shared/model-info.ts\";\nimport { getSupportedThinkingLevels, splitKnownThinkingSuffix, THINKING_LEVELS, type ThinkingLevel } from \"../../shared/model-info.ts\";\nimport type { ChildTier, ModelSelection, Usage } from \"../../shared/types.ts\";\nimport { checkModelScope, type ModelScopeConfig, type ModelScopeViolation, type ModelSource } from \"./model-scope.ts\";\nimport { applyThinkingSuffix } from \"./pi-args.ts\";\n\nexport type { AvailableModelInfo };\n\ninterface ModelAttemptSummary {\n\tmodel: string;\n\tsuccess: boolean;\n\texitCode?: number | null;\n\terror?: string;\n\tusage?: Usage;\n}\n\n/** Strip only a known thinking suffix so model ids that contain colons stay intact. */\nexport function splitThinkingSuffix(model: string): { baseModel: string; thinkingSuffix: string } {\n\treturn splitKnownThinkingSuffix(model);\n}\n\n/** Sentinel model value requesting that a subagent inherit the parent session's model. */\nexport const INHERIT_MODEL = \"inherit\";\n\n/** Minimal shape of the parent session's in-memory model (`ctx.model`). */\nexport interface ParentModel {\n\tprovider: string;\n\tid: string;\n}\n\n/**\n * Normalize a model id or provider segment for fuzzy comparison: case-fold,\n * treat dots/underscores as dashes (so `4.5` matches `4-5`), and collapse\n * repeated separators. Pure.\n */\nexport function normalizeModelSegment(segment: string): string {\n\treturn segment\n\t\t.toLowerCase()\n\t\t.replace(/[._]+/g, \"-\")\n\t\t.replace(/-+/g, \"-\")\n\t\t.replace(/^-|-$/g, \"\");\n}\n\nfunction isPlausibleDateStamp(year: string, month: string, day: string): boolean {\n\tconst yyyy = Number(year);\n\tconst mm = Number(month);\n\tconst dd = Number(day);\n\treturn yyyy >= 1900 && yyyy <= 2099 && mm >= 1 && mm <= 12 && dd >= 1 && dd <= 31;\n}\n\n/** Drop a trailing date stamp (`-20251001` or `-2025-10-01`) so dated and undated ids match. Pure. */\nfunction stripTrailingDateStamp(segment: string): string {\n\tconst dashed = /^(.*)-(\\d{4})-(\\d{2})-(\\d{2})$/.exec(segment);\n\tif (dashed && isPlausibleDateStamp(dashed[2]!, dashed[3]!, dashed[4]!)) return dashed[1]!;\n\tconst compact = /^(.*)-(\\d{4})(\\d{2})(\\d{2})$/.exec(segment);\n\tif (compact && isPlausibleDateStamp(compact[2]!, compact[3]!, compact[4]!)) return compact[1]!;\n\treturn segment;\n}\n\nfunction resolveBaseModelCandidate(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (baseModel.includes(\"/\")) {\n\t\tconst exact = availableModels.find((entry) => entry.fullId === baseModel);\n\t\tif (exact) return exact.fullId;\n\t} else {\n\t\tconst exactMatches = availableModels.filter((entry) => entry.id === baseModel);\n\t\tif (preferredProvider) {\n\t\t\tconst preferredMatch = exactMatches.find((entry) => entry.provider === preferredProvider);\n\t\t\tif (preferredMatch) return preferredMatch.fullId;\n\t\t}\n\t\tif (exactMatches.length === 1) return exactMatches[0]!.fullId;\n\t}\n\n\treturn fuzzyResolveModel(baseModel, availableModels, preferredProvider);\n}\n\n/**\n * Fuzzy-resolve a base model id (thinking suffix already stripped) against the\n * registry, tolerating separator, case, and optional date-stamp differences so\n * users do not have to spell provider/model exactly. A qualified `provider/id`\n * query only matches within the named provider — this never silently switches\n * providers for security/cost-sensitive configs. Returns the matched `fullId`,\n * or `undefined` when there is no match or the match is ambiguous across\n * providers (and no `preferredProvider` disambiguates). Pure.\n */\nexport function fuzzyResolveModel(\n\tbaseModel: string,\n\tavailableModels: AvailableModelInfo[],\n\tpreferredProvider?: string,\n): string | undefined {\n\tlet queryProvider: string | undefined;\n\tlet queryIdRaw = baseModel;\n\tconst slashIdx = baseModel.indexOf(\"/\");\n\tif (slashIdx !== -1) {\n\t\tqueryProvider = normalizeModelSegment(baseModel.slice(0, slashIdx));\n\t\tqueryIdRaw = baseModel.slice(slashIdx + 1);\n\t} else {\n\t\tconst providerSeparators = [\":\", \".\"];\n\t\tfor (const separator of providerSeparators) {\n\t\t\tconst separatorIdx = baseModel.indexOf(separator);\n\t\t\tif (separatorIdx <= 0) continue;\n\t\t\tconst providerPart = normalizeModelSegment(baseModel.slice(0, separatorIdx));\n\t\t\tif (!availableModels.some((entry) => normalizeModelSegment(entry.provider) === providerPart)) continue;\n\t\t\tqueryProvider = providerPart;\n\t\t\tqueryIdRaw = baseModel.slice(separatorIdx + 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\tconst queryId = normalizeModelSegment(queryIdRaw);\n\tconst queryIdNoDate = stripTrailingDateStamp(queryId);\n\n\tconst candidates = availableModels.filter((entry) => {\n\t\tconst entryId = normalizeModelSegment(entry.id);\n\t\tif (entryId !== queryId && stripTrailingDateStamp(entryId) !== queryIdNoDate) return false;\n\t\tif (queryProvider !== undefined && normalizeModelSegment(entry.provider) !== queryProvider) return false;\n\t\treturn true;\n\t});\n\tif (candidates.length === 0) return undefined;\n\tif (preferredProvider) {\n\t\tconst preferredProviderNorm = normalizeModelSegment(preferredProvider);\n\t\tconst preferred = candidates.find((entry) => normalizeModelSegment(entry.provider) === preferredProviderNorm);\n\t\tif (preferred) return preferred.fullId;\n\t}\n\tif (candidates.length === 1) return candidates[0]!.fullId;\n\treturn undefined;\n}\n\n/**\n * Resolve a possibly-loose model id to a canonical `provider/id` (plus any\n * thinking suffix). Exact registry matches win; fuzzy normalization\n * (separator/case/date-stamp via {@link fuzzyResolveModel}) is a fallback so\n * spelling differences still resolve. Never switches providers for a qualified\n * query. Pure.\n */\nexport function resolveModelCandidate(\n\tmodel: string | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string | undefined {\n\tif (!model) return undefined;\n\tif (!availableModels || availableModels.length === 0) return model;\n\n\tconst resolvedWhole = resolveBaseModelCandidate(model, availableModels, preferredProvider);\n\tif (resolvedWhole) return resolvedWhole;\n\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(model);\n\tif (!thinkingSuffix) return model;\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (resolvedBase) return `${resolvedBase}${thinkingSuffix}`;\n\treturn model;\n}\n\nexport interface ResolveSubagentModelOverrideOptions {\n\t/** When set with `enforce: true`, out-of-scope models are rejected. */\n\tscope?: ModelScopeConfig;\n\t/** Origin of the requested model: explicit caller-supplied (hard error) vs inherited (warn). Defaults to `\"inherited\"`. */\n\tsource?: ModelSource;\n\t/** Called for warn-severity violations instead of `console.warn`. */\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nfunction defaultScopeWarn(violation: ModelScopeViolation): void {\n\tconsole.warn(`[pi-subagents] ${violation.message}`);\n}\n\n/**\n * Resolve the `--model` override passed to a spawned subagent.\n *\n * When no model is requested (`undefined`, `false`, empty, or the `\"inherit\"`\n * sentinel), the child must inherit the parent session's *in-memory* model\n * (`provider/id`) instead of being left to resolve its own model. Without an\n * explicit `provider/id`, the child falls back to the global\n * `~/.pi/agent/settings.json` default, which is shared across every open PI\n * session — so a different session that last changed its model in the TUI would\n * silently contaminate this session's subagents (see issue #266). Passing an\n * explicit `provider/id` keeps each session's children isolated to that\n * session's model.\n *\n * An explicitly requested model string is resolved via {@link resolveModelCandidate}.\n * When `options.scope.enforce` is on, an out-of-scope resolved model throws for\n * an explicit (`source: \"explicit\"`) request and warns for an inherited one.\n */\nexport function resolveSubagentModelOverride(\n\trequestedModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: ResolveSubagentModelOverrideOptions,\n): string | undefined {\n\tconst trimmed = typeof requestedModel === \"string\" ? requestedModel.trim() : \"\";\n\tconst explicit = trimmed && trimmed !== INHERIT_MODEL ? trimmed : undefined;\n\tlet resolved: string | undefined;\n\tif (explicit === undefined) {\n\t\tresolved = parentModel ? `${parentModel.provider}/${parentModel.id}` : undefined;\n\t} else {\n\t\tresolved = resolveModelCandidate(explicit, availableModels, preferredProvider);\n\t}\n\tif (resolved && options?.scope?.enforce) {\n\t\tconst source: ModelSource = explicit === undefined ? \"inherited\" : (options.source ?? \"inherited\");\n\t\tconst violation = checkModelScope(resolved, options.scope, source);\n\t\tif (violation) {\n\t\t\tif (violation.severity === \"error\") throw new Error(violation.message);\n\t\t\t(options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t}\n\treturn resolved;\n}\n\nexport function resolveEffectiveSubagentModel(\n\texplicitModel: string | boolean | undefined,\n\tagentModel: string | boolean | undefined,\n\tparentModel: ParentModel | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: Omit<ResolveSubagentModelOverrideOptions, \"source\">,\n): string | undefined {\n\tconst resolved = resolveSubagentModelOverride(\n\t\texplicitModel ?? agentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: explicitModel !== undefined ? \"explicit\" : \"inherited\" },\n\t);\n\tif (resolved || explicitModel === undefined) return resolved;\n\treturn resolveSubagentModelOverride(\n\t\tagentModel,\n\t\tparentModel,\n\t\tavailableModels,\n\t\tpreferredProvider,\n\t\t{ ...options, source: \"inherited\" },\n\t);\n}\n\n// lunr: model tier bridge — every executable child must resolve one configured tier.\nexport function resolveTierModelOverride(tier: unknown): string | undefined {\n\tif (tier !== \"light\" && tier !== \"standard\" && tier !== \"heavy\") {\n\t\tthrow new Error(\"Every subagent execution requires tier: \\\"light\\\", \\\"standard\\\", or \\\"heavy\\\".\");\n\t}\n\tconst tierName = tier.trim();\n\ttry {\n\t\tconst bridge = (globalThis as Record<symbol, unknown>)[Symbol.for(\"@lunr/model-tiers\")] as\n\t\t\t| { getTierModel?: (tier: string) => unknown; isTierModeEnabled?: () => unknown }\n\t\t\t| undefined;\n\t\tif (typeof bridge?.isTierModeEnabled !== \"function\" || typeof bridge?.getTierModel !== \"function\") {\n\t\t\tthrow new Error(\"Model tier settings are unavailable. Reload lunR and try again.\");\n\t\t}\n\t\tif (bridge.isTierModeEnabled() !== true) {\n\t\t\tthrow new Error(\"Model tiers are disabled. Enable them in /settings before launching a subagent.\");\n\t\t}\n\t\tconst model = bridge.getTierModel(tierName);\n\t\tif (typeof model !== \"string\" || !model.trim()) {\n\t\t\tthrow new Error(`Model tier '${tierName}' has no configured model. Configure it in /settings before launching a subagent.`);\n\t\t}\n\t\tconst trimmed = model.trim();\n\t\tconst thinking =\n\t\t\ttypeof bridge.getTierThinking === \"function\" ? bridge.getTierThinking(tierName) : undefined;\n\t\tconst parent = typeof bridge.getParentThinking === \"function\" ? bridge.getParentThinking() : undefined;\n\t\tconst level = (typeof thinking === \"string\" && thinking ? thinking : undefined) ?? (typeof parent === \"string\" && parent ? parent : undefined);\n\t\tif (!level) return trimmed;\n\t\treturn applyThinkingSuffix(trimmed, level, true) ?? trimmed;\n\t} catch (error) {\n\t\tthrow error instanceof Error ? error : new Error(String(error));\n\t}\n}\n\n/** Resolve a required tier and prove its configured model is available to this session. */\nexport function resolveRequiredTierModel(\n\ttier: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n): string {\n\tconst configured = resolveTierModelOverride(tier);\n\tif (!configured) throw new Error(`Model tier '${String(tier)}' could not be resolved.`);\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model tier '${String(tier)}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(configured);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model tier '${String(tier)}' resolves to '${baseModel}', but that model is unavailable or unauthenticated. Configure an available model in /settings.`,\n\t\t);\n\t}\n\treturn `${resolvedBase}${thinkingSuffix}`;\n}\n\nfunction requestedModelString(model: unknown): string | undefined {\n\treturn typeof model === \"string\" && model.trim() && model.trim() !== INHERIT_MODEL ? model.trim() : undefined;\n}\n\nfunction requestedTier(tier: unknown): ChildTier | undefined {\n\treturn tier === \"light\" || tier === \"standard\" || tier === \"heavy\" ? tier : undefined;\n}\n\nfunction parseExplicitThinking(value: unknown, pathLabel = \"thinking\"): ThinkingLevel | undefined {\n\tif (value === undefined) return undefined;\n\tif (value === false || value === \"off\") return \"off\";\n\tif (typeof value !== \"string\" || !(THINKING_LEVELS as readonly string[]).includes(value)) {\n\t\tthrow new Error(`${pathLabel} must be one of ${THINKING_LEVELS.join(\", \")}.`);\n\t}\n\treturn value as ThinkingLevel;\n}\n\n/**\n * Capture how a child model was selected from the original requested params.\n * Must run before callers replace `model` with a resolved override.\n * Exactly one of tier or model; inherit and both are rejected.\n */\nexport function captureModelSelection(input: { model?: unknown; tier?: unknown }): ModelSelection {\n\tconst model = typeof input.model === \"string\" ? input.model.trim() : \"\";\n\tconst hasModel = Boolean(model);\n\tconst tier = requestedTier(input.tier);\n\tif (hasModel && model === INHERIT_MODEL) {\n\t\tthrow new Error('model \"inherit\" is not supported; choose tier: \"light\", \"standard\", or \"heavy\", or an explicit provider/model.');\n\t}\n\tif (hasModel && tier) {\n\t\tthrow new Error('Choose exactly one of tier or model; do not pass both.');\n\t}\n\tif (hasModel) return { kind: \"model\", model };\n\tif (tier) return { kind: \"tier\", tier };\n\tthrow new Error('Every executable child requires tier: \"light\", \"standard\", or \"heavy\", or an explicit model when the user names one.');\n}\n\n/** Resolve and validate an explicit provider/model (+ optional thinking) with no silent fallback. */\nexport function resolveRequiredExplicitModel(\n\tmodel: unknown,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\tthinking?: unknown,\n): string {\n\tconst requested = requestedModelString(model);\n\tif (!requested) {\n\t\tthrow new Error('Explicit model selection requires model as \"provider/id\".');\n\t}\n\tif (!availableModels?.length) {\n\t\tthrow new Error(`Model '${requested}' cannot launch because no authenticated models are available.`);\n\t}\n\tconst { baseModel, thinkingSuffix } = splitThinkingSuffix(requested);\n\tconst resolvedBase = resolveBaseModelCandidate(baseModel, availableModels, preferredProvider);\n\tif (!resolvedBase) {\n\t\tthrow new Error(\n\t\t\t`Model '${baseModel}' is unavailable or unauthenticated. Choose an available provider/model or a configured tier.`,\n\t\t);\n\t}\n\tconst fromSuffix = thinkingSuffix ? thinkingSuffix.slice(1) : undefined;\n\tconst fromParam = parseExplicitThinking(thinking);\n\tif (fromSuffix && fromParam && fromSuffix !== fromParam) {\n\t\tthrow new Error(`Conflicting thinking levels '${fromSuffix}' and '${fromParam}' for model '${requested}'.`);\n\t}\n\tconst level = fromParam ?? fromSuffix;\n\tif (!level) return resolvedBase;\n\tconst info = availableModels.find((entry) => entry.fullId === resolvedBase);\n\tconst supported = getSupportedThinkingLevels(info);\n\tif (!supported.includes(level as ThinkingLevel)) {\n\t\tthrow new Error(\n\t\t\t`Thinking level '${level}' is not supported by '${resolvedBase}'. Supported: ${supported.join(\", \") || \"none\"}.`,\n\t\t);\n\t}\n\treturn applyThinkingSuffix(resolvedBase, level, true) ?? resolvedBase;\n}\n\n/** Resolve the launch model from a captured selection. Tier uses configured thinking; model uses optional explicit thinking. */\nexport function resolveExecutableChildModel(input: {\n\tmodelSelection?: ModelSelection;\n\ttier?: unknown;\n\tmodel?: unknown;\n\tthinking?: unknown;\n\tavailableModels?: AvailableModelInfo[];\n\tpreferredProvider?: string;\n}): string {\n\tconst selection = input.modelSelection ?? captureModelSelection({ model: input.model, tier: input.tier });\n\tif (selection.kind === \"tier\") {\n\t\tif (input.thinking !== undefined) {\n\t\t\tthrow new Error('thinking is only valid with an explicit model; tier children use the configured tier thinking level.');\n\t\t}\n\t\treturn resolveRequiredTierModel(selection.tier, input.availableModels, input.preferredProvider);\n\t}\n\treturn resolveRequiredExplicitModel(input.model, input.availableModels, input.preferredProvider, input.thinking);\n}\n\nexport interface BuildModelCandidatesOptions {\n\t/** Fallback models are inherited agent config and warn, rather than error, when out of scope. */\n\tscope?: ModelScopeConfig;\n\tonWarn?: (violation: ModelScopeViolation) => void;\n}\n\nexport function buildModelCandidates(\n\tprimaryModel: string | undefined,\n\tfallbackModels: string[] | undefined,\n\tavailableModels: AvailableModelInfo[] | undefined,\n\tpreferredProvider?: string,\n\toptions?: BuildModelCandidatesOptions,\n): string[] {\n\tconst seen = new Set<string>();\n\tconst candidates: string[] = [];\n\tconst rawCandidates = [primaryModel, ...(fallbackModels ?? [])];\n\tfor (let index = 0; index < rawCandidates.length; index++) {\n\t\tconst raw = rawCandidates[index];\n\t\tif (!raw) continue;\n\t\tconst normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);\n\t\tif (!normalized || seen.has(normalized)) continue;\n\t\tif (index > 0 && options?.scope?.enforce) {\n\t\t\tconst violation = checkModelScope(normalized, options.scope, \"inherited\");\n\t\t\tif (violation) (options.onWarn ?? defaultScopeWarn)(violation);\n\t\t}\n\t\tseen.add(normalized);\n\t\tcandidates.push(normalized);\n\t}\n\treturn candidates;\n}\n\nconst RETRYABLE_MODEL_FAILURE_PATTERNS = [\n\t/rate\\s*limit/i,\n\t/too many requests/i,\n\t/\\b429\\b/,\n\t/quota/i,\n\t/billing/i,\n\t/credit/i,\n\t/auth(?:entication)?/i,\n\t/unauthori[sz]ed/i,\n\t/forbidden/i,\n\t/api key/i,\n\t/token expired/i,\n\t/invalid key/i,\n\t/provider.*unavailable/i,\n\t/model.*unavailable/i,\n\t/model.*disabled/i,\n\t/model.*not found/i,\n\t/unknown model/i,\n\t/overloaded/i,\n\t/service unavailable/i,\n\t/temporar(?:ily)? unavailable/i,\n\t/connection refused/i,\n\t/fetch failed/i,\n\t/network error/i,\n\t/socket hang up/i,\n\t/stream ended without finish_reason/i,\n\t/upstream/i,\n\t/timed? out/i,\n\t/timeout/i,\n\t/\\b502\\b/,\n\t/\\b503\\b/,\n\t/\\b504\\b/,\n\t/cold.?start/i,\n\t/empty response/i,\n\t/no output/i,\n\t/model.*(?:load|fail|error)/i,\n];\n\n/**\n * Failures reported as `<tool> failed (exit N): ...` or `<tool> failed with\n * exit code N` come from a tool call inside the child's task, not from the\n * provider/model, however network-flavored their details read. Retrying a\n * different model cannot fix them and would rerun the whole task. Tool names\n * include namespaced forms like `mcp.server/write`.\n */\nconst TOOL_FAILURE_PREFIX = /^[\\w.:@/-]+ failed (?:(?:\\(exit \\d+\\):)|(?:with exit code \\d+))(?:\\s|$)/i;\n\nexport function isRetryableModelFailure(error: string | undefined): boolean {\n\tif (!error) return false;\n\tif (TOOL_FAILURE_PREFIX.test(error.trim())) return false;\n\treturn RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));\n}\n\nexport function formatModelAttemptNote(attempt: ModelAttemptSummary, nextModel?: string): string {\n\tconst failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;\n\treturn nextModel\n\t\t? `[fallback] ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`\n\t\t: `[fallback] ${attempt.model} failed: ${failure}.`;\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  export interface RunnerSubagentStep {
2
+ completionTask?: string;
2
3
  /** Session id of the direct parent session for permission-system ask forwarding. */
3
4
  parentSessionId?: string;
4
5
  /** Live parent permission mode snapshotted at spawn. */
@@ -1 +1 @@
1
- {"version":3,"file":"parallel-utils.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nexport interface RunnerSubagentStep {\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\t/** Live parent permission mode snapshotted at spawn. */\n\tparentPermissionMode?: string;\n\tagent?: string;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: \"full\" | \"read-only\";\n\ttier?: import(\"../../shared/types.ts\").ChildTier;\n\ttask: string;\n\timportAsyncRoot?: {\n\t\trunId: string;\n\t\tasyncDir: string;\n\t\tresultPath: string;\n\t\tindex: number;\n\t};\n\tphase?: string;\n\tlabel?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tcwd?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tmodelCandidates?: string[];\n\ttools?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\tmcpDirectTools?: string[];\n\tcompletionGuard?: boolean;\n\tsystemPrompt?: string | null;\n\tsystemPromptMode?: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tskills?: string[];\n\toutputPath?: string;\n\t/** Defer the authoritative output instruction until a dynamic fanout item is materialized. */\n\tnamespaceOutputPath?: boolean;\n\toutputMode?: \"inline\" | \"file-only\";\n\tsessionFile?: string;\n\tmaxSubagentDepth?: number;\n\twaitToolEnabled?: boolean;\n\tstructuredOutput?: {\n\t\tschema: import(\"../../shared/types.ts\").JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tstructuredOutputSchema?: import(\"../../shared/types.ts\").JsonSchemaObject;\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n\ttoolBudget?: import(\"../../shared/types.ts\").ResolvedToolBudget;\n}\n\nexport interface ParallelStepGroup {\n\tparallel: RunnerSubagentStep[];\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tworktree?: boolean;\n}\n\nexport interface DynamicRunnerGroup {\n\texpand: import(\"../../shared/settings.ts\").DynamicExpandSpec;\n\tparallel: RunnerSubagentStep;\n\tcollect: import(\"../../shared/settings.ts\").DynamicCollectSpec;\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tphase?: string;\n\tlabel?: string;\n\tsessionFiles?: (string | undefined)[];\n\tthinkingOverrides?: (string | undefined)[];\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n}\n\nexport type RunnerStep = RunnerSubagentStep | ParallelStepGroup | DynamicRunnerGroup;\n\nexport function isParallelGroup(step: RunnerStep): step is ParallelStepGroup {\n\treturn \"parallel\" in step && Array.isArray(step.parallel);\n}\n\nexport function isDynamicRunnerGroup(step: RunnerStep): step is DynamicRunnerGroup {\n\treturn \"expand\" in step && \"collect\" in step && \"parallel\" in step && !Array.isArray((step as { parallel?: unknown }).parallel);\n}\n\nexport function flattenSteps(steps: RunnerStep[]): RunnerSubagentStep[] {\n\tconst flat: RunnerSubagentStep[] = [];\n\tfor (const step of steps) {\n\t\tif (isParallelGroup(step)) {\n\t\t\tfor (const task of step.parallel) flat.push(task);\n\t\t} else if (isDynamicRunnerGroup(step)) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tflat.push(step);\n\t\t}\n\t}\n\treturn flat;\n}\n\nexport const DEFAULT_GLOBAL_CONCURRENCY_LIMIT = Number.MAX_SAFE_INTEGER;\n\n// lunr: stagger parallel cold starts so the first child's response begins\n// (creating the Anthropic cache entry) before siblings fire identical\n// system prompts. Sequential mode (limit=1) is untouched.\nconst PARALLEL_COLD_START_STAGGER_MS = 1000;\n\n/**\n * A promise-based semaphore for limiting concurrent access across multiple\n * mapConcurrent calls within a single run. Enforces a global cap on the total\n * number of subagent tasks executing simultaneously, regardless of each step's\n * per-step concurrency limit.\n */\nexport class Semaphore {\n\tprivate available: number;\n\tprivate readonly queue: Array<() => void> = [];\n\n\tconstructor(limit: number) {\n\t\tthis.available = Math.max(1, Math.floor(limit) || 1);\n\t}\n\n\tacquire(): Promise<void> {\n\t\tif (this.available > 0) {\n\t\t\tthis.available--;\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.queue.push(resolve);\n\t\t});\n\t}\n\n\trelease(): void {\n\t\tconst next = this.queue.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t} else {\n\t\t\tthis.available++;\n\t\t}\n\t}\n}\n\nexport async function mapConcurrent<T, R>(\n\titems: T[],\n\tlimit: number,\n\tfn: (item: T, i: number) => Promise<R>,\n\tglobalSemaphore?: Semaphore,\n): Promise<R[]> {\n\tconst safeLimit = Math.max(1, Math.floor(limit) || 1);\n\tconst results: R[] = new Array(items.length);\n\tlet next = 0;\n\n\tasync function worker(_workerIndex: number): Promise<void> {\n\t\twhile (next < items.length) {\n\t\t\tconst i = next++;\n\t\t\tif (safeLimit > 1 && i > 0 && PARALLEL_COLD_START_STAGGER_MS > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, PARALLEL_COLD_START_STAGGER_MS * i);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (globalSemaphore) {\n\t\t\t\tawait globalSemaphore.acquire();\n\t\t\t\ttry {\n\t\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t\t} finally {\n\t\t\t\t\tglobalSemaphore.release();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t}\n\t\t}\n\t}\n\n\tawait Promise.all(\n\t\tArray.from({ length: Math.min(safeLimit, items.length) }, (_, wi) => worker(wi)),\n\t);\n\treturn results;\n}\n\nexport interface ParallelTaskResult {\n\tagent: string;\n\ttaskIndex?: number;\n\toutput: string;\n\texitCode: number | null;\n\terror?: string;\n\ttimedOut?: boolean;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\toutputTargetPath?: string;\n\toutputTargetExists?: boolean;\n}\n\nexport function aggregateParallelOutputs(\n\tresults: ParallelTaskResult[],\n\theaderFormat: (index: number, agent: string) => string = (i, agent) =>\n\t\t`=== Parallel Task ${i + 1} (${agent}) ===`,\n): string {\n\treturn results\n\t\t.map((r, i) => {\n\t\t\tconst header = headerFormat(r.taskIndex ?? i, r.agent);\n\t\t\tconst hasOutput = Boolean(r.output?.trim());\n\t\t\tconst status =\n\t\t\t\tr.timedOut\n\t\t\t\t\t? `TIMED OUT${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t: r.exitCode === -1\n\t\t\t\t\t? \"SKIPPED\"\n\t\t\t\t\t: r.exitCode !== 0 && r.exitCode !== null\n\t\t\t\t\t\t? `FAILED (exit code ${r.exitCode})${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t\t: r.error\n\t\t\t\t\t\t\t? `WARNING: ${r.error}`\n\t\t\t\t\t\t\t: !hasOutput && r.outputTargetPath && r.outputTargetExists === false\n\t\t\t\t\t\t\t\t? `EMPTY OUTPUT (expected output file missing: ${r.outputTargetPath})`\n\t\t\t\t\t\t\t\t: !hasOutput && !r.outputTargetPath\n\t\t\t\t\t\t\t\t\t? \"EMPTY OUTPUT (no textual response returned)\"\n\t\t\t\t\t\t\t: \"\";\n\t\t\tconst body = status ? (hasOutput ? `${status}\\n${r.output}` : status) : r.output;\n\t\t\treturn `${header}\\n${body}`;\n\t\t})\n\t\t.join(\"\\n\\n\");\n}\n\nexport const MAX_PARALLEL_CONCURRENCY = Number.MAX_SAFE_INTEGER;\n"]}
1
+ {"version":3,"file":"parallel-utils.d.ts","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nexport interface RunnerSubagentStep {\n\tcompletionTask?: string;\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\t/** Live parent permission mode snapshotted at spawn. */\n\tparentPermissionMode?: string;\n\tagent?: string;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: \"full\" | \"read-only\";\n\ttier?: import(\"../../shared/types.ts\").ChildTier;\n\ttask: string;\n\timportAsyncRoot?: {\n\t\trunId: string;\n\t\tasyncDir: string;\n\t\tresultPath: string;\n\t\tindex: number;\n\t};\n\tphase?: string;\n\tlabel?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tcwd?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tmodelCandidates?: string[];\n\ttools?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\tmcpDirectTools?: string[];\n\tcompletionGuard?: boolean;\n\tsystemPrompt?: string | null;\n\tsystemPromptMode?: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tskills?: string[];\n\toutputPath?: string;\n\t/** Defer the authoritative output instruction until a dynamic fanout item is materialized. */\n\tnamespaceOutputPath?: boolean;\n\toutputMode?: \"inline\" | \"file-only\";\n\tsessionFile?: string;\n\tmaxSubagentDepth?: number;\n\twaitToolEnabled?: boolean;\n\tstructuredOutput?: {\n\t\tschema: import(\"../../shared/types.ts\").JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tstructuredOutputSchema?: import(\"../../shared/types.ts\").JsonSchemaObject;\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n\ttoolBudget?: import(\"../../shared/types.ts\").ResolvedToolBudget;\n}\n\nexport interface ParallelStepGroup {\n\tparallel: RunnerSubagentStep[];\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tworktree?: boolean;\n}\n\nexport interface DynamicRunnerGroup {\n\texpand: import(\"../../shared/settings.ts\").DynamicExpandSpec;\n\tparallel: RunnerSubagentStep;\n\tcollect: import(\"../../shared/settings.ts\").DynamicCollectSpec;\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tphase?: string;\n\tlabel?: string;\n\tsessionFiles?: (string | undefined)[];\n\tthinkingOverrides?: (string | undefined)[];\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n}\n\nexport type RunnerStep = RunnerSubagentStep | ParallelStepGroup | DynamicRunnerGroup;\n\nexport function isParallelGroup(step: RunnerStep): step is ParallelStepGroup {\n\treturn \"parallel\" in step && Array.isArray(step.parallel);\n}\n\nexport function isDynamicRunnerGroup(step: RunnerStep): step is DynamicRunnerGroup {\n\treturn \"expand\" in step && \"collect\" in step && \"parallel\" in step && !Array.isArray((step as { parallel?: unknown }).parallel);\n}\n\nexport function flattenSteps(steps: RunnerStep[]): RunnerSubagentStep[] {\n\tconst flat: RunnerSubagentStep[] = [];\n\tfor (const step of steps) {\n\t\tif (isParallelGroup(step)) {\n\t\t\tfor (const task of step.parallel) flat.push(task);\n\t\t} else if (isDynamicRunnerGroup(step)) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tflat.push(step);\n\t\t}\n\t}\n\treturn flat;\n}\n\nexport const DEFAULT_GLOBAL_CONCURRENCY_LIMIT = Number.MAX_SAFE_INTEGER;\n\n// lunr: stagger parallel cold starts so the first child's response begins\n// (creating the Anthropic cache entry) before siblings fire identical\n// system prompts. Sequential mode (limit=1) is untouched.\nconst PARALLEL_COLD_START_STAGGER_MS = 1000;\n\n/**\n * A promise-based semaphore for limiting concurrent access across multiple\n * mapConcurrent calls within a single run. Enforces a global cap on the total\n * number of subagent tasks executing simultaneously, regardless of each step's\n * per-step concurrency limit.\n */\nexport class Semaphore {\n\tprivate available: number;\n\tprivate readonly queue: Array<() => void> = [];\n\n\tconstructor(limit: number) {\n\t\tthis.available = Math.max(1, Math.floor(limit) || 1);\n\t}\n\n\tacquire(): Promise<void> {\n\t\tif (this.available > 0) {\n\t\t\tthis.available--;\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.queue.push(resolve);\n\t\t});\n\t}\n\n\trelease(): void {\n\t\tconst next = this.queue.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t} else {\n\t\t\tthis.available++;\n\t\t}\n\t}\n}\n\nexport async function mapConcurrent<T, R>(\n\titems: T[],\n\tlimit: number,\n\tfn: (item: T, i: number) => Promise<R>,\n\tglobalSemaphore?: Semaphore,\n): Promise<R[]> {\n\tconst safeLimit = Math.max(1, Math.floor(limit) || 1);\n\tconst results: R[] = new Array(items.length);\n\tlet next = 0;\n\n\tasync function worker(_workerIndex: number): Promise<void> {\n\t\twhile (next < items.length) {\n\t\t\tconst i = next++;\n\t\t\tif (safeLimit > 1 && i > 0 && PARALLEL_COLD_START_STAGGER_MS > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, PARALLEL_COLD_START_STAGGER_MS * i);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (globalSemaphore) {\n\t\t\t\tawait globalSemaphore.acquire();\n\t\t\t\ttry {\n\t\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t\t} finally {\n\t\t\t\t\tglobalSemaphore.release();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t}\n\t\t}\n\t}\n\n\tawait Promise.all(\n\t\tArray.from({ length: Math.min(safeLimit, items.length) }, (_, wi) => worker(wi)),\n\t);\n\treturn results;\n}\n\nexport interface ParallelTaskResult {\n\tagent: string;\n\ttaskIndex?: number;\n\toutput: string;\n\texitCode: number | null;\n\terror?: string;\n\ttimedOut?: boolean;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\toutputTargetPath?: string;\n\toutputTargetExists?: boolean;\n}\n\nexport function aggregateParallelOutputs(\n\tresults: ParallelTaskResult[],\n\theaderFormat: (index: number, agent: string) => string = (i, agent) =>\n\t\t`=== Parallel Task ${i + 1} (${agent}) ===`,\n): string {\n\treturn results\n\t\t.map((r, i) => {\n\t\t\tconst header = headerFormat(r.taskIndex ?? i, r.agent);\n\t\t\tconst hasOutput = Boolean(r.output?.trim());\n\t\t\tconst status =\n\t\t\t\tr.timedOut\n\t\t\t\t\t? `TIMED OUT${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t: r.exitCode === -1\n\t\t\t\t\t? \"SKIPPED\"\n\t\t\t\t\t: r.exitCode !== 0 && r.exitCode !== null\n\t\t\t\t\t\t? `FAILED (exit code ${r.exitCode})${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t\t: r.error\n\t\t\t\t\t\t\t? `WARNING: ${r.error}`\n\t\t\t\t\t\t\t: !hasOutput && r.outputTargetPath && r.outputTargetExists === false\n\t\t\t\t\t\t\t\t? `EMPTY OUTPUT (expected output file missing: ${r.outputTargetPath})`\n\t\t\t\t\t\t\t\t: !hasOutput && !r.outputTargetPath\n\t\t\t\t\t\t\t\t\t? \"EMPTY OUTPUT (no textual response returned)\"\n\t\t\t\t\t\t\t: \"\";\n\t\t\tconst body = status ? (hasOutput ? `${status}\\n${r.output}` : status) : r.output;\n\t\t\treturn `${header}\\n${body}`;\n\t\t})\n\t\t.join(\"\\n\\n\");\n}\n\nexport const MAX_PARALLEL_CONCURRENCY = Number.MAX_SAFE_INTEGER;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parallel-utils.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nexport interface RunnerSubagentStep {\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\t/** Live parent permission mode snapshotted at spawn. */\n\tparentPermissionMode?: string;\n\tagent?: string;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: \"full\" | \"read-only\";\n\ttier?: import(\"../../shared/types.ts\").ChildTier;\n\ttask: string;\n\timportAsyncRoot?: {\n\t\trunId: string;\n\t\tasyncDir: string;\n\t\tresultPath: string;\n\t\tindex: number;\n\t};\n\tphase?: string;\n\tlabel?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tcwd?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tmodelCandidates?: string[];\n\ttools?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\tmcpDirectTools?: string[];\n\tcompletionGuard?: boolean;\n\tsystemPrompt?: string | null;\n\tsystemPromptMode?: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tskills?: string[];\n\toutputPath?: string;\n\t/** Defer the authoritative output instruction until a dynamic fanout item is materialized. */\n\tnamespaceOutputPath?: boolean;\n\toutputMode?: \"inline\" | \"file-only\";\n\tsessionFile?: string;\n\tmaxSubagentDepth?: number;\n\twaitToolEnabled?: boolean;\n\tstructuredOutput?: {\n\t\tschema: import(\"../../shared/types.ts\").JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tstructuredOutputSchema?: import(\"../../shared/types.ts\").JsonSchemaObject;\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n\ttoolBudget?: import(\"../../shared/types.ts\").ResolvedToolBudget;\n}\n\nexport interface ParallelStepGroup {\n\tparallel: RunnerSubagentStep[];\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tworktree?: boolean;\n}\n\nexport interface DynamicRunnerGroup {\n\texpand: import(\"../../shared/settings.ts\").DynamicExpandSpec;\n\tparallel: RunnerSubagentStep;\n\tcollect: import(\"../../shared/settings.ts\").DynamicCollectSpec;\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tphase?: string;\n\tlabel?: string;\n\tsessionFiles?: (string | undefined)[];\n\tthinkingOverrides?: (string | undefined)[];\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n}\n\nexport type RunnerStep = RunnerSubagentStep | ParallelStepGroup | DynamicRunnerGroup;\n\nexport function isParallelGroup(step: RunnerStep): step is ParallelStepGroup {\n\treturn \"parallel\" in step && Array.isArray(step.parallel);\n}\n\nexport function isDynamicRunnerGroup(step: RunnerStep): step is DynamicRunnerGroup {\n\treturn \"expand\" in step && \"collect\" in step && \"parallel\" in step && !Array.isArray((step as { parallel?: unknown }).parallel);\n}\n\nexport function flattenSteps(steps: RunnerStep[]): RunnerSubagentStep[] {\n\tconst flat: RunnerSubagentStep[] = [];\n\tfor (const step of steps) {\n\t\tif (isParallelGroup(step)) {\n\t\t\tfor (const task of step.parallel) flat.push(task);\n\t\t} else if (isDynamicRunnerGroup(step)) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tflat.push(step);\n\t\t}\n\t}\n\treturn flat;\n}\n\nexport const DEFAULT_GLOBAL_CONCURRENCY_LIMIT = Number.MAX_SAFE_INTEGER;\n\n// lunr: stagger parallel cold starts so the first child's response begins\n// (creating the Anthropic cache entry) before siblings fire identical\n// system prompts. Sequential mode (limit=1) is untouched.\nconst PARALLEL_COLD_START_STAGGER_MS = 1000;\n\n/**\n * A promise-based semaphore for limiting concurrent access across multiple\n * mapConcurrent calls within a single run. Enforces a global cap on the total\n * number of subagent tasks executing simultaneously, regardless of each step's\n * per-step concurrency limit.\n */\nexport class Semaphore {\n\tprivate available: number;\n\tprivate readonly queue: Array<() => void> = [];\n\n\tconstructor(limit: number) {\n\t\tthis.available = Math.max(1, Math.floor(limit) || 1);\n\t}\n\n\tacquire(): Promise<void> {\n\t\tif (this.available > 0) {\n\t\t\tthis.available--;\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.queue.push(resolve);\n\t\t});\n\t}\n\n\trelease(): void {\n\t\tconst next = this.queue.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t} else {\n\t\t\tthis.available++;\n\t\t}\n\t}\n}\n\nexport async function mapConcurrent<T, R>(\n\titems: T[],\n\tlimit: number,\n\tfn: (item: T, i: number) => Promise<R>,\n\tglobalSemaphore?: Semaphore,\n): Promise<R[]> {\n\tconst safeLimit = Math.max(1, Math.floor(limit) || 1);\n\tconst results: R[] = new Array(items.length);\n\tlet next = 0;\n\n\tasync function worker(_workerIndex: number): Promise<void> {\n\t\twhile (next < items.length) {\n\t\t\tconst i = next++;\n\t\t\tif (safeLimit > 1 && i > 0 && PARALLEL_COLD_START_STAGGER_MS > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, PARALLEL_COLD_START_STAGGER_MS * i);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (globalSemaphore) {\n\t\t\t\tawait globalSemaphore.acquire();\n\t\t\t\ttry {\n\t\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t\t} finally {\n\t\t\t\t\tglobalSemaphore.release();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t}\n\t\t}\n\t}\n\n\tawait Promise.all(\n\t\tArray.from({ length: Math.min(safeLimit, items.length) }, (_, wi) => worker(wi)),\n\t);\n\treturn results;\n}\n\nexport interface ParallelTaskResult {\n\tagent: string;\n\ttaskIndex?: number;\n\toutput: string;\n\texitCode: number | null;\n\terror?: string;\n\ttimedOut?: boolean;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\toutputTargetPath?: string;\n\toutputTargetExists?: boolean;\n}\n\nexport function aggregateParallelOutputs(\n\tresults: ParallelTaskResult[],\n\theaderFormat: (index: number, agent: string) => string = (i, agent) =>\n\t\t`=== Parallel Task ${i + 1} (${agent}) ===`,\n): string {\n\treturn results\n\t\t.map((r, i) => {\n\t\t\tconst header = headerFormat(r.taskIndex ?? i, r.agent);\n\t\t\tconst hasOutput = Boolean(r.output?.trim());\n\t\t\tconst status =\n\t\t\t\tr.timedOut\n\t\t\t\t\t? `TIMED OUT${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t: r.exitCode === -1\n\t\t\t\t\t? \"SKIPPED\"\n\t\t\t\t\t: r.exitCode !== 0 && r.exitCode !== null\n\t\t\t\t\t\t? `FAILED (exit code ${r.exitCode})${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t\t: r.error\n\t\t\t\t\t\t\t? `WARNING: ${r.error}`\n\t\t\t\t\t\t\t: !hasOutput && r.outputTargetPath && r.outputTargetExists === false\n\t\t\t\t\t\t\t\t? `EMPTY OUTPUT (expected output file missing: ${r.outputTargetPath})`\n\t\t\t\t\t\t\t\t: !hasOutput && !r.outputTargetPath\n\t\t\t\t\t\t\t\t\t? \"EMPTY OUTPUT (no textual response returned)\"\n\t\t\t\t\t\t\t: \"\";\n\t\t\tconst body = status ? (hasOutput ? `${status}\\n${r.output}` : status) : r.output;\n\t\t\treturn `${header}\\n${body}`;\n\t\t})\n\t\t.join(\"\\n\\n\");\n}\n\nexport const MAX_PARALLEL_CONCURRENCY = Number.MAX_SAFE_INTEGER;\n"]}
1
+ {"version":3,"file":"parallel-utils.js","sourceRoot":"","sources":["../../../../../../src/builtin-extensions/pi-subagents/src/runs/shared/parallel-utils.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-nocheck\nexport interface RunnerSubagentStep {\n\tcompletionTask?: string;\n\t/** Session id of the direct parent session for permission-system ask forwarding. */\n\tparentSessionId?: string;\n\t/** Live parent permission mode snapshotted at spawn. */\n\tparentPermissionMode?: string;\n\tagent?: string;\n\tchildId?: string;\n\tdescription?: string;\n\tpermissions?: \"full\" | \"read-only\";\n\ttier?: import(\"../../shared/types.ts\").ChildTier;\n\ttask: string;\n\timportAsyncRoot?: {\n\t\trunId: string;\n\t\tasyncDir: string;\n\t\tresultPath: string;\n\t\tindex: number;\n\t};\n\tphase?: string;\n\tlabel?: string;\n\toutputName?: string;\n\tstructured?: boolean;\n\tcwd?: string;\n\tmodel?: string;\n\tthinking?: string;\n\tmodelSelection?: import(\"../../shared/types.ts\").ModelSelection;\n\tmodelCandidates?: string[];\n\ttools?: string[];\n\textensions?: string[];\n\tsubagentOnlyExtensions?: string[];\n\tmcpDirectTools?: string[];\n\tcompletionGuard?: boolean;\n\tsystemPrompt?: string | null;\n\tsystemPromptMode?: \"append\" | \"replace\";\n\tinheritProjectContext: boolean;\n\tinheritSkills: boolean;\n\tskills?: string[];\n\toutputPath?: string;\n\t/** Defer the authoritative output instruction until a dynamic fanout item is materialized. */\n\tnamespaceOutputPath?: boolean;\n\toutputMode?: \"inline\" | \"file-only\";\n\tsessionFile?: string;\n\tmaxSubagentDepth?: number;\n\twaitToolEnabled?: boolean;\n\tstructuredOutput?: {\n\t\tschema: import(\"../../shared/types.ts\").JsonSchemaObject;\n\t\tschemaPath: string;\n\t\toutputPath: string;\n\t};\n\tstructuredOutputSchema?: import(\"../../shared/types.ts\").JsonSchemaObject;\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n\ttoolBudget?: import(\"../../shared/types.ts\").ResolvedToolBudget;\n}\n\nexport interface ParallelStepGroup {\n\tparallel: RunnerSubagentStep[];\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tworktree?: boolean;\n}\n\nexport interface DynamicRunnerGroup {\n\texpand: import(\"../../shared/settings.ts\").DynamicExpandSpec;\n\tparallel: RunnerSubagentStep;\n\tcollect: import(\"../../shared/settings.ts\").DynamicCollectSpec;\n\tconcurrency?: number;\n\tfailFast?: boolean;\n\tphase?: string;\n\tlabel?: string;\n\tsessionFiles?: (string | undefined)[];\n\tthinkingOverrides?: (string | undefined)[];\n\teffectiveAcceptance?: import(\"../../shared/types.ts\").ResolvedAcceptanceConfig;\n\tacceptanceInput?: import(\"../../shared/types.ts\").AcceptanceInput;\n\tacceptanceRole?: import(\"../../shared/types.ts\").AcceptanceRole;\n}\n\nexport type RunnerStep = RunnerSubagentStep | ParallelStepGroup | DynamicRunnerGroup;\n\nexport function isParallelGroup(step: RunnerStep): step is ParallelStepGroup {\n\treturn \"parallel\" in step && Array.isArray(step.parallel);\n}\n\nexport function isDynamicRunnerGroup(step: RunnerStep): step is DynamicRunnerGroup {\n\treturn \"expand\" in step && \"collect\" in step && \"parallel\" in step && !Array.isArray((step as { parallel?: unknown }).parallel);\n}\n\nexport function flattenSteps(steps: RunnerStep[]): RunnerSubagentStep[] {\n\tconst flat: RunnerSubagentStep[] = [];\n\tfor (const step of steps) {\n\t\tif (isParallelGroup(step)) {\n\t\t\tfor (const task of step.parallel) flat.push(task);\n\t\t} else if (isDynamicRunnerGroup(step)) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\tflat.push(step);\n\t\t}\n\t}\n\treturn flat;\n}\n\nexport const DEFAULT_GLOBAL_CONCURRENCY_LIMIT = Number.MAX_SAFE_INTEGER;\n\n// lunr: stagger parallel cold starts so the first child's response begins\n// (creating the Anthropic cache entry) before siblings fire identical\n// system prompts. Sequential mode (limit=1) is untouched.\nconst PARALLEL_COLD_START_STAGGER_MS = 1000;\n\n/**\n * A promise-based semaphore for limiting concurrent access across multiple\n * mapConcurrent calls within a single run. Enforces a global cap on the total\n * number of subagent tasks executing simultaneously, regardless of each step's\n * per-step concurrency limit.\n */\nexport class Semaphore {\n\tprivate available: number;\n\tprivate readonly queue: Array<() => void> = [];\n\n\tconstructor(limit: number) {\n\t\tthis.available = Math.max(1, Math.floor(limit) || 1);\n\t}\n\n\tacquire(): Promise<void> {\n\t\tif (this.available > 0) {\n\t\t\tthis.available--;\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.queue.push(resolve);\n\t\t});\n\t}\n\n\trelease(): void {\n\t\tconst next = this.queue.shift();\n\t\tif (next) {\n\t\t\tnext();\n\t\t} else {\n\t\t\tthis.available++;\n\t\t}\n\t}\n}\n\nexport async function mapConcurrent<T, R>(\n\titems: T[],\n\tlimit: number,\n\tfn: (item: T, i: number) => Promise<R>,\n\tglobalSemaphore?: Semaphore,\n): Promise<R[]> {\n\tconst safeLimit = Math.max(1, Math.floor(limit) || 1);\n\tconst results: R[] = new Array(items.length);\n\tlet next = 0;\n\n\tasync function worker(_workerIndex: number): Promise<void> {\n\t\twhile (next < items.length) {\n\t\t\tconst i = next++;\n\t\t\tif (safeLimit > 1 && i > 0 && PARALLEL_COLD_START_STAGGER_MS > 0) {\n\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\tsetTimeout(resolve, PARALLEL_COLD_START_STAGGER_MS * i);\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (globalSemaphore) {\n\t\t\t\tawait globalSemaphore.acquire();\n\t\t\t\ttry {\n\t\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t\t} finally {\n\t\t\t\t\tglobalSemaphore.release();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresults[i] = await fn(items[i], i);\n\t\t\t}\n\t\t}\n\t}\n\n\tawait Promise.all(\n\t\tArray.from({ length: Math.min(safeLimit, items.length) }, (_, wi) => worker(wi)),\n\t);\n\treturn results;\n}\n\nexport interface ParallelTaskResult {\n\tagent: string;\n\ttaskIndex?: number;\n\toutput: string;\n\texitCode: number | null;\n\terror?: string;\n\ttimedOut?: boolean;\n\tmodel?: string;\n\tattemptedModels?: string[];\n\toutputTargetPath?: string;\n\toutputTargetExists?: boolean;\n}\n\nexport function aggregateParallelOutputs(\n\tresults: ParallelTaskResult[],\n\theaderFormat: (index: number, agent: string) => string = (i, agent) =>\n\t\t`=== Parallel Task ${i + 1} (${agent}) ===`,\n): string {\n\treturn results\n\t\t.map((r, i) => {\n\t\t\tconst header = headerFormat(r.taskIndex ?? i, r.agent);\n\t\t\tconst hasOutput = Boolean(r.output?.trim());\n\t\t\tconst status =\n\t\t\t\tr.timedOut\n\t\t\t\t\t? `TIMED OUT${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t: r.exitCode === -1\n\t\t\t\t\t? \"SKIPPED\"\n\t\t\t\t\t: r.exitCode !== 0 && r.exitCode !== null\n\t\t\t\t\t\t? `FAILED (exit code ${r.exitCode})${r.error ? `: ${r.error}` : \"\"}`\n\t\t\t\t\t\t: r.error\n\t\t\t\t\t\t\t? `WARNING: ${r.error}`\n\t\t\t\t\t\t\t: !hasOutput && r.outputTargetPath && r.outputTargetExists === false\n\t\t\t\t\t\t\t\t? `EMPTY OUTPUT (expected output file missing: ${r.outputTargetPath})`\n\t\t\t\t\t\t\t\t: !hasOutput && !r.outputTargetPath\n\t\t\t\t\t\t\t\t\t? \"EMPTY OUTPUT (no textual response returned)\"\n\t\t\t\t\t\t\t: \"\";\n\t\t\tconst body = status ? (hasOutput ? `${status}\\n${r.output}` : status) : r.output;\n\t\t\treturn `${header}\\n${body}`;\n\t\t})\n\t\t.join(\"\\n\\n\");\n}\n\nexport const MAX_PARALLEL_CONCURRENCY = Number.MAX_SAFE_INTEGER;\n"]}
@@ -4,6 +4,7 @@ import { type ChildWatchdogConfig } from "../../watchdog/child-status.ts";
4
4
  export declare const SUBAGENT_CHILD_ENV = "PI_SUBAGENT_CHILD";
5
5
  export declare const SUBAGENT_ORCHESTRATOR_TARGET_ENV = "PI_SUBAGENT_ORCHESTRATOR_TARGET";
6
6
  export declare const SUBAGENT_ORCHESTRATOR_SESSION_ID_ENV = "PI_SUBAGENT_ORCHESTRATOR_SESSION_ID";
7
+ export declare const SUBAGENT_SUPERVISOR_SESSION_ID_ENV = "PI_SUBAGENT_SUPERVISOR_SESSION_ID";
7
8
  export declare const SUBAGENT_SUPERVISOR_CHANNEL_DIR_ENV = "PI_SUBAGENT_SUPERVISOR_CHANNEL_DIR";
8
9
  export declare const SUBAGENT_RUN_ID_ENV = "PI_SUBAGENT_RUN_ID";
9
10
  export declare const SUBAGENT_CHILD_AGENT_ENV = "PI_SUBAGENT_CHILD_AGENT";
@@ -25,6 +26,8 @@ export declare const SUBAGENT_STEER_CAPABILITY_ENV = "PI_SUBAGENT_STEER_CAPABILI
25
26
  export declare const SUBAGENT_STEER_ACK_DIR_ENV = "PI_SUBAGENT_STEER_ACK_DIR";
26
27
  interface BuildPiArgsInput {
27
28
  parentSessionId?: string;
29
+ /** Run ownership is a session file or in-memory UUID; parentSessionId remains the routing UUID. */
30
+ supervisorSessionId?: string;
28
31
  baseArgs: string[];
29
32
  task: string;
30
33
  sessionEnabled: boolean;