@abot-ai/runtime 1.7.0 → 1.8.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 (443) hide show
  1. package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
  2. package/dist/src/cli/abot.js +2 -0
  3. package/dist/src/cli/host-companion-bundle.mjs +751 -333
  4. package/dist/src/computer-access/collection-consent.d.ts +9 -0
  5. package/dist/src/computer-access/collection-consent.js +47 -0
  6. package/dist/src/computer-access/command-output-capture.d.ts +17 -6
  7. package/dist/src/computer-access/command-output-capture.js +134 -68
  8. package/dist/src/computer-access/command-output-protection.d.ts +17 -0
  9. package/dist/src/computer-access/command-output-protection.js +59 -0
  10. package/dist/src/computer-access/companion/command-output.d.ts +1 -0
  11. package/dist/src/computer-access/companion/command-output.js +23 -6
  12. package/dist/src/computer-access/companion/install-link-macos.js +2 -1
  13. package/dist/src/computer-access/companion/native-notifications.js +3 -2
  14. package/dist/src/computer-access/companion/native-session.js +6 -2
  15. package/dist/src/computer-access/companion/observation-filter.js +2 -26
  16. package/dist/src/computer-access/companion/observation-process.d.ts +2 -0
  17. package/dist/src/computer-access/companion/observation-process.js +51 -25
  18. package/dist/src/computer-access/companion/observation-redaction.d.ts +2 -7
  19. package/dist/src/computer-access/companion/observation-redaction.js +2 -111
  20. package/dist/src/computer-access/companion/secret-protection-protocol.d.ts +6 -0
  21. package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -0
  22. package/dist/src/computer-access/computer/companion-sessions.js +7 -6
  23. package/dist/src/computer-access/computer/unix-native-process.js +23 -11
  24. package/dist/src/computer-access/handlers.d.ts +2 -1
  25. package/dist/src/computer-access/handlers.js +79 -11
  26. package/dist/src/computer-access/host-observation.d.ts +3 -3
  27. package/dist/src/computer-access/native-observation-connection.d.ts +12 -0
  28. package/dist/src/computer-access/native-observation-connection.js +78 -0
  29. package/dist/src/computer-access/native-observation-ownership.d.ts +6 -0
  30. package/dist/src/computer-access/native-observation-ownership.js +55 -0
  31. package/dist/src/computer-access/native-observation-shutdown.d.ts +7 -0
  32. package/dist/src/computer-access/native-observation-shutdown.js +58 -0
  33. package/dist/src/computer-access/observation-source.d.ts +6 -0
  34. package/dist/src/computer-access/observation-source.js +10 -0
  35. package/dist/src/computer-access/security/desktop-result.d.ts +8 -0
  36. package/dist/src/computer-access/security/desktop-result.js +146 -0
  37. package/dist/src/computer-access/security/observed-error.d.ts +2 -0
  38. package/dist/src/computer-access/security/observed-error.js +10 -0
  39. package/dist/src/computer-access/security/secret-text.d.ts +7 -0
  40. package/dist/src/computer-access/security/secret-text.js +111 -0
  41. package/dist/src/computer-access/security/system-results.d.ts +2 -0
  42. package/dist/src/computer-access/security/system-results.js +53 -0
  43. package/dist/src/computer-access/system-result-protection.d.ts +11 -0
  44. package/dist/src/computer-access/system-result-protection.js +1 -0
  45. package/dist/src/model-gateway/observability/provider-response-capture.d.ts +60 -0
  46. package/dist/src/model-gateway/observability/provider-response-capture.js +68 -0
  47. package/dist/src/model-gateway/observability/provider-response-prefix.d.ts +7 -0
  48. package/dist/src/model-gateway/observability/provider-response-prefix.js +14 -0
  49. package/dist/src/model-gateway/observability/provider-response-tail.d.ts +8 -0
  50. package/dist/src/model-gateway/observability/provider-response-tail.js +28 -0
  51. package/dist/src/model-gateway/observability/provider-sse-diagnostics.d.ts +30 -0
  52. package/dist/src/model-gateway/observability/provider-sse-diagnostics.js +119 -0
  53. package/dist/src/model-gateway/observability/provider-trace.js +30 -8
  54. package/dist/src/model-gateway/providers/ollama/adapter.js +8 -2
  55. package/dist/src/model-gateway/providers/ollama/stream-normalizer.js +70 -50
  56. package/dist/src/model-gateway/providers/ollama/stream-termination.d.ts +6 -0
  57. package/dist/src/model-gateway/providers/ollama/stream-termination.js +20 -0
  58. package/dist/src/model-gateway/providers/openai/adapter.js +9 -7
  59. package/dist/src/model-gateway/providers/openai/diagnostics.d.ts +0 -1
  60. package/dist/src/model-gateway/providers/openai/diagnostics.js +0 -9
  61. package/dist/src/model-gateway/providers/openai/function-output.d.ts +11 -0
  62. package/dist/src/model-gateway/providers/openai/function-output.js +37 -0
  63. package/dist/src/model-gateway/providers/openai/function-result.d.ts +7 -0
  64. package/dist/src/model-gateway/providers/openai/function-result.js +35 -0
  65. package/dist/src/model-gateway/providers/openai/message-output-policy.d.ts +3 -0
  66. package/dist/src/model-gateway/providers/openai/message-output-policy.js +16 -0
  67. package/dist/src/model-gateway/providers/openai/payload.d.ts +0 -2
  68. package/dist/src/model-gateway/providers/openai/payload.js +6 -23
  69. package/dist/src/model-gateway/providers/openai/response-lifetime.d.ts +2 -0
  70. package/dist/src/model-gateway/providers/openai/response-lifetime.js +64 -0
  71. package/dist/src/model-gateway/providers/openai/sse-data.d.ts +9 -0
  72. package/dist/src/model-gateway/providers/openai/sse-data.js +67 -0
  73. package/dist/src/model-gateway/providers/openai/stream-normalizer.d.ts +10 -22
  74. package/dist/src/model-gateway/providers/openai/stream-normalizer.js +78 -79
  75. package/dist/src/model-gateway/providers/openai/stream.js +13 -41
  76. package/dist/src/model-gateway/providers/openai/structured-message-output.d.ts +42 -0
  77. package/dist/src/model-gateway/providers/openai/structured-message-output.js +175 -0
  78. package/dist/src/model-gateway/server.js +5 -1
  79. package/dist/src/plugin-contract/index.d.ts +1 -0
  80. package/dist/src/plugin-contract/index.js +1 -0
  81. package/dist/src/plugin-contract/manifest.d.ts +2 -0
  82. package/dist/src/plugin-contract/manifest.js +1 -0
  83. package/dist/src/plugin-contract/platform-compatibility.d.ts +16 -0
  84. package/dist/src/plugin-contract/platform-compatibility.js +3 -0
  85. package/dist/src/plugin-sdk/computer-access.d.ts +4 -0
  86. package/dist/src/plugin-sdk/computer-access.js +1 -0
  87. package/dist/src/plugin-sdk/files-windows/process.d.ts +3 -0
  88. package/dist/src/plugin-sdk/files-windows/process.js +93 -0
  89. package/dist/src/plugin-sdk/files-windows/read-script.d.ts +1 -0
  90. package/dist/src/plugin-sdk/files-windows/read-script.js +43 -0
  91. package/dist/src/plugin-sdk/files-windows/read.d.ts +6 -0
  92. package/dist/src/plugin-sdk/files-windows/read.js +56 -0
  93. package/dist/src/plugin-sdk/files-windows/result.d.ts +4 -0
  94. package/dist/src/plugin-sdk/files-windows/result.js +67 -0
  95. package/dist/src/plugin-sdk/files.js +4 -0
  96. package/dist/src/plugin-sdk/index.d.ts +1 -0
  97. package/dist/src/plugin-sdk/index.js +1 -0
  98. package/dist/src/plugin-sdk/mutation-result.d.ts +7 -0
  99. package/dist/src/plugin-sdk/mutation-result.js +11 -0
  100. package/dist/src/runtime/adapters/long-term-memory/file-lock/acquisition.js +20 -3
  101. package/dist/src/runtime/adapters/long-term-memory/file-lock/owner-record.js +3 -1
  102. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.d.ts +3 -0
  103. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.js +20 -0
  104. package/dist/src/runtime/adapters/long-term-memory/file-lock/snapshot.js +7 -3
  105. package/dist/src/runtime/adapters/passive-learning-runtime.d.ts +1 -1
  106. package/dist/src/runtime/adapters/passive-learning-runtime.js +3 -3
  107. package/dist/src/runtime/adapters/runtime-observation-connection.d.ts +5 -0
  108. package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
  109. package/dist/src/runtime/local-host/windows-private-access.js +2 -0
  110. package/dist/src/runtime/passive-learning/application-catalog.js +3 -1
  111. package/dist/src/runtime/passive-learning/collection-source.js +7 -0
  112. package/dist/src/runtime/passive-learning/service.js +2 -3
  113. package/dist/src/runtime/passive-learning/status-projection.d.ts +2 -0
  114. package/dist/src/runtime/passive-learning/status-projection.js +9 -0
  115. package/dist/src/runtime/plugins/installation/package.d.ts +8 -0
  116. package/dist/src/runtime/plugins/installation/package.js +2 -0
  117. package/dist/src/runtime/plugins/installation/service.d.ts +7 -0
  118. package/dist/src/runtime/plugins/loader.js +24 -14
  119. package/dist/src/runtime/plugins/manifest-platform-compatibility.d.ts +2 -0
  120. package/dist/src/runtime/plugins/manifest-platform-compatibility.js +39 -0
  121. package/dist/src/runtime/plugins/manifest-validator.js +9 -1
  122. package/dist/src/runtime/plugins/platform-compatibility.d.ts +4 -0
  123. package/dist/src/runtime/plugins/platform-compatibility.js +44 -0
  124. package/dist/src/runtime/request/approval-wait/activation-events.js +19 -7
  125. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.d.ts +20 -0
  126. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.js +118 -0
  127. package/dist/src/runtime/request/approval-wait/super-compaction-restore.js +2 -1
  128. package/dist/src/runtime/request/prepared-execution.js +3 -0
  129. package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +6 -0
  130. package/dist/src/runtime/steps/execution-agent/capability-result-context.js +29 -0
  131. package/dist/src/runtime/steps/execution-agent/format.js +2 -3
  132. package/dist/src/runtime/steps/execution-agent/input.js +1 -1
  133. package/dist/src/runtime/steps/execution-agent/prompt.js +5 -5
  134. package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
  135. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
  136. package/dist/src/runtime/steps/execution-agent/state-context.js +26 -35
  137. package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
  138. package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
  139. package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
  140. package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
  141. package/dist/src/sessions/durable-session-commit.js +3 -3
  142. package/dist/src/sessions/prepared-session-replacement.d.ts +6 -0
  143. package/dist/src/sessions/prepared-session-replacement.js +46 -0
  144. package/dist/src/sessions/session-store.js +3 -3
  145. package/dist/src/shared/passive-observation-self-exclusion.d.ts +5 -0
  146. package/dist/src/shared/passive-observation-self-exclusion.js +37 -0
  147. package/dist/src/shared/windows-file-io/authority-script.d.ts +1 -0
  148. package/dist/src/shared/windows-file-io/authority-script.js +94 -0
  149. package/dist/src/shared/windows-file-io/native-script.d.ts +2 -0
  150. package/dist/src/shared/windows-file-io/native-script.js +120 -0
  151. package/dist/src/shared/windows-file-io/read-bytes-script.d.ts +1 -0
  152. package/dist/src/shared/windows-file-io/read-bytes-script.js +18 -0
  153. package/dist/src/shared/windows-job-object.d.ts +2 -0
  154. package/dist/src/shared/windows-job-object.js +66 -0
  155. package/dist/src/web-ui/app/app-bootstrap.js +14 -1
  156. package/dist/src/web-ui/app/app-state.js +0 -7
  157. package/dist/src/web-ui/app/app.js +53 -156
  158. package/dist/src/web-ui/app/components/automations/node-inspector.js +3 -2
  159. package/dist/src/web-ui/app/components/automations/step-editor-dialog.js +3 -0
  160. package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
  161. package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +7 -1
  162. package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +22 -2
  163. package/dist/src/web-ui/app/components/home-guidance/daily-review.js +2 -2
  164. package/dist/src/web-ui/app/components/home-guidance/home-guidance.js +20 -6
  165. package/dist/src/web-ui/app/components/model-setup/context-window-feedback.js +53 -0
  166. package/dist/src/web-ui/app/components/model-setup/save-flow.js +3 -1
  167. package/dist/src/web-ui/app/components/model-setup/save-outcome.js +1 -0
  168. package/dist/src/web-ui/app/components/model-setup/wizard.js +12 -0
  169. package/dist/src/web-ui/app/components/passive-learning/activity-controls.js +4 -0
  170. package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
  171. package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
  172. package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
  173. package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
  174. package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
  175. package/dist/src/web-ui/app/components/passive-learning/home.js +7 -2
  176. package/dist/src/web-ui/app/components/passive-learning/macos-collection-restart-notice.js +1 -0
  177. package/dist/src/web-ui/app/components/passive-learning/memory.js +2 -4
  178. package/dist/src/web-ui/app/components/passive-learning/workspace-view.js +2 -2
  179. package/dist/src/web-ui/app/components/plugins/compatibility.js +13 -0
  180. package/dist/src/web-ui/app/components/plugins/discovery-rendering.js +9 -1
  181. package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
  182. package/dist/src/web-ui/app/components/plugins/installation.js +2 -1
  183. package/dist/src/web-ui/app/components/plugins/rendering.js +3 -0
  184. package/dist/src/web-ui/app/components/reasoning-override-prompt.js +82 -0
  185. package/dist/src/web-ui/app/components/runtime-config-activation.js +22 -8
  186. package/dist/src/web-ui/app/components/runtime-setup/optional-steps.js +7 -4
  187. package/dist/src/web-ui/app/components/runtime-setup/plugins.js +3 -1
  188. package/dist/src/web-ui/app/components/runtime-setup/rendering.js +6 -4
  189. package/dist/src/web-ui/app/components/runtime-setup-guide.d.ts +1 -0
  190. package/dist/src/web-ui/app/components/schedules/form.js +10 -8
  191. package/dist/src/web-ui/app/components/schedules/workspace.js +23 -4
  192. package/dist/src/web-ui/app/components/session-sidebar-sections.js +2 -2
  193. package/dist/src/web-ui/app/components/spark-chat/handoff-actions.js +9 -3
  194. package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
  195. package/dist/src/web-ui/app/components/spark-chat/settings.js +7 -3
  196. package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
  197. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +50 -0
  198. package/dist/src/web-ui/app/components/system-host/rendering.js +3 -0
  199. package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
  200. package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
  201. package/dist/src/web-ui/app/configuration-feature.js +9 -1
  202. package/dist/src/web-ui/app/controllers/app-event-bindings.js +38 -105
  203. package/dist/src/web-ui/app/controllers/chat-request-controller.d.ts +28 -0
  204. package/dist/src/web-ui/app/controllers/chat-request-controller.js +34 -66
  205. package/dist/src/web-ui/app/controllers/composer-attachments-controller.d.ts +15 -40
  206. package/dist/src/web-ui/app/controllers/composer-attachments-controller.js +26 -69
  207. package/dist/src/web-ui/app/controllers/composer-draft-view.d.ts +27 -0
  208. package/dist/src/web-ui/app/controllers/composer-draft-view.js +48 -0
  209. package/dist/src/web-ui/app/controllers/composer-drafts.d.ts +55 -0
  210. package/dist/src/web-ui/app/controllers/composer-drafts.js +120 -0
  211. package/dist/src/web-ui/app/controllers/composer-feature.d.ts +65 -0
  212. package/dist/src/web-ui/app/controllers/composer-feature.js +124 -0
  213. package/dist/src/web-ui/app/controllers/composer-queue-controller.d.ts +33 -94
  214. package/dist/src/web-ui/app/controllers/composer-queue-controller.js +185 -251
  215. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.d.ts +48 -0
  216. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.js +97 -0
  217. package/dist/src/web-ui/app/controllers/composer-submit-controller.d.ts +30 -61
  218. package/dist/src/web-ui/app/controllers/composer-submit-controller.js +56 -138
  219. package/dist/src/web-ui/app/controllers/composer-surface-controller.js +6 -0
  220. package/dist/src/web-ui/app/controllers/composer-workspace-controller.d.ts +22 -40
  221. package/dist/src/web-ui/app/controllers/composer-workspace-controller.js +49 -165
  222. package/dist/src/web-ui/app/controllers/conversation-navigation-intent.js +15 -0
  223. package/dist/src/web-ui/app/controllers/conversation-request-hydration.js +20 -17
  224. package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +1 -2
  225. package/dist/src/web-ui/app/controllers/conversation-session-controller.js +49 -22
  226. package/dist/src/web-ui/app/controllers/conversation-workspace-activation.js +27 -0
  227. package/dist/src/web-ui/app/controllers/daily-memory-review.js +15 -16
  228. package/dist/src/web-ui/app/controllers/environment-transition.js +126 -0
  229. package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +18 -0
  230. package/dist/src/web-ui/app/controllers/home-composer-feature.d.ts +14 -36
  231. package/dist/src/web-ui/app/controllers/home-composer-feature.js +17 -114
  232. package/dist/src/web-ui/app/controllers/home-conversation-activation.js +6 -8
  233. package/dist/src/web-ui/app/controllers/passive-learning-controller.js +56 -0
  234. package/dist/src/web-ui/app/controllers/projects-controller.d.ts +1 -1
  235. package/dist/src/web-ui/app/controllers/projects-controller.js +6 -1
  236. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +174 -0
  237. package/dist/src/web-ui/app/controllers/runtime-selection-controller.d.ts +7 -0
  238. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +20 -155
  239. package/dist/src/web-ui/app/controllers/session-controller.js +33 -17
  240. package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
  241. package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +12 -14
  242. package/dist/src/web-ui/app/controllers/spark-chat-sync.js +2 -2
  243. package/dist/src/web-ui/app/controllers/steer-controller.js +9 -7
  244. package/dist/src/web-ui/app/controllers/tool-permission-mode-controller.js +1 -1
  245. package/dist/src/web-ui/app/controllers/workspace-conversation-opener.js +34 -0
  246. package/dist/src/web-ui/app/dashboard-feature.js +3 -2
  247. package/dist/src/web-ui/app/lib/reasoning-controls.js +35 -0
  248. package/dist/src/web-ui/app/lib/session-composer-queue-ownership.js +58 -0
  249. package/dist/src/web-ui/app/lib/session-composer-queue.d.ts +12 -0
  250. package/dist/src/web-ui/app/lib/session-composer-queue.js +25 -6
  251. package/dist/src/web-ui/app/passive-learning-feature.js +16 -3
  252. package/dist/src/web-ui/app/schedules-feature.js +5 -3
  253. package/dist/src/web-ui/app/services/client-preferences.d.ts +18 -10
  254. package/dist/src/web-ui/app/services/client-preferences.js +25 -16
  255. package/dist/src/web-ui/app/services/home-guidance-preferences.js +13 -13
  256. package/dist/src/web-ui/app/services/reasoning-override.js +12 -0
  257. package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
  258. package/dist/src/web-ui/app/services/runtime-web-client/memory.js +7 -2
  259. package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +2 -0
  260. package/dist/src/web-ui/app/services/runtime-web-client.d.ts +2 -0
  261. package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
  262. package/dist/src/web-ui/app/services/server-composer-queue.js +32 -0
  263. package/dist/src/web-ui/app/services/session-sidebar-preferences.js +5 -5
  264. package/dist/src/web-ui/app/services/workspace-state-storage.js +116 -0
  265. package/dist/src/web-ui/app/services/workspace-state.js +27 -0
  266. package/dist/src/web-ui/app/spark-chat-conversation.js +34 -45
  267. package/dist/src/web-ui/app/spark-chat-feature.js +10 -4
  268. package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
  269. package/dist/src/web-ui/app/styles/41-plugin-management.css +8 -0
  270. package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +1 -0
  271. package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
  272. package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
  273. package/dist/src/web-ui/app/styles.css +2 -0
  274. package/dist/src/web-ui/client-state/contracts.d.ts +15 -0
  275. package/dist/src/web-ui/client-state/contracts.js +13 -0
  276. package/dist/src/web-ui/client-state/preference-shapes.d.ts +2 -0
  277. package/dist/src/web-ui/client-state/preference-shapes.js +80 -0
  278. package/dist/src/web-ui/client-state/preferences.d.ts +3 -0
  279. package/dist/src/web-ui/client-state/preferences.js +84 -0
  280. package/dist/src/web-ui/client-state/queue.d.ts +3 -0
  281. package/dist/src/web-ui/client-state/queue.js +43 -0
  282. package/dist/src/web-ui/client-state/routes.d.ts +7 -0
  283. package/dist/src/web-ui/client-state/routes.js +58 -0
  284. package/dist/src/web-ui/client-state/store.d.ts +14 -0
  285. package/dist/src/web-ui/client-state/store.js +88 -0
  286. package/dist/src/web-ui/local-runtime/configuration-activation-source.js +2 -0
  287. package/dist/src/web-ui/local-runtime/http.js +11 -2
  288. package/dist/src/web-ui/local-runtime/model-context-capacity-error.d.ts +14 -0
  289. package/dist/src/web-ui/local-runtime/model-context-capacity-error.js +28 -0
  290. package/dist/src/web-ui/local-runtime/model-setup-context-window.d.ts +15 -0
  291. package/dist/src/web-ui/local-runtime/model-setup-context-window.js +25 -0
  292. package/dist/src/web-ui/local-runtime/model-setup-routes.js +2 -0
  293. package/dist/src/web-ui/local-runtime/model-setup-service.js +5 -2
  294. package/dist/src/web-ui/local-runtime/model-setup-validation.d.ts +1 -0
  295. package/dist/src/web-ui/local-runtime/model-setup-validation.js +14 -7
  296. package/dist/src/web-ui/local-runtime/request-body-error.d.ts +11 -0
  297. package/dist/src/web-ui/local-runtime/request-body-error.js +14 -0
  298. package/dist/src/web-ui/local-runtime/request-control-observation.js +2 -2
  299. package/dist/src/web-ui/local-runtime/request-execution.js +18 -18
  300. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.d.ts +2 -0
  301. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.js +35 -22
  302. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.d.ts +2 -9
  303. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +4 -27
  304. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.d.ts +15 -1
  305. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.js +30 -11
  306. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.d.ts +20 -0
  307. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.js +104 -0
  308. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.d.ts +29 -0
  309. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.js +151 -0
  310. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.d.ts +7 -0
  311. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.js +87 -0
  312. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.d.ts +3 -0
  313. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.js +37 -0
  314. package/dist/src/web-ui/local-runtime/runtime-setup-service.js +4 -0
  315. package/dist/src/web-ui/local-runtime-backend.js +14 -0
  316. package/dist/src/web-ui/plugin-management-catalog.d.ts +3 -1
  317. package/dist/src/web-ui/plugin-management-catalog.js +3 -1
  318. package/dist/src/web-ui/plugin-management-service.d.ts +1 -0
  319. package/dist/src/web-ui/plugin-removal-service.d.ts +1 -0
  320. package/dist/src/web-ui/server-readiness.d.ts +3 -0
  321. package/dist/src/web-ui/server-readiness.js +36 -0
  322. package/dist/src/web-ui/server.d.ts +2 -0
  323. package/dist/src/web-ui/server.js +23 -1
  324. package/dist/src/web-ui/system-host-service.js +13 -2
  325. package/dist/src/web-ui/system-host-setup/collection-consent-route.d.ts +3 -0
  326. package/dist/src/web-ui/system-host-setup/collection-consent-route.js +30 -0
  327. package/docs/installation.md +44 -5
  328. package/docs/plugins.md +145 -4
  329. package/docs/tool-execution-result-evidence-contract.md +57 -0
  330. package/docs/windows-companion-store.md +5 -0
  331. package/package.json +4 -2
  332. package/plugins/capability-brief/plugin.json +4 -0
  333. package/plugins/code-outline/README.md +20 -0
  334. package/plugins/code-outline/plugin.json +1 -0
  335. package/plugins/code-outline/source/index.ts +16 -20
  336. package/plugins/code-outline/source/read-failure.ts +40 -0
  337. package/plugins/code-outline/src/index.cjs +614 -29
  338. package/plugins/document-reader/README.md +33 -0
  339. package/plugins/document-reader/plugin.json +1 -0
  340. package/plugins/document-reader/source/pdf-contract.ts +57 -0
  341. package/plugins/document-reader/source/pdf-parser.ts +139 -0
  342. package/plugins/document-reader/source/pdf-process-main.ts +56 -0
  343. package/plugins/document-reader/source/pdf-process.ts +207 -0
  344. package/plugins/document-reader/source/pdf-result.ts +79 -0
  345. package/plugins/document-reader/source/pdf-worker.ts +39 -303
  346. package/plugins/document-reader/source/pdf.ts +4 -1
  347. package/plugins/document-reader/source/read-failure.ts +37 -0
  348. package/plugins/document-reader/source/reader.ts +3 -19
  349. package/plugins/document-reader/src/index.cjs +995 -211
  350. package/plugins/exec/README.md +19 -0
  351. package/plugins/exec/plugin.json +4 -3
  352. package/plugins/exec/skills/exec_skill/SKILL.md +3 -2
  353. package/plugins/exec/source/filesystem-file-observer.ts +98 -0
  354. package/plugins/exec/source/filesystem-observer.ts +8 -79
  355. package/plugins/exec/source/output-files.ts +12 -6
  356. package/plugins/exec/source/paths.ts +3 -1
  357. package/plugins/exec/source/process-manager.ts +8 -24
  358. package/plugins/exec/source/shell-platform.ts +19 -3
  359. package/plugins/exec/source/shell-process.ts +55 -0
  360. package/plugins/exec/source/windows-job-source.ts +1 -0
  361. package/plugins/exec/source/windows-shell-bootstrap.ts +20 -0
  362. package/plugins/exec/src/index.cjs +252 -96
  363. package/plugins/filesystem/README.md +65 -0
  364. package/plugins/filesystem/plugin.json +6 -2
  365. package/plugins/filesystem/source/atomic-write.ts +2 -0
  366. package/plugins/filesystem/source/bounded-io.ts +80 -306
  367. package/plugins/filesystem/source/directory-sample.ts +2 -0
  368. package/plugins/filesystem/source/errors.ts +14 -0
  369. package/plugins/filesystem/source/file-observation.ts +151 -0
  370. package/plugins/filesystem/source/file-version.ts +41 -0
  371. package/plugins/filesystem/source/index.ts +6 -0
  372. package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
  373. package/plugins/filesystem/source/windows/authority-script.ts +1 -0
  374. package/plugins/filesystem/source/windows/native-script.ts +1 -0
  375. package/plugins/filesystem/source/windows/operations.ts +197 -0
  376. package/plugins/filesystem/source/windows/process.ts +214 -0
  377. package/plugins/filesystem/source/windows/publication-script.ts +29 -0
  378. package/plugins/filesystem/source/windows/read-script.ts +63 -0
  379. package/plugins/filesystem/source/windows/request-availability.ts +67 -0
  380. package/plugins/filesystem/source/windows/source.ts +42 -0
  381. package/plugins/filesystem/source/windows/storage-script.ts +11 -0
  382. package/plugins/filesystem/source/windows/streams-script.ts +24 -0
  383. package/plugins/filesystem/source/windows/write-script.ts +86 -0
  384. package/plugins/filesystem/src/index.cjs +1208 -322
  385. package/plugins/json-inspector/README.md +18 -0
  386. package/plugins/json-inspector/plugin.json +1 -0
  387. package/plugins/json-inspector/source/index.ts +16 -19
  388. package/plugins/json-inspector/source/read-failure.ts +42 -0
  389. package/plugins/json-inspector/src/index.cjs +612 -27
  390. package/plugins/local-search/README.md +29 -0
  391. package/plugins/local-search/plugin.json +1 -0
  392. package/plugins/local-search/source/errors.ts +2 -0
  393. package/plugins/local-search/source/paths.ts +3 -0
  394. package/plugins/local-search/source/ripgrep-process.ts +31 -5
  395. package/plugins/local-search/source/ripgrep.ts +3 -3
  396. package/plugins/local-search/source/windows-authority.ts +99 -0
  397. package/plugins/local-search/source/windows-search-lease.ts +49 -0
  398. package/plugins/local-search/source/windows-search-process.ts +91 -0
  399. package/plugins/local-search/source/windows-search-script.ts +52 -0
  400. package/plugins/local-search/src/index.cjs +595 -26
  401. package/plugins/memory/plugin.json +4 -0
  402. package/plugins/memory/source/lock-directory-claim.ts +56 -0
  403. package/plugins/memory/source/lock-owner-file.ts +71 -0
  404. package/plugins/memory/source/lock-path-observation.ts +26 -0
  405. package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
  406. package/plugins/memory/source/store-lock.ts +12 -7
  407. package/plugins/memory/source/store.ts +3 -2
  408. package/plugins/memory/src/index.cjs +174 -25
  409. package/plugins/project-orientation/README.md +23 -0
  410. package/plugins/project-orientation/plugin.json +1 -0
  411. package/plugins/project-orientation/source/index.ts +12 -9
  412. package/plugins/project-orientation/source/inspection-failure.ts +70 -0
  413. package/plugins/project-orientation/source/manifest-summary.ts +9 -2
  414. package/plugins/project-orientation/source/tree.ts +6 -0
  415. package/plugins/project-orientation/src/index.cjs +647 -31
  416. package/plugins/system/README.md +51 -15
  417. package/plugins/system/plugin.json +5 -1
  418. package/plugins/system/skills/system_actions/SKILL.md +1 -1
  419. package/plugins/system/source/command-working-directory.ts +47 -0
  420. package/plugins/system/source/computer/handlers.ts +13 -9
  421. package/plugins/system/source/computer/observation-result.ts +10 -5
  422. package/plugins/system/source/computer/request-computers.ts +10 -3
  423. package/plugins/system/source/computer/request-modules.ts +3 -6
  424. package/plugins/system/source/computer/runtime-platform.ts +18 -0
  425. package/plugins/system/source/host-dispatch.ts +18 -2
  426. package/plugins/system/source/index.ts +5 -3
  427. package/plugins/system/source/local-command-output-retention.ts +16 -0
  428. package/plugins/system/source/local-command-output.ts +16 -8
  429. package/plugins/system/source/request-system-modules.ts +12 -2
  430. package/plugins/system/source/request-target-snapshot.ts +2 -1
  431. package/plugins/system/source/security/desktop-result.ts +177 -0
  432. package/plugins/system/source/security/observed-error.ts +10 -0
  433. package/plugins/system/source/security/secret-text.ts +118 -0
  434. package/plugins/system/source/security/system-results.ts +62 -0
  435. package/plugins/system/source/security/windows-output-directory.ts +82 -0
  436. package/plugins/system/src/index.cjs +837 -151
  437. package/plugins/system-probe/plugin.json +8 -2
  438. package/plugins/system-probe/source/disk-path.ts +8 -0
  439. package/plugins/system-probe/source/index.ts +10 -5
  440. package/plugins/system-probe/source/machine-load.ts +33 -0
  441. package/plugins/system-probe/source/metrics.ts +6 -8
  442. package/plugins/system-probe/src/index.cjs +49 -16
  443. package/plugins/web/plugin.json +4 -0
@@ -0,0 +1,84 @@
1
+ import { isDeepStrictEqual } from "node:util";
2
+ import { ClientStateError } from "./contracts.js";
3
+ import { assertPreferenceShape, isPreferenceObject as isObject } from "./preference-shapes.js";
4
+ const scalarKeys = new Set(["abot-web.environmentId", "abot-web.lastToolPermissionMode"]);
5
+ const jsonKeys = new Set([
6
+ "abot-web.pinnedSessions", "abot-web.currentSessionByEnvironment", "abot-web.sessionModes",
7
+ "abot-web.sessionModels", "abot-web.lastModelByEnvironment", "abot-web.sessionSidebarByEnvironment",
8
+ "abot.spark.launcher.position.v1",
9
+ ]);
10
+ const modes = new Set(["ask", "full_access", "full_plus"]);
11
+ function assertBoundedJson(value, depth = 0) {
12
+ if (depth > 8)
13
+ throw new ClientStateError("invalid_preferences", "Workspace preferences are too deeply nested.");
14
+ if (!value || typeof value !== "object")
15
+ return;
16
+ for (const child of Object.values(value)) {
17
+ assertBoundedJson(child, depth + 1);
18
+ }
19
+ }
20
+ function isGuidanceKey(key) {
21
+ // encodeURIComponent leaves these punctuation characters unescaped. The
22
+ // request and state byte limits bound keys without restricting profile IDs.
23
+ return /^abot-web\.homeGuidance\.(?:[A-Za-z0-9_.!~*'()-]|%[0-9A-Fa-f]{2})+$/.test(key);
24
+ }
25
+ export function decodePreference(key, value) {
26
+ if (!scalarKeys.has(key) && !jsonKeys.has(key) && !isGuidanceKey(key))
27
+ throw new ClientStateError("invalid_preferences", "Unknown workspace preference.");
28
+ if (value === null)
29
+ return undefined;
30
+ if (typeof value !== "string" || value.length > 524_288)
31
+ throw new ClientStateError("invalid_preferences", "Invalid workspace preference value.");
32
+ if (scalarKeys.has(key)) {
33
+ if (key.endsWith("lastToolPermissionMode") && !modes.has(value))
34
+ throw new ClientStateError("invalid_preferences", "Select Ask, Full or Full+.");
35
+ return value;
36
+ }
37
+ let decoded;
38
+ try {
39
+ decoded = JSON.parse(value);
40
+ }
41
+ catch {
42
+ throw new ClientStateError("invalid_preferences", "Workspace preferences must contain JSON.");
43
+ }
44
+ assertBoundedJson(decoded);
45
+ assertPreferenceShape(key, decoded);
46
+ return decoded;
47
+ }
48
+ function ownPreferenceField(record, key) {
49
+ return Object.hasOwn(record, key) ? record[key] : undefined;
50
+ }
51
+ function mergeChangedFields(before, after, current) {
52
+ if (isDeepStrictEqual(before, after))
53
+ return current;
54
+ if (before === undefined && isObject(after) && isObject(current))
55
+ return mergeChangedFields({}, after, current);
56
+ if (isObject(before) && isObject(after) && isObject(current)) {
57
+ const result = Object.assign(Object.create(null), current);
58
+ for (const key of new Set([...Object.keys(before), ...Object.keys(after)])) {
59
+ const next = mergeChangedFields(ownPreferenceField(before, key), ownPreferenceField(after, key), ownPreferenceField(current, key));
60
+ if (next === undefined)
61
+ delete result[key];
62
+ else
63
+ result[key] = next;
64
+ }
65
+ return result;
66
+ }
67
+ if (!isDeepStrictEqual(current, before) && !isDeepStrictEqual(current, after))
68
+ throw new ClientStateError("preferences_changed", "These settings changed in another window. Reload before saving again.", 409);
69
+ return after;
70
+ }
71
+ export function updatePreference(preferences, input) {
72
+ const key = typeof input.key === "string" ? input.key : "";
73
+ const before = decodePreference(key, input.before);
74
+ const after = decodePreference(key, input.value);
75
+ const current = decodePreference(key, preferences[key] ?? null);
76
+ const merged = mergeChangedFields(before, after, current);
77
+ if (merged === undefined) {
78
+ delete preferences[key];
79
+ return;
80
+ }
81
+ const value = scalarKeys.has(key) ? String(merged) : JSON.stringify(merged);
82
+ decodePreference(key, value);
83
+ preferences[key] = value;
84
+ }
@@ -0,0 +1,3 @@
1
+ import { type ClientState } from "./contracts.js";
2
+ /** Runs within the store transaction: a queue item can be released by only one caller. */
3
+ export declare function changeClientQueue(state: ClientState, input: Record<string, unknown>): unknown;
@@ -0,0 +1,43 @@
1
+ import { createSessionComposerQueue } from "../app/lib/session-composer-queue.js";
2
+ import { ClientStateError } from "./contracts.js";
3
+ function queueScope(input) {
4
+ if (!input || typeof input !== "object")
5
+ throw new ClientStateError("invalid_queue_scope", "A conversation is required.");
6
+ const scope = input;
7
+ for (const value of [scope.environmentId, scope.sessionId]) {
8
+ if (typeof value !== "string" || !value.trim())
9
+ throw new ClientStateError("invalid_queue_scope", "Invalid conversation identity.");
10
+ }
11
+ return { environmentId: scope.environmentId, sessionId: scope.sessionId };
12
+ }
13
+ /** Runs within the store transaction: a queue item can be released by only one caller. */
14
+ export function changeClientQueue(state, input) {
15
+ const scope = queueScope(input.scope);
16
+ const ownerId = typeof input.ownerId === "string" && input.ownerId.length <= 128 ? input.ownerId : null;
17
+ const requiresRecoveryOwner = ["claim", "begin", "uncertain"].includes(String(input.action));
18
+ if (requiresRecoveryOwner && !ownerId)
19
+ throw new ClientStateError("invalid_queue_owner", "A window identity is required to recover a queued message.");
20
+ const queue = createSessionComposerQueue({ ownerId, storage: {
21
+ getItem: () => state.queue || null,
22
+ setItem: (_key, value) => { state.queue = value; },
23
+ } });
24
+ const token = typeof input.releaseToken === "string" ? input.releaseToken : "";
25
+ const requestId = typeof input.requestId === "string" ? input.requestId : "";
26
+ if (input.action === "claim")
27
+ return queue.claimBlockedRelease(scope, token, { takeover: input.takeover === true });
28
+ if (input.action === "begin")
29
+ return queue.beginBlockedSend(scope, token);
30
+ if (input.action === "uncertain")
31
+ return queue.markBlockedUncertain(scope, token);
32
+ if (input.action === "enqueue")
33
+ return queue.enqueue(scope, input.item);
34
+ if (input.action === "release")
35
+ return queue.releaseForTerminal(scope, requestId);
36
+ if (input.action === "bind")
37
+ return queue.bindReleasedSuccess(scope, token, requestId);
38
+ if (input.action === "rebind")
39
+ return queue.rebindBlocked(scope, requestId);
40
+ if (input.action === "update")
41
+ return queue.updateBlockedRelease(scope, token, input.item);
42
+ throw new ClientStateError("invalid_queue_action", "Unknown message queue operation.");
43
+ }
@@ -0,0 +1,7 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ export declare class WebClientStateRoutes {
3
+ private readonly changed;
4
+ private readonly store;
5
+ constructor(rootDir: string, changed?: () => void);
6
+ handle(request: IncomingMessage, response: ServerResponse, pathname: string): Promise<boolean>;
7
+ }
@@ -0,0 +1,58 @@
1
+ import { acceptConfigMutationRequest } from "../local-runtime/config-mutation-request.js";
2
+ import { readBody, readJsonBody, sendJson } from "../local-runtime/http.js";
3
+ import { ClientStateError } from "./contracts.js";
4
+ import { updatePreference } from "./preferences.js";
5
+ import { WebClientStateStore } from "./store.js";
6
+ import { changeClientQueue } from "./queue.js";
7
+ export class WebClientStateRoutes {
8
+ changed;
9
+ store;
10
+ constructor(rootDir, changed = () => { }) {
11
+ this.changed = changed;
12
+ this.store = new WebClientStateStore(rootDir);
13
+ }
14
+ async handle(request, response, pathname) {
15
+ if (pathname !== "/web-ui-state")
16
+ return false;
17
+ response.setHeader("cache-control", "no-store");
18
+ try {
19
+ if (request.method === "GET") {
20
+ const { state } = await this.store.transaction(() => null);
21
+ sendJson(response, 200, { ok: true, state });
22
+ return true;
23
+ }
24
+ if (request.method !== "POST") {
25
+ sendJson(response, 405, { ok: false, error: "method_not_allowed" });
26
+ return true;
27
+ }
28
+ if (!acceptConfigMutationRequest(request, response))
29
+ return true;
30
+ const input = readJsonBody(await readBody(request, { maxBytes: 1024 * 1024 }));
31
+ const saved = await this.store.transaction((state) => {
32
+ if (input.kind === "preference") {
33
+ updatePreference(state.preferences, input);
34
+ return null;
35
+ }
36
+ if (input.kind === "queue")
37
+ return changeClientQueue(state, input);
38
+ if (input.kind === "introduction") {
39
+ state.introductionSeen = true;
40
+ return null;
41
+ }
42
+ throw new ClientStateError("invalid_state_operation", "Unknown workspace state operation.");
43
+ });
44
+ sendJson(response, 200, { ok: true, ...saved });
45
+ try {
46
+ this.changed();
47
+ }
48
+ catch { /* Persistence already succeeded; clients also refresh on focus. */ }
49
+ }
50
+ catch (error) {
51
+ const known = error instanceof ClientStateError;
52
+ sendJson(response, known ? error.status : 500, { ok: false,
53
+ error: known ? error.code : "workspace_state_unavailable",
54
+ message: known ? error.message : "Workspace settings could not be saved or loaded. Existing data was preserved. Reload before continuing." });
55
+ }
56
+ return true;
57
+ }
58
+ }
@@ -0,0 +1,14 @@
1
+ import { type ClientState } from "./contracts.js";
2
+ /** One installation; independent of listener ports, browser profiles and operating system. */
3
+ export declare class WebClientStateStore {
4
+ private initialization?;
5
+ readonly directory: string;
6
+ readonly path: string;
7
+ constructor(rootDir: string);
8
+ private load;
9
+ private save;
10
+ transaction<T>(operation: (state: ClientState) => T): Promise<{
11
+ result: T;
12
+ state: ClientState;
13
+ }>;
14
+ }
@@ -0,0 +1,88 @@
1
+ import { open, readFile, rm, lstat } from "node:fs/promises";
2
+ import { join, resolve } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { withFileLock } from "../../runtime/adapters/long-term-memory/file-lock.js";
5
+ import { ensurePrivateRuntimeDirectory } from "../../runtime/local-host/private-directory.js";
6
+ import { replacePreparedSessionFile } from "../../sessions/prepared-session-replacement.js";
7
+ import { isPersistedStore } from "../app/lib/session-composer-queue.js";
8
+ import { ClientStateError, emptyClientState } from "./contracts.js";
9
+ import { decodePreference } from "./preferences.js";
10
+ const maxStateBytes = 8 * 1024 * 1024;
11
+ function decodeState(raw) {
12
+ const state = JSON.parse(raw);
13
+ if (state?.version !== 1 || !Number.isSafeInteger(state.revision) || state.revision < 0 ||
14
+ typeof state.introductionSeen !== "boolean" || !state.preferences ||
15
+ typeof state.preferences !== "object" || Array.isArray(state.preferences) || typeof state.queue !== "string")
16
+ throw new Error("Workspace state is invalid. Its existing file has been preserved.");
17
+ for (const [key, value] of Object.entries(state.preferences))
18
+ decodePreference(key, value);
19
+ if (state.queue && !isPersistedStore(JSON.parse(state.queue)))
20
+ throw new Error("Saved message queue is invalid. Its existing file has been preserved.");
21
+ return state;
22
+ }
23
+ /** One installation; independent of listener ports, browser profiles and operating system. */
24
+ export class WebClientStateStore {
25
+ initialization;
26
+ directory;
27
+ path;
28
+ constructor(rootDir) {
29
+ this.directory = resolve(rootDir, ".runtime", "web-ui", "client-state");
30
+ this.path = join(this.directory, "state.json");
31
+ }
32
+ async load() {
33
+ try {
34
+ const info = await lstat(this.path);
35
+ if (!info.isFile() || info.isSymbolicLink() || info.size > maxStateBytes)
36
+ throw new Error("Workspace state must be a bounded regular file.");
37
+ return decodeState(await readFile(this.path, "utf8"));
38
+ }
39
+ catch (error) {
40
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT")
41
+ return emptyClientState();
42
+ throw error;
43
+ }
44
+ }
45
+ async save(state) {
46
+ const raw = JSON.stringify(state);
47
+ if (Buffer.byteLength(raw) > maxStateBytes)
48
+ throw new ClientStateError("workspace_storage_full", "Workspace settings and queued messages exceed their storage limit. No saved data was discarded.", 413);
49
+ decodeState(raw);
50
+ const temporary = `${this.path}.${randomUUID()}.tmp`;
51
+ try {
52
+ const file = await open(temporary, "wx", 0o600);
53
+ try {
54
+ await file.writeFile(raw);
55
+ await file.sync();
56
+ }
57
+ finally {
58
+ await file.close();
59
+ }
60
+ await replacePreparedSessionFile(temporary, this.path);
61
+ }
62
+ finally {
63
+ await rm(temporary, { force: true });
64
+ }
65
+ }
66
+ async transaction(operation) {
67
+ const initializing = this.initialization ??= ensurePrivateRuntimeDirectory(this.directory);
68
+ try {
69
+ await initializing;
70
+ }
71
+ catch (error) {
72
+ // A later explicit reload may try again after the directory is repaired.
73
+ if (this.initialization === initializing)
74
+ this.initialization = undefined;
75
+ throw error;
76
+ }
77
+ return withFileLock(join(this.directory, "state.lock"), async () => {
78
+ const state = await this.load();
79
+ const before = JSON.stringify(state);
80
+ const result = operation(state);
81
+ if (JSON.stringify(state) !== before) {
82
+ state.revision += 1;
83
+ await this.save(state);
84
+ }
85
+ return { result, state };
86
+ });
87
+ }
88
+ }
@@ -1,3 +1,4 @@
1
+ import { requireRuntimeSetupEditSettled } from "./runtime-setup-edit-recovery.js";
1
2
  import { withPluginConfigurationLock } from "../../runtime/plugins/configuration-write.js";
2
3
  import { ConfigFileConflictError, withConfigFileTransaction, } from "../../runtime/adapters/config-file-transaction.js";
3
4
  import { resolveRequestRunnerConfigReference } from "../../runtime/config/request-runner-config.js";
@@ -10,6 +11,7 @@ function restoreUnappliedRequestRunner(activation, preparation) {
10
11
  /** Cooperating root and linked-file saves wait for activation or restoration to finish. */
11
12
  export function withConfigurationActivationSource(configPath, operation, expectedRevision, pluginRootDir) {
12
13
  return withConfigFileTransaction(configPath, async (transaction) => {
14
+ requireRuntimeSetupEditSettled(pluginRootDir ?? process.cwd());
13
15
  if (expectedRevision !== undefined &&
14
16
  transaction.snapshot.revision !== expectedRevision)
15
17
  throw new ConfigFileConflictError();
@@ -1,3 +1,4 @@
1
+ import { RequestBodyInputError } from "./request-body-error.js";
1
2
  export function sendJson(res, statusCode, payload) {
2
3
  res.writeHead(statusCode, {
3
4
  "content-type": "application/json; charset=utf-8",
@@ -52,9 +53,17 @@ export function getNumber(value) {
52
53
  export function readJsonBody(body) {
53
54
  if (body.length === 0)
54
55
  return {};
55
- const parsed = JSON.parse(body.toString("utf8"));
56
+ let parsed;
57
+ try {
58
+ parsed = JSON.parse(body.toString("utf8"));
59
+ }
60
+ catch (error) {
61
+ if (!(error instanceof SyntaxError))
62
+ throw error;
63
+ throw new RequestBodyInputError("invalid_json");
64
+ }
56
65
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
57
- throw new Error("JSON object body required");
66
+ throw new RequestBodyInputError("json_object_required");
58
67
  }
59
68
  return parsed;
60
69
  }
@@ -0,0 +1,14 @@
1
+ import type { ModelContextCapacityIssue } from "../../runtime/config/model-context-capacity.js";
2
+ export type PublicContextWindowIssue = Readonly<{
3
+ field: "contextWindowTokens";
4
+ declaredTokens: number;
5
+ effectiveTokens: number;
6
+ reservedTokens: number;
7
+ minimumTokens: number;
8
+ allocationTokens?: number;
9
+ environmentId?: string;
10
+ }>;
11
+ export declare function readModelContextCapacityIssue(error: unknown, profileId: string): ModelContextCapacityIssue | undefined;
12
+ export declare function modelContextCapacityMessage(issue: ModelContextCapacityIssue): string;
13
+ /** Project known capacity evidence without exposing config paths or raw issues. */
14
+ export declare function publicContextWindowIssue(issue: ModelContextCapacityIssue, environmentId?: string): PublicContextWindowIssue;
@@ -0,0 +1,28 @@
1
+ import { RuntimeConfigValidationError } from "../../runtime/config/validation.js";
2
+ export function readModelContextCapacityIssue(error, profileId) {
3
+ if (!(error instanceof RuntimeConfigValidationError))
4
+ return undefined;
5
+ return error.capacityIssues.find((issue) => issue.profileId === profileId);
6
+ }
7
+ export function modelContextCapacityMessage(issue) {
8
+ const capacity = `The effective context window is ${issue.effectiveTokens} tokens, but the configured reserves require more than ${issue.reservedTokens} tokens. Use a model-supported context window of at least ${issue.minimumTokens} tokens or adjust the configured reserves.`;
9
+ if (issue.allocationTokens === undefined)
10
+ return capacity;
11
+ if (issue.allocationTokens >= issue.minimumTokens)
12
+ return capacity;
13
+ return `${capacity} The Ollama num_ctx allocation of ${issue.allocationTokens} tokens must also support that window.`;
14
+ }
15
+ /** Project known capacity evidence without exposing config paths or raw issues. */
16
+ export function publicContextWindowIssue(issue, environmentId) {
17
+ return {
18
+ field: "contextWindowTokens",
19
+ declaredTokens: issue.declaredTokens,
20
+ effectiveTokens: issue.effectiveTokens,
21
+ reservedTokens: issue.reservedTokens,
22
+ minimumTokens: issue.minimumTokens,
23
+ ...(issue.allocationTokens === undefined
24
+ ? {}
25
+ : { allocationTokens: issue.allocationTokens }),
26
+ ...(environmentId === undefined ? {} : { environmentId }),
27
+ };
28
+ }
@@ -0,0 +1,15 @@
1
+ import type { ModelContextCapacityIssue } from "../../runtime/config/model-context-capacity.js";
2
+ import { ModelSetupError } from "./model-setup-input.js";
3
+ import { type PublicContextWindowIssue } from "./model-context-capacity-error.js";
4
+ type ModelSetupContextWindowIssue = PublicContextWindowIssue & Readonly<{
5
+ profileId: string;
6
+ }>;
7
+ export declare class ModelSetupContextWindowError extends ModelSetupError {
8
+ readonly contextWindow: ModelSetupContextWindowIssue;
9
+ constructor(issue: ModelContextCapacityIssue, environmentId?: string);
10
+ }
11
+ export declare function throwModelSetupValidationError(error: unknown, profileId: string | undefined, environmentId?: string): never;
12
+ export declare function modelSetupContextWindowErrorDetails(error: unknown): {
13
+ contextWindow?: ModelSetupContextWindowIssue;
14
+ };
15
+ export {};
@@ -0,0 +1,25 @@
1
+ import { ModelSetupError } from "./model-setup-input.js";
2
+ import { modelContextCapacityMessage, publicContextWindowIssue, readModelContextCapacityIssue, } from "./model-context-capacity-error.js";
3
+ export class ModelSetupContextWindowError extends ModelSetupError {
4
+ contextWindow;
5
+ constructor(issue, environmentId) {
6
+ super("context_window_too_small", modelContextCapacityMessage(issue));
7
+ this.contextWindow = {
8
+ ...publicContextWindowIssue(issue, environmentId),
9
+ profileId: issue.profileId,
10
+ };
11
+ }
12
+ }
13
+ export function throwModelSetupValidationError(error, profileId, environmentId) {
14
+ if (profileId === undefined)
15
+ throw error;
16
+ const issue = readModelContextCapacityIssue(error, profileId);
17
+ if (!issue)
18
+ throw error;
19
+ throw new ModelSetupContextWindowError(issue, environmentId);
20
+ }
21
+ export function modelSetupContextWindowErrorDetails(error) {
22
+ if (!(error instanceof ModelSetupContextWindowError))
23
+ return {};
24
+ return { contextWindow: error.contextWindow };
25
+ }
@@ -1,5 +1,6 @@
1
1
  import { assertConfigMutationRequest, ConfigMutationRequestError, } from "./config-mutation-request.js";
2
2
  import { readBody, readJsonBody, sendJson } from "./http.js";
3
+ import { modelSetupContextWindowErrorDetails } from "./model-setup-context-window.js";
3
4
  import { ModelSetupError } from "./model-setup-input.js";
4
5
  export class ModelSetupRoutes {
5
6
  service;
@@ -40,6 +41,7 @@ export class ModelSetupRoutes {
40
41
  error instanceof ConfigMutationRequestError;
41
42
  sendJson(params.response, known ? error.statusCode : 400, {
42
43
  ok: false,
44
+ ...modelSetupContextWindowErrorDetails(error),
43
45
  error: error instanceof ModelSetupError ? error.code : "model_setup_failed",
44
46
  message: known
45
47
  ? error.message
@@ -92,14 +92,17 @@ export class ModelSetupService {
92
92
  provider: provider.config,
93
93
  profile,
94
94
  };
95
- await validateModelAddition(mergeRuntimeModelAddition(source, addition).config, options);
95
+ await validateModelAddition(mergeRuntimeModelAddition(source, addition).config, { ...options, modelProfileId: input.profileId });
96
96
  const credential = await prepareModelCredential(options, provider.config, input.apiKey);
97
97
  return withModelSetupProfile(options, transaction, input.profileId, profile, async (declaration, assertProfileUnchanged) => {
98
98
  const candidate = mergeRuntimeModelAddition(source, {
99
99
  ...addition,
100
100
  profile: declaration,
101
101
  }).config;
102
- await validateModelAddition(candidate, options);
102
+ await validateModelAddition(candidate, {
103
+ ...options,
104
+ modelProfileId: input.profileId,
105
+ });
103
106
  await assertProfileUnchanged();
104
107
  await this.commit(options, candidate, transaction, credential, assertProfileUnchanged);
105
108
  return modelSetupResult(provider, input);
@@ -2,5 +2,6 @@
2
2
  export declare function validateModelConfigurationChange(config: Record<string, unknown>, options: {
3
3
  rootDir: string;
4
4
  configPath: string;
5
+ modelProfileId?: string;
5
6
  }): Promise<void>;
6
7
  export { validateModelConfigurationChange as validateModelAddition };
@@ -1,6 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { rm, writeFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
+ import { throwModelSetupValidationError } from "./model-setup-context-window.js";
4
5
  import { loadRuntimeConfig } from "../../runtime/config.js";
5
6
  import { isRecord } from "../../runtime/config/utils.js";
6
7
  import { validateRuntimeConfigFile } from "../../runtime/config/validation.js";
@@ -19,13 +20,19 @@ export async function validateModelConfigurationChange(config, options) {
19
20
  ? Object.keys(environment.profiles)
20
21
  : [];
21
22
  const environments = profileIds.length ? profileIds : [undefined];
22
- for (const profileId of environments)
23
- loadRuntimeConfig({
24
- rootDir: options.rootDir,
25
- configPath: temporary,
26
- profileId,
27
- env: { ...process.env },
28
- });
23
+ for (const environmentId of environments) {
24
+ try {
25
+ loadRuntimeConfig({
26
+ rootDir: options.rootDir,
27
+ configPath: temporary,
28
+ profileId: environmentId,
29
+ env: { ...process.env },
30
+ });
31
+ }
32
+ catch (error) {
33
+ throwModelSetupValidationError(error, options.modelProfileId, environmentId);
34
+ }
35
+ }
29
36
  }
30
37
  finally {
31
38
  await rm(temporary, { force: true });
@@ -0,0 +1,11 @@
1
+ declare const REQUEST_BODY_ERROR_MESSAGES: {
2
+ readonly invalid_json: "Request body must contain valid JSON.";
3
+ readonly json_object_required: "Request body must be a JSON object.";
4
+ };
5
+ /** A client syntax/shape failure, distinct from unexpected backend exceptions. */
6
+ export declare class RequestBodyInputError extends Error {
7
+ readonly code: keyof typeof REQUEST_BODY_ERROR_MESSAGES;
8
+ readonly statusCode = 400;
9
+ constructor(code: keyof typeof REQUEST_BODY_ERROR_MESSAGES);
10
+ }
11
+ export {};
@@ -0,0 +1,14 @@
1
+ const REQUEST_BODY_ERROR_MESSAGES = {
2
+ invalid_json: "Request body must contain valid JSON.",
3
+ json_object_required: "Request body must be a JSON object.",
4
+ };
5
+ /** A client syntax/shape failure, distinct from unexpected backend exceptions. */
6
+ export class RequestBodyInputError extends Error {
7
+ code;
8
+ statusCode = 400;
9
+ constructor(code) {
10
+ super(REQUEST_BODY_ERROR_MESSAGES[code]);
11
+ this.code = code;
12
+ this.name = "RequestBodyInputError";
13
+ }
14
+ }
@@ -22,10 +22,10 @@ export function traceWebProjection(event, requestId, active, reason, removed) {
22
22
  });
23
23
  }
24
24
  export function webSteerRoute(active, steer) {
25
- if (!active)
26
- return "web_projection_missing";
27
25
  if (steer)
28
26
  return "runtime_owner";
27
+ if (!active)
28
+ return "web_projection_missing";
29
29
  return "local_inbox";
30
30
  }
31
31
  /** Observes the existing routing decision; it never queries or changes an owner. */
@@ -174,26 +174,15 @@ export class LocalRequestExecution {
174
174
  observation.selectRoute("interactive_session_check");
175
175
  const sessions = resolveEnvironment(active.environmentId).services
176
176
  .sessions;
177
- try {
178
- await sessions.assertInteractiveSession?.(active.sessionId);
179
- }
180
- catch (error) {
181
- if (!isAutomationSessionLockedError(error))
182
- throw error;
183
- const acknowledgement = {
184
- type: "steer_ack",
185
- requestId,
186
- steerId,
187
- accepted: false,
188
- reason: "automation_session_locked",
189
- };
190
- observation.result(acknowledgement);
191
- return acknowledgement;
192
- }
177
+ await sessions.assertInteractiveSession?.(active.sessionId);
193
178
  }
194
179
  observation.selectRoute("environment_resolution");
195
- const steer = active
196
- ? resolveEnvironment(active.environmentId).requests.steer
180
+ // Saved approval waits retire the Web view; their resumed owner remains
181
+ // authoritative. Never infer inactivity from a missing local projection.
182
+ const steeringEnvironmentId = active?.environmentId ?? getString(message.environment).trim();
183
+ const hasSteeringEnvironment = steeringEnvironmentId.length > 0;
184
+ const steer = hasSteeringEnvironment
185
+ ? resolveEnvironment(steeringEnvironmentId).requests.steer
197
186
  : undefined;
198
187
  observation.selectRoute(webSteerRoute(active, steer));
199
188
  const result = (steer
@@ -219,6 +208,17 @@ export class LocalRequestExecution {
219
208
  return acknowledgement;
220
209
  }
221
210
  catch (error) {
211
+ if (isAutomationSessionLockedError(error)) {
212
+ const acknowledgement = {
213
+ type: "steer_ack",
214
+ requestId,
215
+ steerId,
216
+ accepted: false,
217
+ reason: "automation_session_locked",
218
+ };
219
+ observation.result(acknowledgement);
220
+ return acknowledgement;
221
+ }
222
222
  observation.failed(error);
223
223
  throw error;
224
224
  }
@@ -1,3 +1,4 @@
1
+ import { type RuntimeSetupCredentialWrite } from "./runtime-setup-credentials.js";
1
2
  import { type RuntimeSetupInput } from "./runtime-setup-input.js";
2
3
  import { type RuntimeSetupDraft } from "./runtime-setup-draft.js";
3
4
  /** Applies only fields owned by the unfinished wizard, retaining optional-step edits. */
@@ -7,6 +8,7 @@ export declare function editRuntimeSetupConnection(params: {
7
8
  draft: RuntimeSetupDraft;
8
9
  input: RuntimeSetupInput;
9
10
  credentialChanged: boolean;
11
+ credentialWrite: RuntimeSetupCredentialWrite;
10
12
  }): Promise<{
11
13
  draft: RuntimeSetupDraft;
12
14
  embeddingInvalidated: boolean;