@vellumai/assistant 0.4.43 → 0.4.45
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/.prettierignore +4 -0
- package/ARCHITECTURE.md +46 -44
- package/README.md +15 -16
- package/bun.lock +10 -35
- package/docs/architecture/integrations.md +102 -215
- package/docs/architecture/keychain-broker.md +1 -1
- package/docs/architecture/memory.md +2 -2
- package/docs/architecture/scheduling.md +1 -1
- package/docs/architecture/security.md +11 -11
- package/docs/error-handling.md +1 -1
- package/docs/trusted-contact-access.md +3 -3
- package/drizzle/meta/0000_snapshot.json +34 -100
- package/drizzle/meta/_journal.json +1 -1
- package/drizzle.config.ts +4 -4
- package/package.json +3 -2
- package/scripts/capture-x-graphql.ts +237 -141
- package/scripts/generate-bundled-tool-registry.ts +223 -0
- package/src/__tests__/access-request-decision.test.ts +0 -1
- package/src/__tests__/actor-token-service.test.ts +23 -24
- package/src/__tests__/agent-loop.test.ts +0 -131
- package/src/__tests__/always-loaded-tools-guard.test.ts +71 -0
- package/src/__tests__/amazon-cdp-integration.test.ts +11 -9
- package/src/__tests__/approval-primitive.test.ts +0 -1
- package/src/__tests__/approval-routes-http.test.ts +11 -3
- package/src/__tests__/asset-materialize-tool.test.ts +0 -1
- package/src/__tests__/asset-search-tool.test.ts +0 -1
- package/src/__tests__/assistant-attachment-directive.test.ts +1 -1
- package/src/__tests__/assistant-events-sse-hardening.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/assistant-feature-flags-integration.test.ts +70 -18
- package/src/__tests__/assistant-id-boundary-guard.test.ts +6 -6
- package/src/__tests__/attachments-store.test.ts +0 -1
- package/src/__tests__/avatar-e2e.test.ts +74 -115
- package/src/__tests__/avatar-router.test.ts +25 -62
- package/src/__tests__/browser-manager.test.ts +24 -0
- package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +4 -3
- package/src/__tests__/browser-skill-endstate.test.ts +8 -11
- package/src/__tests__/btw-routes.test.ts +326 -0
- package/src/__tests__/bundled-asset.test.ts +1 -1
- package/src/__tests__/bundled-skill-retrieval-guard.test.ts +23 -9
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/call-conversation-messages.test.ts +0 -1
- package/src/__tests__/call-domain.test.ts +0 -1
- package/src/__tests__/call-pointer-messages.test.ts +0 -1
- package/src/__tests__/call-recovery.test.ts +0 -1
- package/src/__tests__/call-routes-http.test.ts +0 -1
- package/src/__tests__/call-store.test.ts +0 -1
- package/src/__tests__/canonical-guardian-store.test.ts +0 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +5 -7
- package/src/__tests__/channel-retry-sweep.test.ts +0 -1
- package/src/__tests__/checker.test.ts +32 -36
- package/src/__tests__/compaction.benchmark.test.ts +16 -14
- package/src/__tests__/computer-use-session-lifecycle.test.ts +10 -11
- package/src/__tests__/computer-use-session-working-dir.test.ts +2 -6
- package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +2 -5
- package/src/__tests__/computer-use-tools.test.ts +35 -31
- package/src/__tests__/config-schema.test.ts +11 -15
- package/src/__tests__/config-watcher.test.ts +0 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/conflict-store.test.ts +0 -1
- package/src/__tests__/connection-policy.test.ts +4 -7
- package/src/__tests__/contacts-tools.test.ts +0 -1
- package/src/__tests__/context-memory-e2e.test.ts +2 -4
- package/src/__tests__/context-overflow-reducer.test.ts +2 -4
- package/src/__tests__/context-window-manager.test.ts +147 -60
- package/src/__tests__/contradiction-checker.test.ts +0 -1
- package/src/__tests__/conversation-attention-store.test.ts +0 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +1 -1
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +31 -7
- package/src/__tests__/conversation-routes-slash-commands.test.ts +381 -0
- package/src/__tests__/conversation-store.test.ts +0 -1
- package/src/__tests__/conversation-unread-route.test.ts +1 -2
- package/src/__tests__/credential-security-invariants.test.ts +8 -8
- package/src/__tests__/cross-provider-web-search.test.ts +353 -0
- package/src/__tests__/daemon-assistant-events.test.ts +6 -7
- package/src/__tests__/db-schedule-syntax-migration.test.ts +15 -3
- package/src/__tests__/delete-managed-skill-tool.test.ts +5 -9
- package/src/__tests__/deterministic-verification-control-plane.test.ts +0 -1
- package/src/__tests__/diagnostics-export.test.ts +189 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/emit-signal-routing-intent.test.ts +3 -3
- package/src/__tests__/entity-extractor.test.ts +0 -1
- package/src/__tests__/entity-search.test.ts +0 -1
- package/src/__tests__/ephemeral-permissions.test.ts +2 -4
- package/src/__tests__/error-handler-friendly-messages.test.ts +46 -0
- package/src/__tests__/file-read-tool.test.ts +86 -0
- package/src/__tests__/followup-tools.test.ts +0 -1
- package/src/__tests__/frontmatter.test.ts +77 -34
- package/src/__tests__/gateway-only-enforcement.test.ts +0 -1
- package/src/__tests__/gateway-only-guard.test.ts +1 -1
- package/src/__tests__/guardian-action-conversation-turn.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-executor.test.ts +0 -1
- package/src/__tests__/guardian-action-followup-store.test.ts +0 -1
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +0 -1
- package/src/__tests__/guardian-action-late-reply.test.ts +0 -1
- package/src/__tests__/guardian-action-store.test.ts +0 -1
- package/src/__tests__/guardian-action-sweep.test.ts +0 -1
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +0 -1
- package/src/__tests__/guardian-dispatch.test.ts +1 -2
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-outbound-http.test.ts +0 -1
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +0 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +1 -1
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/guardian-verification-voice-binding.test.ts +0 -1
- package/src/__tests__/guardian-verify-setup-skill-regression.test.ts +3 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +28 -426
- package/src/__tests__/host-bash-proxy.test.ts +335 -0
- package/src/__tests__/host-file-proxy.test.ts +374 -0
- package/src/__tests__/host-shell-tool.test.ts +147 -1
- package/src/__tests__/http-user-message-parity.test.ts +361 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -1
- package/src/__tests__/integration-status.test.ts +3 -8
- package/src/__tests__/intent-routing.test.ts +7 -46
- package/src/__tests__/invite-redemption-service.test.ts +0 -1
- package/src/__tests__/invite-routes-http.test.ts +0 -1
- package/src/__tests__/llm-usage-store.test.ts +0 -1
- package/src/__tests__/managed-avatar-client.test.ts +101 -55
- package/src/__tests__/managed-skill-lifecycle.test.ts +9 -18
- package/src/__tests__/managed-store.test.ts +94 -21
- package/src/__tests__/media-reuse-story.e2e.test.ts +0 -1
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +2 -4
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -1
- package/src/__tests__/memory-recall-quality.test.ts +0 -1
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -1
- package/src/__tests__/memory-regressions.test.ts +0 -1
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -1
- package/src/__tests__/memory-upsert-concurrency.test.ts +0 -1
- package/src/__tests__/messaging-send-tool.test.ts +35 -0
- package/src/__tests__/messaging-skill-split.test.ts +138 -0
- package/src/__tests__/migration-cross-version-compatibility.test.ts +0 -1
- package/src/__tests__/migration-export-http.test.ts +2 -3
- package/src/__tests__/migration-import-commit-http.test.ts +1 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +1 -2
- package/src/__tests__/migration-validate-http.test.ts +1 -2
- package/src/__tests__/native-web-search.test.ts +475 -0
- package/src/__tests__/navigate-settings-tab.test.ts +84 -0
- package/src/__tests__/non-member-access-request.test.ts +0 -1
- package/src/__tests__/notification-broadcaster.test.ts +15 -15
- package/src/__tests__/notification-decision-strategy.test.ts +6 -6
- package/src/__tests__/notification-deep-link.test.ts +7 -7
- package/src/__tests__/notification-guardian-path.test.ts +2 -3
- package/src/__tests__/notification-telegram-adapter.test.ts +1 -1
- package/src/__tests__/notification-thread-candidates.test.ts +4 -4
- package/src/__tests__/onboarding-starter-tasks.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +0 -10
- package/src/__tests__/playbook-execution.test.ts +0 -1
- package/src/__tests__/playbook-tools.test.ts +0 -1
- package/src/__tests__/profile-compiler.test.ts +0 -1
- package/src/__tests__/provider-fail-open-selection.test.ts +12 -2
- package/src/__tests__/provider-managed-proxy-integration.test.ts +25 -0
- package/src/__tests__/qdrant-collection-migration.test.ts +223 -0
- package/src/__tests__/recording-handler.test.ts +30 -94
- package/src/__tests__/registry.test.ts +28 -35
- package/src/__tests__/relay-server.test.ts +0 -1
- package/src/__tests__/ride-shotgun-handler.test.ts +4 -20
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
- package/src/__tests__/runtime-events-sse.test.ts +0 -1
- package/src/__tests__/sandbox-diagnostics.test.ts +0 -1
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +30 -28
- package/src/__tests__/schedule-store.test.ts +441 -1
- package/src/__tests__/schedule-tools.test.ts +468 -7
- package/src/__tests__/scheduler-recurrence.test.ts +196 -23
- package/src/__tests__/scoped-approval-grants.test.ts +0 -1
- package/src/__tests__/scoped-grant-security-matrix.test.ts +0 -1
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +6 -3
- package/src/__tests__/secret-response-routing.test.ts +4 -1
- package/src/__tests__/send-endpoint-busy.test.ts +14 -5
- package/src/__tests__/send-notification-tool.test.ts +0 -7
- package/src/__tests__/sequence-store.test.ts +0 -1
- package/src/__tests__/server-history-render.test.ts +1 -2
- package/src/__tests__/session-abort-tool-results.test.ts +0 -1
- package/src/__tests__/session-agent-loop.test.ts +46 -6
- package/src/__tests__/session-confirmation-signals.test.ts +7 -46
- package/src/__tests__/session-conflict-gate.test.ts +2 -6
- package/src/__tests__/session-error.test.ts +5 -14
- package/src/__tests__/session-init.benchmark.test.ts +3 -5
- package/src/__tests__/session-load-history-repair.test.ts +0 -1
- package/src/__tests__/session-media-retry.test.ts +12 -74
- package/src/__tests__/session-pre-run-repair.test.ts +0 -1
- package/src/__tests__/session-profile-injection.test.ts +2 -6
- package/src/__tests__/session-provider-retry-repair.test.ts +2 -6
- package/src/__tests__/session-queue.test.ts +94 -139
- package/src/__tests__/session-skill-tools.test.ts +115 -115
- package/src/__tests__/session-slash-known.test.ts +0 -1
- package/src/__tests__/session-slash-queue.test.ts +0 -1
- package/src/__tests__/session-slash-unknown.test.ts +0 -1
- package/src/__tests__/session-surfaces-task-progress.test.ts +34 -0
- package/src/__tests__/session-usage.test.ts +0 -1
- package/src/__tests__/session-workspace-cache-state.test.ts +2 -6
- package/src/__tests__/session-workspace-injection.test.ts +2 -6
- package/src/__tests__/session-workspace-tool-tracking.test.ts +2 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +180 -184
- package/src/__tests__/skill-feature-flags.test.ts +125 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -2
- package/src/__tests__/skill-load-tool.test.ts +194 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +27 -16
- package/src/__tests__/skill-projection.benchmark.test.ts +15 -14
- package/src/__tests__/skills.test.ts +14 -53
- package/src/__tests__/slack-channel-config.test.ts +0 -1
- package/src/__tests__/slack-inbound-verification.test.ts +0 -1
- package/src/__tests__/slack-skill.test.ts +1 -1
- package/src/__tests__/starter-task-flow.test.ts +9 -19
- package/src/__tests__/subagent-tools.test.ts +2 -2
- package/src/__tests__/system-prompt.test.ts +7 -7
- package/src/__tests__/task-compiler.test.ts +0 -1
- package/src/__tests__/task-management-tools.test.ts +0 -1
- package/src/__tests__/task-memory-cleanup.test.ts +0 -1
- package/src/__tests__/task-runner.test.ts +0 -1
- package/src/__tests__/task-scheduler.test.ts +0 -1
- package/src/__tests__/terminal-tools.test.ts +0 -1
- package/src/__tests__/test-support/computer-use-skill-harness.ts +2 -4
- package/src/__tests__/thread-seed-composer.test.ts +5 -5
- package/src/__tests__/tool-approval-handler.test.ts +0 -1
- package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -1
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -1
- package/src/__tests__/tool-executor.test.ts +8 -86
- package/src/__tests__/tool-grant-request-escalation.test.ts +0 -1
- package/src/__tests__/tool-notification-listener.test.ts +1 -1
- package/src/__tests__/tool-preview-lifecycle.test.ts +416 -0
- package/src/__tests__/trust-store.test.ts +84 -8
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +0 -1
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -1
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/trusted-contact-verification.test.ts +0 -1
- package/src/__tests__/twilio-provider.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +0 -1
- package/src/__tests__/{request-file-tool.test.ts → ui-file-upload-surface.test.ts} +11 -72
- package/src/__tests__/update-bulletin.test.ts +0 -1
- package/src/__tests__/usage-cache-backfill-migration.test.ts +0 -1
- package/src/__tests__/usage-routes.test.ts +0 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +4 -4
- package/src/__tests__/voice-invite-redemption.test.ts +0 -1
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -1
- package/src/__tests__/voice-session-bridge.test.ts +9 -1
- package/src/__tests__/web-fetch.test.ts +57 -0
- package/src/__tests__/workspace-git-service.test.ts +5 -14
- package/src/__tests__/workspace-policy.test.ts +0 -1
- package/src/agent/loop.ts +22 -34
- package/src/bundler/bundle-signer.ts +4 -4
- package/src/calls/call-controller.ts +1 -1
- package/src/calls/relay-server.ts +1 -1
- package/src/calls/twilio-rest.ts +1 -1
- package/src/calls/voice-session-bridge.ts +3 -1
- package/src/cli/__tests__/notifications.test.ts +3 -4
- package/src/cli/commands/map.ts +2 -6
- package/src/cli/commands/mcp.ts +73 -15
- package/src/cli/commands/notifications.ts +4 -4
- package/src/cli/commands/sessions.ts +9 -1
- package/src/cli/commands/skills.ts +6 -10
- package/src/cli/http-client.ts +2 -3
- package/src/cli/main-screen.tsx +10 -10
- package/src/cli/program.ts +0 -4
- package/src/cli/reference.ts +0 -2
- package/src/cli.ts +15 -9
- package/src/config/__tests__/bundled-tool-registry-guard.test.ts +120 -0
- package/src/config/bundled-skills/_shared/CLI_RETRIEVAL_PATTERN.md +11 -0
- package/src/config/bundled-skills/app-builder/SKILL.md +6 -7
- package/src/config/bundled-skills/app-builder/TOOLS.json +0 -4
- package/src/config/bundled-skills/browser/SKILL.md +6 -1
- package/src/config/bundled-skills/chatgpt-import/SKILL.md +5 -1
- package/src/config/bundled-skills/claude-code/SKILL.md +5 -1
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -1
- package/src/config/bundled-skills/computer-use/TOOLS.json +6 -69
- package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +10 -1
- package/src/config/bundled-skills/contacts/SKILL.md +10 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +35 -0
- package/src/config/bundled-skills/{messaging → contacts}/tools/google-contacts.ts +9 -2
- package/src/config/bundled-skills/document/SKILL.md +4 -1
- package/src/config/bundled-skills/doordash/SKILL.md +8 -2
- package/src/config/bundled-skills/doordash/__tests__/doordash-session.test.ts +1 -82
- package/src/config/bundled-skills/doordash/doordash-cli.ts +17 -28
- package/src/config/bundled-skills/doordash/lib/session.ts +21 -17
- package/src/config/bundled-skills/doordash/lib/shared/platform.ts +4 -1
- package/src/config/bundled-skills/followups/SKILL.md +4 -1
- package/src/config/bundled-skills/gmail/SKILL.md +180 -0
- package/src/config/bundled-skills/gmail/TOOLS.json +506 -0
- package/src/config/bundled-skills/gmail/tools/gmail-archive.ts +149 -0
- package/src/config/bundled-skills/gmail/tools/gmail-attachments.ts +110 -0
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-filters.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-follow-up.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-forward.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/gmail-label.ts +50 -0
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-outreach-scan.ts +8 -90
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-send-draft.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-sender-digest.ts +2 -2
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-trash.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-unsubscribe.ts +1 -1
- package/src/config/bundled-skills/{messaging → gmail}/tools/gmail-vacation.ts +1 -1
- package/src/config/bundled-skills/gmail/tools/shared.ts +47 -0
- package/src/config/bundled-skills/google-calendar/SKILL.md +5 -1
- package/src/config/bundled-skills/image-studio/SKILL.md +5 -1
- package/src/config/bundled-skills/knowledge-graph/SKILL.md +4 -1
- package/src/config/bundled-skills/media-processing/SKILL.md +7 -13
- package/src/config/bundled-skills/media-processing/TOOLS.json +0 -22
- package/src/config/bundled-skills/media-processing/tools/generate-clip.ts +12 -1
- package/src/config/bundled-skills/messaging/SKILL.md +23 -139
- package/src/config/bundled-skills/messaging/TOOLS.json +33 -1215
- package/src/config/bundled-skills/messaging/tools/gmail-mime-helpers.ts +42 -0
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +165 -2
- package/src/config/bundled-skills/messaging/tools/messaging-sender-digest.ts +1 -13
- package/src/config/bundled-skills/messaging/tools/shared.ts +81 -34
- package/src/config/bundled-skills/notifications/SKILL.md +5 -1
- package/src/config/bundled-skills/orchestration/SKILL.md +30 -0
- package/src/config/bundled-skills/orchestration/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-cancel.ts → orchestration/tools/swarm-delegate.ts} +3 -3
- package/src/config/bundled-skills/phone-calls/SKILL.md +9 -1
- package/src/config/bundled-skills/playbooks/SKILL.md +4 -1
- package/src/config/bundled-skills/schedule/SKILL.md +70 -9
- package/src/config/bundled-skills/schedule/TOOLS.json +38 -6
- package/src/config/bundled-skills/screen-watch/SKILL.md +28 -0
- package/src/config/bundled-skills/screen-watch/TOOLS.json +35 -0
- package/src/config/bundled-skills/{reminder/tools/reminder-create.ts → screen-watch/tools/start-screen-watch.ts} +3 -3
- package/src/config/bundled-skills/sequences/SKILL.md +47 -0
- package/src/config/bundled-skills/sequences/TOOLS.json +340 -0
- package/src/config/bundled-skills/sequences/tools/sequence-update.ts +128 -0
- package/src/config/bundled-skills/sequences/tools/shared.ts +9 -0
- package/src/config/bundled-skills/settings/SKILL.md +12 -0
- package/src/config/bundled-skills/settings/TOOLS.json +112 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +43 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +52 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-right-click.ts → settings/tools/set-avatar.ts} +2 -6
- package/src/{tools/system/voice-config.ts → config/bundled-skills/settings/tools/voice-config-update.ts} +59 -96
- package/src/config/bundled-skills/skill-management/SKILL.md +18 -0
- package/src/config/bundled-skills/skill-management/TOOLS.json +90 -0
- package/src/config/bundled-skills/{computer-use/tools/computer-use-double-click.ts → skill-management/tools/delete-managed.ts} +2 -6
- package/src/config/bundled-skills/skill-management/tools/scaffold-managed.ts +12 -0
- package/src/config/bundled-skills/slack/SKILL.md +5 -1
- package/src/config/bundled-skills/subagent/SKILL.md +4 -1
- package/src/config/bundled-skills/tasks/SKILL.md +5 -2
- package/src/config/bundled-skills/transcribe/SKILL.md +4 -1
- package/src/config/bundled-skills/watcher/SKILL.md +4 -1
- package/src/config/bundled-tool-registry.ts +118 -107
- package/src/config/env.ts +5 -2
- package/src/config/feature-flag-registry.json +33 -9
- package/src/config/loader.ts +10 -2
- package/src/config/schema.ts +19 -16
- package/src/config/schemas/inference.ts +12 -22
- package/src/config/schemas/memory-storage.ts +19 -1
- package/src/config/schemas/platform.ts +0 -16
- package/src/config/skill-state.ts +11 -8
- package/src/config/skills.ts +83 -32
- package/src/context/token-estimator.ts +11 -0
- package/src/context/window-manager.ts +180 -151
- package/src/daemon/computer-use-session.ts +11 -43
- package/src/daemon/daemon-control.ts +4 -1
- package/src/daemon/handlers/config-channels.ts +5 -9
- package/src/daemon/handlers/config-ingress.ts +0 -4
- package/src/daemon/handlers/config-model.ts +7 -13
- package/src/daemon/handlers/config-telegram.ts +4 -8
- package/src/daemon/handlers/config-voice.ts +2 -5
- package/src/daemon/handlers/dictation.ts +2 -12
- package/src/daemon/handlers/identity.ts +0 -105
- package/src/daemon/handlers/recording.ts +3 -23
- package/src/daemon/handlers/session-history.ts +42 -10
- package/src/daemon/handlers/sessions.ts +53 -72
- package/src/daemon/handlers/shared.ts +7 -28
- package/src/daemon/handlers/skills.ts +31 -27
- package/src/daemon/host-bash-proxy.ts +148 -0
- package/src/daemon/host-file-proxy.ts +135 -0
- package/src/daemon/lifecycle.ts +53 -41
- package/src/daemon/mcp-reload-service.ts +123 -0
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/apps.ts +0 -25
- package/src/daemon/message-types/browser.ts +1 -1
- package/src/daemon/message-types/computer-use.ts +1 -4
- package/src/daemon/message-types/guardian-actions.ts +1 -1
- package/src/daemon/message-types/host-bash.ts +18 -0
- package/src/daemon/message-types/host-file.ts +44 -0
- package/src/daemon/message-types/integrations.ts +1 -73
- package/src/daemon/message-types/messages.ts +15 -0
- package/src/daemon/message-types/schedules.ts +11 -27
- package/src/daemon/message-types/sessions.ts +8 -2
- package/src/daemon/message-types/settings.ts +1 -1
- package/src/daemon/message-types/shared.ts +1 -1
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/ride-shotgun-handler.ts +35 -43
- package/src/daemon/seed-files.ts +3 -27
- package/src/daemon/server.ts +45 -28
- package/src/daemon/session-agent-loop-handlers.ts +72 -9
- package/src/daemon/session-agent-loop.ts +97 -66
- package/src/daemon/session-attachments.ts +1 -1
- package/src/daemon/session-error.ts +17 -16
- package/src/daemon/session-lifecycle.ts +20 -1
- package/src/daemon/session-media-retry.ts +1 -15
- package/src/daemon/session-messaging.ts +14 -6
- package/src/daemon/session-process.ts +36 -7
- package/src/daemon/session-queue-manager.ts +62 -103
- package/src/daemon/session-runtime-assembly.ts +27 -7
- package/src/daemon/session-skill-tools.ts +12 -11
- package/src/daemon/session-slash.ts +7 -0
- package/src/daemon/session-surfaces.ts +192 -118
- package/src/daemon/session-tool-setup.ts +146 -6
- package/src/daemon/session.ts +75 -37
- package/src/errors.ts +0 -2
- package/src/export/formatter.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +1 -3
- package/src/media/avatar-router.ts +20 -28
- package/src/media/avatar-types.ts +7 -14
- package/src/media/managed-avatar-client.ts +70 -34
- package/src/memory/app-store.ts +0 -18
- package/src/memory/conversation-title-service.ts +1 -2
- package/src/memory/db-init.ts +16 -0
- package/src/memory/embedding-backend.ts +129 -27
- package/src/memory/embedding-gemini.test.ts +256 -0
- package/src/memory/embedding-gemini.ts +47 -13
- package/src/memory/embedding-local.ts +14 -2
- package/src/memory/embedding-ollama.ts +15 -2
- package/src/memory/embedding-openai.ts +15 -2
- package/src/memory/embedding-types.test.ts +116 -0
- package/src/memory/embedding-types.ts +61 -0
- package/src/memory/fingerprint.ts +1 -1
- package/src/memory/indexer.ts +25 -1
- package/src/memory/job-handlers/embedding.test.ts +258 -0
- package/src/memory/job-handlers/embedding.ts +81 -1
- package/src/memory/job-handlers/index-maintenance.ts +35 -1
- package/src/memory/job-handlers/media-processing.ts +11 -1
- package/src/memory/job-utils.ts +21 -6
- package/src/memory/jobs-store.ts +5 -1
- package/src/memory/jobs-worker.ts +8 -0
- package/src/memory/message-content.ts +66 -0
- package/src/memory/migrations/100-core-tables.ts +1 -31
- package/src/memory/migrations/104-core-indexes.ts +0 -11
- package/src/memory/migrations/145-drop-accounts-table.ts +19 -0
- package/src/memory/migrations/146-schedule-oneshot-routing.ts +94 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +129 -0
- package/src/memory/migrations/148-drop-reminders-table.ts +18 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +19 -0
- package/src/memory/qdrant-client.ts +158 -43
- package/src/memory/retriever.test.ts +0 -1
- package/src/memory/retriever.ts +12 -2
- package/src/memory/schema/infrastructure.ts +5 -37
- package/src/memory/search/formatting.ts +34 -9
- package/src/memory/search/semantic.ts +57 -2
- package/src/memory/search/types.ts +2 -1
- package/src/notifications/AGENTS.md +2 -2
- package/src/notifications/README.md +59 -58
- package/src/notifications/adapters/macos.ts +1 -1
- package/src/notifications/broadcaster.ts +5 -5
- package/src/notifications/copy-composer.ts +1 -1
- package/src/notifications/decision-engine.ts +2 -2
- package/src/notifications/destination-resolver.ts +2 -2
- package/src/notifications/emit-signal.ts +8 -8
- package/src/notifications/signal.ts +1 -1
- package/src/notifications/thread-seed-composer.ts +1 -1
- package/src/oauth/connect-orchestrator.ts +1 -1
- package/src/oauth/token-persistence.ts +1 -1
- package/src/permissions/checker.ts +12 -1
- package/src/permissions/defaults.ts +13 -17
- package/src/permissions/trust-store.ts +37 -0
- package/src/permissions/workspace-policy.ts +0 -1
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +11 -0
- package/src/prompts/computer-use-prompt.ts +1 -1
- package/src/prompts/system-prompt.ts +33 -35
- package/src/prompts/templates/BOOTSTRAP.md +0 -3
- package/src/prompts/templates/SOUL.md +1 -2
- package/src/prompts/templates/UPDATES.md +16 -7
- package/src/providers/anthropic/client.ts +87 -33
- package/src/providers/gemini/client.ts +6 -0
- package/src/providers/managed-proxy/constants.ts +5 -0
- package/src/providers/openai/client.ts +15 -0
- package/src/providers/registry.ts +4 -6
- package/src/providers/types.ts +24 -2
- package/src/runtime/AGENTS.md +18 -0
- package/src/runtime/assistant-event-hub.ts +2 -3
- package/src/runtime/assistant-event.ts +4 -4
- package/src/runtime/auth/__tests__/context.test.ts +5 -5
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/guard-tests.test.ts +3 -2
- package/src/runtime/auth/__tests__/{ipc-auth-context.test.ts → local-auth-context.test.ts} +21 -21
- package/src/runtime/auth/__tests__/route-policy.test.ts +2 -2
- package/src/runtime/auth/__tests__/scopes.test.ts +9 -8
- package/src/runtime/auth/__tests__/subject.test.ts +8 -8
- package/src/runtime/auth/__tests__/token-service.test.ts +0 -1
- package/src/runtime/auth/route-policy.ts +8 -8
- package/src/runtime/auth/scopes.ts +2 -1
- package/src/runtime/auth/subject.ts +4 -4
- package/src/runtime/auth/token-service.ts +1 -24
- package/src/runtime/auth/types.ts +3 -3
- package/src/runtime/guardian-action-followup-executor.ts +1 -1
- package/src/runtime/guardian-action-grant-minter.ts +1 -1
- package/src/runtime/guardian-action-service.ts +3 -3
- package/src/runtime/http-server.ts +15 -2
- package/src/runtime/http-types.ts +10 -0
- package/src/runtime/invite-service.ts +3 -3
- package/src/runtime/local-actor-identity.ts +17 -22
- package/src/runtime/middleware/error-handler.ts +14 -1
- package/src/runtime/pending-interactions.ts +21 -9
- package/src/runtime/routes/app-management-routes.ts +63 -67
- package/src/runtime/routes/approval-routes.ts +1 -3
- package/src/runtime/routes/brain-graph/brain-graph.html +1845 -0
- package/src/runtime/routes/brain-graph-routes.ts +4 -42
- package/src/runtime/routes/btw-routes.ts +155 -0
- package/src/runtime/routes/computer-use-routes.ts +77 -31
- package/src/runtime/routes/conversation-routes.ts +234 -47
- package/src/runtime/routes/diagnostics-routes.ts +154 -43
- package/src/runtime/routes/documents-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +1 -1
- package/src/runtime/routes/host-bash-routes.ts +83 -0
- package/src/runtime/routes/host-file-routes.ts +79 -0
- package/src/runtime/routes/integrations/slack/share.ts +1 -1
- package/src/runtime/routes/log-export-routes.ts +120 -0
- package/src/runtime/routes/mcp-routes.ts +20 -0
- package/src/runtime/routes/migration-routes.ts +3 -3
- package/src/runtime/routes/pairing-routes.ts +1 -1
- package/src/runtime/routes/recording-routes.ts +6 -4
- package/src/runtime/routes/schedule-routes.ts +31 -5
- package/src/runtime/routes/session-management-routes.ts +2 -6
- package/src/runtime/routes/session-query-routes.ts +18 -15
- package/src/runtime/routes/settings-routes.ts +7 -351
- package/src/runtime/routes/skills-routes.ts +7 -6
- package/src/runtime/routes/subagents-routes.ts +4 -10
- package/src/runtime/routes/surface-action-routes.ts +3 -14
- package/src/runtime/routes/surface-content-routes.ts +22 -5
- package/src/runtime/routes/work-items-routes.ts +21 -25
- package/src/runtime/routes/workspace-routes.test.ts +3 -3
- package/src/runtime/routes/workspace-utils.ts +1 -1
- package/src/runtime/telegram-streaming-delivery.ts +3 -0
- package/src/runtime/verification-outbound-actions.ts +2 -2
- package/src/schedule/integration-status.ts +0 -6
- package/src/schedule/schedule-store.ts +234 -43
- package/src/schedule/scheduler.ts +73 -74
- package/src/security/oauth2.ts +1 -1
- package/src/sequence/store.ts +12 -2
- package/src/skills/frontmatter.ts +19 -77
- package/src/skills/managed-store.ts +11 -2
- package/src/subagent/manager.ts +5 -3
- package/src/tasks/ephemeral-permissions.ts +3 -5
- package/src/tools/AGENTS.md +37 -0
- package/src/tools/apps/executors.ts +0 -6
- package/src/tools/browser/browser-manager.ts +17 -11
- package/src/tools/browser/jit-auth.ts +4 -1
- package/src/tools/claude-code/claude-code.ts +1 -1
- package/src/tools/computer-use/definitions.ts +48 -60
- package/src/tools/document/document-tool.ts +6 -6
- package/src/tools/document/editor-template.ts +10 -8
- package/src/tools/filesystem/edit.ts +2 -1
- package/src/tools/filesystem/read.ts +20 -2
- package/src/tools/filesystem/write.ts +2 -1
- package/src/tools/host-filesystem/edit.ts +17 -1
- package/src/tools/host-filesystem/read.ts +16 -1
- package/src/tools/host-filesystem/write.ts +15 -1
- package/src/tools/host-terminal/host-shell.ts +24 -0
- package/src/tools/memory/definitions.ts +45 -81
- package/src/tools/memory/handlers.test.ts +0 -1
- package/src/tools/memory/handlers.ts +1 -1
- package/src/tools/memory/register.ts +26 -60
- package/src/tools/network/script-proxy/session-manager.ts +6 -8
- package/src/tools/network/web-fetch.ts +7 -1
- package/src/tools/network/web-search.ts +2 -1
- package/src/tools/registry.ts +23 -0
- package/src/tools/schedule/create.ts +113 -5
- package/src/tools/schedule/list.ts +57 -15
- package/src/tools/schedule/update.ts +73 -3
- package/src/tools/shared/filesystem/image-read.ts +192 -0
- package/src/tools/side-effects.ts +1 -7
- package/src/tools/skills/delete-managed.ts +27 -64
- package/src/tools/skills/execute.ts +54 -0
- package/src/tools/skills/load.ts +127 -5
- package/src/tools/skills/scaffold-managed.ts +93 -172
- package/src/tools/subagent/message.ts +0 -7
- package/src/tools/subagent/spawn.ts +1 -1
- package/src/tools/swarm/delegate.ts +0 -3
- package/src/tools/system/avatar-generator.ts +13 -19
- package/src/tools/system/request-permission.ts +2 -1
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +41 -47
- package/src/tools/types.ts +6 -2
- package/src/tools/ui-surface/definitions.ts +0 -55
- package/src/util/errors.ts +12 -10
- package/src/workspace/git-service.ts +0 -2
- package/src/__tests__/account-registry.test.ts +0 -258
- package/src/__tests__/email-classifier.test.ts +0 -25
- package/src/__tests__/gmail-integration.test.ts +0 -97
- package/src/__tests__/handle-user-message-secret-resume.test.ts +0 -172
- package/src/__tests__/home-base-bootstrap.test.ts +0 -84
- package/src/__tests__/managed-twitter-guardrails.test.ts +0 -353
- package/src/__tests__/prebuilt-home-base-seed.test.ts +0 -79
- package/src/__tests__/recording-intent-fallback.test.ts +0 -199
- package/src/__tests__/recording-intent.test.ts +0 -985
- package/src/__tests__/recording-state-machine.test.ts +0 -1574
- package/src/__tests__/reminder-store.test.ts +0 -350
- package/src/__tests__/reminder.test.ts +0 -337
- package/src/__tests__/scan-result-store.test.ts +0 -121
- package/src/__tests__/twitter-platform-proxy-client.test.ts +0 -450
- package/src/__tests__/view-image-tool.test.ts +0 -241
- package/src/cli/commands/amazon/cart.ts +0 -513
- package/src/cli/commands/amazon/checkout.ts +0 -394
- package/src/cli/commands/amazon/client.ts +0 -513
- package/src/cli/commands/amazon/index.ts +0 -920
- package/src/cli/commands/amazon/product-details.ts +0 -145
- package/src/cli/commands/amazon/request-extractor.ts +0 -187
- package/src/cli/commands/amazon/search.ts +0 -76
- package/src/cli/commands/amazon/session.ts +0 -116
- package/src/cli/commands/twitter/__tests__/cli-error-shaping.test.ts +0 -265
- package/src/cli/commands/twitter/__tests__/cli-read-routing.test.ts +0 -483
- package/src/cli/commands/twitter/__tests__/cli-routing.test.ts +0 -412
- package/src/cli/commands/twitter/__tests__/oauth-client.test.ts +0 -197
- package/src/cli/commands/twitter/client.ts +0 -989
- package/src/cli/commands/twitter/index.ts +0 -1160
- package/src/cli/commands/twitter/oauth-client.ts +0 -94
- package/src/cli/commands/twitter/router.ts +0 -396
- package/src/cli/commands/twitter/session.ts +0 -121
- package/src/config/bundled-skills/agentmail/SKILL.md +0 -132
- package/src/config/bundled-skills/agentmail/icon.svg +0 -21
- package/src/config/bundled-skills/amazon/SKILL.md +0 -137
- package/src/config/bundled-skills/amazon/icon.svg +0 -13
- package/src/config/bundled-skills/api-mapping/SKILL.md +0 -78
- package/src/config/bundled-skills/api-mapping/icon.svg +0 -18
- package/src/config/bundled-skills/cli-discover/SKILL.md +0 -68
- package/src/config/bundled-skills/deploy-fullstack-vercel/SKILL.md +0 -179
- package/src/config/bundled-skills/document-writer/SKILL.md +0 -195
- package/src/config/bundled-skills/elevenlabs-voice/SKILL.md +0 -140
- package/src/config/bundled-skills/email-setup/SKILL.md +0 -68
- package/src/config/bundled-skills/frontend-design/SKILL.md +0 -44
- package/src/config/bundled-skills/frontend-design/icon.svg +0 -16
- package/src/config/bundled-skills/google-oauth-setup/SKILL.md +0 -452
- package/src/config/bundled-skills/guardian-verify-setup/SKILL.md +0 -203
- package/src/config/bundled-skills/influencer/SKILL.md +0 -144
- package/src/config/bundled-skills/influencer/scripts/client.ts +0 -1269
- package/src/config/bundled-skills/influencer/scripts/influencer.ts +0 -267
- package/src/config/bundled-skills/macos-automation/SKILL.md +0 -65
- package/src/config/bundled-skills/macos-automation/icon.svg +0 -12
- package/src/config/bundled-skills/mcp-setup/SKILL.md +0 -75
- package/src/config/bundled-skills/media-processing/tools/media-diagnostics.ts +0 -184
- package/src/config/bundled-skills/messaging/tools/gmail-archive-by-query.ts +0 -80
- package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +0 -29
- package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +0 -56
- package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +0 -34
- package/src/config/bundled-skills/messaging/tools/gmail-download-attachment.ts +0 -47
- package/src/config/bundled-skills/messaging/tools/gmail-label.ts +0 -31
- package/src/config/bundled-skills/messaging/tools/gmail-list-attachments.ts +0 -67
- package/src/config/bundled-skills/messaging/tools/gmail-send-with-attachments.ts +0 -97
- package/src/config/bundled-skills/messaging/tools/gmail-summarize-thread.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/gmail-triage.ts +0 -135
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +0 -24
- package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +0 -201
- package/src/config/bundled-skills/messaging/tools/send-notification.ts +0 -1
- package/src/config/bundled-skills/messaging/tools/sequence-cancel.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-pause.ts +0 -48
- package/src/config/bundled-skills/messaging/tools/sequence-resume.ts +0 -27
- package/src/config/bundled-skills/messaging/tools/sequence-update.ts +0 -56
- package/src/config/bundled-skills/notion/SKILL.md +0 -240
- package/src/config/bundled-skills/notion-oauth-setup/SKILL.md +0 -126
- package/src/config/bundled-skills/oauth-setup/SKILL.md +0 -143
- package/src/config/bundled-skills/public-ingress/SKILL.md +0 -258
- package/src/config/bundled-skills/reminder/SKILL.md +0 -79
- package/src/config/bundled-skills/reminder/TOOLS.json +0 -89
- package/src/config/bundled-skills/reminder/tools/reminder-list.ts +0 -12
- package/src/config/bundled-skills/restaurant-reservation/SKILL.md +0 -141
- package/src/config/bundled-skills/screen-recording/SKILL.md +0 -148
- package/src/config/bundled-skills/self-upgrade/SKILL.md +0 -69
- package/src/config/bundled-skills/skills-catalog/SKILL.md +0 -78
- package/src/config/bundled-skills/slack-app-setup/SKILL.md +0 -178
- package/src/config/bundled-skills/slack-digest-setup/SKILL.md +0 -163
- package/src/config/bundled-skills/slack-oauth-setup/SKILL.md +0 -157
- package/src/config/bundled-skills/start-the-day/SKILL.md +0 -70
- package/src/config/bundled-skills/start-the-day/icon.svg +0 -13
- package/src/config/bundled-skills/telegram-setup/SKILL.md +0 -105
- package/src/config/bundled-skills/time-based-actions/SKILL.md +0 -142
- package/src/config/bundled-skills/twilio-setup/SKILL.md +0 -232
- package/src/config/bundled-skills/twitter/SKILL.md +0 -319
- package/src/config/bundled-skills/twitter/icon.svg +0 -14
- package/src/config/bundled-skills/typescript-eval/SKILL.md +0 -60
- package/src/config/bundled-skills/vercel-token-setup/SKILL.md +0 -214
- package/src/config/bundled-skills/voice-setup/SKILL.md +0 -131
- package/src/config/bundled-skills/voice-setup/icon.svg +0 -20
- package/src/daemon/handlers/pairing.ts +0 -119
- package/src/daemon/handlers/session-user-message.ts +0 -961
- package/src/daemon/recording-executor.ts +0 -180
- package/src/daemon/recording-intent-fallback.ts +0 -162
- package/src/daemon/recording-intent.ts +0 -493
- package/src/home-base/app-link-store.ts +0 -78
- package/src/home-base/bootstrap.ts +0 -74
- package/src/home-base/prebuilt/brain-graph.html +0 -1483
- package/src/home-base/prebuilt/index.html +0 -702
- package/src/home-base/prebuilt/seed-metadata.json +0 -21
- package/src/home-base/prebuilt/seed.ts +0 -122
- package/src/home-base/prebuilt-home-base-updater.ts +0 -36
- package/src/memory/account-store.ts +0 -117
- package/src/messaging/activity-analyzer.ts +0 -76
- package/src/messaging/email-classifier.ts +0 -208
- package/src/messaging/index.ts +0 -2
- package/src/messaging/outreach-classifier.ts +0 -185
- package/src/messaging/thread-summarizer.ts +0 -346
- package/src/messaging/types.ts +0 -17
- package/src/tools/browser/x-auto-navigate.ts +0 -254
- package/src/tools/credentials/account-registry.ts +0 -144
- package/src/tools/filesystem/view-image.ts +0 -244
- package/src/tools/reminder/reminder-store.ts +0 -194
- package/src/tools/reminder/reminder.ts +0 -158
- package/src/tools/system/navigate-settings.ts +0 -74
- package/src/tools/system/open-system-settings.ts +0 -85
- package/src/tools/system/version.ts +0 -54
- package/src/twitter/platform-proxy-client.ts +0 -405
- package/src/util/cookie-session.ts +0 -98
- /package/src/config/bundled-skills/{messaging → gmail}/tools/scan-result-store.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-analytics.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-create.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-delete.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enroll.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-enrollment-list.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-get.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-import.ts +0 -0
- /package/src/config/bundled-skills/{messaging → sequences}/tools/sequence-list.ts +0 -0
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { eq } from "drizzle-orm";
|
|
1
|
+
import { eq, like } from "drizzle-orm";
|
|
2
2
|
|
|
3
|
+
import { getConfig } from "../../config/loader.js";
|
|
3
4
|
import { getLogger } from "../../util/logger.js";
|
|
4
5
|
import { getDb, rawExec } from "../db.js";
|
|
6
|
+
import { selectedBackendSupportsMultimodal } from "../embedding-backend.js";
|
|
5
7
|
import { asString, BackendUnavailableError } from "../job-utils.js";
|
|
6
8
|
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
9
|
+
import { extractMediaBlockMeta } from "../message-content.js";
|
|
7
10
|
import { withQdrantBreaker } from "../qdrant-circuit-breaker.js";
|
|
8
11
|
import { getQdrantClient } from "../qdrant-client.js";
|
|
9
12
|
import {
|
|
13
|
+
mediaAssets,
|
|
10
14
|
memoryEmbeddings,
|
|
11
15
|
memoryItems,
|
|
12
16
|
memorySegments,
|
|
13
17
|
memorySummaries,
|
|
18
|
+
messages,
|
|
14
19
|
} from "../schema.js";
|
|
15
20
|
|
|
16
21
|
const log = getLogger("memory-jobs-worker");
|
|
@@ -48,6 +53,35 @@ export function rebuildIndexJob(): void {
|
|
|
48
53
|
for (const segment of segments) {
|
|
49
54
|
enqueueMemoryJob("embed_segment", { segmentId: segment.id });
|
|
50
55
|
}
|
|
56
|
+
|
|
57
|
+
// Re-enqueue multimodal embedding jobs only when the resolved embedding
|
|
58
|
+
// backend supports multimodal inputs. Without this gate, embed_media and
|
|
59
|
+
// embed_attachment jobs would all fail for text-only backends.
|
|
60
|
+
if (selectedBackendSupportsMultimodal(getConfig())) {
|
|
61
|
+
const assets = db
|
|
62
|
+
.select({ id: mediaAssets.id })
|
|
63
|
+
.from(mediaAssets)
|
|
64
|
+
.where(eq(mediaAssets.status, "indexed"))
|
|
65
|
+
.all();
|
|
66
|
+
for (const asset of assets) {
|
|
67
|
+
enqueueMemoryJob("embed_media", { assetId: asset.id });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const imageMessages = db
|
|
71
|
+
.select({ id: messages.id, content: messages.content })
|
|
72
|
+
.from(messages)
|
|
73
|
+
.where(like(messages.content, '%"type":"image"%'))
|
|
74
|
+
.all();
|
|
75
|
+
for (const msg of imageMessages) {
|
|
76
|
+
const blocks = extractMediaBlockMeta(msg.content);
|
|
77
|
+
for (const block of blocks) {
|
|
78
|
+
enqueueMemoryJob("embed_attachment", {
|
|
79
|
+
messageId: msg.id,
|
|
80
|
+
blockIndex: block.index,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
51
85
|
}
|
|
52
86
|
|
|
53
87
|
export async function deleteQdrantVectorsJob(job: MemoryJob): Promise<void> {
|
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
import { mapSegmentsForAsset } from "../../config/bundled-skills/media-processing/tools/analyze-keyframes.js";
|
|
7
7
|
import { preprocessForAsset } from "../../config/bundled-skills/media-processing/tools/extract-keyframes.js";
|
|
8
8
|
import { reduceForAsset } from "../../config/bundled-skills/media-processing/tools/query-media-events.js";
|
|
9
|
+
import { getConfig } from "../../config/loader.js";
|
|
9
10
|
import { getLogger } from "../../util/logger.js";
|
|
11
|
+
import { selectedBackendSupportsMultimodal } from "../embedding-backend.js";
|
|
10
12
|
import { asString } from "../job-utils.js";
|
|
11
|
-
import type
|
|
13
|
+
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
12
14
|
import { getMediaAssetById, updateMediaAssetStatus } from "../media-store.js";
|
|
13
15
|
|
|
14
16
|
const log = getLogger("media-processing-job");
|
|
@@ -32,6 +34,9 @@ export async function mediaProcessingJob(job: MemoryJob): Promise<void> {
|
|
|
32
34
|
"Skipping media processing pipeline — only video assets are supported",
|
|
33
35
|
);
|
|
34
36
|
updateMediaAssetStatus(mediaAssetId, "indexed");
|
|
37
|
+
if (selectedBackendSupportsMultimodal(getConfig())) {
|
|
38
|
+
enqueueMemoryJob("embed_media", { assetId: mediaAssetId });
|
|
39
|
+
}
|
|
35
40
|
return;
|
|
36
41
|
}
|
|
37
42
|
|
|
@@ -107,4 +112,9 @@ export async function mediaProcessingJob(job: MemoryJob): Promise<void> {
|
|
|
107
112
|
if (result.cancelled) {
|
|
108
113
|
throw new Error(`Media processing cancelled for asset ${mediaAssetId}`);
|
|
109
114
|
}
|
|
115
|
+
|
|
116
|
+
updateMediaAssetStatus(mediaAssetId, "indexed");
|
|
117
|
+
if (selectedBackendSupportsMultimodal(getConfig())) {
|
|
118
|
+
enqueueMemoryJob("embed_media", { assetId: mediaAssetId });
|
|
119
|
+
}
|
|
110
120
|
}
|
package/src/memory/job-utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
2
|
|
|
3
3
|
import { and, eq } from "drizzle-orm";
|
|
4
4
|
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
embedWithBackend,
|
|
11
11
|
getMemoryBackendStatus,
|
|
12
12
|
} from "./embedding-backend.js";
|
|
13
|
+
import type { EmbeddingInput } from "./embedding-types.js";
|
|
14
|
+
import {
|
|
15
|
+
embeddingInputContentHash,
|
|
16
|
+
normalizeEmbeddingInput,
|
|
17
|
+
} from "./embedding-types.js";
|
|
13
18
|
import { withQdrantBreaker } from "./qdrant-circuit-breaker.js";
|
|
14
19
|
import { getQdrantClient } from "./qdrant-client.js";
|
|
15
20
|
import { memoryEmbeddings } from "./schema.js";
|
|
@@ -136,9 +141,9 @@ export function truncate(text: string, max: number): string {
|
|
|
136
141
|
|
|
137
142
|
export async function embedAndUpsert(
|
|
138
143
|
config: AssistantConfig,
|
|
139
|
-
targetType: "segment" | "item" | "summary",
|
|
144
|
+
targetType: "segment" | "item" | "summary" | "media",
|
|
140
145
|
targetId: string,
|
|
141
|
-
|
|
146
|
+
input: EmbeddingInput,
|
|
142
147
|
extraPayload?: Record<string, unknown>,
|
|
143
148
|
): Promise<void> {
|
|
144
149
|
const status = getMemoryBackendStatus(config);
|
|
@@ -148,7 +153,7 @@ export async function embedAndUpsert(
|
|
|
148
153
|
);
|
|
149
154
|
}
|
|
150
155
|
|
|
151
|
-
const contentHash =
|
|
156
|
+
const contentHash = embeddingInputContentHash(input);
|
|
152
157
|
let provider = status.provider;
|
|
153
158
|
let model = status.model!;
|
|
154
159
|
let vector: number[];
|
|
@@ -181,13 +186,21 @@ export async function embedAndUpsert(
|
|
|
181
186
|
vector = JSON.parse(cachedRow.vectorJson!);
|
|
182
187
|
}
|
|
183
188
|
} else {
|
|
184
|
-
const embedded = await embedWithBackend(config, [
|
|
189
|
+
const embedded = await embedWithBackend(config, [input]);
|
|
185
190
|
vector = embedded.vectors[0];
|
|
186
191
|
if (!vector) return;
|
|
187
192
|
provider = embedded.provider;
|
|
188
193
|
model = embedded.model;
|
|
189
194
|
}
|
|
190
195
|
|
|
196
|
+
// Extract text for Qdrant payload: use the raw text for text inputs,
|
|
197
|
+
// or a description string for non-text (image/audio/video) inputs.
|
|
198
|
+
const normalized = normalizeEmbeddingInput(input);
|
|
199
|
+
const payloadText =
|
|
200
|
+
normalized.type === "text"
|
|
201
|
+
? normalized.text
|
|
202
|
+
: `[${normalized.type}:${normalized.mimeType}]`;
|
|
203
|
+
|
|
191
204
|
// Persist embedding in SQLite for cross-restart cache
|
|
192
205
|
const now = Date.now();
|
|
193
206
|
try {
|
|
@@ -234,9 +247,11 @@ export async function embedAndUpsert(
|
|
|
234
247
|
}
|
|
235
248
|
|
|
236
249
|
try {
|
|
250
|
+
const modality = normalized.type;
|
|
237
251
|
await withQdrantBreaker(() =>
|
|
238
252
|
qdrant.upsert(targetType, targetId, vector, {
|
|
239
|
-
text,
|
|
253
|
+
text: payloadText,
|
|
254
|
+
modality,
|
|
240
255
|
created_at: (extraPayload?.created_at as number) ?? now,
|
|
241
256
|
...(extraPayload as Record<string, unknown> | undefined),
|
|
242
257
|
}),
|
package/src/memory/jobs-store.ts
CHANGED
|
@@ -27,12 +27,16 @@ export type MemoryJobType =
|
|
|
27
27
|
| "rebuild_index"
|
|
28
28
|
| "reconcile_fts"
|
|
29
29
|
| "delete_qdrant_vectors"
|
|
30
|
-
| "media_processing"
|
|
30
|
+
| "media_processing"
|
|
31
|
+
| "embed_media"
|
|
32
|
+
| "embed_attachment";
|
|
31
33
|
|
|
32
34
|
const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
33
35
|
"embed_segment",
|
|
34
36
|
"embed_item",
|
|
35
37
|
"embed_summary",
|
|
38
|
+
"embed_media",
|
|
39
|
+
"embed_attachment",
|
|
36
40
|
];
|
|
37
41
|
|
|
38
42
|
export interface MemoryJob<T = Record<string, unknown>> {
|
|
@@ -18,7 +18,9 @@ import {
|
|
|
18
18
|
} from "./job-handlers/conflict.js";
|
|
19
19
|
// ── Per-job-type handlers ──────────────────────────────────────────
|
|
20
20
|
import {
|
|
21
|
+
embedAttachmentJob,
|
|
21
22
|
embedItemJob,
|
|
23
|
+
embedMediaJob,
|
|
22
24
|
embedSegmentJob,
|
|
23
25
|
embedSummaryJob,
|
|
24
26
|
} from "./job-handlers/embedding.js";
|
|
@@ -334,6 +336,12 @@ async function processJob(
|
|
|
334
336
|
case "media_processing":
|
|
335
337
|
await mediaProcessingJob(job);
|
|
336
338
|
return;
|
|
339
|
+
case "embed_media":
|
|
340
|
+
await embedMediaJob(job, config);
|
|
341
|
+
return;
|
|
342
|
+
case "embed_attachment":
|
|
343
|
+
await embedAttachmentJob(job, config);
|
|
344
|
+
return;
|
|
337
345
|
default:
|
|
338
346
|
throw new Error(
|
|
339
347
|
`Unknown memory job type: ${(job as { type: string }).type}`,
|
|
@@ -45,6 +45,17 @@ export function extractTextFromStoredMessageContent(raw: string): string {
|
|
|
45
45
|
);
|
|
46
46
|
}
|
|
47
47
|
break;
|
|
48
|
+
case "server_tool_use": {
|
|
49
|
+
const query =
|
|
50
|
+
typeof block.input?.query === "string"
|
|
51
|
+
? block.input.query
|
|
52
|
+
: block.name;
|
|
53
|
+
lines.push(`[web search: ${query}]`);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case "web_search_tool_result":
|
|
57
|
+
lines.push("[web search results]");
|
|
58
|
+
break;
|
|
48
59
|
default:
|
|
49
60
|
lines.push("<unknown_content_block />");
|
|
50
61
|
}
|
|
@@ -55,6 +66,61 @@ export function extractTextFromStoredMessageContent(raw: string): string {
|
|
|
55
66
|
}
|
|
56
67
|
}
|
|
57
68
|
|
|
69
|
+
export function extractMediaBlocks(raw: string): Array<{
|
|
70
|
+
type: "image";
|
|
71
|
+
data: Buffer;
|
|
72
|
+
mimeType: string;
|
|
73
|
+
index: number;
|
|
74
|
+
}> {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
77
|
+
if (!Array.isArray(parsed)) return [];
|
|
78
|
+
const results: Array<{
|
|
79
|
+
type: "image";
|
|
80
|
+
data: Buffer;
|
|
81
|
+
mimeType: string;
|
|
82
|
+
index: number;
|
|
83
|
+
}> = [];
|
|
84
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
85
|
+
const block = parsed[i] as ContentBlock;
|
|
86
|
+
if (block.type === "image") {
|
|
87
|
+
results.push({
|
|
88
|
+
type: "image" as const,
|
|
89
|
+
data: Buffer.from(block.source.data, "base64"),
|
|
90
|
+
mimeType: block.source.media_type,
|
|
91
|
+
index: i,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
} catch {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Lightweight variant of extractMediaBlocks that returns only type and index
|
|
103
|
+
* metadata without decoding base64 image data into Buffers.
|
|
104
|
+
*/
|
|
105
|
+
export function extractMediaBlockMeta(
|
|
106
|
+
raw: string,
|
|
107
|
+
): Array<{ type: "image"; index: number }> {
|
|
108
|
+
try {
|
|
109
|
+
const parsed = JSON.parse(raw) as unknown;
|
|
110
|
+
if (!Array.isArray(parsed)) return [];
|
|
111
|
+
const results: Array<{ type: "image"; index: number }> = [];
|
|
112
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
113
|
+
const block = parsed[i] as { type?: string };
|
|
114
|
+
if (block.type === "image") {
|
|
115
|
+
results.push({ type: "image" as const, index: i });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return results;
|
|
119
|
+
} catch {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
58
124
|
function stableJson(value: unknown): string {
|
|
59
125
|
try {
|
|
60
126
|
return JSON.stringify(value);
|
|
@@ -5,7 +5,7 @@ import type { DrizzleDb } from "../db-connection.js";
|
|
|
5
5
|
* memory_items, memory_item_sources, memory_item_conflicts, memory_summaries,
|
|
6
6
|
* memory_embeddings, memory_jobs, memory_checkpoints, attachments,
|
|
7
7
|
* message_attachments, message_surfaces, channel_inbound_events,
|
|
8
|
-
* message_runs,
|
|
8
|
+
* message_runs, cron_jobs, cron_runs, documents,
|
|
9
9
|
* published_pages, shared_app_links, home_base_app_links.
|
|
10
10
|
*/
|
|
11
11
|
export function createCoreTables(database: DrizzleDb): void {
|
|
@@ -228,21 +228,6 @@ export function createCoreTables(database: DrizzleDb): void {
|
|
|
228
228
|
)
|
|
229
229
|
`);
|
|
230
230
|
|
|
231
|
-
database.run(/*sql*/ `
|
|
232
|
-
CREATE TABLE IF NOT EXISTS reminders (
|
|
233
|
-
id TEXT PRIMARY KEY,
|
|
234
|
-
label TEXT NOT NULL,
|
|
235
|
-
message TEXT NOT NULL,
|
|
236
|
-
fire_at INTEGER NOT NULL,
|
|
237
|
-
mode TEXT NOT NULL,
|
|
238
|
-
status TEXT NOT NULL,
|
|
239
|
-
fired_at INTEGER,
|
|
240
|
-
conversation_id TEXT,
|
|
241
|
-
created_at INTEGER NOT NULL,
|
|
242
|
-
updated_at INTEGER NOT NULL
|
|
243
|
-
)
|
|
244
|
-
`);
|
|
245
|
-
|
|
246
231
|
database.run(/*sql*/ `
|
|
247
232
|
CREATE TABLE IF NOT EXISTS cron_jobs (
|
|
248
233
|
id TEXT PRIMARY KEY,
|
|
@@ -277,21 +262,6 @@ export function createCoreTables(database: DrizzleDb): void {
|
|
|
277
262
|
)
|
|
278
263
|
`);
|
|
279
264
|
|
|
280
|
-
database.run(/*sql*/ `
|
|
281
|
-
CREATE TABLE IF NOT EXISTS accounts (
|
|
282
|
-
id TEXT PRIMARY KEY,
|
|
283
|
-
service TEXT NOT NULL,
|
|
284
|
-
username TEXT,
|
|
285
|
-
email TEXT,
|
|
286
|
-
display_name TEXT,
|
|
287
|
-
status TEXT NOT NULL DEFAULT 'active',
|
|
288
|
-
credential_ref TEXT,
|
|
289
|
-
metadata_json TEXT,
|
|
290
|
-
created_at INTEGER NOT NULL,
|
|
291
|
-
updated_at INTEGER NOT NULL
|
|
292
|
-
)
|
|
293
|
-
`);
|
|
294
|
-
|
|
295
265
|
database.run(/*sql*/ `
|
|
296
266
|
CREATE TABLE IF NOT EXISTS documents (
|
|
297
267
|
surface_id TEXT PRIMARY KEY,
|
|
@@ -198,10 +198,6 @@ export function createCoreIndexes(database: DrizzleDb): void {
|
|
|
198
198
|
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_message_runs_conversation ON message_runs(conversation_id)`,
|
|
199
199
|
);
|
|
200
200
|
|
|
201
|
-
database.run(
|
|
202
|
-
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_reminders_status_fire_at ON reminders(status, fire_at)`,
|
|
203
|
-
);
|
|
204
|
-
|
|
205
201
|
database.run(
|
|
206
202
|
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next_run ON cron_jobs(enabled, next_run_at)`,
|
|
207
203
|
);
|
|
@@ -212,13 +208,6 @@ export function createCoreIndexes(database: DrizzleDb): void {
|
|
|
212
208
|
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_runs_job_id ON cron_runs(job_id)`,
|
|
213
209
|
);
|
|
214
210
|
|
|
215
|
-
database.run(
|
|
216
|
-
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_accounts_service ON accounts(service)`,
|
|
217
|
-
);
|
|
218
|
-
database.run(
|
|
219
|
-
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_accounts_status ON accounts(status)`,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
211
|
database.run(
|
|
223
212
|
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_llm_usage_events_created_at ON llm_usage_events(created_at)`,
|
|
224
213
|
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Drop the unused legacy accounts table and its indexes.
|
|
7
|
+
*
|
|
8
|
+
* The daemon no longer exposes account_manage or reads from the backing
|
|
9
|
+
* account-store path, so retaining the table only leaves dead state around.
|
|
10
|
+
*/
|
|
11
|
+
export function migrateDropAccountsTable(database: DrizzleDb): void {
|
|
12
|
+
withCrashRecovery(database, "migration_drop_accounts_table_v1", () => {
|
|
13
|
+
const raw = getSqliteFrom(database);
|
|
14
|
+
|
|
15
|
+
raw.exec(/*sql*/ `DROP INDEX IF EXISTS idx_accounts_service`);
|
|
16
|
+
raw.exec(/*sql*/ `DROP INDEX IF EXISTS idx_accounts_status`);
|
|
17
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS accounts`);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extend cron_jobs table with one-shot and routing support.
|
|
5
|
+
*
|
|
6
|
+
* - Make `cron_expression` nullable (SQLite requires table rebuild for
|
|
7
|
+
* nullability changes). One-shot schedules have NULL cron_expression.
|
|
8
|
+
* - Add `mode` column: 'notify' | 'execute'
|
|
9
|
+
* - Add `routing_intent` column: 'single_channel' | 'multi_channel' | 'all_channels'
|
|
10
|
+
* - Add `routing_hints_json` column: opaque JSON routing hints
|
|
11
|
+
* - Add `status` column: 'active' | 'firing' | 'fired' | 'cancelled'
|
|
12
|
+
* - Add composite index for one-shot claiming: (status, next_run_at)
|
|
13
|
+
*/
|
|
14
|
+
export function migrateScheduleOneShotRouting(database: DrizzleDb): void {
|
|
15
|
+
const raw = getSqliteFrom(database);
|
|
16
|
+
|
|
17
|
+
// Check if migration is already done by inspecting whether the status column exists
|
|
18
|
+
const tableInfo = raw
|
|
19
|
+
.query("PRAGMA table_info(cron_jobs)")
|
|
20
|
+
.all() as Array<{ name: string }>;
|
|
21
|
+
const hasStatusColumn = tableInfo.some((col) => col.name === "status");
|
|
22
|
+
if (hasStatusColumn) {
|
|
23
|
+
// Ensure all indexes exist even if the column migration already ran
|
|
24
|
+
raw.exec(
|
|
25
|
+
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next_run ON cron_jobs(enabled, next_run_at)`,
|
|
26
|
+
);
|
|
27
|
+
raw.exec(
|
|
28
|
+
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_syntax_enabled_next_run ON cron_jobs(schedule_syntax, enabled, next_run_at)`,
|
|
29
|
+
);
|
|
30
|
+
raw.exec(
|
|
31
|
+
/*sql*/ `CREATE INDEX IF NOT EXISTS idx_cron_jobs_status_next_run_at ON cron_jobs(status, next_run_at)`,
|
|
32
|
+
);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
raw.exec("PRAGMA foreign_keys = OFF");
|
|
37
|
+
try {
|
|
38
|
+
raw.exec(/*sql*/ `
|
|
39
|
+
BEGIN;
|
|
40
|
+
|
|
41
|
+
CREATE TABLE cron_jobs_new (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
name TEXT NOT NULL,
|
|
44
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
45
|
+
cron_expression TEXT,
|
|
46
|
+
schedule_syntax TEXT NOT NULL DEFAULT 'cron',
|
|
47
|
+
timezone TEXT,
|
|
48
|
+
message TEXT NOT NULL,
|
|
49
|
+
next_run_at INTEGER NOT NULL,
|
|
50
|
+
last_run_at INTEGER,
|
|
51
|
+
last_status TEXT,
|
|
52
|
+
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
53
|
+
created_by TEXT NOT NULL,
|
|
54
|
+
mode TEXT NOT NULL DEFAULT 'execute',
|
|
55
|
+
routing_intent TEXT NOT NULL DEFAULT 'all_channels',
|
|
56
|
+
routing_hints_json TEXT NOT NULL DEFAULT '{}',
|
|
57
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
58
|
+
created_at INTEGER NOT NULL,
|
|
59
|
+
updated_at INTEGER NOT NULL
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
INSERT INTO cron_jobs_new (
|
|
63
|
+
id, name, enabled, cron_expression, schedule_syntax, timezone,
|
|
64
|
+
message, next_run_at, last_run_at, last_status, retry_count,
|
|
65
|
+
created_by, mode, routing_intent, routing_hints_json, status,
|
|
66
|
+
created_at, updated_at
|
|
67
|
+
)
|
|
68
|
+
SELECT
|
|
69
|
+
id, name, enabled, cron_expression, schedule_syntax, timezone,
|
|
70
|
+
message, next_run_at, last_run_at, last_status, retry_count,
|
|
71
|
+
created_by, 'execute', 'all_channels', '{}', 'active',
|
|
72
|
+
created_at, updated_at
|
|
73
|
+
FROM cron_jobs;
|
|
74
|
+
|
|
75
|
+
DROP TABLE cron_jobs;
|
|
76
|
+
ALTER TABLE cron_jobs_new RENAME TO cron_jobs;
|
|
77
|
+
|
|
78
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_enabled_next_run ON cron_jobs(enabled, next_run_at);
|
|
79
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_syntax_enabled_next_run ON cron_jobs(schedule_syntax, enabled, next_run_at);
|
|
80
|
+
CREATE INDEX IF NOT EXISTS idx_cron_jobs_status_next_run_at ON cron_jobs(status, next_run_at);
|
|
81
|
+
|
|
82
|
+
COMMIT;
|
|
83
|
+
`);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
try {
|
|
86
|
+
raw.exec("ROLLBACK");
|
|
87
|
+
} catch {
|
|
88
|
+
/* no active transaction */
|
|
89
|
+
}
|
|
90
|
+
throw e;
|
|
91
|
+
} finally {
|
|
92
|
+
raw.exec("PRAGMA foreign_keys = ON");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Migrate all existing reminders into the cron_jobs (schedules) table as
|
|
6
|
+
* one-shot schedules.
|
|
7
|
+
*
|
|
8
|
+
* Field mapping:
|
|
9
|
+
* reminder.label → cron_jobs.name
|
|
10
|
+
* reminder.message → cron_jobs.message
|
|
11
|
+
* reminder.fire_at → cron_jobs.next_run_at
|
|
12
|
+
* reminder.fired_at → cron_jobs.last_run_at
|
|
13
|
+
* reminder.mode → cron_jobs.mode
|
|
14
|
+
* reminder.routing_intent → cron_jobs.routing_intent
|
|
15
|
+
* reminder.routing_hints_json → cron_jobs.routing_hints_json
|
|
16
|
+
* reminder.created_at → cron_jobs.created_at
|
|
17
|
+
* reminder.updated_at → cron_jobs.updated_at
|
|
18
|
+
*
|
|
19
|
+
* Status mapping:
|
|
20
|
+
* pending → active
|
|
21
|
+
* firing → firing
|
|
22
|
+
* fired → fired
|
|
23
|
+
* cancelled → cancelled
|
|
24
|
+
*
|
|
25
|
+
* Enabled: pending → 1, all others → 0
|
|
26
|
+
*
|
|
27
|
+
* last_status: fired → 'ok', others → NULL
|
|
28
|
+
*
|
|
29
|
+
* One-shot schedules have NULL cron_expression. The reminders table is
|
|
30
|
+
* preserved for the subsequent cleanup PR.
|
|
31
|
+
*/
|
|
32
|
+
export function migrateRemindersToSchedules(database: DrizzleDb): void {
|
|
33
|
+
withCrashRecovery(
|
|
34
|
+
database,
|
|
35
|
+
"migration_reminders_to_schedules_v1",
|
|
36
|
+
() => {
|
|
37
|
+
const raw = getSqliteFrom(database);
|
|
38
|
+
|
|
39
|
+
// Guard: if the reminders table doesn't exist, nothing to migrate.
|
|
40
|
+
const hasReminders = raw
|
|
41
|
+
.query(
|
|
42
|
+
"SELECT name FROM sqlite_master WHERE type='table' AND name='reminders'",
|
|
43
|
+
)
|
|
44
|
+
.get();
|
|
45
|
+
if (!hasReminders) return;
|
|
46
|
+
|
|
47
|
+
// Read all reminders into memory. We use the reminder's original ID as
|
|
48
|
+
// the cron_jobs primary key so that INSERT OR IGNORE deduplicates
|
|
49
|
+
// correctly if the migration re-runs after a crash.
|
|
50
|
+
const reminders = raw.query("SELECT * FROM reminders").all() as Array<{
|
|
51
|
+
id: string;
|
|
52
|
+
label: string;
|
|
53
|
+
message: string;
|
|
54
|
+
fire_at: number;
|
|
55
|
+
mode: string;
|
|
56
|
+
status: string;
|
|
57
|
+
fired_at: number | null;
|
|
58
|
+
routing_intent: string;
|
|
59
|
+
routing_hints_json: string;
|
|
60
|
+
created_at: number;
|
|
61
|
+
updated_at: number;
|
|
62
|
+
}>;
|
|
63
|
+
|
|
64
|
+
if (reminders.length === 0) return;
|
|
65
|
+
|
|
66
|
+
const insert = raw.query(/*sql*/ `
|
|
67
|
+
INSERT OR IGNORE INTO cron_jobs (
|
|
68
|
+
id, name, enabled, cron_expression, schedule_syntax, timezone,
|
|
69
|
+
message, next_run_at, last_run_at, last_status, retry_count,
|
|
70
|
+
created_by, mode, routing_intent, routing_hints_json, status,
|
|
71
|
+
created_at, updated_at
|
|
72
|
+
) VALUES (
|
|
73
|
+
?, ?, ?, NULL, 'cron', NULL,
|
|
74
|
+
?, ?, ?, ?, 0,
|
|
75
|
+
'agent', ?, ?, ?, ?,
|
|
76
|
+
?, ?
|
|
77
|
+
)
|
|
78
|
+
`);
|
|
79
|
+
|
|
80
|
+
// Mark migrated pending reminders as fired so the legacy
|
|
81
|
+
// claimDueReminders path doesn't fire them a second time.
|
|
82
|
+
const markFired = raw.query(/*sql*/ `
|
|
83
|
+
UPDATE reminders SET status = 'fired', fired_at = ?
|
|
84
|
+
WHERE id = ? AND status = 'pending'
|
|
85
|
+
`);
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
raw.exec("BEGIN");
|
|
89
|
+
|
|
90
|
+
for (const r of reminders) {
|
|
91
|
+
const statusMap: Record<string, string> = {
|
|
92
|
+
pending: "active",
|
|
93
|
+
firing: "firing",
|
|
94
|
+
fired: "fired",
|
|
95
|
+
cancelled: "cancelled",
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
insert.run(
|
|
99
|
+
r.id,
|
|
100
|
+
r.label,
|
|
101
|
+
r.status === "pending" ? 1 : 0,
|
|
102
|
+
// message, next_run_at, last_run_at, last_status
|
|
103
|
+
r.message,
|
|
104
|
+
r.fire_at,
|
|
105
|
+
r.fired_at,
|
|
106
|
+
r.status === "fired" ? "ok" : null,
|
|
107
|
+
// mode, routing_intent, routing_hints_json, status
|
|
108
|
+
r.mode,
|
|
109
|
+
r.routing_intent,
|
|
110
|
+
r.routing_hints_json,
|
|
111
|
+
statusMap[r.status] ?? "active",
|
|
112
|
+
// created_at, updated_at
|
|
113
|
+
r.created_at,
|
|
114
|
+
r.updated_at,
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
if (r.status === "pending") {
|
|
118
|
+
markFired.run(Date.now(), r.id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
raw.exec("COMMIT");
|
|
123
|
+
} catch (err) {
|
|
124
|
+
raw.exec("ROLLBACK");
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Drop the legacy reminders table and its index now that all data has been
|
|
6
|
+
* migrated into cron_jobs as one-shot schedules (migration 147).
|
|
7
|
+
*/
|
|
8
|
+
export function migrateDropRemindersTable(database: DrizzleDb): void {
|
|
9
|
+
withCrashRecovery(
|
|
10
|
+
database,
|
|
11
|
+
"migration_drop_reminders_table_v1",
|
|
12
|
+
() => {
|
|
13
|
+
const raw = getSqliteFrom(database);
|
|
14
|
+
raw.run("DROP INDEX IF EXISTS idx_reminders_status_fire_at");
|
|
15
|
+
raw.run("DROP TABLE IF EXISTS reminders");
|
|
16
|
+
},
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -86,6 +86,10 @@ export { migrateRenameVerificationTable } from "./141-rename-verification-table.
|
|
|
86
86
|
export { migrateRenameVerificationSessionIdColumn } from "./142-rename-verification-session-id-column.js";
|
|
87
87
|
export { migrateRenameGuardianVerificationValues } from "./143-rename-guardian-verification-values.js";
|
|
88
88
|
export { migrateRenameVoiceToPhone } from "./144-rename-voice-to-phone.js";
|
|
89
|
+
export { migrateDropAccountsTable } from "./145-drop-accounts-table.js";
|
|
90
|
+
export { migrateScheduleOneShotRouting } from "./146-schedule-oneshot-routing.js";
|
|
91
|
+
export { migrateRemindersToSchedules } from "./147-migrate-reminders-to-schedules.js";
|
|
92
|
+
export { migrateDropRemindersTable } from "./148-drop-reminders-table.js";
|
|
89
93
|
export {
|
|
90
94
|
MIGRATION_REGISTRY,
|
|
91
95
|
type MigrationRegistryEntry,
|
|
@@ -171,6 +171,25 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
|
171
171
|
description:
|
|
172
172
|
'Rename stored "voice" channel values to "phone" across all tables with channel text columns',
|
|
173
173
|
},
|
|
174
|
+
{
|
|
175
|
+
key: "migration_drop_accounts_table_v1",
|
|
176
|
+
version: 25,
|
|
177
|
+
description:
|
|
178
|
+
"Drop the unused legacy accounts table and its leftover indexes after account_manage removal",
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
key: "migration_reminders_to_schedules_v1",
|
|
182
|
+
version: 26,
|
|
183
|
+
description:
|
|
184
|
+
"Copy all existing reminders into cron_jobs as one-shot schedules with correct status and field mapping",
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
key: "migration_drop_reminders_table_v1",
|
|
188
|
+
version: 27,
|
|
189
|
+
dependsOn: ["migration_reminders_to_schedules_v1"],
|
|
190
|
+
description:
|
|
191
|
+
"Drop the legacy reminders table and its index after data migration to cron_jobs",
|
|
192
|
+
},
|
|
174
193
|
];
|
|
175
194
|
|
|
176
195
|
export interface MigrationValidationResult {
|