@vellumai/assistant 0.8.0 → 0.8.2
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 +11 -0
- package/ARCHITECTURE.md +2 -7
- package/Dockerfile +80 -5
- package/README.md +2 -2
- package/bun.lock +11 -1
- package/docker-entrypoint.sh +21 -0
- package/docker-init-apt-root.sh +94 -0
- package/docker-kata-apt-env.sh +39 -0
- package/docs/plugins.md +88 -47
- package/docs/skills.md +9 -7
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/examples/plugins/echo/README.md +27 -27
- package/examples/plugins/echo/package.json +3 -0
- package/examples/plugins/echo/register.ts +31 -31
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/node_modules/@vellumai/slack-text/src/index.test.ts +114 -14
- package/node_modules/@vellumai/slack-text/src/index.ts +82 -18
- package/openapi.yaml +4462 -991
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +135 -14
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +129 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-image-optimize.test.ts +11 -3
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +131 -0
- package/src/__tests__/anthropic-provider.test.ts +137 -2
- package/src/__tests__/app-builder-tool-scripts.test.ts +9 -3
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/app-executors.test.ts +220 -4
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +35 -0
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/bundled-asset.test.ts +6 -6
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-availability-routes.test.ts +206 -0
- package/src/__tests__/channel-delivery-store.test.ts +289 -1
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -1
- package/src/__tests__/clawhub.test.ts +75 -16
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +35 -7
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/compactor-tail-resolution.test.ts +41 -0
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +77 -23
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +35 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +278 -0
- package/src/__tests__/config-sounds-sync.test.ts +97 -0
- package/src/__tests__/config-watcher-skill-reseed.test.ts +453 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +159 -18
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -4
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-search-workspace-source.test.ts +7 -0
- package/src/__tests__/context-token-estimator.test.ts +1 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +4 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +93 -92
- package/src/__tests__/conversation-agent-loop.test.ts +2 -0
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +80 -3
- package/src/__tests__/conversation-fork-crud.test.ts +323 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +54 -18
- package/src/__tests__/conversation-init.benchmark.test.ts +1 -0
- package/src/__tests__/conversation-lifecycle.test.ts +297 -0
- package/src/__tests__/conversation-message-sync-tags.test.ts +97 -0
- package/src/__tests__/conversation-pairing.test.ts +54 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +25 -2
- package/src/__tests__/conversation-provider-retry-repair.test.ts +5 -1
- package/src/__tests__/conversation-queue.test.ts +4 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +80 -13
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-queue.test.ts +59 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +4 -1
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +360 -0
- package/src/__tests__/conversation-sync-tags.test.ts +235 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-security-invariants.test.ts +8 -8
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/db-slack-external-content-normalization.test.ts +301 -0
- package/src/__tests__/delete-managed-skill-tool.test.ts +55 -13
- package/src/__tests__/disk-pressure-tools.test.ts +1 -0
- package/src/__tests__/dm-backfill.test.ts +121 -10
- package/src/__tests__/document-tool-security.test.ts +258 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +0 -1
- package/src/__tests__/edit-propagation.test.ts +33 -0
- package/src/__tests__/empty-response-pipeline.test.ts +0 -4
- package/src/__tests__/external-plugin-loader.test.ts +482 -0
- package/src/__tests__/filing-service.test.ts +163 -3
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/get-skill-detail-audit.test.ts +0 -4
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +42 -69
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/helpers/tar-fixtures.ts +39 -0
- package/src/__tests__/helpers/wait-for.ts +21 -0
- package/src/__tests__/history-repair-pipeline.test.ts +0 -3
- package/src/__tests__/history-repair.test.ts +162 -0
- package/src/__tests__/host-app-control-proxy.test.ts +365 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/image-credentials.test.ts +1 -1
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +156 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +410 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +248 -0
- package/src/__tests__/injector-chain.test.ts +10 -8
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +157 -39
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +107 -3
- package/src/__tests__/list-messages-page-latest.test.ts +55 -0
- package/src/__tests__/llm-call-pipeline.test.ts +0 -3
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +190 -2
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +222 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +100 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/llm-usage-store.test.ts +114 -0
- package/src/__tests__/managed-profile-guard.test.ts +145 -14
- package/src/__tests__/managed-skill-lifecycle.test.ts +109 -18
- package/src/__tests__/managed-store.test.ts +84 -192
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/media-generate-image.test.ts +1 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -2
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/messages-after-tiebreaker.test.ts +122 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -2009
- package/src/__tests__/oauth-commands-routes.test.ts +863 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-provider-profiles.test.ts +9 -0
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-provider.test.ts +24 -0
- package/src/__tests__/openai-responses-cutover-guard.test.ts +48 -19
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/overflow-reduce-pipeline.test.ts +0 -2
- package/src/__tests__/persistence-pipeline.test.ts +0 -2
- package/src/__tests__/{managed-proxy-context.test.ts → platform-proxy-context.test.ts} +1 -1
- package/src/__tests__/platform.test.ts +2 -0
- package/src/__tests__/plugin-api-shim.test.ts +125 -0
- package/src/__tests__/plugin-bootstrap.test.ts +41 -38
- package/src/__tests__/plugin-external-api.test.ts +68 -0
- package/src/__tests__/plugin-registry.test.ts +0 -77
- package/src/__tests__/plugin-route-contribution.test.ts +31 -4
- package/src/__tests__/plugin-skill-contribution.test.ts +0 -2
- package/src/__tests__/plugin-tool-contribution.test.ts +47 -18
- package/src/__tests__/plugin-types.test.ts +15 -23
- package/src/__tests__/process-message-background-slack.test.ts +53 -0
- package/src/__tests__/process-message-display-content.test.ts +421 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-catalog-visibility.test.ts +142 -0
- package/src/__tests__/provider-error-scenarios.test.ts +111 -0
- package/src/__tests__/{provider-managed-proxy-integration.test.ts → provider-platform-proxy-integration.test.ts} +20 -12
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +118 -0
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +65 -13
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +151 -0
- package/src/__tests__/schedule-store.test.ts +94 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +208 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/schema-transforms.test.ts +20 -0
- package/src/__tests__/search-skills-unified.test.ts +0 -5
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/{secret-routes-managed-proxy.test.ts → secret-routes-platform-proxy.test.ts} +12 -4
- package/src/__tests__/server-history-render.test.ts +43 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -12
- package/src/__tests__/skill-load-tool.test.ts +29 -93
- package/src/__tests__/skill-memory.test.ts +23 -3
- package/src/__tests__/skills-file-content-endpoint.test.ts +9 -38
- package/src/__tests__/skills-files-catalog-fallback.test.ts +0 -3
- package/src/__tests__/skills-install-extract.test.ts +49 -38
- package/src/__tests__/skills-install-staging.test.ts +159 -0
- package/src/__tests__/skills-uninstall.test.ts +9 -41
- package/src/__tests__/skills.test.ts +51 -58
- package/src/__tests__/slack-channel-config.test.ts +9 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/subagent-tool-filtering.test.ts +50 -0
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/system-prompt.test.ts +737 -63
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/terminal-tools.test.ts +28 -1
- package/src/__tests__/thread-backfill.test.ts +557 -27
- package/src/__tests__/title-generate-pipeline.test.ts +0 -13
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -3
- package/src/__tests__/tool-error-pipeline.test.ts +0 -3
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +1 -1
- package/src/__tests__/tool-executor.test.ts +16 -4
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -12
- package/src/__tests__/turn-events-store.test.ts +256 -0
- package/src/__tests__/twilio-routes.test.ts +4 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +143 -5
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +198 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +108 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +170 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +53 -20
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +241 -0
- package/src/__tests__/workspace-migration-073-repair-recall-callsite-empty-profile.test.ts +153 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-085-memory-v2-bm25-b-reembed-disabled-v2-pages.test.ts +220 -0
- package/src/__tests__/workspace-migration-086-revert-stale-gemini-mis-rewrites.test.ts +269 -0
- package/src/__tests__/workspace-migration-remove-legacy-skills-index.test.ts +309 -0
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-migrations-runner.test.ts +111 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/image-optimize.ts +13 -5
- package/src/approvals/guardian-request-resolvers.ts +32 -87
- package/src/calls/relay-server.ts +35 -0
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +74 -36
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +109 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/__tests__/unknown-command.test.ts +24 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +578 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/schedules.test.ts +491 -0
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +478 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +429 -434
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/default-action.ts +10 -53
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +162 -516
- package/src/cli/commands/notifications.ts +342 -304
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +176 -297
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/plugins.ts +185 -0
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/schedules.ts +391 -0
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/telemetry.ts +40 -0
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/cli-colors.test.ts +48 -0
- package/src/cli/lib/__tests__/confirm-prompt.test.ts +159 -0
- package/src/cli/lib/__tests__/install-from-github.test.ts +355 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +154 -0
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/__tests__/uninstall-plugin.test.ts +124 -0
- package/src/cli/lib/__tests__/unknown-command.test.ts +106 -0
- package/src/cli/lib/cli-colors.ts +12 -0
- package/src/cli/lib/confirm-prompt.ts +79 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/install-from-github.ts +304 -0
- package/src/cli/lib/list-installed-plugins.ts +137 -0
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/lib/uninstall-plugin.ts +82 -0
- package/src/cli/lib/unknown-command.ts +111 -0
- package/src/cli/program.ts +40 -6
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +23 -21
- package/src/config/bundled-skills/app-builder/TOOLS.json +7 -0
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/computer-use/TOOLS.json +15 -52
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/document/SKILL.md +23 -3
- package/src/config/bundled-skills/document/TOOLS.json +53 -0
- package/src/config/bundled-skills/document/tools/document-delete.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-list.ts +12 -0
- package/src/config/bundled-skills/document/tools/document-read.ts +12 -0
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-skills/skill-management/SKILL.md +2 -2
- package/src/config/bundled-skills/skill-management/TOOLS.json +7 -7
- package/src/config/bundled-tool-registry.ts +6 -2
- package/src/config/feature-flag-registry.json +57 -1
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +140 -52
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +8 -7
- package/src/config/schemas/__tests__/llm-request-logs.test.ts +36 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/channels.ts +8 -0
- package/src/config/schemas/compaction.ts +28 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm-request-logs.ts +81 -0
- package/src/config/schemas/llm.ts +55 -2
- package/src/config/schemas/memory-retrieval.ts +18 -0
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +32 -1
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/schemas/tools.ts +14 -0
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/config/skills.ts +3 -96
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/compactor.ts +1047 -0
- package/src/context/token-estimator.ts +2 -2
- package/src/context/window-manager.ts +197 -1334
- package/src/credential-execution/managed-catalog.ts +37 -0
- package/src/credential-health/credential-health-service.ts +280 -19
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +113 -0
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +138 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +183 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +26 -30
- package/src/daemon/config-watcher.ts +94 -29
- package/src/daemon/conversation-agent-loop-handlers.ts +24 -0
- package/src/daemon/conversation-agent-loop.ts +293 -103
- package/src/daemon/conversation-error.ts +188 -33
- package/src/daemon/conversation-lifecycle.ts +80 -26
- package/src/daemon/conversation-messaging.ts +25 -6
- package/src/daemon/conversation-process.ts +85 -31
- package/src/daemon/conversation-runtime-assembly.ts +30 -6
- package/src/daemon/conversation-slash.ts +184 -25
- package/src/daemon/conversation-store.ts +24 -10
- package/src/daemon/conversation-surfaces.ts +76 -12
- package/src/daemon/conversation-tool-setup.ts +63 -21
- package/src/daemon/conversation.ts +81 -10
- package/src/daemon/external-plugins-bootstrap.ts +231 -185
- package/src/daemon/first-greeting.ts +22 -2
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +13 -130
- package/src/daemon/handlers/config-slack-channel.ts +25 -10
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +14 -5
- package/src/daemon/handlers/skills.ts +166 -84
- package/src/daemon/history-repair.ts +61 -7
- package/src/daemon/host-app-control-proxy.ts +129 -29
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +96 -35
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +79 -70
- package/src/daemon/meet-host-supervisor.ts +20 -19
- package/src/daemon/memory-v2-startup.ts +58 -2
- package/src/daemon/message-protocol.ts +7 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +37 -9
- package/src/daemon/message-types/messages.ts +70 -1
- package/src/daemon/message-types/subagents.ts +1 -0
- package/src/daemon/message-types/sync.ts +61 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/plugin-source-watcher.ts +146 -0
- package/src/daemon/process-message.ts +77 -26
- package/src/daemon/server.ts +34 -20
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/skill-memory-refresh.ts +29 -0
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +221 -3
- package/src/embedded/plugin-api.ts +40 -0
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +79 -53
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +444 -0
- package/src/heartbeat/heartbeat-run-store.ts +3 -1
- package/src/heartbeat/heartbeat-service.ts +189 -127
- package/src/home/__tests__/feed-types.test.ts +99 -127
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +41 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +2 -3
- package/src/index.ts +18 -1
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +55 -6
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +57 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/mcp/client.ts +20 -4
- package/src/media/image-credentials.ts +3 -3
- package/src/memory/__tests__/bookmark-crud.test.ts +264 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-queries.test.ts +263 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +113 -0
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +318 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/__tests__/message-content.test.ts +35 -0
- package/src/memory/bookmark-crud.ts +211 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +80 -8
- package/src/memory/context-search/sources/memory-v2.ts +39 -14
- package/src/memory/context-search/sources/memory.ts +7 -0
- package/src/memory/context-search/sources/workspace.ts +17 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +368 -22
- package/src/memory/conversation-queries.ts +116 -12
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +20 -0
- package/src/memory/delivery-crud.ts +152 -5
- package/src/memory/embedding-backend.ts +6 -5
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/external-conversation-store.ts +66 -5
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +66 -9
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +92 -5
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/tool-handlers.ts +17 -7
- package/src/memory/graph/tools.ts +45 -6
- package/src/memory/indexer.ts +51 -29
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +86 -15
- package/src/memory/jobs/embed-concept-page.ts +65 -20
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +57 -3
- package/src/memory/llm-request-log-source-clickhouse.ts +324 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +64 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/llm-usage-store.ts +125 -5
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +175 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/109-external-conversation-bindings.ts +15 -4
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +107 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +19 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/247-external-conversation-binding-thread-id.ts +78 -0
- package/src/memory/migrations/248-create-onboarding-events.ts +21 -0
- package/src/memory/migrations/249-normalize-slack-external-content.ts +240 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +13 -0
- package/src/memory/migrations/registry.ts +8 -0
- package/src/memory/onboarding-events-store.ts +106 -0
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/schema/bookmarks.ts +36 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +27 -0
- package/src/memory/schema/infrastructure.ts +12 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +1 -4
- package/src/memory/turn-events-store.ts +127 -2
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +11 -12
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +123 -135
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +726 -18
- package/src/memory/v2/__tests__/migration.test.ts +94 -3
- package/src/memory/v2/__tests__/page-index.test.ts +360 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +309 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +138 -3
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +531 -0
- package/src/memory/v2/__tests__/sim.test.ts +45 -1
- package/src/memory/v2/__tests__/skill-store.test.ts +445 -11
- package/src/memory/v2/__tests__/static-context.test.ts +7 -22
- package/src/memory/v2/__tests__/sweep-job.test.ts +95 -0
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +85 -78
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -109
- package/src/memory/v2/migration.ts +147 -20
- package/src/memory/v2/page-index.ts +221 -0
- package/src/memory/v2/page-store.ts +3 -0
- package/src/memory/v2/prompts/consolidation.ts +9 -7
- package/src/memory/v2/prompts/router.ts +195 -0
- package/src/memory/v2/prompts/sweep.ts +2 -2
- package/src/memory/v2/qdrant.ts +234 -93
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +323 -0
- package/src/memory/v2/sim.ts +25 -12
- package/src/memory/v2/skill-store.ts +204 -30
- package/src/memory/v2/static-context.ts +16 -9
- package/src/memory/v2/sweep-job.ts +122 -96
- package/src/memory/v2/types.ts +10 -6
- package/src/memory/validation.ts +13 -0
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +45 -5
- package/src/messaging/providers/slack/__tests__/download.test.ts +231 -0
- package/src/messaging/providers/slack/adapter.ts +43 -5
- package/src/messaging/providers/slack/client.ts +27 -0
- package/src/messaging/providers/slack/deep-link.ts +65 -0
- package/src/messaging/providers/slack/download.ts +104 -0
- package/src/messaging/providers/slack/message-metadata.test.ts +32 -0
- package/src/messaging/providers/slack/message-metadata.ts +27 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +134 -0
- package/src/messaging/providers/slack/render-transcript.ts +69 -5
- package/src/messaging/providers/slack/types.ts +20 -1
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +4 -3
- package/src/notifications/copy-composer.ts +15 -0
- package/src/notifications/decision-engine.ts +2 -1
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +48 -2
- package/src/notifications/home-feed-side-effect.ts +165 -0
- package/src/notifications/signal.ts +8 -1
- package/src/oauth/connection-resolver.ts +8 -4
- package/src/oauth/platform-connection.ts +6 -2
- package/src/oauth/seed-providers.ts +10 -1
- package/src/permissions/checker.ts +14 -0
- package/src/permissions/ipc-risk-types.ts +3 -0
- package/src/permissions/question-prompter.test.ts +416 -0
- package/src/permissions/question-prompter.ts +294 -0
- package/src/platform/client.test.ts +1 -1
- package/src/platform/client.ts +1 -1
- package/src/plugin-api/constants.ts +26 -0
- package/src/plugin-api/index.ts +46 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +144 -0
- package/src/plugins/defaults/circuit-breaker.ts +0 -5
- package/src/plugins/defaults/compaction.ts +0 -4
- package/src/plugins/defaults/empty-response.ts +0 -2
- package/src/plugins/defaults/history-repair.ts +0 -2
- package/src/plugins/defaults/injectors.ts +55 -6
- package/src/plugins/defaults/llm-call.ts +0 -2
- package/src/plugins/defaults/memory-retrieval.ts +0 -1
- package/src/plugins/defaults/overflow-reduce.ts +0 -1
- package/src/plugins/defaults/persistence.ts +0 -2
- package/src/plugins/defaults/title-generate.ts +0 -5
- package/src/plugins/defaults/token-estimate.ts +0 -2
- package/src/plugins/defaults/tool-error.ts +0 -7
- package/src/plugins/defaults/tool-execute.ts +0 -2
- package/src/plugins/defaults/tool-result-truncate.ts +0 -4
- package/src/plugins/ensure-plugin-api-shim.ts +96 -0
- package/src/plugins/external-api.ts +104 -0
- package/src/plugins/external-plugin-loader.ts +367 -0
- package/src/plugins/feature-gate.ts +22 -0
- package/src/plugins/pipeline.ts +37 -0
- package/src/plugins/registry.ts +48 -80
- package/src/plugins/types.ts +74 -53
- package/src/plugins/user-loader.ts +85 -43
- package/src/proactive-artifact/aux-message-injector.ts +11 -0
- package/src/proactive-artifact/job.test.ts +49 -9
- package/src/proactive-artifact/job.ts +4 -0
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +117 -0
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +99 -0
- package/src/prompts/normalize-onboarding.ts +27 -0
- package/src/prompts/sections.ts +302 -0
- package/src/prompts/system-prompt.ts +72 -154
- package/src/prompts/templates/BOOTSTRAP.md +17 -1
- package/src/prompts/templates/system-sections.ts +173 -0
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +303 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +123 -54
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +170 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +210 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +401 -0
- package/src/providers/inference/resolve-auth.ts +73 -0
- package/src/providers/model-catalog.ts +386 -6
- package/src/providers/openai/chat-completions-provider.ts +10 -2
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/openrouter/client.ts +7 -0
- package/src/providers/{managed-proxy → platform-proxy}/constants.ts +4 -1
- package/src/providers/{managed-proxy → platform-proxy}/context.ts +3 -3
- package/src/providers/provider-availability.ts +17 -2
- package/src/providers/provider-catalog-visibility.ts +36 -0
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +151 -159
- package/src/providers/retry.ts +65 -11
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/agent-wake.test.ts +152 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +64 -7
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +311 -9
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +3 -0
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +21 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/migrations/origin-mode.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +268 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +319 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +280 -4
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/question-routes.test.ts +395 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +70 -3
- package/src/runtime/routes/acp-routes-list.test.ts +143 -0
- package/src/runtime/routes/acp-routes.ts +12 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +0 -18
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +156 -0
- package/src/runtime/routes/btw-routes.ts +5 -1
- package/src/runtime/routes/channel-availability-routes.ts +121 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +233 -0
- package/src/runtime/routes/conversation-list-routes.ts +3 -20
- package/src/runtime/routes/conversation-management-routes.ts +47 -85
- package/src/runtime/routes/conversation-query-routes.ts +350 -97
- package/src/runtime/routes/conversation-routes.ts +121 -21
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/documents-routes.ts +25 -86
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/group-routes.ts +5 -0
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-conversation.ts +28 -8
- package/src/runtime/routes/inbound-message-handler.ts +236 -41
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +248 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +118 -7
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +17 -4
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -4
- package/src/runtime/routes/index.ts +42 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +285 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +84 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +361 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/slack/share.ts +4 -52
- package/src/runtime/routes/integrations/slack/token.ts +43 -0
- package/src/runtime/routes/integrations/twilio.ts +7 -13
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-v2-routes.ts +13 -398
- package/src/runtime/routes/notification-routes.ts +3 -1
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1097 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-lifecycle-routes.ts +43 -0
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/question-routes.ts +259 -0
- package/src/runtime/routes/rename-conversation-routes.ts +2 -33
- package/src/runtime/routes/schedule-routes.ts +79 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/subagents-routes.ts +57 -18
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/telemetry-routes.ts +27 -0
- package/src/runtime/routes/tts-routes.ts +93 -1
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/routes/workspace-routes.test.ts +43 -0
- package/src/runtime/routes/workspace-routes.ts +28 -0
- package/src/runtime/services/conversation-serializer.ts +39 -7
- package/src/runtime/sync/resource-sync-events.ts +117 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/schedule-store.ts +27 -2
- package/src/schedule/scheduler.ts +208 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/__tests__/untrusted-content.test.ts +86 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/security/untrusted-content.ts +93 -8
- package/src/sequence/engine.ts +38 -40
- package/src/skills/catalog-files.ts +1 -1
- package/src/skills/catalog-install.ts +233 -116
- package/src/skills/clawhub.ts +70 -13
- package/src/skills/managed-store.ts +4 -119
- package/src/skills/skillssh-registry.ts +27 -48
- package/src/subagent/manager.ts +28 -15
- package/src/telemetry/types.ts +113 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +312 -5
- package/src/telemetry/usage-telemetry-reporter.ts +113 -7
- package/src/tools/apps/executors.ts +58 -7
- package/src/tools/ask-question/ask-question-tool.test.ts +509 -0
- package/src/tools/ask-question/ask-question-tool.ts +304 -0
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +29 -14
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/computer-use/definitions.ts +3 -3
- package/src/tools/credentials/vault.ts +1 -1
- package/src/tools/document/document-tool.ts +124 -1
- package/src/tools/filesystem/edit.ts +1 -1
- package/src/tools/filesystem/list.ts +1 -1
- package/src/tools/filesystem/read.ts +1 -1
- package/src/tools/filesystem/write.ts +5 -2
- package/src/tools/host-filesystem/transfer.ts +1 -1
- package/src/tools/host-terminal/host-shell.ts +1 -1
- package/src/tools/memory/register.test.ts +3 -3
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +14 -6
- package/src/tools/registry.ts +17 -7
- package/src/tools/schedule/create.ts +2 -2
- package/src/tools/schema-transforms.ts +7 -2
- package/src/tools/side-effects.ts +1 -0
- package/src/tools/skills/delete-managed.ts +4 -4
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/skills/scaffold-managed.ts +3 -2
- package/src/tools/subagent/notify-parent.ts +1 -1
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/system/request-permission.ts +2 -2
- package/src/tools/terminal/safe-env.ts +60 -1
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-manifest.ts +2 -0
- package/src/tools/types.ts +72 -21
- package/src/tools/ui-surface/definitions.ts +6 -5
- package/src/tts/__tests__/provider-adapters.test.ts +76 -2
- package/src/tts/providers/elevenlabs-provider.ts +75 -1
- package/src/types/onboarding-context.ts +2 -0
- package/src/usage/attribution.ts +3 -2
- package/src/util/errors.ts +17 -0
- package/src/util/platform.ts +10 -0
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +323 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +94 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +94 -5
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +8 -2
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +117 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +95 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/083-system-prompt-prefix-to-file.ts +191 -0
- package/src/workspace/migrations/084-remove-legacy-skills-index.ts +276 -0
- package/src/workspace/migrations/085-memory-v2-bm25-b-reembed-disabled-v2-pages.ts +137 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +198 -0
- package/src/workspace/migrations/registry.ts +30 -0
- package/src/workspace/migrations/runner.ts +46 -5
- package/src/workspace/migrations/types.ts +17 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/examples/plugins/echo/bun.lock +0 -25
- package/src/__tests__/context-search-pkb-source.test.ts +0 -498
- package/src/__tests__/context-window-manager.test.ts +0 -2093
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -947
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/context/__tests__/compact-prompt.test.ts +0 -63
- package/src/context/prompts/compact.md +0 -26
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -476
- package/src/memory/graph/compaction.ts +0 -299
- package/src/prompts/__tests__/build-cli-reference-section.test.ts +0 -37
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* list APIs.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { and, eq, inArray } from "drizzle-orm";
|
|
10
|
+
import { and, eq, inArray, isNull } from "drizzle-orm";
|
|
11
11
|
|
|
12
12
|
import { getDb } from "./db-connection.js";
|
|
13
13
|
import { externalConversationBindings } from "./schema.js";
|
|
@@ -16,6 +16,7 @@ export interface ExternalConversationBinding {
|
|
|
16
16
|
conversationId: string;
|
|
17
17
|
sourceChannel: string;
|
|
18
18
|
externalChatId: string;
|
|
19
|
+
externalThreadId?: string | null;
|
|
19
20
|
externalUserId?: string | null;
|
|
20
21
|
displayName?: string | null;
|
|
21
22
|
username?: string | null;
|
|
@@ -29,11 +30,19 @@ export interface UpsertBindingInput {
|
|
|
29
30
|
conversationId: string;
|
|
30
31
|
sourceChannel: string;
|
|
31
32
|
externalChatId: string;
|
|
33
|
+
externalThreadId?: string | null;
|
|
32
34
|
externalUserId?: string | null;
|
|
33
35
|
displayName?: string | null;
|
|
34
36
|
username?: string | null;
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
function normalizeExternalThreadId(
|
|
40
|
+
externalThreadId?: string | null,
|
|
41
|
+
): string | null {
|
|
42
|
+
const trimmed = externalThreadId?.trim();
|
|
43
|
+
return trimmed ? trimmed : null;
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
/**
|
|
38
47
|
* Insert or update an external conversation binding on conflict (conversationId).
|
|
39
48
|
* On conflict, updates channel metadata and timestamps.
|
|
@@ -41,12 +50,14 @@ export interface UpsertBindingInput {
|
|
|
41
50
|
export function upsertBinding(input: UpsertBindingInput): void {
|
|
42
51
|
const db = getDb();
|
|
43
52
|
const now = Date.now();
|
|
53
|
+
const externalThreadId = normalizeExternalThreadId(input.externalThreadId);
|
|
44
54
|
|
|
45
|
-
// If a stale binding exists for this
|
|
55
|
+
// If a stale binding exists for this channel/chat/thread tuple under a
|
|
46
56
|
// different conversationId, remove it first so the unique index is not violated.
|
|
47
|
-
const existing =
|
|
57
|
+
const existing = getBindingByChannelChatThread(
|
|
48
58
|
input.sourceChannel,
|
|
49
59
|
input.externalChatId,
|
|
60
|
+
externalThreadId,
|
|
50
61
|
);
|
|
51
62
|
if (existing && existing.conversationId !== input.conversationId) {
|
|
52
63
|
db.delete(externalConversationBindings)
|
|
@@ -64,6 +75,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
|
|
|
64
75
|
conversationId: input.conversationId,
|
|
65
76
|
sourceChannel: input.sourceChannel,
|
|
66
77
|
externalChatId: input.externalChatId,
|
|
78
|
+
externalThreadId,
|
|
67
79
|
externalUserId: input.externalUserId ?? null,
|
|
68
80
|
displayName: input.displayName ?? null,
|
|
69
81
|
username: input.username ?? null,
|
|
@@ -76,6 +88,7 @@ export function upsertBinding(input: UpsertBindingInput): void {
|
|
|
76
88
|
set: {
|
|
77
89
|
sourceChannel: input.sourceChannel,
|
|
78
90
|
externalChatId: input.externalChatId,
|
|
91
|
+
externalThreadId,
|
|
79
92
|
externalUserId: input.externalUserId ?? null,
|
|
80
93
|
displayName: input.displayName ?? null,
|
|
81
94
|
username: input.username ?? null,
|
|
@@ -95,15 +108,18 @@ export function upsertOutboundBinding(input: {
|
|
|
95
108
|
conversationId: string;
|
|
96
109
|
sourceChannel: string;
|
|
97
110
|
externalChatId: string;
|
|
111
|
+
externalThreadId?: string | null;
|
|
98
112
|
}): void {
|
|
99
113
|
const db = getDb();
|
|
100
114
|
const now = Date.now();
|
|
115
|
+
const externalThreadId = normalizeExternalThreadId(input.externalThreadId);
|
|
101
116
|
|
|
102
|
-
// If a stale binding exists for this
|
|
117
|
+
// If a stale binding exists for this channel/chat/thread tuple under a
|
|
103
118
|
// different conversationId, remove it first so the unique index is not violated.
|
|
104
|
-
const existing =
|
|
119
|
+
const existing = getBindingByChannelChatThread(
|
|
105
120
|
input.sourceChannel,
|
|
106
121
|
input.externalChatId,
|
|
122
|
+
externalThreadId,
|
|
107
123
|
);
|
|
108
124
|
if (existing && existing.conversationId !== input.conversationId) {
|
|
109
125
|
db.delete(externalConversationBindings)
|
|
@@ -121,6 +137,7 @@ export function upsertOutboundBinding(input: {
|
|
|
121
137
|
conversationId: input.conversationId,
|
|
122
138
|
sourceChannel: input.sourceChannel,
|
|
123
139
|
externalChatId: input.externalChatId,
|
|
140
|
+
externalThreadId,
|
|
124
141
|
externalUserId: null,
|
|
125
142
|
displayName: null,
|
|
126
143
|
username: null,
|
|
@@ -133,6 +150,7 @@ export function upsertOutboundBinding(input: {
|
|
|
133
150
|
set: {
|
|
134
151
|
sourceChannel: input.sourceChannel,
|
|
135
152
|
externalChatId: input.externalChatId,
|
|
153
|
+
externalThreadId,
|
|
136
154
|
updatedAt: now,
|
|
137
155
|
lastOutboundAt: now,
|
|
138
156
|
},
|
|
@@ -161,8 +179,20 @@ export function getBindingByConversation(
|
|
|
161
179
|
export function getBindingByChannelChat(
|
|
162
180
|
sourceChannel: string,
|
|
163
181
|
externalChatId: string,
|
|
182
|
+
): ExternalConversationBinding | null {
|
|
183
|
+
return getBindingByChannelChatThread(sourceChannel, externalChatId, null);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Look up an external binding by channel + external chat ID + optional thread ID.
|
|
188
|
+
*/
|
|
189
|
+
export function getBindingByChannelChatThread(
|
|
190
|
+
sourceChannel: string,
|
|
191
|
+
externalChatId: string,
|
|
192
|
+
externalThreadId?: string | null,
|
|
164
193
|
): ExternalConversationBinding | null {
|
|
165
194
|
const db = getDb();
|
|
195
|
+
const normalizedThreadId = normalizeExternalThreadId(externalThreadId);
|
|
166
196
|
const row = db
|
|
167
197
|
.select()
|
|
168
198
|
.from(externalConversationBindings)
|
|
@@ -170,6 +200,12 @@ export function getBindingByChannelChat(
|
|
|
170
200
|
and(
|
|
171
201
|
eq(externalConversationBindings.sourceChannel, sourceChannel),
|
|
172
202
|
eq(externalConversationBindings.externalChatId, externalChatId),
|
|
203
|
+
normalizedThreadId
|
|
204
|
+
? eq(
|
|
205
|
+
externalConversationBindings.externalThreadId,
|
|
206
|
+
normalizedThreadId,
|
|
207
|
+
)
|
|
208
|
+
: isNull(externalConversationBindings.externalThreadId),
|
|
173
209
|
),
|
|
174
210
|
)
|
|
175
211
|
.get();
|
|
@@ -195,6 +231,31 @@ export function deleteBindingByChannelChat(
|
|
|
195
231
|
.run();
|
|
196
232
|
}
|
|
197
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Remove an external binding by channel + external chat ID + thread ID.
|
|
236
|
+
*/
|
|
237
|
+
export function deleteBindingByChannelChatThread(
|
|
238
|
+
sourceChannel: string,
|
|
239
|
+
externalChatId: string,
|
|
240
|
+
externalThreadId: string,
|
|
241
|
+
): void {
|
|
242
|
+
const db = getDb();
|
|
243
|
+
const normalizedThreadId = normalizeExternalThreadId(externalThreadId);
|
|
244
|
+
if (!normalizedThreadId) {
|
|
245
|
+
deleteBindingByChannelChat(sourceChannel, externalChatId);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
db.delete(externalConversationBindings)
|
|
249
|
+
.where(
|
|
250
|
+
and(
|
|
251
|
+
eq(externalConversationBindings.sourceChannel, sourceChannel),
|
|
252
|
+
eq(externalConversationBindings.externalChatId, externalChatId),
|
|
253
|
+
eq(externalConversationBindings.externalThreadId, normalizedThreadId),
|
|
254
|
+
),
|
|
255
|
+
)
|
|
256
|
+
.run();
|
|
257
|
+
}
|
|
258
|
+
|
|
198
259
|
/**
|
|
199
260
|
* Get bindings for multiple conversation IDs at once.
|
|
200
261
|
* Returns a map of conversationId -> binding for efficient lookup.
|
|
@@ -107,18 +107,20 @@ mock.module("@qdrant/js-client-rest", () => ({
|
|
|
107
107
|
QdrantClient: MockQdrantClient,
|
|
108
108
|
}));
|
|
109
109
|
|
|
110
|
+
const embedWithBackendMock = mock(async (_config, texts: string[]) => ({
|
|
111
|
+
provider: "local",
|
|
112
|
+
model: "test-model",
|
|
113
|
+
vectors: texts.map(() => [0.1, 0.2, 0.3]) as number[][],
|
|
114
|
+
}));
|
|
115
|
+
const generateSparseEmbeddingMock = mock((_text: string) => ({
|
|
116
|
+
indices: [1, 2, 3],
|
|
117
|
+
values: [0.5, 0.5, 0.5] as number[],
|
|
118
|
+
}));
|
|
110
119
|
const realEmbeddingBackend = await import("../../embedding-backend.js");
|
|
111
120
|
mock.module("../../embedding-backend.js", () => ({
|
|
112
121
|
...realEmbeddingBackend,
|
|
113
|
-
embedWithBackend:
|
|
114
|
-
|
|
115
|
-
model: "test-model",
|
|
116
|
-
vectors: [[0.1, 0.2, 0.3]] as number[][],
|
|
117
|
-
}),
|
|
118
|
-
generateSparseEmbedding: () => ({
|
|
119
|
-
indices: [1, 2, 3],
|
|
120
|
-
values: [0.5, 0.5, 0.5] as number[],
|
|
121
|
-
}),
|
|
122
|
+
embedWithBackend: embedWithBackendMock,
|
|
123
|
+
generateSparseEmbedding: generateSparseEmbeddingMock,
|
|
122
124
|
}));
|
|
123
125
|
|
|
124
126
|
const realQdrantClient = await import("../../qdrant-client.js");
|
|
@@ -293,6 +295,8 @@ beforeEach(() => {
|
|
|
293
295
|
qdrantState.queryResponses.sparse.length = 0;
|
|
294
296
|
loadContextMemoryMock.mockClear();
|
|
295
297
|
retrieveForTurnMock.mockClear();
|
|
298
|
+
embedWithBackendMock.mockClear();
|
|
299
|
+
generateSparseEmbeddingMock.mockClear();
|
|
296
300
|
_resetMemoryV2QdrantForTests();
|
|
297
301
|
});
|
|
298
302
|
|
|
@@ -390,6 +394,59 @@ describe("ConversationGraphMemory.prepareMemory — v2 routing (per-turn path)",
|
|
|
390
394
|
expect(firstBlock.text).toContain("# memory/concepts/alice-vscode.md");
|
|
391
395
|
});
|
|
392
396
|
|
|
397
|
+
test("per-turn dense embedding is computed from combined assistant+user text", async () => {
|
|
398
|
+
// Short referential follow-ups ("do that one") carry no semantic signal
|
|
399
|
+
// on their own — the dense PKB query embedding must mirror v1's
|
|
400
|
+
// `retrieveForTurn` and combine the prior assistant turn so hint search
|
|
401
|
+
// still resolves what "that one" refers to. The sparse vector matches
|
|
402
|
+
// v1 by using the user message alone so lexical signal isn't diluted.
|
|
403
|
+
stageTurn([{ slug: "alice-vscode", denseScore: 0.9 }]);
|
|
404
|
+
|
|
405
|
+
const memory = makeMemory();
|
|
406
|
+
const config = makeConfig(true);
|
|
407
|
+
const assistantText =
|
|
408
|
+
"Alice prefers VS Code as her editor — she finds the extension ecosystem unmatched.";
|
|
409
|
+
const userText = "do that one";
|
|
410
|
+
const messages: Message[] = [
|
|
411
|
+
{
|
|
412
|
+
role: "user",
|
|
413
|
+
content: [
|
|
414
|
+
{ type: "text" as const, text: "what editors did we cover?" },
|
|
415
|
+
],
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
role: "assistant",
|
|
419
|
+
content: [{ type: "text" as const, text: assistantText }],
|
|
420
|
+
},
|
|
421
|
+
{ role: "user", content: [{ type: "text" as const, text: userText }] },
|
|
422
|
+
];
|
|
423
|
+
|
|
424
|
+
await memory.prepareMemory(
|
|
425
|
+
messages,
|
|
426
|
+
config,
|
|
427
|
+
new AbortController().signal,
|
|
428
|
+
noopEvent,
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
// v1's `retrieveForTurn` joins assistantLast + userLast with "\n\n" and
|
|
432
|
+
// embeds the combined string as the dense query vector. Assert the v2
|
|
433
|
+
// path makes the exact same embed call somewhere during this turn.
|
|
434
|
+
const expectedCombined = `${assistantText}\n\n${userText}`;
|
|
435
|
+
const matchingCall = embedWithBackendMock.mock.calls.find((call) => {
|
|
436
|
+
const texts = call[1] as string[];
|
|
437
|
+
return texts.length === 1 && texts[0] === expectedCombined;
|
|
438
|
+
});
|
|
439
|
+
expect(matchingCall).toBeDefined();
|
|
440
|
+
|
|
441
|
+
// Sparse embedding for the per-turn query uses userLast only.
|
|
442
|
+
expect(generateSparseEmbeddingMock.mock.calls).toContainEqual([userText]);
|
|
443
|
+
expect(
|
|
444
|
+
generateSparseEmbeddingMock.mock.calls.some((call) =>
|
|
445
|
+
(call[0] as string).includes(assistantText),
|
|
446
|
+
),
|
|
447
|
+
).toBe(false);
|
|
448
|
+
});
|
|
449
|
+
|
|
393
450
|
test("config on with empty Qdrant hits → no v2 block, v1 fallback skipped", async () => {
|
|
394
451
|
// No `stageTurn` call — every channel returns `{ points: [] }` so the
|
|
395
452
|
// candidate set is empty and `injectMemoryV2Block` returns block=null.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
let flagEnabled = false;
|
|
4
|
+
|
|
5
|
+
mock.module("../../../config/assistant-feature-flags.js", () => ({
|
|
6
|
+
isAssistantFeatureFlagEnabled: (_key: string, _config: unknown) =>
|
|
7
|
+
flagEnabled,
|
|
8
|
+
}));
|
|
9
|
+
|
|
10
|
+
import { getRememberDescription } from "../tools.js";
|
|
11
|
+
|
|
12
|
+
const stubConfig = {} as unknown as Parameters<
|
|
13
|
+
typeof getRememberDescription
|
|
14
|
+
>[0];
|
|
15
|
+
|
|
16
|
+
describe("getRememberDescription", () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
flagEnabled = false;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("flag off — returns the default high-pressure description", () => {
|
|
22
|
+
const desc = getRememberDescription(stubConfig);
|
|
23
|
+
expect(desc).toContain("**CRITICAL:**");
|
|
24
|
+
expect(desc).toContain("most frequently used tool");
|
|
25
|
+
expect(desc).toContain("almost every turn");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("flag on — returns the relaxed judgment-framing description", () => {
|
|
29
|
+
flagEnabled = true;
|
|
30
|
+
const desc = getRememberDescription(stubConfig);
|
|
31
|
+
expect(desc).not.toContain("**CRITICAL:**");
|
|
32
|
+
expect(desc).not.toContain("almost every turn");
|
|
33
|
+
expect(desc).toContain("a retrospective pass");
|
|
34
|
+
expect(desc).toContain("Use judgment");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("the two variants differ", () => {
|
|
38
|
+
flagEnabled = false;
|
|
39
|
+
const off = getRememberDescription(stubConfig);
|
|
40
|
+
flagEnabled = true;
|
|
41
|
+
const on = getRememberDescription(stubConfig);
|
|
42
|
+
expect(off).not.toBe(on);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("corrections-are-priority language is preserved in BOTH variants", () => {
|
|
46
|
+
flagEnabled = false;
|
|
47
|
+
expect(getRememberDescription(stubConfig)).toMatch(
|
|
48
|
+
/Corrections are.*highest priority/i,
|
|
49
|
+
);
|
|
50
|
+
flagEnabled = true;
|
|
51
|
+
expect(getRememberDescription(stubConfig)).toMatch(
|
|
52
|
+
/Corrections are.*highest priority/i,
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
8
|
|
|
9
9
|
import { and, desc, eq, inArray, ne, notInArray } from "drizzle-orm";
|
|
10
|
+
import { z } from "zod";
|
|
10
11
|
|
|
11
12
|
import type { AssistantConfig } from "../../config/types.js";
|
|
12
13
|
import { estimateTextTokens } from "../../context/token-estimator.js";
|
|
@@ -19,6 +20,8 @@ import type {
|
|
|
19
20
|
import { getLogger } from "../../util/logger.js";
|
|
20
21
|
import { getWorkspaceDir } from "../../util/platform.js";
|
|
21
22
|
import { getDb } from "../db-connection.js";
|
|
23
|
+
import { embedWithRetry } from "../embed.js";
|
|
24
|
+
import { generateSparseEmbedding } from "../embedding-backend.js";
|
|
22
25
|
import type { QdrantSparseVector } from "../qdrant-client.js";
|
|
23
26
|
import { memorySummaries } from "../schema.js";
|
|
24
27
|
import { conversations } from "../schema/conversations.js";
|
|
@@ -388,8 +391,15 @@ export class ConversationGraphMemory {
|
|
|
388
391
|
|
|
389
392
|
return await this.runPerTurn(messages, config, abortSignal);
|
|
390
393
|
} catch (err) {
|
|
394
|
+
const errCode =
|
|
395
|
+
err instanceof z.ZodError ? err.issues[0]?.code : undefined;
|
|
391
396
|
log.warn(
|
|
392
|
-
{
|
|
397
|
+
{
|
|
398
|
+
err: err instanceof Error ? err.message : String(err),
|
|
399
|
+
conversationId: this.conversationId,
|
|
400
|
+
turn: this.tracker.getTurn(),
|
|
401
|
+
errCode,
|
|
402
|
+
},
|
|
393
403
|
"Memory retrieval failed (non-fatal)",
|
|
394
404
|
);
|
|
395
405
|
return noopResult;
|
|
@@ -422,10 +432,21 @@ export class ConversationGraphMemory {
|
|
|
422
432
|
"",
|
|
423
433
|
signal,
|
|
424
434
|
);
|
|
425
|
-
this.initialized = true;
|
|
426
|
-
this.needsReload = false;
|
|
427
435
|
|
|
428
436
|
if (v2.routed) {
|
|
437
|
+
// Surface a user-query embedding so PKB hint search still runs on v2
|
|
438
|
+
// turns. v1's `loadContextMemory` produced these as a side effect of
|
|
439
|
+
// hybrid retrieval; the v2 path skips that retrieval, so embed
|
|
440
|
+
// explicitly here.
|
|
441
|
+
const userQueryText = rawUserText ?? userQuery ?? "";
|
|
442
|
+
const userQueryEmbed = await this.computeQueryVectors(
|
|
443
|
+
userQueryText,
|
|
444
|
+
userQueryText,
|
|
445
|
+
config,
|
|
446
|
+
signal,
|
|
447
|
+
);
|
|
448
|
+
this.initialized = true;
|
|
449
|
+
this.needsReload = false;
|
|
429
450
|
this.lastInjectedBlock = v2.injectedBlockText;
|
|
430
451
|
this.lastInjectedNodeIds = [];
|
|
431
452
|
this.lastInjectedImages = new Map();
|
|
@@ -438,6 +459,8 @@ export class ConversationGraphMemory {
|
|
|
438
459
|
mode: "context-load" as const,
|
|
439
460
|
injectedBlockText: v2.injectedBlockText,
|
|
440
461
|
metrics: null,
|
|
462
|
+
userQueryVector: userQueryEmbed.dense,
|
|
463
|
+
userQuerySparseVector: userQueryEmbed.sparse,
|
|
441
464
|
};
|
|
442
465
|
}
|
|
443
466
|
|
|
@@ -449,6 +472,12 @@ export class ConversationGraphMemory {
|
|
|
449
472
|
config,
|
|
450
473
|
signal,
|
|
451
474
|
});
|
|
475
|
+
// Set initialized only after v1 retrieval succeeds. If `loadContextMemory`
|
|
476
|
+
// throws (transient DB/Qdrant failure), `prepareMemory` catches and
|
|
477
|
+
// returns noop, but we want the next turn to retry the bootstrap path
|
|
478
|
+
// rather than be stuck in per-turn mode.
|
|
479
|
+
this.initialized = true;
|
|
480
|
+
this.needsReload = false;
|
|
452
481
|
|
|
453
482
|
if (result.nodes.length === 0) {
|
|
454
483
|
this.lastInjectedBlock = null;
|
|
@@ -569,6 +598,22 @@ export class ConversationGraphMemory {
|
|
|
569
598
|
signal,
|
|
570
599
|
);
|
|
571
600
|
if (v2.routed) {
|
|
601
|
+
// Surface a per-turn query embedding so PKB hint search still runs
|
|
602
|
+
// on v2 turns. v1's `retrieveForTurn` produced these as a side effect;
|
|
603
|
+
// the v2 path skips that retrieval, so embed explicitly here. Match
|
|
604
|
+
// v1's split: dense embeds the combined assistant+user text (short
|
|
605
|
+
// referential follow-ups like "do that one" need the assistant turn
|
|
606
|
+
// for semantic grounding), while sparse uses the user message alone
|
|
607
|
+
// to keep lexical signal focused on what the user actually said.
|
|
608
|
+
const denseQueryText = [assistantLast, userLast]
|
|
609
|
+
.filter((m) => m.length > 0)
|
|
610
|
+
.join("\n\n");
|
|
611
|
+
const perTurnEmbed = await this.computeQueryVectors(
|
|
612
|
+
denseQueryText,
|
|
613
|
+
userLast,
|
|
614
|
+
config,
|
|
615
|
+
signal,
|
|
616
|
+
);
|
|
572
617
|
this.lastInjectedBlock = v2.injectedBlockText;
|
|
573
618
|
this.lastInjectedNodeIds = [];
|
|
574
619
|
this.lastInjectedImages = new Map();
|
|
@@ -581,6 +626,8 @@ export class ConversationGraphMemory {
|
|
|
581
626
|
mode: "per-turn" as const,
|
|
582
627
|
injectedBlockText: v2.injectedBlockText,
|
|
583
628
|
metrics: null,
|
|
629
|
+
queryVector: perTurnEmbed.dense,
|
|
630
|
+
sparseVector: perTurnEmbed.sparse,
|
|
584
631
|
};
|
|
585
632
|
}
|
|
586
633
|
|
|
@@ -652,6 +699,41 @@ export class ConversationGraphMemory {
|
|
|
652
699
|
};
|
|
653
700
|
}
|
|
654
701
|
|
|
702
|
+
/**
|
|
703
|
+
* Embed a query string for PKB hint search on v2 turns. v1 retrieval
|
|
704
|
+
* produced these vectors as a side effect; on v2 we skip retrieval, so
|
|
705
|
+
* the agent loop loses the dense/sparse pair it needs to drive
|
|
706
|
+
* `buildPkbReminderWithHints`. Failures here degrade PKB hints to the
|
|
707
|
+
* static fallback rather than blocking the turn.
|
|
708
|
+
*/
|
|
709
|
+
private async computeQueryVectors(
|
|
710
|
+
denseText: string,
|
|
711
|
+
sparseText: string,
|
|
712
|
+
config: AssistantConfig,
|
|
713
|
+
signal: AbortSignal,
|
|
714
|
+
): Promise<{ dense?: number[]; sparse?: QdrantSparseVector }> {
|
|
715
|
+
const trimmedDense = denseText.trim();
|
|
716
|
+
const trimmedSparse = sparseText.trim();
|
|
717
|
+
let dense: number[] | undefined;
|
|
718
|
+
if (trimmedDense.length > 0) {
|
|
719
|
+
try {
|
|
720
|
+
const result = await embedWithRetry(config, [trimmedDense], { signal });
|
|
721
|
+
dense = result.vectors[0];
|
|
722
|
+
} catch (err) {
|
|
723
|
+
log.warn(
|
|
724
|
+
{ err: err instanceof Error ? err.message : String(err) },
|
|
725
|
+
"Failed to embed query for PKB hints on v2 path",
|
|
726
|
+
);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
let sparse: QdrantSparseVector | undefined;
|
|
730
|
+
if (trimmedSparse.length > 0) {
|
|
731
|
+
const sparseRaw = generateSparseEmbedding(trimmedSparse);
|
|
732
|
+
sparse = sparseRaw.indices.length > 0 ? sparseRaw : undefined;
|
|
733
|
+
}
|
|
734
|
+
return { dense, sparse };
|
|
735
|
+
}
|
|
736
|
+
|
|
655
737
|
/**
|
|
656
738
|
* Run the v2 activation pipeline when the workspace config
|
|
657
739
|
* (`memory.v2.enabled`) is on.
|
|
@@ -716,7 +798,11 @@ export class ConversationGraphMemory {
|
|
|
716
798
|
* Count the leading content blocks on a user message that were added by
|
|
717
799
|
* `injectMemoryBlock`. Memory-injected images use a 3-block pattern
|
|
718
800
|
* (opening `<memory_image>` text + image + closing `</memory_image>` text),
|
|
719
|
-
* followed by a `<memory>…</memory>` text block (legacy `<memory __injected>` is also accepted).
|
|
801
|
+
* followed by a `<memory>…</memory>` text block (legacy `<memory __injected>` is also accepted).
|
|
802
|
+
* The bare `<memory>` form is matched only when the block also ends with
|
|
803
|
+
* `\n</memory>`, so user-authored content that happens to begin with
|
|
804
|
+
* `<memory>` (for example, a message discussing the XML-like markup) is not
|
|
805
|
+
* mistaken for an injected prefix and stripped on re-injection. A legacy
|
|
720
806
|
* 2-block image pattern (no closing tag) is also accepted for backward
|
|
721
807
|
* compatibility. The injection prefix is always contiguous at the start,
|
|
722
808
|
* so we stop at the first non-memory block.
|
|
@@ -729,7 +815,8 @@ export function countMemoryPrefixBlocks(content: ContentBlock[]): number {
|
|
|
729
815
|
const block = content[firstNonMemory];
|
|
730
816
|
if (
|
|
731
817
|
block.type === "text" &&
|
|
732
|
-
(block.text.startsWith("<memory>\n")
|
|
818
|
+
((block.text.startsWith("<memory>\n") &&
|
|
819
|
+
block.text.endsWith("\n</memory>")) ||
|
|
733
820
|
block.text.startsWith("<memory __injected>\n"))
|
|
734
821
|
) {
|
|
735
822
|
firstNonMemory++;
|
|
@@ -723,8 +723,12 @@ export function parseExtractionResponse(
|
|
|
723
723
|
|
|
724
724
|
// Auto-create event trigger when event_date is set but LLM didn't include one,
|
|
725
725
|
// or replace a malformed event trigger (event_date unset) with a valid one.
|
|
726
|
+
// Only auto-create for future events — past-dated memories (historical
|
|
727
|
+
// milestones, dated events that already happened) shouldn't generate
|
|
728
|
+
// ramp/follow-up reminders.
|
|
726
729
|
if (
|
|
727
730
|
node.eventDate != null &&
|
|
731
|
+
node.eventDate > now &&
|
|
728
732
|
(!Array.isArray(raw.triggers) ||
|
|
729
733
|
!raw.triggers.some((t) => t.type === "event" && t.event_date != null))
|
|
730
734
|
) {
|
|
@@ -24,9 +24,7 @@ export function saveGraphMemoryState(
|
|
|
24
24
|
/**
|
|
25
25
|
* Load graph memory state for a conversation, or null if none exists.
|
|
26
26
|
*/
|
|
27
|
-
export function loadGraphMemoryState(
|
|
28
|
-
conversationId: string,
|
|
29
|
-
): string | null {
|
|
27
|
+
export function loadGraphMemoryState(conversationId: string): string | null {
|
|
30
28
|
const db = getDb();
|
|
31
29
|
const row = db
|
|
32
30
|
.select({ stateJson: conversationGraphMemoryState.stateJson })
|
|
@@ -35,3 +33,18 @@ export function loadGraphMemoryState(
|
|
|
35
33
|
.get();
|
|
36
34
|
return row?.stateJson ?? null;
|
|
37
35
|
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Copy the parent conversation's graph memory state row to a new conversation
|
|
39
|
+
* id so the forked conversation resumes with the parent's InContextTracker
|
|
40
|
+
* snapshot (in-context node IDs, per-node turn log, current turn). No-op if
|
|
41
|
+
* the parent has no row yet.
|
|
42
|
+
*/
|
|
43
|
+
export function forkGraphMemoryState(
|
|
44
|
+
parentConversationId: string,
|
|
45
|
+
newConversationId: string,
|
|
46
|
+
): void {
|
|
47
|
+
const stateJson = loadGraphMemoryState(parentConversationId);
|
|
48
|
+
if (stateJson == null) return;
|
|
49
|
+
saveGraphMemoryState(newConversationId, stateJson);
|
|
50
|
+
}
|
|
@@ -69,6 +69,22 @@ export function handleRemember(
|
|
|
69
69
|
return { success: true, message: "Saved to knowledge base." };
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Format `now` as a buffer-entry timestamp (`Mon D, h:mm AM/PM`). Exported so
|
|
74
|
+
* the memory v2 consolidation job can present its cutoff in the same shape
|
|
75
|
+
* the buffer entries use, making the agent's "timestamp ≥ cutoff" comparison
|
|
76
|
+
* unambiguous at minute precision.
|
|
77
|
+
*/
|
|
78
|
+
export function formatBufferTimestamp(now: Date): string {
|
|
79
|
+
const month = now.toLocaleString("en-US", { month: "short" });
|
|
80
|
+
const day = now.getDate();
|
|
81
|
+
const hours = now.getHours();
|
|
82
|
+
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
83
|
+
const ampm = hours >= 12 ? "PM" : "AM";
|
|
84
|
+
const displayHour = hours % 12 || 12;
|
|
85
|
+
return `${month} ${day}, ${displayHour}:${minutes} ${ampm}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
72
88
|
/**
|
|
73
89
|
* Build a timestamped bullet entry for `buffer.md` / `archive/<date>.md`.
|
|
74
90
|
*
|
|
@@ -80,13 +96,7 @@ export function handleRemember(
|
|
|
80
96
|
* entries identically to user-facing `remember()` calls.
|
|
81
97
|
*/
|
|
82
98
|
export function formatRememberEntry(content: string, now: Date): string {
|
|
83
|
-
|
|
84
|
-
const day = now.getDate();
|
|
85
|
-
const hours = now.getHours();
|
|
86
|
-
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
87
|
-
const ampm = hours >= 12 ? "PM" : "AM";
|
|
88
|
-
const displayHour = hours % 12 || 12;
|
|
89
|
-
return `- [${month} ${day}, ${displayHour}:${minutes} ${ampm}] ${content}\n`;
|
|
99
|
+
return `- [${formatBufferTimestamp(now)}] ${content}\n`;
|
|
90
100
|
}
|
|
91
101
|
|
|
92
102
|
/**
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Memory Tool definitions for agentic recall and remember.
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
+
import { isAssistantFeatureFlagEnabled } from "../../config/assistant-feature-flags.js";
|
|
6
|
+
import type { AssistantConfig } from "../../config/types.js";
|
|
5
7
|
import type { ToolDefinition } from "../../providers/types.js";
|
|
6
8
|
import {
|
|
7
9
|
ALL_RECALL_SOURCES,
|
|
@@ -12,13 +14,13 @@ import {
|
|
|
12
14
|
const RECALL_DEPTHS = ["fast", "standard", "deep"] as const;
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
|
-
* Explicit local information search across memory,
|
|
17
|
+
* Explicit local information search across memory, conversations, and
|
|
16
18
|
* workspace files.
|
|
17
19
|
*/
|
|
18
20
|
export const graphRecallDefinition: ToolDefinition = {
|
|
19
21
|
name: "recall",
|
|
20
22
|
description:
|
|
21
|
-
'Search local information the moment you feel uncertain. Use recall for memory,
|
|
23
|
+
'Search local information the moment you feel uncertain. Use recall for memory, past conversations, and workspace files — before you guess, before you ask, before you hedge. Auto-injection is incomplete by design; it surfaces patterns, not the specifics you need to answer well. If you catch yourself reaching for "I think", "I believe", "if I remember", "didn\'t we", "last time" — that\'s the signal. Recall. If a turn references someone, a place, a decision, a document, or prior work you should be able to find locally — recall. Call it multiple times per conversation if the turn warrants it. Be specific in your query for best results.',
|
|
22
24
|
input_schema: {
|
|
23
25
|
type: "object",
|
|
24
26
|
properties: {
|
|
@@ -34,7 +36,7 @@ export const graphRecallDefinition: ToolDefinition = {
|
|
|
34
36
|
enum: [...ALL_RECALL_SOURCES],
|
|
35
37
|
},
|
|
36
38
|
description:
|
|
37
|
-
"Optional local sources to search. Omit to search memory,
|
|
39
|
+
"Optional local sources to search. Omit to search memory, conversations, and workspace files.",
|
|
38
40
|
},
|
|
39
41
|
max_results: {
|
|
40
42
|
type: "integer",
|
|
@@ -53,6 +55,38 @@ export const graphRecallDefinition: ToolDefinition = {
|
|
|
53
55
|
},
|
|
54
56
|
};
|
|
55
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Default (high-pressure) `remember` tool description. Used when the
|
|
60
|
+
* `memory-retrospective` feature flag is OFF. The volume-shaming language
|
|
61
|
+
* ("almost every turn", "most frequently used tool") drives aggressive
|
|
62
|
+
* in-conversation capture for users who don't have the retrospective
|
|
63
|
+
* backstop enabled.
|
|
64
|
+
*/
|
|
65
|
+
const REMEMBER_DESCRIPTION_DEFAULT =
|
|
66
|
+
"Remember anything concrete: facts, preferences, corrections, plans, felt moments, names, dates, decisions. Default to remembering. Never wait until end of conversation. Corrections are highest priority — call remember the same turn the correction lands. **CRITICAL:** You should be calling remember on almost every turn. This should be your most frequently used tool.";
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Relaxed `remember` tool description used when `memory-retrospective` is
|
|
70
|
+
* ON. The retrospective pass catches what isn't captured in the moment, so
|
|
71
|
+
* the in-conversation pressure eases to a judgment framing: pause when
|
|
72
|
+
* something feels worth marking, not because the volume is required.
|
|
73
|
+
*/
|
|
74
|
+
const REMEMBER_DESCRIPTION_RELAXED =
|
|
75
|
+
"Remember anything concrete shared in conversation: corrections, plans, decisions, felt moments, names, dates, commitments, preferences. Corrections are the highest priority — call `remember` the same turn the correction lands. You don't have to call this on every turn; a retrospective pass reviews the conversation after each message-count / time interval and saves what you didn't capture. Use judgment: pause and remember when something feels worth marking, not because the volume is required.";
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Return the description that should appear in the `remember` tool
|
|
79
|
+
* registration for the current config. The variant is selected by the
|
|
80
|
+
* `memory-retrospective` assistant feature flag. Exposed as a function so
|
|
81
|
+
* the tool registrar can compute the value at registration time without
|
|
82
|
+
* importing config layers into the static definition.
|
|
83
|
+
*/
|
|
84
|
+
export function getRememberDescription(config: AssistantConfig): string {
|
|
85
|
+
return isAssistantFeatureFlagEnabled("memory-retrospective", config)
|
|
86
|
+
? REMEMBER_DESCRIPTION_RELAXED
|
|
87
|
+
: REMEMBER_DESCRIPTION_DEFAULT;
|
|
88
|
+
}
|
|
89
|
+
|
|
56
90
|
/**
|
|
57
91
|
* Save a fact to the assistant's knowledge base. The fact is appended to
|
|
58
92
|
* `buffer.md` (immediately available in the next conversation) and the daily
|
|
@@ -60,11 +94,16 @@ export const graphRecallDefinition: ToolDefinition = {
|
|
|
60
94
|
* writes go under `memory/`; otherwise they go under `pkb/`. Consolidation
|
|
61
95
|
* of the buffer into longer-form storage runs as a separate periodic job in
|
|
62
96
|
* both modes.
|
|
97
|
+
*
|
|
98
|
+
* The static `description` field carries the default (high-pressure) text
|
|
99
|
+
* so any direct importer that doesn't go through `getRememberDescription`
|
|
100
|
+
* still gets a valid tool definition. The registered `RememberTool` in
|
|
101
|
+
* `tools/memory/register.ts` overrides this at registration time with the
|
|
102
|
+
* flag-aware variant.
|
|
63
103
|
*/
|
|
64
104
|
export const graphRememberDefinition: ToolDefinition = {
|
|
65
105
|
name: "remember",
|
|
66
|
-
description:
|
|
67
|
-
"Remember anything concrete: facts, preferences, corrections, plans, felt moments, names, dates, decisions. Default to remembering. Never wait until end of conversation. Corrections are highest priority — call remember the same turn the correction lands. **CRITICAL:** You should be calling remember on almost every turn. This should be your most frequently used tool.",
|
|
106
|
+
description: REMEMBER_DESCRIPTION_DEFAULT,
|
|
68
107
|
input_schema: {
|
|
69
108
|
type: "object",
|
|
70
109
|
properties: {
|
|
@@ -76,7 +115,7 @@ export const graphRememberDefinition: ToolDefinition = {
|
|
|
76
115
|
finish_turn: {
|
|
77
116
|
type: "boolean",
|
|
78
117
|
description:
|
|
79
|
-
"When you have nothing else to say and want to
|
|
118
|
+
"When you have nothing else to say and want to yield the turn you MUST set this to true. When true, your turn ends after this tool call. It's critical that you do this in order to avoid unnecessary LLM calls.",
|
|
80
119
|
},
|
|
81
120
|
},
|
|
82
121
|
required: ["content"],
|