@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
|
* GET /v1/channel-verification-sessions/status — check guardian binding status
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
11
13
|
import type { ChannelId } from "../../channels/types.js";
|
|
12
14
|
import {
|
|
13
15
|
createInboundChallenge,
|
|
@@ -243,31 +245,77 @@ export async function handleRevokeVerificationBinding(
|
|
|
243
245
|
|
|
244
246
|
export function channelVerificationRouteDefinitions(): RouteDefinition[] {
|
|
245
247
|
return [
|
|
246
|
-
// Channel verification (unified session API)
|
|
247
248
|
{
|
|
248
249
|
endpoint: "channel-verification-sessions",
|
|
249
250
|
method: "POST",
|
|
251
|
+
summary: "Create verification session",
|
|
252
|
+
description:
|
|
253
|
+
"Create a channel verification session (inbound challenge, outbound, or trusted contact).",
|
|
254
|
+
tags: ["channel-verification"],
|
|
255
|
+
requestBody: z.object({
|
|
256
|
+
channel: z.string().describe("Channel ID"),
|
|
257
|
+
destination: z.string().describe("Outbound destination"),
|
|
258
|
+
rebind: z.boolean(),
|
|
259
|
+
conversationId: z.string(),
|
|
260
|
+
originConversationId: z.string(),
|
|
261
|
+
purpose: z.string().describe("guardian or trusted_contact"),
|
|
262
|
+
contactChannelId: z.string(),
|
|
263
|
+
}),
|
|
250
264
|
handler: async ({ req, authContext }) =>
|
|
251
265
|
handleCreateVerificationSession(req, authContext.assistantId),
|
|
252
266
|
},
|
|
253
267
|
{
|
|
254
268
|
endpoint: "channel-verification-sessions/resend",
|
|
255
269
|
method: "POST",
|
|
270
|
+
summary: "Resend verification code",
|
|
271
|
+
description: "Resend the outbound verification code.",
|
|
272
|
+
tags: ["channel-verification"],
|
|
273
|
+
requestBody: z.object({
|
|
274
|
+
channel: z.string(),
|
|
275
|
+
originConversationId: z.string().optional(),
|
|
276
|
+
}),
|
|
256
277
|
handler: async ({ req }) => handleResendVerificationSession(req),
|
|
257
278
|
},
|
|
258
279
|
{
|
|
259
280
|
endpoint: "channel-verification-sessions",
|
|
260
281
|
method: "DELETE",
|
|
282
|
+
summary: "Cancel verification sessions",
|
|
283
|
+
description:
|
|
284
|
+
"Cancel all active inbound and outbound verification sessions.",
|
|
285
|
+
tags: ["channel-verification"],
|
|
286
|
+
requestBody: z.object({
|
|
287
|
+
channel: z.string(),
|
|
288
|
+
}),
|
|
289
|
+
responseBody: z.object({
|
|
290
|
+
success: z.boolean(),
|
|
291
|
+
channel: z.string(),
|
|
292
|
+
}),
|
|
261
293
|
handler: async ({ req }) => handleCancelVerificationSession(req),
|
|
262
294
|
},
|
|
263
295
|
{
|
|
264
296
|
endpoint: "channel-verification-sessions/revoke",
|
|
265
297
|
method: "POST",
|
|
298
|
+
summary: "Revoke verification binding",
|
|
299
|
+
description: "Cancel all sessions and revoke the guardian binding.",
|
|
300
|
+
tags: ["channel-verification"],
|
|
301
|
+
requestBody: z.object({
|
|
302
|
+
channel: z.string(),
|
|
303
|
+
}),
|
|
266
304
|
handler: async ({ req }) => handleRevokeVerificationBinding(req),
|
|
267
305
|
},
|
|
268
306
|
{
|
|
269
307
|
endpoint: "channel-verification-sessions/status",
|
|
270
308
|
method: "GET",
|
|
309
|
+
summary: "Get verification status",
|
|
310
|
+
description: "Check guardian binding and verification session status.",
|
|
311
|
+
tags: ["channel-verification"],
|
|
312
|
+
queryParams: [
|
|
313
|
+
{
|
|
314
|
+
name: "channel",
|
|
315
|
+
schema: { type: "string" },
|
|
316
|
+
description: "Optional channel ID filter",
|
|
317
|
+
},
|
|
318
|
+
],
|
|
271
319
|
handler: ({ url }) => handleGetVerificationStatus(url),
|
|
272
320
|
},
|
|
273
321
|
];
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* PATCH /v1/contact-channels/:contactChannelId — update a contact channel's status/policy
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
|
|
12
14
|
import {
|
|
13
15
|
deleteContact,
|
|
14
16
|
getAssistantContactMetadata,
|
|
@@ -417,22 +419,82 @@ export function contactRouteDefinitions(): RouteDefinition[] {
|
|
|
417
419
|
{
|
|
418
420
|
endpoint: "contacts",
|
|
419
421
|
method: "GET",
|
|
422
|
+
summary: "List contacts",
|
|
423
|
+
description:
|
|
424
|
+
"Return all contacts, optionally filtered by type or channel status.",
|
|
425
|
+
tags: ["contacts"],
|
|
426
|
+
responseBody: z.object({
|
|
427
|
+
ok: z.boolean(),
|
|
428
|
+
contacts: z
|
|
429
|
+
.array(z.unknown())
|
|
430
|
+
.describe("Contact objects with channels and metadata"),
|
|
431
|
+
}),
|
|
420
432
|
handler: ({ url }) => handleListContacts(url),
|
|
421
433
|
},
|
|
422
434
|
{
|
|
423
435
|
endpoint: "contacts",
|
|
424
436
|
method: "POST",
|
|
437
|
+
summary: "Create or update a contact",
|
|
438
|
+
description:
|
|
439
|
+
"Create a new contact or update an existing one. Supports upsert by contactId or channel handle.",
|
|
440
|
+
tags: ["contacts"],
|
|
441
|
+
requestBody: z.object({
|
|
442
|
+
contactId: z.string().describe("Existing contact ID (for update)"),
|
|
443
|
+
displayName: z.string().describe("Display name"),
|
|
444
|
+
channels: z
|
|
445
|
+
.array(z.unknown())
|
|
446
|
+
.describe("Channel objects with channelId, handle, displayName"),
|
|
447
|
+
assistantMetadata: z
|
|
448
|
+
.object({})
|
|
449
|
+
.passthrough()
|
|
450
|
+
.describe("Assistant-side metadata"),
|
|
451
|
+
}),
|
|
452
|
+
responseBody: z.object({
|
|
453
|
+
ok: z.boolean(),
|
|
454
|
+
contact: z
|
|
455
|
+
.object({})
|
|
456
|
+
.passthrough()
|
|
457
|
+
.describe("Created or updated contact"),
|
|
458
|
+
}),
|
|
425
459
|
handler: async ({ req }) => handleUpsertContact(req),
|
|
426
460
|
},
|
|
427
461
|
{
|
|
428
462
|
endpoint: "contacts/merge",
|
|
429
463
|
method: "POST",
|
|
464
|
+
summary: "Merge two contacts",
|
|
465
|
+
description: "Merge two contacts, keeping one and absorbing the other.",
|
|
466
|
+
tags: ["contacts"],
|
|
467
|
+
requestBody: z.object({
|
|
468
|
+
keepId: z.string().describe("ID of the contact to keep"),
|
|
469
|
+
mergeId: z
|
|
470
|
+
.string()
|
|
471
|
+
.describe("ID of the contact to merge into the kept one"),
|
|
472
|
+
}),
|
|
473
|
+
responseBody: z.object({
|
|
474
|
+
ok: z.boolean(),
|
|
475
|
+
contact: z.object({}).passthrough().describe("Merged contact"),
|
|
476
|
+
}),
|
|
430
477
|
handler: async ({ req }) => handleMergeContacts(req),
|
|
431
478
|
},
|
|
432
479
|
{
|
|
433
480
|
endpoint: "contact-channels/:contactChannelId",
|
|
434
481
|
method: "PATCH",
|
|
435
482
|
policyKey: "contact-channels",
|
|
483
|
+
summary: "Update a contact channel",
|
|
484
|
+
description: "Update status, policy, or reason on a contact's channel.",
|
|
485
|
+
tags: ["contacts"],
|
|
486
|
+
requestBody: z.object({
|
|
487
|
+
status: z.string().describe("Channel status"),
|
|
488
|
+
policy: z.string().describe("Channel policy"),
|
|
489
|
+
reason: z.string().describe("Reason for the change"),
|
|
490
|
+
}),
|
|
491
|
+
responseBody: z.object({
|
|
492
|
+
ok: z.boolean(),
|
|
493
|
+
contact: z
|
|
494
|
+
.object({})
|
|
495
|
+
.passthrough()
|
|
496
|
+
.describe("Updated contact (if applicable)"),
|
|
497
|
+
}),
|
|
436
498
|
handler: async ({ req, params }) =>
|
|
437
499
|
handleUpdateContactChannel(req, params.contactChannelId),
|
|
438
500
|
},
|
|
@@ -450,12 +512,27 @@ export function contactCatchAllRouteDefinitions(): RouteDefinition[] {
|
|
|
450
512
|
endpoint: "contacts/:id",
|
|
451
513
|
method: "GET",
|
|
452
514
|
policyKey: "contacts",
|
|
515
|
+
summary: "Get a contact",
|
|
516
|
+
description:
|
|
517
|
+
"Return a single contact with its channels and assistant metadata.",
|
|
518
|
+
tags: ["contacts"],
|
|
519
|
+
responseBody: z.object({
|
|
520
|
+
ok: z.boolean(),
|
|
521
|
+
contact: z.object({}).passthrough().describe("Contact details"),
|
|
522
|
+
assistantMetadata: z
|
|
523
|
+
.object({})
|
|
524
|
+
.passthrough()
|
|
525
|
+
.describe("Assistant-side metadata"),
|
|
526
|
+
}),
|
|
453
527
|
handler: ({ params }) => handleGetContact(params.id),
|
|
454
528
|
},
|
|
455
529
|
{
|
|
456
530
|
endpoint: "contacts/:id",
|
|
457
531
|
method: "DELETE",
|
|
458
532
|
policyKey: "contacts",
|
|
533
|
+
summary: "Delete a contact",
|
|
534
|
+
description: "Delete a contact by ID.",
|
|
535
|
+
tags: ["contacts"],
|
|
459
536
|
handler: ({ params }) => handleDeleteContact(params.id),
|
|
460
537
|
},
|
|
461
538
|
];
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* useful for assistant/LLM reporting and UI indicators.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
7
9
|
import {
|
|
8
10
|
type AttentionFilterState,
|
|
9
11
|
listConversationAttention,
|
|
@@ -134,6 +136,41 @@ export function conversationAttentionRouteDefinitions(): RouteDefinition[] {
|
|
|
134
136
|
{
|
|
135
137
|
endpoint: "conversations/attention",
|
|
136
138
|
method: "GET",
|
|
139
|
+
summary: "List conversation attention states",
|
|
140
|
+
description:
|
|
141
|
+
"Return attention state (seen/unseen) for conversations, with pagination.",
|
|
142
|
+
tags: ["conversations"],
|
|
143
|
+
queryParams: [
|
|
144
|
+
{
|
|
145
|
+
name: "state",
|
|
146
|
+
schema: { type: "string" },
|
|
147
|
+
description: "Filter: seen, unseen, or all (default all)",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "source",
|
|
151
|
+
schema: { type: "string" },
|
|
152
|
+
description: "Filter by source (default all)",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "channel",
|
|
156
|
+
schema: { type: "string" },
|
|
157
|
+
description: "Filter by source channel",
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: "limit",
|
|
161
|
+
schema: { type: "integer" },
|
|
162
|
+
description: "Max results (1–100, default 20)",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
name: "before",
|
|
166
|
+
schema: { type: "number" },
|
|
167
|
+
description: "Cursor for pagination (timestamp)",
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
responseBody: z.object({
|
|
171
|
+
conversations: z.array(z.unknown()).describe("Attention state objects"),
|
|
172
|
+
hasMore: z.boolean(),
|
|
173
|
+
}),
|
|
137
174
|
handler: ({ url }) => handleListConversationAttention(url),
|
|
138
175
|
},
|
|
139
176
|
];
|
|
@@ -14,9 +14,13 @@
|
|
|
14
14
|
* POST /v1/conversations/reorder — reorder / pin conversations
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import { z } from "zod";
|
|
18
|
+
|
|
17
19
|
import {
|
|
18
20
|
batchSetDisplayOrders,
|
|
21
|
+
countConversationsByScheduleJobId,
|
|
19
22
|
deleteConversation,
|
|
23
|
+
getConversation,
|
|
20
24
|
PRIVATE_CONVERSATION_FORK_ERROR,
|
|
21
25
|
wipeConversation,
|
|
22
26
|
} from "../../memory/conversation-crud.js";
|
|
@@ -27,6 +31,7 @@ import {
|
|
|
27
31
|
setConversationKeyIfAbsent,
|
|
28
32
|
} from "../../memory/conversation-key-store.js";
|
|
29
33
|
import { enqueueMemoryJob } from "../../memory/jobs-store.js";
|
|
34
|
+
import { deleteSchedule } from "../../schedule/schedule-store.js";
|
|
30
35
|
import { UserError } from "../../util/errors.js";
|
|
31
36
|
import { getLogger } from "../../util/logger.js";
|
|
32
37
|
import { httpError } from "../http-errors.js";
|
|
@@ -73,6 +78,22 @@ export function conversationManagementRouteDefinitions(
|
|
|
73
78
|
endpoint: "conversations",
|
|
74
79
|
method: "POST",
|
|
75
80
|
policyKey: "conversations",
|
|
81
|
+
summary: "Create a conversation",
|
|
82
|
+
description: "Create or get an existing conversation by key.",
|
|
83
|
+
tags: ["conversations"],
|
|
84
|
+
requestBody: z.object({
|
|
85
|
+
conversationKey: z
|
|
86
|
+
.string()
|
|
87
|
+
.describe("Idempotency key for the conversation"),
|
|
88
|
+
conversationType: z
|
|
89
|
+
.string()
|
|
90
|
+
.describe("'standard' (default) or 'private'"),
|
|
91
|
+
}),
|
|
92
|
+
responseBody: z.object({
|
|
93
|
+
id: z.string(),
|
|
94
|
+
conversationKey: z.string(),
|
|
95
|
+
conversationType: z.string(),
|
|
96
|
+
}),
|
|
76
97
|
handler: async ({ req }) => {
|
|
77
98
|
let body: { conversationKey?: string; conversationType?: string } = {};
|
|
78
99
|
try {
|
|
@@ -111,6 +132,17 @@ export function conversationManagementRouteDefinitions(
|
|
|
111
132
|
endpoint: "conversations/fork",
|
|
112
133
|
method: "POST",
|
|
113
134
|
policyKey: "conversations/fork",
|
|
135
|
+
summary: "Fork a conversation",
|
|
136
|
+
description:
|
|
137
|
+
"Create a copy of a conversation, optionally truncated at a specific message.",
|
|
138
|
+
tags: ["conversations"],
|
|
139
|
+
requestBody: z.object({
|
|
140
|
+
conversationId: z.string(),
|
|
141
|
+
throughMessageId: z
|
|
142
|
+
.string()
|
|
143
|
+
.describe("Truncate the fork at this message")
|
|
144
|
+
.optional(),
|
|
145
|
+
}),
|
|
114
146
|
handler: async ({ req }) => {
|
|
115
147
|
if (!deps.forkConversation) {
|
|
116
148
|
return httpError(
|
|
@@ -172,6 +204,21 @@ export function conversationManagementRouteDefinitions(
|
|
|
172
204
|
endpoint: "conversations/switch",
|
|
173
205
|
method: "POST",
|
|
174
206
|
policyKey: "conversations/switch",
|
|
207
|
+
summary: "Switch active conversation",
|
|
208
|
+
description: "Set the active conversation for the current session.",
|
|
209
|
+
tags: ["conversations"],
|
|
210
|
+
requestBody: z.object({
|
|
211
|
+
conversationId: z.string(),
|
|
212
|
+
conversationKey: z
|
|
213
|
+
.string()
|
|
214
|
+
.describe("Optional key to register for this conversation")
|
|
215
|
+
.optional(),
|
|
216
|
+
}),
|
|
217
|
+
responseBody: z.object({
|
|
218
|
+
conversationId: z.string(),
|
|
219
|
+
title: z.string(),
|
|
220
|
+
conversationType: z.string(),
|
|
221
|
+
}),
|
|
175
222
|
handler: async ({ req }) => {
|
|
176
223
|
const body = (await req.json()) as {
|
|
177
224
|
conversationId?: string;
|
|
@@ -206,6 +253,12 @@ export function conversationManagementRouteDefinitions(
|
|
|
206
253
|
endpoint: "conversations/:id/name",
|
|
207
254
|
method: "PATCH",
|
|
208
255
|
policyKey: "conversations/name",
|
|
256
|
+
summary: "Rename a conversation",
|
|
257
|
+
description: "Update the display name of a conversation.",
|
|
258
|
+
tags: ["conversations"],
|
|
259
|
+
requestBody: z.object({
|
|
260
|
+
name: z.string(),
|
|
261
|
+
}),
|
|
209
262
|
handler: async ({ req, params }) => {
|
|
210
263
|
const body = (await req.json()) as { name?: string };
|
|
211
264
|
const name = body.name;
|
|
@@ -227,6 +280,10 @@ export function conversationManagementRouteDefinitions(
|
|
|
227
280
|
endpoint: "conversations",
|
|
228
281
|
method: "DELETE",
|
|
229
282
|
policyKey: "conversations/clear-all",
|
|
283
|
+
summary: "Clear all conversations",
|
|
284
|
+
description:
|
|
285
|
+
"Permanently delete ALL conversations, messages, and memory. Requires X-Confirm-Destructive header.",
|
|
286
|
+
tags: ["conversations"],
|
|
230
287
|
handler: ({ req }) => {
|
|
231
288
|
const confirm = req.headers.get("x-confirm-destructive");
|
|
232
289
|
if (confirm !== "clear-all-conversations") {
|
|
@@ -245,6 +302,16 @@ export function conversationManagementRouteDefinitions(
|
|
|
245
302
|
endpoint: "conversations/:id/wipe",
|
|
246
303
|
method: "POST",
|
|
247
304
|
policyKey: "conversations/wipe",
|
|
305
|
+
summary: "Wipe a conversation",
|
|
306
|
+
description:
|
|
307
|
+
"Delete all messages in a conversation and revert associated memory changes.",
|
|
308
|
+
tags: ["conversations"],
|
|
309
|
+
responseBody: z.object({
|
|
310
|
+
wiped: z.boolean(),
|
|
311
|
+
unsupersededItems: z.number().int(),
|
|
312
|
+
deletedSummaries: z.number().int(),
|
|
313
|
+
cancelledJobs: z.number().int(),
|
|
314
|
+
}),
|
|
248
315
|
handler: async ({ params }) => {
|
|
249
316
|
const resolvedId = resolveConversationId(params.id);
|
|
250
317
|
if (!resolvedId) {
|
|
@@ -254,6 +321,20 @@ export function conversationManagementRouteDefinitions(
|
|
|
254
321
|
404,
|
|
255
322
|
);
|
|
256
323
|
}
|
|
324
|
+
|
|
325
|
+
// Cancel the associated schedule job (if any) before wiping the
|
|
326
|
+
// conversation — but only when this is the last conversation that
|
|
327
|
+
// references the schedule. Recurring schedules create a new
|
|
328
|
+
// conversation per run, so we must not cancel the schedule when
|
|
329
|
+
// earlier run conversations are cleaned up.
|
|
330
|
+
const conv = getConversation(resolvedId);
|
|
331
|
+
if (
|
|
332
|
+
conv?.scheduleJobId &&
|
|
333
|
+
countConversationsByScheduleJobId(conv.scheduleJobId) <= 1
|
|
334
|
+
) {
|
|
335
|
+
deleteSchedule(conv.scheduleJobId);
|
|
336
|
+
}
|
|
337
|
+
|
|
257
338
|
deps.destroyConversation(resolvedId);
|
|
258
339
|
const result = wipeConversation(resolvedId);
|
|
259
340
|
// Enqueue Qdrant vector cleanup jobs
|
|
@@ -296,6 +377,9 @@ export function conversationManagementRouteDefinitions(
|
|
|
296
377
|
endpoint: "conversations/:id",
|
|
297
378
|
method: "DELETE",
|
|
298
379
|
policyKey: "conversations",
|
|
380
|
+
summary: "Delete a conversation",
|
|
381
|
+
description: "Permanently delete a single conversation and its messages.",
|
|
382
|
+
tags: ["conversations"],
|
|
299
383
|
handler: async ({ params }) => {
|
|
300
384
|
const resolvedId = resolveConversationId(params.id);
|
|
301
385
|
if (!resolvedId) {
|
|
@@ -305,6 +389,20 @@ export function conversationManagementRouteDefinitions(
|
|
|
305
389
|
404,
|
|
306
390
|
);
|
|
307
391
|
}
|
|
392
|
+
|
|
393
|
+
// Cancel the associated schedule job (if any) before deleting the
|
|
394
|
+
// conversation — but only when this is the last conversation that
|
|
395
|
+
// references the schedule. Recurring schedules create a new
|
|
396
|
+
// conversation per run, so we must not cancel the schedule when
|
|
397
|
+
// earlier run conversations are cleaned up.
|
|
398
|
+
const conv = getConversation(resolvedId);
|
|
399
|
+
if (
|
|
400
|
+
conv?.scheduleJobId &&
|
|
401
|
+
countConversationsByScheduleJobId(conv.scheduleJobId) <= 1
|
|
402
|
+
) {
|
|
403
|
+
deleteSchedule(conv.scheduleJobId);
|
|
404
|
+
}
|
|
405
|
+
|
|
308
406
|
// Tear down the in-memory conversation (abort + dispose) before removing
|
|
309
407
|
// persistence so that a running agent loop doesn't write to a deleted
|
|
310
408
|
// conversation row, tripping FK constraints.
|
|
@@ -339,6 +437,10 @@ export function conversationManagementRouteDefinitions(
|
|
|
339
437
|
endpoint: "conversations/:id/cancel",
|
|
340
438
|
method: "POST",
|
|
341
439
|
policyKey: "conversations/cancel",
|
|
440
|
+
summary: "Cancel generation",
|
|
441
|
+
description:
|
|
442
|
+
"Abort the in-progress assistant response for a conversation.",
|
|
443
|
+
tags: ["conversations"],
|
|
342
444
|
handler: ({ params }) => {
|
|
343
445
|
const resolvedId = resolveConversationId(params.id) ?? params.id;
|
|
344
446
|
deps.cancelGeneration(resolvedId);
|
|
@@ -349,6 +451,14 @@ export function conversationManagementRouteDefinitions(
|
|
|
349
451
|
endpoint: "conversations/:id/undo",
|
|
350
452
|
method: "POST",
|
|
351
453
|
policyKey: "conversations/undo",
|
|
454
|
+
summary: "Undo last message",
|
|
455
|
+
description:
|
|
456
|
+
"Remove the most recent user+assistant message pair from the conversation.",
|
|
457
|
+
tags: ["conversations"],
|
|
458
|
+
responseBody: z.object({
|
|
459
|
+
removedCount: z.number().int(),
|
|
460
|
+
conversationId: z.string(),
|
|
461
|
+
}),
|
|
352
462
|
handler: async ({ params }) => {
|
|
353
463
|
const result = await deps.undoLastMessage(params.id);
|
|
354
464
|
if (!result) {
|
|
@@ -368,6 +478,10 @@ export function conversationManagementRouteDefinitions(
|
|
|
368
478
|
endpoint: "conversations/:id/regenerate",
|
|
369
479
|
method: "POST",
|
|
370
480
|
policyKey: "conversations/regenerate",
|
|
481
|
+
summary: "Regenerate response",
|
|
482
|
+
description:
|
|
483
|
+
"Re-run the assistant for the last user message in a conversation.",
|
|
484
|
+
tags: ["conversations"],
|
|
371
485
|
handler: async ({ params }) => {
|
|
372
486
|
try {
|
|
373
487
|
const result = await deps.regenerateResponse(params.id);
|
|
@@ -397,6 +511,17 @@ export function conversationManagementRouteDefinitions(
|
|
|
397
511
|
endpoint: "conversations/reorder",
|
|
398
512
|
method: "POST",
|
|
399
513
|
policyKey: "conversations/reorder",
|
|
514
|
+
summary: "Reorder conversations",
|
|
515
|
+
description:
|
|
516
|
+
"Batch-update display order and pin state for conversations.",
|
|
517
|
+
tags: ["conversations"],
|
|
518
|
+
requestBody: z.object({
|
|
519
|
+
updates: z
|
|
520
|
+
.array(z.unknown())
|
|
521
|
+
.describe(
|
|
522
|
+
"Array of { conversationId, displayOrder?, isPinned? } objects",
|
|
523
|
+
),
|
|
524
|
+
}),
|
|
400
525
|
handler: async ({ req }) => {
|
|
401
526
|
const body = (await req.json()) as {
|
|
402
527
|
updates?: Array<{
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
* DELETE /v1/messages/queued/:id — delete queued message
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
23
25
|
import {
|
|
24
26
|
deepMergeOverwrite,
|
|
25
27
|
getConfig,
|
|
@@ -43,7 +45,9 @@ import {
|
|
|
43
45
|
performConversationSearch,
|
|
44
46
|
} from "../../daemon/handlers/conversation-history.js";
|
|
45
47
|
import { deleteQueuedMessage } from "../../daemon/handlers/conversations.js";
|
|
48
|
+
import { getAssistantMessageIdsInTurn } from "../../memory/conversation-crud.js";
|
|
46
49
|
import { getRequestLogsByMessageId } from "../../memory/llm-request-log-store.js";
|
|
50
|
+
import { getMemoryRecallLogByMessageIds } from "../../memory/memory-recall-log-store.js";
|
|
47
51
|
import { httpError } from "../http-errors.js";
|
|
48
52
|
import type { RouteDefinition } from "../http-router.js";
|
|
49
53
|
import { normalizeLlmContextPayloads } from "./llm-context-normalization.js";
|
|
@@ -109,6 +113,10 @@ export function conversationQueryRouteDefinitions(
|
|
|
109
113
|
endpoint: "model",
|
|
110
114
|
method: "GET",
|
|
111
115
|
policyKey: "model",
|
|
116
|
+
summary: "Get current model config",
|
|
117
|
+
description:
|
|
118
|
+
"Return the active LLM model ID, provider, and available models.",
|
|
119
|
+
tags: ["config"],
|
|
112
120
|
handler: async () => {
|
|
113
121
|
const info = await getModelInfo();
|
|
114
122
|
return Response.json(info);
|
|
@@ -118,6 +126,13 @@ export function conversationQueryRouteDefinitions(
|
|
|
118
126
|
endpoint: "model",
|
|
119
127
|
method: "PUT",
|
|
120
128
|
policyKey: "model",
|
|
129
|
+
summary: "Set LLM model",
|
|
130
|
+
description: "Change the active LLM model and optionally its provider.",
|
|
131
|
+
tags: ["config"],
|
|
132
|
+
requestBody: z.object({
|
|
133
|
+
modelId: z.string(),
|
|
134
|
+
provider: z.string().describe("Optional provider override").optional(),
|
|
135
|
+
}),
|
|
121
136
|
handler: async ({ req }) => {
|
|
122
137
|
if (!deps.getModelSetContext) {
|
|
123
138
|
return httpError("INTERNAL_ERROR", "Model set not available", 500);
|
|
@@ -165,6 +180,12 @@ export function conversationQueryRouteDefinitions(
|
|
|
165
180
|
endpoint: "model/image-gen",
|
|
166
181
|
method: "PUT",
|
|
167
182
|
policyKey: "model/image-gen",
|
|
183
|
+
summary: "Set image generation model",
|
|
184
|
+
description: "Change the active image generation model.",
|
|
185
|
+
tags: ["config"],
|
|
186
|
+
requestBody: z.object({
|
|
187
|
+
modelId: z.string(),
|
|
188
|
+
}),
|
|
168
189
|
handler: async ({ req }) => {
|
|
169
190
|
if (!deps.getModelSetContext) {
|
|
170
191
|
return httpError(
|
|
@@ -200,6 +221,10 @@ export function conversationQueryRouteDefinitions(
|
|
|
200
221
|
endpoint: "config/embeddings",
|
|
201
222
|
method: "GET",
|
|
202
223
|
policyKey: "config/embeddings",
|
|
224
|
+
summary: "Get embedding config",
|
|
225
|
+
description:
|
|
226
|
+
"Return the active embedding provider, model, and available options.",
|
|
227
|
+
tags: ["config"],
|
|
203
228
|
handler: async () => {
|
|
204
229
|
const info = await getEmbeddingConfigInfo();
|
|
205
230
|
return Response.json(info);
|
|
@@ -209,6 +234,13 @@ export function conversationQueryRouteDefinitions(
|
|
|
209
234
|
endpoint: "config/embeddings",
|
|
210
235
|
method: "PUT",
|
|
211
236
|
policyKey: "config/embeddings",
|
|
237
|
+
summary: "Set embedding config",
|
|
238
|
+
description: "Change the embedding provider and optionally model.",
|
|
239
|
+
tags: ["config"],
|
|
240
|
+
requestBody: z.object({
|
|
241
|
+
provider: z.string(),
|
|
242
|
+
model: z.string().optional(),
|
|
243
|
+
}),
|
|
212
244
|
handler: async ({ req }) => {
|
|
213
245
|
if (!deps.getModelSetContext) {
|
|
214
246
|
return httpError(
|
|
@@ -265,6 +297,12 @@ export function conversationQueryRouteDefinitions(
|
|
|
265
297
|
endpoint: "config/permissions/skip",
|
|
266
298
|
method: "GET",
|
|
267
299
|
policyKey: "config/permissions/skip",
|
|
300
|
+
summary: "Get permission-skip flag",
|
|
301
|
+
description: "Return whether dangerouslySkipPermissions is enabled.",
|
|
302
|
+
tags: ["config"],
|
|
303
|
+
responseBody: z.object({
|
|
304
|
+
enabled: z.boolean(),
|
|
305
|
+
}),
|
|
268
306
|
handler: () => {
|
|
269
307
|
const config = getConfig();
|
|
270
308
|
return Response.json({
|
|
@@ -276,6 +314,12 @@ export function conversationQueryRouteDefinitions(
|
|
|
276
314
|
endpoint: "config/permissions/skip",
|
|
277
315
|
method: "PUT",
|
|
278
316
|
policyKey: "config/permissions/skip",
|
|
317
|
+
summary: "Set permission-skip flag",
|
|
318
|
+
description: "Enable or disable dangerouslySkipPermissions.",
|
|
319
|
+
tags: ["config"],
|
|
320
|
+
requestBody: z.object({
|
|
321
|
+
enabled: z.boolean(),
|
|
322
|
+
}),
|
|
279
323
|
handler: async ({ req }) => {
|
|
280
324
|
const body = (await req.json()) as { enabled?: unknown };
|
|
281
325
|
if (typeof body.enabled !== "boolean") {
|
|
@@ -304,6 +348,9 @@ export function conversationQueryRouteDefinitions(
|
|
|
304
348
|
endpoint: "config",
|
|
305
349
|
method: "GET",
|
|
306
350
|
policyKey: "config",
|
|
351
|
+
summary: "Get full config",
|
|
352
|
+
description: "Return the raw settings.json configuration object.",
|
|
353
|
+
tags: ["config"],
|
|
307
354
|
handler: () => {
|
|
308
355
|
try {
|
|
309
356
|
const raw = loadRawConfig();
|
|
@@ -324,6 +371,10 @@ export function conversationQueryRouteDefinitions(
|
|
|
324
371
|
endpoint: "config",
|
|
325
372
|
method: "PATCH",
|
|
326
373
|
policyKey: "config",
|
|
374
|
+
summary: "Patch config",
|
|
375
|
+
description:
|
|
376
|
+
"Deep-merge a partial JSON object into the settings.json configuration.",
|
|
377
|
+
tags: ["config"],
|
|
327
378
|
handler: async ({ req }) => {
|
|
328
379
|
const body = (await req.json()) as Record<string, unknown>;
|
|
329
380
|
if (
|
|
@@ -359,6 +410,14 @@ export function conversationQueryRouteDefinitions(
|
|
|
359
410
|
endpoint: "conversations/search",
|
|
360
411
|
method: "GET",
|
|
361
412
|
policyKey: "conversations/search",
|
|
413
|
+
summary: "Search conversations",
|
|
414
|
+
description:
|
|
415
|
+
"Full-text search across conversation titles and message content.",
|
|
416
|
+
tags: ["conversations"],
|
|
417
|
+
responseBody: z.object({
|
|
418
|
+
query: z.string(),
|
|
419
|
+
results: z.array(z.unknown()),
|
|
420
|
+
}),
|
|
362
421
|
handler: ({ url }) => {
|
|
363
422
|
const q = url.searchParams.get("q");
|
|
364
423
|
if (!q) {
|
|
@@ -388,6 +447,9 @@ export function conversationQueryRouteDefinitions(
|
|
|
388
447
|
endpoint: "messages/:id/content",
|
|
389
448
|
method: "GET",
|
|
390
449
|
policyKey: "messages/content",
|
|
450
|
+
summary: "Get message content",
|
|
451
|
+
description: "Return the full content of a single message by ID.",
|
|
452
|
+
tags: ["messages"],
|
|
391
453
|
handler: ({ url, params }) => {
|
|
392
454
|
const conversationId = url.searchParams.get("conversationId");
|
|
393
455
|
const result = getMessageContent(
|
|
@@ -406,12 +468,23 @@ export function conversationQueryRouteDefinitions(
|
|
|
406
468
|
endpoint: "messages/:id/llm-context",
|
|
407
469
|
method: "GET",
|
|
408
470
|
policyKey: "messages/llm-context",
|
|
471
|
+
summary: "Get LLM context for a message",
|
|
472
|
+
description:
|
|
473
|
+
"Return request/response logs and memory recall data for a specific message.",
|
|
474
|
+
tags: ["messages"],
|
|
475
|
+
responseBody: z.object({
|
|
476
|
+
messageId: z.string(),
|
|
477
|
+
logs: z.array(z.unknown()),
|
|
478
|
+
memoryRecall: z.object({}).passthrough(),
|
|
479
|
+
}),
|
|
409
480
|
handler: ({ params }) => {
|
|
410
481
|
const messageId = params.id;
|
|
411
482
|
if (!messageId) {
|
|
412
483
|
return httpError("BAD_REQUEST", "message id is required", 400);
|
|
413
484
|
}
|
|
414
485
|
const logs = getRequestLogsByMessageId(messageId);
|
|
486
|
+
const turnMessageIds = getAssistantMessageIdsInTurn(messageId);
|
|
487
|
+
const memoryRecallLog = getMemoryRecallLogByMessageIds(turnMessageIds);
|
|
415
488
|
return Response.json({
|
|
416
489
|
messageId,
|
|
417
490
|
logs: logs.map((log) => {
|
|
@@ -444,6 +517,7 @@ export function conversationQueryRouteDefinitions(
|
|
|
444
517
|
...result,
|
|
445
518
|
};
|
|
446
519
|
}),
|
|
520
|
+
memoryRecall: memoryRecallLog ?? null,
|
|
447
521
|
});
|
|
448
522
|
},
|
|
449
523
|
},
|
|
@@ -453,6 +527,10 @@ export function conversationQueryRouteDefinitions(
|
|
|
453
527
|
endpoint: "messages/queued/:id",
|
|
454
528
|
method: "DELETE",
|
|
455
529
|
policyKey: "messages/queued",
|
|
530
|
+
summary: "Delete a queued message",
|
|
531
|
+
description:
|
|
532
|
+
"Remove a pending message from the conversation queue before it is processed.",
|
|
533
|
+
tags: ["messages"],
|
|
456
534
|
handler: ({ url, params }) => {
|
|
457
535
|
if (!deps.findConversationForQueue) {
|
|
458
536
|
return httpError(
|