@vellumai/assistant 0.5.10 → 0.5.12
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/AGENTS.md +8 -0
- package/ARCHITECTURE.md +43 -43
- package/Dockerfile +3 -0
- package/docs/architecture/integrations.md +37 -42
- package/docs/architecture/memory.md +7 -12
- package/docs/credential-execution-service.md +9 -9
- package/docs/skills.md +1 -1
- package/node_modules/@vellumai/ces-contracts/src/__tests__/grants.test.ts +7 -7
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +5 -4
- package/node_modules/@vellumai/credential-storage/src/index.ts +3 -3
- package/node_modules/@vellumai/credential-storage/src/static-credentials.ts +1 -1
- package/openapi.yaml +7208 -0
- package/package.json +2 -1
- package/scripts/generate-openapi.ts +562 -0
- package/src/__tests__/acp-session.test.ts +239 -44
- package/src/__tests__/assistant-feature-flag-guard.test.ts +8 -8
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +5 -86
- package/src/__tests__/assistant-feature-flags-integration.test.ts +7 -14
- package/src/__tests__/browser-skill-endstate.test.ts +1 -1
- package/src/__tests__/btw-routes.test.ts +8 -0
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +10 -10
- package/src/__tests__/catalog-cache.test.ts +164 -0
- package/src/__tests__/catalog-search.test.ts +61 -0
- package/src/__tests__/channel-approvals.test.ts +7 -7
- package/src/__tests__/channel-readiness-service.test.ts +41 -0
- package/src/__tests__/cli-command-risk-guard.test.ts +181 -6
- package/src/__tests__/config-schema.test.ts +10 -2
- package/src/__tests__/context-memory-e2e.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +396 -0
- package/src/__tests__/conversation-error.test.ts +3 -2
- package/src/__tests__/conversation-skill-tools.test.ts +1 -3
- package/src/__tests__/conversation-title-service.test.ts +2 -15
- package/src/__tests__/credential-execution-feature-gates.test.ts +4 -8
- package/src/__tests__/credential-execution-managed-contract.test.ts +8 -8
- package/src/__tests__/credential-security-e2e.test.ts +4 -4
- package/src/__tests__/credential-security-invariants.test.ts +12 -18
- package/src/__tests__/credential-vault-unit.test.ts +32 -34
- package/src/__tests__/credential-vault.test.ts +25 -33
- package/src/__tests__/credentials-cli.test.ts +3 -3
- package/src/__tests__/daemon-credential-client.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +1 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -0
- package/src/__tests__/heartbeat-service.test.ts +35 -0
- package/src/__tests__/host-bash-proxy.test.ts +79 -0
- package/src/__tests__/host-cu-proxy.test.ts +90 -0
- package/src/__tests__/host-file-proxy.test.ts +89 -0
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/inline-skill-load-permissions.test.ts +3 -3
- package/src/__tests__/integration-status.test.ts +5 -5
- package/src/__tests__/list-messages-attachments.test.ts +171 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +64 -0
- package/src/__tests__/log-export-workspace.test.ts +1 -1
- package/src/__tests__/mcp-abort-signal.test.ts +205 -0
- package/src/__tests__/mcp-client-auth.test.ts +1 -1
- package/src/__tests__/memory-lifecycle-e2e.test.ts +2 -2
- package/src/__tests__/memory-recall-log-store.test.ts +182 -0
- package/src/__tests__/memory-recall-quality.test.ts +6 -8
- package/src/__tests__/memory-regressions.test.ts +53 -42
- package/src/__tests__/memory-retrieval.benchmark.test.ts +5 -9
- package/src/__tests__/messaging-send-tool.test.ts +5 -5
- package/src/__tests__/messaging-skill-split.test.ts +2 -17
- package/src/__tests__/notification-telegram-adapter.test.ts +125 -0
- package/src/__tests__/oauth-cli.test.ts +203 -649
- package/src/__tests__/oauth-provider-profiles.test.ts +55 -20
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/onboarding-template-contract.test.ts +2 -2
- package/src/__tests__/platform-callback-registration.test.ts +119 -0
- package/src/__tests__/secret-ingress-channel.test.ts +261 -0
- package/src/__tests__/secret-ingress-cli.test.ts +201 -0
- package/src/__tests__/secret-ingress-http.test.ts +312 -0
- package/src/__tests__/secret-ingress.test.ts +283 -0
- package/src/__tests__/secret-onetime-send.test.ts +4 -4
- package/src/__tests__/secret-routes-managed-proxy.test.ts +78 -0
- package/src/__tests__/secure-keys-managed-failover.test.ts +73 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +4 -4
- package/src/__tests__/skill-feature-flags.test.ts +11 -19
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -1
- package/src/__tests__/skill-load-inline-command.test.ts +3 -3
- package/src/__tests__/skill-load-inline-includes.test.ts +2 -2
- package/src/__tests__/skill-memory.test.ts +2 -4
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -4
- package/src/__tests__/skill-projection.benchmark.test.ts +1 -3
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +16 -2
- package/src/__tests__/slack-channel-config.test.ts +1 -1
- package/src/__tests__/slack-messaging-token-resolution.test.ts +22 -24
- package/src/__tests__/slack-share-routes.test.ts +5 -5
- package/src/__tests__/slack-skill.test.ts +5 -69
- package/src/__tests__/system-prompt.test.ts +39 -0
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +1 -1
- package/src/__tests__/workspace-migration-018-rekey-compound-credential-keys.test.ts +181 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +5 -4
- package/src/acp/client-handler.ts +113 -31
- package/src/acp/session-manager.ts +29 -27
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/cli/AGENTS.md +113 -0
- package/src/cli/commands/autonomy.ts +3 -5
- package/src/cli/commands/browser-relay.ts +2 -17
- package/src/cli/commands/contacts.ts +6 -4
- package/src/cli/commands/conversations.ts +13 -1
- package/src/cli/commands/credential-execution.ts +17 -3
- package/src/cli/commands/credentials.ts +2 -8
- package/src/cli/commands/memory.ts +2 -3
- package/src/cli/commands/oauth/__tests__/connect.test.ts +706 -0
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +686 -0
- package/src/cli/commands/oauth/__tests__/mode.test.ts +625 -0
- package/src/cli/commands/oauth/__tests__/ping.test.ts +631 -0
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +574 -0
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +416 -0
- package/src/cli/commands/oauth/__tests__/status.test.ts +551 -0
- package/src/cli/commands/oauth/__tests__/token.test.ts +420 -0
- package/src/cli/commands/oauth/apps.ts +87 -50
- package/src/cli/commands/oauth/connect.ts +405 -0
- package/src/cli/commands/oauth/disconnect.ts +285 -0
- package/src/cli/commands/oauth/index.ts +62 -20
- package/src/cli/commands/oauth/mode.ts +251 -0
- package/src/cli/commands/oauth/ping.ts +196 -0
- package/src/cli/commands/oauth/providers.ts +589 -55
- package/src/cli/commands/oauth/request.ts +564 -0
- package/src/cli/commands/oauth/shared.ts +114 -0
- package/src/cli/commands/oauth/status.ts +191 -0
- package/src/cli/commands/oauth/token.ts +150 -0
- package/src/cli/commands/platform/connect.ts +104 -0
- package/src/cli/commands/platform/disconnect.ts +118 -0
- package/src/cli/commands/platform/index.ts +252 -0
- package/src/cli/commands/sequence.ts +5 -4
- package/src/cli/commands/shotgun.ts +16 -0
- package/src/cli/commands/skills.ts +173 -41
- package/src/cli/commands/usage.ts +5 -11
- package/src/cli/lib/daemon-credential-client.ts +22 -38
- package/src/cli/program.ts +1 -1
- package/src/cli.ts +82 -17
- package/src/config/assistant-feature-flags.ts +77 -18
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/app-builder/tools/app-create.ts +1 -1
- package/src/config/bundled-skills/contacts/tools/google-contacts.ts +1 -1
- package/src/config/bundled-skills/conversations/SKILL.md +20 -0
- package/src/config/bundled-skills/conversations/TOOLS.json +23 -0
- package/src/config/bundled-skills/conversations/tools/rename-conversation.ts +66 -0
- package/src/config/bundled-skills/gmail/SKILL.md +13 -13
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +3 -3
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +2 -2
- package/src/config/bundled-skills/gmail/tools/gmail-outreach-scan.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-sender-digest.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/google-calendar/SKILL.md +10 -4
- package/src/config/bundled-skills/google-calendar/tools/shared.ts +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +19 -42
- package/src/config/bundled-skills/messaging/TOOLS.json +9 -9
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +1 -1
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +5 -2
- package/src/config/bundled-skills/messaging/tools/shared.ts +5 -6
- package/src/config/bundled-skills/notifications/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/SKILL.md +2 -2
- package/src/config/bundled-skills/settings/SKILL.md +5 -3
- package/src/config/bundled-skills/settings/TOOLS.json +17 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +50 -0
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +7 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +6 -1
- package/src/config/bundled-skills/settings/tools/identity-avatar.ts +55 -0
- package/src/config/bundled-skills/skills-catalog/SKILL.md +3 -3
- package/src/config/bundled-skills/slack/SKILL.md +58 -44
- package/src/config/bundled-tool-registry.ts +7 -19
- package/src/config/env.ts +5 -1
- package/src/config/feature-flag-registry.json +58 -42
- package/src/config/loader.ts +4 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/security.ts +9 -1
- package/src/config/schemas/services.ts +1 -1
- package/src/config/skill-state.ts +1 -3
- package/src/config/skills.ts +2 -4
- package/src/credential-execution/client.ts +1 -1
- package/src/credential-execution/feature-gates.ts +9 -16
- package/src/credential-execution/process-manager.ts +12 -0
- package/src/daemon/config-watcher.ts +4 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -0
- package/src/daemon/conversation-agent-loop.ts +51 -2
- package/src/daemon/conversation-error.ts +36 -6
- package/src/daemon/conversation-memory.ts +0 -1
- package/src/daemon/conversation-messaging.ts +9 -0
- package/src/daemon/conversation-runtime-assembly.ts +33 -0
- package/src/daemon/conversation-surfaces.ts +120 -14
- package/src/daemon/conversation.ts +5 -0
- package/src/daemon/handlers/config-slack-channel.ts +43 -1
- package/src/daemon/handlers/conversations.ts +41 -33
- package/src/daemon/handlers/skills.ts +148 -3
- package/src/daemon/host-bash-proxy.ts +16 -0
- package/src/daemon/host-cu-proxy.ts +16 -0
- package/src/daemon/host-file-proxy.ts +16 -0
- package/src/daemon/lifecycle.ts +73 -3
- package/src/daemon/message-types/acp.ts +0 -15
- package/src/daemon/message-types/conversations.ts +1 -0
- package/src/daemon/message-types/guardian-actions.ts +2 -0
- package/src/daemon/message-types/host-bash.ts +6 -1
- package/src/daemon/message-types/host-cu.ts +6 -1
- package/src/daemon/message-types/host-file.ts +6 -1
- package/src/daemon/message-types/integrations.ts +0 -1
- package/src/daemon/message-types/memory.ts +0 -1
- package/src/daemon/message-types/messages.ts +9 -1
- package/src/daemon/message-types/schedules.ts +9 -0
- package/src/daemon/server.ts +48 -9
- package/src/email/feature-gate.ts +3 -3
- package/src/heartbeat/heartbeat-service.ts +48 -0
- package/src/hooks/cli.ts +74 -0
- package/src/inbound/platform-callback-registration.ts +68 -19
- package/src/mcp/client.ts +6 -1
- package/src/mcp/manager.ts +2 -1
- package/src/mcp/mcp-oauth-provider.ts +3 -3
- package/src/memory/app-store.ts +3 -3
- package/src/memory/conversation-crud.ts +213 -0
- package/src/memory/conversation-key-store.ts +26 -0
- package/src/memory/conversation-title-service.ts +7 -17
- package/src/memory/db-init.ts +24 -0
- package/src/memory/embedding-local.ts +47 -2
- package/src/memory/indexer.ts +13 -10
- package/src/memory/items-extractor.ts +12 -4
- package/src/memory/job-utils.ts +5 -0
- package/src/memory/jobs-store.ts +10 -2
- package/src/memory/journal-memory.ts +6 -2
- package/src/memory/llm-request-log-store.ts +88 -21
- package/src/memory/memory-recall-log-store.ts +128 -0
- package/src/memory/migrations/194-memory-recall-logs.ts +50 -0
- package/src/memory/migrations/195-oauth-providers-ping-config.ts +23 -0
- package/src/memory/migrations/196-messages-conversation-created-at-index.ts +9 -0
- package/src/memory/migrations/196-strip-integration-prefix-from-provider-keys.ts +186 -0
- package/src/memory/migrations/197-oauth-providers-behavior-columns.ts +29 -0
- package/src/memory/migrations/198-drop-setup-skill-id-column.ts +11 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/retriever.test.ts +4 -5
- package/src/memory/schema/infrastructure.ts +31 -0
- package/src/memory/schema/oauth.ts +14 -0
- package/src/messaging/provider.ts +13 -12
- package/src/messaging/providers/gmail/adapter.ts +44 -35
- package/src/messaging/providers/slack/adapter.ts +63 -33
- package/src/messaging/providers/telegram-bot/adapter.ts +7 -9
- package/src/messaging/providers/whatsapp/adapter.ts +6 -8
- package/src/notifications/adapters/telegram.ts +78 -2
- package/src/oauth/__tests__/identity-verifier.test.ts +464 -0
- package/src/oauth/byo-connection.test.ts +22 -24
- package/src/oauth/connect-orchestrator.ts +79 -64
- package/src/oauth/connect-types.ts +7 -65
- package/src/oauth/connection-resolver.test.ts +13 -13
- package/src/oauth/connection-resolver.ts +3 -4
- package/src/oauth/identity-verifier.ts +177 -0
- package/src/oauth/manual-token-connection.ts +5 -5
- package/src/oauth/oauth-store.ts +251 -5
- package/src/oauth/platform-connection.test.ts +56 -6
- package/src/oauth/platform-connection.ts +8 -1
- package/src/oauth/seed-providers.ts +256 -34
- package/src/permissions/checker.ts +129 -3
- package/src/permissions/trust-client.ts +2 -2
- package/src/platform/client.ts +2 -2
- package/src/prompts/journal-context.ts +6 -1
- package/src/prompts/system-prompt.ts +43 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -5
- package/src/providers/anthropic/client.ts +139 -28
- package/src/runtime/auth/__tests__/middleware.test.ts +19 -0
- package/src/runtime/auth/route-policy.ts +0 -1
- package/src/runtime/btw-sidechain.ts +7 -1
- package/src/runtime/channel-approvals.ts +2 -2
- package/src/runtime/channel-readiness-service.ts +30 -7
- package/src/runtime/guardian-action-service.ts +7 -2
- package/src/runtime/http-router.ts +31 -0
- package/src/runtime/http-server.ts +26 -7
- package/src/runtime/http-types.ts +9 -0
- package/src/runtime/pending-interactions.ts +21 -3
- package/src/runtime/routes/acp-routes.ts +46 -28
- package/src/runtime/routes/app-management-routes.ts +123 -0
- package/src/runtime/routes/app-routes.ts +31 -0
- package/src/runtime/routes/approval-routes.ts +108 -3
- package/src/runtime/routes/attachment-routes.ts +45 -0
- package/src/runtime/routes/avatar-routes.ts +16 -0
- package/src/runtime/routes/brain-graph-routes.ts +18 -0
- package/src/runtime/routes/btw-routes.ts +20 -0
- package/src/runtime/routes/call-routes.ts +81 -0
- package/src/runtime/routes/channel-readiness-routes.ts +48 -7
- package/src/runtime/routes/channel-routes.ts +18 -0
- package/src/runtime/routes/channel-verification-routes.ts +49 -1
- package/src/runtime/routes/contact-routes.ts +77 -0
- package/src/runtime/routes/conversation-attention-routes.ts +37 -0
- package/src/runtime/routes/conversation-management-routes.ts +125 -0
- package/src/runtime/routes/conversation-query-routes.ts +78 -0
- package/src/runtime/routes/conversation-routes.ts +191 -39
- package/src/runtime/routes/conversation-starter-routes.ts +29 -0
- package/src/runtime/routes/debug-routes.ts +23 -0
- package/src/runtime/routes/diagnostics-routes.ts +30 -0
- package/src/runtime/routes/documents-routes.ts +42 -0
- package/src/runtime/routes/events-routes.ts +10 -0
- package/src/runtime/routes/global-search-routes.ts +35 -0
- package/src/runtime/routes/guardian-action-routes.ts +61 -3
- package/src/runtime/routes/guardian-approval-prompt.ts +77 -2
- package/src/runtime/routes/heartbeat-routes.ts +278 -0
- package/src/runtime/routes/host-bash-routes.ts +16 -1
- package/src/runtime/routes/host-cu-routes.ts +23 -1
- package/src/runtime/routes/host-file-routes.ts +18 -1
- package/src/runtime/routes/identity-routes.ts +35 -0
- package/src/runtime/routes/inbound-message-handler.ts +46 -25
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -8
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +30 -2
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -2
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/integrations/twilio.ts +32 -22
- package/src/runtime/routes/invite-routes.ts +83 -0
- package/src/runtime/routes/log-export-routes.ts +14 -0
- package/src/runtime/routes/memory-item-routes.ts +99 -1
- package/src/runtime/routes/migration-rollback-routes.ts +25 -0
- package/src/runtime/routes/migration-routes.ts +40 -0
- package/src/runtime/routes/notification-routes.ts +20 -0
- package/src/runtime/routes/oauth-apps.ts +13 -4
- package/src/runtime/routes/pairing-routes.ts +15 -0
- package/src/runtime/routes/recording-routes.ts +72 -0
- package/src/runtime/routes/schedule-routes.ts +77 -5
- package/src/runtime/routes/secret-routes.ts +99 -14
- package/src/runtime/routes/settings-routes.ts +102 -19
- package/src/runtime/routes/skills-routes.ts +141 -18
- package/src/runtime/routes/subagents-routes.ts +38 -3
- package/src/runtime/routes/surface-action-routes.ts +66 -24
- package/src/runtime/routes/surface-content-routes.ts +20 -0
- package/src/runtime/routes/telemetry-routes.ts +12 -0
- package/src/runtime/routes/trace-event-routes.ts +25 -0
- package/src/runtime/routes/trust-rules-routes.ts +46 -0
- package/src/runtime/routes/tts-routes.ts +15 -4
- package/src/runtime/routes/upgrade-broadcast-routes.ts +38 -0
- package/src/runtime/routes/usage-routes.ts +59 -0
- package/src/runtime/routes/watch-routes.ts +28 -0
- package/src/runtime/routes/work-items-routes.ts +59 -0
- package/src/runtime/routes/workspace-commit-routes.ts +12 -0
- package/src/runtime/routes/workspace-routes.ts +102 -0
- package/src/schedule/integration-status.ts +2 -2
- package/src/schedule/scheduler.ts +7 -1
- package/src/security/AGENTS.md +7 -0
- package/src/security/ces-rpc-credential-backend.ts +19 -16
- package/src/security/credential-backend.ts +1 -1
- package/src/security/encrypted-store.ts +3 -3
- package/src/security/oauth-completion-page.ts +153 -0
- package/src/security/oauth2.ts +58 -17
- package/src/security/secret-ingress.ts +174 -0
- package/src/security/secret-patterns.ts +133 -0
- package/src/security/secret-scanner.ts +28 -117
- package/src/security/secure-keys.ts +207 -7
- package/src/security/token-manager.ts +3 -6
- package/src/signals/bash.ts +6 -1
- package/src/signals/confirm.ts +12 -8
- package/src/signals/user-message.ts +18 -3
- package/src/skills/catalog-cache.ts +44 -0
- package/src/skills/catalog-search.ts +18 -0
- package/src/skills/skill-memory.ts +1 -2
- package/src/tasks/task-runner.ts +7 -1
- package/src/tools/credentials/broker.ts +1 -1
- package/src/tools/credentials/metadata-store.ts +1 -1
- package/src/tools/credentials/post-connect-hooks.ts +1 -1
- package/src/tools/credentials/vault.ts +36 -48
- package/src/tools/host-terminal/host-shell.ts +16 -3
- package/src/tools/mcp/mcp-tool-factory.ts +2 -1
- package/src/tools/memory/definitions.ts +1 -1
- package/src/tools/memory/handlers.test.ts +2 -4
- package/src/tools/skills/load.ts +1 -1
- package/src/tools/skills/sandbox-runner.ts +16 -3
- package/src/tools/terminal/safe-env.ts +7 -0
- package/src/tools/terminal/shell.ts +16 -3
- package/src/tools/tool-manifest.ts +1 -1
- package/src/util/log-redact.ts +9 -34
- package/src/util/logger.ts +11 -1
- package/src/util/sentry-log-stream.ts +51 -0
- package/src/watcher/providers/github.ts +2 -2
- package/src/watcher/providers/gmail.ts +1 -1
- package/src/watcher/providers/google-calendar.ts +1 -1
- package/src/watcher/providers/linear.ts +2 -2
- package/src/workspace/migrations/011-backfill-installation-id.ts +5 -3
- package/src/workspace/migrations/020-rename-oauth-skill-dirs.ts +119 -0
- package/src/workspace/migrations/registry.ts +2 -0
- package/docs/architecture/keychain-broker.md +0 -68
- package/src/cli/commands/oauth/connections.ts +0 -734
- package/src/cli/commands/oauth/platform.ts +0 -525
- package/src/cli/commands/platform.ts +0 -176
- package/src/config/bundled-skills/slack/TOOLS.json +0 -272
- package/src/config/bundled-skills/slack/tools/shared.ts +0 -34
- package/src/config/bundled-skills/slack/tools/slack-add-reaction.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-channel-details.ts +0 -38
- package/src/config/bundled-skills/slack/tools/slack-channel-permissions.ts +0 -146
- package/src/config/bundled-skills/slack/tools/slack-configure-channels.ts +0 -105
- package/src/config/bundled-skills/slack/tools/slack-delete-message.ts +0 -26
- package/src/config/bundled-skills/slack/tools/slack-edit-message.ts +0 -27
- package/src/config/bundled-skills/slack/tools/slack-leave-channel.ts +0 -25
- package/src/config/bundled-skills/slack/tools/slack-scan-digest.ts +0 -372
- package/src/oauth/provider-behaviors.ts +0 -634
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* header. Guardian decisions additionally verify that the actor is the
|
|
9
9
|
* bound guardian.
|
|
10
10
|
*/
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
11
13
|
import { getConversationByKey } from "../../memory/conversation-key-store.js";
|
|
12
14
|
import { addRule } from "../../permissions/trust-store.js";
|
|
13
15
|
import type { UserDecision } from "../../permissions/types.js";
|
|
@@ -69,6 +71,10 @@ export async function handleConfirm(
|
|
|
69
71
|
// pending interaction — the client can retry with corrected values.
|
|
70
72
|
const peeked = pendingInteractions.get(requestId);
|
|
71
73
|
if (!peeked) {
|
|
74
|
+
log.warn(
|
|
75
|
+
{ requestId, decision },
|
|
76
|
+
"Confirmation POST for unknown requestId (already consumed or never registered)",
|
|
77
|
+
);
|
|
72
78
|
return httpError(
|
|
73
79
|
"NOT_FOUND",
|
|
74
80
|
"No pending interaction found for this requestId",
|
|
@@ -129,7 +135,23 @@ export async function handleConfirm(
|
|
|
129
135
|
// Validation passed — consume the pending interaction.
|
|
130
136
|
const interaction = pendingInteractions.resolve(requestId)!;
|
|
131
137
|
|
|
132
|
-
|
|
138
|
+
log.info(
|
|
139
|
+
{
|
|
140
|
+
requestId,
|
|
141
|
+
decision,
|
|
142
|
+
toolName: interaction.confirmationDetails?.toolName,
|
|
143
|
+
conversationId: interaction.conversationId,
|
|
144
|
+
},
|
|
145
|
+
"Confirmation resolved via HTTP",
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// ACP permissions: resolve directly without a Conversation object.
|
|
149
|
+
if (interaction.directResolve) {
|
|
150
|
+
interaction.directResolve(decision as UserDecision);
|
|
151
|
+
return Response.json({ accepted: true });
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
interaction.conversation!.handleConfirmationResponse(
|
|
133
155
|
requestId,
|
|
134
156
|
decision as UserDecision,
|
|
135
157
|
selectedPattern,
|
|
@@ -187,7 +209,7 @@ export async function handleSecret(
|
|
|
187
209
|
);
|
|
188
210
|
}
|
|
189
211
|
|
|
190
|
-
interaction.conversation
|
|
212
|
+
interaction.conversation!.handleSecretResponse(
|
|
191
213
|
requestId,
|
|
192
214
|
value,
|
|
193
215
|
delivery as "store" | "transient_send" | undefined,
|
|
@@ -355,7 +377,9 @@ export function handleListPendingInteractions(
|
|
|
355
377
|
resolvedConversationId,
|
|
356
378
|
);
|
|
357
379
|
|
|
358
|
-
const confirmation = interactions.find(
|
|
380
|
+
const confirmation = interactions.find(
|
|
381
|
+
(i) => i.kind === "confirmation" || i.kind === "acp_confirmation",
|
|
382
|
+
);
|
|
359
383
|
const secret = interactions.find((i) => i.kind === "secret");
|
|
360
384
|
|
|
361
385
|
return Response.json({
|
|
@@ -377,6 +401,8 @@ export function handleListPendingInteractions(
|
|
|
377
401
|
confirmation.confirmationDetails?.persistentDecisionsAllowed,
|
|
378
402
|
temporaryOptionsAvailable:
|
|
379
403
|
confirmation.confirmationDetails?.temporaryOptionsAvailable,
|
|
404
|
+
acpToolKind: confirmation.confirmationDetails?.acpToolKind,
|
|
405
|
+
acpOptions: confirmation.confirmationDetails?.acpOptions,
|
|
380
406
|
}
|
|
381
407
|
: null,
|
|
382
408
|
pendingSecret: secret
|
|
@@ -396,22 +422,101 @@ export function approvalRouteDefinitions(): RouteDefinition[] {
|
|
|
396
422
|
{
|
|
397
423
|
endpoint: "confirm",
|
|
398
424
|
method: "POST",
|
|
425
|
+
summary: "Resolve a pending confirmation",
|
|
426
|
+
description: "Approve or deny a pending tool confirmation by requestId.",
|
|
427
|
+
tags: ["approvals"],
|
|
428
|
+
requestBody: z.object({
|
|
429
|
+
requestId: z.string().describe("Pending interaction request ID"),
|
|
430
|
+
decision: z
|
|
431
|
+
.string()
|
|
432
|
+
.describe(
|
|
433
|
+
"One of: allow, allow_10m, allow_conversation, deny, always_allow, always_deny, always_allow_high_risk",
|
|
434
|
+
),
|
|
435
|
+
selectedPattern: z
|
|
436
|
+
.string()
|
|
437
|
+
.describe("Allowlist pattern for persistent decisions")
|
|
438
|
+
.optional(),
|
|
439
|
+
selectedScope: z
|
|
440
|
+
.string()
|
|
441
|
+
.describe("Scope for persistent decisions")
|
|
442
|
+
.optional(),
|
|
443
|
+
}),
|
|
444
|
+
responseBody: z.object({
|
|
445
|
+
accepted: z.boolean(),
|
|
446
|
+
}),
|
|
399
447
|
handler: async ({ req, authContext }) => handleConfirm(req, authContext),
|
|
400
448
|
},
|
|
401
449
|
{
|
|
402
450
|
endpoint: "secret",
|
|
403
451
|
method: "POST",
|
|
452
|
+
summary: "Resolve a pending secret request",
|
|
453
|
+
description: "Provide a secret value for a pending secret request.",
|
|
454
|
+
tags: ["approvals"],
|
|
455
|
+
requestBody: z.object({
|
|
456
|
+
requestId: z.string().describe("Pending interaction request ID"),
|
|
457
|
+
value: z.string().describe("Secret value").optional(),
|
|
458
|
+
delivery: z
|
|
459
|
+
.string()
|
|
460
|
+
.describe("Delivery mode: store or transient_send")
|
|
461
|
+
.optional(),
|
|
462
|
+
}),
|
|
463
|
+
responseBody: z.object({
|
|
464
|
+
accepted: z.boolean(),
|
|
465
|
+
}),
|
|
404
466
|
handler: async ({ req, authContext }) => handleSecret(req, authContext),
|
|
405
467
|
},
|
|
406
468
|
{
|
|
407
469
|
endpoint: "trust-rules",
|
|
408
470
|
method: "POST",
|
|
471
|
+
summary: "Add a trust rule for a pending confirmation",
|
|
472
|
+
description:
|
|
473
|
+
"Add a trust rule bound to a pending confirmation without resolving it.",
|
|
474
|
+
tags: ["approvals"],
|
|
475
|
+
requestBody: z.object({
|
|
476
|
+
requestId: z.string().describe("Pending confirmation request ID"),
|
|
477
|
+
pattern: z.string().describe("Allowlist pattern"),
|
|
478
|
+
scope: z.string().describe("Scope for the rule"),
|
|
479
|
+
decision: z.string().describe("allow or deny"),
|
|
480
|
+
allowHighRisk: z
|
|
481
|
+
.boolean()
|
|
482
|
+
.describe("Allow high-risk invocations")
|
|
483
|
+
.optional(),
|
|
484
|
+
}),
|
|
485
|
+
responseBody: z.object({
|
|
486
|
+
accepted: z.boolean(),
|
|
487
|
+
}),
|
|
409
488
|
handler: async ({ req, authContext }) =>
|
|
410
489
|
handleTrustRule(req, authContext),
|
|
411
490
|
},
|
|
412
491
|
{
|
|
413
492
|
endpoint: "pending-interactions",
|
|
414
493
|
method: "GET",
|
|
494
|
+
summary: "List pending interactions",
|
|
495
|
+
description:
|
|
496
|
+
"Return pending confirmations and secrets for a conversation.",
|
|
497
|
+
tags: ["approvals"],
|
|
498
|
+
queryParams: [
|
|
499
|
+
{
|
|
500
|
+
name: "conversationKey",
|
|
501
|
+
schema: { type: "string" },
|
|
502
|
+
description: "Conversation key",
|
|
503
|
+
},
|
|
504
|
+
{
|
|
505
|
+
name: "conversationId",
|
|
506
|
+
schema: { type: "string" },
|
|
507
|
+
description: "Conversation ID",
|
|
508
|
+
},
|
|
509
|
+
],
|
|
510
|
+
responseBody: z.object({
|
|
511
|
+
pendingConfirmation: z
|
|
512
|
+
.object({})
|
|
513
|
+
.passthrough()
|
|
514
|
+
.describe("Pending confirmation details or null"),
|
|
515
|
+
pendingSecret: z
|
|
516
|
+
.object({})
|
|
517
|
+
.passthrough()
|
|
518
|
+
.describe("Pending secret request or null"),
|
|
519
|
+
}),
|
|
415
520
|
handler: ({ url, authContext }) =>
|
|
416
521
|
handleListPendingInteractions(url, authContext),
|
|
417
522
|
},
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
5
|
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
|
|
6
8
|
import * as attachmentsStore from "../../memory/attachments-store.js";
|
|
7
9
|
import {
|
|
8
10
|
AttachmentUploadError,
|
|
@@ -261,23 +263,66 @@ export function attachmentRouteDefinitions(): RouteDefinition[] {
|
|
|
261
263
|
{
|
|
262
264
|
endpoint: "attachments",
|
|
263
265
|
method: "POST",
|
|
266
|
+
summary: "Upload attachment",
|
|
267
|
+
description:
|
|
268
|
+
"Upload an attachment as base64 data or file path reference.",
|
|
269
|
+
tags: ["attachments"],
|
|
270
|
+
requestBody: z.object({
|
|
271
|
+
filename: z.string(),
|
|
272
|
+
mimeType: z.string(),
|
|
273
|
+
data: z.string().describe("Base64-encoded file data").optional(),
|
|
274
|
+
filePath: z
|
|
275
|
+
.string()
|
|
276
|
+
.describe("On-disk file path (file-backed upload)")
|
|
277
|
+
.optional(),
|
|
278
|
+
}),
|
|
279
|
+
responseBody: z.object({
|
|
280
|
+
id: z.string(),
|
|
281
|
+
original_filename: z.string(),
|
|
282
|
+
mime_type: z.string(),
|
|
283
|
+
size_bytes: z.number(),
|
|
284
|
+
kind: z.string(),
|
|
285
|
+
}),
|
|
264
286
|
handler: async ({ req }) => handleUploadAttachment(req),
|
|
265
287
|
},
|
|
266
288
|
{
|
|
267
289
|
endpoint: "attachments",
|
|
268
290
|
method: "DELETE",
|
|
291
|
+
summary: "Delete attachment",
|
|
292
|
+
description: "Delete an attachment by ID.",
|
|
293
|
+
tags: ["attachments"],
|
|
294
|
+
requestBody: z.object({
|
|
295
|
+
attachmentId: z.string(),
|
|
296
|
+
}),
|
|
269
297
|
handler: async ({ req }) => handleDeleteAttachment(req),
|
|
270
298
|
},
|
|
271
299
|
{
|
|
272
300
|
endpoint: "attachments/:id/content",
|
|
273
301
|
method: "GET",
|
|
274
302
|
policyKey: "attachments/content",
|
|
303
|
+
summary: "Get attachment content",
|
|
304
|
+
description:
|
|
305
|
+
"Serve raw file bytes for an attachment. Supports Range headers.",
|
|
306
|
+
tags: ["attachments"],
|
|
275
307
|
handler: ({ req, params }) => handleGetAttachmentContent(params.id, req),
|
|
276
308
|
},
|
|
277
309
|
{
|
|
278
310
|
endpoint: "attachments/:id",
|
|
279
311
|
method: "GET",
|
|
280
312
|
policyKey: "attachments",
|
|
313
|
+
summary: "Get attachment metadata",
|
|
314
|
+
description:
|
|
315
|
+
"Return metadata and optional base64 data for an attachment.",
|
|
316
|
+
tags: ["attachments"],
|
|
317
|
+
responseBody: z.object({
|
|
318
|
+
id: z.string(),
|
|
319
|
+
filename: z.string(),
|
|
320
|
+
mimeType: z.string(),
|
|
321
|
+
sizeBytes: z.number(),
|
|
322
|
+
kind: z.string(),
|
|
323
|
+
data: z.string().describe("Base64-encoded content"),
|
|
324
|
+
fileBacked: z.boolean(),
|
|
325
|
+
}),
|
|
281
326
|
handler: ({ params }) => handleGetAttachment(params.id),
|
|
282
327
|
},
|
|
283
328
|
];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
3
5
|
import { getCharacterComponents } from "../../avatar/character-components.js";
|
|
4
6
|
import {
|
|
5
7
|
type CharacterTraits,
|
|
@@ -39,11 +41,25 @@ export function avatarRouteDefinitions(): RouteDefinition[] {
|
|
|
39
41
|
{
|
|
40
42
|
endpoint: "avatar/character-components",
|
|
41
43
|
method: "GET",
|
|
44
|
+
summary: "Get character components",
|
|
45
|
+
description: "Return available avatar character components.",
|
|
46
|
+
tags: ["avatar"],
|
|
42
47
|
handler: () => Response.json(getCharacterComponents()),
|
|
43
48
|
},
|
|
44
49
|
{
|
|
45
50
|
endpoint: "avatar/render-from-traits",
|
|
46
51
|
method: "POST",
|
|
52
|
+
summary: "Render avatar from traits",
|
|
53
|
+
description: "Write character traits and render an avatar PNG.",
|
|
54
|
+
tags: ["avatar"],
|
|
55
|
+
requestBody: z.object({
|
|
56
|
+
bodyShape: z.string(),
|
|
57
|
+
eyeStyle: z.string(),
|
|
58
|
+
color: z.string(),
|
|
59
|
+
}),
|
|
60
|
+
responseBody: z.object({
|
|
61
|
+
ok: z.boolean(),
|
|
62
|
+
}),
|
|
47
63
|
handler: async ({ req }) => {
|
|
48
64
|
let body: CharacterTraits;
|
|
49
65
|
try {
|
|
@@ -9,6 +9,7 @@ import { readFileSync } from "node:fs";
|
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
11
|
import { count } from "drizzle-orm";
|
|
12
|
+
import { z } from "zod";
|
|
12
13
|
|
|
13
14
|
import { getDb } from "../../memory/db.js";
|
|
14
15
|
import { memoryItems } from "../../memory/schema.js";
|
|
@@ -136,11 +137,28 @@ export function brainGraphRouteDefinitions(deps: {
|
|
|
136
137
|
{
|
|
137
138
|
endpoint: "brain-graph",
|
|
138
139
|
method: "GET",
|
|
140
|
+
summary: "Get brain graph data",
|
|
141
|
+
description:
|
|
142
|
+
"Return a knowledge-graph shaped for brain-lobe visualization, with memory items mapped to brain regions.",
|
|
143
|
+
tags: ["brain-graph"],
|
|
144
|
+
responseBody: z.object({
|
|
145
|
+
entities: z.array(z.unknown()).describe("Graph entity nodes"),
|
|
146
|
+
relations: z.array(z.unknown()).describe("Graph relation edges"),
|
|
147
|
+
memorySummary: z
|
|
148
|
+
.array(z.unknown())
|
|
149
|
+
.describe("Memory kind counts and colors"),
|
|
150
|
+
totalKnowledgeCount: z.number().int(),
|
|
151
|
+
generatedAt: z.string().describe("ISO 8601 timestamp"),
|
|
152
|
+
}),
|
|
139
153
|
handler: () => handleGetBrainGraph(),
|
|
140
154
|
},
|
|
141
155
|
{
|
|
142
156
|
endpoint: "brain-graph-ui",
|
|
143
157
|
method: "GET",
|
|
158
|
+
summary: "Serve brain graph UI",
|
|
159
|
+
description:
|
|
160
|
+
"Return the brain-graph HTML visualization page with an embedded auth token.",
|
|
161
|
+
tags: ["brain-graph"],
|
|
144
162
|
handler: () => handleServeBrainGraphUI(deps.mintUiPageToken()),
|
|
145
163
|
},
|
|
146
164
|
];
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import { existsSync, readFileSync } from "node:fs";
|
|
16
16
|
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
|
|
17
19
|
import { getConversationByKey } from "../../memory/conversation-key-store.js";
|
|
20
|
+
import {
|
|
21
|
+
resolveChannelPersona,
|
|
22
|
+
resolveGuardianPersona,
|
|
23
|
+
} from "../../prompts/persona-resolver.js";
|
|
18
24
|
import { getLogger } from "../../util/logger.js";
|
|
19
25
|
import { getWorkspacePromptPath } from "../../util/platform.js";
|
|
20
26
|
import type { AuthContext } from "../auth/types.js";
|
|
@@ -144,10 +150,14 @@ async function handleBtw(
|
|
|
144
150
|
(async () => {
|
|
145
151
|
try {
|
|
146
152
|
const isIntroRequest = conversationKey === IDENTITY_INTRO_KEY;
|
|
153
|
+
const userPersona = resolveGuardianPersona();
|
|
154
|
+
const channelPersona = resolveChannelPersona(undefined);
|
|
147
155
|
const result = await runBtwSidechain({
|
|
148
156
|
content: trimmedContent,
|
|
149
157
|
conversation,
|
|
150
158
|
signal: req.signal,
|
|
159
|
+
userPersona,
|
|
160
|
+
channelPersona,
|
|
151
161
|
onEvent: (event) => {
|
|
152
162
|
if (event.type === "text_delta") {
|
|
153
163
|
controller.enqueue(
|
|
@@ -222,6 +232,16 @@ export function btwRouteDefinitions(deps: {
|
|
|
222
232
|
endpoint: "btw",
|
|
223
233
|
method: "POST",
|
|
224
234
|
policyKey: "btw",
|
|
235
|
+
summary: "Run ephemeral LLM side-chain",
|
|
236
|
+
description:
|
|
237
|
+
"Stream an ephemeral LLM call reusing the conversation's provider and message history. Response is SSE (btw_text_delta, btw_complete, btw_error).",
|
|
238
|
+
tags: ["btw"],
|
|
239
|
+
requestBody: z.object({
|
|
240
|
+
conversationKey: z
|
|
241
|
+
.string()
|
|
242
|
+
.describe("Conversation key to scope the call"),
|
|
243
|
+
content: z.string().describe("User prompt content"),
|
|
244
|
+
}),
|
|
225
245
|
handler: async ({ req, authContext }) =>
|
|
226
246
|
handleBtw(req, deps, authContext),
|
|
227
247
|
},
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* POST /v1/calls/:callSessionId/instruction — relay an instruction to an active call
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
11
13
|
import {
|
|
12
14
|
answerCall,
|
|
13
15
|
cancelCall,
|
|
@@ -288,31 +290,110 @@ export function callRouteDefinitions(deps: {
|
|
|
288
290
|
{
|
|
289
291
|
endpoint: "calls/start",
|
|
290
292
|
method: "POST",
|
|
293
|
+
summary: "Start a call",
|
|
294
|
+
description:
|
|
295
|
+
"Initiate a new outbound phone call. Supports idempotency keys to prevent duplicate calls.",
|
|
296
|
+
tags: ["calls"],
|
|
291
297
|
handler: async ({ req }) => handleStartCall(req, deps.assistantId),
|
|
298
|
+
requestBody: z.object({
|
|
299
|
+
phoneNumber: z.string().describe("Phone number to call").optional(),
|
|
300
|
+
task: z.string().describe("Task description for the call").optional(),
|
|
301
|
+
context: z
|
|
302
|
+
.string()
|
|
303
|
+
.describe("Additional context for the call")
|
|
304
|
+
.optional(),
|
|
305
|
+
conversationId: z.string().describe("Conversation to associate with"),
|
|
306
|
+
callerIdentityMode: z
|
|
307
|
+
.string()
|
|
308
|
+
.describe("Caller identity: 'assistant_number' or 'user_number'")
|
|
309
|
+
.optional(),
|
|
310
|
+
idempotencyKey: z
|
|
311
|
+
.string()
|
|
312
|
+
.describe("Idempotency key to prevent duplicate calls")
|
|
313
|
+
.optional(),
|
|
314
|
+
}),
|
|
315
|
+
responseBody: z.object({
|
|
316
|
+
callSessionId: z.string(),
|
|
317
|
+
callSid: z.string(),
|
|
318
|
+
status: z.string(),
|
|
319
|
+
toNumber: z.string(),
|
|
320
|
+
fromNumber: z.string(),
|
|
321
|
+
callerIdentityMode: z.string(),
|
|
322
|
+
}),
|
|
292
323
|
},
|
|
293
324
|
{
|
|
294
325
|
endpoint: "calls/:id/cancel",
|
|
295
326
|
method: "POST",
|
|
296
327
|
policyKey: "calls/cancel",
|
|
328
|
+
summary: "Cancel a call",
|
|
329
|
+
description: "Cancel an active or pending call.",
|
|
330
|
+
tags: ["calls"],
|
|
297
331
|
handler: async ({ req, params }) => handleCancelCall(req, params.id),
|
|
332
|
+
requestBody: z.object({
|
|
333
|
+
reason: z.string().describe("Cancellation reason"),
|
|
334
|
+
}),
|
|
335
|
+
responseBody: z.object({
|
|
336
|
+
callSessionId: z.string(),
|
|
337
|
+
status: z.string(),
|
|
338
|
+
}),
|
|
298
339
|
},
|
|
299
340
|
{
|
|
300
341
|
endpoint: "calls/:id/answer",
|
|
301
342
|
method: "POST",
|
|
302
343
|
policyKey: "calls/answer",
|
|
344
|
+
summary: "Answer a pending call question",
|
|
345
|
+
description:
|
|
346
|
+
"Provide an answer to a pending question during an active call.",
|
|
347
|
+
tags: ["calls"],
|
|
303
348
|
handler: async ({ req, params }) => handleAnswerCall(req, params.id),
|
|
349
|
+
requestBody: z.object({
|
|
350
|
+
answer: z.string().describe("Answer text"),
|
|
351
|
+
pendingQuestionId: z.string().describe("ID of the pending question"),
|
|
352
|
+
}),
|
|
353
|
+
responseBody: z.object({
|
|
354
|
+
ok: z.boolean(),
|
|
355
|
+
questionId: z.string(),
|
|
356
|
+
}),
|
|
304
357
|
},
|
|
305
358
|
{
|
|
306
359
|
endpoint: "calls/:id/instruction",
|
|
307
360
|
method: "POST",
|
|
308
361
|
policyKey: "calls/instruction",
|
|
362
|
+
summary: "Relay instruction to active call",
|
|
363
|
+
description: "Send a real-time instruction to an active call.",
|
|
364
|
+
tags: ["calls"],
|
|
309
365
|
handler: async ({ req, params }) => handleInstructionCall(req, params.id),
|
|
366
|
+
requestBody: z.object({
|
|
367
|
+
instruction: z.string().describe("Instruction text to relay"),
|
|
368
|
+
}),
|
|
369
|
+
responseBody: z.object({
|
|
370
|
+
ok: z.boolean(),
|
|
371
|
+
}),
|
|
310
372
|
},
|
|
311
373
|
{
|
|
312
374
|
endpoint: "calls/:id",
|
|
313
375
|
method: "GET",
|
|
314
376
|
policyKey: "calls",
|
|
377
|
+
summary: "Get call status",
|
|
378
|
+
description: "Return the current status and details of a call session.",
|
|
379
|
+
tags: ["calls"],
|
|
315
380
|
handler: ({ params }) => handleGetCallStatus(params.id),
|
|
381
|
+
responseBody: z.object({
|
|
382
|
+
callSessionId: z.string(),
|
|
383
|
+
conversationId: z.string(),
|
|
384
|
+
status: z.string(),
|
|
385
|
+
toNumber: z.string(),
|
|
386
|
+
fromNumber: z.string(),
|
|
387
|
+
provider: z.string(),
|
|
388
|
+
providerCallSid: z.string(),
|
|
389
|
+
task: z.string(),
|
|
390
|
+
startedAt: z.string(),
|
|
391
|
+
endedAt: z.string(),
|
|
392
|
+
lastError: z.string(),
|
|
393
|
+
pendingQuestion: z.object({}).passthrough(),
|
|
394
|
+
createdAt: z.string(),
|
|
395
|
+
updatedAt: z.string(),
|
|
396
|
+
}),
|
|
316
397
|
},
|
|
317
398
|
];
|
|
318
399
|
}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* POST /v1/channels/readiness/refresh — invalidate cache and refresh readiness
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
|
|
8
10
|
import type { ChannelId } from "../../channels/types.js";
|
|
9
11
|
import { getReadinessService } from "../../daemon/handlers/config-channels.js";
|
|
10
12
|
import {
|
|
@@ -64,13 +66,18 @@ export async function handleRefreshChannelReadiness(
|
|
|
64
66
|
req: Request,
|
|
65
67
|
): Promise<Response> {
|
|
66
68
|
let body: { channel?: ChannelId; includeRemote?: boolean };
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
const text = await req.text();
|
|
70
|
+
if (!text.trim()) {
|
|
71
|
+
body = {};
|
|
72
|
+
} else {
|
|
73
|
+
try {
|
|
74
|
+
body = JSON.parse(text) as typeof body;
|
|
75
|
+
} catch {
|
|
76
|
+
return Response.json(
|
|
77
|
+
{ success: false, error: "Invalid JSON in request body" },
|
|
78
|
+
{ status: 400 },
|
|
79
|
+
);
|
|
80
|
+
}
|
|
74
81
|
}
|
|
75
82
|
|
|
76
83
|
const service = getReadinessService();
|
|
@@ -123,12 +130,46 @@ export function channelReadinessRouteDefinitions(): RouteDefinition[] {
|
|
|
123
130
|
{
|
|
124
131
|
endpoint: "channels/readiness",
|
|
125
132
|
method: "GET",
|
|
133
|
+
summary: "Get channel readiness",
|
|
134
|
+
description: "Return readiness snapshots for one or all channels.",
|
|
135
|
+
tags: ["channels"],
|
|
126
136
|
handler: async ({ url }) => handleGetChannelReadiness(url),
|
|
137
|
+
queryParams: [
|
|
138
|
+
{
|
|
139
|
+
name: "channel",
|
|
140
|
+
schema: { type: "string" },
|
|
141
|
+
description: "Optional channel ID filter",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "includeRemote",
|
|
145
|
+
schema: { type: "string" },
|
|
146
|
+
description: "Include remote checks (default true)",
|
|
147
|
+
},
|
|
148
|
+
],
|
|
149
|
+
responseBody: z.object({
|
|
150
|
+
success: z.boolean(),
|
|
151
|
+
snapshots: z.array(z.unknown()).describe("Channel readiness snapshots"),
|
|
152
|
+
}),
|
|
127
153
|
},
|
|
128
154
|
{
|
|
129
155
|
endpoint: "channels/readiness/refresh",
|
|
130
156
|
method: "POST",
|
|
157
|
+
summary: "Refresh channel readiness",
|
|
158
|
+
description: "Invalidate cache and re-evaluate channel readiness.",
|
|
159
|
+
tags: ["channels"],
|
|
131
160
|
handler: async ({ req }) => handleRefreshChannelReadiness(req),
|
|
161
|
+
requestBody: z.object({
|
|
162
|
+
channel: z.string().describe("Optional channel ID to refresh"),
|
|
163
|
+
includeRemote: z
|
|
164
|
+
.boolean()
|
|
165
|
+
.describe("Include remote checks (default true)"),
|
|
166
|
+
}),
|
|
167
|
+
responseBody: z.object({
|
|
168
|
+
success: z.boolean(),
|
|
169
|
+
snapshots: z
|
|
170
|
+
.array(z.unknown())
|
|
171
|
+
.describe("Refreshed readiness snapshots"),
|
|
172
|
+
}),
|
|
132
173
|
},
|
|
133
174
|
];
|
|
134
175
|
}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - channel-guardian-routes.ts — guardian approval interception, expiry sweep
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type { HeartbeatService } from "../../heartbeat/heartbeat-service.js";
|
|
11
12
|
import type { RouteDefinition } from "../http-router.js";
|
|
12
13
|
import type {
|
|
13
14
|
ApprovalConversationGenerator,
|
|
@@ -53,17 +54,24 @@ export function channelRouteDefinitions(deps: {
|
|
|
53
54
|
approvalConversationGenerator?: ApprovalConversationGenerator;
|
|
54
55
|
guardianActionCopyGenerator?: GuardianActionCopyGenerator;
|
|
55
56
|
guardianFollowUpConversationGenerator?: GuardianFollowUpConversationGenerator;
|
|
57
|
+
getHeartbeatService?: () => HeartbeatService | undefined;
|
|
56
58
|
}): RouteDefinition[] {
|
|
57
59
|
return [
|
|
58
60
|
{
|
|
59
61
|
endpoint: "channels/conversation",
|
|
60
62
|
method: "DELETE",
|
|
63
|
+
summary: "Delete channel conversation",
|
|
64
|
+
description: "Delete a conversation by channel source.",
|
|
65
|
+
tags: ["channels"],
|
|
61
66
|
handler: async ({ req }) =>
|
|
62
67
|
_handleDeleteConversation(req, deps.assistantId),
|
|
63
68
|
},
|
|
64
69
|
{
|
|
65
70
|
endpoint: "channels/inbound",
|
|
66
71
|
method: "POST",
|
|
72
|
+
summary: "Process inbound channel message",
|
|
73
|
+
description: "Receive an inbound message from a channel integration.",
|
|
74
|
+
tags: ["channels"],
|
|
67
75
|
handler: async ({ req }) =>
|
|
68
76
|
_handleChannelInbound(
|
|
69
77
|
req,
|
|
@@ -73,21 +81,31 @@ export function channelRouteDefinitions(deps: {
|
|
|
73
81
|
deps.approvalConversationGenerator,
|
|
74
82
|
deps.guardianActionCopyGenerator,
|
|
75
83
|
deps.guardianFollowUpConversationGenerator,
|
|
84
|
+
deps.getHeartbeatService?.(),
|
|
76
85
|
),
|
|
77
86
|
},
|
|
78
87
|
{
|
|
79
88
|
endpoint: "channels/delivery-ack",
|
|
80
89
|
method: "POST",
|
|
90
|
+
summary: "Acknowledge channel delivery",
|
|
91
|
+
description: "Acknowledge delivery of a channel message.",
|
|
92
|
+
tags: ["channels"],
|
|
81
93
|
handler: async ({ req }) => _handleChannelDeliveryAck(req),
|
|
82
94
|
},
|
|
83
95
|
{
|
|
84
96
|
endpoint: "channels/dead-letters",
|
|
85
97
|
method: "GET",
|
|
98
|
+
summary: "List dead letters",
|
|
99
|
+
description: "Return undeliverable channel messages.",
|
|
100
|
+
tags: ["channels"],
|
|
86
101
|
handler: () => _handleListDeadLetters(),
|
|
87
102
|
},
|
|
88
103
|
{
|
|
89
104
|
endpoint: "channels/replay",
|
|
90
105
|
method: "POST",
|
|
106
|
+
summary: "Replay dead letters",
|
|
107
|
+
description: "Retry delivery of dead-letter messages.",
|
|
108
|
+
tags: ["channels"],
|
|
91
109
|
handler: async ({ req }) => _handleReplayDeadLetters(req),
|
|
92
110
|
},
|
|
93
111
|
];
|