@vellumai/assistant 0.8.5 → 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 +1 -1
- package/bunfig.toml +6 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- 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 +1900 -166
- 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__/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-feature-flags-integration.test.ts +9 -25
- package/src/__tests__/audit-log-rotation.test.ts +2 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +3 -2
- package/src/__tests__/call-controller.test.ts +3 -2
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +3 -2
- 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 +12 -12
- package/src/__tests__/compaction-events.test.ts +1 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
- package/src/__tests__/computer-use-tools.test.ts +12 -14
- 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__/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 +1 -0
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +34 -0
- package/src/__tests__/conversation-agent-loop.test.ts +488 -2
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
- 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-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-error.test.ts +30 -0
- package/src/__tests__/conversation-fork-crud.test.ts +69 -8
- 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 +1 -0
- 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-history-stripped.test.ts +1 -0
- 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 +5 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +33 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +38 -142
- 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-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 +128 -12
- 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 +1 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -0
- 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 +10 -12
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -5
- package/src/__tests__/credential-vault-unit.test.ts +19 -19
- 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-skill-workflow-prompt.test.ts +5 -4
- 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 +0 -1
- package/src/__tests__/gemini-provider.test.ts +26 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-outbound-http.test.ts +3 -2
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -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 +5 -4
- 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__/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__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-resolver.test.ts +331 -0
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +14 -0
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- 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 +3 -3
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- 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 +3 -2
- package/src/__tests__/openai-provider.test.ts +8 -9
- package/src/__tests__/openai-responses-provider.test.ts +70 -10
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/plugin-bootstrap.test.ts +9 -11
- package/src/__tests__/plugin-tool-contribution.test.ts +41 -38
- 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__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +82 -76
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- 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__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +14 -16
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
- package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
- package/src/__tests__/skill-tool-factory.test.ts +96 -95
- 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 +5 -4
- 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 +1 -0
- package/src/__tests__/system-prompt.test.ts +38 -0
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
- package/src/__tests__/tool-executor.test.ts +55 -10
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
- 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-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/session-manager.ts +5 -6
- package/src/agent/loop.ts +80 -0
- package/src/api/README.md +124 -2
- 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/{events → api/events}/relationship-state-updated.ts +3 -3
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +128 -3
- 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 +687 -52
- 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 +2 -2
- 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__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/memory-v3-render.ts +147 -0
- package/src/cli/commands/memory-v3.ts +255 -4
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +2 -0
- package/src/config/assistant-feature-flags.ts +23 -42
- package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
- 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/call-site-defaults.ts +1 -1
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +17 -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 +15 -0
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +90 -1
- package/src/config/schemas/memory-v2.ts +26 -0
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/token-estimator.ts +10 -5
- 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 +1 -2
- 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 +389 -68
- package/src/daemon/conversation-agent-loop.ts +132 -28
- package/src/daemon/conversation-error.ts +33 -5
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +29 -9
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +33 -48
- package/src/daemon/conversation.ts +26 -46
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +27 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/lifecycle.ts +12 -12
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +10 -17
- package/src/daemon/message-types/conversations.ts +20 -22
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -2
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +23 -38
- package/src/daemon/message-types/subagents.ts +6 -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/switch-inference-profile-tool.ts +13 -3
- package/src/daemon/tool-setup-types.ts +0 -6
- 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 +29 -0
- 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/suggested-prompts.ts +27 -145
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- 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 +28 -29
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
- 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 +1 -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/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +352 -112
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +4 -0
- 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/retriever.test.ts +3 -3
- 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-worker.ts +12 -1
- package/src/memory/llm-request-log-source-clickhouse.ts +80 -0
- package/src/memory/llm-request-log-source-local.ts +24 -0
- package/src/memory/llm-request-log-source.ts +31 -0
- package/src/memory/llm-request-log-store.ts +188 -3
- package/src/memory/memory-v2-activation-log-store.ts +95 -1
- 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 +2 -0
- package/src/memory/schema/conversations.ts +9 -1
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
- package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/metrics.ts +5 -1
- package/src/memory/v2/harness/replay-input.ts +19 -3
- package/src/memory/v2/harness/runner.ts +6 -0
- package/src/memory/v2/harness/trace.ts +6 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +2 -4
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edges.test.ts +144 -1
- package/src/memory/v3/__tests__/filter.test.ts +48 -0
- package/src/memory/v3/__tests__/gate.test.ts +96 -33
- package/src/memory/v3/__tests__/index-composition.test.ts +58 -0
- package/src/memory/v3/__tests__/loop.test.ts +250 -5
- package/src/memory/v3/__tests__/scouts.test.ts +49 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +88 -2
- package/src/memory/v3/__tests__/traversal.test.ts +39 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +77 -0
- package/src/memory/v3/__tests__/validate.test.ts +32 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edges.ts +58 -21
- package/src/memory/v3/filter.ts +27 -22
- package/src/memory/v3/gate.ts +51 -36
- package/src/memory/v3/index-composition.ts +18 -5
- package/src/memory/v3/loop.ts +65 -17
- package/src/memory/v3/scouts.ts +15 -4
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +44 -2
- package/src/memory/v3/traversal.ts +6 -1
- package/src/memory/v3/tree-walk.ts +6 -1
- package/src/memory/v3/validate.ts +56 -33
- 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/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- 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 +11 -1
- 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/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugins/defaults/injectors.ts +2 -8
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/types.ts +57 -13
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/system-prompt.ts +38 -40
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +7 -11
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/call-site-routing.ts +33 -9
- package/src/providers/connection-model-compat.ts +23 -0
- package/src/providers/connection-resolution.ts +39 -20
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +24 -3
- 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/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/model-catalog.ts +35 -1
- package/src/providers/model-intents.ts +3 -3
- 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 +110 -12
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/openai/responses-provider.ts +53 -53
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +18 -9
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +16 -4
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/types.ts +9 -0
- 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/auth/route-policy.ts +10 -0
- 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/migrations/vbundle-builder.ts +3 -2
- 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 +98 -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 +51 -3
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -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/app-management-routes.ts +111 -4
- package/src/runtime/routes/background-wake-routes.ts +188 -20
- package/src/runtime/routes/btw-routes.ts +4 -4
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +147 -0
- package/src/runtime/routes/conversation-management-routes.ts +39 -14
- package/src/runtime/routes/conversation-query-routes.ts +60 -10
- package/src/runtime/routes/conversation-routes.ts +186 -140
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/group-routes.ts +11 -0
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- 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/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +2 -0
- 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-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-v3-routes.ts +160 -2
- package/src/runtime/routes/migration-routes.ts +20 -13
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- 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/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 +1 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- 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/tools/apps/definitions.ts +35 -21
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/computer-use/definitions.ts +268 -266
- package/src/tools/document/document-tool.ts +131 -8
- package/src/tools/execution-target.ts +2 -5
- package/src/tools/executor.ts +18 -55
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/mcp/mcp-tool-factory.ts +0 -2
- 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-search.ts +199 -44
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +146 -103
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/skills/skill-tool-factory.ts +17 -36
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +17 -15
- package/src/tools/ui-surface/definitions.ts +98 -86
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/util/browser.ts +7 -2
- 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 +4 -0
package/package.json
CHANGED
|
@@ -29,7 +29,7 @@ mock.module("../config/env.js", () => ({
|
|
|
29
29
|
checkUnrecognizedEnvVars: () => {},
|
|
30
30
|
}));
|
|
31
31
|
|
|
32
|
-
import { getDb
|
|
32
|
+
import { getDb } from "../memory/db-connection.js";
|
|
33
33
|
import { initializeDb } from "../memory/db-init.js";
|
|
34
34
|
import { resetExternalAssistantIdCache } from "../runtime/auth/external-assistant-id.js";
|
|
35
35
|
import { initAuthSigningKey } from "../runtime/auth/token-service.js";
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
resolveLocalAuthContext,
|
|
38
38
|
resolveLocalTrustContext,
|
|
39
39
|
} from "../runtime/local-actor-identity.js";
|
|
40
|
+
import { resetDbForTesting } from "./db-test-helpers.js";
|
|
40
41
|
|
|
41
42
|
// ---------------------------------------------------------------------------
|
|
42
43
|
// Test signing key
|
|
@@ -50,7 +51,7 @@ initializeDb();
|
|
|
50
51
|
beforeEach(() => {
|
|
51
52
|
initAuthSigningKey(TEST_KEY);
|
|
52
53
|
resetExternalAssistantIdCache();
|
|
53
|
-
|
|
54
|
+
resetDbForTesting();
|
|
54
55
|
initializeDb();
|
|
55
56
|
});
|
|
56
57
|
|
|
@@ -21,7 +21,7 @@ import type {
|
|
|
21
21
|
CheckpointDecision,
|
|
22
22
|
CheckpointInfo,
|
|
23
23
|
} from "../agent/loop.js";
|
|
24
|
-
import { AgentLoop } from "../agent/loop.js";
|
|
24
|
+
import { AgentLoop, isMaxTokensStopReason } from "../agent/loop.js";
|
|
25
25
|
import type {
|
|
26
26
|
Message,
|
|
27
27
|
Provider,
|
|
@@ -63,6 +63,18 @@ function textResponse(text: string): ProviderResponse {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
function maxTokensResponse(
|
|
67
|
+
text: string,
|
|
68
|
+
stopReason: string = "max_tokens",
|
|
69
|
+
): ProviderResponse {
|
|
70
|
+
return {
|
|
71
|
+
content: [{ type: "text", text }],
|
|
72
|
+
model: "mock-model",
|
|
73
|
+
usage: { inputTokens: 10, outputTokens: 5 },
|
|
74
|
+
stopReason,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
66
78
|
function toolUseResponse(
|
|
67
79
|
id: string,
|
|
68
80
|
name: string,
|
|
@@ -107,6 +119,15 @@ function countExitEvents(events: AgentEvent[]): number {
|
|
|
107
119
|
// ---------------------------------------------------------------------------
|
|
108
120
|
|
|
109
121
|
describe("AgentLoop exit-reason instrumentation", () => {
|
|
122
|
+
test("recognizes provider output-token stop reasons", () => {
|
|
123
|
+
expect(isMaxTokensStopReason("max_tokens")).toBe(true);
|
|
124
|
+
expect(isMaxTokensStopReason("MAX_TOKENS")).toBe(true);
|
|
125
|
+
expect(isMaxTokensStopReason("length")).toBe(true);
|
|
126
|
+
expect(isMaxTokensStopReason("max_output_tokens")).toBe(true);
|
|
127
|
+
expect(isMaxTokensStopReason("end_turn")).toBe(false);
|
|
128
|
+
expect(isMaxTokensStopReason(undefined)).toBe(false);
|
|
129
|
+
});
|
|
130
|
+
|
|
110
131
|
test("emits exit event exactly once with 'no_tool_calls' on plain text response", async () => {
|
|
111
132
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
112
133
|
const loop = new AgentLoop(provider, "system prompt");
|
|
@@ -134,6 +155,59 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
134
155
|
expect(events[events.length - 1].type).toBe("agent_loop_exit");
|
|
135
156
|
});
|
|
136
157
|
|
|
158
|
+
test("emits continuation surface event and exits on max_tokens", async () => {
|
|
159
|
+
const { provider } = createMockProvider([
|
|
160
|
+
maxTokensResponse("Partial answer"),
|
|
161
|
+
]);
|
|
162
|
+
const loop = new AgentLoop(provider, "system prompt");
|
|
163
|
+
|
|
164
|
+
const events: AgentEvent[] = [];
|
|
165
|
+
await loop.run([userMessage], (e) => {
|
|
166
|
+
events.push(e);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
expect(events.map((e) => e.type)).toEqual([
|
|
170
|
+
"llm_call_started",
|
|
171
|
+
"usage",
|
|
172
|
+
"max_tokens_reached",
|
|
173
|
+
"message_complete",
|
|
174
|
+
"agent_loop_exit",
|
|
175
|
+
]);
|
|
176
|
+
expect(countExitEvents(events)).toBe(1);
|
|
177
|
+
expect(lastExitEvent(events)?.reason).toBe("max_tokens_reached");
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test("does not persist unexecuted tool_use blocks when max_tokens stops output", async () => {
|
|
181
|
+
const { provider } = createMockProvider([
|
|
182
|
+
{
|
|
183
|
+
content: [
|
|
184
|
+
{ type: "text", text: "I need to check that." },
|
|
185
|
+
{
|
|
186
|
+
type: "tool_use",
|
|
187
|
+
id: "tool-1",
|
|
188
|
+
name: "read_file",
|
|
189
|
+
input: { path: "/tmp/example.txt" },
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
model: "mock-model",
|
|
193
|
+
usage: { inputTokens: 10, outputTokens: 5 },
|
|
194
|
+
stopReason: "max_tokens",
|
|
195
|
+
},
|
|
196
|
+
]);
|
|
197
|
+
const loop = new AgentLoop(provider, "system prompt", {}, dummyTools);
|
|
198
|
+
|
|
199
|
+
const events: AgentEvent[] = [];
|
|
200
|
+
const result = await loop.run([userMessage], (e) => {
|
|
201
|
+
events.push(e);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
expect(events.some((e) => e.type === "tool_use")).toBe(false);
|
|
205
|
+
expect(lastExitEvent(events)?.reason).toBe("max_tokens_reached");
|
|
206
|
+
expect(result[result.length - 1]!.content).toEqual([
|
|
207
|
+
{ type: "text", text: "I need to check that." },
|
|
208
|
+
]);
|
|
209
|
+
});
|
|
210
|
+
|
|
137
211
|
test("emits 'aborted_pre_call' when signal is already aborted at run start", async () => {
|
|
138
212
|
const { provider } = createMockProvider([textResponse("never sent")]);
|
|
139
213
|
const loop = new AgentLoop(provider, "system prompt");
|
|
@@ -142,7 +216,13 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
142
216
|
controller.abort();
|
|
143
217
|
|
|
144
218
|
const events: AgentEvent[] = [];
|
|
145
|
-
await loop.run(
|
|
219
|
+
await loop.run(
|
|
220
|
+
[userMessage],
|
|
221
|
+
(e) => {
|
|
222
|
+
events.push(e);
|
|
223
|
+
},
|
|
224
|
+
controller.signal,
|
|
225
|
+
);
|
|
146
226
|
|
|
147
227
|
expect(countExitEvents(events)).toBe(1);
|
|
148
228
|
expect(lastExitEvent(events)?.reason).toBe("aborted_pre_call");
|
|
@@ -166,7 +246,9 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
166
246
|
);
|
|
167
247
|
|
|
168
248
|
const events: AgentEvent[] = [];
|
|
169
|
-
await loop.run([userMessage], (e) => {
|
|
249
|
+
await loop.run([userMessage], (e) => {
|
|
250
|
+
events.push(e);
|
|
251
|
+
});
|
|
170
252
|
|
|
171
253
|
expect(countExitEvents(events)).toBe(1);
|
|
172
254
|
expect(lastExitEvent(events)?.reason).toBe("yield_to_user");
|
|
@@ -186,13 +268,14 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
186
268
|
toolExecutor,
|
|
187
269
|
);
|
|
188
270
|
|
|
189
|
-
const onCheckpoint = (_info: CheckpointInfo): CheckpointDecision =>
|
|
190
|
-
"yield";
|
|
271
|
+
const onCheckpoint = (_info: CheckpointInfo): CheckpointDecision => "yield";
|
|
191
272
|
|
|
192
273
|
const events: AgentEvent[] = [];
|
|
193
274
|
await loop.run(
|
|
194
275
|
[userMessage],
|
|
195
|
-
(e) => {
|
|
276
|
+
(e) => {
|
|
277
|
+
events.push(e);
|
|
278
|
+
},
|
|
196
279
|
undefined,
|
|
197
280
|
undefined,
|
|
198
281
|
onCheckpoint,
|
|
@@ -211,7 +294,9 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
211
294
|
const loop = new AgentLoop(provider, "system prompt");
|
|
212
295
|
|
|
213
296
|
const events: AgentEvent[] = [];
|
|
214
|
-
await loop.run([userMessage], (e) => {
|
|
297
|
+
await loop.run([userMessage], (e) => {
|
|
298
|
+
events.push(e);
|
|
299
|
+
});
|
|
215
300
|
|
|
216
301
|
expect(countExitEvents(events)).toBe(1);
|
|
217
302
|
expect(lastExitEvent(events)?.reason).toBe("error");
|
|
@@ -238,7 +323,9 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
238
323
|
);
|
|
239
324
|
|
|
240
325
|
const events: AgentEvent[] = [];
|
|
241
|
-
await loop.run([userMessage], (e) => {
|
|
326
|
+
await loop.run([userMessage], (e) => {
|
|
327
|
+
events.push(e);
|
|
328
|
+
});
|
|
242
329
|
|
|
243
330
|
expect(countExitEvents(events)).toBe(1);
|
|
244
331
|
});
|
|
@@ -263,7 +350,13 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
263
350
|
);
|
|
264
351
|
|
|
265
352
|
const events: AgentEvent[] = [];
|
|
266
|
-
await loop.run(
|
|
353
|
+
await loop.run(
|
|
354
|
+
[userMessage],
|
|
355
|
+
(e) => {
|
|
356
|
+
events.push(e);
|
|
357
|
+
},
|
|
358
|
+
controller.signal,
|
|
359
|
+
);
|
|
267
360
|
|
|
268
361
|
expect(countExitEvents(events)).toBe(1);
|
|
269
362
|
expect(lastExitEvent(events)?.reason).toBe("aborted_during_tools");
|
|
@@ -223,7 +223,7 @@ class FakeConversation {
|
|
|
223
223
|
return Promise.resolve();
|
|
224
224
|
}
|
|
225
225
|
persistUserMessage() {
|
|
226
|
-
return Promise.resolve("msg-id");
|
|
226
|
+
return Promise.resolve({ id: "msg-id", deduplicated: false });
|
|
227
227
|
}
|
|
228
228
|
runAgentLoop(
|
|
229
229
|
_content: string,
|
|
@@ -353,6 +353,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
353
353
|
// Always return undefined for the row read so the test fails fast unless
|
|
354
354
|
// executeSubagentSpawn reads from context.overrideProfile first.
|
|
355
355
|
getConversationOverrideProfile: () => undefined,
|
|
356
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
356
357
|
}));
|
|
357
358
|
|
|
358
359
|
import { getSubagentManager } from "../subagent/index.js";
|
|
@@ -22,6 +22,7 @@ import type { Message } from "../providers/types.js";
|
|
|
22
22
|
|
|
23
23
|
mock.module("../memory/conversation-crud.js", () => ({
|
|
24
24
|
getConversationOverrideProfile: () => undefined,
|
|
25
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
25
26
|
}));
|
|
26
27
|
|
|
27
28
|
mock.module("../config/loader.js", () => ({
|
|
@@ -32,6 +32,7 @@ let mockOverrideProfile: string | undefined = undefined;
|
|
|
32
32
|
|
|
33
33
|
mock.module("../memory/conversation-crud.js", () => ({
|
|
34
34
|
getConversationOverrideProfile: (_id: string) => mockOverrideProfile,
|
|
35
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
35
36
|
}));
|
|
36
37
|
|
|
37
38
|
// Mutable stub for `getConfig().llm` consumed by `RetryProvider`'s
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
import { afterAll, describe, expect, test } from "bun:test";
|
|
15
15
|
|
|
16
16
|
import {
|
|
17
|
-
buildToolDefinitions,
|
|
18
17
|
isToolActiveForContext,
|
|
19
18
|
type SkillProjectionContext,
|
|
20
19
|
} from "../daemon/conversation-tool-setup.js";
|
|
21
20
|
import {
|
|
22
21
|
__resetRegistryForTesting,
|
|
22
|
+
getAllToolDefinitions,
|
|
23
23
|
initializeTools,
|
|
24
24
|
} from "../tools/registry.js";
|
|
25
25
|
|
|
@@ -30,7 +30,7 @@ afterAll(() => {
|
|
|
30
30
|
describe("always-loaded tool count", () => {
|
|
31
31
|
test("should be exactly 11 with recall occupying the existing slot", async () => {
|
|
32
32
|
await initializeTools();
|
|
33
|
-
const allDefs =
|
|
33
|
+
const allDefs = getAllToolDefinitions();
|
|
34
34
|
|
|
35
35
|
// Minimal context: no client, no capabilities
|
|
36
36
|
const minimalContext: SkillProjectionContext = {
|
|
@@ -57,6 +57,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
57
57
|
updates.push({ id, content });
|
|
58
58
|
},
|
|
59
59
|
provenanceFromTrustContext: () => ({}),
|
|
60
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
60
61
|
}));
|
|
61
62
|
|
|
62
63
|
mock.module("../memory/llm-request-log-store.js", () => ({
|
|
@@ -151,6 +151,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
151
151
|
addMessage: () => ({ id: `msg-${Date.now()}` }),
|
|
152
152
|
updateConversationUsage: () => {},
|
|
153
153
|
updateConversationTitle: () => {},
|
|
154
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
154
155
|
}));
|
|
155
156
|
|
|
156
157
|
mock.module("../memory/conversation-queries.js", () => ({
|
|
@@ -154,13 +154,9 @@ function makeIdleSession(opts?: {
|
|
|
154
154
|
let processing = false;
|
|
155
155
|
return {
|
|
156
156
|
isProcessing: () => processing,
|
|
157
|
-
persistUserMessage: (
|
|
158
|
-
_content: string,
|
|
159
|
-
_attachments: unknown[],
|
|
160
|
-
requestId?: string,
|
|
161
|
-
) => {
|
|
157
|
+
persistUserMessage: (options: { requestId?: string }) => {
|
|
162
158
|
processing = true;
|
|
163
|
-
return requestId ?? "msg-1";
|
|
159
|
+
return { id: options.requestId ?? "msg-1", deduplicated: false };
|
|
164
160
|
},
|
|
165
161
|
memoryPolicy: {
|
|
166
162
|
scopeId: "default",
|
|
@@ -223,13 +219,9 @@ function makeConfirmationEmittingSession(opts?: {
|
|
|
223
219
|
const tool = opts?.toolName ?? "shell_command";
|
|
224
220
|
return {
|
|
225
221
|
isProcessing: () => processing,
|
|
226
|
-
persistUserMessage: (
|
|
227
|
-
_content: string,
|
|
228
|
-
_attachments: unknown[],
|
|
229
|
-
requestId?: string,
|
|
230
|
-
) => {
|
|
222
|
+
persistUserMessage: (options: { requestId?: string }) => {
|
|
231
223
|
processing = true;
|
|
232
|
-
return requestId ?? "msg-1";
|
|
224
|
+
return { id: options.requestId ?? "msg-1", deduplicated: false };
|
|
233
225
|
},
|
|
234
226
|
memoryPolicy: {
|
|
235
227
|
scopeId: "default",
|
|
@@ -266,7 +258,11 @@ function makeConfirmationEmittingSession(opts?: {
|
|
|
266
258
|
input: { command: "ls" },
|
|
267
259
|
riskLevel: "medium",
|
|
268
260
|
allowlistOptions: [
|
|
269
|
-
{
|
|
261
|
+
{
|
|
262
|
+
label: "Allow ls",
|
|
263
|
+
description: "Allow ls command",
|
|
264
|
+
pattern: "ls",
|
|
265
|
+
},
|
|
270
266
|
],
|
|
271
267
|
scopeOptions: [{ label: "This conversation", scope: "session" }],
|
|
272
268
|
persistentDecisionsAllowed: true,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only utilities for safely interacting with on-disk DB files.
|
|
3
|
+
*
|
|
4
|
+
* Two exports:
|
|
5
|
+
*
|
|
6
|
+
* - `assertNotLiveDb(dbPath)` — per-callsite guard. Throws unless the
|
|
7
|
+
* path resolves under `os.tmpdir()`. Use it before any custom
|
|
8
|
+
* destructive operation not covered by `removeTestDbFiles`.
|
|
9
|
+
* - `removeTestDbFiles(dbPath)` — guarded `rmSync` of the DB file and
|
|
10
|
+
* its sibling `-shm` / `-wal` files. The standard way to clear a
|
|
11
|
+
* test DB between migrations.
|
|
12
|
+
*
|
|
13
|
+
* Defence-in-depth complement to the test-preload-verifier
|
|
14
|
+
* (`os.tmpdir()` containment check during preload). If a future bug
|
|
15
|
+
* lets a test see a non-tmpdir path despite the preload guard, every
|
|
16
|
+
* destructive call still has its own line of defence.
|
|
17
|
+
*
|
|
18
|
+
* Positive assertion: the path MUST resolve under `os.tmpdir()`. Same
|
|
19
|
+
* shape as the preload verifier — no enumeration of "real" paths,
|
|
20
|
+
* works across every deployment.
|
|
21
|
+
*
|
|
22
|
+
* No source-module imports — only node stdlib. Helpers in `__tests__/`
|
|
23
|
+
* must not import from `src/` (see assistant/AGENTS.md). Callers pass
|
|
24
|
+
* the resolved `dbPath` in so this file stays decoupled from
|
|
25
|
+
* `src/util/platform.ts`.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import { realpathSync, rmSync } from "node:fs";
|
|
29
|
+
import { tmpdir } from "node:os";
|
|
30
|
+
import { dirname, sep } from "node:path";
|
|
31
|
+
|
|
32
|
+
function canonicalize(p: string): string {
|
|
33
|
+
try {
|
|
34
|
+
return realpathSync(p);
|
|
35
|
+
} catch {
|
|
36
|
+
// realpathSync throws if the path doesn't exist. Fall back to the
|
|
37
|
+
// parent directory — which must exist for any rmSync target that's
|
|
38
|
+
// about to be touched. Returning the parent path here lets the
|
|
39
|
+
// containment check succeed in the common "file already deleted"
|
|
40
|
+
// case (rmSync with `force: true`) without falsely failing.
|
|
41
|
+
try {
|
|
42
|
+
return realpathSync(dirname(p));
|
|
43
|
+
} catch {
|
|
44
|
+
return p;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function assertNotLiveDb(dbPath: string): void {
|
|
50
|
+
const resolved = canonicalize(dbPath);
|
|
51
|
+
const tmpRoot = canonicalize(tmpdir());
|
|
52
|
+
if (resolved !== tmpRoot && !resolved.startsWith(tmpRoot + sep)) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
[
|
|
55
|
+
`assertNotLiveDb refused: ${dbPath} resolves to ${resolved}, which is not under ${tmpRoot}.`,
|
|
56
|
+
"",
|
|
57
|
+
"Test code must never destructively touch a DB path outside the",
|
|
58
|
+
"process temp directory. If you're seeing this in a passing test,",
|
|
59
|
+
"the test-preload likely didn't run (the verifier should have",
|
|
60
|
+
"caught that already — investigate why it didn't).",
|
|
61
|
+
].join("\n"),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Remove a SQLite DB file and its sibling `-shm` / `-wal` files. Always
|
|
68
|
+
* `force: true` (no error if the file doesn't exist yet). Guarded by
|
|
69
|
+
* `assertNotLiveDb` so a test can never destroy a non-tmpdir path.
|
|
70
|
+
*
|
|
71
|
+
* Caller passes `dbPath` (typically `getDbPath()` from the test file)
|
|
72
|
+
* to keep this helper free of source-module imports.
|
|
73
|
+
*/
|
|
74
|
+
export function removeTestDbFiles(dbPath: string): void {
|
|
75
|
+
assertNotLiveDb(dbPath);
|
|
76
|
+
rmSync(dbPath, { force: true });
|
|
77
|
+
rmSync(`${dbPath}-shm`, { force: true });
|
|
78
|
+
rmSync(`${dbPath}-wal`, { force: true });
|
|
79
|
+
}
|
|
@@ -14,10 +14,11 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
|
14
14
|
|
|
15
15
|
const DECLARED_FLAG_ID = "email-channel";
|
|
16
16
|
const DECLARED_FLAG_KEY = DECLARED_FLAG_ID;
|
|
17
|
-
const SAFE_STORAGE_LIMITS_FLAG = "safe-storage-limits";
|
|
18
17
|
|
|
19
|
-
const { isAssistantFeatureFlagEnabled
|
|
18
|
+
const { isAssistantFeatureFlagEnabled } =
|
|
20
19
|
await import("../config/assistant-feature-flags.js");
|
|
20
|
+
const { setOverridesForTesting } =
|
|
21
|
+
await import("./feature-flag-test-helpers.js");
|
|
21
22
|
const { skillFlagKey } = await import("../config/skill-state.js");
|
|
22
23
|
|
|
23
24
|
// ---------------------------------------------------------------------------
|
|
@@ -25,11 +26,11 @@ const { skillFlagKey } = await import("../config/skill-state.js");
|
|
|
25
26
|
// ---------------------------------------------------------------------------
|
|
26
27
|
|
|
27
28
|
beforeEach(() => {
|
|
28
|
-
|
|
29
|
+
setOverridesForTesting({});
|
|
29
30
|
});
|
|
30
31
|
|
|
31
32
|
afterEach(() => {
|
|
32
|
-
|
|
33
|
+
setOverridesForTesting({});
|
|
33
34
|
});
|
|
34
35
|
|
|
35
36
|
// ---------------------------------------------------------------------------
|
|
@@ -38,14 +39,14 @@ afterEach(() => {
|
|
|
38
39
|
|
|
39
40
|
describe("isAssistantFeatureFlagEnabled", () => {
|
|
40
41
|
test("reads from file-based overrides", () => {
|
|
41
|
-
|
|
42
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
|
|
42
43
|
const config = {} as any;
|
|
43
44
|
|
|
44
45
|
expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(true);
|
|
45
46
|
});
|
|
46
47
|
|
|
47
48
|
test("explicit false override in file-based overrides", () => {
|
|
48
|
-
|
|
49
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
49
50
|
const config = {} as any;
|
|
50
51
|
|
|
51
52
|
expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(
|
|
@@ -63,23 +64,6 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
63
64
|
);
|
|
64
65
|
});
|
|
65
66
|
|
|
66
|
-
test("safe-storage-limits defaults to disabled", () => {
|
|
67
|
-
const config = {} as any;
|
|
68
|
-
|
|
69
|
-
expect(
|
|
70
|
-
isAssistantFeatureFlagEnabled(SAFE_STORAGE_LIMITS_FLAG, config),
|
|
71
|
-
).toBe(false);
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
test("safe-storage-limits respects explicit override", () => {
|
|
75
|
-
_setOverridesForTesting({ [SAFE_STORAGE_LIMITS_FLAG]: true });
|
|
76
|
-
const config = {} as any;
|
|
77
|
-
|
|
78
|
-
expect(
|
|
79
|
-
isAssistantFeatureFlagEnabled(SAFE_STORAGE_LIMITS_FLAG, config),
|
|
80
|
-
).toBe(true);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
67
|
test("unknown flag defaults to false when no persisted override", () => {
|
|
84
68
|
const config = {} as any;
|
|
85
69
|
|
|
@@ -87,7 +71,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
87
71
|
});
|
|
88
72
|
|
|
89
73
|
test("undeclared flag respects persisted override", () => {
|
|
90
|
-
|
|
74
|
+
setOverridesForTesting({ "some-undeclared-flag": false });
|
|
91
75
|
const config = {} as any;
|
|
92
76
|
|
|
93
77
|
expect(isAssistantFeatureFlagEnabled("some-undeclared-flag", config)).toBe(
|
|
@@ -98,7 +82,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
98
82
|
|
|
99
83
|
describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
|
|
100
84
|
test("resolves skill flag via canonical path", () => {
|
|
101
|
-
|
|
85
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
102
86
|
const config = {} as any;
|
|
103
87
|
|
|
104
88
|
expect(
|
|
@@ -12,13 +12,13 @@ mock.module("../util/logger.js", () => ({
|
|
|
12
12
|
}),
|
|
13
13
|
}));
|
|
14
14
|
|
|
15
|
-
import { resetDb } from "../memory/db-connection.js";
|
|
16
15
|
import { getSqlite } from "../memory/db-connection.js";
|
|
17
16
|
import { initializeDb } from "../memory/db-init.js";
|
|
18
17
|
import {
|
|
19
18
|
getRecentInvocations,
|
|
20
19
|
rotateToolInvocations,
|
|
21
20
|
} from "../memory/tool-usage-store.js";
|
|
21
|
+
import { resetDbForTesting } from "./db-test-helpers.js";
|
|
22
22
|
|
|
23
23
|
// ---------------------------------------------------------------------------
|
|
24
24
|
// Helpers
|
|
@@ -57,7 +57,7 @@ const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
|
57
57
|
|
|
58
58
|
describe("audit log rotation", () => {
|
|
59
59
|
beforeAll(() => {
|
|
60
|
-
|
|
60
|
+
resetDbForTesting();
|
|
61
61
|
initializeDb();
|
|
62
62
|
// Insert a conversations row so FK-enforced ORM inserts succeed
|
|
63
63
|
getSqlite().run(
|
|
@@ -130,7 +130,6 @@ mock.module("../runtime/services/analyze-conversation.js", () => ({
|
|
|
130
130
|
|
|
131
131
|
// ── Real imports ──────────────────────────────────────────────────
|
|
132
132
|
|
|
133
|
-
import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
|
|
134
133
|
import { conversationAnalyzeJob } from "../memory/conversation-analyze-job.js";
|
|
135
134
|
import { createConversation } from "../memory/conversation-crud.js";
|
|
136
135
|
import { getDb } from "../memory/db-connection.js";
|
|
@@ -138,6 +137,7 @@ import { initializeDb } from "../memory/db-init.js";
|
|
|
138
137
|
import { indexMessageNow } from "../memory/indexer.js";
|
|
139
138
|
import type { MemoryJob } from "../memory/jobs-store.js";
|
|
140
139
|
import { conversations, memoryJobs, messages } from "../memory/schema.js";
|
|
140
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
141
141
|
|
|
142
142
|
// ── Helpers ───────────────────────────────────────────────────────
|
|
143
143
|
|
|
@@ -279,14 +279,14 @@ beforeEach(() => {
|
|
|
279
279
|
resetTables();
|
|
280
280
|
analyzeCalls.length = 0;
|
|
281
281
|
// Clear any stale feature-flag overrides between tests.
|
|
282
|
-
|
|
282
|
+
setOverridesForTesting({});
|
|
283
283
|
});
|
|
284
284
|
|
|
285
285
|
// ─────────────────────────────────────────────────────────────────
|
|
286
286
|
|
|
287
287
|
describe("auto-analysis end-to-end trigger path", () => {
|
|
288
288
|
test("flag on, batch threshold reached → conversation_analyze enqueued, handler runs, analysis conversation created", async () => {
|
|
289
|
-
|
|
289
|
+
setOverridesForTesting({ "auto-analyze": true });
|
|
290
290
|
|
|
291
291
|
const source = createConversation("source-conv");
|
|
292
292
|
|
|
@@ -329,7 +329,7 @@ describe("auto-analysis end-to-end trigger path", () => {
|
|
|
329
329
|
});
|
|
330
330
|
|
|
331
331
|
test("flag off → no conversation_analyze job is ever enqueued", async () => {
|
|
332
|
-
|
|
332
|
+
setOverridesForTesting({ "auto-analyze": false });
|
|
333
333
|
|
|
334
334
|
const source = createConversation("source-conv-flag-off");
|
|
335
335
|
await indexMessages(source.id, 3);
|
|
@@ -343,7 +343,7 @@ describe("auto-analysis end-to-end trigger path", () => {
|
|
|
343
343
|
});
|
|
344
344
|
|
|
345
345
|
test("recursion guard: indexing into an auto-analysis conversation does not enqueue conversation_analyze or graph_extract", async () => {
|
|
346
|
-
|
|
346
|
+
setOverridesForTesting({ "auto-analyze": true });
|
|
347
347
|
|
|
348
348
|
// Set up an auto-analysis conversation directly. This is the
|
|
349
349
|
// scenario we need to protect against — the analysis agent writes
|
|
@@ -392,7 +392,7 @@ describe("auto-analysis batch trigger uses analysis.batchSize cadence", () => {
|
|
|
392
392
|
const originalV2Enabled = TEST_CONFIG.memory.v2.enabled;
|
|
393
393
|
|
|
394
394
|
beforeEach(() => {
|
|
395
|
-
|
|
395
|
+
setOverridesForTesting({ "auto-analyze": true });
|
|
396
396
|
// memory.v2.enabled gates v1 graph_extract enqueue; force off so
|
|
397
397
|
// these cadence tests can observe the v1 path.
|
|
398
398
|
TEST_CONFIG.memory.v2.enabled = false;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
import { createMockLoggerModule } from "./helpers/mock-logger.js";
|
|
4
|
+
|
|
3
5
|
// Default the warm-pool gate to OPEN — these tests probe background-job
|
|
4
6
|
// disk-pressure behavior, not the pre-first-message guard.
|
|
5
7
|
mock.module("../runtime/pre-first-message-gate.js", () => ({
|
|
@@ -7,14 +9,7 @@ mock.module("../runtime/pre-first-message-gate.js", () => ({
|
|
|
7
9
|
_resetPreFirstMessageGateCacheForTests: () => {},
|
|
8
10
|
}));
|
|
9
11
|
|
|
10
|
-
mock.module("../util/logger.js", () => (
|
|
11
|
-
getLogger: () => ({
|
|
12
|
-
info: () => {},
|
|
13
|
-
debug: () => {},
|
|
14
|
-
warn: () => {},
|
|
15
|
-
error: () => {},
|
|
16
|
-
}),
|
|
17
|
-
}));
|
|
12
|
+
mock.module("../util/logger.js", () => createMockLoggerModule());
|
|
18
13
|
|
|
19
14
|
mock.module("../config/loader.js", () => ({
|
|
20
15
|
getConfig: () => ({
|
|
@@ -157,6 +152,8 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
157
152
|
setLastNotifiedInferenceProfile: mock(() => {}),
|
|
158
153
|
setConversationHistoryStrippedAt: mock(() => {}),
|
|
159
154
|
wipeConversation: mock(() => ({ memoryIds: [] })),
|
|
155
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
156
|
+
extractImageSourcePaths: () => undefined,
|
|
160
157
|
}));
|
|
161
158
|
|
|
162
159
|
mock.module("../memory/conversation-title-service.js", () => ({
|
|
@@ -12,7 +12,6 @@ mock.module("../config/loader.js", () => ({
|
|
|
12
12
|
|
|
13
13
|
import { BROWSER_OPERATION_META } from "../browser/operations.js";
|
|
14
14
|
import { BROWSER_OPERATIONS } from "../browser/types.js";
|
|
15
|
-
import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
|
|
16
15
|
import {
|
|
17
16
|
projectSkillTools,
|
|
18
17
|
resetSkillToolProjection,
|
|
@@ -23,6 +22,7 @@ import {
|
|
|
23
22
|
getAllTools,
|
|
24
23
|
initializeTools,
|
|
25
24
|
} from "../tools/registry.js";
|
|
25
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
26
26
|
import {
|
|
27
27
|
BROWSER_SKILL_ID,
|
|
28
28
|
buildSkillLoadHistory,
|
|
@@ -30,13 +30,13 @@ import {
|
|
|
30
30
|
|
|
31
31
|
afterAll(() => {
|
|
32
32
|
__resetRegistryForTesting();
|
|
33
|
-
|
|
33
|
+
setOverridesForTesting({});
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
describe("browser CLI-only architecture end-state", () => {
|
|
37
37
|
beforeAll(async () => {
|
|
38
38
|
__resetRegistryForTesting();
|
|
39
|
-
|
|
39
|
+
setOverridesForTesting({
|
|
40
40
|
browser: true,
|
|
41
41
|
});
|
|
42
42
|
await initializeTools();
|
|
@@ -38,6 +38,7 @@ const mockAddMessage = mock(() => {});
|
|
|
38
38
|
|
|
39
39
|
mock.module("../memory/conversation-crud.js", () => ({
|
|
40
40
|
addMessage: mockAddMessage,
|
|
41
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
41
42
|
}));
|
|
42
43
|
|
|
43
44
|
const MOCK_TOOLS = [
|
|
@@ -48,8 +49,8 @@ const MOCK_TOOLS = [
|
|
|
48
49
|
},
|
|
49
50
|
];
|
|
50
51
|
|
|
51
|
-
mock.module("../
|
|
52
|
-
|
|
52
|
+
mock.module("../tools/registry.js", () => ({
|
|
53
|
+
getAllToolDefinitions: () => MOCK_TOOLS,
|
|
53
54
|
}));
|
|
54
55
|
|
|
55
56
|
const MOCK_SYSTEM_PROMPT = "You are a helpful assistant.";
|