@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.
- package/docs/activation-funnel-telemetry.md +24 -18
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +15 -0
- package/openapi.yaml +852 -15
- package/package.json +1 -1
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +59 -7
- package/src/__tests__/agent-loop-compaction-strip.test.ts +17 -16
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +174 -30
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-prompt-route.test.ts +1 -0
- package/src/__tests__/credential-security-invariants.test.ts +2 -0
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +51 -0
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +0 -3
- package/src/__tests__/llm-catalog-parity.test.ts +30 -1
- package/src/__tests__/llm-resolver.test.ts +21 -0
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +38 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +5 -0
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +150 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-verification.test.ts +2 -4
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +0 -1
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +33 -33
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +26 -0
- package/src/api/responses/home.ts +26 -0
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +181 -78
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +57 -5
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +134 -4
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +53 -11
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/merge-plugin-tree.ts +149 -49
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +64 -36
- package/src/cli/program.ts +2 -4
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/workflows/SKILL.md +14 -7
- package/src/config/call-site-defaults.ts +3 -0
- package/src/config/feature-flag-registry.json +49 -18
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +94 -34
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +2 -10
- package/src/contacts/contacts-write.ts +1 -2
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +86 -52
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +100 -19
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +16 -11
- package/src/daemon/conversation.ts +64 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +5 -10
- package/src/daemon/handlers/config-slack-channel.ts +20 -0
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -20
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +34 -0
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +10 -0
- package/src/memory/embedding-backend.ts +15 -1
- package/src/memory/jobs-worker.ts +2 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +9 -0
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +10 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +30 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -1
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/slack.ts +55 -73
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +6 -2
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +3 -13
- package/src/notifications/notification-utils.ts +2 -1
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -128
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/index.ts +27 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +35 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +75 -7
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +37 -4
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +2 -12
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +12 -2
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +49 -21
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +5 -1
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +1 -2
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +6 -22
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +35 -13
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +37 -12
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +88 -6
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +40 -7
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +225 -1
- package/src/runtime/routes/workflow-routes.ts +131 -1
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +11 -4
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +29 -18
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +3 -2
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +4 -3
- package/src/tools/schedule/update.ts +2 -1
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/skills/execute.ts +1 -2
- package/src/tools/subagent/spawn.ts +37 -13
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +17 -10
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +25 -2
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +8 -1
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -3
- package/src/workflows/run-manager.ts +64 -0
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/notifications/tool-approval-copy.ts +0 -142
- 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;
|
package/src/providers/retry.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
//
|
|
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) &&
|