@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
|
@@ -10,9 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
|
|
13
|
+
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
13
14
|
import { getConfigReadOnly } from "../../config/loader.js";
|
|
14
15
|
import { getDb } from "../../memory/db-connection.js";
|
|
15
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
AuthSchema,
|
|
18
|
+
type ConnectionModel,
|
|
19
|
+
ConnectionModelSchema,
|
|
20
|
+
ConnectionProviderSchema,
|
|
21
|
+
ConnectionStatusSchema,
|
|
22
|
+
ProviderConnectionSchema,
|
|
23
|
+
VALID_CONNECTION_PROVIDERS,
|
|
24
|
+
} from "../../providers/inference/auth.js";
|
|
16
25
|
import {
|
|
17
26
|
createConnection,
|
|
18
27
|
deleteConnection,
|
|
@@ -21,11 +30,7 @@ import {
|
|
|
21
30
|
MANAGED_CONNECTION_NAMES,
|
|
22
31
|
updateConnection,
|
|
23
32
|
} from "../../providers/inference/connections.js";
|
|
24
|
-
import {
|
|
25
|
-
BadRequestError,
|
|
26
|
-
ConflictError,
|
|
27
|
-
NotFoundError,
|
|
28
|
-
} from "./errors.js";
|
|
33
|
+
import { BadRequestError, ConflictError, NotFoundError } from "./errors.js";
|
|
29
34
|
import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
30
35
|
|
|
31
36
|
// ---------------------------------------------------------------------------
|
|
@@ -33,6 +38,75 @@ import type { RouteDefinition, RouteHandlerArgs } from "./types.js";
|
|
|
33
38
|
// ---------------------------------------------------------------------------
|
|
34
39
|
|
|
35
40
|
const providerConnectionResponseSchema = ProviderConnectionSchema;
|
|
41
|
+
const OPENAI_COMPATIBLE_ENDPOINTS_FLAG = "openai-compatible-endpoints";
|
|
42
|
+
|
|
43
|
+
function openAICompatibleEndpointsEnabled(): boolean {
|
|
44
|
+
return isAssistantFeatureFlagEnabled(
|
|
45
|
+
OPENAI_COMPATIBLE_ENDPOINTS_FLAG,
|
|
46
|
+
getConfigReadOnly(),
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function rejectDisabledOpenAICompatibleProvider(provider: string): void {
|
|
51
|
+
if (provider !== "openai-compatible") return;
|
|
52
|
+
if (openAICompatibleEndpointsEnabled()) return;
|
|
53
|
+
throw new BadRequestError(
|
|
54
|
+
"OpenAI-compatible endpoints are disabled. Enable the openai-compatible-endpoints feature flag to configure this provider.",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Custom provider field parsing (openai-compatible base_url + models)
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
function parseCustomProviderFields(body: Record<string, unknown>): {
|
|
63
|
+
baseUrl?: string | null;
|
|
64
|
+
models?: ConnectionModel[] | null;
|
|
65
|
+
} {
|
|
66
|
+
const out: {
|
|
67
|
+
baseUrl?: string | null;
|
|
68
|
+
models?: ConnectionModel[] | null;
|
|
69
|
+
} = {};
|
|
70
|
+
|
|
71
|
+
if ("base_url" in body) {
|
|
72
|
+
const raw = body.base_url;
|
|
73
|
+
if (raw === null) {
|
|
74
|
+
out.baseUrl = null;
|
|
75
|
+
} else if (typeof raw === "string" && raw.length > 0) {
|
|
76
|
+
try {
|
|
77
|
+
const parsed = new URL(raw);
|
|
78
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
79
|
+
throw new BadRequestError(`Invalid base_url: must be an http(s) URL`);
|
|
80
|
+
}
|
|
81
|
+
} catch (err) {
|
|
82
|
+
if (err instanceof BadRequestError) throw err;
|
|
83
|
+
throw new BadRequestError(
|
|
84
|
+
`Invalid base_url: must be a valid http(s) URL`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
out.baseUrl = raw;
|
|
88
|
+
} else {
|
|
89
|
+
throw new BadRequestError(
|
|
90
|
+
`Invalid base_url: must be a non-empty string or null`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if ("models" in body) {
|
|
96
|
+
const raw = body.models;
|
|
97
|
+
if (raw === null) {
|
|
98
|
+
out.models = null;
|
|
99
|
+
} else {
|
|
100
|
+
const parsed = z.array(ConnectionModelSchema).safeParse(raw);
|
|
101
|
+
if (!parsed.success) {
|
|
102
|
+
throw new BadRequestError(`Invalid models: ${parsed.error.message}`);
|
|
103
|
+
}
|
|
104
|
+
out.models = parsed.data;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
36
110
|
|
|
37
111
|
// ---------------------------------------------------------------------------
|
|
38
112
|
// Handlers
|
|
@@ -40,7 +114,18 @@ const providerConnectionResponseSchema = ProviderConnectionSchema;
|
|
|
40
114
|
|
|
41
115
|
function handleListConnections({ queryParams = {} }: RouteHandlerArgs) {
|
|
42
116
|
const provider = queryParams.provider;
|
|
43
|
-
|
|
117
|
+
if (provider) rejectDisabledOpenAICompatibleProvider(provider);
|
|
118
|
+
const connections = listConnections(
|
|
119
|
+
getDb(),
|
|
120
|
+
provider ? { provider } : undefined,
|
|
121
|
+
);
|
|
122
|
+
if (!openAICompatibleEndpointsEnabled()) {
|
|
123
|
+
return {
|
|
124
|
+
connections: connections.filter(
|
|
125
|
+
(conn) => conn.provider !== "openai-compatible",
|
|
126
|
+
),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
44
129
|
return { connections };
|
|
45
130
|
}
|
|
46
131
|
|
|
@@ -50,6 +135,12 @@ function handleGetConnection({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
50
135
|
|
|
51
136
|
const conn = getConnection(getDb(), name);
|
|
52
137
|
if (!conn) throw new NotFoundError(`Connection "${name}" not found.`);
|
|
138
|
+
if (
|
|
139
|
+
conn.provider === "openai-compatible" &&
|
|
140
|
+
!openAICompatibleEndpointsEnabled()
|
|
141
|
+
) {
|
|
142
|
+
throw new NotFoundError(`Connection "${name}" not found.`);
|
|
143
|
+
}
|
|
53
144
|
|
|
54
145
|
return conn;
|
|
55
146
|
}
|
|
@@ -69,28 +160,41 @@ function handleCreateConnection({ body = {} }: RouteHandlerArgs) {
|
|
|
69
160
|
`Invalid provider "${String(provider)}". Valid: ${VALID_CONNECTION_PROVIDERS.join(", ")}`,
|
|
70
161
|
);
|
|
71
162
|
}
|
|
163
|
+
rejectDisabledOpenAICompatibleProvider(providerResult.data);
|
|
72
164
|
|
|
73
165
|
const authResult = AuthSchema.safeParse(auth);
|
|
74
166
|
if (!authResult.success) {
|
|
75
167
|
throw new BadRequestError(`Invalid auth: ${authResult.error.message}`);
|
|
76
168
|
}
|
|
77
169
|
|
|
78
|
-
const statusResult =
|
|
170
|
+
const statusResult =
|
|
171
|
+
body.status !== undefined
|
|
172
|
+
? ConnectionStatusSchema.safeParse(body.status)
|
|
173
|
+
: null;
|
|
79
174
|
if (statusResult && !statusResult.success) {
|
|
80
175
|
throw new BadRequestError(`Invalid status: must be "active" or "disabled"`);
|
|
81
176
|
}
|
|
82
177
|
|
|
83
178
|
const labelRaw = body.label;
|
|
84
|
-
if (
|
|
85
|
-
|
|
179
|
+
if (
|
|
180
|
+
labelRaw !== undefined &&
|
|
181
|
+
labelRaw !== null &&
|
|
182
|
+
(typeof labelRaw !== "string" || labelRaw.length === 0)
|
|
183
|
+
) {
|
|
184
|
+
throw new BadRequestError(
|
|
185
|
+
`Invalid label: must be a non-empty string or null`,
|
|
186
|
+
);
|
|
86
187
|
}
|
|
87
188
|
|
|
189
|
+
const customFields = parseCustomProviderFields(body);
|
|
190
|
+
|
|
88
191
|
const result = createConnection(getDb(), {
|
|
89
192
|
name,
|
|
90
193
|
provider: providerResult.data,
|
|
91
194
|
auth: authResult.data,
|
|
92
195
|
...(statusResult ? { status: statusResult.data } : {}),
|
|
93
196
|
...(labelRaw !== undefined ? { label: labelRaw as string | null } : {}),
|
|
197
|
+
...customFields,
|
|
94
198
|
});
|
|
95
199
|
|
|
96
200
|
if (!result.ok) {
|
|
@@ -104,52 +208,99 @@ function handleCreateConnection({ body = {} }: RouteHandlerArgs) {
|
|
|
104
208
|
`Invalid provider "${result.error.provider}". Valid: ${VALID_CONNECTION_PROVIDERS.join(", ")}`,
|
|
105
209
|
);
|
|
106
210
|
}
|
|
211
|
+
if (result.error.code === "base_url_required") {
|
|
212
|
+
throw new BadRequestError(
|
|
213
|
+
"base_url is required for openai-compatible connections.",
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
if (result.error.code === "models_required") {
|
|
217
|
+
throw new BadRequestError(
|
|
218
|
+
"At least one model is required for openai-compatible connections.",
|
|
219
|
+
);
|
|
220
|
+
}
|
|
107
221
|
throw new BadRequestError("Invalid auth configuration.");
|
|
108
222
|
}
|
|
109
223
|
|
|
110
224
|
return result.connection;
|
|
111
225
|
}
|
|
112
226
|
|
|
113
|
-
function handleUpdateConnection({
|
|
227
|
+
function handleUpdateConnection({
|
|
228
|
+
pathParams = {},
|
|
229
|
+
body = {},
|
|
230
|
+
}: RouteHandlerArgs) {
|
|
114
231
|
const { name } = pathParams;
|
|
115
232
|
if (!name) throw new BadRequestError("name is required");
|
|
116
233
|
|
|
234
|
+
const existing = getConnection(getDb(), name);
|
|
235
|
+
if (!existing) throw new NotFoundError(`Connection "${name}" not found.`);
|
|
236
|
+
if (
|
|
237
|
+
existing.provider === "openai-compatible" &&
|
|
238
|
+
!openAICompatibleEndpointsEnabled()
|
|
239
|
+
) {
|
|
240
|
+
throw new NotFoundError(`Connection "${name}" not found.`);
|
|
241
|
+
}
|
|
242
|
+
|
|
117
243
|
const auth = body.auth;
|
|
118
244
|
const authResult = AuthSchema.safeParse(auth);
|
|
119
245
|
if (!authResult.success) {
|
|
120
246
|
throw new BadRequestError(`Invalid auth: ${authResult.error.message}`);
|
|
121
247
|
}
|
|
122
248
|
|
|
123
|
-
const statusResult =
|
|
249
|
+
const statusResult =
|
|
250
|
+
body.status !== undefined
|
|
251
|
+
? ConnectionStatusSchema.safeParse(body.status)
|
|
252
|
+
: null;
|
|
124
253
|
if (statusResult && !statusResult.success) {
|
|
125
254
|
throw new BadRequestError(`Invalid status: must be "active" or "disabled"`);
|
|
126
255
|
}
|
|
127
256
|
|
|
128
257
|
const labelRaw = body.label;
|
|
129
|
-
if (
|
|
130
|
-
|
|
258
|
+
if (
|
|
259
|
+
labelRaw !== undefined &&
|
|
260
|
+
labelRaw !== null &&
|
|
261
|
+
(typeof labelRaw !== "string" || labelRaw.length === 0)
|
|
262
|
+
) {
|
|
263
|
+
throw new BadRequestError(
|
|
264
|
+
`Invalid label: must be a non-empty string or null`,
|
|
265
|
+
);
|
|
131
266
|
}
|
|
132
267
|
|
|
133
268
|
// Managed connections: lock auth to `{type:"platform"}`. The boot upsert in
|
|
134
269
|
// `seedCanonicalConnections` would revert any other value on next restart;
|
|
135
270
|
// reject the write here so the surprise loop never happens. Label and status
|
|
136
271
|
// remain user-editable (the boot upsert leaves those alone).
|
|
137
|
-
if (
|
|
272
|
+
if (
|
|
273
|
+
MANAGED_CONNECTION_NAMES.has(name) &&
|
|
274
|
+
authResult.data.type !== "platform"
|
|
275
|
+
) {
|
|
138
276
|
throw new BadRequestError(
|
|
139
277
|
`Cannot change auth on managed connection "${name}". Auth is locked to platform.`,
|
|
140
278
|
);
|
|
141
279
|
}
|
|
142
280
|
|
|
281
|
+
const customFields = parseCustomProviderFields(body);
|
|
282
|
+
|
|
143
283
|
const result = updateConnection(getDb(), name, {
|
|
144
284
|
auth: authResult.data,
|
|
145
285
|
...(statusResult ? { status: statusResult.data } : {}),
|
|
146
286
|
...(labelRaw !== undefined ? { label: labelRaw as string | null } : {}),
|
|
287
|
+
...customFields,
|
|
147
288
|
});
|
|
148
289
|
|
|
149
290
|
if (!result.ok) {
|
|
150
291
|
if (result.error.code === "not_found") {
|
|
151
292
|
throw new NotFoundError(`Connection "${name}" not found.`);
|
|
152
293
|
}
|
|
294
|
+
if (result.error.code === "base_url_required") {
|
|
295
|
+
throw new BadRequestError(
|
|
296
|
+
"base_url is required for openai-compatible connections.",
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
if (result.error.code === "models_required") {
|
|
300
|
+
throw new BadRequestError(
|
|
301
|
+
"At least one model is required for openai-compatible connections.",
|
|
302
|
+
);
|
|
303
|
+
}
|
|
153
304
|
throw new BadRequestError("Invalid auth configuration.");
|
|
154
305
|
}
|
|
155
306
|
|
|
@@ -162,7 +313,14 @@ function handleDeleteConnection({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
162
313
|
|
|
163
314
|
// Existence check first so a stale `llm.default.provider_connection`
|
|
164
315
|
// reference to a missing connection returns 404 (not 409).
|
|
165
|
-
|
|
316
|
+
const existing = getConnection(getDb(), name);
|
|
317
|
+
if (!existing) {
|
|
318
|
+
throw new NotFoundError(`Connection "${name}" not found.`);
|
|
319
|
+
}
|
|
320
|
+
if (
|
|
321
|
+
existing.provider === "openai-compatible" &&
|
|
322
|
+
!openAICompatibleEndpointsEnabled()
|
|
323
|
+
) {
|
|
166
324
|
throw new NotFoundError(`Connection "${name}" not found.`);
|
|
167
325
|
}
|
|
168
326
|
|
|
@@ -180,7 +338,10 @@ function handleDeleteConnection({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
180
338
|
const config = getConfigReadOnly();
|
|
181
339
|
|
|
182
340
|
// llm.default carries provider_connection (LLMConfigBase).
|
|
183
|
-
if (
|
|
341
|
+
if (
|
|
342
|
+
(config.llm?.default as Record<string, unknown> | undefined)
|
|
343
|
+
?.provider_connection === name
|
|
344
|
+
) {
|
|
184
345
|
throw new ConflictError(
|
|
185
346
|
`Connection "${name}" is referenced by llm.default. Update llm.default.provider_connection before deleting.`,
|
|
186
347
|
{ referencedBy: ["llm.default"] },
|
|
@@ -190,7 +351,9 @@ function handleDeleteConnection({ pathParams = {} }: RouteHandlerArgs) {
|
|
|
190
351
|
// llm.profiles.*: only ProfileEntry has provider_connection.
|
|
191
352
|
const profiles = config.llm?.profiles ?? {};
|
|
192
353
|
const referencingProfiles = Object.entries(profiles)
|
|
193
|
-
.filter(
|
|
354
|
+
.filter(
|
|
355
|
+
([, p]) => (p as Record<string, unknown>).provider_connection === name,
|
|
356
|
+
)
|
|
194
357
|
.map(([profileName]) => profileName);
|
|
195
358
|
|
|
196
359
|
const result = deleteConnection(getDb(), name, {
|
|
@@ -234,7 +397,9 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
234
397
|
description: `Filter by provider. One of: ${VALID_CONNECTION_PROVIDERS.join(", ")}`,
|
|
235
398
|
},
|
|
236
399
|
],
|
|
237
|
-
responseBody: z.object({
|
|
400
|
+
responseBody: z.object({
|
|
401
|
+
connections: z.array(providerConnectionResponseSchema),
|
|
402
|
+
}),
|
|
238
403
|
handler: handleListConnections,
|
|
239
404
|
},
|
|
240
405
|
{
|
|
@@ -265,6 +430,8 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
265
430
|
auth: AuthSchema,
|
|
266
431
|
label: z.string().min(1).optional(),
|
|
267
432
|
status: ConnectionStatusSchema.optional(),
|
|
433
|
+
base_url: z.string().url().nullable().optional(),
|
|
434
|
+
models: z.array(ConnectionModelSchema).nullable().optional(),
|
|
268
435
|
}),
|
|
269
436
|
responseBody: providerConnectionResponseSchema,
|
|
270
437
|
responseStatus: "201",
|
|
@@ -288,10 +455,15 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
288
455
|
auth: AuthSchema,
|
|
289
456
|
status: ConnectionStatusSchema.optional(),
|
|
290
457
|
label: z.string().min(1).nullable().optional(),
|
|
458
|
+
base_url: z.string().url().nullable().optional(),
|
|
459
|
+
models: z.array(ConnectionModelSchema).nullable().optional(),
|
|
291
460
|
}),
|
|
292
461
|
responseBody: providerConnectionResponseSchema,
|
|
293
462
|
additionalResponses: {
|
|
294
|
-
"400": {
|
|
463
|
+
"400": {
|
|
464
|
+
description:
|
|
465
|
+
"Invalid auth schema, or attempt to change auth on a managed connection",
|
|
466
|
+
},
|
|
295
467
|
"404": { description: "Connection not found" },
|
|
296
468
|
},
|
|
297
469
|
handler: handleUpdateConnection,
|
|
@@ -308,9 +480,14 @@ export const ROUTES: RouteDefinition[] = [
|
|
|
308
480
|
pathParams: [{ name: "name", description: "Connection name" }],
|
|
309
481
|
responseBody: z.object({ ok: z.literal(true) }),
|
|
310
482
|
additionalResponses: {
|
|
311
|
-
"400": {
|
|
483
|
+
"400": {
|
|
484
|
+
description:
|
|
485
|
+
"Connection is a Vellum-managed connection and cannot be deleted",
|
|
486
|
+
},
|
|
312
487
|
"404": { description: "Connection not found" },
|
|
313
|
-
"409": {
|
|
488
|
+
"409": {
|
|
489
|
+
description: "Connection is referenced by profile(s) or call site(s)",
|
|
490
|
+
},
|
|
314
491
|
},
|
|
315
492
|
handler: handleDeleteConnection,
|
|
316
493
|
},
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route handlers for A2A integration config endpoints.
|
|
3
|
+
*
|
|
4
|
+
* GET /v1/integrations/a2a/config — get current A2A config status
|
|
5
|
+
* POST /v1/integrations/a2a/config — enable A2A channel
|
|
6
|
+
* DELETE /v1/integrations/a2a/config — disable A2A channel
|
|
7
|
+
* POST /v1/integrations/a2a/invite — create a shareable A2A invite token
|
|
8
|
+
* POST /v1/integrations/a2a/invite/complete — sender-side invite completion
|
|
9
|
+
* POST /v1/integrations/a2a/invite/redeem — receiver-side invite redemption
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { isA2AEnabled } from "../../../a2a/feature-gate.js";
|
|
13
|
+
import { getConfig } from "../../../config/loader.js";
|
|
14
|
+
import {
|
|
15
|
+
clearA2AConfig,
|
|
16
|
+
completeA2AInvite,
|
|
17
|
+
createA2AInvite,
|
|
18
|
+
getA2AConfig,
|
|
19
|
+
redeemA2AInvite,
|
|
20
|
+
setA2AConfig,
|
|
21
|
+
} from "../../../daemon/handlers/config-a2a.js";
|
|
22
|
+
import { BadRequestError } from "../errors.js";
|
|
23
|
+
import type { RouteDefinition, RouteHandlerArgs } from "../types.js";
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Helpers
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
function assertA2AFlag(): void {
|
|
30
|
+
if (!isA2AEnabled(getConfig())) {
|
|
31
|
+
throw new BadRequestError("A2A channel is not available");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Handlers
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
function handleGetA2AConfig() {
|
|
40
|
+
assertA2AFlag();
|
|
41
|
+
return getA2AConfig();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handleSetA2AConfig() {
|
|
45
|
+
assertA2AFlag();
|
|
46
|
+
const result = setA2AConfig();
|
|
47
|
+
if (!result.success) {
|
|
48
|
+
throw new BadRequestError(result.error ?? "Failed to enable A2A");
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function handleClearA2AConfig() {
|
|
54
|
+
assertA2AFlag();
|
|
55
|
+
return clearA2AConfig();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function handleCreateA2AInvite({ body = {} }: RouteHandlerArgs) {
|
|
59
|
+
assertA2AFlag();
|
|
60
|
+
const { expiresInHours } = body as { expiresInHours?: unknown };
|
|
61
|
+
if (expiresInHours !== undefined) {
|
|
62
|
+
if (
|
|
63
|
+
typeof expiresInHours !== "number" ||
|
|
64
|
+
!Number.isFinite(expiresInHours) ||
|
|
65
|
+
expiresInHours <= 0
|
|
66
|
+
) {
|
|
67
|
+
throw new BadRequestError(
|
|
68
|
+
"expiresInHours must be a positive finite number",
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const result = createA2AInvite({
|
|
73
|
+
expiresInHours: expiresInHours as number | undefined,
|
|
74
|
+
});
|
|
75
|
+
if (!result.success) {
|
|
76
|
+
throw new BadRequestError(result.error ?? "Failed to create A2A invite");
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function handleCompleteA2AInvite({ body = {} }: RouteHandlerArgs) {
|
|
82
|
+
const { token, senderAssistantId, acceptor } = body as {
|
|
83
|
+
token?: unknown;
|
|
84
|
+
senderAssistantId?: unknown;
|
|
85
|
+
acceptor?: {
|
|
86
|
+
assistantId?: unknown;
|
|
87
|
+
displayName?: unknown;
|
|
88
|
+
gatewayUrl?: unknown;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (typeof token !== "string" || !token) {
|
|
93
|
+
throw new BadRequestError(
|
|
94
|
+
"token is required and must be a non-empty string",
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
if (typeof senderAssistantId !== "string" || !senderAssistantId) {
|
|
98
|
+
throw new BadRequestError(
|
|
99
|
+
"senderAssistantId is required and must be a non-empty string",
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
if (
|
|
103
|
+
!acceptor ||
|
|
104
|
+
typeof acceptor.assistantId !== "string" ||
|
|
105
|
+
!acceptor.assistantId ||
|
|
106
|
+
typeof acceptor.displayName !== "string" ||
|
|
107
|
+
!acceptor.displayName ||
|
|
108
|
+
typeof acceptor.gatewayUrl !== "string" ||
|
|
109
|
+
!acceptor.gatewayUrl
|
|
110
|
+
) {
|
|
111
|
+
throw new BadRequestError(
|
|
112
|
+
"acceptor must include non-empty assistantId, displayName, and gatewayUrl",
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const result = completeA2AInvite({
|
|
117
|
+
token,
|
|
118
|
+
senderAssistantId,
|
|
119
|
+
acceptor: {
|
|
120
|
+
assistantId: acceptor.assistantId,
|
|
121
|
+
displayName: acceptor.displayName,
|
|
122
|
+
gatewayUrl: acceptor.gatewayUrl,
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
if (!result.success) {
|
|
126
|
+
throw new BadRequestError(result.error ?? "Failed to complete A2A invite");
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function handleRedeemA2AInvite({ body = {} }: RouteHandlerArgs) {
|
|
132
|
+
const { sender } = body as {
|
|
133
|
+
sender?: {
|
|
134
|
+
assistantId?: unknown;
|
|
135
|
+
displayName?: unknown;
|
|
136
|
+
gatewayUrl?: unknown;
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
if (
|
|
141
|
+
!sender ||
|
|
142
|
+
typeof sender.assistantId !== "string" ||
|
|
143
|
+
!sender.assistantId ||
|
|
144
|
+
typeof sender.displayName !== "string" ||
|
|
145
|
+
!sender.displayName ||
|
|
146
|
+
typeof sender.gatewayUrl !== "string" ||
|
|
147
|
+
!sender.gatewayUrl
|
|
148
|
+
) {
|
|
149
|
+
throw new BadRequestError(
|
|
150
|
+
"sender must include non-empty assistantId, displayName, and gatewayUrl",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const result = redeemA2AInvite({
|
|
155
|
+
sender: {
|
|
156
|
+
assistantId: sender.assistantId,
|
|
157
|
+
displayName: sender.displayName,
|
|
158
|
+
gatewayUrl: sender.gatewayUrl,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
if (!result.success) {
|
|
162
|
+
throw new BadRequestError(result.error ?? "Failed to redeem A2A invite");
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Route definitions
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
export const ROUTES: RouteDefinition[] = [
|
|
172
|
+
{
|
|
173
|
+
operationId: "integrations_a2a_config_get",
|
|
174
|
+
endpoint: "integrations/a2a/config",
|
|
175
|
+
method: "GET",
|
|
176
|
+
summary: "Get A2A config",
|
|
177
|
+
description: "Check current A2A channel configuration status.",
|
|
178
|
+
tags: ["integrations"],
|
|
179
|
+
requirePolicyEnforcement: true,
|
|
180
|
+
handler: () => handleGetA2AConfig(),
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
operationId: "integrations_a2a_config_post",
|
|
184
|
+
endpoint: "integrations/a2a/config",
|
|
185
|
+
method: "POST",
|
|
186
|
+
summary: "Enable A2A channel",
|
|
187
|
+
description: "Enable the A2A channel for inter-assistant communication.",
|
|
188
|
+
tags: ["integrations"],
|
|
189
|
+
requirePolicyEnforcement: true,
|
|
190
|
+
handler: () => handleSetA2AConfig(),
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
operationId: "integrations_a2a_config_delete",
|
|
194
|
+
endpoint: "integrations/a2a/config",
|
|
195
|
+
method: "DELETE",
|
|
196
|
+
summary: "Disable A2A channel",
|
|
197
|
+
description: "Disable the A2A channel.",
|
|
198
|
+
tags: ["integrations"],
|
|
199
|
+
requirePolicyEnforcement: true,
|
|
200
|
+
handler: () => handleClearA2AConfig(),
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
operationId: "integrations_a2a_invite_post",
|
|
204
|
+
endpoint: "integrations/a2a/invite",
|
|
205
|
+
method: "POST",
|
|
206
|
+
summary: "Create A2A invite",
|
|
207
|
+
description:
|
|
208
|
+
"Create a shareable A2A invite token for link-based contact creation.",
|
|
209
|
+
tags: ["integrations"],
|
|
210
|
+
requirePolicyEnforcement: true,
|
|
211
|
+
handler: handleCreateA2AInvite,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
operationId: "integrations_a2a_invite_complete_post",
|
|
215
|
+
endpoint: "integrations/a2a/invite/complete",
|
|
216
|
+
method: "POST",
|
|
217
|
+
summary: "Complete A2A invite (sender side)",
|
|
218
|
+
description:
|
|
219
|
+
"Called by the platform to finalize the sender side of a link-based A2A connection.",
|
|
220
|
+
tags: ["integrations"],
|
|
221
|
+
requirePolicyEnforcement: true,
|
|
222
|
+
handler: handleCompleteA2AInvite,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
operationId: "integrations_a2a_invite_redeem_post",
|
|
226
|
+
endpoint: "integrations/a2a/invite/redeem",
|
|
227
|
+
method: "POST",
|
|
228
|
+
summary: "Redeem A2A invite (receiver side)",
|
|
229
|
+
description:
|
|
230
|
+
"Called by the platform to create a trusted contact on the receiver side of a link-based A2A connection.",
|
|
231
|
+
tags: ["integrations"],
|
|
232
|
+
requirePolicyEnforcement: true,
|
|
233
|
+
handler: handleRedeemA2AInvite,
|
|
234
|
+
},
|
|
235
|
+
];
|