@vellumai/assistant 0.9.0 → 0.10.0-dev.202606192226.8ed8a6a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +19 -35
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +1128 -119
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/agent-loop-pushes-post-hook-prompt.test.ts +306 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-routes-http.test.ts +128 -0
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compaction-events.test.ts +6 -0
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-process-callsite.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-slash-queue.test.ts +6 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +6 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-pressure-tools.test.ts +41 -1
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/document-tool-security.test.ts +9 -6
- package/src/__tests__/document-update-default-surface.test.ts +202 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/gemini-count-tokens.test.ts +70 -0
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-disk-pressure.test.ts +10 -5
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/secret-response-routing.test.ts +35 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +16 -2
- package/src/__tests__/skill-execute-input.test.ts +177 -1
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/system-storage-cleanup-skill.test.ts +56 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +75 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/db/status.ts +37 -3
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +400 -14
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +31 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +128 -19
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/document-editor/SKILL.md +3 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/system-storage-cleanup/SKILL.md +74 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +44 -0
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +53 -19
- package/src/daemon/conversation.ts +131 -20
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/memory-v2-startup.test.ts +131 -0
- package/src/daemon/memory-v2-startup.ts +100 -1
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/daemon/wake-conversation-ops.ts +1 -0
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/db-logs-attach.test.ts +122 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-async-query.ts +20 -2
- package/src/memory/db-connection.ts +49 -5
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/permissions/secret-prompter.ts +15 -1
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/compaction/window-manager.ts +18 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/injectors.ts +4 -4
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/count-tokens-forwarding.test.ts +98 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/anthropic/client.ts +230 -175
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/call-site-routing.ts +10 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/gemini/client.ts +43 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/ratelimit.ts +9 -0
- package/src/providers/retry.ts +62 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/types.ts +16 -0
- package/src/providers/usage-tracking.ts +7 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +227 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +71 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +126 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +35 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +383 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-routes.ts +40 -9
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +366 -11
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +15 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +30 -6
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +99 -2
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +64 -15
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +10 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/logs-db-path.ts +22 -0
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -8,10 +8,10 @@ mock.module("../../util/logger.js", () => ({
|
|
|
8
8
|
}),
|
|
9
9
|
}));
|
|
10
10
|
|
|
11
|
-
// Mutable
|
|
12
|
-
let
|
|
13
|
-
mock.module("../../
|
|
14
|
-
|
|
11
|
+
// Mutable consent gate, flipped per-test.
|
|
12
|
+
let shareAnalytics = true;
|
|
13
|
+
mock.module("../../platform/consent-cache.js", () => ({
|
|
14
|
+
getCachedShareAnalytics: () => shareAnalytics,
|
|
15
15
|
}));
|
|
16
16
|
|
|
17
17
|
import { getDb } from "../db-connection.js";
|
|
@@ -30,7 +30,7 @@ function resetTable(): void {
|
|
|
30
30
|
|
|
31
31
|
describe("onboarding-events-store: recordActivationEvent", () => {
|
|
32
32
|
beforeEach(() => {
|
|
33
|
-
|
|
33
|
+
shareAnalytics = true;
|
|
34
34
|
resetTable();
|
|
35
35
|
});
|
|
36
36
|
|
|
@@ -66,8 +66,8 @@ describe("onboarding-events-store: recordActivationEvent", () => {
|
|
|
66
66
|
expect(rows[0]!.stepIndex).toBe(2);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
test("returns null and writes no row when
|
|
70
|
-
|
|
69
|
+
test("returns null and writes no row when share_analytics is disabled", () => {
|
|
70
|
+
shareAnalytics = false;
|
|
71
71
|
const event = recordActivationEvent({
|
|
72
72
|
stepName: "activation_moment_1_complete",
|
|
73
73
|
sessionId: "conv-3",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { and, asc, eq, gt, or } from "drizzle-orm";
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { getCachedShareAnalytics } from "../platform/consent-cache.js";
|
|
5
5
|
import { getDb } from "./db-connection.js";
|
|
6
6
|
import { authFallbackEvents } from "./schema.js";
|
|
7
7
|
|
|
@@ -36,7 +36,7 @@ export function recordAuthFallbackCounts(
|
|
|
36
36
|
windowEnd: number,
|
|
37
37
|
counts: AuthFallbackCount[],
|
|
38
38
|
): number {
|
|
39
|
-
if (!
|
|
39
|
+
if (!getCachedShareAnalytics()) return 0;
|
|
40
40
|
if (counts.length === 0) return 0;
|
|
41
41
|
const db = getDb();
|
|
42
42
|
const createdAt = Date.now();
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
2
2
|
import { getConfig } from "../config/loader.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
type TrustClass,
|
|
6
|
-
} from "../runtime/actor-trust-resolver.js";
|
|
3
|
+
import { type TrustClass } from "../runtime/actor-trust-resolver.js";
|
|
4
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
7
5
|
import { getLogger } from "../util/logger.js";
|
|
8
6
|
import { isAutoAnalysisConversation } from "./auto-analysis-guard.js";
|
|
9
7
|
import { isMemoryEnabled, upsertAutoAnalysisJob } from "./jobs-store.js";
|
|
@@ -118,7 +116,7 @@ export function enqueueAutoAnalysisOnCompaction(
|
|
|
118
116
|
conversationId: string,
|
|
119
117
|
trustClass: TrustClass | undefined,
|
|
120
118
|
): void {
|
|
121
|
-
if (
|
|
119
|
+
if (!resolveCapabilities(trustClass).canAccessMemory) {
|
|
122
120
|
return;
|
|
123
121
|
}
|
|
124
122
|
try {
|
|
@@ -7,8 +7,7 @@ import { conversations, messageBookmarks, messages } from "./schema.js";
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Wire-shape representation of a bookmark, joined with the bookmarked
|
|
10
|
-
* message and its parent conversation.
|
|
11
|
-
* `clients/shared/Network/BookmarkSummary.swift` — dates are emitted as
|
|
10
|
+
* message and its parent conversation. Dates are emitted as
|
|
12
11
|
* unix-millisecond integers, and the message preview is capped to keep
|
|
13
12
|
* the list payload bounded.
|
|
14
13
|
*/
|
|
@@ -74,7 +74,7 @@ export interface CanonicalGuardianRequest {
|
|
|
74
74
|
updatedAt: number;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
interface CanonicalGuardianDelivery {
|
|
77
|
+
export interface CanonicalGuardianDelivery {
|
|
78
78
|
id: string;
|
|
79
79
|
requestId: string;
|
|
80
80
|
destinationChannel: string;
|
|
@@ -674,6 +674,44 @@ export function listPendingCanonicalGuardianRequestsByDestinationChat(
|
|
|
674
674
|
return pendingRequests;
|
|
675
675
|
}
|
|
676
676
|
|
|
677
|
+
/**
|
|
678
|
+
* Find the pending canonical request whose guardian-facing delivery landed on a
|
|
679
|
+
* specific channel message (channel + chat + message id).
|
|
680
|
+
*
|
|
681
|
+
* This is the addressing key for emoji-reaction decisions: a reaction carries
|
|
682
|
+
* only the message it is attached to, so the delivered card's message id is how
|
|
683
|
+
* we recover which request the guardian acted on — even when several cards are
|
|
684
|
+
* pending in the same chat. Returns null when no delivery matches or the matched
|
|
685
|
+
* request is no longer pending.
|
|
686
|
+
*/
|
|
687
|
+
export function getPendingCanonicalRequestByDestinationMessage(
|
|
688
|
+
destinationChannel: string,
|
|
689
|
+
destinationChatId: string,
|
|
690
|
+
destinationMessageId: string,
|
|
691
|
+
): CanonicalGuardianRequest | null {
|
|
692
|
+
const db = getDb();
|
|
693
|
+
|
|
694
|
+
const delivery = db
|
|
695
|
+
.select()
|
|
696
|
+
.from(canonicalGuardianDeliveries)
|
|
697
|
+
.where(
|
|
698
|
+
and(
|
|
699
|
+
eq(canonicalGuardianDeliveries.destinationChannel, destinationChannel),
|
|
700
|
+
eq(canonicalGuardianDeliveries.destinationChatId, destinationChatId),
|
|
701
|
+
eq(
|
|
702
|
+
canonicalGuardianDeliveries.destinationMessageId,
|
|
703
|
+
destinationMessageId,
|
|
704
|
+
),
|
|
705
|
+
),
|
|
706
|
+
)
|
|
707
|
+
.get();
|
|
708
|
+
|
|
709
|
+
if (!delivery) return null;
|
|
710
|
+
|
|
711
|
+
const request = getCanonicalGuardianRequest(delivery.requestId);
|
|
712
|
+
return request && request.status === "pending" ? request : null;
|
|
713
|
+
}
|
|
714
|
+
|
|
677
715
|
// ---------------------------------------------------------------------------
|
|
678
716
|
// Conversation scope helpers
|
|
679
717
|
// ---------------------------------------------------------------------------
|
|
@@ -129,7 +129,7 @@ export const messageMetadataSchema = z
|
|
|
129
129
|
* and read gate (conversation history loading) to enforce trust-aware access.
|
|
130
130
|
*/
|
|
131
131
|
provenanceTrustClass: z
|
|
132
|
-
.enum(["guardian", "trusted_contact", "unknown"])
|
|
132
|
+
.enum(["guardian", "trusted_contact", "unverified_contact", "unknown"])
|
|
133
133
|
.optional(),
|
|
134
134
|
provenanceSourceChannel: channelIdSchema.optional(),
|
|
135
135
|
provenanceGuardianExternalUserId: z.string().optional(),
|
|
@@ -2575,12 +2575,17 @@ export function getConversationOriginInterface(
|
|
|
2575
2575
|
* in the given conversation, or `undefined` if none is found.
|
|
2576
2576
|
*
|
|
2577
2577
|
* Used by the pointer message trust resolver to detect conversations
|
|
2578
|
-
* whose audience is a guardian
|
|
2579
|
-
* conversations.
|
|
2578
|
+
* whose audience is a guardian, trusted_contact, or unverified_contact
|
|
2579
|
+
* outside desktop-origin conversations.
|
|
2580
2580
|
*/
|
|
2581
2581
|
export function getConversationRecentProvenanceTrustClass(
|
|
2582
2582
|
conversationId: string,
|
|
2583
|
-
):
|
|
2583
|
+
):
|
|
2584
|
+
| "guardian"
|
|
2585
|
+
| "trusted_contact"
|
|
2586
|
+
| "unverified_contact"
|
|
2587
|
+
| "unknown"
|
|
2588
|
+
| undefined {
|
|
2584
2589
|
const row = rawGet<{ metadata: string | null }>(
|
|
2585
2590
|
`SELECT metadata FROM messages
|
|
2586
2591
|
WHERE conversation_id = ? AND role = 'user' AND metadata IS NOT NULL
|
|
@@ -135,7 +135,16 @@ export function resolveConversationId(idOrKey: string): string | null {
|
|
|
135
135
|
*/
|
|
136
136
|
export function getOrCreateConversation(
|
|
137
137
|
conversationKey: string,
|
|
138
|
-
opts?: {
|
|
138
|
+
opts?: {
|
|
139
|
+
conversationType?: "standard";
|
|
140
|
+
/**
|
|
141
|
+
* Caller-supplied title for the conversation, used only when this call
|
|
142
|
+
* actually creates the row. Treated as a user-set title (`isAutoTitle = 0`)
|
|
143
|
+
* so the async LLM title generator's safe-overwrite check leaves it
|
|
144
|
+
* untouched. Ignored when the conversation already exists.
|
|
145
|
+
*/
|
|
146
|
+
title?: string;
|
|
147
|
+
},
|
|
139
148
|
): {
|
|
140
149
|
conversationId: string;
|
|
141
150
|
conversationType: string;
|
|
@@ -205,13 +214,19 @@ export function getOrCreateConversation(
|
|
|
205
214
|
|
|
206
215
|
const now = Date.now();
|
|
207
216
|
const conversationId = uuid();
|
|
208
|
-
const
|
|
217
|
+
const customTitle = opts?.title?.trim();
|
|
218
|
+
const title = customTitle || GENERATING_TITLE;
|
|
209
219
|
const memoryScopeId = "default";
|
|
210
220
|
|
|
211
221
|
tx.insert(conversations)
|
|
212
222
|
.values({
|
|
213
223
|
id: conversationId,
|
|
214
224
|
title,
|
|
225
|
+
// A caller-supplied title is user-set: mark it non-auto (0) so the
|
|
226
|
+
// async LLM title generator's `canReplaceTitle` check won't overwrite
|
|
227
|
+
// it. Without one, omit the column so it takes its default
|
|
228
|
+
// (AUTO_TITLE_LLM) and follows the auto-generated placeholder flow.
|
|
229
|
+
...(customTitle ? { isAutoTitle: 0 } : {}),
|
|
215
230
|
createdAt: now,
|
|
216
231
|
updatedAt: now,
|
|
217
232
|
totalInputTokens: 0,
|
|
@@ -166,6 +166,7 @@ export async function generateAndPersistConversationTitle(
|
|
|
166
166
|
const fallback = deriveFallbackTitle(context) ?? UNTITLED_FALLBACK;
|
|
167
167
|
updateConversationTitle(conversationId, fallback, AUTO_TITLE_DETERMINISTIC);
|
|
168
168
|
publishConversationTitleChanged(conversationId, fallback);
|
|
169
|
+
logRetryableFallback(params, "no_provider");
|
|
169
170
|
return { title: fallback, updated: true };
|
|
170
171
|
}
|
|
171
172
|
|
|
@@ -206,6 +207,7 @@ export async function generateAndPersistConversationTitle(
|
|
|
206
207
|
const fallback = deriveFallbackTitle(context) ?? UNTITLED_FALLBACK;
|
|
207
208
|
updateConversationTitle(conversationId, fallback, AUTO_TITLE_DETERMINISTIC);
|
|
208
209
|
publishConversationTitleChanged(conversationId, fallback);
|
|
210
|
+
logRetryableFallback(params, "empty_output");
|
|
209
211
|
return { title: fallback, updated: true };
|
|
210
212
|
}
|
|
211
213
|
|
|
@@ -230,7 +232,7 @@ export const titleMutex = new Mutex();
|
|
|
230
232
|
/**
|
|
231
233
|
* Fire-and-forget wrapper for title generation. Failures are logged
|
|
232
234
|
* but do not propagate. On failure, replaces loading placeholder with
|
|
233
|
-
* a
|
|
235
|
+
* a retryable fallback title so loading state is never permanent.
|
|
234
236
|
*
|
|
235
237
|
* Calls are serialized via {@link titleMutex} so burst conversation
|
|
236
238
|
* creation does not overwhelm the LLM provider.
|
|
@@ -244,16 +246,20 @@ export function queueGenerateConversationTitle(
|
|
|
244
246
|
})
|
|
245
247
|
.catch((err) => {
|
|
246
248
|
log.warn(
|
|
247
|
-
|
|
248
|
-
"
|
|
249
|
+
retryableFallbackLogFields(params, "generation_error", err),
|
|
250
|
+
"Conversation title generation used retryable fallback",
|
|
249
251
|
);
|
|
250
|
-
// Replace loading placeholder with
|
|
252
|
+
// Replace loading placeholder with a retryable fallback.
|
|
251
253
|
try {
|
|
252
254
|
const conversation = getConversation(params.conversationId);
|
|
253
255
|
if (conversation && conversation.title === GENERATING_TITLE) {
|
|
254
256
|
const fallback =
|
|
255
257
|
deriveFallbackTitle(params.context) ?? UNTITLED_FALLBACK;
|
|
256
|
-
updateConversationTitle(
|
|
258
|
+
updateConversationTitle(
|
|
259
|
+
params.conversationId,
|
|
260
|
+
fallback,
|
|
261
|
+
AUTO_TITLE_DETERMINISTIC,
|
|
262
|
+
);
|
|
257
263
|
publishConversationTitleChanged(params.conversationId, fallback);
|
|
258
264
|
}
|
|
259
265
|
} catch {
|
|
@@ -268,6 +274,11 @@ export interface RegenerateTitleParams {
|
|
|
268
274
|
conversationId: string;
|
|
269
275
|
provider?: Provider;
|
|
270
276
|
signal?: AbortSignal;
|
|
277
|
+
/**
|
|
278
|
+
* Limit regeneration to placeholder or deterministic titles. Used for retrying
|
|
279
|
+
* failed initial generation without racing against a successful initial title.
|
|
280
|
+
*/
|
|
281
|
+
onlyIfReplaceable?: boolean;
|
|
271
282
|
}
|
|
272
283
|
|
|
273
284
|
/**
|
|
@@ -278,12 +289,15 @@ export interface RegenerateTitleParams {
|
|
|
278
289
|
export async function regenerateConversationTitle(
|
|
279
290
|
params: RegenerateTitleParams,
|
|
280
291
|
): Promise<{ title: string; updated: boolean }> {
|
|
281
|
-
const { conversationId, signal } = params;
|
|
292
|
+
const { conversationId, onlyIfReplaceable, signal } = params;
|
|
282
293
|
|
|
283
294
|
const conversation = getConversation(conversationId);
|
|
284
295
|
if (!conversation || !conversation.isAutoTitle) {
|
|
285
296
|
return { title: conversation?.title ?? UNTITLED_FALLBACK, updated: false };
|
|
286
297
|
}
|
|
298
|
+
if (onlyIfReplaceable && !canReplaceTitle(conversation)) {
|
|
299
|
+
return { title: conversation.title ?? UNTITLED_FALLBACK, updated: false };
|
|
300
|
+
}
|
|
287
301
|
|
|
288
302
|
const provider =
|
|
289
303
|
params.provider ?? (await getConfiguredProvider("conversationTitle"));
|
|
@@ -317,7 +331,11 @@ export async function regenerateConversationTitle(
|
|
|
317
331
|
if (title) {
|
|
318
332
|
// Re-check isAutoTitle before persisting (race guard against manual rename)
|
|
319
333
|
const current = getConversation(conversationId);
|
|
320
|
-
if (
|
|
334
|
+
if (
|
|
335
|
+
!current ||
|
|
336
|
+
!current.isAutoTitle ||
|
|
337
|
+
(onlyIfReplaceable && !canReplaceTitle(current))
|
|
338
|
+
) {
|
|
321
339
|
return { title: current?.title ?? UNTITLED_FALLBACK, updated: false };
|
|
322
340
|
}
|
|
323
341
|
|
|
@@ -408,6 +426,45 @@ function buildTitlePrompt(
|
|
|
408
426
|
return parts.join("\n");
|
|
409
427
|
}
|
|
410
428
|
|
|
429
|
+
function titleGenerationLogFields(params: GenerateTitleParams) {
|
|
430
|
+
return {
|
|
431
|
+
conversationId: params.conversationId,
|
|
432
|
+
contextOrigin: params.context?.origin,
|
|
433
|
+
hasContext: Boolean(params.context),
|
|
434
|
+
userMessageLength: params.userMessage?.length ?? 0,
|
|
435
|
+
assistantResponseLength: params.assistantResponse?.length ?? 0,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
type TitleGenerationFallbackReason =
|
|
440
|
+
| "no_provider"
|
|
441
|
+
| "empty_output"
|
|
442
|
+
| "generation_error";
|
|
443
|
+
|
|
444
|
+
function retryableFallbackLogFields(
|
|
445
|
+
params: GenerateTitleParams,
|
|
446
|
+
reason: TitleGenerationFallbackReason,
|
|
447
|
+
err?: unknown,
|
|
448
|
+
): Record<string, unknown> {
|
|
449
|
+
const fields: Record<string, unknown> = {
|
|
450
|
+
...titleGenerationLogFields(params),
|
|
451
|
+
reason,
|
|
452
|
+
fallbackSource: params.context ? "context" : "untitled",
|
|
453
|
+
};
|
|
454
|
+
if (err) fields.err = err;
|
|
455
|
+
return fields;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function logRetryableFallback(
|
|
459
|
+
params: GenerateTitleParams,
|
|
460
|
+
reason: TitleGenerationFallbackReason,
|
|
461
|
+
): void {
|
|
462
|
+
log.warn(
|
|
463
|
+
retryableFallbackLogFields(params, reason),
|
|
464
|
+
"Conversation title generation used retryable fallback",
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
|
|
411
468
|
const META_FAILURE_TITLES = new Set([
|
|
412
469
|
"missing context",
|
|
413
470
|
"no context",
|
|
@@ -61,6 +61,19 @@ export interface RunAsyncSqliteOptions {
|
|
|
61
61
|
* the runtime pick.
|
|
62
62
|
*/
|
|
63
63
|
forceBackend?: AsyncSqliteBackend;
|
|
64
|
+
/**
|
|
65
|
+
* Database file to run the statement against. Defaults to the main
|
|
66
|
+
* assistant DB (`getDbPath()`). Pass `getLogsDbPath()` to target the
|
|
67
|
+
* secondary append-only file directly.
|
|
68
|
+
*
|
|
69
|
+
* This only affects the `sqlite3-cli` backend, which opens the given file
|
|
70
|
+
* as its own `main` database — so a statement like
|
|
71
|
+
* `DELETE FROM llm_request_logs` runs against the right file with no ATTACH.
|
|
72
|
+
* The in-process fallback always runs on the daemon connection, which has
|
|
73
|
+
* the logs DB ATTACHed, so unqualified table names already resolve to the
|
|
74
|
+
* correct file regardless of this option.
|
|
75
|
+
*/
|
|
76
|
+
dbPath?: string;
|
|
64
77
|
}
|
|
65
78
|
|
|
66
79
|
let warnedAboutFallback = false;
|
|
@@ -74,7 +87,12 @@ export async function runAsyncSqlite(
|
|
|
74
87
|
forced === "in-process-blocking" ? undefined : findSqlite3();
|
|
75
88
|
|
|
76
89
|
if (sqlite3Path && forced !== "in-process-blocking") {
|
|
77
|
-
return runViaCli(
|
|
90
|
+
return runViaCli(
|
|
91
|
+
sqlite3Path,
|
|
92
|
+
sql,
|
|
93
|
+
options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
94
|
+
options.dbPath ?? getDbPath(),
|
|
95
|
+
);
|
|
78
96
|
}
|
|
79
97
|
|
|
80
98
|
if (!warnedAboutFallback) {
|
|
@@ -97,9 +115,9 @@ async function runViaCli(
|
|
|
97
115
|
sqlite3Path: string,
|
|
98
116
|
sql: string,
|
|
99
117
|
timeoutMs: number,
|
|
118
|
+
dbPath: string,
|
|
100
119
|
): Promise<AsyncSqliteResult> {
|
|
101
120
|
const startMs = Date.now();
|
|
102
|
-
const dbPath = getDbPath();
|
|
103
121
|
|
|
104
122
|
log.info(
|
|
105
123
|
{ sqlite3Path, dbPath, timeoutMs, sqlPreview: sql.slice(0, 80) },
|
|
@@ -5,16 +5,59 @@ import { Database } from "bun:sqlite";
|
|
|
5
5
|
|
|
6
6
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
7
7
|
|
|
8
|
+
import { getLogsDbPath } from "../util/logs-db-path.js";
|
|
8
9
|
import { ensureDataDir, getDbPath } from "../util/platform.js";
|
|
9
|
-
import {
|
|
10
|
-
clearStoredDb,
|
|
11
|
-
getStoredDb,
|
|
12
|
-
setStoredDb,
|
|
13
|
-
} from "./db-singleton.js";
|
|
10
|
+
import { clearStoredDb, getStoredDb, setStoredDb } from "./db-singleton.js";
|
|
14
11
|
import * as schema from "./schema.js";
|
|
15
12
|
|
|
16
13
|
export type DrizzleDb = ReturnType<typeof drizzle<typeof schema>>;
|
|
17
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Schema name under which the secondary append-only database file
|
|
17
|
+
* (`assistant-logs.db`) is ATTACHed to the main connection. Tables created in
|
|
18
|
+
* this schema (e.g. `logs.llm_request_logs`) live in the separate file but are
|
|
19
|
+
* still queryable — and joinable against main-schema tables — over the single
|
|
20
|
+
* daemon connection. Because no append-only table exists in the `main` schema,
|
|
21
|
+
* unqualified references (e.g. `llm_request_logs`) resolve to the attached copy.
|
|
22
|
+
*/
|
|
23
|
+
export const LOGS_DB_SCHEMA = "logs";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* ATTACH the append-only logs database to an open connection and apply its
|
|
27
|
+
* per-database PRAGMAs.
|
|
28
|
+
*
|
|
29
|
+
* `journal_mode` and `synchronous` are per-database settings, so they must be
|
|
30
|
+
* set against the attached schema explicitly — the PRAGMAs run on `main` before
|
|
31
|
+
* the attach do not carry over. `busy_timeout`, `foreign_keys`, `cache_size`,
|
|
32
|
+
* and `temp_store` are connection-wide and already configured on the connection.
|
|
33
|
+
*
|
|
34
|
+
* Best-effort: a failure here (e.g. a filesystem permission problem on the new
|
|
35
|
+
* file) must not take down the main database. We log and continue in line with
|
|
36
|
+
* the daemon's "never block startup on a subsystem failure" policy; append-only
|
|
37
|
+
* tables are simply unavailable until the next successful open.
|
|
38
|
+
*
|
|
39
|
+
* The logger is pulled in lazily (dynamic import) only on the error path. This
|
|
40
|
+
* file is intentionally kept import-light — see `db-singleton.ts` — so it does
|
|
41
|
+
* not take a static dependency on the logger (and transitively on pino).
|
|
42
|
+
*/
|
|
43
|
+
function attachLogsDb(sqlite: Database): void {
|
|
44
|
+
const logsPath = getLogsDbPath();
|
|
45
|
+
try {
|
|
46
|
+
// Escape single quotes for the SQL string literal (paths can contain them).
|
|
47
|
+
const escaped = logsPath.replace(/'/g, "''");
|
|
48
|
+
sqlite.exec(`ATTACH DATABASE '${escaped}' AS ${LOGS_DB_SCHEMA}`);
|
|
49
|
+
sqlite.exec(`PRAGMA ${LOGS_DB_SCHEMA}.journal_mode=WAL`);
|
|
50
|
+
sqlite.exec(`PRAGMA ${LOGS_DB_SCHEMA}.synchronous=FULL`);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
void import("../util/logger.js").then(({ getLogger }) =>
|
|
53
|
+
getLogger("db-connection").error(
|
|
54
|
+
{ err, logsPath },
|
|
55
|
+
"Failed to ATTACH logs database; append-only log tables will be unavailable",
|
|
56
|
+
),
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
18
61
|
function canonicalizePathThroughExistingParent(path: string): string {
|
|
19
62
|
const resolvedPath = resolve(path);
|
|
20
63
|
const pendingSegments: string[] = [];
|
|
@@ -86,6 +129,7 @@ export function getDb(): DrizzleDb {
|
|
|
86
129
|
sqlite.exec("PRAGMA foreign_keys = ON");
|
|
87
130
|
sqlite.exec("PRAGMA cache_size=-256000");
|
|
88
131
|
sqlite.exec("PRAGMA temp_store=MEMORY");
|
|
132
|
+
attachLogsDb(sqlite);
|
|
89
133
|
const db = drizzle(sqlite, { schema });
|
|
90
134
|
setStoredDb(db, () => sqlite.close());
|
|
91
135
|
return db;
|
package/src/memory/db-init.ts
CHANGED
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
createSkillLoadedEventsTable,
|
|
41
41
|
createTasksAndWorkItemsTables,
|
|
42
42
|
createWatchersAndLogsTables,
|
|
43
|
+
dropApprovalPromptTsTrackerTable,
|
|
43
44
|
migrate230AcpSessionHistory,
|
|
44
45
|
migrate231RepairMemoryGraphEventDates,
|
|
45
46
|
migrateA2ATasks,
|
|
@@ -68,6 +69,7 @@ import {
|
|
|
68
69
|
migrateChannelInboundDeliveryAttempts,
|
|
69
70
|
migrateChannelInteractionColumns,
|
|
70
71
|
migrateContactChannelsAccessFields,
|
|
72
|
+
migrateContactChannelsRenormalizeAddresses,
|
|
71
73
|
migrateContactChannelsTypeChatIdIndex,
|
|
72
74
|
migrateContactChannelsUniqueExtUser,
|
|
73
75
|
migrateContactsAssistantId,
|
|
@@ -101,6 +103,7 @@ import {
|
|
|
101
103
|
migrateDropConflicts,
|
|
102
104
|
migrateDropContactInteractionColumns,
|
|
103
105
|
migrateDropEntityTables,
|
|
106
|
+
migrateDropExternalUserId,
|
|
104
107
|
migrateDropLegacyMemberGuardianTables,
|
|
105
108
|
migrateDropLoopbackPortColumn,
|
|
106
109
|
migrateDropMemoryItemsTables,
|
|
@@ -194,7 +197,9 @@ import {
|
|
|
194
197
|
migrateRenameVerificationSessionIdColumn,
|
|
195
198
|
migrateRenameVerificationTable,
|
|
196
199
|
migrateRenameVoiceToPhone,
|
|
200
|
+
migrateRewriteBalancedEconomyProfilePins,
|
|
197
201
|
migrateScheduleCapabilities,
|
|
202
|
+
migrateScheduleDefaultNoReuseConversation,
|
|
198
203
|
migrateScheduleDescription,
|
|
199
204
|
migrateScheduleInferenceProfile,
|
|
200
205
|
migrateScheduleOneShotRouting,
|
|
@@ -222,6 +227,7 @@ import {
|
|
|
222
227
|
migrateUsageLlmCallCount,
|
|
223
228
|
migrateVoiceInviteColumns,
|
|
224
229
|
migrateVoiceInviteDisplayMetadata,
|
|
230
|
+
migrateWorkflowJournalLeafTokens,
|
|
225
231
|
migrateWorkflowRuns,
|
|
226
232
|
migrateWorkflowRunTrust,
|
|
227
233
|
recoverCrashedMigrations,
|
|
@@ -229,6 +235,7 @@ import {
|
|
|
229
235
|
runLateMigrations,
|
|
230
236
|
validateMigrationState,
|
|
231
237
|
} from "./migrations/index.js";
|
|
238
|
+
import { runMigrationSteps } from "./migrations/run-migrations.js";
|
|
232
239
|
|
|
233
240
|
// ---------------------------------------------------------------------------
|
|
234
241
|
// Test DB template — run migrations once, reuse across test files
|
|
@@ -518,29 +525,22 @@ export function initializeDb(): void {
|
|
|
518
525
|
migrateBackfillOriginChannelFromBindings,
|
|
519
526
|
migrateContactChannelsUniqueExtUser,
|
|
520
527
|
migrateScheduleCapabilities,
|
|
528
|
+
migrateContactChannelsRenormalizeAddresses,
|
|
529
|
+
migrateScheduleDefaultNoReuseConversation,
|
|
530
|
+
migrateWorkflowJournalLeafTokens,
|
|
531
|
+
migrateDropExternalUserId,
|
|
532
|
+
dropApprovalPromptTsTrackerTable,
|
|
533
|
+
migrateRewriteBalancedEconomyProfilePins,
|
|
521
534
|
];
|
|
522
535
|
|
|
523
536
|
// Run each migration step, catching and logging individual failures so one
|
|
524
537
|
// broken migration doesn't prevent independent later ones from succeeding.
|
|
525
|
-
const
|
|
526
|
-
for (const step of migrationSteps) {
|
|
527
|
-
try {
|
|
528
|
-
log.debug({ migration: step.name }, `Starting migration: ${step.name}`);
|
|
529
|
-
step(database);
|
|
530
|
-
log.debug({ migration: step.name }, `Migration succeeded: ${step.name}`);
|
|
531
|
-
} catch (err) {
|
|
532
|
-
failures.push(step.name);
|
|
533
|
-
log.error(
|
|
534
|
-
{ err, migration: step.name },
|
|
535
|
-
`Migration failed: ${step.name}`,
|
|
536
|
-
);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
538
|
+
const { failed } = runMigrationSteps(database, migrationSteps);
|
|
539
539
|
|
|
540
|
-
if (
|
|
540
|
+
if (failed.length > 0) {
|
|
541
541
|
log.error(
|
|
542
|
-
{ failedMigrations:
|
|
543
|
-
`DB initialization completed with ${
|
|
542
|
+
{ failedMigrations: failed, count: failed.length },
|
|
543
|
+
`DB initialization completed with ${failed.length} failed migration(s)`,
|
|
544
544
|
);
|
|
545
545
|
}
|
|
546
546
|
|
|
@@ -7,6 +7,13 @@ import { PLATFORM_PROVIDER_META } from "../providers/platform-proxy/constants.js
|
|
|
7
7
|
import { resolveManagedProxyContext } from "../providers/platform-proxy/context.js";
|
|
8
8
|
import { getProviderKeyAsync } from "../security/secure-keys.js";
|
|
9
9
|
import { getLogger } from "../util/logger.js";
|
|
10
|
+
import {
|
|
11
|
+
EmbeddingBillingBlockError,
|
|
12
|
+
extractHttpStatus,
|
|
13
|
+
isEmbeddingBillingBreakerOpen,
|
|
14
|
+
recordBillingBlock,
|
|
15
|
+
recordBillingSuccess,
|
|
16
|
+
} from "./embedding-billing-breaker.js";
|
|
10
17
|
import { GeminiEmbeddingBackend } from "./embedding-gemini.js";
|
|
11
18
|
import { OllamaEmbeddingBackend } from "./embedding-ollama.js";
|
|
12
19
|
import { OpenAIEmbeddingBackend } from "./embedding-openai.js";
|
|
@@ -490,6 +497,20 @@ export async function getMemoryBackendStatus(config: AssistantConfig): Promise<{
|
|
|
490
497
|
};
|
|
491
498
|
}
|
|
492
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Thrown by {@link embedWithBackend} when no embedding backend is configured or
|
|
502
|
+
* available. This is a PROCESS-WIDE condition (backend selection is effectively
|
|
503
|
+
* cached for the run), so a caller embedding many items should treat the first
|
|
504
|
+
* occurrence as fatal to the whole batch rather than a per-item failure — see
|
|
505
|
+
* `backfillAllSections`, which aborts on it instead of churning through deletes.
|
|
506
|
+
*/
|
|
507
|
+
export class EmbeddingBackendUnavailableError extends Error {
|
|
508
|
+
constructor(message = "No memory embedding backend configured") {
|
|
509
|
+
super(message);
|
|
510
|
+
this.name = "EmbeddingBackendUnavailableError";
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
493
514
|
export async function embedWithBackend(
|
|
494
515
|
config: AssistantConfig,
|
|
495
516
|
inputs: EmbeddingInput[],
|
|
@@ -499,9 +520,15 @@ export async function embedWithBackend(
|
|
|
499
520
|
model: string;
|
|
500
521
|
vectors: number[][];
|
|
501
522
|
}> {
|
|
523
|
+
// Fail-fast when the billing breaker is open — avoids burning a network
|
|
524
|
+
// round-trip on every caller (embed lane jobs, activation recompute, etc.).
|
|
525
|
+
if (isEmbeddingBillingBreakerOpen()) {
|
|
526
|
+
throw new EmbeddingBillingBlockError();
|
|
527
|
+
}
|
|
528
|
+
|
|
502
529
|
const selection = await selectEmbeddingBackend(config);
|
|
503
530
|
if (!selection.backend) {
|
|
504
|
-
throw new
|
|
531
|
+
throw new EmbeddingBackendUnavailableError(
|
|
505
532
|
selection.reason ?? "No memory embedding backend configured",
|
|
506
533
|
);
|
|
507
534
|
}
|
|
@@ -612,6 +639,10 @@ export async function embedWithBackend(
|
|
|
612
639
|
);
|
|
613
640
|
}
|
|
614
641
|
|
|
642
|
+
// A successful backend call proves billing is active — close the
|
|
643
|
+
// breaker if it was in the probe window.
|
|
644
|
+
recordBillingSuccess();
|
|
645
|
+
|
|
615
646
|
if (isPrimary) {
|
|
616
647
|
const merged = [...cached] as number[][];
|
|
617
648
|
for (let i = 0; i < uncachedIndices.length; i++) {
|
|
@@ -626,6 +657,12 @@ export async function embedWithBackend(
|
|
|
626
657
|
return { provider: backend.provider, model: backend.model, vectors };
|
|
627
658
|
} catch (err) {
|
|
628
659
|
lastErr = err;
|
|
660
|
+
// If ANY backend in the chain returns 402, trip the billing breaker
|
|
661
|
+
// immediately — fallbacks will hit the same depleted balance.
|
|
662
|
+
if (extractHttpStatus(err) === 402) {
|
|
663
|
+
recordBillingBlock();
|
|
664
|
+
throw err;
|
|
665
|
+
}
|
|
629
666
|
if (backends.length > 1) {
|
|
630
667
|
log.warn(
|
|
631
668
|
{ err, provider: backend.provider },
|