@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
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Memory Graph — Core type definitions
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+
/** Classification of what kind of memory a node represents. */
|
|
6
|
+
export type MemoryType =
|
|
7
|
+
| "episodic" // specific moments, conversations, events
|
|
8
|
+
| "semantic" // facts, knowledge, understanding
|
|
9
|
+
| "procedural" // learned skills, how-to knowledge
|
|
10
|
+
| "emotional" // feelings attached to memories
|
|
11
|
+
| "prospective" // future-oriented, things to remember to do
|
|
12
|
+
| "behavioral" // things that change how the assistant acts going forward
|
|
13
|
+
| "narrative" // the story a memory becomes over time
|
|
14
|
+
| "shared"; // memories that belong to a relationship, not either party
|
|
15
|
+
|
|
16
|
+
/** How detailed the memory is — degrades over time via consolidation. */
|
|
17
|
+
export type Fidelity = "vivid" | "clear" | "faded" | "gist" | "gone";
|
|
18
|
+
|
|
19
|
+
/** Shape of emotional intensity decay over time. */
|
|
20
|
+
export type DecayCurve =
|
|
21
|
+
| "linear" // constant rate of decay
|
|
22
|
+
| "logarithmic" // sharp initial drop, long tail (negative events)
|
|
23
|
+
| "transformative" // feeling changes shape, not just intensity (positive milestones)
|
|
24
|
+
| "permanent"; // no decay (core identity markers)
|
|
25
|
+
|
|
26
|
+
/** How the memory was originally acquired. */
|
|
27
|
+
export type SourceType =
|
|
28
|
+
| "direct" // user explicitly stated it
|
|
29
|
+
| "inferred" // assistant derived it from context
|
|
30
|
+
| "observed" // assistant noticed a pattern
|
|
31
|
+
| "told-by-other"; // third party provided it
|
|
32
|
+
|
|
33
|
+
/** Reference to an image stored in a conversation message. */
|
|
34
|
+
export interface ImageRef {
|
|
35
|
+
/** Message ID containing the image. */
|
|
36
|
+
messageId: string;
|
|
37
|
+
/** Index of the image ContentBlock within the message's content array. */
|
|
38
|
+
blockIndex: number;
|
|
39
|
+
/** LLM-generated description of what the image shows. */
|
|
40
|
+
description: string;
|
|
41
|
+
/** MIME type (image/png, image/jpeg, etc). */
|
|
42
|
+
mimeType: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Emotional charge attached to a memory — decays independently from the memory itself. */
|
|
46
|
+
export interface EmotionalCharge {
|
|
47
|
+
/** Positive vs negative sentiment (-1 to 1). */
|
|
48
|
+
valence: number;
|
|
49
|
+
/** Current emotional intensity (0 to 1). Decays per the curve. */
|
|
50
|
+
intensity: number;
|
|
51
|
+
/** Shape of the decay function. */
|
|
52
|
+
decayCurve: DecayCurve;
|
|
53
|
+
/** Rate parameter for decay (higher = faster). */
|
|
54
|
+
decayRate: number;
|
|
55
|
+
/** What the intensity was when the memory was created. */
|
|
56
|
+
originalIntensity: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Graph primitives
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
export interface MemoryNode {
|
|
64
|
+
id: string;
|
|
65
|
+
|
|
66
|
+
/** First-person prose — how the assistant naturally remembers this. */
|
|
67
|
+
content: string;
|
|
68
|
+
type: MemoryType;
|
|
69
|
+
|
|
70
|
+
// -- Temporal --
|
|
71
|
+
/** Epoch ms when the memory was created. Hour/day/month are derived at query time. */
|
|
72
|
+
created: number;
|
|
73
|
+
/** Epoch ms — used ONLY as a decay-rate modifier, NOT a retrieval signal. */
|
|
74
|
+
lastAccessed: number;
|
|
75
|
+
/** Epoch ms of last consolidation pass that touched this node. */
|
|
76
|
+
lastConsolidated: number;
|
|
77
|
+
/** Epoch ms of the event this memory describes (null for non-event memories). */
|
|
78
|
+
eventDate: number | null;
|
|
79
|
+
|
|
80
|
+
// -- Energy --
|
|
81
|
+
emotionalCharge: EmotionalCharge;
|
|
82
|
+
fidelity: Fidelity;
|
|
83
|
+
/** How sure the assistant is this memory is accurate (0–1). */
|
|
84
|
+
confidence: number;
|
|
85
|
+
/** How important this memory is (0–1). Subject to Ebbinghaus decay. */
|
|
86
|
+
significance: number;
|
|
87
|
+
|
|
88
|
+
// -- Reinforcement (Ebbinghaus forgetting curve) --
|
|
89
|
+
/** Resistance to significance decay. Grows with reinforcement (×1.5 per reinforcement). */
|
|
90
|
+
stability: number;
|
|
91
|
+
/** How many times this memory has been confirmed/reinforced. */
|
|
92
|
+
reinforcementCount: number;
|
|
93
|
+
/** Epoch ms of last reinforcement event. */
|
|
94
|
+
lastReinforced: number;
|
|
95
|
+
|
|
96
|
+
// -- Provenance --
|
|
97
|
+
/** Conversation IDs that contributed to this memory. */
|
|
98
|
+
sourceConversations: string[];
|
|
99
|
+
sourceType: SourceType;
|
|
100
|
+
|
|
101
|
+
// -- Narrative --
|
|
102
|
+
/** Role in a larger story arc (e.g. "turning-point", "foreshadowing"). */
|
|
103
|
+
narrativeRole: string | null;
|
|
104
|
+
/** Which story arc this belongs to. */
|
|
105
|
+
partOfStory: string | null;
|
|
106
|
+
|
|
107
|
+
/** Image references attached to this memory (null if text-only). */
|
|
108
|
+
imageRefs: ImageRef[] | null;
|
|
109
|
+
|
|
110
|
+
/** Memory scope for multi-scope isolation. */
|
|
111
|
+
scopeId: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Whether a node is an auto-seeded capability (skill or CLI command) rather
|
|
116
|
+
* than an organically-extracted procedural memory. Capability nodes are
|
|
117
|
+
* created by the seeding systems at startup; organic procedural nodes are
|
|
118
|
+
* extracted from conversations (e.g. "FFmpeg needs -ac 2 for stereo").
|
|
119
|
+
*
|
|
120
|
+
* Only capability nodes should be reserved/excluded from normal retrieval
|
|
121
|
+
* and consolidation — organic procedural nodes participate normally.
|
|
122
|
+
*/
|
|
123
|
+
export function isCapabilityNode(node: MemoryNode): boolean {
|
|
124
|
+
if (node.type !== "procedural") return false;
|
|
125
|
+
// Old seeding systems: content starts with "skill:{id}\n" or "cli:{name}\n"
|
|
126
|
+
if (node.content.startsWith("skill:") || node.content.startsWith("cli:"))
|
|
127
|
+
return true;
|
|
128
|
+
// New seeding system (capability-seed.ts): content matches
|
|
129
|
+
// 'The "{name}" skill ({id}) is available.' or
|
|
130
|
+
// 'The "assistant {name}" CLI command is available.'
|
|
131
|
+
if (
|
|
132
|
+
node.content.startsWith('The "') &&
|
|
133
|
+
node.content.includes(" is available.")
|
|
134
|
+
) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Relationship type between two memory nodes. */
|
|
141
|
+
export type EdgeRelationship =
|
|
142
|
+
| "caused-by"
|
|
143
|
+
| "reminds-of"
|
|
144
|
+
| "contradicts"
|
|
145
|
+
| "depends-on"
|
|
146
|
+
| "part-of"
|
|
147
|
+
| "supersedes"
|
|
148
|
+
| "resolved-by";
|
|
149
|
+
|
|
150
|
+
export interface MemoryEdge {
|
|
151
|
+
id: string;
|
|
152
|
+
sourceNodeId: string;
|
|
153
|
+
targetNodeId: string;
|
|
154
|
+
relationship: EdgeRelationship;
|
|
155
|
+
/** Connection strength (0–1). */
|
|
156
|
+
weight: number;
|
|
157
|
+
/** Epoch ms. */
|
|
158
|
+
created: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Trigger type determines how the trigger condition is evaluated. */
|
|
162
|
+
export type TriggerType = "temporal" | "semantic" | "event";
|
|
163
|
+
|
|
164
|
+
export interface MemoryTrigger {
|
|
165
|
+
id: string;
|
|
166
|
+
/** Which memory node this trigger belongs to. */
|
|
167
|
+
nodeId: string;
|
|
168
|
+
type: TriggerType;
|
|
169
|
+
|
|
170
|
+
// -- Temporal triggers --
|
|
171
|
+
/** Cron-like pattern: "day-of-week:monday", "date:04-08", "time:morning". */
|
|
172
|
+
schedule: string | null;
|
|
173
|
+
|
|
174
|
+
// -- Semantic triggers --
|
|
175
|
+
/** Natural language condition: "user graduates", "topic of cooking comes up". */
|
|
176
|
+
condition: string | null;
|
|
177
|
+
/** Pre-computed embedding of the condition text for fast cosine similarity. */
|
|
178
|
+
conditionEmbedding: Float32Array | null;
|
|
179
|
+
/** Cosine similarity threshold to fire (0–1). */
|
|
180
|
+
threshold: number | null;
|
|
181
|
+
|
|
182
|
+
// -- Event triggers --
|
|
183
|
+
/** Epoch ms of the event date. */
|
|
184
|
+
eventDate: number | null;
|
|
185
|
+
/** Days before the event to start ramping relevance. */
|
|
186
|
+
rampDays: number | null;
|
|
187
|
+
/** Days after the event to maintain elevated relevance. */
|
|
188
|
+
followUpDays: number | null;
|
|
189
|
+
|
|
190
|
+
// -- State --
|
|
191
|
+
/** Whether this trigger fires repeatedly or is consumed on first fire. */
|
|
192
|
+
recurring: boolean;
|
|
193
|
+
/** Whether a one-shot trigger has already fired. */
|
|
194
|
+
consumed: boolean;
|
|
195
|
+
/** Minimum ms between firings for recurring triggers. */
|
|
196
|
+
cooldownMs: number | null;
|
|
197
|
+
/** Epoch ms of last firing. */
|
|
198
|
+
lastFired: number | null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Diff — the extraction/consolidation output format
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
|
|
205
|
+
/** A node to be created (id assigned by store). */
|
|
206
|
+
export type NewNode = Omit<MemoryNode, "id">;
|
|
207
|
+
|
|
208
|
+
/** Partial update to an existing node. */
|
|
209
|
+
export interface NodeUpdate {
|
|
210
|
+
id: string;
|
|
211
|
+
changes: Partial<Omit<MemoryNode, "id">>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** A new edge to create (id assigned by store). */
|
|
215
|
+
export type NewEdge = Omit<MemoryEdge, "id">;
|
|
216
|
+
|
|
217
|
+
/** A new trigger to create (id assigned by store). */
|
|
218
|
+
export type NewTrigger = Omit<MemoryTrigger, "id">;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The atomic diff that extraction/consolidation produces.
|
|
222
|
+
* Applied transactionally to the graph store.
|
|
223
|
+
*/
|
|
224
|
+
export interface MemoryDiff {
|
|
225
|
+
createNodes: NewNode[];
|
|
226
|
+
updateNodes: NodeUpdate[];
|
|
227
|
+
deleteNodeIds: string[];
|
|
228
|
+
createEdges: NewEdge[];
|
|
229
|
+
deleteEdgeIds: string[];
|
|
230
|
+
createTriggers: NewTrigger[];
|
|
231
|
+
deleteTriggerIds: string[];
|
|
232
|
+
/** Node IDs that were reinforced (confirmed/validated) by this extraction. */
|
|
233
|
+
reinforceNodeIds: string[];
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// Scored candidates — used by retrieval pipeline
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
|
|
240
|
+
export interface ScoredNode {
|
|
241
|
+
node: MemoryNode;
|
|
242
|
+
/** Combined retrieval score (higher = more relevant right now). */
|
|
243
|
+
score: number;
|
|
244
|
+
/** Breakdown of score components for debugging/inspection. */
|
|
245
|
+
scoreBreakdown: {
|
|
246
|
+
semanticSimilarity: number;
|
|
247
|
+
effectiveSignificance: number;
|
|
248
|
+
emotionalIntensity: number;
|
|
249
|
+
temporalBoost: number;
|
|
250
|
+
recencyBoost: number;
|
|
251
|
+
triggerBoost: number;
|
|
252
|
+
activationBoost: number;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// Retrieval Metrics
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
|
|
260
|
+
export interface RetrievalMetrics {
|
|
261
|
+
semanticHits: number;
|
|
262
|
+
mergedCount: number;
|
|
263
|
+
selectedCount: number;
|
|
264
|
+
tier1Count: number;
|
|
265
|
+
tier2Count: number;
|
|
266
|
+
hybridSearchLatencyMs: number;
|
|
267
|
+
sparseVectorUsed: boolean;
|
|
268
|
+
embeddingProvider: string | null;
|
|
269
|
+
embeddingModel: string | null;
|
|
270
|
+
queryContext: string | null;
|
|
271
|
+
topCandidates: Array<{
|
|
272
|
+
nodeId: string;
|
|
273
|
+
type: string;
|
|
274
|
+
score: number;
|
|
275
|
+
semanticSimilarity: number;
|
|
276
|
+
recencyBoost: number;
|
|
277
|
+
}>;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
// Results
|
|
282
|
+
// ---------------------------------------------------------------------------
|
|
283
|
+
|
|
284
|
+
export interface ApplyDiffResult {
|
|
285
|
+
nodesCreated: number;
|
|
286
|
+
nodesUpdated: number;
|
|
287
|
+
nodesDeleted: number;
|
|
288
|
+
edgesCreated: number;
|
|
289
|
+
edgesDeleted: number;
|
|
290
|
+
triggersCreated: number;
|
|
291
|
+
triggersDeleted: number;
|
|
292
|
+
nodesReinforced: number;
|
|
293
|
+
/** IDs of newly created nodes (in order of diff.createNodes). */
|
|
294
|
+
createdNodeIds: string[];
|
|
295
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CRUD operations for conversation groups.
|
|
3
|
+
*
|
|
4
|
+
* All functions call ensureGroupMigration() before any DB access
|
|
5
|
+
* to guarantee the conversation_groups table exists.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { v4 as uuid } from "uuid";
|
|
9
|
+
|
|
10
|
+
import { ensureGroupMigration } from "./conversation-group-migration.js";
|
|
11
|
+
import { rawAll, rawExec, rawGet, rawRun } from "./db.js";
|
|
12
|
+
|
|
13
|
+
export interface ConversationGroupRow {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
sortPosition: number;
|
|
17
|
+
isSystemGroup: boolean;
|
|
18
|
+
createdAt?: number;
|
|
19
|
+
updatedAt?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// List
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
export function listGroups(): ConversationGroupRow[] {
|
|
27
|
+
ensureGroupMigration();
|
|
28
|
+
const rows = rawAll<{
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
sort_position: number;
|
|
32
|
+
is_system_group: number;
|
|
33
|
+
created_at: number;
|
|
34
|
+
updated_at: number;
|
|
35
|
+
}>(
|
|
36
|
+
"SELECT id, name, sort_position, is_system_group, created_at, updated_at FROM conversation_groups WHERE id != '_backfill_complete' ORDER BY sort_position ASC",
|
|
37
|
+
);
|
|
38
|
+
return rows.map((r) => ({
|
|
39
|
+
id: r.id,
|
|
40
|
+
name: r.name,
|
|
41
|
+
sortPosition: r.sort_position,
|
|
42
|
+
isSystemGroup: r.is_system_group === 1,
|
|
43
|
+
createdAt: r.created_at,
|
|
44
|
+
updatedAt: r.updated_at,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
// Get
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
export function getGroup(groupId: string): ConversationGroupRow | null {
|
|
53
|
+
ensureGroupMigration();
|
|
54
|
+
const row = rawGet<{
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
sort_position: number;
|
|
58
|
+
is_system_group: number;
|
|
59
|
+
created_at: number;
|
|
60
|
+
updated_at: number;
|
|
61
|
+
}>(
|
|
62
|
+
"SELECT id, name, sort_position, is_system_group, created_at, updated_at FROM conversation_groups WHERE id = ?",
|
|
63
|
+
groupId,
|
|
64
|
+
);
|
|
65
|
+
if (!row) return null;
|
|
66
|
+
return {
|
|
67
|
+
id: row.id,
|
|
68
|
+
name: row.name,
|
|
69
|
+
sortPosition: row.sort_position,
|
|
70
|
+
isSystemGroup: row.is_system_group === 1,
|
|
71
|
+
createdAt: row.created_at,
|
|
72
|
+
updatedAt: row.updated_at,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Create
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Create a custom group. Server assigns sort_position as max(custom) + 1.
|
|
82
|
+
* System groups occupy positions 0 (pinned), 1 (scheduled), 2 (background).
|
|
83
|
+
* First custom group gets position 3. Fallback ?? 2 ensures 2 + 1 = 3 when
|
|
84
|
+
* no custom groups exist.
|
|
85
|
+
*/
|
|
86
|
+
export function createGroup(name: string): ConversationGroupRow {
|
|
87
|
+
ensureGroupMigration();
|
|
88
|
+
const maxPos =
|
|
89
|
+
rawGet<{ max: number | null }>(
|
|
90
|
+
"SELECT MAX(sort_position) as max FROM conversation_groups WHERE is_system_group = 0",
|
|
91
|
+
)?.max ?? 2;
|
|
92
|
+
const sortPosition = maxPos + 1;
|
|
93
|
+
const id = uuid();
|
|
94
|
+
const now = Math.floor(Date.now() / 1000);
|
|
95
|
+
rawRun(
|
|
96
|
+
"INSERT INTO conversation_groups (id, name, sort_position, is_system_group, created_at, updated_at) VALUES (?, ?, ?, 0, ?, ?)",
|
|
97
|
+
id,
|
|
98
|
+
name,
|
|
99
|
+
sortPosition,
|
|
100
|
+
now,
|
|
101
|
+
now,
|
|
102
|
+
);
|
|
103
|
+
return {
|
|
104
|
+
id,
|
|
105
|
+
name,
|
|
106
|
+
sortPosition,
|
|
107
|
+
isSystemGroup: false,
|
|
108
|
+
createdAt: now,
|
|
109
|
+
updatedAt: now,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
// Update
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
|
|
117
|
+
export function updateGroup(
|
|
118
|
+
groupId: string,
|
|
119
|
+
updates: { name?: string; sortPosition?: number },
|
|
120
|
+
): ConversationGroupRow | null {
|
|
121
|
+
ensureGroupMigration();
|
|
122
|
+
const existing = getGroup(groupId);
|
|
123
|
+
if (!existing) return null;
|
|
124
|
+
|
|
125
|
+
const fields: string[] = [];
|
|
126
|
+
const values: (string | number)[] = [];
|
|
127
|
+
|
|
128
|
+
if (updates.name !== undefined) {
|
|
129
|
+
fields.push("name = ?");
|
|
130
|
+
values.push(updates.name);
|
|
131
|
+
}
|
|
132
|
+
if (updates.sortPosition !== undefined) {
|
|
133
|
+
fields.push("sort_position = ?");
|
|
134
|
+
values.push(updates.sortPosition);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (fields.length === 0) return existing;
|
|
138
|
+
|
|
139
|
+
fields.push("updated_at = ?");
|
|
140
|
+
const now = Math.floor(Date.now() / 1000);
|
|
141
|
+
values.push(now);
|
|
142
|
+
values.push(groupId);
|
|
143
|
+
|
|
144
|
+
rawRun(
|
|
145
|
+
`UPDATE conversation_groups SET ${fields.join(", ")} WHERE id = ?`,
|
|
146
|
+
...values,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
return getGroup(groupId);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Delete
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
|
|
156
|
+
// Relies on PRAGMA foreign_keys = ON (set at connection time) so that
|
|
157
|
+
// ON DELETE SET NULL fires and clears group_id on conversations when
|
|
158
|
+
// a group is deleted. If FK enforcement is ever disabled, orphaned
|
|
159
|
+
// group_id values would persist and conversations would appear in a
|
|
160
|
+
// non-existent group.
|
|
161
|
+
export function deleteGroup(groupId: string): boolean {
|
|
162
|
+
ensureGroupMigration();
|
|
163
|
+
rawRun("DELETE FROM conversation_groups WHERE id = ?", groupId);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
// Reorder
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
export function reorderGroups(
|
|
172
|
+
updates: Array<{ groupId: string; sortPosition: number }>,
|
|
173
|
+
): void {
|
|
174
|
+
ensureGroupMigration();
|
|
175
|
+
const now = Math.floor(Date.now() / 1000);
|
|
176
|
+
rawExec("BEGIN");
|
|
177
|
+
try {
|
|
178
|
+
for (const update of updates) {
|
|
179
|
+
rawRun(
|
|
180
|
+
"UPDATE conversation_groups SET sort_position = ?, updated_at = ? WHERE id = ?",
|
|
181
|
+
update.sortPosition,
|
|
182
|
+
now,
|
|
183
|
+
update.groupId,
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
rawExec("COMMIT");
|
|
187
|
+
} catch (err) {
|
|
188
|
+
rawExec("ROLLBACK");
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
}
|
package/src/memory/indexer.ts
CHANGED
|
@@ -149,33 +149,47 @@ export async function indexMessageNow(
|
|
|
149
149
|
tx,
|
|
150
150
|
);
|
|
151
151
|
}
|
|
152
|
-
|
|
153
152
|
});
|
|
154
153
|
|
|
155
154
|
// ── Batch extraction tracking ──────────────────────────────────────
|
|
156
155
|
// Instead of per-message extraction, track pending unextracted messages
|
|
157
156
|
// and trigger batch extraction when the threshold is reached or after idle.
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
157
|
+
if (
|
|
158
|
+
shouldExtract &&
|
|
159
|
+
isTrustedActor &&
|
|
160
|
+
!input.automated &&
|
|
161
|
+
config.extraction.useLLM
|
|
162
|
+
) {
|
|
164
163
|
const batchSize = config.extraction.batchSize ?? 10;
|
|
165
164
|
const idleTimeoutMs = config.extraction.idleTimeoutMs ?? 300_000;
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
// ── Graph extraction ────────────────────────────────────────────
|
|
167
|
+
const graphPendingKey = `graph_extract:${input.conversationId}:pending_count`;
|
|
168
|
+
const graphCurrentVal = getMemoryCheckpoint(graphPendingKey);
|
|
169
|
+
const graphPendingCount =
|
|
170
|
+
(graphCurrentVal ? parseInt(graphCurrentVal, 10) : 0) + 1;
|
|
171
|
+
setMemoryCheckpoint(graphPendingKey, String(graphPendingCount));
|
|
172
|
+
|
|
173
|
+
if (graphPendingCount >= batchSize) {
|
|
174
|
+
enqueueMemoryJob("graph_extract", {
|
|
170
175
|
conversationId: input.conversationId,
|
|
171
176
|
scopeId: input.scopeId ?? "default",
|
|
172
177
|
});
|
|
178
|
+
setMemoryCheckpoint(graphPendingKey, "0");
|
|
173
179
|
}
|
|
174
180
|
|
|
175
|
-
// Also maintain idle debounce: enqueue a delayed batch_extract that fires
|
|
176
|
-
// if no new messages arrive within the idle timeout window.
|
|
177
181
|
upsertDebouncedJob(
|
|
178
|
-
"
|
|
182
|
+
"graph_extract",
|
|
183
|
+
{ conversationId: input.conversationId },
|
|
184
|
+
Date.now() + idleTimeoutMs,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// ── Conversation summarization (independent of extraction) ────────
|
|
188
|
+
// Summaries feed the graph retrieval pipeline via fetchRecentSummaries().
|
|
189
|
+
// Debounced on the same idle timeout — no threshold trigger needed since
|
|
190
|
+
// summaries compress the whole conversation, not incremental batches.
|
|
191
|
+
upsertDebouncedJob(
|
|
192
|
+
"build_conversation_summary",
|
|
179
193
|
{ conversationId: input.conversationId },
|
|
180
194
|
Date.now() + idleTimeoutMs,
|
|
181
195
|
);
|
|
@@ -203,15 +217,19 @@ export async function indexMessageNow(
|
|
|
203
217
|
log.info("Skipping extraction jobs for automated message");
|
|
204
218
|
}
|
|
205
219
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
220
|
+
if (
|
|
221
|
+
!config.extraction.useLLM &&
|
|
222
|
+
shouldExtract &&
|
|
223
|
+
isTrustedActor &&
|
|
224
|
+
!input.automated
|
|
225
|
+
) {
|
|
226
|
+
log.info(
|
|
227
|
+
"Skipping extraction job: LLM extraction is disabled (useLLM=false)",
|
|
228
|
+
);
|
|
208
229
|
}
|
|
209
230
|
|
|
210
231
|
const storedSegments = segments.length - skippedShortSegments;
|
|
211
|
-
const enqueuedJobs =
|
|
212
|
-
storedSegments -
|
|
213
|
-
skippedEmbedJobs +
|
|
214
|
-
mediaBlocks.length;
|
|
232
|
+
const enqueuedJobs = storedSegments - skippedEmbedJobs + mediaBlocks.length;
|
|
215
233
|
return {
|
|
216
234
|
indexedSegments: storedSegments,
|
|
217
235
|
enqueuedJobs,
|
|
@@ -1,65 +1,55 @@
|
|
|
1
|
-
import { and, asc, eq, inArray, lt } from "drizzle-orm";
|
|
2
|
-
|
|
3
1
|
import type { AssistantConfig } from "../../config/types.js";
|
|
4
2
|
import { getLogger } from "../../util/logger.js";
|
|
5
|
-
import { getDb, rawAll, rawRun } from "../db.js";
|
|
6
|
-
import { asPositiveMs } from "../job-utils.js";
|
|
3
|
+
import { getDb, rawAll, rawChanges, rawRun } from "../db.js";
|
|
7
4
|
import { enqueueMemoryJob, type MemoryJob } from "../jobs-store.js";
|
|
8
|
-
import { memoryEmbeddings, memoryItems } from "../schema.js";
|
|
9
5
|
|
|
10
6
|
const log = getLogger("memory-jobs-worker");
|
|
11
7
|
|
|
12
|
-
const
|
|
8
|
+
const PRUNE_BATCH_LIMIT = 100;
|
|
9
|
+
const PRUNE_LOG_BATCH_LIMIT = 1000;
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Delete LLM request/response logs older than the configured retention period.
|
|
13
|
+
* Processes in batches to avoid long DB locks and excessive WAL growth.
|
|
14
|
+
* Re-enqueues itself if more rows remain.
|
|
15
|
+
*/
|
|
16
|
+
export function pruneOldLlmRequestLogsJob(
|
|
15
17
|
job: MemoryJob,
|
|
16
18
|
config: AssistantConfig,
|
|
17
19
|
): void {
|
|
18
|
-
const db = getDb();
|
|
19
20
|
const retentionMs =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
eq(memoryItems.status, "superseded"),
|
|
29
|
-
lt(memoryItems.invalidAt, cutoff),
|
|
30
|
-
),
|
|
31
|
-
)
|
|
32
|
-
.orderBy(asc(memoryItems.invalidAt), asc(memoryItems.id))
|
|
33
|
-
.limit(CLEANUP_BATCH_LIMIT)
|
|
34
|
-
.all();
|
|
35
|
-
if (stale.length === 0) return;
|
|
21
|
+
typeof job.payload.retentionMs === "number" &&
|
|
22
|
+
Number.isFinite(job.payload.retentionMs) &&
|
|
23
|
+
job.payload.retentionMs >= 0
|
|
24
|
+
? job.payload.retentionMs
|
|
25
|
+
: config.memory.cleanup.llmRequestLogRetentionMs;
|
|
26
|
+
|
|
27
|
+
// 0 means disabled
|
|
28
|
+
if (retentionMs === 0) return;
|
|
36
29
|
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
enqueueMemoryJob("cleanup_stale_superseded_items", { retentionMs });
|
|
30
|
+
const cutoffMs = Date.now() - retentionMs;
|
|
31
|
+
|
|
32
|
+
rawRun(
|
|
33
|
+
`DELETE FROM llm_request_logs WHERE rowid IN (SELECT rowid FROM llm_request_logs WHERE created_at < ? LIMIT ?)`,
|
|
34
|
+
cutoffMs,
|
|
35
|
+
PRUNE_LOG_BATCH_LIMIT,
|
|
36
|
+
);
|
|
37
|
+
const deleted = rawChanges();
|
|
38
|
+
|
|
39
|
+
if (deleted >= PRUNE_LOG_BATCH_LIMIT) {
|
|
40
|
+
enqueueMemoryJob("prune_old_llm_request_logs", { retentionMs });
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
log.
|
|
43
|
+
log.info(
|
|
52
44
|
{
|
|
53
|
-
|
|
45
|
+
deleted,
|
|
54
46
|
retentionMs,
|
|
55
|
-
|
|
47
|
+
cutoffMs,
|
|
56
48
|
},
|
|
57
|
-
"
|
|
49
|
+
"Pruned old LLM request logs",
|
|
58
50
|
);
|
|
59
51
|
}
|
|
60
52
|
|
|
61
|
-
const PRUNE_BATCH_LIMIT = 100;
|
|
62
|
-
|
|
63
53
|
/**
|
|
64
54
|
* Delete conversations that have had no activity (updatedAt) for longer than
|
|
65
55
|
* the configured retention period. Processes in batches so a single job doesn't
|