@vellumai/assistant 0.5.16 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +1 -1
- package/Dockerfile +0 -3
- package/knip.json +2 -1
- package/openapi.yaml +660 -80
- package/package.json +1 -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 +57 -3
- package/src/__tests__/app-compiler.test.ts +120 -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 +25 -3
- package/src/__tests__/clawhub.test.ts +54 -24
- package/src/__tests__/cli-command-risk-guard.test.ts +14 -0
- package/src/__tests__/cli-memory.test.ts +74 -69
- package/src/__tests__/config-schema.test.ts +1 -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 +9 -0
- package/src/__tests__/conversation-agent-loop.test.ts +9 -0
- 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 +5 -0
- 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-starter-routes.test.ts +20 -11
- package/src/__tests__/conversation-store.test.ts +2 -6
- package/src/__tests__/conversation-usage.test.ts +2 -6
- package/src/__tests__/conversation-wipe.test.ts +11 -408
- 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__/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__/inbound-invite-redemption.test.ts +2 -6
- package/src/__tests__/injection-block.test.ts +154 -0
- package/src/__tests__/install-meta.test.ts +506 -0
- package/src/__tests__/install-skill-routing.test.ts +292 -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 +2 -14
- package/src/__tests__/list-messages-attachments.test.ts +2 -6
- package/src/__tests__/llm-context-route-provider.test.ts +2 -6
- package/src/__tests__/llm-request-log-turn-query.test.ts +2 -6
- package/src/__tests__/llm-usage-store.test.ts +2 -6
- package/src/__tests__/log-export-workspace.test.ts +2 -6
- package/src/__tests__/managed-store.test.ts +38 -11
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +2 -8
- package/src/__tests__/memory-recall-log-store.test.ts +2 -6
- package/src/__tests__/memory-upsert-concurrency.test.ts +4 -112
- package/src/__tests__/non-member-access-request.test.ts +2 -6
- 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__/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__/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__/provider-error-scenarios.test.ts +21 -0
- package/src/__tests__/rebuild-index-graph-nodes.test.ts +273 -0
- package/src/__tests__/registry.test.ts +2 -2
- 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__/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__/scoped-approval-grants.test.ts +2 -6
- package/src/__tests__/scoped-grant-security-matrix.test.ts +2 -6
- package/src/__tests__/search-skills-unified.test.ts +421 -0
- package/src/__tests__/secret-onetime-send.test.ts +2 -0
- package/src/__tests__/send-endpoint-busy.test.ts +2 -6
- package/src/__tests__/sequence-store.test.ts +2 -6
- package/src/__tests__/server-history-render.test.ts +2 -6
- 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 +11 -11
- package/src/__tests__/skill-memory.test.ts +140 -98
- 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__/task-compiler.test.ts +2 -6
- package/src/__tests__/task-management-tools.test.ts +2 -6
- package/src/__tests__/task-memory-cleanup.test.ts +173 -229
- package/src/__tests__/task-runner.test.ts +2 -6
- package/src/__tests__/task-scheduler.test.ts +2 -6
- package/src/__tests__/test-preload.ts +3 -0
- package/src/__tests__/tool-approval-handler.test.ts +2 -6
- package/src/__tests__/tool-grant-request-escalation.test.ts +2 -6
- package/src/__tests__/tool-side-effects-slack-dm.test.ts +276 -0
- 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 +2 -6
- 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-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 +1 -15
- 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/cli-memory.ts +67 -64
- package/src/cli/commands/avatar.ts +3 -3
- package/src/cli/commands/config.ts +26 -13
- package/src/cli/commands/doctor.ts +2 -2
- package/src/cli/commands/memory.ts +41 -55
- 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 +11 -6
- 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/skills.ts +88 -16
- package/src/cli/commands/trust.ts +2 -2
- package/src/cli/lib/daemon-credential-client.ts +2 -3
- package/src/config/bundled-skills/acp/TOOLS.json +1 -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 +2 -10
- package/src/config/bundled-skills/google-calendar/SKILL.md +1 -9
- package/src/config/bundled-skills/messaging/SKILL.md +10 -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/slack/SKILL.md +1 -7
- package/src/config/bundled-tool-registry.ts +56 -4
- package/src/config/env-registry.ts +15 -8
- package/src/config/feature-flag-registry.json +21 -124
- package/src/config/schemas/platform.ts +8 -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/context-overflow-reducer.ts +46 -2
- package/src/daemon/conversation-agent-loop-handlers.ts +123 -82
- package/src/daemon/conversation-agent-loop.ts +96 -61
- package/src/daemon/conversation-error.ts +31 -8
- package/src/daemon/conversation-lifecycle.ts +33 -0
- package/src/daemon/conversation-media-retry.ts +85 -7
- package/src/daemon/conversation-notifiers.ts +4 -1
- package/src/daemon/conversation-runtime-assembly.ts +5 -0
- package/src/daemon/conversation.ts +41 -2
- package/src/daemon/daemon-control.ts +8 -2
- package/src/daemon/handlers/shared.ts +22 -12
- package/src/daemon/handlers/skills.ts +416 -202
- package/src/daemon/lifecycle.ts +40 -1
- package/src/daemon/main.ts +5 -1
- package/src/daemon/message-types/conversations.ts +4 -1
- package/src/daemon/message-types/messages.ts +3 -1
- package/src/daemon/message-types/skills.ts +97 -36
- package/src/daemon/providers-setup.ts +5 -0
- package/src/daemon/server.ts +11 -2
- package/src/daemon/tool-side-effects.ts +27 -5
- package/src/heartbeat/heartbeat-service.ts +1 -0
- 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/memory/admin.ts +11 -45
- package/src/memory/conversation-bootstrap.ts +2 -0
- package/src/memory/conversation-crud.ts +242 -348
- package/src/memory/conversation-group-migration.ts +157 -0
- package/src/memory/conversation-queries.ts +4 -2
- package/src/memory/db-init.ts +30 -3
- 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 +512 -0
- package/src/memory/graph/capability-seed.ts +297 -0
- package/src/memory/graph/consolidation.ts +691 -0
- package/src/memory/graph/conversation-graph-memory.ts +630 -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 +69 -0
- package/src/memory/graph/extraction.test.ts +936 -0
- package/src/memory/graph/extraction.ts +1254 -0
- package/src/memory/graph/graph-search.ts +266 -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 +439 -0
- package/src/memory/graph/inspect.ts +534 -0
- package/src/memory/graph/narrative.ts +267 -0
- package/src/memory/graph/pattern-scan.ts +269 -0
- package/src/memory/graph/retriever.ts +1008 -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 +1050 -0
- package/src/memory/graph/store.ts +699 -0
- package/src/memory/graph/tool-handlers.ts +426 -0
- package/src/memory/graph/tools.ts +141 -0
- package/src/memory/graph/triggers.test.ts +487 -0
- package/src/memory/graph/triggers.ts +223 -0
- package/src/memory/graph/types.ts +271 -0
- package/src/memory/group-crud.ts +191 -0
- package/src/memory/indexer.ts +37 -19
- package/src/memory/job-handlers/cleanup.ts +0 -53
- 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 +50 -70
- package/src/memory/jobs-worker.ts +147 -112
- 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 +23 -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/index.ts +4 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/qdrant-client.ts +44 -17
- package/src/memory/schema/index.ts +1 -0
- package/src/memory/schema/memory-graph.ts +139 -0
- package/src/memory/search/semantic.ts +47 -91
- package/src/memory/task-memory-cleanup.ts +28 -50
- 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 +9 -0
- package/src/notifications/signal.ts +16 -0
- package/src/oauth/seed-providers.ts +2 -1
- package/src/permissions/checker.ts +24 -3
- package/src/permissions/defaults.ts +4 -4
- package/src/permissions/workspace-policy.ts +1 -1
- package/src/playbooks/playbook-compiler.ts +19 -18
- package/src/playbooks/types.ts +4 -3
- package/src/prompts/system-prompt.ts +3 -29
- package/src/providers/anthropic/client.ts +47 -19
- 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 +7 -0
- package/src/runtime/guardian-reply-router.ts +5 -1
- package/src/runtime/http-server.ts +23 -3
- package/src/runtime/middleware/auth.ts +20 -0
- package/src/runtime/routes/attachment-routes.test.ts +106 -0
- package/src/runtime/routes/attachment-routes.ts +106 -16
- package/src/runtime/routes/brain-graph-routes.ts +21 -22
- package/src/runtime/routes/btw-routes.ts +8 -0
- package/src/runtime/routes/conversation-management-routes.ts +2 -0
- 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/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/memory-item-routes.test.ts +2 -14
- package/src/runtime/routes/memory-item-routes.ts +341 -388
- package/src/runtime/routes/schedule-routes.ts +2 -0
- package/src/runtime/routes/skills-routes.ts +103 -37
- package/src/runtime/routes/work-items-routes.test.ts +2 -6
- package/src/schedule/scheduler.ts +8 -1
- 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 +15 -14
- package/src/skills/clawhub.ts +134 -154
- package/src/skills/install-meta.ts +208 -0
- package/src/skills/managed-store.ts +27 -16
- package/src/skills/skill-memory.ts +152 -77
- package/src/skills/skillssh-registry.ts +19 -17
- package/src/tasks/task-runner.ts +3 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -5
- package/src/tools/browser/runtime-check.ts +3 -1
- package/src/tools/memory/register.ts +63 -46
- package/src/tools/permission-checker.ts +7 -1
- package/src/tools/shared/filesystem/image-read.ts +22 -85
- package/src/tools/terminal/safe-env.ts +1 -0
- package/src/tools/tool-manifest.ts +3 -3
- package/src/util/browser.ts +25 -10
- package/src/util/bun-runtime.ts +172 -0
- package/src/watcher/providers/outlook-calendar.ts +343 -0
- package/src/watcher/providers/outlook.ts +198 -0
- 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/registry.ts +6 -0
- 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/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
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* suggestion chips shown on the empty conversation page.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { and, desc, eq } from "drizzle-orm";
|
|
8
|
+
import { and, desc, eq, sql } from "drizzle-orm";
|
|
9
9
|
import { v4 as uuid } from "uuid";
|
|
10
10
|
|
|
11
11
|
import { loadSkillCatalog } from "../../config/skills.js";
|
|
@@ -26,7 +26,7 @@ import { rawAll, rawGet } from "../raw-query.js";
|
|
|
26
26
|
import {
|
|
27
27
|
conversationStarters,
|
|
28
28
|
memoryCheckpoints,
|
|
29
|
-
|
|
29
|
+
memoryGraphNodes,
|
|
30
30
|
} from "../schema.js";
|
|
31
31
|
|
|
32
32
|
const log = getLogger("conversation-starters-gen");
|
|
@@ -42,32 +42,47 @@ const CK_LAST_GEN_AT = "conversation_starters:last_gen_at";
|
|
|
42
42
|
// ── Rollup construction ───────────────────────────────────────────
|
|
43
43
|
|
|
44
44
|
export function buildMemoryRollup(scopeId: string): string {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
let rows: Array<{
|
|
46
|
+
type: string;
|
|
47
|
+
content: string;
|
|
48
|
+
significance: number | null;
|
|
49
|
+
}>;
|
|
50
|
+
try {
|
|
51
|
+
const db = getDb();
|
|
52
|
+
rows = db
|
|
53
|
+
.select({
|
|
54
|
+
type: memoryGraphNodes.type,
|
|
55
|
+
content: memoryGraphNodes.content,
|
|
56
|
+
significance: memoryGraphNodes.significance,
|
|
57
|
+
})
|
|
58
|
+
.from(memoryGraphNodes)
|
|
59
|
+
.where(
|
|
60
|
+
and(
|
|
61
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
62
|
+
eq(memoryGraphNodes.scopeId, scopeId),
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
.orderBy(desc(memoryGraphNodes.significance))
|
|
66
|
+
.limit(60)
|
|
67
|
+
.all();
|
|
68
|
+
} catch {
|
|
69
|
+
// Table may have been dropped (migration 203)
|
|
70
|
+
return "";
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (rows.length === 0) return "";
|
|
62
74
|
|
|
63
75
|
const byKind = new Map<string, string[]>();
|
|
64
|
-
for (const item of
|
|
65
|
-
|
|
76
|
+
for (const item of rows) {
|
|
77
|
+
const nl = item.content.indexOf("\n");
|
|
78
|
+
const subject = nl >= 0 ? item.content.slice(0, nl) : item.content;
|
|
79
|
+
const statement = nl >= 0 ? item.content.slice(nl + 1) : item.content;
|
|
80
|
+
let lines = byKind.get(item.type);
|
|
66
81
|
if (!lines) {
|
|
67
82
|
lines = [];
|
|
68
|
-
byKind.set(item.
|
|
83
|
+
byKind.set(item.type, lines);
|
|
69
84
|
}
|
|
70
|
-
lines.push(`- ${
|
|
85
|
+
lines.push(`- ${subject}: ${statement}`);
|
|
71
86
|
}
|
|
72
87
|
|
|
73
88
|
let rollup = "";
|
|
@@ -90,21 +105,25 @@ function buildNewItemsDiff(scopeId: string): string {
|
|
|
90
105
|
|
|
91
106
|
const newItems = rawAll<{
|
|
92
107
|
kind: string;
|
|
93
|
-
|
|
94
|
-
statement: string;
|
|
108
|
+
content: string;
|
|
95
109
|
}>(
|
|
96
|
-
`SELECT kind,
|
|
97
|
-
WHERE
|
|
98
|
-
ORDER BY
|
|
110
|
+
`SELECT type AS kind, content FROM memory_graph_nodes
|
|
111
|
+
WHERE fidelity != 'gone' AND scope_id = ? AND created > ?
|
|
112
|
+
ORDER BY created DESC LIMIT 20`,
|
|
99
113
|
scopeId,
|
|
100
|
-
lastGenAt
|
|
114
|
+
lastGenAt
|
|
101
115
|
);
|
|
102
116
|
|
|
103
117
|
if (newItems.length === 0) return "";
|
|
104
118
|
|
|
105
119
|
return (
|
|
106
120
|
"## New since last generation\n" +
|
|
107
|
-
newItems.map((i) =>
|
|
121
|
+
newItems.map((i) => {
|
|
122
|
+
const nl = i.content.indexOf("\n");
|
|
123
|
+
const subject = nl >= 0 ? i.content.slice(0, nl) : i.content;
|
|
124
|
+
const statement = nl >= 0 ? i.content.slice(nl + 1) : i.content;
|
|
125
|
+
return `- (${i.kind}) ${subject}: ${statement}`;
|
|
126
|
+
}).join("\n")
|
|
108
127
|
);
|
|
109
128
|
}
|
|
110
129
|
|
|
@@ -143,8 +162,7 @@ export const CONVERSATION_STARTER_CATEGORIES = [
|
|
|
143
162
|
"integration",
|
|
144
163
|
] as const;
|
|
145
164
|
|
|
146
|
-
export type ConversationStarterCategory =
|
|
147
|
-
(typeof CONVERSATION_STARTER_CATEGORIES)[number];
|
|
165
|
+
export type ConversationStarterCategory = typeof CONVERSATION_STARTER_CATEGORIES[number];
|
|
148
166
|
|
|
149
167
|
interface GeneratedStarter {
|
|
150
168
|
label: string;
|
|
@@ -168,7 +186,15 @@ async function generateStarters(scopeId: string): Promise<GeneratedStarter[]> {
|
|
|
168
186
|
const skills = buildSkillsSummary();
|
|
169
187
|
|
|
170
188
|
const now = new Date();
|
|
171
|
-
const timeContext = `Current time: ${now.toLocaleString("en-US", {
|
|
189
|
+
const timeContext = `Current time: ${now.toLocaleString("en-US", {
|
|
190
|
+
weekday: "long",
|
|
191
|
+
year: "numeric",
|
|
192
|
+
month: "long",
|
|
193
|
+
day: "numeric",
|
|
194
|
+
hour: "numeric",
|
|
195
|
+
minute: "2-digit",
|
|
196
|
+
hour12: true,
|
|
197
|
+
})}`;
|
|
172
198
|
|
|
173
199
|
// Truncate identity context to prevent oversized prompts when SOUL.md /
|
|
174
200
|
// IDENTITY.md / USER.md are large.
|
|
@@ -185,7 +211,11 @@ ${timeContext}
|
|
|
185
211
|
|
|
186
212
|
Your goal: suggest the 4 most useful things this person could ask you to do right now.
|
|
187
213
|
|
|
188
|
-
${
|
|
214
|
+
${
|
|
215
|
+
identityContext
|
|
216
|
+
? `## Assistant identity & user profile\n\n${identityContext}\n\n`
|
|
217
|
+
: ""
|
|
218
|
+
}## What you know
|
|
189
219
|
|
|
190
220
|
${rollup}
|
|
191
221
|
${diff}
|
|
@@ -253,7 +283,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
253
283
|
const response = await provider.sendMessage(
|
|
254
284
|
[
|
|
255
285
|
userMessage(
|
|
256
|
-
"Generate personalized conversation starters based on my context."
|
|
286
|
+
"Generate personalized conversation starters based on my context."
|
|
257
287
|
),
|
|
258
288
|
],
|
|
259
289
|
[
|
|
@@ -303,14 +333,14 @@ Bad → Good (assistant voice → user voice):
|
|
|
303
333
|
},
|
|
304
334
|
},
|
|
305
335
|
signal,
|
|
306
|
-
}
|
|
336
|
+
}
|
|
307
337
|
);
|
|
308
338
|
cleanup();
|
|
309
339
|
|
|
310
340
|
const toolBlock = extractToolUse(response);
|
|
311
341
|
if (!toolBlock) {
|
|
312
342
|
log.warn(
|
|
313
|
-
"No tool_use block in conversation starters generation response"
|
|
343
|
+
"No tool_use block in conversation starters generation response"
|
|
314
344
|
);
|
|
315
345
|
return [];
|
|
316
346
|
}
|
|
@@ -327,7 +357,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
327
357
|
typeof s.label === "string" &&
|
|
328
358
|
s.label.length > 0 &&
|
|
329
359
|
typeof s.prompt === "string" &&
|
|
330
|
-
s.prompt.length > 0
|
|
360
|
+
s.prompt.length > 0
|
|
331
361
|
)
|
|
332
362
|
.slice(0, 4)
|
|
333
363
|
.map((s) => ({
|
|
@@ -336,7 +366,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
336
366
|
category:
|
|
337
367
|
typeof s.category === "string" &&
|
|
338
368
|
(CONVERSATION_STARTER_CATEGORIES as readonly string[]).includes(
|
|
339
|
-
s.category
|
|
369
|
+
s.category
|
|
340
370
|
)
|
|
341
371
|
? s.category
|
|
342
372
|
: "productivity",
|
|
@@ -350,7 +380,7 @@ Bad → Good (assistant voice → user voice):
|
|
|
350
380
|
// ── Job handler ───────────────────────────────────────────────────
|
|
351
381
|
|
|
352
382
|
export async function generateConversationStartersJob(
|
|
353
|
-
job: MemoryJob
|
|
383
|
+
job: MemoryJob
|
|
354
384
|
): Promise<void> {
|
|
355
385
|
const scopeId = asString(job.payload.scopeId) ?? "default";
|
|
356
386
|
|
|
@@ -373,16 +403,24 @@ export async function generateConversationStartersJob(
|
|
|
373
403
|
? parseInt(batchCheckpoint.value, 10) + 1
|
|
374
404
|
: 1;
|
|
375
405
|
|
|
376
|
-
// Collect the memory
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
406
|
+
// Collect the memory types that informed this batch
|
|
407
|
+
let sourceKinds = "";
|
|
408
|
+
try {
|
|
409
|
+
const kindRows = db
|
|
410
|
+
.select({ kind: memoryGraphNodes.type })
|
|
411
|
+
.from(memoryGraphNodes)
|
|
412
|
+
.where(
|
|
413
|
+
and(
|
|
414
|
+
sql`${memoryGraphNodes.fidelity} != 'gone'`,
|
|
415
|
+
eq(memoryGraphNodes.scopeId, scopeId),
|
|
416
|
+
)
|
|
417
|
+
)
|
|
418
|
+
.groupBy(memoryGraphNodes.type)
|
|
419
|
+
.all();
|
|
420
|
+
sourceKinds = kindRows.map((r) => r.kind).join(",");
|
|
421
|
+
} catch {
|
|
422
|
+
// Table may have been dropped (migration 203)
|
|
423
|
+
}
|
|
386
424
|
|
|
387
425
|
// Remove previous starters for this scope before inserting the new batch
|
|
388
426
|
db.delete(conversationStarters)
|
|
@@ -408,8 +446,8 @@ export async function generateConversationStartersJob(
|
|
|
408
446
|
|
|
409
447
|
// Count active items for checkpoint
|
|
410
448
|
const countRow = rawGet<{ c: number }>(
|
|
411
|
-
`SELECT COUNT(*) AS c FROM
|
|
412
|
-
scopeId
|
|
449
|
+
`SELECT COUNT(*) AS c FROM memory_graph_nodes WHERE fidelity != 'gone' AND scope_id = ?`,
|
|
450
|
+
scopeId
|
|
413
451
|
);
|
|
414
452
|
const totalActive = countRow?.c ?? 0;
|
|
415
453
|
|
|
@@ -430,6 +468,6 @@ export async function generateConversationStartersJob(
|
|
|
430
468
|
|
|
431
469
|
log.info(
|
|
432
470
|
{ scopeId, batch: nextBatch, count: starters.length },
|
|
433
|
-
"Generated conversation starters"
|
|
471
|
+
"Generated conversation starters"
|
|
434
472
|
);
|
|
435
473
|
}
|
|
@@ -11,7 +11,6 @@ import type { MemoryJob } from "../jobs-store.js";
|
|
|
11
11
|
import { extractMediaBlocks } from "../message-content.js";
|
|
12
12
|
import {
|
|
13
13
|
mediaAssets,
|
|
14
|
-
memoryItems,
|
|
15
14
|
memorySegments,
|
|
16
15
|
memorySummaries,
|
|
17
16
|
messages,
|
|
@@ -19,7 +18,7 @@ import {
|
|
|
19
18
|
|
|
20
19
|
export async function embedSegmentJob(
|
|
21
20
|
job: MemoryJob,
|
|
22
|
-
config: AssistantConfig
|
|
21
|
+
config: AssistantConfig
|
|
23
22
|
): Promise<void> {
|
|
24
23
|
const segmentId = asString(job.payload.segmentId);
|
|
25
24
|
if (!segmentId) return;
|
|
@@ -38,34 +37,9 @@ export async function embedSegmentJob(
|
|
|
38
37
|
});
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
export async function embedItemJob(
|
|
42
|
-
job: MemoryJob,
|
|
43
|
-
config: AssistantConfig,
|
|
44
|
-
): Promise<void> {
|
|
45
|
-
const itemId = asString(job.payload.itemId);
|
|
46
|
-
if (!itemId) return;
|
|
47
|
-
const db = getDb();
|
|
48
|
-
const item = db
|
|
49
|
-
.select()
|
|
50
|
-
.from(memoryItems)
|
|
51
|
-
.where(eq(memoryItems.id, itemId))
|
|
52
|
-
.get();
|
|
53
|
-
if (!item || item.status !== "active") return;
|
|
54
|
-
const text = `<kind>${item.kind}</kind> ${item.subject}: ${item.statement}`;
|
|
55
|
-
await embedAndUpsert(config, "item", item.id, text, {
|
|
56
|
-
kind: item.kind,
|
|
57
|
-
subject: item.subject,
|
|
58
|
-
status: item.status,
|
|
59
|
-
confidence: item.confidence,
|
|
60
|
-
created_at: item.firstSeenAt,
|
|
61
|
-
last_seen_at: item.lastSeenAt,
|
|
62
|
-
memory_scope_id: item.scopeId,
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
40
|
export async function embedSummaryJob(
|
|
67
41
|
job: MemoryJob,
|
|
68
|
-
config: AssistantConfig
|
|
42
|
+
config: AssistantConfig
|
|
69
43
|
): Promise<void> {
|
|
70
44
|
const summaryId = asString(job.payload.summaryId);
|
|
71
45
|
if (!summaryId) return;
|
|
@@ -86,13 +60,13 @@ export async function embedSummaryJob(
|
|
|
86
60
|
created_at: summary.startAt,
|
|
87
61
|
last_seen_at: summary.endAt,
|
|
88
62
|
memory_scope_id: summary.scopeId,
|
|
89
|
-
}
|
|
63
|
+
}
|
|
90
64
|
);
|
|
91
65
|
}
|
|
92
66
|
|
|
93
67
|
export async function embedMediaJob(
|
|
94
68
|
job: MemoryJob,
|
|
95
|
-
config: AssistantConfig
|
|
69
|
+
config: AssistantConfig
|
|
96
70
|
): Promise<void> {
|
|
97
71
|
const assetId = asString(job.payload.assetId);
|
|
98
72
|
if (!assetId) return;
|
|
@@ -125,7 +99,7 @@ export async function embedMediaJob(
|
|
|
125
99
|
|
|
126
100
|
export async function embedAttachmentJob(
|
|
127
101
|
job: MemoryJob,
|
|
128
|
-
config: AssistantConfig
|
|
102
|
+
config: AssistantConfig
|
|
129
103
|
): Promise<void> {
|
|
130
104
|
const messageId = asString(job.payload.messageId);
|
|
131
105
|
const blockIndex = job.payload.blockIndex as number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { eq, like } from "drizzle-orm";
|
|
1
|
+
import { eq, isNotNull, like, ne } from "drizzle-orm";
|
|
2
2
|
|
|
3
3
|
import { getConfig } from "../../config/loader.js";
|
|
4
4
|
import { getLogger } from "../../util/logger.js";
|
|
@@ -12,7 +12,8 @@ import { getQdrantClient } from "../qdrant-client.js";
|
|
|
12
12
|
import {
|
|
13
13
|
mediaAssets,
|
|
14
14
|
memoryEmbeddings,
|
|
15
|
-
|
|
15
|
+
memoryGraphNodes,
|
|
16
|
+
memoryGraphTriggers,
|
|
16
17
|
memorySegments,
|
|
17
18
|
memorySummaries,
|
|
18
19
|
messages,
|
|
@@ -24,15 +25,6 @@ export async function rebuildIndexJob(): Promise<void> {
|
|
|
24
25
|
const db = getDb();
|
|
25
26
|
db.delete(memoryEmbeddings).run();
|
|
26
27
|
|
|
27
|
-
const items = db
|
|
28
|
-
.select({ id: memoryItems.id })
|
|
29
|
-
.from(memoryItems)
|
|
30
|
-
.where(eq(memoryItems.status, "active"))
|
|
31
|
-
.all();
|
|
32
|
-
for (const item of items) {
|
|
33
|
-
enqueueMemoryJob("embed_item", { itemId: item.id });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
28
|
const summaries = db
|
|
37
29
|
.select({ id: memorySummaries.id })
|
|
38
30
|
.from(memorySummaries)
|
|
@@ -77,6 +69,26 @@ export async function rebuildIndexJob(): Promise<void> {
|
|
|
77
69
|
}
|
|
78
70
|
}
|
|
79
71
|
}
|
|
72
|
+
|
|
73
|
+
// Re-embed graph nodes stored in the memory graph.
|
|
74
|
+
const graphNodes = db
|
|
75
|
+
.select({ id: memoryGraphNodes.id })
|
|
76
|
+
.from(memoryGraphNodes)
|
|
77
|
+
.where(ne(memoryGraphNodes.fidelity, "gone"))
|
|
78
|
+
.all();
|
|
79
|
+
for (const node of graphNodes) {
|
|
80
|
+
enqueueMemoryJob("embed_graph_node", { nodeId: node.id });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Re-embed semantic triggers that have condition text.
|
|
84
|
+
const triggers = db
|
|
85
|
+
.select({ id: memoryGraphTriggers.id })
|
|
86
|
+
.from(memoryGraphTriggers)
|
|
87
|
+
.where(isNotNull(memoryGraphTriggers.condition))
|
|
88
|
+
.all();
|
|
89
|
+
for (const trigger of triggers) {
|
|
90
|
+
enqueueMemoryJob("graph_trigger_embed", { triggerId: trigger.id });
|
|
91
|
+
}
|
|
80
92
|
}
|
|
81
93
|
|
|
82
94
|
export async function deleteQdrantVectorsJob(job: MemoryJob): Promise<void> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { and,
|
|
1
|
+
import { and, asc, eq, gt, sql } from "drizzle-orm";
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import type { AssistantConfig } from "../../config/types.js";
|
|
@@ -19,7 +19,7 @@ import { memorySegments, memorySummaries } from "../schema.js";
|
|
|
19
19
|
const log = getLogger("memory-jobs-worker");
|
|
20
20
|
|
|
21
21
|
const SUMMARY_LLM_TIMEOUT_MS = 20_000;
|
|
22
|
-
const SUMMARY_MAX_TOKENS =
|
|
22
|
+
const SUMMARY_MAX_TOKENS = 1000;
|
|
23
23
|
|
|
24
24
|
const CONVERSATION_SUMMARY_SYSTEM_PROMPT = [
|
|
25
25
|
"You compress conversation transcripts into compact summaries for semantic search and memory retrieval.",
|
|
@@ -37,7 +37,7 @@ const CONVERSATION_SUMMARY_SYSTEM_PROMPT = [
|
|
|
37
37
|
"## Open Items",
|
|
38
38
|
"Unresolved questions, pending tasks, or follow-ups (omit section if none).",
|
|
39
39
|
"",
|
|
40
|
-
"Target
|
|
40
|
+
"Target 400-800 tokens. Be thorough — capture nuance, tone, and relationship dynamics, not just facts.",
|
|
41
41
|
].join("\n");
|
|
42
42
|
|
|
43
43
|
export async function buildConversationSummaryJob(
|
|
@@ -47,14 +47,6 @@ export async function buildConversationSummaryJob(
|
|
|
47
47
|
const conversationId = asString(job.payload.conversationId);
|
|
48
48
|
if (!conversationId) return;
|
|
49
49
|
const db = getDb();
|
|
50
|
-
const rows = db
|
|
51
|
-
.select()
|
|
52
|
-
.from(memorySegments)
|
|
53
|
-
.where(eq(memorySegments.conversationId, conversationId))
|
|
54
|
-
.orderBy(desc(memorySegments.createdAt))
|
|
55
|
-
.limit(40)
|
|
56
|
-
.all();
|
|
57
|
-
if (rows.length === 0) return;
|
|
58
50
|
|
|
59
51
|
const existing = db
|
|
60
52
|
.select()
|
|
@@ -67,9 +59,27 @@ export async function buildConversationSummaryJob(
|
|
|
67
59
|
)
|
|
68
60
|
.get();
|
|
69
61
|
|
|
70
|
-
//
|
|
62
|
+
// Fetch only segments newer than what the existing summary already covers.
|
|
63
|
+
// For first-time summaries, fetch all segments.
|
|
64
|
+
const lastCoveredAt = existing
|
|
65
|
+
? Math.max(existing.startAt, existing.endAt)
|
|
66
|
+
: 0;
|
|
67
|
+
|
|
68
|
+
const conditions = [eq(memorySegments.conversationId, conversationId)];
|
|
69
|
+
if (lastCoveredAt > 0) {
|
|
70
|
+
conditions.push(gt(memorySegments.createdAt, lastCoveredAt));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const rows = db
|
|
74
|
+
.select()
|
|
75
|
+
.from(memorySegments)
|
|
76
|
+
.where(and(...conditions))
|
|
77
|
+
.orderBy(asc(memorySegments.createdAt))
|
|
78
|
+
.all();
|
|
79
|
+
if (rows.length === 0) return;
|
|
80
|
+
|
|
81
|
+
// Build segment text for LLM input (already in chronological order)
|
|
71
82
|
const segmentTexts = rows
|
|
72
|
-
.reverse()
|
|
73
83
|
.map((row) => `[${row.role}] ${truncate(row.text, 600)}`)
|
|
74
84
|
.join("\n\n");
|
|
75
85
|
|
|
@@ -88,6 +98,11 @@ export async function buildConversationSummaryJob(
|
|
|
88
98
|
const now = Date.now();
|
|
89
99
|
const summaryId = existing?.id ?? uuid();
|
|
90
100
|
const nextVersion = (existing?.version ?? 0) + 1;
|
|
101
|
+
const earliestCovered = existing
|
|
102
|
+
? Math.min(existing.startAt, existing.endAt, rows[0].createdAt)
|
|
103
|
+
: rows[0].createdAt;
|
|
104
|
+
const latestCovered = rows[rows.length - 1].createdAt;
|
|
105
|
+
|
|
91
106
|
db.insert(memorySummaries)
|
|
92
107
|
.values({
|
|
93
108
|
id: summaryId,
|
|
@@ -97,8 +112,8 @@ export async function buildConversationSummaryJob(
|
|
|
97
112
|
summary: summaryText,
|
|
98
113
|
tokenEstimate: estimateTextTokens(summaryText),
|
|
99
114
|
version: nextVersion,
|
|
100
|
-
startAt:
|
|
101
|
-
endAt:
|
|
115
|
+
startAt: earliestCovered,
|
|
116
|
+
endAt: latestCovered,
|
|
102
117
|
createdAt: now,
|
|
103
118
|
updatedAt: now,
|
|
104
119
|
})
|
|
@@ -109,8 +124,8 @@ export async function buildConversationSummaryJob(
|
|
|
109
124
|
tokenEstimate: estimateTextTokens(summaryText),
|
|
110
125
|
version: sql`${memorySummaries.version} + 1`,
|
|
111
126
|
scopeId,
|
|
112
|
-
startAt:
|
|
113
|
-
endAt:
|
|
127
|
+
startAt: earliestCovered,
|
|
128
|
+
endAt: latestCovered,
|
|
114
129
|
updatedAt: now,
|
|
115
130
|
},
|
|
116
131
|
})
|
package/src/memory/job-utils.ts
CHANGED
|
@@ -147,7 +147,7 @@ export function truncate(text: string, max: number): string {
|
|
|
147
147
|
|
|
148
148
|
export async function embedAndUpsert(
|
|
149
149
|
config: AssistantConfig,
|
|
150
|
-
targetType: "segment" | "item" | "summary" | "media",
|
|
150
|
+
targetType: "segment" | "item" | "summary" | "media" | "graph_node",
|
|
151
151
|
targetId: string,
|
|
152
152
|
input: EmbeddingInput,
|
|
153
153
|
extraPayload?: Record<string, unknown>,
|