@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,28 @@
1
+ const MAX_PARTIAL_BODY_BYTES = 16_384;
2
+ /** Fixed storage: appending copies only incoming bytes, never the retained tail. */
3
+ export class ProviderResponseTail {
4
+ bytes = Buffer.alloc(MAX_PARTIAL_BODY_BYTES);
5
+ writeOffset = 0;
6
+ usedBytes = 0;
7
+ append(chunk) {
8
+ if (chunk.byteLength >= this.bytes.length) {
9
+ this.bytes.set(chunk.subarray(chunk.byteLength - this.bytes.length));
10
+ this.writeOffset = 0;
11
+ this.usedBytes = this.bytes.length;
12
+ return;
13
+ }
14
+ const firstLength = Math.min(chunk.byteLength, this.bytes.length - this.writeOffset);
15
+ this.bytes.set(chunk.subarray(0, firstLength), this.writeOffset);
16
+ this.bytes.set(chunk.subarray(firstLength), 0);
17
+ this.writeOffset = (this.writeOffset + chunk.byteLength) % this.bytes.length;
18
+ this.usedBytes = Math.min(this.usedBytes + chunk.byteLength, this.bytes.length);
19
+ }
20
+ snapshot() {
21
+ const result = Buffer.alloc(this.usedBytes);
22
+ const start = (this.writeOffset - this.usedBytes + this.bytes.length) % this.bytes.length;
23
+ const firstLength = Math.min(this.usedBytes, this.bytes.length - start);
24
+ result.set(this.bytes.subarray(start, start + firstLength));
25
+ result.set(this.bytes.subarray(0, this.usedBytes - firstLength), firstLength);
26
+ return result;
27
+ }
28
+ }
@@ -0,0 +1,30 @@
1
+ /** Bounded SSE metadata only; never selects or forwards model output. */
2
+ export declare class ProviderSseDiagnostics {
3
+ private pendingLine;
4
+ private droppingLine;
5
+ private afterCarriageReturn;
6
+ private eventType;
7
+ private hasData;
8
+ private data;
9
+ private dataTruncated;
10
+ private eventCount;
11
+ private oversizedLineCount;
12
+ private readonly counts;
13
+ private readonly recentEvents;
14
+ observe(text: string, afterMs: number): void;
15
+ snapshot(): {
16
+ eventCount: number;
17
+ eventTypes: {
18
+ [k: string]: number;
19
+ };
20
+ recentEvents: {
21
+ type: string;
22
+ afterMs: number;
23
+ }[];
24
+ oversizedLineCount: number;
25
+ };
26
+ private appendLinePart;
27
+ private finishLine;
28
+ private appendData;
29
+ private finishEvent;
30
+ }
@@ -0,0 +1,119 @@
1
+ const MAX_LINE_CHARACTERS = 32_768;
2
+ const MAX_DATA_CHARACTERS = 32_768;
3
+ const MAX_EVENT_TYPE_CHARACTERS = 128;
4
+ const MAX_EVENT_TYPES = 32;
5
+ const MAX_RECENT_EVENTS = 32;
6
+ /** Bounded SSE metadata only; never selects or forwards model output. */
7
+ export class ProviderSseDiagnostics {
8
+ pendingLine = "";
9
+ droppingLine = false;
10
+ afterCarriageReturn = false;
11
+ eventType;
12
+ hasData = false;
13
+ data = "";
14
+ dataTruncated = false;
15
+ eventCount = 0;
16
+ oversizedLineCount = 0;
17
+ counts = new Map();
18
+ recentEvents = [];
19
+ observe(text, afterMs) {
20
+ if (text.length === 0)
21
+ return;
22
+ let start = this.afterCarriageReturn && text.startsWith("\n") ? 1 : 0;
23
+ this.afterCarriageReturn = text.endsWith("\r");
24
+ const lineEndings = /\r\n|\r|\n/gu;
25
+ while (start < text.length) {
26
+ lineEndings.lastIndex = start;
27
+ const ending = lineEndings.exec(text);
28
+ this.appendLinePart(text.slice(start, ending?.index));
29
+ if (!ending)
30
+ return;
31
+ this.finishLine(afterMs);
32
+ start = ending.index + ending[0].length;
33
+ }
34
+ }
35
+ snapshot() {
36
+ return {
37
+ eventCount: this.eventCount,
38
+ eventTypes: Object.fromEntries(this.counts),
39
+ recentEvents: [...this.recentEvents],
40
+ oversizedLineCount: this.oversizedLineCount,
41
+ };
42
+ }
43
+ appendLinePart(part) {
44
+ if (this.droppingLine)
45
+ return;
46
+ const remaining = MAX_LINE_CHARACTERS - this.pendingLine.length;
47
+ this.pendingLine += part.slice(0, remaining);
48
+ if (part.length <= remaining)
49
+ return;
50
+ this.droppingLine = true;
51
+ this.oversizedLineCount += 1;
52
+ }
53
+ finishLine(afterMs) {
54
+ const line = this.pendingLine;
55
+ const truncated = this.droppingLine;
56
+ this.pendingLine = "";
57
+ this.droppingLine = false;
58
+ if (line === "") {
59
+ this.finishEvent(afterMs);
60
+ return;
61
+ }
62
+ const colon = line.indexOf(":");
63
+ const field = colon < 0 ? line : line.slice(0, colon);
64
+ let value = colon < 0 ? "" : line.slice(colon + 1);
65
+ if (value.startsWith(" "))
66
+ value = value.slice(1);
67
+ if (field === "event") {
68
+ this.eventType = value.slice(0, MAX_EVENT_TYPE_CHARACTERS);
69
+ return;
70
+ }
71
+ if (field !== "data")
72
+ return;
73
+ this.hasData = true;
74
+ this.appendData(value, truncated);
75
+ }
76
+ appendData(value, truncated) {
77
+ if (this.dataTruncated)
78
+ return;
79
+ if (truncated || this.data.length + value.length + 1 > MAX_DATA_CHARACTERS) {
80
+ this.dataTruncated = true;
81
+ this.data = "";
82
+ return;
83
+ }
84
+ this.data += value + "\n";
85
+ }
86
+ finishEvent(afterMs) {
87
+ const hasData = this.hasData;
88
+ const type = this.eventType ?? readDataEventType(this.data.slice(0, -1));
89
+ this.eventType = undefined;
90
+ this.hasData = false;
91
+ this.data = "";
92
+ this.dataTruncated = false;
93
+ if (!hasData)
94
+ return;
95
+ const recordedType = type || "message";
96
+ const countKey = this.counts.has(recordedType) || this.counts.size < MAX_EVENT_TYPES
97
+ ? recordedType : "(other)";
98
+ this.counts.set(countKey, (this.counts.get(countKey) ?? 0) + 1);
99
+ this.eventCount += 1;
100
+ this.recentEvents.push({ type: recordedType, afterMs });
101
+ if (this.recentEvents.length > MAX_RECENT_EVENTS)
102
+ this.recentEvents.shift();
103
+ }
104
+ }
105
+ function readDataEventType(data) {
106
+ if (data === "")
107
+ return "";
108
+ if (data === "[DONE]")
109
+ return "[DONE]";
110
+ try {
111
+ const value = JSON.parse(data);
112
+ if (value === null || typeof value !== "object" || !("type" in value))
113
+ return "";
114
+ return typeof value.type === "string" ? value.type.slice(0, MAX_EVENT_TYPE_CHARACTERS) : "";
115
+ }
116
+ catch {
117
+ return "";
118
+ }
119
+ }
@@ -2,6 +2,7 @@ import { createProviderTraceContext, serializeProviderError, } from "./provider-
2
2
  import { isModelIoTraceEnabled, traceModelIo } from "./trace-store.js";
3
3
  import { permitsModelContentTrace } from "./content-trace-policy.js";
4
4
  import { toolMediaSafeError } from "./tool-media-privacy.js";
5
+ import { captureProviderResponseBody } from "./provider-response-capture.js";
5
6
  function sanitizeProviderHeaders(headers) {
6
7
  const credentialHeaders = new Set([
7
8
  "authorization",
@@ -21,22 +22,42 @@ async function decodeProviderResponse(response, decodeResponse) {
21
22
  return { decodeError: serializeProviderError(error) };
22
23
  }
23
24
  }
24
- async function captureProviderResponse(context, response, decodeResponse) {
25
+ async function captureProviderResponse(context, response, decodeResponse, startedAt) {
25
26
  try {
26
27
  const rawResponse = response.clone();
27
28
  const decodedResponse = response.clone();
28
- const [body, decodedCapture] = await Promise.all([
29
- rawResponse.text(),
30
- decodeProviderResponse(decodedResponse, decodeResponse),
31
- ]);
29
+ const rawCapture = captureProviderResponseBody(rawResponse, startedAt);
30
+ const decodedCapture = decodeProviderResponse(decodedResponse, decodeResponse);
31
+ const capture = await rawCapture;
32
+ if (capture.outcome === "failed") {
33
+ await traceModelIo({
34
+ event: "provider.failure",
35
+ ...context,
36
+ stage: "response.capture",
37
+ error: serializeProviderError(capture.error),
38
+ response: {
39
+ status: response.status,
40
+ statusText: response.statusText,
41
+ partialBodyPrefix: capture.partialBodyPrefix,
42
+ partialBodyPrefixBytes: capture.partialBodyPrefixBytes,
43
+ partialBodyPrefixTruncated: capture.partialBodyPrefixTruncated,
44
+ partialBody: capture.partialBody,
45
+ partialBodyBytes: capture.partialBodyBytes,
46
+ bodyTruncated: capture.bodyTruncated,
47
+ stream: capture.stream,
48
+ },
49
+ });
50
+ return;
51
+ }
32
52
  await traceModelIo({
33
53
  event: "provider.response",
34
54
  ...context,
35
55
  response: {
36
56
  status: response.status,
37
57
  statusText: response.statusText,
38
- ...decodedCapture,
39
- body,
58
+ ...await decodedCapture,
59
+ body: capture.body,
60
+ stream: capture.stream,
40
61
  },
41
62
  });
42
63
  }
@@ -71,6 +92,7 @@ export async function fetchProviderWithTrace(params) {
71
92
  },
72
93
  });
73
94
  }
95
+ const startedAt = Date.now();
74
96
  try {
75
97
  const response = await params.fetchImpl(params.url, {
76
98
  method: "POST",
@@ -80,7 +102,7 @@ export async function fetchProviderWithTrace(params) {
80
102
  return {
81
103
  response,
82
104
  responseTrace: traceEnabled && contentTraceEnabled
83
- ? captureProviderResponse(context, response, params.decodeResponse)
105
+ ? captureProviderResponse(context, response, params.decodeResponse, startedAt)
84
106
  : Promise.resolve(),
85
107
  };
86
108
  }
@@ -1,9 +1,10 @@
1
1
  import { fetchProviderWithTrace } from "../../model-io-trace.js";
2
- import { toolMediaSafeError, toolMediaSafeMessage } from "../../observability/tool-media-privacy.js";
2
+ import { toolMediaSafeError, toolMediaSafeMessage, } from "../../observability/tool-media-privacy.js";
3
3
  import { buildOllamaPayload, buildOllamaRawPayload, } from "./payload.js";
4
4
  import { emitOllamaRequestProjection, emitOllamaSchemaDiagnostics, emitOllamaTiming, resolveOllamaBaseUrl, } from "./request-diagnostics.js";
5
5
  import { createOllamaStreamDiagnostics, isAbortFailure, } from "./stream-diagnostics.js";
6
6
  import { collectOllamaStream, forwardOllamaStream, } from "./stream-normalizer.js";
7
+ import { OllamaStreamTerminationError } from "./stream-termination.js";
7
8
  import { embedWithOllama } from "./embeddings.js";
8
9
  import { listOllamaEmbeddingModels } from "./embedding-models.js";
9
10
  function readRequestId(params) {
@@ -81,7 +82,12 @@ export function createOllamaProviderAdapter(options) {
81
82
  catch (error) {
82
83
  outcome = resolveFailureOutcome(error);
83
84
  failure = toolMediaSafeError(error, params.requestBody);
84
- throw failure;
85
+ if (!(error instanceof OllamaStreamTerminationError))
86
+ throw failure;
87
+ writer.emit({
88
+ type: "error",
89
+ error: toolMediaSafeMessage(error.message, params.requestBody),
90
+ });
85
91
  }
86
92
  finally {
87
93
  streamDiagnostics.terminate(outcome, failure);
@@ -1,4 +1,5 @@
1
1
  import { buildModelTokenUsage } from "../../protocol/usage.js";
2
+ import { assertOllamaFrameSucceeded, assertOllamaStreamCompleted, } from "./stream-termination.js";
2
3
  function observeNormalizedEvent(options, event) {
3
4
  try {
4
5
  options.onNormalizedEvent?.(event);
@@ -8,6 +9,7 @@ function observeNormalizedEvent(options, event) {
8
9
  }
9
10
  }
10
11
  function readOllamaEvent(json) {
12
+ assertOllamaFrameSucceeded(json);
11
13
  const obj = json && typeof json === "object"
12
14
  ? json
13
15
  : {};
@@ -88,12 +90,7 @@ export function flushNdjsonBuffer(buffer, events, options = {}) {
88
90
  if (!line) {
89
91
  continue;
90
92
  }
91
- try {
92
- writeGatewayEvents(events, JSON.parse(line), options);
93
- }
94
- catch {
95
- // Keep bridge behavior: ignore malformed upstream chunks.
96
- }
93
+ writeGatewayEvents(events, parseOllamaStreamLine(line), options);
97
94
  }
98
95
  return remaining;
99
96
  }
@@ -101,26 +98,39 @@ export async function forwardOllamaStream(body, events, options = {}) {
101
98
  const reader = body.getReader();
102
99
  const decoder = new TextDecoder();
103
100
  let buffer = "";
104
- while (true) {
105
- const { done, value } = await reader.read();
106
- if (done) {
107
- buffer += decoder.decode();
108
- }
109
- else {
110
- buffer += decoder.decode(value, { stream: true });
101
+ let terminalReceived = false;
102
+ const terminalTrackingEvents = {
103
+ emit(event) {
104
+ if (event.type === "done")
105
+ terminalReceived = true;
106
+ events.emit(event);
107
+ },
108
+ };
109
+ try {
110
+ while (true) {
111
+ const { done, value } = await reader.read();
112
+ if (done) {
113
+ buffer += decoder.decode();
114
+ }
115
+ else {
116
+ buffer += decoder.decode(value, { stream: true });
117
+ }
118
+ buffer = flushNdjsonBuffer(buffer, terminalTrackingEvents, options);
119
+ if (done) {
120
+ break;
121
+ }
111
122
  }
112
- buffer = flushNdjsonBuffer(buffer, events, options);
113
- if (done) {
114
- break;
123
+ if (buffer.trim()) {
124
+ writeGatewayEvents(terminalTrackingEvents, parseOllamaStreamLine(buffer.trim()), options);
115
125
  }
126
+ assertOllamaStreamCompleted(terminalReceived);
116
127
  }
117
- if (buffer.trim()) {
118
- try {
119
- writeGatewayEvents(events, JSON.parse(buffer.trim()), options);
120
- }
121
- catch {
122
- // Keep bridge behavior: ignore malformed trailing chunks.
123
- }
128
+ catch (error) {
129
+ void reader.cancel(error).catch(() => { });
130
+ throw error;
131
+ }
132
+ finally {
133
+ reader.releaseLock();
124
134
  }
125
135
  }
126
136
  export async function collectOllamaStream(body, options = {}) {
@@ -132,6 +142,7 @@ export async function collectOllamaStream(body, options = {}) {
132
142
  let usage;
133
143
  let doneReason;
134
144
  const appendJson = (json) => {
145
+ assertOllamaFrameSucceeded(json);
135
146
  const obj = json && typeof json === "object"
136
147
  ? json
137
148
  : {};
@@ -158,39 +169,39 @@ export async function collectOllamaStream(body, options = {}) {
158
169
  observeNormalizedEvent(options, event);
159
170
  }
160
171
  };
161
- while (true) {
162
- const { done, value } = await reader.read();
163
- if (done) {
164
- buffer += decoder.decode();
165
- }
166
- else {
167
- buffer += decoder.decode(value, { stream: true });
168
- }
169
- let newlineIndex;
170
- while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
171
- const line = buffer.slice(0, newlineIndex).trim();
172
- buffer = buffer.slice(newlineIndex + 1);
173
- if (!line) {
174
- continue;
172
+ try {
173
+ while (true) {
174
+ const { done, value } = await reader.read();
175
+ if (done) {
176
+ buffer += decoder.decode();
177
+ }
178
+ else {
179
+ buffer += decoder.decode(value, { stream: true });
175
180
  }
176
- try {
177
- appendJson(JSON.parse(line));
181
+ let newlineIndex;
182
+ while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
183
+ const line = buffer.slice(0, newlineIndex).trim();
184
+ buffer = buffer.slice(newlineIndex + 1);
185
+ if (!line) {
186
+ continue;
187
+ }
188
+ appendJson(parseOllamaStreamLine(line));
178
189
  }
179
- catch {
180
- // Keep bridge behavior: ignore malformed upstream chunks.
190
+ if (done) {
191
+ break;
181
192
  }
182
193
  }
183
- if (done) {
184
- break;
194
+ if (buffer.trim()) {
195
+ appendJson(parseOllamaStreamLine(buffer.trim()));
185
196
  }
197
+ assertOllamaStreamCompleted(doneReason !== undefined);
186
198
  }
187
- if (buffer.trim()) {
188
- try {
189
- appendJson(JSON.parse(buffer.trim()));
190
- }
191
- catch {
192
- // Keep bridge behavior: ignore malformed trailing chunks.
193
- }
199
+ catch (error) {
200
+ void reader.cancel(error).catch(() => { });
201
+ throw error;
202
+ }
203
+ finally {
204
+ reader.releaseLock();
194
205
  }
195
206
  return {
196
207
  text,
@@ -199,3 +210,12 @@ export async function collectOllamaStream(body, options = {}) {
199
210
  ...(doneReason !== undefined ? { doneReason } : {}),
200
211
  };
201
212
  }
213
+ function parseOllamaStreamLine(line) {
214
+ try {
215
+ return JSON.parse(line);
216
+ }
217
+ catch {
218
+ // Preserve tolerance for malformed chunks without swallowing provider errors.
219
+ return undefined;
220
+ }
221
+ }
@@ -0,0 +1,6 @@
1
+ /** A provider stream failed instead of completing its output. */
2
+ export declare class OllamaStreamTerminationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function assertOllamaFrameSucceeded(json: unknown): void;
6
+ export declare function assertOllamaStreamCompleted(terminalReceived: boolean): void;
@@ -0,0 +1,20 @@
1
+ /** A provider stream failed instead of completing its output. */
2
+ export class OllamaStreamTerminationError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "OllamaStreamTerminationError";
6
+ }
7
+ }
8
+ export function assertOllamaFrameSucceeded(json) {
9
+ if (!json || typeof json !== "object" || Array.isArray(json))
10
+ return;
11
+ const error = json.error;
12
+ if (typeof error !== "string")
13
+ return;
14
+ throw new OllamaStreamTerminationError(`ollama_stream_error: ${error || "provider generation failed"}`);
15
+ }
16
+ export function assertOllamaStreamCompleted(terminalReceived) {
17
+ if (terminalReceived)
18
+ return;
19
+ throw new OllamaStreamTerminationError("ollama_stream_missing_terminal");
20
+ }
@@ -1,9 +1,12 @@
1
1
  import { fetchProviderWithTrace } from "../../model-io-trace.js";
2
2
  import { toolMediaSafeError, toolMediaSafeEvent, toolMediaSafeMessage } from "../../observability/tool-media-privacy.js";
3
- import { emitOpenAIMessageOutputDiagnostic, emitOpenAISchemaDiagnostics, emitOpenAIStreamTermination, hasStructuredTextFormat, resolveOpenAIStreamFailureOutcome, } from "./diagnostics.js";
3
+ import { emitOpenAIMessageOutputDiagnostic, emitOpenAISchemaDiagnostics, emitOpenAIStreamTermination, resolveOpenAIStreamFailureOutcome, } from "./diagnostics.js";
4
4
  import { countOpenAIInputTokens } from "./input-token-count.js";
5
5
  import { buildOpenAIResponsesPayload, collectOpenAIResponsesStream, forwardOpenAIResponsesStream, resolveOpenAIProviderSettings, } from "./protocol.js";
6
6
  import { embedWithOpenAI } from "./embeddings.js";
7
+ import { bindOpenAIResponseLifetime } from "./response-lifetime.js";
8
+ import { resolveOpenAIFunctionOutputName } from "./function-output.js";
9
+ import { requiresSingleMessageOutput } from "./message-output-policy.js";
7
10
  export function createOpenAIProviderAdapter() {
8
11
  return Object.freeze({
9
12
  type: "openai",
@@ -24,26 +27,25 @@ export function createOpenAIProviderAdapter() {
24
27
  : "";
25
28
  const payload = buildOpenAIResponsesPayload(params.requestBody, {
26
29
  onFormatProjection: (diagnostics) => emitOpenAISchemaDiagnostics(requestId, diagnostics),
27
- ...(params.inputTokenMeasurement
28
- ? { inputTokenMeasurement: params.inputTokenMeasurement }
29
- : {}),
30
30
  });
31
+ const functionOutputName = resolveOpenAIFunctionOutputName(payload);
31
32
  const streamOptions = {
32
- structuredOutput: hasStructuredTextFormat(payload),
33
+ functionOutputName,
34
+ structuredOutput: requiresSingleMessageOutput(params.requestBody, payload),
33
35
  onMessageOutputDiagnostic: (diagnostic) => emitOpenAIMessageOutputDiagnostic(params, diagnostic),
34
36
  };
35
37
  const { response, responseTrace } = await fetchProviderWithTrace({
36
38
  endpoint: params.endpoint,
37
39
  requestBody: params.requestBody,
38
40
  invocation: params.invocation,
39
- fetchImpl: params.fetchImpl,
41
+ fetchImpl: async (input, init) => bindOpenAIResponseLifetime(await params.fetchImpl(input, init), { functionOutputName }),
40
42
  url: `${settings.baseUrl}/responses`,
41
43
  headers: {
42
44
  "Content-Type": "application/json",
43
45
  Authorization: `Bearer ${settings.apiKey}`,
44
46
  },
45
47
  payload,
46
- decodeResponse: (body) => collectOpenAIResponsesStream(body),
48
+ decodeResponse: (body) => collectOpenAIResponsesStream(body, { functionOutputName }),
47
49
  });
48
50
  if (!response.ok || !response.body) {
49
51
  const message = await response.text();
@@ -2,7 +2,6 @@ import type { OpenAISchemaProjectionDiagnostic } from "../../structured-output/p
2
2
  import type { ModelProviderInvocationParams } from "../contracts.js";
3
3
  import type { OpenAIMessageOutputNormalizationDiagnostic } from "./stream-normalizer.js";
4
4
  export type OpenAIStreamTerminationOutcome = "completed" | "aborted" | "failed";
5
- export declare function hasStructuredTextFormat(payload: Record<string, unknown>): boolean;
6
5
  export declare function emitOpenAISchemaDiagnostics(requestId: string, diagnostics: readonly OpenAISchemaProjectionDiagnostic[]): void;
7
6
  export declare function emitOpenAIMessageOutputDiagnostic(params: ModelProviderInvocationParams, diagnostic: OpenAIMessageOutputNormalizationDiagnostic): void;
8
7
  export declare function resolveOpenAIStreamFailureOutcome(error: unknown): OpenAIStreamTerminationOutcome;
@@ -4,15 +4,6 @@ function serializeDiagnosticError(error) {
4
4
  ? { name: error.name, message: error.message }
5
5
  : { name: "Error", message: String(error) };
6
6
  }
7
- function readRecord(value) {
8
- const isRecord = value !== null && typeof value === "object" && !Array.isArray(value);
9
- return isRecord ? value : undefined;
10
- }
11
- export function hasStructuredTextFormat(payload) {
12
- const text = readRecord(payload.text);
13
- const format = readRecord(text?.format);
14
- return format?.type === "json_schema" || format?.type === "json_object";
15
- }
16
7
  export function emitOpenAISchemaDiagnostics(requestId, diagnostics) {
17
8
  for (const diagnostic of diagnostics) {
18
9
  traceDebug("model-gateway.server", "schema.projection.instruction_injected", {
@@ -0,0 +1,11 @@
1
+ type OpenAIFunctionOutput = Readonly<{
2
+ tools: readonly Record<string, unknown>[];
3
+ tool_choice: Readonly<{
4
+ type: "function";
5
+ name: string;
6
+ }>;
7
+ parallel_tool_calls: false;
8
+ }>;
9
+ export declare function projectOpenAIFunctionOutput(modelStep: unknown, format: unknown): OpenAIFunctionOutput | undefined;
10
+ export declare function resolveOpenAIFunctionOutputName(payload: Record<string, unknown>): string | undefined;
11
+ export {};
@@ -0,0 +1,37 @@
1
+ import { resolveModelInvocationStep } from "../../../shared/model-step-registry.js";
2
+ import { isModelGatewayJsonSchemaFormat, isPlainObject, } from "../../structured-output/format-contract.js";
3
+ function isCapabilityControlsStep(modelStep) {
4
+ return resolveModelInvocationStep(modelStep)?.outputContract === "capability_controls";
5
+ }
6
+ function hasFunctionParametersSchema(format) {
7
+ if (!isModelGatewayJsonSchemaFormat(format))
8
+ return false;
9
+ return format.schema.type === "object";
10
+ }
11
+ // Transport the existing controls envelope as one function's arguments. The
12
+ // Runtime still owns validation, frozen-control merging and execution authority.
13
+ export function projectOpenAIFunctionOutput(modelStep, format) {
14
+ if (!isCapabilityControlsStep(modelStep))
15
+ return undefined;
16
+ if (!hasFunctionParametersSchema(format))
17
+ return undefined;
18
+ return {
19
+ tools: [{
20
+ type: "function",
21
+ name: format.name,
22
+ parameters: format.schema,
23
+ ...(format.description === undefined ? {} : { description: format.description }),
24
+ ...(format.strict === undefined ? {} : { strict: format.strict }),
25
+ }],
26
+ tool_choice: { type: "function", name: format.name },
27
+ parallel_tool_calls: false,
28
+ };
29
+ }
30
+ export function resolveOpenAIFunctionOutputName(payload) {
31
+ const choice = payload.tool_choice;
32
+ if (!isPlainObject(choice))
33
+ return undefined;
34
+ if (choice.type !== "function")
35
+ return undefined;
36
+ return typeof choice.name === "string" ? choice.name : undefined;
37
+ }
@@ -0,0 +1,7 @@
1
+ type OpenAIFunctionResult = Readonly<{
2
+ text: string;
3
+ } | {
4
+ error: string;
5
+ }>;
6
+ export declare function readOpenAIFunctionResult(response: unknown, expectedName: string): OpenAIFunctionResult;
7
+ export {};
@@ -0,0 +1,35 @@
1
+ import { isModelGatewayToolCall } from "../../protocol/message-contract.js";
2
+ import { isPlainObject } from "../../structured-output/format-contract.js";
3
+ function isFunctionCall(value) {
4
+ return isPlainObject(value) && value.type === "function_call";
5
+ }
6
+ function hasCompletedResponseOutput(response) {
7
+ if (!isPlainObject(response))
8
+ return false;
9
+ if (response.status !== "completed")
10
+ return false;
11
+ return Array.isArray(response.output);
12
+ }
13
+ // Only the terminal response snapshot is authoritative. Argument deltas and
14
+ // output_item.done may precede refusal, truncation or a failed response.
15
+ export function readOpenAIFunctionResult(response, expectedName) {
16
+ if (!hasCompletedResponseOutput(response)) {
17
+ return { error: "openai function response not completed" };
18
+ }
19
+ const calls = response.output.filter(isFunctionCall);
20
+ if (calls.length !== 1) {
21
+ return { error: "openai function response requires exactly one call" };
22
+ }
23
+ const call = calls[0];
24
+ if (call.name !== expectedName) {
25
+ return { error: "openai function response name mismatch" };
26
+ }
27
+ if (call.status !== undefined && call.status !== "completed") {
28
+ return { error: "openai function call not completed" };
29
+ }
30
+ const projected = { callId: call.call_id, name: call.name, arguments: call.arguments };
31
+ if (!isModelGatewayToolCall(projected)) {
32
+ return { error: "openai function call arguments or identity invalid" };
33
+ }
34
+ return { text: projected.arguments };
35
+ }
@@ -0,0 +1,3 @@
1
+ import type { ModelGatewayRequest } from "../../types.js";
2
+ /** Content authoring consumes one message even when its wire format is plain text. */
3
+ export declare function requiresSingleMessageOutput(request: ModelGatewayRequest, payload: Record<string, unknown>): boolean;