@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
|
@@ -1,29 +1,36 @@
|
|
|
1
1
|
import { getConfig } from "../config/loader.js";
|
|
2
2
|
import type { AssistantConfig } from "../config/types.js";
|
|
3
3
|
import { getLogger } from "../util/logger.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getMemoryCheckpoint, setMemoryCheckpoint } from "./checkpoints.js";
|
|
5
|
+
import { bootstrapFromHistory } from "./graph/bootstrap.js";
|
|
6
|
+
import { runConsolidation } from "./graph/consolidation.js";
|
|
7
|
+
import { runDecayTick } from "./graph/decay.js";
|
|
8
|
+
import { graphExtractJob } from "./graph/extraction-job.js";
|
|
9
|
+
import {
|
|
10
|
+
embedGraphNodeJob,
|
|
11
|
+
embedGraphTriggerJob,
|
|
12
|
+
} from "./graph/graph-search.js";
|
|
13
|
+
import { runNarrativeRefinement } from "./graph/narrative.js";
|
|
14
|
+
import { runPatternScan } from "./graph/pattern-scan.js";
|
|
5
15
|
import { backfillJob } from "./job-handlers/backfill.js";
|
|
6
|
-
import { batchExtractJob } from "./job-handlers/batch-extraction.js";
|
|
7
16
|
import {
|
|
8
|
-
cleanupStaleSupersededItemsJob,
|
|
9
17
|
pruneOldConversationsJob,
|
|
18
|
+
pruneOldLlmRequestLogsJob,
|
|
10
19
|
} from "./job-handlers/cleanup.js";
|
|
11
20
|
import { generateConversationStartersJob } from "./job-handlers/conversation-starters.js";
|
|
12
21
|
// ── Per-job-type handlers ──────────────────────────────────────────
|
|
13
22
|
import {
|
|
14
23
|
embedAttachmentJob,
|
|
15
|
-
embedItemJob,
|
|
16
24
|
embedMediaJob,
|
|
17
25
|
embedSegmentJob,
|
|
18
26
|
embedSummaryJob,
|
|
19
27
|
} from "./job-handlers/embedding.js";
|
|
20
|
-
import { extractItemsJob } from "./job-handlers/extraction.js";
|
|
21
28
|
import {
|
|
22
29
|
deleteQdrantVectorsJob,
|
|
23
30
|
rebuildIndexJob,
|
|
24
31
|
} from "./job-handlers/index-maintenance.js";
|
|
25
|
-
import { journalCarryForwardJob } from "./job-handlers/journal-carry-forward.js";
|
|
26
32
|
import { mediaProcessingJob } from "./job-handlers/media-processing.js";
|
|
33
|
+
import { buildConversationSummaryJob } from "./job-handlers/summarization.js";
|
|
27
34
|
import {
|
|
28
35
|
BackendUnavailableError,
|
|
29
36
|
classifyError,
|
|
@@ -34,18 +41,37 @@ import {
|
|
|
34
41
|
claimMemoryJobs,
|
|
35
42
|
completeMemoryJob,
|
|
36
43
|
deferMemoryJob,
|
|
37
|
-
enqueueCleanupStaleSupersededItemsJob,
|
|
38
44
|
enqueueMemoryJob,
|
|
39
45
|
enqueuePruneOldConversationsJob,
|
|
46
|
+
enqueuePruneOldLlmRequestLogsJob,
|
|
40
47
|
failMemoryJob,
|
|
41
48
|
failStalledJobs,
|
|
42
49
|
type MemoryJob,
|
|
50
|
+
type MemoryJobType,
|
|
43
51
|
resetRunningJobsToPending,
|
|
44
52
|
} from "./jobs-store.js";
|
|
45
53
|
import { QdrantCircuitOpenError } from "./qdrant-circuit-breaker.js";
|
|
46
54
|
|
|
47
55
|
const log = getLogger("memory-jobs-worker");
|
|
48
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Job types whose handlers have been removed. Existing rows may still sit in
|
|
59
|
+
* the database — the worker completes them silently instead of throwing.
|
|
60
|
+
*/
|
|
61
|
+
const LEGACY_JOB_TYPES = new Set([
|
|
62
|
+
"embed_item",
|
|
63
|
+
"extract_items",
|
|
64
|
+
"batch_extract",
|
|
65
|
+
"extract_entities",
|
|
66
|
+
"cleanup_stale_superseded_items",
|
|
67
|
+
"backfill_entity_relations",
|
|
68
|
+
"refresh_weekly_summary",
|
|
69
|
+
"refresh_monthly_summary",
|
|
70
|
+
"journal_carry_forward",
|
|
71
|
+
"generate_capability_cards",
|
|
72
|
+
"generate_thread_starters",
|
|
73
|
+
]);
|
|
74
|
+
|
|
49
75
|
export const POLL_INTERVAL_MIN_MS = 1_500;
|
|
50
76
|
export const POLL_INTERVAL_MAX_MS = 30_000;
|
|
51
77
|
|
|
@@ -60,31 +86,6 @@ export function startMemoryJobsWorker(): MemoryJobsWorker {
|
|
|
60
86
|
log.info({ recovered }, "Recovered stale running memory jobs");
|
|
61
87
|
}
|
|
62
88
|
|
|
63
|
-
// Startup recovery: enqueue batch_extract for conversations with pending
|
|
64
|
-
// unextracted messages (e.g. after a crash mid-conversation).
|
|
65
|
-
try {
|
|
66
|
-
const pendingRows = rawAll<{ key: string; value: string }>(
|
|
67
|
-
`SELECT key, value FROM memory_checkpoints WHERE key LIKE 'batch_extract:%:pending_count' AND CAST(value AS INTEGER) > 0`,
|
|
68
|
-
);
|
|
69
|
-
for (const row of pendingRows) {
|
|
70
|
-
// Extract conversationId from key: "batch_extract:<conversationId>:pending_count"
|
|
71
|
-
const parts = row.key.split(":");
|
|
72
|
-
if (parts.length >= 3) {
|
|
73
|
-
const conversationId = parts.slice(1, -1).join(":");
|
|
74
|
-
enqueueMemoryJob("batch_extract", { conversationId });
|
|
75
|
-
log.info(
|
|
76
|
-
{ conversationId, pendingCount: row.value },
|
|
77
|
-
"Recovered pending batch extraction on startup",
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} catch (err) {
|
|
82
|
-
log.warn(
|
|
83
|
-
{ err: err instanceof Error ? err.message : String(err) },
|
|
84
|
-
"Failed to recover pending batch extractions on startup",
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
89
|
let stopped = false;
|
|
89
90
|
let tickRunning = false;
|
|
90
91
|
let timer: ReturnType<typeof setTimeout>;
|
|
@@ -145,9 +146,6 @@ export async function runMemoryJobsOnce(
|
|
|
145
146
|
if (!config.memory.enabled) return 0;
|
|
146
147
|
const enableScheduledCleanup = options.enableScheduledCleanup === true;
|
|
147
148
|
|
|
148
|
-
// Periodic stale item sweep (throttled to at most once per hour)
|
|
149
|
-
sweepStaleItems(config);
|
|
150
|
-
|
|
151
149
|
// Fail jobs that have been running longer than the configured timeout
|
|
152
150
|
const timedOut = failStalledJobs(config.memory.jobs.stalledJobTimeoutMs);
|
|
153
151
|
if (timedOut > 0) {
|
|
@@ -161,6 +159,7 @@ export async function runMemoryJobsOnce(
|
|
|
161
159
|
if (enableScheduledCleanup) {
|
|
162
160
|
maybeEnqueueScheduledCleanupJobs(config);
|
|
163
161
|
}
|
|
162
|
+
maybeEnqueueGraphMaintenanceJobs();
|
|
164
163
|
return 0;
|
|
165
164
|
}
|
|
166
165
|
|
|
@@ -256,9 +255,67 @@ export async function runMemoryJobsOnce(
|
|
|
256
255
|
if (enableScheduledCleanup) {
|
|
257
256
|
maybeEnqueueScheduledCleanupJobs(config);
|
|
258
257
|
}
|
|
258
|
+
maybeEnqueueGraphMaintenanceJobs();
|
|
259
259
|
return processed;
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
// ── Graph lifecycle job handlers ──────────────────────────────────
|
|
263
|
+
|
|
264
|
+
function graphDecayJob(job: MemoryJob): void {
|
|
265
|
+
const scopeId = (job.payload as { scopeId?: string })?.scopeId ?? "default";
|
|
266
|
+
const result = runDecayTick(scopeId);
|
|
267
|
+
log.info({ jobId: job.id, ...result }, "Graph decay tick complete");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function graphConsolidateJob(
|
|
271
|
+
job: MemoryJob,
|
|
272
|
+
config: AssistantConfig,
|
|
273
|
+
): Promise<void> {
|
|
274
|
+
const scopeId = (job.payload as { scopeId?: string })?.scopeId ?? "default";
|
|
275
|
+
const result = await runConsolidation(scopeId, config);
|
|
276
|
+
log.info(
|
|
277
|
+
{
|
|
278
|
+
jobId: job.id,
|
|
279
|
+
updated: result.totalUpdated,
|
|
280
|
+
deleted: result.totalDeleted,
|
|
281
|
+
mergeEdges: result.totalMergeEdges,
|
|
282
|
+
},
|
|
283
|
+
"Graph consolidation complete",
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async function graphPatternScanJob(
|
|
288
|
+
job: MemoryJob,
|
|
289
|
+
config: AssistantConfig,
|
|
290
|
+
): Promise<void> {
|
|
291
|
+
const scopeId = (job.payload as { scopeId?: string })?.scopeId ?? "default";
|
|
292
|
+
const result = await runPatternScan(scopeId, config);
|
|
293
|
+
log.info(
|
|
294
|
+
{
|
|
295
|
+
jobId: job.id,
|
|
296
|
+
patterns: result.patternsDetected,
|
|
297
|
+
edges: result.edgesCreated,
|
|
298
|
+
},
|
|
299
|
+
"Graph pattern scan complete",
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
async function graphNarrativeRefineJob(
|
|
304
|
+
job: MemoryJob,
|
|
305
|
+
config: AssistantConfig,
|
|
306
|
+
): Promise<void> {
|
|
307
|
+
const scopeId = (job.payload as { scopeId?: string })?.scopeId ?? "default";
|
|
308
|
+
const result = await runNarrativeRefinement(scopeId, config);
|
|
309
|
+
log.info(
|
|
310
|
+
{
|
|
311
|
+
jobId: job.id,
|
|
312
|
+
updated: result.nodesUpdated,
|
|
313
|
+
arcs: result.arcsIdentified,
|
|
314
|
+
},
|
|
315
|
+
"Graph narrative refinement complete",
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
|
|
262
319
|
// ── Job error handling ─────────────────────────────────────────────
|
|
263
320
|
|
|
264
321
|
function handleJobError(job: MemoryJob, err: unknown): void {
|
|
@@ -321,45 +378,21 @@ async function processJob(
|
|
|
321
378
|
case "embed_segment":
|
|
322
379
|
await embedSegmentJob(job, config);
|
|
323
380
|
return;
|
|
324
|
-
case "embed_item":
|
|
325
|
-
await embedItemJob(job, config);
|
|
326
|
-
return;
|
|
327
381
|
case "embed_summary":
|
|
328
382
|
await embedSummaryJob(job, config);
|
|
329
383
|
return;
|
|
330
|
-
case "extract_items":
|
|
331
|
-
await extractItemsJob(job);
|
|
332
|
-
return;
|
|
333
|
-
case "batch_extract":
|
|
334
|
-
await batchExtractJob(job);
|
|
335
|
-
return;
|
|
336
|
-
case "extract_entities":
|
|
337
|
-
// Entity extraction has been removed — silently drop legacy jobs
|
|
338
|
-
return;
|
|
339
|
-
case "cleanup_stale_superseded_items":
|
|
340
|
-
cleanupStaleSupersededItemsJob(job, config);
|
|
341
|
-
return;
|
|
342
384
|
case "prune_old_conversations":
|
|
343
385
|
pruneOldConversationsJob(job, config);
|
|
344
386
|
return;
|
|
387
|
+
case "prune_old_llm_request_logs":
|
|
388
|
+
pruneOldLlmRequestLogsJob(job, config);
|
|
389
|
+
return;
|
|
345
390
|
case "build_conversation_summary":
|
|
346
|
-
|
|
347
|
-
// of batch extraction. Silently skip legacy jobs.
|
|
348
|
-
log.debug(
|
|
349
|
-
{ jobId: job.id },
|
|
350
|
-
"Skipping deprecated build_conversation_summary job — handled by batch extraction",
|
|
351
|
-
);
|
|
391
|
+
await buildConversationSummaryJob(job, config);
|
|
352
392
|
return;
|
|
353
393
|
case "backfill":
|
|
354
394
|
await backfillJob(job, config);
|
|
355
395
|
return;
|
|
356
|
-
case "backfill_entity_relations":
|
|
357
|
-
// Entity relation backfill has been removed — silently drop legacy jobs
|
|
358
|
-
return;
|
|
359
|
-
case "refresh_weekly_summary":
|
|
360
|
-
case "refresh_monthly_summary":
|
|
361
|
-
// Global summary rollups have been removed — silently drop legacy jobs
|
|
362
|
-
return;
|
|
363
396
|
case "rebuild_index":
|
|
364
397
|
await rebuildIndexJob();
|
|
365
398
|
return;
|
|
@@ -375,22 +408,42 @@ async function processJob(
|
|
|
375
408
|
case "embed_attachment":
|
|
376
409
|
await embedAttachmentJob(job, config);
|
|
377
410
|
return;
|
|
378
|
-
case "
|
|
379
|
-
await
|
|
411
|
+
case "embed_graph_node":
|
|
412
|
+
await embedGraphNodeJob(job, config);
|
|
413
|
+
return;
|
|
414
|
+
case "graph_trigger_embed":
|
|
415
|
+
await embedGraphTriggerJob(job, config);
|
|
416
|
+
return;
|
|
417
|
+
case "graph_extract":
|
|
418
|
+
await graphExtractJob(job, config);
|
|
419
|
+
return;
|
|
420
|
+
case "graph_decay":
|
|
421
|
+
graphDecayJob(job);
|
|
422
|
+
return;
|
|
423
|
+
case "graph_consolidate":
|
|
424
|
+
await graphConsolidateJob(job, config);
|
|
425
|
+
return;
|
|
426
|
+
case "graph_pattern_scan":
|
|
427
|
+
await graphPatternScanJob(job, config);
|
|
428
|
+
return;
|
|
429
|
+
case "graph_narrative_refine":
|
|
430
|
+
await graphNarrativeRefineJob(job, config);
|
|
380
431
|
return;
|
|
381
432
|
case "generate_conversation_starters":
|
|
382
433
|
await generateConversationStartersJob(job);
|
|
383
434
|
return;
|
|
384
|
-
case "
|
|
385
|
-
|
|
386
|
-
return;
|
|
387
|
-
case "generate_thread_starters":
|
|
388
|
-
// Thread starters renamed to conversation starters — silently drop legacy jobs
|
|
435
|
+
case "graph_bootstrap":
|
|
436
|
+
await bootstrapFromHistory();
|
|
389
437
|
return;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
)
|
|
438
|
+
|
|
439
|
+
default: {
|
|
440
|
+
const rawType = (job as { type: string }).type;
|
|
441
|
+
if (LEGACY_JOB_TYPES.has(rawType)) {
|
|
442
|
+
log.debug({ jobId: job.id, type: rawType }, "Dropping legacy job");
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
throw new Error(`Unknown memory job type: ${rawType}`);
|
|
446
|
+
}
|
|
394
447
|
}
|
|
395
448
|
}
|
|
396
449
|
|
|
@@ -416,82 +469,80 @@ export function maybeEnqueueScheduledCleanupJobs(
|
|
|
416
469
|
if (nowMs - lastScheduledCleanupEnqueueMs < cleanup.enqueueIntervalMs)
|
|
417
470
|
return false;
|
|
418
471
|
|
|
419
|
-
const staleSupersededItemsJobId = enqueueCleanupStaleSupersededItemsJob(
|
|
420
|
-
cleanup.supersededItemRetentionMs,
|
|
421
|
-
);
|
|
422
472
|
const pruneConversationsJobId =
|
|
423
473
|
cleanup.conversationRetentionDays > 0
|
|
424
474
|
? enqueuePruneOldConversationsJob(cleanup.conversationRetentionDays)
|
|
425
475
|
: null;
|
|
476
|
+
const pruneLlmRequestLogsJobId =
|
|
477
|
+
cleanup.llmRequestLogRetentionMs > 0
|
|
478
|
+
? enqueuePruneOldLlmRequestLogsJob(cleanup.llmRequestLogRetentionMs)
|
|
479
|
+
: null;
|
|
426
480
|
lastScheduledCleanupEnqueueMs = nowMs;
|
|
427
481
|
log.debug(
|
|
428
482
|
{
|
|
429
|
-
staleSupersededItemsJobId,
|
|
430
483
|
pruneConversationsJobId,
|
|
484
|
+
pruneLlmRequestLogsJobId,
|
|
431
485
|
enqueueIntervalMs: cleanup.enqueueIntervalMs,
|
|
432
|
-
supersededItemRetentionMs: cleanup.supersededItemRetentionMs,
|
|
433
486
|
conversationRetentionDays: cleanup.conversationRetentionDays,
|
|
487
|
+
llmRequestLogRetentionMs: cleanup.llmRequestLogRetentionMs,
|
|
434
488
|
},
|
|
435
489
|
"Enqueued scheduled memory cleanup jobs",
|
|
436
490
|
);
|
|
437
491
|
return true;
|
|
438
492
|
}
|
|
439
493
|
|
|
440
|
-
// ──
|
|
494
|
+
// ── Graph maintenance scheduling ──────────────────────────────────
|
|
441
495
|
|
|
442
|
-
const
|
|
443
|
-
|
|
496
|
+
const GRAPH_DECAY_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
|
|
497
|
+
const GRAPH_CONSOLIDATE_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours
|
|
498
|
+
const GRAPH_PATTERN_SCAN_INTERVAL_MS = 24 * 60 * 60 * 1000; // 1 day
|
|
499
|
+
const GRAPH_NARRATIVE_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000; // 1 week
|
|
444
500
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
501
|
+
const GRAPH_MAINTENANCE_CHECKPOINTS = {
|
|
502
|
+
decay: "graph_maintenance:decay:last_run",
|
|
503
|
+
consolidate: "graph_maintenance:consolidate:last_run",
|
|
504
|
+
patternScan: "graph_maintenance:pattern_scan:last_run",
|
|
505
|
+
narrative: "graph_maintenance:narrative:last_run",
|
|
506
|
+
} as const;
|
|
449
507
|
|
|
450
508
|
/**
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
* This is non-destructive: items keep their data but get an `invalid_at`
|
|
456
|
-
* timestamp that excludes them from retrieval queries.
|
|
509
|
+
* Enqueue periodic graph maintenance jobs (decay, consolidation, pattern scan, narrative).
|
|
510
|
+
* Uses durable checkpoints so intervals survive daemon restarts — jobs only fire
|
|
511
|
+
* when the actual elapsed time since last run exceeds the interval.
|
|
457
512
|
*/
|
|
458
|
-
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
);
|
|
488
|
-
if (
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
"Marked stale memory items as invalid",
|
|
492
|
-
);
|
|
493
|
-
totalMarked += changes;
|
|
513
|
+
function maybeEnqueueGraphMaintenanceJobs(nowMs = Date.now()): void {
|
|
514
|
+
const schedule: Array<{
|
|
515
|
+
key: string;
|
|
516
|
+
intervalMs: number;
|
|
517
|
+
jobType: MemoryJobType;
|
|
518
|
+
}> = [
|
|
519
|
+
{
|
|
520
|
+
key: GRAPH_MAINTENANCE_CHECKPOINTS.decay,
|
|
521
|
+
intervalMs: GRAPH_DECAY_INTERVAL_MS,
|
|
522
|
+
jobType: "graph_decay",
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
key: GRAPH_MAINTENANCE_CHECKPOINTS.consolidate,
|
|
526
|
+
intervalMs: GRAPH_CONSOLIDATE_INTERVAL_MS,
|
|
527
|
+
jobType: "graph_consolidate",
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
key: GRAPH_MAINTENANCE_CHECKPOINTS.patternScan,
|
|
531
|
+
intervalMs: GRAPH_PATTERN_SCAN_INTERVAL_MS,
|
|
532
|
+
jobType: "graph_pattern_scan",
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
key: GRAPH_MAINTENANCE_CHECKPOINTS.narrative,
|
|
536
|
+
intervalMs: GRAPH_NARRATIVE_INTERVAL_MS,
|
|
537
|
+
jobType: "graph_narrative_refine",
|
|
538
|
+
},
|
|
539
|
+
];
|
|
540
|
+
|
|
541
|
+
for (const { key, intervalMs, jobType } of schedule) {
|
|
542
|
+
const lastRun = parseInt(getMemoryCheckpoint(key) ?? "0", 10);
|
|
543
|
+
if (nowMs - lastRun >= intervalMs) {
|
|
544
|
+
enqueueMemoryJob(jobType, {});
|
|
545
|
+
setMemoryCheckpoint(key, String(nowMs));
|
|
494
546
|
}
|
|
495
547
|
}
|
|
496
|
-
return totalMarked;
|
|
497
548
|
}
|
|
@@ -91,10 +91,7 @@ export function backfillMessageIdOnLogs(
|
|
|
91
91
|
* for a conversation), this targets only the given log rows — safe for
|
|
92
92
|
* concurrent watch/assistant turns.
|
|
93
93
|
*/
|
|
94
|
-
export function setMessageIdOnLogs(
|
|
95
|
-
logIds: string[],
|
|
96
|
-
messageId: string,
|
|
97
|
-
): void {
|
|
94
|
+
export function setMessageIdOnLogs(logIds: string[], messageId: string): void {
|
|
98
95
|
if (logIds.length === 0) return;
|
|
99
96
|
const db = getDb();
|
|
100
97
|
db.update(llmRequestLogs)
|
|
@@ -185,18 +182,75 @@ function selectOrphanedLogsInRange(
|
|
|
185
182
|
.all();
|
|
186
183
|
}
|
|
187
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Find unlinked logs — logs with `message_id IS NULL` that haven't been
|
|
187
|
+
* backfilled yet. This covers the race where the client queries the inspector
|
|
188
|
+
* before `backfillMessageIdOnLogs` runs in `handleMessageComplete`, or when
|
|
189
|
+
* the backfill fails silently (try-catch in the agent loop).
|
|
190
|
+
*
|
|
191
|
+
* Scoped to a single conversation and a time range to avoid cross-turn bleed.
|
|
192
|
+
*/
|
|
193
|
+
function selectUnlinkedLogsInRange(
|
|
194
|
+
conversationId: string,
|
|
195
|
+
startTime: number,
|
|
196
|
+
endTime: number,
|
|
197
|
+
): LogRow[] {
|
|
198
|
+
if (endTime <= startTime) return [];
|
|
199
|
+
const db = getDb();
|
|
200
|
+
return db
|
|
201
|
+
.select({
|
|
202
|
+
id: llmRequestLogs.id,
|
|
203
|
+
conversationId: llmRequestLogs.conversationId,
|
|
204
|
+
messageId: llmRequestLogs.messageId,
|
|
205
|
+
provider: llmRequestLogs.provider,
|
|
206
|
+
requestPayload: llmRequestLogs.requestPayload,
|
|
207
|
+
responsePayload: llmRequestLogs.responsePayload,
|
|
208
|
+
createdAt: llmRequestLogs.createdAt,
|
|
209
|
+
})
|
|
210
|
+
.from(llmRequestLogs)
|
|
211
|
+
.where(
|
|
212
|
+
and(
|
|
213
|
+
eq(llmRequestLogs.conversationId, conversationId),
|
|
214
|
+
gte(llmRequestLogs.createdAt, startTime),
|
|
215
|
+
lte(llmRequestLogs.createdAt, endTime),
|
|
216
|
+
isNull(llmRequestLogs.messageId),
|
|
217
|
+
),
|
|
218
|
+
)
|
|
219
|
+
.orderBy(llmRequestLogs.createdAt)
|
|
220
|
+
.all();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function getRequestLogById(logId: string): LogRow | null {
|
|
224
|
+
const db = getDb();
|
|
225
|
+
return (
|
|
226
|
+
db
|
|
227
|
+
.select({
|
|
228
|
+
id: llmRequestLogs.id,
|
|
229
|
+
conversationId: llmRequestLogs.conversationId,
|
|
230
|
+
messageId: llmRequestLogs.messageId,
|
|
231
|
+
provider: llmRequestLogs.provider,
|
|
232
|
+
requestPayload: llmRequestLogs.requestPayload,
|
|
233
|
+
responsePayload: llmRequestLogs.responsePayload,
|
|
234
|
+
createdAt: llmRequestLogs.createdAt,
|
|
235
|
+
})
|
|
236
|
+
.from(llmRequestLogs)
|
|
237
|
+
.where(eq(llmRequestLogs.id, logId))
|
|
238
|
+
.get() ?? null
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
188
242
|
export function getRequestLogsByMessageId(messageId: string): LogRow[] {
|
|
189
243
|
// Resolve all assistant message IDs in the same turn so the inspector
|
|
190
244
|
// shows every LLM call from the entire agent turn, not just the queried message.
|
|
191
245
|
const turnMessageIds = getAssistantMessageIdsInTurn(messageId);
|
|
192
246
|
const turnLogs = selectLogsByMessageIds(turnMessageIds);
|
|
193
247
|
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
//
|
|
248
|
+
// Recovery: find logs in the turn's time window that the message-ID-based
|
|
249
|
+
// query missed. Two categories:
|
|
250
|
+
// 1. Orphaned — messageId references a deleted message (retry/deleteLastExchange).
|
|
251
|
+
// 2. Unlinked — messageId is still NULL because the backfill hasn't run yet
|
|
252
|
+
// or failed silently. This covers the race where the client queries the
|
|
253
|
+
// inspector before handleMessageComplete persists and backfills.
|
|
200
254
|
const message = getMessageById(messageId);
|
|
201
255
|
if (message) {
|
|
202
256
|
const bounds = getTurnTimeBounds(message.conversationId, message.createdAt);
|
|
@@ -206,10 +260,16 @@ export function getRequestLogsByMessageId(messageId: string): LogRow[] {
|
|
|
206
260
|
bounds.startTime,
|
|
207
261
|
bounds.endTime,
|
|
208
262
|
);
|
|
209
|
-
|
|
263
|
+
const unlinkedLogs = selectUnlinkedLogsInRange(
|
|
264
|
+
message.conversationId,
|
|
265
|
+
bounds.startTime,
|
|
266
|
+
bounds.endTime,
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (orphanedLogs.length > 0 || unlinkedLogs.length > 0) {
|
|
210
270
|
const seen = new Set(turnLogs.map((l) => l.id));
|
|
211
271
|
const merged = [...turnLogs];
|
|
212
|
-
for (const log of orphanedLogs) {
|
|
272
|
+
for (const log of [...orphanedLogs, ...unlinkedLogs]) {
|
|
213
273
|
if (!seen.has(log.id)) {
|
|
214
274
|
merged.push(log);
|
|
215
275
|
seen.add(log.id);
|
|
@@ -218,6 +278,30 @@ export function getRequestLogsByMessageId(messageId: string): LogRow[] {
|
|
|
218
278
|
merged.sort(
|
|
219
279
|
(a, b) => a.createdAt - b.createdAt || a.id.localeCompare(b.id),
|
|
220
280
|
);
|
|
281
|
+
|
|
282
|
+
// Opportunistically backfill recovered unlinked logs so future queries
|
|
283
|
+
// hit the fast indexed-by-messageId path. Guard with isNull so this
|
|
284
|
+
// recovery path never overwrites a messageId already set by an
|
|
285
|
+
// authoritative caller (e.g. watch-notifier).
|
|
286
|
+
if (unlinkedLogs.length > 0 && turnMessageIds.length > 0) {
|
|
287
|
+
try {
|
|
288
|
+
const db = getDb();
|
|
289
|
+
const ids = unlinkedLogs.map((l) => l.id);
|
|
290
|
+
const targetMessageId = turnMessageIds[turnMessageIds.length - 1]!;
|
|
291
|
+
db.update(llmRequestLogs)
|
|
292
|
+
.set({ messageId: targetMessageId })
|
|
293
|
+
.where(
|
|
294
|
+
and(
|
|
295
|
+
inArray(llmRequestLogs.id, ids),
|
|
296
|
+
isNull(llmRequestLogs.messageId),
|
|
297
|
+
),
|
|
298
|
+
)
|
|
299
|
+
.run();
|
|
300
|
+
} catch {
|
|
301
|
+
// non-fatal — the recovery already returned the right data
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
221
305
|
return merged;
|
|
222
306
|
}
|
|
223
307
|
}
|
|
@@ -23,9 +23,12 @@ export interface RecordMemoryRecallLogParams {
|
|
|
23
23
|
topCandidatesJson: unknown;
|
|
24
24
|
injectedText?: string;
|
|
25
25
|
reason?: string;
|
|
26
|
+
queryContext?: string;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
export function recordMemoryRecallLog(
|
|
29
|
+
export function recordMemoryRecallLog(
|
|
30
|
+
params: RecordMemoryRecallLogParams,
|
|
31
|
+
): void {
|
|
29
32
|
const db = getDb();
|
|
30
33
|
db.insert(memoryRecallLogs)
|
|
31
34
|
.values({
|
|
@@ -51,6 +54,7 @@ export function recordMemoryRecallLog(params: RecordMemoryRecallLogParams): void
|
|
|
51
54
|
topCandidatesJson: JSON.stringify(params.topCandidatesJson),
|
|
52
55
|
injectedText: params.injectedText ?? null,
|
|
53
56
|
reason: params.reason ?? null,
|
|
57
|
+
queryContext: params.queryContext ?? null,
|
|
54
58
|
createdAt: Date.now(),
|
|
55
59
|
})
|
|
56
60
|
.run();
|
|
@@ -90,6 +94,47 @@ export interface MemoryRecallLog {
|
|
|
90
94
|
topCandidates: unknown;
|
|
91
95
|
injectedText: string | null;
|
|
92
96
|
reason: string | null;
|
|
97
|
+
queryContext: string | null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Normalizes top-candidate entries from the stored SSE-event format
|
|
102
|
+
* (key/finalScore/semantic/recency/kind) to the inspector format expected
|
|
103
|
+
* by the Swift MemoryRecallCandidate struct (nodeId/score/semanticSimilarity/recencyBoost).
|
|
104
|
+
* Entries already in inspector format pass through unchanged.
|
|
105
|
+
*/
|
|
106
|
+
export function normalizeTopCandidates(raw: unknown): unknown {
|
|
107
|
+
if (!Array.isArray(raw)) return raw;
|
|
108
|
+
return raw.flatMap((entry: Record<string, unknown>) => {
|
|
109
|
+
if (!entry || typeof entry !== "object") return [];
|
|
110
|
+
|
|
111
|
+
// Start with a shallow copy, then apply field renames
|
|
112
|
+
const { key, finalScore, semantic, recency, kind: _kind, ...rest } = entry;
|
|
113
|
+
|
|
114
|
+
// nodeId: prefer existing nodeId, fall back to key
|
|
115
|
+
if (rest.nodeId === undefined && key !== undefined) {
|
|
116
|
+
rest.nodeId = key;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// score: prefer existing score, fall back to finalScore
|
|
120
|
+
if (rest.score === undefined && finalScore !== undefined) {
|
|
121
|
+
rest.score = finalScore;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// semanticSimilarity: prefer existing, fall back to semantic
|
|
125
|
+
if (rest.semanticSimilarity === undefined && semantic !== undefined) {
|
|
126
|
+
rest.semanticSimilarity = semantic;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// recencyBoost: prefer existing, fall back to recency
|
|
130
|
+
if (rest.recencyBoost === undefined && recency !== undefined) {
|
|
131
|
+
rest.recencyBoost = recency;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// kind is stripped (not in the Swift model) — already excluded via destructuring
|
|
135
|
+
|
|
136
|
+
return rest;
|
|
137
|
+
});
|
|
93
138
|
}
|
|
94
139
|
|
|
95
140
|
export function getMemoryRecallLogByMessageIds(
|
|
@@ -109,9 +154,7 @@ export function getMemoryRecallLogByMessageIds(
|
|
|
109
154
|
degraded: !!row.degraded,
|
|
110
155
|
provider: row.provider,
|
|
111
156
|
model: row.model,
|
|
112
|
-
degradation: row.degradationJson
|
|
113
|
-
? JSON.parse(row.degradationJson)
|
|
114
|
-
: null,
|
|
157
|
+
degradation: row.degradationJson ? JSON.parse(row.degradationJson) : null,
|
|
115
158
|
semanticHits: row.semanticHits,
|
|
116
159
|
mergedCount: row.mergedCount,
|
|
117
160
|
selectedCount: row.selectedCount,
|
|
@@ -121,8 +164,9 @@ export function getMemoryRecallLogByMessageIds(
|
|
|
121
164
|
sparseVectorUsed: !!row.sparseVectorUsed,
|
|
122
165
|
injectedTokens: row.injectedTokens,
|
|
123
166
|
latencyMs: row.latencyMs,
|
|
124
|
-
topCandidates: JSON.parse(row.topCandidatesJson),
|
|
167
|
+
topCandidates: normalizeTopCandidates(JSON.parse(row.topCandidatesJson)),
|
|
125
168
|
injectedText: row.injectedText,
|
|
126
169
|
reason: row.reason,
|
|
170
|
+
queryContext: row.queryContext,
|
|
127
171
|
};
|
|
128
172
|
}
|