@ljwei-stak/dsh-model-route-bot 0.66.3 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.dsh-plugin/bot-product.mjs +81 -5
  2. package/.dsh-plugin/client.js +17490 -1791
  3. package/README.i18n.yaml +4 -4
  4. package/README.md +409 -364
  5. package/README.zh.md +409 -364
  6. package/apps/integration-client/README.md +31 -7
  7. package/apps/integration-client/api.mjs +14 -3
  8. package/apps/integration-client/binding-editor.jsx +308 -109
  9. package/apps/integration-client/binding-model.mjs +262 -0
  10. package/apps/integration-client/binding.css +144 -0
  11. package/apps/integration-client/bot-model-status.mjs +18 -0
  12. package/apps/integration-client/bot-profile-identity.jsx +197 -0
  13. package/apps/integration-client/bot-profile.css +57 -0
  14. package/apps/integration-client/bot-profile.mjs +97 -0
  15. package/apps/integration-client/bot-settings-dialog.css +18 -0
  16. package/apps/integration-client/bot-settings-dialog.jsx +111 -0
  17. package/apps/integration-client/bot-thread-header-bridge.css +20 -0
  18. package/apps/integration-client/bot-thread-header.jsx +278 -0
  19. package/apps/integration-client/bot-threads-panel.jsx +378 -0
  20. package/apps/integration-client/bot-threads.css +169 -0
  21. package/apps/integration-client/chat-design.mjs +250 -0
  22. package/apps/integration-client/chat-ui.jsx +175 -0
  23. package/apps/integration-client/chat.css +477 -0
  24. package/apps/integration-client/composer-draft-binding.mjs +50 -0
  25. package/apps/integration-client/composer-draft-bound.jsx +14 -0
  26. package/apps/integration-client/composer-draft-host.jsx +142 -0
  27. package/apps/integration-client/composer-draft-session.jsx +287 -0
  28. package/apps/integration-client/composer-draft-witness.mjs +115 -0
  29. package/apps/integration-client/composer-draft.css +4 -0
  30. package/apps/integration-client/composer-draft.mjs +322 -0
  31. package/apps/integration-client/contact-attention.jsx +54 -0
  32. package/apps/integration-client/data-panel.jsx +439 -0
  33. package/apps/integration-client/data.css +69 -0
  34. package/apps/integration-client/desktop-bridge.mjs +1 -0
  35. package/apps/integration-client/desktop-http-socket.mjs +49 -0
  36. package/apps/integration-client/desktop-keyboard.mjs +32 -0
  37. package/apps/integration-client/desktop-pane.jsx +99 -30
  38. package/apps/integration-client/desktop-stream.mjs +13 -3
  39. package/apps/integration-client/desktop-tools.jsx +19 -0
  40. package/apps/integration-client/desktop-touch.mjs +27 -0
  41. package/apps/integration-client/desktop.css +41 -0
  42. package/apps/integration-client/independent-chat-controller.mjs +224 -0
  43. package/apps/integration-client/independent-chat-entry.jsx +61 -0
  44. package/apps/integration-client/independent-chat-navigation.mjs +21 -0
  45. package/apps/integration-client/independent-chat-page.jsx +148 -0
  46. package/apps/integration-client/independent-chat-rich.jsx +64 -0
  47. package/apps/integration-client/independent-chat-rich.mjs +30 -0
  48. package/apps/integration-client/independent-chat.css +73 -0
  49. package/apps/integration-client/index.jsx +24 -16
  50. package/apps/integration-client/library-panel.jsx +4 -1
  51. package/apps/integration-client/licenses/jsqr-1.4.0-LICENSE.txt +202 -0
  52. package/apps/integration-client/main-route-editor.jsx +94 -0
  53. package/apps/integration-client/main-route-model.mjs +100 -0
  54. package/apps/integration-client/model-picker.css +37 -0
  55. package/apps/integration-client/model-picker.jsx +83 -0
  56. package/apps/integration-client/native-activity.css +141 -0
  57. package/apps/integration-client/native-activity.jsx +276 -0
  58. package/apps/integration-client/native-activity.mjs +384 -0
  59. package/apps/integration-client/notifications-panel.jsx +186 -0
  60. package/apps/integration-client/notifications.css +126 -0
  61. package/apps/integration-client/pairing-qr.jsx +79 -0
  62. package/apps/integration-client/panels.jsx +126 -115
  63. package/apps/integration-client/product-slots.jsx +46 -0
  64. package/apps/integration-client/routine-recorder.mjs +23 -2
  65. package/apps/integration-client/secure-pairing.jsx +84 -0
  66. package/apps/integration-client/tasks-panel.jsx +32 -10
  67. package/apps/integration-client/ui-icons.jsx +17 -0
  68. package/apps/integration-client/usage-explorer.jsx +43 -0
  69. package/apps/integration-client/usage-report.mjs +71 -0
  70. package/apps/integration-client/usage.css +34 -0
  71. package/apps/integration-client/web-panel-model.mjs +140 -0
  72. package/apps/integration-client/web-panel-page.jsx +221 -0
  73. package/apps/integration-client/web-panel-pins-live.jsx +28 -0
  74. package/apps/integration-client/web-panel.css +139 -0
  75. package/apps/integration-client/workspace-model.mjs +67 -0
  76. package/apps/integration-client/workspace-navigation.mjs +56 -0
  77. package/apps/integration-client/workspace-ui.jsx +173 -0
  78. package/apps/integration-client/workspace.css +332 -0
  79. package/modules/bot-runtime/SOURCE.json +176 -50
  80. package/modules/bot-runtime/index.mjs +169 -13
  81. package/modules/bot-runtime/product-overlay/OVERLAY.json +128 -2
  82. package/modules/bot-runtime/product-overlay/base/src/client/header.js +244 -0
  83. package/modules/bot-runtime/product-overlay/base/src/client/learning-card.js +202 -0
  84. package/modules/bot-runtime/product-overlay/base/src/client/model-menu.js +371 -0
  85. package/modules/bot-runtime/product-overlay/base/src/client/secret-card.js +363 -0
  86. package/modules/bot-runtime/product-overlay/base/src/client/sources.js +68 -0
  87. package/modules/bot-runtime/product-overlay/base/src/client/turn-error.js +260 -0
  88. package/modules/bot-runtime/product-overlay/base/src/host/channel.js +647 -0
  89. package/modules/bot-runtime/product-overlay/base/src/host/memory.js +2050 -0
  90. package/modules/bot-runtime/product-overlay/base/src/host/models.js +314 -0
  91. package/modules/bot-runtime/product-overlay/base/src/host/parts.js +1473 -0
  92. package/modules/bot-runtime/product-overlay/base/src/host/privacy.js +368 -0
  93. package/modules/bot-runtime/product-overlay/base/src/host/roster.js +776 -0
  94. package/modules/bot-runtime/product-overlay/base/src/host/store.js +512 -0
  95. package/modules/bot-runtime/product-overlay/base/src/host/usage.js +653 -0
  96. package/modules/bot-runtime/product-overlay/patches/src/client/details-drawer.js.patch +48 -2
  97. package/modules/bot-runtime/product-overlay/patches/src/client/header.js.patch +41 -0
  98. package/modules/bot-runtime/product-overlay/patches/src/client/index.js.patch +33 -1
  99. package/modules/bot-runtime/product-overlay/patches/src/client/learning-card.js.patch +20 -0
  100. package/modules/bot-runtime/product-overlay/patches/src/client/model-menu.js.patch +24 -0
  101. package/modules/bot-runtime/product-overlay/patches/src/client/secret-card.js.patch +25 -0
  102. package/modules/bot-runtime/product-overlay/patches/src/client/sources.js.patch +52 -0
  103. package/modules/bot-runtime/product-overlay/patches/src/client/turn-error.js.patch +23 -0
  104. package/modules/bot-runtime/product-overlay/patches/src/host/channel.js.patch +46 -0
  105. package/modules/bot-runtime/product-overlay/patches/src/host/memory.js.patch +11 -0
  106. package/modules/bot-runtime/product-overlay/patches/src/host/models.js.patch +16 -0
  107. package/modules/bot-runtime/product-overlay/patches/src/host/parts.js.patch +95 -0
  108. package/modules/bot-runtime/product-overlay/patches/src/host/privacy.js.patch +11 -0
  109. package/modules/bot-runtime/product-overlay/patches/src/host/roster.js.patch +145 -0
  110. package/modules/bot-runtime/product-overlay/patches/src/host/store.js.patch +68 -0
  111. package/modules/bot-runtime/product-overlay/patches/src/host/usage.js.patch +11 -0
  112. package/modules/bot-runtime/read-model.mjs +19 -4
  113. package/modules/bot-runtime/vendor/ds-bot/src/client/details-drawer.js +15 -5
  114. package/modules/bot-runtime/vendor/ds-bot/src/client/header.js +9 -2
  115. package/modules/bot-runtime/vendor/ds-bot/src/client/index.js +9 -2
  116. package/modules/bot-runtime/vendor/ds-bot/src/client/learning-card.js +2 -2
  117. package/modules/bot-runtime/vendor/ds-bot/src/client/model-menu.js +5 -3
  118. package/modules/bot-runtime/vendor/ds-bot/src/client/secret-card.js +3 -3
  119. package/modules/bot-runtime/vendor/ds-bot/src/client/sources.js +25 -2
  120. package/modules/bot-runtime/vendor/ds-bot/src/client/turn-error.js +3 -2
  121. package/modules/bot-runtime/vendor/ds-bot/src/host/channel.js +14 -2
  122. package/modules/bot-runtime/vendor/ds-bot/src/host/memory.js +1 -1
  123. package/modules/bot-runtime/vendor/ds-bot/src/host/models.js +7 -0
  124. package/modules/bot-runtime/vendor/ds-bot/src/host/parts.js +26 -9
  125. package/modules/bot-runtime/vendor/ds-bot/src/host/privacy.js +1 -1
  126. package/modules/bot-runtime/vendor/ds-bot/src/host/roster.js +112 -3
  127. package/modules/bot-runtime/vendor/ds-bot/src/host/store.js +34 -1
  128. package/modules/bot-runtime/vendor/ds-bot/src/host/usage.js +1 -1
  129. package/modules/independent-runtime/index.mjs +152 -62
  130. package/modules/independent-runtime/remote-tools.mjs +8 -5
  131. package/modules/openmaus-protocol/NOTICE +10 -0
  132. package/modules/openmaus-protocol/README.md +15 -0
  133. package/modules/openmaus-protocol/SOURCE.json +68 -0
  134. package/modules/openmaus-protocol/dist/protocol.mjs +1203 -0
  135. package/modules/openmaus-protocol/index.mjs +1 -0
  136. package/modules/openmaus-protocol/transport.mjs +77 -0
  137. package/modules/openmaus-protocol/vendor/LICENSE +202 -0
  138. package/modules/openmaus-protocol/vendor/companion/src/e2e/README.md +405 -0
  139. package/modules/openmaus-protocol/vendor/companion/src/e2e/credentials.ts +128 -0
  140. package/modules/openmaus-protocol/vendor/companion/src/e2e/descriptor.ts +84 -0
  141. package/modules/openmaus-protocol/vendor/companion/src/e2e/noise.ts +456 -0
  142. package/modules/openmaus-protocol/vendor/companion/src/e2e/phone.ts +104 -0
  143. package/modules/openmaus-protocol/vendor/companion/src/e2e/session.ts +417 -0
  144. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.json +2565 -0
  145. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.sha256 +1 -0
  146. package/modules/openmaus-protocol/vendor/companion/src/e2e/yamux.ts +335 -0
  147. package/package.json +20 -6
  148. package/packages/bot-acp/README.md +156 -0
  149. package/packages/bot-acp/licenses/LICENSE-OpenMausBot +202 -0
  150. package/packages/bot-acp/licenses/NOTICE.md +27 -0
  151. package/packages/bot-acp/src/acp-adapter.mjs +795 -0
  152. package/packages/bot-acp/src/acp-host.mjs +148 -0
  153. package/packages/bot-acp/src/native-launch.mjs +121 -0
  154. package/packages/bot-acp/src/permission-policy.mjs +283 -0
  155. package/packages/bot-acp/src/rpc-codec.mjs +265 -0
  156. package/packages/bot-acp/src/session-core.mjs +581 -0
  157. package/packages/bot-acp/src/stdio-rpc.mjs +329 -0
  158. package/packages/bot-engines/README.md +281 -0
  159. package/packages/bot-engines/licenses/LICENSE-OpenMausBot +202 -0
  160. package/packages/bot-engines/licenses/NOTICE.md +32 -0
  161. package/packages/bot-engines/src/claude-engine.mjs +772 -0
  162. package/packages/bot-engines/src/claude-llm-adapter.mjs +797 -0
  163. package/packages/bot-engines/src/claude-llm-turn.mjs +292 -0
  164. package/packages/bot-engines/src/claude-permission-broker.mjs +130 -0
  165. package/packages/bot-engines/src/claude-permission-proxy.mjs +87 -0
  166. package/packages/bot-engines/src/claude-protocol.mjs +177 -0
  167. package/packages/bot-engines/src/driver-catalog.mjs +334 -0
  168. package/packages/bot-engines/src/host-loop-request.mjs +95 -0
  169. package/packages/bot-engines/src/host-registrations.mjs +105 -0
  170. package/packages/capability-broker/src/cli-bootstrap.mjs +86 -16
  171. package/packages/capability-broker/src/cli-bridge-response.mjs +80 -0
  172. package/packages/capability-broker/src/cli-stdio-bridge.mjs +21 -8
  173. package/packages/cli-runtime/src/codex-session-core.mjs +4 -0
  174. package/packages/cli-runtime/src/native-cli-output.mjs +57 -0
  175. package/packages/cli-runtime/src/native-peer.ps1 +51 -3
  176. package/packages/cli-runtime/src/native-process.mjs +77 -14
  177. package/packages/model-router-plugin/README.md +3 -3
  178. package/packages/model-router-plugin/package.json +1 -1
  179. package/packages/orchestration/src/binding-product.mjs +19 -0
  180. package/packages/orchestration/src/bot-data-actions.mjs +45 -0
  181. package/packages/orchestration/src/bot-data-chart.mjs +109 -0
  182. package/packages/orchestration/src/bot-data-context.mjs +44 -0
  183. package/packages/orchestration/src/bot-data-engine.mjs +809 -0
  184. package/packages/orchestration/src/bot-data-io.mjs +186 -0
  185. package/packages/orchestration/src/bot-data-sql.mjs +195 -0
  186. package/packages/orchestration/src/bot-data-surface.mjs +144 -0
  187. package/packages/orchestration/src/bot-data-tools.mjs +68 -0
  188. package/packages/orchestration/src/bot-data-worker.mjs +228 -0
  189. package/packages/orchestration/src/bot-independent-execution.mjs +195 -0
  190. package/packages/orchestration/src/bot-independent-stream.mjs +74 -0
  191. package/packages/orchestration/src/bot-loop.mjs +152 -19
  192. package/packages/orchestration/src/bot-notifications.mjs +159 -0
  193. package/packages/orchestration/src/bot-policy.mjs +43 -4
  194. package/packages/orchestration/src/bot-profile.mjs +171 -0
  195. package/packages/orchestration/src/bot-routine.mjs +4 -4
  196. package/packages/orchestration/src/bot-runtime-assembly.mjs +255 -8
  197. package/packages/orchestration/src/bot-runtime-switch.mjs +13 -2
  198. package/packages/orchestration/src/bot-serving.mjs +164 -0
  199. package/packages/orchestration/src/bot-session-store.mjs +105 -9
  200. package/packages/orchestration/src/bot-settings.mjs +50 -11
  201. package/packages/orchestration/src/bot-thread-admission.mjs +84 -0
  202. package/packages/orchestration/src/bot-thread-host.mjs +187 -0
  203. package/packages/orchestration/src/bot-threads.mjs +790 -0
  204. package/packages/orchestration/src/data-product-access.mjs +37 -0
  205. package/packages/orchestration/src/data-tool-contract.mjs +291 -0
  206. package/packages/orchestration/src/desktop-http-carrier.mjs +120 -0
  207. package/packages/orchestration/src/desktop-proxy.mjs +311 -0
  208. package/packages/orchestration/src/desktop-sessions.mjs +43 -9
  209. package/packages/orchestration/src/ds-lifecycle.mjs +31 -4
  210. package/packages/orchestration/src/grant-refresh-queue.mjs +17 -0
  211. package/packages/orchestration/src/independent-chat-page.mjs +39 -0
  212. package/packages/orchestration/src/independent-chat-service.mjs +308 -0
  213. package/packages/orchestration/src/independent-context-state.mjs +44 -0
  214. package/packages/orchestration/src/independent-message-wire.mjs +84 -0
  215. package/packages/orchestration/src/independent-tool-catalog.mjs +175 -0
  216. package/packages/orchestration/src/independent-tool-families.mjs +73 -0
  217. package/packages/orchestration/src/independent-tool-host.mjs +344 -0
  218. package/packages/orchestration/src/main-bot-grant.mjs +15 -0
  219. package/packages/orchestration/src/main-model-routes.mjs +208 -0
  220. package/packages/orchestration/src/model-accounting.mjs +99 -35
  221. package/packages/orchestration/src/model-auxiliary-dispatch.mjs +187 -0
  222. package/packages/orchestration/src/model-loop-frame.mjs +179 -0
  223. package/packages/orchestration/src/model-prepared-generation.mjs +175 -0
  224. package/packages/orchestration/src/model-request-bounds.mjs +111 -0
  225. package/packages/orchestration/src/native-activity-contract.mjs +491 -0
  226. package/packages/orchestration/src/native-activity-service.mjs +102 -0
  227. package/packages/orchestration/src/native-activity-store.mjs +249 -0
  228. package/packages/orchestration/src/native-conversation-tools.mjs +78 -0
  229. package/packages/orchestration/src/native-data-tools.mjs +100 -0
  230. package/packages/orchestration/src/native-remote-actions.mjs +742 -0
  231. package/packages/orchestration/src/native-team-tools.mjs +73 -0
  232. package/packages/orchestration/src/pairing-invite.mjs +37 -0
  233. package/packages/orchestration/src/product-composition.mjs +1559 -1001
  234. package/packages/orchestration/src/remote-machines.mjs +82 -14
  235. package/packages/orchestration/src/routine-execution.mjs +5 -3
  236. package/packages/orchestration/src/routine-session.mjs +19 -13
  237. package/packages/orchestration/src/secure-pairing-host.mjs +112 -0
  238. package/packages/orchestration/src/task-journal.mjs +29 -0
  239. package/packages/orchestration/src/task-product.mjs +17 -0
  240. package/packages/orchestration/src/team-assignment-store.mjs +120 -0
  241. package/packages/orchestration/src/team-bridge.mjs +282 -0
  242. package/packages/orchestration/src/team-scheduler.mjs +83 -0
  243. package/packages/orchestration/src/team-sdk-tools.mjs +84 -0
  244. package/packages/orchestration/src/team-tool-contract.mjs +284 -0
  245. package/packages/orchestration/src/ui-host-namespace.mjs +23 -0
  246. package/packages/orchestration/src/web-panel-actions.mjs +103 -0
  247. package/packages/orchestration/src/web-panel-framing.mjs +227 -0
  248. package/packages/orchestration/src/web-panel-store.mjs +206 -0
  249. package/remote-computer-agent/README.md +39 -29
  250. package/remote-computer-agent/build.mjs +3 -0
  251. package/remote-computer-agent/dist/OPENMAUSBOT_LICENSE +202 -0
  252. package/remote-computer-agent/dist/OPENMAUSBOT_NOTICE +10 -0
  253. package/remote-computer-agent/dist/OPENMAUSBOT_SOURCE.json +68 -0
  254. package/remote-computer-agent/dist/cli-stdio-bridge.mjs +215 -25
  255. package/remote-computer-agent/dist/cli-stdio-bridge.mjs.map +4 -4
  256. package/remote-computer-agent/dist/cli.mjs +1688 -168
  257. package/remote-computer-agent/dist/cli.mjs.map +4 -4
  258. package/remote-computer-agent/dist/index.mjs +1579 -122
  259. package/remote-computer-agent/dist/index.mjs.map +4 -4
  260. package/remote-computer-agent/dist/native-peer.ps1 +51 -3
  261. package/remote-computer-agent/package-lock.json +308 -2
  262. package/remote-computer-agent/package.json +2 -1
  263. package/remote-computer-agent/pair-device.ps1 +20 -0
  264. package/remote-computer-agent/setup.ps1 +38 -16
  265. package/remote-computer-agent/src/cli.ts +24 -3
  266. package/remote-computer-agent/src/desktop-session.ts +11 -3
  267. package/remote-computer-agent/src/e2e-server.ts +81 -0
  268. package/remote-computer-agent/src/pairing-page.ts +35 -0
  269. package/remote-computer-agent/src/protocol.ts +25 -25
  270. package/remote-computer-agent/src/secure-pairing.ts +105 -0
  271. package/remote-computer-agent/src/store.ts +20 -5
  272. package/remote-computer-agent/src/transport.ts +39 -15
@@ -6,14 +6,38 @@ import * as fs from 'node:fs'
6
6
  import { createBotLibrary } from '../packages/orchestration/src/bot-library.mjs'
7
7
  import { libraryRoot, registerLibraryTools } from './shared/library-tools.mjs'
8
8
  import { createBotRoutineStore, routineStoreDir } from '../packages/orchestration/src/bot-routine-store.mjs'
9
- import { createPluginRuntime } from '../modules/independent-runtime/index.mjs'
9
+ import { createPluginRuntime, runtimeSwitchPath } from '../modules/independent-runtime/index.mjs'
10
10
  import { inject as botRuntimeInject } from '../modules/bot-runtime/index.mjs'
11
+ import { createBotServing } from '../packages/orchestration/src/bot-serving.mjs'
12
+ import { openRuntimeSwitch } from '../packages/orchestration/src/bot-runtime-switch.mjs'
11
13
  import { createDiagnosticAccountStream, startBotProduct } from '../packages/orchestration/src/product-composition.mjs'
12
14
  import { createDeferredRouterState } from '../packages/orchestration/src/deferred-router-state.mjs'
13
15
  import { BotRuntimeConfig, normalizeBotRuntimeConfig } from '../packages/orchestration/src/bot-runtime-config.mjs'
14
16
  import { assertMigrationStartupAllowed } from '../packages/orchestration/src/migration-startup-gate.mjs'
17
+ import { createIndependentConversationReader } from '../packages/orchestration/src/independent-chat-page.mjs'
15
18
 
16
19
  export const inject = botRuntimeInject
20
+ // Which runtime serves a Bot is committed state: the switch file the independent runtime owns.
21
+ // It is read back on every admission, and a read that fails refuses the call instead of assuming
22
+ // the integration path. Absence of the adapter is not proof that nothing was ever moved — a Host
23
+ // that restarts with the independent runtime switched off still has the file a move wrote — so the
24
+ // file itself is read when no adapter answers. Only a Host that never constructed the independent
25
+ // runtime at all has no switch to read, and only there is integration the truth.
26
+ const switches = new Map()
27
+ const switchFor = file => {
28
+ if (!switches.has(file)) switches.set(file, openRuntimeSwitch({ file }))
29
+ return switches.get(file)
30
+ }
31
+ export const runtimeModeOf = ctx => botId => {
32
+ const adapter = (() => { try { return ctx.get?.('botRuntimeAdapter') ?? null } catch { return null } })()
33
+ if (adapter && typeof adapter.modeOf === 'function') return adapter.modeOf(botId)
34
+ const file = (() => { try { return ctx.get?.('botRuntimeSwitchFile') ?? null } catch { return null } })()
35
+ if (typeof file !== 'string' || file === '') return 'integration'
36
+ // The switch's own reader: an absent file is "nothing was ever switched", a corrupt one throws
37
+ // and the admission refuses. Nothing here resets or overwrites a committed mode.
38
+ return switchFor(file).modeOf(botId)
39
+ }
40
+ const servingOf = ctx => { try { return ctx.get?.('botServing') ?? null } catch { return null } }
17
41
  export const configFields = {
18
42
  // Unified Bot product composition (DS Bot runtime + this plugin). Isolated
19
43
  // test compositions provide their own policy/runtime and disable this.
@@ -29,10 +53,23 @@ export const configFields = {
29
53
  }).default({ enabled: false, preset: 'balanced', autoGrant: { machineTools: true, cliTools: false } }),
30
54
  operatorPassthrough: z.object({ enabled: z.boolean().default(true) }).default({ enabled: true }),
31
55
  independentRuntime: z.object({
56
+ // `provider`, `model` and `workspaceRoot` are no longer read for authority: the committed Bot
57
+ // decides the model it runs on, and the Host decides which tools it may reach. They stay in the
58
+ // schema so an existing configuration keeps parsing; nothing here falls back to them.
32
59
  enabled: z.boolean().default(false), provider: z.string().default(''), model: z.string().default(''),
33
60
  dir: z.string().max(4096).default(''), workspaceRoot: z.string().max(4096).default(''),
34
61
  maxSteps: z.number().step(1).min(1).max(200).default(16), fullTextHistory: z.boolean().default(false),
35
62
  }).default({ enabled: false }),
63
+ // Host-owned pinned conversation routes. Bot bindings select only the
64
+ // advertised provider/model; messages cannot supply these launch details.
65
+ conversationEngines: z.array(z.object({
66
+ id: z.string().max(100), driver: z.union(['claude']).default('claude'),
67
+ provider: z.string().max(100), model: z.string().max(100), name: z.string().max(128),
68
+ entry: z.object({ executable: z.string().max(4096), sha256: z.string().pattern(/^[a-f0-9]{64}$/), version: z.string().max(32),
69
+ script: z.string().max(4096), scriptSha256: z.string().pattern(/^[a-f0-9]{64}$/) }),
70
+ credentialRef: z.string().max(80), deadlineMs: z.number().step(1).min(1000).max(7200000),
71
+ hostTools: z.boolean().default(false),
72
+ })).max(32).default([]),
36
73
  // 托管任务的官方 CLI 入口:executable/sha256/version 必须来自安装核验
37
74
  // (探针期由 pinCodexExecutable 复核),Bot 与任务入参均不能提供入口。
38
75
  // 未配置时默认产品不注册 CLI 任务后端。sessionFactory 仅供宿主级隔离验证
@@ -66,20 +103,31 @@ export function start(ctx, config, { installRouterStateStore, executeConfiguredA
66
103
  deferredRouterState = createDeferredRouterState({ file: storageFile })
67
104
  installRouterStateStore(deferredRouterState.state)
68
105
  }
106
+ // The one serving admission, published before the runtime exists: the integrated stream and
107
+ // the independent runtime both take their lease from it, so "is this Bot being served" has one
108
+ // answer in one Host.
109
+ let serving = null
110
+ if (productHost) {
111
+ serving = createBotServing({ modeOf: runtimeModeOf(ctx) })
112
+ try { ctx.provide('botServing', serving) } catch { serving = servingOf(ctx) ?? serving }
113
+ }
69
114
  let botProduct
70
115
  const taskCli = (() => { const value = config?.taskCli; return (typeof value === 'function' ? value() : value) ?? null })()
116
+ const conversationEngines = (() => { const value = config?.conversationEngines; return (typeof value === 'function' ? value() : value) ?? [] })()
71
117
  try {
72
118
  botProduct = productHost ? startBotProduct(ctx, { config, accountStream: createDiagnosticAccountStream(),
73
119
  deferredRouterState, storageFile: deferredRouterState?.state.file, legacyFile: defaultStatePath(),
74
120
  // N09: the managed Task runner reuses this plugin's own execution entries,
75
121
  // so the composition never needs a second copy of the MR runtime.
76
- mr: { executeConfiguredAssignment, rerunRecordedStep, routerStateStore }, taskCli,
122
+ mr: { executeConfiguredAssignment, rerunRecordedStep, routerStateStore }, taskCli, conversationEngines,
77
123
  runtimeConfig: normalizeBotRuntimeConfig(config?.botRuntime) }) : null
78
124
  } catch (error) {
79
125
  deferredRouterState?.reject(error)
80
126
  throw error
81
127
  }
82
- if (botProduct) ctx.effect(() => async () => { await botProduct.dispose() }, 'model-router-galgame: bot product')
128
+ if (botProduct) {
129
+ ctx.effect(() => async () => { await botProduct.dispose() }, 'model-router-galgame: bot product')
130
+ }
83
131
  return botProduct
84
132
  }
85
133
 
@@ -88,28 +136,56 @@ export function connect(ctx, config, { stateDir, valueOf }) {
88
136
  // instead of taking the plugin down.
89
137
  let botRouting = null
90
138
  try { botRouting = ctx.get?.('botRouting') ?? null } catch { botRouting = null }
139
+ // The same admission the Bot product's model stream holds, so one Host answers "is this Bot
140
+ // being served" once. The product publishes it; without a product there is still one switch
141
+ // and one lease, so it is built here instead of being skipped.
142
+ const serving = servingOf(ctx) ?? createBotServing({ modeOf: runtimeModeOf(ctx) })
91
143
  let botRuntime = null
92
144
  try {
93
145
  const runtime = createPluginRuntime({
94
146
  ctx,
95
- settings: { ...(valueOf(config, 'independentRuntime', {}) ?? {}), remoteInvoke: (botId, tool, args) => {
147
+ settings: { ...(valueOf(config, 'independentRuntime', {}) ?? {}), remoteInvoke: (botId, tool, args, context) => {
96
148
  const invoker = ctx.get?.('botRemoteToolInvoker')
97
149
  if (!invoker) throw new Error('REMOTE_TOOL_SERVICE_UNAVAILABLE')
98
- return invoker.invoke(botId, tool, args)
150
+ return invoker.invoke(botId, tool, args, context)
99
151
  } },
100
152
  stateDir,
153
+ serving,
101
154
  })
102
155
  if (runtime) botRuntime = {
156
+ turn: request => runtime.turn(request),
157
+ contextOf: botId => runtime.contextOf(botId),
158
+ newConversation: (botId, options) => runtime.newConversation(botId, options),
159
+ reconcileConversation: (botId, options) => runtime.reconcileConversation(botId, options),
160
+ conversationPage: createIndependentConversationReader({ dir: runtimeSwitchPath({ settings: valueOf(config, 'independentRuntime', {}) ?? {}, stateDir }) }),
103
161
  // One row per moved Bot: the runtime it is on plus its transcript size, never message bodies.
104
162
  list: async () => runtime.inventory(runtime.list().map(row => row.botId)).map(row => ({ botId: row.botId, mode: row.runtime, changedAt: row.updatedAt ?? null, turns: row.turns, messages: row.messages })),
105
163
  move: (botId, mode) => runtime.move(botId, mode),
106
164
  history: (botId, options) => runtime.history(botId, options),
107
165
  readMessage: (botId, index) => runtime.readMessage(botId, index),
166
+ // The committed runtime, read from the switch itself. A Bot that cannot be read back is
167
+ // refused by every admission that asks, never defaulted to the integration path.
168
+ describe: botId => runtime.describe(botId),
169
+ workThreadTurn: request => runtime.workThreadTurn(request),
170
+ workThreadRead: (...args) => runtime.workThreadRead(...args),
171
+ captureTeamOrigin: request => runtime.captureTeamOrigin(request),
172
+ teamOriginCurrent: (...args) => runtime.teamOriginCurrent(...args),
173
+ resumeTeamTurn: request => runtime.resumeTeamTurn(request),
174
+ modeOf: botId => runtime.describe(botId)?.runtime ?? null,
175
+ busyBots: () => runtime.busyBots(),
176
+ dispose: () => runtime.close(),
108
177
  }
109
178
  } catch (error) {
110
179
  ctx.logger?.('model-router: independent runtime unavailable: %s', error?.message ?? error)
111
180
  }
112
181
  try { ctx.provide('botRuntimeAdapter', botRuntime) } catch { /* provided only once */ }
182
+ if (botRuntime) ctx.effect(() => () => botRuntime.dispose(), 'model-router: independent runtime')
183
+ // Where the committed mode lives, published whether or not the independent runtime was
184
+ // constructed: a Bot moved before a restart that switched it off must still be readable, so a
185
+ // Host that cannot answer "which runtime serves this Bot" refuses instead of assuming.
186
+ try {
187
+ ctx.provide('botRuntimeSwitchFile', join(runtimeSwitchPath({ settings: valueOf(config, 'independentRuntime', {}) ?? {}, stateDir }), 'runtime-switch.json'))
188
+ } catch { /* provided only once */ }
113
189
  return { botRuntime, botRouting }
114
190
  }
115
191