@vellumai/assistant 0.5.6 → 0.5.8
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 +3 -2
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docker-entrypoint.sh +9 -0
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/memory.md +13 -11
- 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/error.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/grants.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/handles.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/index.ts +1 -1
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +120 -1
- 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 +0 -114
- package/src/__tests__/approval-cascade.test.ts +0 -1
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-fill-credential.test.ts +1 -1
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/ces-startup-timeout.test.ts +40 -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 -2
- package/src/__tests__/config-schema.test.ts +3 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +0 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +0 -2
- package/src/__tests__/conversation-agent-loop.test.ts +2 -4
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-confirmation-signals.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +15 -1
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-messaging-secret-redirect.test.ts +1 -1
- package/src/__tests__/conversation-pre-run-repair.test.ts +0 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +0 -1
- package/src/__tests__/conversation-queue.test.ts +0 -1
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-slash-queue.test.ts +0 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +0 -1
- package/src/__tests__/conversation-title-service.test.ts +87 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +0 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +0 -1
- package/src/__tests__/credential-execution-client.test.ts +5 -2
- package/src/__tests__/credential-execution-feature-gates.test.ts +59 -30
- package/src/__tests__/credential-execution-managed-contract.test.ts +35 -20
- package/src/__tests__/credential-security-e2e.test.ts +1 -67
- package/src/__tests__/credential-security-invariants.test.ts +6 -50
- package/src/__tests__/credentials-cli.test.ts +82 -3
- package/src/__tests__/daemon-credential-client.test.ts +123 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -0
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/gateway-client-managed-outbound.test.ts +79 -1
- 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__/journal-context.test.ts +335 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -3
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/memory-lifecycle-e2e.test.ts +70 -25
- package/src/__tests__/memory-recall-quality.test.ts +48 -17
- package/src/__tests__/memory-regressions.test.ts +408 -363
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -3
- 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 +2 -7
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/notification-decision-strategy.test.ts +71 -0
- package/src/__tests__/oauth-cli.test.ts +5 -1
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +0 -37
- package/src/__tests__/provider-error-scenarios.test.ts +0 -267
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/provider-streaming.benchmark.test.ts +2 -81
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/relay-server.test.ts +1 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/script-proxy-injection-runtime.test.ts +1 -1
- package/src/__tests__/secret-onetime-send.test.ts +1 -1
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +95 -272
- 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-memory.test.ts +17 -3
- 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__/stale-approval-dedup.test.ts +171 -0
- package/src/__tests__/stt-hints.test.ts +437 -0
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +14 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/twilio-routes-twiml.test.ts +139 -1
- 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-quality.test.ts +58 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -7
- 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 +220 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/acp/agent-process.ts +9 -1
- package/src/agent/loop.ts +1 -1
- package/src/approvals/guardian-request-resolvers.ts +164 -38
- package/src/calls/__tests__/tts-text-sanitizer.test.ts +254 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +90 -8
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +129 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/stt-hints.ts +189 -0
- package/src/calls/tts-text-sanitizer.ts +61 -0
- package/src/calls/twilio-routes.ts +34 -5
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +38 -5
- package/src/calls/voice-session-bridge.ts +7 -12
- package/src/cli/commands/avatar.ts +2 -2
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/credentials.ts +128 -82
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/keys.ts +7 -7
- package/src/cli/commands/memory.ts +1 -1
- package/src/cli/commands/oauth/connections.ts +11 -29
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +525 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/cli/lib/daemon-credential-client.ts +284 -0
- package/src/cli.ts +1 -1
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/AGENTS.md +34 -0
- package/src/config/bundled-skills/acp/SKILL.md +10 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +0 -4
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +2 -2
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +1 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +1 -0
- package/src/config/bundled-skills/settings/SKILL.md +15 -2
- package/src/config/bundled-skills/settings/TOOLS.json +47 -2
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +59 -0
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +80 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-skills/slack/SKILL.md +1 -1
- package/src/config/bundled-tool-registry.ts +5 -11
- package/src/config/defaults.ts +0 -2
- package/src/config/env-registry.ts +5 -5
- package/src/config/env.ts +21 -14
- package/src/config/feature-flag-registry.json +49 -9
- package/src/config/loader.ts +106 -42
- package/src/config/schema.ts +9 -29
- package/src/config/schemas/calls.ts +30 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/inference.ts +2 -2
- package/src/config/schemas/journal.ts +16 -0
- package/src/config/schemas/memory-processing.ts +2 -2
- package/src/config/schemas/security.ts +0 -4
- package/src/config/types.ts +1 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- 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/credential-execution/startup-timeout.ts +36 -0
- package/src/daemon/approval-generators.ts +3 -9
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +5 -0
- package/src/daemon/conversation-error.ts +13 -1
- package/src/daemon/conversation-memory.ts +1 -2
- package/src/daemon/conversation-process.ts +18 -1
- package/src/daemon/conversation-surfaces.ts +30 -1
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +21 -1
- package/src/daemon/guardian-action-generators.ts +3 -9
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +234 -51
- package/src/daemon/message-types/conversations.ts +4 -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 +32 -95
- package/src/events/domain-events.ts +2 -1
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/app-store.ts +31 -0
- package/src/memory/conversation-title-service.ts +50 -1
- package/src/memory/db-init.ts +16 -0
- package/src/memory/indexer.ts +19 -10
- package/src/memory/items-extractor.ts +328 -321
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/job-handlers/summarization.ts +26 -16
- package/src/memory/jobs-store.ts +63 -6
- package/src/memory/jobs-worker.ts +31 -7
- package/src/memory/journal-memory.ts +214 -0
- 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/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/193-add-source-type-columns.ts +81 -0
- package/src/memory/migrations/index.ts +5 -0
- package/src/memory/migrations/registry.ts +98 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/retriever.test.ts +37 -25
- package/src/memory/retriever.ts +24 -49
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/memory/schema/memory-core.ts +2 -0
- package/src/memory/search/formatting.ts +7 -44
- package/src/memory/search/staleness.ts +4 -0
- package/src/memory/search/tier-classifier.ts +10 -2
- package/src/memory/search/types.ts +2 -5
- package/src/memory/task-memory-cleanup.ts +4 -3
- package/src/notifications/adapters/slack.ts +168 -6
- package/src/notifications/broadcaster.ts +1 -0
- package/src/notifications/copy-composer.ts +59 -2
- package/src/notifications/decision-engine.ts +4 -1
- package/src/notifications/signal.ts +2 -0
- package/src/notifications/types.ts +2 -0
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/journal-context.ts +133 -0
- package/src/prompts/persona-resolver.ts +194 -0
- package/src/prompts/system-prompt.ts +44 -4
- package/src/prompts/templates/SOUL.md +10 -0
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/provider-send-message.ts +3 -32
- package/src/providers/registry.ts +29 -179
- package/src/providers/types.ts +1 -1
- package/src/runtime/access-request-helper.ts +4 -0
- 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/__tests__/guard-tests.test.ts +9 -50
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +17 -1
- package/src/runtime/auth/token-service.ts +43 -138
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/gateway-client.ts +47 -4
- package/src/runtime/guardian-decision-types.ts +45 -4
- package/src/runtime/http-server.ts +31 -3
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/access-request-decision.ts +2 -2
- package/src/runtime/routes/app-management-routes.ts +2 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +219 -30
- package/src/runtime/routes/approval-strategies/guardian-text-engine-strategy.ts +37 -14
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/channel-readiness-routes.ts +9 -4
- package/src/runtime/routes/conversation-query-routes.ts +63 -1
- package/src/runtime/routes/conversation-routes.ts +4 -44
- package/src/runtime/routes/debug-routes.ts +12 -9
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/guardian-approval-interception.ts +168 -11
- package/src/runtime/routes/guardian-approval-prompt.ts +6 -1
- package/src/runtime/routes/guardian-approval-reply-helpers.ts +103 -21
- package/src/runtime/routes/identity-routes.ts +19 -30
- package/src/runtime/routes/inbound-message-handler.ts +31 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +64 -5
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +52 -40
- 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/twilio.ts +52 -10
- 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 +3 -3
- package/src/runtime/routes/memory-item-routes.ts +46 -14
- 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/secret-routes.ts +141 -10
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +96 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
- 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/security/ces-credential-client.ts +75 -29
- package/src/security/ces-rpc-credential-backend.ts +86 -0
- package/src/security/credential-backend.ts +22 -92
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +113 -115
- package/src/skills/catalog-install.ts +6 -32
- package/src/skills/skill-memory.ts +1 -0
- package/src/subagent/manager.ts +2 -5
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/acp/spawn.ts +78 -1
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/credentials/vault.ts +5 -3
- package/src/tools/executor.ts +0 -4
- package/src/tools/memory/definitions.ts +3 -2
- package/src/tools/memory/handlers.ts +10 -7
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/types.ts +0 -8
- package/src/util/browser.ts +15 -0
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +4 -51
- package/src/workspace/git-service.ts +5 -2
- 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 +96 -0
- package/src/workspace/migrations/018-rekey-compound-credential-keys.ts +184 -0
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +103 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +27 -5
- package/src/workspace/migrations/registry.ts +12 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/workspace/provider-commit-message-generator.ts +12 -21
- 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__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/provider-fail-open-selection.test.ts +0 -271
- package/src/__tests__/provider-failover-actual-provider.test.ts +0 -66
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- 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/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/memory/search/lexical.ts +0 -48
- package/src/providers/failover.ts +0 -186
- 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
|
@@ -7,6 +7,13 @@ export interface ServiceGroupUpdateStarting {
|
|
|
7
7
|
expectedDowntimeSeconds: number;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/** Broadcast to connected clients with a progress update during an upgrade or rollback. */
|
|
11
|
+
export interface ServiceGroupUpdateProgress {
|
|
12
|
+
type: "service_group_update_progress";
|
|
13
|
+
/** A short, user-friendly status message describing what's happening right now. */
|
|
14
|
+
statusMessage: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
10
17
|
/** Broadcast to connected clients when a service group update has completed. */
|
|
11
18
|
export interface ServiceGroupUpdateComplete {
|
|
12
19
|
type: "service_group_update_complete";
|
|
@@ -20,4 +27,5 @@ export interface ServiceGroupUpdateComplete {
|
|
|
20
27
|
|
|
21
28
|
export type _UpgradesServerMessages =
|
|
22
29
|
| ServiceGroupUpdateStarting
|
|
30
|
+
| ServiceGroupUpdateProgress
|
|
23
31
|
| ServiceGroupUpdateComplete;
|
package/src/daemon/server.ts
CHANGED
|
@@ -20,13 +20,7 @@ import {
|
|
|
20
20
|
import { getConfig } from "../config/loader.js";
|
|
21
21
|
import { onContactChange } from "../contacts/contact-events.js";
|
|
22
22
|
import type { CesClient } from "../credential-execution/client.js";
|
|
23
|
-
import {
|
|
24
|
-
import { isCesToolsEnabled } from "../credential-execution/feature-gates.js";
|
|
25
|
-
import {
|
|
26
|
-
type CesProcessManager,
|
|
27
|
-
CesUnavailableError,
|
|
28
|
-
createCesProcessManager,
|
|
29
|
-
} from "../credential-execution/process-manager.js";
|
|
23
|
+
import type { CesProcessManager } from "../credential-execution/process-manager.js";
|
|
30
24
|
import type { HeartbeatService } from "../heartbeat/heartbeat-service.js";
|
|
31
25
|
import * as attachmentsStore from "../memory/attachments-store.js";
|
|
32
26
|
import {
|
|
@@ -45,10 +39,9 @@ import {
|
|
|
45
39
|
import { updateMetaFile } from "../memory/conversation-disk-view.js";
|
|
46
40
|
import { getOrCreateConversation } from "../memory/conversation-key-store.js";
|
|
47
41
|
import { buildSystemPrompt } from "../prompts/system-prompt.js";
|
|
48
|
-
import { resolveManagedProxyContext } from "../providers/managed-proxy/context.js";
|
|
49
42
|
import { RateLimitProvider } from "../providers/ratelimit.js";
|
|
50
43
|
import {
|
|
51
|
-
|
|
44
|
+
getProvider,
|
|
52
45
|
initializeProviders,
|
|
53
46
|
} from "../providers/registry.js";
|
|
54
47
|
import { buildAssistantEvent } from "../runtime/assistant-event.js";
|
|
@@ -57,13 +50,11 @@ import { DAEMON_INTERNAL_ASSISTANT_ID } from "../runtime/assistant-scope.js";
|
|
|
57
50
|
import { getSigningKeyFingerprint } from "../runtime/auth/token-service.js";
|
|
58
51
|
import { bridgeConfirmationRequestToGuardian } from "../runtime/confirmation-request-guardian-bridge.js";
|
|
59
52
|
import * as pendingInteractions from "../runtime/pending-interactions.js";
|
|
60
|
-
import { checkIngressForSecrets } from "../security/secret-ingress.js";
|
|
61
53
|
import { registerCancelCallback } from "../signals/cancel.js";
|
|
62
54
|
import { registerConversationUndoCallback } from "../signals/conversation-undo.js";
|
|
63
55
|
import { appendEventToStream } from "../signals/event-stream.js";
|
|
64
56
|
import { registerUserMessageCallback } from "../signals/user-message.js";
|
|
65
57
|
import { getSubagentManager } from "../subagent/index.js";
|
|
66
|
-
import { IngressBlockedError } from "../util/errors.js";
|
|
67
58
|
import { getLogger } from "../util/logger.js";
|
|
68
59
|
import {
|
|
69
60
|
getSandboxWorkingDir,
|
|
@@ -253,7 +244,6 @@ export class DaemonServer {
|
|
|
253
244
|
private conversationOptions = new Map<string, ConversationCreateOptions>();
|
|
254
245
|
private conversationCreating = new Map<string, Promise<Conversation>>();
|
|
255
246
|
private sharedRequestTimestamps: number[] = [];
|
|
256
|
-
private httpPort: number | undefined;
|
|
257
247
|
private unsubscribeContactChange: (() => void) | null = null;
|
|
258
248
|
private evictor: ConversationEvictor;
|
|
259
249
|
private _hubChain: Promise<void> = Promise.resolve();
|
|
@@ -262,8 +252,8 @@ export class DaemonServer {
|
|
|
262
252
|
private configWatcher = new ConfigWatcher();
|
|
263
253
|
|
|
264
254
|
// CES (Credential Execution Service) — process-level singleton.
|
|
265
|
-
//
|
|
266
|
-
//
|
|
255
|
+
// Lifecycle is managed by startCesProcess() in lifecycle.ts; the server
|
|
256
|
+
// receives the result via setCes().
|
|
267
257
|
private cesProcessManager?: CesProcessManager;
|
|
268
258
|
private cesClientPromise?: Promise<CesClient | undefined>;
|
|
269
259
|
private cesInitAbortController?: AbortController;
|
|
@@ -274,6 +264,31 @@ export class DaemonServer {
|
|
|
274
264
|
*/
|
|
275
265
|
assistantId: string = DAEMON_INTERNAL_ASSISTANT_ID;
|
|
276
266
|
|
|
267
|
+
/**
|
|
268
|
+
* Inject the CES client and process manager from the caller (lifecycle.ts).
|
|
269
|
+
* Must be called before start().
|
|
270
|
+
*/
|
|
271
|
+
setCes(result: {
|
|
272
|
+
client: CesClient | undefined;
|
|
273
|
+
processManager: CesProcessManager | undefined;
|
|
274
|
+
clientPromise: Promise<CesClient | undefined> | undefined;
|
|
275
|
+
abortController: AbortController | undefined;
|
|
276
|
+
}): void {
|
|
277
|
+
this.cesClientRef = result.client;
|
|
278
|
+
this.cesProcessManager = result.processManager;
|
|
279
|
+
this.cesInitAbortController = result.abortController;
|
|
280
|
+
|
|
281
|
+
// Wrap the external promise so that cesClientRef stays in sync once the
|
|
282
|
+
// handshake completes — the async work runs in lifecycle.ts but the
|
|
283
|
+
// server needs the resolved client reference for getCesClient().
|
|
284
|
+
if (result.clientPromise) {
|
|
285
|
+
this.cesClientPromise = result.clientPromise.then((client) => {
|
|
286
|
+
this.cesClientRef = client;
|
|
287
|
+
return client;
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
277
292
|
/**
|
|
278
293
|
* Return the CES client reference (if available).
|
|
279
294
|
* Used by routes that need to push updates to CES (e.g. secret-routes).
|
|
@@ -538,73 +553,6 @@ export class DaemonServer {
|
|
|
538
553
|
this.broadcast({ type: "contacts_changed" });
|
|
539
554
|
});
|
|
540
555
|
|
|
541
|
-
// CES lifecycle — start the CES process and perform the RPC handshake
|
|
542
|
-
// once at server level. The managed sidecar accepts exactly one bootstrap
|
|
543
|
-
// connection, so this must be a process-level singleton.
|
|
544
|
-
if (isCesToolsEnabled(config)) {
|
|
545
|
-
const pm = createCesProcessManager({ assistantConfig: config });
|
|
546
|
-
this.cesProcessManager = pm;
|
|
547
|
-
const abortController = new AbortController();
|
|
548
|
-
this.cesInitAbortController = abortController;
|
|
549
|
-
this.cesClientPromise = (async () => {
|
|
550
|
-
try {
|
|
551
|
-
const transport = await pm.start();
|
|
552
|
-
if (abortController.signal.aborted) {
|
|
553
|
-
throw new Error("CES initialization aborted during shutdown");
|
|
554
|
-
}
|
|
555
|
-
const client = createCesClient(transport);
|
|
556
|
-
this.cesClientRef = client;
|
|
557
|
-
// Resolve the assistant API key so CES can use it for platform
|
|
558
|
-
// credential materialisation. In managed mode the key is provisioned
|
|
559
|
-
// after hatch and stored in the credential store — CES can't read
|
|
560
|
-
// the env var, so we pass it via the handshake.
|
|
561
|
-
const proxyCtx = await resolveManagedProxyContext();
|
|
562
|
-
const { accepted, reason } = await client.handshake(
|
|
563
|
-
proxyCtx.assistantApiKey
|
|
564
|
-
? { assistantApiKey: proxyCtx.assistantApiKey }
|
|
565
|
-
: undefined,
|
|
566
|
-
);
|
|
567
|
-
if (abortController.signal.aborted) {
|
|
568
|
-
client.close();
|
|
569
|
-
throw new Error("CES initialization aborted during shutdown");
|
|
570
|
-
}
|
|
571
|
-
if (accepted) {
|
|
572
|
-
log.info(
|
|
573
|
-
"CES client initialized and handshake accepted (server-level)",
|
|
574
|
-
);
|
|
575
|
-
return client;
|
|
576
|
-
}
|
|
577
|
-
log.warn(
|
|
578
|
-
{ reason },
|
|
579
|
-
"CES handshake rejected — CES tools will be unavailable",
|
|
580
|
-
);
|
|
581
|
-
client.close();
|
|
582
|
-
this.cesClientRef = undefined;
|
|
583
|
-
await pm.stop();
|
|
584
|
-
// Reset so next session can retry initialization
|
|
585
|
-
this.cesClientPromise = undefined;
|
|
586
|
-
return undefined;
|
|
587
|
-
} catch (err) {
|
|
588
|
-
if (err instanceof CesUnavailableError) {
|
|
589
|
-
log.info(
|
|
590
|
-
{ reason: err.message },
|
|
591
|
-
"CES is not available — CES tools will be unavailable",
|
|
592
|
-
);
|
|
593
|
-
} else {
|
|
594
|
-
log.warn(
|
|
595
|
-
{ error: err instanceof Error ? err.message : String(err) },
|
|
596
|
-
"Failed to initialize CES client — CES tools will be unavailable",
|
|
597
|
-
);
|
|
598
|
-
}
|
|
599
|
-
await pm.stop().catch(() => {});
|
|
600
|
-
// Reset so next session can retry initialization
|
|
601
|
-
this.cesClientRef = undefined;
|
|
602
|
-
this.cesClientPromise = undefined;
|
|
603
|
-
return undefined;
|
|
604
|
-
}
|
|
605
|
-
})();
|
|
606
|
-
}
|
|
607
|
-
|
|
608
556
|
log.info("DaemonServer started (HTTP-only mode)");
|
|
609
557
|
}
|
|
610
558
|
|
|
@@ -656,11 +604,9 @@ export class DaemonServer {
|
|
|
656
604
|
|
|
657
605
|
// ── Conversation management ──────────────────────────────────────────────
|
|
658
606
|
|
|
659
|
-
|
|
660
|
-
this.httpPort = port;
|
|
607
|
+
broadcastStatus(): void {
|
|
661
608
|
this.broadcast({
|
|
662
|
-
type: "
|
|
663
|
-
httpPort: port,
|
|
609
|
+
type: "assistant_status",
|
|
664
610
|
version: daemonVersion,
|
|
665
611
|
keyFingerprint: getSigningKeyFingerprint(),
|
|
666
612
|
});
|
|
@@ -756,9 +702,8 @@ export class DaemonServer {
|
|
|
756
702
|
|
|
757
703
|
const createPromise = (async () => {
|
|
758
704
|
const config = getConfig();
|
|
759
|
-
let provider =
|
|
705
|
+
let provider = getProvider(
|
|
760
706
|
config.services.inference.provider,
|
|
761
|
-
config.providerOrder,
|
|
762
707
|
);
|
|
763
708
|
const { rateLimit } = config;
|
|
764
709
|
if (rateLimit.maxRequestsPerMinute > 0) {
|
|
@@ -884,14 +829,6 @@ export class DaemonServer {
|
|
|
884
829
|
filePath?: string;
|
|
885
830
|
}[];
|
|
886
831
|
}> {
|
|
887
|
-
const ingressCheck = checkIngressForSecrets(content);
|
|
888
|
-
if (ingressCheck.blocked) {
|
|
889
|
-
throw new IngressBlockedError(
|
|
890
|
-
ingressCheck.userNotice!,
|
|
891
|
-
ingressCheck.detectedTypes,
|
|
892
|
-
);
|
|
893
|
-
}
|
|
894
|
-
|
|
895
832
|
const conversation = await this.getOrCreateConversation(
|
|
896
833
|
conversationId,
|
|
897
834
|
options,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Platform callback route registration for containerized deployments.
|
|
3
3
|
*
|
|
4
4
|
* When the assistant daemon runs inside a container (IS_CONTAINERIZED=true)
|
|
5
|
-
* with a configured
|
|
5
|
+
* with a configured VELLUM_PLATFORM_URL and PLATFORM_ASSISTANT_ID, external
|
|
6
6
|
* service callbacks (Twilio webhooks, OAuth redirects, Telegram webhooks, etc.)
|
|
7
7
|
* must route through the platform's gateway proxy instead of hitting the
|
|
8
8
|
* assistant directly.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* webhooks to the correct containerized assistant instance.
|
|
13
13
|
*
|
|
14
14
|
* The platform endpoint is:
|
|
15
|
-
* POST {
|
|
15
|
+
* POST {VELLUM_PLATFORM_URL}/v1/internal/gateway/callback-routes/register/
|
|
16
16
|
*
|
|
17
17
|
* It accepts { assistant_id, callback_path, type } and returns a stable
|
|
18
18
|
* callback_url that external services should use.
|
|
@@ -30,7 +30,7 @@ const log = getLogger("platform-callback-registration");
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* Whether the daemon should register callback routes with the platform.
|
|
33
|
-
* True when IS_CONTAINERIZED,
|
|
33
|
+
* True when IS_CONTAINERIZED, VELLUM_PLATFORM_URL, and PLATFORM_ASSISTANT_ID
|
|
34
34
|
* are all set. Intentionally does **not** require the managed proxy API key
|
|
35
35
|
* so that callback-only flows (OAuth transport, Telegram/Twilio callback
|
|
36
36
|
* registration) work during partial bootstrap before the key is injected.
|
package/src/instrument.ts
CHANGED
|
@@ -39,14 +39,17 @@ function redactObject(obj: unknown): unknown {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* Call after dotenv has loaded so
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* Call after dotenv has loaded so SENTRY_DSN_ASSISTANT is available.
|
|
43
|
+
* Initializes Sentry when the DSN is set; no-ops when empty/unset so
|
|
44
|
+
* local dev builds don't send crash reports. If the user later opts out
|
|
45
|
+
* via the sendDiagnostics config key (or VELLUM_DEV=1), call closeSentry()
|
|
46
|
+
* after config is loaded to stop future event capturing.
|
|
46
47
|
*/
|
|
47
48
|
export function initSentry(): void {
|
|
49
|
+
const dsn = getSentryDsn();
|
|
50
|
+
if (!dsn) return;
|
|
48
51
|
Sentry.init({
|
|
49
|
-
dsn
|
|
52
|
+
dsn,
|
|
50
53
|
release: `vellum-assistant@${APP_VERSION}`,
|
|
51
54
|
dist: COMMIT_SHA,
|
|
52
55
|
environment: APP_VERSION === "0.0.0-dev" ? "development" : "production",
|
package/src/memory/app-store.ts
CHANGED
|
@@ -64,6 +64,37 @@ export function isMultifileApp(app: AppDefinition): boolean {
|
|
|
64
64
|
return app.formatVersion === 2;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Inline dist assets (main.js, main.css) into the compiled HTML so it can be
|
|
69
|
+
* delivered as a self-contained string via loadHTMLString/SSE without needing
|
|
70
|
+
* the client to resolve external script/stylesheet URLs.
|
|
71
|
+
*/
|
|
72
|
+
export function inlineDistAssets(appDir: string, html: string): string {
|
|
73
|
+
const distDir = join(appDir, "dist");
|
|
74
|
+
|
|
75
|
+
// Inline main.js
|
|
76
|
+
const jsPath = join(distDir, "main.js");
|
|
77
|
+
if (existsSync(jsPath)) {
|
|
78
|
+
const js = readFileSync(jsPath, "utf-8");
|
|
79
|
+
html = html.replace(
|
|
80
|
+
/<script\s+type="module"\s+src="main\.js"\s*><\/script>/,
|
|
81
|
+
`<script type="module">${js}</script>`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Inline main.css
|
|
86
|
+
const cssPath = join(distDir, "main.css");
|
|
87
|
+
if (existsSync(cssPath)) {
|
|
88
|
+
const css = readFileSync(cssPath, "utf-8");
|
|
89
|
+
html = html.replace(
|
|
90
|
+
/<link\s+rel="stylesheet"\s+href="main\.css"\s*>/,
|
|
91
|
+
`<style>${css}</style>`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return html;
|
|
96
|
+
}
|
|
97
|
+
|
|
67
98
|
export interface AppRecord {
|
|
68
99
|
id: string;
|
|
69
100
|
appId: string;
|
|
@@ -358,12 +358,61 @@ function deriveFallbackTitle(context?: TitleContext): string | null {
|
|
|
358
358
|
return null;
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
+
/**
|
|
362
|
+
* Extract only human-authored text from stored message content for title
|
|
363
|
+
* generation. Unlike extractTextFromStoredMessageContent (which includes
|
|
364
|
+
* tool metadata like "Tool use (...): {...}"), this only extracts:
|
|
365
|
+
* - `text` blocks (the actual conversation content)
|
|
366
|
+
* - `tool_result` string content (topical signal from tool responses)
|
|
367
|
+
* — web_search_tool_result is skipped (structured search data, not topical)
|
|
368
|
+
*
|
|
369
|
+
* Returns empty string for content-block arrays with no extractable text,
|
|
370
|
+
* preventing raw JSON from polluting the title prompt.
|
|
371
|
+
*/
|
|
372
|
+
function extractTextForTitle(raw: string): string {
|
|
373
|
+
try {
|
|
374
|
+
const parsed = JSON.parse(raw);
|
|
375
|
+
if (typeof parsed === "string") return parsed;
|
|
376
|
+
if (!Array.isArray(parsed)) return raw;
|
|
377
|
+
const texts: string[] = [];
|
|
378
|
+
for (const block of parsed) {
|
|
379
|
+
if (!block || typeof block !== "object") continue;
|
|
380
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
381
|
+
texts.push(block.text);
|
|
382
|
+
// guard:allow-tool-result-only — web_search_tool_result has structured
|
|
383
|
+
// search result arrays, not useful for title generation; only plain
|
|
384
|
+
// tool_result string content carries topical signal.
|
|
385
|
+
} else if (block.type === "tool_result") {
|
|
386
|
+
if (typeof block.content === "string") {
|
|
387
|
+
texts.push(block.content);
|
|
388
|
+
} else if (Array.isArray(block.content)) {
|
|
389
|
+
for (const nested of block.content) {
|
|
390
|
+
if (
|
|
391
|
+
nested &&
|
|
392
|
+
typeof nested === "object" &&
|
|
393
|
+
nested.type === "text" &&
|
|
394
|
+
typeof nested.text === "string"
|
|
395
|
+
) {
|
|
396
|
+
texts.push(nested.text);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return texts.join("\n");
|
|
403
|
+
} catch {
|
|
404
|
+
return raw;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
361
408
|
function buildRegenerationPrompt(recentMessages: MessageRow[]): string {
|
|
362
409
|
const parts: string[] = ["Recent messages:"];
|
|
363
410
|
|
|
364
411
|
for (const msg of recentMessages) {
|
|
412
|
+
const text = extractTextForTitle(msg.content);
|
|
413
|
+
if (!text) continue;
|
|
365
414
|
const role = msg.role === "user" ? "User" : "Assistant";
|
|
366
|
-
parts.push(`${role}: ${truncate(
|
|
415
|
+
parts.push(`${role}: ${truncate(text, 200, "")}`);
|
|
367
416
|
}
|
|
368
417
|
|
|
369
418
|
return parts.join("\n");
|
package/src/memory/db-init.ts
CHANGED
|
@@ -34,13 +34,16 @@ import {
|
|
|
34
34
|
createSequenceTables,
|
|
35
35
|
createTasksAndWorkItemsTables,
|
|
36
36
|
createWatchersAndLogsTables,
|
|
37
|
+
migrateAddSourceTypeColumns,
|
|
37
38
|
migrateAssistantContactMetadata,
|
|
39
|
+
migrateBackfillAudioAttachmentMimeTypes,
|
|
38
40
|
migrateBackfillContactInteractionStats,
|
|
39
41
|
migrateBackfillGuardianPrincipalId,
|
|
40
42
|
migrateBackfillInlineAttachmentsToDisk,
|
|
41
43
|
migrateBackfillUsageCacheAccounting,
|
|
42
44
|
migrateCallSessionInviteMetadata,
|
|
43
45
|
migrateCallSessionMode,
|
|
46
|
+
migrateCallSessionSkipDisclosure,
|
|
44
47
|
migrateCanonicalGuardianDeliveriesDestinationIndex,
|
|
45
48
|
migrateCanonicalGuardianRequesterChatId,
|
|
46
49
|
migrateCapabilityCardColumns,
|
|
@@ -51,6 +54,7 @@ import {
|
|
|
51
54
|
migrateContactsAssistantId,
|
|
52
55
|
migrateContactsNotesColumn,
|
|
53
56
|
migrateContactsRolePrincipal,
|
|
57
|
+
migrateContactsUserFileColumn,
|
|
54
58
|
migrateConversationForkLineage,
|
|
55
59
|
migrateConversationsThreadTypeIndex,
|
|
56
60
|
migrateCreateThreadStartersTable,
|
|
@@ -492,6 +496,18 @@ export function initializeDb(): void {
|
|
|
492
496
|
// 86. Drop simplified-memory tables and reducer checkpoint columns
|
|
493
497
|
migrateDropSimplifiedMemory(database);
|
|
494
498
|
|
|
499
|
+
// 87. Add skip_disclosure column to call_sessions for per-call disclosure control
|
|
500
|
+
migrateCallSessionSkipDisclosure(database);
|
|
501
|
+
|
|
502
|
+
// 88. Backfill correct MIME types for audio attachments stored as application/octet-stream
|
|
503
|
+
migrateBackfillAudioAttachmentMimeTypes(database);
|
|
504
|
+
|
|
505
|
+
// 89. Add user_file column to contacts for per-user persona file mapping
|
|
506
|
+
migrateContactsUserFileColumn(database);
|
|
507
|
+
|
|
508
|
+
// 90. Add source_type and source_message_role columns to memory_items
|
|
509
|
+
migrateAddSourceTypeColumns(database);
|
|
510
|
+
|
|
495
511
|
validateMigrationState(database);
|
|
496
512
|
|
|
497
513
|
if (process.env.BUN_TEST === "1") {
|
package/src/memory/indexer.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
|
7
7
|
import { getLogger } from "../util/logger.js";
|
|
8
8
|
import { getDb } from "./db.js";
|
|
9
9
|
import { selectedBackendSupportsMultimodal } from "./embedding-backend.js";
|
|
10
|
-
import { enqueueMemoryJob } from "./jobs-store.js";
|
|
10
|
+
import { enqueueMemoryJob, upsertDebouncedJob } from "./jobs-store.js";
|
|
11
11
|
import {
|
|
12
12
|
extractMediaBlockMeta,
|
|
13
13
|
extractTextFromStoredMessageContent,
|
|
@@ -17,6 +17,11 @@ import { segmentText } from "./segmenter.js";
|
|
|
17
17
|
|
|
18
18
|
const log = getLogger("memory-indexer");
|
|
19
19
|
|
|
20
|
+
/** Delay before a conversation summary job becomes eligible to run.
|
|
21
|
+
* Each new message in the same conversation resets the timer, so the
|
|
22
|
+
* summary is only built once the conversation has been idle for this long. */
|
|
23
|
+
const SUMMARY_DEBOUNCE_MS = 3 * 60 * 1000; // 3 minutes
|
|
24
|
+
|
|
20
25
|
export interface IndexMessageInput {
|
|
21
26
|
messageId: string;
|
|
22
27
|
conversationId: string;
|
|
@@ -54,9 +59,11 @@ export async function indexMessageNow(
|
|
|
54
59
|
|
|
55
60
|
const text = extractTextFromStoredMessageContent(input.content);
|
|
56
61
|
if (text.length === 0) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
upsertDebouncedJob(
|
|
63
|
+
"build_conversation_summary",
|
|
64
|
+
{ conversationId: input.conversationId },
|
|
65
|
+
Date.now() + SUMMARY_DEBOUNCE_MS,
|
|
66
|
+
);
|
|
60
67
|
return { indexedSegments: 0, enqueuedJobs: 1 };
|
|
61
68
|
}
|
|
62
69
|
|
|
@@ -152,14 +159,16 @@ export async function indexMessageNow(
|
|
|
152
159
|
tx,
|
|
153
160
|
);
|
|
154
161
|
}
|
|
155
|
-
enqueueMemoryJob(
|
|
156
|
-
"build_conversation_summary",
|
|
157
|
-
{ conversationId: input.conversationId },
|
|
158
|
-
Date.now(),
|
|
159
|
-
tx,
|
|
160
|
-
);
|
|
161
162
|
});
|
|
162
163
|
|
|
164
|
+
// Debounced outside the transaction — each new message pushes the summary
|
|
165
|
+
// job's runAfter forward so it only fires once the conversation is idle.
|
|
166
|
+
upsertDebouncedJob(
|
|
167
|
+
"build_conversation_summary",
|
|
168
|
+
{ conversationId: input.conversationId },
|
|
169
|
+
Date.now() + SUMMARY_DEBOUNCE_MS,
|
|
170
|
+
);
|
|
171
|
+
|
|
163
172
|
if (skippedEmbedJobs > 0) {
|
|
164
173
|
log.debug(
|
|
165
174
|
`Skipped ${skippedEmbedJobs}/${segments.length} embed_segment jobs (content unchanged)`,
|