@vellumai/assistant 0.3.5 → 0.3.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/README.md +51 -0
- package/eslint.config.mjs +31 -0
- package/package.json +1 -1
- package/scripts/ipc/check-swift-decoder-drift.ts +4 -1
- package/scripts/ipc/generate-swift.ts +18 -2
- package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +338 -1
- package/src/__tests__/approval-conversation-turn.test.ts +214 -0
- package/src/__tests__/browser-manager.test.ts +1 -0
- package/src/__tests__/call-conversation-messages.test.ts +130 -0
- package/src/__tests__/call-orchestrator.test.ts +752 -271
- package/src/__tests__/call-pointer-messages.test.ts +148 -0
- package/src/__tests__/call-recovery.test.ts +3 -0
- package/src/__tests__/call-routes-http.test.ts +5 -0
- package/src/__tests__/call-store.test.ts +3 -0
- package/src/__tests__/channel-approval-routes.test.ts +1260 -85
- package/src/__tests__/channel-approval.test.ts +37 -0
- package/src/__tests__/channel-approvals.test.ts +4 -65
- package/src/__tests__/channel-guardian.test.ts +556 -0
- package/src/__tests__/channel-readiness-service.test.ts +74 -7
- package/src/__tests__/checker.test.ts +14 -7
- package/src/__tests__/clarification-resolver.test.ts +44 -24
- package/src/__tests__/commit-message-enrichment-service.test.ts +9 -4
- package/src/__tests__/computer-use-session-working-dir.test.ts +8 -0
- package/src/__tests__/config-schema.test.ts +12 -7
- package/src/__tests__/context-window-manager.test.ts +30 -2
- package/src/__tests__/contradiction-checker.test.ts +20 -5
- package/src/__tests__/credential-security-invariants.test.ts +6 -2
- package/src/__tests__/db-migration-rollback.test.ts +752 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +2 -0
- package/src/__tests__/fuzzy-match-property.test.ts +5 -5
- package/src/__tests__/guardian-action-store.test.ts +123 -0
- package/src/__tests__/guardian-action-sweep.test.ts +277 -0
- package/src/__tests__/guardian-dispatch.test.ts +389 -0
- package/src/__tests__/guardian-question-copy.test.ts +47 -0
- package/src/__tests__/handlers-telegram-config.test.ts +4 -2
- package/src/__tests__/handlers-twilio-config.test.ts +126 -0
- package/src/__tests__/intent-routing.test.ts +2 -0
- package/src/__tests__/ipc-snapshot.test.ts +228 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +828 -0
- package/src/__tests__/model-intents.test.ts +96 -0
- package/src/__tests__/no-direct-anthropic-sdk-imports.test.ts +42 -0
- package/src/__tests__/oauth2-gateway-transport.test.ts +130 -0
- package/src/__tests__/onboarding-starter-tasks.test.ts +2 -0
- package/src/__tests__/provider-commit-message-generator.test.ts +89 -13
- package/src/__tests__/provider-error-scenarios.test.ts +621 -0
- package/src/__tests__/provider-fail-open-selection.test.ts +119 -0
- package/src/__tests__/qdrant-manager.test.ts +27 -20
- package/src/__tests__/relay-server.test.ts +779 -40
- package/src/__tests__/run-orchestrator-assistant-events.test.ts +2 -0
- package/src/__tests__/run-orchestrator.test.ts +20 -4
- package/src/__tests__/runtime-runs-http.test.ts +17 -1
- package/src/__tests__/runtime-runs.test.ts +16 -0
- package/src/__tests__/schedule-store.test.ts +18 -4
- package/src/__tests__/scheduler-recurrence.test.ts +13 -4
- package/src/__tests__/session-abort-tool-results.test.ts +6 -0
- package/src/__tests__/session-agent-loop.test.ts +857 -0
- package/src/__tests__/session-conflict-gate.test.ts +6 -0
- package/src/__tests__/session-pre-run-repair.test.ts +6 -0
- package/src/__tests__/session-profile-injection.test.ts +6 -0
- package/src/__tests__/session-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/session-queue.test.ts +6 -0
- package/src/__tests__/session-runtime-assembly.test.ts +237 -13
- package/src/__tests__/session-slash-known.test.ts +6 -0
- package/src/__tests__/session-slash-queue.test.ts +6 -0
- package/src/__tests__/session-slash-unknown.test.ts +6 -0
- package/src/__tests__/session-surfaces-task-progress.test.ts +2 -0
- package/src/__tests__/session-tool-setup-app-refresh.test.ts +1 -0
- package/src/__tests__/session-tool-setup-memory-scope.test.ts +1 -0
- package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +1 -0
- package/src/__tests__/session-workspace-injection.test.ts +6 -0
- package/src/__tests__/session-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/skills.test.ts +2 -0
- package/src/__tests__/sms-messaging-provider.test.ts +2 -1
- package/src/__tests__/starter-task-flow.test.ts +2 -0
- package/src/__tests__/swarm-dag-pathological.test.ts +535 -0
- package/src/__tests__/system-prompt.test.ts +2 -0
- package/src/__tests__/task-management-tools.test.ts +2 -2
- package/src/__tests__/task-runner.test.ts +14 -4
- package/src/__tests__/terminal-tools.test.ts +25 -19
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +545 -0
- package/src/__tests__/tool-executor-shell-integration.test.ts +11 -11
- package/src/__tests__/tool-executor.test.ts +23 -24
- package/src/__tests__/trust-store.test.ts +3 -3
- package/src/__tests__/twilio-rest.test.ts +29 -0
- package/src/__tests__/twilio-routes-elevenlabs.test.ts +3 -0
- package/src/__tests__/twilio-routes-twiml.test.ts +11 -0
- package/src/__tests__/twilio-routes.test.ts +141 -21
- package/src/__tests__/user-reference.test.ts +2 -0
- package/src/__tests__/voice-quality.test.ts +222 -0
- package/src/__tests__/web-search.test.ts +45 -29
- package/src/agent/loop.ts +1 -1
- package/src/agent-heartbeat/agent-heartbeat-service.ts +2 -10
- package/src/amazon/client.ts +1418 -0
- package/src/amazon/request-extractor.ts +135 -0
- package/src/amazon/session.ts +109 -0
- package/src/autonomy/autonomy-store.ts +5 -5
- package/src/browser-extension-relay/client.ts +124 -0
- package/src/browser-extension-relay/protocol.ts +63 -0
- package/src/browser-extension-relay/server.ts +177 -0
- package/src/bundler/app-bundler.ts +3 -3
- package/src/bundler/bundle-signer.ts +1 -1
- package/src/bundler/signature-verifier.ts +1 -1
- package/src/calls/call-conversation-messages.ts +33 -0
- package/src/calls/call-domain.ts +106 -5
- package/src/calls/call-orchestrator.ts +252 -54
- package/src/calls/call-pointer-messages.ts +53 -0
- package/src/calls/call-recovery.ts +3 -8
- package/src/calls/call-store.ts +69 -87
- package/src/calls/elevenlabs-config.ts +3 -2
- package/src/calls/guardian-action-sweep.ts +105 -0
- package/src/calls/guardian-dispatch.ts +203 -0
- package/src/calls/guardian-question-copy.ts +133 -0
- package/src/calls/relay-server.ts +466 -8
- package/src/calls/speaker-identification.ts +1 -1
- package/src/calls/twilio-config.ts +7 -5
- package/src/calls/twilio-provider.ts +6 -4
- package/src/calls/twilio-rest.ts +40 -15
- package/src/calls/twilio-routes.ts +60 -45
- package/src/calls/types.ts +3 -1
- package/src/channels/types.ts +25 -0
- package/src/cli/amazon.ts +815 -0
- package/src/cli/config-commands.ts +2 -2
- package/src/cli/core-commands.ts +4 -3
- package/src/cli/influencer.ts +244 -0
- package/src/cli/map.ts +89 -6
- package/src/cli.ts +1 -1
- package/src/config/agent-schema.ts +171 -0
- package/src/config/bundled-skills/amazon/SKILL.md +127 -0
- package/src/config/bundled-skills/amazon/icon.svg +13 -0
- package/src/config/bundled-skills/api-mapping/SKILL.md +78 -0
- package/src/config/bundled-skills/browser/SKILL.md +1 -0
- package/src/config/bundled-skills/browser/TOOLS.json +17 -0
- package/src/config/bundled-skills/browser/tools/browser-wait-for-download.ts +25 -0
- package/src/config/bundled-skills/doordash/SKILL.md +51 -51
- package/src/config/bundled-skills/email-setup/SKILL.md +14 -5
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +183 -0
- package/src/config/bundled-skills/influencer/SKILL.md +144 -0
- package/src/config/bundled-skills/macos-automation/icon.svg +12 -0
- package/src/config/bundled-skills/media-processing/SKILL.md +72 -95
- package/src/config/bundled-skills/media-processing/TOOLS.json +57 -147
- package/src/config/bundled-skills/media-processing/__tests__/concurrency-pool.test.ts +77 -0
- package/src/config/bundled-skills/media-processing/__tests__/cost-tracker.test.ts +69 -0
- package/src/config/bundled-skills/media-processing/__tests__/preprocess.test.ts +303 -0
- package/src/config/bundled-skills/media-processing/services/concurrency-pool.ts +55 -0
- package/src/config/bundled-skills/media-processing/services/cost-tracker.ts +86 -0
- package/src/config/bundled-skills/media-processing/services/gemini-map.ts +339 -0
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +551 -0
- package/src/config/bundled-skills/media-processing/services/processing-pipeline.ts +7 -9
- package/src/config/bundled-skills/media-processing/services/reduce.ts +197 -0
- package/src/config/bundled-skills/media-processing/tools/analyze-keyframes.ts +88 -253
- package/src/config/bundled-skills/media-processing/tools/extract-keyframes.ts +22 -153
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +28 -51
- package/src/config/bundled-skills/media-processing/tools/query-media-events.ts +35 -270
- package/src/config/bundled-skills/messaging/SKILL.md +12 -2
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +4 -7
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +2 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +86 -21
- package/src/config/bundled-skills/twitter/icon.svg +14 -0
- package/src/config/bundled-tool-registry.ts +310 -0
- package/src/config/calls-schema.ts +181 -0
- package/src/config/core-schema.ts +309 -0
- package/src/config/defaults.ts +27 -3
- package/src/config/env-registry.ts +169 -0
- package/src/config/env.ts +175 -0
- package/src/config/loader.ts +6 -6
- package/src/config/memory-schema.ts +528 -0
- package/src/config/sandbox-schema.ts +55 -0
- package/src/config/schema.ts +157 -1138
- package/src/config/skill-state.ts +1 -1
- package/src/config/skills-schema.ts +32 -0
- package/src/config/skills.ts +35 -24
- package/src/config/system-prompt.ts +107 -56
- package/src/config/templates/SOUL.md +1 -1
- package/src/config/types.ts +1 -0
- package/src/config/user-reference.ts +4 -9
- package/src/config/vellum-skills/catalog.json +0 -7
- package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +5 -1
- package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +1 -0
- package/src/config/vellum-skills/sms-setup/SKILL.md +112 -14
- package/src/context/window-manager.ts +27 -7
- package/src/daemon/approval-generators.ts +186 -0
- package/src/daemon/approved-devices-store.ts +140 -0
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/classifier.ts +35 -32
- package/src/daemon/config-watcher.ts +1 -1
- package/src/daemon/daemon-control.ts +254 -0
- package/src/daemon/handlers/apps.ts +2 -3
- package/src/daemon/handlers/config-channels.ts +158 -0
- package/src/daemon/handlers/config-inbox.ts +540 -0
- package/src/daemon/handlers/config-ingress.ts +231 -0
- package/src/daemon/handlers/config-integrations.ts +258 -0
- package/src/daemon/handlers/config-model.ts +143 -0
- package/src/daemon/handlers/config-parental.ts +163 -0
- package/src/daemon/handlers/config-scheduling.ts +172 -0
- package/src/daemon/handlers/config-slack.ts +92 -0
- package/src/daemon/handlers/config-telegram.ts +301 -0
- package/src/daemon/handlers/config-tools.ts +177 -0
- package/src/daemon/handlers/config-trust.ts +104 -0
- package/src/daemon/handlers/config-twilio.ts +1080 -0
- package/src/daemon/handlers/config.ts +53 -2463
- package/src/daemon/handlers/diagnostics.ts +1 -1
- package/src/daemon/handlers/dictation.ts +4 -6
- package/src/daemon/handlers/documents.ts +18 -32
- package/src/daemon/handlers/index.ts +9 -0
- package/src/daemon/handlers/misc.ts +3 -5
- package/src/daemon/handlers/pairing.ts +98 -0
- package/src/daemon/handlers/sessions.ts +74 -5
- package/src/daemon/handlers/shared.ts +3 -1
- package/src/daemon/handlers/skills.ts +1 -1
- package/src/daemon/handlers/twitter-auth.ts +2 -0
- package/src/daemon/handlers/work-items.ts +2 -2
- package/src/daemon/handlers/workspace-files.ts +4 -3
- package/src/daemon/install-cli-launchers.ts +113 -0
- package/src/daemon/ipc-contract/apps.ts +356 -0
- package/src/daemon/ipc-contract/browser.ts +74 -0
- package/src/daemon/ipc-contract/computer-use.ts +151 -0
- package/src/daemon/ipc-contract/diagnostics.ts +56 -0
- package/src/daemon/ipc-contract/documents.ts +74 -0
- package/src/daemon/ipc-contract/inbox.ts +209 -0
- package/src/daemon/ipc-contract/integrations.ts +284 -0
- package/src/daemon/ipc-contract/memory.ts +48 -0
- package/src/daemon/ipc-contract/messages.ts +211 -0
- package/src/daemon/ipc-contract/pairing.ts +45 -0
- package/src/daemon/ipc-contract/parental-control.ts +95 -0
- package/src/daemon/ipc-contract/schedules.ts +97 -0
- package/src/daemon/ipc-contract/sessions.ts +321 -0
- package/src/daemon/ipc-contract/shared.ts +42 -0
- package/src/daemon/ipc-contract/skills.ts +120 -0
- package/src/daemon/ipc-contract/subagents.ts +58 -0
- package/src/daemon/ipc-contract/surfaces.ts +250 -0
- package/src/daemon/ipc-contract/trust.ts +60 -0
- package/src/daemon/ipc-contract/work-items.ts +225 -0
- package/src/daemon/ipc-contract/workspace.ts +113 -0
- package/src/daemon/ipc-contract-inventory.json +62 -0
- package/src/daemon/ipc-contract-inventory.ts +55 -29
- package/src/daemon/ipc-contract.ts +227 -2527
- package/src/daemon/ipc-protocol.ts +1 -1
- package/src/daemon/ipc-validate.ts +7 -0
- package/src/daemon/lifecycle.ts +97 -379
- package/src/daemon/pairing-store.ts +177 -0
- package/src/daemon/providers-setup.ts +43 -0
- package/src/daemon/ride-shotgun-handler.ts +67 -2
- package/src/daemon/server.ts +60 -44
- package/src/daemon/session-agent-loop-handlers.ts +421 -0
- package/src/daemon/session-agent-loop.ts +113 -275
- package/src/daemon/session-dynamic-profile.ts +1 -1
- package/src/daemon/session-history.ts +1 -1
- package/src/daemon/session-media-retry.ts +1 -1
- package/src/daemon/session-messaging.ts +37 -2
- package/src/daemon/session-notifiers.ts +5 -25
- package/src/daemon/session-process.ts +99 -59
- package/src/daemon/session-queue-manager.ts +98 -4
- package/src/daemon/session-runtime-assembly.ts +149 -15
- package/src/daemon/session-surfaces.ts +26 -4
- package/src/daemon/session-tool-setup.ts +28 -30
- package/src/daemon/session-workspace.ts +1 -1
- package/src/daemon/session.ts +24 -1
- package/src/daemon/shutdown-handlers.ts +122 -0
- package/src/daemon/trace-emitter.ts +1 -1
- package/src/daemon/watch-handler.ts +36 -33
- package/src/doordash/cart-queries.ts +787 -0
- package/src/doordash/client.ts +144 -127
- package/src/doordash/order-queries.ts +85 -0
- package/src/doordash/queries.ts +10 -1308
- package/src/doordash/search-queries.ts +203 -0
- package/src/doordash/session.ts +3 -2
- package/src/doordash/store-queries.ts +246 -0
- package/src/doordash/types.ts +367 -0
- package/src/email/providers/agentmail.ts +2 -1
- package/src/email/providers/index.ts +3 -2
- package/src/email/service.ts +3 -2
- package/src/errors.ts +43 -0
- package/src/home-base/prebuilt/seed.ts +1 -1
- package/src/hooks/cli.ts +6 -5
- package/src/hooks/config.ts +6 -8
- package/src/hooks/discovery.ts +6 -5
- package/src/hooks/manager.ts +4 -3
- package/src/hooks/runner.ts +2 -2
- package/src/hooks/templates.ts +5 -5
- package/src/inbound/public-ingress-urls.ts +3 -1
- package/src/index.ts +4 -2
- package/src/influencer/client.ts +1104 -0
- package/src/instrument.ts +4 -3
- package/src/logfire.ts +4 -3
- package/src/memory/admin.ts +25 -35
- package/src/memory/attachments-store.ts +4 -7
- package/src/memory/channel-delivery-store.ts +30 -1
- package/src/memory/channel-guardian-store.ts +200 -1
- package/src/memory/clarification-resolver.ts +37 -33
- package/src/memory/conflict-store.ts +67 -61
- package/src/memory/contradiction-checker.ts +141 -117
- package/src/memory/conversation-store.ts +335 -51
- package/src/memory/db-connection.ts +27 -4
- package/src/memory/db-init.ts +121 -4
- package/src/memory/db.ts +14 -1
- package/src/memory/embedding-backend.ts +27 -5
- package/src/memory/embedding-ollama.ts +2 -1
- package/src/memory/entity-extractor.ts +38 -35
- package/src/memory/guardian-action-store.ts +430 -0
- package/src/memory/inbox-escalation-projection.ts +59 -0
- package/src/memory/inbox-thread-store.ts +218 -0
- package/src/memory/ingress-invite-store.ts +338 -0
- package/src/memory/ingress-member-store.ts +350 -0
- package/src/memory/items-extractor.ts +91 -97
- package/src/memory/job-handlers/index-maintenance.ts +3 -3
- package/src/memory/job-handlers/media-processing.ts +11 -42
- package/src/memory/job-handlers/summarization.ts +32 -26
- package/src/memory/job-utils.ts +3 -10
- package/src/memory/jobs-store.ts +6 -9
- package/src/memory/jobs-worker.ts +51 -36
- package/src/memory/migrations/001-job-deferrals.ts +45 -0
- package/src/memory/migrations/002-tool-invocations-fk.ts +43 -0
- package/src/memory/migrations/003-memory-fts-backfill.ts +24 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +87 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +80 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +62 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +254 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +208 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +83 -0
- package/src/memory/migrations/010-ext-conv-bindings-channel-chat-unique.ts +56 -0
- package/src/memory/migrations/011-call-sessions-provider-sid-dedup.ts +63 -0
- package/src/memory/migrations/012-call-sessions-add-initiated-from.ts +19 -0
- package/src/memory/migrations/013-guardian-action-tables.ts +68 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +76 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +27 -0
- package/src/memory/migrations/016-memory-segments-indexes.ts +11 -0
- package/src/memory/migrations/017-memory-items-indexes.ts +12 -0
- package/src/memory/migrations/018-remaining-table-indexes.ts +13 -0
- package/src/memory/migrations/index.ts +24 -0
- package/src/memory/migrations/registry.ts +79 -0
- package/src/memory/migrations/validate-migration-state.ts +69 -0
- package/src/memory/qdrant-manager.ts +49 -8
- package/src/memory/query-builder.ts +1 -1
- package/src/memory/raw-query.ts +119 -0
- package/src/memory/recall-cache.ts +4 -1
- package/src/memory/retriever.ts +163 -47
- package/src/memory/schema-migration.ts +25 -984
- package/src/memory/schema.ts +130 -7
- package/src/memory/search/entity.ts +10 -19
- package/src/memory/search/lexical.ts +81 -52
- package/src/memory/search/ranking.ts +21 -22
- package/src/memory/search/semantic.ts +157 -19
- package/src/memory/shared-app-links-store.ts +4 -5
- package/src/memory/validation.ts +19 -0
- package/src/messaging/draft-store.ts +5 -6
- package/src/messaging/providers/sms/adapter.ts +3 -6
- package/src/messaging/providers/telegram-bot/adapter.ts +2 -5
- package/src/messaging/providers/whatsapp/adapter.ts +136 -0
- package/src/messaging/providers/whatsapp/client.ts +67 -0
- package/src/messaging/style-analyzer.ts +5 -4
- package/src/messaging/thread-summarizer.ts +61 -69
- package/src/messaging/triage-engine.ts +62 -71
- package/src/migrations/config-merge.ts +53 -0
- package/src/migrations/data-layout.ts +68 -0
- package/src/migrations/data-merge.ts +33 -0
- package/src/migrations/hooks-merge.ts +90 -0
- package/src/migrations/index.ts +6 -0
- package/src/migrations/log.ts +23 -0
- package/src/migrations/skills-merge.ts +33 -0
- package/src/migrations/workspace-layout.ts +79 -0
- package/src/permissions/checker.ts +126 -11
- package/src/permissions/prompter.ts +14 -0
- package/src/permissions/shell-identity.ts +31 -1
- package/src/permissions/trust-store.ts +21 -1
- package/src/providers/anthropic/client.ts +4 -4
- package/src/providers/failover.ts +2 -2
- package/src/providers/model-intents.ts +70 -0
- package/src/providers/ollama/client.ts +2 -1
- package/src/providers/provider-send-message.ts +176 -0
- package/src/providers/registry.ts +71 -30
- package/src/providers/retry.ts +35 -1
- package/src/providers/types.ts +12 -1
- package/src/runtime/approval-conversation-turn.ts +97 -0
- package/src/runtime/approval-message-composer.ts +115 -5
- package/src/runtime/assistant-event-hub.ts +3 -1
- package/src/runtime/channel-approval-parser.ts +36 -2
- package/src/runtime/channel-approvals.ts +0 -21
- package/src/runtime/channel-guardian-service.ts +48 -7
- package/src/runtime/channel-readiness-service.ts +160 -34
- package/src/runtime/channel-readiness-types.ts +10 -4
- package/src/runtime/channel-retry-sweep.ts +184 -0
- package/src/runtime/guardian-context-resolver.ts +108 -0
- package/src/runtime/http-server.ts +289 -745
- package/src/runtime/http-types.ts +56 -3
- package/src/runtime/middleware/auth.ts +116 -0
- package/src/runtime/middleware/error-handler.ts +33 -0
- package/src/runtime/middleware/twilio-validation.ts +127 -0
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/call-routes.ts +49 -6
- package/src/runtime/routes/channel-delivery-routes.ts +170 -0
- package/src/runtime/routes/channel-guardian-routes.ts +1191 -0
- package/src/runtime/routes/channel-inbound-routes.ts +1152 -0
- package/src/runtime/routes/channel-route-shared.ts +144 -0
- package/src/runtime/routes/channel-routes.ts +32 -1634
- package/src/runtime/routes/conversation-routes.ts +50 -7
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +126 -0
- package/src/runtime/routes/pairing-routes.ts +144 -0
- package/src/runtime/routes/run-routes.ts +15 -1
- package/src/runtime/run-orchestrator.ts +52 -34
- package/src/schedule/schedule-store.ts +36 -32
- package/src/schedule/scheduler.ts +3 -3
- package/src/security/encrypted-store.ts +5 -7
- package/src/security/oauth2.ts +45 -15
- package/src/security/parental-control-store.ts +183 -0
- package/src/security/secret-allowlist.ts +4 -3
- package/src/security/secret-scanner.ts +5 -5
- package/src/security/secure-keys.ts +1 -1
- package/src/security/token-manager.ts +3 -2
- package/src/services/vercel-deploy.ts +6 -2
- package/src/skills/tool-manifest.ts +3 -3
- package/src/skills/vellum-catalog-remote.ts +75 -16
- package/src/slack/slack-webhook.ts +2 -1
- package/src/swarm/orchestrator.ts +92 -1
- package/src/swarm/router-planner.ts +6 -9
- package/src/swarm/worker-prompts.ts +9 -12
- package/src/tasks/task-compiler.ts +19 -28
- package/src/tasks/task-runner.ts +1 -1
- package/src/tools/assets/search.ts +15 -14
- package/src/tools/browser/__tests__/auth-detector.test.ts +1 -0
- package/src/tools/browser/auto-navigate.ts +1 -0
- package/src/tools/browser/browser-execution.ts +13 -1
- package/src/tools/browser/browser-manager.ts +119 -4
- package/src/tools/browser/network-recorder.ts +5 -0
- package/src/tools/credentials/broker.ts +11 -2
- package/src/tools/credentials/metadata-store.ts +18 -14
- package/src/tools/credentials/post-connect-hooks.ts +61 -0
- package/src/tools/credentials/vault.ts +49 -23
- package/src/tools/executor.ts +80 -18
- package/src/tools/host-terminal/cli-discover.ts +1 -1
- package/src/tools/network/script-proxy/http-forwarder.ts +1 -1
- package/src/tools/network/script-proxy/mitm-handler.ts +1 -1
- package/src/tools/network/script-proxy/server.ts +1 -1
- package/src/tools/network/script-proxy/session-manager.ts +6 -5
- package/src/tools/network/web-fetch.ts +18 -2
- package/src/tools/network/web-search.ts +7 -3
- package/src/tools/reminder/reminder-store.ts +14 -15
- package/src/tools/schedule/create.ts +1 -0
- package/src/tools/schedule/list.ts +2 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +5 -7
- package/src/tools/skills/skill-script-runner.ts +24 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -0
- package/src/tools/tasks/work-item-enqueue.ts +2 -2
- package/src/tools/terminal/evaluate-typescript.ts +21 -12
- package/src/tools/terminal/parser.ts +50 -0
- package/src/tools/watcher/delete.ts +6 -0
- package/src/tools/weather/service.ts +1 -1
- package/src/twitter/client.ts +190 -24
- package/src/twitter/session.ts +4 -3
- package/src/util/clipboard.ts +1 -1
- package/src/util/errors.ts +65 -8
- package/src/util/fs.ts +40 -0
- package/src/util/json.ts +10 -0
- package/src/util/log-redact.ts +189 -0
- package/src/util/logger.ts +25 -18
- package/src/util/object.ts +3 -0
- package/src/util/platform.ts +72 -365
- package/src/util/pricing.ts +1 -1
- package/src/util/promise-guard.ts +1 -1
- package/src/util/retry.ts +19 -0
- package/src/util/row-mapper.ts +79 -0
- package/src/util/silently.ts +21 -0
- package/src/watcher/engine.ts +5 -1
- package/src/watcher/provider-types.ts +20 -0
- package/src/watcher/providers/github.ts +156 -0
- package/src/watcher/providers/gmail.ts +1 -0
- package/src/watcher/providers/google-calendar.ts +1 -0
- package/src/watcher/providers/linear.ts +460 -0
- package/src/watcher/providers/slack.ts +1 -0
- package/src/work-items/work-item-runner.ts +1 -1
- package/src/workspace/git-service.ts +1 -1
- package/src/workspace/provider-commit-message-generator.ts +51 -22
- package/src/__tests__/call-bridge.test.ts +0 -517
- package/src/__tests__/session-process-bridge.test.ts +0 -244
- package/src/calls/call-bridge.ts +0 -168
- package/src/config/bundled-skills/media-processing/services/capability-registry.ts +0 -137
- package/src/config/bundled-skills/media-processing/services/event-detection-service.ts +0 -280
- package/src/config/bundled-skills/media-processing/services/feedback-aggregation.ts +0 -144
- package/src/config/bundled-skills/media-processing/services/feedback-store.ts +0 -136
- package/src/config/bundled-skills/media-processing/services/retrieval-service.ts +0 -95
- package/src/config/bundled-skills/media-processing/services/timeline-service.ts +0 -267
- package/src/config/bundled-skills/media-processing/tools/detect-events.ts +0 -110
- package/src/config/bundled-skills/media-processing/tools/recalibrate.ts +0 -235
- package/src/config/bundled-skills/media-processing/tools/select-tracking-profile.ts +0 -142
- package/src/config/bundled-skills/media-processing/tools/submit-feedback.ts +0 -150
- package/src/config/vellum-skills/google-oauth-setup/SKILL.md +0 -199
package/src/memory/db-init.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getDb } from './db-connection.js';
|
|
1
|
+
import { getDb, getSqliteFrom } from './db-connection.js';
|
|
3
2
|
import { getLogger } from '../util/logger.js';
|
|
4
3
|
import {
|
|
5
4
|
migrateJobDeferrals,
|
|
@@ -12,7 +11,15 @@ import {
|
|
|
12
11
|
migrateLlmUsageEventsDropAssistantId,
|
|
13
12
|
migrateExtConvBindingsChannelChatUnique,
|
|
14
13
|
migrateCallSessionsProviderSidDedup,
|
|
14
|
+
migrateCallSessionsAddInitiatedFrom,
|
|
15
15
|
migrateMemoryFtsBackfill,
|
|
16
|
+
migrateGuardianActionTables,
|
|
17
|
+
migrateBackfillInboxThreadStateFromBindings,
|
|
18
|
+
migrateDropActiveSearchIndex,
|
|
19
|
+
migrateMemorySegmentsIndexes,
|
|
20
|
+
migrateMemoryItemsIndexes,
|
|
21
|
+
migrateRemainingTableIndexes,
|
|
22
|
+
validateMigrationState,
|
|
16
23
|
} from './schema-migration.js';
|
|
17
24
|
|
|
18
25
|
const log = getLogger('memory-db');
|
|
@@ -31,7 +38,8 @@ export function initializeDb(): void {
|
|
|
31
38
|
total_estimated_cost REAL NOT NULL DEFAULT 0,
|
|
32
39
|
context_summary TEXT,
|
|
33
40
|
context_compacted_message_count INTEGER NOT NULL DEFAULT 0,
|
|
34
|
-
context_compacted_at INTEGER
|
|
41
|
+
context_compacted_at INTEGER,
|
|
42
|
+
source TEXT NOT NULL DEFAULT 'user'
|
|
35
43
|
)
|
|
36
44
|
`);
|
|
37
45
|
|
|
@@ -524,7 +532,9 @@ export function initializeDb(): void {
|
|
|
524
532
|
try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN retry_after INTEGER`); } catch { /* already exists */ }
|
|
525
533
|
try { database.run(/*sql*/ `ALTER TABLE channel_inbound_events ADD COLUMN raw_payload TEXT`); } catch { /* already exists */ }
|
|
526
534
|
try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN thread_type TEXT NOT NULL DEFAULT 'standard'`); } catch { /* already exists */ }
|
|
535
|
+
try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN source TEXT NOT NULL DEFAULT 'user'`); } catch { /* already exists */ }
|
|
527
536
|
try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN memory_scope_id TEXT NOT NULL DEFAULT 'default'`); } catch { /* already exists */ }
|
|
537
|
+
try { database.run(/*sql*/ `ALTER TABLE conversations ADD COLUMN origin_channel TEXT`); } catch { /* already exists */ }
|
|
528
538
|
try { database.run(/*sql*/ `ALTER TABLE attachments ADD COLUMN thumbnail_base64 TEXT`); } catch { /* already exists */ }
|
|
529
539
|
try { database.run(/*sql*/ `ALTER TABLE cron_jobs ADD COLUMN schedule_syntax TEXT NOT NULL DEFAULT 'cron'`); } catch { /* already exists */ }
|
|
530
540
|
try { database.run(/*sql*/ `ALTER TABLE messages ADD COLUMN metadata TEXT`); } catch { /* already exists */ }
|
|
@@ -542,6 +552,7 @@ export function initializeDb(): void {
|
|
|
542
552
|
// Indexes for query performance on large datasets
|
|
543
553
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_request_logs_conv_created ON llm_request_logs(conversation_id, created_at)`);
|
|
544
554
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_messages_conversation_id ON messages(conversation_id)`);
|
|
555
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_messages_created_at ON messages(created_at)`);
|
|
545
556
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_tool_invocations_conversation_id ON tool_invocations(conversation_id)`);
|
|
546
557
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_conversations_updated_at ON conversations(updated_at)`);
|
|
547
558
|
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_segments_message_segment ON memory_segments(message_id, segment_index)`);
|
|
@@ -558,10 +569,21 @@ export function initializeDb(): void {
|
|
|
558
569
|
WHERE status = 'pending_clarification'
|
|
559
570
|
`);
|
|
560
571
|
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_memory_items_fingerprint_scope ON memory_items(fingerprint, scope_id)`);
|
|
572
|
+
database.run(/*sql*/ `DROP INDEX IF EXISTS idx_memory_items_fingerprint`);
|
|
561
573
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_kind_status ON memory_items(kind, status)`);
|
|
562
574
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_status_invalid_at ON memory_items(status, invalid_at)`);
|
|
563
575
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_scope_status_kind ON memory_items(scope_id, status, kind)`);
|
|
576
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_scope_kind_status ON memory_items(scope_id, kind, status)`);
|
|
564
577
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_items_last_seen_at ON memory_items(last_seen_at)`);
|
|
578
|
+
// Partial covering index for directItemSearch: the LIKE '%term%' pattern can't
|
|
579
|
+
// seek a B-tree, but this index lets SQLite scan only active non-invalidated rows
|
|
580
|
+
// and evaluate LIKE + return columns without touching the main table.
|
|
581
|
+
migrateDropActiveSearchIndex(database);
|
|
582
|
+
database.run(/*sql*/ `
|
|
583
|
+
CREATE INDEX IF NOT EXISTS idx_memory_items_active_search
|
|
584
|
+
ON memory_items(status, invalid_at, last_seen_at DESC, subject, statement, id, kind, confidence, importance, first_seen_at, scope_id)
|
|
585
|
+
WHERE status = 'active' AND invalid_at IS NULL
|
|
586
|
+
`);
|
|
565
587
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_embeddings_target ON memory_embeddings(target_type, target_id)`);
|
|
566
588
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_embeddings_provider_model ON memory_embeddings(provider, model)`);
|
|
567
589
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_memory_embeddings_content_hash ON memory_embeddings(content_hash, provider, model)`);
|
|
@@ -583,7 +605,7 @@ export function initializeDb(): void {
|
|
|
583
605
|
// Deduplicate before creating unique index — existing DBs may have duplicate content_hash values.
|
|
584
606
|
// Re-point message_attachments to the survivor (MIN rowid per content_hash), then delete dupes.
|
|
585
607
|
{
|
|
586
|
-
const raw = (database
|
|
608
|
+
const raw = getSqliteFrom(database);
|
|
587
609
|
raw.exec(/*sql*/ `
|
|
588
610
|
UPDATE message_attachments
|
|
589
611
|
SET attachment_id = (
|
|
@@ -782,6 +804,12 @@ export function initializeDb(): void {
|
|
|
782
804
|
try { database.run(/*sql*/ `ALTER TABLE call_sessions ADD COLUMN caller_identity_mode TEXT`); } catch { /* already exists */ }
|
|
783
805
|
try { database.run(/*sql*/ `ALTER TABLE call_sessions ADD COLUMN caller_identity_source TEXT`); } catch { /* already exists */ }
|
|
784
806
|
|
|
807
|
+
// Persist assistantId so the webhook path can resolve assistant-scoped Twilio numbers
|
|
808
|
+
try { database.run(/*sql*/ `ALTER TABLE call_sessions ADD COLUMN assistant_id TEXT`); } catch { /* already exists */ }
|
|
809
|
+
|
|
810
|
+
// Track which conversation initiated the call (the chat where call_start was invoked)
|
|
811
|
+
migrateCallSessionsAddInitiatedFrom(database);
|
|
812
|
+
|
|
785
813
|
// Unique constraint: at most one non-null provider_call_sid per (provider, provider_call_sid).
|
|
786
814
|
// On upgraded databases that pre-date this constraint, duplicate rows may exist; deduplicate
|
|
787
815
|
// them first to avoid a UNIQUE constraint failure that would prevent startup.
|
|
@@ -1159,5 +1187,94 @@ export function initializeDb(): void {
|
|
|
1159
1187
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_media_event_feedback_event_id ON media_event_feedback(event_id)`);
|
|
1160
1188
|
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_media_event_feedback_type ON media_event_feedback(asset_id, feedback_type)`);
|
|
1161
1189
|
|
|
1190
|
+
// ── Assistant Inbox ──────────────────────────────────────────────────
|
|
1191
|
+
|
|
1192
|
+
database.run(/*sql*/ `
|
|
1193
|
+
CREATE TABLE IF NOT EXISTS assistant_ingress_invites (
|
|
1194
|
+
id TEXT PRIMARY KEY,
|
|
1195
|
+
assistant_id TEXT NOT NULL DEFAULT 'self',
|
|
1196
|
+
source_channel TEXT NOT NULL,
|
|
1197
|
+
token_hash TEXT NOT NULL,
|
|
1198
|
+
created_by_session_id TEXT,
|
|
1199
|
+
note TEXT,
|
|
1200
|
+
max_uses INTEGER NOT NULL DEFAULT 1 CHECK (max_uses > 0),
|
|
1201
|
+
use_count INTEGER NOT NULL DEFAULT 0 CHECK (use_count >= 0),
|
|
1202
|
+
expires_at INTEGER NOT NULL,
|
|
1203
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
1204
|
+
redeemed_by_external_user_id TEXT,
|
|
1205
|
+
redeemed_by_external_chat_id TEXT,
|
|
1206
|
+
redeemed_at INTEGER,
|
|
1207
|
+
created_at INTEGER NOT NULL,
|
|
1208
|
+
updated_at INTEGER NOT NULL
|
|
1209
|
+
)
|
|
1210
|
+
`);
|
|
1211
|
+
|
|
1212
|
+
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_ingress_invites_token_hash ON assistant_ingress_invites(token_hash)`);
|
|
1213
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_ingress_invites_channel_status ON assistant_ingress_invites(assistant_id, source_channel, status, expires_at)`);
|
|
1214
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_ingress_invites_channel_created ON assistant_ingress_invites(assistant_id, source_channel, created_at)`);
|
|
1215
|
+
|
|
1216
|
+
database.run(/*sql*/ `
|
|
1217
|
+
CREATE TABLE IF NOT EXISTS assistant_ingress_members (
|
|
1218
|
+
id TEXT PRIMARY KEY,
|
|
1219
|
+
assistant_id TEXT NOT NULL DEFAULT 'self',
|
|
1220
|
+
source_channel TEXT NOT NULL,
|
|
1221
|
+
external_user_id TEXT,
|
|
1222
|
+
external_chat_id TEXT,
|
|
1223
|
+
display_name TEXT,
|
|
1224
|
+
username TEXT,
|
|
1225
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
1226
|
+
policy TEXT NOT NULL DEFAULT 'allow',
|
|
1227
|
+
invite_id TEXT REFERENCES assistant_ingress_invites(id),
|
|
1228
|
+
created_by_session_id TEXT,
|
|
1229
|
+
revoked_reason TEXT,
|
|
1230
|
+
blocked_reason TEXT,
|
|
1231
|
+
last_seen_at INTEGER,
|
|
1232
|
+
created_at INTEGER NOT NULL,
|
|
1233
|
+
updated_at INTEGER NOT NULL,
|
|
1234
|
+
CHECK (external_user_id IS NOT NULL OR external_chat_id IS NOT NULL)
|
|
1235
|
+
)
|
|
1236
|
+
`);
|
|
1237
|
+
|
|
1238
|
+
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_ingress_members_user ON assistant_ingress_members(assistant_id, source_channel, external_user_id) WHERE external_user_id IS NOT NULL`);
|
|
1239
|
+
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_ingress_members_chat ON assistant_ingress_members(assistant_id, source_channel, external_chat_id) WHERE external_chat_id IS NOT NULL`);
|
|
1240
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_ingress_members_status_policy ON assistant_ingress_members(assistant_id, source_channel, status, policy)`);
|
|
1241
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_ingress_members_updated ON assistant_ingress_members(assistant_id, source_channel, updated_at)`);
|
|
1242
|
+
|
|
1243
|
+
database.run(/*sql*/ `
|
|
1244
|
+
CREATE TABLE IF NOT EXISTS assistant_inbox_thread_state (
|
|
1245
|
+
conversation_id TEXT PRIMARY KEY REFERENCES conversations(id) ON DELETE CASCADE,
|
|
1246
|
+
assistant_id TEXT NOT NULL DEFAULT 'self',
|
|
1247
|
+
source_channel TEXT NOT NULL,
|
|
1248
|
+
external_chat_id TEXT NOT NULL,
|
|
1249
|
+
external_user_id TEXT,
|
|
1250
|
+
display_name TEXT,
|
|
1251
|
+
username TEXT,
|
|
1252
|
+
last_inbound_at INTEGER,
|
|
1253
|
+
last_outbound_at INTEGER,
|
|
1254
|
+
last_message_at INTEGER,
|
|
1255
|
+
unread_count INTEGER NOT NULL DEFAULT 0,
|
|
1256
|
+
pending_escalation_count INTEGER NOT NULL DEFAULT 0,
|
|
1257
|
+
has_pending_escalation INTEGER NOT NULL DEFAULT 0,
|
|
1258
|
+
created_at INTEGER NOT NULL,
|
|
1259
|
+
updated_at INTEGER NOT NULL
|
|
1260
|
+
)
|
|
1261
|
+
`);
|
|
1262
|
+
|
|
1263
|
+
database.run(/*sql*/ `CREATE UNIQUE INDEX IF NOT EXISTS idx_inbox_thread_state_channel ON assistant_inbox_thread_state(assistant_id, source_channel, external_chat_id)`);
|
|
1264
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_inbox_thread_state_last_msg ON assistant_inbox_thread_state(assistant_id, last_message_at)`);
|
|
1265
|
+
database.run(/*sql*/ `CREATE INDEX IF NOT EXISTS idx_inbox_thread_state_escalation ON assistant_inbox_thread_state(assistant_id, has_pending_escalation, last_message_at)`);
|
|
1266
|
+
|
|
1267
|
+
migrateBackfillInboxThreadStateFromBindings(database);
|
|
1268
|
+
|
|
1269
|
+
migrateGuardianActionTables(database);
|
|
1270
|
+
|
|
1162
1271
|
migrateMemoryFtsBackfill(database);
|
|
1272
|
+
|
|
1273
|
+
migrateMemorySegmentsIndexes(database);
|
|
1274
|
+
|
|
1275
|
+
migrateMemoryItemsIndexes(database);
|
|
1276
|
+
|
|
1277
|
+
migrateRemainingTableIndexes(database);
|
|
1278
|
+
|
|
1279
|
+
validateMigrationState(database);
|
|
1163
1280
|
}
|
package/src/memory/db.ts
CHANGED
|
@@ -1,2 +1,15 @@
|
|
|
1
|
-
export { getDb, resetDb } from './db-connection.js';
|
|
1
|
+
export { getDb, resetDb, getSqlite, getSqliteFrom, type DrizzleDb } from './db-connection.js';
|
|
2
2
|
export { initializeDb } from './db-init.js';
|
|
3
|
+
export {
|
|
4
|
+
rawGet,
|
|
5
|
+
rawAll,
|
|
6
|
+
rawRun,
|
|
7
|
+
rawExec,
|
|
8
|
+
rawChanges,
|
|
9
|
+
rawGetFrom,
|
|
10
|
+
rawAllFrom,
|
|
11
|
+
rawRunFrom,
|
|
12
|
+
rawExecFrom,
|
|
13
|
+
rawPrepare,
|
|
14
|
+
rawPrepareFrom,
|
|
15
|
+
} from './raw-query.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import type { AssistantConfig } from '../config/types.js';
|
|
3
3
|
import { getLogger } from '../util/logger.js';
|
|
4
|
+
import { getOllamaBaseUrlEnv } from '../config/env.js';
|
|
4
5
|
import { GeminiEmbeddingBackend } from './embedding-gemini.js';
|
|
5
6
|
import { LocalEmbeddingBackend } from './embedding-local.js';
|
|
6
7
|
import { OllamaEmbeddingBackend } from './embedding-ollama.js';
|
|
@@ -14,8 +15,17 @@ const backendCache = new Map<string, EmbeddingBackend>();
|
|
|
14
15
|
// ── In-memory embedding vector cache ──────────────────────────────
|
|
15
16
|
// LRU cache keyed by sha256(provider + model + text) → embedding vector.
|
|
16
17
|
// Avoids redundant API calls / local compute for identical content.
|
|
17
|
-
|
|
18
|
+
// Eviction is based on estimated byte size (32 MB cap) rather than entry count,
|
|
19
|
+
// since vector dimensions vary across providers/models.
|
|
20
|
+
const VECTOR_CACHE_MAX_BYTES = 33_554_432; // 32 MB
|
|
18
21
|
const vectorCache = new Map<string, number[]>();
|
|
22
|
+
let vectorCacheBytes = 0;
|
|
23
|
+
|
|
24
|
+
/** Estimate in-memory byte cost of a single cache entry. */
|
|
25
|
+
function estimateEntryBytes(key: string, vector: number[]): number {
|
|
26
|
+
// key: UTF-16 chars (2 bytes each) + vector: 8 bytes per float64
|
|
27
|
+
return key.length * 2 + vector.length * 8;
|
|
28
|
+
}
|
|
19
29
|
|
|
20
30
|
function vectorCacheKey(provider: string, model: string, text: string): string {
|
|
21
31
|
return createHash('sha256').update(`${provider}\0${model}\0${text}`).digest('hex');
|
|
@@ -34,18 +44,30 @@ function getFromVectorCache(provider: string, model: string, text: string): numb
|
|
|
34
44
|
|
|
35
45
|
function putInVectorCache(provider: string, model: string, text: string, vector: number[]): void {
|
|
36
46
|
const key = vectorCacheKey(provider, model, text);
|
|
37
|
-
|
|
38
|
-
|
|
47
|
+
// If replacing an existing entry, subtract its old cost first
|
|
48
|
+
const existing = vectorCache.get(key);
|
|
49
|
+
if (existing !== undefined) {
|
|
50
|
+
vectorCacheBytes -= estimateEntryBytes(key, existing);
|
|
51
|
+
vectorCache.delete(key);
|
|
52
|
+
}
|
|
53
|
+
const entryBytes = estimateEntryBytes(key, vector);
|
|
54
|
+
// Evict oldest entries until we have room
|
|
55
|
+
while (vectorCacheBytes + entryBytes > VECTOR_CACHE_MAX_BYTES && vectorCache.size > 0) {
|
|
39
56
|
const oldest = vectorCache.keys().next().value;
|
|
40
|
-
if (oldest
|
|
57
|
+
if (oldest === undefined) break;
|
|
58
|
+
const oldVec = vectorCache.get(oldest)!;
|
|
59
|
+
vectorCacheBytes -= estimateEntryBytes(oldest, oldVec);
|
|
60
|
+
vectorCache.delete(oldest);
|
|
41
61
|
}
|
|
42
62
|
vectorCache.set(key, vector);
|
|
63
|
+
vectorCacheBytes += entryBytes;
|
|
43
64
|
}
|
|
44
65
|
|
|
45
66
|
/** Clear cached embedding backends and the in-memory vector cache. */
|
|
46
67
|
export function clearEmbeddingBackendCache(): void {
|
|
47
68
|
backendCache.clear();
|
|
48
69
|
vectorCache.clear();
|
|
70
|
+
vectorCacheBytes = 0;
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
function cacheKey(provider: string, model: string): string {
|
|
@@ -293,5 +315,5 @@ function selectFallbackBackends(config: AssistantConfig, exclude: EmbeddingProvi
|
|
|
293
315
|
function isOllamaConfigured(config: AssistantConfig): boolean {
|
|
294
316
|
return config.provider === 'ollama'
|
|
295
317
|
|| Boolean(config.apiKeys.ollama)
|
|
296
|
-
|| Boolean(
|
|
318
|
+
|| Boolean(getOllamaBaseUrlEnv());
|
|
297
319
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EmbeddingBackend, EmbeddingRequestOptions } from './embedding-backend.js';
|
|
2
|
+
import { getOllamaBaseUrlEnv } from '../config/env.js';
|
|
2
3
|
|
|
3
4
|
interface OllamaEmbeddingsResponse {
|
|
4
5
|
data?: Array<{ embedding: number[] }>;
|
|
@@ -49,7 +50,7 @@ export class OllamaEmbeddingBackend implements EmbeddingBackend {
|
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
function resolveBaseUrl(override?: string): string {
|
|
52
|
-
const value = (override ??
|
|
53
|
+
const value = (override ?? getOllamaBaseUrlEnv() ?? DEFAULT_OLLAMA_BASE_URL).trim();
|
|
53
54
|
if (value.endsWith('/')) return value.slice(0, -1);
|
|
54
55
|
return value;
|
|
55
56
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
2
1
|
import { eq, sql } from 'drizzle-orm';
|
|
3
|
-
import { getConfig } from '../config/loader.js';
|
|
4
2
|
import type { MemoryEntityConfig } from '../config/types.js';
|
|
5
3
|
import { getLogger } from '../util/logger.js';
|
|
6
4
|
import { truncate } from '../util/truncate.js';
|
|
5
|
+
import { getConfiguredProvider, createTimeout, extractToolUse, userMessage } from '../providers/provider-send-message.js';
|
|
7
6
|
import { getDb } from './db.js';
|
|
8
7
|
import { memoryEntities, memoryEntityRelations, memoryItemEntities } from './schema.js';
|
|
9
8
|
|
|
@@ -123,51 +122,55 @@ export async function extractEntitiesWithLLM(
|
|
|
123
122
|
text: string,
|
|
124
123
|
entityConfig: MemoryEntityConfig,
|
|
125
124
|
): Promise<ExtractedEntityGraph> {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
log.debug('No Anthropic API key available for entity extraction');
|
|
125
|
+
const provider = getConfiguredProvider();
|
|
126
|
+
if (!provider) {
|
|
127
|
+
log.debug('Configured provider unavailable for entity extraction');
|
|
130
128
|
return { entities: [], relations: [] };
|
|
131
129
|
}
|
|
132
130
|
|
|
133
131
|
const extractRelations = entityConfig.extractRelations?.enabled ?? false;
|
|
134
132
|
|
|
135
133
|
try {
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
system: ENTITY_EXTRACTION_SYSTEM_PROMPT,
|
|
142
|
-
tools: [{
|
|
134
|
+
const { signal, cleanup } = createTimeout(ENTITY_EXTRACTION_TIMEOUT_MS);
|
|
135
|
+
try {
|
|
136
|
+
const response = await provider.sendMessage(
|
|
137
|
+
[userMessage(text)],
|
|
138
|
+
[{
|
|
143
139
|
name: 'store_entities',
|
|
144
140
|
description: 'Store extracted entities from the text',
|
|
145
141
|
input_schema: buildToolInputSchema(extractRelations),
|
|
146
142
|
}],
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return { entities: [], relations: [] };
|
|
159
|
-
}
|
|
143
|
+
ENTITY_EXTRACTION_SYSTEM_PROMPT,
|
|
144
|
+
{
|
|
145
|
+
config: {
|
|
146
|
+
model: entityConfig.model,
|
|
147
|
+
max_tokens: 1024,
|
|
148
|
+
tool_choice: { type: 'tool' as const, name: 'store_entities' },
|
|
149
|
+
},
|
|
150
|
+
signal,
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
cleanup();
|
|
160
154
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
155
|
+
const toolBlock = extractToolUse(response);
|
|
156
|
+
if (!toolBlock) {
|
|
157
|
+
log.warn('No tool_use block in entity extraction response');
|
|
158
|
+
return { entities: [], relations: [] };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const input = toolBlock.input as { entities?: LLMExtractedEntity[]; relations?: LLMExtractedRelation[] };
|
|
162
|
+
if (!Array.isArray(input.entities)) {
|
|
163
|
+
log.warn('Invalid entities in entity extraction response');
|
|
164
|
+
return { entities: [], relations: [] };
|
|
165
|
+
}
|
|
166
166
|
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
const entities = parseExtractedEntities(input.entities);
|
|
168
|
+
const relations = extractRelations ? parseExtractedRelations(input.relations) : [];
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
return { entities, relations };
|
|
171
|
+
} finally {
|
|
172
|
+
cleanup();
|
|
173
|
+
}
|
|
171
174
|
} catch (err) {
|
|
172
175
|
const message = err instanceof Error ? err.message : String(err);
|
|
173
176
|
log.warn({ err: message }, 'Entity extraction LLM call failed');
|
|
@@ -284,7 +287,7 @@ export function upsertEntityRelation(input: UpsertEntityRelationInput): void {
|
|
|
284
287
|
memoryEntityRelations.targetEntityId,
|
|
285
288
|
memoryEntityRelations.relation,
|
|
286
289
|
],
|
|
287
|
-
set: normalizedEvidence ===
|
|
290
|
+
set: normalizedEvidence === undefined
|
|
288
291
|
? {
|
|
289
292
|
firstSeenAt: sql`MIN(${memoryEntityRelations.firstSeenAt}, ${seenAt})`,
|
|
290
293
|
lastSeenAt: sql`MAX(${memoryEntityRelations.lastSeenAt}, ${seenAt})`,
|