@caupulican/pi-adaptative 0.80.102 → 0.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/dist/cli/session-picker.d.ts +1 -1
  3. package/dist/cli/session-picker.d.ts.map +1 -1
  4. package/dist/cli/session-picker.js.map +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +7 -1
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts +11 -0
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/config.js +17 -3
  11. package/dist/config.js.map +1 -1
  12. package/dist/core/agent-session-runtime.d.ts +1 -1
  13. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  14. package/dist/core/agent-session-runtime.js +6 -6
  15. package/dist/core/agent-session-runtime.js.map +1 -1
  16. package/dist/core/agent-session-services.d.ts +1 -1
  17. package/dist/core/agent-session-services.d.ts.map +1 -1
  18. package/dist/core/agent-session-services.js.map +1 -1
  19. package/dist/core/agent-session.d.ts +152 -512
  20. package/dist/core/agent-session.d.ts.map +1 -1
  21. package/dist/core/agent-session.js +635 -4590
  22. package/dist/core/agent-session.js.map +1 -1
  23. package/dist/core/autonomy/session-lane-record.d.ts +1 -1
  24. package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
  25. package/dist/core/autonomy/session-lane-record.js.map +1 -1
  26. package/dist/core/autonomy/status.d.ts +1 -0
  27. package/dist/core/autonomy/status.d.ts.map +1 -1
  28. package/dist/core/autonomy/status.js +1 -0
  29. package/dist/core/autonomy/status.js.map +1 -1
  30. package/dist/core/autonomy-telemetry.d.ts +80 -0
  31. package/dist/core/autonomy-telemetry.d.ts.map +1 -0
  32. package/dist/core/autonomy-telemetry.js +266 -0
  33. package/dist/core/autonomy-telemetry.js.map +1 -0
  34. package/dist/core/background-lane-controller.d.ts +186 -0
  35. package/dist/core/background-lane-controller.d.ts.map +1 -0
  36. package/dist/core/background-lane-controller.js +691 -0
  37. package/dist/core/background-lane-controller.js.map +1 -0
  38. package/dist/core/bash-execution-controller.d.ts +51 -0
  39. package/dist/core/bash-execution-controller.d.ts.map +1 -0
  40. package/dist/core/bash-execution-controller.js +96 -0
  41. package/dist/core/bash-execution-controller.js.map +1 -0
  42. package/dist/core/bash-executor.d.ts.map +1 -1
  43. package/dist/core/bash-executor.js +9 -2
  44. package/dist/core/bash-executor.js.map +1 -1
  45. package/dist/core/compaction-support.d.ts +56 -0
  46. package/dist/core/compaction-support.d.ts.map +1 -0
  47. package/dist/core/compaction-support.js +99 -0
  48. package/dist/core/compaction-support.js.map +1 -0
  49. package/dist/core/context/artifact-retrieval.d.ts +1 -1
  50. package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
  51. package/dist/core/context/artifact-retrieval.js +1 -1
  52. package/dist/core/context/artifact-retrieval.js.map +1 -1
  53. package/dist/core/context/context-composition.d.ts.map +1 -1
  54. package/dist/core/context/context-composition.js +1 -1
  55. package/dist/core/context/context-composition.js.map +1 -1
  56. package/dist/core/context/tool-output-packer.d.ts +1 -1
  57. package/dist/core/context/tool-output-packer.d.ts.map +1 -1
  58. package/dist/core/context/tool-output-packer.js +1 -1
  59. package/dist/core/context/tool-output-packer.js.map +1 -1
  60. package/dist/core/context-gc.d.ts.map +1 -1
  61. package/dist/core/context-gc.js +1 -1
  62. package/dist/core/context-gc.js.map +1 -1
  63. package/dist/core/context-pipeline.d.ts +223 -0
  64. package/dist/core/context-pipeline.d.ts.map +1 -0
  65. package/dist/core/context-pipeline.js +594 -0
  66. package/dist/core/context-pipeline.js.map +1 -0
  67. package/dist/core/cost/daily-usage.d.ts +1 -1
  68. package/dist/core/cost/daily-usage.d.ts.map +1 -1
  69. package/dist/core/cost/daily-usage.js +1 -1
  70. package/dist/core/cost/daily-usage.js.map +1 -1
  71. package/dist/core/cost/session-usage.d.ts +1 -1
  72. package/dist/core/cost/session-usage.d.ts.map +1 -1
  73. package/dist/core/cost/session-usage.js +1 -1
  74. package/dist/core/cost/session-usage.js.map +1 -1
  75. package/dist/core/delegation/session-worker-result.d.ts +1 -1
  76. package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
  77. package/dist/core/delegation/session-worker-result.js.map +1 -1
  78. package/dist/core/exec.d.ts +2 -0
  79. package/dist/core/exec.d.ts.map +1 -1
  80. package/dist/core/exec.js +15 -9
  81. package/dist/core/exec.js.map +1 -1
  82. package/dist/core/export-html/index.d.ts +1 -1
  83. package/dist/core/export-html/index.d.ts.map +1 -1
  84. package/dist/core/export-html/index.js +2 -2
  85. package/dist/core/export-html/index.js.map +1 -1
  86. package/dist/core/extensions/builtin.d.ts.map +1 -1
  87. package/dist/core/extensions/builtin.js +2 -2
  88. package/dist/core/extensions/builtin.js.map +1 -1
  89. package/dist/core/extensions/runner.d.ts +1 -1
  90. package/dist/core/extensions/runner.d.ts.map +1 -1
  91. package/dist/core/extensions/runner.js.map +1 -1
  92. package/dist/core/extensions/types.d.ts +2 -4
  93. package/dist/core/extensions/types.d.ts.map +1 -1
  94. package/dist/core/extensions/types.js.map +1 -1
  95. package/dist/core/goal-loop-controller.d.ts +24 -0
  96. package/dist/core/goal-loop-controller.d.ts.map +1 -0
  97. package/dist/core/goal-loop-controller.js +83 -0
  98. package/dist/core/goal-loop-controller.js.map +1 -0
  99. package/dist/core/goals/goal-runtime-snapshot.d.ts +1 -1
  100. package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
  101. package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
  102. package/dist/core/goals/session-goal-state.d.ts +1 -1
  103. package/dist/core/goals/session-goal-state.d.ts.map +1 -1
  104. package/dist/core/goals/session-goal-state.js.map +1 -1
  105. package/dist/core/index.d.ts +1 -1
  106. package/dist/core/index.d.ts.map +1 -1
  107. package/dist/core/index.js.map +1 -1
  108. package/dist/core/learning/learning-audit.d.ts +1 -1
  109. package/dist/core/learning/learning-audit.d.ts.map +1 -1
  110. package/dist/core/learning/learning-audit.js.map +1 -1
  111. package/dist/core/learning/session-learning-decision.d.ts +1 -1
  112. package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
  113. package/dist/core/learning/session-learning-decision.js.map +1 -1
  114. package/dist/core/local-runtime-controller.d.ts +99 -0
  115. package/dist/core/local-runtime-controller.d.ts.map +1 -0
  116. package/dist/core/local-runtime-controller.js +214 -0
  117. package/dist/core/local-runtime-controller.js.map +1 -0
  118. package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
  119. package/dist/core/memory/providers/transcript-recall.js +1 -1
  120. package/dist/core/memory/providers/transcript-recall.js.map +1 -1
  121. package/dist/core/memory-controller.d.ts +139 -0
  122. package/dist/core/memory-controller.d.ts.map +1 -0
  123. package/dist/core/memory-controller.js +323 -0
  124. package/dist/core/memory-controller.js.map +1 -0
  125. package/dist/core/model-router/status.d.ts +1 -1
  126. package/dist/core/model-router/status.d.ts.map +1 -1
  127. package/dist/core/model-router/status.js.map +1 -1
  128. package/dist/core/model-router-controller.d.ts +140 -0
  129. package/dist/core/model-router-controller.d.ts.map +1 -0
  130. package/dist/core/model-router-controller.js +623 -0
  131. package/dist/core/model-router-controller.js.map +1 -0
  132. package/dist/core/model-selection-controller.d.ts +95 -0
  133. package/dist/core/model-selection-controller.d.ts.map +1 -0
  134. package/dist/core/model-selection-controller.js +252 -0
  135. package/dist/core/model-selection-controller.js.map +1 -0
  136. package/dist/core/models/model-ref.d.ts +13 -0
  137. package/dist/core/models/model-ref.d.ts.map +1 -1
  138. package/dist/core/models/model-ref.js +22 -0
  139. package/dist/core/models/model-ref.js.map +1 -1
  140. package/dist/core/profile-filter-controller.d.ts +77 -0
  141. package/dist/core/profile-filter-controller.d.ts.map +1 -0
  142. package/dist/core/profile-filter-controller.js +159 -0
  143. package/dist/core/profile-filter-controller.js.map +1 -0
  144. package/dist/core/reflection-controller.d.ts +111 -0
  145. package/dist/core/reflection-controller.d.ts.map +1 -0
  146. package/dist/core/reflection-controller.js +412 -0
  147. package/dist/core/reflection-controller.js.map +1 -0
  148. package/dist/core/research/model-fitness.d.ts +12 -0
  149. package/dist/core/research/model-fitness.d.ts.map +1 -1
  150. package/dist/core/research/model-fitness.js +21 -0
  151. package/dist/core/research/model-fitness.js.map +1 -1
  152. package/dist/core/research/session-evidence-bundle.d.ts +1 -1
  153. package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
  154. package/dist/core/research/session-evidence-bundle.js.map +1 -1
  155. package/dist/core/runtime-builder.d.ts +222 -0
  156. package/dist/core/runtime-builder.d.ts.map +1 -0
  157. package/dist/core/runtime-builder.js +640 -0
  158. package/dist/core/runtime-builder.js.map +1 -0
  159. package/dist/core/sdk.d.ts +2 -2
  160. package/dist/core/sdk.d.ts.map +1 -1
  161. package/dist/core/sdk.js +3 -4
  162. package/dist/core/sdk.js.map +1 -1
  163. package/dist/core/session-analytics.d.ts +96 -0
  164. package/dist/core/session-analytics.d.ts.map +1 -0
  165. package/dist/core/session-analytics.js +331 -0
  166. package/dist/core/session-analytics.js.map +1 -0
  167. package/dist/core/session-manager-factory.d.ts +18 -0
  168. package/dist/core/session-manager-factory.d.ts.map +1 -0
  169. package/dist/core/session-manager-factory.js +32 -0
  170. package/dist/core/session-manager-factory.js.map +1 -0
  171. package/dist/core/session-tree-navigator.d.ts +68 -0
  172. package/dist/core/session-tree-navigator.d.ts.map +1 -0
  173. package/dist/core/session-tree-navigator.js +217 -0
  174. package/dist/core/session-tree-navigator.js.map +1 -0
  175. package/dist/core/system-prompt-builder.d.ts +63 -0
  176. package/dist/core/system-prompt-builder.d.ts.map +1 -0
  177. package/dist/core/system-prompt-builder.js +181 -0
  178. package/dist/core/system-prompt-builder.js.map +1 -0
  179. package/dist/core/tool-gate-controller.d.ts +36 -0
  180. package/dist/core/tool-gate-controller.d.ts.map +1 -0
  181. package/dist/core/tool-gate-controller.js +94 -0
  182. package/dist/core/tool-gate-controller.js.map +1 -0
  183. package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
  184. package/dist/core/tools/artifact-retrieve.js +1 -1
  185. package/dist/core/tools/artifact-retrieve.js.map +1 -1
  186. package/dist/core/tools/bash.d.ts +4 -2
  187. package/dist/core/tools/bash.d.ts.map +1 -1
  188. package/dist/core/tools/bash.js +49 -7
  189. package/dist/core/tools/bash.js.map +1 -1
  190. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  191. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  192. package/dist/core/tools/file-mutation-queue.js +61 -1
  193. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  194. package/dist/core/tools/find.d.ts +1 -1
  195. package/dist/core/tools/find.d.ts.map +1 -1
  196. package/dist/core/tools/find.js +1 -1
  197. package/dist/core/tools/find.js.map +1 -1
  198. package/dist/core/tools/grep.d.ts +1 -1
  199. package/dist/core/tools/grep.d.ts.map +1 -1
  200. package/dist/core/tools/grep.js +1 -1
  201. package/dist/core/tools/grep.js.map +1 -1
  202. package/dist/core/tools/index.d.ts +1 -1
  203. package/dist/core/tools/index.d.ts.map +1 -1
  204. package/dist/core/tools/index.js +1 -1
  205. package/dist/core/tools/index.js.map +1 -1
  206. package/dist/core/tools/ls.d.ts +1 -1
  207. package/dist/core/tools/ls.d.ts.map +1 -1
  208. package/dist/core/tools/ls.js +1 -1
  209. package/dist/core/tools/ls.js.map +1 -1
  210. package/dist/core/tools/output-accumulator.d.ts +1 -1
  211. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  212. package/dist/core/tools/output-accumulator.js +1 -1
  213. package/dist/core/tools/output-accumulator.js.map +1 -1
  214. package/dist/core/tools/read.d.ts +1 -1
  215. package/dist/core/tools/read.d.ts.map +1 -1
  216. package/dist/core/tools/read.js +1 -1
  217. package/dist/core/tools/read.js.map +1 -1
  218. package/dist/core/tools/render-utils.d.ts.map +1 -1
  219. package/dist/core/tools/render-utils.js +1 -1
  220. package/dist/core/tools/render-utils.js.map +1 -1
  221. package/dist/index.d.ts +2 -3
  222. package/dist/index.d.ts.map +1 -1
  223. package/dist/index.js +3 -4
  224. package/dist/index.js.map +1 -1
  225. package/dist/main.d.ts.map +1 -1
  226. package/dist/main.js +13 -12
  227. package/dist/main.js.map +1 -1
  228. package/dist/modes/interactive/auth-dialogs-controller.d.ts +59 -0
  229. package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -0
  230. package/dist/modes/interactive/auth-dialogs-controller.js +398 -0
  231. package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -0
  232. package/dist/modes/interactive/auto-learn-controller.d.ts +168 -0
  233. package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -0
  234. package/dist/modes/interactive/auto-learn-controller.js +1239 -0
  235. package/dist/modes/interactive/auto-learn-controller.js.map +1 -0
  236. package/dist/modes/interactive/autocomplete-provider.d.ts +26 -0
  237. package/dist/modes/interactive/autocomplete-provider.d.ts.map +1 -0
  238. package/dist/modes/interactive/autocomplete-provider.js +103 -0
  239. package/dist/modes/interactive/autocomplete-provider.js.map +1 -0
  240. package/dist/modes/interactive/autonomy-commands.d.ts +38 -0
  241. package/dist/modes/interactive/autonomy-commands.d.ts.map +1 -0
  242. package/dist/modes/interactive/autonomy-commands.js +142 -0
  243. package/dist/modes/interactive/autonomy-commands.js.map +1 -0
  244. package/dist/modes/interactive/clipboard-input.d.ts +37 -0
  245. package/dist/modes/interactive/clipboard-input.d.ts.map +1 -0
  246. package/dist/modes/interactive/clipboard-input.js +59 -0
  247. package/dist/modes/interactive/clipboard-input.js.map +1 -0
  248. package/dist/modes/interactive/compaction-queue.d.ts +30 -0
  249. package/dist/modes/interactive/compaction-queue.d.ts.map +1 -0
  250. package/dist/modes/interactive/compaction-queue.js +91 -0
  251. package/dist/modes/interactive/compaction-queue.js.map +1 -0
  252. package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
  253. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  254. package/dist/modes/interactive/components/bash-execution.js +1 -1
  255. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  256. package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
  257. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  258. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  259. package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
  260. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  261. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  262. package/dist/modes/interactive/components/custom-message.d.ts +1 -1
  263. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  264. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  265. package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
  266. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  268. package/dist/modes/interactive/components/session-selector.d.ts +1 -1
  269. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  271. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  272. package/dist/modes/interactive/components/tool-execution.js +2 -2
  273. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  274. package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
  275. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  276. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  277. package/dist/modes/interactive/config-backup.d.ts +27 -0
  278. package/dist/modes/interactive/config-backup.d.ts.map +1 -0
  279. package/dist/modes/interactive/config-backup.js +146 -0
  280. package/dist/modes/interactive/config-backup.js.map +1 -0
  281. package/dist/modes/interactive/editor-overlay-host.d.ts +48 -0
  282. package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -0
  283. package/dist/modes/interactive/editor-overlay-host.js +43 -0
  284. package/dist/modes/interactive/editor-overlay-host.js.map +1 -0
  285. package/dist/modes/interactive/extension-ui-host.d.ts +165 -0
  286. package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -0
  287. package/dist/modes/interactive/extension-ui-host.js +610 -0
  288. package/dist/modes/interactive/extension-ui-host.js.map +1 -0
  289. package/dist/modes/interactive/external-editor.d.ts +18 -0
  290. package/dist/modes/interactive/external-editor.d.ts.map +1 -0
  291. package/dist/modes/interactive/external-editor.js +107 -0
  292. package/dist/modes/interactive/external-editor.js.map +1 -0
  293. package/dist/modes/interactive/history-reload-math.d.ts +24 -0
  294. package/dist/modes/interactive/history-reload-math.d.ts.map +1 -0
  295. package/dist/modes/interactive/history-reload-math.js +129 -0
  296. package/dist/modes/interactive/history-reload-math.js.map +1 -0
  297. package/dist/modes/interactive/interactive-mode.d.ts +22 -238
  298. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  299. package/dist/modes/interactive/interactive-mode.js +714 -5910
  300. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  301. package/dist/modes/interactive/key-handlers.d.ts +46 -0
  302. package/dist/modes/interactive/key-handlers.d.ts.map +1 -0
  303. package/dist/modes/interactive/key-handlers.js +80 -0
  304. package/dist/modes/interactive/key-handlers.js.map +1 -0
  305. package/dist/modes/interactive/local-model-commands.d.ts +68 -0
  306. package/dist/modes/interactive/local-model-commands.d.ts.map +1 -0
  307. package/dist/modes/interactive/local-model-commands.js +288 -0
  308. package/dist/modes/interactive/local-model-commands.js.map +1 -0
  309. package/dist/modes/interactive/profile-menu-controller.d.ts +77 -0
  310. package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -0
  311. package/dist/modes/interactive/profile-menu-controller.js +917 -0
  312. package/dist/modes/interactive/profile-menu-controller.js.map +1 -0
  313. package/dist/modes/interactive/report-commands.d.ts +46 -0
  314. package/dist/modes/interactive/report-commands.d.ts.map +1 -0
  315. package/dist/modes/interactive/report-commands.js +255 -0
  316. package/dist/modes/interactive/report-commands.js.map +1 -0
  317. package/dist/modes/interactive/resource-display.d.ts +73 -0
  318. package/dist/modes/interactive/resource-display.d.ts.map +1 -0
  319. package/dist/modes/interactive/resource-display.js +278 -0
  320. package/dist/modes/interactive/resource-display.js.map +1 -0
  321. package/dist/modes/interactive/resource-shell-commands.d.ts +64 -0
  322. package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -0
  323. package/dist/modes/interactive/resource-shell-commands.js +202 -0
  324. package/dist/modes/interactive/resource-shell-commands.js.map +1 -0
  325. package/dist/modes/interactive/session-flow-commands.d.ts +139 -0
  326. package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -0
  327. package/dist/modes/interactive/session-flow-commands.js +458 -0
  328. package/dist/modes/interactive/session-flow-commands.js.map +1 -0
  329. package/dist/modes/interactive/session-io-commands.d.ts +73 -0
  330. package/dist/modes/interactive/session-io-commands.d.ts.map +1 -0
  331. package/dist/modes/interactive/session-io-commands.js +202 -0
  332. package/dist/modes/interactive/session-io-commands.js.map +1 -0
  333. package/dist/modes/interactive/settings-selector-flow.d.ts +42 -0
  334. package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -0
  335. package/dist/modes/interactive/settings-selector-flow.js +287 -0
  336. package/dist/modes/interactive/settings-selector-flow.js.map +1 -0
  337. package/dist/modes/interactive/signal-lifecycle.d.ts +55 -0
  338. package/dist/modes/interactive/signal-lifecycle.d.ts.map +1 -0
  339. package/dist/modes/interactive/signal-lifecycle.js +177 -0
  340. package/dist/modes/interactive/signal-lifecycle.js.map +1 -0
  341. package/dist/modes/interactive/startup-checks.d.ts +38 -0
  342. package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
  343. package/dist/modes/interactive/startup-checks.js +189 -0
  344. package/dist/modes/interactive/startup-checks.js.map +1 -0
  345. package/dist/modes/rpc/rpc-client.d.ts +1 -1
  346. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  347. package/dist/modes/rpc/rpc-client.js.map +1 -1
  348. package/dist/modes/rpc/rpc-types.d.ts +1 -1
  349. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  350. package/dist/modes/rpc/rpc-types.js.map +1 -1
  351. package/dist/utils/paths.d.ts +2 -14
  352. package/dist/utils/paths.d.ts.map +1 -1
  353. package/dist/utils/paths.js +5 -30
  354. package/dist/utils/paths.js.map +1 -1
  355. package/dist/utils/process-memory.d.ts +8 -0
  356. package/dist/utils/process-memory.d.ts.map +1 -0
  357. package/dist/utils/process-memory.js +11 -0
  358. package/dist/utils/process-memory.js.map +1 -0
  359. package/dist/utils/shell.d.ts +0 -9
  360. package/dist/utils/shell.d.ts.map +1 -1
  361. package/dist/utils/shell.js +0 -37
  362. package/dist/utils/shell.js.map +1 -1
  363. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  364. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  365. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  366. package/examples/extensions/sandbox/package-lock.json +2 -2
  367. package/examples/extensions/sandbox/package.json +1 -1
  368. package/examples/extensions/with-deps/package-lock.json +2 -2
  369. package/examples/extensions/with-deps/package.json +1 -1
  370. package/examples/sdk/11-sessions.ts +8 -8
  371. package/examples/sdk/13-session-runtime.ts +1 -1
  372. package/npm-shrinkwrap.json +12 -12
  373. package/package.json +4 -4
  374. package/dist/core/compaction/branch-summarization.d.ts +0 -88
  375. package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
  376. package/dist/core/compaction/branch-summarization.js +0 -243
  377. package/dist/core/compaction/branch-summarization.js.map +0 -1
  378. package/dist/core/compaction/compaction.d.ts +0 -143
  379. package/dist/core/compaction/compaction.d.ts.map +0 -1
  380. package/dist/core/compaction/compaction.js +0 -659
  381. package/dist/core/compaction/compaction.js.map +0 -1
  382. package/dist/core/compaction/index.d.ts +0 -7
  383. package/dist/core/compaction/index.d.ts.map +0 -1
  384. package/dist/core/compaction/index.js +0 -7
  385. package/dist/core/compaction/index.js.map +0 -1
  386. package/dist/core/compaction/utils.d.ts +0 -38
  387. package/dist/core/compaction/utils.d.ts.map +0 -1
  388. package/dist/core/compaction/utils.js +0 -153
  389. package/dist/core/compaction/utils.js.map +0 -1
  390. package/dist/core/message-retention.d.ts +0 -26
  391. package/dist/core/message-retention.d.ts.map +0 -1
  392. package/dist/core/message-retention.js +0 -95
  393. package/dist/core/message-retention.js.map +0 -1
  394. package/dist/core/messages.d.ts +0 -77
  395. package/dist/core/messages.d.ts.map +0 -1
  396. package/dist/core/messages.js +0 -123
  397. package/dist/core/messages.js.map +0 -1
  398. package/dist/core/session-manager.d.ts +0 -337
  399. package/dist/core/session-manager.d.ts.map +0 -1
  400. package/dist/core/session-manager.js +0 -1328
  401. package/dist/core/session-manager.js.map +0 -1
  402. package/dist/core/tools/truncate.d.ts +0 -70
  403. package/dist/core/tools/truncate.d.ts.map +0 -1
  404. package/dist/core/tools/truncate.js +0 -215
  405. package/dist/core/tools/truncate.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/export-html/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAQ5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,oFAAoF;IACpF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACpF,4GAA4G;IAC5G,YAAY,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAChF,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACd;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACzD;AASD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAgMD;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,EAAE,EAAE,cAAc,EAClB,KAAK,CAAC,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAC9B,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BzG","sourcesContent":["import type { AgentState } from \"@caupulican/pi-agent-core\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { basename, join } from \"path\";\nimport { APP_NAME, getExportTemplateDir } from \"../../config.ts\";\nimport { getResolvedThemeColors, getThemeExportColors } from \"../../modes/interactive/theme/theme.ts\";\nimport { normalizePath, resolvePath } from \"../../utils/paths.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { SessionEntry } from \"../session-manager.ts\";\nimport { SessionManager } from \"../session-manager.ts\";\n\n/**\n * Interface for rendering custom tools to HTML.\n * Used by agent-session to pre-render extension tool output.\n */\nexport interface ToolHtmlRenderer {\n\t/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */\n\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;\n\t/** Render a tool result to HTML. Returns collapsed/expanded or undefined if tool has no custom renderer. */\n\trenderResult(\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\tdetails: unknown,\n\t\tisError: boolean,\n\t): { collapsed?: string; expanded?: string } | undefined;\n}\n\n/** Pre-rendered HTML for a custom tool call and result */\ninterface RenderedToolHtml {\n\tcallHtml?: string;\n\tresultHtmlCollapsed?: string;\n\tresultHtmlExpanded?: string;\n}\n\nexport interface ExportOptions {\n\toutputPath?: string;\n\tthemeName?: string;\n\t/** Optional tool renderer for custom tools */\n\ttoolRenderer?: ToolHtmlRenderer;\n}\n\n/** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */\nfunction parseColor(color: string): { r: number; g: number; b: number } | undefined {\n\tconst hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);\n\tif (hexMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(hexMatch[1], 16),\n\t\t\tg: Number.parseInt(hexMatch[2], 16),\n\t\t\tb: Number.parseInt(hexMatch[3], 16),\n\t\t};\n\t}\n\tconst rgbMatch = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n\tif (rgbMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(rgbMatch[1], 10),\n\t\t\tg: Number.parseInt(rgbMatch[2], 10),\n\t\t\tb: Number.parseInt(rgbMatch[3], 10),\n\t\t};\n\t}\n\treturn undefined;\n}\n\n/** Calculate relative luminance of a color (0-1, higher = lighter). */\nfunction getLuminance(r: number, g: number, b: number): number {\n\tconst toLinear = (c: number) => {\n\t\tconst s = c / 255;\n\t\treturn s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n\t};\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */\nfunction adjustBrightness(color: string, factor: number): string {\n\tconst parsed = parseColor(color);\n\tif (!parsed) return color;\n\tconst adjust = (c: number) => Math.min(255, Math.max(0, Math.round(c * factor)));\n\treturn `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;\n}\n\n/** Derive export background colors from a base color (e.g., userMessageBg). */\nfunction deriveExportColors(baseColor: string): { pageBg: string; cardBg: string; infoBg: string } {\n\tconst parsed = parseColor(baseColor);\n\tif (!parsed) {\n\t\treturn {\n\t\t\tpageBg: \"rgb(24, 24, 30)\",\n\t\t\tcardBg: \"rgb(30, 30, 36)\",\n\t\t\tinfoBg: \"rgb(60, 55, 40)\",\n\t\t};\n\t}\n\n\tconst luminance = getLuminance(parsed.r, parsed.g, parsed.b);\n\tconst isLight = luminance > 0.5;\n\n\tif (isLight) {\n\t\treturn {\n\t\t\tpageBg: adjustBrightness(baseColor, 0.96),\n\t\t\tcardBg: baseColor,\n\t\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,\n\t\t};\n\t}\n\treturn {\n\t\tpageBg: adjustBrightness(baseColor, 0.7),\n\t\tcardBg: adjustBrightness(baseColor, 0.85),\n\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,\n\t};\n}\n\n/**\n * Generate CSS custom property declarations from theme colors.\n */\nfunction generateThemeVars(themeName?: string): string {\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst lines: string[] = [];\n\tfor (const [key, value] of Object.entries(colors)) {\n\t\tlines.push(`--${key}: ${value};`);\n\t}\n\n\t// Use explicit theme export colors if available, otherwise derive from userMessageBg\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst userMessageBg = colors.userMessageBg || \"#343541\";\n\tconst derivedColors = deriveExportColors(userMessageBg);\n\n\tlines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);\n\tlines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);\n\tlines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);\n\n\treturn lines.join(\"\\n \");\n}\n\ninterface SessionData {\n\theader: ReturnType<SessionManager[\"getHeader\"]>;\n\tentries: ReturnType<SessionManager[\"getEntries\"]>;\n\tleafId: string | null;\n\tsystemPrompt?: string;\n\ttools?: Array<Pick<ToolDefinition, \"name\" | \"description\" | \"parameters\">>;\n\t/** Pre-rendered HTML for custom tool calls/results, keyed by tool call ID */\n\trenderedTools?: Record<string, RenderedToolHtml>;\n}\n\n/**\n * Core HTML generation logic shared by both export functions.\n */\nfunction generateHtml(sessionData: SessionData, themeName?: string): string {\n\tconst templateDir = getExportTemplateDir();\n\tconst template = readFileSync(join(templateDir, \"template.html\"), \"utf-8\");\n\tconst templateCss = readFileSync(join(templateDir, \"template.css\"), \"utf-8\");\n\tconst templateJs = readFileSync(join(templateDir, \"template.js\"), \"utf-8\");\n\tconst markedJs = readFileSync(join(templateDir, \"vendor\", \"marked.min.js\"), \"utf-8\");\n\tconst hljsJs = readFileSync(join(templateDir, \"vendor\", \"highlight.min.js\"), \"utf-8\");\n\n\tconst themeVars = generateThemeVars(themeName);\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst derivedExportColors = deriveExportColors(colors.userMessageBg || \"#343541\");\n\tconst bodyBg = themeExport.pageBg ?? derivedExportColors.pageBg;\n\tconst containerBg = themeExport.cardBg ?? derivedExportColors.cardBg;\n\tconst infoBg = themeExport.infoBg ?? derivedExportColors.infoBg;\n\n\t// Base64 encode session data to avoid escaping issues\n\tconst sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString(\"base64\");\n\n\t// Build the CSS with theme variables injected\n\tconst css = templateCss\n\t\t.replace(\"{{THEME_VARS}}\", themeVars)\n\t\t.replace(\"{{BODY_BG}}\", bodyBg)\n\t\t.replace(\"{{CONTAINER_BG}}\", containerBg)\n\t\t.replace(\"{{INFO_BG}}\", infoBg);\n\n\treturn template\n\t\t.replace(\"{{CSS}}\", css)\n\t\t.replace(\"{{JS}}\", templateJs)\n\t\t.replace(\"{{SESSION_DATA}}\", sessionDataBase64)\n\t\t.replace(\"{{MARKED_JS}}\", markedJs)\n\t\t.replace(\"{{HIGHLIGHT_JS}}\", hljsJs);\n}\n\n/** Tools rendered directly by the HTML template (not pre-rendered via TUI→ANSI→HTML pipeline) */\nconst TEMPLATE_RENDERED_TOOLS = new Set([\"bash\", \"read\", \"write\", \"edit\", \"ls\"]);\n\n/**\n * Pre-render custom tools to HTML using their TUI renderers.\n */\nfunction preRenderCustomTools(\n\tentries: SessionEntry[],\n\ttoolRenderer: ToolHtmlRenderer,\n): Record<string, RenderedToolHtml> {\n\tconst renderedTools: Record<string, RenderedToolHtml> = {};\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"message\") continue;\n\t\tconst msg = entry.message;\n\n\t\t// Find tool calls in assistant messages\n\t\tif (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"toolCall\" && !TEMPLATE_RENDERED_TOOLS.has(block.name)) {\n\t\t\t\t\tconst callHtml = toolRenderer.renderCall(block.id, block.name, block.arguments);\n\t\t\t\t\tif (callHtml) {\n\t\t\t\t\t\trenderedTools[block.id] = { callHtml };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find tool results\n\t\tif (msg.role === \"toolResult\" && msg.toolCallId) {\n\t\t\tconst toolName = msg.toolName || \"\";\n\t\t\t// Only render if we have a pre-rendered call OR it's not template-rendered\n\t\t\tconst existing = renderedTools[msg.toolCallId];\n\t\t\tif (existing || !TEMPLATE_RENDERED_TOOLS.has(toolName)) {\n\t\t\t\tconst rendered = toolRenderer.renderResult(\n\t\t\t\t\tmsg.toolCallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\tmsg.content,\n\t\t\t\t\tmsg.details,\n\t\t\t\t\tmsg.isError || false,\n\t\t\t\t);\n\t\t\t\tif (rendered) {\n\t\t\t\t\trenderedTools[msg.toolCallId] = {\n\t\t\t\t\t\t...existing,\n\t\t\t\t\t\tresultHtmlCollapsed: rendered.collapsed,\n\t\t\t\t\t\tresultHtmlExpanded: rendered.expanded,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn renderedTools;\n}\n\n/**\n * Export session to HTML using SessionManager and AgentState.\n * Used by TUI's /export command.\n */\nexport async function exportSessionToHtml(\n\tsm: SessionManager,\n\tstate?: AgentState,\n\toptions?: ExportOptions | string,\n): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\n\tconst sessionFile = sm.getSessionFile();\n\tif (!sessionFile) {\n\t\tthrow new Error(\"Cannot export in-memory session to HTML\");\n\t}\n\tif (!existsSync(sessionFile)) {\n\t\tthrow new Error(\"Nothing to export yet - start a conversation first\");\n\t}\n\n\tconst entries = sm.getEntries();\n\n\t// Pre-render custom tools if a tool renderer is provided\n\tlet renderedTools: Record<string, RenderedToolHtml> | undefined;\n\tif (opts.toolRenderer) {\n\t\trenderedTools = preRenderCustomTools(entries, opts.toolRenderer);\n\t\t// Only include if we actually rendered something\n\t\tif (Object.keys(renderedTools).length === 0) {\n\t\t\trenderedTools = undefined;\n\t\t}\n\t}\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries,\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: state?.systemPrompt,\n\t\ttools: state?.tools?.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),\n\t\trenderedTools,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst sessionBasename = basename(sessionFile, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${sessionBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n\n/**\n * Export session file to HTML (standalone, without AgentState).\n * Used by CLI for exporting arbitrary session files.\n */\nexport async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\tconst resolvedInputPath = resolvePath(inputPath);\n\n\tif (!existsSync(resolvedInputPath)) {\n\t\tthrow new Error(`File not found: ${resolvedInputPath}`);\n\t}\n\n\tconst sm = SessionManager.open(resolvedInputPath);\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries: sm.getEntries(),\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: undefined,\n\t\ttools: undefined,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst inputBasename = basename(resolvedInputPath, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${inputBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n"]}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/export-html/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,gCAAgC,CAAC;AASnF;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,oFAAoF;IACpF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IACpF,4GAA4G;IAC5G,YAAY,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,EAChF,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,GACd;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CACzD;AASD,MAAM,WAAW,aAAa;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAgMD;;;GAGG;AACH,wBAAsB,mBAAmB,CACxC,EAAE,EAAE,cAAc,EAClB,KAAK,CAAC,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAC9B,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BzG","sourcesContent":["import type { AgentState } from \"@caupulican/pi-agent-core\";\nimport type { SessionEntry, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { basename, join } from \"path\";\nimport { APP_NAME, getExportTemplateDir } from \"../../config.ts\";\nimport { getResolvedThemeColors, getThemeExportColors } from \"../../modes/interactive/theme/theme.ts\";\nimport { normalizePath, resolvePath } from \"../../utils/paths.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { openSession } from \"../session-manager-factory.ts\";\n\n/**\n * Interface for rendering custom tools to HTML.\n * Used by agent-session to pre-render extension tool output.\n */\nexport interface ToolHtmlRenderer {\n\t/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */\n\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;\n\t/** Render a tool result to HTML. Returns collapsed/expanded or undefined if tool has no custom renderer. */\n\trenderResult(\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\tdetails: unknown,\n\t\tisError: boolean,\n\t): { collapsed?: string; expanded?: string } | undefined;\n}\n\n/** Pre-rendered HTML for a custom tool call and result */\ninterface RenderedToolHtml {\n\tcallHtml?: string;\n\tresultHtmlCollapsed?: string;\n\tresultHtmlExpanded?: string;\n}\n\nexport interface ExportOptions {\n\toutputPath?: string;\n\tthemeName?: string;\n\t/** Optional tool renderer for custom tools */\n\ttoolRenderer?: ToolHtmlRenderer;\n}\n\n/** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */\nfunction parseColor(color: string): { r: number; g: number; b: number } | undefined {\n\tconst hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);\n\tif (hexMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(hexMatch[1], 16),\n\t\t\tg: Number.parseInt(hexMatch[2], 16),\n\t\t\tb: Number.parseInt(hexMatch[3], 16),\n\t\t};\n\t}\n\tconst rgbMatch = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n\tif (rgbMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(rgbMatch[1], 10),\n\t\t\tg: Number.parseInt(rgbMatch[2], 10),\n\t\t\tb: Number.parseInt(rgbMatch[3], 10),\n\t\t};\n\t}\n\treturn undefined;\n}\n\n/** Calculate relative luminance of a color (0-1, higher = lighter). */\nfunction getLuminance(r: number, g: number, b: number): number {\n\tconst toLinear = (c: number) => {\n\t\tconst s = c / 255;\n\t\treturn s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n\t};\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */\nfunction adjustBrightness(color: string, factor: number): string {\n\tconst parsed = parseColor(color);\n\tif (!parsed) return color;\n\tconst adjust = (c: number) => Math.min(255, Math.max(0, Math.round(c * factor)));\n\treturn `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;\n}\n\n/** Derive export background colors from a base color (e.g., userMessageBg). */\nfunction deriveExportColors(baseColor: string): { pageBg: string; cardBg: string; infoBg: string } {\n\tconst parsed = parseColor(baseColor);\n\tif (!parsed) {\n\t\treturn {\n\t\t\tpageBg: \"rgb(24, 24, 30)\",\n\t\t\tcardBg: \"rgb(30, 30, 36)\",\n\t\t\tinfoBg: \"rgb(60, 55, 40)\",\n\t\t};\n\t}\n\n\tconst luminance = getLuminance(parsed.r, parsed.g, parsed.b);\n\tconst isLight = luminance > 0.5;\n\n\tif (isLight) {\n\t\treturn {\n\t\t\tpageBg: adjustBrightness(baseColor, 0.96),\n\t\t\tcardBg: baseColor,\n\t\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,\n\t\t};\n\t}\n\treturn {\n\t\tpageBg: adjustBrightness(baseColor, 0.7),\n\t\tcardBg: adjustBrightness(baseColor, 0.85),\n\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,\n\t};\n}\n\n/**\n * Generate CSS custom property declarations from theme colors.\n */\nfunction generateThemeVars(themeName?: string): string {\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst lines: string[] = [];\n\tfor (const [key, value] of Object.entries(colors)) {\n\t\tlines.push(`--${key}: ${value};`);\n\t}\n\n\t// Use explicit theme export colors if available, otherwise derive from userMessageBg\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst userMessageBg = colors.userMessageBg || \"#343541\";\n\tconst derivedColors = deriveExportColors(userMessageBg);\n\n\tlines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);\n\tlines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);\n\tlines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);\n\n\treturn lines.join(\"\\n \");\n}\n\ninterface SessionData {\n\theader: ReturnType<SessionManager[\"getHeader\"]>;\n\tentries: ReturnType<SessionManager[\"getEntries\"]>;\n\tleafId: string | null;\n\tsystemPrompt?: string;\n\ttools?: Array<Pick<ToolDefinition, \"name\" | \"description\" | \"parameters\">>;\n\t/** Pre-rendered HTML for custom tool calls/results, keyed by tool call ID */\n\trenderedTools?: Record<string, RenderedToolHtml>;\n}\n\n/**\n * Core HTML generation logic shared by both export functions.\n */\nfunction generateHtml(sessionData: SessionData, themeName?: string): string {\n\tconst templateDir = getExportTemplateDir();\n\tconst template = readFileSync(join(templateDir, \"template.html\"), \"utf-8\");\n\tconst templateCss = readFileSync(join(templateDir, \"template.css\"), \"utf-8\");\n\tconst templateJs = readFileSync(join(templateDir, \"template.js\"), \"utf-8\");\n\tconst markedJs = readFileSync(join(templateDir, \"vendor\", \"marked.min.js\"), \"utf-8\");\n\tconst hljsJs = readFileSync(join(templateDir, \"vendor\", \"highlight.min.js\"), \"utf-8\");\n\n\tconst themeVars = generateThemeVars(themeName);\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst derivedExportColors = deriveExportColors(colors.userMessageBg || \"#343541\");\n\tconst bodyBg = themeExport.pageBg ?? derivedExportColors.pageBg;\n\tconst containerBg = themeExport.cardBg ?? derivedExportColors.cardBg;\n\tconst infoBg = themeExport.infoBg ?? derivedExportColors.infoBg;\n\n\t// Base64 encode session data to avoid escaping issues\n\tconst sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString(\"base64\");\n\n\t// Build the CSS with theme variables injected\n\tconst css = templateCss\n\t\t.replace(\"{{THEME_VARS}}\", themeVars)\n\t\t.replace(\"{{BODY_BG}}\", bodyBg)\n\t\t.replace(\"{{CONTAINER_BG}}\", containerBg)\n\t\t.replace(\"{{INFO_BG}}\", infoBg);\n\n\treturn template\n\t\t.replace(\"{{CSS}}\", css)\n\t\t.replace(\"{{JS}}\", templateJs)\n\t\t.replace(\"{{SESSION_DATA}}\", sessionDataBase64)\n\t\t.replace(\"{{MARKED_JS}}\", markedJs)\n\t\t.replace(\"{{HIGHLIGHT_JS}}\", hljsJs);\n}\n\n/** Tools rendered directly by the HTML template (not pre-rendered via TUI→ANSI→HTML pipeline) */\nconst TEMPLATE_RENDERED_TOOLS = new Set([\"bash\", \"read\", \"write\", \"edit\", \"ls\"]);\n\n/**\n * Pre-render custom tools to HTML using their TUI renderers.\n */\nfunction preRenderCustomTools(\n\tentries: SessionEntry[],\n\ttoolRenderer: ToolHtmlRenderer,\n): Record<string, RenderedToolHtml> {\n\tconst renderedTools: Record<string, RenderedToolHtml> = {};\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"message\") continue;\n\t\tconst msg = entry.message;\n\n\t\t// Find tool calls in assistant messages\n\t\tif (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"toolCall\" && !TEMPLATE_RENDERED_TOOLS.has(block.name)) {\n\t\t\t\t\tconst callHtml = toolRenderer.renderCall(block.id, block.name, block.arguments);\n\t\t\t\t\tif (callHtml) {\n\t\t\t\t\t\trenderedTools[block.id] = { callHtml };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find tool results\n\t\tif (msg.role === \"toolResult\" && msg.toolCallId) {\n\t\t\tconst toolName = msg.toolName || \"\";\n\t\t\t// Only render if we have a pre-rendered call OR it's not template-rendered\n\t\t\tconst existing = renderedTools[msg.toolCallId];\n\t\t\tif (existing || !TEMPLATE_RENDERED_TOOLS.has(toolName)) {\n\t\t\t\tconst rendered = toolRenderer.renderResult(\n\t\t\t\t\tmsg.toolCallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\tmsg.content,\n\t\t\t\t\tmsg.details,\n\t\t\t\t\tmsg.isError || false,\n\t\t\t\t);\n\t\t\t\tif (rendered) {\n\t\t\t\t\trenderedTools[msg.toolCallId] = {\n\t\t\t\t\t\t...existing,\n\t\t\t\t\t\tresultHtmlCollapsed: rendered.collapsed,\n\t\t\t\t\t\tresultHtmlExpanded: rendered.expanded,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn renderedTools;\n}\n\n/**\n * Export session to HTML using SessionManager and AgentState.\n * Used by TUI's /export command.\n */\nexport async function exportSessionToHtml(\n\tsm: SessionManager,\n\tstate?: AgentState,\n\toptions?: ExportOptions | string,\n): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\n\tconst sessionFile = sm.getSessionFile();\n\tif (!sessionFile) {\n\t\tthrow new Error(\"Cannot export in-memory session to HTML\");\n\t}\n\tif (!existsSync(sessionFile)) {\n\t\tthrow new Error(\"Nothing to export yet - start a conversation first\");\n\t}\n\n\tconst entries = sm.getEntries();\n\n\t// Pre-render custom tools if a tool renderer is provided\n\tlet renderedTools: Record<string, RenderedToolHtml> | undefined;\n\tif (opts.toolRenderer) {\n\t\trenderedTools = preRenderCustomTools(entries, opts.toolRenderer);\n\t\t// Only include if we actually rendered something\n\t\tif (Object.keys(renderedTools).length === 0) {\n\t\t\trenderedTools = undefined;\n\t\t}\n\t}\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries,\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: state?.systemPrompt,\n\t\ttools: state?.tools?.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),\n\t\trenderedTools,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst sessionBasename = basename(sessionFile, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${sessionBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n\n/**\n * Export session file to HTML (standalone, without AgentState).\n * Used by CLI for exporting arbitrary session files.\n */\nexport async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\tconst resolvedInputPath = resolvePath(inputPath);\n\n\tif (!existsSync(resolvedInputPath)) {\n\t\tthrow new Error(`File not found: ${resolvedInputPath}`);\n\t}\n\n\tconst sm = openSession(resolvedInputPath);\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries: sm.getEntries(),\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: undefined,\n\t\ttools: undefined,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst inputBasename = basename(resolvedInputPath, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${inputBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n"]}
@@ -3,7 +3,7 @@ import { basename, join } from "path";
3
3
  import { APP_NAME, getExportTemplateDir } from "../../config.js";
4
4
  import { getResolvedThemeColors, getThemeExportColors } from "../../modes/interactive/theme/theme.js";
5
5
  import { normalizePath, resolvePath } from "../../utils/paths.js";
6
- import { SessionManager } from "../session-manager.js";
6
+ import { openSession } from "../session-manager-factory.js";
7
7
  /** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */
8
8
  function parseColor(color) {
9
9
  const hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);
@@ -206,7 +206,7 @@ export async function exportFromFile(inputPath, options) {
206
206
  if (!existsSync(resolvedInputPath)) {
207
207
  throw new Error(`File not found: ${resolvedInputPath}`);
208
208
  }
209
- const sm = SessionManager.open(resolvedInputPath);
209
+ const sm = openSession(resolvedInputPath);
210
210
  const sessionData = {
211
211
  header: sm.getHeader(),
212
212
  entries: sm.getEntries(),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/export-html/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentState } from \"@caupulican/pi-agent-core\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { basename, join } from \"path\";\nimport { APP_NAME, getExportTemplateDir } from \"../../config.ts\";\nimport { getResolvedThemeColors, getThemeExportColors } from \"../../modes/interactive/theme/theme.ts\";\nimport { normalizePath, resolvePath } from \"../../utils/paths.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport type { SessionEntry } from \"../session-manager.ts\";\nimport { SessionManager } from \"../session-manager.ts\";\n\n/**\n * Interface for rendering custom tools to HTML.\n * Used by agent-session to pre-render extension tool output.\n */\nexport interface ToolHtmlRenderer {\n\t/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */\n\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;\n\t/** Render a tool result to HTML. Returns collapsed/expanded or undefined if tool has no custom renderer. */\n\trenderResult(\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\tdetails: unknown,\n\t\tisError: boolean,\n\t): { collapsed?: string; expanded?: string } | undefined;\n}\n\n/** Pre-rendered HTML for a custom tool call and result */\ninterface RenderedToolHtml {\n\tcallHtml?: string;\n\tresultHtmlCollapsed?: string;\n\tresultHtmlExpanded?: string;\n}\n\nexport interface ExportOptions {\n\toutputPath?: string;\n\tthemeName?: string;\n\t/** Optional tool renderer for custom tools */\n\ttoolRenderer?: ToolHtmlRenderer;\n}\n\n/** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */\nfunction parseColor(color: string): { r: number; g: number; b: number } | undefined {\n\tconst hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);\n\tif (hexMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(hexMatch[1], 16),\n\t\t\tg: Number.parseInt(hexMatch[2], 16),\n\t\t\tb: Number.parseInt(hexMatch[3], 16),\n\t\t};\n\t}\n\tconst rgbMatch = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n\tif (rgbMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(rgbMatch[1], 10),\n\t\t\tg: Number.parseInt(rgbMatch[2], 10),\n\t\t\tb: Number.parseInt(rgbMatch[3], 10),\n\t\t};\n\t}\n\treturn undefined;\n}\n\n/** Calculate relative luminance of a color (0-1, higher = lighter). */\nfunction getLuminance(r: number, g: number, b: number): number {\n\tconst toLinear = (c: number) => {\n\t\tconst s = c / 255;\n\t\treturn s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n\t};\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */\nfunction adjustBrightness(color: string, factor: number): string {\n\tconst parsed = parseColor(color);\n\tif (!parsed) return color;\n\tconst adjust = (c: number) => Math.min(255, Math.max(0, Math.round(c * factor)));\n\treturn `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;\n}\n\n/** Derive export background colors from a base color (e.g., userMessageBg). */\nfunction deriveExportColors(baseColor: string): { pageBg: string; cardBg: string; infoBg: string } {\n\tconst parsed = parseColor(baseColor);\n\tif (!parsed) {\n\t\treturn {\n\t\t\tpageBg: \"rgb(24, 24, 30)\",\n\t\t\tcardBg: \"rgb(30, 30, 36)\",\n\t\t\tinfoBg: \"rgb(60, 55, 40)\",\n\t\t};\n\t}\n\n\tconst luminance = getLuminance(parsed.r, parsed.g, parsed.b);\n\tconst isLight = luminance > 0.5;\n\n\tif (isLight) {\n\t\treturn {\n\t\t\tpageBg: adjustBrightness(baseColor, 0.96),\n\t\t\tcardBg: baseColor,\n\t\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,\n\t\t};\n\t}\n\treturn {\n\t\tpageBg: adjustBrightness(baseColor, 0.7),\n\t\tcardBg: adjustBrightness(baseColor, 0.85),\n\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,\n\t};\n}\n\n/**\n * Generate CSS custom property declarations from theme colors.\n */\nfunction generateThemeVars(themeName?: string): string {\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst lines: string[] = [];\n\tfor (const [key, value] of Object.entries(colors)) {\n\t\tlines.push(`--${key}: ${value};`);\n\t}\n\n\t// Use explicit theme export colors if available, otherwise derive from userMessageBg\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst userMessageBg = colors.userMessageBg || \"#343541\";\n\tconst derivedColors = deriveExportColors(userMessageBg);\n\n\tlines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);\n\tlines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);\n\tlines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);\n\n\treturn lines.join(\"\\n \");\n}\n\ninterface SessionData {\n\theader: ReturnType<SessionManager[\"getHeader\"]>;\n\tentries: ReturnType<SessionManager[\"getEntries\"]>;\n\tleafId: string | null;\n\tsystemPrompt?: string;\n\ttools?: Array<Pick<ToolDefinition, \"name\" | \"description\" | \"parameters\">>;\n\t/** Pre-rendered HTML for custom tool calls/results, keyed by tool call ID */\n\trenderedTools?: Record<string, RenderedToolHtml>;\n}\n\n/**\n * Core HTML generation logic shared by both export functions.\n */\nfunction generateHtml(sessionData: SessionData, themeName?: string): string {\n\tconst templateDir = getExportTemplateDir();\n\tconst template = readFileSync(join(templateDir, \"template.html\"), \"utf-8\");\n\tconst templateCss = readFileSync(join(templateDir, \"template.css\"), \"utf-8\");\n\tconst templateJs = readFileSync(join(templateDir, \"template.js\"), \"utf-8\");\n\tconst markedJs = readFileSync(join(templateDir, \"vendor\", \"marked.min.js\"), \"utf-8\");\n\tconst hljsJs = readFileSync(join(templateDir, \"vendor\", \"highlight.min.js\"), \"utf-8\");\n\n\tconst themeVars = generateThemeVars(themeName);\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst derivedExportColors = deriveExportColors(colors.userMessageBg || \"#343541\");\n\tconst bodyBg = themeExport.pageBg ?? derivedExportColors.pageBg;\n\tconst containerBg = themeExport.cardBg ?? derivedExportColors.cardBg;\n\tconst infoBg = themeExport.infoBg ?? derivedExportColors.infoBg;\n\n\t// Base64 encode session data to avoid escaping issues\n\tconst sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString(\"base64\");\n\n\t// Build the CSS with theme variables injected\n\tconst css = templateCss\n\t\t.replace(\"{{THEME_VARS}}\", themeVars)\n\t\t.replace(\"{{BODY_BG}}\", bodyBg)\n\t\t.replace(\"{{CONTAINER_BG}}\", containerBg)\n\t\t.replace(\"{{INFO_BG}}\", infoBg);\n\n\treturn template\n\t\t.replace(\"{{CSS}}\", css)\n\t\t.replace(\"{{JS}}\", templateJs)\n\t\t.replace(\"{{SESSION_DATA}}\", sessionDataBase64)\n\t\t.replace(\"{{MARKED_JS}}\", markedJs)\n\t\t.replace(\"{{HIGHLIGHT_JS}}\", hljsJs);\n}\n\n/** Tools rendered directly by the HTML template (not pre-rendered via TUI→ANSI→HTML pipeline) */\nconst TEMPLATE_RENDERED_TOOLS = new Set([\"bash\", \"read\", \"write\", \"edit\", \"ls\"]);\n\n/**\n * Pre-render custom tools to HTML using their TUI renderers.\n */\nfunction preRenderCustomTools(\n\tentries: SessionEntry[],\n\ttoolRenderer: ToolHtmlRenderer,\n): Record<string, RenderedToolHtml> {\n\tconst renderedTools: Record<string, RenderedToolHtml> = {};\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"message\") continue;\n\t\tconst msg = entry.message;\n\n\t\t// Find tool calls in assistant messages\n\t\tif (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"toolCall\" && !TEMPLATE_RENDERED_TOOLS.has(block.name)) {\n\t\t\t\t\tconst callHtml = toolRenderer.renderCall(block.id, block.name, block.arguments);\n\t\t\t\t\tif (callHtml) {\n\t\t\t\t\t\trenderedTools[block.id] = { callHtml };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find tool results\n\t\tif (msg.role === \"toolResult\" && msg.toolCallId) {\n\t\t\tconst toolName = msg.toolName || \"\";\n\t\t\t// Only render if we have a pre-rendered call OR it's not template-rendered\n\t\t\tconst existing = renderedTools[msg.toolCallId];\n\t\t\tif (existing || !TEMPLATE_RENDERED_TOOLS.has(toolName)) {\n\t\t\t\tconst rendered = toolRenderer.renderResult(\n\t\t\t\t\tmsg.toolCallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\tmsg.content,\n\t\t\t\t\tmsg.details,\n\t\t\t\t\tmsg.isError || false,\n\t\t\t\t);\n\t\t\t\tif (rendered) {\n\t\t\t\t\trenderedTools[msg.toolCallId] = {\n\t\t\t\t\t\t...existing,\n\t\t\t\t\t\tresultHtmlCollapsed: rendered.collapsed,\n\t\t\t\t\t\tresultHtmlExpanded: rendered.expanded,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn renderedTools;\n}\n\n/**\n * Export session to HTML using SessionManager and AgentState.\n * Used by TUI's /export command.\n */\nexport async function exportSessionToHtml(\n\tsm: SessionManager,\n\tstate?: AgentState,\n\toptions?: ExportOptions | string,\n): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\n\tconst sessionFile = sm.getSessionFile();\n\tif (!sessionFile) {\n\t\tthrow new Error(\"Cannot export in-memory session to HTML\");\n\t}\n\tif (!existsSync(sessionFile)) {\n\t\tthrow new Error(\"Nothing to export yet - start a conversation first\");\n\t}\n\n\tconst entries = sm.getEntries();\n\n\t// Pre-render custom tools if a tool renderer is provided\n\tlet renderedTools: Record<string, RenderedToolHtml> | undefined;\n\tif (opts.toolRenderer) {\n\t\trenderedTools = preRenderCustomTools(entries, opts.toolRenderer);\n\t\t// Only include if we actually rendered something\n\t\tif (Object.keys(renderedTools).length === 0) {\n\t\t\trenderedTools = undefined;\n\t\t}\n\t}\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries,\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: state?.systemPrompt,\n\t\ttools: state?.tools?.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),\n\t\trenderedTools,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst sessionBasename = basename(sessionFile, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${sessionBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n\n/**\n * Export session file to HTML (standalone, without AgentState).\n * Used by CLI for exporting arbitrary session files.\n */\nexport async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\tconst resolvedInputPath = resolvePath(inputPath);\n\n\tif (!existsSync(resolvedInputPath)) {\n\t\tthrow new Error(`File not found: ${resolvedInputPath}`);\n\t}\n\n\tconst sm = SessionManager.open(resolvedInputPath);\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries: sm.getEntries(),\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: undefined,\n\t\ttools: undefined,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst inputBasename = basename(resolvedInputPath, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${inputBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/export-html/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentState } from \"@caupulican/pi-agent-core\";\nimport type { SessionEntry, SessionManager } from \"@caupulican/pi-agent-core/node\";\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { basename, join } from \"path\";\nimport { APP_NAME, getExportTemplateDir } from \"../../config.ts\";\nimport { getResolvedThemeColors, getThemeExportColors } from \"../../modes/interactive/theme/theme.ts\";\nimport { normalizePath, resolvePath } from \"../../utils/paths.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { openSession } from \"../session-manager-factory.ts\";\n\n/**\n * Interface for rendering custom tools to HTML.\n * Used by agent-session to pre-render extension tool output.\n */\nexport interface ToolHtmlRenderer {\n\t/** Render a tool call to HTML. Returns undefined if tool has no custom renderer. */\n\trenderCall(toolCallId: string, toolName: string, args: unknown): string | undefined;\n\t/** Render a tool result to HTML. Returns collapsed/expanded or undefined if tool has no custom renderer. */\n\trenderResult(\n\t\ttoolCallId: string,\n\t\ttoolName: string,\n\t\tresult: Array<{ type: string; text?: string; data?: string; mimeType?: string }>,\n\t\tdetails: unknown,\n\t\tisError: boolean,\n\t): { collapsed?: string; expanded?: string } | undefined;\n}\n\n/** Pre-rendered HTML for a custom tool call and result */\ninterface RenderedToolHtml {\n\tcallHtml?: string;\n\tresultHtmlCollapsed?: string;\n\tresultHtmlExpanded?: string;\n}\n\nexport interface ExportOptions {\n\toutputPath?: string;\n\tthemeName?: string;\n\t/** Optional tool renderer for custom tools */\n\ttoolRenderer?: ToolHtmlRenderer;\n}\n\n/** Parse a color string to RGB values. Supports hex (#RRGGBB) and rgb(r,g,b) formats. */\nfunction parseColor(color: string): { r: number; g: number; b: number } | undefined {\n\tconst hexMatch = color.match(/^#([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/);\n\tif (hexMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(hexMatch[1], 16),\n\t\t\tg: Number.parseInt(hexMatch[2], 16),\n\t\t\tb: Number.parseInt(hexMatch[3], 16),\n\t\t};\n\t}\n\tconst rgbMatch = color.match(/^rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)$/);\n\tif (rgbMatch) {\n\t\treturn {\n\t\t\tr: Number.parseInt(rgbMatch[1], 10),\n\t\t\tg: Number.parseInt(rgbMatch[2], 10),\n\t\t\tb: Number.parseInt(rgbMatch[3], 10),\n\t\t};\n\t}\n\treturn undefined;\n}\n\n/** Calculate relative luminance of a color (0-1, higher = lighter). */\nfunction getLuminance(r: number, g: number, b: number): number {\n\tconst toLinear = (c: number) => {\n\t\tconst s = c / 255;\n\t\treturn s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n\t};\n\treturn 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);\n}\n\n/** Adjust color brightness. Factor > 1 lightens, < 1 darkens. */\nfunction adjustBrightness(color: string, factor: number): string {\n\tconst parsed = parseColor(color);\n\tif (!parsed) return color;\n\tconst adjust = (c: number) => Math.min(255, Math.max(0, Math.round(c * factor)));\n\treturn `rgb(${adjust(parsed.r)}, ${adjust(parsed.g)}, ${adjust(parsed.b)})`;\n}\n\n/** Derive export background colors from a base color (e.g., userMessageBg). */\nfunction deriveExportColors(baseColor: string): { pageBg: string; cardBg: string; infoBg: string } {\n\tconst parsed = parseColor(baseColor);\n\tif (!parsed) {\n\t\treturn {\n\t\t\tpageBg: \"rgb(24, 24, 30)\",\n\t\t\tcardBg: \"rgb(30, 30, 36)\",\n\t\t\tinfoBg: \"rgb(60, 55, 40)\",\n\t\t};\n\t}\n\n\tconst luminance = getLuminance(parsed.r, parsed.g, parsed.b);\n\tconst isLight = luminance > 0.5;\n\n\tif (isLight) {\n\t\treturn {\n\t\t\tpageBg: adjustBrightness(baseColor, 0.96),\n\t\t\tcardBg: baseColor,\n\t\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 10)}, ${Math.min(255, parsed.g + 5)}, ${Math.max(0, parsed.b - 20)})`,\n\t\t};\n\t}\n\treturn {\n\t\tpageBg: adjustBrightness(baseColor, 0.7),\n\t\tcardBg: adjustBrightness(baseColor, 0.85),\n\t\tinfoBg: `rgb(${Math.min(255, parsed.r + 20)}, ${Math.min(255, parsed.g + 15)}, ${parsed.b})`,\n\t};\n}\n\n/**\n * Generate CSS custom property declarations from theme colors.\n */\nfunction generateThemeVars(themeName?: string): string {\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst lines: string[] = [];\n\tfor (const [key, value] of Object.entries(colors)) {\n\t\tlines.push(`--${key}: ${value};`);\n\t}\n\n\t// Use explicit theme export colors if available, otherwise derive from userMessageBg\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst userMessageBg = colors.userMessageBg || \"#343541\";\n\tconst derivedColors = deriveExportColors(userMessageBg);\n\n\tlines.push(`--exportPageBg: ${themeExport.pageBg ?? derivedColors.pageBg};`);\n\tlines.push(`--exportCardBg: ${themeExport.cardBg ?? derivedColors.cardBg};`);\n\tlines.push(`--exportInfoBg: ${themeExport.infoBg ?? derivedColors.infoBg};`);\n\n\treturn lines.join(\"\\n \");\n}\n\ninterface SessionData {\n\theader: ReturnType<SessionManager[\"getHeader\"]>;\n\tentries: ReturnType<SessionManager[\"getEntries\"]>;\n\tleafId: string | null;\n\tsystemPrompt?: string;\n\ttools?: Array<Pick<ToolDefinition, \"name\" | \"description\" | \"parameters\">>;\n\t/** Pre-rendered HTML for custom tool calls/results, keyed by tool call ID */\n\trenderedTools?: Record<string, RenderedToolHtml>;\n}\n\n/**\n * Core HTML generation logic shared by both export functions.\n */\nfunction generateHtml(sessionData: SessionData, themeName?: string): string {\n\tconst templateDir = getExportTemplateDir();\n\tconst template = readFileSync(join(templateDir, \"template.html\"), \"utf-8\");\n\tconst templateCss = readFileSync(join(templateDir, \"template.css\"), \"utf-8\");\n\tconst templateJs = readFileSync(join(templateDir, \"template.js\"), \"utf-8\");\n\tconst markedJs = readFileSync(join(templateDir, \"vendor\", \"marked.min.js\"), \"utf-8\");\n\tconst hljsJs = readFileSync(join(templateDir, \"vendor\", \"highlight.min.js\"), \"utf-8\");\n\n\tconst themeVars = generateThemeVars(themeName);\n\tconst colors = getResolvedThemeColors(themeName);\n\tconst themeExport = getThemeExportColors(themeName);\n\tconst derivedExportColors = deriveExportColors(colors.userMessageBg || \"#343541\");\n\tconst bodyBg = themeExport.pageBg ?? derivedExportColors.pageBg;\n\tconst containerBg = themeExport.cardBg ?? derivedExportColors.cardBg;\n\tconst infoBg = themeExport.infoBg ?? derivedExportColors.infoBg;\n\n\t// Base64 encode session data to avoid escaping issues\n\tconst sessionDataBase64 = Buffer.from(JSON.stringify(sessionData)).toString(\"base64\");\n\n\t// Build the CSS with theme variables injected\n\tconst css = templateCss\n\t\t.replace(\"{{THEME_VARS}}\", themeVars)\n\t\t.replace(\"{{BODY_BG}}\", bodyBg)\n\t\t.replace(\"{{CONTAINER_BG}}\", containerBg)\n\t\t.replace(\"{{INFO_BG}}\", infoBg);\n\n\treturn template\n\t\t.replace(\"{{CSS}}\", css)\n\t\t.replace(\"{{JS}}\", templateJs)\n\t\t.replace(\"{{SESSION_DATA}}\", sessionDataBase64)\n\t\t.replace(\"{{MARKED_JS}}\", markedJs)\n\t\t.replace(\"{{HIGHLIGHT_JS}}\", hljsJs);\n}\n\n/** Tools rendered directly by the HTML template (not pre-rendered via TUI→ANSI→HTML pipeline) */\nconst TEMPLATE_RENDERED_TOOLS = new Set([\"bash\", \"read\", \"write\", \"edit\", \"ls\"]);\n\n/**\n * Pre-render custom tools to HTML using their TUI renderers.\n */\nfunction preRenderCustomTools(\n\tentries: SessionEntry[],\n\ttoolRenderer: ToolHtmlRenderer,\n): Record<string, RenderedToolHtml> {\n\tconst renderedTools: Record<string, RenderedToolHtml> = {};\n\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"message\") continue;\n\t\tconst msg = entry.message;\n\n\t\t// Find tool calls in assistant messages\n\t\tif (msg.role === \"assistant\" && Array.isArray(msg.content)) {\n\t\t\tfor (const block of msg.content) {\n\t\t\t\tif (block.type === \"toolCall\" && !TEMPLATE_RENDERED_TOOLS.has(block.name)) {\n\t\t\t\t\tconst callHtml = toolRenderer.renderCall(block.id, block.name, block.arguments);\n\t\t\t\t\tif (callHtml) {\n\t\t\t\t\t\trenderedTools[block.id] = { callHtml };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Find tool results\n\t\tif (msg.role === \"toolResult\" && msg.toolCallId) {\n\t\t\tconst toolName = msg.toolName || \"\";\n\t\t\t// Only render if we have a pre-rendered call OR it's not template-rendered\n\t\t\tconst existing = renderedTools[msg.toolCallId];\n\t\t\tif (existing || !TEMPLATE_RENDERED_TOOLS.has(toolName)) {\n\t\t\t\tconst rendered = toolRenderer.renderResult(\n\t\t\t\t\tmsg.toolCallId,\n\t\t\t\t\ttoolName,\n\t\t\t\t\tmsg.content,\n\t\t\t\t\tmsg.details,\n\t\t\t\t\tmsg.isError || false,\n\t\t\t\t);\n\t\t\t\tif (rendered) {\n\t\t\t\t\trenderedTools[msg.toolCallId] = {\n\t\t\t\t\t\t...existing,\n\t\t\t\t\t\tresultHtmlCollapsed: rendered.collapsed,\n\t\t\t\t\t\tresultHtmlExpanded: rendered.expanded,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn renderedTools;\n}\n\n/**\n * Export session to HTML using SessionManager and AgentState.\n * Used by TUI's /export command.\n */\nexport async function exportSessionToHtml(\n\tsm: SessionManager,\n\tstate?: AgentState,\n\toptions?: ExportOptions | string,\n): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\n\tconst sessionFile = sm.getSessionFile();\n\tif (!sessionFile) {\n\t\tthrow new Error(\"Cannot export in-memory session to HTML\");\n\t}\n\tif (!existsSync(sessionFile)) {\n\t\tthrow new Error(\"Nothing to export yet - start a conversation first\");\n\t}\n\n\tconst entries = sm.getEntries();\n\n\t// Pre-render custom tools if a tool renderer is provided\n\tlet renderedTools: Record<string, RenderedToolHtml> | undefined;\n\tif (opts.toolRenderer) {\n\t\trenderedTools = preRenderCustomTools(entries, opts.toolRenderer);\n\t\t// Only include if we actually rendered something\n\t\tif (Object.keys(renderedTools).length === 0) {\n\t\t\trenderedTools = undefined;\n\t\t}\n\t}\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries,\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: state?.systemPrompt,\n\t\ttools: state?.tools?.map((t) => ({ name: t.name, description: t.description, parameters: t.parameters })),\n\t\trenderedTools,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst sessionBasename = basename(sessionFile, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${sessionBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n\n/**\n * Export session file to HTML (standalone, without AgentState).\n * Used by CLI for exporting arbitrary session files.\n */\nexport async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {\n\tconst opts: ExportOptions = typeof options === \"string\" ? { outputPath: options } : options || {};\n\tconst resolvedInputPath = resolvePath(inputPath);\n\n\tif (!existsSync(resolvedInputPath)) {\n\t\tthrow new Error(`File not found: ${resolvedInputPath}`);\n\t}\n\n\tconst sm = openSession(resolvedInputPath);\n\n\tconst sessionData: SessionData = {\n\t\theader: sm.getHeader(),\n\t\tentries: sm.getEntries(),\n\t\tleafId: sm.getLeafId(),\n\t\tsystemPrompt: undefined,\n\t\ttools: undefined,\n\t};\n\n\tconst html = generateHtml(sessionData, opts.themeName);\n\n\tlet outputPath = opts.outputPath ? normalizePath(opts.outputPath) : undefined;\n\tif (!outputPath) {\n\t\tconst inputBasename = basename(resolvedInputPath, \".jsonl\");\n\t\toutputPath = `${APP_NAME}-session-${inputBasename}.html`;\n\t}\n\n\twriteFileSync(outputPath, html, \"utf8\");\n\treturn outputPath;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAChH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiN3D,wBAAgB,oCAAoC,CACnD,cAAc,EAAE,MAAM,MAAM,EAAE,EAC9B,WAAW,EAAE,MAAM,QAAQ,EAAE,EAC7B,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,eAAe,EAClE,oBAAoB,CAAC,EAAE,MAAM;IAC5B,SAAS,EAAE,0BAA0B,CAAC;IACtC,eAAe,EAAE,2BAA2B,CAAC;CAC7C,GACC,cAAc,EAAE,CAsIlB","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport { Type } from \"typebox\";\nimport { estimateTokens } from \"../compaction/compaction.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"../context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"../context-gc.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from \"../messages.ts\";\nimport type { CompactionEntry, SessionEntry } from \"../session-manager.ts\";\nimport type { ToolDefinition, ToolInfo } from \"./types.ts\";\n\ntype ContextAuditParams = {\n\tmaxItems?: number;\n\tminTokens?: number;\n\tquery?: string;\n\tincludePreviews?: boolean;\n};\n\ntype AuditRow = {\n\tkind: string;\n\trole?: string;\n\tentryId?: string;\n\ttimestamp?: string;\n\ttokens: number;\n\tchars: number;\n\tlabel: string;\n\tpreview: string;\n};\n\nconst DEFAULT_MAX_ITEMS = 40;\nconst MAX_MAX_ITEMS = 200;\nconst DEFAULT_PREVIEW_CHARS = 220;\nconst MAX_PREVIEW_CHARS = 600;\n\nfunction estimateTextTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction cap(text: string, limit = DEFAULT_PREVIEW_CHARS): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\treturn compact.length > limit ? `${compact.slice(0, Math.max(0, limit - 1))}…` : compact;\n}\n\nfunction contentText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.map((part) => {\n\t\t\tif (!part || typeof part !== \"object\") return \"\";\n\t\t\tconst typed = part as { type?: string; text?: string; thinking?: string; name?: string; arguments?: unknown };\n\t\t\tif (typed.type === \"text\") return typed.text || \"\";\n\t\t\tif (typed.type === \"thinking\") return `[thinking ${typed.thinking?.length ?? 0} chars]`;\n\t\t\tif (typed.type === \"toolCall\")\n\t\t\t\treturn `[toolCall ${typed.name || \"unknown\"} ${JSON.stringify(typed.arguments ?? {})}]`;\n\t\t\tif (typed.type === \"image\") return \"[image]\";\n\t\t\treturn \"\";\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\n\nfunction messagePreview(message: AgentMessage): string {\n\tswitch (message.role) {\n\t\tcase \"assistant\":\n\t\tcase \"user\":\n\t\tcase \"toolResult\":\n\t\tcase \"custom\":\n\t\t\treturn contentText((message as { content?: unknown }).content);\n\t\tcase \"bashExecution\":\n\t\t\treturn `Ran ${message.command}\\n${message.output}`;\n\t\tcase \"branchSummary\":\n\t\tcase \"compactionSummary\":\n\t\t\treturn message.summary;\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\nfunction messageLabel(message: AgentMessage): string {\n\tif (message.role === \"assistant\") {\n\t\tconst toolCalls = message.content.filter((part) => part.type === \"toolCall\").length;\n\t\treturn toolCalls > 0 ? `assistant (${toolCalls} tool call${toolCalls === 1 ? \"\" : \"s\"})` : \"assistant\";\n\t}\n\tif (message.role === \"toolResult\") return `tool result: ${message.toolName}`;\n\tif (message.role === \"custom\") return `custom: ${message.customType}`;\n\tif (message.role === \"bashExecution\") return \"bash execution\";\n\tif (message.role === \"branchSummary\") return \"branch summary\";\n\tif (message.role === \"compactionSummary\") return \"compaction summary\";\n\treturn message.role;\n}\n\nfunction addRow(rows: AuditRow[], entry: SessionEntry, message: AgentMessage, kindOverride?: string) {\n\tconst preview = messagePreview(message);\n\trows.push({\n\t\tkind: kindOverride || entry.type,\n\t\trole: message.role,\n\t\tentryId: entry.id,\n\t\ttimestamp: entry.timestamp,\n\t\ttokens: estimateTokens(message),\n\t\tchars: preview.length,\n\t\tlabel: messageLabel(message),\n\t\tpreview: cap(preview),\n\t});\n}\n\nfunction messageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tif (entry.type === \"message\") return entry.message;\n\tif (entry.type === \"custom_message\") {\n\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\t}\n\treturn undefined;\n}\n\nfunction latestCompaction(entries: SessionEntry[]): CompactionEntry | undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"compaction\") return entry;\n\t}\n\treturn undefined;\n}\n\nfunction activeContextMessages(entries: SessionEntry[]): AgentMessage[] {\n\tconst messages: AgentMessage[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) messages.push(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\treturn messages;\n}\n\nfunction activeContextRows(entries: SessionEntry[]): AuditRow[] {\n\tconst rows: AuditRow[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) addRow(rows, entry, message);\n\t\t}\n\t\treturn rows;\n\t}\n\n\tconst compactionMessage = createCompactionSummaryMessage(\n\t\tcompaction.summary,\n\t\tcompaction.tokensBefore,\n\t\tcompaction.timestamp,\n\t);\n\taddRow(rows, compaction, compactionMessage, \"compaction\");\n\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\treturn rows;\n}\n\nfunction groupRows(rows: AuditRow[]): Array<[string, { count: number; tokens: number; chars: number }]> {\n\tconst groups = new Map<string, { count: number; tokens: number; chars: number }>();\n\tfor (const row of rows) {\n\t\tconst key = row.label;\n\t\tconst current = groups.get(key) ?? { count: 0, tokens: 0, chars: 0 };\n\t\tcurrent.count += 1;\n\t\tcurrent.tokens += row.tokens;\n\t\tcurrent.chars += row.chars;\n\t\tgroups.set(key, current);\n\t}\n\treturn [...groups.entries()].sort((a, b) => b[1].tokens - a[1].tokens);\n}\n\n/** Bounded, deterministic summary lines for the memory-retrieval/prompt-inclusion diagnostic (safe metadata only, no content). */\nfunction formatMemoryRetrievalLine(retrieval: MemoryRetrievalDiagnostics): string {\n\treturn `Memory retrieval: ${retrieval.enabled ? `enabled (max ${retrieval.maxResults} results)` : \"disabled\"}`;\n}\n\nfunction formatMemoryProviderLines(retrieval: MemoryRetrievalDiagnostics): string[] {\n\treturn retrieval.providerReports.map((providerReport) => {\n\t\tconst rejection =\n\t\t\tproviderReport.rejectionReasons.length > 0 ? `; rejected: ${providerReport.rejectionReasons.join(\", \")}` : \"\";\n\t\treturn ` provider ${providerReport.providerId}: ${providerReport.status} (${providerReport.resultCount} result(s)${rejection})`;\n\t});\n}\n\nfunction formatMemoryPromptInclusionLine(promptInclusion: MemoryPromptInclusionReport): string {\n\treturn `Prompt inclusion: ${promptInclusion.status} (${promptInclusion.includedCount} included, ${promptInclusion.omittedCount} omitted, ${promptInclusion.blockChars} chars)`;\n}\n\nexport function createCoreDiagnosticsToolDefinitions(\n\tgetActiveTools: () => string[],\n\tgetAllTools: () => ToolInfo[],\n\tgetContextGcReport?: (messages: AgentMessage[]) => ContextGcReport,\n\tgetMemoryDiagnostics?: () => {\n\t\tretrieval: MemoryRetrievalDiagnostics;\n\t\tpromptInclusion: MemoryPromptInclusionReport;\n\t},\n): ToolDefinition[] {\n\treturn [\n\t\t{\n\t\t\tname: \"context_audit\",\n\t\t\tlabel: \"Context Audit\",\n\t\t\tdescription:\n\t\t\t\t\"Audit the current provider-visible context composition: model window usage, system prompt estimate, active tool schema estimate, active session message rows, and heaviest context contributors.\",\n\t\t\tpromptSnippet: \"Audit current loaded context composition before optimizing context usage.\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Use context_audit when the user asks what is consuming context, why the footer shows a high percentage, or which messages/tools/system prompt content are loaded.\",\n\t\t\t\t\"Keep output bounded; use query/minTokens/maxItems to narrow rather than dumping full context.\",\n\t\t\t\t\"Treat token counts as estimates except provider usage from ctx.getContextUsage, which is still model/provider dependent.\",\n\t\t\t],\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tmaxItems: Type.Optional(\n\t\t\t\t\t\tType.Number({ description: \"Maximum heaviest session-context rows to show. Default 40, max 200.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tminTokens: Type.Optional(\n\t\t\t\t\t\tType.Number({\n\t\t\t\t\t\t\tdescription: \"Only show session-context rows with at least this many estimated tokens.\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tquery: Type.Optional(\n\t\t\t\t\t\tType.String({ description: \"Case-insensitive filter over row label and preview.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tincludePreviews: Type.Optional(\n\t\t\t\t\t\tType.Boolean({ description: \"Include bounded row previews. Defaults true.\" }),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\tasync execute(_toolCallId, params: ContextAuditParams, _signal, _onUpdate, ctx) {\n\t\t\t\tconst maxItems = Math.max(1, Math.min(MAX_MAX_ITEMS, Math.floor(params.maxItems ?? DEFAULT_MAX_ITEMS)));\n\t\t\t\tconst minTokens = Math.max(0, Math.floor(params.minTokens ?? 0));\n\t\t\t\tconst includePreviews = params.includePreviews !== false;\n\t\t\t\tconst query = params.query?.trim().toLowerCase();\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst rows = activeContextRows(branch);\n\t\t\t\tconst activeMessages = activeContextMessages(branch);\n\t\t\t\tconst contextGcReport = getContextGcReport?.(activeMessages);\n\t\t\t\tconst memoryDiagnostics = getMemoryDiagnostics?.();\n\t\t\t\tconst contextUsage = ctx.getContextUsage();\n\t\t\t\tconst systemPrompt = ctx.getSystemPrompt?.() || \"\";\n\t\t\t\tconst activeTools = new Set(getActiveTools());\n\t\t\t\tconst allTools = getAllTools();\n\t\t\t\tconst activeToolInfos = allTools.filter((tool) => activeTools.has(tool.name));\n\t\t\t\tconst systemTokens = estimateTextTokens(systemPrompt);\n\t\t\t\tconst toolSchemaChars = JSON.stringify(\n\t\t\t\t\tactiveToolInfos.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t\t\tpromptGuidelines: tool.promptGuidelines,\n\t\t\t\t\t})),\n\t\t\t\t).length;\n\t\t\t\tconst toolSchemaTokens = Math.ceil(toolSchemaChars / 4);\n\t\t\t\tconst rowTokenSum = rows.reduce((sum, row) => sum + row.tokens, 0);\n\t\t\t\tconst effectiveRowTokenSum = Math.max(0, rowTokenSum - (contextGcReport?.savedTokens ?? 0));\n\t\t\t\tconst usageText = contextUsage\n\t\t\t\t\t? contextUsage.tokens === null || contextUsage.percent === null\n\t\t\t\t\t\t? `provider usage: unknown/${contextUsage.contextWindow} tokens (usually right after compaction)`\n\t\t\t\t\t\t: `provider usage: ${contextUsage.tokens}/${contextUsage.contextWindow} tokens (${contextUsage.percent.toFixed(1)}%)`\n\t\t\t\t\t: \"provider usage: unavailable (no active model/context window)\";\n\t\t\t\tconst providerTokens = contextUsage?.tokens ?? null;\n\t\t\t\tconst unattributed =\n\t\t\t\t\tproviderTokens === null\n\t\t\t\t\t\t? null\n\t\t\t\t\t\t: Math.max(0, providerTokens - systemTokens - toolSchemaTokens - rowTokenSum);\n\n\t\t\t\tlet filtered = rows.filter((row) => row.tokens >= minTokens);\n\t\t\t\tif (query) {\n\t\t\t\t\tfiltered = filtered.filter((row) => `${row.label}\\n${row.preview}`.toLowerCase().includes(query));\n\t\t\t\t}\n\t\t\t\tconst heaviest = [...filtered].sort((a, b) => b.tokens - a.tokens).slice(0, maxItems);\n\t\t\t\tconst groupLines = groupRows(rows)\n\t\t\t\t\t.slice(0, 12)\n\t\t\t\t\t.map(([label, group]) => `- ${label}: ${group.tokens} est tok across ${group.count} row(s)`);\n\t\t\t\tconst rowLines = heaviest.map((row, index) => {\n\t\t\t\t\tconst base = `${index + 1}. ${row.tokens} est tok · ${row.label} · ${row.entryId ?? \"no-entry\"}`;\n\t\t\t\t\treturn includePreviews\n\t\t\t\t\t\t? `${base}\\n ${cap(row.preview, MAX_PREVIEW_CHARS) || \"(no text preview)\"}`\n\t\t\t\t\t\t: base;\n\t\t\t\t});\n\n\t\t\t\tconst lines = [\n\t\t\t\t\t\"Context audit\",\n\t\t\t\t\tusageText,\n\t\t\t\t\t`active branch rows: ${rows.length}; session row estimate: ${rowTokenSum} tokens`,\n\t\t\t\t\tcontextGcReport\n\t\t\t\t\t\t? `Context GC estimate: ${contextGcReport.savedTokens} tokens saved by packing ${contextGcReport.packedCount} stale row(s); effective session row estimate: ${effectiveRowTokenSum} tokens`\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\t`system prompt estimate: ${systemTokens} tokens (${systemPrompt.length} chars)`,\n\t\t\t\t\t`active tool schema estimate: ${toolSchemaTokens} tokens across ${activeToolInfos.length} active tool(s)`,\n\t\t\t\t\tunattributed === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `provider-reported remainder not mapped by chars/4 rows: ${unattributed} tokens`,\n\t\t\t\t\t...(memoryDiagnostics\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\tformatMemoryRetrievalLine(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\t...formatMemoryProviderLines(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\tformatMemoryPromptInclusionLine(memoryDiagnostics.promptInclusion),\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Largest groups:\",\n\t\t\t\t\t...(groupLines.length ? groupLines : [\"- none\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t`Heaviest rows${query ? ` matching ${JSON.stringify(params.query)}` : \"\"}:`,\n\t\t\t\t\t...(rowLines.length ? rowLines : [\"- none\"]),\n\t\t\t\t].filter((line): line is string => line !== undefined);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tcontextUsage,\n\t\t\t\t\t\tsystemPrompt: {\n\t\t\t\t\t\t\tchars: systemPrompt.length,\n\t\t\t\t\t\t\testimatedTokens: systemTokens,\n\t\t\t\t\t\t\tpreview: cap(systemPrompt, MAX_PREVIEW_CHARS),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tactiveTools: activeToolInfos.map((tool) => tool.name),\n\t\t\t\t\t\ttoolSchemaEstimate: { chars: toolSchemaChars, estimatedTokens: toolSchemaTokens },\n\t\t\t\t\t\trowTokenSum,\n\t\t\t\t\t\teffectiveRowTokenSum,\n\t\t\t\t\t\tcontextGc: contextGcReport,\n\t\t\t\t\t\trows,\n\t\t\t\t\t\tmemory: memoryDiagnostics,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t];\n}\n"]}
1
+ {"version":3,"file":"builtin.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/builtin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAQ9D,OAAO,KAAK,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAChH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAiN3D,wBAAgB,oCAAoC,CACnD,cAAc,EAAE,MAAM,MAAM,EAAE,EAC9B,WAAW,EAAE,MAAM,QAAQ,EAAE,EAC7B,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,eAAe,EAClE,oBAAoB,CAAC,EAAE,MAAM;IAC5B,SAAS,EAAE,0BAA0B,CAAC;IACtC,eAAe,EAAE,2BAA2B,CAAC;CAC7C,GACC,cAAc,EAAE,CAsIlB","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport {\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"@caupulican/pi-agent-core\";\nimport { type CompactionEntry, estimateTokens, type SessionEntry } from \"@caupulican/pi-agent-core/node\";\nimport { Type } from \"typebox\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"../context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"../context-gc.ts\";\nimport type { ToolDefinition, ToolInfo } from \"./types.ts\";\n\ntype ContextAuditParams = {\n\tmaxItems?: number;\n\tminTokens?: number;\n\tquery?: string;\n\tincludePreviews?: boolean;\n};\n\ntype AuditRow = {\n\tkind: string;\n\trole?: string;\n\tentryId?: string;\n\ttimestamp?: string;\n\ttokens: number;\n\tchars: number;\n\tlabel: string;\n\tpreview: string;\n};\n\nconst DEFAULT_MAX_ITEMS = 40;\nconst MAX_MAX_ITEMS = 200;\nconst DEFAULT_PREVIEW_CHARS = 220;\nconst MAX_PREVIEW_CHARS = 600;\n\nfunction estimateTextTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction cap(text: string, limit = DEFAULT_PREVIEW_CHARS): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\treturn compact.length > limit ? `${compact.slice(0, Math.max(0, limit - 1))}…` : compact;\n}\n\nfunction contentText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.map((part) => {\n\t\t\tif (!part || typeof part !== \"object\") return \"\";\n\t\t\tconst typed = part as { type?: string; text?: string; thinking?: string; name?: string; arguments?: unknown };\n\t\t\tif (typed.type === \"text\") return typed.text || \"\";\n\t\t\tif (typed.type === \"thinking\") return `[thinking ${typed.thinking?.length ?? 0} chars]`;\n\t\t\tif (typed.type === \"toolCall\")\n\t\t\t\treturn `[toolCall ${typed.name || \"unknown\"} ${JSON.stringify(typed.arguments ?? {})}]`;\n\t\t\tif (typed.type === \"image\") return \"[image]\";\n\t\t\treturn \"\";\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\n\nfunction messagePreview(message: AgentMessage): string {\n\tswitch (message.role) {\n\t\tcase \"assistant\":\n\t\tcase \"user\":\n\t\tcase \"toolResult\":\n\t\tcase \"custom\":\n\t\t\treturn contentText((message as { content?: unknown }).content);\n\t\tcase \"bashExecution\":\n\t\t\treturn `Ran ${message.command}\\n${message.output}`;\n\t\tcase \"branchSummary\":\n\t\tcase \"compactionSummary\":\n\t\t\treturn message.summary;\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\nfunction messageLabel(message: AgentMessage): string {\n\tif (message.role === \"assistant\") {\n\t\tconst toolCalls = message.content.filter((part) => part.type === \"toolCall\").length;\n\t\treturn toolCalls > 0 ? `assistant (${toolCalls} tool call${toolCalls === 1 ? \"\" : \"s\"})` : \"assistant\";\n\t}\n\tif (message.role === \"toolResult\") return `tool result: ${message.toolName}`;\n\tif (message.role === \"custom\") return `custom: ${message.customType}`;\n\tif (message.role === \"bashExecution\") return \"bash execution\";\n\tif (message.role === \"branchSummary\") return \"branch summary\";\n\tif (message.role === \"compactionSummary\") return \"compaction summary\";\n\treturn message.role;\n}\n\nfunction addRow(rows: AuditRow[], entry: SessionEntry, message: AgentMessage, kindOverride?: string) {\n\tconst preview = messagePreview(message);\n\trows.push({\n\t\tkind: kindOverride || entry.type,\n\t\trole: message.role,\n\t\tentryId: entry.id,\n\t\ttimestamp: entry.timestamp,\n\t\ttokens: estimateTokens(message),\n\t\tchars: preview.length,\n\t\tlabel: messageLabel(message),\n\t\tpreview: cap(preview),\n\t});\n}\n\nfunction messageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tif (entry.type === \"message\") return entry.message;\n\tif (entry.type === \"custom_message\") {\n\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\t}\n\treturn undefined;\n}\n\nfunction latestCompaction(entries: SessionEntry[]): CompactionEntry | undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"compaction\") return entry;\n\t}\n\treturn undefined;\n}\n\nfunction activeContextMessages(entries: SessionEntry[]): AgentMessage[] {\n\tconst messages: AgentMessage[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) messages.push(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\treturn messages;\n}\n\nfunction activeContextRows(entries: SessionEntry[]): AuditRow[] {\n\tconst rows: AuditRow[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) addRow(rows, entry, message);\n\t\t}\n\t\treturn rows;\n\t}\n\n\tconst compactionMessage = createCompactionSummaryMessage(\n\t\tcompaction.summary,\n\t\tcompaction.tokensBefore,\n\t\tcompaction.timestamp,\n\t);\n\taddRow(rows, compaction, compactionMessage, \"compaction\");\n\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\treturn rows;\n}\n\nfunction groupRows(rows: AuditRow[]): Array<[string, { count: number; tokens: number; chars: number }]> {\n\tconst groups = new Map<string, { count: number; tokens: number; chars: number }>();\n\tfor (const row of rows) {\n\t\tconst key = row.label;\n\t\tconst current = groups.get(key) ?? { count: 0, tokens: 0, chars: 0 };\n\t\tcurrent.count += 1;\n\t\tcurrent.tokens += row.tokens;\n\t\tcurrent.chars += row.chars;\n\t\tgroups.set(key, current);\n\t}\n\treturn [...groups.entries()].sort((a, b) => b[1].tokens - a[1].tokens);\n}\n\n/** Bounded, deterministic summary lines for the memory-retrieval/prompt-inclusion diagnostic (safe metadata only, no content). */\nfunction formatMemoryRetrievalLine(retrieval: MemoryRetrievalDiagnostics): string {\n\treturn `Memory retrieval: ${retrieval.enabled ? `enabled (max ${retrieval.maxResults} results)` : \"disabled\"}`;\n}\n\nfunction formatMemoryProviderLines(retrieval: MemoryRetrievalDiagnostics): string[] {\n\treturn retrieval.providerReports.map((providerReport) => {\n\t\tconst rejection =\n\t\t\tproviderReport.rejectionReasons.length > 0 ? `; rejected: ${providerReport.rejectionReasons.join(\", \")}` : \"\";\n\t\treturn ` provider ${providerReport.providerId}: ${providerReport.status} (${providerReport.resultCount} result(s)${rejection})`;\n\t});\n}\n\nfunction formatMemoryPromptInclusionLine(promptInclusion: MemoryPromptInclusionReport): string {\n\treturn `Prompt inclusion: ${promptInclusion.status} (${promptInclusion.includedCount} included, ${promptInclusion.omittedCount} omitted, ${promptInclusion.blockChars} chars)`;\n}\n\nexport function createCoreDiagnosticsToolDefinitions(\n\tgetActiveTools: () => string[],\n\tgetAllTools: () => ToolInfo[],\n\tgetContextGcReport?: (messages: AgentMessage[]) => ContextGcReport,\n\tgetMemoryDiagnostics?: () => {\n\t\tretrieval: MemoryRetrievalDiagnostics;\n\t\tpromptInclusion: MemoryPromptInclusionReport;\n\t},\n): ToolDefinition[] {\n\treturn [\n\t\t{\n\t\t\tname: \"context_audit\",\n\t\t\tlabel: \"Context Audit\",\n\t\t\tdescription:\n\t\t\t\t\"Audit the current provider-visible context composition: model window usage, system prompt estimate, active tool schema estimate, active session message rows, and heaviest context contributors.\",\n\t\t\tpromptSnippet: \"Audit current loaded context composition before optimizing context usage.\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Use context_audit when the user asks what is consuming context, why the footer shows a high percentage, or which messages/tools/system prompt content are loaded.\",\n\t\t\t\t\"Keep output bounded; use query/minTokens/maxItems to narrow rather than dumping full context.\",\n\t\t\t\t\"Treat token counts as estimates except provider usage from ctx.getContextUsage, which is still model/provider dependent.\",\n\t\t\t],\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tmaxItems: Type.Optional(\n\t\t\t\t\t\tType.Number({ description: \"Maximum heaviest session-context rows to show. Default 40, max 200.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tminTokens: Type.Optional(\n\t\t\t\t\t\tType.Number({\n\t\t\t\t\t\t\tdescription: \"Only show session-context rows with at least this many estimated tokens.\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tquery: Type.Optional(\n\t\t\t\t\t\tType.String({ description: \"Case-insensitive filter over row label and preview.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tincludePreviews: Type.Optional(\n\t\t\t\t\t\tType.Boolean({ description: \"Include bounded row previews. Defaults true.\" }),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\tasync execute(_toolCallId, params: ContextAuditParams, _signal, _onUpdate, ctx) {\n\t\t\t\tconst maxItems = Math.max(1, Math.min(MAX_MAX_ITEMS, Math.floor(params.maxItems ?? DEFAULT_MAX_ITEMS)));\n\t\t\t\tconst minTokens = Math.max(0, Math.floor(params.minTokens ?? 0));\n\t\t\t\tconst includePreviews = params.includePreviews !== false;\n\t\t\t\tconst query = params.query?.trim().toLowerCase();\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst rows = activeContextRows(branch);\n\t\t\t\tconst activeMessages = activeContextMessages(branch);\n\t\t\t\tconst contextGcReport = getContextGcReport?.(activeMessages);\n\t\t\t\tconst memoryDiagnostics = getMemoryDiagnostics?.();\n\t\t\t\tconst contextUsage = ctx.getContextUsage();\n\t\t\t\tconst systemPrompt = ctx.getSystemPrompt?.() || \"\";\n\t\t\t\tconst activeTools = new Set(getActiveTools());\n\t\t\t\tconst allTools = getAllTools();\n\t\t\t\tconst activeToolInfos = allTools.filter((tool) => activeTools.has(tool.name));\n\t\t\t\tconst systemTokens = estimateTextTokens(systemPrompt);\n\t\t\t\tconst toolSchemaChars = JSON.stringify(\n\t\t\t\t\tactiveToolInfos.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t\t\tpromptGuidelines: tool.promptGuidelines,\n\t\t\t\t\t})),\n\t\t\t\t).length;\n\t\t\t\tconst toolSchemaTokens = Math.ceil(toolSchemaChars / 4);\n\t\t\t\tconst rowTokenSum = rows.reduce((sum, row) => sum + row.tokens, 0);\n\t\t\t\tconst effectiveRowTokenSum = Math.max(0, rowTokenSum - (contextGcReport?.savedTokens ?? 0));\n\t\t\t\tconst usageText = contextUsage\n\t\t\t\t\t? contextUsage.tokens === null || contextUsage.percent === null\n\t\t\t\t\t\t? `provider usage: unknown/${contextUsage.contextWindow} tokens (usually right after compaction)`\n\t\t\t\t\t\t: `provider usage: ${contextUsage.tokens}/${contextUsage.contextWindow} tokens (${contextUsage.percent.toFixed(1)}%)`\n\t\t\t\t\t: \"provider usage: unavailable (no active model/context window)\";\n\t\t\t\tconst providerTokens = contextUsage?.tokens ?? null;\n\t\t\t\tconst unattributed =\n\t\t\t\t\tproviderTokens === null\n\t\t\t\t\t\t? null\n\t\t\t\t\t\t: Math.max(0, providerTokens - systemTokens - toolSchemaTokens - rowTokenSum);\n\n\t\t\t\tlet filtered = rows.filter((row) => row.tokens >= minTokens);\n\t\t\t\tif (query) {\n\t\t\t\t\tfiltered = filtered.filter((row) => `${row.label}\\n${row.preview}`.toLowerCase().includes(query));\n\t\t\t\t}\n\t\t\t\tconst heaviest = [...filtered].sort((a, b) => b.tokens - a.tokens).slice(0, maxItems);\n\t\t\t\tconst groupLines = groupRows(rows)\n\t\t\t\t\t.slice(0, 12)\n\t\t\t\t\t.map(([label, group]) => `- ${label}: ${group.tokens} est tok across ${group.count} row(s)`);\n\t\t\t\tconst rowLines = heaviest.map((row, index) => {\n\t\t\t\t\tconst base = `${index + 1}. ${row.tokens} est tok · ${row.label} · ${row.entryId ?? \"no-entry\"}`;\n\t\t\t\t\treturn includePreviews\n\t\t\t\t\t\t? `${base}\\n ${cap(row.preview, MAX_PREVIEW_CHARS) || \"(no text preview)\"}`\n\t\t\t\t\t\t: base;\n\t\t\t\t});\n\n\t\t\t\tconst lines = [\n\t\t\t\t\t\"Context audit\",\n\t\t\t\t\tusageText,\n\t\t\t\t\t`active branch rows: ${rows.length}; session row estimate: ${rowTokenSum} tokens`,\n\t\t\t\t\tcontextGcReport\n\t\t\t\t\t\t? `Context GC estimate: ${contextGcReport.savedTokens} tokens saved by packing ${contextGcReport.packedCount} stale row(s); effective session row estimate: ${effectiveRowTokenSum} tokens`\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\t`system prompt estimate: ${systemTokens} tokens (${systemPrompt.length} chars)`,\n\t\t\t\t\t`active tool schema estimate: ${toolSchemaTokens} tokens across ${activeToolInfos.length} active tool(s)`,\n\t\t\t\t\tunattributed === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `provider-reported remainder not mapped by chars/4 rows: ${unattributed} tokens`,\n\t\t\t\t\t...(memoryDiagnostics\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\tformatMemoryRetrievalLine(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\t...formatMemoryProviderLines(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\tformatMemoryPromptInclusionLine(memoryDiagnostics.promptInclusion),\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Largest groups:\",\n\t\t\t\t\t...(groupLines.length ? groupLines : [\"- none\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t`Heaviest rows${query ? ` matching ${JSON.stringify(params.query)}` : \"\"}:`,\n\t\t\t\t\t...(rowLines.length ? rowLines : [\"- none\"]),\n\t\t\t\t].filter((line): line is string => line !== undefined);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tcontextUsage,\n\t\t\t\t\t\tsystemPrompt: {\n\t\t\t\t\t\t\tchars: systemPrompt.length,\n\t\t\t\t\t\t\testimatedTokens: systemTokens,\n\t\t\t\t\t\t\tpreview: cap(systemPrompt, MAX_PREVIEW_CHARS),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tactiveTools: activeToolInfos.map((tool) => tool.name),\n\t\t\t\t\t\ttoolSchemaEstimate: { chars: toolSchemaChars, estimatedTokens: toolSchemaTokens },\n\t\t\t\t\t\trowTokenSum,\n\t\t\t\t\t\teffectiveRowTokenSum,\n\t\t\t\t\t\tcontextGc: contextGcReport,\n\t\t\t\t\t\trows,\n\t\t\t\t\t\tmemory: memoryDiagnostics,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t];\n}\n"]}
@@ -1,6 +1,6 @@
1
+ import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "@caupulican/pi-agent-core";
2
+ import { estimateTokens } from "@caupulican/pi-agent-core/node";
1
3
  import { Type } from "typebox";
2
- import { estimateTokens } from "../compaction/compaction.js";
3
- import { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from "../messages.js";
4
4
  const DEFAULT_MAX_ITEMS = 40;
5
5
  const MAX_MAX_ITEMS = 200;
6
6
  const DEFAULT_PREVIEW_CHARS = 220;
@@ -1 +1 @@
1
- {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../src/core/extensions/builtin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport { Type } from \"typebox\";\nimport { estimateTokens } from \"../compaction/compaction.ts\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"../context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"../context-gc.ts\";\nimport { createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage } from \"../messages.ts\";\nimport type { CompactionEntry, SessionEntry } from \"../session-manager.ts\";\nimport type { ToolDefinition, ToolInfo } from \"./types.ts\";\n\ntype ContextAuditParams = {\n\tmaxItems?: number;\n\tminTokens?: number;\n\tquery?: string;\n\tincludePreviews?: boolean;\n};\n\ntype AuditRow = {\n\tkind: string;\n\trole?: string;\n\tentryId?: string;\n\ttimestamp?: string;\n\ttokens: number;\n\tchars: number;\n\tlabel: string;\n\tpreview: string;\n};\n\nconst DEFAULT_MAX_ITEMS = 40;\nconst MAX_MAX_ITEMS = 200;\nconst DEFAULT_PREVIEW_CHARS = 220;\nconst MAX_PREVIEW_CHARS = 600;\n\nfunction estimateTextTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction cap(text: string, limit = DEFAULT_PREVIEW_CHARS): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\treturn compact.length > limit ? `${compact.slice(0, Math.max(0, limit - 1))}…` : compact;\n}\n\nfunction contentText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.map((part) => {\n\t\t\tif (!part || typeof part !== \"object\") return \"\";\n\t\t\tconst typed = part as { type?: string; text?: string; thinking?: string; name?: string; arguments?: unknown };\n\t\t\tif (typed.type === \"text\") return typed.text || \"\";\n\t\t\tif (typed.type === \"thinking\") return `[thinking ${typed.thinking?.length ?? 0} chars]`;\n\t\t\tif (typed.type === \"toolCall\")\n\t\t\t\treturn `[toolCall ${typed.name || \"unknown\"} ${JSON.stringify(typed.arguments ?? {})}]`;\n\t\t\tif (typed.type === \"image\") return \"[image]\";\n\t\t\treturn \"\";\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\n\nfunction messagePreview(message: AgentMessage): string {\n\tswitch (message.role) {\n\t\tcase \"assistant\":\n\t\tcase \"user\":\n\t\tcase \"toolResult\":\n\t\tcase \"custom\":\n\t\t\treturn contentText((message as { content?: unknown }).content);\n\t\tcase \"bashExecution\":\n\t\t\treturn `Ran ${message.command}\\n${message.output}`;\n\t\tcase \"branchSummary\":\n\t\tcase \"compactionSummary\":\n\t\t\treturn message.summary;\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\nfunction messageLabel(message: AgentMessage): string {\n\tif (message.role === \"assistant\") {\n\t\tconst toolCalls = message.content.filter((part) => part.type === \"toolCall\").length;\n\t\treturn toolCalls > 0 ? `assistant (${toolCalls} tool call${toolCalls === 1 ? \"\" : \"s\"})` : \"assistant\";\n\t}\n\tif (message.role === \"toolResult\") return `tool result: ${message.toolName}`;\n\tif (message.role === \"custom\") return `custom: ${message.customType}`;\n\tif (message.role === \"bashExecution\") return \"bash execution\";\n\tif (message.role === \"branchSummary\") return \"branch summary\";\n\tif (message.role === \"compactionSummary\") return \"compaction summary\";\n\treturn message.role;\n}\n\nfunction addRow(rows: AuditRow[], entry: SessionEntry, message: AgentMessage, kindOverride?: string) {\n\tconst preview = messagePreview(message);\n\trows.push({\n\t\tkind: kindOverride || entry.type,\n\t\trole: message.role,\n\t\tentryId: entry.id,\n\t\ttimestamp: entry.timestamp,\n\t\ttokens: estimateTokens(message),\n\t\tchars: preview.length,\n\t\tlabel: messageLabel(message),\n\t\tpreview: cap(preview),\n\t});\n}\n\nfunction messageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tif (entry.type === \"message\") return entry.message;\n\tif (entry.type === \"custom_message\") {\n\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\t}\n\treturn undefined;\n}\n\nfunction latestCompaction(entries: SessionEntry[]): CompactionEntry | undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"compaction\") return entry;\n\t}\n\treturn undefined;\n}\n\nfunction activeContextMessages(entries: SessionEntry[]): AgentMessage[] {\n\tconst messages: AgentMessage[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) messages.push(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\treturn messages;\n}\n\nfunction activeContextRows(entries: SessionEntry[]): AuditRow[] {\n\tconst rows: AuditRow[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) addRow(rows, entry, message);\n\t\t}\n\t\treturn rows;\n\t}\n\n\tconst compactionMessage = createCompactionSummaryMessage(\n\t\tcompaction.summary,\n\t\tcompaction.tokensBefore,\n\t\tcompaction.timestamp,\n\t);\n\taddRow(rows, compaction, compactionMessage, \"compaction\");\n\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\treturn rows;\n}\n\nfunction groupRows(rows: AuditRow[]): Array<[string, { count: number; tokens: number; chars: number }]> {\n\tconst groups = new Map<string, { count: number; tokens: number; chars: number }>();\n\tfor (const row of rows) {\n\t\tconst key = row.label;\n\t\tconst current = groups.get(key) ?? { count: 0, tokens: 0, chars: 0 };\n\t\tcurrent.count += 1;\n\t\tcurrent.tokens += row.tokens;\n\t\tcurrent.chars += row.chars;\n\t\tgroups.set(key, current);\n\t}\n\treturn [...groups.entries()].sort((a, b) => b[1].tokens - a[1].tokens);\n}\n\n/** Bounded, deterministic summary lines for the memory-retrieval/prompt-inclusion diagnostic (safe metadata only, no content). */\nfunction formatMemoryRetrievalLine(retrieval: MemoryRetrievalDiagnostics): string {\n\treturn `Memory retrieval: ${retrieval.enabled ? `enabled (max ${retrieval.maxResults} results)` : \"disabled\"}`;\n}\n\nfunction formatMemoryProviderLines(retrieval: MemoryRetrievalDiagnostics): string[] {\n\treturn retrieval.providerReports.map((providerReport) => {\n\t\tconst rejection =\n\t\t\tproviderReport.rejectionReasons.length > 0 ? `; rejected: ${providerReport.rejectionReasons.join(\", \")}` : \"\";\n\t\treturn ` provider ${providerReport.providerId}: ${providerReport.status} (${providerReport.resultCount} result(s)${rejection})`;\n\t});\n}\n\nfunction formatMemoryPromptInclusionLine(promptInclusion: MemoryPromptInclusionReport): string {\n\treturn `Prompt inclusion: ${promptInclusion.status} (${promptInclusion.includedCount} included, ${promptInclusion.omittedCount} omitted, ${promptInclusion.blockChars} chars)`;\n}\n\nexport function createCoreDiagnosticsToolDefinitions(\n\tgetActiveTools: () => string[],\n\tgetAllTools: () => ToolInfo[],\n\tgetContextGcReport?: (messages: AgentMessage[]) => ContextGcReport,\n\tgetMemoryDiagnostics?: () => {\n\t\tretrieval: MemoryRetrievalDiagnostics;\n\t\tpromptInclusion: MemoryPromptInclusionReport;\n\t},\n): ToolDefinition[] {\n\treturn [\n\t\t{\n\t\t\tname: \"context_audit\",\n\t\t\tlabel: \"Context Audit\",\n\t\t\tdescription:\n\t\t\t\t\"Audit the current provider-visible context composition: model window usage, system prompt estimate, active tool schema estimate, active session message rows, and heaviest context contributors.\",\n\t\t\tpromptSnippet: \"Audit current loaded context composition before optimizing context usage.\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Use context_audit when the user asks what is consuming context, why the footer shows a high percentage, or which messages/tools/system prompt content are loaded.\",\n\t\t\t\t\"Keep output bounded; use query/minTokens/maxItems to narrow rather than dumping full context.\",\n\t\t\t\t\"Treat token counts as estimates except provider usage from ctx.getContextUsage, which is still model/provider dependent.\",\n\t\t\t],\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tmaxItems: Type.Optional(\n\t\t\t\t\t\tType.Number({ description: \"Maximum heaviest session-context rows to show. Default 40, max 200.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tminTokens: Type.Optional(\n\t\t\t\t\t\tType.Number({\n\t\t\t\t\t\t\tdescription: \"Only show session-context rows with at least this many estimated tokens.\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tquery: Type.Optional(\n\t\t\t\t\t\tType.String({ description: \"Case-insensitive filter over row label and preview.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tincludePreviews: Type.Optional(\n\t\t\t\t\t\tType.Boolean({ description: \"Include bounded row previews. Defaults true.\" }),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\tasync execute(_toolCallId, params: ContextAuditParams, _signal, _onUpdate, ctx) {\n\t\t\t\tconst maxItems = Math.max(1, Math.min(MAX_MAX_ITEMS, Math.floor(params.maxItems ?? DEFAULT_MAX_ITEMS)));\n\t\t\t\tconst minTokens = Math.max(0, Math.floor(params.minTokens ?? 0));\n\t\t\t\tconst includePreviews = params.includePreviews !== false;\n\t\t\t\tconst query = params.query?.trim().toLowerCase();\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst rows = activeContextRows(branch);\n\t\t\t\tconst activeMessages = activeContextMessages(branch);\n\t\t\t\tconst contextGcReport = getContextGcReport?.(activeMessages);\n\t\t\t\tconst memoryDiagnostics = getMemoryDiagnostics?.();\n\t\t\t\tconst contextUsage = ctx.getContextUsage();\n\t\t\t\tconst systemPrompt = ctx.getSystemPrompt?.() || \"\";\n\t\t\t\tconst activeTools = new Set(getActiveTools());\n\t\t\t\tconst allTools = getAllTools();\n\t\t\t\tconst activeToolInfos = allTools.filter((tool) => activeTools.has(tool.name));\n\t\t\t\tconst systemTokens = estimateTextTokens(systemPrompt);\n\t\t\t\tconst toolSchemaChars = JSON.stringify(\n\t\t\t\t\tactiveToolInfos.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t\t\tpromptGuidelines: tool.promptGuidelines,\n\t\t\t\t\t})),\n\t\t\t\t).length;\n\t\t\t\tconst toolSchemaTokens = Math.ceil(toolSchemaChars / 4);\n\t\t\t\tconst rowTokenSum = rows.reduce((sum, row) => sum + row.tokens, 0);\n\t\t\t\tconst effectiveRowTokenSum = Math.max(0, rowTokenSum - (contextGcReport?.savedTokens ?? 0));\n\t\t\t\tconst usageText = contextUsage\n\t\t\t\t\t? contextUsage.tokens === null || contextUsage.percent === null\n\t\t\t\t\t\t? `provider usage: unknown/${contextUsage.contextWindow} tokens (usually right after compaction)`\n\t\t\t\t\t\t: `provider usage: ${contextUsage.tokens}/${contextUsage.contextWindow} tokens (${contextUsage.percent.toFixed(1)}%)`\n\t\t\t\t\t: \"provider usage: unavailable (no active model/context window)\";\n\t\t\t\tconst providerTokens = contextUsage?.tokens ?? null;\n\t\t\t\tconst unattributed =\n\t\t\t\t\tproviderTokens === null\n\t\t\t\t\t\t? null\n\t\t\t\t\t\t: Math.max(0, providerTokens - systemTokens - toolSchemaTokens - rowTokenSum);\n\n\t\t\t\tlet filtered = rows.filter((row) => row.tokens >= minTokens);\n\t\t\t\tif (query) {\n\t\t\t\t\tfiltered = filtered.filter((row) => `${row.label}\\n${row.preview}`.toLowerCase().includes(query));\n\t\t\t\t}\n\t\t\t\tconst heaviest = [...filtered].sort((a, b) => b.tokens - a.tokens).slice(0, maxItems);\n\t\t\t\tconst groupLines = groupRows(rows)\n\t\t\t\t\t.slice(0, 12)\n\t\t\t\t\t.map(([label, group]) => `- ${label}: ${group.tokens} est tok across ${group.count} row(s)`);\n\t\t\t\tconst rowLines = heaviest.map((row, index) => {\n\t\t\t\t\tconst base = `${index + 1}. ${row.tokens} est tok · ${row.label} · ${row.entryId ?? \"no-entry\"}`;\n\t\t\t\t\treturn includePreviews\n\t\t\t\t\t\t? `${base}\\n ${cap(row.preview, MAX_PREVIEW_CHARS) || \"(no text preview)\"}`\n\t\t\t\t\t\t: base;\n\t\t\t\t});\n\n\t\t\t\tconst lines = [\n\t\t\t\t\t\"Context audit\",\n\t\t\t\t\tusageText,\n\t\t\t\t\t`active branch rows: ${rows.length}; session row estimate: ${rowTokenSum} tokens`,\n\t\t\t\t\tcontextGcReport\n\t\t\t\t\t\t? `Context GC estimate: ${contextGcReport.savedTokens} tokens saved by packing ${contextGcReport.packedCount} stale row(s); effective session row estimate: ${effectiveRowTokenSum} tokens`\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\t`system prompt estimate: ${systemTokens} tokens (${systemPrompt.length} chars)`,\n\t\t\t\t\t`active tool schema estimate: ${toolSchemaTokens} tokens across ${activeToolInfos.length} active tool(s)`,\n\t\t\t\t\tunattributed === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `provider-reported remainder not mapped by chars/4 rows: ${unattributed} tokens`,\n\t\t\t\t\t...(memoryDiagnostics\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\tformatMemoryRetrievalLine(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\t...formatMemoryProviderLines(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\tformatMemoryPromptInclusionLine(memoryDiagnostics.promptInclusion),\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Largest groups:\",\n\t\t\t\t\t...(groupLines.length ? groupLines : [\"- none\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t`Heaviest rows${query ? ` matching ${JSON.stringify(params.query)}` : \"\"}:`,\n\t\t\t\t\t...(rowLines.length ? rowLines : [\"- none\"]),\n\t\t\t\t].filter((line): line is string => line !== undefined);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tcontextUsage,\n\t\t\t\t\t\tsystemPrompt: {\n\t\t\t\t\t\t\tchars: systemPrompt.length,\n\t\t\t\t\t\t\testimatedTokens: systemTokens,\n\t\t\t\t\t\t\tpreview: cap(systemPrompt, MAX_PREVIEW_CHARS),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tactiveTools: activeToolInfos.map((tool) => tool.name),\n\t\t\t\t\t\ttoolSchemaEstimate: { chars: toolSchemaChars, estimatedTokens: toolSchemaTokens },\n\t\t\t\t\t\trowTokenSum,\n\t\t\t\t\t\teffectiveRowTokenSum,\n\t\t\t\t\t\tcontextGc: contextGcReport,\n\t\t\t\t\t\trows,\n\t\t\t\t\t\tmemory: memoryDiagnostics,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t];\n}\n"]}
1
+ {"version":3,"file":"builtin.js","sourceRoot":"","sources":["../../../src/core/extensions/builtin.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@caupulican/pi-agent-core\";\nimport {\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"@caupulican/pi-agent-core\";\nimport { type CompactionEntry, estimateTokens, type SessionEntry } from \"@caupulican/pi-agent-core/node\";\nimport { Type } from \"typebox\";\nimport type { MemoryPromptInclusionReport, MemoryRetrievalDiagnostics } from \"../context/memory-diagnostics.ts\";\nimport type { ContextGcReport } from \"../context-gc.ts\";\nimport type { ToolDefinition, ToolInfo } from \"./types.ts\";\n\ntype ContextAuditParams = {\n\tmaxItems?: number;\n\tminTokens?: number;\n\tquery?: string;\n\tincludePreviews?: boolean;\n};\n\ntype AuditRow = {\n\tkind: string;\n\trole?: string;\n\tentryId?: string;\n\ttimestamp?: string;\n\ttokens: number;\n\tchars: number;\n\tlabel: string;\n\tpreview: string;\n};\n\nconst DEFAULT_MAX_ITEMS = 40;\nconst MAX_MAX_ITEMS = 200;\nconst DEFAULT_PREVIEW_CHARS = 220;\nconst MAX_PREVIEW_CHARS = 600;\n\nfunction estimateTextTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction cap(text: string, limit = DEFAULT_PREVIEW_CHARS): string {\n\tconst compact = text.replace(/\\s+/g, \" \").trim();\n\treturn compact.length > limit ? `${compact.slice(0, Math.max(0, limit - 1))}…` : compact;\n}\n\nfunction contentText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.map((part) => {\n\t\t\tif (!part || typeof part !== \"object\") return \"\";\n\t\t\tconst typed = part as { type?: string; text?: string; thinking?: string; name?: string; arguments?: unknown };\n\t\t\tif (typed.type === \"text\") return typed.text || \"\";\n\t\t\tif (typed.type === \"thinking\") return `[thinking ${typed.thinking?.length ?? 0} chars]`;\n\t\t\tif (typed.type === \"toolCall\")\n\t\t\t\treturn `[toolCall ${typed.name || \"unknown\"} ${JSON.stringify(typed.arguments ?? {})}]`;\n\t\t\tif (typed.type === \"image\") return \"[image]\";\n\t\t\treturn \"\";\n\t\t})\n\t\t.filter(Boolean)\n\t\t.join(\"\\n\");\n}\n\nfunction messagePreview(message: AgentMessage): string {\n\tswitch (message.role) {\n\t\tcase \"assistant\":\n\t\tcase \"user\":\n\t\tcase \"toolResult\":\n\t\tcase \"custom\":\n\t\t\treturn contentText((message as { content?: unknown }).content);\n\t\tcase \"bashExecution\":\n\t\t\treturn `Ran ${message.command}\\n${message.output}`;\n\t\tcase \"branchSummary\":\n\t\tcase \"compactionSummary\":\n\t\t\treturn message.summary;\n\t\tdefault:\n\t\t\treturn \"\";\n\t}\n}\n\nfunction messageLabel(message: AgentMessage): string {\n\tif (message.role === \"assistant\") {\n\t\tconst toolCalls = message.content.filter((part) => part.type === \"toolCall\").length;\n\t\treturn toolCalls > 0 ? `assistant (${toolCalls} tool call${toolCalls === 1 ? \"\" : \"s\"})` : \"assistant\";\n\t}\n\tif (message.role === \"toolResult\") return `tool result: ${message.toolName}`;\n\tif (message.role === \"custom\") return `custom: ${message.customType}`;\n\tif (message.role === \"bashExecution\") return \"bash execution\";\n\tif (message.role === \"branchSummary\") return \"branch summary\";\n\tif (message.role === \"compactionSummary\") return \"compaction summary\";\n\treturn message.role;\n}\n\nfunction addRow(rows: AuditRow[], entry: SessionEntry, message: AgentMessage, kindOverride?: string) {\n\tconst preview = messagePreview(message);\n\trows.push({\n\t\tkind: kindOverride || entry.type,\n\t\trole: message.role,\n\t\tentryId: entry.id,\n\t\ttimestamp: entry.timestamp,\n\t\ttokens: estimateTokens(message),\n\t\tchars: preview.length,\n\t\tlabel: messageLabel(message),\n\t\tpreview: cap(preview),\n\t});\n}\n\nfunction messageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tif (entry.type === \"message\") return entry.message;\n\tif (entry.type === \"custom_message\") {\n\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\t}\n\tif (entry.type === \"branch_summary\" && entry.summary) {\n\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\t}\n\treturn undefined;\n}\n\nfunction latestCompaction(entries: SessionEntry[]): CompactionEntry | undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry?.type === \"compaction\") return entry;\n\t}\n\treturn undefined;\n}\n\nfunction activeContextMessages(entries: SessionEntry[]): AgentMessage[] {\n\tconst messages: AgentMessage[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) messages.push(message);\n\t\t}\n\t\treturn messages;\n\t}\n\n\tmessages.push(createCompactionSummaryMessage(compaction.summary, compaction.tokensBefore, compaction.timestamp));\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) messages.push(message);\n\t}\n\treturn messages;\n}\n\nfunction activeContextRows(entries: SessionEntry[]): AuditRow[] {\n\tconst rows: AuditRow[] = [];\n\tconst compaction = latestCompaction(entries);\n\tif (!compaction) {\n\t\tfor (const entry of entries) {\n\t\t\tconst message = messageFromEntry(entry);\n\t\t\tif (message) addRow(rows, entry, message);\n\t\t}\n\t\treturn rows;\n\t}\n\n\tconst compactionMessage = createCompactionSummaryMessage(\n\t\tcompaction.summary,\n\t\tcompaction.tokensBefore,\n\t\tcompaction.timestamp,\n\t);\n\taddRow(rows, compaction, compactionMessage, \"compaction\");\n\n\tconst compactionIndex = entries.findIndex((entry) => entry.id === compaction.id);\n\tlet foundFirstKept = false;\n\tfor (let index = 0; index < compactionIndex; index++) {\n\t\tconst entry = entries[index];\n\t\tif (entry.id === compaction.firstKeptEntryId) foundFirstKept = true;\n\t\tif (!foundFirstKept) continue;\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\tfor (let index = compactionIndex + 1; index < entries.length; index++) {\n\t\tconst entry = entries[index];\n\t\tconst message = messageFromEntry(entry);\n\t\tif (message) addRow(rows, entry, message);\n\t}\n\treturn rows;\n}\n\nfunction groupRows(rows: AuditRow[]): Array<[string, { count: number; tokens: number; chars: number }]> {\n\tconst groups = new Map<string, { count: number; tokens: number; chars: number }>();\n\tfor (const row of rows) {\n\t\tconst key = row.label;\n\t\tconst current = groups.get(key) ?? { count: 0, tokens: 0, chars: 0 };\n\t\tcurrent.count += 1;\n\t\tcurrent.tokens += row.tokens;\n\t\tcurrent.chars += row.chars;\n\t\tgroups.set(key, current);\n\t}\n\treturn [...groups.entries()].sort((a, b) => b[1].tokens - a[1].tokens);\n}\n\n/** Bounded, deterministic summary lines for the memory-retrieval/prompt-inclusion diagnostic (safe metadata only, no content). */\nfunction formatMemoryRetrievalLine(retrieval: MemoryRetrievalDiagnostics): string {\n\treturn `Memory retrieval: ${retrieval.enabled ? `enabled (max ${retrieval.maxResults} results)` : \"disabled\"}`;\n}\n\nfunction formatMemoryProviderLines(retrieval: MemoryRetrievalDiagnostics): string[] {\n\treturn retrieval.providerReports.map((providerReport) => {\n\t\tconst rejection =\n\t\t\tproviderReport.rejectionReasons.length > 0 ? `; rejected: ${providerReport.rejectionReasons.join(\", \")}` : \"\";\n\t\treturn ` provider ${providerReport.providerId}: ${providerReport.status} (${providerReport.resultCount} result(s)${rejection})`;\n\t});\n}\n\nfunction formatMemoryPromptInclusionLine(promptInclusion: MemoryPromptInclusionReport): string {\n\treturn `Prompt inclusion: ${promptInclusion.status} (${promptInclusion.includedCount} included, ${promptInclusion.omittedCount} omitted, ${promptInclusion.blockChars} chars)`;\n}\n\nexport function createCoreDiagnosticsToolDefinitions(\n\tgetActiveTools: () => string[],\n\tgetAllTools: () => ToolInfo[],\n\tgetContextGcReport?: (messages: AgentMessage[]) => ContextGcReport,\n\tgetMemoryDiagnostics?: () => {\n\t\tretrieval: MemoryRetrievalDiagnostics;\n\t\tpromptInclusion: MemoryPromptInclusionReport;\n\t},\n): ToolDefinition[] {\n\treturn [\n\t\t{\n\t\t\tname: \"context_audit\",\n\t\t\tlabel: \"Context Audit\",\n\t\t\tdescription:\n\t\t\t\t\"Audit the current provider-visible context composition: model window usage, system prompt estimate, active tool schema estimate, active session message rows, and heaviest context contributors.\",\n\t\t\tpromptSnippet: \"Audit current loaded context composition before optimizing context usage.\",\n\t\t\tpromptGuidelines: [\n\t\t\t\t\"Use context_audit when the user asks what is consuming context, why the footer shows a high percentage, or which messages/tools/system prompt content are loaded.\",\n\t\t\t\t\"Keep output bounded; use query/minTokens/maxItems to narrow rather than dumping full context.\",\n\t\t\t\t\"Treat token counts as estimates except provider usage from ctx.getContextUsage, which is still model/provider dependent.\",\n\t\t\t],\n\t\t\tparameters: Type.Object(\n\t\t\t\t{\n\t\t\t\t\tmaxItems: Type.Optional(\n\t\t\t\t\t\tType.Number({ description: \"Maximum heaviest session-context rows to show. Default 40, max 200.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tminTokens: Type.Optional(\n\t\t\t\t\t\tType.Number({\n\t\t\t\t\t\t\tdescription: \"Only show session-context rows with at least this many estimated tokens.\",\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tquery: Type.Optional(\n\t\t\t\t\t\tType.String({ description: \"Case-insensitive filter over row label and preview.\" }),\n\t\t\t\t\t),\n\t\t\t\t\tincludePreviews: Type.Optional(\n\t\t\t\t\t\tType.Boolean({ description: \"Include bounded row previews. Defaults true.\" }),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{ additionalProperties: false },\n\t\t\t),\n\t\t\tasync execute(_toolCallId, params: ContextAuditParams, _signal, _onUpdate, ctx) {\n\t\t\t\tconst maxItems = Math.max(1, Math.min(MAX_MAX_ITEMS, Math.floor(params.maxItems ?? DEFAULT_MAX_ITEMS)));\n\t\t\t\tconst minTokens = Math.max(0, Math.floor(params.minTokens ?? 0));\n\t\t\t\tconst includePreviews = params.includePreviews !== false;\n\t\t\t\tconst query = params.query?.trim().toLowerCase();\n\n\t\t\t\tconst branch = ctx.sessionManager.getBranch();\n\t\t\t\tconst rows = activeContextRows(branch);\n\t\t\t\tconst activeMessages = activeContextMessages(branch);\n\t\t\t\tconst contextGcReport = getContextGcReport?.(activeMessages);\n\t\t\t\tconst memoryDiagnostics = getMemoryDiagnostics?.();\n\t\t\t\tconst contextUsage = ctx.getContextUsage();\n\t\t\t\tconst systemPrompt = ctx.getSystemPrompt?.() || \"\";\n\t\t\t\tconst activeTools = new Set(getActiveTools());\n\t\t\t\tconst allTools = getAllTools();\n\t\t\t\tconst activeToolInfos = allTools.filter((tool) => activeTools.has(tool.name));\n\t\t\t\tconst systemTokens = estimateTextTokens(systemPrompt);\n\t\t\t\tconst toolSchemaChars = JSON.stringify(\n\t\t\t\t\tactiveToolInfos.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\tparameters: tool.parameters,\n\t\t\t\t\t\tpromptGuidelines: tool.promptGuidelines,\n\t\t\t\t\t})),\n\t\t\t\t).length;\n\t\t\t\tconst toolSchemaTokens = Math.ceil(toolSchemaChars / 4);\n\t\t\t\tconst rowTokenSum = rows.reduce((sum, row) => sum + row.tokens, 0);\n\t\t\t\tconst effectiveRowTokenSum = Math.max(0, rowTokenSum - (contextGcReport?.savedTokens ?? 0));\n\t\t\t\tconst usageText = contextUsage\n\t\t\t\t\t? contextUsage.tokens === null || contextUsage.percent === null\n\t\t\t\t\t\t? `provider usage: unknown/${contextUsage.contextWindow} tokens (usually right after compaction)`\n\t\t\t\t\t\t: `provider usage: ${contextUsage.tokens}/${contextUsage.contextWindow} tokens (${contextUsage.percent.toFixed(1)}%)`\n\t\t\t\t\t: \"provider usage: unavailable (no active model/context window)\";\n\t\t\t\tconst providerTokens = contextUsage?.tokens ?? null;\n\t\t\t\tconst unattributed =\n\t\t\t\t\tproviderTokens === null\n\t\t\t\t\t\t? null\n\t\t\t\t\t\t: Math.max(0, providerTokens - systemTokens - toolSchemaTokens - rowTokenSum);\n\n\t\t\t\tlet filtered = rows.filter((row) => row.tokens >= minTokens);\n\t\t\t\tif (query) {\n\t\t\t\t\tfiltered = filtered.filter((row) => `${row.label}\\n${row.preview}`.toLowerCase().includes(query));\n\t\t\t\t}\n\t\t\t\tconst heaviest = [...filtered].sort((a, b) => b.tokens - a.tokens).slice(0, maxItems);\n\t\t\t\tconst groupLines = groupRows(rows)\n\t\t\t\t\t.slice(0, 12)\n\t\t\t\t\t.map(([label, group]) => `- ${label}: ${group.tokens} est tok across ${group.count} row(s)`);\n\t\t\t\tconst rowLines = heaviest.map((row, index) => {\n\t\t\t\t\tconst base = `${index + 1}. ${row.tokens} est tok · ${row.label} · ${row.entryId ?? \"no-entry\"}`;\n\t\t\t\t\treturn includePreviews\n\t\t\t\t\t\t? `${base}\\n ${cap(row.preview, MAX_PREVIEW_CHARS) || \"(no text preview)\"}`\n\t\t\t\t\t\t: base;\n\t\t\t\t});\n\n\t\t\t\tconst lines = [\n\t\t\t\t\t\"Context audit\",\n\t\t\t\t\tusageText,\n\t\t\t\t\t`active branch rows: ${rows.length}; session row estimate: ${rowTokenSum} tokens`,\n\t\t\t\t\tcontextGcReport\n\t\t\t\t\t\t? `Context GC estimate: ${contextGcReport.savedTokens} tokens saved by packing ${contextGcReport.packedCount} stale row(s); effective session row estimate: ${effectiveRowTokenSum} tokens`\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\t`system prompt estimate: ${systemTokens} tokens (${systemPrompt.length} chars)`,\n\t\t\t\t\t`active tool schema estimate: ${toolSchemaTokens} tokens across ${activeToolInfos.length} active tool(s)`,\n\t\t\t\t\tunattributed === null\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: `provider-reported remainder not mapped by chars/4 rows: ${unattributed} tokens`,\n\t\t\t\t\t...(memoryDiagnostics\n\t\t\t\t\t\t? [\n\t\t\t\t\t\t\t\tformatMemoryRetrievalLine(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\t...formatMemoryProviderLines(memoryDiagnostics.retrieval),\n\t\t\t\t\t\t\t\tformatMemoryPromptInclusionLine(memoryDiagnostics.promptInclusion),\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t: []),\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Largest groups:\",\n\t\t\t\t\t...(groupLines.length ? groupLines : [\"- none\"]),\n\t\t\t\t\t\"\",\n\t\t\t\t\t`Heaviest rows${query ? ` matching ${JSON.stringify(params.query)}` : \"\"}:`,\n\t\t\t\t\t...(rowLines.length ? rowLines : [\"- none\"]),\n\t\t\t\t].filter((line): line is string => line !== undefined);\n\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\" as const, text: lines.join(\"\\n\") }],\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\tcontextUsage,\n\t\t\t\t\t\tsystemPrompt: {\n\t\t\t\t\t\t\tchars: systemPrompt.length,\n\t\t\t\t\t\t\testimatedTokens: systemTokens,\n\t\t\t\t\t\t\tpreview: cap(systemPrompt, MAX_PREVIEW_CHARS),\n\t\t\t\t\t\t},\n\t\t\t\t\t\tactiveTools: activeToolInfos.map((tool) => tool.name),\n\t\t\t\t\t\ttoolSchemaEstimate: { chars: toolSchemaChars, estimatedTokens: toolSchemaTokens },\n\t\t\t\t\t\trowTokenSum,\n\t\t\t\t\t\teffectiveRowTokenSum,\n\t\t\t\t\t\tcontextGc: contextGcReport,\n\t\t\t\t\t\trows,\n\t\t\t\t\t\tmemory: memoryDiagnostics,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t];\n}\n"]}
@@ -2,12 +2,12 @@
2
2
  * Extension runner - executes extensions and manages their lifecycle.
3
3
  */
4
4
  import type { AgentMessage } from "@caupulican/pi-agent-core";
5
+ import type { SessionManager } from "@caupulican/pi-agent-core/node";
5
6
  import type { ImageContent } from "@caupulican/pi-ai";
6
7
  import type { KeyId } from "@caupulican/pi-tui";
7
8
  import type { ResourceDiagnostic } from "../diagnostics.ts";
8
9
  import type { KeybindingsConfig } from "../keybindings.ts";
9
10
  import type { ModelRegistry } from "../model-registry.ts";
10
- import type { SessionManager } from "../session-manager.ts";
11
11
  import type { BuildSystemPromptOptions } from "../system-prompt.ts";
12
12
  import type { BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderRequestEvent, ContextEvent, Extension, ExtensionActions, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionError, ExtensionEvent, ExtensionFlag, ExtensionRuntime, ExtensionShortcut, ExtensionUIContext, InputEvent, InputEventResult, InputSource, MessageEndEvent, MessageRenderer, ProviderConfig, RegisteredTool, ReplacedSessionContext, ResolvedCommand, ResourcesDiscoverEvent, SessionBeforeCompactResult, SessionBeforeForkResult, SessionBeforeSwitchResult, SessionBeforeTreeResult, SessionShutdownEvent, ToolCallEvent, ToolCallEventResult, ToolResultEvent, ToolResultEventResult, UserBashEvent, UserBashEventResult } from "./types.ts";
13
13
  /** Combined result from all before_agent_start handlers */