@vellumai/assistant 0.9.1-staging.1 → 0.10.0-staging.2

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 (433) hide show
  1. package/docs/activation-funnel-telemetry.md +24 -18
  2. package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
  3. package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
  4. package/node_modules/@vellumai/gateway-client/src/index.ts +15 -0
  5. package/openapi.yaml +852 -15
  6. package/package.json +1 -1
  7. package/src/__tests__/access-request-card-view.test.ts +98 -0
  8. package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
  9. package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +59 -7
  10. package/src/__tests__/agent-loop-compaction-strip.test.ts +17 -16
  11. package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
  12. package/src/__tests__/app-compiler.test.ts +15 -1
  13. package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
  14. package/src/__tests__/call-pointer-messages.test.ts +28 -0
  15. package/src/__tests__/cancel-clears-processing.test.ts +89 -0
  16. package/src/__tests__/channel-approval-routes.test.ts +0 -4
  17. package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
  18. package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
  19. package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
  20. package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
  21. package/src/__tests__/config-loader-backfill.test.ts +174 -30
  22. package/src/__tests__/config-schema.test.ts +35 -0
  23. package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
  24. package/src/__tests__/contact-store-user-file.test.ts +0 -6
  25. package/src/__tests__/contacts-tools.test.ts +29 -0
  26. package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
  27. package/src/__tests__/conversation-agent-loop.test.ts +58 -0
  28. package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
  29. package/src/__tests__/conversation-lifecycle.test.ts +7 -9
  30. package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
  31. package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
  32. package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
  33. package/src/__tests__/conversation-title-service.test.ts +62 -0
  34. package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
  35. package/src/__tests__/credential-prompt-route.test.ts +1 -0
  36. package/src/__tests__/credential-security-invariants.test.ts +2 -0
  37. package/src/__tests__/disk-pressure-policy.test.ts +12 -0
  38. package/src/__tests__/disk-usage.test.ts +65 -0
  39. package/src/__tests__/dynamic-page-surface.test.ts +51 -0
  40. package/src/__tests__/gateway-flag-listener.test.ts +110 -1
  41. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  42. package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
  43. package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
  44. package/src/__tests__/guardian-grant-minting.test.ts +3 -35
  45. package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
  46. package/src/__tests__/guardian-routing-state.test.ts +0 -1
  47. package/src/__tests__/headless-browser-mode.test.ts +10 -0
  48. package/src/__tests__/headless-browser-navigate.test.ts +8 -3
  49. package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
  50. package/src/__tests__/host-browser-proxy.test.ts +87 -0
  51. package/src/__tests__/injector-v3-suppression.test.ts +27 -20
  52. package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
  53. package/src/__tests__/invite-redemption-service.test.ts +0 -3
  54. package/src/__tests__/llm-catalog-parity.test.ts +30 -1
  55. package/src/__tests__/llm-resolver.test.ts +21 -0
  56. package/src/__tests__/llm-schema.test.ts +1 -0
  57. package/src/__tests__/managed-profile-guard.test.ts +163 -4
  58. package/src/__tests__/mcp-health-check.test.ts +6 -7
  59. package/src/__tests__/media-stream-server-integration.test.ts +317 -13
  60. package/src/__tests__/path-policy.test.ts +34 -0
  61. package/src/__tests__/persona-resolver.test.ts +38 -0
  62. package/src/__tests__/plugin-api-provider.test.ts +24 -0
  63. package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
  64. package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
  65. package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
  66. package/src/__tests__/reaction-persistence.test.ts +150 -29
  67. package/src/__tests__/relay-server.test.ts +285 -0
  68. package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
  69. package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
  70. package/src/__tests__/skill-execute-input.test.ts +5 -0
  71. package/src/__tests__/skills.test.ts +51 -0
  72. package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
  73. package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
  74. package/src/__tests__/subagent-tools.test.ts +150 -0
  75. package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
  76. package/src/__tests__/title-generate-hook.test.ts +100 -3
  77. package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
  78. package/src/__tests__/tool-audit-listener.test.ts +7 -7
  79. package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
  80. package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
  81. package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
  82. package/src/__tests__/trusted-contact-verification.test.ts +2 -4
  83. package/src/__tests__/twilio-routes.test.ts +81 -1
  84. package/src/__tests__/voice-invite-redemption.test.ts +0 -1
  85. package/src/__tests__/weak-open-model.test.ts +30 -0
  86. package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
  87. package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
  88. package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
  89. package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
  90. package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
  91. package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
  92. package/src/agent/loop.ts +33 -33
  93. package/src/api/events/tool-result.ts +6 -0
  94. package/src/api/events/workflow-completed.ts +53 -0
  95. package/src/api/events/workflow-leaf-finished.ts +38 -0
  96. package/src/api/events/workflow-leaf-started.ts +35 -0
  97. package/src/api/events/workflow-progress.ts +32 -0
  98. package/src/api/events/workflow-started.ts +31 -0
  99. package/src/api/index.ts +40 -0
  100. package/src/api/responses/conversation-message.ts +26 -0
  101. package/src/api/responses/home.ts +26 -0
  102. package/src/api/responses/workflow-journal.ts +53 -0
  103. package/src/approvals/guardian-card-withdrawal.ts +145 -0
  104. package/src/approvals/guardian-decision-primitive.ts +26 -3
  105. package/src/approvals/guardian-request-resolvers.ts +181 -78
  106. package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
  107. package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
  108. package/src/calls/call-pointer-messages.ts +10 -4
  109. package/src/calls/channel-admission-reader.ts +104 -0
  110. package/src/calls/guardian-dispatch.ts +17 -45
  111. package/src/calls/media-stream-server.ts +84 -2
  112. package/src/calls/relay-server.ts +66 -0
  113. package/src/calls/relay-setup-router.ts +82 -1
  114. package/src/calls/twilio-routes.ts +17 -8
  115. package/src/cli/commands/clients.ts +3 -0
  116. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
  117. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
  118. package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
  119. package/src/cli/commands/memory/index.ts +30 -0
  120. package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
  121. package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
  122. package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
  123. package/src/cli/commands/oauth/status.test.ts +36 -0
  124. package/src/cli/commands/oauth/status.ts +23 -3
  125. package/src/cli/commands/plugins.ts +57 -5
  126. package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
  127. package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +134 -4
  128. package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
  129. package/src/cli/lib/__tests__/upgrade-plugin.test.ts +53 -11
  130. package/src/cli/lib/inspect-plugin.ts +12 -1
  131. package/src/cli/lib/merge-plugin-tree.ts +149 -49
  132. package/src/cli/lib/plugin-surfaces.ts +104 -0
  133. package/src/cli/lib/upgrade-plugin.ts +64 -36
  134. package/src/cli/program.ts +2 -4
  135. package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
  136. package/src/config/assistant-feature-flags.ts +22 -7
  137. package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
  138. package/src/config/bundled-skills/messaging/SKILL.md +6 -4
  139. package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
  140. package/src/config/bundled-skills/workflows/SKILL.md +14 -7
  141. package/src/config/call-site-defaults.ts +3 -0
  142. package/src/config/feature-flag-registry.json +49 -18
  143. package/src/config/llm-resolver.ts +3 -0
  144. package/src/config/memory-v3-gate.ts +11 -0
  145. package/src/config/schema.ts +8 -6
  146. package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
  147. package/src/config/schemas/call-site-catalog.ts +7 -0
  148. package/src/config/schemas/channels.ts +11 -0
  149. package/src/config/schemas/llm.ts +31 -0
  150. package/src/config/schemas/memory-lifecycle.ts +3 -7
  151. package/src/config/schemas/memory-v3.ts +6 -0
  152. package/src/config/schemas/services.ts +18 -0
  153. package/src/config/seed-inference-profiles.ts +94 -34
  154. package/src/config/skills.ts +21 -0
  155. package/src/config/sync-gated-profiles.ts +220 -0
  156. package/src/contacts/contact-store.ts +2 -10
  157. package/src/contacts/contacts-write.ts +1 -2
  158. package/src/contacts/types.ts +0 -1
  159. package/src/context/compactor.ts +86 -52
  160. package/src/context/strip-injections.ts +58 -10
  161. package/src/context/token-estimator.ts +1 -1
  162. package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
  163. package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
  164. package/src/daemon/conversation-agent-loop.ts +100 -19
  165. package/src/daemon/conversation-history.ts +1 -1
  166. package/src/daemon/conversation-lifecycle.ts +3 -5
  167. package/src/daemon/conversation-process.ts +13 -5
  168. package/src/daemon/conversation-runtime-assembly.ts +13 -15
  169. package/src/daemon/conversation-surfaces.ts +26 -0
  170. package/src/daemon/conversation-tool-setup.ts +16 -11
  171. package/src/daemon/conversation.ts +64 -14
  172. package/src/daemon/disk-pressure-policy.ts +5 -3
  173. package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
  174. package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
  175. package/src/daemon/handlers/config-a2a.ts +0 -2
  176. package/src/daemon/handlers/config-channels.ts +5 -10
  177. package/src/daemon/handlers/config-slack-channel.ts +20 -0
  178. package/src/daemon/handlers/conversations.ts +107 -0
  179. package/src/daemon/host-browser-proxy.ts +41 -0
  180. package/src/daemon/lifecycle.ts +55 -20
  181. package/src/daemon/message-provenance.ts +2 -0
  182. package/src/daemon/message-types/contacts.ts +0 -1
  183. package/src/daemon/message-types/web-activity.ts +7 -1
  184. package/src/daemon/message-types/workflows.ts +83 -1
  185. package/src/daemon/tool-setup-types.ts +4 -0
  186. package/src/daemon/trust-context.ts +1 -1
  187. package/src/events/tool-audit-listener.ts +2 -2
  188. package/src/home/feed-source-enrichment.test.ts +151 -0
  189. package/src/home/feed-source-enrichment.ts +176 -0
  190. package/src/instrument.ts +18 -6
  191. package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
  192. package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
  193. package/src/ipc/assistant-server.ts +37 -4
  194. package/src/ipc/gateway-flag-listener.ts +18 -2
  195. package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
  196. package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
  197. package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
  198. package/src/memory/__tests__/memory-retrospective-job.test.ts +34 -0
  199. package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
  200. package/src/memory/auth-fallback-events-store.ts +2 -2
  201. package/src/memory/auto-analysis-enqueue.ts +3 -5
  202. package/src/memory/canonical-guardian-store.ts +39 -1
  203. package/src/memory/conversation-crud.ts +9 -4
  204. package/src/memory/conversation-key-store.ts +17 -2
  205. package/src/memory/conversation-title-service.ts +64 -7
  206. package/src/memory/db-init.ts +10 -0
  207. package/src/memory/embedding-backend.ts +15 -1
  208. package/src/memory/jobs-worker.ts +2 -1
  209. package/src/memory/lifecycle-events-store.ts +2 -2
  210. package/src/memory/memory-retrospective-enqueue.ts +31 -6
  211. package/src/memory/memory-retrospective-job.ts +9 -0
  212. package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
  213. package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
  214. package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
  215. package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +10 -0
  216. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
  217. package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
  218. package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
  219. package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
  220. package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
  221. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
  222. package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
  223. package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
  224. package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
  225. package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +30 -0
  226. package/src/memory/migrations/index.ts +5 -0
  227. package/src/memory/onboarding-events-store.ts +3 -3
  228. package/src/memory/schema/contacts.ts +0 -1
  229. package/src/memory/skill-loaded-events-store.test.ts +7 -15
  230. package/src/memory/skill-loaded-events-store.ts +2 -2
  231. package/src/memory/tool-executed-events-store.test.ts +7 -7
  232. package/src/memory/turn-trace-store.test.ts +736 -0
  233. package/src/memory/turn-trace-store.ts +364 -0
  234. package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
  235. package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
  236. package/src/memory/v2/consolidation-job.ts +2 -2
  237. package/src/memory/v2/skill-content.ts +25 -7
  238. package/src/memory/v2/skill-store.ts +7 -1
  239. package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
  240. package/src/memory/v3-eval/eval-packets.ts +546 -0
  241. package/src/messaging/providers/slack/api.ts +31 -0
  242. package/src/messaging/providers/slack/send.test.ts +114 -2
  243. package/src/messaging/providers/slack/send.ts +30 -7
  244. package/src/messaging/providers/slack/withdraw.test.ts +200 -0
  245. package/src/messaging/providers/slack/withdraw.ts +161 -0
  246. package/src/notifications/AGENTS.md +2 -0
  247. package/src/notifications/access-request-copy.ts +72 -59
  248. package/src/notifications/adapters/slack.ts +55 -73
  249. package/src/notifications/approval-card-data.ts +333 -0
  250. package/src/notifications/broadcaster.ts +6 -2
  251. package/src/notifications/canonical-delivery-recorder.ts +139 -0
  252. package/src/notifications/copy-composer.ts +3 -3
  253. package/src/notifications/decision-engine.ts +4 -2
  254. package/src/notifications/destination-resolver.ts +4 -6
  255. package/src/notifications/guardian-question-mode.ts +10 -0
  256. package/src/notifications/home-feed-side-effect.ts +3 -13
  257. package/src/notifications/notification-utils.ts +2 -1
  258. package/src/notifications/signal.ts +79 -43
  259. package/src/notifications/types.ts +98 -128
  260. package/src/permissions/checker.test.ts +51 -0
  261. package/src/permissions/checker.ts +185 -26
  262. package/src/permissions/ipc-risk-types.ts +24 -0
  263. package/src/permissions/question-prompter.test.ts +27 -0
  264. package/src/permissions/question-prompter.ts +4 -0
  265. package/src/platform/client.test.ts +119 -0
  266. package/src/platform/client.ts +66 -0
  267. package/src/platform/consent-cache.test.ts +267 -0
  268. package/src/platform/consent-cache.ts +174 -0
  269. package/src/plugin-api/index.ts +27 -0
  270. package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
  271. package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
  272. package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
  273. package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
  274. package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
  275. package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
  276. package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
  277. package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
  278. package/src/plugins/defaults/advisor/config.ts +21 -0
  279. package/src/plugins/defaults/advisor/consult.ts +93 -0
  280. package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
  281. package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
  282. package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
  283. package/src/plugins/defaults/advisor/package.json +14 -0
  284. package/src/plugins/defaults/advisor/steering.ts +67 -0
  285. package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
  286. package/src/plugins/defaults/advisor/transcript.ts +76 -0
  287. package/src/plugins/defaults/index.ts +35 -0
  288. package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
  289. package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
  290. package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
  291. package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
  292. package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
  293. package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
  294. package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +75 -7
  295. package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
  296. package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
  297. package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
  298. package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
  299. package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +37 -4
  300. package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
  301. package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
  302. package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
  303. package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +2 -12
  304. package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
  305. package/src/prompts/persona-resolver.ts +12 -2
  306. package/src/prompts/templates/system-sections.ts +7 -2
  307. package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
  308. package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
  309. package/src/providers/__tests__/retry-callsite.test.ts +176 -0
  310. package/src/providers/atlascloud/client.ts +85 -0
  311. package/src/providers/fetch-provider-catalog.ts +85 -0
  312. package/src/providers/inference/adapter-factory.ts +3 -0
  313. package/src/providers/model-catalog.ts +58 -0
  314. package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
  315. package/src/providers/openai/chat-completions-provider.ts +7 -0
  316. package/src/providers/openai/responses-provider.ts +10 -0
  317. package/src/providers/provider-send-message.ts +11 -3
  318. package/src/providers/retry.ts +53 -12
  319. package/src/providers/search-provider-catalog.ts +10 -0
  320. package/src/providers/weak-open-model.ts +22 -0
  321. package/src/runtime/__tests__/agent-wake.test.ts +181 -0
  322. package/src/runtime/__tests__/client-health.test.ts +44 -0
  323. package/src/runtime/access-request-helper.ts +21 -53
  324. package/src/runtime/actor-trust-resolver.ts +49 -21
  325. package/src/runtime/agent-wake.ts +52 -0
  326. package/src/runtime/assistant-event-hub.ts +18 -4
  327. package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
  328. package/src/runtime/auth/require-bound-guardian.ts +1 -4
  329. package/src/runtime/capabilities.test.ts +120 -0
  330. package/src/runtime/capabilities.ts +197 -0
  331. package/src/runtime/channel-approval-types.ts +5 -1
  332. package/src/runtime/channel-retry-sweep.ts +1 -0
  333. package/src/runtime/channel-verification-service.ts +1 -2
  334. package/src/runtime/client-health.ts +26 -0
  335. package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
  336. package/src/runtime/effective-capabilities.test.ts +128 -0
  337. package/src/runtime/effective-capabilities.ts +84 -0
  338. package/src/runtime/guardian-reply-router.ts +106 -21
  339. package/src/runtime/invite-redemption-service.ts +6 -22
  340. package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
  341. package/src/runtime/migrations/vbundle-builder.ts +49 -20
  342. package/src/runtime/pending-interactions.ts +15 -0
  343. package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
  344. package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
  345. package/src/runtime/routes/__tests__/plugins-routes.test.ts +35 -13
  346. package/src/runtime/routes/browser-tabs-routes.ts +9 -0
  347. package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
  348. package/src/runtime/routes/client-routes.ts +10 -0
  349. package/src/runtime/routes/contact-routes.ts +31 -8
  350. package/src/runtime/routes/conversation-management-routes.ts +80 -1
  351. package/src/runtime/routes/conversation-query-routes.ts +68 -22
  352. package/src/runtime/routes/conversation-routes.ts +37 -12
  353. package/src/runtime/routes/events-routes.ts +1 -3
  354. package/src/runtime/routes/guardian-approval-interception.ts +14 -73
  355. package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
  356. package/src/runtime/routes/home-feed-routes.ts +8 -3
  357. package/src/runtime/routes/inbound-message-handler.ts +214 -228
  358. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +88 -6
  359. package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
  360. package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
  361. package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
  362. package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
  363. package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
  364. package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
  365. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
  366. package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
  367. package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
  368. package/src/runtime/routes/index.ts +2 -0
  369. package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
  370. package/src/runtime/routes/integrations/slack/channel.ts +36 -0
  371. package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
  372. package/src/runtime/routes/mcp-auth-routes.ts +233 -41
  373. package/src/runtime/routes/memory-eval-routes.ts +87 -0
  374. package/src/runtime/routes/notification-routes.ts +122 -133
  375. package/src/runtime/routes/platform-routes.ts +2 -2
  376. package/src/runtime/routes/plugins-routes.ts +40 -7
  377. package/src/runtime/routes/secret-routes.ts +10 -0
  378. package/src/runtime/routes/surface-action-routes.ts +2 -1
  379. package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
  380. package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
  381. package/src/runtime/routes/workflow-routes.test.ts +225 -1
  382. package/src/runtime/routes/workflow-routes.ts +131 -1
  383. package/src/runtime/tool-grant-request-helper.ts +18 -16
  384. package/src/runtime/trust-context-resolver.ts +8 -5
  385. package/src/schedule/schedule-store.ts +1 -1
  386. package/src/schedule/scheduler-types.ts +5 -1
  387. package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
  388. package/src/security/secret-patterns.ts +3 -0
  389. package/src/subagent/manager.ts +11 -4
  390. package/src/telemetry/trace-collection-policy.test.ts +28 -0
  391. package/src/telemetry/trace-collection-policy.ts +30 -0
  392. package/src/telemetry/types.ts +89 -0
  393. package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
  394. package/src/telemetry/usage-telemetry-reporter.ts +148 -41
  395. package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
  396. package/src/tools/browser/browser-execution.ts +29 -18
  397. package/src/tools/document/document-tool.ts +2 -3
  398. package/src/tools/executor.ts +5 -3
  399. package/src/tools/host-terminal/host-shell.ts +5 -4
  400. package/src/tools/memory/register.ts +2 -2
  401. package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
  402. package/src/tools/network/__tests__/web-search.test.ts +143 -0
  403. package/src/tools/network/web-fetch.ts +372 -1
  404. package/src/tools/network/web-search.ts +213 -10
  405. package/src/tools/permission-checker.ts +3 -2
  406. package/src/tools/registry.ts +20 -0
  407. package/src/tools/schedule/create.ts +4 -3
  408. package/src/tools/schedule/update.ts +2 -1
  409. package/src/tools/shared/filesystem/path-policy.ts +39 -13
  410. package/src/tools/skills/execute.ts +1 -2
  411. package/src/tools/subagent/spawn.ts +37 -13
  412. package/src/tools/terminal/shell.ts +10 -4
  413. package/src/tools/tool-approval-handler.ts +17 -10
  414. package/src/tools/types.ts +9 -0
  415. package/src/tools/ui-surface/definitions.ts +25 -2
  416. package/src/tools/verification-control-plane-policy.ts +3 -1
  417. package/src/tools/workflows/run-workflow.ts +1 -0
  418. package/src/util/disk-usage.ts +78 -23
  419. package/src/util/platform.ts +8 -1
  420. package/src/watcher/telemetry.ts +2 -2
  421. package/src/workflows/engine.test.ts +175 -1
  422. package/src/workflows/engine.ts +82 -0
  423. package/src/workflows/journal-store.test.ts +70 -0
  424. package/src/workflows/journal-store.ts +18 -3
  425. package/src/workflows/run-manager.test.ts +171 -3
  426. package/src/workflows/run-manager.ts +64 -0
  427. package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
  428. package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
  429. package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
  430. package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
  431. package/src/workspace/migrations/registry.ts +8 -0
  432. package/src/notifications/tool-approval-copy.ts +0 -142
  433. package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
@@ -425,6 +425,62 @@ describe("RetryProvider — callSite resolution", () => {
425
425
  expect(config.temperature).toBe(0.5);
426
426
  });
427
427
 
428
+ test("forwards resolved topP to wire `top_p` (non-thinking provider)", async () => {
429
+ // `topP` (schema, camelCase) renames to `top_p` on the wire, mirroring
430
+ // `maxTokens`→`max_tokens`. Fireworks has no thinking constraint, so the
431
+ // value passes straight through.
432
+ setLlmConfig({
433
+ default: {
434
+ provider: "fireworks",
435
+ model: "fireworks-model",
436
+ topP: 0.95,
437
+ },
438
+ callSites: { mainAgent: {} },
439
+ });
440
+
441
+ let seen: SendMessageOptions | undefined;
442
+ const wrapped = new RetryProvider(
443
+ makeProvider("fireworks", (options) => {
444
+ seen = options;
445
+ }),
446
+ );
447
+
448
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
449
+ config: { callSite: "mainAgent" },
450
+ });
451
+
452
+ const config = seen?.config as Record<string, unknown>;
453
+ expect(config.top_p).toBe(0.95);
454
+ });
455
+
456
+ test("does NOT forward top_p when resolved topP is null (schema default)", async () => {
457
+ setLlmConfig({
458
+ default: {
459
+ provider: "fireworks",
460
+ model: "fireworks-model",
461
+ // `topP` defaults to null — "let provider pick".
462
+ },
463
+ callSites: { mainAgent: {} },
464
+ });
465
+
466
+ let seen: SendMessageOptions | undefined;
467
+ const wrapped = new RetryProvider(
468
+ makeProvider("fireworks", (options) => {
469
+ seen = options;
470
+ }),
471
+ );
472
+
473
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
474
+ config: { callSite: "mainAgent" },
475
+ });
476
+
477
+ const config = seen?.config as Record<string, unknown>;
478
+ // Must NOT be set — `top_p: null` would either be a wire error or override
479
+ // sensible provider defaults, mirroring the `temperature` handling.
480
+ expect(config.top_p).toBeUndefined();
481
+ expect("top_p" in config).toBe(false);
482
+ });
483
+
428
484
  test("strips effort/speed for providers that don't support them (e.g. fireworks)", async () => {
429
485
  setLlmConfig({
430
486
  default: {
@@ -773,6 +829,126 @@ describe("RetryProvider — thinking/temperature conflict guard", () => {
773
829
  });
774
830
  });
775
831
 
832
+ // ── RetryProvider — Anthropic thinking + top_p conflict guard ───────────────
833
+ //
834
+ // Anthropic rejects *any* `top_p` modification when extended thinking is
835
+ // enabled (same constraint family as `temperature` ≠ 1, but with no
836
+ // "=== 1 is fine" exception). This guard drops the offending `top_p` so the
837
+ // request goes through with Anthropic's default instead of 400ing at the wire.
838
+
839
+ describe("RetryProvider — thinking/top_p conflict guard", () => {
840
+ test("drops top_p when thinking is enabled (Anthropic)", async () => {
841
+ setLlmConfig({
842
+ default: {
843
+ provider: "anthropic",
844
+ model: "claude-opus-4-7",
845
+ thinking: { enabled: true, streamThinking: true },
846
+ topP: 0.95,
847
+ },
848
+ callSites: { mainAgent: {} },
849
+ });
850
+
851
+ let seen: SendMessageOptions | undefined;
852
+ const wrapped = new RetryProvider(
853
+ makeProvider("anthropic", (options) => {
854
+ seen = options;
855
+ }),
856
+ );
857
+
858
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
859
+ config: { callSite: "mainAgent" },
860
+ });
861
+
862
+ const config = seen?.config as Record<string, unknown>;
863
+ expect(config.thinking).toEqual({ type: "adaptive" });
864
+ expect(config.top_p).toBeUndefined();
865
+ expect("top_p" in config).toBe(false);
866
+ });
867
+
868
+ test("drops top_p for OpenRouter when fronting an `anthropic/*` model", async () => {
869
+ setLlmConfig({
870
+ default: {
871
+ provider: "openrouter",
872
+ model: "anthropic/claude-opus-4-7",
873
+ thinking: { enabled: true, streamThinking: true },
874
+ topP: 0.9,
875
+ },
876
+ callSites: { mainAgent: {} },
877
+ });
878
+
879
+ let seen: SendMessageOptions | undefined;
880
+ const wrapped = new RetryProvider(
881
+ makeProvider("openrouter", (options) => {
882
+ seen = options;
883
+ }),
884
+ );
885
+
886
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
887
+ config: { callSite: "mainAgent" },
888
+ });
889
+
890
+ const config = seen?.config as Record<string, unknown>;
891
+ expect(config.model).toBe("anthropic/claude-opus-4-7");
892
+ expect(config.top_p).toBeUndefined();
893
+ });
894
+
895
+ test("preserves top_p when thinking is enabled on a non-Anthropic provider (fireworks)", async () => {
896
+ // Fireworks (and other non-Anthropic providers) don't share Anthropic's
897
+ // top_p-with-thinking constraint — the guard must not over-reach. Note
898
+ // that fireworks strips `thinking` itself, but `top_p` stays.
899
+ setLlmConfig({
900
+ default: {
901
+ provider: "fireworks",
902
+ model: "fireworks-model",
903
+ thinking: { enabled: true, streamThinking: true },
904
+ topP: 0.95,
905
+ },
906
+ callSites: { mainAgent: {} },
907
+ });
908
+
909
+ let seen: SendMessageOptions | undefined;
910
+ const wrapped = new RetryProvider(
911
+ makeProvider("fireworks", (options) => {
912
+ seen = options;
913
+ }),
914
+ );
915
+
916
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
917
+ config: { callSite: "mainAgent" },
918
+ });
919
+
920
+ const config = seen?.config as Record<string, unknown>;
921
+ expect(config.top_p).toBe(0.95);
922
+ });
923
+
924
+ test("preserves top_p when thinking is disabled (Anthropic)", async () => {
925
+ setLlmConfig({
926
+ default: {
927
+ provider: "anthropic",
928
+ model: "claude-opus-4-7",
929
+ thinking: { enabled: false, streamThinking: false },
930
+ topP: 0.95,
931
+ },
932
+ callSites: { mainAgent: {} },
933
+ });
934
+
935
+ let seen: SendMessageOptions | undefined;
936
+ const wrapped = new RetryProvider(
937
+ makeProvider("anthropic", (options) => {
938
+ seen = options;
939
+ }),
940
+ );
941
+
942
+ await wrapped.sendMessage(DUMMY_MESSAGES, {
943
+ config: { callSite: "mainAgent" },
944
+ });
945
+
946
+ const config = seen?.config as Record<string, unknown>;
947
+ expect(config.thinking).toEqual({ type: "disabled" });
948
+ expect(config.top_p).toBe(0.95);
949
+ });
950
+ });
951
+
776
952
  // ── RetryProvider — pre-resolved model fast-path ────────────────────────────
777
953
 
778
954
  describe("RetryProvider — no callSite (pre-resolved config passes through)", () => {
@@ -0,0 +1,85 @@
1
+ import OpenAI from "openai";
2
+
3
+ import { getLogger } from "../../util/logger.js";
4
+ import { OpenAIChatCompletionsProvider } from "../openai/chat-completions-provider.js";
5
+
6
+ const log = getLogger("atlascloud-client");
7
+
8
+ /** Validation-specific timeout (10s) so a stalled network doesn't block key submission. */
9
+ const VALIDATION_TIMEOUT_MS = 10_000;
10
+
11
+ export interface AtlasCloudProviderOptions {
12
+ apiKey?: string;
13
+ streamTimeoutMs?: number;
14
+ }
15
+
16
+ /**
17
+ * Atlas Cloud exposes a single OpenAI-compatible endpoint. Unlike MiniMax it
18
+ * has no regional fallback host, so validation targets this URL only.
19
+ */
20
+ const DEFAULT_ATLASCLOUD_BASE_URL = "https://api.atlascloud.ai/v1";
21
+
22
+ /**
23
+ * Validate an Atlas Cloud API key by listing models against the OpenAI-compatible
24
+ * endpoint. Definitive auth failures (401/403) reject the key; transient errors
25
+ * (429, 5xx, network) allow the key to be stored so a flaky network doesn't
26
+ * block setup.
27
+ */
28
+ export async function validateAtlasCloudApiKey(
29
+ apiKey: string,
30
+ ): Promise<{ valid: true } | { valid: false; reason: string }> {
31
+ try {
32
+ const client = new OpenAI({
33
+ apiKey,
34
+ baseURL: DEFAULT_ATLASCLOUD_BASE_URL,
35
+ timeout: VALIDATION_TIMEOUT_MS,
36
+ maxRetries: 0,
37
+ });
38
+ await client.models.list();
39
+ return { valid: true };
40
+ } catch (error) {
41
+ if (error instanceof OpenAI.APIError) {
42
+ if (error.status === 401) {
43
+ return { valid: false, reason: "API key is invalid or expired." };
44
+ }
45
+ if (error.status === 403) {
46
+ return {
47
+ valid: false,
48
+ reason: `Atlas Cloud API error (${error.status}): ${error.message}`,
49
+ };
50
+ }
51
+ // Transient errors (429, 5xx, etc.) — allow the key to be stored.
52
+ log.warn(
53
+ { status: error.status },
54
+ "Atlas Cloud API returned a transient error during key validation — allowing key",
55
+ );
56
+ return { valid: true };
57
+ }
58
+ // Network errors — allow the key to be stored.
59
+ log.warn(
60
+ { error: error instanceof Error ? error.message : String(error) },
61
+ "Network error during Atlas Cloud key validation — allowing key",
62
+ );
63
+ return { valid: true };
64
+ }
65
+ }
66
+
67
+ export class AtlasCloudProvider extends OpenAIChatCompletionsProvider {
68
+ constructor(
69
+ apiKey: string,
70
+ model: string,
71
+ options: AtlasCloudProviderOptions = {},
72
+ ) {
73
+ super(apiKey, model, {
74
+ baseURL: DEFAULT_ATLASCLOUD_BASE_URL,
75
+ providerName: "atlascloud",
76
+ providerLabel: "Atlas Cloud",
77
+ streamTimeoutMs: options.streamTimeoutMs,
78
+ // Atlas Cloud hosts reasoning models (e.g. DeepSeek) that emit chain of
79
+ // thought via `reasoning_content` rather than inline `<think>` tags. The
80
+ // base provider parses this field into thinking blocks and replays it on
81
+ // multi-turn requests.
82
+ assistantReasoningField: "reasoning_content",
83
+ });
84
+ }
85
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Canonical catalog of built-in web-fetch providers.
3
+ *
4
+ * This is the single source of truth that drives the config-schema enum
5
+ * (`VALID_WEB_FETCH_PROVIDERS` in `assistant/src/config/schemas/services.ts`)
6
+ * and the client picker mirror in
7
+ * `clients/web/src/assistant/generated/web-fetch-provider-catalog.gen.ts`.
8
+ *
9
+ * Mirrors `search-provider-catalog.ts`. Where web-search distinguishes
10
+ * `managed` (platform proxy) from `byok` (user key), web-fetch has no managed
11
+ * proxy yet, so the two kinds are:
12
+ *
13
+ * - `builtin` — the daemon's own HTTP fetch + extract path (`default`). No
14
+ * key, always available, the default.
15
+ * - `byok` — an external provider that needs a user-supplied key (e.g.
16
+ * `firecrawl`, which scrapes via its hosted API and returns clean
17
+ * markdown, including for JavaScript-rendered pages the builtin fetcher
18
+ * can't see).
19
+ *
20
+ * BYOK fetch providers intentionally reuse the SAME bare-name credential as
21
+ * their search counterpart (e.g. `firecrawl` → `FIRECRAWL_API_KEY`), so a
22
+ * single stored key powers both `web_search` and `web_fetch`. The key is
23
+ * already registered in `API_KEY_PROVIDERS` via `SEARCH_PROVIDER_CATALOG`;
24
+ * this catalog deliberately does NOT re-register it.
25
+ */
26
+
27
+ export type FetchProviderKind = "builtin" | "byok";
28
+
29
+ export interface FetchProviderCatalogEntry {
30
+ /** Stable provider identifier. Matches config values. */
31
+ readonly id: string;
32
+ /** Short display name used by picker UIs. */
33
+ readonly displayName: string;
34
+ /** Optional long display name for prose contexts. */
35
+ readonly displayNameLong?: string;
36
+ /** `builtin` (no key) or `byok` (user-supplied key). */
37
+ readonly kind: FetchProviderKind;
38
+ /** Placeholder shown in the API-key input. BYOK providers only. */
39
+ readonly apiKeyPrefix?: string;
40
+ /** Environment variable name carrying the API key. BYOK providers only. */
41
+ readonly envVar?: string;
42
+ /** Secret-catalog key (the bare provider name accepted by
43
+ * `getProviderKeyAsync`). BYOK providers only. */
44
+ readonly secretKey?: string;
45
+ /** Privacy-policy URL surfaced in marketing data-sharing docs.
46
+ * BYOK providers only. */
47
+ readonly privacyPolicyUrl?: string;
48
+ }
49
+
50
+ export const FETCH_PROVIDER_CATALOG: readonly FetchProviderCatalogEntry[] = [
51
+ {
52
+ id: "default",
53
+ displayName: "Built-in",
54
+ displayNameLong: "Built-in fetcher",
55
+ kind: "builtin",
56
+ },
57
+ {
58
+ id: "firecrawl",
59
+ displayName: "Firecrawl",
60
+ kind: "byok",
61
+ apiKeyPrefix: "fc-...",
62
+ envVar: "FIRECRAWL_API_KEY",
63
+ secretKey: "firecrawl",
64
+ privacyPolicyUrl: "https://www.firecrawl.dev/privacy-policy",
65
+ },
66
+ ];
67
+
68
+ /** Provider ids accepted by the web-fetch config schema. */
69
+ export const FETCH_PROVIDER_IDS: readonly string[] =
70
+ FETCH_PROVIDER_CATALOG.map((p) => p.id);
71
+
72
+ /** Catalog entries that require a user-supplied API key. */
73
+ export const BYOK_FETCH_PROVIDERS: readonly FetchProviderCatalogEntry[] =
74
+ FETCH_PROVIDER_CATALOG.filter((p) => p.kind === "byok");
75
+
76
+ /** BYOK fetch-provider ids. */
77
+ export const BYOK_FETCH_PROVIDER_IDS: readonly string[] =
78
+ BYOK_FETCH_PROVIDERS.map((p) => p.id);
79
+
80
+ /** Look up a single catalog entry by id. Returns `undefined` if unknown. */
81
+ export function getFetchProvider(
82
+ id: string,
83
+ ): FetchProviderCatalogEntry | undefined {
84
+ return FETCH_PROVIDER_CATALOG.find((p) => p.id === id);
85
+ }
@@ -19,6 +19,7 @@
19
19
  */
20
20
 
21
21
  import { AnthropicProvider } from "../anthropic/client.js";
22
+ import { AtlasCloudProvider } from "../atlascloud/client.js";
22
23
  import { FireworksProvider } from "../fireworks/client.js";
23
24
  import { GeminiProvider } from "../gemini/client.js";
24
25
  import { MinimaxProvider } from "../minimax/client.js";
@@ -114,6 +115,8 @@ const ADAPTER_FACTORIES: Record<string, AdapterFactory> = {
114
115
  }),
115
116
  minimax: ({ apiKey, model, streamTimeoutMs }) =>
116
117
  new MinimaxProvider(apiKey, model, { streamTimeoutMs }),
118
+ atlascloud: ({ apiKey, model, streamTimeoutMs }) =>
119
+ new AtlasCloudProvider(apiKey, model, { streamTimeoutMs }),
117
120
  };
118
121
 
119
122
  /**
@@ -677,6 +677,23 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
677
677
  cacheReadPer1mTokens: 0.16,
678
678
  },
679
679
  },
680
+ {
681
+ id: "accounts/fireworks/models/glm-5p2",
682
+ displayName: "GLM 5.2",
683
+ // Fireworks serves GLM 5.2 with a 1,040K input window.
684
+ contextWindowTokens: 1040000,
685
+ maxOutputTokens: 131072,
686
+ supportsThinking: true,
687
+ supportsCaching: true,
688
+ supportsVision: false,
689
+ supportsToolUse: true,
690
+ maxEffort: "max",
691
+ pricing: {
692
+ inputPer1mTokens: 1.4,
693
+ outputPer1mTokens: 4.4,
694
+ cacheReadPer1mTokens: 0.26,
695
+ },
696
+ },
680
697
  {
681
698
  id: "accounts/fireworks/models/kimi-k2p5",
682
699
  displayName: "Kimi K2.5",
@@ -1148,6 +1165,18 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
1148
1165
  supportsToolUse: false,
1149
1166
  pricing: { inputPer1mTokens: 0.2, outputPer1mTokens: 1.1 },
1150
1167
  },
1168
+ // Z.ai
1169
+ {
1170
+ id: "z-ai/glm-5.2",
1171
+ displayName: "GLM-5.2",
1172
+ contextWindowTokens: 1048576,
1173
+ maxOutputTokens: 131072,
1174
+ supportsThinking: true,
1175
+ supportsCaching: false,
1176
+ supportsVision: false,
1177
+ supportsToolUse: true,
1178
+ pricing: { inputPer1mTokens: 1.4, outputPer1mTokens: 4.4 },
1179
+ },
1151
1180
  // Mistral
1152
1181
  {
1153
1182
  id: "mistralai/mistral-medium-3",
@@ -1284,6 +1313,35 @@ const RAW_PROVIDER_CATALOG: ProviderCatalogEntry[] = [
1284
1313
  apiKeyUrl: "https://platform.minimax.io/",
1285
1314
  apiKeyPlaceholder: "sk-cp-...",
1286
1315
  },
1316
+ {
1317
+ id: "atlascloud",
1318
+ displayName: "Atlas Cloud",
1319
+ subtitle:
1320
+ "Atlas Cloud AI models (OpenAI-compatible). Requires an Atlas Cloud API key.",
1321
+ setupMode: "api-key",
1322
+ setupHint: "Enter your Atlas Cloud API key to enable Atlas Cloud models.",
1323
+ envVar: "ATLASCLOUD_API_KEY",
1324
+ credentialsGuide: {
1325
+ description: "Sign in to the Atlas Cloud console and create an API key.",
1326
+ url: "https://www.atlascloud.ai/console",
1327
+ linkLabel: "Open Atlas Cloud Console",
1328
+ },
1329
+ models: [
1330
+ {
1331
+ id: "deepseek-ai/deepseek-v4-pro",
1332
+ displayName: "DeepSeek V4 Pro",
1333
+ contextWindowTokens: 128000,
1334
+ maxOutputTokens: 8192,
1335
+ supportsThinking: true,
1336
+ supportsCaching: false,
1337
+ supportsVision: false,
1338
+ supportsToolUse: true,
1339
+ },
1340
+ ],
1341
+ defaultModel: "deepseek-ai/deepseek-v4-pro",
1342
+ apiKeyUrl: "https://www.atlascloud.ai/console",
1343
+ apiKeyPlaceholder: "apikey-...",
1344
+ },
1287
1345
  ];
1288
1346
 
1289
1347
  export const PROVIDER_CATALOG: ProviderCatalogEntry[] =
@@ -460,6 +460,39 @@ describe("OpenAIChatCompletionsProvider reasoning parsing", () => {
460
460
  expect(params.messages[0].content).toBeNull();
461
461
  });
462
462
 
463
+ test("forwards config.top_p onto the request body", async () => {
464
+ const { provider, requests } = stubProvider([
465
+ {
466
+ choices: [{ delta: { content: "ok" }, finish_reason: "stop" }],
467
+ usage: { prompt_tokens: 2, completion_tokens: 1 },
468
+ },
469
+ ]);
470
+
471
+ await provider.sendMessage(
472
+ [{ role: "user", content: [{ type: "text", text: "hi" }] }],
473
+ { config: { top_p: 0.95 } },
474
+ );
475
+
476
+ const params = requests[0] as { top_p?: number };
477
+ expect(params.top_p).toBe(0.95);
478
+ });
479
+
480
+ test("omits top_p from the request body when not configured", async () => {
481
+ const { provider, requests } = stubProvider([
482
+ {
483
+ choices: [{ delta: { content: "ok" }, finish_reason: "stop" }],
484
+ usage: { prompt_tokens: 2, completion_tokens: 1 },
485
+ },
486
+ ]);
487
+
488
+ await provider.sendMessage([
489
+ { role: "user", content: [{ type: "text", text: "hi" }] },
490
+ ]);
491
+
492
+ const params = requests[0] as { top_p?: number };
493
+ expect(params.top_p).toBeUndefined();
494
+ });
495
+
463
496
  test("skips Anthropic-originated thinking blocks (with signatures)", async () => {
464
497
  const { provider, requests } = stubProvider(
465
498
  [
@@ -367,6 +367,7 @@ export class OpenAIChatCompletionsProvider implements Provider {
367
367
  const logitBias = configObj?.logit_bias as
368
368
  | Record<string, number>
369
369
  | undefined;
370
+ const topP = configObj?.top_p as number | undefined;
370
371
  const usageAttributionHeaders = configObj?.usageAttributionHeaders as
371
372
  | Record<string, string>
372
373
  | undefined;
@@ -398,6 +399,12 @@ export class OpenAIChatCompletionsProvider implements Provider {
398
399
  params.logit_bias = logitBias;
399
400
  }
400
401
 
402
+ // `top_p` (nucleus sampling). Forwarded explicitly because this client
403
+ // builds `params` field-by-field rather than spreading the config object.
404
+ if (typeof topP === "number") {
405
+ params.top_p = topP;
406
+ }
407
+
401
408
  // Subclasses (OpenRouter) may already have nested effort under
402
409
  // `reasoning.effort` via `buildExtraCreateParams`. Skip the flat
403
410
  // `reasoning_effort` assignment in that case to avoid sending both forms,
@@ -243,6 +243,16 @@ export class OpenAIResponsesProvider implements Provider {
243
243
  params.text = { verbosity };
244
244
  }
245
245
 
246
+ // Sampling params (`top_p`/`temperature`) are intentionally NOT forwarded
247
+ // on the Responses path. OpenAI reasoning models (o-series, GPT-5
248
+ // reasoning) reject them with HTTP 400 when reasoning is active, and the
249
+ // resolved `effort` defaults to a reasoning effort, so `reasoning` is set
250
+ // on essentially every Responses request. The profile editor therefore
251
+ // doesn't surface `topP` for the native `openai` provider (mirroring
252
+ // `temperature`, which is also never offered/forwarded here); OpenAI-
253
+ // compatible connections, which use the chat-completions client, honor
254
+ // `top_p` normally.
255
+
246
256
  if (tools && tools.length > 0) {
247
257
  if (
248
258
  this.useNativeWebSearch &&
@@ -48,6 +48,7 @@ export class CallSiteConfiguredProvider implements Provider {
48
48
  private readonly inner: Provider,
49
49
  private readonly callSite: LLMCallSite,
50
50
  private readonly overrideProfile?: string,
51
+ private readonly forceOverrideProfile?: boolean,
51
52
  ) {
52
53
  this.name = inner.name;
53
54
  this.tokenEstimationProvider = inner.tokenEstimationProvider;
@@ -71,6 +72,10 @@ export class CallSiteConfiguredProvider implements Provider {
71
72
  this.overrideProfile !== undefined
72
73
  ? { overrideProfile: this.overrideProfile }
73
74
  : {}),
75
+ ...(config?.forceOverrideProfile === undefined &&
76
+ this.forceOverrideProfile !== undefined
77
+ ? { forceOverrideProfile: this.forceOverrideProfile }
78
+ : {}),
74
79
  },
75
80
  });
76
81
  }
@@ -88,13 +93,15 @@ export class CallSiteConfiguredProvider implements Provider {
88
93
  * matching call-site identifier from `LLMCallSiteEnum` when adding a new
89
94
  * caller. Pass `opts.overrideProfile` to apply a per-call ad-hoc profile
90
95
  * override (e.g. a per-conversation pinned profile) on top of any workspace
91
- * `activeProfile`.
96
+ * `activeProfile`. Pass `opts.forceOverrideProfile` to float that override
97
+ * above the call-site layers (named site profile + call-site override) for
98
+ * non-main-agent call sites — see `ResolveCallSiteOpts.forceOverrideProfile`.
92
99
  *
93
100
  * Returns `null` when no providers are available at all.
94
101
  */
95
102
  export async function resolveConfiguredProvider(
96
103
  callSite: LLMCallSite,
97
- opts: { overrideProfile?: string } = {},
104
+ opts: { overrideProfile?: string; forceOverrideProfile?: boolean } = {},
98
105
  ): Promise<ConfiguredProviderResult | null> {
99
106
  const config = getConfig();
100
107
 
@@ -174,6 +181,7 @@ export async function resolveConfiguredProvider(
174
181
  connectionProvider,
175
182
  callSite,
176
183
  opts.overrideProfile,
184
+ opts.forceOverrideProfile,
177
185
  ),
178
186
  configuredProviderName: inferenceProvider,
179
187
  };
@@ -189,7 +197,7 @@ export async function resolveConfiguredProvider(
189
197
  */
190
198
  export async function getConfiguredProvider(
191
199
  callSite: LLMCallSite,
192
- opts: { overrideProfile?: string } = {},
200
+ opts: { overrideProfile?: string; forceOverrideProfile?: boolean } = {},
193
201
  ): Promise<Provider | null> {
194
202
  const result = await resolveConfiguredProvider(callSite, opts);
195
203
  return result?.provider ?? null;
@@ -268,6 +268,16 @@ function normalizeSendMessageOptions(
268
268
  ) {
269
269
  nextConfig.temperature = resolved.temperature;
270
270
  }
271
+ // `topP` (schema, camelCase) maps to the provider wire field `top_p`.
272
+ // Defaults to `null` ("no opinion"); only forward an actual number so we
273
+ // never send `top_p: null`, mirroring the `temperature` handling above.
274
+ if (
275
+ nextConfig.top_p === undefined &&
276
+ resolved.topP !== null &&
277
+ resolved.topP !== undefined
278
+ ) {
279
+ nextConfig.top_p = resolved.topP;
280
+ }
271
281
  if (nextConfig.thinking === undefined && resolved.thinking !== undefined) {
272
282
  nextConfig.thinking = resolved.thinking;
273
283
  }
@@ -428,12 +438,16 @@ function normalizeSendMessageOptions(
428
438
  // - Other providers: not our problem here (e.g. OpenAI reasoning models
429
439
  // strip `temperature` upstream; non-Anthropic OpenRouter reasoning
430
440
  // models don't have this exact constraint).
431
- const isThinkingTemperatureConflict = (() => {
441
+ //
442
+ // Anthropic applies the same constraint family to `top_p` (see the `top_p`
443
+ // guard below), so the "thinking is enabled on the Anthropic wire" predicate
444
+ // is shared between the two guards.
445
+ const isThinkingEnabledOnAnthropicWire = (() => {
432
446
  const model = typeof nextConfig.model === "string" ? nextConfig.model : "";
433
- // Claude Fable always reasons in adaptive mode, so the `temperature: 1`
434
- // constraint applies even when no explicit `thinking` config is present
435
- // (a disabled config was already dropped above). For every other model
436
- // the constraint only applies when thinking is actually enabled.
447
+ // Claude Fable always reasons in adaptive mode, so the constraint applies
448
+ // even when no explicit `thinking` config is present (a disabled config was
449
+ // already dropped above). For every other model the constraint only applies
450
+ // when thinking is actually enabled.
437
451
  if (!isAdaptiveThinkingOnlyModel(model)) {
438
452
  if (nextConfig.thinking == null) {
439
453
  return false;
@@ -442,13 +456,6 @@ function normalizeSendMessageOptions(
442
456
  return false;
443
457
  }
444
458
  }
445
- const temp = nextConfig.temperature;
446
- if (typeof temp !== "number") {
447
- return false;
448
- }
449
- if (temp === 1) {
450
- return false;
451
- }
452
459
  if (providerName === "anthropic") {
453
460
  return true;
454
461
  }
@@ -457,6 +464,18 @@ function normalizeSendMessageOptions(
457
464
  }
458
465
  return false;
459
466
  })();
467
+ const isThinkingTemperatureConflict = (() => {
468
+ if (!isThinkingEnabledOnAnthropicWire) {
469
+ return false;
470
+ }
471
+ const temp = nextConfig.temperature;
472
+ if (typeof temp !== "number") {
473
+ return false;
474
+ }
475
+ // Unlike `top_p`, `temperature: 1` is explicitly accepted alongside
476
+ // thinking, so it's the one value that doesn't conflict.
477
+ return temp !== 1;
478
+ })();
460
479
  if (isThinkingTemperatureConflict) {
461
480
  log.warn(
462
481
  {
@@ -472,6 +491,28 @@ function normalizeSendMessageOptions(
472
491
  delete nextConfig.temperature;
473
492
  }
474
493
 
494
+ // Anthropic (and OpenRouter fronting Anthropic) also rejects requests that
495
+ // combine extended thinking with *any* `top_p` modification. Unlike
496
+ // `temperature` there is no "=== 1 is fine" exception — when thinking is
497
+ // enabled the request must not set `top_p` at all. Drop it with a warn log
498
+ // so the request goes through with Anthropic's default, keeping `thinking`
499
+ // (the more deliberate, profile-level choice) for the same reasons as the
500
+ // temperature guard above.
501
+ if (isThinkingEnabledOnAnthropicWire && nextConfig.top_p !== undefined) {
502
+ log.warn(
503
+ {
504
+ providerName,
505
+ callSite: config.callSite,
506
+ droppedTopP: nextConfig.top_p,
507
+ },
508
+ "Dropping `top_p` because thinking is enabled — Anthropic does not " +
509
+ "accept `top_p` modifications when thinking/adaptive mode is on. Set " +
510
+ "`thinking: { type: 'disabled' }` on the call site if you need a " +
511
+ "specific top_p.",
512
+ );
513
+ delete nextConfig.top_p;
514
+ }
515
+
475
516
  // effort is supported by Anthropic, OpenAI, and OpenAI-compatible providers; strip for others
476
517
  if (
477
518
  !EFFORT_SUPPORTED_PROVIDERS.has(providerName) &&