@vellumai/assistant 0.5.16 → 0.6.1
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/AGENTS.md +4 -0
- package/ARCHITECTURE.md +69 -16
- package/Dockerfile +2 -5
- package/bun.lock +6 -2
- package/docker-entrypoint.sh +32 -1
- package/docs/architecture/integrations.md +1 -1
- package/docs/architecture/memory.md +21 -24
- package/knip.json +2 -1
- package/openapi.yaml +1198 -83
- package/package.json +5 -1
- package/src/__tests__/actor-token-service.test.ts +68 -0
- package/src/__tests__/agent-loop.test.ts +0 -32
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/anthropic-provider.test.ts +217 -98
- package/src/__tests__/app-compiler.test.ts +120 -0
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +47 -1
- package/src/__tests__/app-source-watcher.test.ts +159 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +2 -2
- package/src/__tests__/call-conversation-messages.test.ts +2 -6
- package/src/__tests__/call-domain.test.ts +2 -6
- package/src/__tests__/call-pointer-messages.test.ts +2 -14
- package/src/__tests__/call-recovery.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +2 -6
- package/src/__tests__/call-store.test.ts +2 -6
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +2 -6
- package/src/__tests__/canonical-guardian-store.test.ts +2 -6
- package/src/__tests__/channel-delivery-store.test.ts +2 -6
- package/src/__tests__/channel-retry-sweep.test.ts +2 -6
- package/src/__tests__/checker.test.ts +63 -9
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/config-schema.test.ts +6 -1
- package/src/__tests__/config-set-platform-guard.test.ts +302 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -6
- package/src/__tests__/contacts-tools.test.ts +31 -0
- package/src/__tests__/context-overflow-reducer.test.ts +86 -0
- package/src/__tests__/context-token-estimator.test.ts +175 -10
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +13 -6
- package/src/__tests__/conversation-agent-loop.test.ts +13 -51
- package/src/__tests__/conversation-attachments.test.ts +2 -6
- package/src/__tests__/conversation-attention-store.test.ts +2 -6
- package/src/__tests__/conversation-clear-safety.test.ts +2 -6
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +4 -10
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -6
- package/src/__tests__/conversation-disk-view.test.ts +2 -6
- package/src/__tests__/conversation-error.test.ts +33 -2
- package/src/__tests__/conversation-fork-crud.test.ts +2 -6
- package/src/__tests__/conversation-history-web-search.test.ts +6 -1
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -1
- package/src/__tests__/conversation-media-retry.test.ts +91 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +653 -832
- package/src/__tests__/conversation-runtime-workspace.test.ts +1 -93
- package/src/__tests__/conversation-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +17 -4
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +13 -414
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -12
- package/src/__tests__/conversation-workspace-injection.test.ts +25 -26
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -1
- package/src/__tests__/copy-composer-tc-templates.test.ts +335 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +3 -3
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +2 -2
- package/src/__tests__/credential-security-e2e.test.ts +2 -0
- package/src/__tests__/date-context.test.ts +76 -210
- package/src/__tests__/db-schedule-syntax-migration.test.ts +16 -1
- package/src/__tests__/file-list-tool.test.ts +219 -0
- package/src/__tests__/first-greeting.test.ts +1 -1
- package/src/__tests__/followup-tools.test.ts +2 -6
- package/src/__tests__/graph-extraction-event-date.test.ts +186 -0
- package/src/__tests__/guardian-action-conversation-turn.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-executor.test.ts +2 -6
- package/src/__tests__/guardian-action-followup-store.test.ts +2 -6
- package/src/__tests__/guardian-action-grant-mint-consume.test.ts +2 -6
- package/src/__tests__/guardian-action-late-reply.test.ts +2 -6
- package/src/__tests__/guardian-action-store.test.ts +2 -6
- package/src/__tests__/guardian-binding-drift-heal.test.ts +2 -6
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +8 -8
- package/src/__tests__/guardian-dispatch.test.ts +2 -6
- package/src/__tests__/guardian-grant-minting.test.ts +2 -14
- package/src/__tests__/guardian-principal-id-roundtrip.test.ts +2 -6
- package/src/__tests__/guardian-routing-invariants.test.ts +192 -6
- package/src/__tests__/guardian-routing-state.test.ts +2 -6
- package/src/__tests__/guardian-verification-voice-binding.test.ts +2 -6
- package/src/__tests__/heartbeat-service.test.ts +180 -3
- package/src/__tests__/identity-routes.test.ts +328 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +178 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +293 -0
- package/src/__tests__/invite-redemption-service.test.ts +2 -6
- package/src/__tests__/invite-routes-http.test.ts +2 -6
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +17 -28
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/list-messages-tool-merge.test.ts +300 -0
- package/src/__tests__/llm-context-normalization.test.ts +18 -18
- package/src/__tests__/llm-context-route-provider.test.ts +103 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +164 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +74 -111
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/mcp-abort-signal.test.ts +5 -0
- package/src/__tests__/mcp-client-auth.test.ts +5 -0
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +134 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/migration-export-streaming.test.ts +304 -0
- package/src/__tests__/migration-import-commit-http.test.ts +11 -10
- package/src/__tests__/mock-fetch.ts +87 -0
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- package/src/__tests__/notification-decision-recipient-context.test.ts +282 -0
- package/src/__tests__/notification-guardian-path.test.ts +2 -6
- package/src/__tests__/oauth-cli.test.ts +364 -2
- package/src/__tests__/oauth2-gateway-transport.test.ts +18 -3
- package/src/__tests__/onboarding-template-contract.test.ts +62 -14
- package/src/__tests__/outlook-attachments.test.ts +301 -0
- package/src/__tests__/outlook-automation-tools.test.ts +425 -0
- package/src/__tests__/outlook-categories.test.ts +212 -0
- package/src/__tests__/outlook-client-automation.test.ts +246 -0
- package/src/__tests__/outlook-compose-tools.test.ts +325 -0
- package/src/__tests__/outlook-declutter-tools.test.ts +585 -0
- package/src/__tests__/outlook-email-watcher.test.ts +322 -0
- package/src/__tests__/outlook-follow-up.test.ts +196 -0
- package/src/__tests__/outlook-messaging-provider.test.ts +498 -3
- package/src/__tests__/outlook-trash.test.ts +77 -0
- package/src/__tests__/outlook-unsubscribe.test.ts +250 -0
- package/src/__tests__/parser.test.ts +32 -0
- package/src/__tests__/permission-checker-host-gate.test.ts +452 -0
- package/src/__tests__/permission-controls-v2-flag.test.ts +55 -0
- package/src/__tests__/permission-mode-sse.test.ts +418 -0
- package/src/__tests__/permission-mode-store.test.ts +277 -0
- package/src/__tests__/permission-mode.test.ts +101 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +359 -0
- package/src/__tests__/platform-callback-registration.test.ts +4 -4
- package/src/__tests__/playbook-execution.test.ts +76 -80
- package/src/__tests__/playbook-tools.test.ts +5 -7
- package/src/__tests__/profiler-routes.test.ts +502 -0
- package/src/__tests__/profiler-run-store.test.ts +441 -0
- package/src/__tests__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/proxy-approval-callback.test.ts +4 -75
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +3 -3
- package/src/__tests__/require-fresh-approval.test.ts +64 -2
- package/src/__tests__/runtime-events-sse-parity.test.ts +2 -6
- package/src/__tests__/runtime-events-sse.test.ts +2 -6
- package/src/__tests__/sandbox-host-parity.test.ts +5 -4
- package/src/__tests__/schedule-store.test.ts +2 -6
- package/src/__tests__/schedule-tools.test.ts +2 -6
- package/src/__tests__/scheduler-recurrence.test.ts +1 -5
- package/src/__tests__/scheduler-reuse-conversation.test.ts +368 -0
- package/src/__tests__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/scrub-corrupted-image-attachments.test.ts +278 -0
- package/src/__tests__/search-skills-unified.test.ts +422 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +44 -9
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- package/src/__tests__/set-permission-mode.test.ts +274 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +38 -31
- package/src/__tests__/skill-feature-flags.test.ts +6 -6
- package/src/__tests__/skill-load-feature-flag.test.ts +23 -11
- package/src/__tests__/skill-memory.test.ts +2 -741
- package/src/__tests__/skills-uninstall.test.ts +2 -2
- package/src/__tests__/skills.test.ts +1 -1
- package/src/__tests__/slack-inbound-verification.test.ts +2 -6
- package/src/__tests__/strip-memory-injections.test.ts +187 -0
- package/src/__tests__/subagent-detail.test.ts +84 -0
- package/src/__tests__/subagent-disposal.test.ts +308 -0
- package/src/__tests__/subagent-manager-notify.test.ts +19 -10
- package/src/__tests__/subagent-notify-parent.test.ts +390 -0
- package/src/__tests__/subagent-role-registry.test.ts +108 -0
- package/src/__tests__/subagent-tool-filtering.test.ts +71 -0
- package/src/__tests__/subagent-tools.test.ts +464 -4
- package/src/__tests__/system-prompt-ask-mode.test.ts +139 -0
- package/src/__tests__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +185 -241
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/terminal-tools.test.ts +17 -27
- package/src/__tests__/test-preload.ts +7 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-executor.test.ts +4 -26
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +277 -0
- package/src/__tests__/top-level-renderer.test.ts +10 -13
- package/src/__tests__/trust-store.test.ts +1 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +2 -6
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +118 -8
- package/src/__tests__/trusted-contact-multichannel.test.ts +2 -6
- package/src/__tests__/trusted-contact-verification.test.ts +2 -6
- package/src/__tests__/turn-boundary-resolution.test.ts +2 -6
- package/src/__tests__/usage-cache-backfill-migration.test.ts +1 -6
- package/src/__tests__/usage-routes.test.ts +2 -6
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/voice-invite-redemption.test.ts +2 -6
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -6
- package/src/__tests__/voice-session-bridge.test.ts +2 -6
- package/src/__tests__/volume-security-guard.test.ts +2 -0
- package/src/__tests__/workspace-lifecycle.test.ts +29 -1
- package/src/__tests__/workspace-migration-009-backfill-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +2 -6
- package/src/__tests__/workspace-migration-026-backfill-install-meta.test.ts +558 -0
- package/src/__tests__/workspace-migration-028-recover-conversations-from-disk-view.test.ts +387 -0
- package/src/__tests__/workspace-policy.test.ts +1 -1
- package/src/agent/attachments.ts +7 -2
- package/src/agent/image-optimize.ts +165 -0
- package/src/agent/loop.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +24 -0
- package/src/avatar/traits-png-sync.ts +3 -3
- package/src/bundler/app-compiler.ts +179 -2
- package/src/bundler/package-resolver.ts +3 -5
- package/src/cli/__tests__/notifications.test.ts +1 -2
- package/src/cli/__tests__/run-assistant-command.ts +29 -0
- package/src/cli/commands/__tests__/email-download.test.ts +245 -0
- package/src/cli/commands/__tests__/email-list.test.ts +192 -0
- package/src/cli/commands/__tests__/email-register.test.ts +186 -0
- package/src/cli/commands/__tests__/email-send.test.ts +291 -0
- package/src/cli/commands/__tests__/email-status.test.ts +181 -0
- package/src/cli/commands/__tests__/email-unregister.test.ts +139 -0
- package/src/cli/commands/__tests__/routes.test.ts +562 -0
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/conversations.ts +1 -8
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/email.ts +584 -835
- package/src/cli/commands/memory.ts +37 -84
- package/src/cli/commands/notifications.ts +7 -2
- package/src/cli/commands/oauth/__tests__/connect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +2 -2
- package/src/cli/commands/oauth/__tests__/mode.test.ts +8 -1
- package/src/cli/commands/oauth/__tests__/status.test.ts +2 -2
- package/src/cli/commands/oauth/connect.ts +25 -11
- package/src/cli/commands/oauth/mode.ts +7 -0
- package/src/cli/commands/oauth/shared.ts +39 -3
- package/src/cli/commands/platform/__tests__/connect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +1 -1
- package/src/cli/commands/platform/__tests__/status.test.ts +5 -5
- package/src/cli/commands/platform/index.ts +16 -16
- package/src/cli/commands/routes.ts +396 -0
- package/src/cli/commands/skills.ts +218 -36
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/cli/program.ts +2 -0
- package/src/cli.ts +1 -120
- package/src/config/bundled-skills/acp/TOOLS.json +1 -1
- package/src/config/bundled-skills/app-builder/SKILL.md +4 -1
- package/src/config/bundled-skills/contacts/SKILL.md +0 -1
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -8
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -4
- package/src/config/bundled-skills/gmail/SKILL.md +4 -12
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +17 -18
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +40 -33
- package/src/config/bundled-skills/outlook/SKILL.md +189 -0
- package/src/config/bundled-skills/outlook/TOOLS.json +530 -0
- package/src/config/bundled-skills/outlook/tools/outlook-attachments.ts +85 -0
- package/src/config/bundled-skills/outlook/tools/outlook-categories.ts +77 -0
- package/src/config/bundled-skills/outlook/tools/outlook-draft.ts +84 -0
- package/src/config/bundled-skills/outlook/tools/outlook-follow-up.ts +94 -0
- package/src/config/bundled-skills/outlook/tools/outlook-forward.ts +49 -0
- package/src/config/bundled-skills/outlook/tools/outlook-outreach-scan.ts +237 -0
- package/src/config/bundled-skills/outlook/tools/outlook-rules.ts +161 -0
- package/src/config/bundled-skills/outlook/tools/outlook-send-draft.ts +32 -0
- package/src/config/bundled-skills/outlook/tools/outlook-sender-digest.ts +272 -0
- package/src/config/bundled-skills/outlook/tools/outlook-trash.ts +29 -0
- package/src/config/bundled-skills/outlook/tools/outlook-unsubscribe.ts +129 -0
- package/src/config/bundled-skills/outlook/tools/outlook-vacation.ts +87 -0
- package/src/config/bundled-skills/outlook/tools/shared.ts +20 -0
- package/src/config/bundled-skills/outlook-calendar/SKILL.md +51 -0
- package/src/config/bundled-skills/outlook-calendar/TOOLS.json +221 -0
- package/src/config/bundled-skills/outlook-calendar/calendar-client.ts +252 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-check-availability.ts +53 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-create-event.ts +74 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-get-event.ts +18 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-list-events.ts +46 -0
- package/src/config/bundled-skills/outlook-calendar/tools/outlook-calendar-rsvp.ts +36 -0
- package/src/config/bundled-skills/outlook-calendar/tools/shared.ts +17 -0
- package/src/config/bundled-skills/outlook-calendar/types.ts +120 -0
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +47 -40
- package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +16 -29
- package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +16 -18
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +39 -47
- package/src/config/bundled-skills/schedule/SKILL.md +22 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +8 -0
- package/src/config/bundled-skills/settings/tools/avatar-get.ts +3 -13
- package/src/config/bundled-skills/settings/tools/avatar-remove.ts +2 -4
- package/src/config/bundled-skills/settings/tools/avatar-update.ts +5 -2
- package/src/config/bundled-skills/slack/SKILL.md +3 -7
- package/src/config/bundled-skills/subagent/SKILL.md +43 -3
- package/src/config/bundled-skills/subagent/TOOLS.json +29 -4
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +78 -8
- package/src/config/feature-flag-registry.json +38 -125
- package/src/config/schema.ts +8 -0
- package/src/config/schemas/filing.ts +51 -0
- package/src/config/schemas/heartbeat.ts +15 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/schemas/security.ts +14 -0
- package/src/config/schemas/timeouts.ts +1 -1
- package/src/config/skills.ts +18 -7
- package/src/context/token-estimator.ts +25 -18
- package/src/context/window-manager.ts +6 -2
- package/src/credential-execution/process-manager.ts +3 -1
- package/src/daemon/app-source-watcher.ts +93 -0
- package/src/daemon/config-watcher.ts +79 -1
- package/src/daemon/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +143 -82
- package/src/daemon/conversation-agent-loop.ts +236 -108
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-history.ts +4 -19
- package/src/daemon/conversation-lifecycle.ts +36 -9
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-process.ts +13 -7
- package/src/daemon/conversation-runtime-assembly.ts +305 -306
- package/src/daemon/conversation-tool-setup.ts +44 -14
- package/src/daemon/conversation-workspace.ts +1 -2
- package/src/daemon/conversation.ts +59 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/date-context.ts +26 -53
- package/src/daemon/first-greeting.ts +1 -1
- package/src/daemon/handlers/conversations.ts +4 -7
- package/src/daemon/handlers/shared.test.ts +143 -0
- package/src/daemon/handlers/shared.ts +85 -17
- package/src/daemon/handlers/skills.ts +416 -209
- package/src/daemon/lifecycle.ts +212 -131
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +29 -7
- package/src/daemon/message-types/messages.ts +12 -2
- package/src/daemon/message-types/schedules.ts +1 -0
- package/src/daemon/message-types/settings.ts +6 -0
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/profiler-run-store.ts +557 -0
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +100 -11
- package/src/daemon/shutdown-handlers.ts +5 -0
- package/src/daemon/tool-side-effects.ts +50 -8
- package/src/export/transcript-formatter.ts +148 -0
- package/src/filing/filing-service.ts +228 -0
- package/src/heartbeat/heartbeat-service.ts +97 -7
- package/src/hooks/cli.ts +2 -2
- package/src/hooks/runner.ts +15 -38
- package/src/inbound/platform-callback-registration.ts +14 -14
- package/src/mcp/client.ts +6 -0
- package/src/mcp/mcp-oauth-provider.ts +149 -27
- package/src/memory/admin.ts +42 -75
- package/src/memory/app-store.ts +69 -0
- package/src/memory/conversation-bootstrap.ts +3 -1
- package/src/memory/conversation-crud.ts +211 -288
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +61 -13
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/db-init.ts +194 -361
- package/src/memory/embed.ts +73 -0
- package/src/memory/embedding-backend.ts +8 -14
- package/src/memory/embedding-runtime-manager.ts +12 -114
- package/src/memory/fingerprint.ts +2 -2
- package/src/memory/graph/bootstrap.ts +521 -0
- package/src/memory/graph/capability-seed.ts +449 -0
- package/src/memory/graph/consolidation.ts +725 -0
- package/src/memory/graph/conversation-graph-memory.ts +659 -0
- package/src/memory/graph/decay.test.ts +208 -0
- package/src/memory/graph/decay.ts +195 -0
- package/src/memory/graph/extraction-job.ts +74 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1297 -0
- package/src/memory/graph/graph-memory-state-store.ts +37 -0
- package/src/memory/graph/graph-search.ts +280 -0
- package/src/memory/graph/image-ref-utils.ts +29 -0
- package/src/memory/graph/injection.test.ts +513 -0
- package/src/memory/graph/injection.ts +469 -0
- package/src/memory/graph/inspect.ts +543 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1111 -0
- package/src/memory/graph/scoring.test.ts +548 -0
- package/src/memory/graph/scoring.ts +232 -0
- package/src/memory/graph/serendipity.ts +65 -0
- package/src/memory/graph/store.test.ts +1098 -0
- package/src/memory/graph/store.ts +838 -0
- package/src/memory/graph/tool-handlers.ts +301 -0
- package/src/memory/graph/tools.ts +97 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +295 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +32 -42
- package/src/memory/job-handlers/conversation-starters.ts +91 -53
- package/src/memory/job-handlers/embedding.ts +5 -31
- package/src/memory/job-handlers/index-maintenance.ts +23 -11
- package/src/memory/job-handlers/summarization.ts +32 -17
- package/src/memory/job-utils.ts +1 -1
- package/src/memory/jobs-store.ts +21 -31
- package/src/memory/jobs-worker.ts +180 -129
- package/src/memory/llm-request-log-store.ts +96 -12
- package/src/memory/memory-recall-log-store.ts +49 -5
- package/src/memory/message-content.ts +1 -0
- package/src/memory/migrations/202-memory-graph-tables.ts +130 -0
- package/src/memory/migrations/203-drop-memory-items-tables.ts +55 -0
- package/src/memory/migrations/204-rename-memory-graph-type-values.ts +46 -0
- package/src/memory/migrations/205-memory-graph-image-refs.ts +11 -0
- package/src/memory/migrations/206-memory-graph-node-edits.ts +19 -0
- package/src/memory/migrations/206-scrub-corrupted-image-attachments.ts +131 -0
- package/src/memory/migrations/207-conversation-graph-memory-state.ts +20 -0
- package/src/memory/migrations/208-conversations-last-message-at.ts +35 -0
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +85 -0
- package/src/memory/migrations/210-schedule-reuse-conversation.ts +13 -0
- package/src/memory/migrations/211-memory-recall-logs-query-context.ts +21 -0
- package/src/memory/migrations/212-llm-request-logs-created-at-index.ts +19 -0
- package/src/memory/migrations/index.ts +12 -0
- package/src/memory/migrations/registry.ts +16 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/conversations.ts +14 -0
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/infrastructure.ts +8 -1
- package/src/memory/schema/memory-core.ts +0 -51
- package/src/memory/schema/memory-graph.ts +154 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +58 -61
- package/src/messaging/providers/outlook/adapter.ts +8 -1
- package/src/messaging/providers/outlook/client.ts +299 -0
- package/src/messaging/providers/outlook/types.ts +118 -0
- package/src/notifications/adapters/macos.ts +1 -0
- package/src/notifications/copy-composer.ts +95 -0
- package/src/notifications/decision-engine.ts +35 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +36 -4
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/permission-mode-store.ts +180 -0
- package/src/permissions/permission-mode.ts +31 -0
- package/src/permissions/workspace-policy.ts +10 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +62 -36
- package/src/prompts/templates/BOOTSTRAP-REFERENCE.md +100 -0
- package/src/prompts/templates/BOOTSTRAP.md +70 -165
- package/src/prompts/templates/HEARTBEAT.md +3 -1
- package/src/prompts/templates/SOUL.md +25 -4
- package/src/prompts/templates/UPDATES.md +8 -0
- package/src/providers/anthropic/client.ts +136 -220
- package/src/providers/gemini/client.ts +1 -1
- package/src/providers/openai/client.ts +1 -1
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +19 -3
- package/src/runtime/actor-trust-resolver.ts +5 -1
- package/src/runtime/auth/route-policy.ts +30 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +55 -5
- package/src/runtime/http-types.ts +12 -1
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/migrations/vbundle-builder.ts +389 -3
- package/src/runtime/migrations/vbundle-importer.ts +8 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +378 -0
- package/src/runtime/routes/app-management-routes.ts +1 -11
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +26 -0
- package/src/runtime/routes/archive-utils.ts +29 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/avatar-routes.ts +2 -9
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +22 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +173 -0
- package/src/runtime/routes/conversation-management-routes.ts +3 -14
- package/src/runtime/routes/conversation-query-routes.ts +49 -3
- package/src/runtime/routes/conversation-routes.ts +264 -44
- package/src/runtime/routes/conversation-starter-routes.ts +2 -2
- package/src/runtime/routes/debug-routes.ts +1 -1
- package/src/runtime/routes/global-search-routes.ts +21 -19
- package/src/runtime/routes/group-routes.ts +207 -0
- package/src/runtime/routes/guardian-action-routes.ts +21 -10
- package/src/runtime/routes/guardian-bootstrap-routes.ts +23 -19
- package/src/runtime/routes/heartbeat-routes.ts +4 -10
- package/src/runtime/routes/identity-routes.ts +53 -18
- package/src/runtime/routes/inbound-message-handler.ts +19 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +292 -0
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +207 -0
- package/src/runtime/routes/llm-context-normalization.ts +14 -10
- package/src/runtime/routes/log-export-routes.ts +23 -275
- package/src/runtime/routes/memory-item-routes.test.ts +170 -247
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/migration-routes.ts +18 -7
- package/src/runtime/routes/profiler-routes.ts +350 -0
- package/src/runtime/routes/schedule-routes.ts +28 -11
- package/src/runtime/routes/settings-routes.ts +95 -8
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/subagents-routes.ts +28 -7
- package/src/runtime/routes/user-route-dispatcher.ts +223 -0
- package/src/runtime/routes/user-routes.ts +41 -0
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/runtime/routes/workspace-routes.ts +0 -1
- package/src/schedule/schedule-store.ts +30 -0
- package/src/schedule/scheduler.ts +52 -18
- package/src/security/oauth2.ts +1 -1
- package/src/security/secure-keys.ts +4 -8
- package/src/shared/provider-env-vars.ts +19 -0
- package/src/skills/catalog-cache.ts +5 -0
- package/src/skills/catalog-install.ts +25 -16
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +29 -18
- package/src/skills/skill-memory.ts +12 -229
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/subagent/index.ts +13 -3
- package/src/subagent/manager.ts +308 -29
- package/src/subagent/types.ts +68 -0
- package/src/tasks/task-runner.ts +7 -5
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/apps/executors.ts +29 -4
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/filesystem/list.ts +93 -0
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +85 -1
- package/src/tools/registry.ts +4 -0
- package/src/tools/schedule/create.ts +3 -0
- package/src/tools/schedule/list.ts +1 -0
- package/src/tools/schedule/update.ts +6 -0
- package/src/tools/shared/filesystem/errors.ts +5 -0
- package/src/tools/shared/filesystem/file-ops-service.ts +90 -2
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/shared/filesystem/types.ts +17 -0
- package/src/tools/shared/shell-output.ts +31 -2
- package/src/tools/subagent/abort.ts +12 -2
- package/src/tools/subagent/message.ts +9 -2
- package/src/tools/subagent/notify-parent.ts +79 -0
- package/src/tools/subagent/read.ts +29 -8
- package/src/tools/subagent/resolve.ts +21 -0
- package/src/tools/subagent/spawn.ts +2 -0
- package/src/tools/subagent/status.ts +11 -1
- package/src/tools/system/avatar-generator.ts +3 -3
- package/src/tools/system/register.ts +23 -0
- package/src/tools/system/set-permission-mode.ts +103 -0
- package/src/tools/terminal/parser.ts +30 -5
- package/src/tools/terminal/safe-env.ts +17 -1
- package/src/tools/tool-manifest.ts +9 -3
- package/src/tools/types.ts +2 -0
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/util/logger.ts +1 -1
- package/src/util/platform.ts +50 -17
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- package/src/workspace/migrations/023-move-config-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/024-move-runtime-files-to-workspace.ts +2 -2
- package/src/workspace/migrations/025-remove-oauth-app-setup-skills.ts +76 -0
- package/src/workspace/migrations/026-backfill-install-meta.ts +325 -0
- package/src/workspace/migrations/027-remove-orphaned-optimized-images-cache.ts +42 -0
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +270 -0
- package/src/workspace/migrations/029-seed-pkb.ts +84 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/top-level-renderer.ts +5 -9
- package/src/__tests__/cli-memory.test.ts +0 -372
- package/src/__tests__/clipboard.test.ts +0 -88
- package/src/__tests__/context-memory-e2e.test.ts +0 -415
- package/src/__tests__/journal-context.test.ts +0 -268
- package/src/__tests__/memory-context-benchmark.benchmark.test.ts +0 -297
- package/src/__tests__/memory-lifecycle-e2e.test.ts +0 -459
- package/src/__tests__/memory-query-builder.test.ts +0 -59
- package/src/__tests__/memory-recall-quality.test.ts +0 -1046
- package/src/__tests__/memory-regressions.experimental.test.ts +0 -629
- package/src/__tests__/memory-regressions.test.ts +0 -3696
- package/src/__tests__/memory-retrieval.benchmark.test.ts +0 -295
- package/src/cli/cli-memory.ts +0 -176
- package/src/daemon/conversation-memory.ts +0 -207
- package/src/memory/conversation-starters-cadence.ts +0 -74
- package/src/memory/items-extractor.ts +0 -860
- package/src/memory/job-handlers/batch-extraction.ts +0 -753
- package/src/memory/job-handlers/extraction.ts +0 -40
- package/src/memory/job-handlers/journal-carry-forward.test.ts +0 -355
- package/src/memory/job-handlers/journal-carry-forward.ts +0 -255
- package/src/memory/journal-memory.ts +0 -224
- package/src/memory/query-builder.ts +0 -47
- package/src/memory/query-expansion.ts +0 -83
- package/src/memory/retriever.test.ts +0 -1592
- package/src/memory/retriever.ts +0 -1331
- package/src/memory/search/formatting.test.ts +0 -140
- package/src/memory/search/formatting.ts +0 -262
- package/src/memory/search/mmr.ts +0 -139
- package/src/memory/search/ranking.ts +0 -15
- package/src/memory/search/staleness.ts +0 -40
- package/src/memory/search/tier-classifier.ts +0 -18
- package/src/memory/search/types.ts +0 -121
- package/src/prompts/journal-context.ts +0 -154
- package/src/tools/memory/definitions.ts +0 -69
- package/src/tools/memory/handlers.test.ts +0 -562
- package/src/tools/memory/handlers.ts +0 -434
- package/src/util/clipboard.ts +0 -34
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* suggestion chips shown on the empty conversation page.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { and, desc, eq } from "drizzle-orm";
|
|
8
|
+
import { and, desc, eq, sql } from "drizzle-orm";
|
|
9
9
|
import { v4 as uuid } from "uuid";
|
|
10
10
|
|
|
11
11
|
import { loadSkillCatalog } from "../../config/skills.js";
|
|
@@ -26,7 +26,7 @@ import { rawAll, rawGet } from "../raw-query.js";
|
|
|
26
26
|
import {
|
|
27
27
|
conversationStarters,
|
|
28
28
|
memoryCheckpoints,
|
|
29
|
-
|
|
29
|
+
memoryGraphNodes,
|
|
30
30
|
} from "../schema.js";
|
|
31
31
|
|
|
32
32
|
const log = getLogger("conversation-starters-gen");
|
|
@@ -42,32 +42,47 @@ const CK_LAST_GEN_AT = "conversation_starters:last_gen_at";
|
|
|
42
42
|
// ── Rollup construction ───────────────────────────────────────────
|
|
43
43
|
|
|
44
44
|
export function buildMemoryRollup(scopeId: string): string {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
let rows: Array<{
|
|
46
|
+
type: string;
|
|
47
|
+
content: string;
|
|
48
|
+
significance: number | null;
|
|
49
|
+
}>;
|
|
50
|
+
try {
|
|
51
|
+
const db = getDb();
|
|
52
|
+
rows = db
|
|
53
|
+
.select({
|
|
54
|
+
type: memoryGraphNodes.type,
|
|
55
|
+
content: memoryGraphNodes.content,
|
|
56
|
+
significance: memoryGraphNodes.significance,
|
|
57
|
+
})
|
|
58
|
+
.from(memoryGraphNodes)
|
|
59
|
+
.where(
|
|
60
|
+
and(
|
|
61
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
62
|
+
eq(memoryGraphNodes.scopeId, scopeId),
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
.orderBy(desc(memoryGraphNodes.significance))
|
|
66
|
+
.limit(60)
|
|
67
|
+
.all();
|
|
68
|
+
} catch {
|
|
69
|
+
// Table may have been dropped (migration 203)
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (rows.length === 0) return "";
|
|
62
74
|
|
|
63
75
|
const byKind = new Map<string, string[]>();
|
|
64
|
-
for (const item of
|
|
65
|
-
|
|
76
|
+
for (const item of rows) {
|
|
77
|
+
const nl = item.content.indexOf("\n");
|
|
78
|
+
const subject = nl >= 0 ? item.content.slice(0, nl) : item.content;
|
|
79
|
+
const statement = nl >= 0 ? item.content.slice(nl + 1) : item.content;
|
|
80
|
+
let lines = byKind.get(item.type);
|
|
66
81
|
if (!lines) {
|
|
67
82
|
lines = [];
|
|
68
|
-
byKind.set(item.
|
|
83
|
+
byKind.set(item.type, lines);
|
|
69
84
|
}
|
|
70
|
-
lines.push(`- ${
|
|
85
|
+
lines.push(`- ${subject}: ${statement}`);
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
let rollup = "";
|
|
@@ -90,21 +105,25 @@ function buildNewItemsDiff(scopeId: string): string {
|
|
|
90
105
|
|
|
91
106
|
const newItems = rawAll<{
|
|
92
107
|
kind: string;
|
|
93
|
-
|
|
94
|
-
statement: string;
|
|
108
|
+
content: string;
|
|
95
109
|
}>(
|
|
96
|
-
`SELECT kind,
|
|
97
|
-
WHERE
|
|
98
|
-
ORDER BY
|
|
110
|
+
`SELECT type AS kind, content FROM memory_graph_nodes
|
|
111
|
+
WHERE fidelity != 'gone' AND scope_id = ? AND created > ?
|
|
112
|
+
ORDER BY created DESC LIMIT 20`,
|
|
99
113
|
scopeId,
|
|
100
|
-
lastGenAt
|
|
114
|
+
lastGenAt
|
|
101
115
|
);
|
|
102
116
|
|
|
103
117
|
if (newItems.length === 0) return "";
|
|
104
118
|
|
|
105
119
|
return (
|
|
106
120
|
"## New since last generation\n" +
|
|
107
|
-
newItems.map((i) =>
|
|
121
|
+
newItems.map((i) => {
|
|
122
|
+
const nl = i.content.indexOf("\n");
|
|
123
|
+
const subject = nl >= 0 ? i.content.slice(0, nl) : i.content;
|
|
124
|
+
const statement = nl >= 0 ? i.content.slice(nl + 1) : i.content;
|
|
125
|
+
return `- (${i.kind}) ${subject}: ${statement}`;
|
|
126
|
+
}).join("\n")
|
|
108
127
|
);
|
|
109
128
|
}
|
|
110
129
|
|
|
@@ -143,8 +162,7 @@ export const CONVERSATION_STARTER_CATEGORIES = [
|
|
|
143
162
|
"integration",
|
|
144
163
|
] as const;
|
|
145
164
|
|
|
146
|
-
export type ConversationStarterCategory =
|
|
147
|
-
(typeof CONVERSATION_STARTER_CATEGORIES)[number];
|
|
165
|
+
export type ConversationStarterCategory = typeof CONVERSATION_STARTER_CATEGORIES[number];
|
|
148
166
|
|
|
149
167
|
interface GeneratedStarter {
|
|
150
168
|
label: string;
|
|
@@ -168,7 +186,15 @@ async function generateStarters(scopeId: string): Promise<GeneratedStarter[]> {
|
|
|
168
186
|
const skills = buildSkillsSummary();
|
|
169
187
|
|
|
170
188
|
const now = new Date();
|
|
171
|
-
const timeContext = `Current time: ${now.toLocaleString("en-US", {
|
|
189
|
+
const timeContext = `Current time: ${now.toLocaleString("en-US", {
|
|
190
|
+
weekday: "long",
|
|
191
|
+
year: "numeric",
|
|
192
|
+
month: "long",
|
|
193
|
+
day: "numeric",
|
|
194
|
+
hour: "numeric",
|
|
195
|
+
minute: "2-digit",
|
|
196
|
+
hour12: true,
|
|
197
|
+
})}`;
|
|
172
198
|
|
|
173
199
|
// Truncate identity context to prevent oversized prompts when SOUL.md /
|
|
174
200
|
// IDENTITY.md / USER.md are large.
|
|
@@ -185,7 +211,11 @@ ${timeContext}
|
|
|
185
211
|
|
|
186
212
|
Your goal: suggest the 4 most useful things this person could ask you to do right now.
|
|
187
213
|
|
|
188
|
-
${
|
|
214
|
+
${
|
|
215
|
+
identityContext
|
|
216
|
+
? `## Assistant identity & user profile\n\n${identityContext}\n\n`
|
|
217
|
+
: ""
|
|
218
|
+
}## What you know
|
|
189
219
|
|
|
190
220
|
${rollup}
|
|
191
221
|
${diff}
|
|
@@ -253,7 +283,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
253
283
|
const response = await provider.sendMessage(
|
|
254
284
|
[
|
|
255
285
|
userMessage(
|
|
256
|
-
"Generate personalized conversation starters based on my context."
|
|
286
|
+
"Generate personalized conversation starters based on my context."
|
|
257
287
|
),
|
|
258
288
|
],
|
|
259
289
|
[
|
|
@@ -303,14 +333,14 @@ Bad → Good (assistant voice → user voice):
|
|
|
303
333
|
},
|
|
304
334
|
},
|
|
305
335
|
signal,
|
|
306
|
-
}
|
|
336
|
+
}
|
|
307
337
|
);
|
|
308
338
|
cleanup();
|
|
309
339
|
|
|
310
340
|
const toolBlock = extractToolUse(response);
|
|
311
341
|
if (!toolBlock) {
|
|
312
342
|
log.warn(
|
|
313
|
-
"No tool_use block in conversation starters generation response"
|
|
343
|
+
"No tool_use block in conversation starters generation response"
|
|
314
344
|
);
|
|
315
345
|
return [];
|
|
316
346
|
}
|
|
@@ -327,7 +357,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
327
357
|
typeof s.label === "string" &&
|
|
328
358
|
s.label.length > 0 &&
|
|
329
359
|
typeof s.prompt === "string" &&
|
|
330
|
-
s.prompt.length > 0
|
|
360
|
+
s.prompt.length > 0
|
|
331
361
|
)
|
|
332
362
|
.slice(0, 4)
|
|
333
363
|
.map((s) => ({
|
|
@@ -336,7 +366,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
336
366
|
category:
|
|
337
367
|
typeof s.category === "string" &&
|
|
338
368
|
(CONVERSATION_STARTER_CATEGORIES as readonly string[]).includes(
|
|
339
|
-
s.category
|
|
369
|
+
s.category
|
|
340
370
|
)
|
|
341
371
|
? s.category
|
|
342
372
|
: "productivity",
|
|
@@ -350,7 +380,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
350
380
|
// ── Job handler ───────────────────────────────────────────────────
|
|
351
381
|
|
|
352
382
|
export async function generateConversationStartersJob(
|
|
353
|
-
job: MemoryJob
|
|
383
|
+
job: MemoryJob
|
|
354
384
|
): Promise<void> {
|
|
355
385
|
const scopeId = asString(job.payload.scopeId) ?? "default";
|
|
356
386
|
|
|
@@ -373,16 +403,24 @@ export async function generateConversationStartersJob(
|
|
|
373
403
|
? parseInt(batchCheckpoint.value, 10) + 1
|
|
374
404
|
: 1;
|
|
375
405
|
|
|
376
|
-
// Collect the memory
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
406
|
+
// Collect the memory types that informed this batch
|
|
407
|
+
let sourceKinds = "";
|
|
408
|
+
try {
|
|
409
|
+
const kindRows = db
|
|
410
|
+
.select({ kind: memoryGraphNodes.type })
|
|
411
|
+
.from(memoryGraphNodes)
|
|
412
|
+
.where(
|
|
413
|
+
and(
|
|
414
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
415
|
+
eq(memoryGraphNodes.scopeId, scopeId),
|
|
416
|
+
)
|
|
417
|
+
)
|
|
418
|
+
.groupBy(memoryGraphNodes.type)
|
|
419
|
+
.all();
|
|
420
|
+
sourceKinds = kindRows.map((r) => r.kind).join(",");
|
|
421
|
+
} catch {
|
|
422
|
+
// Table may have been dropped (migration 203)
|
|
423
|
+
}
|
|
386
424
|
|
|
387
425
|
// Remove previous starters for this scope before inserting the new batch
|
|
388
426
|
db.delete(conversationStarters)
|
|
@@ -408,8 +446,8 @@ export async function generateConversationStartersJob(
|
|
|
408
446
|
|
|
409
447
|
// Count active items for checkpoint
|
|
410
448
|
const countRow = rawGet<{ c: number }>(
|
|
411
|
-
`SELECT COUNT(*) AS c FROM
|
|
412
|
-
scopeId
|
|
449
|
+
`SELECT COUNT(*) AS c FROM memory_graph_nodes WHERE fidelity != 'gone' AND scope_id = ?`,
|
|
450
|
+
scopeId
|
|
413
451
|
);
|
|
414
452
|
const totalActive = countRow?.c ?? 0;
|
|
415
453
|
|
|
@@ -430,6 +468,6 @@ export async function generateConversationStartersJob(
|
|
|
430
468
|
|
|
431
469
|
log.info(
|
|
432
470
|
{ scopeId, batch: nextBatch, count: starters.length },
|
|
433
|
-
"Generated conversation starters"
|
|
471
|
+
"Generated conversation starters"
|
|
434
472
|
);
|
|
435
473
|
}
|
|
@@ -11,7 +11,6 @@ import type { MemoryJob } from "../jobs-store.js";
|
|
|
11
11
|
import { extractMediaBlocks } from "../message-content.js";
|
|
12
12
|
import {
|
|
13
13
|
mediaAssets,
|
|
14
|
-
memoryItems,
|
|
15
14
|
memorySegments,
|
|
16
15
|
memorySummaries,
|
|
17
16
|
messages,
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
|
|
20
19
|
export async function embedSegmentJob(
|
|
21
20
|
job: MemoryJob,
|
|
22
|
-
config: AssistantConfig
|
|
21
|
+
config: AssistantConfig
|
|
23
22
|
): Promise<void> {
|
|
24
23
|
const segmentId = asString(job.payload.segmentId);
|
|
25
24
|
if (!segmentId) return;
|
|
@@ -38,34 +37,9 @@ export async function embedSegmentJob(
|
|
|
38
37
|
});
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
export async function embedItemJob(
|
|
42
|
-
job: MemoryJob,
|
|
43
|
-
config: AssistantConfig,
|
|
44
|
-
): Promise<void> {
|
|
45
|
-
const itemId = asString(job.payload.itemId);
|
|
46
|
-
if (!itemId) return;
|
|
47
|
-
const db = getDb();
|
|
48
|
-
const item = db
|
|
49
|
-
.select()
|
|
50
|
-
.from(memoryItems)
|
|
51
|
-
.where(eq(memoryItems.id, itemId))
|
|
52
|
-
.get();
|
|
53
|
-
if (!item || item.status !== "active") return;
|
|
54
|
-
const text = `<kind>${item.kind}</kind> ${item.subject}: ${item.statement}`;
|
|
55
|
-
await embedAndUpsert(config, "item", item.id, text, {
|
|
56
|
-
kind: item.kind,
|
|
57
|
-
subject: item.subject,
|
|
58
|
-
status: item.status,
|
|
59
|
-
confidence: item.confidence,
|
|
60
|
-
created_at: item.firstSeenAt,
|
|
61
|
-
last_seen_at: item.lastSeenAt,
|
|
62
|
-
memory_scope_id: item.scopeId,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
40
|
export async function embedSummaryJob(
|
|
67
41
|
job: MemoryJob,
|
|
68
|
-
config: AssistantConfig
|
|
42
|
+
config: AssistantConfig
|
|
69
43
|
): Promise<void> {
|
|
70
44
|
const summaryId = asString(job.payload.summaryId);
|
|
71
45
|
if (!summaryId) return;
|
|
@@ -86,13 +60,13 @@ export async function embedSummaryJob(
|
|
|
86
60
|
created_at: summary.startAt,
|
|
87
61
|
last_seen_at: summary.endAt,
|
|
88
62
|
memory_scope_id: summary.scopeId,
|
|
89
|
-
}
|
|
63
|
+
}
|
|
90
64
|
);
|
|
91
65
|
}
|
|
92
66
|
|
|
93
67
|
export async function embedMediaJob(
|
|
94
68
|
job: MemoryJob,
|
|
95
|
-
config: AssistantConfig
|
|
69
|
+
config: AssistantConfig
|
|
96
70
|
): Promise<void> {
|
|
97
71
|
const assetId = asString(job.payload.assetId);
|
|
98
72
|
if (!assetId) return;
|
|
@@ -125,7 +99,7 @@ export async function embedMediaJob(
|
|
|
125
99
|
|
|
126
100
|
export async function embedAttachmentJob(
|
|
127
101
|
job: MemoryJob,
|
|
128
|
-
config: AssistantConfig
|
|
102
|
+
config: AssistantConfig
|
|
129
103
|
): Promise<void> {
|
|
130
104
|
const messageId = asString(job.payload.messageId);
|
|
131
105
|
const blockIndex = job.payload.blockIndex as number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq, like } from "drizzle-orm";
|
|
1
|
+
import { eq, isNotNull, like, ne } from "drizzle-orm";
|
|
2
2
|
|
|
3
3
|
import { getConfig } from "../../config/loader.js";
|
|
4
4
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -12,7 +12,8 @@ import { getQdrantClient } from "../qdrant-client.js";
|
|
|
12
12
|
import {
|
|
13
13
|
mediaAssets,
|
|
14
14
|
memoryEmbeddings,
|
|
15
|
-
|
|
15
|
+
memoryGraphNodes,
|
|
16
|
+
memoryGraphTriggers,
|
|
16
17
|
memorySegments,
|
|
17
18
|
memorySummaries,
|
|
18
19
|
messages,
|
|
@@ -24,15 +25,6 @@ export async function rebuildIndexJob(): Promise<void> {
|
|
|
24
25
|
const db = getDb();
|
|
25
26
|
db.delete(memoryEmbeddings).run();
|
|
26
27
|
|
|
27
|
-
const items = db
|
|
28
|
-
.select({ id: memoryItems.id })
|
|
29
|
-
.from(memoryItems)
|
|
30
|
-
.where(eq(memoryItems.status, "active"))
|
|
31
|
-
.all();
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
enqueueMemoryJob("embed_item", { itemId: item.id });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
28
|
const summaries = db
|
|
37
29
|
.select({ id: memorySummaries.id })
|
|
38
30
|
.from(memorySummaries)
|
|
@@ -77,6 +69,26 @@ export async function rebuildIndexJob(): Promise<void> {
|
|
|
77
69
|
}
|
|
78
70
|
}
|
|
79
71
|
}
|
|
72
|
+
|
|
73
|
+
// Re-embed graph nodes stored in the memory graph.
|
|
74
|
+
const graphNodes = db
|
|
75
|
+
.select({ id: memoryGraphNodes.id })
|
|
76
|
+
.from(memoryGraphNodes)
|
|
77
|
+
.where(ne(memoryGraphNodes.fidelity, "gone"))
|
|
78
|
+
.all();
|
|
79
|
+
for (const node of graphNodes) {
|
|
80
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Re-embed semantic triggers that have condition text.
|
|
84
|
+
const triggers = db
|
|
85
|
+
.select({ id: memoryGraphTriggers.id })
|
|
86
|
+
.from(memoryGraphTriggers)
|
|
87
|
+
.where(isNotNull(memoryGraphTriggers.condition))
|
|
88
|
+
.all();
|
|
89
|
+
for (const trigger of triggers) {
|
|
90
|
+
enqueueMemoryJob("graph_trigger_embed", { triggerId: trigger.id });
|
|
91
|
+
}
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
export async function deleteQdrantVectorsJob(job: MemoryJob): Promise<void> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and,
|
|
1
|
+
import { and, asc, eq, gt, sql } from "drizzle-orm";
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import type { AssistantConfig } from "../../config/types.js";
|
|
@@ -19,7 +19,7 @@ import { memorySegments, memorySummaries } from "../schema.js";
|
|
|
19
19
|
const log = getLogger("memory-jobs-worker");
|
|
20
20
|
|
|
21
21
|
const SUMMARY_LLM_TIMEOUT_MS = 20_000;
|
|
22
|
-
const SUMMARY_MAX_TOKENS =
|
|
22
|
+
const SUMMARY_MAX_TOKENS = 1000;
|
|
23
23
|
|
|
24
24
|
const CONVERSATION_SUMMARY_SYSTEM_PROMPT = [
|
|
25
25
|
"You compress conversation transcripts into compact summaries for semantic search and memory retrieval.",
|
|
@@ -37,7 +37,7 @@ const CONVERSATION_SUMMARY_SYSTEM_PROMPT = [
|
|
|
37
37
|
"## Open Items",
|
|
38
38
|
"Unresolved questions, pending tasks, or follow-ups (omit section if none).",
|
|
39
39
|
"",
|
|
40
|
-
"Target
|
|
40
|
+
"Target 400-800 tokens. Be thorough — capture nuance, tone, and relationship dynamics, not just facts.",
|
|
41
41
|
].join("\n");
|
|
42
42
|
|
|
43
43
|
export async function buildConversationSummaryJob(
|
|
@@ -47,14 +47,6 @@ export async function buildConversationSummaryJob(
|
|
|
47
47
|
const conversationId = asString(job.payload.conversationId);
|
|
48
48
|
if (!conversationId) return;
|
|
49
49
|
const db = getDb();
|
|
50
|
-
const rows = db
|
|
51
|
-
.select()
|
|
52
|
-
.from(memorySegments)
|
|
53
|
-
.where(eq(memorySegments.conversationId, conversationId))
|
|
54
|
-
.orderBy(desc(memorySegments.createdAt))
|
|
55
|
-
.limit(40)
|
|
56
|
-
.all();
|
|
57
|
-
if (rows.length === 0) return;
|
|
58
50
|
|
|
59
51
|
const existing = db
|
|
60
52
|
.select()
|
|
@@ -67,9 +59,27 @@ export async function buildConversationSummaryJob(
|
|
|
67
59
|
)
|
|
68
60
|
.get();
|
|
69
61
|
|
|
70
|
-
//
|
|
62
|
+
// Fetch only segments newer than what the existing summary already covers.
|
|
63
|
+
// For first-time summaries, fetch all segments.
|
|
64
|
+
const lastCoveredAt = existing
|
|
65
|
+
? Math.max(existing.startAt, existing.endAt)
|
|
66
|
+
: 0;
|
|
67
|
+
|
|
68
|
+
const conditions = [eq(memorySegments.conversationId, conversationId)];
|
|
69
|
+
if (lastCoveredAt > 0) {
|
|
70
|
+
conditions.push(gt(memorySegments.createdAt, lastCoveredAt));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const rows = db
|
|
74
|
+
.select()
|
|
75
|
+
.from(memorySegments)
|
|
76
|
+
.where(and(...conditions))
|
|
77
|
+
.orderBy(asc(memorySegments.createdAt))
|
|
78
|
+
.all();
|
|
79
|
+
if (rows.length === 0) return;
|
|
80
|
+
|
|
81
|
+
// Build segment text for LLM input (already in chronological order)
|
|
71
82
|
const segmentTexts = rows
|
|
72
|
-
.reverse()
|
|
73
83
|
.map((row) => `[${row.role}] ${truncate(row.text, 600)}`)
|
|
74
84
|
.join("\n\n");
|
|
75
85
|
|
|
@@ -88,6 +98,11 @@ export async function buildConversationSummaryJob(
|
|
|
88
98
|
const now = Date.now();
|
|
89
99
|
const summaryId = existing?.id ?? uuid();
|
|
90
100
|
const nextVersion = (existing?.version ?? 0) + 1;
|
|
101
|
+
const earliestCovered = existing
|
|
102
|
+
? Math.min(existing.startAt, existing.endAt, rows[0].createdAt)
|
|
103
|
+
: rows[0].createdAt;
|
|
104
|
+
const latestCovered = rows[rows.length - 1].createdAt;
|
|
105
|
+
|
|
91
106
|
db.insert(memorySummaries)
|
|
92
107
|
.values({
|
|
93
108
|
id: summaryId,
|
|
@@ -97,8 +112,8 @@ export async function buildConversationSummaryJob(
|
|
|
97
112
|
summary: summaryText,
|
|
98
113
|
tokenEstimate: estimateTextTokens(summaryText),
|
|
99
114
|
version: nextVersion,
|
|
100
|
-
startAt:
|
|
101
|
-
endAt:
|
|
115
|
+
startAt: earliestCovered,
|
|
116
|
+
endAt: latestCovered,
|
|
102
117
|
createdAt: now,
|
|
103
118
|
updatedAt: now,
|
|
104
119
|
})
|
|
@@ -109,8 +124,8 @@ export async function buildConversationSummaryJob(
|
|
|
109
124
|
tokenEstimate: estimateTextTokens(summaryText),
|
|
110
125
|
version: sql`${memorySummaries.version} + 1`,
|
|
111
126
|
scopeId,
|
|
112
|
-
startAt:
|
|
113
|
-
endAt:
|
|
127
|
+
startAt: earliestCovered,
|
|
128
|
+
endAt: latestCovered,
|
|
114
129
|
updatedAt: now,
|
|
115
130
|
},
|
|
116
131
|
})
|
package/src/memory/job-utils.ts
CHANGED
|
@@ -147,7 +147,7 @@ export function truncate(text: string, max: number): string {
|
|
|
147
147
|
|
|
148
148
|
export async function embedAndUpsert(
|
|
149
149
|
config: AssistantConfig,
|
|
150
|
-
targetType: "segment" | "item" | "summary" | "media",
|
|
150
|
+
targetType: "segment" | "item" | "summary" | "media" | "graph_node",
|
|
151
151
|
targetId: string,
|
|
152
152
|
input: EmbeddingInput,
|
|
153
153
|
extraPayload?: Record<string, unknown>,
|
package/src/memory/jobs-store.ts
CHANGED
|
@@ -14,16 +14,9 @@ const log = getLogger("memory-jobs-store");
|
|
|
14
14
|
|
|
15
15
|
export type MemoryJobType =
|
|
16
16
|
| "embed_segment"
|
|
17
|
-
| "embed_item"
|
|
18
17
|
| "embed_summary"
|
|
19
|
-
| "extract_items"
|
|
20
|
-
| "extract_entities"
|
|
21
|
-
| "batch_extract"
|
|
22
|
-
| "cleanup_stale_superseded_items"
|
|
23
18
|
| "prune_old_conversations"
|
|
24
|
-
| "
|
|
25
|
-
| "refresh_weekly_summary"
|
|
26
|
-
| "refresh_monthly_summary"
|
|
19
|
+
| "prune_old_llm_request_logs"
|
|
27
20
|
| "build_conversation_summary"
|
|
28
21
|
| "backfill"
|
|
29
22
|
| "rebuild_index"
|
|
@@ -32,16 +25,22 @@ export type MemoryJobType =
|
|
|
32
25
|
| "embed_media"
|
|
33
26
|
| "embed_attachment"
|
|
34
27
|
| "generate_conversation_starters"
|
|
35
|
-
| "
|
|
36
|
-
| "
|
|
37
|
-
| "
|
|
28
|
+
| "embed_graph_node"
|
|
29
|
+
| "graph_extract"
|
|
30
|
+
| "graph_decay"
|
|
31
|
+
| "graph_consolidate"
|
|
32
|
+
| "graph_pattern_scan"
|
|
33
|
+
| "graph_narrative_refine"
|
|
34
|
+
| "graph_trigger_embed"
|
|
35
|
+
| "graph_bootstrap";
|
|
38
36
|
|
|
39
37
|
const EMBED_JOB_TYPES: MemoryJobType[] = [
|
|
40
38
|
"embed_segment",
|
|
41
|
-
"embed_item",
|
|
42
39
|
"embed_summary",
|
|
43
40
|
"embed_media",
|
|
44
41
|
"embed_attachment",
|
|
42
|
+
"embed_graph_node",
|
|
43
|
+
"graph_trigger_embed",
|
|
45
44
|
];
|
|
46
45
|
|
|
47
46
|
export interface MemoryJob<T = Record<string, unknown>> {
|
|
@@ -129,14 +128,10 @@ export function upsertDebouncedJob(
|
|
|
129
128
|
}
|
|
130
129
|
|
|
131
130
|
/**
|
|
132
|
-
* Check whether a pending or running
|
|
133
|
-
*
|
|
134
|
-
* enqueues while a carry-forward job is still in flight.
|
|
131
|
+
* Check whether a pending or running job of the given type already exists.
|
|
132
|
+
* Used to prevent duplicate enqueues for long-running maintenance jobs.
|
|
135
133
|
*/
|
|
136
|
-
export function
|
|
137
|
-
filename: string,
|
|
138
|
-
userSlug: string,
|
|
139
|
-
): boolean {
|
|
134
|
+
export function hasActiveJobOfType(type: MemoryJobType): boolean {
|
|
140
135
|
const db = getDb();
|
|
141
136
|
return (
|
|
142
137
|
db
|
|
@@ -144,27 +139,22 @@ export function hasActiveCarryForwardJob(
|
|
|
144
139
|
.from(memoryJobs)
|
|
145
140
|
.where(
|
|
146
141
|
and(
|
|
147
|
-
eq(memoryJobs.type,
|
|
142
|
+
eq(memoryJobs.type, type),
|
|
148
143
|
inArray(memoryJobs.status, ["pending", "running"]),
|
|
149
|
-
sql`json_extract(${memoryJobs.payload}, '$.filename') = ${filename}`,
|
|
150
|
-
sql`json_extract(${memoryJobs.payload}, '$.userSlug') = ${userSlug}`,
|
|
151
144
|
),
|
|
152
145
|
)
|
|
153
146
|
.get() != null
|
|
154
147
|
);
|
|
155
148
|
}
|
|
156
149
|
|
|
157
|
-
export function
|
|
158
|
-
retentionMs?: number,
|
|
159
|
-
): string {
|
|
150
|
+
export function enqueuePruneOldLlmRequestLogsJob(retentionMs?: number): string {
|
|
160
151
|
const db = getDb();
|
|
161
|
-
const now = Date.now();
|
|
162
152
|
const existing = db
|
|
163
153
|
.select()
|
|
164
154
|
.from(memoryJobs)
|
|
165
155
|
.where(
|
|
166
156
|
and(
|
|
167
|
-
eq(memoryJobs.type, "
|
|
157
|
+
eq(memoryJobs.type, "prune_old_llm_request_logs"),
|
|
168
158
|
inArray(memoryJobs.status, ["pending", "running"]),
|
|
169
159
|
),
|
|
170
160
|
)
|
|
@@ -175,7 +165,7 @@ export function enqueueCleanupStaleSupersededItemsJob(
|
|
|
175
165
|
existing.status === "pending" &&
|
|
176
166
|
typeof retentionMs === "number" &&
|
|
177
167
|
Number.isFinite(retentionMs) &&
|
|
178
|
-
retentionMs
|
|
168
|
+
retentionMs >= 0
|
|
179
169
|
) {
|
|
180
170
|
let payload: Record<string, unknown> = {};
|
|
181
171
|
try {
|
|
@@ -187,7 +177,7 @@ export function enqueueCleanupStaleSupersededItemsJob(
|
|
|
187
177
|
db.update(memoryJobs)
|
|
188
178
|
.set({
|
|
189
179
|
payload: JSON.stringify({ ...payload, retentionMs }),
|
|
190
|
-
updatedAt: now,
|
|
180
|
+
updatedAt: Date.now(),
|
|
191
181
|
})
|
|
192
182
|
.where(eq(memoryJobs.id, existing.id))
|
|
193
183
|
.run();
|
|
@@ -198,10 +188,10 @@ export function enqueueCleanupStaleSupersededItemsJob(
|
|
|
198
188
|
const payload =
|
|
199
189
|
typeof retentionMs === "number" &&
|
|
200
190
|
Number.isFinite(retentionMs) &&
|
|
201
|
-
retentionMs
|
|
191
|
+
retentionMs >= 0
|
|
202
192
|
? { retentionMs }
|
|
203
193
|
: {};
|
|
204
|
-
return enqueueMemoryJob("
|
|
194
|
+
return enqueueMemoryJob("prune_old_llm_request_logs", payload);
|
|
205
195
|
}
|
|
206
196
|
|
|
207
197
|
export function enqueuePruneOldConversationsJob(
|