@vellumai/assistant 0.8.1 → 0.8.3
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/ARCHITECTURE.md +13 -19
- package/Dockerfile +75 -1
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +17 -0
- package/docker-init-apt-root.sh +167 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +642 -5
- package/package.json +3 -1
- package/scripts/generate-openapi.ts +83 -10
- package/scripts/sync-llm-catalog.ts +2 -2
- package/scripts/sync-web-search-catalog.ts +47 -25
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-loop-exit-reason.test.ts +272 -0
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +195 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +45 -0
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/compactor-tail-resolution.test.ts +147 -0
- package/src/__tests__/config-get-vision-flag.test.ts +136 -0
- package/src/__tests__/config-loader-backfill.test.ts +115 -18
- package/src/__tests__/config-schema.test.ts +21 -0
- package/src/__tests__/config-set-route.test.ts +80 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/context-search-conversations-source.test.ts +117 -2
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +31 -65
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +92 -92
- package/src/__tests__/conversation-agent-loop.test.ts +59 -1
- package/src/__tests__/conversation-error.test.ts +42 -3
- package/src/__tests__/conversation-fork-crud.test.ts +82 -0
- package/src/__tests__/conversation-inference-profile-route.test.ts +40 -4
- package/src/__tests__/conversation-lifecycle.test.ts +173 -0
- package/src/__tests__/conversation-media-retry.test.ts +19 -8
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-callsite.test.ts +4 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +102 -13
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +3 -2
- package/src/__tests__/date-context.test.ts +45 -0
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +151 -55
- package/src/__tests__/filing-service.test.ts +140 -0
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/guardian-action-no-hardcoded-copy.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +43 -62
- package/src/__tests__/heartbeat-service.test.ts +24 -164
- package/src/__tests__/helpers/channel-test-adapter.ts +0 -2
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +73 -0
- package/src/__tests__/host-app-control-proxy.test.ts +507 -10
- package/src/__tests__/host-proxy-preactivation.test.ts +200 -13
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +1 -1
- package/src/__tests__/inference-profile-reaper.test.ts +4 -2
- package/src/__tests__/inference-profile-session-handler.test.ts +18 -6
- package/src/__tests__/inference-profile-session-ipc.test.ts +17 -5
- package/src/__tests__/injector-background-turn.test.ts +153 -0
- package/src/__tests__/injector-chain.test.ts +15 -8
- package/src/__tests__/install-skill-routing.test.ts +155 -37
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +99 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-callsite-catalog.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +58 -13
- package/src/__tests__/llm-request-log-agent-loop-exit-reason.test.ts +116 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +138 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +36 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +29 -53
- package/src/__tests__/llm-resolver.test.ts +255 -2
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +41 -29
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/notification-decision-fallback.test.ts +0 -91
- package/src/__tests__/notification-decision-strategy.test.ts +14 -31
- package/src/__tests__/notification-deep-link.test.ts +15 -0
- package/src/__tests__/notification-guardian-path.test.ts +1 -2
- package/src/__tests__/notification-platform-adapter.test.ts +5 -4
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -0
- package/src/__tests__/notification-vellum-adapter.test.ts +113 -0
- package/src/__tests__/oauth-commands-routes.test.ts +168 -16
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/openai-provider.test.ts +242 -3
- package/src/__tests__/openai-responses-cutover-guard.test.ts +17 -9
- package/src/__tests__/openrouter-provider-only.test.ts +51 -3
- package/src/__tests__/openrouter-token-estimation.test.ts +34 -25
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +7 -2
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +10 -36
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +0 -1
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +16 -15
- package/src/__tests__/plugin-types.test.ts +3 -13
- package/src/__tests__/process-message-background-slack.test.ts +8 -1
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +158 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +33 -31
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-routes.test.ts +50 -3
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +54 -7
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +1 -1
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -12
- package/src/__tests__/skill-load-tool.test.ts +27 -89
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/system-prompt.test.ts +670 -63
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/user-plugin-loader.test.ts +0 -7
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +32 -10
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +115 -3
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +50 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-087-memory-router-balanced-profile.test.ts +228 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/a2a/__tests__/agent-card.test.ts +98 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +597 -0
- package/src/a2a/__tests__/protocol-helpers.test.ts +113 -0
- package/src/a2a/__tests__/task-store.test.ts +246 -0
- package/src/a2a/agent-card.ts +58 -0
- package/src/a2a/feature-gate.ts +8 -0
- package/src/a2a/protocol-constants.ts +21 -0
- package/src/a2a/protocol-errors.ts +50 -0
- package/src/a2a/protocol-types.ts +162 -0
- package/src/a2a/task-store.ts +168 -0
- package/src/acp/resolve-agent.ts +1 -1
- package/src/agent/image-optimize.ts +13 -5
- package/src/agent/loop.ts +167 -18
- package/src/calls/voice-session-bridge.ts +61 -42
- package/src/channels/config.ts +9 -0
- package/src/channels/types.ts +122 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/changelog.test.ts +304 -319
- package/src/cli/{__tests__ → commands/__tests__}/notifications.test.ts +201 -28
- package/src/cli/commands/__tests__/schedules.test.ts +960 -0
- package/src/cli/commands/changelog.ts +106 -42
- package/src/cli/commands/conversations.ts +102 -17
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/notifications.ts +388 -346
- package/src/cli/commands/plugins.ts +252 -0
- package/src/cli/commands/schedules.ts +683 -0
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +261 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/install-from-github.ts +303 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/search-plugins.ts +163 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +52 -2
- package/src/config/assistant-feature-flags.ts +24 -54
- package/src/config/bundled-skills/app-builder/SKILL.md +140 -22
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -0
- package/src/config/call-site-defaults.ts +105 -0
- package/src/config/feature-flag-registry.json +41 -9
- package/src/config/llm-resolver.ts +52 -1
- package/src/config/loader.ts +64 -38
- package/src/config/schema.ts +9 -10
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +3 -3
- package/src/config/schemas/channels.ts +17 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/conversations.ts +10 -0
- package/src/config/schemas/heartbeat.ts +23 -0
- package/src/config/schemas/llm-request-logs.ts +31 -7
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/memory-retrospective.ts +1 -1
- package/src/config/schemas/memory-v2.ts +4 -4
- package/src/config/schemas/memory.ts +3 -1
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/seed-inference-profiles.ts +99 -29
- package/src/config/skills.ts +3 -96
- package/src/context/compactor.ts +1107 -0
- package/src/context/token-estimator.ts +34 -36
- package/src/context/window-manager.ts +197 -1520
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +33 -18
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +74 -0
- package/src/daemon/approval-generators.ts +8 -6
- package/src/daemon/config-watcher.ts +94 -31
- package/src/daemon/conversation-agent-loop-handlers.ts +78 -0
- package/src/daemon/conversation-agent-loop.ts +198 -11
- package/src/daemon/conversation-error.ts +171 -37
- package/src/daemon/conversation-lifecycle.ts +53 -40
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +49 -12
- package/src/daemon/conversation-runtime-assembly.ts +25 -1
- package/src/daemon/conversation-slash.ts +12 -5
- package/src/daemon/conversation-store.ts +11 -4
- package/src/daemon/conversation-tool-setup.ts +39 -7
- package/src/daemon/conversation.ts +33 -8
- package/src/daemon/date-context.ts +40 -0
- package/src/daemon/external-plugins-bootstrap.ts +217 -181
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/guardian-action-generators.ts +1 -125
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +248 -0
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +154 -0
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +133 -0
- package/src/daemon/handlers/__tests__/config-a2a.test.ts +95 -0
- package/src/daemon/handlers/config-a2a.ts +289 -0
- package/src/daemon/handlers/config-model.ts +6 -5
- package/src/daemon/handlers/config-slack-channel.ts +15 -3
- package/src/daemon/handlers/conversations.ts +1 -0
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +111 -108
- package/src/daemon/history-repair.ts +28 -1
- package/src/daemon/host-app-control-proxy.ts +153 -27
- package/src/daemon/host-proxy-preactivation.ts +85 -18
- package/src/daemon/lifecycle.ts +89 -91
- package/src/daemon/meet-host-supervisor.ts +5 -4
- package/src/daemon/memory-v2-startup.ts +85 -0
- package/src/daemon/message-protocol.ts +1 -0
- package/src/daemon/message-types/conversations.ts +25 -0
- package/src/daemon/message-types/messages.ts +61 -0
- package/src/daemon/message-types/notifications.ts +21 -0
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pkb-reminder-builder.test.ts +11 -54
- package/src/daemon/pkb-reminder-builder.ts +5 -20
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +24 -3
- package/src/daemon/server.ts +11 -2
- package/src/daemon/skill-memory-refresh.ts +33 -0
- package/src/daemon/wake-target-adapter.ts +2 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/export/__tests__/transcript-formatter.test.ts +121 -0
- package/src/export/transcript-formatter.ts +54 -20
- package/src/filing/filing-service.ts +39 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +135 -6
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +73 -189
- package/src/home/__tests__/feed-types.test.ts +80 -0
- package/src/home/feed-types.ts +36 -2
- package/src/home/post-connect-feed.ts +1 -0
- package/src/index.ts +18 -1
- package/src/ipc/cli-client.ts +147 -45
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +33 -27
- package/src/memory/__tests__/conversation-queries.test.ts +483 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +2 -50
- package/src/memory/__tests__/memory-retrospective-job.test.ts +87 -4
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +119 -14
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +42 -10
- package/src/memory/context-search/sources/conversations.ts +62 -2
- package/src/memory/context-search/sources/workspace.ts +4 -0
- package/src/memory/conversation-crud.ts +63 -19
- package/src/memory/conversation-queries.ts +197 -11
- package/src/memory/conversation-title-service.ts +26 -4
- package/src/memory/db-init.ts +12 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +4 -4
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +150 -12
- package/src/memory/graph/conversation-graph-memory.ts +49 -21
- package/src/memory/graph/tools.ts +9 -40
- package/src/memory/indexer.ts +34 -29
- package/src/memory/invite-store.ts +53 -0
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +73 -0
- package/src/memory/jobs/embed-concept-page.ts +20 -11
- package/src/memory/jobs-worker.ts +6 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +24 -12
- package/src/memory/llm-request-log-source.ts +19 -52
- package/src/memory/llm-request-log-store.ts +92 -1
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-enqueue.ts +1 -20
- package/src/memory/memory-retrospective-job.ts +33 -6
- package/src/memory/memory-retrospective-startup-cleanup.ts +72 -5
- package/src/memory/message-content.ts +1 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/229-delete-private-conversations.test.ts +38 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +7 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/250-provider-connection-base-url-and-models.ts +28 -0
- package/src/memory/migrations/251-a2a-tasks.ts +49 -0
- package/src/memory/migrations/252-llm-request-log-agent-loop-exit-reason.ts +32 -0
- package/src/memory/migrations/index.ts +9 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/schema/a2a.ts +15 -0
- package/src/memory/schema/bookmarks.ts +0 -2
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/inference.ts +3 -3
- package/src/memory/schema/infrastructure.ts +13 -0
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/activation-store.test.ts +25 -23
- package/src/memory/v2/__tests__/activation.test.ts +0 -8
- package/src/memory/v2/__tests__/cli-command-store.test.ts +404 -0
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +25 -4
- package/src/memory/v2/__tests__/injection.test.ts +288 -11
- package/src/memory/v2/__tests__/migration.test.ts +87 -0
- package/src/memory/v2/__tests__/page-index.test.ts +83 -0
- package/src/memory/v2/__tests__/prompts-router.test.ts +58 -6
- package/src/memory/v2/__tests__/qdrant.test.ts +66 -3
- package/src/memory/v2/__tests__/router.test.ts +15 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +387 -8
- package/src/memory/v2/__tests__/static-context.test.ts +12 -1
- package/src/memory/v2/activation-store.ts +14 -16
- package/src/memory/v2/cli-command-content.ts +19 -0
- package/src/memory/v2/cli-command-store.ts +304 -0
- package/src/memory/v2/frontmatter-sweep.ts +7 -1
- package/src/memory/v2/injection.ts +81 -26
- package/src/memory/v2/migration.ts +49 -19
- package/src/memory/v2/page-index.ts +63 -8
- package/src/memory/v2/prompts/router.ts +11 -8
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +135 -7
- package/src/memory/v2/router.ts +9 -8
- package/src/memory/v2/skill-store.ts +120 -35
- package/src/memory/v2/static-context.ts +4 -4
- package/src/memory/v2/types.ts +23 -0
- package/src/messaging/providers/a2a/__tests__/deliver.test.ts +274 -0
- package/src/messaging/providers/a2a/deliver.ts +156 -0
- package/src/messaging/providers/gmail/client.ts +9 -2
- package/src/messaging/providers/index.ts +11 -2
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/__tests__/broadcaster.test.ts +203 -0
- package/src/notifications/__tests__/decision-engine.test.ts +283 -0
- package/src/notifications/__tests__/deterministic-checks.test.ts +286 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +430 -7
- package/src/notifications/adapters/macos.ts +12 -2
- package/src/notifications/broadcaster.ts +29 -4
- package/src/notifications/conversation-pairing.ts +2 -1
- package/src/notifications/copy-composer.ts +17 -64
- package/src/notifications/decision-engine.ts +113 -45
- package/src/notifications/deterministic-checks.ts +96 -0
- package/src/notifications/emit-signal.ts +21 -1
- package/src/notifications/home-feed-side-effect.ts +138 -5
- package/src/notifications/signal.ts +3 -5
- package/src/notifications/types.ts +8 -0
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.test.ts +43 -3
- package/src/oauth/platform-connection.ts +19 -6
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +34 -1
- package/src/plugin-api/types.ts +104 -22
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +74 -22
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +187 -42
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +40 -26
- package/src/plugins/user-loader.ts +21 -2
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +37 -5
- package/src/prompts/__tests__/system-prompt.test.ts +10 -43
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +95 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +63 -174
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +164 -0
- package/src/providers/__tests__/inference.test.ts +24 -7
- package/src/providers/anthropic/client.ts +28 -28
- package/src/providers/call-site-routing.ts +24 -6
- package/src/providers/connection-resolution.ts +68 -11
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +74 -0
- package/src/providers/inference/__tests__/connections-openai-compatible.test.ts +175 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +15 -0
- package/src/providers/inference/adapter-factory.ts +32 -6
- package/src/providers/inference/auth.ts +12 -0
- package/src/providers/inference/backfill.ts +14 -1
- package/src/providers/inference/connections.ts +159 -34
- package/src/providers/inference/resolve-auth.ts +14 -4
- package/src/providers/model-catalog.ts +249 -12
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +235 -0
- package/src/providers/openai/chat-completions-provider.ts +169 -8
- package/src/providers/openrouter/client.ts +49 -4
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -2
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +38 -0
- package/src/providers/provider-send-message.ts +27 -12
- package/src/providers/registry.ts +52 -15
- package/src/providers/retry.ts +47 -1
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/agent-wake.ts +103 -15
- package/src/runtime/auth/route-policy.ts +21 -1
- package/src/runtime/btw-sidechain.ts +2 -0
- package/src/runtime/http-server.ts +7 -16
- package/src/runtime/http-types.ts +19 -47
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +17 -0
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +258 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +172 -23
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +275 -44
- package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +12 -0
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +64 -1
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +5 -3
- package/src/runtime/routes/auth-routes.ts +1 -1
- package/src/runtime/routes/bookmark-routes.ts +5 -3
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +126 -0
- package/src/runtime/routes/consolidation-routes.ts +100 -0
- package/src/runtime/routes/conversation-cli-routes.ts +44 -3
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +17 -42
- package/src/runtime/routes/conversation-query-routes.ts +99 -35
- package/src/runtime/routes/conversation-routes.ts +97 -11
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +111 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +32 -1
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/index.ts +8 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +17 -44
- package/src/runtime/routes/inference-profile-session-reaper.ts +7 -21
- package/src/runtime/routes/inference-provider-connection-routes.ts +199 -22
- package/src/runtime/routes/integrations/a2a.ts +235 -0
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +6 -13
- package/src/runtime/routes/llm-call-sites-routes.ts +11 -1
- package/src/runtime/routes/notification-routes.ts +1 -1
- package/src/runtime/routes/oauth-commands-routes.ts +105 -15
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +4 -7
- package/src/runtime/routes/subagents-routes.ts +98 -18
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +27 -2
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +93 -1
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +9 -1
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +17 -7
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/browser-execution.ts +15 -11
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/memory/register.ts +1 -9
- package/src/tools/permission-checker.ts +1 -1
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +107 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/watcher/__tests__/engine.test.ts +22 -0
- package/src/watcher/engine.ts +6 -2
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +80 -15
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +35 -22
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +3 -1
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/087-memory-router-balanced-profile.ts +91 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/migrations/runner.ts +39 -9
- package/src/workspace/migrations/types.ts +4 -0
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-window-manager.test.ts +0 -2481
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -441
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +0 -55
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- package/src/runtime/guardian-action-conversation-turn.ts +0 -99
|
@@ -12,9 +12,6 @@ import {
|
|
|
12
12
|
userInfo,
|
|
13
13
|
} from "../../../../messaging/providers/slack/client.js";
|
|
14
14
|
import type { SlackConversation } from "../../../../messaging/providers/slack/types.js";
|
|
15
|
-
import { getConnectionByProvider } from "../../../../oauth/oauth-store.js";
|
|
16
|
-
import { credentialKey } from "../../../../security/credential-key.js";
|
|
17
|
-
import { getSecureKeyAsync } from "../../../../security/secure-keys.js";
|
|
18
15
|
import { getLogger } from "../../../../util/logger.js";
|
|
19
16
|
import {
|
|
20
17
|
BadRequestError,
|
|
@@ -23,50 +20,10 @@ import {
|
|
|
23
20
|
ServiceUnavailableError,
|
|
24
21
|
} from "../../errors.js";
|
|
25
22
|
import type { RouteDefinition, RouteHandlerArgs } from "../../types.js";
|
|
23
|
+
import { resolveSlackToken } from "./token.js";
|
|
26
24
|
|
|
27
25
|
const log = getLogger("slack-share");
|
|
28
26
|
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
// Shared helpers
|
|
31
|
-
// ---------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Resolve a Slack token for the Share UI, mirroring the read/write auth split
|
|
35
|
-
* in `messaging/providers/slack/adapter.ts`.
|
|
36
|
-
*
|
|
37
|
-
* For Socket Mode installs (tokens stored under `credential/slack_channel/*`),
|
|
38
|
-
* prefer the user OAuth token (xoxp-) for reads when present — this lets the
|
|
39
|
-
* channel picker surface channels the user belongs to but the bot doesn't.
|
|
40
|
-
* Fall back to the bot token (xoxb-) otherwise.
|
|
41
|
-
*
|
|
42
|
-
* Writes MUST always use the bot token so posted messages come from the bot
|
|
43
|
-
* identity, never the user. Passing `user_token` to chat.postMessage would
|
|
44
|
-
* post as the user — unambiguously wrong for Share UI behavior.
|
|
45
|
-
*
|
|
46
|
-
* For legacy OAuth installs (no Socket Mode tokens), fall back to the OAuth
|
|
47
|
-
* connection's access_token, which is the bot token in Slack's OAuth v2 flow.
|
|
48
|
-
*/
|
|
49
|
-
async function resolveSlackToken(
|
|
50
|
-
mode: "read" | "write",
|
|
51
|
-
): Promise<string | undefined> {
|
|
52
|
-
const botToken = await getSecureKeyAsync(
|
|
53
|
-
credentialKey("slack_channel", "bot_token"),
|
|
54
|
-
);
|
|
55
|
-
if (botToken) {
|
|
56
|
-
if (mode === "read") {
|
|
57
|
-
const userToken = await getSecureKeyAsync(
|
|
58
|
-
credentialKey("slack_channel", "user_token"),
|
|
59
|
-
);
|
|
60
|
-
return userToken ?? botToken;
|
|
61
|
-
}
|
|
62
|
-
return botToken;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const conn = getConnectionByProvider("slack");
|
|
66
|
-
if (!conn) return undefined;
|
|
67
|
-
return await getSecureKeyAsync(`oauth_connection/${conn.id}/access_token`);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
27
|
// ---------------------------------------------------------------------------
|
|
71
28
|
// GET /v1/slack/channels
|
|
72
29
|
// ---------------------------------------------------------------------------
|
|
@@ -179,15 +136,11 @@ export async function handleShareToSlackChannel({
|
|
|
179
136
|
};
|
|
180
137
|
|
|
181
138
|
if (!appId || !channelId) {
|
|
182
|
-
throw new BadRequestError(
|
|
183
|
-
"Missing required fields: appId, channelId",
|
|
184
|
-
);
|
|
139
|
+
throw new BadRequestError("Missing required fields: appId, channelId");
|
|
185
140
|
}
|
|
186
141
|
|
|
187
142
|
if (typeof appId !== "string" || typeof channelId !== "string") {
|
|
188
|
-
throw new BadRequestError(
|
|
189
|
-
"Fields appId and channelId must be strings",
|
|
190
|
-
);
|
|
143
|
+
throw new BadRequestError("Fields appId and channelId must be strings");
|
|
191
144
|
}
|
|
192
145
|
|
|
193
146
|
if (message !== undefined && typeof message !== "string") {
|
|
@@ -245,8 +198,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
245
198
|
endpoint: "slack/channels",
|
|
246
199
|
method: "GET",
|
|
247
200
|
summary: "List Slack channels",
|
|
248
|
-
description:
|
|
249
|
-
"List Slack channels, groups, and DMs for the channel picker.",
|
|
201
|
+
description: "List Slack channels, groups, and DMs for the channel picker.",
|
|
250
202
|
tags: ["integrations"],
|
|
251
203
|
requirePolicyEnforcement: true,
|
|
252
204
|
handler: () => handleListSlackChannels(),
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Slack token resolver.
|
|
3
|
+
*
|
|
4
|
+
* Resolve a Slack token for the Share UI, mirroring the read/write auth split
|
|
5
|
+
* in `messaging/providers/slack/adapter.ts`.
|
|
6
|
+
*
|
|
7
|
+
* For Socket Mode installs (tokens stored under `credential/slack_channel/*`),
|
|
8
|
+
* prefer the user OAuth token (xoxp-) for reads when present — this lets the
|
|
9
|
+
* channel picker surface channels the user belongs to but the bot doesn't.
|
|
10
|
+
* Fall back to the bot token (xoxb-) otherwise.
|
|
11
|
+
*
|
|
12
|
+
* Writes MUST always use the bot token so posted messages come from the bot
|
|
13
|
+
* identity, never the user. Passing `user_token` to chat.postMessage would
|
|
14
|
+
* post as the user — unambiguously wrong for Share UI behavior.
|
|
15
|
+
*
|
|
16
|
+
* For legacy OAuth installs (no Socket Mode tokens), fall back to the OAuth
|
|
17
|
+
* connection's access_token, which is the bot token in Slack's OAuth v2 flow.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { getConnectionByProvider } from "../../../../oauth/oauth-store.js";
|
|
21
|
+
import { credentialKey } from "../../../../security/credential-key.js";
|
|
22
|
+
import { getSecureKeyAsync } from "../../../../security/secure-keys.js";
|
|
23
|
+
|
|
24
|
+
export async function resolveSlackToken(
|
|
25
|
+
mode: "read" | "write",
|
|
26
|
+
): Promise<string | undefined> {
|
|
27
|
+
const botToken = await getSecureKeyAsync(
|
|
28
|
+
credentialKey("slack_channel", "bot_token"),
|
|
29
|
+
);
|
|
30
|
+
if (botToken) {
|
|
31
|
+
if (mode === "read") {
|
|
32
|
+
const userToken = await getSecureKeyAsync(
|
|
33
|
+
credentialKey("slack_channel", "user_token"),
|
|
34
|
+
);
|
|
35
|
+
return userToken ?? botToken;
|
|
36
|
+
}
|
|
37
|
+
return botToken;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const conn = getConnectionByProvider("slack");
|
|
41
|
+
if (!conn) return undefined;
|
|
42
|
+
return await getSecureKeyAsync(`oauth_connection/${conn.id}/access_token`);
|
|
43
|
+
}
|
|
@@ -95,8 +95,7 @@ export async function handleSetTwilioCredentials({
|
|
|
95
95
|
|
|
96
96
|
// Validate credentials against Twilio API
|
|
97
97
|
const authHeader =
|
|
98
|
-
"Basic " +
|
|
99
|
-
Buffer.from(`${accountSid}:${authToken}`).toString("base64");
|
|
98
|
+
"Basic " + Buffer.from(`${accountSid}:${authToken}`).toString("base64");
|
|
100
99
|
try {
|
|
101
100
|
const res = await fetch(
|
|
102
101
|
`https://api.twilio.com/2010-04-01/Accounts/${accountSid}.json`,
|
|
@@ -121,9 +120,7 @@ export async function handleSetTwilioCredentials({
|
|
|
121
120
|
accountSid,
|
|
122
121
|
);
|
|
123
122
|
if (!sidStored) {
|
|
124
|
-
throw new InternalError(
|
|
125
|
-
"Failed to store Account SID in secure storage",
|
|
126
|
-
);
|
|
123
|
+
throw new InternalError("Failed to store Account SID in secure storage");
|
|
127
124
|
}
|
|
128
125
|
|
|
129
126
|
const tokenStored = await setSecureKeyAsync(
|
|
@@ -132,14 +129,13 @@ export async function handleSetTwilioCredentials({
|
|
|
132
129
|
);
|
|
133
130
|
if (!tokenStored) {
|
|
134
131
|
await deleteSecureKeyAsync(credentialKey("twilio", "account_sid"));
|
|
135
|
-
throw new InternalError(
|
|
136
|
-
"Failed to store Auth Token in secure storage",
|
|
137
|
-
);
|
|
132
|
+
throw new InternalError("Failed to store Auth Token in secure storage");
|
|
138
133
|
}
|
|
139
134
|
|
|
140
135
|
const raw = loadRawConfig();
|
|
141
136
|
const twilio = (raw?.twilio ?? {}) as Record<string, unknown>;
|
|
142
137
|
twilio.accountSid = accountSid;
|
|
138
|
+
twilio.setupStarted = true;
|
|
143
139
|
saveRawConfig({ ...raw, twilio });
|
|
144
140
|
|
|
145
141
|
upsertCredentialMetadata("twilio", "account_sid", {
|
|
@@ -210,9 +206,7 @@ async function handleListTwilioNumbers() {
|
|
|
210
206
|
return { success: true, hasCredentials: true, numbers };
|
|
211
207
|
}
|
|
212
208
|
|
|
213
|
-
export async function handleProvisionTwilioNumber({
|
|
214
|
-
body,
|
|
215
|
-
}: RouteHandlerArgs) {
|
|
209
|
+
export async function handleProvisionTwilioNumber({ body }: RouteHandlerArgs) {
|
|
216
210
|
if (!(await hasTwilioCredentials())) {
|
|
217
211
|
throw new BadRequestError(
|
|
218
212
|
"Twilio credentials not configured. Set credentials first.",
|
|
@@ -323,8 +317,7 @@ async function handleReleaseTwilioNumber({ body }: RouteHandlerArgs) {
|
|
|
323
317
|
};
|
|
324
318
|
const raw = loadRawConfig();
|
|
325
319
|
const twilio = (raw?.twilio ?? {}) as Record<string, unknown>;
|
|
326
|
-
const phoneNumber =
|
|
327
|
-
requestedNumber || (twilio.phoneNumber as string) || "";
|
|
320
|
+
const phoneNumber = requestedNumber || (twilio.phoneNumber as string) || "";
|
|
328
321
|
|
|
329
322
|
if (!phoneNumber) {
|
|
330
323
|
throw new BadRequestError(
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
+
import { resolveDefaultProfileKey } from "../../config/llm-resolver.js";
|
|
2
|
+
import { loadConfig } from "../../config/loader.js";
|
|
1
3
|
import { CALL_SITE_CATALOG, CALL_SITE_DOMAINS } from "../../config/schemas/call-site-catalog.js";
|
|
4
|
+
import type { LLMCallSite } from "../../config/schemas/llm.js";
|
|
2
5
|
import type { RouteDefinition } from "./types.js";
|
|
3
6
|
|
|
4
7
|
async function handleGetCallSites() {
|
|
8
|
+
const { llm } = loadConfig();
|
|
5
9
|
return {
|
|
6
10
|
domains: CALL_SITE_DOMAINS,
|
|
7
|
-
callSites: CALL_SITE_CATALOG
|
|
11
|
+
callSites: CALL_SITE_CATALOG.map((entry) => ({
|
|
12
|
+
...entry,
|
|
13
|
+
defaultProfile: resolveDefaultProfileKey(
|
|
14
|
+
entry.id as LLMCallSite,
|
|
15
|
+
llm,
|
|
16
|
+
),
|
|
17
|
+
})),
|
|
8
18
|
};
|
|
9
19
|
}
|
|
10
20
|
|
|
@@ -52,7 +52,7 @@ function handleNotificationIntentResult({ body = {} }: RouteHandlerArgs) {
|
|
|
52
52
|
|
|
53
53
|
const AttentionHintsSchema = z.object({
|
|
54
54
|
requiresAction: z.boolean(),
|
|
55
|
-
urgency: z.enum(["low", "medium", "high"]),
|
|
55
|
+
urgency: z.enum(["low", "medium", "high", "critical"]),
|
|
56
56
|
deadlineAt: z.number().optional(),
|
|
57
57
|
isAsyncBackground: z.boolean(),
|
|
58
58
|
visibleInSourceNow: z.boolean(),
|
|
@@ -7,7 +7,12 @@
|
|
|
7
7
|
|
|
8
8
|
import { readFileSync } from "node:fs";
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
getConfig,
|
|
12
|
+
loadRawConfig,
|
|
13
|
+
saveRawConfig,
|
|
14
|
+
setNestedValue,
|
|
15
|
+
} from "../../config/loader.js";
|
|
11
16
|
import {
|
|
12
17
|
getServiceMode,
|
|
13
18
|
type Services,
|
|
@@ -26,9 +31,11 @@ import {
|
|
|
26
31
|
getProvider,
|
|
27
32
|
listActiveConnectionsByProvider,
|
|
28
33
|
listConnections,
|
|
34
|
+
type OAuthProviderRow,
|
|
29
35
|
} from "../../oauth/oauth-store.js";
|
|
30
36
|
import { VellumPlatformClient } from "../../platform/client.js";
|
|
31
37
|
import { withValidToken } from "../../security/token-manager.js";
|
|
38
|
+
import { matchHostPattern } from "../../tools/credentials/host-pattern-match.js";
|
|
32
39
|
import { getLogger } from "../../util/logger.js";
|
|
33
40
|
import { BadRequestError, InternalError, NotFoundError } from "./errors.js";
|
|
34
41
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
@@ -121,6 +128,82 @@ async function countManagedConnections(provider: string): Promise<number> {
|
|
|
121
128
|
}
|
|
122
129
|
}
|
|
123
130
|
|
|
131
|
+
function parseUrl(value: string | null | undefined): URL | undefined {
|
|
132
|
+
if (!value) return undefined;
|
|
133
|
+
try {
|
|
134
|
+
return new URL(value);
|
|
135
|
+
} catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function getAllowedRequestHostPatterns(
|
|
141
|
+
providerRow: OAuthProviderRow,
|
|
142
|
+
): string[] {
|
|
143
|
+
const patterns: string[] = [];
|
|
144
|
+
|
|
145
|
+
if (providerRow.injectionTemplates) {
|
|
146
|
+
try {
|
|
147
|
+
const parsed = JSON.parse(providerRow.injectionTemplates) as unknown;
|
|
148
|
+
if (Array.isArray(parsed)) {
|
|
149
|
+
for (const entry of parsed) {
|
|
150
|
+
if (
|
|
151
|
+
entry &&
|
|
152
|
+
typeof entry === "object" &&
|
|
153
|
+
typeof (entry as { hostPattern?: unknown }).hostPattern === "string"
|
|
154
|
+
) {
|
|
155
|
+
const hostPattern = (
|
|
156
|
+
entry as { hostPattern: string }
|
|
157
|
+
).hostPattern.trim();
|
|
158
|
+
if (hostPattern) patterns.push(hostPattern);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
// Fall back to the provider's base URL host below.
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (patterns.length === 0) {
|
|
168
|
+
const baseUrl = parseUrl(providerRow.baseUrl);
|
|
169
|
+
if (baseUrl) patterns.push(baseUrl.hostname);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return [...new Set(patterns)];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function assertOAuthRequestUrlAllowed(
|
|
176
|
+
providerRow: OAuthProviderRow,
|
|
177
|
+
parsedUrl: URL,
|
|
178
|
+
): void {
|
|
179
|
+
const providerBaseUrl = parseUrl(providerRow.baseUrl);
|
|
180
|
+
const allowedProtocol = providerBaseUrl?.protocol ?? "https:";
|
|
181
|
+
if (parsedUrl.protocol !== allowedProtocol) {
|
|
182
|
+
throw new BadRequestError(
|
|
183
|
+
`OAuth request URL for "${providerRow.provider}" must use ${allowedProtocol.replace(/:$/, "")}.`,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const allowedHostPatterns = getAllowedRequestHostPatterns(providerRow);
|
|
188
|
+
if (allowedHostPatterns.length === 0) {
|
|
189
|
+
throw new BadRequestError(
|
|
190
|
+
`OAuth provider "${providerRow.provider}" does not define an allowed request host.`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const allowed = allowedHostPatterns.some(
|
|
195
|
+
(pattern) =>
|
|
196
|
+
matchHostPattern(parsedUrl.hostname, pattern, {
|
|
197
|
+
includeApexForWildcard: true,
|
|
198
|
+
}) !== "none",
|
|
199
|
+
);
|
|
200
|
+
if (!allowed) {
|
|
201
|
+
throw new BadRequestError(
|
|
202
|
+
`OAuth request URL host "${parsedUrl.hostname}" is not allowed for "${providerRow.provider}". Allowed hosts: ${allowedHostPatterns.join(", ")}.`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
124
207
|
// ---------------------------------------------------------------------------
|
|
125
208
|
// Disconnect handler
|
|
126
209
|
// ---------------------------------------------------------------------------
|
|
@@ -176,7 +259,9 @@ async function handleDisconnect({ body = {} }: RouteHandlerArgs) {
|
|
|
176
259
|
accountLabel = match.account_label;
|
|
177
260
|
} else {
|
|
178
261
|
if (entries.length === 0) {
|
|
179
|
-
throw new NotFoundError(
|
|
262
|
+
throw new NotFoundError(
|
|
263
|
+
`No active connections found for "${b.provider}".`,
|
|
264
|
+
);
|
|
180
265
|
}
|
|
181
266
|
if (entries.length > 1) {
|
|
182
267
|
throw new BadRequestError(
|
|
@@ -235,7 +320,9 @@ async function handleDisconnect({ body = {} }: RouteHandlerArgs) {
|
|
|
235
320
|
} else {
|
|
236
321
|
const active = listActiveConnectionsByProvider(b.provider);
|
|
237
322
|
if (active.length === 0) {
|
|
238
|
-
throw new NotFoundError(
|
|
323
|
+
throw new NotFoundError(
|
|
324
|
+
`No active connections found for "${b.provider}".`,
|
|
325
|
+
);
|
|
239
326
|
}
|
|
240
327
|
if (active.length > 1) {
|
|
241
328
|
throw new BadRequestError(
|
|
@@ -582,11 +669,7 @@ async function handleToken({ body = {} }: RouteHandlerArgs) {
|
|
|
582
669
|
tokenOpts = { connectionId: conn.id };
|
|
583
670
|
}
|
|
584
671
|
|
|
585
|
-
const token = await withValidToken(
|
|
586
|
-
b.provider,
|
|
587
|
-
async (t) => t,
|
|
588
|
-
tokenOpts,
|
|
589
|
-
);
|
|
672
|
+
const token = await withValidToken(b.provider, async (t) => t, tokenOpts);
|
|
590
673
|
|
|
591
674
|
return { ok: true, token };
|
|
592
675
|
}
|
|
@@ -666,6 +749,7 @@ async function handleRequest({ body = {} }: RouteHandlerArgs) {
|
|
|
666
749
|
|
|
667
750
|
if (b.url.startsWith("http://") || b.url.startsWith("https://")) {
|
|
668
751
|
const parsed = new URL(b.url);
|
|
752
|
+
assertOAuthRequestUrlAllowed(providerRow, parsed);
|
|
669
753
|
baseUrl = `${parsed.protocol}//${parsed.host}`;
|
|
670
754
|
requestPath = parsed.pathname;
|
|
671
755
|
for (const [key, value] of parsed.searchParams.entries()) {
|
|
@@ -717,7 +801,12 @@ async function handleRequest({ body = {} }: RouteHandlerArgs) {
|
|
|
717
801
|
const query: Record<string, string | string[]> = { ...queryFromUrl };
|
|
718
802
|
|
|
719
803
|
// Use pre-parsed data from CLI, or fall back to raw data string for direct API callers
|
|
720
|
-
const resolvedData =
|
|
804
|
+
const resolvedData =
|
|
805
|
+
b.parsed_data !== undefined
|
|
806
|
+
? b.parsed_data
|
|
807
|
+
: b.data !== undefined
|
|
808
|
+
? readBodyData(b.data)
|
|
809
|
+
: undefined;
|
|
721
810
|
|
|
722
811
|
if (resolvedData !== undefined) {
|
|
723
812
|
const rawBody = resolvedData;
|
|
@@ -855,7 +944,9 @@ async function handleManagedConnect({ body = {} }: RouteHandlerArgs) {
|
|
|
855
944
|
return { ok: true, connect_url: result.connect_url };
|
|
856
945
|
}
|
|
857
946
|
|
|
858
|
-
async function handleManagedConnectPoll({
|
|
947
|
+
async function handleManagedConnectPoll({
|
|
948
|
+
queryParams = {},
|
|
949
|
+
}: RouteHandlerArgs) {
|
|
859
950
|
const provider = queryParams.provider;
|
|
860
951
|
if (!provider) throw new BadRequestError("provider query param is required");
|
|
861
952
|
|
|
@@ -894,7 +985,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
894
985
|
endpoint: "oauth/mode",
|
|
895
986
|
method: "GET",
|
|
896
987
|
summary: "Get OAuth mode",
|
|
897
|
-
description:
|
|
988
|
+
description:
|
|
989
|
+
"Get the current OAuth mode (managed or your-own) for a provider.",
|
|
898
990
|
tags: ["oauth"],
|
|
899
991
|
requirePolicyEnforcement: true,
|
|
900
992
|
queryParams: [
|
|
@@ -913,8 +1005,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
913
1005
|
method: "POST",
|
|
914
1006
|
policyKey: "oauth/mode.set",
|
|
915
1007
|
summary: "Set OAuth mode",
|
|
916
|
-
description:
|
|
917
|
-
"Set the OAuth mode (managed or your-own) for a provider.",
|
|
1008
|
+
description: "Set the OAuth mode (managed or your-own) for a provider.",
|
|
918
1009
|
tags: ["oauth"],
|
|
919
1010
|
requirePolicyEnforcement: true,
|
|
920
1011
|
handler: handleModeSet,
|
|
@@ -955,8 +1046,7 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
955
1046
|
method: "POST",
|
|
956
1047
|
policyKey: "oauth/token",
|
|
957
1048
|
summary: "Get OAuth token",
|
|
958
|
-
description:
|
|
959
|
-
"Retrieve a valid OAuth access token for a BYO-mode provider.",
|
|
1049
|
+
description: "Retrieve a valid OAuth access token for a BYO-mode provider.",
|
|
960
1050
|
tags: ["oauth"],
|
|
961
1051
|
requirePolicyEnforcement: true,
|
|
962
1052
|
handler: handleToken,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport-agnostic routes for OAuth lifecycle events.
|
|
3
|
+
*
|
|
4
|
+
* Allows CLI commands to notify the daemon when OAuth state changes
|
|
5
|
+
* (e.g. after `assistant oauth connect`) so the daemon can refresh its
|
|
6
|
+
* cached config and credential state.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
|
|
11
|
+
import { getConfig, invalidateConfigCache } from "../../config/loader.js";
|
|
12
|
+
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
13
|
+
|
|
14
|
+
// ── Handlers ──────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
function handleOAuthConnectionChanged(_args: RouteHandlerArgs): {
|
|
17
|
+
refreshed: boolean;
|
|
18
|
+
} {
|
|
19
|
+
invalidateConfigCache();
|
|
20
|
+
// Force re-read from disk so subsequent resolveOAuthConnection() calls
|
|
21
|
+
// in this process see the current mode setting.
|
|
22
|
+
getConfig();
|
|
23
|
+
return { refreshed: true };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ── Routes ────────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
export const ROUTES: RouteDefinition[] = [
|
|
29
|
+
{
|
|
30
|
+
operationId: "oauth_connection_changed",
|
|
31
|
+
endpoint: "oauth/connection-changed",
|
|
32
|
+
method: "POST",
|
|
33
|
+
policyKey: "oauth/connection-changed",
|
|
34
|
+
handler: handleOAuthConnectionChanged,
|
|
35
|
+
summary: "Notify the assistant that an OAuth connection changed",
|
|
36
|
+
description:
|
|
37
|
+
"Invalidates the config cache so the assistant picks up mode and credential changes immediately.",
|
|
38
|
+
tags: ["oauth"],
|
|
39
|
+
responseBody: z.object({
|
|
40
|
+
refreshed: z.boolean(),
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
];
|