@xopcai/xopc 0.0.86 → 0.0.88

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 (658) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/adapters/cli-login.js +3 -3
  3. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  4. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  5. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  6. package/dist/extensions/telegram/src/delivery-chat-id.d.ts +1 -1
  7. package/dist/extensions/telegram/src/delivery-chat-id.js +1 -1
  8. package/dist/extensions/telegram/src/delivery-chat-id.js.map +1 -1
  9. package/dist/extensions/telegram/src/plugin.js +1 -1
  10. package/dist/extensions/telegram/src/routing-integration.js +3 -2
  11. package/dist/extensions/telegram/src/routing-integration.js.map +1 -1
  12. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  13. package/dist/extensions/telegram/xopc.extension.json +1 -1
  14. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js +2 -2
  15. package/dist/extensions/weixin/src/__tests__/workflow-progress.test.js.map +1 -1
  16. package/dist/extensions/weixin/src/api/api.js +3 -3
  17. package/dist/extensions/weixin/src/api/api.js.map +1 -1
  18. package/dist/extensions/weixin/src/auth/accounts.js +12 -12
  19. package/dist/extensions/weixin/src/auth/accounts.js.map +1 -1
  20. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  21. package/dist/extensions/weixin/src/delivery-to.js +2 -2
  22. package/dist/extensions/weixin/src/delivery-to.js.map +1 -1
  23. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  24. package/dist/extensions/weixin/src/messaging/debug-mode.js +5 -5
  25. package/dist/extensions/weixin/src/messaging/debug-mode.js.map +1 -1
  26. package/dist/extensions/weixin/src/messaging/inbound.js +11 -11
  27. package/dist/extensions/weixin/src/messaging/inbound.js.map +1 -1
  28. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  29. package/dist/extensions/weixin/src/plugin.js +1 -1
  30. package/dist/extensions/weixin/src/storage/sync-buf.js +4 -4
  31. package/dist/extensions/weixin/src/storage/sync-buf.js.map +1 -1
  32. package/dist/extensions/weixin/src/workflow-progress.d.ts +1 -1
  33. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  34. package/dist/extensions/weixin/src/workflow-progress.js.map +1 -1
  35. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +222 -0
  36. package/dist/gateway/static/root/assets/{apps-page-DrfytjOb.js → apps-page-wKWf3l57.js} +1 -1
  37. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +1 -0
  38. package/dist/gateway/static/root/assets/{channels-status-swr-Bs5kMCMI.js → channels-status-swr-DIsl75Y3.js} +1 -1
  39. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +1 -0
  40. package/dist/gateway/static/root/assets/{cron-api-BuVcZ5zR.js → cron-api-N9hvuRrn.js} +1 -1
  41. package/dist/gateway/static/root/assets/{cron-page-BMrloeFH.js → cron-page-tlNGNxhP.js} +1 -1
  42. package/dist/gateway/static/root/assets/{dist-CKU1OOTf.js → dist-CJwfHYvT.js} +1 -1
  43. package/dist/gateway/static/root/assets/{extension-debug-page-BdW_46sN.js → extension-debug-page-BVJohZoZ.js} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-page-DW47KI82.js → extension-page-BT2tmElC.js} +1 -1
  45. package/dist/gateway/static/root/assets/extension-settings-page-BSS47c2j.js +1 -0
  46. package/dist/gateway/static/root/assets/{fetch-B2MYHbWg.js → fetch-BaFNUtkE.js} +1 -1
  47. package/dist/gateway/static/root/assets/{field-primitives-DPG-oJmx.js → field-primitives-QwYEq6Hz.js} +1 -1
  48. package/dist/gateway/static/root/assets/{heartbeat-config-api-C8dNts9i.js → heartbeat-config-api-BVSidEDJ.js} +1 -1
  49. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +1 -0
  50. package/dist/gateway/static/root/assets/{index-BmVYculr.js → index-qNrVJp-y.js} +97 -95
  51. package/dist/gateway/static/root/assets/{logs-page-sTsVWz0X.js → logs-page-DDonPVLn.js} +1 -1
  52. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +1 -0
  53. package/dist/gateway/static/root/assets/{settings-form-section-DuvRQW--.js → settings-form-section-B8N3A3Zo.js} +1 -1
  54. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +3 -0
  55. package/dist/gateway/static/root/assets/{share-preview-page-BtG2kLDh.js → share-preview-page-Q7KqkO-u.js} +1 -1
  56. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +2 -0
  57. package/dist/gateway/static/root/assets/{theme-store-DryYl3qD.js → theme-store-BbRc5ugR.js} +1 -1
  58. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +7 -0
  59. package/dist/gateway/static/root/assets/{utils-BY7bU1DT.js → utils-CxDGduqK.js} +1 -1
  60. package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +1 -0
  61. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +27 -0
  62. package/dist/gateway/static/root/index.html +6 -5
  63. package/dist/package.js +1 -1
  64. package/dist/src/agent/agent-manager.js +7 -7
  65. package/dist/src/agent/agent-scope.d.ts +4 -0
  66. package/dist/src/agent/agent-scope.js +53 -10
  67. package/dist/src/agent/agent-scope.js.map +1 -1
  68. package/dist/src/agent/bootstrap/filter-bootstrap-files.js +2 -1
  69. package/dist/src/agent/bootstrap/filter-bootstrap-files.js.map +1 -1
  70. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  71. package/dist/src/agent/child-agent-factory.d.ts +15 -0
  72. package/dist/src/agent/child-agent-factory.js +35 -2
  73. package/dist/src/agent/child-agent-factory.js.map +1 -1
  74. package/dist/src/agent/client-error-format.d.ts +20 -0
  75. package/dist/src/agent/client-error-format.js +97 -0
  76. package/dist/src/agent/client-error-format.js.map +1 -0
  77. package/dist/src/agent/context/workspace-seed.js +2 -2
  78. package/dist/src/agent/embedded/run-turn.js +23 -4
  79. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  80. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -1
  81. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  82. package/dist/src/agent/embedded/tool-result-truncation.js +2 -1
  83. package/dist/src/agent/embedded/tool-result-truncation.js.map +1 -1
  84. package/dist/src/agent/fallback/candidates.js +2 -2
  85. package/dist/src/agent/fallback/candidates.js.map +1 -1
  86. package/dist/src/agent/goals/goal-locale.d.ts +1 -1
  87. package/dist/src/agent/goals/goal-run-store.js +4 -4
  88. package/dist/src/agent/goals/persistent-goal-apis.d.ts +0 -2
  89. package/dist/src/agent/goals/persistent-goal-service.js +1 -2
  90. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  91. package/dist/src/agent/goals/post-turn.js +2 -2
  92. package/dist/src/agent/image/generation/normalization.js +2 -12
  93. package/dist/src/agent/image/generation/normalization.js.map +1 -1
  94. package/dist/src/agent/image/generation/provider-registry.d.ts +4 -8
  95. package/dist/src/agent/image/generation/provider-registry.js.map +1 -1
  96. package/dist/src/agent/image/generation/runtime.d.ts +2 -2
  97. package/dist/src/agent/image/generation/runtime.js.map +1 -1
  98. package/dist/src/agent/image/generation/types.d.ts +0 -18
  99. package/dist/src/agent/image/image-helpers.js +6 -1
  100. package/dist/src/agent/image/image-helpers.js.map +1 -1
  101. package/dist/src/agent/image/index.d.ts +1 -1
  102. package/dist/src/agent/image/load-image-media.js +2 -2
  103. package/dist/src/agent/inbound/inbound-loop.d.ts +5 -0
  104. package/dist/src/agent/inbound/inbound-loop.js +41 -10
  105. package/dist/src/agent/inbound/inbound-loop.js.map +1 -1
  106. package/dist/src/agent/inbound/turn-dispatcher.d.ts +4 -0
  107. package/dist/src/agent/inbound/turn-dispatcher.js +7 -5
  108. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  109. package/dist/src/agent/ipc/bus.js +1 -1
  110. package/dist/src/agent/ipc/inbox.js +2 -2
  111. package/dist/src/agent/ipc/socket.js +1 -1
  112. package/dist/src/agent/mcp/bundle-mcp-materialize.js +2 -1
  113. package/dist/src/agent/mcp/bundle-mcp-materialize.js.map +1 -1
  114. package/dist/src/agent/mcp/bundle-mcp-names.js +2 -1
  115. package/dist/src/agent/mcp/bundle-mcp-names.js.map +1 -1
  116. package/dist/src/agent/mcp/bundle-mcp-runtime.js +2 -1
  117. package/dist/src/agent/mcp/bundle-mcp-runtime.js.map +1 -1
  118. package/dist/src/agent/mcp/mcp-transport-config.js +2 -1
  119. package/dist/src/agent/mcp/mcp-transport-config.js.map +1 -1
  120. package/dist/src/agent/mcp/mcp-transport.js +2 -1
  121. package/dist/src/agent/mcp/mcp-transport.js.map +1 -1
  122. package/dist/src/agent/media-generation/runtime-shared.js +2 -9
  123. package/dist/src/agent/media-generation/runtime-shared.js.map +1 -1
  124. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  125. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  126. package/dist/src/agent/memory/dreaming/events.js +1 -1
  127. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  128. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  129. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  130. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  131. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  132. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  133. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  134. package/dist/src/agent/messaging/command-handler.d.ts +6 -0
  135. package/dist/src/agent/messaging/command-handler.js +5 -0
  136. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  137. package/dist/src/agent/models/manager.js +1 -1
  138. package/dist/src/agent/orchestration/llm-turn-retry.d.ts +2 -0
  139. package/dist/src/agent/orchestration/llm-turn-retry.js +9 -1
  140. package/dist/src/agent/orchestration/llm-turn-retry.js.map +1 -1
  141. package/dist/src/agent/prompt/safety.d.ts +0 -7
  142. package/dist/src/agent/prompt/safety.js +1 -20
  143. package/dist/src/agent/prompt/safety.js.map +1 -1
  144. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  145. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  146. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  147. package/dist/src/agent/sandbox/path-policy.js +2 -2
  148. package/dist/src/agent/service/build-direct-message-content.js +2 -2
  149. package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
  150. package/dist/src/agent/service/direct-turn-helpers.d.ts +3 -1
  151. package/dist/src/agent/service/direct-turn-helpers.js +6 -1
  152. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  153. package/dist/src/agent/service/process-direct-one-shot.d.ts +4 -0
  154. package/dist/src/agent/service/process-direct-one-shot.js +15 -2
  155. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  156. package/dist/src/agent/service/process-direct-streaming.d.ts +4 -0
  157. package/dist/src/agent/service/process-direct-streaming.js +53 -7
  158. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  159. package/dist/src/agent/service/webchat-tts.d.ts +1 -2
  160. package/dist/src/agent/service/webchat-tts.js +2 -2
  161. package/dist/src/agent/service/webchat-tts.js.map +1 -1
  162. package/dist/src/agent/service.d.ts +8 -0
  163. package/dist/src/agent/service.js +25 -5
  164. package/dist/src/agent/service.js.map +1 -1
  165. package/dist/src/agent/session/session-inspector.js +1 -1
  166. package/dist/src/agent/skills/config.js +1 -1
  167. package/dist/src/agent/skills/hub-hash.js +2 -2
  168. package/dist/src/agent/skills/hub-lock.js +1 -1
  169. package/dist/src/agent/skills/hub-pull.js +2 -2
  170. package/dist/src/agent/skills/index.js +1 -1
  171. package/dist/src/agent/skills/managed-store.js +1 -1
  172. package/dist/src/agent/skills/scanner.js +1 -1
  173. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  174. package/dist/src/agent/skills/skill-manager.js +1 -1
  175. package/dist/src/agent/tools/create-share-tool.js +27 -20
  176. package/dist/src/agent/tools/create-share-tool.js.map +1 -1
  177. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  178. package/dist/src/agent/tools/factory.js +2 -2
  179. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  180. package/dist/src/agent/tools/index.d.ts +0 -1
  181. package/dist/src/agent/tools/index.js +4 -5
  182. package/dist/src/agent/tools/send-media.js +1 -1
  183. package/dist/src/agent/tools/shell.js +0 -13
  184. package/dist/src/agent/tools/shell.js.map +1 -1
  185. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  186. package/dist/src/agent/tools/workflow-tool.js +70 -16
  187. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  188. package/dist/src/agent/tools/write.js +1 -1
  189. package/dist/src/agent/workflow/agent-progress.d.ts +5 -0
  190. package/dist/src/agent/workflow/agent-progress.js +65 -0
  191. package/dist/src/agent/workflow/agent-progress.js.map +1 -0
  192. package/dist/src/agent/workflow/builtins/audit-repo.d.ts +1 -1
  193. package/dist/src/agent/workflow/builtins/audit-repo.js +14 -0
  194. package/dist/src/agent/workflow/builtins/audit-repo.js.map +1 -1
  195. package/dist/src/agent/workflow/builtins/debug-incident.d.ts +1 -1
  196. package/dist/src/agent/workflow/builtins/debug-incident.js +14 -0
  197. package/dist/src/agent/workflow/builtins/debug-incident.js.map +1 -1
  198. package/dist/src/agent/workflow/builtins/implementation-plan.d.ts +12 -0
  199. package/dist/src/agent/workflow/builtins/implementation-plan.js +175 -0
  200. package/dist/src/agent/workflow/builtins/implementation-plan.js.map +1 -0
  201. package/dist/src/agent/workflow/builtins/index.d.ts +3 -1
  202. package/dist/src/agent/workflow/builtins/index.js +11 -1
  203. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  204. package/dist/src/agent/workflow/builtins/multi-perspective-review.d.ts +1 -1
  205. package/dist/src/agent/workflow/builtins/multi-perspective-review.js +14 -0
  206. package/dist/src/agent/workflow/builtins/multi-perspective-review.js.map +1 -1
  207. package/dist/src/agent/workflow/builtins/pr-review.d.ts +1 -1
  208. package/dist/src/agent/workflow/builtins/pr-review.js +14 -0
  209. package/dist/src/agent/workflow/builtins/pr-review.js.map +1 -1
  210. package/dist/src/agent/workflow/builtins/release-check.d.ts +11 -0
  211. package/dist/src/agent/workflow/builtins/release-check.js +165 -0
  212. package/dist/src/agent/workflow/builtins/release-check.js.map +1 -0
  213. package/dist/src/agent/workflow/builtins/research.d.ts +1 -1
  214. package/dist/src/agent/workflow/builtins/research.js +14 -0
  215. package/dist/src/agent/workflow/builtins/research.js.map +1 -1
  216. package/dist/src/agent/workflow/catalog.js +1 -1
  217. package/dist/src/agent/workflow/channel-capability.d.ts +3 -3
  218. package/dist/src/agent/workflow/index.d.ts +2 -1
  219. package/dist/src/agent/workflow/index.js +3 -2
  220. package/dist/src/agent/workflow/lint.d.ts +38 -0
  221. package/dist/src/agent/workflow/lint.js +74 -0
  222. package/dist/src/agent/workflow/lint.js.map +1 -0
  223. package/dist/src/agent/workflow/meta-locale.d.ts +12 -0
  224. package/dist/src/agent/workflow/meta-locale.js +62 -0
  225. package/dist/src/agent/workflow/meta-locale.js.map +1 -0
  226. package/dist/src/agent/workflow/parser.js +7 -1
  227. package/dist/src/agent/workflow/parser.js.map +1 -1
  228. package/dist/src/agent/workflow/runtime.d.ts +4 -1
  229. package/dist/src/agent/workflow/runtime.js +88 -8
  230. package/dist/src/agent/workflow/runtime.js.map +1 -1
  231. package/dist/src/agent/workflow/snapshot.js +2 -12
  232. package/dist/src/agent/workflow/snapshot.js.map +1 -1
  233. package/dist/src/agent/workflow/step-labels.d.ts +8 -0
  234. package/dist/src/agent/workflow/step-labels.js +48 -0
  235. package/dist/src/agent/workflow/step-labels.js.map +1 -0
  236. package/dist/src/agent/workflow/subagent-runner.js +46 -1
  237. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  238. package/dist/src/agent/workflow/types.d.ts +76 -1
  239. package/dist/src/auth/credentials.d.ts +5 -0
  240. package/dist/src/auth/credentials.js +12 -3
  241. package/dist/src/auth/credentials.js.map +1 -1
  242. package/dist/src/auth/profiles/store.js +1 -1
  243. package/dist/src/auth/sync-provider-auth.js +1 -1
  244. package/dist/src/browser/cache-dir-policy.js +1 -1
  245. package/dist/src/browser/cdp-local-launcher.js +2 -2
  246. package/dist/src/browser/index.js +4 -4
  247. package/dist/src/browser/manager.d.ts +1 -3
  248. package/dist/src/browser/manager.js +0 -6
  249. package/dist/src/browser/manager.js.map +1 -1
  250. package/dist/src/browser/providers/browser-ext-install.d.ts +4 -4
  251. package/dist/src/browser/providers/browser-ext-install.js +41 -88
  252. package/dist/src/browser/providers/browser-ext-install.js.map +1 -1
  253. package/dist/src/browser/providers/cloakbrowser.d.ts +0 -5
  254. package/dist/src/browser/providers/cloakbrowser.js +6 -59
  255. package/dist/src/browser/providers/cloakbrowser.js.map +1 -1
  256. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  257. package/dist/src/browser/stealth.js +1 -1
  258. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  259. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  260. package/dist/src/channels/attachments/voice-stt-webchat.js +10 -8
  261. package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
  262. package/dist/src/channels/outbound/persist-store.js +1 -1
  263. package/dist/src/channels/pairing/allow-from-file.js +9 -9
  264. package/dist/src/channels/pairing/allow-from-file.js.map +1 -1
  265. package/dist/src/channels/pairing/pairing-store.js +7 -7
  266. package/dist/src/channels/pairing/pairing-store.js.map +1 -1
  267. package/dist/src/chat-commands/builtins/config.js +2 -2
  268. package/dist/src/chat-commands/builtins/session.js +1 -1
  269. package/dist/src/chat-commands/builtins/session.js.map +1 -1
  270. package/dist/src/chat-commands/builtins/tts.js +2 -2
  271. package/dist/src/chat-commands/builtins/tts.js.map +1 -1
  272. package/dist/src/chat-commands/context.d.ts +3 -0
  273. package/dist/src/chat-commands/context.js +22 -4
  274. package/dist/src/chat-commands/context.js.map +1 -1
  275. package/dist/src/chat-commands/session-key.d.ts +4 -37
  276. package/dist/src/chat-commands/session-key.js +49 -85
  277. package/dist/src/chat-commands/session-key.js.map +1 -1
  278. package/dist/src/chat-commands/types.d.ts +2 -0
  279. package/dist/src/cli/commands/agent/interactive.js +2 -2
  280. package/dist/src/cli/commands/agent/interactive.js.map +1 -1
  281. package/dist/src/cli/commands/agent/sessions.js +2 -2
  282. package/dist/src/cli/commands/agent/sessions.js.map +1 -1
  283. package/dist/src/cli/commands/agent.js +4 -5
  284. package/dist/src/cli/commands/agent.js.map +1 -1
  285. package/dist/src/cli/commands/channels.js +1 -5
  286. package/dist/src/cli/commands/channels.js.map +1 -1
  287. package/dist/src/cli/commands/config.js +1 -1
  288. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  289. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  290. package/dist/src/cli/commands/doctor/checks/session-integrity.js +1 -1
  291. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  292. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  293. package/dist/src/cli/commands/extension-dev.js +1 -1
  294. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  295. package/dist/src/cli/commands/extension-pack.js +1 -1
  296. package/dist/src/cli/commands/gateway/lifecycle-core.js +1 -1
  297. package/dist/src/cli/commands/gateway/lifecycle-core.js.map +1 -1
  298. package/dist/src/cli/commands/gateway/logs.d.ts +9 -0
  299. package/dist/src/cli/commands/gateway/logs.js +50 -17
  300. package/dist/src/cli/commands/gateway/logs.js.map +1 -1
  301. package/dist/src/cli/commands/image.js +23 -22
  302. package/dist/src/cli/commands/image.js.map +1 -1
  303. package/dist/src/cli/commands/init.js +4 -4
  304. package/dist/src/cli/commands/onboard.js +1 -1
  305. package/dist/src/cli/commands/session/utils.js +2 -2
  306. package/dist/src/cli/commands/session/utils.js.map +1 -1
  307. package/dist/src/cli/commands/update.js +26 -46
  308. package/dist/src/cli/commands/update.js.map +1 -1
  309. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  310. package/dist/src/cli/utils/session.d.ts +0 -5
  311. package/dist/src/cli/utils/session.js +1 -6
  312. package/dist/src/cli/utils/session.js.map +1 -1
  313. package/dist/src/commands/agents.config.js +1 -1
  314. package/dist/src/commands/agents.config.js.map +1 -1
  315. package/dist/src/config/agent-profile.js +6 -28
  316. package/dist/src/config/agent-profile.js.map +1 -1
  317. package/dist/src/config/agent-typed-models.d.ts +18 -0
  318. package/dist/src/config/agent-typed-models.js +53 -0
  319. package/dist/src/config/agent-typed-models.js.map +1 -0
  320. package/dist/src/config/gateway-bind.js +1 -1
  321. package/dist/src/config/index.js +6 -6
  322. package/dist/src/config/loader.js +2 -2
  323. package/dist/src/config/model-input.js +2 -5
  324. package/dist/src/config/model-input.js.map +1 -1
  325. package/dist/src/config/models-json.js +2 -2
  326. package/dist/src/config/paths-state.js +1 -1
  327. package/dist/src/config/profile.js +2 -2
  328. package/dist/src/config/schema.d.ts +253 -217
  329. package/dist/src/config/schema.js +91 -40
  330. package/dist/src/config/schema.js.map +1 -1
  331. package/dist/src/config/voice.d.ts +3 -28
  332. package/dist/src/config/voice.js +27 -261
  333. package/dist/src/config/voice.js.map +1 -1
  334. package/dist/src/config/workspace-path-helpers.d.ts +1 -2
  335. package/dist/src/config/workspace-path-helpers.js.map +1 -1
  336. package/dist/src/config/workspace-path.js +1 -1
  337. package/dist/src/cron/executor.js +2 -2
  338. package/dist/src/cron/persistence.js +1 -1
  339. package/dist/src/cron/run-log-store.js +1 -1
  340. package/dist/src/daemon/constants.js +1 -1
  341. package/dist/src/daemon/install-plan.js +27 -3
  342. package/dist/src/daemon/install-plan.js.map +1 -1
  343. package/dist/src/daemon/launchd.d.ts +8 -0
  344. package/dist/src/daemon/launchd.js +7 -14
  345. package/dist/src/daemon/launchd.js.map +1 -1
  346. package/dist/src/daemon/schtasks.d.ts +25 -0
  347. package/dist/src/daemon/schtasks.js +168 -48
  348. package/dist/src/daemon/schtasks.js.map +1 -1
  349. package/dist/src/daemon/service.js +5 -4
  350. package/dist/src/daemon/service.js.map +1 -1
  351. package/dist/src/daemon/systemd.d.ts +6 -0
  352. package/dist/src/daemon/systemd.js +20 -5
  353. package/dist/src/daemon/systemd.js.map +1 -1
  354. package/dist/src/extensions/activation-context.js +0 -1
  355. package/dist/src/extensions/activation-context.js.map +1 -1
  356. package/dist/src/extensions/bundle-mcp.js +1 -1
  357. package/dist/src/extensions/discover-extensions.js +1 -1
  358. package/dist/src/extensions/health.js +1 -1
  359. package/dist/src/extensions/loader.js +1 -1
  360. package/dist/src/extensions/lockfile.js +2 -2
  361. package/dist/src/extensions/normalize-manifest.js +0 -1
  362. package/dist/src/extensions/normalize-manifest.js.map +1 -1
  363. package/dist/src/extensions/types/manifest.d.ts +0 -2
  364. package/dist/src/gateway/agent-builtin-tools.d.ts +1 -1
  365. package/dist/src/gateway/agent-builtin-tools.js +1 -0
  366. package/dist/src/gateway/agent-builtin-tools.js.map +1 -1
  367. package/dist/src/gateway/agents-admin.d.ts +9 -0
  368. package/dist/src/gateway/agents-admin.js +28 -4
  369. package/dist/src/gateway/agents-admin.js.map +1 -1
  370. package/dist/src/gateway/config-tools-web.js +3 -2
  371. package/dist/src/gateway/config-tools-web.js.map +1 -1
  372. package/dist/src/gateway/file-path-classifier.js +2 -2
  373. package/dist/src/gateway/heartbeat/service.js +2 -2
  374. package/dist/src/gateway/heartbeat/service.js.map +1 -1
  375. package/dist/src/gateway/hono/app.js +1 -1
  376. package/dist/src/gateway/hono/lib/agent-model.d.ts +25 -10
  377. package/dist/src/gateway/hono/lib/agent-model.js +60 -36
  378. package/dist/src/gateway/hono/lib/agent-model.js.map +1 -1
  379. package/dist/src/gateway/hono/lib/config-payload.js +29 -6
  380. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  381. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  382. package/dist/src/gateway/hono/lib/mask-secret-length.d.ts +6 -0
  383. package/dist/src/gateway/hono/lib/mask-secret-length.js +16 -0
  384. package/dist/src/gateway/hono/lib/mask-secret-length.js.map +1 -0
  385. package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +1 -1
  386. package/dist/src/gateway/hono/lib/safe-providers-config.js +2 -1
  387. package/dist/src/gateway/hono/lib/safe-providers-config.js.map +1 -1
  388. package/dist/src/gateway/hono/lib/safe-voice-config.js +16 -54
  389. package/dist/src/gateway/hono/lib/safe-voice-config.js.map +1 -1
  390. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  391. package/dist/src/gateway/hono/oauth.js +1 -1
  392. package/dist/src/gateway/hono/routes/agents.js +2 -2
  393. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  394. package/dist/src/gateway/hono/routes/config-patch/agents.js +25 -7
  395. package/dist/src/gateway/hono/routes/config-patch/agents.js.map +1 -1
  396. package/dist/src/gateway/hono/routes/config-patch/channels.js +0 -11
  397. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  398. package/dist/src/gateway/hono/routes/config-patch/gateway.js +3 -2
  399. package/dist/src/gateway/hono/routes/config-patch/gateway.js.map +1 -1
  400. package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -3
  401. package/dist/src/gateway/hono/routes/config-patch/misc.js.map +1 -1
  402. package/dist/src/gateway/hono/routes/config.js +59 -0
  403. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  404. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  405. package/dist/src/gateway/hono/routes/goals.js +1 -1
  406. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  407. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  408. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  409. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  410. package/dist/src/gateway/hono/routes/models.js +75 -12
  411. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  412. package/dist/src/gateway/hono/routes/sessions.js +28 -7
  413. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  414. package/dist/src/gateway/hono/routes/shares.js +15 -13
  415. package/dist/src/gateway/hono/routes/shares.js.map +1 -1
  416. package/dist/src/gateway/hono/routes/tunnel.js +1 -1
  417. package/dist/src/gateway/hono/routes/update.js +4 -2
  418. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  419. package/dist/src/gateway/hono/routes/voice.js +75 -0
  420. package/dist/src/gateway/hono/routes/voice.js.map +1 -1
  421. package/dist/src/gateway/hono/routes/workflows.d.ts +3 -0
  422. package/dist/src/gateway/hono/routes/workflows.js +347 -0
  423. package/dist/src/gateway/hono/routes/workflows.js.map +1 -0
  424. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  425. package/dist/src/gateway/hono/sse.js +16 -33
  426. package/dist/src/gateway/hono/sse.js.map +1 -1
  427. package/dist/src/gateway/lock.js +11 -11
  428. package/dist/src/gateway/lock.js.map +1 -1
  429. package/dist/src/gateway/ports.js +6 -6
  430. package/dist/src/gateway/ports.js.map +1 -1
  431. package/dist/src/gateway/resolve-webchat-session-key.d.ts +19 -0
  432. package/dist/src/gateway/resolve-webchat-session-key.js +46 -0
  433. package/dist/src/gateway/resolve-webchat-session-key.js.map +1 -0
  434. package/dist/src/gateway/service/agent-runner.js +2 -2
  435. package/dist/src/gateway/service/marketplace-service.js +2 -2
  436. package/dist/src/gateway/service/run-gateway-agent.js +9 -11
  437. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  438. package/dist/src/gateway/service/sessions-api.d.ts +3 -0
  439. package/dist/src/gateway/service/sessions-api.js +8 -0
  440. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  441. package/dist/src/gateway/service.d.ts +3 -2
  442. package/dist/src/gateway/service.js +9 -8
  443. package/dist/src/gateway/service.js.map +1 -1
  444. package/dist/src/gateway/session-reset-service.d.ts +20 -0
  445. package/dist/src/gateway/session-reset-service.js +54 -0
  446. package/dist/src/gateway/session-reset-service.js.map +1 -0
  447. package/dist/src/gateway/startup-readiness.d.ts +1 -1
  448. package/dist/src/gateway/startup-readiness.js +1 -0
  449. package/dist/src/gateway/startup-readiness.js.map +1 -1
  450. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  451. package/dist/src/heartbeat/index.js +1 -1
  452. package/dist/src/infra/gateway-processes.js +2 -2
  453. package/dist/src/infra/gateway-processes.js.map +1 -1
  454. package/dist/src/infra/restart.js +2 -2
  455. package/dist/src/infra/run-command.d.ts +16 -0
  456. package/dist/src/infra/run-command.js +67 -0
  457. package/dist/src/infra/run-command.js.map +1 -0
  458. package/dist/src/infra/update-check.js +1 -1
  459. package/dist/src/infra/update-global.d.ts +45 -0
  460. package/dist/src/infra/update-global.js +224 -0
  461. package/dist/src/infra/update-global.js.map +1 -0
  462. package/dist/src/infra/update-lock.js +3 -3
  463. package/dist/src/infra/update-runner.js +1 -1
  464. package/dist/src/infra/update-startup.js +2 -2
  465. package/dist/src/infra/write-file-atomic.js +2 -2
  466. package/dist/src/mcp/channel-shared.js +2 -1
  467. package/dist/src/mcp/channel-shared.js.map +1 -1
  468. package/dist/src/providers/auth-runtime/auth-profile-store.js +2 -2
  469. package/dist/src/providers/auth-runtime/auth-profile-store.js.map +1 -1
  470. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -12
  471. package/dist/src/providers/auth-runtime/resolve-auth.js.map +1 -1
  472. package/dist/src/providers/auth-runtime/types.d.ts +6 -12
  473. package/dist/src/providers/index.js +2 -2
  474. package/dist/src/providers/model-registry.js +1 -1
  475. package/dist/src/routing/agent-session-key.d.ts +58 -0
  476. package/dist/src/routing/agent-session-key.js +164 -0
  477. package/dist/src/routing/agent-session-key.js.map +1 -0
  478. package/dist/src/routing/index.d.ts +1 -1
  479. package/dist/src/routing/index.js +4 -2
  480. package/dist/src/routing/index.js.map +1 -1
  481. package/dist/src/routing/resolve-route.d.ts +15 -0
  482. package/dist/src/routing/resolve-route.js +41 -20
  483. package/dist/src/routing/resolve-route.js.map +1 -1
  484. package/dist/src/routing/resolve-tui-session-key.d.ts +25 -0
  485. package/dist/src/routing/resolve-tui-session-key.js +54 -0
  486. package/dist/src/routing/resolve-tui-session-key.js.map +1 -0
  487. package/dist/src/routing/session-key-utils.d.ts +24 -0
  488. package/dist/src/routing/session-key-utils.js +92 -0
  489. package/dist/src/routing/session-key-utils.js.map +1 -0
  490. package/dist/src/routing/session-key.d.ts +19 -49
  491. package/dist/src/routing/session-key.js +143 -116
  492. package/dist/src/routing/session-key.js.map +1 -1
  493. package/dist/src/session/config-store.js +2 -2
  494. package/dist/src/session/index.d.ts +6 -0
  495. package/dist/src/session/index.js +7 -1
  496. package/dist/src/session/init-session-turn.d.ts +30 -0
  497. package/dist/src/session/init-session-turn.js +102 -0
  498. package/dist/src/session/init-session-turn.js.map +1 -0
  499. package/dist/src/session/lifecycle-timestamps.d.ts +8 -0
  500. package/dist/src/session/lifecycle-timestamps.js +16 -0
  501. package/dist/src/session/lifecycle-timestamps.js.map +1 -0
  502. package/dist/src/session/manager.d.ts +7 -1
  503. package/dist/src/session/manager.js +8 -1
  504. package/dist/src/session/manager.js.map +1 -1
  505. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  506. package/dist/src/session/parity/sessions-json-file.js +1 -1
  507. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  508. package/dist/src/session/parity/transcript-paths.js +2 -2
  509. package/dist/src/session/parity/transcript-paths.js.map +1 -1
  510. package/dist/src/session/parity/xopc-session-disk-entry.d.ts +6 -0
  511. package/dist/src/session/reset-policy.d.ts +32 -0
  512. package/dist/src/session/reset-policy.js +65 -0
  513. package/dist/src/session/reset-policy.js.map +1 -0
  514. package/dist/src/session/reset-triggers.d.ts +20 -0
  515. package/dist/src/session/reset-triggers.js +63 -0
  516. package/dist/src/session/reset-triggers.js.map +1 -0
  517. package/dist/src/session/reset-type.d.ts +12 -0
  518. package/dist/src/session/reset-type.js +25 -0
  519. package/dist/src/session/reset-type.js.map +1 -0
  520. package/dist/src/session/resolve-session.d.ts +30 -0
  521. package/dist/src/session/resolve-session.js +93 -0
  522. package/dist/src/session/resolve-session.js.map +1 -0
  523. package/dist/src/session/search-index-cache.js +1 -1
  524. package/dist/src/session/search-index.js +1 -1
  525. package/dist/src/session/session-title.js +3 -2
  526. package/dist/src/session/session-title.js.map +1 -1
  527. package/dist/src/session/store.d.ts +11 -4
  528. package/dist/src/session/store.js +62 -11
  529. package/dist/src/session/store.js.map +1 -1
  530. package/dist/src/session/transcript-events.js +2 -1
  531. package/dist/src/session/transcript-events.js.map +1 -1
  532. package/dist/src/share/share-auto.js +2 -2
  533. package/dist/src/share/share-store.js +3 -3
  534. package/dist/src/share/share-thumbnail.js +2 -2
  535. package/dist/src/share/share-url.d.ts +33 -0
  536. package/dist/src/share/share-url.js +56 -14
  537. package/dist/src/share/share-url.js.map +1 -1
  538. package/dist/src/share/share-zip.js +1 -1
  539. package/dist/src/share/site-share-store.js +3 -3
  540. package/dist/src/share/site-static-serve.js +1 -1
  541. package/dist/src/tui/backends/embedded-backend.js +4 -9
  542. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  543. package/dist/src/tui/backends/gateway-sse-backend.js +1 -1
  544. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  545. package/dist/src/tui/clipboard-image.js +3 -3
  546. package/dist/src/tui/components/chat-log.js +3 -3
  547. package/dist/src/tui/components/chat-log.js.map +1 -1
  548. package/dist/src/tui/theme-manager.js +1 -1
  549. package/dist/src/tui/theme.d.ts +0 -2
  550. package/dist/src/tui/theme.js +1 -3
  551. package/dist/src/tui/theme.js.map +1 -1
  552. package/dist/src/tui/tui-agent-events.js +2 -1
  553. package/dist/src/tui/tui-agent-events.js.map +1 -1
  554. package/dist/src/tui/tui-commands.d.ts +3 -0
  555. package/dist/src/tui/tui-commands.js +45 -10
  556. package/dist/src/tui/tui-commands.js.map +1 -1
  557. package/dist/src/tui/tui-keybindings-file.js +2 -22
  558. package/dist/src/tui/tui-keybindings-file.js.map +1 -1
  559. package/dist/src/tui/tui-scoped-models.js +2 -2
  560. package/dist/src/tui/tui-session-actions.d.ts +28 -0
  561. package/dist/src/tui/tui-session-actions.js +88 -0
  562. package/dist/src/tui/tui-session-actions.js.map +1 -0
  563. package/dist/src/tui/tui-settings.js +1 -1
  564. package/dist/src/tui/tui.js +54 -49
  565. package/dist/src/tui/tui.js.map +1 -1
  566. package/dist/src/tunnel/frpc-binary.js +3 -3
  567. package/dist/src/tunnel/frpc-config.js +1 -1
  568. package/dist/src/tunnel/frpc-extract.js +1 -1
  569. package/dist/src/tunnel/tunnel-state.js +1 -1
  570. package/dist/src/utils/logger/audit.js +1 -1
  571. package/dist/src/utils/logger/log-store.js +1 -1
  572. package/dist/src/utils/logger/rotation.js +1 -1
  573. package/dist/src/utils/string-coerce.d.ts +2 -0
  574. package/dist/src/utils/string-coerce.js +10 -1
  575. package/dist/src/utils/string-coerce.js.map +1 -1
  576. package/dist/src/voice/metadata/builtin.d.ts +2 -0
  577. package/dist/src/voice/metadata/builtin.js +420 -0
  578. package/dist/src/voice/metadata/builtin.js.map +1 -0
  579. package/dist/src/voice/metadata/index.d.ts +4 -0
  580. package/dist/src/voice/metadata/index.js +3 -0
  581. package/dist/src/voice/metadata/registry.d.ts +5 -0
  582. package/dist/src/voice/metadata/registry.js +34 -0
  583. package/dist/src/voice/metadata/registry.js.map +1 -0
  584. package/dist/src/voice/metadata/types.d.ts +41 -0
  585. package/dist/src/voice/metadata/types.js +1 -0
  586. package/dist/src/voice/stt/config-slice.d.ts +2 -5
  587. package/dist/src/voice/stt/config-slice.js +5 -26
  588. package/dist/src/voice/stt/config-slice.js.map +1 -1
  589. package/dist/src/voice/stt/list-providers.d.ts +3 -3
  590. package/dist/src/voice/stt/list-providers.js +41 -6
  591. package/dist/src/voice/stt/list-providers.js.map +1 -1
  592. package/dist/src/voice/stt/types.d.ts +1 -18
  593. package/dist/src/voice/stt/types.js +4 -2
  594. package/dist/src/voice/stt/types.js.map +1 -1
  595. package/dist/src/voice/tts/audio.js +1 -1
  596. package/dist/src/voice/tts/config-slice.d.ts +3 -7
  597. package/dist/src/voice/tts/config-slice.js +7 -38
  598. package/dist/src/voice/tts/config-slice.js.map +1 -1
  599. package/dist/src/voice/tts/list-providers.d.ts +3 -3
  600. package/dist/src/voice/tts/list-providers.js +41 -6
  601. package/dist/src/voice/tts/list-providers.js.map +1 -1
  602. package/dist/src/voice/tts/merge-config.js +2 -48
  603. package/dist/src/voice/tts/merge-config.js.map +1 -1
  604. package/dist/src/voice/tts/providers/alibaba-speech.js +1 -1
  605. package/dist/src/voice/tts/providers/alibaba-speech.js.map +1 -1
  606. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  607. package/dist/src/voice/tts/types.d.ts +1 -29
  608. package/dist/src/voice/tts/types.js +19 -17
  609. package/dist/src/voice/tts/types.js.map +1 -1
  610. package/dist/src/workflows/domain/command.d.ts +18 -0
  611. package/dist/src/workflows/domain/command.js +1 -0
  612. package/dist/src/workflows/domain/definition.d.ts +62 -0
  613. package/dist/src/workflows/domain/definition.js +1 -0
  614. package/dist/src/workflows/domain/event.d.ts +67 -0
  615. package/dist/src/workflows/domain/event.js +1 -0
  616. package/dist/src/workflows/domain/index.d.ts +5 -0
  617. package/dist/src/workflows/domain/index.js +2 -0
  618. package/dist/src/workflows/domain/result.d.ts +65 -0
  619. package/dist/src/workflows/domain/result.js +1 -0
  620. package/dist/src/workflows/domain/run.d.ts +120 -0
  621. package/dist/src/workflows/domain/run.js +14 -0
  622. package/dist/src/workflows/domain/run.js.map +1 -0
  623. package/dist/src/workflows/engine/index.d.ts +2 -0
  624. package/dist/src/workflows/engine/index.js +3 -0
  625. package/dist/src/workflows/engine/projector.d.ts +3 -0
  626. package/dist/src/workflows/engine/projector.js +205 -0
  627. package/dist/src/workflows/engine/projector.js.map +1 -0
  628. package/dist/src/workflows/engine/workflow-engine.d.ts +31 -0
  629. package/dist/src/workflows/engine/workflow-engine.js +188 -0
  630. package/dist/src/workflows/engine/workflow-engine.js.map +1 -0
  631. package/dist/src/workflows/index.d.ts +6 -0
  632. package/dist/src/workflows/index.js +11 -0
  633. package/dist/src/workflows/runtime/index.d.ts +1 -0
  634. package/dist/src/workflows/runtime/index.js +4 -0
  635. package/dist/src/workflows/runtime/script-runtime.d.ts +3 -0
  636. package/dist/src/workflows/runtime/script-runtime.js +3 -0
  637. package/dist/src/workflows/store/event-store.d.ts +17 -0
  638. package/dist/src/workflows/store/event-store.js +83 -0
  639. package/dist/src/workflows/store/event-store.js.map +1 -0
  640. package/dist/src/workflows/store/paths.d.ts +7 -0
  641. package/dist/src/workflows/store/paths.js +26 -0
  642. package/dist/src/workflows/store/paths.js.map +1 -0
  643. package/dist/src/workflows/store/run-store.d.ts +13 -0
  644. package/dist/src/workflows/store/run-store.js +68 -0
  645. package/dist/src/workflows/store/run-store.js.map +1 -0
  646. package/package.json +5 -8
  647. package/dist/gateway/static/root/assets/agents-mS3_HpRI.js +0 -222
  648. package/dist/gateway/static/root/assets/channels-settings-BG6b9KrW.js +0 -1
  649. package/dist/gateway/static/root/assets/extension-settings-page-B-W4x2xP.js +0 -1
  650. package/dist/gateway/static/root/assets/index-ew_2L2We.css +0 -1
  651. package/dist/gateway/static/root/assets/sessions-page-FaG_Vlkb.js +0 -1
  652. package/dist/gateway/static/root/assets/settings-page-Bet1OerL.js +0 -3
  653. package/dist/gateway/static/root/assets/skills-page-DhUO235y.js +0 -2
  654. package/dist/gateway/static/root/assets/url-BwNL6Rgk.js +0 -3
  655. package/dist/gateway/static/root/assets/voice-api-key-field-CGEydndO.js +0 -1
  656. package/dist/src/agent/tools/browser-legacy-tools.d.ts +0 -17
  657. package/dist/src/agent/tools/browser-legacy-tools.js +0 -766
  658. package/dist/src/agent/tools/browser-legacy-tools.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { getRoutingInfo } from './session-key.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly persistentGoalApis?: PersistentGoalApis;\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n const routing = getRoutingInfo(this.sessionKey);\n await this.deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: '✅ New session started. Previous session has been archived.',\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n // Fallback to config default\n const modelConfig = this.config.agents?.defaults?.model;\n return typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary || 'minimax/minimax-m2.1';\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.thinkingDefault;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(this.config, this.sessionKey, sc);\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.reasoningDefault;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.verboseDefault;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../../../src/chat-commands/context.ts"],"sourcesContent":["/**\n * Command Context Implementation\n * \n * Provides the concrete implementation of CommandContext interface,\n * bridging commands to core services (AgentService, SessionStore, etc.)\n */\n\nimport type {\n CommandContext,\n ReplyOptions,\n UIComponent,\n SessionInfo,\n ModelInfo,\n UsageStats,\n PlatformFeature,\n MessageSource,\n CompactSessionResult,\n} from './types.js';\nimport { getSessionDisplayName } from './session-key.js';\nimport type { Config } from '../config/schema.js';\nimport type { AgentMessage } from '@earendil-works/pi-agent-core';\nimport type { MessageBus } from '../infra/bus/index.js';\nimport type { SessionStore, SessionConfigStore } from '../session/index.js';\nimport { createLogger } from '../utils/logger.js';\nimport { getRoutingInfo } from './session-key.js';\nimport { saveConfig } from '../config/loader.js';\nimport type { ThinkLevel, ReasoningLevel, VerboseLevel } from '../agent/transcript/thinking-types.js';\nimport { mkdir, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { effectiveWorkspacePathForSession } from '../session/session-workspace.js';\nimport { wrapMarkdownExportAsHtml } from '../session/chat-export.js';\nimport type { CompactionResult } from '../agent/memory/compaction.js';\nimport type { PersistentGoalApis } from '../agent/goals/persistent-goal-apis.js';\n\nconst log = createLogger('CommandContext');\n\nexport interface CommandContextDeps {\n sessionKey: string;\n source: MessageSource;\n channelId: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n config: Config;\n bus: MessageBus;\n sessionStore: SessionStore;\n sessionConfigStore?: SessionConfigStore;\n /** After persisting session thinking, sync pi-agent in-memory state */\n applySessionThinkingLevel?: (sessionKey: string, level: ThinkLevel) => void;\n // Callbacks for platform-specific operations\n replyHandler: (text: string, options?: ReplyOptions) => Promise<void>;\n componentHandler?: (component: UIComponent) => Promise<void>;\n typingHandler?: (typing: boolean) => Promise<void>;\n supportedFeatures: PlatformFeature[];\n /** Called after session files are removed so in-memory agents match disk */\n invalidateAgentSession?: (sessionKey: string) => void;\n /** Reset session in place (archive + new session id); optional — falls back to clearSession */\n resetSession?: (sessionKey: string) => Promise<void>;\n // Model management (optional, will be injected)\n getCurrentModel?: () => string;\n switchModel?: (modelId: string) => Promise<boolean>;\n listModels?: () => Promise<ModelInfo[]>;\n getUsage?: () => Promise<UsageStats>;\n /** Stop current LLM turn and clear channel preview stream (Telegram draft, etc.) */\n abortCurrentTurn?: () => Promise<void>;\n\n compactSession?: (\n sessionKey: string,\n options?: { instructions?: string; force?: boolean },\n ) => Promise<CompactionResult>;\n\n btwQuery?: (sessionKey: string, question: string) => Promise<{ text: string; error?: string }>;\n\n getSessionContextReport?: (\n sessionKey: string,\n mode: 'list' | 'detail' | 'json',\n ) => Promise<string>;\n\n persistentGoalApis?: PersistentGoalApis;\n}\n\nexport class CommandContextImpl implements CommandContext {\n readonly sessionKey: string;\n readonly source: MessageSource;\n readonly channelId: string;\n readonly chatId: string;\n readonly senderId: string;\n readonly isGroup: boolean;\n readonly config: Config;\n readonly abortCurrentTurn?: () => Promise<void>;\n readonly persistentGoalApis?: PersistentGoalApis;\n\n private deps: CommandContextDeps;\n\n constructor(deps: CommandContextDeps) {\n this.sessionKey = deps.sessionKey;\n this.source = deps.source;\n this.channelId = deps.channelId;\n this.chatId = deps.chatId;\n this.senderId = deps.senderId;\n this.isGroup = deps.isGroup;\n this.config = deps.config;\n this.deps = deps;\n\n if (deps.abortCurrentTurn) {\n const run = deps.abortCurrentTurn;\n this.abortCurrentTurn = async () => {\n await run();\n };\n }\n\n this.persistentGoalApis = deps.persistentGoalApis;\n }\n\n // === Reply API ===\n\n async reply(text: string, options?: ReplyOptions): Promise<void> {\n await this.deps.replyHandler(text, options);\n }\n\n async replyComponent(component: UIComponent): Promise<void> {\n if (this.deps.componentHandler) {\n await this.deps.componentHandler(component);\n } else {\n // Fallback to text representation\n await this.reply(this.renderComponentAsText(component));\n }\n }\n\n async setTyping(typing: boolean): Promise<void> {\n if (this.deps.typingHandler) {\n await this.deps.typingHandler(typing);\n }\n }\n\n // === Session Management ===\n\n async getSession(): Promise<AgentMessage[]> {\n return this.deps.sessionStore.load(this.sessionKey);\n }\n\n async resetSession(): Promise<void> {\n if (this.deps.resetSession) {\n await this.deps.resetSession(this.sessionKey);\n } else if (typeof this.deps.sessionStore.reset === 'function') {\n const outcome = await this.deps.sessionStore.reset(this.sessionKey);\n if (!outcome) {\n throw new Error('Session not found');\n }\n this.deps.invalidateAgentSession?.(this.sessionKey);\n } else {\n await this.clearSession();\n return;\n }\n\n const routing = getRoutingInfo(this.sessionKey);\n await this.deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: '✅ New session started. Previous transcript archived; model and session overrides kept.',\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session reset');\n }\n\n async clearSession(): Promise<void> {\n // Archive first if has messages\n const messages = await this.getSession();\n if (messages.length > 0) {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey, messageCount: messages.length }, 'Session archived');\n }\n\n // Delete session\n await this.deps.sessionStore.deleteSession(this.sessionKey);\n this.deps.invalidateAgentSession?.(this.sessionKey);\n\n // Publish outbound message to confirm\n const routing = getRoutingInfo(this.sessionKey);\n await this.deps.bus.publishOutbound({\n channel: routing.channel,\n chat_id: routing.chatId,\n content: '✅ Session cleared.',\n type: 'message',\n metadata: {\n threadId: routing.threadId,\n },\n });\n\n log.info({ sessionKey: this.sessionKey }, 'Session cleared');\n }\n\n async archiveSession(): Promise<void> {\n await this.deps.sessionStore.archive(this.sessionKey);\n log.info({ sessionKey: this.sessionKey }, 'Session archived');\n }\n\n async listSessions(): Promise<SessionInfo[]> {\n // TODO: Implement listSessions in SessionStore\n // For now, return current session only\n const messages = await this.getSession();\n return [{\n key: this.sessionKey,\n name: getSessionDisplayName(this.sessionKey),\n messageCount: messages.length,\n createdAt: new Date(),\n updatedAt: new Date(),\n isActive: true,\n }];\n }\n\n async switchSession(sessionKey: string): Promise<void> {\n // This is mainly for CLI/Web UI where you can switch between sessions\n // For Telegram, each chat has its own session\n log.info({ from: this.sessionKey, to: sessionKey }, 'Session switch requested');\n \n // Note: In the current architecture, switching session means\n // the next message will use a different sessionKey\n // The actual switch happens at the adapter level\n }\n\n // === Model Management ===\n\n getCurrentModel(): string {\n if (this.deps.getCurrentModel) {\n return this.deps.getCurrentModel();\n }\n \n // Fallback to config default\n return this.config.agents?.defaults?.model?.primary || 'minimax/minimax-m2.1';\n }\n\n async listModels(): Promise<ModelInfo[]> {\n if (this.deps.listModels) {\n return this.deps.listModels();\n }\n \n // Fallback to empty list\n return [];\n }\n\n async switchModel(modelId: string): Promise<boolean> {\n if (this.deps.switchModel) {\n return this.deps.switchModel(modelId);\n }\n \n // No model manager available\n await this.reply('❌ Model switching not available in this context.');\n return false;\n }\n\n async getUsage(): Promise<UsageStats> {\n if (this.deps.getUsage) {\n return this.deps.getUsage();\n }\n \n // Fallback: calculate from session\n const messages = await this.getSession();\n let promptTokens = 0;\n let completionTokens = 0;\n \n for (const msg of messages) {\n if ('usage' in msg && msg.usage) {\n promptTokens += msg.usage.input || 0;\n completionTokens += msg.usage.output || 0;\n }\n }\n \n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n messageCount: messages.length,\n };\n }\n\n // === Platform Features ===\n\n supports(feature: PlatformFeature): boolean {\n return this.deps.supportedFeatures.includes(feature);\n }\n\n // === Configuration ===\n\n getConfig(): Config {\n return this.config;\n }\n\n async updateConfig(path: string, value: unknown): Promise<boolean> {\n try {\n // Update config object using path\n const keys = path.split('.');\n let target: Record<string, unknown> = this.config as Record<string, unknown>;\n \n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!(key in target) || typeof target[key] !== 'object' || target[key] === null) {\n target[key] = {};\n }\n target = target[key] as Record<string, unknown>;\n }\n \n target[keys[keys.length - 1]] = value;\n \n // Save to disk\n await saveConfig(this.config);\n \n log.info({ path, value }, 'Config updated via command');\n return true;\n } catch (error) {\n log.error({ err: error, path, value }, 'Failed to update config');\n return false;\n }\n }\n\n // === Private Helpers ===\n\n // === Thinking Configuration ===\n\n /**\n * Get the session config store (if available)\n */\n getSessionConfigStore(): SessionConfigStore | undefined {\n return this.deps.sessionConfigStore;\n }\n\n /**\n * Get current thinking level (session override or default)\n */\n async getThinkingLevel(): Promise<ThinkLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.thinkingLevel) {\n return sessionConfig.thinkingLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.thinkingDefault;\n }\n\n /**\n * Set thinking level for this session\n */\n async setThinkingLevel(level: ThinkLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { thinkingLevel: level });\n }\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n syncAgentThinkingLevel(level: ThinkLevel): void {\n this.deps.applySessionThinkingLevel?.(this.sessionKey, level);\n }\n\n async compactSession(options?: { instructions?: string; force?: boolean }): Promise<CompactSessionResult | null> {\n if (!this.deps.compactSession) {\n return null;\n }\n const r = await this.deps.compactSession(this.sessionKey, options);\n return {\n compacted: r.compacted,\n tokensBefore: r.tokensBefore,\n tokensAfter: r.tokensAfter,\n summary: r.summary,\n };\n }\n\n async btwQuery(question: string): Promise<{ text: string; error?: string }> {\n if (!this.deps.btwQuery) {\n return { text: '', error: 'Side questions are not available in this environment.' };\n }\n return this.deps.btwQuery(this.sessionKey, question);\n }\n\n async exportSessionToWorkspace(format: 'markdown' | 'html' | 'json'): Promise<{ path: string }> {\n const exportFmt = format === 'json' ? 'json' : 'markdown';\n let body = await this.deps.sessionStore.exportSession(this.sessionKey, exportFmt);\n if (format === 'html') {\n body = wrapMarkdownExportAsHtml(`Session ${this.sessionKey}`, body);\n }\n const sc = this.deps.sessionConfigStore\n ? await this.deps.sessionConfigStore.get(this.sessionKey)\n : null;\n const root = effectiveWorkspacePathForSession(this.config, this.sessionKey, sc);\n const dir = join(root, 'exports');\n await mkdir(dir, { recursive: true });\n const safe = this.sessionKey.replace(/[^a-zA-Z0-9._-]+/g, '_').slice(0, 96);\n const ext = format === 'json' ? 'json' : format === 'html' ? 'html' : 'md';\n const name = `session-${safe}-${Date.now()}.${ext}`;\n const outPath = join(dir, name);\n await writeFile(outPath, body, 'utf-8');\n return { path: outPath };\n }\n\n async agentContextReport(mode: 'list' | 'detail' | 'json' = 'list'): Promise<string> {\n if (!this.deps.getSessionContextReport) {\n return 'Context report is not available in this environment.';\n }\n return this.deps.getSessionContextReport(this.sessionKey, mode);\n }\n\n /**\n * Get current reasoning level (session override or default)\n */\n async getReasoningLevel(): Promise<ReasoningLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.reasoningLevel) {\n return sessionConfig.reasoningLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.reasoningDefault;\n }\n\n /**\n * Set reasoning level for this session\n */\n async setReasoningLevel(level: ReasoningLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { reasoningLevel: level });\n }\n }\n\n /**\n * Get current verbose level (session override or default)\n */\n async getVerboseLevel(): Promise<VerboseLevel | undefined> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n const sessionConfig = await configStore.get(this.sessionKey);\n if (sessionConfig?.verboseLevel) {\n return sessionConfig.verboseLevel;\n }\n }\n // Fallback to agent default\n return this.config.agents?.defaults?.verboseDefault;\n }\n\n /**\n * Set verbose level for this session\n */\n async setVerboseLevel(level: VerboseLevel): Promise<void> {\n const configStore = this.deps.sessionConfigStore;\n if (configStore) {\n await configStore.update(this.sessionKey, { verboseLevel: level });\n }\n }\n\n private renderComponentAsText(component: UIComponent): string {\n switch (component.type) {\n case 'buttons':\n return component.buttons.map(b => `[${b.text}]`).join(' ');\n \n case 'select':\n return component.options.map(o => `- ${o.label}`).join('\\n');\n \n case 'model-picker':\n return component.providers.map(p => \n `**${p.name}**\\n${p.models.map(m => ` - ${m.name}`).join('\\n')}`\n ).join('\\n\\n');\n \n case 'usage-display':\n return `📊 Usage Stats:\\n` +\n `📥 Prompt: ${component.stats.promptTokens.toLocaleString()} tokens\\n` +\n `📤 Completion: ${component.stats.completionTokens.toLocaleString()} tokens\\n` +\n `📊 Total: ${component.stats.totalTokens.toLocaleString()} tokens`;\n \n case 'session-list':\n return component.sessions.map(s => \n `${s.isActive ? '▶️' : ' '} ${s.key} (${s.messageCount} messages)`\n ).join('\\n');\n \n case 'text-input':\n return component.placeholder || 'Enter text...';\n \n default:\n return '[UI Component]';\n }\n }\n}\n\n/**\n * Create a command context from dependencies\n */\nexport function createCommandContext(deps: CommandContextDeps): CommandContext {\n return new CommandContextImpl(deps);\n}\n"],"mappings":"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"}
@@ -1,14 +1,5 @@
1
1
  /**
2
- * Session Key Generator
3
- *
4
- * Uses the new routing system session key format:
5
- * {agentId}:{source}:{accountId}:{peerKind}:{peerId}[:thread:{threadId}][:scope:{scopeId}]
6
- *
7
- * Examples:
8
- * - main:telegram:default:dm:123456
9
- * - main:telegram:default:group:-100123456
10
- * - main:gateway:default:direct:chat_abc123
11
- * - main:cli:default:direct:cli
2
+ * Session Key Generator — OpenClaw `agent:{agentId}:{rest}` format.
12
3
  */
13
4
  import type { MessageSource } from './types.js';
14
5
  export interface SessionKeyContext {
@@ -18,28 +9,13 @@ export interface SessionKeyContext {
18
9
  senderId: string;
19
10
  isGroup: boolean;
20
11
  threadId?: string;
21
- /** Agent ID (defaults to 'main') */
22
12
  agentId?: string;
23
- /** Account ID (defaults to 'default') */
24
13
  accountId?: string;
14
+ mainKey?: string;
15
+ dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer';
16
+ identityLinks?: Record<string, string[]>;
25
17
  }
26
- /**
27
- * Generate a unified session key using the new routing format
28
- *
29
- * Format: {agentId}:{source}:{accountId}:{peerKind}:{peerId}[:thread:{threadId}]
30
- *
31
- * Examples:
32
- * - telegram DM: main:telegram:default:dm:123456
33
- * - telegram Group: main:telegram:default:group:-100123456
34
- * - gateway: main:gateway:default:direct:chat_abc123
35
- * - cli: main:cli:default:direct:cli
36
- */
37
18
  export declare function generateSessionKey(ctx: SessionKeyContext): string;
38
- /**
39
- * Parse a session key into its components
40
- *
41
- * Returns a UI-oriented shape (`type`, `chatId`, etc.) derived from the routing key.
42
- */
43
19
  export declare function parseSessionKey(sessionKey: string): {
44
20
  source: MessageSource;
45
21
  type: 'dm' | 'group' | 'thread' | 'direct' | 'other';
@@ -48,17 +24,8 @@ export declare function parseSessionKey(sessionKey: string): {
48
24
  agentId?: string;
49
25
  accountId?: string;
50
26
  };
51
- /**
52
- * Check if a session key is valid
53
- */
54
27
  export declare function isValidSessionKey(sessionKey: string): boolean;
55
- /**
56
- * Get display name for a session key
57
- */
58
28
  export declare function getSessionDisplayName(sessionKey: string): string;
59
- /**
60
- * Extract channel info from session key for reply routing
61
- */
62
29
  export declare function getRoutingInfo(sessionKey: string): {
63
30
  channel: string;
64
31
  chatId: string;
@@ -1,95 +1,69 @@
1
- import { buildSessionKey, init_session_key, parseSessionKey as parseSessionKey$1 } from "../routing/session-key.js";
1
+ import { buildAgentMainSessionKey, buildAgentPeerSessionKey } from "../routing/agent-session-key.js";
2
+ import { init_session_key, parseSessionKey as parseSessionKey$1 } from "../routing/session-key.js";
2
3
  //#region src/chat-commands/session-key.ts
3
4
  init_session_key();
4
- /**
5
- * Generate a unified session key using the new routing format
6
- *
7
- * Format: {agentId}:{source}:{accountId}:{peerKind}:{peerId}[:thread:{threadId}]
8
- *
9
- * Examples:
10
- * - telegram DM: main:telegram:default:dm:123456
11
- * - telegram Group: main:telegram:default:group:-100123456
12
- * - gateway: main:gateway:default:direct:chat_abc123
13
- * - cli: main:cli:default:direct:cli
14
- */
15
5
  function generateSessionKey(ctx) {
16
- const { source, chatId, senderId, isGroup, threadId, agentId, accountId } = ctx;
17
- const effectiveAgentId = agentId ?? "main";
18
- const effectiveAccountId = accountId ?? "default";
19
- if (source === "cli") return buildSessionKey({
20
- agentId: effectiveAgentId,
21
- source: "cli",
22
- accountId: effectiveAccountId,
23
- peerKind: "direct",
24
- peerId: chatId === "direct" ? "cli" : chatId
25
- });
26
- if (source === "webui" || source === "gateway") return buildSessionKey({
27
- agentId: effectiveAgentId,
28
- source: source === "webui" ? "gateway" : source,
29
- accountId: effectiveAccountId,
30
- peerKind: "direct",
31
- peerId: chatId
32
- });
33
- if (source === "api") return buildSessionKey({
34
- agentId: effectiveAgentId,
35
- source: "api",
36
- accountId: effectiveAccountId,
37
- peerKind: "direct",
38
- peerId: chatId
39
- });
40
- if (source === "system") return buildSessionKey({
41
- agentId: effectiveAgentId,
42
- source: "system",
43
- accountId: effectiveAccountId,
44
- peerKind: "direct",
45
- peerId: chatId
46
- });
47
- if (!isGroup) return buildSessionKey({
48
- agentId: effectiveAgentId,
49
- source,
50
- accountId: effectiveAccountId,
51
- peerKind: "dm",
52
- peerId: senderId,
53
- threadId
54
- });
55
- return buildSessionKey({
6
+ const effectiveAgentId = ctx.agentId ?? "main";
7
+ const effectiveAccountId = ctx.accountId ?? "default";
8
+ const channel = ctx.source === "webui" ? "webchat" : ctx.source;
9
+ if (ctx.source === "cli") {
10
+ if (ctx.chatId === "direct" || ctx.chatId === "main") return buildAgentMainSessionKey({
11
+ agentId: effectiveAgentId,
12
+ mainKey: ctx.mainKey
13
+ });
14
+ return buildAgentPeerSessionKey({
15
+ agentId: effectiveAgentId,
16
+ mainKey: ctx.mainKey,
17
+ channel: "cli",
18
+ accountId: effectiveAccountId,
19
+ peerKind: "direct",
20
+ peerId: ctx.chatId,
21
+ dmScope: "per-peer"
22
+ });
23
+ }
24
+ if (!ctx.isGroup) {
25
+ const key = buildAgentPeerSessionKey({
26
+ agentId: effectiveAgentId,
27
+ mainKey: ctx.mainKey,
28
+ channel,
29
+ accountId: effectiveAccountId,
30
+ peerKind: "direct",
31
+ peerId: ctx.senderId,
32
+ identityLinks: ctx.identityLinks,
33
+ dmScope: ctx.dmScope ?? "per-account-channel-peer"
34
+ });
35
+ if (ctx.threadId) return `${key}:thread:${ctx.threadId.toLowerCase()}`;
36
+ return key;
37
+ }
38
+ let key = buildAgentPeerSessionKey({
56
39
  agentId: effectiveAgentId,
57
- source,
40
+ mainKey: ctx.mainKey,
41
+ channel,
58
42
  accountId: effectiveAccountId,
59
43
  peerKind: "group",
60
- peerId: chatId,
61
- threadId
44
+ peerId: ctx.chatId,
45
+ identityLinks: ctx.identityLinks
62
46
  });
47
+ if (ctx.threadId) key = `${key}:thread:${ctx.threadId.toLowerCase()}`;
48
+ return key;
63
49
  }
64
- /**
65
- * Parse a session key into its components
66
- *
67
- * Returns a UI-oriented shape (`type`, `chatId`, etc.) derived from the routing key.
68
- */
69
50
  function parseSessionKey(sessionKey) {
70
51
  const parsed = parseSessionKey$1(sessionKey);
71
- if (!parsed) {
72
- const parts = sessionKey.split(":");
73
- return {
74
- source: parts[0] || "system",
75
- type: "other",
76
- chatId: parts[parts.length - 1] || "unknown"
77
- };
78
- }
52
+ if (!parsed) return {
53
+ source: "system",
54
+ type: "other",
55
+ chatId: "unknown"
56
+ };
79
57
  let type;
80
58
  switch (parsed.peerKind) {
81
59
  case "dm":
82
- type = "dm";
60
+ case "direct":
61
+ type = parsed.peerKind === "direct" && parsed.peerId === "main" ? "direct" : "dm";
83
62
  break;
84
63
  case "group":
85
- type = parsed.threadId ? "thread" : "group";
86
- break;
87
64
  case "channel":
88
65
  type = parsed.threadId ? "thread" : "group";
89
66
  break;
90
- case "direct":
91
- type = "direct";
92
- break;
93
67
  default: type = "other";
94
68
  }
95
69
  return {
@@ -101,29 +75,19 @@ function parseSessionKey(sessionKey) {
101
75
  accountId: parsed.accountId
102
76
  };
103
77
  }
104
- /**
105
- * Check if a session key is valid
106
- */
107
78
  function isValidSessionKey(sessionKey) {
108
- if (!sessionKey || typeof sessionKey !== "string") return false;
109
79
  return parseSessionKey$1(sessionKey) !== null;
110
80
  }
111
- /**
112
- * Get display name for a session key
113
- */
114
81
  function getSessionDisplayName(sessionKey) {
115
82
  const parsed = parseSessionKey(sessionKey);
116
83
  switch (parsed.type) {
117
84
  case "dm": return `Private Chat (${parsed.source})`;
118
85
  case "group": return `Group (${parsed.source})`;
119
86
  case "thread": return `Thread (${parsed.source})`;
120
- case "direct": return parsed.source === "cli" ? "CLI Direct" : `Direct (${parsed.source})`;
87
+ case "direct": return parsed.chatId === "main" ? "Main session" : `Direct (${parsed.source})`;
121
88
  default: return `${parsed.source}:${parsed.chatId}`;
122
89
  }
123
90
  }
124
- /**
125
- * Extract channel info from session key for reply routing
126
- */
127
91
  function getRoutingInfo(sessionKey) {
128
92
  const parsed = parseSessionKey(sessionKey);
129
93
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"session-key.js","names":["parseRoutingSessionKey"],"sources":["../../../src/chat-commands/session-key.ts"],"sourcesContent":["/**\n * Session Key Generator\n * \n * Uses the new routing system session key format:\n * {agentId}:{source}:{accountId}:{peerKind}:{peerId}[:thread:{threadId}][:scope:{scopeId}]\n * \n * Examples:\n * - main:telegram:default:dm:123456\n * - main:telegram:default:group:-100123456\n * - main:gateway:default:direct:chat_abc123\n * - main:cli:default:direct:cli\n */\n\nimport type { MessageSource } from './types.js';\nimport { buildSessionKey, parseSessionKey as parseRoutingSessionKey } from '../routing/session-key.js';\n\nexport interface SessionKeyContext {\n source: MessageSource;\n channelId?: string; // e.g., 'telegram:default'\n chatId: string; // Platform-specific chat ID\n senderId: string; // Sender's platform ID\n isGroup: boolean;\n threadId?: string; // For forum/thread support\n /** Agent ID (defaults to 'main') */\n agentId?: string;\n /** Account ID (defaults to 'default') */\n accountId?: string;\n}\n\n/**\n * Generate a unified session key using the new routing format\n * \n * Format: {agentId}:{source}:{accountId}:{peerKind}:{peerId}[:thread:{threadId}]\n * \n * Examples:\n * - telegram DM: main:telegram:default:dm:123456\n * - telegram Group: main:telegram:default:group:-100123456\n * - gateway: main:gateway:default:direct:chat_abc123\n * - cli: main:cli:default:direct:cli\n */\nexport function generateSessionKey(ctx: SessionKeyContext): string {\n const { source, chatId, senderId, isGroup, threadId, agentId, accountId } = ctx;\n \n const effectiveAgentId = agentId ?? 'main';\n const effectiveAccountId = accountId ?? 'default';\n\n // CLI special handling\n if (source === 'cli') {\n return buildSessionKey({\n agentId: effectiveAgentId,\n source: 'cli',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: chatId === 'direct' ? 'cli' : chatId,\n });\n }\n \n // Web UI / Gateway special handling\n if (source === 'webui' || source === 'gateway') {\n return buildSessionKey({\n agentId: effectiveAgentId,\n source: source === 'webui' ? 'gateway' : source,\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: chatId,\n });\n }\n \n // API special handling\n if (source === 'api') {\n return buildSessionKey({\n agentId: effectiveAgentId,\n source: 'api',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: chatId,\n });\n }\n \n // System messages\n if (source === 'system') {\n return buildSessionKey({\n agentId: effectiveAgentId,\n source: 'system',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: chatId,\n });\n }\n \n // Private/DM chat\n if (!isGroup) {\n // Use senderId for private chats (consistent regardless of who initiates)\n return buildSessionKey({\n agentId: effectiveAgentId,\n source,\n accountId: effectiveAccountId,\n peerKind: 'dm',\n peerId: senderId,\n threadId,\n });\n }\n \n // Group chat\n return buildSessionKey({\n agentId: effectiveAgentId,\n source,\n accountId: effectiveAccountId,\n peerKind: 'group',\n peerId: chatId,\n threadId,\n });\n}\n\n/**\n * Parse a session key into its components\n * \n * Returns a UI-oriented shape (`type`, `chatId`, etc.) derived from the routing key.\n */\nexport function parseSessionKey(sessionKey: string): {\n source: MessageSource;\n type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n chatId: string;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n} {\n const parsed = parseRoutingSessionKey(sessionKey);\n \n if (!parsed) {\n // Fallback for unparseable keys\n const parts = sessionKey.split(':');\n return {\n source: (parts[0] as MessageSource) || 'system',\n type: 'other',\n chatId: parts[parts.length - 1] || 'unknown',\n };\n }\n \n // Map routing peer kind to coarse UI type\n let type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n switch (parsed.peerKind) {\n case 'dm':\n type = 'dm';\n break;\n case 'group':\n type = parsed.threadId ? 'thread' : 'group';\n break;\n case 'channel':\n type = parsed.threadId ? 'thread' : 'group';\n break;\n case 'direct':\n type = 'direct';\n break;\n default:\n type = 'other';\n }\n \n return {\n source: parsed.source as MessageSource,\n type,\n chatId: parsed.peerId,\n threadId: parsed.threadId,\n agentId: parsed.agentId,\n accountId: parsed.accountId,\n };\n}\n\n/**\n * Check if a session key is valid\n */\nexport function isValidSessionKey(sessionKey: string): boolean {\n if (!sessionKey || typeof sessionKey !== 'string') return false;\n \n const parsed = parseRoutingSessionKey(sessionKey);\n return parsed !== null;\n}\n\n/**\n * Get display name for a session key\n */\nexport function getSessionDisplayName(sessionKey: string): string {\n const parsed = parseSessionKey(sessionKey);\n \n switch (parsed.type) {\n case 'dm':\n return `Private Chat (${parsed.source})`;\n case 'group':\n return `Group (${parsed.source})`;\n case 'thread':\n return `Thread (${parsed.source})`;\n case 'direct':\n return parsed.source === 'cli' ? 'CLI Direct' : `Direct (${parsed.source})`;\n default:\n return `${parsed.source}:${parsed.chatId}`;\n }\n}\n\n/**\n * Extract channel info from session key for reply routing\n */\nexport function getRoutingInfo(sessionKey: string): {\n channel: string;\n chatId: string;\n threadId?: string;\n} {\n const parsed = parseSessionKey(sessionKey);\n \n return {\n channel: parsed.source,\n chatId: parsed.chatId,\n threadId: parsed.threadId,\n };\n}\n"],"mappings":";;kBAcuG;;;;;;;;;;;;AA0BvG,SAAgB,mBAAmB,KAAgC;CACjE,MAAM,EAAE,QAAQ,QAAQ,UAAU,SAAS,UAAU,SAAS,cAAc;CAE5E,MAAM,mBAAmB,WAAW;CACpC,MAAM,qBAAqB,aAAa;AAGxC,KAAI,WAAW,MACb,QAAO,gBAAgB;EACrB,SAAS;EACT,QAAQ;EACR,WAAW;EACX,UAAU;EACV,QAAQ,WAAW,WAAW,QAAQ;EACvC,CAAC;AAIJ,KAAI,WAAW,WAAW,WAAW,UACnC,QAAO,gBAAgB;EACrB,SAAS;EACT,QAAQ,WAAW,UAAU,YAAY;EACzC,WAAW;EACX,UAAU;EACV,QAAQ;EACT,CAAC;AAIJ,KAAI,WAAW,MACb,QAAO,gBAAgB;EACrB,SAAS;EACT,QAAQ;EACR,WAAW;EACX,UAAU;EACV,QAAQ;EACT,CAAC;AAIJ,KAAI,WAAW,SACb,QAAO,gBAAgB;EACrB,SAAS;EACT,QAAQ;EACR,WAAW;EACX,UAAU;EACV,QAAQ;EACT,CAAC;AAIJ,KAAI,CAAC,QAEH,QAAO,gBAAgB;EACrB,SAAS;EACT;EACA,WAAW;EACX,UAAU;EACV,QAAQ;EACR;EACD,CAAC;AAIJ,QAAO,gBAAgB;EACrB,SAAS;EACT;EACA,WAAW;EACX,UAAU;EACV,QAAQ;EACR;EACD,CAAC;;;;;;;AAQJ,SAAgB,gBAAgB,YAO9B;CACA,MAAM,SAASA,kBAAuB,WAAW;AAEjD,KAAI,CAAC,QAAQ;EAEX,MAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,SAAO;GACL,QAAS,MAAM,MAAwB;GACvC,MAAM;GACN,QAAQ,MAAM,MAAM,SAAS,MAAM;GACpC;;CAIH,IAAI;AACJ,SAAQ,OAAO,UAAf;EACE,KAAK;AACH,UAAO;AACP;EACF,KAAK;AACH,UAAO,OAAO,WAAW,WAAW;AACpC;EACF,KAAK;AACH,UAAO,OAAO,WAAW,WAAW;AACpC;EACF,KAAK;AACH,UAAO;AACP;EACF,QACE,QAAO;;AAGX,QAAO;EACL,QAAQ,OAAO;EACf;EACA,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,WAAW,OAAO;EACnB;;;;;AAMH,SAAgB,kBAAkB,YAA6B;AAC7D,KAAI,CAAC,cAAc,OAAO,eAAe,SAAU,QAAO;AAG1D,QADeA,kBAAuB,WACzB,KAAK;;;;;AAMpB,SAAgB,sBAAsB,YAA4B;CAChE,MAAM,SAAS,gBAAgB,WAAW;AAE1C,SAAQ,OAAO,MAAf;EACE,KAAK,KACH,QAAO,iBAAiB,OAAO,OAAO;EACxC,KAAK,QACH,QAAO,UAAU,OAAO,OAAO;EACjC,KAAK,SACH,QAAO,WAAW,OAAO,OAAO;EAClC,KAAK,SACH,QAAO,OAAO,WAAW,QAAQ,eAAe,WAAW,OAAO,OAAO;EAC3E,QACE,QAAO,GAAG,OAAO,OAAO,GAAG,OAAO;;;;;;AAOxC,SAAgB,eAAe,YAI7B;CACA,MAAM,SAAS,gBAAgB,WAAW;AAE1C,QAAO;EACL,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,UAAU,OAAO;EAClB"}
1
+ {"version":3,"file":"session-key.js","names":["parseRoutingSessionKey"],"sources":["../../../src/chat-commands/session-key.ts"],"sourcesContent":["/**\n * Session Key Generator OpenClaw `agent:{agentId}:{rest}` format.\n */\n\nimport type { MessageSource } from './types.js';\nimport {\n buildAgentMainSessionKey,\n buildAgentPeerSessionKey,\n parseSessionKey as parseRoutingSessionKey,\n} from '../routing/session-key.js';\n\nexport interface SessionKeyContext {\n source: MessageSource;\n channelId?: string;\n chatId: string;\n senderId: string;\n isGroup: boolean;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n mainKey?: string;\n dmScope?: 'main' | 'per-peer' | 'per-channel-peer' | 'per-account-channel-peer';\n identityLinks?: Record<string, string[]>;\n}\n\nexport function generateSessionKey(ctx: SessionKeyContext): string {\n const effectiveAgentId = ctx.agentId ?? 'main';\n const effectiveAccountId = ctx.accountId ?? 'default';\n const channel = ctx.source === 'webui' ? 'webchat' : ctx.source;\n\n if (ctx.source === 'cli') {\n if (ctx.chatId === 'direct' || ctx.chatId === 'main') {\n return buildAgentMainSessionKey({ agentId: effectiveAgentId, mainKey: ctx.mainKey });\n }\n return buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel: 'cli',\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.chatId,\n dmScope: 'per-peer',\n });\n }\n\n if (!ctx.isGroup) {\n const key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'direct',\n peerId: ctx.senderId,\n identityLinks: ctx.identityLinks,\n dmScope: ctx.dmScope ?? 'per-account-channel-peer',\n });\n if (ctx.threadId) {\n return `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n }\n\n let key = buildAgentPeerSessionKey({\n agentId: effectiveAgentId,\n mainKey: ctx.mainKey,\n channel,\n accountId: effectiveAccountId,\n peerKind: 'group',\n peerId: ctx.chatId,\n identityLinks: ctx.identityLinks,\n });\n if (ctx.threadId) {\n key = `${key}:thread:${ctx.threadId.toLowerCase()}`;\n }\n return key;\n}\n\nexport function parseSessionKey(sessionKey: string): {\n source: MessageSource;\n type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n chatId: string;\n threadId?: string;\n agentId?: string;\n accountId?: string;\n} {\n const parsed = parseRoutingSessionKey(sessionKey);\n\n if (!parsed) {\n return {\n source: 'system',\n type: 'other',\n chatId: 'unknown',\n };\n }\n\n let type: 'dm' | 'group' | 'thread' | 'direct' | 'other';\n switch (parsed.peerKind) {\n case 'dm':\n case 'direct':\n type = parsed.peerKind === 'direct' && parsed.peerId === 'main' ? 'direct' : 'dm';\n break;\n case 'group':\n case 'channel':\n type = parsed.threadId ? 'thread' : 'group';\n break;\n default:\n type = 'other';\n }\n\n return {\n source: parsed.source as MessageSource,\n type,\n chatId: parsed.peerId,\n threadId: parsed.threadId,\n agentId: parsed.agentId,\n accountId: parsed.accountId,\n };\n}\n\nexport function isValidSessionKey(sessionKey: string): boolean {\n return parseRoutingSessionKey(sessionKey) !== null;\n}\n\nexport function getSessionDisplayName(sessionKey: string): string {\n const parsed = parseSessionKey(sessionKey);\n\n switch (parsed.type) {\n case 'dm':\n return `Private Chat (${parsed.source})`;\n case 'group':\n return `Group (${parsed.source})`;\n case 'thread':\n return `Thread (${parsed.source})`;\n case 'direct':\n return parsed.chatId === 'main' ? 'Main session' : `Direct (${parsed.source})`;\n default:\n return `${parsed.source}:${parsed.chatId}`;\n }\n}\n\nexport function getRoutingInfo(sessionKey: string): {\n channel: string;\n chatId: string;\n threadId?: string;\n} {\n const parsed = parseSessionKey(sessionKey);\n\n return {\n channel: parsed.source,\n chatId: parsed.chatId,\n threadId: parsed.threadId,\n };\n}\n"],"mappings":";;;kBASmC;AAgBnC,SAAgB,mBAAmB,KAAgC;CACjE,MAAM,mBAAmB,IAAI,WAAW;CACxC,MAAM,qBAAqB,IAAI,aAAa;CAC5C,MAAM,UAAU,IAAI,WAAW,UAAU,YAAY,IAAI;AAEzD,KAAI,IAAI,WAAW,OAAO;AACxB,MAAI,IAAI,WAAW,YAAY,IAAI,WAAW,OAC5C,QAAO,yBAAyB;GAAE,SAAS;GAAkB,SAAS,IAAI;GAAS,CAAC;AAEtF,SAAO,yBAAyB;GAC9B,SAAS;GACT,SAAS,IAAI;GACb,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,SAAS;GACV,CAAC;;AAGJ,KAAI,CAAC,IAAI,SAAS;EAChB,MAAM,MAAM,yBAAyB;GACnC,SAAS;GACT,SAAS,IAAI;GACb;GACA,WAAW;GACX,UAAU;GACV,QAAQ,IAAI;GACZ,eAAe,IAAI;GACnB,SAAS,IAAI,WAAW;GACzB,CAAC;AACF,MAAI,IAAI,SACN,QAAO,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEpD,SAAO;;CAGT,IAAI,MAAM,yBAAyB;EACjC,SAAS;EACT,SAAS,IAAI;EACb;EACA,WAAW;EACX,UAAU;EACV,QAAQ,IAAI;EACZ,eAAe,IAAI;EACpB,CAAC;AACF,KAAI,IAAI,SACN,OAAM,GAAG,IAAI,UAAU,IAAI,SAAS,aAAa;AAEnD,QAAO;;AAGT,SAAgB,gBAAgB,YAO9B;CACA,MAAM,SAASA,kBAAuB,WAAW;AAEjD,KAAI,CAAC,OACH,QAAO;EACL,QAAQ;EACR,MAAM;EACN,QAAQ;EACT;CAGH,IAAI;AACJ,SAAQ,OAAO,UAAf;EACE,KAAK;EACL,KAAK;AACH,UAAO,OAAO,aAAa,YAAY,OAAO,WAAW,SAAS,WAAW;AAC7E;EACF,KAAK;EACL,KAAK;AACH,UAAO,OAAO,WAAW,WAAW;AACpC;EACF,QACE,QAAO;;AAGX,QAAO;EACL,QAAQ,OAAO;EACf;EACA,QAAQ,OAAO;EACf,UAAU,OAAO;EACjB,SAAS,OAAO;EAChB,WAAW,OAAO;EACnB;;AAGH,SAAgB,kBAAkB,YAA6B;AAC7D,QAAOA,kBAAuB,WAAW,KAAK;;AAGhD,SAAgB,sBAAsB,YAA4B;CAChE,MAAM,SAAS,gBAAgB,WAAW;AAE1C,SAAQ,OAAO,MAAf;EACE,KAAK,KACH,QAAO,iBAAiB,OAAO,OAAO;EACxC,KAAK,QACH,QAAO,UAAU,OAAO,OAAO;EACjC,KAAK,SACH,QAAO,WAAW,OAAO,OAAO;EAClC,KAAK,SACH,QAAO,OAAO,WAAW,SAAS,iBAAiB,WAAW,OAAO,OAAO;EAC9E,QACE,QAAO,GAAG,OAAO,OAAO,GAAG,OAAO;;;AAIxC,SAAgB,eAAe,YAI7B;CACA,MAAM,SAAS,gBAAgB,WAAW;AAE1C,QAAO;EACL,SAAS,OAAO;EAChB,QAAQ,OAAO;EACf,UAAU,OAAO;EAClB"}
@@ -128,6 +128,8 @@ export interface CommandContext {
128
128
  getSession(): Promise<AgentMessage[]>;
129
129
  /** Clear current session (start fresh) */
130
130
  clearSession(): Promise<void>;
131
+ /** Reset session in place (archive transcript, new session id; preserve overrides) */
132
+ resetSession(): Promise<void>;
131
133
  /** Archive current session */
132
134
  archiveSession(): Promise<void>;
133
135
  /** List user's sessions */
@@ -1,4 +1,4 @@
1
- import { getSessionManager } from "../../utils/session.js";
1
+ import { getSessionIndex } from "../../utils/session.js";
2
2
  import { listSessions } from "./sessions.js";
3
3
  import { renderStreamToTerminal } from "./stream-renderer.js";
4
4
  //#region src/cli/commands/agent/interactive.ts
@@ -26,7 +26,7 @@ async function startInteractiveChat(agent, options) {
26
26
  }
27
27
  if (trimmed.startsWith(":session ")) {
28
28
  const newSessionKey = trimmed.slice(9).trim();
29
- if (await (await getSessionManager()).getSessionMetadata(newSessionKey)) {
29
+ if (await (await getSessionIndex()).getSessionMetadata(newSessionKey)) {
30
30
  sessionKey = newSessionKey;
31
31
  console.log(`🔄 Switched to session: ${sessionKey}\n`);
32
32
  } else console.log(`❌ Session not found: ${newSessionKey}\n`);
@@ -1 +1 @@
1
- {"version":3,"file":"interactive.js","names":[],"sources":["../../../../../src/cli/commands/agent/interactive.ts"],"sourcesContent":["/**\n * Interactive chat mode for agent command\n */\n\nimport type { Interface as _Interface } from 'readline';\nimport type { AgentService } from '../../../agent/index.js';\nimport { getSessionManager } from '../../utils/session.js';\nimport { listSessions } from './sessions.js';\nimport { renderStreamToTerminal } from './stream-renderer.js';\n\nexport interface InteractiveOptions {\n workspace: string;\n sessionKey: string;\n continuingSession: boolean;\n}\n\n/**\n * Start interactive chat mode\n */\nexport async function startInteractiveChat(\n agent: AgentService,\n options: InteractiveOptions\n): Promise<void> {\n const { sessionKey: initialSessionKey, continuingSession } = options;\n \n let sessionKey = initialSessionKey;\n\n if (continuingSession) {\n console.log('🧠 Interactive chat mode - Continuing session\\n');\n } else {\n console.log('🧠 Interactive chat mode (Ctrl+C to exit)\\n');\n }\n\n const readline = await import('readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n\n rl.on('line', async (input) => {\n const trimmed = input.trim();\n \n // Handle special commands\n if (trimmed === ':sessions' || trimmed === ':list') {\n rl.pause();\n await listSessions();\n rl.resume();\n rl.prompt();\n return;\n }\n \n if (trimmed.startsWith(':session ')) {\n const newSessionKey = trimmed.slice(9).trim();\n const manager = await getSessionManager();\n const session = await manager.getSessionMetadata(newSessionKey);\n if (session) {\n sessionKey = newSessionKey;\n console.log(`🔄 Switched to session: ${sessionKey}\\n`);\n } else {\n console.log(`❌ Session not found: ${newSessionKey}\\n`);\n }\n rl.prompt();\n return;\n }\n\n if (trimmed === ':help') {\n printHelp();\n rl.prompt();\n return;\n }\n\n if (trimmed === ':quit' || trimmed === ':exit') {\n rl.close();\n return;\n }\n\n rl.pause();\n await renderStreamToTerminal(agent, input, sessionKey);\n rl.resume();\n rl.prompt();\n });\n\n rl.on('close', async () => {\n console.log('\\n👋 Goodbye!');\n process.exit(0);\n });\n\n rl.setPrompt('You: ');\n rl.prompt();\n}\n\nfunction printHelp(): void {\n console.log(`\n📖 Available commands:\n :sessions, :list - List available sessions\n :session <key> - Switch to another session\n :quit, :exit - Exit interactive mode\n :help - Show this help\n`);\n}\n"],"mappings":";;;;;;;AAmBA,eAAsB,qBACpB,OACA,SACe;CACf,MAAM,EAAE,YAAY,mBAAmB,sBAAsB;CAE7D,IAAI,aAAa;AAEjB,KAAI,kBACF,SAAQ,IAAI,kDAAkD;KAE9D,SAAQ,IAAI,8CAA8C;CAI5D,MAAM,MAAK,MADY,OAAO,aACV,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,UAAU;EACX,CAAC;AAEF,IAAG,GAAG,QAAQ,OAAO,UAAU;EAC7B,MAAM,UAAU,MAAM,MAAM;AAG5B,MAAI,YAAY,eAAe,YAAY,SAAS;AAClD,MAAG,OAAO;AACV,SAAM,cAAc;AACpB,MAAG,QAAQ;AACX,MAAG,QAAQ;AACX;;AAGF,MAAI,QAAQ,WAAW,YAAY,EAAE;GACnC,MAAM,gBAAgB,QAAQ,MAAM,EAAE,CAAC,MAAM;AAG7C,OAAI,OADkB,MADA,mBAAmB,EACX,mBAAmB,cAAc,EAClD;AACX,iBAAa;AACb,YAAQ,IAAI,2BAA2B,WAAW,IAAI;SAEtD,SAAQ,IAAI,wBAAwB,cAAc,IAAI;AAExD,MAAG,QAAQ;AACX;;AAGF,MAAI,YAAY,SAAS;AACvB,cAAW;AACX,MAAG,QAAQ;AACX;;AAGF,MAAI,YAAY,WAAW,YAAY,SAAS;AAC9C,MAAG,OAAO;AACV;;AAGF,KAAG,OAAO;AACV,QAAM,uBAAuB,OAAO,OAAO,WAAW;AACtD,KAAG,QAAQ;AACX,KAAG,QAAQ;GACX;AAEF,IAAG,GAAG,SAAS,YAAY;AACzB,UAAQ,IAAI,gBAAgB;AAC5B,UAAQ,KAAK,EAAE;GACf;AAEF,IAAG,UAAU,QAAQ;AACrB,IAAG,QAAQ;;AAGb,SAAS,YAAkB;AACzB,SAAQ,IAAI;;;;;;EAMZ"}
1
+ {"version":3,"file":"interactive.js","names":[],"sources":["../../../../../src/cli/commands/agent/interactive.ts"],"sourcesContent":["/**\n * Interactive chat mode for agent command\n */\n\nimport type { Interface as _Interface } from 'readline';\nimport type { AgentService } from '../../../agent/index.js';\nimport { getSessionIndex } from '../../utils/session.js';\nimport { listSessions } from './sessions.js';\nimport { renderStreamToTerminal } from './stream-renderer.js';\n\nexport interface InteractiveOptions {\n workspace: string;\n sessionKey: string;\n continuingSession: boolean;\n}\n\n/**\n * Start interactive chat mode\n */\nexport async function startInteractiveChat(\n agent: AgentService,\n options: InteractiveOptions\n): Promise<void> {\n const { sessionKey: initialSessionKey, continuingSession } = options;\n \n let sessionKey = initialSessionKey;\n\n if (continuingSession) {\n console.log('🧠 Interactive chat mode - Continuing session\\n');\n } else {\n console.log('🧠 Interactive chat mode (Ctrl+C to exit)\\n');\n }\n\n const readline = await import('readline');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n\n rl.on('line', async (input) => {\n const trimmed = input.trim();\n \n // Handle special commands\n if (trimmed === ':sessions' || trimmed === ':list') {\n rl.pause();\n await listSessions();\n rl.resume();\n rl.prompt();\n return;\n }\n \n if (trimmed.startsWith(':session ')) {\n const newSessionKey = trimmed.slice(9).trim();\n const manager = await getSessionIndex();\n const session = await manager.getSessionMetadata(newSessionKey);\n if (session) {\n sessionKey = newSessionKey;\n console.log(`🔄 Switched to session: ${sessionKey}\\n`);\n } else {\n console.log(`❌ Session not found: ${newSessionKey}\\n`);\n }\n rl.prompt();\n return;\n }\n\n if (trimmed === ':help') {\n printHelp();\n rl.prompt();\n return;\n }\n\n if (trimmed === ':quit' || trimmed === ':exit') {\n rl.close();\n return;\n }\n\n rl.pause();\n await renderStreamToTerminal(agent, input, sessionKey);\n rl.resume();\n rl.prompt();\n });\n\n rl.on('close', async () => {\n console.log('\\n👋 Goodbye!');\n process.exit(0);\n });\n\n rl.setPrompt('You: ');\n rl.prompt();\n}\n\nfunction printHelp(): void {\n console.log(`\n📖 Available commands:\n :sessions, :list - List available sessions\n :session <key> - Switch to another session\n :quit, :exit - Exit interactive mode\n :help - Show this help\n`);\n}\n"],"mappings":";;;;;;;AAmBA,eAAsB,qBACpB,OACA,SACe;CACf,MAAM,EAAE,YAAY,mBAAmB,sBAAsB;CAE7D,IAAI,aAAa;AAEjB,KAAI,kBACF,SAAQ,IAAI,kDAAkD;KAE9D,SAAQ,IAAI,8CAA8C;CAI5D,MAAM,MAAK,MADY,OAAO,aACV,gBAAgB;EAClC,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,UAAU;EACX,CAAC;AAEF,IAAG,GAAG,QAAQ,OAAO,UAAU;EAC7B,MAAM,UAAU,MAAM,MAAM;AAG5B,MAAI,YAAY,eAAe,YAAY,SAAS;AAClD,MAAG,OAAO;AACV,SAAM,cAAc;AACpB,MAAG,QAAQ;AACX,MAAG,QAAQ;AACX;;AAGF,MAAI,QAAQ,WAAW,YAAY,EAAE;GACnC,MAAM,gBAAgB,QAAQ,MAAM,EAAE,CAAC,MAAM;AAG7C,OAAI,OADkB,MADA,iBAAiB,EACT,mBAAmB,cAAc,EAClD;AACX,iBAAa;AACb,YAAQ,IAAI,2BAA2B,WAAW,IAAI;SAEtD,SAAQ,IAAI,wBAAwB,cAAc,IAAI;AAExD,MAAG,QAAQ;AACX;;AAGF,MAAI,YAAY,SAAS;AACvB,cAAW;AACX,MAAG,QAAQ;AACX;;AAGF,MAAI,YAAY,WAAW,YAAY,SAAS;AAC9C,MAAG,OAAO;AACV;;AAGF,KAAG,OAAO;AACV,QAAM,uBAAuB,OAAO,OAAO,WAAW;AACtD,KAAG,QAAQ;AACX,KAAG,QAAQ;GACX;AAEF,IAAG,GAAG,SAAS,YAAY;AACzB,UAAQ,IAAI,gBAAgB;AAC5B,UAAQ,KAAK,EAAE;GACf;AAEF,IAAG,UAAU,QAAQ;AACrB,IAAG,QAAQ;;AAGb,SAAS,YAAkB;AACzB,SAAQ,IAAI;;;;;;EAMZ"}
@@ -1,4 +1,4 @@
1
- import { getSessionManager } from "../../utils/session.js";
1
+ import { getSessionIndex } from "../../utils/session.js";
2
2
  //#region src/cli/commands/agent/sessions.ts
3
3
  /**
4
4
  * Session listing for agent command
@@ -7,7 +7,7 @@ import { getSessionManager } from "../../utils/session.js";
7
7
  * List available sessions in a table format
8
8
  */
9
9
  async function listSessions() {
10
- const result = await (await getSessionManager()).listSessions({
10
+ const result = await (await getSessionIndex()).listSessions({
11
11
  limit: 20,
12
12
  sortBy: "updatedAt",
13
13
  sortOrder: "desc"
@@ -1 +1 @@
1
- {"version":3,"file":"sessions.js","names":[],"sources":["../../../../../src/cli/commands/agent/sessions.ts"],"sourcesContent":["/**\n * Session listing for agent command\n */\n\nimport { getSessionManager } from '../../utils/session.js';\n\n/**\n * List available sessions in a table format\n */\nexport async function listSessions(): Promise<void> {\n const manager = await getSessionManager();\n \n const result = await manager.listSessions({ limit: 20, sortBy: 'updatedAt', sortOrder: 'desc' });\n \n console.log('\\n📋 Available Sessions:\\n');\n if (result.items.length === 0) {\n console.log('No sessions found.');\n return;\n }\n \n console.log('Key'.padEnd(35) + 'Name'.padEnd(20) + 'Messages'.padEnd(10) + 'Updated');\n console.log('─'.repeat(85));\n \n for (const session of result.items) {\n const name = (session.name || '-').slice(0, 18).padEnd(20);\n const messages = String(session.messageCount).padEnd(10);\n const updated = new Date(session.updatedAt).toLocaleDateString();\n console.log(`${session.key.slice(0, 33).padEnd(35)}${name}${messages}${updated}`);\n }\n console.log();\n}\n"],"mappings":";;;;;;;;AASA,eAAsB,eAA8B;CAGlD,MAAM,SAAS,OAAM,MAFC,mBAAmB,EAEZ,aAAa;EAAE,OAAO;EAAI,QAAQ;EAAa,WAAW;EAAQ,CAAC;AAEhG,SAAQ,IAAI,6BAA6B;AACzC,KAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,UAAQ,IAAI,qBAAqB;AACjC;;AAGF,SAAQ,IAAI,MAAM,OAAO,GAAG,GAAG,OAAO,OAAO,GAAG,GAAG,WAAW,OAAO,GAAG,GAAG,UAAU;AACrF,SAAQ,IAAI,IAAI,OAAO,GAAG,CAAC;AAE3B,MAAK,MAAM,WAAW,OAAO,OAAO;EAClC,MAAM,QAAQ,QAAQ,QAAQ,KAAK,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG;EAC1D,MAAM,WAAW,OAAO,QAAQ,aAAa,CAAC,OAAO,GAAG;EACxD,MAAM,UAAU,IAAI,KAAK,QAAQ,UAAU,CAAC,oBAAoB;AAChE,UAAQ,IAAI,GAAG,QAAQ,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,OAAO,WAAW,UAAU;;AAEnF,SAAQ,KAAK"}
1
+ {"version":3,"file":"sessions.js","names":[],"sources":["../../../../../src/cli/commands/agent/sessions.ts"],"sourcesContent":["/**\n * Session listing for agent command\n */\n\nimport { getSessionIndex } from '../../utils/session.js';\n\n/**\n * List available sessions in a table format\n */\nexport async function listSessions(): Promise<void> {\n const manager = await getSessionIndex();\n \n const result = await manager.listSessions({ limit: 20, sortBy: 'updatedAt', sortOrder: 'desc' });\n \n console.log('\\n📋 Available Sessions:\\n');\n if (result.items.length === 0) {\n console.log('No sessions found.');\n return;\n }\n \n console.log('Key'.padEnd(35) + 'Name'.padEnd(20) + 'Messages'.padEnd(10) + 'Updated');\n console.log('─'.repeat(85));\n \n for (const session of result.items) {\n const name = (session.name || '-').slice(0, 18).padEnd(20);\n const messages = String(session.messageCount).padEnd(10);\n const updated = new Date(session.updatedAt).toLocaleDateString();\n console.log(`${session.key.slice(0, 33).padEnd(35)}${name}${messages}${updated}`);\n }\n console.log();\n}\n"],"mappings":";;;;;;;;AASA,eAAsB,eAA8B;CAGlD,MAAM,SAAS,OAAM,MAFC,iBAAiB,EAEV,aAAa;EAAE,OAAO;EAAI,QAAQ;EAAa,WAAW;EAAQ,CAAC;AAEhG,SAAQ,IAAI,6BAA6B;AACzC,KAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,UAAQ,IAAI,qBAAqB;AACjC;;AAGF,SAAQ,IAAI,MAAM,OAAO,GAAG,GAAG,OAAO,OAAO,GAAG,GAAG,WAAW,OAAO,GAAG,GAAG,UAAU;AACrF,SAAQ,IAAI,IAAI,OAAO,GAAG,CAAC;AAE3B,MAAK,MAAM,WAAW,OAAO,OAAO;EAClC,MAAM,QAAQ,QAAQ,QAAQ,KAAK,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG;EAC1D,MAAM,WAAW,OAAO,QAAQ,aAAa,CAAC,OAAO,GAAG;EACxD,MAAM,UAAU,IAAI,KAAK,QAAQ,UAAU,CAAC,oBAAoB;AAChE,UAAQ,IAAI,GAAG,QAAQ,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,OAAO,WAAW,UAAU;;AAEnF,SAAQ,KAAK"}
@@ -34,8 +34,7 @@ function createAgentCommand(_ctx) {
34
34
  await listSessions();
35
35
  return;
36
36
  }
37
- const modelConfig = config.agents?.defaults?.model;
38
- const modelFromConfig = typeof modelConfig === "string" ? modelConfig : modelConfig?.primary;
37
+ const modelFromConfig = config.agents?.defaults?.model?.primary;
39
38
  const modelId = options.model?.trim() || modelFromConfig;
40
39
  const bus = new MessageBus();
41
40
  if (ctx.isVerbose) log.info({
@@ -43,10 +42,10 @@ function createAgentCommand(_ctx) {
43
42
  workspace,
44
43
  session: options.session
45
44
  }, "Starting agent");
46
- let sessionKey = options.session || "cli:direct";
45
+ let sessionKey = options.session || "agent:main:main";
47
46
  if (options.session) {
48
- const { getSessionManager } = await import("../utils/session.js");
49
- const session = await (await getSessionManager()).getSessionMetadata(options.session);
47
+ const { getSessionIndex } = await import("../utils/session.js");
48
+ const session = await (await getSessionIndex()).getSessionMetadata(options.session);
50
49
  if (!session) {
51
50
  console.error(`❌ Session not found: ${options.session}`);
52
51
  console.log("Use --list to see available sessions.");
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","names":[],"sources":["../../../../src/cli/commands/agent.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { AgentService } from '../../agent/index.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { getContextWithOpts } from '../context.js';\nimport { ExtensionLoader } from '../../extensions/index.js';\nimport { join } from 'path';\nimport { listSessions } from './agent/sessions.js';\nimport { startInteractiveChat } from './agent/interactive.js';\nimport { renderStreamToTerminal } from './agent/stream-renderer.js';\n\nconst log = createLogger('AgentCommand');\n\ninterface AgentCommandOptions {\n message?: string;\n model?: string;\n interactive?: boolean;\n session?: string;\n list?: boolean;\n}\n\nfunction createAgentCommand(_ctx: CLIContext): Command {\n const cmd = new Command('agent')\n .description('Chat with the AI agent')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc agent -m \"Hello\" # Single message',\n 'xopc agent --model demo/demo-chat-7b -m \"Hi\" # Override model for one shot',\n 'xopc agent -i # Interactive chat mode',\n 'xopc agent -i --session telegram:dm:123456 # Continue existing session',\n 'xopc agent --list # List available sessions',\n ])\n )\n .option('--model <id>', 'Model ref for this run (e.g. demo/demo-chat-7b, anthropic/claude-sonnet-4-5)')\n .option('-m, --message <text>', 'Single message to send')\n .option('-i, --interactive', 'Interactive chat mode')\n .option('-s, --session <key>', 'Continue an existing session (use --list to see available sessions)')\n .option('-l, --list', 'List available sessions and exit')\n .action(async (options: AgentCommandOptions) => {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const workspace = getWorkspacePath(config) || ctx.workspacePath;\n\n // Handle --list option\n if (options.list) {\n await listSessions();\n return;\n }\n\n const modelConfig = config.agents?.defaults?.model;\n const modelFromConfig = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n const modelId = (options.model?.trim() || modelFromConfig) as string | undefined;\n const bus = new MessageBus();\n\n if (ctx.isVerbose) {\n log.info({ model: modelId, workspace, session: options.session }, 'Starting agent');\n }\n\n // Validate session key if provided\n let sessionKey = options.session || 'cli:direct';\n if (options.session) {\n const { getSessionManager } = await import('../utils/session.js');\n const manager = await getSessionManager();\n const session = await manager.getSessionMetadata(options.session);\n if (!session) {\n console.error(`❌ Session not found: ${options.session}`);\n console.log('Use --list to see available sessions.');\n process.exit(1);\n }\n console.log(`📂 Continuing session: ${options.session} (${session.messageCount} messages)\\n`);\n }\n\n // Initialize extension loader (manifest-first activation: env, channels, model, extensions.*)\n let extensionLoader: ExtensionLoader | null = null;\n try {\n extensionLoader = new ExtensionLoader({\n workspaceDir: workspace,\n extensionsDir: join(workspace, '.extensions'),\n });\n extensionLoader.setConfig(config as Parameters<ExtensionLoader['setConfig']>[0]);\n extensionLoader.setRuntimeContext({ bus });\n await extensionLoader.loadByActivationPlan();\n const n = extensionLoader.getRegistry().extensions.size;\n if (n > 0) {\n log.info({ count: n }, 'Extensions loaded');\n }\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage: em }, `CLI agent: failed to load extensions: ${em}`);\n }\n\n const { createCliReadlineClarifyRequestFn } = await import('../../agent/tools/cli-clarify.js');\n\n const agent = new AgentService(bus, {\n workspace,\n model: modelId,\n config,\n extensionRegistry: extensionLoader?.getRegistry(),\n gatewayClarify: {\n requestClarification: createCliReadlineClarifyRequestFn(),\n },\n });\n\n // Start agent service in background\n agent.start().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage: em }, `CLI agent service exited: ${em}`);\n });\n\n // Start outbound message processor for CLI mode\n let running = true;\n const _outboundProcessor = (async () => {\n while (running) {\n try {\n const msg = await bus.consumeOutbound();\n console.log(`\\n📤 [${msg.channel}] ${msg.chat_id}: ${msg.content.slice(0, 100)}...`);\n } catch (error) {\n if (error instanceof MessageBusShutdownError) {\n break;\n }\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em }, `CLI outbound processor failed: ${em}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n\n const shutdown = async () => {\n running = false;\n bus.shutdown();\n await agent.stop();\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n if (options.message) {\n const oneShotModel = options.model?.trim();\n if (oneShotModel) {\n await agent.switchModelForSession(sessionKey, oneShotModel);\n }\n await renderStreamToTerminal(agent, options.message, sessionKey);\n if (oneShotModel) {\n await agent.resetSessionModelToAgentDefault(sessionKey);\n }\n await shutdown();\n } else if (options.interactive) {\n const interactiveModel = options.model?.trim();\n if (interactiveModel) {\n await agent.switchModelForSession(sessionKey, interactiveModel);\n }\n await startInteractiveChat(agent, {\n workspace,\n sessionKey,\n continuingSession: !!options.session,\n });\n } else {\n await shutdown();\n cmd.help();\n }\n });\n\n return cmd;\n}\n\nregister({\n id: 'agent',\n name: 'agent',\n description: 'Chat with the AI agent',\n factory: createAgentCommand,\n metadata: {\n category: 'runtime',\n examples: [\n 'xopc agent -m \"Hello\"',\n 'xopc agent --model demo/demo-chat-7b -m \"Hello demo!\"',\n 'xopc agent -i',\n ],\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent.js","names":[],"sources":["../../../../src/cli/commands/agent.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { AgentService } from '../../agent/index.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport { register, formatExamples, type CLIContext } from '../registry.js';\nimport { getContextWithOpts } from '../context.js';\nimport { ExtensionLoader } from '../../extensions/index.js';\nimport { join } from 'path';\nimport { listSessions } from './agent/sessions.js';\nimport { startInteractiveChat } from './agent/interactive.js';\nimport { renderStreamToTerminal } from './agent/stream-renderer.js';\n\nconst log = createLogger('AgentCommand');\n\ninterface AgentCommandOptions {\n message?: string;\n model?: string;\n interactive?: boolean;\n session?: string;\n list?: boolean;\n}\n\nfunction createAgentCommand(_ctx: CLIContext): Command {\n const cmd = new Command('agent')\n .description('Chat with the AI agent')\n .addHelpText(\n 'after',\n formatExamples([\n 'xopc agent -m \"Hello\" # Single message',\n 'xopc agent --model demo/demo-chat-7b -m \"Hi\" # Override model for one shot',\n 'xopc agent -i # Interactive chat mode',\n 'xopc agent -i --session telegram:dm:123456 # Continue existing session',\n 'xopc agent --list # List available sessions',\n ])\n )\n .option('--model <id>', 'Model ref for this run (e.g. demo/demo-chat-7b, anthropic/claude-sonnet-4-5)')\n .option('-m, --message <text>', 'Single message to send')\n .option('-i, --interactive', 'Interactive chat mode')\n .option('-s, --session <key>', 'Continue an existing session (use --list to see available sessions)')\n .option('-l, --list', 'List available sessions and exit')\n .action(async (options: AgentCommandOptions) => {\n const ctx = getContextWithOpts();\n const config = loadConfig(ctx.configPath);\n const workspace = getWorkspacePath(config) || ctx.workspacePath;\n\n // Handle --list option\n if (options.list) {\n await listSessions();\n return;\n }\n\n const modelFromConfig = config.agents?.defaults?.model?.primary;\n const modelId = (options.model?.trim() || modelFromConfig) as string | undefined;\n const bus = new MessageBus();\n\n if (ctx.isVerbose) {\n log.info({ model: modelId, workspace, session: options.session }, 'Starting agent');\n }\n\n // Validate session key if provided\n let sessionKey = options.session || 'agent:main:main';\n if (options.session) {\n const { getSessionIndex } = await import('../utils/session.js');\n const manager = await getSessionIndex();\n const session = await manager.getSessionMetadata(options.session);\n if (!session) {\n console.error(`❌ Session not found: ${options.session}`);\n console.log('Use --list to see available sessions.');\n process.exit(1);\n }\n console.log(`📂 Continuing session: ${options.session} (${session.messageCount} messages)\\n`);\n }\n\n // Initialize extension loader (manifest-first activation: env, channels, model, extensions.*)\n let extensionLoader: ExtensionLoader | null = null;\n try {\n extensionLoader = new ExtensionLoader({\n workspaceDir: workspace,\n extensionsDir: join(workspace, '.extensions'),\n });\n extensionLoader.setConfig(config as Parameters<ExtensionLoader['setConfig']>[0]);\n extensionLoader.setRuntimeContext({ bus });\n await extensionLoader.loadByActivationPlan();\n const n = extensionLoader.getRegistry().extensions.size;\n if (n > 0) {\n log.info({ count: n }, 'Extensions loaded');\n }\n } catch (error) {\n const em = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage: em }, `CLI agent: failed to load extensions: ${em}`);\n }\n\n const { createCliReadlineClarifyRequestFn } = await import('../../agent/tools/cli-clarify.js');\n\n const agent = new AgentService(bus, {\n workspace,\n model: modelId,\n config,\n extensionRegistry: extensionLoader?.getRegistry(),\n gatewayClarify: {\n requestClarification: createCliReadlineClarifyRequestFn(),\n },\n });\n\n // Start agent service in background\n agent.start().catch((err) => {\n const em = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage: em }, `CLI agent service exited: ${em}`);\n });\n\n // Start outbound message processor for CLI mode\n let running = true;\n const _outboundProcessor = (async () => {\n while (running) {\n try {\n const msg = await bus.consumeOutbound();\n console.log(`\\n📤 [${msg.channel}] ${msg.chat_id}: ${msg.content.slice(0, 100)}...`);\n } catch (error) {\n if (error instanceof MessageBusShutdownError) {\n break;\n }\n const em = error instanceof Error ? error.message : String(error);\n log.error({ err: error, errorMessage: em }, `CLI outbound processor failed: ${em}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n\n const shutdown = async () => {\n running = false;\n bus.shutdown();\n await agent.stop();\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n if (options.message) {\n const oneShotModel = options.model?.trim();\n if (oneShotModel) {\n await agent.switchModelForSession(sessionKey, oneShotModel);\n }\n await renderStreamToTerminal(agent, options.message, sessionKey);\n if (oneShotModel) {\n await agent.resetSessionModelToAgentDefault(sessionKey);\n }\n await shutdown();\n } else if (options.interactive) {\n const interactiveModel = options.model?.trim();\n if (interactiveModel) {\n await agent.switchModelForSession(sessionKey, interactiveModel);\n }\n await startInteractiveChat(agent, {\n workspace,\n sessionKey,\n continuingSession: !!options.session,\n });\n } else {\n await shutdown();\n cmd.help();\n }\n });\n\n return cmd;\n}\n\nregister({\n id: 'agent',\n name: 'agent',\n description: 'Chat with the AI agent',\n factory: createAgentCommand,\n metadata: {\n category: 'runtime',\n examples: [\n 'xopc agent -m \"Hello\"',\n 'xopc agent --model demo/demo-chat-7b -m \"Hello demo!\"',\n 'xopc agent -i',\n ],\n },\n});\n"],"mappings":"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"}
@@ -279,7 +279,6 @@ function applyTelegramAccount(cfg, accountId, botToken, enable) {
279
279
  const channels = { ...cfg.channels ?? {} };
280
280
  const tg = { ...channels.telegram ?? {} };
281
281
  if (enable) tg.enabled = true;
282
- tg.botToken = botToken;
283
282
  const accounts = { ...tg.accounts ?? {} };
284
283
  accounts[accountId] = {
285
284
  ...accounts[accountId] ?? {},
@@ -302,10 +301,7 @@ function removeChannelAccount(cfg, channelId, accountId) {
302
301
  if (!(accountId in accounts)) throw new SetupValidationError([{ message: `No account "${accountId}" on channel "${channelId}".` }]);
303
302
  delete accounts[accountId];
304
303
  ch.accounts = accounts;
305
- if (Object.keys(accounts).length === 0) {
306
- ch.enabled = false;
307
- if (channelId === "telegram") delete ch.botToken;
308
- }
304
+ if (Object.keys(accounts).length === 0) ch.enabled = false;
309
305
  channels[channelId] = ch;
310
306
  return {
311
307
  ...cfg,