@xandout/libra-harness 0.1.34 → 0.1.90

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 (453) hide show
  1. package/README.md +30 -30
  2. package/dist/agent.d.ts +8 -0
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +205 -193
  5. package/dist/agent.js.map +1 -1
  6. package/dist/ai-sdk-model.d.ts.map +1 -1
  7. package/dist/ai-sdk-model.js +91 -78
  8. package/dist/ai-sdk-model.js.map +1 -1
  9. package/dist/context.d.ts +2 -0
  10. package/dist/context.d.ts.map +1 -1
  11. package/dist/{extras/extensions → extensions}/auto-steer/extension.d.ts +1 -1
  12. package/dist/extensions/auto-steer/extension.d.ts.map +1 -0
  13. package/dist/extensions/auto-steer/extension.js.map +1 -0
  14. package/dist/extensions/auto-steer/index.d.ts.map +1 -0
  15. package/dist/extensions/auto-steer/index.js.map +1 -0
  16. package/dist/extensions/code-tools/extension.d.ts +15 -0
  17. package/dist/extensions/code-tools/extension.d.ts.map +1 -0
  18. package/dist/extensions/code-tools/extension.js +73 -0
  19. package/dist/extensions/code-tools/extension.js.map +1 -0
  20. package/dist/extensions/code-tools/extension.test.d.ts.map +1 -0
  21. package/dist/extensions/code-tools/extension.test.js +504 -0
  22. package/dist/extensions/code-tools/extension.test.js.map +1 -0
  23. package/dist/extensions/code-tools/index.d.ts.map +1 -0
  24. package/dist/extensions/code-tools/index.js.map +1 -0
  25. package/dist/{extras/extensions → extensions}/code-tools/tools/code-search.d.ts +2 -2
  26. package/dist/extensions/code-tools/tools/code-search.d.ts.map +1 -0
  27. package/dist/{extras/extensions → extensions}/code-tools/tools/code-search.js +1 -1
  28. package/dist/extensions/code-tools/tools/code-search.js.map +1 -0
  29. package/dist/extensions/code-tools/tools/find.d.ts.map +1 -0
  30. package/dist/extensions/code-tools/tools/find.js +83 -0
  31. package/dist/extensions/code-tools/tools/find.js.map +1 -0
  32. package/dist/extensions/code-tools/tools/grep.d.ts.map +1 -0
  33. package/dist/extensions/code-tools/tools/grep.js +90 -0
  34. package/dist/extensions/code-tools/tools/grep.js.map +1 -0
  35. package/dist/extensions/code-tools/tools/read.d.ts.map +1 -0
  36. package/dist/{extras/extensions → extensions}/code-tools/tools/read.js +17 -25
  37. package/dist/extensions/code-tools/tools/read.js.map +1 -0
  38. package/dist/{extras/extensions → extensions}/code-tools/tools/shared.d.ts +5 -1
  39. package/dist/extensions/code-tools/tools/shared.d.ts.map +1 -0
  40. package/dist/{extras/extensions → extensions}/code-tools/tools/shared.js +68 -0
  41. package/dist/extensions/code-tools/tools/shared.js.map +1 -0
  42. package/dist/extensions/code-tools/tools/shell.d.ts +39 -0
  43. package/dist/extensions/code-tools/tools/shell.d.ts.map +1 -0
  44. package/dist/extensions/code-tools/tools/shell.js +441 -0
  45. package/dist/extensions/code-tools/tools/shell.js.map +1 -0
  46. package/dist/{extras/extensions → extensions}/code-tools/tools/todo.d.ts +0 -3
  47. package/dist/extensions/code-tools/tools/todo.d.ts.map +1 -0
  48. package/dist/{extras/extensions → extensions}/code-tools/tools/todo.js +0 -8
  49. package/dist/extensions/code-tools/tools/todo.js.map +1 -0
  50. package/dist/extensions/code-tools/tools/view-image.d.ts +10 -0
  51. package/dist/extensions/code-tools/tools/view-image.d.ts.map +1 -0
  52. package/dist/extensions/code-tools/tools/view-image.js +87 -0
  53. package/dist/extensions/code-tools/tools/view-image.js.map +1 -0
  54. package/dist/extensions/code-tools/tools/write.d.ts.map +1 -0
  55. package/dist/{extras/extensions → extensions}/code-tools/tools/write.js +47 -37
  56. package/dist/extensions/code-tools/tools/write.js.map +1 -0
  57. package/dist/{extras/extensions → extensions}/disk-session/extension.d.ts +45 -2
  58. package/dist/extensions/disk-session/extension.d.ts.map +1 -0
  59. package/dist/extensions/disk-session/extension.js +818 -0
  60. package/dist/extensions/disk-session/extension.js.map +1 -0
  61. package/dist/extensions/disk-session/extension.test.d.ts.map +1 -0
  62. package/dist/{extras/extensions → extensions}/disk-session/extension.test.js +445 -16
  63. package/dist/extensions/disk-session/extension.test.js.map +1 -0
  64. package/dist/extensions/disk-session/index.d.ts +3 -0
  65. package/dist/extensions/disk-session/index.d.ts.map +1 -0
  66. package/dist/extensions/disk-session/index.js +2 -0
  67. package/dist/extensions/disk-session/index.js.map +1 -0
  68. package/dist/{extras/extensions → extensions}/emoji/extension.d.ts +1 -1
  69. package/dist/extensions/emoji/extension.d.ts.map +1 -0
  70. package/dist/extensions/emoji/extension.js.map +1 -0
  71. package/dist/extensions/emoji/index.d.ts.map +1 -0
  72. package/dist/extensions/emoji/index.js.map +1 -0
  73. package/dist/extensions/filesystem/extension.d.ts.map +1 -0
  74. package/dist/extensions/filesystem/extension.js.map +1 -0
  75. package/dist/extensions/filesystem/extension.test.d.ts.map +1 -0
  76. package/dist/extensions/filesystem/extension.test.js.map +1 -0
  77. package/dist/extensions/filesystem/index.d.ts.map +1 -0
  78. package/dist/extensions/filesystem/index.js.map +1 -0
  79. package/dist/extensions/index.d.ts +3 -0
  80. package/dist/extensions/index.d.ts.map +1 -0
  81. package/dist/extensions/index.js +2 -0
  82. package/dist/extensions/index.js.map +1 -0
  83. package/dist/{extras/extensions → extensions}/keyword-extractor/extension.d.ts +1 -1
  84. package/dist/extensions/keyword-extractor/extension.d.ts.map +1 -0
  85. package/dist/{extras/extensions → extensions}/keyword-extractor/extension.js +1 -1
  86. package/dist/extensions/keyword-extractor/extension.js.map +1 -0
  87. package/dist/extensions/keyword-extractor/extension.test.d.ts.map +1 -0
  88. package/dist/extensions/keyword-extractor/extension.test.js.map +1 -0
  89. package/dist/extensions/keyword-extractor/index.d.ts.map +1 -0
  90. package/dist/extensions/keyword-extractor/index.js.map +1 -0
  91. package/dist/extensions/keyword-extractor/nlp.d.ts.map +1 -0
  92. package/dist/extensions/keyword-extractor/nlp.js.map +1 -0
  93. package/dist/extensions/keyword-extractor/nlp.test.d.ts.map +1 -0
  94. package/dist/extensions/keyword-extractor/nlp.test.js.map +1 -0
  95. package/dist/{extras/extension-loader.d.ts → extensions/loader.d.ts} +1 -1
  96. package/dist/extensions/loader.d.ts.map +1 -0
  97. package/dist/{extras/extension-loader.js → extensions/loader.js} +2 -2
  98. package/dist/extensions/loader.js.map +1 -0
  99. package/dist/{extras/extensions → extensions}/logger/extension.d.ts +1 -1
  100. package/dist/extensions/logger/extension.d.ts.map +1 -0
  101. package/dist/{extras/extensions → extensions}/logger/extension.js +1 -1
  102. package/dist/extensions/logger/extension.js.map +1 -0
  103. package/dist/extensions/logger/index.d.ts.map +1 -0
  104. package/dist/extensions/logger/index.js.map +1 -0
  105. package/dist/{extras/extensions → extensions}/mcp/extension.d.ts +1 -1
  106. package/dist/extensions/mcp/extension.d.ts.map +1 -0
  107. package/dist/extensions/mcp/extension.js.map +1 -0
  108. package/dist/extensions/mcp/extension.test.d.ts.map +1 -0
  109. package/dist/{extras/extensions → extensions}/mcp/extension.test.js +1 -1
  110. package/dist/extensions/mcp/extension.test.js.map +1 -0
  111. package/dist/extensions/mcp/index.d.ts.map +1 -0
  112. package/dist/extensions/mcp/index.js.map +1 -0
  113. package/dist/{extras/extensions → extensions}/mem-session/extension.d.ts +2 -2
  114. package/dist/extensions/mem-session/extension.d.ts.map +1 -0
  115. package/dist/extensions/mem-session/extension.js.map +1 -0
  116. package/dist/extensions/mem-session/index.d.ts.map +1 -0
  117. package/dist/extensions/mem-session/index.js.map +1 -0
  118. package/dist/{extras/extensions → extensions}/memory/extension.d.ts +1 -1
  119. package/dist/extensions/memory/extension.d.ts.map +1 -0
  120. package/dist/{extras/extensions → extensions}/memory/extension.js +1 -1
  121. package/dist/extensions/memory/extension.js.map +1 -0
  122. package/dist/extensions/memory/index.d.ts +4 -0
  123. package/dist/extensions/memory/index.d.ts.map +1 -0
  124. package/dist/extensions/memory/index.js.map +1 -0
  125. package/dist/{extras/extensions → extensions}/memory/llm-extractor.d.ts +1 -1
  126. package/dist/extensions/memory/llm-extractor.d.ts.map +1 -0
  127. package/dist/{extras/extensions → extensions}/memory/llm-extractor.js +1 -1
  128. package/dist/extensions/memory/llm-extractor.js.map +1 -0
  129. package/dist/{extras/extensions → extensions}/memory/types.d.ts +2 -2
  130. package/dist/extensions/memory/types.d.ts.map +1 -0
  131. package/dist/extensions/memory/types.js.map +1 -0
  132. package/dist/{extras/extensions → extensions}/otel/extension.d.ts +1 -1
  133. package/dist/extensions/otel/extension.d.ts.map +1 -0
  134. package/dist/{extras/extensions → extensions}/otel/extension.js +1 -1
  135. package/dist/extensions/otel/extension.js.map +1 -0
  136. package/dist/extensions/otel/extension.test.d.ts.map +1 -0
  137. package/dist/{extras/extensions → extensions}/otel/extension.test.js +1 -1
  138. package/dist/extensions/otel/extension.test.js.map +1 -0
  139. package/dist/extensions/otel/index.d.ts.map +1 -0
  140. package/dist/extensions/otel/index.js.map +1 -0
  141. package/dist/extensions/otel/jsonl-span-exporter.d.ts.map +1 -0
  142. package/dist/extensions/otel/jsonl-span-exporter.js.map +1 -0
  143. package/dist/{extras/extensions → extensions}/scripts/extension.d.ts +1 -1
  144. package/dist/extensions/scripts/extension.d.ts.map +1 -0
  145. package/dist/extensions/scripts/extension.js.map +1 -0
  146. package/dist/extensions/scripts/extension.test.d.ts.map +1 -0
  147. package/dist/extensions/scripts/extension.test.js.map +1 -0
  148. package/dist/extensions/scripts/index.d.ts.map +1 -0
  149. package/dist/extensions/scripts/index.js.map +1 -0
  150. package/dist/{extras/extensions → extensions}/skills/extension.d.ts +1 -1
  151. package/dist/extensions/skills/extension.d.ts.map +1 -0
  152. package/dist/extensions/skills/extension.js.map +1 -0
  153. package/dist/extensions/skills/extension.test.d.ts.map +1 -0
  154. package/dist/{extras/extensions → extensions}/skills/extension.test.js +1 -1
  155. package/dist/extensions/skills/extension.test.js.map +1 -0
  156. package/dist/extensions/skills/index.d.ts.map +1 -0
  157. package/dist/extensions/skills/index.js.map +1 -0
  158. package/dist/{extras/extensions → extensions}/streaming/extension.d.ts +1 -1
  159. package/dist/extensions/streaming/extension.d.ts.map +1 -0
  160. package/dist/extensions/streaming/extension.js.map +1 -0
  161. package/dist/extensions/streaming/index.d.ts.map +1 -0
  162. package/dist/extensions/streaming/index.js.map +1 -0
  163. package/dist/{extras/extensions → extensions}/structured-output/extension.d.ts +1 -1
  164. package/dist/extensions/structured-output/extension.d.ts.map +1 -0
  165. package/dist/extensions/structured-output/extension.js.map +1 -0
  166. package/dist/extensions/structured-output/index.d.ts.map +1 -0
  167. package/dist/extensions/structured-output/index.js.map +1 -0
  168. package/dist/{extras/extensions → extensions}/timestamp/extension.d.ts +1 -1
  169. package/dist/extensions/timestamp/extension.d.ts.map +1 -0
  170. package/dist/extensions/timestamp/extension.js.map +1 -0
  171. package/dist/extensions/timestamp/index.d.ts.map +1 -0
  172. package/dist/extensions/timestamp/index.js.map +1 -0
  173. package/dist/{extras/extensions → extensions}/token-stats/extension.d.ts +1 -1
  174. package/dist/extensions/token-stats/extension.d.ts.map +1 -0
  175. package/dist/extensions/token-stats/extension.js.map +1 -0
  176. package/dist/extensions/token-stats/extension.test.d.ts.map +1 -0
  177. package/dist/{extras/extensions → extensions}/token-stats/extension.test.js +1 -1
  178. package/dist/extensions/token-stats/extension.test.js.map +1 -0
  179. package/dist/extensions/token-stats/index.d.ts.map +1 -0
  180. package/dist/extensions/token-stats/index.js.map +1 -0
  181. package/dist/{extras/extensions → extensions}/tool-buffer/extension.d.ts +1 -1
  182. package/dist/extensions/tool-buffer/extension.d.ts.map +1 -0
  183. package/dist/extensions/tool-buffer/extension.js.map +1 -0
  184. package/dist/extensions/tool-buffer/extension.test.d.ts.map +1 -0
  185. package/dist/{extras/extensions → extensions}/tool-buffer/extension.test.js +1 -1
  186. package/dist/extensions/tool-buffer/extension.test.js.map +1 -0
  187. package/dist/extensions/tool-buffer/index.d.ts.map +1 -0
  188. package/dist/extensions/tool-buffer/index.js.map +1 -0
  189. package/dist/{extras/extensions → extensions}/weather-tool/extension.d.ts +1 -1
  190. package/dist/extensions/weather-tool/extension.d.ts.map +1 -0
  191. package/dist/extensions/weather-tool/extension.js.map +1 -0
  192. package/dist/extensions/weather-tool/index.d.ts.map +1 -0
  193. package/dist/extensions/weather-tool/index.js.map +1 -0
  194. package/dist/handle.d.ts +4 -0
  195. package/dist/handle.d.ts.map +1 -1
  196. package/dist/{extras/models → models}/ai-sdk-resolver.d.ts +1 -1
  197. package/dist/models/ai-sdk-resolver.d.ts.map +1 -0
  198. package/dist/{extras/models → models}/ai-sdk-resolver.js +1 -1
  199. package/dist/models/ai-sdk-resolver.js.map +1 -0
  200. package/dist/models/index.d.ts.map +1 -0
  201. package/dist/models/index.js.map +1 -0
  202. package/dist/{extras/models → models}/routing-model.d.ts +1 -1
  203. package/dist/models/routing-model.d.ts.map +1 -0
  204. package/dist/{extras/models → models}/routing-model.js +1 -1
  205. package/dist/models/routing-model.js.map +1 -0
  206. package/dist/openai-provider/index.d.ts.map +1 -0
  207. package/dist/openai-provider/index.js.map +1 -0
  208. package/dist/{extras/openai-provider → openai-provider}/server.d.ts +1 -1
  209. package/dist/openai-provider/server.d.ts.map +1 -0
  210. package/dist/openai-provider/server.js.map +1 -0
  211. package/package.json +108 -83
  212. package/dist/extras/extension-loader.d.ts.map +0 -1
  213. package/dist/extras/extension-loader.js.map +0 -1
  214. package/dist/extras/extensions/auto-steer/extension.d.ts.map +0 -1
  215. package/dist/extras/extensions/auto-steer/extension.js.map +0 -1
  216. package/dist/extras/extensions/auto-steer/index.d.ts.map +0 -1
  217. package/dist/extras/extensions/auto-steer/index.js.map +0 -1
  218. package/dist/extras/extensions/code-tools/extension.d.ts +0 -83
  219. package/dist/extras/extensions/code-tools/extension.d.ts.map +0 -1
  220. package/dist/extras/extensions/code-tools/extension.js +0 -93
  221. package/dist/extras/extensions/code-tools/extension.js.map +0 -1
  222. package/dist/extras/extensions/code-tools/extension.test.d.ts.map +0 -1
  223. package/dist/extras/extensions/code-tools/extension.test.js +0 -656
  224. package/dist/extras/extensions/code-tools/extension.test.js.map +0 -1
  225. package/dist/extras/extensions/code-tools/index.d.ts.map +0 -1
  226. package/dist/extras/extensions/code-tools/index.js.map +0 -1
  227. package/dist/extras/extensions/code-tools/tools/code-search.d.ts.map +0 -1
  228. package/dist/extras/extensions/code-tools/tools/code-search.js.map +0 -1
  229. package/dist/extras/extensions/code-tools/tools/find.d.ts.map +0 -1
  230. package/dist/extras/extensions/code-tools/tools/find.js +0 -161
  231. package/dist/extras/extensions/code-tools/tools/find.js.map +0 -1
  232. package/dist/extras/extensions/code-tools/tools/grep.d.ts.map +0 -1
  233. package/dist/extras/extensions/code-tools/tools/grep.js +0 -307
  234. package/dist/extras/extensions/code-tools/tools/grep.js.map +0 -1
  235. package/dist/extras/extensions/code-tools/tools/read.d.ts.map +0 -1
  236. package/dist/extras/extensions/code-tools/tools/read.js.map +0 -1
  237. package/dist/extras/extensions/code-tools/tools/shared.d.ts.map +0 -1
  238. package/dist/extras/extensions/code-tools/tools/shared.js.map +0 -1
  239. package/dist/extras/extensions/code-tools/tools/shell.d.ts +0 -49
  240. package/dist/extras/extensions/code-tools/tools/shell.d.ts.map +0 -1
  241. package/dist/extras/extensions/code-tools/tools/shell.js +0 -623
  242. package/dist/extras/extensions/code-tools/tools/shell.js.map +0 -1
  243. package/dist/extras/extensions/code-tools/tools/todo.d.ts.map +0 -1
  244. package/dist/extras/extensions/code-tools/tools/todo.js.map +0 -1
  245. package/dist/extras/extensions/code-tools/tools/write.d.ts.map +0 -1
  246. package/dist/extras/extensions/code-tools/tools/write.js.map +0 -1
  247. package/dist/extras/extensions/disk-session/extension.d.ts.map +0 -1
  248. package/dist/extras/extensions/disk-session/extension.js +0 -640
  249. package/dist/extras/extensions/disk-session/extension.js.map +0 -1
  250. package/dist/extras/extensions/disk-session/extension.test.d.ts.map +0 -1
  251. package/dist/extras/extensions/disk-session/extension.test.js.map +0 -1
  252. package/dist/extras/extensions/disk-session/index.d.ts +0 -3
  253. package/dist/extras/extensions/disk-session/index.d.ts.map +0 -1
  254. package/dist/extras/extensions/disk-session/index.js +0 -2
  255. package/dist/extras/extensions/disk-session/index.js.map +0 -1
  256. package/dist/extras/extensions/emoji/extension.d.ts.map +0 -1
  257. package/dist/extras/extensions/emoji/extension.js.map +0 -1
  258. package/dist/extras/extensions/emoji/index.d.ts.map +0 -1
  259. package/dist/extras/extensions/emoji/index.js.map +0 -1
  260. package/dist/extras/extensions/filesystem/extension.d.ts.map +0 -1
  261. package/dist/extras/extensions/filesystem/extension.js.map +0 -1
  262. package/dist/extras/extensions/filesystem/extension.test.d.ts.map +0 -1
  263. package/dist/extras/extensions/filesystem/extension.test.js.map +0 -1
  264. package/dist/extras/extensions/filesystem/index.d.ts.map +0 -1
  265. package/dist/extras/extensions/filesystem/index.js.map +0 -1
  266. package/dist/extras/extensions/keyword-extractor/extension.d.ts.map +0 -1
  267. package/dist/extras/extensions/keyword-extractor/extension.js.map +0 -1
  268. package/dist/extras/extensions/keyword-extractor/extension.test.d.ts.map +0 -1
  269. package/dist/extras/extensions/keyword-extractor/extension.test.js.map +0 -1
  270. package/dist/extras/extensions/keyword-extractor/index.d.ts.map +0 -1
  271. package/dist/extras/extensions/keyword-extractor/index.js.map +0 -1
  272. package/dist/extras/extensions/keyword-extractor/nlp.d.ts.map +0 -1
  273. package/dist/extras/extensions/keyword-extractor/nlp.js.map +0 -1
  274. package/dist/extras/extensions/keyword-extractor/nlp.test.d.ts.map +0 -1
  275. package/dist/extras/extensions/keyword-extractor/nlp.test.js.map +0 -1
  276. package/dist/extras/extensions/logger/extension.d.ts.map +0 -1
  277. package/dist/extras/extensions/logger/extension.js.map +0 -1
  278. package/dist/extras/extensions/logger/index.d.ts.map +0 -1
  279. package/dist/extras/extensions/logger/index.js.map +0 -1
  280. package/dist/extras/extensions/mcp/extension.d.ts.map +0 -1
  281. package/dist/extras/extensions/mcp/extension.js.map +0 -1
  282. package/dist/extras/extensions/mcp/extension.test.d.ts.map +0 -1
  283. package/dist/extras/extensions/mcp/extension.test.js.map +0 -1
  284. package/dist/extras/extensions/mcp/index.d.ts.map +0 -1
  285. package/dist/extras/extensions/mcp/index.js.map +0 -1
  286. package/dist/extras/extensions/mem-session/extension.d.ts.map +0 -1
  287. package/dist/extras/extensions/mem-session/extension.js.map +0 -1
  288. package/dist/extras/extensions/mem-session/index.d.ts.map +0 -1
  289. package/dist/extras/extensions/mem-session/index.js.map +0 -1
  290. package/dist/extras/extensions/memory/extension.d.ts.map +0 -1
  291. package/dist/extras/extensions/memory/extension.js.map +0 -1
  292. package/dist/extras/extensions/memory/index.d.ts +0 -5
  293. package/dist/extras/extensions/memory/index.d.ts.map +0 -1
  294. package/dist/extras/extensions/memory/index.js.map +0 -1
  295. package/dist/extras/extensions/memory/llm-extractor.d.ts.map +0 -1
  296. package/dist/extras/extensions/memory/llm-extractor.js.map +0 -1
  297. package/dist/extras/extensions/memory/types.d.ts.map +0 -1
  298. package/dist/extras/extensions/memory/types.js.map +0 -1
  299. package/dist/extras/extensions/otel/extension.d.ts.map +0 -1
  300. package/dist/extras/extensions/otel/extension.js.map +0 -1
  301. package/dist/extras/extensions/otel/extension.test.d.ts.map +0 -1
  302. package/dist/extras/extensions/otel/extension.test.js.map +0 -1
  303. package/dist/extras/extensions/otel/index.d.ts.map +0 -1
  304. package/dist/extras/extensions/otel/index.js.map +0 -1
  305. package/dist/extras/extensions/otel/jsonl-span-exporter.d.ts.map +0 -1
  306. package/dist/extras/extensions/otel/jsonl-span-exporter.js.map +0 -1
  307. package/dist/extras/extensions/scripts/extension.d.ts.map +0 -1
  308. package/dist/extras/extensions/scripts/extension.js.map +0 -1
  309. package/dist/extras/extensions/scripts/extension.test.d.ts.map +0 -1
  310. package/dist/extras/extensions/scripts/extension.test.js.map +0 -1
  311. package/dist/extras/extensions/scripts/index.d.ts.map +0 -1
  312. package/dist/extras/extensions/scripts/index.js.map +0 -1
  313. package/dist/extras/extensions/skills/extension.d.ts.map +0 -1
  314. package/dist/extras/extensions/skills/extension.js.map +0 -1
  315. package/dist/extras/extensions/skills/extension.test.d.ts.map +0 -1
  316. package/dist/extras/extensions/skills/extension.test.js.map +0 -1
  317. package/dist/extras/extensions/skills/index.d.ts.map +0 -1
  318. package/dist/extras/extensions/skills/index.js.map +0 -1
  319. package/dist/extras/extensions/streaming/extension.d.ts.map +0 -1
  320. package/dist/extras/extensions/streaming/extension.js.map +0 -1
  321. package/dist/extras/extensions/streaming/index.d.ts.map +0 -1
  322. package/dist/extras/extensions/streaming/index.js.map +0 -1
  323. package/dist/extras/extensions/structured-output/extension.d.ts.map +0 -1
  324. package/dist/extras/extensions/structured-output/extension.js.map +0 -1
  325. package/dist/extras/extensions/structured-output/index.d.ts.map +0 -1
  326. package/dist/extras/extensions/structured-output/index.js.map +0 -1
  327. package/dist/extras/extensions/timestamp/extension.d.ts.map +0 -1
  328. package/dist/extras/extensions/timestamp/extension.js.map +0 -1
  329. package/dist/extras/extensions/timestamp/index.d.ts.map +0 -1
  330. package/dist/extras/extensions/timestamp/index.js.map +0 -1
  331. package/dist/extras/extensions/token-stats/extension.d.ts.map +0 -1
  332. package/dist/extras/extensions/token-stats/extension.js.map +0 -1
  333. package/dist/extras/extensions/token-stats/extension.test.d.ts.map +0 -1
  334. package/dist/extras/extensions/token-stats/extension.test.js.map +0 -1
  335. package/dist/extras/extensions/token-stats/index.d.ts.map +0 -1
  336. package/dist/extras/extensions/token-stats/index.js.map +0 -1
  337. package/dist/extras/extensions/tool-buffer/extension.d.ts.map +0 -1
  338. package/dist/extras/extensions/tool-buffer/extension.js.map +0 -1
  339. package/dist/extras/extensions/tool-buffer/extension.test.d.ts.map +0 -1
  340. package/dist/extras/extensions/tool-buffer/extension.test.js.map +0 -1
  341. package/dist/extras/extensions/tool-buffer/index.d.ts.map +0 -1
  342. package/dist/extras/extensions/tool-buffer/index.js.map +0 -1
  343. package/dist/extras/extensions/weather-tool/extension.d.ts.map +0 -1
  344. package/dist/extras/extensions/weather-tool/extension.js.map +0 -1
  345. package/dist/extras/extensions/weather-tool/index.d.ts.map +0 -1
  346. package/dist/extras/extensions/weather-tool/index.js.map +0 -1
  347. package/dist/extras/models/ai-sdk-resolver.d.ts.map +0 -1
  348. package/dist/extras/models/ai-sdk-resolver.js.map +0 -1
  349. package/dist/extras/models/index.d.ts.map +0 -1
  350. package/dist/extras/models/index.js.map +0 -1
  351. package/dist/extras/models/routing-model.d.ts.map +0 -1
  352. package/dist/extras/models/routing-model.js.map +0 -1
  353. package/dist/extras/openai-provider/index.d.ts.map +0 -1
  354. package/dist/extras/openai-provider/index.js.map +0 -1
  355. package/dist/extras/openai-provider/server.d.ts.map +0 -1
  356. package/dist/extras/openai-provider/server.js.map +0 -1
  357. /package/dist/{extras/extensions → extensions}/auto-steer/extension.js +0 -0
  358. /package/dist/{extras/extensions → extensions}/auto-steer/extension.json +0 -0
  359. /package/dist/{extras/extensions → extensions}/auto-steer/index.d.ts +0 -0
  360. /package/dist/{extras/extensions → extensions}/auto-steer/index.js +0 -0
  361. /package/dist/{extras/extensions → extensions}/code-tools/extension.json +0 -0
  362. /package/dist/{extras/extensions → extensions}/code-tools/extension.test.d.ts +0 -0
  363. /package/dist/{extras/extensions → extensions}/code-tools/index.d.ts +0 -0
  364. /package/dist/{extras/extensions → extensions}/code-tools/index.js +0 -0
  365. /package/dist/{extras/extensions → extensions}/code-tools/tools/find.d.ts +0 -0
  366. /package/dist/{extras/extensions → extensions}/code-tools/tools/grep.d.ts +0 -0
  367. /package/dist/{extras/extensions → extensions}/code-tools/tools/read.d.ts +0 -0
  368. /package/dist/{extras/extensions → extensions}/code-tools/tools/write.d.ts +0 -0
  369. /package/dist/{extras/extensions → extensions}/disk-session/extension.json +0 -0
  370. /package/dist/{extras/extensions → extensions}/disk-session/extension.test.d.ts +0 -0
  371. /package/dist/{extras/extensions → extensions}/emoji/extension.js +0 -0
  372. /package/dist/{extras/extensions → extensions}/emoji/extension.json +0 -0
  373. /package/dist/{extras/extensions → extensions}/emoji/index.d.ts +0 -0
  374. /package/dist/{extras/extensions → extensions}/emoji/index.js +0 -0
  375. /package/dist/{extras/extensions → extensions}/filesystem/extension.d.ts +0 -0
  376. /package/dist/{extras/extensions → extensions}/filesystem/extension.js +0 -0
  377. /package/dist/{extras/extensions → extensions}/filesystem/extension.json +0 -0
  378. /package/dist/{extras/extensions → extensions}/filesystem/extension.test.d.ts +0 -0
  379. /package/dist/{extras/extensions → extensions}/filesystem/extension.test.js +0 -0
  380. /package/dist/{extras/extensions → extensions}/filesystem/index.d.ts +0 -0
  381. /package/dist/{extras/extensions → extensions}/filesystem/index.js +0 -0
  382. /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.json +0 -0
  383. /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.test.d.ts +0 -0
  384. /package/dist/{extras/extensions → extensions}/keyword-extractor/extension.test.js +0 -0
  385. /package/dist/{extras/extensions → extensions}/keyword-extractor/index.d.ts +0 -0
  386. /package/dist/{extras/extensions → extensions}/keyword-extractor/index.js +0 -0
  387. /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.d.ts +0 -0
  388. /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.js +0 -0
  389. /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.test.d.ts +0 -0
  390. /package/dist/{extras/extensions → extensions}/keyword-extractor/nlp.test.js +0 -0
  391. /package/dist/{extras/extensions → extensions}/logger/extension.json +0 -0
  392. /package/dist/{extras/extensions → extensions}/logger/index.d.ts +0 -0
  393. /package/dist/{extras/extensions → extensions}/logger/index.js +0 -0
  394. /package/dist/{extras/extensions → extensions}/mcp/extension.js +0 -0
  395. /package/dist/{extras/extensions → extensions}/mcp/extension.json +0 -0
  396. /package/dist/{extras/extensions → extensions}/mcp/extension.test.d.ts +0 -0
  397. /package/dist/{extras/extensions → extensions}/mcp/index.d.ts +0 -0
  398. /package/dist/{extras/extensions → extensions}/mcp/index.js +0 -0
  399. /package/dist/{extras/extensions → extensions}/mem-session/extension.js +0 -0
  400. /package/dist/{extras/extensions → extensions}/mem-session/extension.json +0 -0
  401. /package/dist/{extras/extensions → extensions}/mem-session/index.d.ts +0 -0
  402. /package/dist/{extras/extensions → extensions}/mem-session/index.js +0 -0
  403. /package/dist/{extras/extensions → extensions}/memory/extension.json +0 -0
  404. /package/dist/{extras/extensions → extensions}/memory/index.js +0 -0
  405. /package/dist/{extras/extensions → extensions}/memory/types.js +0 -0
  406. /package/dist/{extras/extensions → extensions}/otel/extension.json +0 -0
  407. /package/dist/{extras/extensions → extensions}/otel/extension.test.d.ts +0 -0
  408. /package/dist/{extras/extensions → extensions}/otel/index.d.ts +0 -0
  409. /package/dist/{extras/extensions → extensions}/otel/index.js +0 -0
  410. /package/dist/{extras/extensions → extensions}/otel/jsonl-span-exporter.d.ts +0 -0
  411. /package/dist/{extras/extensions → extensions}/otel/jsonl-span-exporter.js +0 -0
  412. /package/dist/{extras/extensions → extensions}/scripts/extension.js +0 -0
  413. /package/dist/{extras/extensions → extensions}/scripts/extension.json +0 -0
  414. /package/dist/{extras/extensions → extensions}/scripts/extension.test.d.ts +0 -0
  415. /package/dist/{extras/extensions → extensions}/scripts/extension.test.js +0 -0
  416. /package/dist/{extras/extensions → extensions}/scripts/index.d.ts +0 -0
  417. /package/dist/{extras/extensions → extensions}/scripts/index.js +0 -0
  418. /package/dist/{extras/extensions → extensions}/skills/extension.js +0 -0
  419. /package/dist/{extras/extensions → extensions}/skills/extension.json +0 -0
  420. /package/dist/{extras/extensions → extensions}/skills/extension.test.d.ts +0 -0
  421. /package/dist/{extras/extensions → extensions}/skills/index.d.ts +0 -0
  422. /package/dist/{extras/extensions → extensions}/skills/index.js +0 -0
  423. /package/dist/{extras/extensions → extensions}/streaming/extension.js +0 -0
  424. /package/dist/{extras/extensions → extensions}/streaming/extension.json +0 -0
  425. /package/dist/{extras/extensions → extensions}/streaming/index.d.ts +0 -0
  426. /package/dist/{extras/extensions → extensions}/streaming/index.js +0 -0
  427. /package/dist/{extras/extensions → extensions}/structured-output/extension.js +0 -0
  428. /package/dist/{extras/extensions → extensions}/structured-output/extension.json +0 -0
  429. /package/dist/{extras/extensions → extensions}/structured-output/index.d.ts +0 -0
  430. /package/dist/{extras/extensions → extensions}/structured-output/index.js +0 -0
  431. /package/dist/{extras/extensions → extensions}/timestamp/extension.js +0 -0
  432. /package/dist/{extras/extensions → extensions}/timestamp/extension.json +0 -0
  433. /package/dist/{extras/extensions → extensions}/timestamp/index.d.ts +0 -0
  434. /package/dist/{extras/extensions → extensions}/timestamp/index.js +0 -0
  435. /package/dist/{extras/extensions → extensions}/token-stats/extension.js +0 -0
  436. /package/dist/{extras/extensions → extensions}/token-stats/extension.json +0 -0
  437. /package/dist/{extras/extensions → extensions}/token-stats/extension.test.d.ts +0 -0
  438. /package/dist/{extras/extensions → extensions}/token-stats/index.d.ts +0 -0
  439. /package/dist/{extras/extensions → extensions}/token-stats/index.js +0 -0
  440. /package/dist/{extras/extensions → extensions}/tool-buffer/extension.js +0 -0
  441. /package/dist/{extras/extensions → extensions}/tool-buffer/extension.json +0 -0
  442. /package/dist/{extras/extensions → extensions}/tool-buffer/extension.test.d.ts +0 -0
  443. /package/dist/{extras/extensions → extensions}/tool-buffer/index.d.ts +0 -0
  444. /package/dist/{extras/extensions → extensions}/tool-buffer/index.js +0 -0
  445. /package/dist/{extras/extensions → extensions}/weather-tool/extension.js +0 -0
  446. /package/dist/{extras/extensions → extensions}/weather-tool/extension.json +0 -0
  447. /package/dist/{extras/extensions → extensions}/weather-tool/index.d.ts +0 -0
  448. /package/dist/{extras/extensions → extensions}/weather-tool/index.js +0 -0
  449. /package/dist/{extras/models → models}/index.d.ts +0 -0
  450. /package/dist/{extras/models → models}/index.js +0 -0
  451. /package/dist/{extras/openai-provider → openai-provider}/index.d.ts +0 -0
  452. /package/dist/{extras/openai-provider → openai-provider}/index.js +0 -0
  453. /package/dist/{extras/openai-provider → openai-provider}/server.js +0 -0
@@ -1,640 +0,0 @@
1
- import { readFileSync, appendFileSync, mkdirSync, readdirSync, writeFileSync, existsSync, renameSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- /**
4
- * Default resolver: reads `metadata.session` as a `SessionIdentity`,
5
- * falls back to `metadata.sessionId` as a plain key, then to `'default'`.
6
- */
7
- const defaultResolver = {
8
- resolve(metadata) {
9
- const session = metadata.session;
10
- if (session && typeof session.key === 'string')
11
- return session;
12
- const sessionId = metadata.sessionId;
13
- if (sessionId)
14
- return { key: sessionId, messageTs: '' };
15
- return { key: 'default', messageTs: '' };
16
- },
17
- };
18
- /**
19
- * Disk-backed session extension.
20
- *
21
- * ## Architecture
22
- *
23
- * **One JSONL file per session** (`<sessionKey>.jsonl`). Append-only —
24
- * every message the agent sees (human or bot, top-level or threaded) is
25
- * appended. This log is the source of truth.
26
- *
27
- * **Snapshot at beforeTurn**: when a turn starts, the extension takes a
28
- * read-only snapshot of the session log at that moment. The turn runs
29
- * against the snapshot. Concurrent turns each take their own snapshot
30
- * and don't see each other's in-progress work.
31
- *
32
- * **Fork for threads**: when a thread reply comes in (identity has
33
- * `threadTs`), the snapshot is filtered to include only:
34
- * 1. Top-level messages before the thread parent (channel context)
35
- * 2. All messages in that thread (parent + replies)
36
- * 3. Recent top-level messages after the last thread reply
37
- *
38
- * **Append after turn**: when the turn finishes, new messages (user +
39
- * assistant + tool calls) are appended to the session log. No data is
40
- * ever rewritten or reordered.
41
- *
42
- * **Stable prefix for LLM caching**: the messages array is built as
43
- * [system prompt] + [stable session history] + [new user message]
44
- * The session history grows monotonically (append-only), so earlier
45
- * tokens stay cached upstream. Per-turn metadata is injected at the end
46
- * of the context (by a host-side `beforeContext` hook), not the
47
- * beginning, to preserve the cache prefix.
48
- *
49
- * ## Host integration
50
- *
51
- * The host supplies a {@link SessionResolver} (or writes
52
- * `metadata.session`) so the extension knows which session a turn
53
- * belongs to. The extension itself is host-agnostic — it doesn't know
54
- * about Slack, Discord, or any other platform.
55
- */
56
- export default function createDiskSessionExtension(config) {
57
- const dir = config?.sessionDir ?? './sessions';
58
- const maxRecords = config?.maxRecords ?? 1000;
59
- const maxContextMessages = config?.maxContextMessages ?? 50;
60
- const channelContextMessages = config?.channelContextMessages ?? 10;
61
- const recentChannelMessages = config?.recentChannelMessages ?? 5;
62
- const loadOnStartup = config?.loadOnStartup ?? true;
63
- const resolver = config?.resolver ?? defaultResolver;
64
- mkdirSync(dir, { recursive: true });
65
- // In-memory cache: sessionKey → SessionRecord[]
66
- // This is the live log. Reads take a snapshot (copy); writes append.
67
- const store = new Map();
68
- // ── Load existing sessions from disk ──────────────────────────
69
- if (loadOnStartup) {
70
- try {
71
- const files = readdirSync(dir).filter((f) => f.endsWith('.jsonl'));
72
- let totalRecords = 0;
73
- for (const file of files) {
74
- try {
75
- const raw = readFileSync(join(dir, file), 'utf-8');
76
- const lines = raw.split('\n').filter((l) => l.trim());
77
- const records = lines.map((l) => JSON.parse(l));
78
- const sessionKey = file.replace(/\.jsonl$/, '');
79
- store.set(sessionKey, records.slice(-maxRecords));
80
- totalRecords += records.length;
81
- }
82
- catch {
83
- // Skip corrupt files.
84
- }
85
- }
86
- if (store.size > 0 && config?.verbose !== false) {
87
- console.log(`[disk-session] loaded ${store.size} session(s), ${totalRecords} record(s) from ${dir}`);
88
- }
89
- }
90
- catch {
91
- // Directory doesn't exist — start empty.
92
- }
93
- }
94
- function filePath(sessionKey) {
95
- const safe = sessionKey.replace(/[^a-zA-Z0-9_-]/g, '_');
96
- return join(dir, `${safe}.jsonl`);
97
- }
98
- function appendToFile(sessionKey, records) {
99
- if (records.length === 0)
100
- return;
101
- const lines = records.map((r) => JSON.stringify(r)).join('\n') + '\n';
102
- try {
103
- appendFileSync(filePath(sessionKey), lines);
104
- }
105
- catch (err) {
106
- console.error(`[disk-session] failed to append to ${sessionKey}:`, err);
107
- }
108
- }
109
- // ── Convert between Message and SessionRecord ──────────────────
110
- function toMessage(r) {
111
- return {
112
- // `toMessage` is only called on records that passed
113
- // `isConversationMessage`, which excludes 'control' (and 'tool').
114
- role: r.role,
115
- content: r.content,
116
- ...(r.toolCalls ? { toolCalls: r.toolCalls } : {}),
117
- ...(r.toolCallId ? { toolCallId: r.toolCallId } : {}),
118
- ...(r.name ? { name: r.name } : {}),
119
- };
120
- }
121
- function toRecord(msg, ts, threadTs) {
122
- return {
123
- role: msg.role,
124
- content: msg.content,
125
- ...(msg.toolCalls ? { toolCalls: msg.toolCalls } : {}),
126
- ...(msg.toolCallId ? { toolCallId: msg.toolCallId } : {}),
127
- ...(msg.name ? { name: msg.name } : {}),
128
- ts,
129
- ...(threadTs ? { threadTs } : {}),
130
- recordedAt: new Date().toISOString(),
131
- };
132
- }
133
- // Filter for context windows: only keep user messages, system
134
- // messages (background channel context), and assistant messages with
135
- // text content (not tool-call intermediates or control records).
136
- // Tool messages, control records, and assistant messages that only
137
- // contain toolCalls are turn-internal mechanics — including them
138
- // without the full tool-call flow produces invalid message sequences
139
- // for the LLM. Control records (e.g. /halt) are persisted for audit
140
- // but never shown to the model.
141
- const isConversationMessage = (r) => {
142
- if (r.role === 'tool')
143
- return false;
144
- if (r.role === 'control')
145
- return false;
146
- // Drop any assistant message that has tool_calls — even if it also
147
- // has text content. Keeping it without the matching tool response
148
- // messages produces an invalid sequence for the LLM.
149
- if (r.role === 'assistant' && r.toolCalls?.length)
150
- return false;
151
- return true; // user, system, assistant (without tool calls)
152
- };
153
- // Drop trailing user messages that don't have a following assistant
154
- // response. This happens when a turn was interrupted (crash, halt,
155
- // kill -9). Including an unanswered user request from a prior session
156
- // confuses the agent — it sees a request it never responded to.
157
- function dropIncompleteTrailingTurn(records) {
158
- const result = [...records];
159
- while (result.length > 0 && result[result.length - 1].role === 'user') {
160
- result.pop();
161
- }
162
- return result;
163
- }
164
- // ── Build context (the "fork") from a snapshot ────────────────
165
- // The snapshot is a read-only copy of the session records at the
166
- // moment the turn started. This function builds the messages array
167
- // that the agent will see.
168
- //
169
- // For top-level messages and DMs: last N records (simple slice).
170
- // For thread replies: channel context before parent + thread history.
171
- function buildContext(snapshot, threadTs, isDirect) {
172
- if (snapshot.length === 0)
173
- return [];
174
- // DM or top-level message: last N messages, but filter out
175
- // tool-call intermediates that might get split by the slice.
176
- if (isDirect || !threadTs) {
177
- const filtered = snapshot.filter(isConversationMessage);
178
- // Drop incomplete turns: a user message at the end without a
179
- // following assistant response means the turn was interrupted
180
- // (crash, halt, etc). Including it would confuse the agent with
181
- // an unanswered request from a previous session.
182
- const complete = dropIncompleteTrailingTurn(filtered);
183
- return complete
184
- .slice(-maxContextMessages)
185
- .map(toMessage);
186
- }
187
- // Thread: fork from channel context.
188
- const parentIdx = snapshot.findIndex((r) => r.ts === threadTs);
189
- if (parentIdx === -1) {
190
- // Parent not in snapshot (evicted from cache or very old).
191
- // Fall back to last N messages.
192
- return snapshot
193
- .filter(isConversationMessage)
194
- .slice(-maxContextMessages)
195
- .map(toMessage);
196
- }
197
- // Top-level messages before the parent (channel context at fork point).
198
- const topLevelBefore = snapshot
199
- .slice(0, parentIdx)
200
- .filter((r) => !r.threadTs && isConversationMessage(r))
201
- .slice(-channelContextMessages);
202
- // All messages in this thread (including the parent).
203
- // Filter out tool-call intermediates — they produce invalid message
204
- // sequences if they get split or truncated by the context window.
205
- const threadMessages = snapshot
206
- .filter((r) => (r.ts === threadTs || r.threadTs === threadTs) && isConversationMessage(r));
207
- // Recent top-level messages after the last thread reply.
208
- // This gives the agent awareness of what's happened in the channel
209
- // since the thread was last active — without pulling in the entire
210
- // channel history. Find the last thread message's index in the
211
- // snapshot by ts, then take top-level messages after it.
212
- const lastThreadTs = threadMessages[threadMessages.length - 1]?.ts ?? threadTs;
213
- let lastThreadIdx = parentIdx;
214
- for (let i = snapshot.length - 1; i >= 0; i--) {
215
- if (snapshot[i].ts === lastThreadTs) {
216
- lastThreadIdx = i;
217
- break;
218
- }
219
- }
220
- const recentTopLevel = recentChannelMessages > 0
221
- ? snapshot
222
- .slice(lastThreadIdx + 1)
223
- .filter((r) => !r.threadTs && isConversationMessage(r))
224
- .slice(-recentChannelMessages)
225
- : [];
226
- return [...topLevelBefore, ...threadMessages, ...recentTopLevel].map(toMessage);
227
- }
228
- // ── Resolve session identity from turn metadata ───────────────
229
- function identityFromCtx(ctx) {
230
- return resolver.resolve(ctx.turn.request.metadata ?? {});
231
- }
232
- return {
233
- name: 'disk-session',
234
- priority: -100,
235
- install(agent) {
236
- // ── beforeTurn: take snapshot, build context, prepend ─────
237
- // The snapshot is a copy of the session records at this moment.
238
- // Concurrent turns each get their own snapshot — they don't
239
- // see each other's in-progress work.
240
- agent.hook('beforeTurn', 'disk-session', async (ctx) => {
241
- const identity = identityFromCtx(ctx);
242
- if (!identity)
243
- return;
244
- const { key, messageTs, threadTs, isDirect } = identity;
245
- const isDm = isDirect ?? false;
246
- // Snapshot: copy the current records (read-only).
247
- const liveRecords = store.get(key) ?? [];
248
- const snapshot = [...liveRecords];
249
- // Build the forked context from the snapshot.
250
- const history = buildContext(snapshot, threadTs, isDm);
251
- // ── Persist the user message immediately ────────────────
252
- // Write the incoming user message to disk NOW, before the
253
- // agent runs. If the process crashes mid-turn, the user's
254
- // message is already saved. The assistant response is
255
- // appended later in afterTurn.
256
- //
257
- // The system prompt is captured at afterTurn (not here) because
258
- // beforeContext hooks (which run after beforeTurn) may modify
259
- // ctx.turn.systemPrompt. Recording it here would miss those
260
- // modifications. See afterTurn for the capture.
261
- //
262
- // Enrichment bag: any extension that ran before us in
263
- // beforeTurn may have written into `sessionMeta`. We persist
264
- // it opaquely — disk-session does not inspect the contents.
265
- const sessionMeta = ctx.turn.metadata.sessionMeta;
266
- const userRecord = {
267
- ...toRecord({ role: 'user', content: ctx.turn.request.message }, messageTs, threadTs),
268
- ...(sessionMeta ? { meta: sessionMeta } : {}),
269
- };
270
- const records = store.get(key) ?? [];
271
- records.push(userRecord);
272
- if (records.length > maxRecords) {
273
- records.splice(0, records.length - maxRecords);
274
- }
275
- store.set(key, records);
276
- appendToFile(key, [userRecord]);
277
- // Track how many history messages we prepended so afterTurn
278
- // knows where new messages start. +1 for the user message
279
- // we just added to the log (it's in the snapshot but not in
280
- // the history we built — the history was built from the
281
- // snapshot BEFORE adding the user record).
282
- ctx.turn.metadata['_diskSessionHistoryLen'] = history.length;
283
- if (history.length > 0) {
284
- ctx.turn.messages = [...history, ...ctx.turn.messages];
285
- }
286
- });
287
- // ── afterLLM: accumulate token usage + append assistant msg ──
288
- // Each LLM call returns usage (prompt/completion tokens). We
289
- // accumulate them across all iterations in the turn so the final
290
- // assistant record has the total cost.
291
- //
292
- // We also append the assistant message (including tool calls) to
293
- // the session log immediately, so the JSONL file is updated
294
- // iteration by iteration rather than only at afterTurn. Tool
295
- // results are appended in the afterTool hook below.
296
- agent.hook('afterLLM', 'disk-session', async (ctx) => {
297
- const identity = identityFromCtx(ctx);
298
- if (!identity)
299
- return;
300
- const { key, messageTs, threadTs } = identity;
301
- const usage = ctx.modelResponse?.usage;
302
- if (usage) {
303
- const prev = ctx.turn.metadata['_diskSessionUsage'] ?? { promptTokens: 0, completionTokens: 0, iterations: 0 };
304
- ctx.turn.metadata['_diskSessionUsage'] = {
305
- promptTokens: prev.promptTokens + usage.promptTokens,
306
- completionTokens: prev.completionTokens + usage.completionTokens,
307
- iterations: prev.iterations + 1,
308
- ...(usage.cachedPromptTokens && {
309
- cachedPromptTokens: (prev.cachedPromptTokens ?? 0) + usage.cachedPromptTokens,
310
- }),
311
- ...(usage.reasoningTokens && {
312
- reasoningTokens: (prev.reasoningTokens ?? 0) + usage.reasoningTokens,
313
- }),
314
- };
315
- }
316
- // ── Incremental append: write the assistant message now ──
317
- // The agent core pushes the assistant message to turn.messages
318
- // AFTER afterLLM fires, so we can't read it from there yet.
319
- // Instead, we build the record from modelResponse.message.
320
- const modelResponse = ctx.modelResponse;
321
- if (modelResponse?.message) {
322
- const sessionMeta = ctx.turn.metadata.sessionMeta;
323
- const record = {
324
- ...toRecord(modelResponse.message, messageTs, threadTs),
325
- ...(sessionMeta ? { meta: sessionMeta } : {}),
326
- };
327
- const records = store.get(key) ?? [];
328
- records.push(record);
329
- if (records.length > maxRecords) {
330
- records.splice(0, records.length - maxRecords);
331
- }
332
- store.set(key, records);
333
- appendToFile(key, [record]);
334
- // Track how many records we've already written so afterTurn
335
- // doesn't duplicate them.
336
- const written = ctx.turn.metadata['_diskSessionWritten'] ?? 0;
337
- ctx.turn.metadata['_diskSessionWritten'] = written + 1;
338
- }
339
- });
340
- // ── afterTool: append tool results incrementally ──────────────
341
- // Each tool result is written to disk as soon as it completes,
342
- // so the JSONL file reflects progress in real time.
343
- agent.hook('afterTool', 'disk-session', async (ctx) => {
344
- const identity = identityFromCtx(ctx);
345
- if (!identity)
346
- return;
347
- const { key, messageTs, threadTs } = identity;
348
- const toolResult = ctx.toolResult;
349
- const toolCall = ctx.toolCall;
350
- if (!toolResult || !toolCall)
351
- return;
352
- const sessionMeta = ctx.turn.metadata.sessionMeta;
353
- const record = {
354
- role: 'tool',
355
- content: toolResult.content,
356
- toolCallId: toolResult.toolCallId,
357
- name: toolCall.name,
358
- ts: messageTs,
359
- ...(threadTs ? { threadTs } : {}),
360
- recordedAt: new Date().toISOString(),
361
- ...(sessionMeta ? { meta: sessionMeta } : {}),
362
- };
363
- const records = store.get(key) ?? [];
364
- records.push(record);
365
- if (records.length > maxRecords) {
366
- records.splice(0, records.length - maxRecords);
367
- }
368
- store.set(key, records);
369
- appendToFile(key, [record]);
370
- const written = ctx.turn.metadata['_diskSessionWritten'] ?? 0;
371
- ctx.turn.metadata['_diskSessionWritten'] = written + 1;
372
- });
373
- // ── afterTurn: append assistant response + tool calls ─────
374
- // The user message was already persisted in beforeTurn.
375
- // Here we only append the NEW non-user, non-system messages
376
- // (assistant responses, tool calls, tool results).
377
- agent.hook('afterTurn', 'disk-session', async (ctx) => {
378
- const identity = identityFromCtx(ctx);
379
- if (!identity)
380
- return;
381
- const { key, messageTs, threadTs } = identity;
382
- const historyLen = ctx.turn.metadata['_diskSessionHistoryLen'] ?? 0;
383
- delete ctx.turn.metadata['_diskSessionHistoryLen'];
384
- // ── Compaction: rotate the session file ──────────────────
385
- // When metadata.compacting is set, this turn was a compaction
386
- // request (triggered by /compact). The agent's response is the
387
- // summary. Instead of appending to the old session, we:
388
- // 1. Rename the old JSONL file with a timestamp suffix
389
- // 2. Seed a new session with the summary as the first record
390
- // The compaction request/response are already in the old file
391
- // (written by beforeTurn + the normal append below would have
392
- // run, but we return early before that).
393
- const isCompacting = ctx.turn.request.metadata?.compacting === true;
394
- if (isCompacting) {
395
- const summary = ctx.turn.response?.message ?? '';
396
- // Archive the old file with a timestamp suffix.
397
- const oldPath = filePath(key);
398
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
399
- const archivedName = `${key.replace(/[^a-zA-Z0-9_-]/g, '_')}_${timestamp}.jsonl`;
400
- const archivedPath = join(dir, archivedName);
401
- if (existsSync(oldPath)) {
402
- renameSync(oldPath, archivedPath);
403
- }
404
- // Seed the new session with the summary.
405
- const summaryRecord = {
406
- role: 'assistant',
407
- content: `[Session summary — prior conversation compacted ${new Date().toISOString()}]\n\n${summary}`,
408
- ts: messageTs || String(Date.now() / 1000),
409
- recordedAt: new Date().toISOString(),
410
- };
411
- store.set(key, [summaryRecord]);
412
- appendToFile(key, [summaryRecord]);
413
- // Store the archived filename so the host can report it.
414
- ctx.turn.metadata['_compactArchivedFile'] = archivedName;
415
- return;
416
- }
417
- // Messages: [history...] [system?] [user msg] [assistant] [tool calls...]
418
- // The beforeContext hook may have inserted a system message.
419
- // Skip it when counting new messages.
420
- const systemMsgCount = ctx.turn.messages[historyLen]?.role === 'system' ? 1 : 0;
421
- const newStart = historyLen + systemMsgCount;
422
- const newMessages = ctx.turn.messages.slice(newStart);
423
- // Persist non-user, non-system messages here. The initial user
424
- // message was already written in beforeTurn. EXCEPTION: steering
425
- // messages are injected mid-turn as user messages with a
426
- // [steering] prefix — those are new and must be persisted.
427
- let filteredMessages = newMessages.filter((m) => {
428
- if (m.role === 'system')
429
- return false;
430
- if (m.role === 'user') {
431
- const text = typeof m.content === 'string'
432
- ? m.content
433
- : Array.isArray(m.content)
434
- ? m.content.filter((p) => p.type === 'text').map((p) => p.text).join('')
435
- : '';
436
- return text.startsWith('[steering]');
437
- }
438
- return true;
439
- });
440
- // ── Skip records already written incrementally ───────────
441
- // afterLLM and afterTool hooks append assistant messages and
442
- // tool results as they happen. Skip those here to avoid
443
- // duplicates. Only the final assistant response (with no tool
444
- // calls) may not have been written yet — it's the one that
445
- // ends the turn without triggering afterTool.
446
- const alreadyWritten = ctx.turn.metadata['_diskSessionWritten'] ?? 0;
447
- delete ctx.turn.metadata['_diskSessionWritten'];
448
- if (alreadyWritten > 0) {
449
- filteredMessages = filteredMessages.slice(alreadyWritten);
450
- }
451
- if (filteredMessages.length === 0) {
452
- // All records were already written incrementally by afterLLM
453
- // and afterTool. Still need to backfill the system prompt on
454
- // the user record and clean up usage metadata.
455
- delete ctx.turn.metadata['_diskSessionUsage'];
456
- // ── Backfill system prompt on the last user record ───────
457
- const finalSystemPrompt = ctx.turn.systemPrompt;
458
- if (finalSystemPrompt) {
459
- const records = store.get(key) ?? [];
460
- for (let i = records.length - 1; i >= 0; i--) {
461
- if (records[i].role === 'user') {
462
- records[i].systemPrompt = finalSystemPrompt;
463
- break;
464
- }
465
- }
466
- appendToFile(key, [{
467
- role: 'control',
468
- content: '',
469
- recordedAt: new Date().toISOString(),
470
- systemPrompt: finalSystemPrompt,
471
- }]);
472
- }
473
- return;
474
- }
475
- // Pull accumulated usage for this turn (set by afterLLM hook).
476
- const usage = ctx.turn.metadata['_diskSessionUsage'];
477
- delete ctx.turn.metadata['_diskSessionUsage'];
478
- // Enrichment bag (same convention as beforeTurn): any
479
- // extension may have written into `sessionMeta` during the
480
- // turn. Persist it opaquely on each new record.
481
- const sessionMeta = ctx.turn.metadata.sessionMeta;
482
- // Convert to records with correlation metadata.
483
- const newRecords = filteredMessages.map((msg) => {
484
- const record = {
485
- ...toRecord(msg, messageTs, threadTs),
486
- ...(sessionMeta ? { meta: sessionMeta } : {}),
487
- };
488
- // Attach usage to the LAST assistant record (the final response).
489
- // Intermediate assistant records (tool-call requests) don't get usage.
490
- return record;
491
- });
492
- // Attach accumulated usage to the last assistant record.
493
- if (usage) {
494
- let lastAssistantIdx = -1;
495
- for (let i = newRecords.length - 1; i >= 0; i--) {
496
- if (newRecords[i].role === 'assistant') {
497
- lastAssistantIdx = i;
498
- break;
499
- }
500
- }
501
- if (lastAssistantIdx !== -1) {
502
- newRecords[lastAssistantIdx].usage = usage;
503
- }
504
- }
505
- // Append to in-memory log.
506
- const records = store.get(key) ?? [];
507
- records.push(...newRecords);
508
- // ── Backfill system prompt on the last user record ───────
509
- // The system prompt wasn't available at beforeTurn (beforeContext
510
- // hooks hadn't run yet). Now it's final, so update the last user
511
- // record in the in-memory store and append a correction record
512
- // to the JSONL so the audit trail has the complete prompt.
513
- const finalSystemPrompt = ctx.turn.systemPrompt;
514
- if (finalSystemPrompt) {
515
- for (let i = records.length - 1; i >= 0; i--) {
516
- if (records[i].role === 'user') {
517
- records[i].systemPrompt = finalSystemPrompt;
518
- break;
519
- }
520
- }
521
- // Append a lightweight audit record so the JSONL file also
522
- // has the final system prompt (the user record in the file
523
- // was written without it at beforeTurn).
524
- appendToFile(key, [{
525
- role: 'control',
526
- content: '',
527
- recordedAt: new Date().toISOString(),
528
- systemPrompt: finalSystemPrompt,
529
- }]);
530
- }
531
- // Trim in-memory cache (file keeps full history).
532
- if (records.length > maxRecords) {
533
- records.splice(0, records.length - maxRecords);
534
- }
535
- store.set(key, records);
536
- // Append to JSONL file (append-only, never rewritten).
537
- appendToFile(key, newRecords);
538
- });
539
- },
540
- /** Get all records for a session. */
541
- getRecords(sessionKey = 'default') {
542
- return store.get(sessionKey) ?? [];
543
- },
544
- /**
545
- * Append a control record (e.g. /halt) to the session log.
546
- * Control records are persisted to disk but never included in the
547
- * LLM context — they're for audit/logging only.
548
- */
549
- appendControl(sessionKey, content, ts, threadTs) {
550
- const record = {
551
- role: 'control',
552
- content,
553
- ts: ts ?? String(Date.now() / 1000),
554
- ...(threadTs ? { threadTs } : {}),
555
- recordedAt: new Date().toISOString(),
556
- };
557
- const records = store.get(sessionKey);
558
- if (records) {
559
- records.push(record);
560
- if (records.length > maxRecords) {
561
- store.set(sessionKey, records.slice(-maxRecords));
562
- }
563
- }
564
- else {
565
- store.set(sessionKey, [record]);
566
- }
567
- appendToFile(sessionKey, [record]);
568
- },
569
- /**
570
- * Append a background message to the session log. Stored as a
571
- * `system` record so the agent sees it as context ("here's what
572
- * the channel discussed") rather than a message to respond to.
573
- *
574
- * Unlike `appendControl`, system records ARE included in the LLM
575
- * context window — they appear in the conversation history when
576
- * the agent is triggered, giving it awareness of recent channel
577
- * activity without needing to be mentioned on every message.
578
- *
579
- * The host should include sender info in the content (e.g.
580
- * `[U123]: hey anyone seen the invoice?`) so the agent can
581
- * distinguish who said what. Additional metadata (files, blocks,
582
- * etc.) goes in `opts.meta` and is persisted to the JSONL for
583
- * audit/debugging but not shown to the LLM.
584
- */
585
- appendMessage(sessionKey, content, opts) {
586
- const record = {
587
- role: 'system',
588
- content,
589
- ts: opts?.ts ?? String(Date.now() / 1000),
590
- ...(opts?.threadTs ? { threadTs: opts.threadTs } : {}),
591
- recordedAt: new Date().toISOString(),
592
- ...(opts?.meta ? { meta: opts.meta } : {}),
593
- };
594
- const records = store.get(sessionKey);
595
- if (records) {
596
- records.push(record);
597
- if (records.length > maxRecords) {
598
- store.set(sessionKey, records.slice(-maxRecords));
599
- }
600
- }
601
- else {
602
- store.set(sessionKey, [record]);
603
- }
604
- appendToFile(sessionKey, [record]);
605
- },
606
- /** List all session keys. */
607
- getSessions() {
608
- return Array.from(store.keys());
609
- },
610
- /** Clear a single session (memory + disk). */
611
- clear(sessionKey = 'default') {
612
- store.delete(sessionKey);
613
- const path = filePath(sessionKey);
614
- if (existsSync(path)) {
615
- try {
616
- writeFileSync(path, '');
617
- }
618
- catch {
619
- // ignore
620
- }
621
- }
622
- },
623
- /** Clear all sessions. */
624
- clearAll() {
625
- for (const key of store.keys()) {
626
- const path = filePath(key);
627
- if (existsSync(path)) {
628
- try {
629
- writeFileSync(path, '');
630
- }
631
- catch {
632
- // ignore
633
- }
634
- }
635
- }
636
- store.clear();
637
- },
638
- };
639
- }
640
- //# sourceMappingURL=extension.js.map