@vellumai/assistant 0.4.48 → 0.4.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +26 -35
- package/README.md +5 -26
- package/docs/architecture/integrations.md +45 -41
- package/docs/architecture/keychain-broker.md +3 -3
- package/docs/architecture/memory.md +180 -119
- package/docs/runbook-trusted-contacts.md +3 -8
- package/hook-templates/debug-prompt-logger/hook.json +1 -1
- package/hook-templates/debug-prompt-logger/run.sh +1 -3
- package/package.json +2 -2
- package/src/__tests__/actor-token-service.test.ts +0 -1
- package/src/__tests__/agent-loop.test.ts +3 -1
- package/src/__tests__/anthropic-provider.test.ts +249 -2
- package/src/__tests__/approval-cascade.test.ts +796 -0
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +4 -0
- package/src/__tests__/assistant-attachments.test.ts +12 -34
- package/src/__tests__/assistant-feature-flag-guard.test.ts +0 -23
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +76 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -1
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +2 -2
- package/src/__tests__/canonical-guardian-store.test.ts +95 -0
- package/src/__tests__/channel-guardian.test.ts +0 -2
- package/src/__tests__/channel-readiness-routes.test.ts +15 -6
- package/src/__tests__/channel-readiness-service.test.ts +10 -9
- package/src/__tests__/checker.test.ts +13 -20
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +1 -1
- package/src/__tests__/computer-use-tools.test.ts +2 -19
- package/src/__tests__/config-schema.test.ts +1 -68
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-image-dimensions.test.ts +332 -0
- package/src/__tests__/context-memory-e2e.test.ts +11 -100
- package/src/__tests__/context-token-estimator.test.ts +196 -13
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +152 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +2 -0
- package/src/__tests__/credential-metadata-store.test.ts +64 -73
- package/src/__tests__/credential-security-e2e.test.ts +1 -0
- package/src/__tests__/credential-security-invariants.test.ts +13 -7
- package/src/__tests__/credential-vault-unit.test.ts +284 -49
- package/src/__tests__/credential-vault.test.ts +150 -16
- package/src/__tests__/credentials-cli.test.ts +71 -0
- package/src/__tests__/cu-unified-flow.test.ts +532 -0
- package/src/__tests__/date-context.test.ts +93 -77
- package/src/__tests__/deterministic-verification-control-plane.test.ts +64 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +3 -3
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +93 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -39
- package/src/__tests__/heartbeat-service.test.ts +0 -1
- package/src/__tests__/history-repair.test.ts +245 -0
- package/src/__tests__/host-cu-proxy.test.ts +791 -0
- package/src/__tests__/host-shell-tool.test.ts +27 -15
- package/src/__tests__/http-user-message-parity.test.ts +2 -0
- package/src/__tests__/ingress-url-consistency.test.ts +14 -21
- package/src/__tests__/integration-status.test.ts +32 -51
- package/src/__tests__/intent-routing.test.ts +0 -1
- package/src/__tests__/invite-redemption-service.test.ts +65 -1
- package/src/__tests__/invite-routes-http.test.ts +10 -9
- package/src/__tests__/keychain-broker-client.test.ts +14 -46
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +56 -18
- package/src/__tests__/memory-lifecycle-e2e.test.ts +244 -387
- package/src/__tests__/memory-recall-quality.test.ts +244 -407
- package/src/__tests__/memory-regressions.experimental.test.ts +126 -101
- package/src/__tests__/memory-regressions.test.ts +477 -2841
- package/src/__tests__/memory-retrieval.benchmark.test.ts +33 -150
- package/src/__tests__/memory-upsert-concurrency.test.ts +5 -244
- package/src/__tests__/mime-builder.test.ts +28 -0
- package/src/__tests__/native-web-search.test.ts +1 -0
- package/src/__tests__/notification-routing-intent.test.ts +0 -1
- package/src/__tests__/oauth-cli.test.ts +941 -15
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -9
- package/src/__tests__/oauth-scope-policy.test.ts +4 -6
- package/src/__tests__/oauth-store.test.ts +870 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/provider-error-scenarios.test.ts +0 -1
- package/src/__tests__/provider-streaming.benchmark.test.ts +0 -1
- package/src/__tests__/public-ingress-urls.test.ts +15 -21
- package/src/__tests__/qdrant-collection-migration.test.ts +53 -8
- package/src/__tests__/recording-handler.test.ts +3 -4
- package/src/__tests__/registry.test.ts +2 -3
- package/src/__tests__/relay-server.test.ts +46 -1
- package/src/__tests__/runtime-events-sse.test.ts +55 -7
- package/src/__tests__/schedule-store.test.ts +0 -1
- package/src/__tests__/schedule-tools.test.ts +32 -0
- package/src/__tests__/scheduler-recurrence.test.ts +0 -1
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/script-proxy-certs.test.ts +1 -1
- package/src/__tests__/secret-ingress-handler.test.ts +0 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -0
- package/src/__tests__/secure-keys.test.ts +7 -2
- package/src/__tests__/send-endpoint-busy.test.ts +24 -6
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/session-abort-tool-results.test.ts +1 -14
- package/src/__tests__/session-agent-loop-overflow.test.ts +1583 -0
- package/src/__tests__/session-agent-loop.test.ts +19 -15
- package/src/__tests__/session-confirmation-signals.test.ts +1 -15
- package/src/__tests__/session-error.test.ts +124 -2
- package/src/__tests__/session-history-web-search.test.ts +918 -0
- package/src/__tests__/session-init.benchmark.test.ts +4 -5
- package/src/__tests__/session-pre-run-repair.test.ts +1 -14
- package/src/__tests__/session-provider-retry-repair.test.ts +25 -28
- package/src/__tests__/session-queue.test.ts +37 -27
- package/src/__tests__/session-runtime-assembly.test.ts +54 -0
- package/src/__tests__/session-slash-known.test.ts +1 -15
- package/src/__tests__/session-slash-queue.test.ts +1 -15
- package/src/__tests__/session-slash-unknown.test.ts +1 -15
- package/src/__tests__/session-workspace-cache-state.test.ts +3 -33
- package/src/__tests__/session-workspace-injection.test.ts +3 -37
- package/src/__tests__/session-workspace-tool-tracking.test.ts +3 -37
- package/src/__tests__/skill-include-graph.test.ts +66 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +0 -1
- package/src/__tests__/skill-load-tool.test.ts +149 -1
- package/src/__tests__/skill-projection-feature-flag.test.ts +0 -1
- package/src/__tests__/skills-install-extract.test.ts +93 -0
- package/src/__tests__/skills-uninstall.test.ts +1 -1
- package/src/__tests__/skills.test.ts +3 -3
- package/src/__tests__/skillssh-registry.test.ts +451 -0
- package/src/__tests__/slack-channel-config.test.ts +67 -3
- package/src/__tests__/slack-share-routes.test.ts +17 -19
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/telegram-invite-adapter.test.ts +18 -22
- package/src/__tests__/terminal-tools.test.ts +4 -3
- package/src/__tests__/test-support/computer-use-skill-harness.ts +3 -2
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +0 -1
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/trust-store-pattern-matches.test.ts +29 -0
- package/src/__tests__/trust-store.test.ts +7 -13
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -16
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -1
- package/src/__tests__/voice-invite-redemption.test.ts +32 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/agent/ax-tree-compaction.test.ts +286 -0
- package/src/agent/loop.ts +104 -131
- package/src/approvals/AGENTS.md +1 -1
- package/src/approvals/guardian-request-resolvers.ts +14 -2
- package/src/bundler/compiler-tools.ts +66 -2
- package/src/calls/call-domain.ts +133 -6
- package/src/calls/call-store.ts +6 -0
- package/src/calls/relay-server.ts +52 -18
- package/src/calls/relay-setup-router.ts +17 -1
- package/src/calls/twilio-config.ts +3 -8
- package/src/calls/twilio-routes.ts +1 -2
- package/src/calls/types.ts +3 -1
- package/src/calls/voice-ingress-preflight.ts +1 -1
- package/src/cli/commands/browser-relay.ts +18 -12
- package/src/cli/commands/completions.ts +0 -3
- package/src/cli/commands/credentials.ts +101 -15
- package/src/cli/commands/doctor.ts +4 -3
- package/src/cli/commands/mcp.ts +46 -59
- package/src/cli/commands/memory.ts +16 -165
- package/src/cli/commands/oauth/apps.ts +284 -0
- package/src/cli/commands/oauth/connections.ts +633 -0
- package/src/cli/commands/oauth/index.ts +52 -0
- package/src/cli/commands/oauth/providers.ts +256 -0
- package/src/cli/commands/sessions.ts +5 -2
- package/src/cli/commands/skills.ts +177 -339
- package/src/cli/http-client.ts +0 -20
- package/src/cli/main-screen.tsx +2 -2
- package/src/cli/program.ts +6 -11
- package/src/cli/reference.ts +1 -3
- package/src/cli.ts +4 -10
- package/src/config/assistant-feature-flags.ts +0 -3
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +1 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +3 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +23 -5
- package/src/config/bundled-skills/computer-use/tools/{computer-use-request-control.ts → computer-use-observe.ts} +1 -5
- package/src/config/bundled-skills/google-calendar/calendar-client.ts +21 -16
- package/src/config/bundled-skills/messaging/tools/shared.ts +1 -4
- package/src/config/bundled-skills/settings/SKILL.md +1 -1
- package/src/config/bundled-skills/settings/TOOLS.json +2 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +5 -33
- package/src/config/bundled-tool-registry.ts +2 -5
- package/src/config/env-registry.ts +14 -83
- package/src/config/env.ts +11 -50
- package/src/config/feature-flag-registry.json +16 -16
- package/src/config/loader.ts +0 -6
- package/src/config/schema.ts +4 -13
- package/src/config/schemas/memory-lifecycle.ts +0 -9
- package/src/config/schemas/memory-processing.ts +0 -180
- package/src/config/schemas/memory-retrieval.ts +32 -104
- package/src/config/schemas/memory.ts +0 -10
- package/src/config/skills.ts +21 -2
- package/src/config/types.ts +0 -4
- package/src/context/image-dimensions.ts +229 -0
- package/src/context/token-estimator.ts +75 -12
- package/src/context/window-manager.ts +53 -11
- package/src/daemon/assistant-attachments.ts +1 -13
- package/src/daemon/config-watcher.ts +61 -3
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/date-context.ts +114 -31
- package/src/daemon/handlers/config-ingress.ts +8 -33
- package/src/daemon/handlers/config-slack-channel.ts +49 -46
- package/src/daemon/handlers/config-telegram.ts +32 -16
- package/src/daemon/handlers/sessions.ts +27 -36
- package/src/daemon/handlers/shared.ts +0 -130
- package/src/daemon/handlers/skills.ts +20 -1
- package/src/daemon/history-repair.ts +72 -8
- package/src/daemon/host-cu-proxy.ts +430 -0
- package/src/daemon/lifecycle.ts +67 -71
- package/src/daemon/mcp-reload-service.ts +2 -2
- package/src/daemon/message-protocol.ts +3 -0
- package/src/daemon/message-types/computer-use.ts +1 -129
- package/src/daemon/message-types/host-cu.ts +19 -0
- package/src/daemon/message-types/memory.ts +4 -16
- package/src/daemon/message-types/messages.ts +4 -0
- package/src/daemon/message-types/sessions.ts +4 -0
- package/src/daemon/server.ts +25 -21
- package/src/daemon/session-agent-loop-handlers.ts +40 -0
- package/src/daemon/session-agent-loop.ts +334 -48
- package/src/daemon/session-attachments.ts +1 -2
- package/src/daemon/session-error.ts +89 -6
- package/src/daemon/session-history.ts +17 -7
- package/src/daemon/session-media-retry.ts +6 -2
- package/src/daemon/session-memory.ts +69 -149
- package/src/daemon/session-process.ts +10 -1
- package/src/daemon/session-runtime-assembly.ts +49 -19
- package/src/daemon/session-slash.ts +1 -1
- package/src/daemon/session-surfaces.ts +43 -28
- package/src/daemon/session-tool-setup.ts +9 -10
- package/src/daemon/session.ts +150 -17
- package/src/daemon/tool-side-effects.ts +2 -8
- package/src/daemon/watch-handler.ts +2 -2
- package/src/events/tool-metrics-listener.ts +2 -2
- package/src/hooks/manager.ts +1 -4
- package/src/inbound/public-ingress-urls.ts +7 -7
- package/src/instrument.ts +61 -1
- package/src/logfire.ts +16 -5
- package/src/memory/admin.ts +2 -191
- package/src/memory/canonical-guardian-store.ts +38 -2
- package/src/memory/conversation-crud.ts +0 -33
- package/src/memory/conversation-key-store.ts +21 -0
- package/src/memory/conversation-queries.ts +22 -3
- package/src/memory/db-init.ts +32 -0
- package/src/memory/embedding-backend.ts +84 -8
- package/src/memory/embedding-types.ts +9 -1
- package/src/memory/indexer.ts +7 -46
- package/src/memory/items-extractor.ts +274 -76
- package/src/memory/job-handlers/backfill.ts +2 -127
- package/src/memory/job-handlers/cleanup.ts +2 -16
- package/src/memory/job-handlers/extraction.ts +2 -138
- package/src/memory/job-handlers/index-maintenance.ts +1 -6
- package/src/memory/job-handlers/summarization.ts +3 -148
- package/src/memory/job-utils.ts +21 -59
- package/src/memory/jobs-store.ts +1 -159
- package/src/memory/jobs-worker.ts +9 -52
- package/src/memory/migrations/104-core-indexes.ts +3 -3
- package/src/memory/migrations/149-oauth-tables.ts +62 -0
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +98 -0
- package/src/memory/migrations/151-oauth-providers-ping-url.ts +11 -0
- package/src/memory/migrations/152-memory-item-supersession.ts +44 -0
- package/src/memory/migrations/153-drop-entity-tables.ts +15 -0
- package/src/memory/migrations/154-drop-fts.ts +20 -0
- package/src/memory/migrations/155-drop-conflicts.ts +7 -0
- package/src/memory/migrations/156-call-session-invite-metadata.ts +24 -0
- package/src/memory/migrations/index.ts +8 -0
- package/src/memory/qdrant-client.ts +148 -51
- package/src/memory/raw-query.ts +1 -1
- package/src/memory/retriever.test.ts +294 -273
- package/src/memory/retriever.ts +421 -645
- package/src/memory/schema/calls.ts +2 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-core.ts +3 -48
- package/src/memory/schema/oauth.ts +67 -0
- package/src/memory/search/formatting.ts +263 -176
- package/src/memory/search/lexical.ts +1 -254
- package/src/memory/search/ranking.ts +0 -455
- package/src/memory/search/semantic.ts +100 -14
- package/src/memory/search/staleness.ts +47 -0
- package/src/memory/search/tier-classifier.ts +21 -0
- package/src/memory/search/types.ts +15 -77
- package/src/memory/task-memory-cleanup.ts +4 -6
- package/src/messaging/provider.ts +4 -4
- package/src/messaging/providers/gmail/client.ts +82 -2
- package/src/messaging/providers/gmail/mime-builder.ts +17 -7
- package/src/messaging/providers/gmail/people-client.ts +10 -10
- package/src/messaging/providers/telegram-bot/adapter.ts +17 -17
- package/src/messaging/providers/whatsapp/adapter.ts +11 -8
- package/src/messaging/registry.ts +2 -32
- package/src/notifications/copy-composer.ts +0 -5
- package/src/notifications/signal.ts +4 -5
- package/src/oauth/byo-connection.test.ts +133 -25
- package/src/oauth/byo-connection.ts +22 -6
- package/src/oauth/connect-orchestrator.ts +113 -57
- package/src/oauth/connect-types.ts +17 -23
- package/src/oauth/connection-resolver.ts +35 -11
- package/src/oauth/connection.ts +1 -1
- package/src/oauth/manual-token-connection.ts +104 -0
- package/src/oauth/oauth-store.ts +582 -0
- package/src/oauth/platform-connection.test.ts +29 -0
- package/src/oauth/platform-connection.ts +6 -5
- package/src/oauth/provider-behaviors.ts +124 -0
- package/src/oauth/scope-policy.ts +9 -2
- package/src/oauth/seed-providers.ts +167 -0
- package/src/oauth/token-persistence.ts +81 -77
- package/src/permissions/checker.ts +3 -3
- package/src/permissions/defaults.ts +1 -1
- package/src/permissions/prompter.ts +10 -1
- package/src/permissions/trust-store.ts +36 -1
- package/src/playbooks/playbook-compiler.ts +1 -1
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +3 -1
- package/src/prompts/system-prompt.ts +46 -42
- package/src/providers/anthropic/client.ts +59 -20
- package/src/providers/retry.ts +1 -27
- package/src/providers/types.ts +7 -1
- package/src/runtime/AGENTS.md +9 -0
- package/src/runtime/auth/route-policy.ts +6 -6
- package/src/runtime/channel-reply-delivery.ts +0 -40
- package/src/runtime/gateway-client.ts +0 -7
- package/src/runtime/guardian-reply-router.ts +24 -22
- package/src/runtime/http-server.ts +10 -8
- package/src/runtime/http-types.ts +2 -2
- package/src/runtime/invite-redemption-service.ts +19 -1
- package/src/runtime/invite-service.ts +25 -0
- package/src/runtime/middleware/twilio-validation.ts +1 -11
- package/src/runtime/pending-interactions.ts +14 -12
- package/src/runtime/routes/brain-graph-routes.ts +10 -90
- package/src/runtime/routes/channel-delivery-routes.ts +0 -1
- package/src/runtime/routes/conversation-routes.ts +81 -19
- package/src/runtime/routes/events-routes.ts +21 -11
- package/src/runtime/routes/host-cu-routes.ts +97 -0
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +21 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +12 -111
- package/src/runtime/routes/integrations/slack/share.ts +6 -7
- package/src/runtime/routes/log-export-routes.ts +126 -8
- package/src/runtime/routes/memory-item-routes.test.ts +754 -0
- package/src/runtime/routes/memory-item-routes.ts +503 -0
- package/src/runtime/routes/session-management-routes.ts +3 -3
- package/src/runtime/routes/settings-routes.ts +55 -48
- package/src/runtime/routes/surface-action-routes.ts +1 -1
- package/src/runtime/routes/trust-rules-routes.ts +14 -0
- package/src/runtime/routes/watch-routes.ts +128 -0
- package/src/runtime/routes/workspace-routes.ts +2 -1
- package/src/schedule/integration-status.ts +10 -9
- package/src/security/credential-key.ts +0 -156
- package/src/security/keychain-broker-client.ts +22 -10
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +25 -3
- package/src/security/token-manager.ts +137 -64
- package/src/skills/catalog-install.ts +414 -0
- package/src/skills/include-graph.ts +32 -0
- package/src/skills/skillssh-registry.ts +503 -0
- package/src/telegram/bot-username.ts +2 -3
- package/src/tools/assets/search.ts +5 -1
- package/src/tools/browser/network-recorder.ts +1 -1
- package/src/tools/browser/network-recording-types.ts +1 -1
- package/src/tools/computer-use/definitions.ts +36 -11
- package/src/tools/computer-use/registry.ts +5 -6
- package/src/tools/credentials/broker.ts +1 -2
- package/src/tools/credentials/metadata-store.ts +17 -121
- package/src/tools/credentials/vault.ts +92 -167
- package/src/tools/memory/definitions.ts +4 -13
- package/src/tools/memory/handlers.test.ts +83 -103
- package/src/tools/memory/handlers.ts +50 -85
- package/src/tools/registry.ts +2 -7
- package/src/tools/schedule/create.ts +8 -1
- package/src/tools/schedule/update.ts +8 -1
- package/src/tools/skills/load.ts +85 -3
- package/src/tools/watch/watch-state.ts +0 -12
- package/src/util/logger.ts +7 -41
- package/src/util/platform.ts +9 -28
- package/src/watcher/providers/google-calendar.ts +2 -1
- package/src/__tests__/clarification-resolver.test.ts +0 -193
- package/src/__tests__/computer-use-session-compaction.test.ts +0 -143
- package/src/__tests__/computer-use-session-lifecycle.test.ts +0 -322
- package/src/__tests__/computer-use-session-working-dir.test.ts +0 -166
- package/src/__tests__/computer-use-skill-baseline.test.ts +0 -78
- package/src/__tests__/computer-use-skill-endstate.test.ts +0 -105
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +0 -249
- package/src/__tests__/conflict-intent-tokenization.test.ts +0 -160
- package/src/__tests__/conflict-policy.test.ts +0 -269
- package/src/__tests__/conflict-store.test.ts +0 -372
- package/src/__tests__/contradiction-checker.test.ts +0 -361
- package/src/__tests__/entity-extractor.test.ts +0 -211
- package/src/__tests__/entity-search.test.ts +0 -1117
- package/src/__tests__/profile-compiler.test.ts +0 -392
- package/src/__tests__/ride-shotgun-handler.test.ts +0 -452
- package/src/__tests__/session-conflict-gate.test.ts +0 -1228
- package/src/__tests__/session-profile-injection.test.ts +0 -557
- package/src/cli/commands/dev.ts +0 -129
- package/src/cli/commands/map.ts +0 -391
- package/src/cli/commands/oauth.ts +0 -77
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +0 -25
- package/src/config/bundled-skills/knowledge-graph/TOOLS.json +0 -66
- package/src/config/bundled-skills/knowledge-graph/tools/graph-query.ts +0 -211
- package/src/daemon/computer-use-session.ts +0 -1026
- package/src/daemon/ride-shotgun-handler.ts +0 -569
- package/src/daemon/session-conflict-gate.ts +0 -167
- package/src/daemon/session-dynamic-profile.ts +0 -77
- package/src/memory/clarification-resolver.ts +0 -417
- package/src/memory/conflict-intent.ts +0 -205
- package/src/memory/conflict-policy.ts +0 -127
- package/src/memory/conflict-store.ts +0 -410
- package/src/memory/contradiction-checker.ts +0 -508
- package/src/memory/entity-extractor.ts +0 -535
- package/src/memory/format-recall.ts +0 -47
- package/src/memory/fts-reconciler.ts +0 -165
- package/src/memory/job-handlers/conflict.ts +0 -200
- package/src/memory/profile-compiler.ts +0 -195
- package/src/memory/recall-cache.ts +0 -117
- package/src/memory/search/entity.ts +0 -535
- package/src/memory/search/query-expansion.test.ts +0 -70
- package/src/memory/search/query-expansion.ts +0 -118
- package/src/oauth/provider-base-urls.ts +0 -21
- package/src/oauth/provider-profiles.ts +0 -192
- package/src/prompts/computer-use-prompt.ts +0 -98
- package/src/runtime/routes/computer-use-routes.ts +0 -641
- package/src/runtime/routes/mcp-routes.ts +0 -20
- package/src/runtime/telegram-streaming-delivery.test.ts +0 -729
- package/src/runtime/telegram-streaming-delivery.ts +0 -393
- package/src/tools/computer-use/request-computer-control.ts +0 -56
package/ARCHITECTURE.md
CHANGED
|
@@ -468,7 +468,7 @@ A complementary access-granting flow where the guardian proactively creates a sh
|
|
|
468
468
|
|
|
469
469
|
| Channel | Status | Prerequisites |
|
|
470
470
|
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
471
|
-
| Telegram | Shipped | Bot username resolved from credential metadata or
|
|
471
|
+
| Telegram | Shipped | Bot username resolved from credential metadata or config |
|
|
472
472
|
| Voice | Shipped | Identity-bound voice code redemption via DTMF/speech in the relay state machine. Always-on canonical behavior with personalized friend/guardian name prompts. |
|
|
473
473
|
| Slack | Deferred | Needs DM-safe ingress — Socket Mode handles channel messages but DM-initiated invite flows need routing |
|
|
474
474
|
|
|
@@ -692,15 +692,10 @@ graph LR
|
|
|
692
692
|
MSG["messages<br/>───────────────<br/>id, conversation_id (FK)<br/>role: user | assistant<br/>content: JSON array<br/>created_at"]
|
|
693
693
|
TOOL["tool_invocations<br/>───────────────<br/>tool_name, input, result<br/>decision, risk_level<br/>duration_ms"]
|
|
694
694
|
SEG["memory_segments<br/>───────────────<br/>Text chunks for retrieval<br/>Linked to messages<br/>token_estimate per segment"]
|
|
695
|
-
FTS["memory_segment_fts<br/>───────────────<br/>FTS5 virtual table<br/>Auto-synced via triggers<br/>Powers lexical search"]
|
|
696
695
|
ITEMS["memory_items<br/>───────────────<br/>Extracted facts/entities<br/>kind, subject, statement<br/>confidence, fingerprint (dedup)<br/>verification_state, scope_id<br/>first/last seen timestamps"]
|
|
697
|
-
CONFLICTS["memory_item_conflicts<br/>───────────────<br/>Pending/resolved contradiction pairs<br/>existing_item_id + candidate_item_id<br/>clarification question + resolution note<br/>partial unique pending pair index"]
|
|
698
|
-
ENTITIES["memory_entities<br/>───────────────<br/>Canonical entities + aliases<br/>mention_count, first/last seen<br/>Resolved across messages"]
|
|
699
|
-
RELS["memory_entity_relations<br/>───────────────<br/>Directional entity edges<br/>Unique by source/target/relation<br/>first/last seen + evidence"]
|
|
700
|
-
ITEM_ENTS["memory_item_entities<br/>───────────────<br/>Join table linking extracted<br/>memory_items to entities"]
|
|
701
696
|
SUM["memory_summaries<br/>───────────────<br/>scope: conversation | weekly<br/>Compressed history for context<br/>window management"]
|
|
702
697
|
EMB["memory_embeddings<br/>───────────────<br/>target: segment | item | summary<br/>provider + model metadata<br/>vector_json (float array)<br/>Powers semantic search"]
|
|
703
|
-
JOBS["memory_jobs<br/>───────────────<br/>Async task queue<br/>Types: embed, extract,<br/>summarize, backfill
|
|
698
|
+
JOBS["memory_jobs<br/>───────────────<br/>Async task queue<br/>Types: embed, extract,<br/>summarize, backfill, cleanup<br/>Status: pending → running →<br/>completed | failed"]
|
|
704
699
|
ATT["attachments<br/>───────────────<br/>base64-encoded file data<br/>mime_type, size_bytes<br/>Linked to messages via<br/>message_attachments join"]
|
|
705
700
|
REM["reminders<br/>───────────────<br/>One-time scheduled reminders<br/>label, message, fireAt<br/>mode: notify | execute<br/>status: pending → fired | cancelled<br/>routing_intent: single_channel |<br/>multi_channel | all_channels<br/>routing_hints_json (free-form)"]
|
|
706
701
|
SCHED_JOBS["cron_jobs (recurrence schedules)<br/>───────────────<br/>Recurring schedule definitions<br/>cron_expression: cron or RRULE string<br/>schedule_syntax: 'cron' | 'rrule'<br/>timezone, message, next_run_at<br/>enabled, retry_count<br/>Legacy alias: scheduleJobs"]
|
|
@@ -940,8 +935,7 @@ graph TB
|
|
|
940
935
|
end
|
|
941
936
|
|
|
942
937
|
subgraph "Text Q&A Session"
|
|
943
|
-
TEXT_TOOLS["Tools: sandbox file_* / bash,<br/>host_file_* / host_bash,<br/>ui_show, ...<br/>+ dynamically projected skill tools<br/>(browser_* via bundled browser skill)"]
|
|
944
|
-
ESCALATE["computer_use_request_control<br/>(proxy tool)"]
|
|
938
|
+
TEXT_TOOLS["Tools: sandbox file_* / bash,<br/>host_file_* / host_bash,<br/>ui_show, ...<br/>+ dynamically projected skill tools<br/>(browser_* via bundled browser skill,<br/>computer_use_* via bundled computer-use skill)"]
|
|
945
939
|
end
|
|
946
940
|
|
|
947
941
|
SUBMIT --> SLASH_CHECK
|
|
@@ -953,22 +947,21 @@ graph TB
|
|
|
953
947
|
CLASSIFIER -->|"text_qa"| QA_ROUTE
|
|
954
948
|
|
|
955
949
|
QA_ROUTE --> TEXT_TOOLS
|
|
956
|
-
TEXT_TOOLS -.->|"
|
|
957
|
-
ESCALATE -.->|"Creates CU session<br/>via surfaceProxyResolver"| CU_ROUTE
|
|
950
|
+
TEXT_TOOLS -.->|"computer_use_* actions<br/>forwarded via HostCuProxy"| CU_ROUTE
|
|
958
951
|
```
|
|
959
952
|
|
|
960
953
|
### Action Execution Hierarchy
|
|
961
954
|
|
|
962
955
|
The text_qa system prompt includes an action execution hierarchy that guides tool selection toward the least invasive method:
|
|
963
956
|
|
|
964
|
-
| Priority | Method | Tool
|
|
965
|
-
| --------------- | ------------------------------ |
|
|
966
|
-
| **BEST** | Sandboxed filesystem/shell | `file_*`, `bash`
|
|
967
|
-
| **BETTER** | Explicit host filesystem/shell | `host_file_*`, `host_bash`
|
|
968
|
-
| **GOOD** | Headless browser | `browser_*` (bundled `browser` skill)
|
|
969
|
-
| **LAST RESORT** | Foreground computer use | `
|
|
957
|
+
| Priority | Method | Tool | When to use |
|
|
958
|
+
| --------------- | ------------------------------ | ----------------------------------------------- | ----------------------------------------------------------- |
|
|
959
|
+
| **BEST** | Sandboxed filesystem/shell | `file_*`, `bash` | Work that can stay isolated in sandbox filesystem |
|
|
960
|
+
| **BETTER** | Explicit host filesystem/shell | `host_file_*`, `host_bash` | Host reads/writes/commands that must touch the real machine |
|
|
961
|
+
| **GOOD** | Headless browser | `browser_*` (bundled `browser` skill) | Web automation, form filling, scraping (background) |
|
|
962
|
+
| **LAST RESORT** | Foreground computer use | `computer_use_*` (bundled `computer-use` skill) | Only on explicit user request ("go ahead", "take over") |
|
|
970
963
|
|
|
971
|
-
|
|
964
|
+
Computer-use tools are proxy tools provided by the bundled `computer-use` skill, preactivated via `preactivatedSkillIds` in desktop sessions. Each tool forwards actions to the connected macOS client via `HostCuProxy`, which handles request/resolve proxying, step counting, loop detection, and observation formatting within the unified agent loop. These tools are not core-registered at daemon startup; they exist only through skill projection.
|
|
972
965
|
|
|
973
966
|
### Sandbox Filesystem and Host Access
|
|
974
967
|
|
|
@@ -988,7 +981,7 @@ graph TB
|
|
|
988
981
|
SBPL --> SB_FS["Sandbox filesystem root<br/>~/.vellum/workspace"]
|
|
989
982
|
BWRAP --> SB_FS
|
|
990
983
|
|
|
991
|
-
EXEC -->|"host_file_* / host_bash
|
|
984
|
+
EXEC -->|"host_file_* / host_bash"| HOST_TOOLS["Host-target tools<br/>(unchanged by backend choice)"]
|
|
992
985
|
EXEC -->|"computer_use_* (skill-projected<br/>in CU sessions only)"| SKILL_CU_TOOLS["CU skill tools<br/>(bundled computer-use skill)"]
|
|
993
986
|
HOST_TOOLS --> CHECK["Permission checker + trust-store"]
|
|
994
987
|
SKILL_CU_TOOLS --> CHECK
|
|
@@ -1005,7 +998,7 @@ graph TB
|
|
|
1005
998
|
- **Host tools unchanged**: `host_bash`, `host_file_read`, `host_file_write`, and `host_file_edit` always execute directly on the host regardless of which sandbox backend is active.
|
|
1006
999
|
- Sandbox defaults: `file_*` and `bash` execute within `~/.vellum/workspace`.
|
|
1007
1000
|
- Host access is explicit: `host_file_read`, `host_file_write`, `host_file_edit`, and `host_bash` are separate tools.
|
|
1008
|
-
- Prompt defaults: host tools
|
|
1001
|
+
- Prompt defaults: host tools and `computer_use_*` skill-projected actions default to `ask` unless a trust rule allowlists/denylists them.
|
|
1009
1002
|
- Browser tool defaults: all `browser_*` tools are auto-allowed by default via seeded allow rules at priority 100, preserving the frictionless UX from when browser was a core tool.
|
|
1010
1003
|
- Confirmation payloads include `executionTarget` (`sandbox` or `host`) so clients can label where the action will run.
|
|
1011
1004
|
|
|
@@ -1187,16 +1180,16 @@ skills/<skill-id>/
|
|
|
1187
1180
|
|
|
1188
1181
|
The following capabilities ship as bundled skills in `assistant/src/config/bundled-skills/`:
|
|
1189
1182
|
|
|
1190
|
-
| Skill ID | Tools
|
|
1191
|
-
| --------------- |
|
|
1192
|
-
| `browser` | `browser_navigate`, `browser_snapshot`, `browser_screenshot`, `browser_close`, `browser_click`, `browser_type`, `browser_press_key`, `browser_wait_for`, `browser_extract`, `browser_fill_credential`
|
|
1193
|
-
| `gmail` | Gmail search, archive, send, etc.
|
|
1194
|
-
| `claude-code` | Claude Code tool
|
|
1195
|
-
| `computer-use` | `
|
|
1196
|
-
| `weather` | `get-weather`
|
|
1197
|
-
| `app-builder` | `app_create`, `app_list`, `app_query`, `app_update`, `app_delete`, `app_file_list`, `app_file_read`, `app_file_edit`, `app_file_write`
|
|
1198
|
-
| `self-upgrade` | (instruction-only)
|
|
1199
|
-
| `start-the-day` | (instruction-only)
|
|
1183
|
+
| Skill ID | Tools | Purpose |
|
|
1184
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1185
|
+
| `browser` | `browser_navigate`, `browser_snapshot`, `browser_screenshot`, `browser_close`, `browser_click`, `browser_type`, `browser_press_key`, `browser_wait_for`, `browser_extract`, `browser_fill_credential` | Headless browser automation — web scraping, form filling, interaction (previously core-registered as `headless-browser`; now skill-provided with default allow rules) |
|
|
1186
|
+
| `gmail` | Gmail search, archive, send, etc. | Email management via OAuth2 integration |
|
|
1187
|
+
| `claude-code` | Claude Code tool | Delegate coding tasks to Claude Code subprocess |
|
|
1188
|
+
| `computer-use` | `computer_use_observe`, `computer_use_click`, `computer_use_type_text`, `computer_use_key`, `computer_use_scroll`, `computer_use_drag`, `computer_use_wait`, `computer_use_open_app`, `computer_use_run_applescript`, `computer_use_done`, `computer_use_respond` | Computer-use proxy tools — preactivated via `preactivatedSkillIds` in desktop sessions. Each tool forwards actions to the connected macOS client via `HostCuProxy`, which handles request/resolve proxying, step counting, loop detection, and observation formatting within the unified agent loop. |
|
|
1189
|
+
| `weather` | `get-weather` | Fetch current weather data |
|
|
1190
|
+
| `app-builder` | `app_create`, `app_list`, `app_query`, `app_update`, `app_delete`, `app_file_list`, `app_file_read`, `app_file_edit`, `app_file_write` | Dynamic app authoring — CRUD and file-level editing for persistent apps (activated via `skill_load app-builder`; `app_open` remains a core proxy tool) |
|
|
1191
|
+
| `self-upgrade` | (instruction-only) | Self-improvement workflow |
|
|
1192
|
+
| `start-the-day` | (instruction-only) | Morning briefing routine |
|
|
1200
1193
|
|
|
1201
1194
|
### Activation and Projection Flow
|
|
1202
1195
|
|
|
@@ -1240,7 +1233,7 @@ graph TB
|
|
|
1240
1233
|
RESOLVE --> PROVIDER
|
|
1241
1234
|
```
|
|
1242
1235
|
|
|
1243
|
-
**Internal preactivation**: Some bundled skills are preactivated programmatically rather than by user slash commands or model discovery. For example,
|
|
1236
|
+
**Internal preactivation**: Some bundled skills are preactivated programmatically rather than by user slash commands or model discovery. For example, desktop sessions set `preactivatedSkillIds: ['computer-use']`, causing `projectSkillTools()` to load the 11 `computer_use_*` tool definitions from the bundled skill's `TOOLS.json` on the first turn. These proxy tools forward actions to the connected macOS client via `HostCuProxy`.
|
|
1244
1237
|
|
|
1245
1238
|
### Skill Tool Execution
|
|
1246
1239
|
|
|
@@ -1709,7 +1702,7 @@ graph TB
|
|
|
1709
1702
|
end
|
|
1710
1703
|
|
|
1711
1704
|
subgraph "SSE Transport"
|
|
1712
|
-
SSE_ROUTE["SSE Route<br/>GET /v1/events?conversationKey
|
|
1705
|
+
SSE_ROUTE["SSE Route<br/>GET /v1/events[?conversationKey=...]<br/>(events-routes.ts)<br/>──────────────────────<br/>ReadableStream + CountQueuingStrategy(16)<br/>Heartbeat every 30 s<br/>Slow-consumer shed"]
|
|
1713
1706
|
end
|
|
1714
1707
|
|
|
1715
1708
|
subgraph "Clients"
|
|
@@ -1917,10 +1910,8 @@ Connected channels are resolved at signal emission time: vellum is always includ
|
|
|
1917
1910
|
| User preferences | UserDefaults | plist | Foundation | Permanent |
|
|
1918
1911
|
| Session logs | `~/Library/.../logs/session-*.json` | JSON per session | Swift Codable | Unbounded |
|
|
1919
1912
|
| Conversations & messages | `~/.vellum/workspace/data/db/assistant.db` | SQLite + WAL | Drizzle ORM (Bun) | Permanent |
|
|
1920
|
-
| Memory segments
|
|
1913
|
+
| Memory segments | `~/.vellum/workspace/data/db/assistant.db` | SQLite | Drizzle ORM | Permanent |
|
|
1921
1914
|
| Extracted facts | `~/.vellum/workspace/data/db/assistant.db` | SQLite | Drizzle ORM | Permanent, deduped |
|
|
1922
|
-
| Conflict lifecycle rows | `~/.vellum/workspace/data/db/assistant.db` | SQLite | Drizzle ORM | Pending until clarified, then retained as resolved history |
|
|
1923
|
-
| Entity graph (entities/relations/item links) | `~/.vellum/workspace/data/db/assistant.db` | SQLite | Drizzle ORM | Permanent, deduped by unique relation edge |
|
|
1924
1915
|
| Embeddings | `~/.vellum/workspace/data/db/assistant.db` | JSON float arrays | Drizzle ORM | Permanent |
|
|
1925
1916
|
| Async job queue | `~/.vellum/workspace/data/db/assistant.db` | SQLite | Drizzle ORM | Completed jobs persist |
|
|
1926
1917
|
| Attachments | `~/.vellum/workspace/data/db/assistant.db` | Base64 in SQLite | Drizzle ORM | Permanent |
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ CLI / macOS app / iOS app
|
|
|
16
16
|
│ ├── Google Gemini (secondary)
|
|
17
17
|
│ └── Ollama (local models)
|
|
18
18
|
│
|
|
19
|
-
├── Memory System (
|
|
19
|
+
├── Memory System (Qdrant Hybrid Search)
|
|
20
20
|
├── Skill Tool System (bundled + managed + workspace)
|
|
21
21
|
├── Swarm Orchestration (DAG scheduler + worker pool)
|
|
22
22
|
├── Script Proxy (credential injection + MITM)
|
|
@@ -73,7 +73,6 @@ For low-level development (e.g., working on the assistant runtime itself):
|
|
|
73
73
|
```bash
|
|
74
74
|
bun run src/index.ts daemon start # start daemon only
|
|
75
75
|
bun run src/index.ts # interactive CLI session
|
|
76
|
-
bun run src/index.ts dev # dev mode (auto-restart on file changes)
|
|
77
76
|
```
|
|
78
77
|
|
|
79
78
|
### CLI commands
|
|
@@ -84,7 +83,6 @@ bun run src/index.ts dev # dev mode (auto-restart on file changes)
|
|
|
84
83
|
| `vellum sleep` | Stop assistant + gateway processes |
|
|
85
84
|
| `vellum ps` | List assistants and per-assistant process status |
|
|
86
85
|
| `assistant` | Launch interactive CLI session |
|
|
87
|
-
| `assistant dev` | Run assistant with auto-restart on file changes |
|
|
88
86
|
| `assistant sessions list\|new\|export\|clear` | Manage conversation sessions |
|
|
89
87
|
| `assistant config set\|get\|list` | Manage configuration |
|
|
90
88
|
| `assistant keys set\|list\|delete` | Manage API keys in secure storage |
|
|
@@ -101,7 +99,7 @@ assistant/
|
|
|
101
99
|
│ ├── daemon/ # Daemon server, session management
|
|
102
100
|
│ ├── agent/ # Agent loop and LLM interaction
|
|
103
101
|
│ ├── providers/ # LLM provider integrations (Anthropic, OpenAI, Gemini, Ollama)
|
|
104
|
-
│ ├── memory/ # Conversation store, memory indexer, recall (
|
|
102
|
+
│ ├── memory/ # Conversation store, memory indexer, recall (Qdrant hybrid search)
|
|
105
103
|
│ ├── skills/ # Skill catalog, loading, and tool factory
|
|
106
104
|
│ ├── tools/ # Built-in tool definitions
|
|
107
105
|
│ ├── swarm/ # Swarm orchestration (DAG scheduler, worker pool)
|
|
@@ -241,12 +239,9 @@ The per-assistant mapping is propagated to the gateway via the config file watch
|
|
|
241
239
|
|
|
242
240
|
### Phone Number Resolution Order
|
|
243
241
|
|
|
244
|
-
At runtime, `getTwilioConfig()` resolves the phone number
|
|
242
|
+
At runtime, `getTwilioConfig()` resolves the phone number from **`twilio.phoneNumber` in config** — the primary source of truth, written by `provision_number` and `assign_number`.
|
|
245
243
|
|
|
246
|
-
|
|
247
|
-
2. **`twilio.phoneNumber` in config** — the primary source of truth, written by `provision_number` and `assign_number`.
|
|
248
|
-
|
|
249
|
-
If no number is found after both sources, an error is thrown.
|
|
244
|
+
If no number is found, an error is thrown.
|
|
250
245
|
|
|
251
246
|
### Assistant-Scoped Guardian State
|
|
252
247
|
|
|
@@ -451,7 +446,7 @@ If no guardian binding exists, escalation fails closed — the message is denied
|
|
|
451
446
|
|
|
452
447
|
## Database
|
|
453
448
|
|
|
454
|
-
SQLite via Drizzle ORM, stored at `~/.vellum/workspace/data/db/assistant.db`. Key tables include conversations, messages, tool invocations, attachments, memory segments
|
|
449
|
+
SQLite via Drizzle ORM, stored at `~/.vellum/workspace/data/db/assistant.db`. Key tables include conversations, messages, tool invocations, attachments, memory segments, memory items, reminders, and recurrence schedules (cron + RRULE).
|
|
455
450
|
|
|
456
451
|
> **Note:** The recurrence schedule system supports both cron expressions and iCalendar RRULE syntax. Use the `expression` field with an explicit `syntax` discriminator. See [`docs/architecture/scheduling.md`](docs/architecture/scheduling.md) for details.
|
|
457
452
|
|
|
@@ -476,22 +471,6 @@ docker run --rm -p 3001:3001 \
|
|
|
476
471
|
|
|
477
472
|
The image exposes port `3001` and bundles the `assistant` CLI binary.
|
|
478
473
|
|
|
479
|
-
## Ride Shotgun
|
|
480
|
-
|
|
481
|
-
Ride Shotgun is a background screen-watching feature that observes user workflows. It has two modes:
|
|
482
|
-
|
|
483
|
-
- **Observe mode** — captures periodic screenshots and generates a workflow summary via the LLM.
|
|
484
|
-
- **Learn mode** — records browser network traffic alongside screenshots to capture API patterns. The assistant owns CDP browser lifecycle: `ride-shotgun-handler.ts` calls `ensureChromeWithCdp()` to launch or connect to Chrome with remote debugging, so clients do not need to pre-launch Chrome with `--remote-debugging-port`.
|
|
485
|
-
|
|
486
|
-
Key modules:
|
|
487
|
-
|
|
488
|
-
| File | Purpose |
|
|
489
|
-
| --------------------------------------- | ------------------------------------------------------- |
|
|
490
|
-
| `src/daemon/ride-shotgun-handler.ts` | Session orchestration, CDP bootstrap, network recording |
|
|
491
|
-
| `src/tools/browser/chrome-cdp.ts` | Reusable Chrome CDP launcher (`ensureChromeWithCdp`) |
|
|
492
|
-
| `src/tools/browser/network-recorder.ts` | CDP-based network traffic capture |
|
|
493
|
-
| `src/tools/browser/recording-store.ts` | Session recording persistence |
|
|
494
|
-
|
|
495
474
|
## Troubleshooting
|
|
496
475
|
|
|
497
476
|
### Guardian and gateway-origin issues
|
|
@@ -28,7 +28,7 @@ graph TB
|
|
|
28
28
|
DRAFT["messaging_draft"]
|
|
29
29
|
SENDER_DIGEST["messaging_sender_digest"]
|
|
30
30
|
ARCHIVE_BY_SENDER["messaging_archive_by_sender"]
|
|
31
|
-
SHARED["shared.ts<br/>resolveProvider +
|
|
31
|
+
SHARED["shared.ts<br/>resolveProvider + getProviderConnection"]
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
subgraph "Gmail Skill (bundled-skills/gmail/)"
|
|
@@ -121,7 +121,8 @@ sequenceDiagram
|
|
|
121
121
|
participant OAuth as OAuth2 PKCE Flow
|
|
122
122
|
participant Browser as System Browser
|
|
123
123
|
participant Google as Google OAuth Server
|
|
124
|
-
participant
|
|
124
|
+
participant Store as SQLite OAuth Store
|
|
125
|
+
participant Vault as Secure Keychain
|
|
125
126
|
participant TokenMgr as TokenManager
|
|
126
127
|
participant Tool as Gmail Tool Executor
|
|
127
128
|
participant API as Gmail REST API
|
|
@@ -140,20 +141,25 @@ sequenceDiagram
|
|
|
140
141
|
Google->>OAuth: callback with auth code
|
|
141
142
|
OAuth->>Google: exchange code + code_verifier for tokens
|
|
142
143
|
Google-->>OAuth: access + refresh tokens
|
|
143
|
-
OAuth->>
|
|
144
|
-
|
|
144
|
+
OAuth->>Store: storeOAuth2Tokens() → upsert oauth_app + oauth_connection rows
|
|
145
|
+
Store->>Vault: setSecureKeyAsync("oauth_connection/{id}/access_token")
|
|
146
|
+
Store->>Vault: setSecureKeyAsync("oauth_connection/{id}/refresh_token")
|
|
147
|
+
Store->>Store: write expiresAt, grantedScopes to oauth_connections
|
|
145
148
|
OAuth-->>Handler: success + account email
|
|
146
149
|
Handler->>HTTP: integration_connect_result {success, accountInfo}
|
|
147
150
|
HTTP->>UI: show connected state
|
|
148
151
|
|
|
149
152
|
Note over UI,API: Tool Execution Flow
|
|
150
153
|
Tool->>TokenMgr: withValidToken("gmail", callback)
|
|
151
|
-
TokenMgr->>
|
|
152
|
-
TokenMgr->>Vault:
|
|
154
|
+
TokenMgr->>Store: getConnectionByProvider("integration:gmail")
|
|
155
|
+
TokenMgr->>Vault: getSecureKey("oauth_connection/{conn.id}/access_token")
|
|
156
|
+
TokenMgr->>Store: check oauth_connections.expires_at
|
|
153
157
|
alt Token expired
|
|
158
|
+
TokenMgr->>Store: resolveRefreshConfig() → tokenUrl, clientId from provider/app rows
|
|
154
159
|
TokenMgr->>Google: refresh with refresh_token
|
|
155
160
|
Google-->>TokenMgr: new access token
|
|
156
|
-
TokenMgr->>Vault:
|
|
161
|
+
TokenMgr->>Vault: setSecureKeyAsync("oauth_connection/{id}/access_token")
|
|
162
|
+
TokenMgr->>Store: updateConnection(expiresAt)
|
|
157
163
|
end
|
|
158
164
|
TokenMgr->>Tool: callback(validToken)
|
|
159
165
|
Tool->>API: Gmail REST API call with Bearer token
|
|
@@ -167,13 +173,13 @@ sequenceDiagram
|
|
|
167
173
|
|
|
168
174
|
| Decision | Rationale |
|
|
169
175
|
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
170
|
-
| PKCE by default, optional client_secret | Desktop apps prefer PKCE; some providers (Slack) require a secret, which is stored in
|
|
176
|
+
| PKCE by default, optional client_secret | Desktop apps prefer PKCE; some providers (Slack) require a secret, which is stored in the secure keychain (`oauth_app/{id}/client_secret`) for autonomous refresh |
|
|
171
177
|
| Shared connect orchestrator | All OAuth providers route through `orchestrateOAuthConnect()`, which resolves profiles, enforces scope policy, runs the flow, stores tokens, and verifies identity. Adding a provider is a declarative profile entry, not new orchestration code |
|
|
172
178
|
| Canonical credential naming | All reads and writes use `client_id`/`client_secret` as canonical field names |
|
|
173
179
|
| Gateway callback transport | OAuth callbacks are now routed through the gateway at `${ingress.publicBaseUrl}/webhooks/oauth/callback` instead of a loopback redirect URI. This enables OAuth flows to work in remote and tunneled deployments. |
|
|
174
180
|
| Unified `MessagingProvider` interface | All platforms implement the same contract; generic tools work immediately for new providers |
|
|
175
181
|
| Provider auto-selection | If only one provider is connected, tools skip the `platform` parameter — seamless single-platform UX |
|
|
176
|
-
| Token expiry in
|
|
182
|
+
| Token expiry in SQLite oauth-store | `oauth_connections.expires_at` column tracks token expiry; `TokenManager` reads it for proactive refresh with 5min buffer. No separate metadata store needed |
|
|
177
183
|
| Confidence scores on medium-risk tools | LLM self-reports confidence (0-1); enables future trust calibration without blocking execution |
|
|
178
184
|
| Platform-specific extension tools | Operations unique to one platform (e.g. Gmail labels, Slack reactions) are separate tools, not forced into the generic interface |
|
|
179
185
|
| Identity verification before token storage | OAuth2 tokens are only persisted after a successful identity verification call, preventing storage of invalid or mismatched credentials |
|
|
@@ -197,34 +203,32 @@ sequenceDiagram
|
|
|
197
203
|
| `assistant/src/watcher/providers/gmail.ts` | Gmail watcher using History API |
|
|
198
204
|
| `assistant/src/watcher/providers/github.ts` | GitHub watcher for PRs, issues, review requests, and mentions |
|
|
199
205
|
| `assistant/src/watcher/providers/linear.ts` | Linear watcher for assigned issues, status changes, and @mentions |
|
|
200
|
-
| `assistant/src/oauth/provider-
|
|
206
|
+
| `assistant/src/oauth/provider-behaviors.ts` | Provider behavior registry: identity verifiers, setup metadata, injection templates |
|
|
201
207
|
| `assistant/src/oauth/connect-orchestrator.ts` | Shared OAuth connect orchestrator: profile resolution, scope policy, flow execution, token storage |
|
|
202
208
|
| `assistant/src/oauth/scope-policy.ts` | Deterministic scope resolution and policy enforcement |
|
|
203
|
-
| `assistant/src/oauth/connect-types.ts` | Shared types: `
|
|
209
|
+
| `assistant/src/oauth/connect-types.ts` | Shared types: `OAuthProviderBehavior`, `OAuthScopePolicy`, `OAuthConnectResult` |
|
|
204
210
|
| `assistant/src/oauth/token-persistence.ts` | Token storage helper: persists tokens, metadata, and runs post-connect hooks |
|
|
205
211
|
| `assistant/src/daemon/handlers/oauth-connect.ts` | Generic OAuth connect handler (`oauth_connect_start` / `oauth_connect_result`) |
|
|
206
212
|
|
|
207
213
|
---
|
|
208
214
|
|
|
209
|
-
## OAuth Extensibility — Provider
|
|
215
|
+
## OAuth Extensibility — Provider Behaviors, Scope Policy, and Connect Orchestrator
|
|
210
216
|
|
|
211
|
-
The OAuth extensibility layer makes adding a new OAuth provider a declarative operation.
|
|
217
|
+
The OAuth extensibility layer makes adding a new OAuth provider a declarative operation. Protocol fields (auth URLs, token URLs, scopes, scope policy) are stored in the `oauth_providers` database table, while behavioral fields (identity verifiers, setup metadata, injection templates) live in the **provider behavior registry**. The shared **connect orchestrator** handles the full flow from provider resolution through token storage.
|
|
212
218
|
|
|
213
|
-
### Provider
|
|
219
|
+
### Provider Behavior Registry
|
|
214
220
|
|
|
215
|
-
`assistant/src/oauth/provider-
|
|
221
|
+
`assistant/src/oauth/provider-behaviors.ts` contains the `PROVIDER_BEHAVIORS` map — a registry of behavioral aspects for well-known OAuth providers. Each behavior (`OAuthProviderBehavior`) declares:
|
|
216
222
|
|
|
217
|
-
| Field
|
|
218
|
-
|
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `callbackTransport` | `'loopback'` (local redirect) or `'gateway'` (public ingress) |
|
|
223
|
-
| `identityVerifier` | Async function that fetches human-readable account info (e.g. `@username`, email) after token exchange |
|
|
224
|
-
| `setup` | Optional metadata for the generic OAuth setup skill (display name, dashboard URL, app type) |
|
|
225
|
-
| `injectionTemplates` | Auto-applied credential injection rules for the script proxy |
|
|
223
|
+
| Field | Purpose |
|
|
224
|
+
| -------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
225
|
+
| `identityVerifier` | Async function that fetches human-readable account info (e.g. `@username`, email) after token exchange |
|
|
226
|
+
| `setup` | Optional metadata for the generic OAuth setup skill (display name, dashboard URL, app type) |
|
|
227
|
+
| `injectionTemplates` | Auto-applied credential injection rules for the script proxy |
|
|
226
228
|
|
|
227
|
-
|
|
229
|
+
Protocol fields (`authUrl`, `tokenUrl`, `defaultScopes`, `scopePolicy`, `callbackTransport`) are stored in the `oauth_providers` database table rather than in code.
|
|
230
|
+
|
|
231
|
+
Registered providers: `integration:gmail`, `integration:slack`, `integration:notion`. Short aliases (e.g. `gmail`, `slack`) are resolved via `resolveService()`.
|
|
228
232
|
|
|
229
233
|
### Scope Policy Engine
|
|
230
234
|
|
|
@@ -244,9 +248,9 @@ Returns `{ ok: true, scopes }` or `{ ok: false, error, allowedScopes }`.
|
|
|
244
248
|
`assistant/src/oauth/connect-orchestrator.ts` exports `orchestrateOAuthConnect(options)`, which runs the full OAuth2 flow:
|
|
245
249
|
|
|
246
250
|
1. **Resolve service** — alias expansion via `resolveService()`.
|
|
247
|
-
2. **Load
|
|
251
|
+
2. **Load behavior** — `getProviderBehavior()` from the registry; load protocol fields from the `oauth_providers` DB table.
|
|
248
252
|
3. **Compute scopes** — `resolveScopes()` with scope policy enforcement.
|
|
249
|
-
4. **Build OAuth config** —
|
|
253
|
+
4. **Build OAuth config** — assemble protocol-level config from the DB provider row.
|
|
250
254
|
5. **Run flow** — interactive (opens browser, blocks until completion) or deferred (returns auth URL for the caller to deliver).
|
|
251
255
|
6. **Verify identity** — runs the profile's `identityVerifier` if defined.
|
|
252
256
|
7. **Store tokens** — `storeOAuth2Tokens()` persists access/refresh tokens, client credentials, and metadata.
|
|
@@ -266,24 +270,24 @@ This replaces provider-specific handlers — any provider in the registry can be
|
|
|
266
270
|
|
|
267
271
|
### Adding a New OAuth Provider
|
|
268
272
|
|
|
269
|
-
1. **
|
|
273
|
+
1. **Register protocol fields** in the `oauth_providers` database table (via CLI or migration):
|
|
270
274
|
- Set `authUrl`, `tokenUrl`, `defaultScopes`, `scopePolicy`, and `callbackTransport`.
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
275
|
+
2. **Optional: declare behavioral fields** in `PROVIDER_BEHAVIORS` (`oauth/provider-behaviors.ts`):
|
|
276
|
+
- Add an `identityVerifier` — an async function that fetches the user's account info from the provider's API.
|
|
277
|
+
- Add `setup` metadata — `displayName`, `dashboardUrl`, `appType` enable the generic OAuth setup skill to guide users through app creation.
|
|
278
|
+
- Add `injectionTemplates` — for providers whose tokens should be auto-injected by the script proxy.
|
|
279
|
+
3. **No handler code needed** — the generic `oauth_connect_start` handler and the connect orchestrator handle the flow automatically.
|
|
276
280
|
|
|
277
281
|
### Key Source Files
|
|
278
282
|
|
|
279
|
-
| File | Role
|
|
280
|
-
| ------------------------------------------------ |
|
|
281
|
-
| `assistant/src/oauth/provider-
|
|
282
|
-
| `assistant/src/oauth/scope-policy.ts` | Scope resolution and policy enforcement (pure, no I/O)
|
|
283
|
-
| `assistant/src/oauth/connect-orchestrator.ts` | Shared connect orchestrator (profile → scopes → flow → tokens)
|
|
284
|
-
| `assistant/src/oauth/connect-types.ts` | Shared types (`
|
|
285
|
-
| `assistant/src/oauth/token-persistence.ts` | Token storage: keychain writes, metadata upsert, post-connect hooks
|
|
286
|
-
| `assistant/src/daemon/handlers/oauth-connect.ts` | Generic `oauth_connect_start` / `oauth_connect_result` handler
|
|
283
|
+
| File | Role |
|
|
284
|
+
| ------------------------------------------------ | -------------------------------------------------------------------------------- |
|
|
285
|
+
| `assistant/src/oauth/provider-behaviors.ts` | Provider behavior registry and alias resolution |
|
|
286
|
+
| `assistant/src/oauth/scope-policy.ts` | Scope resolution and policy enforcement (pure, no I/O) |
|
|
287
|
+
| `assistant/src/oauth/connect-orchestrator.ts` | Shared connect orchestrator (profile → scopes → flow → tokens) |
|
|
288
|
+
| `assistant/src/oauth/connect-types.ts` | Shared types (`OAuthProviderBehavior`, `OAuthScopePolicy`, `OAuthConnectResult`) |
|
|
289
|
+
| `assistant/src/oauth/token-persistence.ts` | Token storage: keychain writes, metadata upsert, post-connect hooks |
|
|
290
|
+
| `assistant/src/daemon/handlers/oauth-connect.ts` | Generic `oauth_connect_start` / `oauth_connect_result` handler |
|
|
287
291
|
|
|
288
292
|
---
|
|
289
293
|
|
|
@@ -66,7 +66,7 @@ graph LR
|
|
|
66
66
|
### Transport
|
|
67
67
|
|
|
68
68
|
- Unix domain socket: `~/.vellum/keychain-broker.sock`
|
|
69
|
-
- Socket path is
|
|
69
|
+
- Socket path is derived from the data directory (e.g., `join(getRootDir(), "keychain-broker.sock")`)
|
|
70
70
|
- Newline-delimited JSON (`\n` as message boundary)
|
|
71
71
|
|
|
72
72
|
### Request envelope
|
|
@@ -157,8 +157,8 @@ XPC provides stronger caller identity guarantees via audit tokens and code requi
|
|
|
157
157
|
|
|
158
158
|
## Developer Experience
|
|
159
159
|
|
|
160
|
-
- **Debug builds:** The `#if !DEBUG` guard compiles out the entire `KeychainBrokerServer`. The
|
|
161
|
-
- **Release builds:** The broker starts automatically with the app. The daemon discovers
|
|
160
|
+
- **Debug builds:** The `#if !DEBUG` guard compiles out the entire `KeychainBrokerServer`. The broker socket is not created, so clients see the broker as unavailable and use the encrypted store. Developers never encounter keychain prompts during the edit-build-run cycle.
|
|
161
|
+
- **Release builds:** The broker starts automatically with the app. The daemon discovers the broker via the derived socket path (`join(getRootDir(), "keychain-broker.sock")`) and token file. No configuration needed.
|
|
162
162
|
- **CLI-only / headless:** No macOS app means no broker socket. All storage uses the encrypted file store. This is the expected path for CI, servers, and non-macOS platforms.
|
|
163
163
|
|
|
164
164
|
## Callsite Policy
|