@vellumai/assistant 0.5.5 → 0.5.7
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/.env.example +16 -2
- package/ARCHITECTURE.md +6 -75
- package/Dockerfile +4 -5
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/security.md +0 -17
- package/docs/credential-execution-service.md +2 -2
- package/node_modules/@vellumai/ces-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
- package/node_modules/@vellumai/credential-storage/package.json +1 -0
- package/node_modules/@vellumai/egress-proxy/package.json +1 -0
- package/package.json +2 -3
- package/src/__tests__/actor-token-service.test.ts +1 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -5
- package/src/__tests__/channel-readiness-service.test.ts +1 -60
- package/src/__tests__/checker.test.ts +4 -2
- package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +3 -3
- package/src/__tests__/context-window-manager.test.ts +78 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-title-service.test.ts +117 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
- package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
- package/src/__tests__/credential-security-e2e.test.ts +0 -66
- package/src/__tests__/credential-security-invariants.test.ts +4 -45
- package/src/__tests__/credentials-cli.test.ts +78 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +98 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/guardian-routing-state.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +6 -7
- package/src/__tests__/http-user-message-parity.test.ts +3 -103
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
- package/src/__tests__/intent-routing.test.ts +0 -13
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/memory-regressions.test.ts +8 -30
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-import-commit-http.test.ts +2 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
- package/src/__tests__/migration-validate-http.test.ts +2 -2
- package/src/__tests__/non-member-access-request.test.ts +0 -5
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/require-fresh-approval.test.ts +4 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +83 -263
- package/src/__tests__/shell-identity.test.ts +96 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
- package/src/__tests__/skill-feature-flags.test.ts +46 -45
- package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
- package/src/__tests__/skill-load-inline-command.test.ts +8 -12
- package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
- package/src/__tests__/skill-load-tool.test.ts +0 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
- package/src/__tests__/skills.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +0 -4
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/tool-executor.test.ts +4 -0
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +85 -7
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +117 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/twilio-routes.ts +2 -1
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +26 -5
- package/src/calls/voice-session-bridge.ts +6 -12
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/conversations.ts +0 -18
- package/src/cli/commands/credentials.ts +34 -4
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +179 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-tool-registry.ts +1 -11
- package/src/config/env-registry.ts +1 -1
- package/src/config/env.ts +16 -16
- package/src/config/feature-flag-registry.json +48 -16
- package/src/config/loader.ts +98 -31
- package/src/config/schema.ts +4 -25
- package/src/config/schemas/calls.ts +13 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/memory.ts +0 -4
- package/src/config/schemas/platform.ts +1 -1
- package/src/config/schemas/security.ts +4 -4
- package/src/config/types.ts +0 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- package/src/context/window-manager.ts +53 -2
- package/src/credential-execution/approval-bridge.ts +1 -0
- package/src/credential-execution/executable-discovery.ts +28 -4
- package/src/credential-execution/feature-gates.ts +16 -0
- package/src/credential-execution/process-manager.ts +38 -0
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +6 -4
- package/src/daemon/conversation-agent-loop.ts +0 -60
- package/src/daemon/conversation-memory.ts +0 -117
- package/src/daemon/conversation-runtime-assembly.ts +0 -2
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +10 -1
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/conversations.ts +0 -11
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +229 -96
- package/src/daemon/message-types/conversations.ts +3 -4
- package/src/daemon/message-types/diagnostics.ts +3 -22
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/message-types/upgrades.ts +8 -0
- package/src/daemon/server.ts +30 -92
- package/src/events/domain-events.ts +2 -1
- package/src/followups/followup-store.ts +5 -2
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/conversation-crud.ts +0 -236
- package/src/memory/conversation-title-service.ts +76 -11
- package/src/memory/db-init.ts +15 -11
- package/src/memory/indexer.ts +15 -106
- package/src/memory/items-extractor.ts +15 -1
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/job-handlers/embedding.ts +0 -79
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +30 -13
- package/src/memory/jobs-worker.ts +31 -27
- package/src/memory/migrations/001-job-deferrals.ts +19 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
- package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
- package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
- package/src/memory/migrations/116-messages-fts.ts +106 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
- package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
- package/src/memory/migrations/141-rename-verification-table.ts +54 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
- package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
- package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
- package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
- package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
- package/src/memory/migrations/189-drop-simplified-memory.ts +42 -0
- package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
- package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
- package/src/memory/migrations/index.ts +5 -3
- package/src/memory/migrations/registry.ts +90 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-client.ts +4 -6
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/conversations.ts +0 -3
- package/src/memory/schema/index.ts +0 -2
- package/src/messaging/draft-store.ts +2 -2
- package/src/notifications/decision-engine.ts +4 -1
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/defaults.ts +3 -3
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/trust-client.ts +2 -13
- package/src/permissions/trust-store.ts +8 -3
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/persona-resolver.ts +138 -0
- package/src/prompts/system-prompt.ts +36 -4
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/registry.ts +27 -40
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +29 -1
- package/src/runtime/auth/token-service.ts +53 -15
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/http-server.ts +29 -2
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/conversation-management-routes.ts +0 -36
- package/src/runtime/routes/conversation-query-routes.ts +106 -2
- package/src/runtime/routes/conversation-routes.ts +4 -43
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/identity-routes.ts +18 -29
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
- package/src/runtime/routes/integrations/vercel.ts +89 -0
- package/src/runtime/routes/log-export-routes.ts +5 -0
- package/src/runtime/routes/memory-item-routes.test.ts +221 -3
- package/src/runtime/routes/memory-item-routes.ts +144 -4
- package/src/runtime/routes/migration-rollback-routes.ts +209 -0
- package/src/runtime/routes/migration-routes.ts +17 -1
- package/src/runtime/routes/notification-routes.ts +58 -0
- package/src/runtime/routes/schedule-routes.ts +65 -0
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +86 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +175 -0
- package/src/runtime/routes/workspace-commit-routes.ts +62 -0
- package/src/runtime/routes/workspace-routes.test.ts +22 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +86 -2
- package/src/schedule/schedule-store.ts +0 -21
- package/src/security/ces-credential-client.ts +59 -22
- package/src/security/ces-rpc-credential-backend.ts +85 -0
- package/src/security/credential-backend.ts +12 -88
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +94 -113
- package/src/skills/catalog-install.ts +13 -7
- package/src/skills/inline-command-render.ts +5 -1
- package/src/skills/inline-command-runner.ts +30 -2
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/executor.ts +0 -4
- package/src/tools/memory/handlers.ts +1 -129
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/permission-checker.ts +18 -0
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/load.ts +9 -2
- package/src/tools/types.ts +0 -8
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +8 -55
- package/src/util/xml.ts +8 -0
- package/src/workspace/git-service.ts +5 -2
- package/src/workspace/heartbeat-service.ts +5 -24
- package/src/workspace/migrations/001-avatar-rename.ts +15 -0
- package/src/workspace/migrations/003-seed-device-id.ts +17 -1
- package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
- package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
- package/src/workspace/migrations/006-services-config.ts +49 -0
- package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/__tests__/archive-recall.test.ts +0 -560
- package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
- package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
- package/src/__tests__/conversation-memory-dirty-tail.test.ts +0 -150
- package/src/__tests__/conversation-switch-memory-reduction.test.ts +0 -474
- package/src/__tests__/db-memory-archive-migration.test.ts +0 -372
- package/src/__tests__/db-memory-brief-state-migration.test.ts +0 -213
- package/src/__tests__/db-memory-reducer-checkpoints.test.ts +0 -273
- package/src/__tests__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/memory-brief-open-loops.test.ts +0 -530
- package/src/__tests__/memory-brief-time.test.ts +0 -285
- package/src/__tests__/memory-brief-wrapper.test.ts +0 -311
- package/src/__tests__/memory-chunk-archive.test.ts +0 -400
- package/src/__tests__/memory-chunk-dual-write.test.ts +0 -453
- package/src/__tests__/memory-episode-archive.test.ts +0 -370
- package/src/__tests__/memory-episode-dual-write.test.ts +0 -626
- package/src/__tests__/memory-observation-archive.test.ts +0 -375
- package/src/__tests__/memory-observation-dual-write.test.ts +0 -318
- package/src/__tests__/memory-reducer-job.test.ts +0 -538
- package/src/__tests__/memory-reducer-scheduling.test.ts +0 -473
- package/src/__tests__/memory-reducer-store.test.ts +0 -728
- package/src/__tests__/memory-reducer-types.test.ts +0 -707
- package/src/__tests__/memory-reducer.test.ts +0 -704
- package/src/__tests__/memory-simplified-config.test.ts +0 -281
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- package/src/__tests__/simplified-memory-e2e.test.ts +0 -666
- package/src/__tests__/simplified-memory-runtime.test.ts +0 -616
- package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
- package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
- package/src/__tests__/swarm-orchestrator.test.ts +0 -463
- package/src/__tests__/swarm-plan-validator.test.ts +0 -384
- package/src/__tests__/swarm-recursion.test.ts +0 -197
- package/src/__tests__/swarm-router-planner.test.ts +0 -234
- package/src/__tests__/swarm-tool.test.ts +0 -185
- package/src/__tests__/swarm-worker-backend.test.ts +0 -144
- package/src/__tests__/swarm-worker-runner.test.ts +0 -288
- package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
- package/src/commands/cc-command-registry.ts +0 -248
- package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
- package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
- package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
- package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
- package/src/config/schemas/memory-simplified.ts +0 -101
- package/src/config/schemas/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/memory/archive-recall.ts +0 -516
- package/src/memory/archive-store.ts +0 -400
- package/src/memory/brief-formatting.ts +0 -33
- package/src/memory/brief-open-loops.ts +0 -266
- package/src/memory/brief-time.ts +0 -162
- package/src/memory/brief.ts +0 -75
- package/src/memory/job-handlers/backfill-simplified-memory.ts +0 -462
- package/src/memory/job-handlers/reduce-conversation-memory.ts +0 -229
- package/src/memory/migrations/185-memory-brief-state.ts +0 -52
- package/src/memory/migrations/186-memory-archive.ts +0 -109
- package/src/memory/migrations/187-memory-reducer-checkpoints.ts +0 -19
- package/src/memory/reducer-scheduler.ts +0 -242
- package/src/memory/reducer-store.ts +0 -271
- package/src/memory/reducer-types.ts +0 -106
- package/src/memory/reducer.ts +0 -467
- package/src/memory/schema/memory-archive.ts +0 -121
- package/src/memory/schema/memory-brief.ts +0 -55
- package/src/runtime/local-gateway-health.ts +0 -275
- package/src/security/secret-ingress.ts +0 -68
- package/src/swarm/backend-claude-code.ts +0 -225
- package/src/swarm/checkpoint.ts +0 -137
- package/src/swarm/graph-utils.ts +0 -53
- package/src/swarm/index.ts +0 -55
- package/src/swarm/limits.ts +0 -66
- package/src/swarm/orchestrator.ts +0 -424
- package/src/swarm/plan-validator.ts +0 -117
- package/src/swarm/router-planner.ts +0 -162
- package/src/swarm/router-prompts.ts +0 -39
- package/src/swarm/synthesizer.ts +0 -81
- package/src/swarm/types.ts +0 -72
- package/src/swarm/worker-backend.ts +0 -131
- package/src/swarm/worker-prompts.ts +0 -80
- package/src/swarm/worker-runner.ts +0 -170
- package/src/tools/claude-code/claude-code.ts +0 -610
- package/src/tools/swarm/delegate.ts +0 -205
|
@@ -33,7 +33,9 @@ export function recoverCrashedMigrations(database: DrizzleDb): string[] {
|
|
|
33
33
|
return [];
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
const crashed = rows
|
|
36
|
+
const crashed = rows
|
|
37
|
+
.filter((r) => r.value === "started" || r.value === "rolling_back")
|
|
38
|
+
.map((r) => r.key);
|
|
37
39
|
if (crashed.length === 0) return [];
|
|
38
40
|
|
|
39
41
|
log.error(
|
|
@@ -83,7 +85,12 @@ export function withCrashRecovery(
|
|
|
83
85
|
const existing = raw
|
|
84
86
|
.query(`SELECT value FROM memory_checkpoints WHERE key = ?`)
|
|
85
87
|
.get(checkpointKey) as { value: string } | null;
|
|
86
|
-
if (
|
|
88
|
+
if (
|
|
89
|
+
existing &&
|
|
90
|
+
existing.value !== "started" &&
|
|
91
|
+
existing.value !== "rolling_back"
|
|
92
|
+
)
|
|
93
|
+
return;
|
|
87
94
|
|
|
88
95
|
raw
|
|
89
96
|
.query(
|
|
@@ -126,12 +133,14 @@ export function validateMigrationState(
|
|
|
126
133
|
.all() as Array<{ key: string; value: string }>;
|
|
127
134
|
} catch {
|
|
128
135
|
// memory_checkpoints may not exist on a very old database; skip.
|
|
129
|
-
return { crashed: [], dependencyViolations: [] };
|
|
136
|
+
return { crashed: [], dependencyViolations: [], unknownCheckpoints: [] };
|
|
130
137
|
}
|
|
131
138
|
|
|
132
|
-
// Any remaining 'started' checkpoints after recovery +
|
|
133
|
-
// indicate a migration that was retried but failed again.
|
|
134
|
-
const crashed = rows
|
|
139
|
+
// Any remaining 'started' or 'rolling_back' checkpoints after recovery +
|
|
140
|
+
// migration execution indicate a migration that was retried but failed again.
|
|
141
|
+
const crashed = rows
|
|
142
|
+
.filter((r) => r.value === "started" || r.value === "rolling_back")
|
|
143
|
+
.map((r) => r.key);
|
|
135
144
|
if (crashed.length > 0) {
|
|
136
145
|
log.error(
|
|
137
146
|
{ crashed },
|
|
@@ -149,11 +158,14 @@ export function validateMigrationState(
|
|
|
149
158
|
);
|
|
150
159
|
}
|
|
151
160
|
|
|
152
|
-
// Only rows whose value is NOT 'started' represent truly
|
|
153
|
-
// In-progress/crashed checkpoints
|
|
154
|
-
// dependencies — the migration never finished, so its postconditions
|
|
161
|
+
// Only rows whose value is NOT 'started' or 'rolling_back' represent truly
|
|
162
|
+
// completed migrations. In-progress/crashed checkpoints must not count as
|
|
163
|
+
// applied dependencies — the migration never finished, so its postconditions
|
|
164
|
+
// are unmet.
|
|
155
165
|
const completed = new Set(
|
|
156
|
-
rows
|
|
166
|
+
rows
|
|
167
|
+
.filter((r) => r.value !== "started" && r.value !== "rolling_back")
|
|
168
|
+
.map((r) => r.key),
|
|
157
169
|
);
|
|
158
170
|
|
|
159
171
|
const dependencyViolations: Array<{
|
|
@@ -191,5 +203,119 @@ export function validateMigrationState(
|
|
|
191
203
|
);
|
|
192
204
|
}
|
|
193
205
|
|
|
194
|
-
|
|
206
|
+
// Detect checkpoints that exist in the database but have no corresponding
|
|
207
|
+
// registry entry — these are from a newer version of the daemon.
|
|
208
|
+
//
|
|
209
|
+
// The memory_checkpoints table is a general-purpose key-value store also
|
|
210
|
+
// used by non-migration subsystems (e.g., "identity:intro:text",
|
|
211
|
+
// "conversation_starters:item_count_at_last_gen"). Filter to only keys
|
|
212
|
+
// that follow migration naming conventions before comparing against the
|
|
213
|
+
// registry to avoid false-positive warnings.
|
|
214
|
+
const registryKeys = new Set(MIGRATION_REGISTRY.map((e) => e.key));
|
|
215
|
+
const isMigrationKey = (k: string): boolean =>
|
|
216
|
+
k.startsWith("migration_") ||
|
|
217
|
+
k.startsWith("backfill_") ||
|
|
218
|
+
k.startsWith("drop_");
|
|
219
|
+
const unknownCheckpoints = [...completed].filter(
|
|
220
|
+
(k) => isMigrationKey(k) && !registryKeys.has(k),
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
if (unknownCheckpoints.length > 0) {
|
|
224
|
+
log.warn(
|
|
225
|
+
{ unknownCheckpoints },
|
|
226
|
+
`Database contains ${unknownCheckpoints.length} migration checkpoint(s) from a newer version. Data may be incompatible.`,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return { crashed, dependencyViolations, unknownCheckpoints };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Roll back all completed memory (database) migrations with version > targetVersion.
|
|
235
|
+
*
|
|
236
|
+
* Iterates eligible migrations in reverse version order. For each:
|
|
237
|
+
* 1. Marks the checkpoint as `"rolling_back"` for crash recovery.
|
|
238
|
+
* 2. Calls `entry.down(database)` — each down() manages its own transactions.
|
|
239
|
+
* (`down` is required on `MigrationRegistryEntry` at the type level.)
|
|
240
|
+
* 3. Deletes the checkpoint from `memory_checkpoints`.
|
|
241
|
+
*
|
|
242
|
+
* **Usage**: Pass the target version number you want to roll back *to*. All
|
|
243
|
+
* migrations with a higher version number that have been applied will be
|
|
244
|
+
* reversed. For example, `rollbackMemoryMigration(db, 5)` rolls back all
|
|
245
|
+
* applied migrations with version > 5.
|
|
246
|
+
*
|
|
247
|
+
* **Checkpoint state**: Each rolled-back migration's checkpoint is deleted
|
|
248
|
+
* from `memory_checkpoints`. If the process crashes mid-rollback, the
|
|
249
|
+
* `"rolling_back"` marker is detected and cleared by
|
|
250
|
+
* `recoverCrashedMigrations` on the next startup.
|
|
251
|
+
*
|
|
252
|
+
* **Warning — data loss**: Some down() migrations may not fully restore the
|
|
253
|
+
* original state (e.g., DROP TABLE migrations recreate the table but cannot
|
|
254
|
+
* recover the original data). Review each migration's down() implementation
|
|
255
|
+
* before calling this function programmatically.
|
|
256
|
+
*
|
|
257
|
+
* **Important**: Stop the assistant before running rollbacks. Rolling back
|
|
258
|
+
* migrations while the assistant is running may cause schema mismatches,
|
|
259
|
+
* query failures, or data corruption.
|
|
260
|
+
*
|
|
261
|
+
* @param database The Drizzle database instance.
|
|
262
|
+
* @param targetVersion Roll back to this version (exclusive — all migrations
|
|
263
|
+
* with version > targetVersion are reversed).
|
|
264
|
+
* @returns The list of rolled-back migration keys.
|
|
265
|
+
*/
|
|
266
|
+
export function rollbackMemoryMigration(
|
|
267
|
+
database: DrizzleDb,
|
|
268
|
+
targetVersion: number,
|
|
269
|
+
): string[] {
|
|
270
|
+
const raw = getSqliteFrom(database);
|
|
271
|
+
|
|
272
|
+
// Read completed checkpoints to determine which migrations have been applied.
|
|
273
|
+
let rows: Array<{ key: string; value: string }>;
|
|
274
|
+
try {
|
|
275
|
+
rows = raw
|
|
276
|
+
.query(`SELECT key, value FROM memory_checkpoints`)
|
|
277
|
+
.all() as Array<{ key: string; value: string }>;
|
|
278
|
+
} catch {
|
|
279
|
+
return [];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const completedKeys = new Set(
|
|
283
|
+
rows
|
|
284
|
+
.filter((r) => r.value !== "started" && r.value !== "rolling_back")
|
|
285
|
+
.map((r) => r.key),
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
// Find registry entries with version > targetVersion that have completed checkpoints.
|
|
289
|
+
const toRollback = MIGRATION_REGISTRY.filter(
|
|
290
|
+
(entry) => entry.version > targetVersion && completedKeys.has(entry.key),
|
|
291
|
+
).sort((a, b) => b.version - a.version); // reverse version order
|
|
292
|
+
|
|
293
|
+
const rolledBack: string[] = [];
|
|
294
|
+
|
|
295
|
+
for (const entry of toRollback) {
|
|
296
|
+
// Mark as rolling_back for crash recovery — if the process crashes here,
|
|
297
|
+
// recoverCrashedMigrations will clear this checkpoint on next startup.
|
|
298
|
+
raw
|
|
299
|
+
.query(
|
|
300
|
+
`UPDATE memory_checkpoints SET value = 'rolling_back', updated_at = ? WHERE key = ?`,
|
|
301
|
+
)
|
|
302
|
+
.run(Date.now(), entry.key);
|
|
303
|
+
|
|
304
|
+
// Execute the down migration — let it manage its own transaction lifecycle.
|
|
305
|
+
// Many down() functions call BEGIN/COMMIT internally or use PRAGMA statements
|
|
306
|
+
// that are no-ops inside a transaction.
|
|
307
|
+
entry.down(database);
|
|
308
|
+
|
|
309
|
+
// Delete the checkpoint after down() succeeds — outside any transaction
|
|
310
|
+
// so it's not affected by down()'s internal transaction management.
|
|
311
|
+
raw.query(`DELETE FROM memory_checkpoints WHERE key = ?`).run(entry.key);
|
|
312
|
+
|
|
313
|
+
log.info(
|
|
314
|
+
{ key: entry.key, version: entry.version },
|
|
315
|
+
`Rolled back migration "${entry.key}" (version ${entry.version})`,
|
|
316
|
+
);
|
|
317
|
+
rolledBack.push(entry.key);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return rolledBack;
|
|
195
321
|
}
|
|
@@ -101,6 +101,15 @@ export function isQdrantBreakerOpen(): boolean {
|
|
|
101
101
|
return breakerState !== "closed";
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Returns true when the breaker is open and the cooldown has elapsed,
|
|
106
|
+
* meaning the next call to `withQdrantBreaker` will transition to half-open.
|
|
107
|
+
* Use this to allow a single probe job through when embed jobs are otherwise skipped.
|
|
108
|
+
*/
|
|
109
|
+
export function shouldAllowQdrantProbe(): boolean {
|
|
110
|
+
return breakerState === "open" && Date.now() - openedAt >= COOLDOWN_MS;
|
|
111
|
+
}
|
|
112
|
+
|
|
104
113
|
/** @internal Test-only: reset circuit breaker state */
|
|
105
114
|
export function _resetQdrantBreaker(): void {
|
|
106
115
|
breakerState = "closed";
|
|
@@ -20,7 +20,7 @@ export interface QdrantClientConfig {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface QdrantPointPayload {
|
|
23
|
-
target_type: "segment" | "item" | "summary" | "
|
|
23
|
+
target_type: "segment" | "item" | "summary" | "media";
|
|
24
24
|
target_id: string;
|
|
25
25
|
text: string;
|
|
26
26
|
kind?: string;
|
|
@@ -230,7 +230,7 @@ export class VellumQdrantClient {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
async upsert(
|
|
233
|
-
targetType: "segment" | "item" | "summary" | "
|
|
233
|
+
targetType: "segment" | "item" | "summary" | "media",
|
|
234
234
|
targetId: string,
|
|
235
235
|
vector: number[],
|
|
236
236
|
payload: Omit<QdrantPointPayload, "target_type" | "target_id">,
|
|
@@ -324,9 +324,7 @@ export class VellumQdrantClient {
|
|
|
324
324
|
async searchWithFilter(
|
|
325
325
|
vector: number[],
|
|
326
326
|
limit: number,
|
|
327
|
-
targetTypes: Array<
|
|
328
|
-
"segment" | "item" | "summary" | "media" | "chunk" | "episode"
|
|
329
|
-
>,
|
|
327
|
+
targetTypes: Array<"segment" | "item" | "summary" | "media">,
|
|
330
328
|
excludeMessageIds?: string[],
|
|
331
329
|
scopeIds?: string[],
|
|
332
330
|
): Promise<QdrantSearchResult[]> {
|
|
@@ -349,7 +347,7 @@ export class VellumQdrantClient {
|
|
|
349
347
|
},
|
|
350
348
|
{
|
|
351
349
|
key: "target_type",
|
|
352
|
-
match: { any: ["segment", "summary", "media"
|
|
350
|
+
match: { any: ["segment", "summary", "media"] },
|
|
353
351
|
},
|
|
354
352
|
],
|
|
355
353
|
});
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
existsSync,
|
|
5
5
|
mkdirSync,
|
|
6
6
|
readFileSync,
|
|
7
|
+
symlinkSync,
|
|
7
8
|
unlinkSync,
|
|
8
9
|
writeFileSync,
|
|
9
10
|
} from "node:fs";
|
|
@@ -12,7 +13,7 @@ import { dirname, join } from "node:path";
|
|
|
12
13
|
|
|
13
14
|
import type { Subprocess } from "bun";
|
|
14
15
|
|
|
15
|
-
import { getQdrantUrlEnv } from "../config/env.js";
|
|
16
|
+
import { getQdrantReadyzTimeoutMs, getQdrantUrlEnv } from "../config/env.js";
|
|
16
17
|
import { getLogger } from "../util/logger.js";
|
|
17
18
|
import { getDataDir } from "../util/platform.js";
|
|
18
19
|
|
|
@@ -47,6 +48,8 @@ export interface QdrantManagerConfig {
|
|
|
47
48
|
*/
|
|
48
49
|
export class QdrantManager {
|
|
49
50
|
private process: Subprocess | null = null;
|
|
51
|
+
private stderrBuffer = "";
|
|
52
|
+
private stderrDrained: Promise<void> = Promise.resolve();
|
|
50
53
|
private readonly url: string;
|
|
51
54
|
private readonly host: string;
|
|
52
55
|
private readonly port: number;
|
|
@@ -67,7 +70,8 @@ export class QdrantManager {
|
|
|
67
70
|
|
|
68
71
|
this.readyzPollIntervalMs =
|
|
69
72
|
config.readyzPollIntervalMs ?? READYZ_POLL_INTERVAL_MS;
|
|
70
|
-
this.readyzTimeoutMs =
|
|
73
|
+
this.readyzTimeoutMs =
|
|
74
|
+
config.readyzTimeoutMs ?? getQdrantReadyzTimeoutMs() ?? READYZ_TIMEOUT_MS;
|
|
71
75
|
this.shutdownGraceMs = config.shutdownGraceMs ?? SHUTDOWN_GRACE_MS;
|
|
72
76
|
|
|
73
77
|
// External mode only if QDRANT_URL is explicitly set
|
|
@@ -92,13 +96,15 @@ export class QdrantManager {
|
|
|
92
96
|
await this.installBinary(binaryPath);
|
|
93
97
|
}
|
|
94
98
|
|
|
99
|
+
const spawnPath = this.ensureVellumSymlink(binaryPath);
|
|
100
|
+
|
|
95
101
|
log.info(
|
|
96
|
-
{ binaryPath, storagePath: this.storagePath, port: this.port },
|
|
102
|
+
{ binaryPath: spawnPath, storagePath: this.storagePath, port: this.port },
|
|
97
103
|
"Starting Qdrant",
|
|
98
104
|
);
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
cmd: [
|
|
106
|
+
const proc = Bun.spawn({
|
|
107
|
+
cmd: [spawnPath],
|
|
102
108
|
env: {
|
|
103
109
|
...process.env,
|
|
104
110
|
QDRANT__SERVICE__HOST: this.host,
|
|
@@ -109,8 +115,10 @@ export class QdrantManager {
|
|
|
109
115
|
QDRANT__LOG_LEVEL: "WARN",
|
|
110
116
|
},
|
|
111
117
|
stdout: "ignore",
|
|
112
|
-
stderr: "
|
|
118
|
+
stderr: "pipe",
|
|
113
119
|
});
|
|
120
|
+
this.process = proc;
|
|
121
|
+
this.drainStderrFrom(proc.stderr);
|
|
114
122
|
|
|
115
123
|
if (this.process.pid) {
|
|
116
124
|
this.writePid(this.process.pid);
|
|
@@ -150,6 +158,7 @@ export class QdrantManager {
|
|
|
150
158
|
}
|
|
151
159
|
|
|
152
160
|
this.process = null;
|
|
161
|
+
this.stderrBuffer = "";
|
|
153
162
|
this.cleanupPid();
|
|
154
163
|
log.info("Qdrant stopped");
|
|
155
164
|
}
|
|
@@ -259,6 +268,15 @@ export class QdrantManager {
|
|
|
259
268
|
private async waitForReady(): Promise<void> {
|
|
260
269
|
const start = Date.now();
|
|
261
270
|
while (Date.now() - start < this.readyzTimeoutMs) {
|
|
271
|
+
// Fail fast if the managed process exited before becoming ready
|
|
272
|
+
if (this.process != null && this.process.exitCode != null) {
|
|
273
|
+
await this.stderrDrained;
|
|
274
|
+
const stderr = this.stderrBuffer.trim();
|
|
275
|
+
throw new Error(
|
|
276
|
+
`Qdrant process exited with code ${this.process.exitCode} before becoming ready` +
|
|
277
|
+
(stderr ? `\nstderr:\n${stderr}` : ""),
|
|
278
|
+
);
|
|
279
|
+
}
|
|
262
280
|
try {
|
|
263
281
|
const res = await fetch(`${this.url}/readyz`);
|
|
264
282
|
if (res.ok) return;
|
|
@@ -267,11 +285,32 @@ export class QdrantManager {
|
|
|
267
285
|
}
|
|
268
286
|
await Bun.sleep(this.readyzPollIntervalMs);
|
|
269
287
|
}
|
|
288
|
+
const stderr = this.stderrBuffer.trim();
|
|
270
289
|
throw new Error(
|
|
271
|
-
`Qdrant did not become ready within ${this.readyzTimeoutMs}ms at ${this.url}
|
|
290
|
+
`Qdrant did not become ready within ${this.readyzTimeoutMs}ms at ${this.url}` +
|
|
291
|
+
(stderr ? `\nstderr:\n${stderr}` : ""),
|
|
272
292
|
);
|
|
273
293
|
}
|
|
274
294
|
|
|
295
|
+
private drainStderrFrom(stream: ReadableStream<Uint8Array>): void {
|
|
296
|
+
const reader = stream.getReader();
|
|
297
|
+
const decoder = new TextDecoder();
|
|
298
|
+
this.stderrDrained = (async () => {
|
|
299
|
+
try {
|
|
300
|
+
for (;;) {
|
|
301
|
+
const { done, value } = await reader.read();
|
|
302
|
+
if (done) break;
|
|
303
|
+
this.stderrBuffer += decoder.decode(value, { stream: true });
|
|
304
|
+
if (this.stderrBuffer.length > 4096) {
|
|
305
|
+
this.stderrBuffer = this.stderrBuffer.slice(-4096);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
// Stream closed or error — expected during shutdown
|
|
310
|
+
}
|
|
311
|
+
})();
|
|
312
|
+
}
|
|
313
|
+
|
|
275
314
|
private getBinaryPath(): string {
|
|
276
315
|
return join(getDataDir(), "qdrant", "bin", "qdrant");
|
|
277
316
|
}
|
|
@@ -314,4 +353,22 @@ export class QdrantManager {
|
|
|
314
353
|
}
|
|
315
354
|
}
|
|
316
355
|
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Ensures a `vellum-qdrant` symlink exists next to the real binary so that
|
|
359
|
+
* `lsof` reports "vellum-qdrant" in the COMMAND column, making the process
|
|
360
|
+
* discoverable by tools that scan for "vellum" in process names.
|
|
361
|
+
*/
|
|
362
|
+
private ensureVellumSymlink(binaryPath: string): string {
|
|
363
|
+
const symlinkPath = join(dirname(binaryPath), "vellum-qdrant");
|
|
364
|
+
if (!existsSync(symlinkPath)) {
|
|
365
|
+
try {
|
|
366
|
+
symlinkSync(binaryPath, symlinkPath);
|
|
367
|
+
} catch {
|
|
368
|
+
// Fall back to the real binary if symlink creation fails
|
|
369
|
+
return binaryPath;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return symlinkPath;
|
|
373
|
+
}
|
|
317
374
|
}
|
|
@@ -27,6 +27,7 @@ export const callSessions = sqliteTable(
|
|
|
27
27
|
inviteGuardianName: text("invite_guardian_name"),
|
|
28
28
|
callerIdentityMode: text("caller_identity_mode"),
|
|
29
29
|
callerIdentitySource: text("caller_identity_source"),
|
|
30
|
+
skipDisclosure: integer("skip_disclosure").notNull().default(0),
|
|
30
31
|
initiatedFromConversationId: text("initiated_from_conversation_id"),
|
|
31
32
|
startedAt: integer("started_at"),
|
|
32
33
|
endedAt: integer("ended_at"),
|
|
@@ -10,6 +10,7 @@ export const contacts = sqliteTable("contacts", {
|
|
|
10
10
|
updatedAt: integer("updated_at").notNull(),
|
|
11
11
|
role: text("role").notNull().default("contact"), // 'guardian' | 'contact'
|
|
12
12
|
principalId: text("principal_id"), // internal auth principal (nullable)
|
|
13
|
+
userFile: text("user_file"), // workspace-relative path to per-user persona file
|
|
13
14
|
contactType: text("contact_type").notNull().default("human"), // 'human' | 'assistant'
|
|
14
15
|
});
|
|
15
16
|
|
|
@@ -30,9 +30,6 @@ export const conversations = sqliteTable(
|
|
|
30
30
|
forkParentMessageId: text("fork_parent_message_id"),
|
|
31
31
|
isAutoTitle: integer("is_auto_title").notNull().default(1),
|
|
32
32
|
scheduleJobId: text("schedule_job_id"),
|
|
33
|
-
memoryReducedThroughMessageId: text("memory_reduced_through_message_id"),
|
|
34
|
-
memoryDirtyTailSinceMessageId: text("memory_dirty_tail_since_message_id"),
|
|
35
|
-
memoryLastReducedAt: integer("memory_last_reduced_at"),
|
|
36
33
|
},
|
|
37
34
|
(table) => [
|
|
38
35
|
index("idx_conversations_updated_at").on(table.updatedAt),
|
|
@@ -3,8 +3,6 @@ export * from "./contacts.js";
|
|
|
3
3
|
export * from "./conversations.js";
|
|
4
4
|
export * from "./guardian.js";
|
|
5
5
|
export * from "./infrastructure.js";
|
|
6
|
-
export * from "./memory-archive.js";
|
|
7
|
-
export * from "./memory-brief.js";
|
|
8
6
|
export * from "./memory-core.js";
|
|
9
7
|
export * from "./notifications.js";
|
|
10
8
|
export * from "./oauth.js";
|
|
@@ -10,7 +10,7 @@ import { readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
|
|
12
12
|
import { ensureDir, pathExists } from "../util/fs.js";
|
|
13
|
-
import {
|
|
13
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
14
14
|
|
|
15
15
|
export interface Draft {
|
|
16
16
|
id: string;
|
|
@@ -25,7 +25,7 @@ export interface Draft {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function getDraftsDir(platform: string): string {
|
|
28
|
-
const dir = join(
|
|
28
|
+
const dir = join(getWorkspaceDir(), "data", "drafts", platform);
|
|
29
29
|
ensureDir(dir);
|
|
30
30
|
return dir;
|
|
31
31
|
}
|
|
@@ -13,6 +13,7 @@ import { v4 as uuid } from "uuid";
|
|
|
13
13
|
|
|
14
14
|
import { getDeliverableChannels } from "../channels/config.js";
|
|
15
15
|
import { getConfig } from "../config/loader.js";
|
|
16
|
+
import { resolveGuardianPersona } from "../prompts/persona-resolver.js";
|
|
16
17
|
import { buildCoreIdentityContext } from "../prompts/system-prompt.js";
|
|
17
18
|
import {
|
|
18
19
|
createTimeout,
|
|
@@ -800,7 +801,9 @@ async function classifyWithLLM(
|
|
|
800
801
|
const candidateContext = candidateSet
|
|
801
802
|
? (serializeCandidatesForPrompt(candidateSet) ?? undefined)
|
|
802
803
|
: undefined;
|
|
803
|
-
const rawIdentityContext = buildCoreIdentityContext(
|
|
804
|
+
const rawIdentityContext = buildCoreIdentityContext({
|
|
805
|
+
userPersona: resolveGuardianPersona(),
|
|
806
|
+
});
|
|
804
807
|
const identityContext = rawIdentityContext
|
|
805
808
|
? truncate(rawIdentityContext, MAX_IDENTITY_CONTEXT_CHARS, "\n…[truncated]")
|
|
806
809
|
: undefined;
|
|
@@ -156,10 +156,12 @@ async function resolvePlatformConnectionId(
|
|
|
156
156
|
);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
const body = (await response.json()) as
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
const body = (await response.json()) as unknown;
|
|
160
|
+
const connections = (
|
|
161
|
+
Array.isArray(body)
|
|
162
|
+
? body
|
|
163
|
+
: ((body as Record<string, unknown>).results ?? [])
|
|
164
|
+
) as Array<{ id: string; account_label?: string }>;
|
|
163
165
|
|
|
164
166
|
if (connections.length === 0) {
|
|
165
167
|
throw new Error(
|
|
@@ -147,7 +147,6 @@ const LOW_RISK_PROGRAMS = new Set([
|
|
|
147
147
|
"du",
|
|
148
148
|
"df",
|
|
149
149
|
"assistant",
|
|
150
|
-
"vellum",
|
|
151
150
|
]);
|
|
152
151
|
|
|
153
152
|
// High-risk shell programs / patterns
|
|
@@ -201,32 +200,6 @@ const LOW_RISK_GIT_SUBCOMMANDS = new Set([
|
|
|
201
200
|
"reflog",
|
|
202
201
|
]);
|
|
203
202
|
|
|
204
|
-
// Mutating assistant/vellum CLI subcommands that should be escalated to Medium
|
|
205
|
-
// risk. Most assistant/vellum subcommands are read-only and stay Low risk.
|
|
206
|
-
// This mirrors the git subcommand pattern — only known mutating operations
|
|
207
|
-
// get escalated.
|
|
208
|
-
const MEDIUM_RISK_CLI_SUBCOMMANDS = new Set([
|
|
209
|
-
"credentials",
|
|
210
|
-
"config",
|
|
211
|
-
"bash",
|
|
212
|
-
"trust",
|
|
213
|
-
"autonomy",
|
|
214
|
-
"contacts",
|
|
215
|
-
"mcp",
|
|
216
|
-
"keys",
|
|
217
|
-
"wake",
|
|
218
|
-
"sleep",
|
|
219
|
-
"hatch",
|
|
220
|
-
"retire",
|
|
221
|
-
"clean",
|
|
222
|
-
"setup",
|
|
223
|
-
"upgrade",
|
|
224
|
-
"recover",
|
|
225
|
-
"login",
|
|
226
|
-
"use",
|
|
227
|
-
"pair",
|
|
228
|
-
]);
|
|
229
|
-
|
|
230
203
|
// Commands that wrap another program — the real program appears as the first
|
|
231
204
|
// non-flag argument. When one of these is the segment program we look through
|
|
232
205
|
// its args to find the effective program (e.g. `env curl …` → curl).
|
|
@@ -771,17 +744,6 @@ async function classifyRiskUncached(
|
|
|
771
744
|
continue;
|
|
772
745
|
}
|
|
773
746
|
|
|
774
|
-
if (prog === "vellum" || prog === "assistant") {
|
|
775
|
-
const subcommand = firstPositionalArg(seg.args);
|
|
776
|
-
if (subcommand && MEDIUM_RISK_CLI_SUBCOMMANDS.has(subcommand)) {
|
|
777
|
-
// Known mutating subcommands are medium
|
|
778
|
-
maxRisk = RiskLevel.Medium;
|
|
779
|
-
continue;
|
|
780
|
-
}
|
|
781
|
-
// Read-only / unknown subcommands stay at current risk
|
|
782
|
-
continue;
|
|
783
|
-
}
|
|
784
|
-
|
|
785
747
|
if (!LOW_RISK_PROGRAMS.has(prog)) {
|
|
786
748
|
// Unknown program → medium
|
|
787
749
|
if (maxRisk === RiskLevel.Low) {
|
|
@@ -2,7 +2,7 @@ import { join } from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { getConfig } from "../config/loader.js";
|
|
4
4
|
import { getBundledSkillsDir } from "../config/skills.js";
|
|
5
|
-
import {
|
|
5
|
+
import { getWorkspaceDir } from "../util/platform.js";
|
|
6
6
|
|
|
7
7
|
export interface DefaultRuleTemplate {
|
|
8
8
|
id: string;
|
|
@@ -116,7 +116,7 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
116
116
|
// Workspace prompt files — the agent should always be able to read, edit,
|
|
117
117
|
// and write these without prompting. Also allow `rm BOOTSTRAP.md` so the
|
|
118
118
|
// agent can delete it at the end of the onboarding ritual.
|
|
119
|
-
const workspaceDir =
|
|
119
|
+
const workspaceDir = getWorkspaceDir().replaceAll("\\", "/");
|
|
120
120
|
const WORKSPACE_PROMPT_FILES = [
|
|
121
121
|
"IDENTITY.md",
|
|
122
122
|
"USER.md",
|
|
@@ -163,7 +163,7 @@ export function getDefaultRuleTemplates(): DefaultRuleTemplate[] {
|
|
|
163
163
|
// Skill source directories — writing or editing skill source files should
|
|
164
164
|
// require explicit user approval so a compromised agent loop cannot silently
|
|
165
165
|
// modify skill code to escalate privileges.
|
|
166
|
-
const managedSkillsDir = join(
|
|
166
|
+
const managedSkillsDir = join(getWorkspaceDir(), "skills").replaceAll(
|
|
167
167
|
"\\",
|
|
168
168
|
"/",
|
|
169
169
|
);
|