@ai-agent-forge/agent-forge 0.88.1 → 0.88.3

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 (518) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/README.md +1 -1
  3. package/bundled-plugins/agent-loop-policy/agent-forge.json +1 -1
  4. package/bundled-plugins/agent-loop-policy/plugin.json +1 -1
  5. package/bundled-plugins/coding-tools/agent-forge.json +1 -1
  6. package/bundled-plugins/coding-tools/plugin.json +1 -1
  7. package/bundled-plugins/compaction-policy/agent-forge.json +1 -1
  8. package/bundled-plugins/compaction-policy/plugin.json +1 -1
  9. package/bundled-plugins/overflow-policy/agent-forge.json +1 -1
  10. package/bundled-plugins/overflow-policy/plugin.json +1 -1
  11. package/bundled-plugins/provider-failover/agent-forge.json +1 -1
  12. package/bundled-plugins/provider-failover/plugin.json +1 -1
  13. package/bundled-plugins/retry-policy/agent-forge.json +1 -1
  14. package/bundled-plugins/retry-policy/plugin.json +1 -1
  15. package/dist/artifacts/paged-read.d.ts +6 -1
  16. package/dist/artifacts/paged-read.d.ts.map +1 -1
  17. package/dist/artifacts/paged-read.js.map +1 -1
  18. package/dist/bundle/.build-manifest.json +283 -263
  19. package/dist/bundle/chunks/{anthropic-messages-PLAKXR73.js → anthropic-messages-3FJHRAJL.js} +2 -2
  20. package/dist/bundle/chunks/anthropic.js +1 -1
  21. package/dist/bundle/chunks/{azure-openai-responses-OUWQ2AZD.js → azure-openai-responses-GCL47IDS.js} +1 -1
  22. package/dist/bundle/chunks/bedrock-converse-stream.js +1 -1
  23. package/dist/bundle/chunks/{chunk-Z72JWUZ4.js → chunk-32YDZI4J.js} +1 -1
  24. package/dist/bundle/chunks/{chunk-AQLNTW2B.js → chunk-755VNWIF.js} +17 -16
  25. package/dist/bundle/chunks/{chunk-LZOEQITZ.js → chunk-B42Y2VME.js} +120 -104
  26. package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-BVVSHK6W.js} +1 -1
  27. package/dist/bundle/chunks/{chunk-6R7UI4IY.js → chunk-QDLOMKF6.js} +1 -1
  28. package/dist/bundle/chunks/{chunk-D3ARGZFR.js → chunk-V3ACW7VD.js} +3 -3
  29. package/dist/bundle/chunks/{google-generative-ai-DLII6DAT.js → google-generative-ai-6BMXWA44.js} +1 -1
  30. package/dist/bundle/chunks/{google-vertex-G7BZL7GM.js → google-vertex-6H7NLRTK.js} +1 -1
  31. package/dist/bundle/chunks/image-resize-worker.js +3 -3
  32. package/dist/bundle/chunks/{mistral-conversations-JXUK24ID.js → mistral-conversations-IXUHSFSJ.js} +1 -1
  33. package/dist/bundle/chunks/{openai-codex-responses-5GSGFIPG.js → openai-codex-responses-YHUAEVCM.js} +1 -1
  34. package/dist/bundle/chunks/openai-codex.js +1 -1
  35. package/dist/bundle/chunks/{openai-completions-EI2I6DTG.js → openai-completions-ULQCFC72.js} +1 -1
  36. package/dist/bundle/chunks/openai-responses-NLLAJDPS.js +2 -0
  37. package/dist/bundle/chunks/{openrouter-images-G4GQRUSG.js → openrouter-images-GZZQZXMS.js} +1 -1
  38. package/dist/bundle/chunks/openrouter.js +1 -1
  39. package/dist/bundle/chunks/{pi-messages-PWU2VJMR.js → pi-messages-EJTI2EJ3.js} +1 -1
  40. package/dist/bundle/chunks/virtual-modules-TQWEGNNZ.js +5 -0
  41. package/dist/bundle/cli.js +1 -1
  42. package/dist/bundle/client.js +1 -1
  43. package/dist/bundle/index.js +1 -1
  44. package/dist/bundle/rpc-entry.js +1 -1
  45. package/dist/cli/args.d.ts +0 -1
  46. package/dist/cli/args.d.ts.map +1 -1
  47. package/dist/cli/args.js +1 -4
  48. package/dist/cli/args.js.map +1 -1
  49. package/dist/cli/config-selector.d.ts.map +1 -1
  50. package/dist/cli/config-selector.js +1 -1
  51. package/dist/cli/config-selector.js.map +1 -1
  52. package/dist/cli/experimental/cli.d.ts +3 -3
  53. package/dist/cli/experimental/cli.d.ts.map +1 -1
  54. package/dist/cli/experimental/cli.js +2 -2
  55. package/dist/cli/experimental/cli.js.map +1 -1
  56. package/dist/cli/experimental/commands/agent-forge.d.ts +15 -0
  57. package/dist/cli/experimental/commands/agent-forge.d.ts.map +1 -0
  58. package/dist/cli/experimental/commands/{pi.js → agent-forge.js} +4 -4
  59. package/dist/cli/experimental/commands/agent-forge.js.map +1 -0
  60. package/dist/cli/plugin-command.d.ts.map +1 -1
  61. package/dist/cli/plugin-command.js +8 -2
  62. package/dist/cli/plugin-command.js.map +1 -1
  63. package/dist/cli/startup-ui.d.ts.map +1 -1
  64. package/dist/cli/startup-ui.js +1 -1
  65. package/dist/cli/startup-ui.js.map +1 -1
  66. package/dist/config.d.ts +4 -4
  67. package/dist/config.d.ts.map +1 -1
  68. package/dist/config.js +7 -7
  69. package/dist/config.js.map +1 -1
  70. package/dist/core/agent-forge-manifest.d.ts +7 -0
  71. package/dist/core/agent-forge-manifest.d.ts.map +1 -0
  72. package/dist/core/{pi-manifest.js → agent-forge-manifest.js} +4 -4
  73. package/dist/core/agent-forge-manifest.js.map +1 -0
  74. package/dist/core/agent-session-compaction.d.ts +1 -1
  75. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  76. package/dist/core/agent-session-compaction.js +3 -3
  77. package/dist/core/agent-session-compaction.js.map +1 -1
  78. package/dist/core/agent-session-internal.d.ts +2 -0
  79. package/dist/core/agent-session-internal.d.ts.map +1 -1
  80. package/dist/core/agent-session-internal.js.map +1 -1
  81. package/dist/core/agent-session-lifecycle.d.ts.map +1 -1
  82. package/dist/core/agent-session-lifecycle.js +12 -1
  83. package/dist/core/agent-session-lifecycle.js.map +1 -1
  84. package/dist/core/agent-session-projection.d.ts.map +1 -1
  85. package/dist/core/agent-session-projection.js +3 -3
  86. package/dist/core/agent-session-projection.js.map +1 -1
  87. package/dist/core/agent-session-services.d.ts +3 -1
  88. package/dist/core/agent-session-services.d.ts.map +1 -1
  89. package/dist/core/agent-session-services.js +2 -1
  90. package/dist/core/agent-session-services.js.map +1 -1
  91. package/dist/core/agent-session-store.d.ts.map +1 -1
  92. package/dist/core/agent-session-store.js +6 -1
  93. package/dist/core/agent-session-store.js.map +1 -1
  94. package/dist/core/agent-session-tools.d.ts.map +1 -1
  95. package/dist/core/agent-session-tools.js +13 -0
  96. package/dist/core/agent-session-tools.js.map +1 -1
  97. package/dist/core/agent-session.d.ts +24 -0
  98. package/dist/core/agent-session.d.ts.map +1 -1
  99. package/dist/core/agent-session.js +58 -4
  100. package/dist/core/agent-session.js.map +1 -1
  101. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  102. package/dist/core/compaction/branch-summarization.js +1 -1
  103. package/dist/core/compaction/branch-summarization.js.map +1 -1
  104. package/dist/core/experimental.d.ts.map +1 -1
  105. package/dist/core/experimental.js +1 -3
  106. package/dist/core/experimental.js.map +1 -1
  107. package/dist/core/extensions/capability-runtime-store.d.ts +20 -1
  108. package/dist/core/extensions/capability-runtime-store.d.ts.map +1 -1
  109. package/dist/core/extensions/capability-runtime-store.js +67 -0
  110. package/dist/core/extensions/capability-runtime-store.js.map +1 -1
  111. package/dist/core/extensions/capability-runtime-types.d.ts +14 -0
  112. package/dist/core/extensions/capability-runtime-types.d.ts.map +1 -1
  113. package/dist/core/extensions/capability-runtime-types.js +7 -1
  114. package/dist/core/extensions/capability-runtime-types.js.map +1 -1
  115. package/dist/core/extensions/capability-runtime.d.ts.map +1 -1
  116. package/dist/core/extensions/capability-runtime.js +144 -42
  117. package/dist/core/extensions/capability-runtime.js.map +1 -1
  118. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  119. package/dist/core/extensions/virtual-modules.js +6 -1
  120. package/dist/core/extensions/virtual-modules.js.map +1 -1
  121. package/dist/core/facade/coding-agent-facade.d.ts +1 -1
  122. package/dist/core/facade/coding-agent-facade.d.ts.map +1 -1
  123. package/dist/core/facade/coding-agent-facade.js +1 -1
  124. package/dist/core/facade/coding-agent-facade.js.map +1 -1
  125. package/dist/core/i18n/locales/zh-cn/cli.d.ts.map +1 -1
  126. package/dist/core/i18n/locales/zh-cn/cli.js +2 -0
  127. package/dist/core/i18n/locales/zh-cn/cli.js.map +1 -1
  128. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts +1 -1
  129. package/dist/core/i18n/locales/zh-cn/core-contract-final.d.ts.map +1 -1
  130. package/dist/core/i18n/locales/zh-cn/core-contract-final.js +3 -3
  131. package/dist/core/i18n/locales/zh-cn/core-contract-final.js.map +1 -1
  132. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.d.ts.map +1 -1
  133. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js +1 -1
  134. package/dist/core/i18n/locales/zh-cn/core-contract-plugins.js.map +1 -1
  135. package/dist/core/i18n/locales/zh-cn/core-errors.d.ts.map +1 -1
  136. package/dist/core/i18n/locales/zh-cn/core-errors.js +1 -1
  137. package/dist/core/i18n/locales/zh-cn/core-errors.js.map +1 -1
  138. package/dist/core/i18n/locales/zh-cn/index.d.ts.map +1 -1
  139. package/dist/core/i18n/locales/zh-cn/index.js +2 -0
  140. package/dist/core/i18n/locales/zh-cn/index.js.map +1 -1
  141. package/dist/core/i18n/locales/zh-cn/interactive-mode.d.ts.map +1 -1
  142. package/dist/core/i18n/locales/zh-cn/interactive-mode.js +5 -0
  143. package/dist/core/i18n/locales/zh-cn/interactive-mode.js.map +1 -1
  144. package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts +7 -0
  145. package/dist/core/i18n/locales/zh-cn/session-cleanup.d.ts.map +1 -0
  146. package/dist/core/i18n/locales/zh-cn/session-cleanup.js +15 -0
  147. package/dist/core/i18n/locales/zh-cn/session-cleanup.js.map +1 -0
  148. package/dist/core/i18n/locales/zh-cn/slash-commands.d.ts.map +1 -1
  149. package/dist/core/i18n/locales/zh-cn/slash-commands.js +1 -0
  150. package/dist/core/i18n/locales/zh-cn/slash-commands.js.map +1 -1
  151. package/dist/core/i18n/locales/zh-cn/tui-components-misc.d.ts.map +1 -1
  152. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js +2 -0
  153. package/dist/core/i18n/locales/zh-cn/tui-components-misc.js.map +1 -1
  154. package/dist/core/model-resolver.d.ts +2 -0
  155. package/dist/core/model-resolver.d.ts.map +1 -1
  156. package/dist/core/model-resolver.js +4 -1
  157. package/dist/core/model-resolver.js.map +1 -1
  158. package/dist/core/package-resource-collection.d.ts.map +1 -1
  159. package/dist/core/package-resource-collection.js +5 -5
  160. package/dist/core/package-resource-collection.js.map +1 -1
  161. package/dist/core/provider-composer.d.ts.map +1 -1
  162. package/dist/core/provider-composer.js +3 -3
  163. package/dist/core/provider-composer.js.map +1 -1
  164. package/dist/core/resource-loader.d.ts.map +1 -1
  165. package/dist/core/resource-loader.js +1 -1
  166. package/dist/core/resource-loader.js.map +1 -1
  167. package/dist/core/sdk.d.ts +1 -1
  168. package/dist/core/sdk.d.ts.map +1 -1
  169. package/dist/core/sdk.js +30 -8
  170. package/dist/core/sdk.js.map +1 -1
  171. package/dist/core/session-cleanup.d.ts +49 -0
  172. package/dist/core/session-cleanup.d.ts.map +1 -0
  173. package/dist/core/session-cleanup.js +159 -0
  174. package/dist/core/session-cleanup.js.map +1 -0
  175. package/dist/core/session-index.d.ts +75 -0
  176. package/dist/core/session-index.d.ts.map +1 -0
  177. package/dist/core/session-index.js +455 -0
  178. package/dist/core/session-index.js.map +1 -0
  179. package/dist/core/session-manager.d.ts +9 -0
  180. package/dist/core/session-manager.d.ts.map +1 -1
  181. package/dist/core/session-manager.js +206 -51
  182. package/dist/core/session-manager.js.map +1 -1
  183. package/dist/core/settings-manager.d.ts.map +1 -1
  184. package/dist/core/settings-manager.js +5 -10
  185. package/dist/core/settings-manager.js.map +1 -1
  186. package/dist/core/slash-commands.d.ts.map +1 -1
  187. package/dist/core/slash-commands.js +5 -0
  188. package/dist/core/slash-commands.js.map +1 -1
  189. package/dist/core/system-prompt.d.ts.map +1 -1
  190. package/dist/core/system-prompt.js +12 -1
  191. package/dist/core/system-prompt.js.map +1 -1
  192. package/dist/core/timings.d.ts.map +1 -1
  193. package/dist/core/timings.js +1 -3
  194. package/dist/core/timings.js.map +1 -1
  195. package/dist/core/tools/capability-mount.d.ts +40 -0
  196. package/dist/core/tools/capability-mount.d.ts.map +1 -0
  197. package/dist/core/tools/capability-mount.js +112 -0
  198. package/dist/core/tools/capability-mount.js.map +1 -0
  199. package/dist/core/tools/render-utils.d.ts +1 -1
  200. package/dist/core/tools/render-utils.d.ts.map +1 -1
  201. package/dist/core/tools/render-utils.js.map +1 -1
  202. package/dist/core/tools/tool-definition.d.ts +1 -1
  203. package/dist/core/tools/tool-definition.d.ts.map +1 -1
  204. package/dist/core/tools/tool-definition.js.map +1 -1
  205. package/dist/core/trace-retention.d.ts +16 -1
  206. package/dist/core/trace-retention.d.ts.map +1 -1
  207. package/dist/core/trace-retention.js +43 -20
  208. package/dist/core/trace-retention.js.map +1 -1
  209. package/dist/export-html/ansi-to-html.d.ts.map +1 -0
  210. package/dist/export-html/ansi-to-html.js.map +1 -0
  211. package/dist/{core/export-html → export-html}/index.d.ts +1 -1
  212. package/dist/export-html/index.d.ts.map +1 -0
  213. package/dist/{core/export-html → export-html}/index.js +5 -5
  214. package/dist/export-html/index.js.map +1 -0
  215. package/dist/{core/export-html → export-html}/tool-renderer.d.ts +2 -2
  216. package/dist/export-html/tool-renderer.d.ts.map +1 -0
  217. package/dist/export-html/tool-renderer.js.map +1 -0
  218. package/dist/{modes/interactive → host}/model-catalog-refresh.d.ts +1 -1
  219. package/dist/host/model-catalog-refresh.d.ts.map +1 -0
  220. package/dist/{modes/interactive → host}/model-catalog-refresh.js +1 -1
  221. package/dist/host/model-catalog-refresh.js.map +1 -0
  222. package/dist/index.d.ts +5 -5
  223. package/dist/index.d.ts.map +1 -1
  224. package/dist/index.js +12 -12
  225. package/dist/index.js.map +1 -1
  226. package/dist/main.d.ts.map +1 -1
  227. package/dist/main.js +26 -14
  228. package/dist/main.js.map +1 -1
  229. package/dist/modes/interactive/components/agents-view.d.ts.map +1 -1
  230. package/dist/modes/interactive/components/agents-view.js +1 -1
  231. package/dist/modes/interactive/components/agents-view.js.map +1 -1
  232. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  233. package/dist/modes/interactive/components/armin.js +1 -1
  234. package/dist/modes/interactive/components/armin.js.map +1 -1
  235. package/dist/modes/interactive/components/assistant-message.d.ts +6 -0
  236. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  237. package/dist/modes/interactive/components/assistant-message.js +108 -27
  238. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  239. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/bash-execution.js +1 -1
  241. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  242. package/dist/modes/interactive/components/bordered-loader.d.ts +1 -1
  243. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  244. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  245. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  246. package/dist/modes/interactive/components/branch-summary-message.js +1 -1
  247. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  248. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  249. package/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  250. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  251. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/config-selector.js +1 -1
  253. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  254. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/custom-entry.js +1 -1
  256. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  257. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  258. package/dist/modes/interactive/components/custom-message.js +1 -1
  259. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  260. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  261. package/dist/modes/interactive/components/daxnuts.js +1 -1
  262. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  263. package/dist/modes/interactive/components/dialog-editor.d.ts.map +1 -1
  264. package/dist/modes/interactive/components/dialog-editor.js +1 -1
  265. package/dist/modes/interactive/components/dialog-editor.js.map +1 -1
  266. package/dist/modes/interactive/components/dialog-input.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/dialog-input.js +1 -1
  268. package/dist/modes/interactive/components/dialog-input.js.map +1 -1
  269. package/dist/modes/interactive/components/dialog-selector.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/dialog-selector.js +1 -1
  271. package/dist/modes/interactive/components/dialog-selector.js.map +1 -1
  272. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/diff.js +1 -1
  274. package/dist/modes/interactive/components/diff.js.map +1 -1
  275. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/dynamic-border.js +1 -1
  277. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  278. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -1
  279. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/first-time-setup.js +1 -1
  281. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  282. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  283. package/dist/modes/interactive/components/footer.js +1 -1
  284. package/dist/modes/interactive/components/footer.js.map +1 -1
  285. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  286. package/dist/modes/interactive/components/keybinding-hints.js +1 -1
  287. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  288. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  289. package/dist/modes/interactive/components/login-dialog.js +1 -1
  290. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  291. package/dist/modes/interactive/components/mermaid.d.ts +1 -1
  292. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  293. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  294. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  295. package/dist/modes/interactive/components/model-selector.js +2 -2
  296. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  297. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  298. package/dist/modes/interactive/components/oauth-selector.js +1 -1
  299. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  300. package/dist/modes/interactive/components/plugin-manager-entry.d.ts.map +1 -1
  301. package/dist/modes/interactive/components/plugin-manager-entry.js +1 -1
  302. package/dist/modes/interactive/components/plugin-manager-entry.js.map +1 -1
  303. package/dist/modes/interactive/components/plugin-selection-entry.d.ts.map +1 -1
  304. package/dist/modes/interactive/components/plugin-selection-entry.js +1 -1
  305. package/dist/modes/interactive/components/plugin-selection-entry.js.map +1 -1
  306. package/dist/modes/interactive/components/queue-manager-selector.d.ts.map +1 -1
  307. package/dist/modes/interactive/components/queue-manager-selector.js +1 -1
  308. package/dist/modes/interactive/components/queue-manager-selector.js.map +1 -1
  309. package/dist/modes/interactive/components/render-types.d.ts +1 -1
  310. package/dist/modes/interactive/components/render-types.d.ts.map +1 -1
  311. package/dist/modes/interactive/components/render-types.js.map +1 -1
  312. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  313. package/dist/modes/interactive/components/scoped-models-selector.js +1 -1
  314. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  315. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  316. package/dist/modes/interactive/components/session-selector-search.js +5 -1
  317. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  318. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  319. package/dist/modes/interactive/components/session-selector.js +11 -2
  320. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  321. package/dist/modes/interactive/components/settings-selector.d.ts +1 -1
  322. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  323. package/dist/modes/interactive/components/settings-selector.js +1 -1
  324. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  325. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  326. package/dist/modes/interactive/components/settings-submenu.js +1 -1
  327. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  328. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  329. package/dist/modes/interactive/components/show-images-selector.js +1 -1
  330. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  331. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  332. package/dist/modes/interactive/components/skill-invocation-message.js +1 -1
  333. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  334. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  335. package/dist/modes/interactive/components/status-indicator.js +1 -1
  336. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  337. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  338. package/dist/modes/interactive/components/theme-selector.js +1 -1
  339. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  340. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  341. package/dist/modes/interactive/components/thinking-selector.js +1 -1
  342. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  343. package/dist/modes/interactive/components/tool-execution.d.ts +19 -0
  344. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  345. package/dist/modes/interactive/components/tool-execution.js +139 -4
  346. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  347. package/dist/modes/interactive/components/tool-run-group.d.ts +44 -0
  348. package/dist/modes/interactive/components/tool-run-group.d.ts.map +1 -0
  349. package/dist/modes/interactive/components/tool-run-group.js +121 -0
  350. package/dist/modes/interactive/components/tool-run-group.js.map +1 -0
  351. package/dist/modes/interactive/components/tree-list.d.ts.map +1 -1
  352. package/dist/modes/interactive/components/tree-list.js +1 -1
  353. package/dist/modes/interactive/components/tree-list.js.map +1 -1
  354. package/dist/modes/interactive/components/tree-render.d.ts.map +1 -1
  355. package/dist/modes/interactive/components/tree-render.js +1 -1
  356. package/dist/modes/interactive/components/tree-render.js.map +1 -1
  357. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  358. package/dist/modes/interactive/components/tree-selector.js +1 -1
  359. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  360. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  361. package/dist/modes/interactive/components/user-message-selector.js +1 -1
  362. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/user-message.js +1 -1
  365. package/dist/modes/interactive/components/user-message.js.map +1 -1
  366. package/dist/modes/interactive/components/workflow-view.d.ts.map +1 -1
  367. package/dist/modes/interactive/components/workflow-view.js +1 -1
  368. package/dist/modes/interactive/components/workflow-view.js.map +1 -1
  369. package/dist/modes/interactive/interactive-auth.d.ts +1 -1
  370. package/dist/modes/interactive/interactive-auth.d.ts.map +1 -1
  371. package/dist/modes/interactive/interactive-auth.js +1 -1
  372. package/dist/modes/interactive/interactive-auth.js.map +1 -1
  373. package/dist/modes/interactive/interactive-commands.d.ts +125 -6
  374. package/dist/modes/interactive/interactive-commands.d.ts.map +1 -1
  375. package/dist/modes/interactive/interactive-commands.js +698 -4
  376. package/dist/modes/interactive/interactive-commands.js.map +1 -1
  377. package/dist/modes/interactive/interactive-events.d.ts +174 -0
  378. package/dist/modes/interactive/interactive-events.d.ts.map +1 -0
  379. package/dist/modes/interactive/interactive-events.js +704 -0
  380. package/dist/modes/interactive/interactive-events.js.map +1 -0
  381. package/dist/modes/interactive/interactive-format.d.ts.map +1 -1
  382. package/dist/modes/interactive/interactive-format.js +1 -1
  383. package/dist/modes/interactive/interactive-format.js.map +1 -1
  384. package/dist/modes/interactive/interactive-lifecycle.d.ts +94 -0
  385. package/dist/modes/interactive/interactive-lifecycle.d.ts.map +1 -0
  386. package/dist/modes/interactive/interactive-lifecycle.js +177 -0
  387. package/dist/modes/interactive/interactive-lifecycle.js.map +1 -0
  388. package/dist/modes/interactive/interactive-mode.d.ts +254 -129
  389. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  390. package/dist/modes/interactive/interactive-mode.js +275 -2101
  391. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  392. package/dist/modes/interactive/interactive-queues.d.ts +96 -0
  393. package/dist/modes/interactive/interactive-queues.d.ts.map +1 -0
  394. package/dist/modes/interactive/interactive-queues.js +183 -0
  395. package/dist/modes/interactive/interactive-queues.js.map +1 -0
  396. package/dist/modes/interactive/interactive-selectors.d.ts +95 -5
  397. package/dist/modes/interactive/interactive-selectors.d.ts.map +1 -1
  398. package/dist/modes/interactive/interactive-selectors.js +517 -6
  399. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  400. package/dist/modes/interactive/startup-services.d.ts +31 -0
  401. package/dist/modes/interactive/startup-services.d.ts.map +1 -0
  402. package/dist/modes/interactive/startup-services.js +123 -0
  403. package/dist/modes/interactive/startup-services.js.map +1 -0
  404. package/dist/modes/memory-preheat.d.ts +11 -0
  405. package/dist/modes/memory-preheat.d.ts.map +1 -0
  406. package/dist/modes/memory-preheat.js +20 -0
  407. package/dist/modes/memory-preheat.js.map +1 -0
  408. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  409. package/dist/modes/rpc/rpc-mode.js +3 -1
  410. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  411. package/dist/plugins/ecosystem/cli.d.ts.map +1 -1
  412. package/dist/plugins/ecosystem/cli.js +6 -3
  413. package/dist/plugins/ecosystem/cli.js.map +1 -1
  414. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts +7 -1
  415. package/dist/plugins/ecosystem/node-plugin-bootstrap.d.ts.map +1 -1
  416. package/dist/plugins/ecosystem/node-plugin-bootstrap.js +50 -3
  417. package/dist/plugins/ecosystem/node-plugin-bootstrap.js.map +1 -1
  418. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts +28 -16
  419. package/dist/plugins/ecosystem/plugin-bootstrap.d.ts.map +1 -1
  420. package/dist/plugins/ecosystem/plugin-bootstrap.js +35 -33
  421. package/dist/plugins/ecosystem/plugin-bootstrap.js.map +1 -1
  422. package/dist/profile/plugin-profiles.d.ts +1 -1
  423. package/dist/profile/plugin-profiles.d.ts.map +1 -1
  424. package/dist/profile/plugin-profiles.js +18 -0
  425. package/dist/profile/plugin-profiles.js.map +1 -1
  426. package/dist/remote/server-assembly.d.ts.map +1 -1
  427. package/dist/remote/server-assembly.js +7 -2
  428. package/dist/remote/server-assembly.js.map +1 -1
  429. package/dist/{profiles → suites}/builtin-suites.d.ts +14 -4
  430. package/dist/suites/builtin-suites.d.ts.map +1 -0
  431. package/dist/{profiles → suites}/builtin-suites.js +20 -5
  432. package/dist/suites/builtin-suites.js.map +1 -0
  433. package/dist/suites/resolved-agent-profile.d.ts.map +1 -0
  434. package/dist/suites/resolved-agent-profile.js.map +1 -0
  435. package/dist/suites/suite-lifecycle.d.ts.map +1 -0
  436. package/dist/suites/suite-lifecycle.js.map +1 -0
  437. package/dist/suites/suite-loader.d.ts.map +1 -0
  438. package/dist/suites/suite-loader.js.map +1 -0
  439. package/dist/{modes/interactive/theme → theme}/dark.json +1 -1
  440. package/dist/{modes/interactive/theme → theme}/light.json +1 -1
  441. package/dist/{modes/interactive/theme → theme}/theme-controller.d.ts +1 -1
  442. package/dist/theme/theme-controller.d.ts.map +1 -0
  443. package/dist/{modes/interactive/theme → theme}/theme-controller.js +1 -1
  444. package/dist/theme/theme-controller.js.map +1 -0
  445. package/dist/{modes/interactive/theme → theme}/theme.d.ts +1 -1
  446. package/dist/theme/theme.d.ts.map +1 -0
  447. package/dist/{modes/interactive/theme → theme}/theme.js +5 -5
  448. package/dist/theme/theme.js.map +1 -0
  449. package/docs/compaction.md +7 -7
  450. package/docs/environment-variables.md +10 -4
  451. package/docs/keybindings.md +3 -3
  452. package/docs/models.md +17 -17
  453. package/docs/packages.md +1 -1
  454. package/docs/prompt-templates.md +1 -1
  455. package/docs/rpc.md +2 -2
  456. package/docs/sdk.md +5 -5
  457. package/docs/session-format.md +3 -3
  458. package/docs/settings.md +368 -354
  459. package/docs/shell-aliases.md +1 -1
  460. package/docs/skills.md +1 -1
  461. package/docs/terminal-setup.md +17 -17
  462. package/docs/themes.md +5 -5
  463. package/docs/tmux.md +4 -4
  464. package/docs/tui.md +1 -1
  465. package/docs/windows.md +1 -1
  466. package/examples/extensions/bash-spawn-hook/index.ts +1 -1
  467. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  468. package/examples/extensions/with-deps/package-lock.json +2 -2
  469. package/examples/extensions/with-deps/package.json +1 -6
  470. package/examples/extensions/with-deps/plugin.json +1 -1
  471. package/package.json +2 -2
  472. package/dist/bundle/chunks/openai-responses-AUJQ3NWT.js +0 -2
  473. package/dist/bundle/chunks/virtual-modules-WF6WRHP7.js +0 -5
  474. package/dist/cli/experimental/commands/pi.d.ts +0 -15
  475. package/dist/cli/experimental/commands/pi.d.ts.map +0 -1
  476. package/dist/cli/experimental/commands/pi.js.map +0 -1
  477. package/dist/core/export-html/ansi-to-html.d.ts.map +0 -1
  478. package/dist/core/export-html/ansi-to-html.js.map +0 -1
  479. package/dist/core/export-html/index.d.ts.map +0 -1
  480. package/dist/core/export-html/index.js.map +0 -1
  481. package/dist/core/export-html/tool-renderer.d.ts.map +0 -1
  482. package/dist/core/export-html/tool-renderer.js.map +0 -1
  483. package/dist/core/pi-manifest.d.ts +0 -7
  484. package/dist/core/pi-manifest.d.ts.map +0 -1
  485. package/dist/core/pi-manifest.js.map +0 -1
  486. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +0 -1
  487. package/dist/modes/interactive/model-catalog-refresh.js.map +0 -1
  488. package/dist/modes/interactive/theme/theme-controller.d.ts.map +0 -1
  489. package/dist/modes/interactive/theme/theme-controller.js.map +0 -1
  490. package/dist/modes/interactive/theme/theme.d.ts.map +0 -1
  491. package/dist/modes/interactive/theme/theme.js.map +0 -1
  492. package/dist/profiles/builtin-suites.d.ts.map +0 -1
  493. package/dist/profiles/builtin-suites.js.map +0 -1
  494. package/dist/profiles/resolved-agent-profile.d.ts.map +0 -1
  495. package/dist/profiles/resolved-agent-profile.js.map +0 -1
  496. package/dist/profiles/suite-lifecycle.d.ts.map +0 -1
  497. package/dist/profiles/suite-lifecycle.js.map +0 -1
  498. package/dist/profiles/suite-loader.d.ts.map +0 -1
  499. package/dist/profiles/suite-loader.js.map +0 -1
  500. package/dist/utils/deprecation.d.ts +0 -4
  501. package/dist/utils/deprecation.d.ts.map +0 -1
  502. package/dist/utils/deprecation.js +0 -13
  503. package/dist/utils/deprecation.js.map +0 -1
  504. /package/dist/{core/export-html → export-html}/ansi-to-html.d.ts +0 -0
  505. /package/dist/{core/export-html → export-html}/ansi-to-html.js +0 -0
  506. /package/dist/{core/export-html → export-html}/template.css +0 -0
  507. /package/dist/{core/export-html → export-html}/template.html +0 -0
  508. /package/dist/{core/export-html → export-html}/template.js +0 -0
  509. /package/dist/{core/export-html → export-html}/tool-renderer.js +0 -0
  510. /package/dist/{core/export-html → export-html}/vendor/highlight.min.js +0 -0
  511. /package/dist/{core/export-html → export-html}/vendor/marked.min.js +0 -0
  512. /package/dist/{profiles → suites}/resolved-agent-profile.d.ts +0 -0
  513. /package/dist/{profiles → suites}/resolved-agent-profile.js +0 -0
  514. /package/dist/{profiles → suites}/suite-lifecycle.d.ts +0 -0
  515. /package/dist/{profiles → suites}/suite-lifecycle.js +0 -0
  516. /package/dist/{profiles → suites}/suite-loader.d.ts +0 -0
  517. /package/dist/{profiles → suites}/suite-loader.js +0 -0
  518. /package/dist/{modes/interactive/theme → theme}/theme-schema.json +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAsD,MAAM,yBAAyB,CAAC;AAChH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAQjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,uEAAuE;IACvE,UAAU,EAAE,wBAAwB,CAAC;IACrC,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CAoDxG;AAWD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAwE9B","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
1
+ {"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAsD,MAAM,yBAAyB,CAAC;AAChH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAQjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,EAIN,KAAK,cAAc,EAGnB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,uEAAuE;IACvE,UAAU,EAAE,wBAAwB,CAAC;IACrC,gEAAgE;IAChE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CAoDxG;AAWD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAwE9B","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 256000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
@@ -160,7 +160,7 @@ Summary of that exploration:
160
160
  export async function generateBranchSummary(entries, options) {
161
161
  const { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;
162
162
  // Token budget = context window minus reserved space for prompt + response
163
- const contextWindow = model.contextWindow || 128000;
163
+ const contextWindow = model.contextWindow || 256000;
164
164
  const tokenBudget = contextWindow - reserveTokens;
165
165
  const { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);
166
166
  if (messages.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
1
+ {"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../../src/core/compaction/branch-summarization.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { type AgentMessage, BRANCH_SUMMARY_PROMPT, SUMMARIZATION_SYSTEM_PROMPT } from \"@agent-forge/agent-core\";\nimport type { Usage } from \"@agent-forge/ai/compat\";\nimport type { SummaryModelFactsV1, SummaryModelInvocationV1 } from \"../extensions/public-api.ts\";\nimport { SUMMARY_MODEL_INVOCATION_ERROR_CODES } from \"../extensions/public-api.ts\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session-manager.ts\";\nimport { estimateTokens, formatSummaryFailure } from \"./compaction.ts\";\nimport {\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\tusage?: Usage;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Host-owned single-shot completion boundary for the summary call. */\n\tinvocation: SummaryModelInvocationV1;\n\t/** Provider-agnostic facts about the resolved summary model. */\n\tmodel: SummaryModelFactsV1;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved when selecting branch history (default 16384) */\n\treserveTokens?: number;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\tconst details = entry.details as BranchSummaryDetails;\n\t\t\tif (Array.isArray(details.readFiles)) {\n\t\t\t\tfor (const f of details.readFiles) fileOps.read.add(f);\n\t\t\t}\n\t\t\tif (Array.isArray(details.modifiedFiles)) {\n\t\t\t\t// Modified files go into both edited and written for proper deduplication\n\t\t\t\tfor (const f of details.modifiedFiles) {\n\t\t\t\t\tfileOps.edited.add(f);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.unshift(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.unshift(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `The user explored a different conversation branch before returning here.\nSummary of that exploration:\n\n`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst { invocation, model, signal, customInstructions, replaceInstructions, reserveTokens = 16384 } = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 256000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `<conversation>\\n${conversationText}\\n</conversation>\\n\\n${instructions}`;\n\n\tconst maxTokens = Math.min(4096, model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY);\n\n\t// One host-mediated completion: auth, transport selection, retry budget and\n\t// cache routing stay host-owned, so SDK request behavior (timeouts, retries,\n\t// attribution headers) stays consistent without running through agent state.\n\tconst result = await invocation.invoke(\n\t\t{\n\t\t\tversion: 1,\n\t\t\tsystemPrompt: SUMMARIZATION_SYSTEM_PROMPT,\n\t\t\tprompt: promptText,\n\t\t\tmaxTokens,\n\t\t},\n\t\tsignal,\n\t);\n\n\t// Check if aborted or errored\n\tif (result.status === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (result.status === \"failed\") {\n\t\t// Transport exceptions historically surfaced raw; provider-side failures\n\t\t// keep the labeled formatting.\n\t\treturn {\n\t\t\terror:\n\t\t\t\tresult.error.code === SUMMARY_MODEL_INVOCATION_ERROR_CODES.transportError\n\t\t\t\t\t? result.error.message\n\t\t\t\t\t: formatSummaryFailure(\"Branch summarization\", result.error),\n\t\t};\n\t}\n\n\t// Prepend preamble to provide context about the branch summary\n\tlet summary = BRANCH_SUMMARY_PREAMBLE + result.text;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\tusage: result.usage as Usage | undefined,\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,wBAAgB,8BAA8B,IAAI,OAAO,CAIxD","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\tconst configuredValue = process.env.AGENT_FORGE_EXPERIMENTAL;\n\t// Legacy fallback for installations configured before the Agent Forge rename.\n\treturn configuredValue === undefined ? process.env.PI_EXPERIMENTAL === \"1\" : configuredValue === \"1\";\n}\n"]}
1
+ {"version":3,"file":"experimental.d.ts","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,wBAAgB,8BAA8B,IAAI,OAAO,CAExD","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\treturn process.env.AGENT_FORGE_EXPERIMENTAL === \"1\";\n}\n"]}
@@ -1,6 +1,4 @@
1
1
  export function areExperimentalFeaturesEnabled() {
2
- const configuredValue = process.env.AGENT_FORGE_EXPERIMENTAL;
3
- // Legacy fallback for installations configured before the Agent Forge rename.
4
- return configuredValue === undefined ? process.env.PI_EXPERIMENTAL === "1" : configuredValue === "1";
2
+ return process.env.AGENT_FORGE_EXPERIMENTAL === "1";
5
3
  }
6
4
  //# sourceMappingURL=experimental.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,8BAA8B,GAAY;IACzD,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IAC7D,8EAA8E;IAC9E,OAAO,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,GAAG,CAAC,CAAC,CAAC,eAAe,KAAK,GAAG,CAAC;AAAA,CACrG","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\tconst configuredValue = process.env.AGENT_FORGE_EXPERIMENTAL;\n\t// Legacy fallback for installations configured before the Agent Forge rename.\n\treturn configuredValue === undefined ? process.env.PI_EXPERIMENTAL === \"1\" : configuredValue === \"1\";\n}\n"]}
1
+ {"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/core/experimental.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,8BAA8B,GAAY;IACzD,OAAO,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG,CAAC;AAAA,CACpD","sourcesContent":["export function areExperimentalFeaturesEnabled(): boolean {\n\treturn process.env.AGENT_FORGE_EXPERIMENTAL === \"1\";\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { CapabilityRuntimeState, RegisteredCapability, RegisteredPluginCapability } from "./capability-runtime-types.ts";
2
- import type { OperationHandle } from "./public-api.ts";
2
+ import type { DiagnosticsSpanSnapshot, LoggerRecord, OperationHandle, OperationStatus, PluginRejection } from "./public-api.ts";
3
3
  /**
4
4
  * Create the mutable state container for one capability runtime. Every map,
5
5
  * set, and array is created once and mutated in place; `eventSequence` is the
@@ -31,4 +31,23 @@ export declare function invokeRegisteredCapabilityWithSignal<T, TResult>(state:
31
31
  export declare function invokePluginCapability<TResult>(state: CapabilityRuntimeState, registered: RegisteredPluginCapability, input: unknown, signal: AbortSignal): Promise<TResult>;
32
32
  export declare function trackOperation<TResult>(state: CapabilityRuntimeState, ownerTokens: readonly symbol[], handle: OperationHandle<TResult>): OperationHandle<TResult>;
33
33
  export declare function cancelOwnedOperations(state: CapabilityRuntimeState, ownerToken: symbol, owner: string): void;
34
+ /**
35
+ * Bounded write for `statuses`. Setting an existing id keeps its insertion
36
+ * slot and never evicts. A new id at capacity evicts the oldest terminal
37
+ * (non-running) entry in insertion order; when every entry is running the
38
+ * insert proceeds above the limit because evicting a running status would
39
+ * make reportOperationStep reject the operation's remaining steps.
40
+ */
41
+ export declare function setOperationStatus(state: CapabilityRuntimeState, id: string, status: OperationStatus): void;
42
+ /**
43
+ * Bounded insert for `spans`. A new span at capacity evicts the oldest
44
+ * terminal (non-running) span first; when every span is still running it
45
+ * falls back to the oldest span in insertion order. Updates to an existing
46
+ * span (annotate/end/cancel) go through the map in place and never evict.
47
+ */
48
+ export declare function setDiagnosticsSpan(state: CapabilityRuntimeState, spanId: string, snapshot: DiagnosticsSpanSnapshot): void;
49
+ /** Bounded append for `logs`: keep the most recent {@link MAX_RUNTIME_LOG_RECORDS} records. */
50
+ export declare function pushRuntimeLog(state: CapabilityRuntimeState, record: LoggerRecord): void;
51
+ /** Bounded append for `pluginRejections`: keep the most recent {@link MAX_PLUGIN_REJECTIONS} records. */
52
+ export declare function pushPluginRejection(state: CapabilityRuntimeState, rejection: PluginRejection): void;
34
53
  //# sourceMappingURL=capability-runtime-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability-runtime-store.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/capability-runtime-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,sBAAsB,EAGtB,oBAAoB,EACpB,0BAA0B,EAO1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAaX,eAAe,EASf,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,sBAAsB,CAwCrE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI/F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEjE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAED,wBAAgB,gCAAgC,CAAC,CAAC,EACjD,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,GACjC,IAAI,CAIN;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,CAAC,EAAE,OAAO,EAC1D,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACnC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;GAIG;AACH,wBAAsB,oCAAoC,CAAC,CAAC,EAAE,OAAO,EACpE,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACnC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EACnD,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,0BAA0B,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED,wBAAgB,cAAc,CAAC,OAAO,EACrC,KAAK,EAAE,sBAAsB,EAC7B,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAC9B,eAAe,CAAC,OAAO,CAAC,CAgB1B;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM5G","sourcesContent":["import { cancellationError } from \"./capability-runtime-operation.ts\";\nimport { detachedSnapshot } from \"./capability-runtime-snapshot.ts\";\nimport type {\n\tAPIState,\n\tCapabilityRuntimeState,\n\tOperationHandler,\n\tQueuedLifecycleDelivery,\n\tRegisteredCapability,\n\tRegisteredPluginCapability,\n\tStateWatcher,\n\tStoredContributionPoint,\n\tStoredLifecycleDefinition,\n\tStoredLifecycleRegistration,\n\tStoredOutputArtifact,\n\tStoredState,\n} from \"./capability-runtime-types.ts\";\nimport type { LifecycleDeliveryQueue } from \"./lifecycle-delivery-queue.ts\";\nimport type {\n\tAgentLoopHookHandlerV1,\n\tAgentLoopHookPositionV1,\n\tAgentRunLoopStrategyV1,\n\tBranchSummaryPolicy,\n\tCapabilityAPI,\n\tCapabilityCommandDefinition,\n\tCompactionPolicy,\n\tContextStrategy,\n\tDiagnosticsSpanSnapshot,\n\tDisposableRegistration,\n\tEventEnvelope,\n\tLoggerRecord,\n\tOperationHandle,\n\tOperationStatus,\n\tOverflowPolicy,\n\tPluginRejection,\n\tProviderHeaderTransform,\n\tRetryPolicy,\n\tRuntimeInspectorLifecycleDeliveryReportSnapshot,\n\tSkillDefinition,\n\tStreamFnWrapper,\n} from \"./public-api.ts\";\n\n/**\n * Create the mutable state container for one capability runtime. Every map,\n * set, and array is created once and mutated in place; `eventSequence` is the\n * single mutable primitive shared with the lifecycle dispatch module.\n */\nexport function createCapabilityRuntimeState(): CapabilityRuntimeState {\n\treturn {\n\t\ttools: new Map<string, RegisteredCapability<unknown>>(),\n\t\tskills: new Map<string, RegisteredCapability<SkillDefinition>>(),\n\t\tretryPolicies: new Map<string, RegisteredCapability<RetryPolicy>>(),\n\t\tcompactionPolicies: new Map<string, RegisteredCapability<CompactionPolicy>>(),\n\t\toverflowPolicies: new Map<string, RegisteredCapability<OverflowPolicy>>(),\n\t\tbranchSummaryPolicies: new Map<string, RegisteredCapability<BranchSummaryPolicy>>(),\n\t\trunLoopStrategies: new Map<string, RegisteredCapability<AgentRunLoopStrategyV1>>(),\n\t\tloopHooks: new Map<AgentLoopHookPositionV1, RegisteredCapability<AgentLoopHookHandlerV1>[]>(),\n\t\tcommands: new Map<string, RegisteredCapability<CapabilityCommandDefinition>>(),\n\t\toperations: new Map<string, RegisteredCapability<OperationHandler>>(),\n\t\trpcMethods: new Map<string, RegisteredCapability<(input: unknown) => unknown | Promise<unknown>>>(),\n\t\tcontextStrategies: new Map<string, RegisteredCapability<ContextStrategy>>(),\n\t\tpluginCapabilities: new Map<string, RegisteredPluginCapability>(),\n\t\tproviderHeaderTransforms: new Map<string, RegisteredCapability<ProviderHeaderTransform>>(),\n\t\tstreamFnWrappers: new Map<string, RegisteredCapability<StreamFnWrapper>>(),\n\t\tcontributionPoints: new Map<string, StoredContributionPoint<unknown>>(),\n\t\tlifecycleDefinitions: new Map<string, StoredLifecycleDefinition>(),\n\t\tlifecycleRegistrations: new Map<string, Map<string, StoredLifecycleRegistration>>(),\n\t\tsubscribers: new Map<string, Map<string, RegisteredCapability<(event: EventEnvelope) => void | Promise<void>>>>(),\n\t\tstatuses: new Map<string, OperationStatus>(),\n\t\tactiveOperationsByOwnerToken: new Map<symbol, Set<OperationHandle<unknown>>>(),\n\t\tpluginRegistrations: new Map<string, Set<DisposableRegistration>>(),\n\t\tapiStates: new Map<CapabilityAPI, APIState>(),\n\t\tactiveOwnerTokens: new Set<symbol>(),\n\t\toutputArtifacts: new Map<string, StoredOutputArtifact>(),\n\t\tstateByOwner: new Map<string, Map<string, StoredState>>(),\n\t\tstateRevisionsByOwner: new Map<string, Map<string, number>>(),\n\t\tstateWatchers: new Map<string, Map<string, StateWatcher>>(),\n\t\tstateByInstance: new Map<string, Map<string, Map<string, StoredState>>>(),\n\t\tstateRevisionsByInstance: new Map<string, Map<string, Map<string, number>>>(),\n\t\tstateWatchersByInstance: new Map<string, Map<string, Map<string, StateWatcher>>>(),\n\t\tlogs: [] as LoggerRecord[],\n\t\tspans: new Map<string, DiagnosticsSpanSnapshot>(),\n\t\tlifecycleReports: [] as RuntimeInspectorLifecycleDeliveryReportSnapshot[],\n\t\tlifecycleDeliveryQueues: new Set<LifecycleDeliveryQueue<QueuedLifecycleDelivery<unknown>>>(),\n\t\tpluginRejections: [] as PluginRejection[],\n\t\teventSequence: 0,\n\t};\n}\n\n/**\n * A synchronous bootstrap plugin violated its lifecycle contract after its\n * disposer had already run. The synchronous caller receives a contract error;\n * observe a later rejection too so it cannot become an unhandled promise.\n */\nexport function observeUnexpectedAsyncCleanup(result: PromiseLike<void>, pluginId: string): void {\n\tvoid Promise.resolve(result).catch((error) => {\n\t\tconsole.error(`Asynchronous cleanup rejected after synchronous plugin disposal was rejected: ${pluginId}`, error);\n\t});\n}\n\nexport function createRevokedCapabilityError(owner: string): Error {\n\treturn new Error(`Capability API is revoked: ${owner}`);\n}\n\nexport function isRevokedCapabilityError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.startsWith(\"Capability API is revoked: \");\n}\n\nexport function assertRegisteredCapabilityActive<T>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n): void {\n\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\tthrow createRevokedCapabilityError(registered.owner);\n\t}\n}\n\n/**\n * Invoke an extension-owned callback with a lifecycle check before and after\n * awaiting it. A callback that resolves after its owner is revoked must not\n * publish a late result, and its rejection is normalized to the lifecycle\n * error so callers can distinguish revocation from plugin failures.\n */\nexport async function invokeRegisteredCapability<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered);\n\ttry {\n\t\tconst result = await invoke(registered.value);\n\t\tassertRegisteredCapabilityActive(state, registered);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Invoke a policy with its optional host cancellation signal. The signal is\n * checked before dispatch and after the policy settles; revocation remains\n * the stronger lifecycle error when both happen during one invocation.\n */\nexport async function invokeRegisteredCapabilityWithSignal<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tsignal: AbortSignal | undefined,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tif (signal?.aborted) throw cancellationError(signal.reason);\n\ttry {\n\t\tconst result = await invokeRegisteredCapability(state, registered, invoke);\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\tthrow error;\n\t}\n}\n\nexport async function invokePluginCapability<TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredPluginCapability,\n\tinput: unknown,\n\tsignal: AbortSignal,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\ttry {\n\t\tconst result = await registered.handler(detachedSnapshot(input), { signal });\n\t\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\t\treturn detachedSnapshot(result) as TResult;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) throw createRevokedCapabilityError(registered.owner);\n\t\tthrow error;\n\t}\n}\n\nexport function trackOperation<TResult>(\n\tstate: CapabilityRuntimeState,\n\townerTokens: readonly symbol[],\n\thandle: OperationHandle<TResult>,\n): OperationHandle<TResult> {\n\tfor (const ownerToken of ownerTokens) {\n\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken) ?? new Set<OperationHandle<unknown>>();\n\t\thandles.add(handle as OperationHandle<unknown>);\n\t\tstate.activeOperationsByOwnerToken.set(ownerToken, handles);\n\t}\n\tconst remove = () => {\n\t\tfor (const ownerToken of ownerTokens) {\n\t\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\t\t\tif (!handles) continue;\n\t\t\thandles.delete(handle as OperationHandle<unknown>);\n\t\t\tif (handles.size === 0) state.activeOperationsByOwnerToken.delete(ownerToken);\n\t\t}\n\t};\n\tvoid handle.result.then(remove, remove);\n\treturn handle;\n}\n\nexport function cancelOwnedOperations(state: CapabilityRuntimeState, ownerToken: symbol, owner: string): void {\n\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\tif (!handles) return;\n\tstate.activeOperationsByOwnerToken.delete(ownerToken);\n\tconst reason = createRevokedCapabilityError(owner);\n\tfor (const handle of handles) void handle.cancel(reason.message);\n}\n"]}
1
+ {"version":3,"file":"capability-runtime-store.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/capability-runtime-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,sBAAsB,EAGtB,oBAAoB,EACpB,0BAA0B,EAO1B,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EASX,uBAAuB,EAGvB,YAAY,EACZ,eAAe,EACf,eAAe,EAEf,eAAe,EAMf,MAAM,iBAAiB,CAAC;AAgBzB;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,sBAAsB,CAwCrE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI/F;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAEjE;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEhE;AAED,wBAAgB,gCAAgC,CAAC,CAAC,EACjD,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,GACjC,IAAI,CAIN;AAED;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAAC,CAAC,EAAE,OAAO,EAC1D,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACnC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC,CAYlB;AAED;;;;GAIG;AACH,wBAAsB,oCAAoC,CAAC,CAAC,EAAE,OAAO,EACpE,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC,EACnC,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAClD,OAAO,CAAC,OAAO,CAAC,CAalB;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EACnD,KAAK,EAAE,sBAAsB,EAC7B,UAAU,EAAE,0BAA0B,EACtC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,WAAW,GACjB,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED,wBAAgB,cAAc,CAAC,OAAO,EACrC,KAAK,EAAE,sBAAsB,EAC7B,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAC9B,eAAe,CAAC,OAAO,CAAC,CAgB1B;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAM5G;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAU3G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,KAAK,EAAE,sBAAsB,EAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,uBAAuB,GAC/B,IAAI,CAgBN;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,KAAK,EAAE,sBAAsB,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAGxF;AAED,yGAAyG;AACzG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI,CAGnG","sourcesContent":["import { cancellationError } from \"./capability-runtime-operation.ts\";\nimport { detachedSnapshot } from \"./capability-runtime-snapshot.ts\";\nimport type {\n\tAPIState,\n\tCapabilityRuntimeState,\n\tOperationHandler,\n\tQueuedLifecycleDelivery,\n\tRegisteredCapability,\n\tRegisteredPluginCapability,\n\tStateWatcher,\n\tStoredContributionPoint,\n\tStoredLifecycleDefinition,\n\tStoredLifecycleRegistration,\n\tStoredOutputArtifact,\n\tStoredState,\n} from \"./capability-runtime-types.ts\";\nimport type { LifecycleDeliveryQueue } from \"./lifecycle-delivery-queue.ts\";\nimport type {\n\tAgentLoopHookHandlerV1,\n\tAgentLoopHookPositionV1,\n\tAgentRunLoopStrategyV1,\n\tBranchSummaryPolicy,\n\tCapabilityAPI,\n\tCapabilityCommandDefinition,\n\tCompactionPolicy,\n\tContextStrategy,\n\tDiagnosticsSpanSnapshot,\n\tDisposableRegistration,\n\tEventEnvelope,\n\tLoggerRecord,\n\tOperationHandle,\n\tOperationStatus,\n\tOverflowPolicy,\n\tPluginRejection,\n\tProviderHeaderTransform,\n\tRetryPolicy,\n\tRuntimeInspectorLifecycleDeliveryReportSnapshot,\n\tSkillDefinition,\n\tStreamFnWrapper,\n} from \"./public-api.ts\";\n\n/**\n * 有界诊断容器上限(上限与逐出规则的权威来源:docs/design/插件基础能力设计.md §8.3):statuses/spans/logs/pluginRejections 只服务\n * 诊断与查询面(getOperationStatus、inspect),进程生命周期内只增不减,这里为\n * 各容器钉住\"保留最近 N 条,超限逐出最旧\"的进程级上限。\n */\n/** Operation 状态快照上限 1024:超限按插入序逐出最旧的已终态条目;在途 running 条目绝不逐出(getOperationStatus 返回非 running 会让 reportOperationStep 拒绝后续 step)。全部在途时跳过逐出、插入超过上限——statuses 没有终态删除路径,size 自此恒驻峰值水位、不再回落(并发在途天然小)。 */\nconst MAX_OPERATION_STATUSES = 1024;\n/** Diagnostics span 快照上限 1024:超限优先逐出最旧的已终态 span,全部 running 时按插入序逐出最旧。 */\nconst MAX_DIAGNOSTICS_SPANS = 1024;\n/** 运行时日志记录上限 1000(与 lifecycleReports 有界先例同风格):超限逐出最旧记录。 */\nconst MAX_RUNTIME_LOG_RECORDS = 1000;\n/** 插件启动拒绝记录上限 128:超限逐出最旧记录。 */\nconst MAX_PLUGIN_REJECTIONS = 128;\n\n/**\n * Create the mutable state container for one capability runtime. Every map,\n * set, and array is created once and mutated in place; `eventSequence` is the\n * single mutable primitive shared with the lifecycle dispatch module.\n */\nexport function createCapabilityRuntimeState(): CapabilityRuntimeState {\n\treturn {\n\t\ttools: new Map<string, RegisteredCapability<unknown>>(),\n\t\tskills: new Map<string, RegisteredCapability<SkillDefinition>>(),\n\t\tretryPolicies: new Map<string, RegisteredCapability<RetryPolicy>>(),\n\t\tcompactionPolicies: new Map<string, RegisteredCapability<CompactionPolicy>>(),\n\t\toverflowPolicies: new Map<string, RegisteredCapability<OverflowPolicy>>(),\n\t\tbranchSummaryPolicies: new Map<string, RegisteredCapability<BranchSummaryPolicy>>(),\n\t\trunLoopStrategies: new Map<string, RegisteredCapability<AgentRunLoopStrategyV1>>(),\n\t\tloopHooks: new Map<AgentLoopHookPositionV1, RegisteredCapability<AgentLoopHookHandlerV1>[]>(),\n\t\tcommands: new Map<string, RegisteredCapability<CapabilityCommandDefinition>>(),\n\t\toperations: new Map<string, RegisteredCapability<OperationHandler>>(),\n\t\trpcMethods: new Map<string, RegisteredCapability<(input: unknown) => unknown | Promise<unknown>>>(),\n\t\tcontextStrategies: new Map<string, RegisteredCapability<ContextStrategy>>(),\n\t\tpluginCapabilities: new Map<string, RegisteredPluginCapability>(),\n\t\tproviderHeaderTransforms: new Map<string, RegisteredCapability<ProviderHeaderTransform>>(),\n\t\tstreamFnWrappers: new Map<string, RegisteredCapability<StreamFnWrapper>>(),\n\t\tcontributionPoints: new Map<string, StoredContributionPoint<unknown>>(),\n\t\tlifecycleDefinitions: new Map<string, StoredLifecycleDefinition>(),\n\t\tlifecycleRegistrations: new Map<string, Map<string, StoredLifecycleRegistration>>(),\n\t\tsubscribers: new Map<string, Map<string, RegisteredCapability<(event: EventEnvelope) => void | Promise<void>>>>(),\n\t\tstatuses: new Map<string, OperationStatus>(),\n\t\tactiveOperationsByOwnerToken: new Map<symbol, Set<OperationHandle<unknown>>>(),\n\t\tpluginRegistrations: new Map<string, Set<DisposableRegistration>>(),\n\t\tapiStates: new Map<CapabilityAPI, APIState>(),\n\t\tactiveOwnerTokens: new Set<symbol>(),\n\t\toutputArtifacts: new Map<string, StoredOutputArtifact>(),\n\t\tstateByOwner: new Map<string, Map<string, StoredState>>(),\n\t\tstateRevisionsByOwner: new Map<string, Map<string, number>>(),\n\t\tstateWatchers: new Map<string, Map<string, StateWatcher>>(),\n\t\tstateByInstance: new Map<string, Map<string, Map<string, StoredState>>>(),\n\t\tstateRevisionsByInstance: new Map<string, Map<string, Map<string, number>>>(),\n\t\tstateWatchersByInstance: new Map<string, Map<string, Map<string, StateWatcher>>>(),\n\t\tlogs: [] as LoggerRecord[],\n\t\tspans: new Map<string, DiagnosticsSpanSnapshot>(),\n\t\tlifecycleReports: [] as RuntimeInspectorLifecycleDeliveryReportSnapshot[],\n\t\tlifecycleDeliveryQueues: new Set<LifecycleDeliveryQueue<QueuedLifecycleDelivery<unknown>>>(),\n\t\tpluginRejections: [] as PluginRejection[],\n\t\teventSequence: 0,\n\t};\n}\n\n/**\n * A synchronous bootstrap plugin violated its lifecycle contract after its\n * disposer had already run. The synchronous caller receives a contract error;\n * observe a later rejection too so it cannot become an unhandled promise.\n */\nexport function observeUnexpectedAsyncCleanup(result: PromiseLike<void>, pluginId: string): void {\n\tvoid Promise.resolve(result).catch((error) => {\n\t\tconsole.error(`Asynchronous cleanup rejected after synchronous plugin disposal was rejected: ${pluginId}`, error);\n\t});\n}\n\nexport function createRevokedCapabilityError(owner: string): Error {\n\treturn new Error(`Capability API is revoked: ${owner}`);\n}\n\nexport function isRevokedCapabilityError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.startsWith(\"Capability API is revoked: \");\n}\n\nexport function assertRegisteredCapabilityActive<T>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n): void {\n\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\tthrow createRevokedCapabilityError(registered.owner);\n\t}\n}\n\n/**\n * Invoke an extension-owned callback with a lifecycle check before and after\n * awaiting it. A callback that resolves after its owner is revoked must not\n * publish a late result, and its rejection is normalized to the lifecycle\n * error so callers can distinguish revocation from plugin failures.\n */\nexport async function invokeRegisteredCapability<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered);\n\ttry {\n\t\tconst result = await invoke(registered.value);\n\t\tassertRegisteredCapabilityActive(state, registered);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Invoke a policy with its optional host cancellation signal. The signal is\n * checked before dispatch and after the policy settles; revocation remains\n * the stronger lifecycle error when both happen during one invocation.\n */\nexport async function invokeRegisteredCapabilityWithSignal<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tsignal: AbortSignal | undefined,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tif (signal?.aborted) throw cancellationError(signal.reason);\n\ttry {\n\t\tconst result = await invokeRegisteredCapability(state, registered, invoke);\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\tthrow error;\n\t}\n}\n\nexport async function invokePluginCapability<TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredPluginCapability,\n\tinput: unknown,\n\tsignal: AbortSignal,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\ttry {\n\t\tconst result = await registered.handler(detachedSnapshot(input), { signal });\n\t\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\t\treturn detachedSnapshot(result) as TResult;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) throw createRevokedCapabilityError(registered.owner);\n\t\tthrow error;\n\t}\n}\n\nexport function trackOperation<TResult>(\n\tstate: CapabilityRuntimeState,\n\townerTokens: readonly symbol[],\n\thandle: OperationHandle<TResult>,\n): OperationHandle<TResult> {\n\tfor (const ownerToken of ownerTokens) {\n\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken) ?? new Set<OperationHandle<unknown>>();\n\t\thandles.add(handle as OperationHandle<unknown>);\n\t\tstate.activeOperationsByOwnerToken.set(ownerToken, handles);\n\t}\n\tconst remove = () => {\n\t\tfor (const ownerToken of ownerTokens) {\n\t\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\t\t\tif (!handles) continue;\n\t\t\thandles.delete(handle as OperationHandle<unknown>);\n\t\t\tif (handles.size === 0) state.activeOperationsByOwnerToken.delete(ownerToken);\n\t\t}\n\t};\n\tvoid handle.result.then(remove, remove);\n\treturn handle;\n}\n\nexport function cancelOwnedOperations(state: CapabilityRuntimeState, ownerToken: symbol, owner: string): void {\n\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\tif (!handles) return;\n\tstate.activeOperationsByOwnerToken.delete(ownerToken);\n\tconst reason = createRevokedCapabilityError(owner);\n\tfor (const handle of handles) void handle.cancel(reason.message);\n}\n\n/**\n * Bounded write for `statuses`. Setting an existing id keeps its insertion\n * slot and never evicts. A new id at capacity evicts the oldest terminal\n * (non-running) entry in insertion order; when every entry is running the\n * insert proceeds above the limit because evicting a running status would\n * make reportOperationStep reject the operation's remaining steps.\n */\nexport function setOperationStatus(state: CapabilityRuntimeState, id: string, status: OperationStatus): void {\n\tif (state.statuses.size >= MAX_OPERATION_STATUSES && !state.statuses.has(id)) {\n\t\tfor (const [key, value] of state.statuses) {\n\t\t\tif (value !== \"running\") {\n\t\t\t\tstate.statuses.delete(key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tstate.statuses.set(id, status);\n}\n\n/**\n * Bounded insert for `spans`. A new span at capacity evicts the oldest\n * terminal (non-running) span first; when every span is still running it\n * falls back to the oldest span in insertion order. Updates to an existing\n * span (annotate/end/cancel) go through the map in place and never evict.\n */\nexport function setDiagnosticsSpan(\n\tstate: CapabilityRuntimeState,\n\tspanId: string,\n\tsnapshot: DiagnosticsSpanSnapshot,\n): void {\n\tif (state.spans.size >= MAX_DIAGNOSTICS_SPANS && !state.spans.has(spanId)) {\n\t\tlet evicted = false;\n\t\tfor (const [key, span] of state.spans) {\n\t\t\tif (span.status !== \"running\") {\n\t\t\t\tstate.spans.delete(key);\n\t\t\t\tevicted = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!evicted) {\n\t\t\tconst oldest = state.spans.keys().next();\n\t\t\tif (!oldest.done) state.spans.delete(oldest.value);\n\t\t}\n\t}\n\tstate.spans.set(spanId, snapshot);\n}\n\n/** Bounded append for `logs`: keep the most recent {@link MAX_RUNTIME_LOG_RECORDS} records. */\nexport function pushRuntimeLog(state: CapabilityRuntimeState, record: LoggerRecord): void {\n\tif (state.logs.length >= MAX_RUNTIME_LOG_RECORDS) state.logs.shift();\n\tstate.logs.push(record);\n}\n\n/** Bounded append for `pluginRejections`: keep the most recent {@link MAX_PLUGIN_REJECTIONS} records. */\nexport function pushPluginRejection(state: CapabilityRuntimeState, rejection: PluginRejection): void {\n\tif (state.pluginRejections.length >= MAX_PLUGIN_REJECTIONS) state.pluginRejections.shift();\n\tstate.pluginRejections.push(rejection);\n}\n"]}
@@ -1,5 +1,18 @@
1
1
  import { cancellationError } from "./capability-runtime-operation.js";
2
2
  import { detachedSnapshot } from "./capability-runtime-snapshot.js";
3
+ /**
4
+ * 有界诊断容器上限(上限与逐出规则的权威来源:docs/design/插件基础能力设计.md §8.3):statuses/spans/logs/pluginRejections 只服务
5
+ * 诊断与查询面(getOperationStatus、inspect),进程生命周期内只增不减,这里为
6
+ * 各容器钉住"保留最近 N 条,超限逐出最旧"的进程级上限。
7
+ */
8
+ /** Operation 状态快照上限 1024:超限按插入序逐出最旧的已终态条目;在途 running 条目绝不逐出(getOperationStatus 返回非 running 会让 reportOperationStep 拒绝后续 step)。全部在途时跳过逐出、插入超过上限——statuses 没有终态删除路径,size 自此恒驻峰值水位、不再回落(并发在途天然小)。 */
9
+ const MAX_OPERATION_STATUSES = 1024;
10
+ /** Diagnostics span 快照上限 1024:超限优先逐出最旧的已终态 span,全部 running 时按插入序逐出最旧。 */
11
+ const MAX_DIAGNOSTICS_SPANS = 1024;
12
+ /** 运行时日志记录上限 1000(与 lifecycleReports 有界先例同风格):超限逐出最旧记录。 */
13
+ const MAX_RUNTIME_LOG_RECORDS = 1000;
14
+ /** 插件启动拒绝记录上限 128:超限逐出最旧记录。 */
15
+ const MAX_PLUGIN_REJECTIONS = 128;
3
16
  /**
4
17
  * Create the mutable state container for one capability runtime. Every map,
5
18
  * set, and array is created once and mutated in place; `eventSequence` is the
@@ -151,4 +164,58 @@ export function cancelOwnedOperations(state, ownerToken, owner) {
151
164
  for (const handle of handles)
152
165
  void handle.cancel(reason.message);
153
166
  }
167
+ /**
168
+ * Bounded write for `statuses`. Setting an existing id keeps its insertion
169
+ * slot and never evicts. A new id at capacity evicts the oldest terminal
170
+ * (non-running) entry in insertion order; when every entry is running the
171
+ * insert proceeds above the limit because evicting a running status would
172
+ * make reportOperationStep reject the operation's remaining steps.
173
+ */
174
+ export function setOperationStatus(state, id, status) {
175
+ if (state.statuses.size >= MAX_OPERATION_STATUSES && !state.statuses.has(id)) {
176
+ for (const [key, value] of state.statuses) {
177
+ if (value !== "running") {
178
+ state.statuses.delete(key);
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ state.statuses.set(id, status);
184
+ }
185
+ /**
186
+ * Bounded insert for `spans`. A new span at capacity evicts the oldest
187
+ * terminal (non-running) span first; when every span is still running it
188
+ * falls back to the oldest span in insertion order. Updates to an existing
189
+ * span (annotate/end/cancel) go through the map in place and never evict.
190
+ */
191
+ export function setDiagnosticsSpan(state, spanId, snapshot) {
192
+ if (state.spans.size >= MAX_DIAGNOSTICS_SPANS && !state.spans.has(spanId)) {
193
+ let evicted = false;
194
+ for (const [key, span] of state.spans) {
195
+ if (span.status !== "running") {
196
+ state.spans.delete(key);
197
+ evicted = true;
198
+ break;
199
+ }
200
+ }
201
+ if (!evicted) {
202
+ const oldest = state.spans.keys().next();
203
+ if (!oldest.done)
204
+ state.spans.delete(oldest.value);
205
+ }
206
+ }
207
+ state.spans.set(spanId, snapshot);
208
+ }
209
+ /** Bounded append for `logs`: keep the most recent {@link MAX_RUNTIME_LOG_RECORDS} records. */
210
+ export function pushRuntimeLog(state, record) {
211
+ if (state.logs.length >= MAX_RUNTIME_LOG_RECORDS)
212
+ state.logs.shift();
213
+ state.logs.push(record);
214
+ }
215
+ /** Bounded append for `pluginRejections`: keep the most recent {@link MAX_PLUGIN_REJECTIONS} records. */
216
+ export function pushPluginRejection(state, rejection) {
217
+ if (state.pluginRejections.length >= MAX_PLUGIN_REJECTIONS)
218
+ state.pluginRejections.shift();
219
+ state.pluginRejections.push(rejection);
220
+ }
154
221
  //# sourceMappingURL=capability-runtime-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability-runtime-store.js","sourceRoot":"","sources":["../../../src/core/extensions/capability-runtime-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { cancellationError } from \"./capability-runtime-operation.ts\";\nimport { detachedSnapshot } from \"./capability-runtime-snapshot.ts\";\nimport type {\n\tAPIState,\n\tCapabilityRuntimeState,\n\tOperationHandler,\n\tQueuedLifecycleDelivery,\n\tRegisteredCapability,\n\tRegisteredPluginCapability,\n\tStateWatcher,\n\tStoredContributionPoint,\n\tStoredLifecycleDefinition,\n\tStoredLifecycleRegistration,\n\tStoredOutputArtifact,\n\tStoredState,\n} from \"./capability-runtime-types.ts\";\nimport type { LifecycleDeliveryQueue } from \"./lifecycle-delivery-queue.ts\";\nimport type {\n\tAgentLoopHookHandlerV1,\n\tAgentLoopHookPositionV1,\n\tAgentRunLoopStrategyV1,\n\tBranchSummaryPolicy,\n\tCapabilityAPI,\n\tCapabilityCommandDefinition,\n\tCompactionPolicy,\n\tContextStrategy,\n\tDiagnosticsSpanSnapshot,\n\tDisposableRegistration,\n\tEventEnvelope,\n\tLoggerRecord,\n\tOperationHandle,\n\tOperationStatus,\n\tOverflowPolicy,\n\tPluginRejection,\n\tProviderHeaderTransform,\n\tRetryPolicy,\n\tRuntimeInspectorLifecycleDeliveryReportSnapshot,\n\tSkillDefinition,\n\tStreamFnWrapper,\n} from \"./public-api.ts\";\n\n/**\n * Create the mutable state container for one capability runtime. Every map,\n * set, and array is created once and mutated in place; `eventSequence` is the\n * single mutable primitive shared with the lifecycle dispatch module.\n */\nexport function createCapabilityRuntimeState(): CapabilityRuntimeState {\n\treturn {\n\t\ttools: new Map<string, RegisteredCapability<unknown>>(),\n\t\tskills: new Map<string, RegisteredCapability<SkillDefinition>>(),\n\t\tretryPolicies: new Map<string, RegisteredCapability<RetryPolicy>>(),\n\t\tcompactionPolicies: new Map<string, RegisteredCapability<CompactionPolicy>>(),\n\t\toverflowPolicies: new Map<string, RegisteredCapability<OverflowPolicy>>(),\n\t\tbranchSummaryPolicies: new Map<string, RegisteredCapability<BranchSummaryPolicy>>(),\n\t\trunLoopStrategies: new Map<string, RegisteredCapability<AgentRunLoopStrategyV1>>(),\n\t\tloopHooks: new Map<AgentLoopHookPositionV1, RegisteredCapability<AgentLoopHookHandlerV1>[]>(),\n\t\tcommands: new Map<string, RegisteredCapability<CapabilityCommandDefinition>>(),\n\t\toperations: new Map<string, RegisteredCapability<OperationHandler>>(),\n\t\trpcMethods: new Map<string, RegisteredCapability<(input: unknown) => unknown | Promise<unknown>>>(),\n\t\tcontextStrategies: new Map<string, RegisteredCapability<ContextStrategy>>(),\n\t\tpluginCapabilities: new Map<string, RegisteredPluginCapability>(),\n\t\tproviderHeaderTransforms: new Map<string, RegisteredCapability<ProviderHeaderTransform>>(),\n\t\tstreamFnWrappers: new Map<string, RegisteredCapability<StreamFnWrapper>>(),\n\t\tcontributionPoints: new Map<string, StoredContributionPoint<unknown>>(),\n\t\tlifecycleDefinitions: new Map<string, StoredLifecycleDefinition>(),\n\t\tlifecycleRegistrations: new Map<string, Map<string, StoredLifecycleRegistration>>(),\n\t\tsubscribers: new Map<string, Map<string, RegisteredCapability<(event: EventEnvelope) => void | Promise<void>>>>(),\n\t\tstatuses: new Map<string, OperationStatus>(),\n\t\tactiveOperationsByOwnerToken: new Map<symbol, Set<OperationHandle<unknown>>>(),\n\t\tpluginRegistrations: new Map<string, Set<DisposableRegistration>>(),\n\t\tapiStates: new Map<CapabilityAPI, APIState>(),\n\t\tactiveOwnerTokens: new Set<symbol>(),\n\t\toutputArtifacts: new Map<string, StoredOutputArtifact>(),\n\t\tstateByOwner: new Map<string, Map<string, StoredState>>(),\n\t\tstateRevisionsByOwner: new Map<string, Map<string, number>>(),\n\t\tstateWatchers: new Map<string, Map<string, StateWatcher>>(),\n\t\tstateByInstance: new Map<string, Map<string, Map<string, StoredState>>>(),\n\t\tstateRevisionsByInstance: new Map<string, Map<string, Map<string, number>>>(),\n\t\tstateWatchersByInstance: new Map<string, Map<string, Map<string, StateWatcher>>>(),\n\t\tlogs: [] as LoggerRecord[],\n\t\tspans: new Map<string, DiagnosticsSpanSnapshot>(),\n\t\tlifecycleReports: [] as RuntimeInspectorLifecycleDeliveryReportSnapshot[],\n\t\tlifecycleDeliveryQueues: new Set<LifecycleDeliveryQueue<QueuedLifecycleDelivery<unknown>>>(),\n\t\tpluginRejections: [] as PluginRejection[],\n\t\teventSequence: 0,\n\t};\n}\n\n/**\n * A synchronous bootstrap plugin violated its lifecycle contract after its\n * disposer had already run. The synchronous caller receives a contract error;\n * observe a later rejection too so it cannot become an unhandled promise.\n */\nexport function observeUnexpectedAsyncCleanup(result: PromiseLike<void>, pluginId: string): void {\n\tvoid Promise.resolve(result).catch((error) => {\n\t\tconsole.error(`Asynchronous cleanup rejected after synchronous plugin disposal was rejected: ${pluginId}`, error);\n\t});\n}\n\nexport function createRevokedCapabilityError(owner: string): Error {\n\treturn new Error(`Capability API is revoked: ${owner}`);\n}\n\nexport function isRevokedCapabilityError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.startsWith(\"Capability API is revoked: \");\n}\n\nexport function assertRegisteredCapabilityActive<T>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n): void {\n\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\tthrow createRevokedCapabilityError(registered.owner);\n\t}\n}\n\n/**\n * Invoke an extension-owned callback with a lifecycle check before and after\n * awaiting it. A callback that resolves after its owner is revoked must not\n * publish a late result, and its rejection is normalized to the lifecycle\n * error so callers can distinguish revocation from plugin failures.\n */\nexport async function invokeRegisteredCapability<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered);\n\ttry {\n\t\tconst result = await invoke(registered.value);\n\t\tassertRegisteredCapabilityActive(state, registered);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Invoke a policy with its optional host cancellation signal. The signal is\n * checked before dispatch and after the policy settles; revocation remains\n * the stronger lifecycle error when both happen during one invocation.\n */\nexport async function invokeRegisteredCapabilityWithSignal<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tsignal: AbortSignal | undefined,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tif (signal?.aborted) throw cancellationError(signal.reason);\n\ttry {\n\t\tconst result = await invokeRegisteredCapability(state, registered, invoke);\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\tthrow error;\n\t}\n}\n\nexport async function invokePluginCapability<TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredPluginCapability,\n\tinput: unknown,\n\tsignal: AbortSignal,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\ttry {\n\t\tconst result = await registered.handler(detachedSnapshot(input), { signal });\n\t\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\t\treturn detachedSnapshot(result) as TResult;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) throw createRevokedCapabilityError(registered.owner);\n\t\tthrow error;\n\t}\n}\n\nexport function trackOperation<TResult>(\n\tstate: CapabilityRuntimeState,\n\townerTokens: readonly symbol[],\n\thandle: OperationHandle<TResult>,\n): OperationHandle<TResult> {\n\tfor (const ownerToken of ownerTokens) {\n\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken) ?? new Set<OperationHandle<unknown>>();\n\t\thandles.add(handle as OperationHandle<unknown>);\n\t\tstate.activeOperationsByOwnerToken.set(ownerToken, handles);\n\t}\n\tconst remove = () => {\n\t\tfor (const ownerToken of ownerTokens) {\n\t\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\t\t\tif (!handles) continue;\n\t\t\thandles.delete(handle as OperationHandle<unknown>);\n\t\t\tif (handles.size === 0) state.activeOperationsByOwnerToken.delete(ownerToken);\n\t\t}\n\t};\n\tvoid handle.result.then(remove, remove);\n\treturn handle;\n}\n\nexport function cancelOwnedOperations(state: CapabilityRuntimeState, ownerToken: symbol, owner: string): void {\n\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\tif (!handles) return;\n\tstate.activeOperationsByOwnerToken.delete(ownerToken);\n\tconst reason = createRevokedCapabilityError(owner);\n\tfor (const handle of handles) void handle.cancel(reason.message);\n}\n"]}
1
+ {"version":3,"file":"capability-runtime-store.js","sourceRoot":"","sources":["../../../src/core/extensions/capability-runtime-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { cancellationError } from \"./capability-runtime-operation.ts\";\nimport { detachedSnapshot } from \"./capability-runtime-snapshot.ts\";\nimport type {\n\tAPIState,\n\tCapabilityRuntimeState,\n\tOperationHandler,\n\tQueuedLifecycleDelivery,\n\tRegisteredCapability,\n\tRegisteredPluginCapability,\n\tStateWatcher,\n\tStoredContributionPoint,\n\tStoredLifecycleDefinition,\n\tStoredLifecycleRegistration,\n\tStoredOutputArtifact,\n\tStoredState,\n} from \"./capability-runtime-types.ts\";\nimport type { LifecycleDeliveryQueue } from \"./lifecycle-delivery-queue.ts\";\nimport type {\n\tAgentLoopHookHandlerV1,\n\tAgentLoopHookPositionV1,\n\tAgentRunLoopStrategyV1,\n\tBranchSummaryPolicy,\n\tCapabilityAPI,\n\tCapabilityCommandDefinition,\n\tCompactionPolicy,\n\tContextStrategy,\n\tDiagnosticsSpanSnapshot,\n\tDisposableRegistration,\n\tEventEnvelope,\n\tLoggerRecord,\n\tOperationHandle,\n\tOperationStatus,\n\tOverflowPolicy,\n\tPluginRejection,\n\tProviderHeaderTransform,\n\tRetryPolicy,\n\tRuntimeInspectorLifecycleDeliveryReportSnapshot,\n\tSkillDefinition,\n\tStreamFnWrapper,\n} from \"./public-api.ts\";\n\n/**\n * 有界诊断容器上限(上限与逐出规则的权威来源:docs/design/插件基础能力设计.md §8.3):statuses/spans/logs/pluginRejections 只服务\n * 诊断与查询面(getOperationStatus、inspect),进程生命周期内只增不减,这里为\n * 各容器钉住\"保留最近 N 条,超限逐出最旧\"的进程级上限。\n */\n/** Operation 状态快照上限 1024:超限按插入序逐出最旧的已终态条目;在途 running 条目绝不逐出(getOperationStatus 返回非 running 会让 reportOperationStep 拒绝后续 step)。全部在途时跳过逐出、插入超过上限——statuses 没有终态删除路径,size 自此恒驻峰值水位、不再回落(并发在途天然小)。 */\nconst MAX_OPERATION_STATUSES = 1024;\n/** Diagnostics span 快照上限 1024:超限优先逐出最旧的已终态 span,全部 running 时按插入序逐出最旧。 */\nconst MAX_DIAGNOSTICS_SPANS = 1024;\n/** 运行时日志记录上限 1000(与 lifecycleReports 有界先例同风格):超限逐出最旧记录。 */\nconst MAX_RUNTIME_LOG_RECORDS = 1000;\n/** 插件启动拒绝记录上限 128:超限逐出最旧记录。 */\nconst MAX_PLUGIN_REJECTIONS = 128;\n\n/**\n * Create the mutable state container for one capability runtime. Every map,\n * set, and array is created once and mutated in place; `eventSequence` is the\n * single mutable primitive shared with the lifecycle dispatch module.\n */\nexport function createCapabilityRuntimeState(): CapabilityRuntimeState {\n\treturn {\n\t\ttools: new Map<string, RegisteredCapability<unknown>>(),\n\t\tskills: new Map<string, RegisteredCapability<SkillDefinition>>(),\n\t\tretryPolicies: new Map<string, RegisteredCapability<RetryPolicy>>(),\n\t\tcompactionPolicies: new Map<string, RegisteredCapability<CompactionPolicy>>(),\n\t\toverflowPolicies: new Map<string, RegisteredCapability<OverflowPolicy>>(),\n\t\tbranchSummaryPolicies: new Map<string, RegisteredCapability<BranchSummaryPolicy>>(),\n\t\trunLoopStrategies: new Map<string, RegisteredCapability<AgentRunLoopStrategyV1>>(),\n\t\tloopHooks: new Map<AgentLoopHookPositionV1, RegisteredCapability<AgentLoopHookHandlerV1>[]>(),\n\t\tcommands: new Map<string, RegisteredCapability<CapabilityCommandDefinition>>(),\n\t\toperations: new Map<string, RegisteredCapability<OperationHandler>>(),\n\t\trpcMethods: new Map<string, RegisteredCapability<(input: unknown) => unknown | Promise<unknown>>>(),\n\t\tcontextStrategies: new Map<string, RegisteredCapability<ContextStrategy>>(),\n\t\tpluginCapabilities: new Map<string, RegisteredPluginCapability>(),\n\t\tproviderHeaderTransforms: new Map<string, RegisteredCapability<ProviderHeaderTransform>>(),\n\t\tstreamFnWrappers: new Map<string, RegisteredCapability<StreamFnWrapper>>(),\n\t\tcontributionPoints: new Map<string, StoredContributionPoint<unknown>>(),\n\t\tlifecycleDefinitions: new Map<string, StoredLifecycleDefinition>(),\n\t\tlifecycleRegistrations: new Map<string, Map<string, StoredLifecycleRegistration>>(),\n\t\tsubscribers: new Map<string, Map<string, RegisteredCapability<(event: EventEnvelope) => void | Promise<void>>>>(),\n\t\tstatuses: new Map<string, OperationStatus>(),\n\t\tactiveOperationsByOwnerToken: new Map<symbol, Set<OperationHandle<unknown>>>(),\n\t\tpluginRegistrations: new Map<string, Set<DisposableRegistration>>(),\n\t\tapiStates: new Map<CapabilityAPI, APIState>(),\n\t\tactiveOwnerTokens: new Set<symbol>(),\n\t\toutputArtifacts: new Map<string, StoredOutputArtifact>(),\n\t\tstateByOwner: new Map<string, Map<string, StoredState>>(),\n\t\tstateRevisionsByOwner: new Map<string, Map<string, number>>(),\n\t\tstateWatchers: new Map<string, Map<string, StateWatcher>>(),\n\t\tstateByInstance: new Map<string, Map<string, Map<string, StoredState>>>(),\n\t\tstateRevisionsByInstance: new Map<string, Map<string, Map<string, number>>>(),\n\t\tstateWatchersByInstance: new Map<string, Map<string, Map<string, StateWatcher>>>(),\n\t\tlogs: [] as LoggerRecord[],\n\t\tspans: new Map<string, DiagnosticsSpanSnapshot>(),\n\t\tlifecycleReports: [] as RuntimeInspectorLifecycleDeliveryReportSnapshot[],\n\t\tlifecycleDeliveryQueues: new Set<LifecycleDeliveryQueue<QueuedLifecycleDelivery<unknown>>>(),\n\t\tpluginRejections: [] as PluginRejection[],\n\t\teventSequence: 0,\n\t};\n}\n\n/**\n * A synchronous bootstrap plugin violated its lifecycle contract after its\n * disposer had already run. The synchronous caller receives a contract error;\n * observe a later rejection too so it cannot become an unhandled promise.\n */\nexport function observeUnexpectedAsyncCleanup(result: PromiseLike<void>, pluginId: string): void {\n\tvoid Promise.resolve(result).catch((error) => {\n\t\tconsole.error(`Asynchronous cleanup rejected after synchronous plugin disposal was rejected: ${pluginId}`, error);\n\t});\n}\n\nexport function createRevokedCapabilityError(owner: string): Error {\n\treturn new Error(`Capability API is revoked: ${owner}`);\n}\n\nexport function isRevokedCapabilityError(error: unknown): boolean {\n\treturn error instanceof Error && error.message.startsWith(\"Capability API is revoked: \");\n}\n\nexport function assertRegisteredCapabilityActive<T>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n): void {\n\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\tthrow createRevokedCapabilityError(registered.owner);\n\t}\n}\n\n/**\n * Invoke an extension-owned callback with a lifecycle check before and after\n * awaiting it. A callback that resolves after its owner is revoked must not\n * publish a late result, and its rejection is normalized to the lifecycle\n * error so callers can distinguish revocation from plugin failures.\n */\nexport async function invokeRegisteredCapability<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered);\n\ttry {\n\t\tconst result = await invoke(registered.value);\n\t\tassertRegisteredCapabilityActive(state, registered);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Invoke a policy with its optional host cancellation signal. The signal is\n * checked before dispatch and after the policy settles; revocation remains\n * the stronger lifecycle error when both happen during one invocation.\n */\nexport async function invokeRegisteredCapabilityWithSignal<T, TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredCapability<T>,\n\tsignal: AbortSignal | undefined,\n\tinvoke: (value: T) => TResult | PromiseLike<TResult>,\n): Promise<TResult> {\n\tif (signal?.aborted) throw cancellationError(signal.reason);\n\ttry {\n\t\tconst result = await invokeRegisteredCapability(state, registered, invoke);\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\treturn result;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) {\n\t\t\tthrow createRevokedCapabilityError(registered.owner);\n\t\t}\n\t\tif (signal?.aborted) throw cancellationError(signal.reason);\n\t\tthrow error;\n\t}\n}\n\nexport async function invokePluginCapability<TResult>(\n\tstate: CapabilityRuntimeState,\n\tregistered: RegisteredPluginCapability,\n\tinput: unknown,\n\tsignal: AbortSignal,\n): Promise<TResult> {\n\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\ttry {\n\t\tconst result = await registered.handler(detachedSnapshot(input), { signal });\n\t\tassertRegisteredCapabilityActive(state, registered as unknown as RegisteredCapability<unknown>);\n\t\treturn detachedSnapshot(result) as TResult;\n\t} catch (error) {\n\t\tif (!state.activeOwnerTokens.has(registered.ownerToken)) throw createRevokedCapabilityError(registered.owner);\n\t\tthrow error;\n\t}\n}\n\nexport function trackOperation<TResult>(\n\tstate: CapabilityRuntimeState,\n\townerTokens: readonly symbol[],\n\thandle: OperationHandle<TResult>,\n): OperationHandle<TResult> {\n\tfor (const ownerToken of ownerTokens) {\n\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken) ?? new Set<OperationHandle<unknown>>();\n\t\thandles.add(handle as OperationHandle<unknown>);\n\t\tstate.activeOperationsByOwnerToken.set(ownerToken, handles);\n\t}\n\tconst remove = () => {\n\t\tfor (const ownerToken of ownerTokens) {\n\t\t\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\t\t\tif (!handles) continue;\n\t\t\thandles.delete(handle as OperationHandle<unknown>);\n\t\t\tif (handles.size === 0) state.activeOperationsByOwnerToken.delete(ownerToken);\n\t\t}\n\t};\n\tvoid handle.result.then(remove, remove);\n\treturn handle;\n}\n\nexport function cancelOwnedOperations(state: CapabilityRuntimeState, ownerToken: symbol, owner: string): void {\n\tconst handles = state.activeOperationsByOwnerToken.get(ownerToken);\n\tif (!handles) return;\n\tstate.activeOperationsByOwnerToken.delete(ownerToken);\n\tconst reason = createRevokedCapabilityError(owner);\n\tfor (const handle of handles) void handle.cancel(reason.message);\n}\n\n/**\n * Bounded write for `statuses`. Setting an existing id keeps its insertion\n * slot and never evicts. A new id at capacity evicts the oldest terminal\n * (non-running) entry in insertion order; when every entry is running the\n * insert proceeds above the limit because evicting a running status would\n * make reportOperationStep reject the operation's remaining steps.\n */\nexport function setOperationStatus(state: CapabilityRuntimeState, id: string, status: OperationStatus): void {\n\tif (state.statuses.size >= MAX_OPERATION_STATUSES && !state.statuses.has(id)) {\n\t\tfor (const [key, value] of state.statuses) {\n\t\t\tif (value !== \"running\") {\n\t\t\t\tstate.statuses.delete(key);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tstate.statuses.set(id, status);\n}\n\n/**\n * Bounded insert for `spans`. A new span at capacity evicts the oldest\n * terminal (non-running) span first; when every span is still running it\n * falls back to the oldest span in insertion order. Updates to an existing\n * span (annotate/end/cancel) go through the map in place and never evict.\n */\nexport function setDiagnosticsSpan(\n\tstate: CapabilityRuntimeState,\n\tspanId: string,\n\tsnapshot: DiagnosticsSpanSnapshot,\n): void {\n\tif (state.spans.size >= MAX_DIAGNOSTICS_SPANS && !state.spans.has(spanId)) {\n\t\tlet evicted = false;\n\t\tfor (const [key, span] of state.spans) {\n\t\t\tif (span.status !== \"running\") {\n\t\t\t\tstate.spans.delete(key);\n\t\t\t\tevicted = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!evicted) {\n\t\t\tconst oldest = state.spans.keys().next();\n\t\t\tif (!oldest.done) state.spans.delete(oldest.value);\n\t\t}\n\t}\n\tstate.spans.set(spanId, snapshot);\n}\n\n/** Bounded append for `logs`: keep the most recent {@link MAX_RUNTIME_LOG_RECORDS} records. */\nexport function pushRuntimeLog(state: CapabilityRuntimeState, record: LoggerRecord): void {\n\tif (state.logs.length >= MAX_RUNTIME_LOG_RECORDS) state.logs.shift();\n\tstate.logs.push(record);\n}\n\n/** Bounded append for `pluginRejections`: keep the most recent {@link MAX_PLUGIN_REJECTIONS} records. */\nexport function pushPluginRejection(state: CapabilityRuntimeState, rejection: PluginRejection): void {\n\tif (state.pluginRejections.length >= MAX_PLUGIN_REJECTIONS) state.pluginRejections.shift();\n\tstate.pluginRejections.push(rejection);\n}\n"]}
@@ -119,6 +119,13 @@ export interface APIState {
119
119
  compositionInstances?: Set<AgentInstance>;
120
120
  compositionDefinitions?: Set<AgentDefinition>;
121
121
  }
122
+ /**
123
+ * output.put 驻留缓冲上限(M4 双层限额的缓冲半层):单个输出工件的内存驻留
124
+ * 封顶。超限后停止继续缓冲(AsyncIterable 仍完整消费,只丢弃数据),驻留视图
125
+ * 变为 head + 截断标记 + 完整流末尾 64 KiB tail;ref.sizeBytes/truncated 由
126
+ * 运行时计算(sizeBytes 恒为原始总字节数),commit 观察者只收截断视图。
127
+ */
128
+ export declare const OUTPUT_ARTIFACT_MAX_BUFFER_BYTES: number;
122
129
  export interface StoredOutputArtifact {
123
130
  ref: OutputArtifactRef;
124
131
  bytes: Uint8Array;
@@ -208,6 +215,13 @@ export interface CapabilityRuntime {
208
215
  }[];
209
216
  listContributions(pointId: string, version: number): readonly ContributionEntry[];
210
217
  hasLifecycleEvent(id: string, version: number): boolean;
218
+ /**
219
+ * Whether at least one lifecycle registration currently exists for the event
220
+ * key (registration-map presence; owner activity is rechecked at delivery).
221
+ * Hot-path gate for per-delta producers (model.stream): lets the host skip
222
+ * envelope snapshot and clone work when nothing observes the event.
223
+ */
224
+ hasLifecycleSubscribers(type: string, version: number): boolean;
211
225
  dispatchLifecycle<TData>(request: LifecycleDispatchRequest<TData>): Promise<LifecycleDispatchResult<TData>>;
212
226
  /**
213
227
  * Record one startup plugin rejection (D-028): the rejection stays visible in