@xopcai/xopc 0.0.117 → 0.0.118

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 (277) hide show
  1. package/README.md +24 -23
  2. package/README.zh-CN.md +45 -42
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BBLhJ2C6.js → agent-avatar-dicebear-dzUrQoeZ.js} +1 -1
  6. package/dist/gateway/static/root/assets/agents-BCxZbkOw.js +2 -0
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-CBpLONvG.js → app-management-settings-panel-bxYJVJpx.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CGcc54yj.js → appearance-settings-BCIykXlI.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-DdDx0V4z.js → apps-page--wMEL00f.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-DZsVqMhU.js → archive-plugin-Cki4SfU2.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CIol6JWX.js → attachment-load-D-KnS2Do.js} +1 -1
  12. package/dist/gateway/static/root/assets/{binary-plugins-B3UauMfp.js → binary-plugins-D2sgvJja.js} +1 -1
  13. package/dist/gateway/static/root/assets/{block-editor-2HJoFchH.js → block-editor-DIq-4Gvb.js} +27 -27
  14. package/dist/gateway/static/root/assets/browser-settings-page-DRhKdn81.js +8 -0
  15. package/dist/gateway/static/root/assets/{capability-presets-api-XQoMTI0A.js → capability-presets-api-CorhiHlg.js} +1 -1
  16. package/dist/gateway/static/root/assets/capability-presets-settings-panel-qFx9Jtce.js +1 -0
  17. package/dist/gateway/static/root/assets/channels-settings-BAwAkqIA.js +1 -0
  18. package/dist/gateway/static/root/assets/connectors-page-BQLcfitM.js +2 -0
  19. package/dist/gateway/static/root/assets/{cron-api-R41aQCX9.js → cron-api-qGwmL-24.js} +1 -1
  20. package/dist/gateway/static/root/assets/cron-page-BBWMAj8-.js +3 -0
  21. package/dist/gateway/static/root/assets/{dreaming-settings-Bceaw1PG.js → dreaming-settings-Dw89Obml.js} +1 -1
  22. package/dist/gateway/static/root/assets/{extension-debug-page-DX5WRE_t.js → extension-debug-page-DYu1KaFQ.js} +1 -1
  23. package/dist/gateway/static/root/assets/{extension-page-Buah7Bw-.js → extension-page-B3W6QwlZ.js} +1 -1
  24. package/dist/gateway/static/root/assets/{extension-settings-page-DuroLVnf.js → extension-settings-page-D7VQ-cxE.js} +1 -1
  25. package/dist/gateway/static/root/assets/{fetch-B5zdl27C.js → fetch-B7xDPu-R.js} +1 -1
  26. package/dist/gateway/static/root/assets/{format-interval-label-Dn_QKIqb.js → format-interval-label-BzxafKxR.js} +1 -1
  27. package/dist/gateway/static/root/assets/{gateway-config-api-gT4ZhE7h.js → gateway-config-api-BTBLSeUu.js} +1 -1
  28. package/dist/gateway/static/root/assets/{gateway-settings-iISWAZRm.js → gateway-settings-Cmwy58rS.js} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-startup-retry-B3kL8KGY.js → gateway-startup-retry-CYj9FWCp.js} +1 -1
  30. package/dist/gateway/static/root/assets/goal-detail-page-l7mu5GWX.js +1 -0
  31. package/dist/gateway/static/root/assets/{goals-config-api-AR-fVh0P.js → goals-config-api-CQQgzPr3.js} +1 -1
  32. package/dist/gateway/static/root/assets/{goals-page-Cpb21ezg.js → goals-page-BHitvJAv.js} +2 -2
  33. package/dist/gateway/static/root/assets/{goals-settings-CPAuFwoD.js → goals-settings-CYVY4NGp.js} +1 -1
  34. package/dist/gateway/static/root/assets/{heartbeat-config-api-D7bKFEeO.js → heartbeat-config-api-DriO_CN9.js} +1 -1
  35. package/dist/gateway/static/root/assets/heartbeat-settings-CUQTKxg7.js +1 -0
  36. package/dist/gateway/static/root/assets/index-C17Tsd_b.css +1 -0
  37. package/dist/gateway/static/root/assets/{index-CwhK8qCh.js → index-Cc41r16l.js} +120 -51
  38. package/dist/gateway/static/root/assets/{interval-presets-0DtsnxE0.js → interval-presets-DFPCKW_W.js} +1 -1
  39. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BPREtN8B.js → keyboard-shortcuts-settings-CcVcqstx.js} +1 -1
  40. package/dist/gateway/static/root/assets/{logs-page-DefCgF4o.js → logs-page-C2Uqvae9.js} +2 -2
  41. package/dist/gateway/static/root/assets/{markdown-split-ChbR9LGO.js → markdown-split-BwOFrJ2E.js} +1 -1
  42. package/dist/gateway/static/root/assets/{media-plugins-B82oP80n.js → media-plugins-Cnz6Q5G6.js} +1 -1
  43. package/dist/gateway/static/root/assets/messages-B1iSKjiw.js +3 -0
  44. package/dist/gateway/static/root/assets/models-hub-panel-BfLfcta8.js +2 -0
  45. package/dist/gateway/static/root/assets/note-detail-page-BjwOQBfT.js +2 -0
  46. package/dist/gateway/static/root/assets/{note-image-lightbox-CDknITM3.js → note-image-lightbox-B-Svpmza.js} +1 -1
  47. package/dist/gateway/static/root/assets/notes-page-DktdBiwB.js +1 -0
  48. package/dist/gateway/static/root/assets/{preview-open-alternatives-DV3xQsWB.js → preview-open-alternatives-Bss4TiwP.js} +1 -1
  49. package/dist/gateway/static/root/assets/remote-access-hub-rfVx96fq.js +1 -0
  50. package/dist/gateway/static/root/assets/{save-bar-controls-BODCXnvY.js → save-bar-controls-BRNjdgKq.js} +1 -1
  51. package/dist/gateway/static/root/assets/{schedule-field-CgJSCD3B.js → schedule-field-CUCKODde.js} +1 -1
  52. package/dist/gateway/static/root/assets/{schema-form-qtfEI6QM.js → schema-form-Dub9sy8r.js} +1 -1
  53. package/dist/gateway/static/root/assets/sessions-page-DbtMFuuH.js +1 -0
  54. package/dist/gateway/static/root/assets/settings-advanced-gate-5re5gAnP.js +1 -0
  55. package/dist/gateway/static/root/assets/{settings-collapsible-section-BHZKjVcS.js → settings-collapsible-section-BeFLavGi.js} +1 -1
  56. package/dist/gateway/static/root/assets/{settings-form-section-5i35D-J1.js → settings-form-section-dmyaPOTG.js} +1 -1
  57. package/dist/gateway/static/root/assets/settings-page-D-WMyLlj.js +1 -0
  58. package/dist/gateway/static/root/assets/setup-status-panel-Cl-DEJAU.js +1 -0
  59. package/dist/gateway/static/root/assets/{share-preview-page-B0H63tDv.js → share-preview-page-C8glrdqe.js} +1 -1
  60. package/dist/gateway/static/root/assets/shares-settings-CyPVvbLt.js +1 -0
  61. package/dist/gateway/static/root/assets/skill-reload-api-CleTH1oz.js +1 -0
  62. package/dist/gateway/static/root/assets/skills-page-Ck8hdXqR.js +2 -0
  63. package/dist/gateway/static/root/assets/{system-settings-panel-DXs2VmBt.js → system-settings-panel-DI-LN_8G.js} +1 -1
  64. package/dist/gateway/static/root/assets/{typed-models-lib-4gPuydz_.js → typed-models-lib-kX9duch4.js} +1 -1
  65. package/dist/gateway/static/root/assets/{use-channel-catalog-BCjP_VHb.js → use-channel-catalog-DqlWTsDb.js} +1 -1
  66. package/dist/gateway/static/root/assets/user-profile-settings-panel-B-UFPMXy.js +1 -0
  67. package/dist/gateway/static/root/assets/utils-Dm0hKalR.js +1 -0
  68. package/dist/gateway/static/root/assets/voice-api-key-field-C73IVZeC.js +1 -0
  69. package/dist/gateway/static/root/assets/{voice-player-store-BlF9V05n.js → voice-player-store-C_ArLJPM.js} +1 -1
  70. package/dist/gateway/static/root/assets/workflows-page-BtFGp2y_.js +18 -0
  71. package/dist/gateway/static/root/index.html +5 -5
  72. package/dist/package.js +1 -1
  73. package/dist/src/agent/agent-manager.js +2 -1
  74. package/dist/src/agent/agent-manager.js.map +1 -1
  75. package/dist/src/agent/agent-scope.js +0 -2
  76. package/dist/src/agent/agent-scope.js.map +1 -1
  77. package/dist/src/agent/background-review/prompts.d.ts +2 -2
  78. package/dist/src/agent/background-review/prompts.js +2 -2
  79. package/dist/src/agent/background-review/prompts.js.map +1 -1
  80. package/dist/src/agent/background-review/settings.d.ts +1 -1
  81. package/dist/src/agent/background-review/settings.js +7 -8
  82. package/dist/src/agent/background-review/settings.js.map +1 -1
  83. package/dist/src/agent/bootstrap/bootstrap-cache.d.ts +1 -0
  84. package/dist/src/agent/bootstrap/bootstrap-cache.js +4 -3
  85. package/dist/src/agent/bootstrap/bootstrap-cache.js.map +1 -1
  86. package/dist/src/agent/bootstrap/bootstrap-files.d.ts +4 -0
  87. package/dist/src/agent/bootstrap/bootstrap-files.js +4 -3
  88. package/dist/src/agent/bootstrap/bootstrap-files.js.map +1 -1
  89. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +4 -2
  90. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  91. package/dist/src/agent/bootstrap/load-bootstrap-files.d.ts +2 -1
  92. package/dist/src/agent/bootstrap/load-bootstrap-files.js +17 -16
  93. package/dist/src/agent/bootstrap/load-bootstrap-files.js.map +1 -1
  94. package/dist/src/agent/bootstrap/types.d.ts +1 -1
  95. package/dist/src/agent/context/workspace-templates/AGENTS.md +1 -1
  96. package/dist/src/agent/context/workspace.d.ts +4 -2
  97. package/dist/src/agent/context/workspace.js +5 -4
  98. package/dist/src/agent/context/workspace.js.map +1 -1
  99. package/dist/src/agent/embedded/run-for-session.js +4 -1
  100. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  101. package/dist/src/agent/fallback/candidates.js +10 -11
  102. package/dist/src/agent/fallback/candidates.js.map +1 -1
  103. package/dist/src/agent/memory/builtin-memory-store.d.ts +4 -2
  104. package/dist/src/agent/memory/builtin-memory-store.js +11 -6
  105. package/dist/src/agent/memory/builtin-memory-store.js.map +1 -1
  106. package/dist/src/agent/memory/builtin-provider.js +36 -7
  107. package/dist/src/agent/memory/builtin-provider.js.map +1 -1
  108. package/dist/src/agent/memory/candidate-extractor.d.ts +6 -0
  109. package/dist/src/agent/memory/candidate-extractor.js +60 -0
  110. package/dist/src/agent/memory/candidate-extractor.js.map +1 -0
  111. package/dist/src/agent/memory/manager.d.ts +2 -1
  112. package/dist/src/agent/memory/manager.js +27 -3
  113. package/dist/src/agent/memory/manager.js.map +1 -1
  114. package/dist/src/agent/memory/memory-config.js +3 -0
  115. package/dist/src/agent/memory/memory-config.js.map +1 -1
  116. package/dist/src/agent/memory/prefetch-coordinator.js.map +1 -1
  117. package/dist/src/agent/memory/types.d.ts +27 -4
  118. package/dist/src/agent/prompt/memory/index.d.ts +4 -2
  119. package/dist/src/agent/prompt/memory/index.js +18 -12
  120. package/dist/src/agent/prompt/memory/index.js.map +1 -1
  121. package/dist/src/agent/prompt/sections/memory-skills.js +1 -1
  122. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -1
  123. package/dist/src/agent/prompt/service-prompt-builder.js +4 -19
  124. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  125. package/dist/src/agent/reply/post-compaction-context.js +1 -3
  126. package/dist/src/agent/reply/post-compaction-context.js.map +1 -1
  127. package/dist/src/agent/reply/startup-context.js +1 -5
  128. package/dist/src/agent/reply/startup-context.js.map +1 -1
  129. package/dist/src/agent/service.d.ts +3 -3
  130. package/dist/src/agent/service.js +7 -8
  131. package/dist/src/agent/service.js.map +1 -1
  132. package/dist/src/agent/tools/curated-memory-tool.js +57 -2
  133. package/dist/src/agent/tools/curated-memory-tool.js.map +1 -1
  134. package/dist/src/agent/tools/web-extract.js +6 -8
  135. package/dist/src/agent/tools/web-extract.js.map +1 -1
  136. package/dist/src/agent-manifest/index.js +2 -2
  137. package/dist/src/agent-manifest/resolver.d.ts +3 -2
  138. package/dist/src/agent-manifest/resolver.js +5 -3
  139. package/dist/src/agent-manifest/resolver.js.map +1 -1
  140. package/dist/src/agent-manifest/schema.d.ts +232 -0
  141. package/dist/src/agent-manifest/schema.js +4 -2
  142. package/dist/src/agent-manifest/schema.js.map +1 -1
  143. package/dist/src/agent-manifest/validator.d.ts +3 -2
  144. package/dist/src/agent-manifest/validator.js +2 -1
  145. package/dist/src/agent-manifest/validator.js.map +1 -1
  146. package/dist/src/channels/pipeline.d.ts +1 -1
  147. package/dist/src/channels/pipeline.js.map +1 -1
  148. package/dist/src/chat-commands/agent-edit.js +0 -1
  149. package/dist/src/chat-commands/agent-edit.js.map +1 -1
  150. package/dist/src/chat-commands/builtins/model.js +2 -2
  151. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  152. package/dist/src/cli/command-manifest.d.ts +1 -1
  153. package/dist/src/cli/command-manifest.js +1 -1
  154. package/dist/src/cli/command-manifest.js.map +1 -1
  155. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  156. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -0
  157. package/dist/src/cli/commands/doctor/checks/provider-auth.js.map +1 -1
  158. package/dist/src/cli/commands/doctor/checks/workspace-status.js +0 -1
  159. package/dist/src/cli/commands/doctor/checks/workspace-status.js.map +1 -1
  160. package/dist/src/cli/commands/init.js +7 -6
  161. package/dist/src/cli/commands/init.js.map +1 -1
  162. package/dist/src/cli/commands/models.js +13 -31
  163. package/dist/src/cli/commands/models.js.map +1 -1
  164. package/dist/src/cli/commands/onboard/model.js +17 -10
  165. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  166. package/dist/src/cli/commands/onboard.js +2 -2
  167. package/dist/src/cli/commands/onboard.js.map +1 -1
  168. package/dist/src/cli/commands/tui.js +2 -2
  169. package/dist/src/cli/commands/tui.js.map +1 -1
  170. package/dist/src/cli/index.d.ts +1 -0
  171. package/dist/src/cli/index.js +10 -5
  172. package/dist/src/cli/index.js.map +1 -1
  173. package/dist/src/cli/registry.js +1 -1
  174. package/dist/src/cli/registry.js.map +1 -1
  175. package/dist/src/cli/templates.d.ts +1 -1
  176. package/dist/src/cli/templates.js +1 -11
  177. package/dist/src/cli/templates.js.map +1 -1
  178. package/dist/src/commands/agents.config.js +2 -10
  179. package/dist/src/commands/agents.config.js.map +1 -1
  180. package/dist/src/config/agent-profile.js +3 -2
  181. package/dist/src/config/agent-profile.js.map +1 -1
  182. package/dist/src/config/agent-typed-models.js +3 -5
  183. package/dist/src/config/agent-typed-models.js.map +1 -1
  184. package/dist/src/config/index.js +2 -2
  185. package/dist/src/config/paths.d.ts +8 -1
  186. package/dist/src/config/paths.js +16 -3
  187. package/dist/src/config/paths.js.map +1 -1
  188. package/dist/src/config/schema.d.ts +32 -32
  189. package/dist/src/config/schema.js +46 -26
  190. package/dist/src/config/schema.js.map +1 -1
  191. package/dist/src/gateway/agents-admin.d.ts +7 -0
  192. package/dist/src/gateway/agents-admin.js +51 -20
  193. package/dist/src/gateway/agents-admin.js.map +1 -1
  194. package/dist/src/gateway/chat-stream/mapper.js +9 -2
  195. package/dist/src/gateway/chat-stream/mapper.js.map +1 -1
  196. package/dist/src/gateway/global-defaults-admin.d.ts +36 -0
  197. package/dist/src/gateway/global-defaults-admin.js +146 -0
  198. package/dist/src/gateway/global-defaults-admin.js.map +1 -0
  199. package/dist/src/gateway/hono/routes/agents.js +33 -1
  200. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  201. package/dist/src/gateway/hono/routes/commands-skills.js +4 -5
  202. package/dist/src/gateway/hono/routes/commands-skills.js.map +1 -1
  203. package/dist/src/gateway/hono/routes/global-defaults.d.ts +3 -0
  204. package/dist/src/gateway/hono/routes/global-defaults.js +61 -0
  205. package/dist/src/gateway/hono/routes/global-defaults.js.map +1 -0
  206. package/dist/src/gateway/hono/routes/lazy-bundles.js +11 -3
  207. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  208. package/dist/src/gateway/hono/routes/memory.js +75 -4
  209. package/dist/src/gateway/hono/routes/memory.js.map +1 -1
  210. package/dist/src/gateway/hono/routes/models.js +1 -1
  211. package/dist/src/gateway/service/marketplace-service.d.ts +4 -4
  212. package/dist/src/gateway/service/marketplace-service.js +11 -7
  213. package/dist/src/gateway/service/marketplace-service.js.map +1 -1
  214. package/dist/src/notes/service.js +3 -1
  215. package/dist/src/notes/service.js.map +1 -1
  216. package/dist/src/providers/index.d.ts +4 -5
  217. package/dist/src/providers/index.js +16 -16
  218. package/dist/src/providers/index.js.map +1 -1
  219. package/dist/src/session/session-workspace.js +2 -7
  220. package/dist/src/session/session-workspace.js.map +1 -1
  221. package/dist/src/session/store.js +0 -5
  222. package/dist/src/session/store.js.map +1 -1
  223. package/dist/src/storage/sqlite/index.d.ts +1 -1
  224. package/dist/src/storage/sqlite/index.js +2 -2
  225. package/dist/src/storage/sqlite/memory-index-repository.d.ts +1 -0
  226. package/dist/src/storage/sqlite/memory-index-repository.js +15 -14
  227. package/dist/src/storage/sqlite/memory-index-repository.js.map +1 -1
  228. package/dist/src/storage/sqlite/memory-records-repository.d.ts +44 -1
  229. package/dist/src/storage/sqlite/memory-records-repository.js +164 -20
  230. package/dist/src/storage/sqlite/memory-records-repository.js.map +1 -1
  231. package/dist/src/storage/sqlite/migrations/014_memory_record_governance.sql +10 -0
  232. package/dist/src/storage/sqlite/migrations/015_memory_trace_feedback.sql +4 -0
  233. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  234. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  235. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  236. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  237. package/dist/src/storage/sqlite/schema.js +1 -1
  238. package/dist/src/tui/backends/embedded-backend.d.ts +3 -0
  239. package/dist/src/tui/backends/embedded-backend.js +37 -20
  240. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  241. package/dist/src/tui/backends/gateway-sse-backend.d.ts +1 -0
  242. package/dist/src/tui/backends/gateway-sse-backend.js +16 -3
  243. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  244. package/dist/src/tui/components/tui-header.d.ts +0 -1
  245. package/dist/src/tui/components/tui-header.js +3 -8
  246. package/dist/src/tui/components/tui-header.js.map +1 -1
  247. package/dist/src/tui/tui-startup-resources.js +2 -1
  248. package/dist/src/tui/tui-startup-resources.js.map +1 -1
  249. package/dist/src/tui/tui-startup-text.js +12 -12
  250. package/dist/src/tui/tui-startup-text.js.map +1 -1
  251. package/dist/src/tui/tui.js +4 -1
  252. package/dist/src/tui/tui.js.map +1 -1
  253. package/package.json +1 -1
  254. package/dist/gateway/static/root/assets/agents-C6xgagZd.js +0 -71
  255. package/dist/gateway/static/root/assets/browser-settings-page-CUOO-PQk.js +0 -8
  256. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CfqF-kGr.js +0 -1
  257. package/dist/gateway/static/root/assets/channels-settings-BYyRzsex.js +0 -1
  258. package/dist/gateway/static/root/assets/connectors-page-DIvEz4NX.js +0 -2
  259. package/dist/gateway/static/root/assets/cron-page-D97nFqQD.js +0 -3
  260. package/dist/gateway/static/root/assets/goal-detail-page-DCUROLMQ.js +0 -1
  261. package/dist/gateway/static/root/assets/heartbeat-settings-CC69vNx0.js +0 -1
  262. package/dist/gateway/static/root/assets/index-CyfhARL-.css +0 -1
  263. package/dist/gateway/static/root/assets/messages-Cf1O9JB0.js +0 -3
  264. package/dist/gateway/static/root/assets/models-hub-panel-DmKiIihT.js +0 -2
  265. package/dist/gateway/static/root/assets/note-detail-page-CxxfLRJZ.js +0 -2
  266. package/dist/gateway/static/root/assets/notes-page-X2slSx7V.js +0 -1
  267. package/dist/gateway/static/root/assets/remote-access-hub-BvmUWqgu.js +0 -1
  268. package/dist/gateway/static/root/assets/sessions-page-B0yESuuL.js +0 -1
  269. package/dist/gateway/static/root/assets/settings-advanced-gate-q2M8RKOo.js +0 -1
  270. package/dist/gateway/static/root/assets/settings-page-CGozabLD.js +0 -1
  271. package/dist/gateway/static/root/assets/setup-status-panel-FoOSe6nU.js +0 -1
  272. package/dist/gateway/static/root/assets/shares-settings-Cy5zWyYQ.js +0 -1
  273. package/dist/gateway/static/root/assets/skill-reload-api-DaZNFro9.js +0 -1
  274. package/dist/gateway/static/root/assets/skills-page-CnwtUzvw.js +0 -2
  275. package/dist/gateway/static/root/assets/voice-api-key-field-DvKiOglO.js +0 -1
  276. package/dist/gateway/static/root/assets/workflows-page-CAVZcONQ.js +0 -18
  277. package/dist/src/agent/context/workspace-templates/USER.md +0 -24
@@ -1 +1 @@
1
- {"version":3,"file":"memory-records-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-records-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n MemoryKind,\n MemoryRecord,\n MemorySearchResult,\n MemorySignal,\n} from '../../agent/memory/types.js';\nimport { escapeFts5Query } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\ntype MemoryRecordRow = {\n record_id: string;\n provider_id: string;\n kind: string;\n agent_id: string;\n workspace_id: string | null;\n session_key: string | null;\n content: string;\n source_json: string;\n confidence: number | null;\n tags_json: string;\n created_at: number;\n updated_at: number;\n};\n\ntype MemoryRecordSearchRow = MemoryRecordRow & {\n rank: number;\n};\n\nexport interface UpsertMemoryRecordInput {\n id?: string;\n providerId: string;\n kind: MemoryKind;\n agentId: string;\n workspaceId?: string;\n sessionKey?: string;\n content: string;\n source?: MemoryRecord['source'];\n confidence?: number;\n tags?: string[];\n nowMs?: number;\n}\n\nexport interface ListMemoryRecordsOptions {\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n kind?: MemoryKind;\n limit?: number;\n offset?: number;\n}\n\nexport interface SearchMemoryRecordsOptions {\n query: string;\n agentId?: string;\n workspaceId?: string;\n providerId?: string;\n kinds?: MemoryKind[];\n maxResults?: number;\n minScore?: number;\n}\n\nexport interface AppendMemorySignalInput {\n signal: MemorySignal;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n nowMs?: number;\n}\n\nexport interface MemorySignalRowPayload {\n signalId: string;\n source: string;\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n score?: number;\n content?: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\ntype MemorySignalRow = {\n signal_id: string;\n source: string;\n record_id: string | null;\n provider_id: string | null;\n agent_id: string | null;\n workspace_id: string | null;\n session_key: string | null;\n score: number | null;\n content: string | null;\n metadata_json: string;\n created_at: number;\n};\n\ntype MemoryTraceRow = {\n trace_id: string;\n session_key: string | null;\n turn_id: string | null;\n phase: string;\n provider_id: string;\n request_json: string;\n result_count: number | null;\n selected_record_ids_json: string;\n skipped_reason: string | null;\n error: string | null;\n duration_ms: number;\n created_at: number;\n};\n\nexport interface AppendMemoryTraceEventInput {\n sessionKey?: string;\n turnId?: string;\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test';\n providerId: string;\n request?: unknown;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n durationMs?: number;\n nowMs?: number;\n}\n\nexport interface MemoryTraceEventPayload {\n traceId: string;\n sessionKey?: string;\n turnId?: string;\n phase: string;\n providerId: string;\n request: unknown;\n resultCount?: number;\n selectedRecordIds: string[];\n skippedReason?: string;\n error?: string;\n durationMs: number;\n createdAt: string;\n}\n\nfunction parseStringArray(json: string): string[] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction parseSource(json: string): MemoryRecord['source'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return parsed && typeof parsed === 'object' ? (parsed as MemoryRecord['source']) : {};\n } catch {\n return {};\n }\n}\n\nfunction rowToRecord(row: MemoryRecordRow): MemoryRecord {\n return {\n id: row.record_id,\n kind: row.kind as MemoryKind,\n scope: {\n agentId: row.agent_id,\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n },\n content: row.content,\n source: parseSource(row.source_json),\n ...(row.confidence != null ? { confidence: row.confidence } : {}),\n createdAt: new Date(row.created_at).toISOString(),\n updatedAt: new Date(row.updated_at).toISOString(),\n tags: parseStringArray(row.tags_json),\n };\n}\n\nfunction bm25ToScore(rank: number): number {\n return Math.max(0, Math.min(1, 1 / (1 + Math.max(0, rank))));\n}\n\nfunction upsertMemoryRecordFts(\n db: ReturnType<typeof getSqliteDatabase>,\n row: Pick<UpsertMemoryRecordInput, 'providerId' | 'kind' | 'agentId' | 'workspaceId' | 'content'> & { id: string },\n): void {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(row.id);\n if (!row.content.trim()) return;\n db.prepare(\n `INSERT INTO memory_records_fts (\n content, record_id, provider_id, kind, agent_id, workspace_id\n ) VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(row.content, row.id, row.providerId, row.kind, row.agentId, row.workspaceId ?? null);\n}\n\nexport function upsertMemoryRecord(input: UpsertMemoryRecordInput): MemoryRecord {\n const id = input.id ?? randomUUID();\n const now = input.nowMs ?? Date.now();\n const source = {\n ...(input.source ?? {}),\n provider: input.source?.provider ?? input.providerId,\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_records (\n record_id, provider_id, kind, agent_id, workspace_id, session_key,\n content, source_json, confidence, tags_json, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(record_id) DO UPDATE SET\n provider_id = excluded.provider_id,\n kind = excluded.kind,\n agent_id = excluded.agent_id,\n workspace_id = excluded.workspace_id,\n session_key = excluded.session_key,\n content = excluded.content,\n source_json = excluded.source_json,\n confidence = excluded.confidence,\n tags_json = excluded.tags_json,\n updated_at = excluded.updated_at`,\n ).run(\n id,\n input.providerId,\n input.kind,\n input.agentId,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.content,\n JSON.stringify(source),\n input.confidence ?? null,\n JSON.stringify(input.tags ?? []),\n now,\n now,\n );\n upsertMemoryRecordFts(db, { ...input, id });\n });\n\n return {\n id,\n kind: input.kind,\n scope: {\n agentId: input.agentId,\n ...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),\n ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),\n },\n content: input.content,\n source,\n ...(input.confidence != null ? { confidence: input.confidence } : {}),\n createdAt: new Date(now).toISOString(),\n updatedAt: new Date(now).toISOString(),\n tags: input.tags ?? [],\n };\n}\n\nexport function getMemoryRecord(recordId: string): MemoryRecord | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_records WHERE record_id = ?`)\n .get(recordId) as MemoryRecordRow | undefined;\n return row ? rowToRecord(row) : null;\n}\n\nexport function listMemoryRecords(options: ListMemoryRecordsOptions = {}): MemoryRecord[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.kind) {\n where.push('kind = ?');\n params.push(options.kind);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const offset = Math.max(0, options.offset ?? 0);\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_records\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as MemoryRecordRow[];\n return rows.map(rowToRecord);\n}\n\nexport function searchMemoryRecords(options: SearchMemoryRecordsOptions): MemorySearchResult[] {\n const query = escapeFts5Query(options.query);\n if (!query) return [];\n\n const filters: string[] = ['memory_records_fts MATCH ?'];\n const params: Array<string | number | null> = [query];\n if (options.agentId) {\n filters.push('f.agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n filters.push('f.workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.providerId) {\n filters.push('f.provider_id = ?');\n params.push(options.providerId);\n }\n if (options.kinds && options.kinds.length > 0) {\n filters.push(`f.kind IN (${options.kinds.map(() => '?').join(', ')})`);\n params.push(...options.kinds);\n }\n\n const maxResults = Math.max(1, Math.min(50, options.maxResults ?? 5));\n const minScore = options.minScore ?? 0;\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT\n r.*,\n bm25(memory_records_fts) AS rank\n FROM memory_records_fts f\n JOIN memory_records r ON r.record_id = f.record_id\n WHERE ${filters.join(' AND ')}\n ORDER BY rank\n LIMIT ?`,\n )\n .all(...params, maxResults * 3) as MemoryRecordSearchRow[];\n\n return rows\n .map((row) => {\n const record = rowToRecord(row);\n const score = bm25ToScore(row.rank);\n return {\n record,\n score,\n snippet: record.content,\n citation: {\n providerId: row.provider_id,\n recordId: row.record_id,\n path: record.source.path,\n lineStart: record.source.lineStart,\n lineEnd: record.source.lineEnd,\n createdAt: record.createdAt,\n },\n };\n })\n .filter((result) => result.score >= minScore)\n .slice(0, maxResults);\n}\n\nexport function deleteMemoryRecord(recordId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(recordId);\n const result = db.prepare(`DELETE FROM memory_records WHERE record_id = ?`).run(recordId);\n return result.changes > 0;\n });\n}\n\nexport function appendMemorySignal(input: AppendMemorySignalInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_signals (\n signal_id, source, record_id, provider_id, agent_id, workspace_id,\n session_key, score, content, metadata_json, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.signal.source,\n input.signal.recordId ?? null,\n input.providerId ?? null,\n input.agentId ?? null,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.signal.score ?? null,\n input.signal.content ?? null,\n JSON.stringify(input.signal.metadata ?? {}),\n now,\n );\n if (input.signal.recordId) {\n db.prepare(\n `UPDATE memory_records\n SET recall_count = recall_count + 1, last_recalled_at = ?, updated_at = MAX(updated_at, ?)\n WHERE record_id = ?`,\n ).run(now, now, input.signal.recordId);\n }\n });\n return id;\n}\n\nexport function listMemorySignals(options: {\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n limit?: number;\n} = {}): MemorySignalRowPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.recordId) {\n where.push('record_id = ?');\n params.push(options.recordId);\n }\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_signals\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemorySignalRow[];\n return rows.map((row) => {\n let metadata: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(row.metadata_json) as unknown;\n if (parsed && typeof parsed === 'object') metadata = parsed as Record<string, unknown>;\n } catch {\n metadata = {};\n }\n return {\n signalId: row.signal_id,\n source: row.source,\n ...(row.record_id ? { recordId: row.record_id } : {}),\n ...(row.provider_id ? { providerId: row.provider_id } : {}),\n ...(row.agent_id ? { agentId: row.agent_id } : {}),\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.score != null ? { score: row.score } : {}),\n ...(row.content ? { content: row.content } : {}),\n metadata,\n createdAt: new Date(row.created_at).toISOString(),\n };\n });\n}\n\nexport function getMemoryProviderState(providerId: string, scopeKey: string): unknown | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT state_json FROM memory_provider_state WHERE provider_id = ? AND scope_key = ?`)\n .get(providerId, scopeKey) as { state_json: string } | undefined;\n if (!row) return null;\n try {\n return JSON.parse(row.state_json) as unknown;\n } catch {\n return null;\n }\n}\n\nexport function setMemoryProviderState(providerId: string, scopeKey: string, state: unknown): void {\n const now = Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_provider_state (provider_id, scope_key, state_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(provider_id, scope_key) DO UPDATE SET\n state_json = excluded.state_json,\n updated_at = excluded.updated_at`,\n ).run(providerId, scopeKey, JSON.stringify(state ?? null), now);\n });\n}\n\nexport function appendMemoryTraceEvent(input: AppendMemoryTraceEventInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_trace_events (\n trace_id, session_key, turn_id, phase, provider_id, request_json,\n result_count, selected_record_ids_json, skipped_reason, error, duration_ms, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.sessionKey ?? null,\n input.turnId ?? null,\n input.phase,\n input.providerId,\n JSON.stringify(input.request ?? {}),\n input.resultCount ?? null,\n JSON.stringify(input.selectedRecordIds ?? []),\n input.skippedReason ?? null,\n input.error ?? null,\n Math.max(0, Math.floor(input.durationMs ?? 0)),\n now,\n );\n });\n return id;\n}\n\nexport function listMemoryTraceEvents(options: {\n providerId?: string;\n sessionKey?: string;\n phase?: string;\n limit?: number;\n} = {}): MemoryTraceEventPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n if (options.phase) {\n where.push('phase = ?');\n params.push(options.phase);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n return rows.map((row) => ({\n traceId: row.trace_id,\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.turn_id ? { turnId: row.turn_id } : {}),\n phase: row.phase,\n providerId: row.provider_id,\n request: parseJsonValue(row.request_json, {}),\n ...(row.result_count != null ? { resultCount: row.result_count } : {}),\n selectedRecordIds: parseStringArray(row.selected_record_ids_json),\n ...(row.skipped_reason ? { skippedReason: row.skipped_reason } : {}),\n ...(row.error ? { error: row.error } : {}),\n durationMs: row.duration_ms,\n createdAt: new Date(row.created_at).toISOString(),\n }));\n}\n\nfunction parseJsonValue(json: string, fallback: unknown): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"memory-records-repository.js","names":[],"sources":["../../../../src/storage/sqlite/memory-records-repository.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\n\nimport type {\n MemoryKind,\n MemoryRecord,\n MemorySensitivity,\n MemorySearchResult,\n MemorySignal,\n MemoryStatus,\n} from '../../agent/memory/types.js';\nimport { escapeFts5Query } from './fts.js';\nimport { getSqliteDatabase, runSqliteWriteTransaction } from './transaction.js';\n\ntype MemoryRecordRow = {\n record_id: string;\n provider_id: string;\n kind: string;\n agent_id: string;\n workspace_id: string | null;\n session_key: string | null;\n content: string;\n source_json: string;\n confidence: number | null;\n tags_json: string;\n status: string;\n sensitivity: string;\n evidence_json: string;\n review_after: number | null;\n expires_at: number | null;\n created_at: number;\n updated_at: number;\n};\n\ntype MemoryRecordSearchRow = MemoryRecordRow & {\n rank: number;\n};\n\nexport interface UpsertMemoryRecordInput {\n id?: string;\n providerId: string;\n kind: MemoryKind;\n agentId: string;\n workspaceId?: string;\n sessionKey?: string;\n content: string;\n source?: MemoryRecord['source'];\n confidence?: number;\n tags?: string[];\n status?: MemoryStatus;\n sensitivity?: MemorySensitivity;\n evidence?: MemoryRecord['evidence'];\n reviewAfter?: string;\n expiresAt?: string;\n nowMs?: number;\n}\n\nexport interface ListMemoryRecordsOptions {\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n kind?: MemoryKind;\n status?: MemoryStatus;\n limit?: number;\n offset?: number;\n}\n\nexport interface SearchMemoryRecordsOptions {\n query: string;\n agentId?: string;\n workspaceId?: string;\n providerId?: string;\n kinds?: MemoryKind[];\n statuses?: MemoryStatus[];\n maxResults?: number;\n minScore?: number;\n}\n\nexport interface AppendMemorySignalInput {\n signal: MemorySignal;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n nowMs?: number;\n}\n\nexport interface MemorySignalRowPayload {\n signalId: string;\n source: string;\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n sessionKey?: string;\n score?: number;\n content?: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\ntype MemorySignalRow = {\n signal_id: string;\n source: string;\n record_id: string | null;\n provider_id: string | null;\n agent_id: string | null;\n workspace_id: string | null;\n session_key: string | null;\n score: number | null;\n content: string | null;\n metadata_json: string;\n created_at: number;\n};\n\ntype MemoryTraceRow = {\n trace_id: string;\n session_key: string | null;\n turn_id: string | null;\n phase: string;\n provider_id: string;\n request_json: string;\n result_count: number | null;\n selected_record_ids_json: string;\n skipped_reason: string | null;\n error: string | null;\n feedback_json: string;\n duration_ms: number;\n created_at: number;\n};\n\nexport type MemoryTraceFeedbackOutcome = 'helpful' | 'not_helpful' | 'mixed' | 'irrelevant';\n\nexport interface MemoryTraceFeedback {\n outcome: MemoryTraceFeedbackOutcome;\n score?: number;\n reason?: string;\n source?: 'user' | 'evaluator' | 'system';\n createdAt: string;\n updatedAt?: string;\n}\n\nexport interface AppendMemoryTraceEventInput {\n sessionKey?: string;\n turnId?: string;\n phase: 'search' | 'read' | 'write' | 'update' | 'delete' | 'sync' | 'inject' | 'test';\n providerId: string;\n request?: unknown;\n resultCount?: number;\n selectedRecordIds?: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n durationMs?: number;\n nowMs?: number;\n}\n\nexport interface SetMemoryTraceFeedbackInput {\n traceId: string;\n feedback: Omit<MemoryTraceFeedback, 'createdAt' | 'updatedAt'> & {\n createdAt?: string;\n updatedAt?: string;\n };\n nowMs?: number;\n}\n\nexport interface MemoryTraceEventPayload {\n traceId: string;\n sessionKey?: string;\n turnId?: string;\n phase: string;\n providerId: string;\n request: unknown;\n resultCount?: number;\n selectedRecordIds: string[];\n skippedReason?: string;\n error?: string;\n feedback?: MemoryTraceFeedback;\n durationMs: number;\n createdAt: string;\n}\n\nexport interface MemoryRecallFeedbackSummary {\n recordId: string;\n helpful: number;\n notHelpful: number;\n mixed: number;\n irrelevant: number;\n total: number;\n averageScore: number | null;\n lastFeedbackAt?: string;\n}\n\nfunction parseStringArray(json: string): string[] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string') : [];\n } catch {\n return [];\n }\n}\n\nfunction parseEvidence(json: string): MemoryRecord['evidence'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.filter((item): item is NonNullable<MemoryRecord['evidence']>[number] =>\n Boolean(item) && typeof item === 'object',\n );\n } catch {\n return [];\n }\n}\n\nfunction parseMemoryTraceFeedback(json: string): MemoryTraceFeedback | undefined {\n try {\n const parsed = JSON.parse(json) as unknown;\n if (!parsed || typeof parsed !== 'object') return undefined;\n const obj = parsed as Record<string, unknown>;\n const outcome = obj.outcome;\n if (\n outcome !== 'helpful' &&\n outcome !== 'not_helpful' &&\n outcome !== 'mixed' &&\n outcome !== 'irrelevant'\n ) {\n return undefined;\n }\n return {\n outcome,\n ...(typeof obj.score === 'number' ? { score: obj.score } : {}),\n ...(typeof obj.reason === 'string' ? { reason: obj.reason } : {}),\n ...(obj.source === 'user' || obj.source === 'evaluator' || obj.source === 'system'\n ? { source: obj.source }\n : {}),\n createdAt: typeof obj.createdAt === 'string' ? obj.createdAt : new Date(0).toISOString(),\n ...(typeof obj.updatedAt === 'string' ? { updatedAt: obj.updatedAt } : {}),\n };\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeMemoryTraceFeedback(\n input: SetMemoryTraceFeedbackInput['feedback'],\n nowMs = Date.now(),\n existing?: MemoryTraceFeedback,\n): MemoryTraceFeedback {\n const score = typeof input.score === 'number'\n ? Math.max(-1, Math.min(1, input.score))\n : undefined;\n const reason = typeof input.reason === 'string' && input.reason.trim()\n ? input.reason.trim().slice(0, 1000)\n : undefined;\n const nowIso = new Date(nowMs).toISOString();\n return {\n outcome: input.outcome,\n ...(score != null ? { score } : {}),\n ...(reason ? { reason } : {}),\n ...(input.source ? { source: input.source } : {}),\n createdAt: input.createdAt ?? existing?.createdAt ?? nowIso,\n updatedAt: input.updatedAt ?? nowIso,\n };\n}\n\nfunction memoryTraceRowToPayload(row: MemoryTraceRow): MemoryTraceEventPayload {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n return {\n traceId: row.trace_id,\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.turn_id ? { turnId: row.turn_id } : {}),\n phase: row.phase,\n providerId: row.provider_id,\n request: parseJsonValue(row.request_json, {}),\n ...(row.result_count != null ? { resultCount: row.result_count } : {}),\n selectedRecordIds: parseStringArray(row.selected_record_ids_json),\n ...(row.skipped_reason ? { skippedReason: row.skipped_reason } : {}),\n ...(row.error ? { error: row.error } : {}),\n ...(feedback ? { feedback } : {}),\n durationMs: row.duration_ms,\n createdAt: new Date(row.created_at).toISOString(),\n };\n}\n\nfunction parseOptionalTimestamp(value: string | undefined): number | null {\n if (!value?.trim()) return null;\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction timestampToIso(value: number | null): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\nfunction parseSource(json: string): MemoryRecord['source'] {\n try {\n const parsed = JSON.parse(json) as unknown;\n return parsed && typeof parsed === 'object' ? (parsed as MemoryRecord['source']) : {};\n } catch {\n return {};\n }\n}\n\nfunction rowToRecord(row: MemoryRecordRow): MemoryRecord {\n return {\n id: row.record_id,\n kind: row.kind as MemoryKind,\n status: row.status as MemoryStatus,\n scope: {\n agentId: row.agent_id,\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n },\n content: row.content,\n source: parseSource(row.source_json),\n ...(row.confidence != null ? { confidence: row.confidence } : {}),\n sensitivity: row.sensitivity as MemorySensitivity,\n evidence: parseEvidence(row.evidence_json),\n ...(timestampToIso(row.review_after) ? { reviewAfter: timestampToIso(row.review_after) } : {}),\n ...(timestampToIso(row.expires_at) ? { expiresAt: timestampToIso(row.expires_at) } : {}),\n createdAt: new Date(row.created_at).toISOString(),\n updatedAt: new Date(row.updated_at).toISOString(),\n tags: parseStringArray(row.tags_json),\n };\n}\n\nfunction bm25ToScore(rank: number): number {\n return Math.max(0, Math.min(1, 1 / (1 + Math.max(0, rank))));\n}\n\nfunction upsertMemoryRecordFts(\n db: ReturnType<typeof getSqliteDatabase>,\n row: Pick<UpsertMemoryRecordInput, 'providerId' | 'kind' | 'agentId' | 'workspaceId' | 'content'> & { id: string },\n): void {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(row.id);\n if (!row.content.trim()) return;\n db.prepare(\n `INSERT INTO memory_records_fts (\n content, record_id, provider_id, kind, agent_id, workspace_id\n ) VALUES (?, ?, ?, ?, ?, ?)`,\n ).run(row.content, row.id, row.providerId, row.kind, row.agentId, row.workspaceId ?? null);\n}\n\nexport function upsertMemoryRecord(input: UpsertMemoryRecordInput): MemoryRecord {\n const id = input.id ?? randomUUID();\n const now = input.nowMs ?? Date.now();\n const status = input.status ?? 'active';\n const sensitivity = input.sensitivity ?? 'normal';\n const reviewAfter = parseOptionalTimestamp(input.reviewAfter);\n const expiresAt = parseOptionalTimestamp(input.expiresAt);\n const source = {\n ...(input.source ?? {}),\n provider: input.source?.provider ?? input.providerId,\n };\n\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_records (\n record_id, provider_id, kind, agent_id, workspace_id, session_key,\n content, source_json, confidence, tags_json, status, sensitivity,\n evidence_json, review_after, expires_at, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(record_id) DO UPDATE SET\n provider_id = excluded.provider_id,\n kind = excluded.kind,\n agent_id = excluded.agent_id,\n workspace_id = excluded.workspace_id,\n session_key = excluded.session_key,\n content = excluded.content,\n source_json = excluded.source_json,\n confidence = excluded.confidence,\n tags_json = excluded.tags_json,\n status = excluded.status,\n sensitivity = excluded.sensitivity,\n evidence_json = excluded.evidence_json,\n review_after = excluded.review_after,\n expires_at = excluded.expires_at,\n updated_at = excluded.updated_at`,\n ).run(\n id,\n input.providerId,\n input.kind,\n input.agentId,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.content,\n JSON.stringify(source),\n input.confidence ?? null,\n JSON.stringify(input.tags ?? []),\n status,\n sensitivity,\n JSON.stringify(input.evidence ?? []),\n reviewAfter,\n expiresAt,\n now,\n now,\n );\n upsertMemoryRecordFts(db, { ...input, id });\n });\n\n return {\n id,\n kind: input.kind,\n status,\n scope: {\n agentId: input.agentId,\n ...(input.workspaceId ? { workspaceId: input.workspaceId } : {}),\n ...(input.sessionKey ? { sessionKey: input.sessionKey } : {}),\n },\n content: input.content,\n source,\n ...(input.confidence != null ? { confidence: input.confidence } : {}),\n sensitivity,\n evidence: input.evidence ?? [],\n ...(reviewAfter != null ? { reviewAfter: new Date(reviewAfter).toISOString() } : {}),\n ...(expiresAt != null ? { expiresAt: new Date(expiresAt).toISOString() } : {}),\n createdAt: new Date(now).toISOString(),\n updatedAt: new Date(now).toISOString(),\n tags: input.tags ?? [],\n };\n}\n\nexport function getMemoryRecord(recordId: string): MemoryRecord | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_records WHERE record_id = ?`)\n .get(recordId) as MemoryRecordRow | undefined;\n return row ? rowToRecord(row) : null;\n}\n\nexport function listMemoryRecords(options: ListMemoryRecordsOptions = {}): MemoryRecord[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.kind) {\n where.push('kind = ?');\n params.push(options.kind);\n }\n if (options.status) {\n where.push('status = ?');\n params.push(options.status);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const offset = Math.max(0, options.offset ?? 0);\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_records\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY updated_at DESC\n LIMIT ? OFFSET ?`,\n )\n .all(...params, limit, offset) as MemoryRecordRow[];\n return rows.map(rowToRecord);\n}\n\nexport function searchMemoryRecords(options: SearchMemoryRecordsOptions): MemorySearchResult[] {\n const query = escapeFts5Query(options.query);\n if (!query) return [];\n\n const filters: string[] = ['memory_records_fts MATCH ?'];\n const params: Array<string | number | null> = [query];\n if (options.agentId) {\n filters.push('f.agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n filters.push('f.workspace_id = ?');\n params.push(options.workspaceId);\n }\n if (options.providerId) {\n filters.push('f.provider_id = ?');\n params.push(options.providerId);\n }\n if (options.kinds && options.kinds.length > 0) {\n filters.push(`f.kind IN (${options.kinds.map(() => '?').join(', ')})`);\n params.push(...options.kinds);\n }\n const statuses = options.statuses && options.statuses.length > 0 ? options.statuses : ['active'];\n filters.push(`r.status IN (${statuses.map(() => '?').join(', ')})`);\n params.push(...statuses);\n\n const maxResults = Math.max(1, Math.min(50, options.maxResults ?? 5));\n const minScore = options.minScore ?? 0;\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT\n r.*,\n bm25(memory_records_fts) AS rank\n FROM memory_records_fts f\n JOIN memory_records r ON r.record_id = f.record_id\n WHERE ${filters.join(' AND ')}\n ORDER BY rank\n LIMIT ?`,\n )\n .all(...params, maxResults * 3) as MemoryRecordSearchRow[];\n\n return rows\n .map((row) => {\n const record = rowToRecord(row);\n const score = bm25ToScore(row.rank);\n return {\n record,\n score,\n snippet: record.content,\n citation: {\n providerId: row.provider_id,\n recordId: row.record_id,\n path: record.source.path,\n lineStart: record.source.lineStart,\n lineEnd: record.source.lineEnd,\n createdAt: record.createdAt,\n },\n };\n })\n .filter((result) => result.score >= minScore)\n .slice(0, maxResults);\n}\n\nexport function deleteMemoryRecord(recordId: string): boolean {\n return runSqliteWriteTransaction((db) => {\n db.prepare(`DELETE FROM memory_records_fts WHERE record_id = ?`).run(recordId);\n const result = db.prepare(`DELETE FROM memory_records WHERE record_id = ?`).run(recordId);\n return result.changes > 0;\n });\n}\n\nexport function appendMemorySignal(input: AppendMemorySignalInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_signals (\n signal_id, source, record_id, provider_id, agent_id, workspace_id,\n session_key, score, content, metadata_json, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.signal.source,\n input.signal.recordId ?? null,\n input.providerId ?? null,\n input.agentId ?? null,\n input.workspaceId ?? null,\n input.sessionKey ?? null,\n input.signal.score ?? null,\n input.signal.content ?? null,\n JSON.stringify(input.signal.metadata ?? {}),\n now,\n );\n if (input.signal.recordId) {\n db.prepare(\n `UPDATE memory_records\n SET recall_count = recall_count + 1, last_recalled_at = ?, updated_at = MAX(updated_at, ?)\n WHERE record_id = ?`,\n ).run(now, now, input.signal.recordId);\n }\n });\n return id;\n}\n\nexport function listMemorySignals(options: {\n recordId?: string;\n providerId?: string;\n agentId?: string;\n workspaceId?: string;\n limit?: number;\n} = {}): MemorySignalRowPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.recordId) {\n where.push('record_id = ?');\n params.push(options.recordId);\n }\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.agentId) {\n where.push('agent_id = ?');\n params.push(options.agentId);\n }\n if (options.workspaceId) {\n where.push('workspace_id = ?');\n params.push(options.workspaceId);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_signals\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemorySignalRow[];\n return rows.map((row) => {\n let metadata: Record<string, unknown> = {};\n try {\n const parsed = JSON.parse(row.metadata_json) as unknown;\n if (parsed && typeof parsed === 'object') metadata = parsed as Record<string, unknown>;\n } catch {\n metadata = {};\n }\n return {\n signalId: row.signal_id,\n source: row.source,\n ...(row.record_id ? { recordId: row.record_id } : {}),\n ...(row.provider_id ? { providerId: row.provider_id } : {}),\n ...(row.agent_id ? { agentId: row.agent_id } : {}),\n ...(row.workspace_id ? { workspaceId: row.workspace_id } : {}),\n ...(row.session_key ? { sessionKey: row.session_key } : {}),\n ...(row.score != null ? { score: row.score } : {}),\n ...(row.content ? { content: row.content } : {}),\n metadata,\n createdAt: new Date(row.created_at).toISOString(),\n };\n });\n}\n\nexport function getMemoryProviderState(providerId: string, scopeKey: string): unknown | null {\n const row = getSqliteDatabase()\n .prepare(`SELECT state_json FROM memory_provider_state WHERE provider_id = ? AND scope_key = ?`)\n .get(providerId, scopeKey) as { state_json: string } | undefined;\n if (!row) return null;\n try {\n return JSON.parse(row.state_json) as unknown;\n } catch {\n return null;\n }\n}\n\nexport function setMemoryProviderState(providerId: string, scopeKey: string, state: unknown): void {\n const now = Date.now();\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_provider_state (provider_id, scope_key, state_json, updated_at)\n VALUES (?, ?, ?, ?)\n ON CONFLICT(provider_id, scope_key) DO UPDATE SET\n state_json = excluded.state_json,\n updated_at = excluded.updated_at`,\n ).run(providerId, scopeKey, JSON.stringify(state ?? null), now);\n });\n}\n\nexport function appendMemoryTraceEvent(input: AppendMemoryTraceEventInput): string {\n const id = randomUUID();\n const now = input.nowMs ?? Date.now();\n const feedback = input.feedback\n ? normalizeMemoryTraceFeedback(input.feedback, now)\n : undefined;\n runSqliteWriteTransaction((db) => {\n db.prepare(\n `INSERT INTO memory_trace_events (\n trace_id, session_key, turn_id, phase, provider_id, request_json,\n result_count, selected_record_ids_json, skipped_reason, error, feedback_json, duration_ms, created_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n ).run(\n id,\n input.sessionKey ?? null,\n input.turnId ?? null,\n input.phase,\n input.providerId,\n JSON.stringify(input.request ?? {}),\n input.resultCount ?? null,\n JSON.stringify(input.selectedRecordIds ?? []),\n input.skippedReason ?? null,\n input.error ?? null,\n JSON.stringify(feedback ?? {}),\n Math.max(0, Math.floor(input.durationMs ?? 0)),\n now,\n );\n });\n return id;\n}\n\nexport function listMemoryTraceEvents(options: {\n providerId?: string;\n sessionKey?: string;\n phase?: string;\n limit?: number;\n} = {}): MemoryTraceEventPayload[] {\n const where: string[] = [];\n const params: Array<string | number | null> = [];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n if (options.phase) {\n where.push('phase = ?');\n params.push(options.phase);\n }\n const limit = Math.max(1, Math.min(500, options.limit ?? 100));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n ${where.length > 0 ? `WHERE ${where.join(' AND ')}` : ''}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n return rows.map(memoryTraceRowToPayload);\n}\n\nexport function setMemoryTraceFeedback(input: SetMemoryTraceFeedbackInput): MemoryTraceEventPayload | null {\n const existing = getSqliteDatabase()\n .prepare(`SELECT * FROM memory_trace_events WHERE trace_id = ?`)\n .get(input.traceId) as MemoryTraceRow | undefined;\n if (!existing) {\n return null;\n }\n const feedback = normalizeMemoryTraceFeedback(\n input.feedback,\n input.nowMs,\n parseMemoryTraceFeedback(existing.feedback_json),\n );\n runSqliteWriteTransaction((db) => {\n db.prepare(`UPDATE memory_trace_events SET feedback_json = ? WHERE trace_id = ?`)\n .run(JSON.stringify(feedback), input.traceId);\n });\n return memoryTraceRowToPayload({ ...existing, feedback_json: JSON.stringify(feedback) });\n}\n\nexport function summarizeMemoryRecallFeedback(options: {\n recordId?: string;\n providerId?: string;\n sessionKey?: string;\n limit?: number;\n} = {}): MemoryRecallFeedbackSummary[] {\n const where = ['phase IN (?, ?)'];\n const params: Array<string | number> = ['search', 'inject'];\n if (options.providerId) {\n where.push('provider_id = ?');\n params.push(options.providerId);\n }\n if (options.sessionKey) {\n where.push('session_key = ?');\n params.push(options.sessionKey);\n }\n const limit = Math.max(1, Math.min(5000, options.limit ?? 1000));\n const rows = getSqliteDatabase()\n .prepare(\n `SELECT * FROM memory_trace_events\n WHERE ${where.join(' AND ')}\n ORDER BY created_at DESC\n LIMIT ?`,\n )\n .all(...params, limit) as MemoryTraceRow[];\n\n const summaries = new Map<string, MemoryRecallFeedbackSummary & { scoreTotal: number; scoreCount: number }>();\n for (const row of rows) {\n const feedback = parseMemoryTraceFeedback(row.feedback_json);\n if (!feedback) continue;\n const recordIds = parseStringArray(row.selected_record_ids_json);\n for (const recordId of recordIds) {\n if (options.recordId && recordId !== options.recordId) continue;\n const current = summaries.get(recordId) ?? {\n recordId,\n helpful: 0,\n notHelpful: 0,\n mixed: 0,\n irrelevant: 0,\n total: 0,\n averageScore: null,\n scoreTotal: 0,\n scoreCount: 0,\n };\n if (feedback.outcome === 'helpful') current.helpful += 1;\n if (feedback.outcome === 'not_helpful') current.notHelpful += 1;\n if (feedback.outcome === 'mixed') current.mixed += 1;\n if (feedback.outcome === 'irrelevant') current.irrelevant += 1;\n current.total += 1;\n if (typeof feedback.score === 'number') {\n current.scoreTotal += feedback.score;\n current.scoreCount += 1;\n current.averageScore = current.scoreTotal / current.scoreCount;\n }\n current.lastFeedbackAt ??= feedback.updatedAt ?? feedback.createdAt;\n summaries.set(recordId, current);\n }\n }\n\n return [...summaries.values()]\n .map(({ scoreTotal: _scoreTotal, scoreCount: _scoreCount, ...summary }) => summary)\n .sort((a, b) => b.total - a.total);\n}\n\nfunction parseJsonValue(json: string, fallback: unknown): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch {\n return fallback;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ ALTER TABLE memory_records ADD COLUMN status TEXT NOT NULL DEFAULT 'active';
2
+ ALTER TABLE memory_records ADD COLUMN sensitivity TEXT NOT NULL DEFAULT 'normal';
3
+ ALTER TABLE memory_records ADD COLUMN evidence_json TEXT NOT NULL DEFAULT '[]';
4
+ ALTER TABLE memory_records ADD COLUMN review_after INTEGER;
5
+ ALTER TABLE memory_records ADD COLUMN expires_at INTEGER;
6
+
7
+ CREATE INDEX IF NOT EXISTS idx_memory_records_status_updated
8
+ ON memory_records(status, updated_at DESC);
9
+ CREATE INDEX IF NOT EXISTS idx_memory_records_status_scope_updated
10
+ ON memory_records(status, agent_id, workspace_id, updated_at DESC);
@@ -0,0 +1,4 @@
1
+ ALTER TABLE memory_trace_events ADD COLUMN feedback_json TEXT NOT NULL DEFAULT '{}';
2
+
3
+ CREATE INDEX IF NOT EXISTS idx_memory_trace_phase_created
4
+ ON memory_trace_events(phase, created_at DESC);
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
3
3
  /** Baseline schema version applied from schema.sql on first open. */
4
4
  export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
5
5
  /** Latest schema version this release supports (increment when adding migrations). */
6
- export declare const XOPC_DB_SCHEMA_VERSION = 13;
6
+ export declare const XOPC_DB_SCHEMA_VERSION = 15;
7
7
  export declare function resolveMigrationsDir(override?: string): string;
8
8
  /**
9
9
  * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
12
12
  /** Baseline schema version applied from schema.sql on first open. */
13
13
  const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
14
14
  /** Latest schema version this release supports (increment when adding migrations). */
15
- const XOPC_DB_SCHEMA_VERSION = 13;
15
+ const XOPC_DB_SCHEMA_VERSION = 15;
16
16
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
17
17
  function resolveMigrationsDir(override) {
18
18
  if (override) return override;
@@ -46,7 +46,7 @@ function applySingleMigration(db, migration) {
46
46
  * Each step runs in its own transaction and updates schema_meta on success.
47
47
  */
48
48
  function applyPendingMigrations(db, options = {}) {
49
- const targetVersion = options.targetVersion ?? 13;
49
+ const targetVersion = options.targetVersion ?? 15;
50
50
  let currentVersion = readSchemaVersion(db);
51
51
  if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
52
52
  if (currentVersion >= targetVersion) return currentVersion;
@@ -62,7 +62,7 @@ function applyPendingMigrations(db, options = {}) {
62
62
  }
63
63
  /** Inspect schema version without mutating the database. */
64
64
  function inspectSchemaMigrationStatus(db, options = {}) {
65
- const appVersion = options.targetVersion ?? 13;
65
+ const appVersion = options.targetVersion ?? 15;
66
66
  const dbVersion = readSchemaVersion(db);
67
67
  if (dbVersion > appVersion) return {
68
68
  dbVersion,
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 13;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
1
+ {"version":3,"file":"runner.js","names":[],"sources":["../../../../../src/storage/sqlite/migrations/runner.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { DatabaseSync } from 'node:sqlite';\n\nimport { createLogger } from '../../../utils/logger.js';\nimport { readSchemaVersion, setSchemaVersion } from '../schema-version.js';\nimport { discoverSqlMigrations } from './discover.js';\nimport {\n DatabaseSchemaMigrationGapError,\n DatabaseSchemaTooNewError,\n} from './errors.js';\nimport type { ApplyMigrationsOptions, SqlMigration } from './types.js';\n\nconst log = createLogger('Sqlite:Migrations');\n\n/** Baseline schema version applied from schema.sql on first open. */\nexport const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;\n\n/** Latest schema version this release supports (increment when adding migrations). */\nexport const XOPC_DB_SCHEMA_VERSION = 15;\n\nconst MODULE_DIR = dirname(fileURLToPath(import.meta.url));\n\nexport function resolveMigrationsDir(override?: string): string {\n if (override) {\n return override;\n }\n // Packaged Electron gateway bundle: `out/server/index.js` + `out/server/migrations/`.\n const siblingDir = join(MODULE_DIR, 'migrations');\n if (existsSync(siblingDir)) {\n return siblingDir;\n }\n // Dev / dist: SQL files live next to `migrations/runner.js`.\n return MODULE_DIR;\n}\n\nfunction migrationByTarget(\n migrations: SqlMigration[],\n targetVersion: number,\n): SqlMigration | undefined {\n return migrations.find((migration) => migration.targetVersion === targetVersion);\n}\n\nfunction applySingleMigration(db: DatabaseSync, migration: SqlMigration): void {\n log.info({ targetVersion: migration.targetVersion, file: migration.filename }, 'Applying SQLite migration');\n db.exec('BEGIN IMMEDIATE');\n try {\n db.exec(migration.sql);\n setSchemaVersion(db, migration.targetVersion);\n db.exec('COMMIT');\n } catch (error) {\n try {\n db.exec('ROLLBACK');\n } catch {\n /* preserve original error */\n }\n const em = error instanceof Error ? error.message : String(error);\n throw new Error(\n `SQLite migration to v${migration.targetVersion} (${migration.filename}) failed: ${em}`,\n { cause: error },\n );\n }\n}\n\n/**\n * Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.\n * Each step runs in its own transaction and updates schema_meta on success.\n */\nexport function applyPendingMigrations(\n db: DatabaseSync,\n options: ApplyMigrationsOptions = {},\n): number {\n const targetVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n let currentVersion = readSchemaVersion(db);\n\n if (currentVersion > targetVersion) {\n throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);\n }\n\n if (currentVersion >= targetVersion) {\n return currentVersion;\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n\n while (currentVersion < targetVersion) {\n const nextVersion = currentVersion + 1;\n const migration = migrationByTarget(migrations, nextVersion);\n if (!migration) {\n throw new DatabaseSchemaMigrationGapError(currentVersion, targetVersion, nextVersion);\n }\n applySingleMigration(db, migration);\n currentVersion = nextVersion;\n }\n\n return currentVersion;\n}\n\nexport type SchemaMigrationStatus = {\n dbVersion: number;\n appVersion: number;\n pendingVersions: number[];\n isTooNew: boolean;\n hasMigrationGap: boolean;\n missingVersion: number | null;\n};\n\n/** Inspect schema version without mutating the database. */\nexport function inspectSchemaMigrationStatus(\n db: DatabaseSync,\n options: Pick<ApplyMigrationsOptions, 'migrationsDir' | 'targetVersion'> = {},\n): SchemaMigrationStatus {\n const appVersion = options.targetVersion ?? XOPC_DB_SCHEMA_VERSION;\n const dbVersion = readSchemaVersion(db);\n const isTooNew = dbVersion > appVersion;\n\n if (isTooNew) {\n return {\n dbVersion,\n appVersion,\n pendingVersions: [],\n isTooNew: true,\n hasMigrationGap: false,\n missingVersion: null,\n };\n }\n\n const migrations = discoverSqlMigrations(resolveMigrationsDir(options.migrationsDir));\n const pendingVersions: number[] = [];\n let hasMigrationGap = false;\n let missingVersion: number | null = null;\n\n for (let version = dbVersion + 1; version <= appVersion; version++) {\n if (migrationByTarget(migrations, version)) {\n pendingVersions.push(version);\n } else {\n hasMigrationGap = true;\n missingVersion = version;\n break;\n }\n }\n\n return {\n dbVersion,\n appVersion,\n pendingVersions,\n isTooNew: false,\n hasMigrationGap,\n missingVersion,\n };\n}\n"],"mappings":";;;;;;;;;aAMwD;AASxD,MAAM,MAAM,aAAa,oBAAoB;;AAG7C,MAAa,kCAAkC;;AAG/C,MAAa,yBAAyB;AAEtC,MAAM,aAAa,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE1D,SAAgB,qBAAqB,UAA2B;AAC9D,KAAI,SACF,QAAO;CAGT,MAAM,aAAa,KAAK,YAAY,aAAa;AACjD,KAAI,WAAW,WAAW,CACxB,QAAO;AAGT,QAAO;;AAGT,SAAS,kBACP,YACA,eAC0B;AAC1B,QAAO,WAAW,MAAM,cAAc,UAAU,kBAAkB,cAAc;;AAGlF,SAAS,qBAAqB,IAAkB,WAA+B;AAC7E,KAAI,KAAK;EAAE,eAAe,UAAU;EAAe,MAAM,UAAU;EAAU,EAAE,4BAA4B;AAC3G,IAAG,KAAK,kBAAkB;AAC1B,KAAI;AACF,KAAG,KAAK,UAAU,IAAI;AACtB,mBAAiB,IAAI,UAAU,cAAc;AAC7C,KAAG,KAAK,SAAS;UACV,OAAO;AACd,MAAI;AACF,MAAG,KAAK,WAAW;UACb;EAGR,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACjE,QAAM,IAAI,MACR,wBAAwB,UAAU,cAAc,IAAI,UAAU,SAAS,YAAY,MACnF,EAAE,OAAO,OAAO,CACjB;;;;;;;AAQL,SAAgB,uBACd,IACA,UAAkC,EAAE,EAC5B;CACR,MAAM,gBAAgB,QAAQ,iBAAA;CAC9B,IAAI,iBAAiB,kBAAkB,GAAG;AAE1C,KAAI,iBAAiB,cACnB,OAAM,IAAI,0BAA0B,gBAAgB,cAAc;AAGpE,KAAI,kBAAkB,cACpB,QAAO;CAGT,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;AAErF,QAAO,iBAAiB,eAAe;EACrC,MAAM,cAAc,iBAAiB;EACrC,MAAM,YAAY,kBAAkB,YAAY,YAAY;AAC5D,MAAI,CAAC,UACH,OAAM,IAAI,gCAAgC,gBAAgB,eAAe,YAAY;AAEvF,uBAAqB,IAAI,UAAU;AACnC,mBAAiB;;AAGnB,QAAO;;;AAaT,SAAgB,6BACd,IACA,UAA2E,EAAE,EACtD;CACvB,MAAM,aAAa,QAAQ,iBAAA;CAC3B,MAAM,YAAY,kBAAkB,GAAG;AAGvC,KAFiB,YAAY,WAG3B,QAAO;EACL;EACA;EACA,iBAAiB,EAAE;EACnB,UAAU;EACV,iBAAiB;EACjB,gBAAgB;EACjB;CAGH,MAAM,aAAa,sBAAsB,qBAAqB,QAAQ,cAAc,CAAC;CACrF,MAAM,kBAA4B,EAAE;CACpC,IAAI,kBAAkB;CACtB,IAAI,iBAAgC;AAEpC,MAAK,IAAI,UAAU,YAAY,GAAG,WAAW,YAAY,UACvD,KAAI,kBAAkB,YAAY,QAAQ,CACxC,iBAAgB,KAAK,QAAQ;MACxB;AACL,oBAAkB;AAClB,mBAAiB;AACjB;;AAIJ,QAAO;EACL;EACA;EACA;EACA,UAAU;EACV;EACA;EACD"}
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
19
19
  export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
20
20
 
21
21
  /** Latest schema version this release supports (increment when adding migrations). */
22
- export const XOPC_DB_SCHEMA_VERSION = 13;
22
+ export const XOPC_DB_SCHEMA_VERSION = 15;
23
23
 
24
24
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
25
25
 
@@ -31,7 +31,7 @@ function ensureXopcDatabaseSchema(db) {
31
31
  bootstrapFreshDatabase(db);
32
32
  currentVersion = 11;
33
33
  }
34
- applyPendingMigrations(db, { targetVersion: 13 });
34
+ applyPendingMigrations(db, { targetVersion: 15 });
35
35
  }
36
36
  //#endregion
37
37
  export { SCHEMA_META_SCHEMA_VERSION_KEY, XOPC_DB_BASELINE_SCHEMA_VERSION, XOPC_DB_SCHEMA_VERSION, ensureSchemaMetaTable, ensureXopcDatabaseSchema, readSchemaVersion, readSchemaVersionForTest, setSchemaVersion };
@@ -17,6 +17,7 @@ export declare class EmbeddedBackend implements TuiBackend {
17
17
  private readonly opts?;
18
18
  private bus;
19
19
  private agent;
20
+ private agentLoading;
20
21
  private config;
21
22
  private workspace;
22
23
  private sessionIndex;
@@ -30,6 +31,8 @@ export declare class EmbeddedBackend implements TuiBackend {
30
31
  constructor(opts?: EmbeddedBackendOptions);
31
32
  get connectionLabel(): string;
32
33
  start(): void;
34
+ private ensureAgent;
35
+ private createAgent;
33
36
  stop(): void;
34
37
  getActiveSignal(): AbortSignal | undefined;
35
38
  private getWorkflowRunService;
@@ -4,7 +4,6 @@ import { init_agent_session_key, resolveAgentIdFromSessionKey } from "../../rout
4
4
  import { createLogger } from "../../utils/logger/index.js";
5
5
  import { init_logger } from "../../utils/logger.js";
6
6
  import { loadConfig } from "../../config/loader.js";
7
- import { getAvailableModels, init_providers } from "../../providers/index.js";
8
7
  import { createCreateShareTool, isShareToolAvailable } from "../../agent/tools/create-share-tool.js";
9
8
  import { openXopcDatabase } from "../../storage/sqlite/connection.js";
10
9
  import "../../storage/sqlite/index.js";
@@ -16,8 +15,6 @@ import "../../session/index.js";
16
15
  import { parseModelRef } from "../../agent/models/selection.js";
17
16
  import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
18
17
  import "../../infra/bus/index.js";
19
- import { AgentService } from "../../agent/service.js";
20
- import "../../agent/index.js";
21
18
  import { getWorkspacePath } from "../../config/workspace-path-helpers.js";
22
19
  import "../../config/index.js";
23
20
  import { buildWorkflowChildTools } from "../../agent/workflow/workflow-child-tools.js";
@@ -34,7 +31,6 @@ import { isAbsolute, relative, resolve } from "node:path";
34
31
  init_agent_scope();
35
32
  init_agent_session_key();
36
33
  init_schema();
37
- init_providers();
38
34
  init_logger();
39
35
  const log = createLogger("TUI:Embedded");
40
36
  function isPathSameOrInside(parentDir, childDir) {
@@ -50,6 +46,7 @@ function isPathSameOrInside(parentDir, childDir) {
50
46
  var EmbeddedBackend = class {
51
47
  bus;
52
48
  agent = null;
49
+ agentLoading = null;
53
50
  config = null;
54
51
  workspace = "";
55
52
  sessionIndex = null;
@@ -74,7 +71,6 @@ var EmbeddedBackend = class {
74
71
  this.config = config;
75
72
  const workspace = getWorkspacePath(config);
76
73
  this.workspace = workspace;
77
- const modelId = getAgentDefaultModelRef(config);
78
74
  openXopcDatabase();
79
75
  this.sessionIndex = new SessionIndex({ config });
80
76
  this.sessionIndexReady = this.sessionIndex.initialize().catch((err) => {
@@ -85,11 +81,39 @@ var EmbeddedBackend = class {
85
81
  }, `Embedded session index initialization failed: ${errorMessage}`);
86
82
  throw err;
87
83
  });
88
- this.agent = new AgentService(this.bus, {
84
+ this.onConnected?.();
85
+ setTimeout(() => {
86
+ this.ensureAgent().catch((err) => {
87
+ const errorMessage = err instanceof Error ? err.message : String(err);
88
+ log.error({
89
+ err,
90
+ errorMessage
91
+ }, `Embedded agent failed: ${errorMessage}`);
92
+ this.onDisconnected?.(errorMessage);
93
+ });
94
+ }, 750);
95
+ this.processOutbound();
96
+ }
97
+ async ensureAgent() {
98
+ if (this.agent) return this.agent;
99
+ if (this.agentLoading) return this.agentLoading;
100
+ if (!this.config || !this.sessionIndex) throw new Error("Embedded backend not started");
101
+ this.agentLoading = this.createAgent(this.config, this.sessionIndex);
102
+ try {
103
+ return await this.agentLoading;
104
+ } finally {
105
+ this.agentLoading = null;
106
+ }
107
+ }
108
+ async createAgent(config, sessionIndex) {
109
+ const { AgentService } = await import("../../agent/service.js");
110
+ const workspace = this.workspace || getWorkspacePath(config);
111
+ const modelId = getAgentDefaultModelRef(config);
112
+ const agent = new AgentService(this.bus, {
89
113
  workspace,
90
114
  model: modelId,
91
115
  config,
92
- sessionStore: this.sessionIndex.getStore(),
116
+ sessionStore: sessionIndex.getStore(),
93
117
  getWorkflowRunService: () => this.getWorkflowRunService(),
94
118
  extensionRegistry: this.opts?.extensionRegistry,
95
119
  isWorkspaceTrusted: (workspaceDir) => {
@@ -99,17 +123,9 @@ var EmbeddedBackend = class {
99
123
  if (implicit && isPathSameOrInside(implicit, workspaceDir)) return true;
100
124
  }
101
125
  });
102
- this.agent.start().then(() => {
103
- this.onConnected?.();
104
- }).catch((err) => {
105
- const errorMessage = err instanceof Error ? err.message : String(err);
106
- log.error({
107
- err,
108
- errorMessage
109
- }, `Embedded agent failed: ${errorMessage}`);
110
- this.onDisconnected?.(errorMessage);
111
- });
112
- this.processOutbound();
126
+ this.agent = agent;
127
+ await agent.start();
128
+ return agent;
113
129
  }
114
130
  stop() {
115
131
  this.running = false;
@@ -186,7 +202,7 @@ var EmbeddedBackend = class {
186
202
  }
187
203
  }
188
204
  async sendChat(opts) {
189
- if (!this.agent) throw new Error("Agent not started");
205
+ const agent = await this.ensureAgent();
190
206
  const runId = crypto.randomUUID();
191
207
  this.chatAbort?.abort();
192
208
  this.chatAbort = new AbortController();
@@ -204,7 +220,7 @@ var EmbeddedBackend = class {
204
220
  (async () => {
205
221
  try {
206
222
  const messageForAgent = opts.message.trimStart().startsWith("/") ? opts.message : prependEnvelopeTimestamp(opts.message);
207
- const stream = this.agent.turnDispatcher.processDirectStreaming(messageForAgent, opts.sessionKey, opts.attachments, opts.thinking, {
223
+ const stream = agent.turnDispatcher.processDirectStreaming(messageForAgent, opts.sessionKey, opts.attachments, opts.thinking, {
208
224
  signal,
209
225
  runId
210
226
  });
@@ -379,6 +395,7 @@ var EmbeddedBackend = class {
379
395
  }
380
396
  }
381
397
  async listModels() {
398
+ const { getAvailableModels } = await import("../../providers/index.js");
382
399
  return (await getAvailableModels()).map((model) => ({
383
400
  id: model.id,
384
401
  name: model.name ?? model.id,
@@ -1 +1 @@
1
- {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport { AgentService } from '../../agent/index.js';\nimport { listAgentEntries, normalizeAgentId } from '../../agent/agent-scope.js';\nimport { resolveAgentIdFromSessionKey } from '../../routing/agent-session-key.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport { createCreateShareTool, isShareToolAvailable } from '../../agent/tools/create-share-tool.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { getAvailableModels } from '../../providers/index.js';\nimport { evictEmbeddedSessionRunner } from '../../agent/embedded/session-runner.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { openXopcDatabase } from '../../storage/sqlite/index.js';\nimport { buildWorkflowChildTools } from '../../agent/workflow/workflow-child-tools.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { WorkflowRunService } from '../../workflows/service/workflow-run-service.js';\nimport { WorkflowSessionBridge } from '../../workflows/service/workflow-session-bridge.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { sessionMetadataToTuiItem } from '../tui-session-format.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport { ChatStreamMapper } from '../../gateway/chat-stream/mapper.js';\nimport { collectTuiStartupResources } from '../tui-startup-resources.js';\nimport { fuzzySearchWorkspaceFiles } from '../../gateway/workspace-file-search.js';\n\nconst log = createLogger('TUI:Embedded');\n\ninterface EmbeddedBackendOptions {\n extensionRegistry?: ExtensionRegistryImpl;\n implicitTrustedWorkspace?: string;\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nfunction isPathSameOrInside(parentDir: string, childDir: string): boolean {\n const rel = relative(resolve(parentDir), resolve(childDir));\n return rel === '' || (!!rel && !rel.startsWith('..') && !isAbsolute(rel));\n}\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private config: ReturnType<typeof loadConfig> | null = null;\n private workspace = '';\n private sessionIndex: SessionIndex | null = null;\n private sessionIndexReady: Promise<void> | null = null;\n private workflowRunService: WorkflowRunService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor(private readonly opts?: EmbeddedBackendOptions) {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = loadConfig();\n this.config = config;\n const workspace = getWorkspacePath(config);\n this.workspace = workspace;\n const modelId = getAgentDefaultModelRef(config);\n openXopcDatabase();\n this.sessionIndex = new SessionIndex({ config });\n this.sessionIndexReady = this.sessionIndex.initialize().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage }, `Embedded session index initialization failed: ${errorMessage}`);\n throw err;\n });\n\n this.agent = new AgentService(this.bus, {\n workspace,\n model: modelId,\n config,\n sessionStore: this.sessionIndex.getStore(),\n getWorkflowRunService: () => this.getWorkflowRunService(),\n extensionRegistry: this.opts?.extensionRegistry,\n isWorkspaceTrusted: (workspaceDir) => {\n const explicit = this.opts?.isWorkspaceTrusted?.(workspaceDir);\n if (explicit !== undefined && explicit !== null) {\n return explicit;\n }\n const implicit = this.opts?.implicitTrustedWorkspace;\n if (implicit && isPathSameOrInside(implicit, workspaceDir)) {\n return true;\n }\n return undefined;\n },\n });\n\n this.agent.start().then(() => {\n this.onConnected?.();\n }).catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n\n // Process outbound messages in background\n this.processOutbound();\n }\n\n stop(): void {\n this.running = false;\n this.chatAbort?.abort();\n this.chatAbort = null;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n private getWorkflowRunService(): WorkflowRunService {\n if (this.workflowRunService) return this.workflowRunService;\n if (!this.config || !this.sessionIndex || !this.agent) {\n throw new Error('Embedded workflow runtime is not ready.');\n }\n\n const host: GatewayWorkflowHost = {\n currentConfig: this.config,\n currentWorkspacePath: this.workspace,\n messageBusInstance: this.bus,\n agentService: {\n getModelForSession: (sessionKey) => this.agent!.getModelForSession(sessionKey),\n },\n sessionIndexInstance: this.sessionIndex,\n emit: (event, payload) => {\n this.onEvent?.({\n event,\n data: payload,\n source: 'broadcast',\n });\n },\n };\n\n this.workflowRunService = new WorkflowRunService({\n service: host,\n sessionBridge: new WorkflowSessionBridge(host),\n buildChildTools: buildWorkflowChildTools,\n });\n return this.workflowRunService;\n }\n\n async getStartupResources(sessionKey: string) {\n return collectTuiStartupResources(loadConfig(), sessionKey);\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n await this.sessionIndexReady;\n const agentId = opts.agentId?.trim() || resolveAgentIdFromSessionKey(opts.sessionKey);\n const result = await this.getWorkflowRunService().startWorkflowRun({\n agentId,\n definitionId: opts.definitionId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n goal: opts.goal,\n input: opts.input,\n });\n if (result.ok === false) {\n throw new Error(result.message);\n }\n return {\n runId: result.runId,\n sessionKey: result.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n if (!this.agent) return [];\n try {\n const workspaceRoot = await this.agent.getEffectiveWorkspacePathForSession(sessionKey);\n return await fuzzySearchWorkspaceFiles(workspaceRoot, query, options?.limit ?? 15);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n if (!this.agent) throw new Error('Agent not started');\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n const mapper = new ChatStreamMapper({ runId, sessionKey: opts.sessionKey, channel: 'tui' });\n for (const event of mapper.start()) {\n this.onEvent?.({ event: event.type, data: event, source: 'embedded' });\n }\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = this.agent!.turnDispatcher.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n opts.attachments,\n opts.thinking,\n { signal, runId },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n for (const mapped of mapper.map(event)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n\n if (!signal.aborted) {\n for (const mapped of mapper.end('success')) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n for (const mapped of mapper.error(errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n for (const mapped of mapper.end('error', errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n const ok = await this.agent.turnDispatcher.steerWebchatSession(opts.sessionKey, opts.message);\n return { ok };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);\n return {\n messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n if (!this.agent) return [];\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded loadTranscriptTree failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n if (!this.agent) return computeTuiSessionStats([]);\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded getSessionStats failed: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n if (!this.agent) return [];\n try {\n const result = await this.agent.sessionStore.list({\n limit: 200,\n sortBy: 'updatedAt',\n sortOrder: 'desc',\n });\n return result.items.map(sessionMetadataToTuiItem);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded listSessions failed: ${errorMessage}`);\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const config = loadConfig();\n const agents = new Map<string, TuiAgentInfo>();\n for (const entry of listAgentEntries(config)) {\n if (entry.enabled === false) continue;\n const id = normalizeAgentId(entry.id);\n agents.set(id, {\n id,\n enabled: true,\n });\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n await this.agent.sessionStore.updateMetadata(sessionKey, { name: name.trim() });\n return { ok: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded renameSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n const ok = await this.agent.sessionStore.deleteSession(sessionKey);\n return { ok };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded deleteSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n if (!this.agent) {\n const config = loadConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n try {\n const cfg = await this.agent.sessionInspector.agentConfig(sessionKey);\n const parsed = parseModelRef(cfg.model);\n const usage = await this.agent.sessionInspector.contextUsage(sessionKey);\n return {\n model: parsed?.model ?? cfg.model,\n modelProvider: parsed?.provider,\n thinkingLevel: cfg.thinkingLevel,\n reasoningLevel: cfg.reasoningLevel,\n verboseLevel: cfg.verboseLevel,\n totalTokens: usage.estimatedTokens,\n contextWindow: usage.contextWindow,\n contextUsagePercent: usage.usagePercent,\n effectiveWorkspacePath: cfg.effectiveWorkspacePath,\n workingDirectoryLocked: cfg.workingDirectoryLocked,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `getSessionInfo failed: ${errorMessage}`);\n const config = loadConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const models = await getAvailableModels();\n return models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n provider: model.provider,\n contextWindow: model.contextWindow,\n }));\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n if (!this.agent) return;\n await this.agent.resetSession(sessionKey);\n }\n\n async patchSession(\n sessionKey: string,\n patch: Record<string, unknown>,\n ): Promise<void> {\n if (!this.agent) return;\n const result = await this.agent.sessionConfig.patch(sessionKey, {\n model: typeof patch.model === 'string' ? patch.model : undefined,\n thinkingLevel: typeof patch.thinkingLevel === 'string' ? patch.thinkingLevel : undefined,\n reasoningLevel: typeof patch.reasoningLevel === 'string' ? patch.reasoningLevel : undefined,\n verboseLevel: typeof patch.verboseLevel === 'string' ? patch.verboseLevel : undefined,\n workingDirectory: typeof patch.workingDirectory === 'string' ? patch.workingDirectory : undefined,\n });\n if (!result.ok) {\n throw new Error(result.error);\n }\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n if (!this.agent) return { compacted: false, summary: 'Agent not started' };\n try {\n const result = await this.agent.sessionInspector.compact(sessionKey, {\n force: options?.force ?? true,\n instructions: options?.instructions,\n });\n if (!result.compacted) return { compacted: false, summary: 'Nothing to compact' };\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.exportSession(sessionKey, format);\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.importSessionExport(targetSessionKey, jsonContent);\n }\n\n async createShare(\n _sessionKey: string,\n request: TuiShareRequest,\n _options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const config = loadConfig();\n if (!isShareToolAvailable(config)) {\n throw new Error('Sharing is disabled in gateway config');\n }\n const workspace = getWorkspacePath(config);\n const tool = createCreateShareTool({\n workspace,\n getConfig: () => config,\n getAgentId: () => 'tui',\n });\n const result = await tool.execute(\n 'tui-share',\n {\n filePath: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n },\n );\n const details = (result.details ?? {}) as Record<string, unknown>;\n const error = typeof details.error === 'string' ? details.error : undefined;\n if (error) {\n throw new Error(error);\n }\n const shareUrl = typeof details.shareUrl === 'string' ? details.shareUrl : undefined;\n if (!shareUrl) {\n const text = result.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('\\n')\n .trim();\n throw new Error(text || 'Share failed');\n }\n return {\n kind: typeof details.kind === 'string' ? details.kind : 'share',\n shareUrl,\n title: typeof details.title === 'string' ? details.title : undefined,\n description: typeof details.description === 'string' ? details.description : undefined,\n thumbnailUrl: typeof details.thumbnailUrl === 'string' ? details.thumbnailUrl : undefined,\n reachability: typeof details.reachability === 'string' ? details.reachability : undefined,\n reachabilityHint:\n typeof details.reachabilityHint === 'string' ? details.reachabilityHint : undefined,\n expiresAt: typeof details.expiresAt === 'string' ? details.expiresAt : undefined,\n maxViews: typeof details.maxViews === 'number' ? details.maxViews : null,\n routingReason:\n typeof (details.routing as { reason?: unknown } | undefined)?.reason === 'string'\n ? ((details.routing as { reason: string }).reason)\n : undefined,\n routingHint:\n typeof (details.routing as { hint?: unknown } | undefined)?.hint === 'string'\n ? ((details.routing as { hint: string }).hint)\n : undefined,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n if (!this.agent) {\n return { text: '', error: 'Agent not started' };\n }\n return this.agent.sessionInspector.btwQuery(sessionKey, question);\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.forkSession(sourceSessionKey, targetSessionKey);\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n return this.agent.sessionStore.forkSessionRows(sourceSessionKey, targetSessionKey, { throughRow });\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptLabelEntry(sessionKey, { targetId: entryId, label });\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomEntry(sessionKey, { customType, data });\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomMessageEntry(sessionKey, message);\n evictEmbeddedSessionRunner(sessionKey, 'tui_custom_message_appended');\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptBashExecutionEntry(sessionKey, entry);\n evictEmbeddedSessionRunner(sessionKey, 'tui_bash_execution_appended');\n return { ok: true };\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAGgF;wBACE;aAMjB;gBAEH;aAST;AA0BrD,MAAM,MAAM,aAAa,eAAe;AAQxC,SAAS,mBAAmB,WAAmB,UAA2B;CACxE,MAAM,MAAM,SAAS,QAAQ,UAAU,EAAE,QAAQ,SAAS,CAAC;AAC3D,QAAO,QAAQ,MAAO,CAAC,CAAC,OAAO,CAAC,IAAI,WAAW,KAAK,IAAI,CAAC,WAAW,IAAI;;;;;;;;AAS1E,IAAa,kBAAb,MAAmD;CACjD;CACA,QAAqC;CACrC,SAAuD;CACvD,YAAoB;CACpB,eAA4C;CAC5C,oBAAkD;CAClD,qBAAwD;CACxD,UAAkB;CAClB,YAA4C;CAE5C;CACA;CACA;CAEA,YAAY,MAAgD;AAA/B,OAAA,OAAA;AAC3B,OAAK,MAAM,IAAI,YAAY;;CAG7B,IAAI,kBAA0B;AAC5B,SAAO;;CAGT,QAAc;AACZ,MAAI,KAAK,QAAS;AAClB,OAAK,UAAU;EAEf,MAAM,SAAS,YAAY;AAC3B,OAAK,SAAS;EACd,MAAM,YAAY,iBAAiB,OAAO;AAC1C,OAAK,YAAY;EACjB,MAAM,UAAU,wBAAwB,OAAO;AAC/C,oBAAkB;AAClB,OAAK,eAAe,IAAI,aAAa,EAAE,QAAQ,CAAC;AAChD,OAAK,oBAAoB,KAAK,aAAa,YAAY,CAAC,OAAO,QAAiB;GAC9E,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AACrE,OAAI,KAAK;IAAE;IAAK;IAAc,EAAE,iDAAiD,eAAe;AAChG,SAAM;IACN;AAEF,OAAK,QAAQ,IAAI,aAAa,KAAK,KAAK;GACtC;GACA,OAAO;GACP;GACA,cAAc,KAAK,aAAa,UAAU;GAC1C,6BAA6B,KAAK,uBAAuB;GACzD,mBAAmB,KAAK,MAAM;GAC9B,qBAAqB,iBAAiB;IACpC,MAAM,WAAW,KAAK,MAAM,qBAAqB,aAAa;AAC9D,QAAI,aAAa,KAAA,KAAa,aAAa,KACzC,QAAO;IAET,MAAM,WAAW,KAAK,MAAM;AAC5B,QAAI,YAAY,mBAAmB,UAAU,aAAa,CACxD,QAAO;;GAIZ,CAAC;AAEF,OAAK,MAAM,OAAO,CAAC,WAAW;AAC5B,QAAK,eAAe;IACpB,CAAC,OAAO,QAAQ;GAChB,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AACrE,OAAI,MAAM;IAAE;IAAK;IAAc,EAAE,0BAA0B,eAAe;AAC1E,QAAK,iBAAiB,aAAa;IACnC;AAGF,OAAK,iBAAiB;;CAGxB,OAAa;AACX,OAAK,UAAU;AACf,OAAK,WAAW,OAAO;AACvB,OAAK,YAAY;AACjB,OAAK,IAAI,UAAU;AACd,OAAK,OAAO,MAAM;AACvB,OAAK,QAAQ;;CAGf,kBAA2C;EACzC,MAAM,SAAS,KAAK,WAAW;AAC/B,SAAO,UAAU,CAAC,OAAO,UAAU,SAAS,KAAA;;CAG9C,wBAAoD;AAClD,MAAI,KAAK,mBAAoB,QAAO,KAAK;AACzC,MAAI,CAAC,KAAK,UAAU,CAAC,KAAK,gBAAgB,CAAC,KAAK,MAC9C,OAAM,IAAI,MAAM,0CAA0C;EAG5D,MAAM,OAA4B;GAChC,eAAe,KAAK;GACpB,sBAAsB,KAAK;GAC3B,oBAAoB,KAAK;GACzB,cAAc,EACZ,qBAAqB,eAAe,KAAK,MAAO,mBAAmB,WAAW,EAC/E;GACD,sBAAsB,KAAK;GAC3B,OAAO,OAAO,YAAY;AACxB,SAAK,UAAU;KACb;KACA,MAAM;KACN,QAAQ;KACT,CAAC;;GAEL;AAED,OAAK,qBAAqB,IAAI,mBAAmB;GAC/C,SAAS;GACT,eAAe,IAAI,sBAAsB,KAAK;GAC9C,iBAAiB;GAClB,CAAC;AACF,SAAO,KAAK;;CAGd,MAAM,oBAAoB,YAAoB;AAC5C,SAAO,2BAA2B,YAAY,EAAE,WAAW;;CAG7D,MAAM,iBAAiB,MAAsE;AAC3F,QAAM,KAAK;EACX,MAAM,UAAU,KAAK,SAAS,MAAM,IAAI,6BAA6B,KAAK,WAAW;EACrF,MAAM,SAAS,MAAM,KAAK,uBAAuB,CAAC,iBAAiB;GACjE;GACA,cAAc,KAAK;GACnB,kBAAkB,KAAK;GACvB,QAAQ;IAAE,MAAM;IAAQ,YAAY,KAAK;IAAY;GACrD,MAAM,KAAK;GACX,OAAO,KAAK;GACb,CAAC;AACF,MAAI,OAAO,OAAO,MAChB,OAAM,IAAI,MAAM,OAAO,QAAQ;AAEjC,SAAO;GACL,OAAO,OAAO;GACd,YAAY,OAAO;GACnB,cAAc,KAAK;GACpB;;CAGH,MAAM,qBACJ,YACA,OACA,SACwC;AACxC,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE;AAC1B,MAAI;AAEF,UAAO,MAAM,0BAA0B,MADX,KAAK,MAAM,oCAAoC,WAAW,EAChC,OAAO,SAAS,SAAS,GAAG;WAC3E,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAY;IAAc,EAAE,0CAA0C,eAAe;AAC5G,UAAO,EAAE;;;CAIb,MAAM,SAAS,MAAmD;AAChE,MAAI,CAAC,KAAK,MAAO,OAAM,IAAI,MAAM,oBAAoB;EAErD,MAAM,QAAQ,OAAO,YAAY;AACjC,OAAK,WAAW,OAAO;AACvB,OAAK,YAAY,IAAI,iBAAiB;EACtC,MAAM,SAAS,KAAK,UAAU;EAE9B,MAAM,SAAS,IAAI,iBAAiB;GAAE;GAAO,YAAY,KAAK;GAAY,SAAS;GAAO,CAAC;AAC3F,OAAK,MAAM,SAAS,OAAO,OAAO,CAChC,MAAK,UAAU;GAAE,OAAO,MAAM;GAAM,MAAM;GAAO,QAAQ;GAAY,CAAC;AAIxE,GAAM,YAAY;AAChB,OAAI;IAIF,MAAM,kBAAkB,KAAK,QAAQ,WAAW,CAAC,WAAW,IAAI,GAC5D,KAAK,UACL,yBAAyB,KAAK,QAAQ;IAE1C,MAAM,SAAS,KAAK,MAAO,eAAe,uBACxC,iBACA,KAAK,YACL,KAAK,aACL,KAAK,UACL;KAAE;KAAQ;KAAO,CAClB;AAED,eAAW,MAAM,SAAS,QAAQ;AAChC,SAAI,OAAO,QAAS;AACpB,UAAK,MAAM,UAAU,OAAO,IAAI,MAAM,CACpC,MAAK,UAAU;MAAE,OAAO,OAAO;MAAM,MAAM;MAAQ,QAAQ;MAAY,CAAC;;AAI5E,QAAI,CAAC,OAAO,QACV,MAAK,MAAM,UAAU,OAAO,IAAI,UAAU,CACxC,MAAK,UAAU;KAAE,OAAO,OAAO;KAAM,MAAM;KAAQ,QAAQ;KAAY,CAAC;YAGrE,OAAO;AACd,QAAI,OAAO,QAAS;IACpB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,SAAK,MAAM,UAAU,OAAO,MAAM,aAAa,CAC7C,MAAK,UAAU;KAAE,OAAO,OAAO;KAAM,MAAM;KAAQ,QAAQ;KAAY,CAAC;AAE1E,SAAK,MAAM,UAAU,OAAO,IAAI,SAAS,aAAa,CACpD,MAAK,UAAU;KAAE,OAAO,OAAO;KAAM,MAAM;KAAQ,QAAQ;KAAY,CAAC;;MAG1E;AAEJ,SAAO,EAAE,OAAO;;CAGlB,MAAM,UAAU,OAAwE;AACtF,MAAI,KAAK,WAAW;AAClB,QAAK,UAAU,OAAO;AACtB,QAAK,YAAY;AACjB,UAAO,EAAE,IAAI,MAAM;;AAErB,SAAO,EAAE,IAAI,OAAO;;CAGtB,MAAM,UAAU,MAAyE;AACvF,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE,IAAI,OAAO;AAErC,SAAO,EAAE,IAAA,MADQ,KAAK,MAAM,eAAe,oBAAoB,KAAK,YAAY,KAAK,QAAQ,EAChF;;CAGf,MAAM,YAAY,MAG0B;AAC1C,MAAI,CAAC,KAAK,MACR,QAAO,EAAE,UAAU,EAAE,EAAE;AAEzB,MAAI;AAEF,UAAO,EACL,UAAU,8BAA8B,MAFvB,KAAK,MAAM,aAAa,mBAAmB,KAAK,WAAW,EAE9B,EAAE,OAAO,KAAK,OAAO,CAAC,EACrE;WACM,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAc,EAAE,gCAAgC,eAAe;AACtF,UAAO,EAAE,UAAU,EAAE,EAAE;;;CAI3B,MAAM,mBAAmB,YAAuD;AAC9E,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE;AAC1B,MAAI;AAEF,UAAO,uBAAuB,MADX,KAAK,MAAM,aAAa,mBAAmB,WAAW,CACtC;WAC5B,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAY;IAAc,EAAE,uCAAuC,eAAe;AACzG,UAAO,EAAE;;;CAIb,MAAM,gBAAgB,YAA8C;AAClE,MAAI,CAAC,KAAK,MAAO,QAAO,uBAAuB,EAAE,CAAC;AAClD,MAAI;AAEF,UAAO,uBAAuB,MADX,KAAK,MAAM,aAAa,mBAAmB,WAAW,CACtC;WAC5B,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAY;IAAc,EAAE,oCAAoC,eAAe;AACtG,UAAO,uBAAuB,EAAE,CAAC;;;CAIrC,MAAM,eAA0C;AAC9C,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE;AAC1B,MAAI;AAMF,WAAO,MALc,KAAK,MAAM,aAAa,KAAK;IAChD,OAAO;IACP,QAAQ;IACR,WAAW;IACZ,CAAC,EACY,MAAM,IAAI,yBAAyB;WAC1C,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAc,EAAE,iCAAiC,eAAe;AACvF,UAAO,EAAE;;;CAIb,MAAM,aAAsC;EAC1C,MAAM,SAAS,YAAY;EAC3B,MAAM,yBAAS,IAAI,KAA2B;AAC9C,OAAK,MAAM,SAAS,iBAAiB,OAAO,EAAE;AAC5C,OAAI,MAAM,YAAY,MAAO;GAC7B,MAAM,KAAK,iBAAiB,MAAM,GAAG;AACrC,UAAO,IAAI,IAAI;IACb;IACA,SAAS;IACV,CAAC;;AAEJ,SAAO,CAAC,GAAG,OAAO,QAAQ,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,CAAC;;CAGtE,MAAM,cAAc,YAAoB,MAAwC;AAC9E,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE,IAAI,OAAO;AACrC,MAAI;AACF,SAAM,KAAK,MAAM,aAAa,eAAe,YAAY,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;AAC/E,UAAO,EAAE,IAAI,MAAM;WACZ,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAY;IAAc,EAAE,kCAAkC,eAAe;AACpG,UAAO,EAAE,IAAI,OAAO;;;CAIxB,MAAM,cAAc,YAA8C;AAChE,MAAI,CAAC,KAAK,MAAO,QAAO,EAAE,IAAI,OAAO;AACrC,MAAI;AAEF,UAAO,EAAE,IAAA,MADQ,KAAK,MAAM,aAAa,cAAc,WAAW,EACrD;WACN,OAAO;GACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,OAAI,KAAK;IAAE,KAAK;IAAO;IAAY;IAAc,EAAE,kCAAkC,eAAe;AACpG,UAAO,EAAE,IAAI,OAAO;;;CAIxB,MAAM,eAAe,YAA0C;AAC7D,MAAI,CAAC,KAAK,MAGR,QAAO,EAAE,OADK,wBADC,YAC6B,CACvB,IAAI,KAAA,GAAW;AAEtC,MAAI;GACF,MAAM,MAAM,MAAM,KAAK,MAAM,iBAAiB,YAAY,WAAW;GACrE,MAAM,SAAS,cAAc,IAAI,MAAM;GACvC,MAAM,QAAQ,MAAM,KAAK,MAAM,iBAAiB,aAAa,WAAW;AACxE,UAAO;IACL,OAAO,QAAQ,SAAS,IAAI;IAC5B,eAAe,QAAQ;IACvB,eAAe,IAAI;IACnB,gBAAgB,IAAI;IACpB,cAAc,IAAI;IAClB,aAAa,MAAM;IACnB,eAAe,MAAM;IACrB,qBAAqB,MAAM;IAC3B,wBAAwB,IAAI;IAC5B,wBAAwB,IAAI;IAC7B;WACM,KAAK;GACZ,MAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AACrE,OAAI,KAAK;IAAE;IAAK;IAAY;IAAc,EAAE,0BAA0B,eAAe;AAGrF,UAAO,EAAE,OADK,wBADC,YAC6B,CACvB,IAAI,KAAA,GAAW;;;CAIxC,MAAM,aAAwC;AAE5C,UAAO,MADc,oBAAoB,EAC3B,KAAK,WAAW;GAC5B,IAAI,MAAM;GACV,MAAM,MAAM,QAAQ,MAAM;GAC1B,UAAU,MAAM;GAChB,eAAe,MAAM;GACtB,EAAE;;CAGL,MAAM,aAAa,YAAmC;AACpD,MAAI,CAAC,KAAK,MAAO;AACjB,QAAM,KAAK,MAAM,aAAa,WAAW;;CAG3C,MAAM,aACJ,YACA,OACe;AACf,MAAI,CAAC,KAAK,MAAO;EACjB,MAAM,SAAS,MAAM,KAAK,MAAM,cAAc,MAAM,YAAY;GAC9D,OAAO,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,KAAA;GACvD,eAAe,OAAO,MAAM,kBAAkB,WAAW,MAAM,gBAAgB,KAAA;GAC/E,gBAAgB,OAAO,MAAM,mBAAmB,WAAW,MAAM,iBAAiB,KAAA;GAClF,cAAc,OAAO,MAAM,iBAAiB,WAAW,MAAM,eAAe,KAAA;GAC5E,kBAAkB,OAAO,MAAM,qBAAqB,WAAW,MAAM,mBAAmB,KAAA;GACzF,CAAC;AACF,MAAI,CAAC,OAAO,GACV,OAAM,IAAI,MAAM,OAAO,MAAM;;CAIjC,MAAM,eACJ,YACA,SAC8B;AAC9B,MAAI,CAAC,KAAK,MAAO,QAAO;GAAE,WAAW;GAAO,SAAS;GAAqB;AAC1E,MAAI;GACF,MAAM,SAAS,MAAM,KAAK,MAAM,iBAAiB,QAAQ,YAAY;IACnE,OAAO,SAAS,SAAS;IACzB,cAAc,SAAS;IACxB,CAAC;AACF,OAAI,CAAC,OAAO,UAAW,QAAO;IAAE,WAAW;IAAO,SAAS;IAAsB;AACjF,UAAO;IACL,WAAW;IACX,SAAS,cAAc,OAAO,gBAAgB,IAAI,KAAK,OAAO,eAAe,IAAI;IACjF,cAAc,OAAO;IACrB,aAAa,OAAO;IACpB,mBAAmB,OAAO;IAC3B;WACM,KAAK;AAEZ,UAAO;IAAE,WAAW;IAAO,SADN,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;IACnB;;;CAItD,MAAM,cAAc,YAAoB,QAAuC;AAC7E,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,SAAO,KAAK,MAAM,aAAa,cAAc,YAAY,OAAO;;CAGlE,MAAM,cACJ,kBACA,aACmD;AACnD,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,SAAO,KAAK,MAAM,aAAa,oBAAoB,kBAAkB,YAAY;;CAGnF,MAAM,YACJ,aACA,SACA,UACyB;AACzB,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;EAEtC,MAAM,SAAS,YAAY;AAC3B,MAAI,CAAC,qBAAqB,OAAO,CAC/B,OAAM,IAAI,MAAM,wCAAwC;EAQ1D,MAAM,SAAS,MALF,sBAAsB;GACjC,WAFgB,iBAAiB,OAExB;GACT,iBAAiB;GACjB,kBAAkB;GACnB,CACwB,CAAC,QACxB,aACA;GACE,UAAU,QAAQ;GAClB,UAAU,QAAQ;GAClB,MAAM,QAAQ;GACd,OAAO,QAAQ;GACf,aAAa,QAAQ;GACtB,CACF;EACD,MAAM,UAAW,OAAO,WAAW,EAAE;EACrC,MAAM,QAAQ,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,KAAA;AAClE,MAAI,MACF,OAAM,IAAI,MAAM,MAAM;EAExB,MAAM,WAAW,OAAO,QAAQ,aAAa,WAAW,QAAQ,WAAW,KAAA;AAC3E,MAAI,CAAC,UAAU;GACb,MAAM,OAAO,OAAO,QACjB,KAAK,SAAU,KAAK,SAAS,SAAS,KAAK,OAAO,GAAI,CACtD,KAAK,KAAK,CACV,MAAM;AACT,SAAM,IAAI,MAAM,QAAQ,eAAe;;AAEzC,SAAO;GACL,MAAM,OAAO,QAAQ,SAAS,WAAW,QAAQ,OAAO;GACxD;GACA,OAAO,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ,KAAA;GAC3D,aAAa,OAAO,QAAQ,gBAAgB,WAAW,QAAQ,cAAc,KAAA;GAC7E,cAAc,OAAO,QAAQ,iBAAiB,WAAW,QAAQ,eAAe,KAAA;GAChF,cAAc,OAAO,QAAQ,iBAAiB,WAAW,QAAQ,eAAe,KAAA;GAChF,kBACE,OAAO,QAAQ,qBAAqB,WAAW,QAAQ,mBAAmB,KAAA;GAC5E,WAAW,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY,KAAA;GACvE,UAAU,OAAO,QAAQ,aAAa,WAAW,QAAQ,WAAW;GACpE,eACE,OAAQ,QAAQ,SAA8C,WAAW,WACnE,QAAQ,QAA+B,SACzC,KAAA;GACN,aACE,OAAQ,QAAQ,SAA4C,SAAS,WAC/D,QAAQ,QAA6B,OACvC,KAAA;GACP;;CAGH,MAAM,SAAS,YAAoB,UAA6D;AAC9F,MAAI,CAAC,KAAK,MACR,QAAO;GAAE,MAAM;GAAI,OAAO;GAAqB;AAEjD,SAAO,KAAK,MAAM,iBAAiB,SAAS,YAAY,SAAS;;CAGnE,MAAM,YACJ,kBACA,kBACmD;AACnD,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,SAAO,KAAK,MAAM,aAAa,YAAY,kBAAkB,iBAAiB;;CAGhF,MAAM,cACJ,kBACA,kBACA,SACmD;AACnD,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;EAEtC,MAAM,aAAa,iCAAiC,QAAQ;AAC5D,MAAI,cAAc,KAChB,OAAM,IAAI,MAAM,6BAA6B,UAAU;AAEzD,SAAO,KAAK,MAAM,aAAa,gBAAgB,kBAAkB,kBAAkB,EAAE,YAAY,CAAC;;CAGpG,MAAM,mBACJ,YACA,SACA,OAC0B;AAC1B,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,QAAM,KAAK,MAAM,aAAa,2BAA2B,YAAY;GAAE,UAAU;GAAS;GAAO,CAAC;AAClG,SAAO,EAAE,IAAI,MAAM;;CAGrB,MAAM,kBACJ,YACA,YACA,MAC0B;AAC1B,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,QAAM,KAAK,MAAM,aAAa,4BAA4B,YAAY;GAAE;GAAY;GAAM,CAAC;AAC3F,SAAO,EAAE,IAAI,MAAM;;CAGrB,MAAM,oBACJ,YACA,SAM0B;AAC1B,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,QAAM,KAAK,MAAM,aAAa,mCAAmC,YAAY,QAAQ;AACrF,6BAA2B,YAAY,8BAA8B;AACrE,SAAO,EAAE,IAAI,MAAM;;CAGrB,MAAM,oBACJ,YACA,OAS0B;AAC1B,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,oBAAoB;AAEtC,QAAM,KAAK,MAAM,aAAa,mCAAmC,YAAY,MAAM;AACnF,6BAA2B,YAAY,8BAA8B;AACrE,SAAO,EAAE,IAAI,MAAM;;CAGrB,kBAAgC;AAC9B,GAAM,YAAY;AAChB,UAAO,KAAK,QACV,KAAI;IACF,MAAM,MAAM,MAAM,KAAK,IAAI,iBAAiB;AAC5C,QAAI,MAAM;KAAE,SAAS,IAAI;KAAS,QAAQ,IAAI;KAAS,EAAE,mBAAmB;YACrE,OAAO;AACd,QAAI,iBAAiB,wBAAyB;IAC9C,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,QAAI,KAAK;KAAE,KAAK;KAAO;KAAc,EAAE,8BAA8B,eAAe;AACpF,UAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAK,CAAC;;MAG3D"}
1
+ {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import type { ExtensionRegistryImpl } from '../../extensions/loader.js';\nimport { isAbsolute, relative, resolve } from 'node:path';\nimport type { AgentService } from '../../agent/service.js';\nimport { listAgentEntries, normalizeAgentId } from '../../agent/agent-scope.js';\nimport { resolveAgentIdFromSessionKey } from '../../routing/agent-session-key.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport { createCreateShareTool, isShareToolAvailable } from '../../agent/tools/create-share-tool.js';\nimport { transcriptRowsToClientHistory } from '../../session/client-history.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { getAgentDefaultModelRef } from '../../config/schema.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { evictEmbeddedSessionRunner } from '../../agent/embedded/session-runner.js';\nimport type { ExportFormat } from '../../session/types.js';\nimport { SessionIndex } from '../../session/index.js';\nimport { openXopcDatabase } from '../../storage/sqlite/index.js';\nimport { buildWorkflowChildTools } from '../../agent/workflow/workflow-child-tools.js';\nimport type { GatewayWorkflowHost } from '../../gateway/gateway-workflow-host.types.js';\nimport { WorkflowRunService } from '../../workflows/service/workflow-run-service.js';\nimport { WorkflowSessionBridge } from '../../workflows/service/workflow-session-bridge.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiCompactionResult,\n TuiEvent,\n TuiModelChoice,\n TuiShareRequest,\n TuiShareResult,\n TuiSessionStats,\n TuiSessionItem,\n TuiTranscriptTreeEntry,\n TuiAgentInfo,\n TuiWorkspaceFileSearchEntry,\n TuiWorkflowRunStartRequest,\n TuiWorkflowRunStartResult,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\nimport { sessionMetadataToTuiItem } from '../tui-session-format.js';\nimport { computeTuiSessionStats } from '../tui-session-stats.js';\nimport { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from '../tui-transcript-tree.js';\nimport { ChatStreamMapper } from '../../gateway/chat-stream/mapper.js';\nimport { collectTuiStartupResources } from '../tui-startup-resources.js';\nimport { fuzzySearchWorkspaceFiles } from '../../gateway/workspace-file-search.js';\n\nconst log = createLogger('TUI:Embedded');\n\ninterface EmbeddedBackendOptions {\n extensionRegistry?: ExtensionRegistryImpl;\n implicitTrustedWorkspace?: string;\n isWorkspaceTrusted?: (workspaceDir: string) => boolean | null | undefined;\n}\n\nfunction isPathSameOrInside(parentDir: string, childDir: string): boolean {\n const rel = relative(resolve(parentDir), resolve(childDir));\n return rel === '' || (!!rel && !rel.startsWith('..') && !isAbsolute(rel));\n}\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private agentLoading: Promise<AgentService> | null = null;\n private config: ReturnType<typeof loadConfig> | null = null;\n private workspace = '';\n private sessionIndex: SessionIndex | null = null;\n private sessionIndexReady: Promise<void> | null = null;\n private workflowRunService: WorkflowRunService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor(private readonly opts?: EmbeddedBackendOptions) {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = loadConfig();\n this.config = config;\n const workspace = getWorkspacePath(config);\n this.workspace = workspace;\n openXopcDatabase();\n this.sessionIndex = new SessionIndex({ config });\n this.sessionIndexReady = this.sessionIndex.initialize().catch((err: unknown) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, errorMessage }, `Embedded session index initialization failed: ${errorMessage}`);\n throw err;\n });\n\n this.onConnected?.();\n setTimeout(() => {\n void this.ensureAgent().catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n }, 750);\n\n // Process outbound messages in background\n this.processOutbound();\n }\n\n private async ensureAgent(): Promise<AgentService> {\n if (this.agent) {\n return this.agent;\n }\n if (this.agentLoading) {\n return this.agentLoading;\n }\n if (!this.config || !this.sessionIndex) {\n throw new Error('Embedded backend not started');\n }\n\n this.agentLoading = this.createAgent(this.config, this.sessionIndex);\n try {\n return await this.agentLoading;\n } finally {\n this.agentLoading = null;\n }\n }\n\n private async createAgent(config: ReturnType<typeof loadConfig>, sessionIndex: SessionIndex): Promise<AgentService> {\n const { AgentService } = await import('../../agent/service.js');\n const workspace = this.workspace || getWorkspacePath(config);\n const modelId = getAgentDefaultModelRef(config);\n const agent = new AgentService(this.bus, {\n workspace,\n model: modelId,\n config,\n sessionStore: sessionIndex.getStore(),\n getWorkflowRunService: () => this.getWorkflowRunService(),\n extensionRegistry: this.opts?.extensionRegistry,\n isWorkspaceTrusted: (workspaceDir) => {\n const explicit = this.opts?.isWorkspaceTrusted?.(workspaceDir);\n if (explicit !== undefined && explicit !== null) {\n return explicit;\n }\n const implicit = this.opts?.implicitTrustedWorkspace;\n if (implicit && isPathSameOrInside(implicit, workspaceDir)) {\n return true;\n }\n return undefined;\n },\n });\n this.agent = agent;\n await agent.start();\n return agent;\n }\n\n stop(): void {\n this.running = false;\n this.chatAbort?.abort();\n this.chatAbort = null;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n getActiveSignal(): AbortSignal | undefined {\n const signal = this.chatAbort?.signal;\n return signal && !signal.aborted ? signal : undefined;\n }\n\n private getWorkflowRunService(): WorkflowRunService {\n if (this.workflowRunService) return this.workflowRunService;\n if (!this.config || !this.sessionIndex || !this.agent) {\n throw new Error('Embedded workflow runtime is not ready.');\n }\n\n const host: GatewayWorkflowHost = {\n currentConfig: this.config,\n currentWorkspacePath: this.workspace,\n messageBusInstance: this.bus,\n agentService: {\n getModelForSession: (sessionKey) => this.agent!.getModelForSession(sessionKey),\n },\n sessionIndexInstance: this.sessionIndex,\n emit: (event, payload) => {\n this.onEvent?.({\n event,\n data: payload,\n source: 'broadcast',\n });\n },\n };\n\n this.workflowRunService = new WorkflowRunService({\n service: host,\n sessionBridge: new WorkflowSessionBridge(host),\n buildChildTools: buildWorkflowChildTools,\n });\n return this.workflowRunService;\n }\n\n async getStartupResources(sessionKey: string) {\n return collectTuiStartupResources(loadConfig(), sessionKey);\n }\n\n async startWorkflowRun(opts: TuiWorkflowRunStartRequest): Promise<TuiWorkflowRunStartResult> {\n await this.sessionIndexReady;\n const agentId = opts.agentId?.trim() || resolveAgentIdFromSessionKey(opts.sessionKey);\n const result = await this.getWorkflowRunService().startWorkflowRun({\n agentId,\n definitionId: opts.definitionId,\n parentSessionKey: opts.sessionKey,\n source: { kind: 'chat', sessionKey: opts.sessionKey },\n goal: opts.goal,\n input: opts.input,\n });\n if (result.ok === false) {\n throw new Error(result.message);\n }\n return {\n runId: result.runId,\n sessionKey: result.sessionKey,\n definitionId: opts.definitionId,\n };\n }\n\n async searchWorkspaceFiles(\n sessionKey: string,\n query: string,\n options?: { limit?: number },\n ): Promise<TuiWorkspaceFileSearchEntry[]> {\n if (!this.agent) return [];\n try {\n const workspaceRoot = await this.agent.getEffectiveWorkspacePathForSession(sessionKey);\n return await fuzzySearchWorkspaceFiles(workspaceRoot, query, options?.limit ?? 15);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded workspace file search failed: ${errorMessage}`);\n return [];\n }\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n const agent = await this.ensureAgent();\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n const mapper = new ChatStreamMapper({ runId, sessionKey: opts.sessionKey, channel: 'tui' });\n for (const event of mapper.start()) {\n this.onEvent?.({ event: event.type, data: event, source: 'embedded' });\n }\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = agent.turnDispatcher.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n opts.attachments,\n opts.thinking,\n { signal, runId },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n for (const mapped of mapper.map(event)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n\n if (!signal.aborted) {\n for (const mapped of mapper.end('success')) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n for (const mapped of mapper.error(errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n for (const mapped of mapper.end('error', errorMessage)) {\n this.onEvent?.({ event: mapped.type, data: mapped, source: 'embedded' });\n }\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async steerChat(opts: { sessionKey: string; message: string }): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n const ok = await this.agent.turnDispatcher.steerWebchatSession(opts.sessionKey, opts.message);\n return { ok };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(opts.sessionKey);\n return {\n messages: transcriptRowsToClientHistory(rows, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async loadTranscriptTree(sessionKey: string): Promise<TuiTranscriptTreeEntry[]> {\n if (!this.agent) return [];\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return buildTuiTranscriptTree(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded loadTranscriptTree failed: ${errorMessage}`);\n return [];\n }\n }\n\n async getSessionStats(sessionKey: string): Promise<TuiSessionStats> {\n if (!this.agent) return computeTuiSessionStats([]);\n try {\n const rows = await this.agent.sessionStore.loadTranscriptRows(sessionKey);\n return computeTuiSessionStats(rows);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded getSessionStats failed: ${errorMessage}`);\n return computeTuiSessionStats([]);\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n if (!this.agent) return [];\n try {\n const result = await this.agent.sessionStore.list({\n limit: 200,\n sortBy: 'updatedAt',\n sortOrder: 'desc',\n });\n return result.items.map(sessionMetadataToTuiItem);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded listSessions failed: ${errorMessage}`);\n return [];\n }\n }\n\n async listAgents(): Promise<TuiAgentInfo[]> {\n const config = loadConfig();\n const agents = new Map<string, TuiAgentInfo>();\n for (const entry of listAgentEntries(config)) {\n if (entry.enabled === false) continue;\n const id = normalizeAgentId(entry.id);\n agents.set(id, {\n id,\n enabled: true,\n });\n }\n return [...agents.values()].sort((a, b) => a.id.localeCompare(b.id));\n }\n\n async renameSession(sessionKey: string, name: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n await this.agent.sessionStore.updateMetadata(sessionKey, { name: name.trim() });\n return { ok: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded renameSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async deleteSession(sessionKey: string): Promise<{ ok: boolean }> {\n if (!this.agent) return { ok: false };\n try {\n const ok = await this.agent.sessionStore.deleteSession(sessionKey);\n return { ok };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, sessionKey, errorMessage }, `Embedded deleteSession failed: ${errorMessage}`);\n return { ok: false };\n }\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n if (!this.agent) {\n const config = loadConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n try {\n const cfg = await this.agent.sessionInspector.agentConfig(sessionKey);\n const parsed = parseModelRef(cfg.model);\n const usage = await this.agent.sessionInspector.contextUsage(sessionKey);\n return {\n model: parsed?.model ?? cfg.model,\n modelProvider: parsed?.provider,\n thinkingLevel: cfg.thinkingLevel,\n reasoningLevel: cfg.reasoningLevel,\n verboseLevel: cfg.verboseLevel,\n totalTokens: usage.estimatedTokens,\n contextWindow: usage.contextWindow,\n contextUsagePercent: usage.usagePercent,\n effectiveWorkspacePath: cfg.effectiveWorkspacePath,\n workingDirectoryLocked: cfg.workingDirectoryLocked,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `getSessionInfo failed: ${errorMessage}`);\n const config = loadConfig();\n const model = getAgentDefaultModelRef(config);\n return { model: model ?? undefined };\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const { getAvailableModels } = await import('../../providers/index.js');\n const models = await getAvailableModels();\n return models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n provider: model.provider,\n contextWindow: model.contextWindow,\n }));\n }\n\n async resetSession(sessionKey: string): Promise<void> {\n if (!this.agent) return;\n await this.agent.resetSession(sessionKey);\n }\n\n async patchSession(\n sessionKey: string,\n patch: Record<string, unknown>,\n ): Promise<void> {\n if (!this.agent) return;\n const result = await this.agent.sessionConfig.patch(sessionKey, {\n model: typeof patch.model === 'string' ? patch.model : undefined,\n thinkingLevel: typeof patch.thinkingLevel === 'string' ? patch.thinkingLevel : undefined,\n reasoningLevel: typeof patch.reasoningLevel === 'string' ? patch.reasoningLevel : undefined,\n verboseLevel: typeof patch.verboseLevel === 'string' ? patch.verboseLevel : undefined,\n workingDirectory: typeof patch.workingDirectory === 'string' ? patch.workingDirectory : undefined,\n });\n if (!result.ok) {\n throw new Error(result.error);\n }\n }\n\n async compactSession(\n sessionKey: string,\n options?: { force?: boolean; instructions?: string },\n ): Promise<TuiCompactionResult> {\n if (!this.agent) return { compacted: false, summary: 'Agent not started' };\n try {\n const result = await this.agent.sessionInspector.compact(sessionKey, {\n force: options?.force ?? true,\n instructions: options?.instructions,\n });\n if (!result.compacted) return { compacted: false, summary: 'Nothing to compact' };\n return {\n compacted: true,\n summary: `Compacted (${result.tokensBefore ?? '?'} → ${result.tokensAfter ?? '?'} tokens)`,\n tokensBefore: result.tokensBefore,\n tokensAfter: result.tokensAfter,\n transcriptSummary: result.summary,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n return { compacted: false, summary: errorMessage };\n }\n }\n\n async exportSession(sessionKey: string, format: ExportFormat): Promise<string> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.exportSession(sessionKey, format);\n }\n\n async importSession(\n targetSessionKey: string,\n jsonContent: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.importSessionExport(targetSessionKey, jsonContent);\n }\n\n async createShare(\n _sessionKey: string,\n request: TuiShareRequest,\n _options?: { agentId?: string },\n ): Promise<TuiShareResult> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const config = loadConfig();\n if (!isShareToolAvailable(config)) {\n throw new Error('Sharing is disabled in gateway config');\n }\n const workspace = getWorkspacePath(config);\n const tool = createCreateShareTool({\n workspace,\n getConfig: () => config,\n getAgentId: () => 'tui',\n });\n const result = await tool.execute(\n 'tui-share',\n {\n filePath: request.path,\n audience: request.audience,\n mode: request.mode,\n title: request.title,\n description: request.description,\n },\n );\n const details = (result.details ?? {}) as Record<string, unknown>;\n const error = typeof details.error === 'string' ? details.error : undefined;\n if (error) {\n throw new Error(error);\n }\n const shareUrl = typeof details.shareUrl === 'string' ? details.shareUrl : undefined;\n if (!shareUrl) {\n const text = result.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('\\n')\n .trim();\n throw new Error(text || 'Share failed');\n }\n return {\n kind: typeof details.kind === 'string' ? details.kind : 'share',\n shareUrl,\n title: typeof details.title === 'string' ? details.title : undefined,\n description: typeof details.description === 'string' ? details.description : undefined,\n thumbnailUrl: typeof details.thumbnailUrl === 'string' ? details.thumbnailUrl : undefined,\n reachability: typeof details.reachability === 'string' ? details.reachability : undefined,\n reachabilityHint:\n typeof details.reachabilityHint === 'string' ? details.reachabilityHint : undefined,\n expiresAt: typeof details.expiresAt === 'string' ? details.expiresAt : undefined,\n maxViews: typeof details.maxViews === 'number' ? details.maxViews : null,\n routingReason:\n typeof (details.routing as { reason?: unknown } | undefined)?.reason === 'string'\n ? ((details.routing as { reason: string }).reason)\n : undefined,\n routingHint:\n typeof (details.routing as { hint?: unknown } | undefined)?.hint === 'string'\n ? ((details.routing as { hint: string }).hint)\n : undefined,\n };\n }\n\n async btwQuery(sessionKey: string, question: string): Promise<{ text: string; error?: string }> {\n if (!this.agent) {\n return { text: '', error: 'Agent not started' };\n }\n return this.agent.sessionInspector.btwQuery(sessionKey, question);\n }\n\n async forkSession(\n sourceSessionKey: string,\n targetSessionKey: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n return this.agent.sessionStore.forkSession(sourceSessionKey, targetSessionKey);\n }\n\n async forkSessionAt(\n sourceSessionKey: string,\n targetSessionKey: string,\n entryId: string,\n ): Promise<{ sessionKey: string; rowCount: number }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n const throughRow = transcriptTreeEntryIdToRowNumber(entryId);\n if (throughRow == null) {\n throw new Error(`Invalid transcript entry: ${entryId}`);\n }\n return this.agent.sessionStore.forkSessionRows(sourceSessionKey, targetSessionKey, { throughRow });\n }\n\n async setTranscriptLabel(\n sessionKey: string,\n entryId: string,\n label: string | undefined,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptLabelEntry(sessionKey, { targetId: entryId, label });\n return { ok: true };\n }\n\n async appendCustomEntry(\n sessionKey: string,\n customType: string,\n data?: unknown,\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomEntry(sessionKey, { customType, data });\n return { ok: true };\n }\n\n async appendCustomMessage(\n sessionKey: string,\n message: {\n customType: string;\n content?: string | unknown[];\n display?: boolean;\n details?: unknown;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptCustomMessageEntry(sessionKey, message);\n evictEmbeddedSessionRunner(sessionKey, 'tui_custom_message_appended');\n return { ok: true };\n }\n\n async appendBashExecution(\n sessionKey: string,\n entry: {\n command: string;\n output?: string;\n exitCode?: number | null;\n signal?: string | null;\n excludeFromContext?: boolean;\n truncated?: boolean;\n fullOutputPath?: string;\n },\n ): Promise<{ ok: boolean }> {\n if (!this.agent) {\n throw new Error('Agent not started');\n }\n await this.agent.sessionStore.appendTranscriptBashExecutionEntry(sessionKey, entry);\n evictEmbeddedSessionRunner(sessionKey, 'tui_bash_execution_appended');\n return { ok: true };\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":"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"}
@@ -5,6 +5,7 @@ interface GatewaySSEOptions {
5
5
  url: string;
6
6
  token?: string;
7
7
  }
8
+ export declare function normalizeGatewaySseEvent(evt: TuiEvent): TuiEvent;
8
9
  /**
9
10
  * TUI backend that communicates with a running xopc gateway via HTTP + SSE.
10
11
  *