@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
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
} from "../permissions/checker.js";
|
|
110
110
|
import { _clearGlobalCacheForTesting } from "../permissions/gateway-threshold-reader.js";
|
|
111
111
|
import { RiskLevel } from "../permissions/types.js";
|
|
112
|
-
import { registerTool } from "../tools/registry.js";
|
|
112
|
+
import { registerSkillTools, registerTool } from "../tools/registry.js";
|
|
113
113
|
import type { Tool } from "../tools/types.js";
|
|
114
114
|
import * as platformModule from "../util/platform.js";
|
|
115
115
|
|
|
@@ -128,33 +128,35 @@ const STRICT_GATEWAY_THRESHOLDS = {
|
|
|
128
128
|
} as const;
|
|
129
129
|
|
|
130
130
|
// Register a mock skill-origin tool for testing default-ask policy.
|
|
131
|
+
// Ownership is recorded by `registerSkillTools(skillId, tools)`, not by
|
|
132
|
+
// stamping a field on the `Tool` object — `isToolOwnerSkillBundled()` reads
|
|
133
|
+
// from the registry via `getToolOwner(name)` to find the owning skill id.
|
|
131
134
|
const mockSkillTool: Tool = {
|
|
132
135
|
name: "skill_test_tool",
|
|
133
136
|
description: "A test skill tool",
|
|
134
137
|
category: "skill",
|
|
135
138
|
defaultRiskLevel: RiskLevel.Low,
|
|
136
139
|
executionTarget: "sandbox",
|
|
137
|
-
origin: "skill",
|
|
138
|
-
ownerSkillId: "test-skill",
|
|
139
140
|
input_schema: { type: "object" as const, properties: {} },
|
|
140
141
|
execute: async () => ({ content: "ok", isError: false }),
|
|
141
142
|
};
|
|
142
|
-
|
|
143
|
+
registerSkillTools("test-skill", [mockSkillTool]);
|
|
143
144
|
|
|
144
|
-
// Register a mock bundled skill-origin tool for testing strict mode + bundled
|
|
145
|
+
// Register a mock bundled skill-origin tool for testing strict mode + bundled
|
|
146
|
+
// policy. `app-builder` is a real entry under `bundled-skills/`, so
|
|
147
|
+
// `loadSkillCatalog()` reports it as `bundled: true` and the permission
|
|
148
|
+
// checker derives `isSkillBundled = true` from the registry's ownersByName
|
|
149
|
+
// map (populated by `registerSkillTools`) without any per-tool stamp.
|
|
145
150
|
const mockBundledSkillTool: Tool = {
|
|
146
151
|
name: "skill_bundled_test_tool",
|
|
147
152
|
description: "A test bundled skill tool",
|
|
148
153
|
category: "skill",
|
|
149
154
|
defaultRiskLevel: RiskLevel.Low,
|
|
150
155
|
executionTarget: "sandbox",
|
|
151
|
-
origin: "skill",
|
|
152
|
-
ownerSkillId: "gmail",
|
|
153
|
-
ownerSkillBundled: true,
|
|
154
156
|
input_schema: { type: "object" as const, properties: {} },
|
|
155
157
|
execute: async () => ({ content: "ok", isError: false }),
|
|
156
158
|
};
|
|
157
|
-
|
|
159
|
+
registerSkillTools("app-builder", [mockBundledSkillTool]);
|
|
158
160
|
|
|
159
161
|
// Register CU tools so check() can look them up in the tool registry
|
|
160
162
|
// instead of falling through to Medium (unknown tool).
|
|
@@ -386,12 +388,10 @@ describe("Permission Checker", () => {
|
|
|
386
388
|
category: "skill",
|
|
387
389
|
defaultRiskLevel: RiskLevel.Medium,
|
|
388
390
|
executionTarget: "sandbox",
|
|
389
|
-
origin: "skill",
|
|
390
|
-
ownerSkillId: "test-skill",
|
|
391
391
|
input_schema: { type: "object" as const, properties: {} },
|
|
392
392
|
execute: async () => ({ content: "ok", isError: false }),
|
|
393
393
|
};
|
|
394
|
-
|
|
394
|
+
registerSkillTools("test-skill", [mediumSkillTool]);
|
|
395
395
|
const result = await check("skill_medium_tool", {}, "/tmp");
|
|
396
396
|
expect(result.decision).toBe("prompt");
|
|
397
397
|
expect(result.reason).toContain("Skill tool");
|
|
@@ -150,6 +150,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
150
150
|
addMessage: () => ({ id: `msg-${Date.now()}` }),
|
|
151
151
|
updateConversationUsage: () => {},
|
|
152
152
|
updateConversationTitle: () => {},
|
|
153
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
153
154
|
}));
|
|
154
155
|
|
|
155
156
|
mock.module("../memory/conversation-queries.js", () => ({
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the compaction-trail store helpers:
|
|
3
|
+
* - `getCompactionLogsBetween` (windowed trail fetch)
|
|
4
|
+
* - `getPreviousNonCompactionCallCreatedAt` (window-floor resolver)
|
|
5
|
+
*
|
|
6
|
+
* Exercises the SQL directly against a real in-memory DB — same pattern
|
|
7
|
+
* as `llm-request-log-turn-query.test.ts`. Each test sets up a small
|
|
8
|
+
* conversation, inserts a mix of `mainAgent` / `compactionAgent` /
|
|
9
|
+
* NULL-call-site rows with controlled `createdAt` timestamps, and
|
|
10
|
+
* asserts the right subset comes back.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
14
|
+
|
|
15
|
+
mock.module("../util/logger.js", () => ({
|
|
16
|
+
getLogger: () =>
|
|
17
|
+
new Proxy({} as Record<string, unknown>, {
|
|
18
|
+
get: () => () => {},
|
|
19
|
+
}),
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
mock.module("../config/loader.js", () => ({
|
|
23
|
+
getConfig: () => ({
|
|
24
|
+
ui: {},
|
|
25
|
+
model: "test",
|
|
26
|
+
provider: "test",
|
|
27
|
+
memory: { enabled: false },
|
|
28
|
+
rateLimit: { maxRequestsPerMinute: 0 },
|
|
29
|
+
secretDetection: { enabled: false },
|
|
30
|
+
}),
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
import { eq } from "drizzle-orm";
|
|
34
|
+
|
|
35
|
+
import { createConversation } from "../memory/conversation-crud.js";
|
|
36
|
+
import { getDb } from "../memory/db-connection.js";
|
|
37
|
+
import { initializeDb } from "../memory/db-init.js";
|
|
38
|
+
import {
|
|
39
|
+
getCompactionLogsBetween,
|
|
40
|
+
getPreviousNonCompactionCallCreatedAt,
|
|
41
|
+
recordRequestLog,
|
|
42
|
+
} from "../memory/llm-request-log-store.js";
|
|
43
|
+
import { llmRequestLogs } from "../memory/schema.js";
|
|
44
|
+
|
|
45
|
+
initializeDb();
|
|
46
|
+
|
|
47
|
+
function resetTables(): void {
|
|
48
|
+
const db = getDb();
|
|
49
|
+
db.delete(llmRequestLogs).run();
|
|
50
|
+
db.run("DELETE FROM messages");
|
|
51
|
+
db.run("DELETE FROM conversations");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Insert a log row and overwrite its `createdAt` so tests can assert
|
|
56
|
+
* order/cutoff without relying on `Date.now()` timing.
|
|
57
|
+
*/
|
|
58
|
+
function insertLogAt(
|
|
59
|
+
conversationId: string,
|
|
60
|
+
createdAt: number,
|
|
61
|
+
callSite: "mainAgent" | "compactionAgent" | null,
|
|
62
|
+
): string {
|
|
63
|
+
const id = recordRequestLog(
|
|
64
|
+
conversationId,
|
|
65
|
+
"{}",
|
|
66
|
+
"{}",
|
|
67
|
+
undefined,
|
|
68
|
+
"anthropic",
|
|
69
|
+
callSite ?? undefined,
|
|
70
|
+
);
|
|
71
|
+
// Use the Drizzle update builder rather than `db.run("UPDATE … ?")` —
|
|
72
|
+
// the drizzle wrapper doesn't accept positional parameters the same
|
|
73
|
+
// way `bun:sqlite` does, and a silent no-op there manifests as zero
|
|
74
|
+
// rows in the query under test (the inserted `created_at` keeps its
|
|
75
|
+
// `Date.now()` value and ends up far in the future of the cutoff).
|
|
76
|
+
const db = getDb();
|
|
77
|
+
db.update(llmRequestLogs)
|
|
78
|
+
.set({ createdAt })
|
|
79
|
+
.where(eq(llmRequestLogs.id, id))
|
|
80
|
+
.run();
|
|
81
|
+
return id;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
describe("getCompactionLogsBetween", () => {
|
|
85
|
+
beforeEach(() => {
|
|
86
|
+
resetTables();
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("returns only compactionAgent rows in the conversation, in the (after, before) window", () => {
|
|
90
|
+
const conv = createConversation("test-conv");
|
|
91
|
+
|
|
92
|
+
// Timeline (createdAt in ms):
|
|
93
|
+
// 100 → compactionAgent ← excluded (before the floor — would belong to an earlier turn)
|
|
94
|
+
// 150 ← floor (the prior real call's createdAt)
|
|
95
|
+
// 200 → mainAgent ← excluded (wrong call site)
|
|
96
|
+
// 300 → compactionAgent ← included
|
|
97
|
+
// 400 → null call site ← excluded (pre-migration row, not a compaction)
|
|
98
|
+
// 500 ← ceiling (the selected call's createdAt)
|
|
99
|
+
// 600 → compactionAgent ← excluded (after ceiling)
|
|
100
|
+
insertLogAt(conv.id, 100, "compactionAgent");
|
|
101
|
+
insertLogAt(conv.id, 200, "mainAgent");
|
|
102
|
+
insertLogAt(conv.id, 300, "compactionAgent");
|
|
103
|
+
insertLogAt(conv.id, 400, null);
|
|
104
|
+
insertLogAt(conv.id, 600, "compactionAgent");
|
|
105
|
+
|
|
106
|
+
const result = getCompactionLogsBetween(conv.id, 150, 500);
|
|
107
|
+
expect(result).toHaveLength(1);
|
|
108
|
+
expect(result[0]!.createdAt).toBe(300);
|
|
109
|
+
expect(result[0]!.callSite).toBe("compactionAgent");
|
|
110
|
+
expect(result[0]!.conversationId).toBe(conv.id);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("null floor matches all compactions before the ceiling (first-real-call case)", () => {
|
|
114
|
+
const conv = createConversation("null-floor");
|
|
115
|
+
|
|
116
|
+
insertLogAt(conv.id, 100, "compactionAgent");
|
|
117
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
118
|
+
insertLogAt(conv.id, 300, "compactionAgent");
|
|
119
|
+
insertLogAt(conv.id, 600, "compactionAgent");
|
|
120
|
+
|
|
121
|
+
const result = getCompactionLogsBetween(conv.id, null, 500);
|
|
122
|
+
expect(result.map((r) => r.createdAt)).toEqual([100, 200, 300]);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("uses strict < at the ceiling (a row exactly at the cutoff is excluded)", () => {
|
|
126
|
+
const conv = createConversation("strict-ceiling");
|
|
127
|
+
|
|
128
|
+
insertLogAt(conv.id, 100, "compactionAgent");
|
|
129
|
+
insertLogAt(conv.id, 500, "compactionAgent"); // exactly at the ceiling
|
|
130
|
+
|
|
131
|
+
const result = getCompactionLogsBetween(conv.id, null, 500);
|
|
132
|
+
expect(result).toHaveLength(1);
|
|
133
|
+
expect(result[0]!.createdAt).toBe(100);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("uses strict > at the floor (a row exactly at the floor is excluded)", () => {
|
|
137
|
+
const conv = createConversation("strict-floor");
|
|
138
|
+
|
|
139
|
+
insertLogAt(conv.id, 150, "compactionAgent"); // exactly at the floor
|
|
140
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
141
|
+
|
|
142
|
+
const result = getCompactionLogsBetween(conv.id, 150, 500);
|
|
143
|
+
expect(result).toHaveLength(1);
|
|
144
|
+
expect(result[0]!.createdAt).toBe(200);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("scopes by conversation_id (other conversations are invisible)", () => {
|
|
148
|
+
const a = createConversation("conv-a");
|
|
149
|
+
const b = createConversation("conv-b");
|
|
150
|
+
|
|
151
|
+
insertLogAt(a.id, 100, "compactionAgent");
|
|
152
|
+
insertLogAt(b.id, 150, "compactionAgent");
|
|
153
|
+
insertLogAt(a.id, 200, "compactionAgent");
|
|
154
|
+
|
|
155
|
+
const result = getCompactionLogsBetween(a.id, null, 500);
|
|
156
|
+
expect(result).toHaveLength(2);
|
|
157
|
+
for (const row of result) {
|
|
158
|
+
expect(row.conversationId).toBe(a.id);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("returns rows in chronological order by createdAt then id", () => {
|
|
163
|
+
const conv = createConversation("ordered");
|
|
164
|
+
|
|
165
|
+
// Insert out of order to verify the ORDER BY clause does the work.
|
|
166
|
+
insertLogAt(conv.id, 300, "compactionAgent");
|
|
167
|
+
insertLogAt(conv.id, 100, "compactionAgent");
|
|
168
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
169
|
+
|
|
170
|
+
const result = getCompactionLogsBetween(conv.id, null, 500);
|
|
171
|
+
expect(result.map((r) => r.createdAt)).toEqual([100, 200, 300]);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("returns an empty array when no compaction rows fall in the window", () => {
|
|
175
|
+
const conv = createConversation("empty");
|
|
176
|
+
|
|
177
|
+
// mainAgent (wrong site) + compactionAgent after the ceiling.
|
|
178
|
+
insertLogAt(conv.id, 100, "mainAgent");
|
|
179
|
+
insertLogAt(conv.id, 600, "compactionAgent");
|
|
180
|
+
|
|
181
|
+
const result = getCompactionLogsBetween(conv.id, null, 500);
|
|
182
|
+
expect(result).toEqual([]);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test("returns an empty array for an unknown conversation_id", () => {
|
|
186
|
+
const result = getCompactionLogsBetween("nonexistent-conv", null, 500);
|
|
187
|
+
expect(result).toEqual([]);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("getPreviousNonCompactionCallCreatedAt", () => {
|
|
192
|
+
beforeEach(() => {
|
|
193
|
+
resetTables();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("returns the most recent non-compaction call's createdAt before the cutoff", () => {
|
|
197
|
+
const conv = createConversation("prior-call");
|
|
198
|
+
|
|
199
|
+
// Timeline:
|
|
200
|
+
// 100 → mainAgent
|
|
201
|
+
// 200 → compactionAgent ← skipped (we want the previous *real* call)
|
|
202
|
+
// 300 → mainAgent ← this should be the answer for cutoff=500
|
|
203
|
+
// 400 → compactionAgent ← skipped
|
|
204
|
+
// 500 ← cutoff
|
|
205
|
+
// 600 → mainAgent ← excluded (after cutoff)
|
|
206
|
+
insertLogAt(conv.id, 100, "mainAgent");
|
|
207
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
208
|
+
insertLogAt(conv.id, 300, "mainAgent");
|
|
209
|
+
insertLogAt(conv.id, 400, "compactionAgent");
|
|
210
|
+
insertLogAt(conv.id, 600, "mainAgent");
|
|
211
|
+
|
|
212
|
+
const result = getPreviousNonCompactionCallCreatedAt(conv.id, 500);
|
|
213
|
+
expect(result).toBe(300);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
test("returns null when no non-compaction call exists before the cutoff", () => {
|
|
217
|
+
const conv = createConversation("no-prior");
|
|
218
|
+
|
|
219
|
+
// Only compactions before the cutoff.
|
|
220
|
+
insertLogAt(conv.id, 100, "compactionAgent");
|
|
221
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
222
|
+
|
|
223
|
+
const result = getPreviousNonCompactionCallCreatedAt(conv.id, 500);
|
|
224
|
+
expect(result).toBeNull();
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("returns null for an unknown conversation_id", () => {
|
|
228
|
+
const result = getPreviousNonCompactionCallCreatedAt("nope", 500);
|
|
229
|
+
expect(result).toBeNull();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("treats NULL call_site (pre-migration-264) as a real agent call", () => {
|
|
233
|
+
const conv = createConversation("null-site");
|
|
234
|
+
|
|
235
|
+
// Pre-migration rows have NULL call_site. They were mainAgent calls
|
|
236
|
+
// in practice, so the floor walker must surface them.
|
|
237
|
+
insertLogAt(conv.id, 100, null);
|
|
238
|
+
insertLogAt(conv.id, 200, "compactionAgent");
|
|
239
|
+
|
|
240
|
+
const result = getPreviousNonCompactionCallCreatedAt(conv.id, 500);
|
|
241
|
+
expect(result).toBe(100);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test("uses strict < at the cutoff (a row exactly at the cutoff is excluded)", () => {
|
|
245
|
+
const conv = createConversation("strict-prior");
|
|
246
|
+
|
|
247
|
+
insertLogAt(conv.id, 100, "mainAgent");
|
|
248
|
+
insertLogAt(conv.id, 500, "mainAgent"); // exactly at the cutoff
|
|
249
|
+
|
|
250
|
+
const result = getPreviousNonCompactionCallCreatedAt(conv.id, 500);
|
|
251
|
+
expect(result).toBe(100);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("scopes by conversation_id (a prior call in another conversation is invisible)", () => {
|
|
255
|
+
const a = createConversation("conv-a");
|
|
256
|
+
const b = createConversation("conv-b");
|
|
257
|
+
|
|
258
|
+
insertLogAt(b.id, 100, "mainAgent"); // wrong conversation
|
|
259
|
+
insertLogAt(a.id, 200, "compactionAgent");
|
|
260
|
+
|
|
261
|
+
const result = getPreviousNonCompactionCallCreatedAt(a.id, 500);
|
|
262
|
+
expect(result).toBeNull();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
@@ -113,8 +113,9 @@ describe("computer-use skill manifest regression", () => {
|
|
|
113
113
|
await initializeTools();
|
|
114
114
|
|
|
115
115
|
// Simulate what projectSkillTools() does when the computer-use skill is
|
|
116
|
-
// activated: create
|
|
117
|
-
//
|
|
116
|
+
// activated: create Tool objects matching the manifest names and register
|
|
117
|
+
// them through `registerSkillTools(skillId, tools)`, which records
|
|
118
|
+
// ownership in the registry's `ownersByName` map. This must not throw.
|
|
118
119
|
const skillTools: Tool[] = manifest.tools.map(
|
|
119
120
|
(entry: { name: string; description: string }) => ({
|
|
120
121
|
name: entry.name,
|
|
@@ -122,13 +123,14 @@ describe("computer-use skill manifest regression", () => {
|
|
|
122
123
|
input_schema: { type: "object" as const, properties: {} },
|
|
123
124
|
category: "computer-use",
|
|
124
125
|
defaultRiskLevel: RiskLevel.Low,
|
|
125
|
-
origin: "skill" as const,
|
|
126
|
-
ownerSkillId: "computer-use",
|
|
127
126
|
execute: async () => ({ content: "stub", isError: false }),
|
|
128
127
|
}),
|
|
129
128
|
);
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
// Owner flows in through `registerSkillTools(skillId, tools)` and lands
|
|
131
|
+
// in the registry's `ownersByName` map — the tools themselves carry no
|
|
132
|
+
// per-tool owner field.
|
|
133
|
+
expect(() => registerSkillTools("computer-use", skillTools)).not.toThrow();
|
|
132
134
|
|
|
133
135
|
// Clean up
|
|
134
136
|
unregisterSkillTools("computer-use");
|
|
@@ -40,12 +40,6 @@ describe("computer-use tool definitions", () => {
|
|
|
40
40
|
expect(allComputerUseTools.length).toBe(11);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
test("all tools have proxy execution mode", () => {
|
|
44
|
-
for (const tool of allComputerUseTools) {
|
|
45
|
-
expect(tool.executionMode).toBe("proxy");
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
|
|
49
43
|
test("all tools belong to computer-use category", () => {
|
|
50
44
|
for (const tool of allComputerUseTools) {
|
|
51
45
|
expect(tool.category).toBe("computer-use");
|
|
@@ -94,8 +88,10 @@ describe("computer_use_click (unified)", () => {
|
|
|
94
88
|
expect(props.y.type).toBe("integer");
|
|
95
89
|
});
|
|
96
90
|
|
|
97
|
-
test("execute
|
|
98
|
-
|
|
91
|
+
test("execute returns isError when no proxy resolver is configured", async () => {
|
|
92
|
+
const result = await computerUseClickTool.execute({}, ctx);
|
|
93
|
+
expect(result.isError).toBe(true);
|
|
94
|
+
expect(result.content).toMatch(/No proxy resolver/);
|
|
99
95
|
});
|
|
100
96
|
});
|
|
101
97
|
|
|
@@ -107,10 +103,10 @@ describe("computer_use_type_text", () => {
|
|
|
107
103
|
expect(schema(computerUseTypeTextTool).required).toContain("reasoning");
|
|
108
104
|
});
|
|
109
105
|
|
|
110
|
-
test("execute
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
);
|
|
106
|
+
test("execute returns isError when no proxy resolver is configured", async () => {
|
|
107
|
+
const result = await computerUseTypeTextTool.execute({}, ctx);
|
|
108
|
+
expect(result.isError).toBe(true);
|
|
109
|
+
expect(result.content).toMatch(/No proxy resolver/);
|
|
114
110
|
});
|
|
115
111
|
});
|
|
116
112
|
|
|
@@ -122,8 +118,10 @@ describe("computer_use_key", () => {
|
|
|
122
118
|
expect(schema(computerUseKeyTool).required).toContain("reasoning");
|
|
123
119
|
});
|
|
124
120
|
|
|
125
|
-
test("execute
|
|
126
|
-
|
|
121
|
+
test("execute returns isError when no proxy resolver is configured", async () => {
|
|
122
|
+
const result = await computerUseKeyTool.execute({}, ctx);
|
|
123
|
+
expect(result.isError).toBe(true);
|
|
124
|
+
expect(result.content).toMatch(/No proxy resolver/);
|
|
127
125
|
});
|
|
128
126
|
});
|
|
129
127
|
|
|
@@ -82,7 +82,7 @@ import { migrateProviderConnectionStatusLabel } from "../memory/migrations/244-p
|
|
|
82
82
|
import { migrateProviderConnectionBaseUrlAndModels } from "../memory/migrations/250-provider-connection-base-url-and-models.js";
|
|
83
83
|
import * as schema from "../memory/schema.js";
|
|
84
84
|
import { getConnection } from "../providers/inference/connections.js";
|
|
85
|
-
import {
|
|
85
|
+
import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
|
|
86
86
|
|
|
87
87
|
// ---------------------------------------------------------------------------
|
|
88
88
|
// Helpers
|
|
@@ -328,14 +328,14 @@ describe("loadConfig startup behavior", () => {
|
|
|
328
328
|
const updatesPath = join(WORKSPACE_DIR, "UPDATES.md");
|
|
329
329
|
if (existsSync(updatesPath)) rmSync(updatesPath, { force: true });
|
|
330
330
|
ensureTestDir();
|
|
331
|
-
|
|
331
|
+
setStorePathForTesting(join(WORKSPACE_DIR, "keys.enc"));
|
|
332
332
|
delete process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH;
|
|
333
333
|
delete process.env.IS_PLATFORM;
|
|
334
334
|
invalidateConfigCache();
|
|
335
335
|
});
|
|
336
336
|
|
|
337
337
|
afterEach(() => {
|
|
338
|
-
|
|
338
|
+
setStorePathForTesting(null);
|
|
339
339
|
delete process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH;
|
|
340
340
|
delete process.env.IS_PLATFORM;
|
|
341
341
|
invalidateConfigCache();
|
|
@@ -943,14 +943,14 @@ describe("seedInferenceProfiles BYOK-mode managed profile labels", () => {
|
|
|
943
943
|
}
|
|
944
944
|
}
|
|
945
945
|
ensureTestDir();
|
|
946
|
-
|
|
946
|
+
setStorePathForTesting(join(WORKSPACE_DIR, "keys.enc"));
|
|
947
947
|
delete process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH;
|
|
948
948
|
delete process.env.IS_PLATFORM;
|
|
949
949
|
invalidateConfigCache();
|
|
950
950
|
});
|
|
951
951
|
|
|
952
952
|
afterEach(() => {
|
|
953
|
-
|
|
953
|
+
setStorePathForTesting(null);
|
|
954
954
|
delete process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH;
|
|
955
955
|
delete process.env.IS_PLATFORM;
|
|
956
956
|
invalidateConfigCache();
|
|
@@ -1037,9 +1037,10 @@ describe("seedInferenceProfiles BYOK-mode managed profile labels", () => {
|
|
|
1037
1037
|
"anthropic-managed",
|
|
1038
1038
|
);
|
|
1039
1039
|
expect("status" in raw.llm.profiles.balanced).toBe(false);
|
|
1040
|
-
|
|
1041
|
-
expect(getConnection(db, "
|
|
1042
|
-
expect(getConnection(db, "
|
|
1040
|
+
// Connections exist (status is no longer a connection-level concept).
|
|
1041
|
+
expect(getConnection(db, "anthropic-managed")).not.toBeNull();
|
|
1042
|
+
expect(getConnection(db, "openai-managed")).not.toBeNull();
|
|
1043
|
+
expect(getConnection(db, "gemini-managed")).not.toBeNull();
|
|
1043
1044
|
});
|
|
1044
1045
|
|
|
1045
1046
|
test("off-platform managed-inference hatch respects explicit non-managed active connection", () => {
|
|
@@ -1075,26 +1076,10 @@ describe("seedInferenceProfiles BYOK-mode managed profile labels", () => {
|
|
|
1075
1076
|
expect(raw.llm.profiles.balanced.provider_connection).toBe(
|
|
1076
1077
|
"anthropic-personal",
|
|
1077
1078
|
);
|
|
1078
|
-
|
|
1079
|
-
expect(getConnection(db, "
|
|
1080
|
-
expect(getConnection(db, "
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
test("off-platform BYOK hatch still disables managed connections", () => {
|
|
1084
|
-
const overlayPath = join(WORKSPACE_DIR, "hatch-overlay.json");
|
|
1085
|
-
writeFileSync(
|
|
1086
|
-
overlayPath,
|
|
1087
|
-
JSON.stringify({ llm: { default: { provider: "anthropic" } } }, null, 2) +
|
|
1088
|
-
"\n",
|
|
1089
|
-
);
|
|
1090
|
-
process.env.VELLUM_DEFAULT_WORKSPACE_CONFIG_PATH = overlayPath;
|
|
1091
|
-
const db = createProviderConnectionsDb();
|
|
1092
|
-
|
|
1093
|
-
mergeDefaultConfigAndSeedInferenceProfiles(db);
|
|
1094
|
-
|
|
1095
|
-
expect(getConnection(db, "anthropic-managed")?.status).toBe("disabled");
|
|
1096
|
-
expect(getConnection(db, "openai-managed")?.status).toBe("disabled");
|
|
1097
|
-
expect(getConnection(db, "gemini-managed")?.status).toBe("disabled");
|
|
1079
|
+
// Connections exist (status is no longer a connection-level concept).
|
|
1080
|
+
expect(getConnection(db, "anthropic-managed")).not.toBeNull();
|
|
1081
|
+
expect(getConnection(db, "openai-managed")).not.toBeNull();
|
|
1082
|
+
expect(getConnection(db, "gemini-managed")).not.toBeNull();
|
|
1098
1083
|
});
|
|
1099
1084
|
|
|
1100
1085
|
test("non-hatch off-platform boot does NOT auto-disable freshly-materialized managed profiles", () => {
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
loadConfig,
|
|
24
24
|
loadRawConfig,
|
|
25
25
|
} from "../config/loader.js";
|
|
26
|
-
import {
|
|
26
|
+
import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
|
|
27
27
|
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
// Helpers
|
|
@@ -65,12 +65,12 @@ function listQuarantinedFiles(): string[] {
|
|
|
65
65
|
describe("loadConfig corrupt-file recovery", () => {
|
|
66
66
|
beforeEach(() => {
|
|
67
67
|
resetWorkspace();
|
|
68
|
-
|
|
68
|
+
setStorePathForTesting(join(WORKSPACE_DIR, "keys.enc"));
|
|
69
69
|
invalidateConfigCache();
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
afterEach(() => {
|
|
73
|
-
|
|
73
|
+
setStorePathForTesting(null);
|
|
74
74
|
invalidateConfigCache();
|
|
75
75
|
});
|
|
76
76
|
|
|
@@ -187,12 +187,12 @@ describe("loadConfig corrupt-file recovery", () => {
|
|
|
187
187
|
describe("loadRawConfig corrupt-file recovery", () => {
|
|
188
188
|
beforeEach(() => {
|
|
189
189
|
resetWorkspace();
|
|
190
|
-
|
|
190
|
+
setStorePathForTesting(join(WORKSPACE_DIR, "keys.enc"));
|
|
191
191
|
invalidateConfigCache();
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
afterEach(() => {
|
|
195
|
-
|
|
195
|
+
setStorePathForTesting(null);
|
|
196
196
|
invalidateConfigCache();
|
|
197
197
|
});
|
|
198
198
|
|