@vellumai/assistant 0.8.4 → 0.8.6
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 +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { DrizzleDb } from "../db-connection.js";
|
|
2
|
+
import { getSqliteFrom } from "../db-connection.js";
|
|
3
|
+
import { withCrashRecovery } from "./validate-migration-state.js";
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_KEY = "migration_memory_v3_auto_edges_v1";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create the memory_v3_auto_edges table — the **learned** edge graph, a
|
|
9
|
+
* distinct class from the curated `edges:` frontmatter graph.
|
|
10
|
+
*
|
|
11
|
+
* Each row is a weighted directed association `source_slug → target_slug` that
|
|
12
|
+
* the edge-learning job (`memory_v3_edge_learning`) accrues from *used*
|
|
13
|
+
* co-activations (migration 262's `memory_v3_coactivation` rows) and decays
|
|
14
|
+
* over time. `weight` is a multiplicatively-decaying real; `last_reinforced_at`
|
|
15
|
+
* is the wall-clock ms of the most recent reinforcement, used by the decay
|
|
16
|
+
* pass to compute elapsed time per pair.
|
|
17
|
+
*
|
|
18
|
+
* Auto-edges are advisory: the read path consumes only above-threshold pairs
|
|
19
|
+
* via edge-expansion's `extraAdjacency` seam, and high-weight pairs surface as
|
|
20
|
+
* promotion *candidates* for the assistant to ratify into curated `edges:`
|
|
21
|
+
* during consolidation. This table never auto-writes page frontmatter.
|
|
22
|
+
*
|
|
23
|
+
* `PRIMARY KEY(source_slug, target_slug)` makes each ordered pair unique, so
|
|
24
|
+
* reinforce is a single UPSERT. The index on `(weight)` keeps the
|
|
25
|
+
* above-threshold scan and top-N promotion-candidate read cheap as the learned
|
|
26
|
+
* graph grows.
|
|
27
|
+
*/
|
|
28
|
+
export function migrateMemoryV3AutoEdges(database: DrizzleDb): void {
|
|
29
|
+
withCrashRecovery(database, CHECKPOINT_KEY, () => {
|
|
30
|
+
const raw = getSqliteFrom(database);
|
|
31
|
+
raw.exec(/*sql*/ `
|
|
32
|
+
CREATE TABLE IF NOT EXISTS memory_v3_auto_edges (
|
|
33
|
+
source_slug TEXT NOT NULL,
|
|
34
|
+
target_slug TEXT NOT NULL,
|
|
35
|
+
weight REAL NOT NULL,
|
|
36
|
+
last_reinforced_at INTEGER NOT NULL,
|
|
37
|
+
PRIMARY KEY (source_slug, target_slug)
|
|
38
|
+
)
|
|
39
|
+
`);
|
|
40
|
+
raw.exec(/*sql*/ `
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_memory_v3_auto_edges_weight
|
|
42
|
+
ON memory_v3_auto_edges (weight)
|
|
43
|
+
`);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function downMemoryV3AutoEdges(database: DrizzleDb): void {
|
|
48
|
+
const raw = getSqliteFrom(database);
|
|
49
|
+
raw.exec(/*sql*/ `DROP TABLE IF EXISTS memory_v3_auto_edges`);
|
|
50
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds `call_site` (nullable TEXT) to the `llm_request_logs` table.
|
|
5
|
+
*
|
|
6
|
+
* Records the logical call site that produced the row — `mainAgent`,
|
|
7
|
+
* `compactionAgent`, etc. (string values from `LLMCallSite` in
|
|
8
|
+
* `config/schemas/llm.ts`). Lets the LLM Context Inspector and other
|
|
9
|
+
* observability tools filter "show me only compaction calls" without
|
|
10
|
+
* having to infer from request payload shape.
|
|
11
|
+
*
|
|
12
|
+
* No backfill — historical rows stay NULL ("we don't know"). New rows
|
|
13
|
+
* stamped at insertion time by callers of `recordRequestLog`.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent — re-running is a no-op once the column exists. Modeled on
|
|
16
|
+
* migration 252 (`llm-request-log-agent-loop-exit-reason`).
|
|
17
|
+
*/
|
|
18
|
+
export function migrateLlmRequestLogCallSite(database: DrizzleDb): void {
|
|
19
|
+
const raw = getSqliteFrom(database);
|
|
20
|
+
|
|
21
|
+
const columns = raw
|
|
22
|
+
.query(`PRAGMA table_info(llm_request_logs)`)
|
|
23
|
+
.all() as Array<{ name: string }>;
|
|
24
|
+
const columnNames = new Set(columns.map((c) => c.name));
|
|
25
|
+
|
|
26
|
+
if (!columnNames.has("call_site")) {
|
|
27
|
+
raw.exec(`ALTER TABLE llm_request_logs ADD COLUMN call_site TEXT`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Drops the `status` column from the `provider_connections` table.
|
|
5
|
+
*
|
|
6
|
+
* Connection status ("active" | "disabled") has been removed — connections
|
|
7
|
+
* either exist or they don't. Profile status (enabled/disabled) is a separate
|
|
8
|
+
* concept and is untouched by this migration.
|
|
9
|
+
*
|
|
10
|
+
* Idempotent: checks PRAGMA table_info before issuing the DROP so re-running
|
|
11
|
+
* on a database that already lacks the column is a no-op.
|
|
12
|
+
*
|
|
13
|
+
* SQLite 3.35.0+ (Bun bundles a recent SQLite) supports ALTER TABLE DROP COLUMN.
|
|
14
|
+
*/
|
|
15
|
+
export function migrateDropProviderConnectionStatus(database: DrizzleDb): void {
|
|
16
|
+
const raw = getSqliteFrom(database);
|
|
17
|
+
|
|
18
|
+
const columns = raw
|
|
19
|
+
.query(`PRAGMA table_info(provider_connections)`)
|
|
20
|
+
.all() as Array<{ name: string }>;
|
|
21
|
+
const columnNames = new Set(columns.map((c) => c.name));
|
|
22
|
+
|
|
23
|
+
if (columnNames.has("status")) {
|
|
24
|
+
raw.exec(`ALTER TABLE provider_connections DROP COLUMN status`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type DrizzleDb, getSqliteFrom } from "../db-connection.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds `client_message_id` (nullable TEXT) to the `messages` table and
|
|
5
|
+
* creates a partial unique index on `(conversation_id, client_message_id)`
|
|
6
|
+
* for rows where `client_message_id IS NOT NULL`.
|
|
7
|
+
*
|
|
8
|
+
* The client-generated correlation nonce was previously wire-protocol-only
|
|
9
|
+
* (echoed on SSE `user_message_echo` events for optimistic-row dedup) but
|
|
10
|
+
* never persisted. Storing it enables server-side idempotency: a duplicate
|
|
11
|
+
* INSERT with the same `(conversation_id, client_message_id)` pair is
|
|
12
|
+
* silently skipped via `ON CONFLICT DO NOTHING`.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent — re-running is a no-op once the column and index exist.
|
|
15
|
+
*/
|
|
16
|
+
export function migrateMessagesClientMessageId(database: DrizzleDb): void {
|
|
17
|
+
const raw = getSqliteFrom(database);
|
|
18
|
+
|
|
19
|
+
const columns = raw.query(`PRAGMA table_info(messages)`).all() as Array<{
|
|
20
|
+
name: string;
|
|
21
|
+
}>;
|
|
22
|
+
const columnNames = new Set(columns.map((c) => c.name));
|
|
23
|
+
|
|
24
|
+
if (!columnNames.has("client_message_id")) {
|
|
25
|
+
raw.exec(`ALTER TABLE messages ADD COLUMN client_message_id TEXT`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Partial unique index: only enforced when client_message_id is non-NULL.
|
|
29
|
+
// Messages without a client_message_id (assistant messages, system-generated
|
|
30
|
+
// messages, legacy rows) are unconstrained.
|
|
31
|
+
const indexes = raw.query(`PRAGMA index_list(messages)`).all() as Array<{
|
|
32
|
+
name: string;
|
|
33
|
+
}>;
|
|
34
|
+
const indexNames = new Set(indexes.map((i) => i.name));
|
|
35
|
+
|
|
36
|
+
if (!indexNames.has("idx_messages_conv_client_msg_id")) {
|
|
37
|
+
raw.exec(
|
|
38
|
+
`CREATE UNIQUE INDEX idx_messages_conv_client_msg_id
|
|
39
|
+
ON messages (conversation_id, client_message_id)
|
|
40
|
+
WHERE client_message_id IS NOT NULL`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -234,6 +234,25 @@ export {
|
|
|
234
234
|
downConversationCleanedAt,
|
|
235
235
|
migrateConversationCleanedAt,
|
|
236
236
|
} from "./259-conversation-cleaned-at.js";
|
|
237
|
+
export {
|
|
238
|
+
downRenameCleanedAt,
|
|
239
|
+
migrateRenameCleanedAt,
|
|
240
|
+
} from "./260-rename-cleaned-at.js";
|
|
241
|
+
export {
|
|
242
|
+
downLlmUsageAddRawUsage,
|
|
243
|
+
migrateLlmUsageAddRawUsage,
|
|
244
|
+
} from "./261-llm-usage-add-raw-usage.js";
|
|
245
|
+
export {
|
|
246
|
+
downMemoryV3Coactivation,
|
|
247
|
+
migrateMemoryV3Coactivation,
|
|
248
|
+
} from "./262-memory-v3-coactivation.js";
|
|
249
|
+
export {
|
|
250
|
+
downMemoryV3AutoEdges,
|
|
251
|
+
migrateMemoryV3AutoEdges,
|
|
252
|
+
} from "./263-memory-v3-auto-edges.js";
|
|
253
|
+
export { migrateLlmRequestLogCallSite } from "./264-llm-request-log-call-site.js";
|
|
254
|
+
export { migrateDropProviderConnectionStatus } from "./265-drop-provider-connection-status.js";
|
|
255
|
+
export { migrateMessagesClientMessageId } from "./266-messages-client-message-id.js";
|
|
237
256
|
export {
|
|
238
257
|
MIGRATION_REGISTRY,
|
|
239
258
|
type MigrationRegistryEntry,
|
|
@@ -53,6 +53,10 @@ import { downA2ATasks } from "./251-a2a-tasks.js";
|
|
|
53
53
|
import { downExternalConversationBindingChatName } from "./254-external-conversation-binding-chat-name.js";
|
|
54
54
|
import { downMemoryV2InjectionEvents } from "./256-memory-v2-injection-events.js";
|
|
55
55
|
import { downConversationCleanedAt } from "./259-conversation-cleaned-at.js";
|
|
56
|
+
import { downRenameCleanedAt } from "./260-rename-cleaned-at.js";
|
|
57
|
+
import { downLlmUsageAddRawUsage } from "./261-llm-usage-add-raw-usage.js";
|
|
58
|
+
import { downMemoryV3Coactivation } from "./262-memory-v3-coactivation.js";
|
|
59
|
+
import { downMemoryV3AutoEdges } from "./263-memory-v3-auto-edges.js";
|
|
56
60
|
|
|
57
61
|
export interface MigrationRegistryEntry {
|
|
58
62
|
/** The checkpoint key written to memory_checkpoints on completion. */
|
|
@@ -453,6 +457,35 @@ export const MIGRATION_REGISTRY: MigrationRegistryEntry[] = [
|
|
|
453
457
|
"Add cleaned_at timestamp to conversations so /clean survives reload and forks inherit conditionally on fork point",
|
|
454
458
|
down: downConversationCleanedAt,
|
|
455
459
|
},
|
|
460
|
+
{
|
|
461
|
+
key: "migration_rename_cleaned_at_v1",
|
|
462
|
+
version: 53,
|
|
463
|
+
dependsOn: ["migration_conversation_cleaned_at_v1"],
|
|
464
|
+
description:
|
|
465
|
+
"Rename conversations.cleaned_at to history_stripped_at; the marker now records any injection-strip event (including compaction), not just /clean",
|
|
466
|
+
down: downRenameCleanedAt,
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
key: "migration_llm_usage_add_raw_usage_v1",
|
|
470
|
+
version: 54,
|
|
471
|
+
description:
|
|
472
|
+
"Add raw_usage TEXT column to llm_usage_events for storing the provider's untouched usage block as JSON (Anthropic TTL breakdown, OpenAI prompt/completion token details, etc.) so downstream consumers can extract provider-specific detail without per-field schema changes",
|
|
473
|
+
down: downLlmUsageAddRawUsage,
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
key: "migration_memory_v3_coactivation_v1",
|
|
477
|
+
version: 55,
|
|
478
|
+
description:
|
|
479
|
+
"Create memory_v3_coactivation table — append-only log of pass-1 → pass-N co-activation pairs (gradient signal) emitted by the v3 retrieval loop and reconciled later by edge-learning",
|
|
480
|
+
down: downMemoryV3Coactivation,
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
key: "migration_memory_v3_auto_edges_v1",
|
|
484
|
+
version: 56,
|
|
485
|
+
description:
|
|
486
|
+
"Create memory_v3_auto_edges table — weighted, decaying learned association graph (distinct from curated edges:) accrued by the edge-learning job from used co-activations and consumed above-threshold by edge expansion",
|
|
487
|
+
down: downMemoryV3AutoEdges,
|
|
488
|
+
},
|
|
456
489
|
];
|
|
457
490
|
|
|
458
491
|
export function getMaxMigrationVersion(): number {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
1
2
|
import {
|
|
2
3
|
index,
|
|
3
4
|
integer,
|
|
4
5
|
real,
|
|
5
6
|
sqliteTable,
|
|
6
7
|
text,
|
|
8
|
+
uniqueIndex,
|
|
7
9
|
} from "drizzle-orm/sqlite-core";
|
|
8
10
|
|
|
9
11
|
export const conversations = sqliteTable(
|
|
@@ -21,7 +23,7 @@ export const conversations = sqliteTable(
|
|
|
21
23
|
.notNull()
|
|
22
24
|
.default(0),
|
|
23
25
|
contextCompactedAt: integer("context_compacted_at"),
|
|
24
|
-
|
|
26
|
+
historyStrippedAt: integer("history_stripped_at"),
|
|
25
27
|
slackContextCompactionWatermarkTs: text(
|
|
26
28
|
"slack_context_compaction_watermark_ts",
|
|
27
29
|
),
|
|
@@ -66,8 +68,14 @@ export const messages = sqliteTable(
|
|
|
66
68
|
content: text("content").notNull(),
|
|
67
69
|
createdAt: integer("created_at").notNull(),
|
|
68
70
|
metadata: text("metadata"),
|
|
71
|
+
clientMessageId: text("client_message_id"),
|
|
69
72
|
},
|
|
70
|
-
(table) => [
|
|
73
|
+
(table) => [
|
|
74
|
+
index("idx_messages_conversation_id").on(table.conversationId),
|
|
75
|
+
uniqueIndex("idx_messages_conv_client_msg_id")
|
|
76
|
+
.on(table.conversationId, table.clientMessageId)
|
|
77
|
+
.where(sql`client_message_id IS NOT NULL`),
|
|
78
|
+
],
|
|
71
79
|
);
|
|
72
80
|
|
|
73
81
|
export const toolInvocations = sqliteTable(
|
|
@@ -15,7 +15,6 @@ export const providerConnections = sqliteTable(
|
|
|
15
15
|
name: text("name").primaryKey(),
|
|
16
16
|
provider: text("provider").notNull(),
|
|
17
17
|
auth: text("auth").notNull(),
|
|
18
|
-
status: text("status").notNull().default("active"),
|
|
19
18
|
label: text("label"),
|
|
20
19
|
baseUrl: text("base_url"),
|
|
21
20
|
models: text("models"),
|
|
@@ -138,6 +138,16 @@ export const llmRequestLogs = sqliteTable(
|
|
|
138
138
|
responsePayload: text("response_payload").notNull(),
|
|
139
139
|
createdAt: integer("created_at").notNull(),
|
|
140
140
|
agentLoopExitReason: text("agent_loop_exit_reason"),
|
|
141
|
+
/**
|
|
142
|
+
* Logical call site that produced this row — e.g. `mainAgent`,
|
|
143
|
+
* `compactionAgent`. Stored as free-form text rather than enum-bound
|
|
144
|
+
* so a new call site can ship without a schema bump, but in practice
|
|
145
|
+
* callers pass values from `LLMCallSite` (`config/schemas/llm.ts`).
|
|
146
|
+
*
|
|
147
|
+
* Historical rows (pre-migration 264) stay NULL — "we don't know"
|
|
148
|
+
* rather than guessing `mainAgent`.
|
|
149
|
+
*/
|
|
150
|
+
callSite: text("call_site"),
|
|
141
151
|
},
|
|
142
152
|
(table) => [
|
|
143
153
|
index("idx_llm_request_logs_message_id").on(table.messageId),
|
|
@@ -217,6 +227,17 @@ export const llmUsageEvents = sqliteTable(
|
|
|
217
227
|
outputTokens: integer("output_tokens").notNull(),
|
|
218
228
|
cacheCreationInputTokens: integer("cache_creation_input_tokens"),
|
|
219
229
|
cacheReadInputTokens: integer("cache_read_input_tokens"),
|
|
230
|
+
/**
|
|
231
|
+
* The provider's untouched `usage` block, serialized as JSON. Anthropic
|
|
232
|
+
* nests the TTL breakdown under `cache_creation.ephemeral_{5m,1h}_input_tokens`;
|
|
233
|
+
* OpenAI nests cached-read details under `prompt_tokens_details`; both are
|
|
234
|
+
* just preserved verbatim so admin charts and downstream consumers can
|
|
235
|
+
* extract whatever provider-specific detail they need without a schema
|
|
236
|
+
* change every time a provider exposes a new field. `null` when the
|
|
237
|
+
* provider didn't return a usage block or for rows persisted before
|
|
238
|
+
* migration 260.
|
|
239
|
+
*/
|
|
240
|
+
rawUsage: text("raw_usage"),
|
|
220
241
|
estimatedCostUsd: real("estimated_cost_usd"),
|
|
221
242
|
pricingStatus: text("pricing_status").notNull(),
|
|
222
243
|
llmCallCount: integer("llm_call_count"),
|
|
@@ -2,6 +2,7 @@ import { count, desc, lt } from "drizzle-orm";
|
|
|
2
2
|
import { v4 as uuid } from "uuid";
|
|
3
3
|
|
|
4
4
|
import { getLogger } from "../util/logger.js";
|
|
5
|
+
import { runAsyncSqlite } from "./db-async-query.js";
|
|
5
6
|
import { getDb } from "./db-connection.js";
|
|
6
7
|
import { toolInvocations } from "./schema.js";
|
|
7
8
|
|
|
@@ -47,25 +48,52 @@ export function getRecentInvocations(limit: number) {
|
|
|
47
48
|
const log = getLogger("audit-log");
|
|
48
49
|
|
|
49
50
|
/**
|
|
50
|
-
* Delete tool invocation records older than the specified number of
|
|
51
|
-
* Returns the number of deleted records. Does nothing if
|
|
51
|
+
* Delete tool invocation records older than the specified number of
|
|
52
|
+
* days. Returns the number of deleted records. Does nothing if
|
|
53
|
+
* `retentionDays` is zero, negative, or non-finite.
|
|
54
|
+
*
|
|
55
|
+
* The DELETE runs through {@link runAsyncSqlite}: when the host has a
|
|
56
|
+
* `sqlite3` CLI it executes in a subprocess and the daemon's main
|
|
57
|
+
* event loop stays responsive. On hosts without the CLI the
|
|
58
|
+
* abstraction falls back to in-process blocking execution — the same
|
|
59
|
+
* behaviour the daemon had before this abstraction existed.
|
|
52
60
|
*/
|
|
53
|
-
export function rotateToolInvocations(
|
|
54
|
-
|
|
61
|
+
export async function rotateToolInvocations(
|
|
62
|
+
retentionDays: number,
|
|
63
|
+
): Promise<number> {
|
|
64
|
+
if (!Number.isFinite(retentionDays) || retentionDays <= 0) return 0;
|
|
55
65
|
|
|
56
|
-
|
|
66
|
+
// Math.floor guarantees a plain integer literal in the inlined SQL
|
|
67
|
+
// below; no decimal, no exponent, no surprise characters.
|
|
68
|
+
const cutoffMs = Math.floor(
|
|
69
|
+
Date.now() - retentionDays * 24 * 60 * 60 * 1000,
|
|
70
|
+
);
|
|
57
71
|
const db = getDb();
|
|
58
72
|
|
|
59
|
-
// Count before delete
|
|
73
|
+
// Count before delete so we can return + log the affected row count
|
|
74
|
+
// (`runAsyncSqlite` does not surface SQLite's `changes()` value).
|
|
60
75
|
const [countRow] = db
|
|
61
76
|
.select({ value: count() })
|
|
62
77
|
.from(toolInvocations)
|
|
63
|
-
.where(lt(toolInvocations.createdAt,
|
|
78
|
+
.where(lt(toolInvocations.createdAt, cutoffMs))
|
|
64
79
|
.all();
|
|
65
80
|
const toDelete = countRow?.value ?? 0;
|
|
66
81
|
if (toDelete === 0) return 0;
|
|
67
82
|
|
|
68
|
-
|
|
83
|
+
// `runAsyncSqlite` takes a raw SQL string — sqlite3 CLI subprocesses
|
|
84
|
+
// see SQL on stdin without a binding layer. `cutoffMs` is a plain
|
|
85
|
+
// integer (see Math.floor above), so inlining it here is safe.
|
|
86
|
+
const result = await runAsyncSqlite(
|
|
87
|
+
`DELETE FROM tool_invocations WHERE created_at < ${cutoffMs}`,
|
|
88
|
+
);
|
|
89
|
+
if (!result.ok) {
|
|
90
|
+
log.error(
|
|
91
|
+
{ error: result.error, backend: result.backend, toDelete },
|
|
92
|
+
"tool_invocations purge failed",
|
|
93
|
+
);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
69
97
|
log.info(
|
|
70
98
|
`Rotated ${toDelete} audit log entries older than ${retentionDays} day(s)`,
|
|
71
99
|
);
|
|
@@ -202,7 +202,10 @@ afterAll(() => {
|
|
|
202
202
|
rmSync(tmpWorkspace, { recursive: true, force: true });
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
-
const { getDb
|
|
205
|
+
const { getDb } = await import("../../db-connection.js");
|
|
206
|
+
const { resetDbForTesting } = await import(
|
|
207
|
+
"../../../__tests__/db-test-helpers.js"
|
|
208
|
+
);
|
|
206
209
|
const { initializeDb } = await import("../../db-init.js");
|
|
207
210
|
const { rawExec } = await import("../../raw-query.js");
|
|
208
211
|
const { conversations, memoryJobs, messages } = await import("../../schema.js");
|
|
@@ -247,7 +250,7 @@ function makeJob(
|
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
beforeEach(() => {
|
|
250
|
-
|
|
253
|
+
resetDbForTesting();
|
|
251
254
|
initializeDb();
|
|
252
255
|
// The shared template-DB caching does not clear WAL state between tests,
|
|
253
256
|
// so explicitly truncate every table this suite writes to. Without this,
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
mock.module("../../../util/logger.js", () => ({
|
|
4
|
+
getLogger: () =>
|
|
5
|
+
new Proxy({} as Record<string, unknown>, { get: () => () => {} }),
|
|
6
|
+
}));
|
|
7
|
+
|
|
8
|
+
mock.module("../../../config/loader.js", () => ({
|
|
9
|
+
getConfig: () => ({ memory: { enabled: false } }),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
import type { AssistantConfig } from "../../../config/types.js";
|
|
13
|
+
import { getDb } from "../../db-connection.js";
|
|
14
|
+
import { initializeDb } from "../../db-init.js";
|
|
15
|
+
import type { MemoryV2ConceptRowRecord } from "../../memory-v2-activation-log-store.js";
|
|
16
|
+
import {
|
|
17
|
+
conversations,
|
|
18
|
+
memoryV2ActivationLogs,
|
|
19
|
+
messages,
|
|
20
|
+
} from "../../schema.js";
|
|
21
|
+
import { runComparisonOverHistory } from "../harness/compare.js";
|
|
22
|
+
import type { RetrievalOutput, Retriever } from "../harness/retriever.js";
|
|
23
|
+
|
|
24
|
+
initializeDb();
|
|
25
|
+
|
|
26
|
+
// loadNowText reads workspace files; a nonexistent dir yields "".
|
|
27
|
+
const WORKSPACE = "/tmp/harness-compare-nonexistent-workspace";
|
|
28
|
+
|
|
29
|
+
const ZERO_CONFIG = {
|
|
30
|
+
d: 0,
|
|
31
|
+
c_user: 0,
|
|
32
|
+
c_assistant: 0,
|
|
33
|
+
c_now: 0,
|
|
34
|
+
k: 0,
|
|
35
|
+
hops: 0,
|
|
36
|
+
top_k: 0,
|
|
37
|
+
epsilon: 0,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
let seq = 0;
|
|
41
|
+
|
|
42
|
+
function config(historicalPairs: number): AssistantConfig {
|
|
43
|
+
return {
|
|
44
|
+
memory: { v2: { router: { historical_pairs: historicalPairs } } },
|
|
45
|
+
} as unknown as AssistantConfig;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function ensureConversation(id: string): void {
|
|
49
|
+
getDb()
|
|
50
|
+
.insert(conversations)
|
|
51
|
+
.values({ id, createdAt: 0, updatedAt: 0 })
|
|
52
|
+
.onConflictDoNothing()
|
|
53
|
+
.run();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function insertMessage(
|
|
57
|
+
id: string,
|
|
58
|
+
conversationId: string,
|
|
59
|
+
role: string,
|
|
60
|
+
text: string,
|
|
61
|
+
createdAt: number,
|
|
62
|
+
): void {
|
|
63
|
+
ensureConversation(conversationId);
|
|
64
|
+
getDb()
|
|
65
|
+
.insert(messages)
|
|
66
|
+
.values({
|
|
67
|
+
id,
|
|
68
|
+
conversationId,
|
|
69
|
+
role,
|
|
70
|
+
content: JSON.stringify([{ type: "text", text }]),
|
|
71
|
+
createdAt,
|
|
72
|
+
})
|
|
73
|
+
.run();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function makeConcept(
|
|
77
|
+
slug: string,
|
|
78
|
+
status: MemoryV2ConceptRowRecord["status"],
|
|
79
|
+
): MemoryV2ConceptRowRecord {
|
|
80
|
+
return {
|
|
81
|
+
slug,
|
|
82
|
+
finalActivation: 0,
|
|
83
|
+
ownActivation: 0,
|
|
84
|
+
priorActivation: 0,
|
|
85
|
+
simUser: 0,
|
|
86
|
+
simAssistant: 0,
|
|
87
|
+
simNow: 0,
|
|
88
|
+
simUserRerankBoost: 0,
|
|
89
|
+
simAssistantRerankBoost: 0,
|
|
90
|
+
inRerankPool: false,
|
|
91
|
+
spreadContribution: 0,
|
|
92
|
+
source: "router",
|
|
93
|
+
status,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function insertRouterLog(
|
|
98
|
+
conversationId: string,
|
|
99
|
+
messageId: string,
|
|
100
|
+
turn: number,
|
|
101
|
+
concepts: MemoryV2ConceptRowRecord[],
|
|
102
|
+
createdAt: number,
|
|
103
|
+
): void {
|
|
104
|
+
ensureConversation(conversationId);
|
|
105
|
+
getDb()
|
|
106
|
+
.insert(memoryV2ActivationLogs)
|
|
107
|
+
.values({
|
|
108
|
+
id: `log-${seq++}`,
|
|
109
|
+
conversationId,
|
|
110
|
+
messageId,
|
|
111
|
+
turn,
|
|
112
|
+
mode: "router",
|
|
113
|
+
conceptsJson: JSON.stringify(concepts),
|
|
114
|
+
skillsJson: "[]",
|
|
115
|
+
configJson: JSON.stringify(ZERO_CONFIG),
|
|
116
|
+
createdAt,
|
|
117
|
+
})
|
|
118
|
+
.run();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function stubRetriever(name: string, selected: string[]): Retriever {
|
|
122
|
+
return {
|
|
123
|
+
name,
|
|
124
|
+
retrieve: async (): Promise<RetrievalOutput> => ({
|
|
125
|
+
selectedSlugs: selected,
|
|
126
|
+
sourceBySlug: new Map(selected.map((s): [string, string] => [s, name])),
|
|
127
|
+
}),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function reset(): void {
|
|
132
|
+
const db = getDb();
|
|
133
|
+
db.delete(memoryV2ActivationLogs).run();
|
|
134
|
+
db.delete(messages).run();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Seed one router turn: user msg, assistant anchor, and the logged picks. */
|
|
138
|
+
function seedTurn(groundTruth: string[]): void {
|
|
139
|
+
insertMessage("u1", "c1", "user", "hello", 10);
|
|
140
|
+
insertMessage("a1", "c1", "assistant", "hi", 20); // anchor for turn 1
|
|
141
|
+
insertRouterLog(
|
|
142
|
+
"c1",
|
|
143
|
+
"a1",
|
|
144
|
+
1,
|
|
145
|
+
groundTruth.map((slug) => makeConcept(slug, "injected")),
|
|
146
|
+
20,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
describe("harness/compare runComparisonOverHistory", () => {
|
|
151
|
+
beforeEach(reset);
|
|
152
|
+
|
|
153
|
+
test("scores a stub retriever against the logged ground truth", async () => {
|
|
154
|
+
seedTurn(["p1", "p2"]);
|
|
155
|
+
|
|
156
|
+
const report = await runComparisonOverHistory({
|
|
157
|
+
db: getDb(),
|
|
158
|
+
workspaceDir: WORKSPACE,
|
|
159
|
+
config: config(1),
|
|
160
|
+
retrievers: [stubRetriever("stub", ["p1", "z"])],
|
|
161
|
+
ks: [5],
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
expect(report.turnsConsidered).toBe(1);
|
|
165
|
+
expect(report.turnsScored).toBe(1);
|
|
166
|
+
expect(report.turnsSkipped).toBe(0);
|
|
167
|
+
// hit p1, miss p2 → recall@5 = 1/2
|
|
168
|
+
expect(report.retrievers[0]?.aggregate.meanRecallAtK[5]).toBeCloseTo(0.5);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("pageExists narrows the ground truth set", async () => {
|
|
172
|
+
seedTurn(["p1", "p2"]);
|
|
173
|
+
|
|
174
|
+
const report = await runComparisonOverHistory({
|
|
175
|
+
db: getDb(),
|
|
176
|
+
workspaceDir: WORKSPACE,
|
|
177
|
+
config: config(1),
|
|
178
|
+
retrievers: [stubRetriever("stub", ["p1", "z"])],
|
|
179
|
+
ks: [5],
|
|
180
|
+
pageExists: (slug) => slug === "p1", // p2 no longer exists
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// ground truth is just {p1}; stub selected p1 → recall 1.0
|
|
184
|
+
expect(report.retrievers[0]?.aggregate.meanRecallAtK[5]).toBeCloseTo(1);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { aggregate, evalTurn, recallAtK } from "../harness/metrics.js";
|
|
4
|
+
import type { RetrievalOutput } from "../harness/retriever.js";
|
|
5
|
+
|
|
6
|
+
function out(
|
|
7
|
+
selected: string[],
|
|
8
|
+
sourceBySlug: Record<string, string> = {},
|
|
9
|
+
): RetrievalOutput {
|
|
10
|
+
return {
|
|
11
|
+
selectedSlugs: selected,
|
|
12
|
+
sourceBySlug: new Map(Object.entries(sourceBySlug)),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe("harness/metrics recallAtK", () => {
|
|
17
|
+
test("fraction of ground truth recovered within k", () => {
|
|
18
|
+
const gt = new Set(["a", "b", "c", "d"]);
|
|
19
|
+
expect(recallAtK(["a", "b", "x"], gt, 10)).toBeCloseTo(0.5);
|
|
20
|
+
// only the top-2 selections count toward recall@2
|
|
21
|
+
expect(recallAtK(["a", "b", "c", "d"], gt, 2)).toBeCloseTo(0.5);
|
|
22
|
+
expect(recallAtK(["a", "b", "c", "d"], gt, 10)).toBeCloseTo(1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("empty ground truth is vacuously complete (recall 1)", () => {
|
|
26
|
+
expect(recallAtK([], new Set<string>(), 5)).toBe(1);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("duplicate selections cannot push recall above 1.0", () => {
|
|
30
|
+
// A retriever emitting the same slug twice must not double-count it.
|
|
31
|
+
expect(recallAtK(["a", "a"], new Set(["a"]), 10)).toBe(1);
|
|
32
|
+
// Duplicates inside the top-k window still count once.
|
|
33
|
+
const gt = new Set(["a", "b"]);
|
|
34
|
+
expect(recallAtK(["a", "a", "b"], gt, 10)).toBeCloseTo(1);
|
|
35
|
+
expect(recallAtK(["a", "a", "b"], gt, 2)).toBeCloseTo(0.5);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe("harness/metrics evalTurn", () => {
|
|
40
|
+
test("hits / misses / extras and per-lane attribution", () => {
|
|
41
|
+
const e = evalTurn(
|
|
42
|
+
out(["a", "b", "z"], { a: "tree", b: "sparse", z: "dense" }),
|
|
43
|
+
["a", "b", "c"],
|
|
44
|
+
[5],
|
|
45
|
+
);
|
|
46
|
+
expect(e.hits.sort()).toEqual(["a", "b"]);
|
|
47
|
+
expect(e.misses).toEqual(["c"]);
|
|
48
|
+
// selected but not in ground truth — reported as diff, not error
|
|
49
|
+
expect(e.extras).toEqual(["z"]);
|
|
50
|
+
expect(e.recallAtK[5]).toBeCloseTo(2 / 3);
|
|
51
|
+
expect(e.hitsByLane).toEqual({ tree: 1, sparse: 1 });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("failureReason surfaces and recall is 0", () => {
|
|
55
|
+
const o: RetrievalOutput = {
|
|
56
|
+
selectedSlugs: [],
|
|
57
|
+
sourceBySlug: new Map(),
|
|
58
|
+
failureReason: "no_provider",
|
|
59
|
+
};
|
|
60
|
+
const e = evalTurn(o, ["a"], [5]);
|
|
61
|
+
expect(e.failureReason).toBe("no_provider");
|
|
62
|
+
expect(e.recallAtK[5]).toBe(0);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("harness/metrics aggregate", () => {
|
|
67
|
+
test("means recall@k and failure rate across turns", () => {
|
|
68
|
+
const ks = [5];
|
|
69
|
+
const t1 = evalTurn(out(["a"]), ["a"], ks); // recall 1
|
|
70
|
+
const t2 = evalTurn(out([]), ["a"], ks); // recall 0
|
|
71
|
+
const agg = aggregate([t1, t2], ks);
|
|
72
|
+
expect(agg.turns).toBe(2);
|
|
73
|
+
expect(agg.meanRecallAtK[5]).toBeCloseTo(0.5);
|
|
74
|
+
expect(agg.failureRate).toBe(0);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("empty input is well-defined", () => {
|
|
78
|
+
const agg = aggregate([], [5]);
|
|
79
|
+
expect(agg.turns).toBe(0);
|
|
80
|
+
expect(agg.meanRecallAtK[5]).toBe(0);
|
|
81
|
+
expect(agg.failureRate).toBe(0);
|
|
82
|
+
});
|
|
83
|
+
});
|