@abot-ai/runtime 1.7.0 → 1.8.1

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 (532) hide show
  1. package/README.md +216 -222
  2. package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
  3. package/dist/src/capabilities/tool-request-resources.d.ts +3 -0
  4. package/dist/src/capabilities/tool-types.d.ts +4 -0
  5. package/dist/src/cli/abot.js +2 -0
  6. package/dist/src/cli/host-companion-bundle.mjs +751 -333
  7. package/dist/src/computer-access/collection-consent.d.ts +9 -0
  8. package/dist/src/computer-access/collection-consent.js +47 -0
  9. package/dist/src/computer-access/command-output-capture.d.ts +17 -6
  10. package/dist/src/computer-access/command-output-capture.js +134 -68
  11. package/dist/src/computer-access/command-output-protection.d.ts +17 -0
  12. package/dist/src/computer-access/command-output-protection.js +59 -0
  13. package/dist/src/computer-access/companion/command-output.d.ts +1 -0
  14. package/dist/src/computer-access/companion/command-output.js +23 -6
  15. package/dist/src/computer-access/companion/install-link-macos.js +2 -1
  16. package/dist/src/computer-access/companion/native-notifications.js +3 -2
  17. package/dist/src/computer-access/companion/native-session.js +6 -2
  18. package/dist/src/computer-access/companion/observation-filter.js +2 -26
  19. package/dist/src/computer-access/companion/observation-process.d.ts +2 -0
  20. package/dist/src/computer-access/companion/observation-process.js +51 -25
  21. package/dist/src/computer-access/companion/observation-redaction.d.ts +2 -7
  22. package/dist/src/computer-access/companion/observation-redaction.js +2 -111
  23. package/dist/src/computer-access/companion/secret-protection-protocol.d.ts +6 -0
  24. package/dist/src/computer-access/companion/secret-protection-protocol.js +6 -0
  25. package/dist/src/computer-access/computer/companion-sessions.js +7 -6
  26. package/dist/src/computer-access/computer/unix-native-process.js +23 -11
  27. package/dist/src/computer-access/handlers.d.ts +2 -1
  28. package/dist/src/computer-access/handlers.js +79 -11
  29. package/dist/src/computer-access/host-observation.d.ts +3 -3
  30. package/dist/src/computer-access/native-observation-connection.d.ts +12 -0
  31. package/dist/src/computer-access/native-observation-connection.js +78 -0
  32. package/dist/src/computer-access/native-observation-ownership.d.ts +6 -0
  33. package/dist/src/computer-access/native-observation-ownership.js +55 -0
  34. package/dist/src/computer-access/native-observation-shutdown.d.ts +7 -0
  35. package/dist/src/computer-access/native-observation-shutdown.js +58 -0
  36. package/dist/src/computer-access/observation-source.d.ts +6 -0
  37. package/dist/src/computer-access/observation-source.js +10 -0
  38. package/dist/src/computer-access/security/desktop-result.d.ts +8 -0
  39. package/dist/src/computer-access/security/desktop-result.js +146 -0
  40. package/dist/src/computer-access/security/observed-error.d.ts +2 -0
  41. package/dist/src/computer-access/security/observed-error.js +10 -0
  42. package/dist/src/computer-access/security/secret-text.d.ts +7 -0
  43. package/dist/src/computer-access/security/secret-text.js +111 -0
  44. package/dist/src/computer-access/security/system-results.d.ts +2 -0
  45. package/dist/src/computer-access/security/system-results.js +53 -0
  46. package/dist/src/computer-access/system-result-protection.d.ts +11 -0
  47. package/dist/src/computer-access/system-result-protection.js +1 -0
  48. package/dist/src/model-gateway/observability/provider-response-capture.d.ts +60 -0
  49. package/dist/src/model-gateway/observability/provider-response-capture.js +68 -0
  50. package/dist/src/model-gateway/observability/provider-response-prefix.d.ts +7 -0
  51. package/dist/src/model-gateway/observability/provider-response-prefix.js +14 -0
  52. package/dist/src/model-gateway/observability/provider-response-tail.d.ts +8 -0
  53. package/dist/src/model-gateway/observability/provider-response-tail.js +28 -0
  54. package/dist/src/model-gateway/observability/provider-sse-diagnostics.d.ts +30 -0
  55. package/dist/src/model-gateway/observability/provider-sse-diagnostics.js +119 -0
  56. package/dist/src/model-gateway/observability/provider-trace.js +30 -8
  57. package/dist/src/model-gateway/protocol/message-contract.d.ts +1 -0
  58. package/dist/src/model-gateway/protocol/message-contract.js +1 -1
  59. package/dist/src/model-gateway/providers/ollama/adapter.js +8 -2
  60. package/dist/src/model-gateway/providers/ollama/stream-normalizer.js +70 -50
  61. package/dist/src/model-gateway/providers/ollama/stream-termination.d.ts +6 -0
  62. package/dist/src/model-gateway/providers/ollama/stream-termination.js +20 -0
  63. package/dist/src/model-gateway/providers/openai/adapter.js +9 -7
  64. package/dist/src/model-gateway/providers/openai/diagnostics.d.ts +0 -1
  65. package/dist/src/model-gateway/providers/openai/diagnostics.js +0 -9
  66. package/dist/src/model-gateway/providers/openai/function-output.d.ts +11 -0
  67. package/dist/src/model-gateway/providers/openai/function-output.js +37 -0
  68. package/dist/src/model-gateway/providers/openai/function-result.d.ts +7 -0
  69. package/dist/src/model-gateway/providers/openai/function-result.js +35 -0
  70. package/dist/src/model-gateway/providers/openai/message-output-policy.d.ts +3 -0
  71. package/dist/src/model-gateway/providers/openai/message-output-policy.js +16 -0
  72. package/dist/src/model-gateway/providers/openai/payload.d.ts +0 -2
  73. package/dist/src/model-gateway/providers/openai/payload.js +6 -23
  74. package/dist/src/model-gateway/providers/openai/response-lifetime.d.ts +2 -0
  75. package/dist/src/model-gateway/providers/openai/response-lifetime.js +64 -0
  76. package/dist/src/model-gateway/providers/openai/sse-data.d.ts +9 -0
  77. package/dist/src/model-gateway/providers/openai/sse-data.js +67 -0
  78. package/dist/src/model-gateway/providers/openai/stream-normalizer.d.ts +10 -22
  79. package/dist/src/model-gateway/providers/openai/stream-normalizer.js +78 -79
  80. package/dist/src/model-gateway/providers/openai/stream.js +13 -41
  81. package/dist/src/model-gateway/providers/openai/structured-message-output.d.ts +42 -0
  82. package/dist/src/model-gateway/providers/openai/structured-message-output.js +175 -0
  83. package/dist/src/model-gateway/server/chat-handler.js +5 -7
  84. package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
  85. package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
  86. package/dist/src/model-gateway/server.js +5 -1
  87. package/dist/src/plugin-contract/index.d.ts +1 -0
  88. package/dist/src/plugin-contract/index.js +1 -0
  89. package/dist/src/plugin-contract/manifest.d.ts +2 -0
  90. package/dist/src/plugin-contract/manifest.js +1 -0
  91. package/dist/src/plugin-contract/platform-compatibility.d.ts +16 -0
  92. package/dist/src/plugin-contract/platform-compatibility.js +3 -0
  93. package/dist/src/plugin-sdk/computer-access.d.ts +4 -0
  94. package/dist/src/plugin-sdk/computer-access.js +1 -0
  95. package/dist/src/plugin-sdk/files-windows/process.d.ts +3 -0
  96. package/dist/src/plugin-sdk/files-windows/process.js +93 -0
  97. package/dist/src/plugin-sdk/files-windows/read-script.d.ts +1 -0
  98. package/dist/src/plugin-sdk/files-windows/read-script.js +43 -0
  99. package/dist/src/plugin-sdk/files-windows/read.d.ts +6 -0
  100. package/dist/src/plugin-sdk/files-windows/read.js +56 -0
  101. package/dist/src/plugin-sdk/files-windows/result.d.ts +4 -0
  102. package/dist/src/plugin-sdk/files-windows/result.js +67 -0
  103. package/dist/src/plugin-sdk/files.js +4 -0
  104. package/dist/src/plugin-sdk/index.d.ts +1 -0
  105. package/dist/src/plugin-sdk/index.js +1 -0
  106. package/dist/src/plugin-sdk/mutation-result.d.ts +7 -0
  107. package/dist/src/plugin-sdk/mutation-result.js +11 -0
  108. package/dist/src/runtime/adapters/long-term-memory/file-lock/acquisition.js +20 -3
  109. package/dist/src/runtime/adapters/long-term-memory/file-lock/owner-record.js +3 -1
  110. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.d.ts +3 -0
  111. package/dist/src/runtime/adapters/long-term-memory/file-lock/path-observation.js +20 -0
  112. package/dist/src/runtime/adapters/long-term-memory/file-lock/snapshot.js +7 -3
  113. package/dist/src/runtime/adapters/passive-learning-runtime.d.ts +1 -1
  114. package/dist/src/runtime/adapters/passive-learning-runtime.js +3 -3
  115. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
  116. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
  117. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
  118. package/dist/src/runtime/adapters/runtime-observation-connection.d.ts +5 -0
  119. package/dist/src/runtime/adapters/runtime-observation-connection.js +13 -0
  120. package/dist/src/runtime/capabilities/tool-availability.js +6 -0
  121. package/dist/src/runtime/context/capability-brief.d.ts +2 -2
  122. package/dist/src/runtime/context/capability-brief.js +3 -3
  123. package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
  124. package/dist/src/runtime/context/capability-descriptions.js +57 -20
  125. package/dist/src/runtime/local-host/windows-private-access.js +2 -0
  126. package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +6 -1
  127. package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
  128. package/dist/src/runtime/long-term-memory/initial-context.d.ts +17 -0
  129. package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
  130. package/dist/src/runtime/long-term-memory/projection.js +1 -1
  131. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +2 -1
  132. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
  133. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +5 -2
  134. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +2 -1
  135. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
  136. package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
  137. package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
  138. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
  139. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
  140. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  141. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
  142. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +3 -1
  143. package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +1 -1
  144. package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +5 -1
  145. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
  146. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -0
  147. package/dist/src/runtime/passive-learning/application-catalog.js +3 -1
  148. package/dist/src/runtime/passive-learning/collection-source.js +7 -0
  149. package/dist/src/runtime/passive-learning/service.js +2 -3
  150. package/dist/src/runtime/passive-learning/status-projection.d.ts +2 -0
  151. package/dist/src/runtime/passive-learning/status-projection.js +9 -0
  152. package/dist/src/runtime/plugins/installation/package.d.ts +8 -0
  153. package/dist/src/runtime/plugins/installation/package.js +2 -0
  154. package/dist/src/runtime/plugins/installation/service.d.ts +7 -0
  155. package/dist/src/runtime/plugins/loader.js +24 -14
  156. package/dist/src/runtime/plugins/manifest-platform-compatibility.d.ts +2 -0
  157. package/dist/src/runtime/plugins/manifest-platform-compatibility.js +39 -0
  158. package/dist/src/runtime/plugins/manifest-projection.js +3 -0
  159. package/dist/src/runtime/plugins/manifest-validator.js +9 -1
  160. package/dist/src/runtime/plugins/platform-compatibility.d.ts +4 -0
  161. package/dist/src/runtime/plugins/platform-compatibility.js +44 -0
  162. package/dist/src/runtime/request/approval-wait/activation-events.js +19 -7
  163. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.d.ts +20 -0
  164. package/dist/src/runtime/request/approval-wait/execution-compaction-restore.js +118 -0
  165. package/dist/src/runtime/request/approval-wait/super-compaction-restore.js +2 -1
  166. package/dist/src/runtime/request/capability-execution-freshness.js +6 -1
  167. package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
  168. package/dist/src/runtime/request/prepared-execution.js +3 -0
  169. package/dist/src/runtime/request/root-contract.d.ts +2 -0
  170. package/dist/src/runtime/request/root-execution-kernel.js +1 -0
  171. package/dist/src/runtime/request/runner.js +9 -3
  172. package/dist/src/runtime/request/supervisor-root-execution.js +6 -0
  173. package/dist/src/runtime/steps/execution-agent/capability-result-context.d.ts +6 -0
  174. package/dist/src/runtime/steps/execution-agent/capability-result-context.js +29 -0
  175. package/dist/src/runtime/steps/execution-agent/contracts.d.ts +10 -0
  176. package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
  177. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
  178. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
  179. package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
  180. package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
  181. package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
  182. package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
  183. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
  184. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
  185. package/dist/src/runtime/steps/execution-agent/format.js +4 -3
  186. package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
  187. package/dist/src/runtime/steps/execution-agent/input.js +22 -1
  188. package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
  189. package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
  190. package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
  191. package/dist/src/runtime/steps/execution-agent/prompt.js +7 -8
  192. package/dist/src/runtime/steps/execution-agent/response-prompt.js +1 -0
  193. package/dist/src/runtime/steps/execution-agent/response-run.js +5 -11
  194. package/dist/src/runtime/steps/execution-agent/run.js +4 -1
  195. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +3 -5
  196. package/dist/src/runtime/steps/execution-agent/state-context.js +5 -51
  197. package/dist/src/runtime/steps/execution-agent/work-plan-contract.d.ts +1 -3
  198. package/dist/src/runtime/steps/execution-agent/work-plan-contract.js +0 -55
  199. package/dist/src/runtime/steps/execution-agent/work-plan-schema.d.ts +3 -0
  200. package/dist/src/runtime/steps/execution-agent/work-plan-schema.js +61 -0
  201. package/dist/src/runtime/steps/planner-decision/capability-brief.d.ts +2 -0
  202. package/dist/src/runtime/steps/planner-decision/prompt.js +26 -49
  203. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +1 -0
  204. package/dist/src/runtime/steps/supervisor-decision/input.js +5 -0
  205. package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +1 -0
  206. package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -2
  207. package/dist/src/runtime/steps/supervisor-decision/run.d.ts +1 -0
  208. package/dist/src/runtime/steps/supervisor-decision/run.js +4 -0
  209. package/dist/src/runtime/steps/supervisor-response/run.d.ts +2 -0
  210. package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
  211. package/dist/src/sessions/durable-session-commit.js +3 -3
  212. package/dist/src/sessions/prepared-session-replacement.d.ts +6 -0
  213. package/dist/src/sessions/prepared-session-replacement.js +46 -0
  214. package/dist/src/sessions/session-store.js +3 -3
  215. package/dist/src/shared/passive-observation-self-exclusion.d.ts +5 -0
  216. package/dist/src/shared/passive-observation-self-exclusion.js +37 -0
  217. package/dist/src/shared/windows-file-io/authority-script.d.ts +1 -0
  218. package/dist/src/shared/windows-file-io/authority-script.js +94 -0
  219. package/dist/src/shared/windows-file-io/native-script.d.ts +2 -0
  220. package/dist/src/shared/windows-file-io/native-script.js +120 -0
  221. package/dist/src/shared/windows-file-io/read-bytes-script.d.ts +1 -0
  222. package/dist/src/shared/windows-file-io/read-bytes-script.js +18 -0
  223. package/dist/src/shared/windows-job-object.d.ts +2 -0
  224. package/dist/src/shared/windows-job-object.js +66 -0
  225. package/dist/src/web-ui/app/ARCHITECTURE.md +1 -1
  226. package/dist/src/web-ui/app/app-bootstrap.js +14 -1
  227. package/dist/src/web-ui/app/app-state.js +0 -7
  228. package/dist/src/web-ui/app/app.js +54 -156
  229. package/dist/src/web-ui/app/components/automations/node-inspector.js +3 -2
  230. package/dist/src/web-ui/app/components/automations/step-editor-dialog.js +3 -0
  231. package/dist/src/web-ui/app/components/automations/timeline.js +3 -2
  232. package/dist/src/web-ui/app/components/composer-submission-notice.js +50 -0
  233. package/dist/src/web-ui/app/components/config-workspace/model-plugin-permissions.js +7 -1
  234. package/dist/src/web-ui/app/components/config-workspace/workspace-mutations.js +22 -2
  235. package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
  236. package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
  237. package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
  238. package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
  239. package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
  240. package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
  241. package/dist/src/web-ui/app/components/home-guidance/daily-review.js +2 -2
  242. package/dist/src/web-ui/app/components/home-guidance/home-guidance.js +20 -6
  243. package/dist/src/web-ui/app/components/model-setup/context-window-feedback.js +53 -0
  244. package/dist/src/web-ui/app/components/model-setup/save-flow.js +3 -1
  245. package/dist/src/web-ui/app/components/model-setup/save-outcome.js +1 -0
  246. package/dist/src/web-ui/app/components/model-setup/wizard.js +12 -0
  247. package/dist/src/web-ui/app/components/operations-summary.js +2 -1
  248. package/dist/src/web-ui/app/components/passive-learning/activity-controls.js +4 -0
  249. package/dist/src/web-ui/app/components/passive-learning/collection-access.js +35 -0
  250. package/dist/src/web-ui/app/components/passive-learning/collection-consent-dialog.js +59 -0
  251. package/dist/src/web-ui/app/components/passive-learning/collection-consent-gate.js +94 -0
  252. package/dist/src/web-ui/app/components/passive-learning/computer-update-notice.js +6 -0
  253. package/dist/src/web-ui/app/components/passive-learning/failure-copy.js +1 -0
  254. package/dist/src/web-ui/app/components/passive-learning/home-widget-preview.js +32 -0
  255. package/dist/src/web-ui/app/components/passive-learning/home.js +11 -3
  256. package/dist/src/web-ui/app/components/passive-learning/macos-collection-restart-notice.js +1 -0
  257. package/dist/src/web-ui/app/components/passive-learning/memory.js +2 -4
  258. package/dist/src/web-ui/app/components/passive-learning/workspace-view.js +2 -2
  259. package/dist/src/web-ui/app/components/plugins/compatibility.js +13 -0
  260. package/dist/src/web-ui/app/components/plugins/discovery-rendering.js +9 -1
  261. package/dist/src/web-ui/app/components/plugins/installation-compatibility.js +7 -0
  262. package/dist/src/web-ui/app/components/plugins/installation.js +2 -1
  263. package/dist/src/web-ui/app/components/plugins/rendering.js +3 -0
  264. package/dist/src/web-ui/app/components/reasoning-override-prompt.js +82 -0
  265. package/dist/src/web-ui/app/components/runtime-config-activation.js +22 -8
  266. package/dist/src/web-ui/app/components/runtime-setup/optional-steps.js +7 -4
  267. package/dist/src/web-ui/app/components/runtime-setup/plugins.js +3 -1
  268. package/dist/src/web-ui/app/components/runtime-setup/rendering.js +6 -4
  269. package/dist/src/web-ui/app/components/runtime-setup-guide.d.ts +1 -0
  270. package/dist/src/web-ui/app/components/schedules/details.js +3 -2
  271. package/dist/src/web-ui/app/components/schedules/form.js +10 -8
  272. package/dist/src/web-ui/app/components/schedules/workspace.js +23 -4
  273. package/dist/src/web-ui/app/components/session-sidebar-sections.js +2 -2
  274. package/dist/src/web-ui/app/components/spark-chat/handoff-actions.js +9 -3
  275. package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
  276. package/dist/src/web-ui/app/components/spark-chat/placement.js +4 -7
  277. package/dist/src/web-ui/app/components/spark-chat/settings.js +8 -4
  278. package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
  279. package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
  280. package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
  281. package/dist/src/web-ui/app/components/system-host/macos-permissions.js +2 -0
  282. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +50 -0
  283. package/dist/src/web-ui/app/components/system-host/rendering.js +6 -3
  284. package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
  285. package/dist/src/web-ui/app/components/workspace-storage-notice.js +37 -0
  286. package/dist/src/web-ui/app/computer-access-feature.js +13 -1
  287. package/dist/src/web-ui/app/configuration-environment-refresh.js +27 -34
  288. package/dist/src/web-ui/app/configuration-feature.js +11 -1
  289. package/dist/src/web-ui/app/controllers/app-event-bindings.js +38 -105
  290. package/dist/src/web-ui/app/controllers/chat-request-controller.d.ts +28 -0
  291. package/dist/src/web-ui/app/controllers/chat-request-controller.js +34 -66
  292. package/dist/src/web-ui/app/controllers/composer-attachments-controller.d.ts +15 -40
  293. package/dist/src/web-ui/app/controllers/composer-attachments-controller.js +26 -69
  294. package/dist/src/web-ui/app/controllers/composer-draft-view.d.ts +27 -0
  295. package/dist/src/web-ui/app/controllers/composer-draft-view.js +48 -0
  296. package/dist/src/web-ui/app/controllers/composer-drafts.d.ts +55 -0
  297. package/dist/src/web-ui/app/controllers/composer-drafts.js +120 -0
  298. package/dist/src/web-ui/app/controllers/composer-feature.d.ts +65 -0
  299. package/dist/src/web-ui/app/controllers/composer-feature.js +124 -0
  300. package/dist/src/web-ui/app/controllers/composer-queue-controller.d.ts +33 -94
  301. package/dist/src/web-ui/app/controllers/composer-queue-controller.js +185 -251
  302. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.d.ts +48 -0
  303. package/dist/src/web-ui/app/controllers/composer-submission-lifecycle.js +97 -0
  304. package/dist/src/web-ui/app/controllers/composer-submit-controller.d.ts +30 -61
  305. package/dist/src/web-ui/app/controllers/composer-submit-controller.js +56 -138
  306. package/dist/src/web-ui/app/controllers/composer-surface-controller.js +6 -0
  307. package/dist/src/web-ui/app/controllers/composer-workspace-controller.d.ts +22 -40
  308. package/dist/src/web-ui/app/controllers/composer-workspace-controller.js +49 -165
  309. package/dist/src/web-ui/app/controllers/conversation-navigation-intent.js +15 -0
  310. package/dist/src/web-ui/app/controllers/conversation-request-hydration.js +20 -17
  311. package/dist/src/web-ui/app/controllers/conversation-session-controller.d.ts +1 -2
  312. package/dist/src/web-ui/app/controllers/conversation-session-controller.js +49 -22
  313. package/dist/src/web-ui/app/controllers/conversation-workspace-activation.js +27 -0
  314. package/dist/src/web-ui/app/controllers/daily-memory-review.js +15 -16
  315. package/dist/src/web-ui/app/controllers/environment-transition.js +126 -0
  316. package/dist/src/web-ui/app/controllers/environment-workspace-preparation.js +18 -0
  317. package/dist/src/web-ui/app/controllers/home-composer-feature.d.ts +14 -36
  318. package/dist/src/web-ui/app/controllers/home-composer-feature.js +17 -114
  319. package/dist/src/web-ui/app/controllers/home-conversation-activation.js +6 -8
  320. package/dist/src/web-ui/app/controllers/operations-controller.js +2 -1
  321. package/dist/src/web-ui/app/controllers/passive-learning-controller.js +56 -0
  322. package/dist/src/web-ui/app/controllers/projects-controller.d.ts +1 -1
  323. package/dist/src/web-ui/app/controllers/projects-controller.js +6 -1
  324. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +174 -0
  325. package/dist/src/web-ui/app/controllers/runtime-selection-controller.d.ts +7 -0
  326. package/dist/src/web-ui/app/controllers/runtime-selection-controller.js +20 -155
  327. package/dist/src/web-ui/app/controllers/session-controller.js +33 -17
  328. package/dist/src/web-ui/app/controllers/session-pin-updates.js +14 -0
  329. package/dist/src/web-ui/app/controllers/session-sidebar-controller.js +12 -14
  330. package/dist/src/web-ui/app/controllers/spark-chat-sync.js +2 -2
  331. package/dist/src/web-ui/app/controllers/steer-controller.js +9 -7
  332. package/dist/src/web-ui/app/controllers/tool-permission-mode-controller.js +1 -1
  333. package/dist/src/web-ui/app/controllers/workspace-conversation-opener.js +34 -0
  334. package/dist/src/web-ui/app/dashboard-feature.js +12 -2
  335. package/dist/src/web-ui/app/lib/reasoning-controls.js +40 -0
  336. package/dist/src/web-ui/app/lib/session-composer-queue-ownership.js +58 -0
  337. package/dist/src/web-ui/app/lib/session-composer-queue.d.ts +12 -0
  338. package/dist/src/web-ui/app/lib/session-composer-queue.js +25 -6
  339. package/dist/src/web-ui/app/passive-learning-feature.js +18 -5
  340. package/dist/src/web-ui/app/schedules-feature.js +5 -3
  341. package/dist/src/web-ui/app/services/client-preferences.d.ts +18 -10
  342. package/dist/src/web-ui/app/services/client-preferences.js +25 -16
  343. package/dist/src/web-ui/app/services/home-guidance-preferences.js +13 -13
  344. package/dist/src/web-ui/app/services/reasoning-override.js +12 -0
  345. package/dist/src/web-ui/app/services/runtime-web-client/automations.js +10 -2
  346. package/dist/src/web-ui/app/services/runtime-web-client/memory.js +7 -2
  347. package/dist/src/web-ui/app/services/runtime-web-client/system-host.js +2 -0
  348. package/dist/src/web-ui/app/services/runtime-web-client.d.ts +2 -0
  349. package/dist/src/web-ui/app/services/runtime-web-client.js +2 -0
  350. package/dist/src/web-ui/app/services/server-composer-queue.js +32 -0
  351. package/dist/src/web-ui/app/services/session-sidebar-preferences.js +5 -5
  352. package/dist/src/web-ui/app/services/workspace-state-storage.js +116 -0
  353. package/dist/src/web-ui/app/services/workspace-state.js +27 -0
  354. package/dist/src/web-ui/app/spark-chat-conversation.js +34 -45
  355. package/dist/src/web-ui/app/spark-chat-feature.js +10 -4
  356. package/dist/src/web-ui/app/styles/21-composer-controls.css +16 -0
  357. package/dist/src/web-ui/app/styles/41-plugin-management.css +8 -0
  358. package/dist/src/web-ui/app/styles/42-model-plugin-permissions.css +1 -0
  359. package/dist/src/web-ui/app/styles/49-collection-consent.css +30 -0
  360. package/dist/src/web-ui/app/styles/64-workspace-storage.css +23 -0
  361. package/dist/src/web-ui/app/styles/95-home-widgets.css +109 -0
  362. package/dist/src/web-ui/app/styles.css +3 -0
  363. package/dist/src/web-ui/client-state/contracts.d.ts +15 -0
  364. package/dist/src/web-ui/client-state/contracts.js +13 -0
  365. package/dist/src/web-ui/client-state/preference-shapes.d.ts +2 -0
  366. package/dist/src/web-ui/client-state/preference-shapes.js +80 -0
  367. package/dist/src/web-ui/client-state/preferences.d.ts +3 -0
  368. package/dist/src/web-ui/client-state/preferences.js +84 -0
  369. package/dist/src/web-ui/client-state/queue.d.ts +3 -0
  370. package/dist/src/web-ui/client-state/queue.js +43 -0
  371. package/dist/src/web-ui/client-state/routes.d.ts +7 -0
  372. package/dist/src/web-ui/client-state/routes.js +58 -0
  373. package/dist/src/web-ui/client-state/store.d.ts +14 -0
  374. package/dist/src/web-ui/client-state/store.js +88 -0
  375. package/dist/src/web-ui/local-runtime/configuration-activation-source.js +2 -0
  376. package/dist/src/web-ui/local-runtime/http.js +11 -2
  377. package/dist/src/web-ui/local-runtime/model-context-capacity-error.d.ts +14 -0
  378. package/dist/src/web-ui/local-runtime/model-context-capacity-error.js +28 -0
  379. package/dist/src/web-ui/local-runtime/model-setup-context-window.d.ts +15 -0
  380. package/dist/src/web-ui/local-runtime/model-setup-context-window.js +25 -0
  381. package/dist/src/web-ui/local-runtime/model-setup-routes.js +2 -0
  382. package/dist/src/web-ui/local-runtime/model-setup-service.js +5 -2
  383. package/dist/src/web-ui/local-runtime/model-setup-validation.d.ts +1 -0
  384. package/dist/src/web-ui/local-runtime/model-setup-validation.js +14 -7
  385. package/dist/src/web-ui/local-runtime/request-body-error.d.ts +11 -0
  386. package/dist/src/web-ui/local-runtime/request-body-error.js +14 -0
  387. package/dist/src/web-ui/local-runtime/request-control-observation.js +2 -2
  388. package/dist/src/web-ui/local-runtime/request-execution.js +18 -18
  389. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.d.ts +2 -0
  390. package/dist/src/web-ui/local-runtime/runtime-setup-connection-edit.js +35 -22
  391. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.d.ts +2 -9
  392. package/dist/src/web-ui/local-runtime/runtime-setup-context-window.js +4 -27
  393. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.d.ts +15 -1
  394. package/dist/src/web-ui/local-runtime/runtime-setup-credentials.js +30 -11
  395. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.d.ts +20 -0
  396. package/dist/src/web-ui/local-runtime/runtime-setup-edit-files.js +104 -0
  397. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.d.ts +29 -0
  398. package/dist/src/web-ui/local-runtime/runtime-setup-edit-journal.js +151 -0
  399. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.d.ts +7 -0
  400. package/dist/src/web-ui/local-runtime/runtime-setup-edit-recovery.js +87 -0
  401. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.d.ts +3 -0
  402. package/dist/src/web-ui/local-runtime/runtime-setup-edit-transaction.js +37 -0
  403. package/dist/src/web-ui/local-runtime/runtime-setup-service.js +4 -0
  404. package/dist/src/web-ui/local-runtime-backend.js +14 -0
  405. package/dist/src/web-ui/plugin-management-catalog.d.ts +3 -1
  406. package/dist/src/web-ui/plugin-management-catalog.js +3 -1
  407. package/dist/src/web-ui/plugin-management-service.d.ts +1 -0
  408. package/dist/src/web-ui/plugin-removal-service.d.ts +1 -0
  409. package/dist/src/web-ui/server-readiness.d.ts +3 -0
  410. package/dist/src/web-ui/server-readiness.js +36 -0
  411. package/dist/src/web-ui/server.d.ts +2 -0
  412. package/dist/src/web-ui/server.js +23 -1
  413. package/dist/src/web-ui/system-host-service.js +13 -2
  414. package/dist/src/web-ui/system-host-setup/collection-consent-route.d.ts +3 -0
  415. package/dist/src/web-ui/system-host-setup/collection-consent-route.js +30 -0
  416. package/docs/installation.md +44 -5
  417. package/docs/plugins.md +174 -28
  418. package/docs/tool-execution-result-evidence-contract.md +57 -0
  419. package/docs/windows-companion-store.md +5 -0
  420. package/package.json +4 -2
  421. package/plugins/capability-brief/plugin.json +5 -1
  422. package/plugins/code-outline/README.md +20 -0
  423. package/plugins/code-outline/plugin.json +2 -1
  424. package/plugins/code-outline/source/index.ts +16 -20
  425. package/plugins/code-outline/source/read-failure.ts +40 -0
  426. package/plugins/code-outline/src/index.cjs +614 -29
  427. package/plugins/document-reader/README.md +33 -0
  428. package/plugins/document-reader/plugin.json +2 -1
  429. package/plugins/document-reader/source/pdf-contract.ts +57 -0
  430. package/plugins/document-reader/source/pdf-parser.ts +139 -0
  431. package/plugins/document-reader/source/pdf-process-main.ts +56 -0
  432. package/plugins/document-reader/source/pdf-process.ts +207 -0
  433. package/plugins/document-reader/source/pdf-result.ts +79 -0
  434. package/plugins/document-reader/source/pdf-worker.ts +39 -303
  435. package/plugins/document-reader/source/pdf.ts +4 -1
  436. package/plugins/document-reader/source/read-failure.ts +37 -0
  437. package/plugins/document-reader/source/reader.ts +3 -19
  438. package/plugins/document-reader/src/index.cjs +995 -211
  439. package/plugins/exec/README.md +19 -0
  440. package/plugins/exec/plugin.json +4 -3
  441. package/plugins/exec/skills/exec_skill/SKILL.md +3 -2
  442. package/plugins/exec/source/filesystem-file-observer.ts +98 -0
  443. package/plugins/exec/source/filesystem-observer.ts +8 -79
  444. package/plugins/exec/source/output-files.ts +12 -6
  445. package/plugins/exec/source/paths.ts +3 -1
  446. package/plugins/exec/source/process-manager.ts +8 -24
  447. package/plugins/exec/source/shell-platform.ts +19 -3
  448. package/plugins/exec/source/shell-process.ts +55 -0
  449. package/plugins/exec/source/windows-job-source.ts +1 -0
  450. package/plugins/exec/source/windows-shell-bootstrap.ts +20 -0
  451. package/plugins/exec/src/index.cjs +252 -96
  452. package/plugins/filesystem/README.md +65 -0
  453. package/plugins/filesystem/plugin.json +7 -3
  454. package/plugins/filesystem/source/atomic-write.ts +2 -0
  455. package/plugins/filesystem/source/bounded-io.ts +80 -306
  456. package/plugins/filesystem/source/directory-sample.ts +2 -0
  457. package/plugins/filesystem/source/errors.ts +14 -0
  458. package/plugins/filesystem/source/file-observation.ts +151 -0
  459. package/plugins/filesystem/source/file-version.ts +41 -0
  460. package/plugins/filesystem/source/index.ts +6 -0
  461. package/plugins/filesystem/source/mutation-coordinator.ts +1 -0
  462. package/plugins/filesystem/source/windows/authority-script.ts +1 -0
  463. package/plugins/filesystem/source/windows/native-script.ts +1 -0
  464. package/plugins/filesystem/source/windows/operations.ts +197 -0
  465. package/plugins/filesystem/source/windows/process.ts +214 -0
  466. package/plugins/filesystem/source/windows/publication-script.ts +29 -0
  467. package/plugins/filesystem/source/windows/read-script.ts +63 -0
  468. package/plugins/filesystem/source/windows/request-availability.ts +67 -0
  469. package/plugins/filesystem/source/windows/source.ts +42 -0
  470. package/plugins/filesystem/source/windows/storage-script.ts +11 -0
  471. package/plugins/filesystem/source/windows/streams-script.ts +24 -0
  472. package/plugins/filesystem/source/windows/write-script.ts +86 -0
  473. package/plugins/filesystem/src/index.cjs +1208 -322
  474. package/plugins/json-inspector/README.md +18 -0
  475. package/plugins/json-inspector/plugin.json +2 -1
  476. package/plugins/json-inspector/source/index.ts +16 -19
  477. package/plugins/json-inspector/source/read-failure.ts +42 -0
  478. package/plugins/json-inspector/src/index.cjs +612 -27
  479. package/plugins/local-search/README.md +29 -0
  480. package/plugins/local-search/plugin.json +2 -1
  481. package/plugins/local-search/source/errors.ts +2 -0
  482. package/plugins/local-search/source/paths.ts +3 -0
  483. package/plugins/local-search/source/ripgrep-process.ts +31 -5
  484. package/plugins/local-search/source/ripgrep.ts +3 -3
  485. package/plugins/local-search/source/windows-authority.ts +99 -0
  486. package/plugins/local-search/source/windows-search-lease.ts +49 -0
  487. package/plugins/local-search/source/windows-search-process.ts +91 -0
  488. package/plugins/local-search/source/windows-search-script.ts +52 -0
  489. package/plugins/local-search/src/index.cjs +595 -26
  490. package/plugins/memory/plugin.json +5 -1
  491. package/plugins/memory/source/lock-directory-claim.ts +56 -0
  492. package/plugins/memory/source/lock-owner-file.ts +71 -0
  493. package/plugins/memory/source/lock-path-observation.ts +26 -0
  494. package/plugins/memory/source/prepared-memory-replacement.ts +40 -0
  495. package/plugins/memory/source/store-lock.ts +12 -7
  496. package/plugins/memory/source/store.ts +3 -2
  497. package/plugins/memory/src/index.cjs +174 -25
  498. package/plugins/project-orientation/README.md +23 -0
  499. package/plugins/project-orientation/plugin.json +2 -1
  500. package/plugins/project-orientation/source/index.ts +12 -9
  501. package/plugins/project-orientation/source/inspection-failure.ts +70 -0
  502. package/plugins/project-orientation/source/manifest-summary.ts +9 -2
  503. package/plugins/project-orientation/source/tree.ts +6 -0
  504. package/plugins/project-orientation/src/index.cjs +647 -31
  505. package/plugins/system/README.md +51 -15
  506. package/plugins/system/plugin.json +6 -2
  507. package/plugins/system/skills/system_actions/SKILL.md +1 -1
  508. package/plugins/system/source/command-working-directory.ts +47 -0
  509. package/plugins/system/source/computer/handlers.ts +13 -9
  510. package/plugins/system/source/computer/observation-result.ts +10 -5
  511. package/plugins/system/source/computer/request-computers.ts +10 -3
  512. package/plugins/system/source/computer/request-modules.ts +3 -6
  513. package/plugins/system/source/computer/runtime-platform.ts +18 -0
  514. package/plugins/system/source/host-dispatch.ts +18 -2
  515. package/plugins/system/source/index.ts +5 -3
  516. package/plugins/system/source/local-command-output-retention.ts +16 -0
  517. package/plugins/system/source/local-command-output.ts +16 -8
  518. package/plugins/system/source/request-system-modules.ts +12 -2
  519. package/plugins/system/source/request-target-snapshot.ts +2 -1
  520. package/plugins/system/source/security/desktop-result.ts +177 -0
  521. package/plugins/system/source/security/observed-error.ts +10 -0
  522. package/plugins/system/source/security/secret-text.ts +118 -0
  523. package/plugins/system/source/security/system-results.ts +62 -0
  524. package/plugins/system/source/security/windows-output-directory.ts +82 -0
  525. package/plugins/system/src/index.cjs +837 -151
  526. package/plugins/system-probe/plugin.json +9 -3
  527. package/plugins/system-probe/source/disk-path.ts +8 -0
  528. package/plugins/system-probe/source/index.ts +10 -5
  529. package/plugins/system-probe/source/machine-load.ts +33 -0
  530. package/plugins/system-probe/source/metrics.ts +6 -8
  531. package/plugins/system-probe/src/index.cjs +49 -16
  532. package/plugins/web/plugin.json +5 -1
@@ -0,0 +1,13 @@
1
+ export function emptyClientState() {
2
+ return { version: 1, revision: 0, introductionSeen: false,
3
+ preferences: { "abot-web.lastToolPermissionMode": "ask" }, queue: "" };
4
+ }
5
+ export class ClientStateError extends Error {
6
+ code;
7
+ status;
8
+ constructor(code, message, status = 400) {
9
+ super(message);
10
+ this.code = code;
11
+ this.status = status;
12
+ }
13
+ }
@@ -0,0 +1,2 @@
1
+ export declare function isPreferenceObject(value: unknown): value is Record<string, unknown>;
2
+ export declare function assertPreferenceShape(key: string, value: unknown): void;
@@ -0,0 +1,80 @@
1
+ import { ClientStateError } from "./contracts.js";
2
+ const modes = new Set(["ask", "full_access", "full_plus"]);
3
+ export function isPreferenceObject(value) {
4
+ return value !== null && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+ function isStringList(value) {
7
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
8
+ }
9
+ function hasOnlyFields(value, fields) {
10
+ return Object.keys(value).every((key) => fields.includes(key));
11
+ }
12
+ function isSessionMode(value) {
13
+ if (!isPreferenceObject(value))
14
+ return false;
15
+ if (!hasOnlyFields(value, ["toolPermissionMode", "savedAt"]))
16
+ return false;
17
+ if (typeof value.toolPermissionMode !== "string" || !modes.has(value.toolPermissionMode))
18
+ return false;
19
+ return Number.isFinite(value.savedAt);
20
+ }
21
+ function isSidebarPreference(value) {
22
+ if (!isPreferenceObject(value))
23
+ return false;
24
+ if (!hasOnlyFields(value, ["archivedSessionIds", "orderedSessionIds"]))
25
+ return false;
26
+ return isStringList(value.archivedSessionIds) && isStringList(value.orderedSessionIds);
27
+ }
28
+ function isLauncherPosition(value) {
29
+ if (!isPreferenceObject(value))
30
+ return false;
31
+ if (!hasOnlyFields(value, ["x", "y"]))
32
+ return false;
33
+ return Number.isFinite(value.x) && Number.isFinite(value.y);
34
+ }
35
+ function isGuidancePreference(value) {
36
+ if (!isPreferenceObject(value))
37
+ return false;
38
+ if (!hasOnlyFields(value, ["offeredOn", "dismissed", "reviewed"]))
39
+ return false;
40
+ if (value.offeredOn !== undefined && typeof value.offeredOn !== "string")
41
+ return false;
42
+ if (value.dismissed !== undefined && (!isStringList(value.dismissed) || value.dismissed.length > 8))
43
+ return false;
44
+ if (value.reviewed === undefined)
45
+ return true;
46
+ if (!Array.isArray(value.reviewed) || value.reviewed.length > 200)
47
+ return false;
48
+ const seen = new Set();
49
+ for (const item of value.reviewed) {
50
+ if (!isPreferenceObject(item))
51
+ return false;
52
+ if (!hasOnlyFields(item, ["id", "updatedAt"]))
53
+ return false;
54
+ if (typeof item.id !== "string" || typeof item.updatedAt !== "string")
55
+ return false;
56
+ if (seen.has(item.id))
57
+ return false;
58
+ seen.add(item.id);
59
+ }
60
+ return true;
61
+ }
62
+ function hasPreferenceShape(key, value) {
63
+ if (key === "abot-web.pinnedSessions")
64
+ return isStringList(value);
65
+ if (key === "abot.spark.launcher.position.v1")
66
+ return isLauncherPosition(value);
67
+ if (key.startsWith("abot-web.homeGuidance."))
68
+ return isGuidancePreference(value);
69
+ if (!isPreferenceObject(value))
70
+ return false;
71
+ if (key === "abot-web.sessionModes")
72
+ return Object.values(value).every(isSessionMode);
73
+ if (key === "abot-web.sessionSidebarByEnvironment")
74
+ return Object.values(value).every(isSidebarPreference);
75
+ return Object.values(value).every((item) => typeof item === "string");
76
+ }
77
+ export function assertPreferenceShape(key, value) {
78
+ if (!hasPreferenceShape(key, value))
79
+ throw new ClientStateError("invalid_preferences", "Invalid workspace preferences or unbounded memory review receipts.");
80
+ }
@@ -0,0 +1,3 @@
1
+ import { type ClientPreferences } from "./contracts.js";
2
+ export declare function decodePreference(key: string, value: unknown): unknown;
3
+ export declare function updatePreference(preferences: ClientPreferences, input: Record<string, unknown>): void;
@@ -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
+ }