@vellumai/assistant 0.8.4 → 0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -1
- package/ARCHITECTURE.md +3 -3
- package/bunfig.toml +6 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +4 -3
- package/knip.json +2 -1
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +12 -13
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +4 -1
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +2748 -216
- package/package.json +1 -1
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-exit-reason.test.ts +102 -9
- package/src/__tests__/agent-loop-override-profile.test.ts +2 -1
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +1 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +1 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -2
- package/src/__tests__/annotate-risk-options.test.ts +1 -0
- package/src/__tests__/anthropic-provider.test.ts +34 -37
- package/src/__tests__/approval-cascade.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +9 -13
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +12 -28
- package/src/__tests__/audit-log-rotation.test.ts +72 -18
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/background-workers-disk-pressure.test.ts +8 -11
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +5 -5
- package/src/__tests__/call-controller.test.ts +3 -3
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +3 -2
- package/src/__tests__/channel-guardian.test.ts +6 -5
- package/src/__tests__/channel-readiness-slack-remote.test.ts +175 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +320 -3
- package/src/__tests__/checker.test.ts +18 -27
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-trail-store.test.ts +264 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +215 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +12 -16
- package/src/__tests__/computer-use-tools.test.ts +14 -18
- package/src/__tests__/config-loader-backfill.test.ts +13 -28
- package/src/__tests__/config-loader-corrupt.test.ts +5 -5
- package/src/__tests__/config-loader-platform-defaults.test.ts +93 -26
- package/src/__tests__/config-loader-quarantine-bulletin.test.ts +3 -3
- package/src/__tests__/config-managed-gemini-defaults.test.ts +3 -4
- package/src/__tests__/config-schema.test.ts +10 -10
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-token-estimator.test.ts +22 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +5 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +231 -2
- package/src/__tests__/conversation-agent-loop.test.ts +581 -54
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -0
- package/src/__tests__/conversation-app-control-instantiation.test.ts +31 -24
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -0
- package/src/__tests__/conversation-attention-store.test.ts +101 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +3 -2
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +61 -0
- package/src/__tests__/conversation-fork-crud.test.ts +239 -15
- package/src/__tests__/conversation-fork-route.test.ts +3 -2
- package/src/__tests__/conversation-history-web-search.test.ts +1 -0
- package/src/__tests__/conversation-inference-profile-list.test.ts +3 -2
- package/src/__tests__/conversation-inference-profile-route.test.ts +3 -2
- package/src/__tests__/conversation-lifecycle.test.ts +53 -11
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -1
- package/src/__tests__/{conversation-load-cleaned-at.test.ts → conversation-load-history-stripped.test.ts} +14 -13
- package/src/__tests__/conversation-pairing.test.ts +53 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +26 -7
- package/src/__tests__/conversation-process-callsite.test.ts +1 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +333 -291
- package/src/__tests__/conversation-routes-disk-view.test.ts +112 -18
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +33 -8
- package/src/__tests__/conversation-routes-slash-commands.test.ts +68 -2
- package/src/__tests__/conversation-runtime-assembly.test.ts +78 -0
- package/src/__tests__/conversation-skill-tools.test.ts +40 -147
- package/src/__tests__/conversation-slash-queue.test.ts +84 -32
- package/src/__tests__/conversation-slash-unknown.test.ts +5 -0
- package/src/__tests__/conversation-speed-override.test.ts +1 -0
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +46 -0
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-standalone.test.ts +6 -3
- package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -3
- package/src/__tests__/conversation-surfaces-table-action.test.ts +7 -17
- package/src/__tests__/conversation-sync-tags.test.ts +218 -35
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +30 -0
- package/src/__tests__/conversation-usage.test.ts +1 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -1
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +19 -19
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +6 -5
- package/src/__tests__/credential-vault-unit.test.ts +21 -21
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +56 -2
- package/src/__tests__/db-connection-isolation.test.ts +7 -6
- package/src/__tests__/db-conversation-fork-lineage-migration.test.ts +8 -10
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +7 -10
- package/src/__tests__/db-llm-request-log-provider-migration.test.ts +9 -15
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +58 -41
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +0 -33
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +26 -40
- package/src/__tests__/document-create-dedupe.test.ts +189 -0
- package/src/__tests__/document-find-replace.test.ts +3 -2
- package/src/__tests__/document-tool-security.test.ts +81 -2
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/encrypted-store-test-helpers.ts +56 -0
- package/src/__tests__/encrypted-store.test.ts +11 -9
- package/src/__tests__/feature-flag-test-helpers.ts +53 -0
- package/src/__tests__/filing-service.test.ts +1 -0
- package/src/__tests__/first-greeting.test.ts +62 -12
- package/src/__tests__/gateway-flag-listener.test.ts +236 -0
- package/src/__tests__/gemini-provider.test.ts +104 -0
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +10 -7
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +5 -0
- package/src/__tests__/heartbeat-service.test.ts +5 -0
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-shell-tool.test.ts +6 -5
- package/src/__tests__/host-transfer-routes-targeted.test.ts +1 -0
- package/src/__tests__/http-conversation-lineage.test.ts +3 -2
- package/src/__tests__/http-user-message-parity.test.ts +29 -7
- package/src/__tests__/identity-intro-cache.test.ts +133 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +44 -72
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-disk-pressure.test.ts +3 -17
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-hidden-metadata.test.ts +80 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +70 -11
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +408 -9
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +16 -2
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/messaging-send-tool.test.ts +1 -0
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +4 -6
- package/src/__tests__/native-web-search.test.ts +30 -2
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/oauth-commands-routes.test.ts +37 -0
- package/src/__tests__/oauth-provider-visibility.test.ts +8 -8
- package/src/__tests__/oauth-store.test.ts +3 -2
- package/src/__tests__/onboarding-template-contract.test.ts +4 -3
- package/src/__tests__/openai-provider.test.ts +54 -9
- package/src/__tests__/openai-responses-provider.test.ts +176 -14
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +46 -1
- package/src/__tests__/pending-interactions-resolved-event.test.ts +0 -1
- package/src/__tests__/persistence-pipeline.test.ts +139 -1
- package/src/__tests__/persistence-secret-redaction.test.ts +83 -12
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -2
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +11 -13
- package/src/__tests__/plugin-tool-contribution.test.ts +50 -40
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +21 -16
- package/src/__tests__/process-message-display-content.test.ts +19 -22
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-platform-proxy-integration.test.ts +216 -4
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +84 -84
- package/src/__tests__/relay-server.test.ts +10 -10
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/schedule-store.test.ts +16 -1
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +5 -1
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +81 -42
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +8 -10
- package/src/__tests__/skill-feature-flags.test.ts +16 -18
- package/src/__tests__/skill-load-feature-flag.test.ts +5 -5
- package/src/__tests__/skill-projection-feature-flag.test.ts +48 -37
- package/src/__tests__/skill-projection.benchmark.test.ts +7 -13
- package/src/__tests__/skill-tool-factory.test.ts +97 -96
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/subagent-call-site-routing.test.ts +11 -3
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +6 -5
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +183 -131
- package/src/__tests__/terminal-tools.test.ts +1 -1
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +35 -12
- package/src/__tests__/tool-executor.test.ts +64 -72
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-preview-lifecycle.test.ts +1 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +3 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +2 -1
- package/src/__tests__/voice-session-bridge.test.ts +37 -28
- package/src/__tests__/workspace-git-service.test.ts +6 -5
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/__tests__/workspace-migration-090-memory-router-cost-optimized-profile.test.ts +326 -0
- package/src/__tests__/workspace-migration-091-retighten-migration-onboarding-thread.test.ts +166 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +6 -7
- package/src/agent/loop.ts +88 -0
- package/src/api/README.md +127 -0
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/events/assistant-outbound-attachment.ts +51 -0
- package/src/api/events/assistant-text-delta.ts +32 -0
- package/src/api/events/assistant-turn-start.ts +33 -0
- package/src/api/events/document-comment-created.ts +48 -0
- package/src/api/events/document-comment-deleted.ts +24 -0
- package/src/api/events/document-comment-reopened.ts +25 -0
- package/src/api/events/document-comment-resolved.ts +27 -0
- package/src/api/events/generation-cancelled.ts +24 -0
- package/src/api/events/generation-handoff.ts +41 -0
- package/src/api/events/message-complete.ts +42 -0
- package/src/api/events/open-url.ts +30 -0
- package/src/api/events/relationship-state-updated.ts +25 -0
- package/src/api/events/tool-use-start.ts +32 -0
- package/src/api/index.ts +129 -0
- package/src/api/package.json +10 -0
- package/src/api/responses/llm-context-response.ts +39 -0
- package/src/api/responses/llm-request-log-entry.ts +93 -0
- package/src/api/responses/memory-recall-log.ts +65 -0
- package/src/api/responses/memory-v2-activation-log.ts +78 -0
- package/src/background-wake/background-wake-routes.test.ts +868 -0
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/voice-session-bridge.ts +4 -4
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +1 -0
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +176 -1
- package/src/cli/commands/memory-v3-render.ts +491 -0
- package/src/cli/commands/memory-v3.ts +567 -0
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +4 -0
- package/src/config/assistant-feature-flags.ts +39 -46
- package/src/config/bundled-skills/document-editor/SKILL.md +16 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +18 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +1 -1
- package/src/config/bundled-skills/schedule/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/call-site-defaults.ts +8 -7
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +33 -17
- package/src/config/llm-context-resolution.ts +10 -1
- package/src/config/llm-resolver.ts +121 -15
- package/src/config/loader.ts +4 -5
- package/src/config/schemas/__tests__/memory-v2.test.ts +228 -1
- package/src/config/schemas/call-site-catalog.ts +21 -7
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +102 -2
- package/src/config/schemas/memory-v2.ts +272 -0
- package/src/config/schemas/memory.ts +2 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +52 -0
- package/src/context/token-estimator.ts +10 -5
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-execution/executable-discovery.ts +40 -0
- package/src/credential-execution/process-manager.ts +6 -2
- package/src/credential-health/credential-health-service.ts +125 -40
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -6
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +13 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +2 -3
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +1 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +390 -80
- package/src/daemon/conversation-agent-loop.ts +244 -90
- package/src/daemon/conversation-error.ts +64 -6
- package/src/daemon/conversation-lifecycle.ts +27 -22
- package/src/daemon/conversation-messaging.ts +84 -43
- package/src/daemon/conversation-process.ts +74 -37
- package/src/daemon/conversation-runtime-assembly.ts +38 -17
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-surfaces.ts +69 -34
- package/src/daemon/conversation-tool-setup.ts +77 -32
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +40 -75
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +9 -2
- package/src/daemon/disk-pressure-guard.ts +39 -29
- package/src/daemon/first-greeting.ts +31 -13
- package/src/daemon/handlers/config-model.test.ts +1 -0
- package/src/daemon/handlers/conversations.ts +11 -3
- package/src/daemon/handlers/shared.ts +6 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +4 -4
- package/src/daemon/host-file-proxy.ts +4 -4
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +10 -10
- package/src/daemon/lifecycle.ts +29 -26
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +11 -24
- package/src/daemon/message-types/conversations.ts +22 -27
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/home.ts +2 -14
- package/src/daemon/message-types/integrations.ts +2 -7
- package/src/daemon/message-types/messages.ts +25 -48
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/process-message.ts +9 -9
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +62 -0
- package/src/daemon/tool-setup-types.ts +7 -0
- package/src/daemon/wake-target-adapter.ts +10 -0
- package/src/documents/document-store.ts +38 -0
- package/src/export/__tests__/transcript-formatter.test.ts +1 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +30 -1
- package/src/heartbeat/heartbeat-service.ts +63 -0
- package/src/home/__tests__/feed-writer.test.ts +161 -0
- package/src/home/__tests__/post-connect-feed.test.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +55 -59
- package/src/home/feed-writer.ts +146 -7
- package/src/home/home-greeting.ts +0 -9
- package/src/home/suggested-prompts.ts +27 -154
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/__tests__/memory.test.ts +1 -0
- package/src/ipc/skill-routes/__tests__/registries.test.ts +36 -7
- package/src/ipc/skill-routes/memory.ts +4 -3
- package/src/ipc/skill-routes/registries.ts +35 -40
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +242 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +26 -5
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +1 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +1 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +31 -0
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +423 -182
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +14 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/db-singleton.ts +77 -0
- package/src/memory/delivery-channels.ts +82 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +2 -4
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +66 -22
- package/src/memory/llm-request-log-source-clickhouse.ts +122 -2
- package/src/memory/llm-request-log-source-local.ts +31 -0
- package/src/memory/llm-request-log-source.ts +40 -2
- package/src/memory/llm-request-log-store.ts +228 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-enqueue.ts +8 -1
- package/src/memory/memory-retrospective-job.ts +5 -0
- package/src/memory/memory-v2-activation-log-store.ts +110 -7
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/index.ts +19 -0
- package/src/memory/migrations/registry.ts +33 -0
- package/src/memory/schema/conversations.ts +10 -2
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +21 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +83 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +230 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +135 -0
- package/src/memory/v2/__tests__/injection.test.ts +127 -98
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +171 -3
- package/src/memory/v2/__tests__/sweep-job.test.ts +6 -3
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +128 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +240 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +112 -0
- package/src/memory/v2/harness/trace.ts +64 -0
- package/src/memory/v2/injection.ts +21 -15
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +171 -18
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +466 -0
- package/src/memory/v3/__tests__/coretrieval-seed.test.ts +270 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +706 -0
- package/src/memory/v3/__tests__/filter.test.ts +560 -0
- package/src/memory/v3/__tests__/gate.test.ts +637 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +291 -0
- package/src/memory/v3/__tests__/loop.test.ts +775 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +489 -0
- package/src/memory/v3/__tests__/shadow-diff.test.ts +225 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +398 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +508 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +784 -0
- package/src/memory/v3/__tests__/validate.test.ts +277 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/coretrieval-seed.ts +240 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +286 -0
- package/src/memory/v3/filter.ts +286 -0
- package/src/memory/v3/gate.ts +349 -0
- package/src/memory/v3/index-composition.ts +126 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +430 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +431 -0
- package/src/memory/v3/shadow-diff.ts +287 -0
- package/src/memory/v3/shadow-middleware.ts +347 -0
- package/src/memory/v3/traversal.ts +211 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +356 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +323 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +23 -3
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +40 -50
- package/src/notifications/signal.ts +10 -0
- package/src/notifications/types.ts +37 -0
- package/src/oauth/byo-connection.test.ts +67 -3
- package/src/oauth/byo-connection.ts +32 -5
- package/src/oauth/connect-orchestrator.ts +9 -0
- package/src/oauth/connection-resolver.test.ts +76 -0
- package/src/oauth/connection-resolver.ts +49 -10
- package/src/oauth/manual-token-connection.ts +51 -3
- package/src/oauth/seed-providers.ts +3 -0
- package/src/permissions/approval-policy.test.ts +19 -5
- package/src/permissions/approval-policy.ts +14 -3
- package/src/permissions/checker.ts +21 -8
- package/src/permissions/prompter.ts +3 -3
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +2 -2
- package/src/platform/client.test.ts +24 -1
- package/src/platform/client.ts +8 -0
- package/src/platform/feature-gate.ts +15 -0
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +20 -19
- package/src/plugins/defaults/persistence.ts +25 -6
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +68 -29
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/proactive-artifact/job.test.ts +1 -0
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +39 -7
- package/src/prompts/system-prompt.ts +84 -221
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP.md +9 -13
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +230 -8
- package/src/providers/__tests__/connection-model-compat.test.ts +233 -0
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +32 -66
- package/src/providers/call-site-routing.ts +42 -6
- package/src/providers/connection-model-compat.ts +61 -0
- package/src/providers/connection-resolution.ts +47 -14
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +70 -6
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +78 -1
- package/src/providers/model-intents.ts +4 -4
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -5
- package/src/providers/openai/chat-completions-provider.ts +116 -15
- package/src/providers/openai/codex-models.ts +20 -0
- package/src/providers/openai/responses-provider.ts +87 -30
- package/src/providers/openrouter/client.ts +13 -8
- package/src/providers/provider-send-message.ts +20 -5
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +50 -7
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +9 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +1 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +1 -0
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +1 -0
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +46 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-readiness-service.ts +68 -0
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +47 -14
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/http-types.ts +0 -2
- package/src/runtime/migrations/vbundle-builder.ts +12 -4
- package/src/runtime/pending-interactions.ts +0 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +406 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +204 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +13 -50
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +76 -9
- package/src/runtime/routes/__tests__/memory-v3-simulate-params.test.ts +35 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +294 -0
- package/src/runtime/routes/__tests__/task-routes.test.ts +48 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/app-management-routes.ts +111 -4
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +356 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +4 -10
- package/src/runtime/routes/conversation-analysis-routes.ts +6 -0
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-compaction-routes.ts +263 -0
- package/src/runtime/routes/conversation-list-routes.ts +159 -4
- package/src/runtime/routes/conversation-management-routes.ts +108 -26
- package/src/runtime/routes/conversation-query-routes.ts +200 -44
- package/src/runtime/routes/conversation-routes.ts +409 -521
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/conversations-import-routes.ts +19 -6
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/documents-routes.ts +10 -1
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +35 -8
- package/src/runtime/routes/home-feed-routes.ts +129 -0
- package/src/runtime/routes/host-browser-routes.ts +10 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-intro-cache.ts +61 -16
- package/src/runtime/routes/identity-routes.ts +30 -9
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +530 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +57 -8
- package/src/runtime/routes/index.ts +10 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +5 -26
- package/src/runtime/routes/integrations/vercel.ts +15 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +215 -5
- package/src/runtime/routes/memory-v3-routes.ts +474 -0
- package/src/runtime/routes/migration-routes.ts +32 -28
- package/src/runtime/routes/notification-routes.ts +63 -1
- package/src/runtime/routes/oauth-commands-routes.ts +6 -1
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +5 -4
- package/src/runtime/routes/surface-action-routes.ts +1 -38
- package/src/runtime/routes/surface-content-routes.ts +12 -5
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +3 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -0
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/schedule-store.ts +8 -1
- package/src/schedule/scheduler.ts +111 -15
- package/src/security/__tests__/provider-key-env-fallback.test.ts +3 -3
- package/src/security/encrypted-store.ts +7 -16
- package/src/security/store-path-override.ts +61 -0
- package/src/signals/user-message.ts +5 -8
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +13 -13
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +36 -28
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +70 -0
- package/src/tools/browser/browser-execution.ts +16 -3
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +3 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +12 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +27 -1
- package/src/tools/browser/cdp-client/factory.ts +100 -17
- package/src/tools/browser/cdp-client/local-cdp-client.ts +12 -0
- package/src/tools/browser/cdp-client/types.ts +65 -0
- package/src/tools/browser/pinned-tabs.ts +96 -40
- package/src/tools/computer-use/definitions.ts +282 -336
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-tool.ts +189 -7
- package/src/tools/execution-target.ts +18 -23
- package/src/tools/executor.ts +24 -56
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -10
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/managed-search-proxy.test.ts +282 -0
- package/src/tools/network/__tests__/web-search.test.ts +211 -3
- package/src/tools/network/managed-search-proxy.ts +183 -0
- package/src/tools/network/web-fetch.ts +3 -9
- package/src/tools/network/web-search.ts +224 -76
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +150 -123
- package/src/tools/schedule/create.ts +1 -1
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +18 -44
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +32 -101
- package/src/tools/ui-surface/definitions.ts +104 -108
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/browser.ts +7 -2
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -2
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/090-memory-router-cost-optimized-profile.ts +109 -0
- package/src/workspace/migrations/091-retighten-migration-onboarding-thread.ts +41 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/daemon/query-complexity-router.ts +0 -75
- package/src/prompts/cache-boundary.ts +0 -8
|
@@ -106,6 +106,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
106
106
|
provenanceFromTrustContext: () => undefined,
|
|
107
107
|
setConversationOriginChannelIfUnset: () => {},
|
|
108
108
|
setConversationOriginInterfaceIfUnset: () => {},
|
|
109
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
109
110
|
}));
|
|
110
111
|
|
|
111
112
|
mock.module("../runtime/local-actor-identity.js", () => ({
|
|
@@ -187,7 +188,10 @@ function makeRequest(
|
|
|
187
188
|
});
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
const persistUserMessageMock = mock(async () =>
|
|
191
|
+
const persistUserMessageMock = mock(async () => ({
|
|
192
|
+
id: "persisted-id",
|
|
193
|
+
deduplicated: false,
|
|
194
|
+
}));
|
|
191
195
|
const runAgentLoopMock = mock(async () => undefined);
|
|
192
196
|
|
|
193
197
|
function makeSendMessageDeps() {
|
|
@@ -25,7 +25,6 @@ mock.module("../util/logger.js", () => ({
|
|
|
25
25
|
|
|
26
26
|
import type { CesClient } from "../credential-execution/client.js";
|
|
27
27
|
import * as encryptedStore from "../security/encrypted-store.js";
|
|
28
|
-
import { _setStorePath } from "../security/encrypted-store.js";
|
|
29
28
|
import {
|
|
30
29
|
_resetBackend,
|
|
31
30
|
deleteSecureKeyAsync,
|
|
@@ -36,6 +35,7 @@ import {
|
|
|
36
35
|
setCesReconnect,
|
|
37
36
|
setSecureKeyAsync,
|
|
38
37
|
} from "../security/secure-keys.js";
|
|
38
|
+
import { setStorePathForTesting } from "./encrypted-store-test-helpers.js";
|
|
39
39
|
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
41
41
|
// Use a temp directory for encrypted store tests
|
|
@@ -59,11 +59,11 @@ describe("secure-keys", () => {
|
|
|
59
59
|
rmSync(TEST_DIR, { recursive: true });
|
|
60
60
|
}
|
|
61
61
|
mkdirSync(TEST_DIR, { recursive: true });
|
|
62
|
-
|
|
62
|
+
setStorePathForTesting(STORE_PATH);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
afterEach(() => {
|
|
66
|
-
|
|
66
|
+
setStorePathForTesting(null);
|
|
67
67
|
_resetBackend();
|
|
68
68
|
delete process.env.VELLUM_DEV;
|
|
69
69
|
delete process.env.VELLUM_DESKTOP_APP;
|
|
@@ -136,13 +136,9 @@ function makeCompletingConversation(): Conversation {
|
|
|
136
136
|
const messages: unknown[] = [];
|
|
137
137
|
return {
|
|
138
138
|
isProcessing: () => processing,
|
|
139
|
-
persistUserMessage: (
|
|
140
|
-
_content: string,
|
|
141
|
-
_attachments: unknown[],
|
|
142
|
-
requestId?: string,
|
|
143
|
-
) => {
|
|
139
|
+
persistUserMessage: (options: { requestId?: string }) => {
|
|
144
140
|
processing = true;
|
|
145
|
-
return requestId ?? "msg-1";
|
|
141
|
+
return { id: options.requestId ?? "msg-1", deduplicated: false };
|
|
146
142
|
},
|
|
147
143
|
memoryPolicy: {
|
|
148
144
|
scopeId: "default",
|
|
@@ -188,18 +184,14 @@ function makeHangingConversation(): Conversation {
|
|
|
188
184
|
const messages: unknown[] = [];
|
|
189
185
|
const enqueuedMessages: Array<{
|
|
190
186
|
content: string;
|
|
191
|
-
onEvent
|
|
192
|
-
requestId
|
|
187
|
+
onEvent?: (msg: ServerMessage) => void;
|
|
188
|
+
requestId?: string;
|
|
193
189
|
}> = [];
|
|
194
190
|
return {
|
|
195
191
|
isProcessing: () => processing,
|
|
196
|
-
persistUserMessage: (
|
|
197
|
-
_content: string,
|
|
198
|
-
_attachments: unknown[],
|
|
199
|
-
requestId?: string,
|
|
200
|
-
) => {
|
|
192
|
+
persistUserMessage: (options: { requestId?: string }) => {
|
|
201
193
|
processing = true;
|
|
202
|
-
return requestId ?? "msg-1";
|
|
194
|
+
return { id: options.requestId ?? "msg-1", deduplicated: false };
|
|
203
195
|
},
|
|
204
196
|
memoryPolicy: {
|
|
205
197
|
scopeId: "default",
|
|
@@ -223,14 +215,20 @@ function makeHangingConversation(): Conversation {
|
|
|
223
215
|
hasPendingConfirmation: () => false,
|
|
224
216
|
denyAllPendingConfirmations: () => {},
|
|
225
217
|
getQueueDepth: () => enqueuedMessages.length,
|
|
226
|
-
enqueueMessage: (
|
|
227
|
-
content: string
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
218
|
+
enqueueMessage: (options: {
|
|
219
|
+
content: string;
|
|
220
|
+
onEvent?: (msg: ServerMessage) => void;
|
|
221
|
+
requestId?: string;
|
|
222
|
+
}) => {
|
|
223
|
+
enqueuedMessages.push({
|
|
224
|
+
content: options.content,
|
|
225
|
+
onEvent: options.onEvent,
|
|
226
|
+
requestId: options.requestId,
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
queued: true,
|
|
230
|
+
requestId: options.requestId ?? "hanging-req",
|
|
231
|
+
};
|
|
234
232
|
},
|
|
235
233
|
runAgentLoop: async () => {
|
|
236
234
|
// Hang forever
|
|
@@ -259,14 +257,9 @@ function makePendingApprovalConversation(
|
|
|
259
257
|
const messages: unknown[] = [];
|
|
260
258
|
const runAgentLoopMock = mock(async () => {});
|
|
261
259
|
const enqueueMessageMock = mock(
|
|
262
|
-
(
|
|
263
|
-
_content: string,
|
|
264
|
-
_attachments: unknown[],
|
|
265
|
-
_onEvent: (msg: ServerMessage) => void,
|
|
266
|
-
queuedRequestId: string,
|
|
267
|
-
) => ({
|
|
260
|
+
(options: { content: string; requestId?: string }) => ({
|
|
268
261
|
queued: true,
|
|
269
|
-
requestId:
|
|
262
|
+
requestId: options.requestId ?? "queued-req",
|
|
270
263
|
}),
|
|
271
264
|
);
|
|
272
265
|
const denyAllPendingConfirmationsMock = mock(() => {
|
|
@@ -278,11 +271,10 @@ function makePendingApprovalConversation(
|
|
|
278
271
|
|
|
279
272
|
const conversation = {
|
|
280
273
|
isProcessing: () => processing,
|
|
281
|
-
persistUserMessage: (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
) => reqId ?? "msg-1",
|
|
274
|
+
persistUserMessage: (options: { requestId?: string }) => ({
|
|
275
|
+
id: options.requestId ?? "msg-1",
|
|
276
|
+
deduplicated: false,
|
|
277
|
+
}),
|
|
286
278
|
memoryPolicy: {
|
|
287
279
|
scopeId: "default",
|
|
288
280
|
includeDefaultFallback: false,
|
|
@@ -895,7 +887,7 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
895
887
|
await stopServer();
|
|
896
888
|
});
|
|
897
889
|
|
|
898
|
-
test("accepts message when conversationKey is omitted (
|
|
890
|
+
test("accepts message when conversationKey is omitted (vellum channel mints fresh)", async () => {
|
|
899
891
|
await startServer(() => makeCompletingConversation());
|
|
900
892
|
|
|
901
893
|
const res = await fetch(messagesUrl(), {
|
|
@@ -908,14 +900,24 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
908
900
|
}),
|
|
909
901
|
});
|
|
910
902
|
expect(res.status).toBe(202);
|
|
903
|
+
const body = (await res.json()) as {
|
|
904
|
+
accepted: boolean;
|
|
905
|
+
conversationId: string;
|
|
906
|
+
};
|
|
907
|
+
expect(body.accepted).toBe(true);
|
|
908
|
+
expect(body.conversationId).toBeTruthy();
|
|
909
|
+
|
|
910
|
+
// The vellum channel never falls through to the shared
|
|
911
|
+
// `default:vellum:<interface>` thread: each empty-handed send mints
|
|
912
|
+
// a fresh conversation so the first-message id surfaces to the client.
|
|
913
|
+
expect(getConversationByKey("default:vellum:macos")).toBeNull();
|
|
911
914
|
|
|
912
915
|
await stopServer();
|
|
913
916
|
});
|
|
914
917
|
|
|
915
|
-
test("two
|
|
918
|
+
test("two empty-handed vellum sends each mint distinct conversations", async () => {
|
|
916
919
|
await startServer(() => makeCompletingConversation());
|
|
917
920
|
|
|
918
|
-
// First message — no conversationKey
|
|
919
921
|
const res1 = await fetch(messagesUrl(), {
|
|
920
922
|
method: "POST",
|
|
921
923
|
headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
|
|
@@ -926,8 +928,8 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
926
928
|
}),
|
|
927
929
|
});
|
|
928
930
|
expect(res1.status).toBe(202);
|
|
931
|
+
const body1 = (await res1.json()) as { conversationId: string };
|
|
929
932
|
|
|
930
|
-
// Second message — same channel/interface, still no conversationKey
|
|
931
933
|
const res2 = await fetch(messagesUrl(), {
|
|
932
934
|
method: "POST",
|
|
933
935
|
headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
|
|
@@ -938,12 +940,49 @@ describe("POST /v1/messages — queue-if-busy and hub publishing", () => {
|
|
|
938
940
|
}),
|
|
939
941
|
});
|
|
940
942
|
expect(res2.status).toBe(202);
|
|
943
|
+
const body2 = (await res2.json()) as { conversationId: string };
|
|
944
|
+
|
|
945
|
+
expect(body1.conversationId).toBeTruthy();
|
|
946
|
+
expect(body2.conversationId).toBeTruthy();
|
|
947
|
+
expect(body1.conversationId).not.toBe(body2.conversationId);
|
|
948
|
+
|
|
949
|
+
await stopServer();
|
|
950
|
+
});
|
|
951
|
+
|
|
952
|
+
test("two empty-handed phone sends share the default channel thread", async () => {
|
|
953
|
+
await startServer(() => makeCompletingConversation());
|
|
954
|
+
|
|
955
|
+
const res1 = await fetch(messagesUrl(), {
|
|
956
|
+
method: "POST",
|
|
957
|
+
headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
|
|
958
|
+
body: JSON.stringify({
|
|
959
|
+
content: "First",
|
|
960
|
+
sourceChannel: "phone",
|
|
961
|
+
interface: "phone",
|
|
962
|
+
}),
|
|
963
|
+
});
|
|
964
|
+
expect(res1.status).toBe(202);
|
|
965
|
+
const body1 = (await res1.json()) as { conversationId: string };
|
|
966
|
+
|
|
967
|
+
const res2 = await fetch(messagesUrl(), {
|
|
968
|
+
method: "POST",
|
|
969
|
+
headers: { "Content-Type": "application/json", ...AUTH_HEADERS },
|
|
970
|
+
body: JSON.stringify({
|
|
971
|
+
content: "Second",
|
|
972
|
+
sourceChannel: "phone",
|
|
973
|
+
interface: "phone",
|
|
974
|
+
}),
|
|
975
|
+
});
|
|
976
|
+
expect(res2.status).toBe(202);
|
|
977
|
+
const body2 = (await res2.json()) as { conversationId: string };
|
|
941
978
|
|
|
942
|
-
//
|
|
943
|
-
//
|
|
944
|
-
|
|
979
|
+
// Non-vellum channels keep the legacy `default:<channel>:<interface>`
|
|
980
|
+
// co-location so repeated inbound messages from the same external
|
|
981
|
+
// channel/interface land on a single thread.
|
|
982
|
+
expect(body1.conversationId).toBe(body2.conversationId);
|
|
983
|
+
const mapping = getConversationByKey("default:phone:phone");
|
|
945
984
|
expect(mapping).not.toBeNull();
|
|
946
|
-
expect(mapping!.conversationId).
|
|
985
|
+
expect(mapping!.conversationId).toBe(body1.conversationId);
|
|
947
986
|
|
|
948
987
|
await stopServer();
|
|
949
988
|
});
|
|
@@ -578,7 +578,10 @@ describe("getAttachmentsForMessage", () => {
|
|
|
578
578
|
db.run("DELETE FROM conversations");
|
|
579
579
|
});
|
|
580
580
|
|
|
581
|
-
async function createMessage(
|
|
581
|
+
async function createMessage(
|
|
582
|
+
role: "user" | "assistant" | "system",
|
|
583
|
+
content: string,
|
|
584
|
+
): Promise<string> {
|
|
582
585
|
const conv = createConversation("test");
|
|
583
586
|
const msg = await addMessage(conv.id, role, content);
|
|
584
587
|
return msg.id;
|
|
@@ -287,7 +287,7 @@ describe("shell tool proxy mode", () => {
|
|
|
287
287
|
});
|
|
288
288
|
|
|
289
289
|
test("schema includes network_mode and credential_ids", () => {
|
|
290
|
-
const def = shellTool
|
|
290
|
+
const def = shellTool;
|
|
291
291
|
const props = (def.input_schema as { properties: Record<string, unknown> })
|
|
292
292
|
.properties;
|
|
293
293
|
expect(props.network_mode).toBeDefined();
|
|
@@ -7,17 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
9
9
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
isAssistantFeatureFlagEnabled,
|
|
13
|
-
} from "../config/assistant-feature-flags.js";
|
|
10
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
11
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
14
12
|
|
|
15
13
|
beforeEach(() => {
|
|
16
|
-
|
|
14
|
+
setOverridesForTesting({});
|
|
17
15
|
});
|
|
18
16
|
|
|
19
17
|
afterEach(() => {
|
|
20
|
-
|
|
18
|
+
setOverridesForTesting({});
|
|
21
19
|
});
|
|
22
20
|
import type { AssistantConfig } from "../config/schema.js";
|
|
23
21
|
import { resolveSkillStates, skillFlagKey } from "../config/skill-state.js";
|
|
@@ -150,7 +148,7 @@ describe("frontmatter feature-flag integration", () => {
|
|
|
150
148
|
});
|
|
151
149
|
|
|
152
150
|
test("resolveSkillStates includes skill with featureFlag when flag is ON", () => {
|
|
153
|
-
|
|
151
|
+
setOverridesForTesting({
|
|
154
152
|
"email-channel": true,
|
|
155
153
|
});
|
|
156
154
|
const skill = buildSkillSummary("email-setup", SKILL_MD_WITH_FLAG)!;
|
|
@@ -174,7 +172,7 @@ describe("frontmatter feature-flag integration", () => {
|
|
|
174
172
|
test("resolveSkillStates never gates skill without featureFlag", () => {
|
|
175
173
|
const skill = buildSkillSummary("plain-skill", SKILL_MD_WITHOUT_FLAG)!;
|
|
176
174
|
// Even with an explicit false override for this skill ID, it should pass through
|
|
177
|
-
|
|
175
|
+
setOverridesForTesting({
|
|
178
176
|
"plain-skill": false,
|
|
179
177
|
});
|
|
180
178
|
const config = makeConfig();
|
|
@@ -210,7 +208,7 @@ describe("frontmatter feature-flag integration", () => {
|
|
|
210
208
|
expect(resolvedDefault.length).toBe(0);
|
|
211
209
|
|
|
212
210
|
// Step 6: With override enabled, skill passes through
|
|
213
|
-
|
|
211
|
+
setOverridesForTesting({ [key!]: true });
|
|
214
212
|
const configOn = makeConfig();
|
|
215
213
|
expect(isAssistantFeatureFlagEnabled(key!, configOn)).toBe(true);
|
|
216
214
|
|
|
@@ -219,7 +217,7 @@ describe("frontmatter feature-flag integration", () => {
|
|
|
219
217
|
expect(resolvedOn[0].summary.id).toBe("email-setup");
|
|
220
218
|
|
|
221
219
|
// Step 7: With override disabled, skill is filtered out
|
|
222
|
-
|
|
220
|
+
setOverridesForTesting({ [key!]: false });
|
|
223
221
|
const configOff = makeConfig();
|
|
224
222
|
expect(isAssistantFeatureFlagEnabled(key!, configOff)).toBe(false);
|
|
225
223
|
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
_setOverridesForTesting,
|
|
5
|
-
isAssistantFeatureFlagEnabled,
|
|
6
|
-
} from "../config/assistant-feature-flags.js";
|
|
3
|
+
import { isAssistantFeatureFlagEnabled } from "../config/assistant-feature-flags.js";
|
|
7
4
|
import type { AssistantConfig } from "../config/schema.js";
|
|
8
5
|
import { resolveSkillStates, skillFlagKey } from "../config/skill-state.js";
|
|
9
6
|
import type { SkillSummary } from "../config/skills.js";
|
|
7
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
10
8
|
|
|
11
9
|
beforeEach(() => {
|
|
12
|
-
|
|
10
|
+
setOverridesForTesting({});
|
|
13
11
|
});
|
|
14
12
|
|
|
15
13
|
afterEach(() => {
|
|
16
|
-
|
|
14
|
+
setOverridesForTesting({});
|
|
17
15
|
});
|
|
18
16
|
|
|
19
17
|
const DECLARED_FLAG_ID = "email-channel";
|
|
@@ -103,7 +101,7 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
|
|
|
103
101
|
});
|
|
104
102
|
|
|
105
103
|
test("returns true when skill key is explicitly true", () => {
|
|
106
|
-
|
|
104
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
|
|
107
105
|
const config = makeConfig();
|
|
108
106
|
expect(
|
|
109
107
|
isAssistantFeatureFlagEnabled(
|
|
@@ -114,7 +112,7 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
|
|
|
114
112
|
});
|
|
115
113
|
|
|
116
114
|
test("returns false when skill key is explicitly false", () => {
|
|
117
|
-
|
|
115
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
118
116
|
const config = makeConfig();
|
|
119
117
|
expect(
|
|
120
118
|
isAssistantFeatureFlagEnabled(
|
|
@@ -130,13 +128,13 @@ describe("isAssistantFeatureFlagEnabled with skillFlagKey", () => {
|
|
|
130
128
|
// ---------------------------------------------------------------------------
|
|
131
129
|
|
|
132
130
|
describe("isAssistantFeatureFlagEnabled", () => {
|
|
133
|
-
test("returns
|
|
131
|
+
test("returns false for unknown flags (closed by default)", () => {
|
|
134
132
|
const config = makeConfig();
|
|
135
|
-
expect(isAssistantFeatureFlagEnabled("unknown", config)).toBe(
|
|
133
|
+
expect(isAssistantFeatureFlagEnabled("unknown", config)).toBe(false);
|
|
136
134
|
});
|
|
137
135
|
|
|
138
136
|
test("file-based override overrides registry default", () => {
|
|
139
|
-
|
|
137
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
140
138
|
const config = makeConfig();
|
|
141
139
|
expect(isAssistantFeatureFlagEnabled(DECLARED_FLAG_KEY, config)).toBe(
|
|
142
140
|
false,
|
|
@@ -152,7 +150,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
152
150
|
});
|
|
153
151
|
|
|
154
152
|
test("respects persisted overrides for undeclared keys", () => {
|
|
155
|
-
|
|
153
|
+
setOverridesForTesting({ "some-undeclared-flag": false });
|
|
156
154
|
const config = makeConfig();
|
|
157
155
|
expect(isAssistantFeatureFlagEnabled("some-undeclared-flag", config)).toBe(
|
|
158
156
|
false,
|
|
@@ -166,7 +164,7 @@ describe("isAssistantFeatureFlagEnabled", () => {
|
|
|
166
164
|
|
|
167
165
|
describe("resolveSkillStates with feature flags", () => {
|
|
168
166
|
test("flag OFF skill does not appear in resolved list", () => {
|
|
169
|
-
|
|
167
|
+
setOverridesForTesting({
|
|
170
168
|
[DECLARED_FLAG_KEY]: false,
|
|
171
169
|
[ENABLED_UNDECLARED_FLAG_KEY]: true,
|
|
172
170
|
});
|
|
@@ -188,7 +186,7 @@ describe("resolveSkillStates with feature flags", () => {
|
|
|
188
186
|
});
|
|
189
187
|
|
|
190
188
|
test("flag ON skill appears normally", () => {
|
|
191
|
-
|
|
189
|
+
setOverridesForTesting({
|
|
192
190
|
[DECLARED_FLAG_KEY]: true,
|
|
193
191
|
[ENABLED_UNDECLARED_FLAG_KEY]: true,
|
|
194
192
|
});
|
|
@@ -230,7 +228,7 @@ describe("resolveSkillStates with feature flags", () => {
|
|
|
230
228
|
});
|
|
231
229
|
|
|
232
230
|
test("feature flag OFF takes precedence over user-enabled config entry", () => {
|
|
233
|
-
|
|
231
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
234
232
|
const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
|
|
235
233
|
const config = makeConfig({
|
|
236
234
|
skills: {
|
|
@@ -256,7 +254,7 @@ describe("resolveSkillStates with feature flags", () => {
|
|
|
256
254
|
});
|
|
257
255
|
|
|
258
256
|
test("multiple skills with mixed flags — persisted overrides respected", () => {
|
|
259
|
-
|
|
257
|
+
setOverridesForTesting({
|
|
260
258
|
[DECLARED_FLAG_KEY]: false,
|
|
261
259
|
[ENABLED_UNDECLARED_FLAG_KEY]: true,
|
|
262
260
|
deploy: false,
|
|
@@ -296,7 +294,7 @@ describe("resolveSkillStates with frontmatter featureFlag", () => {
|
|
|
296
294
|
});
|
|
297
295
|
|
|
298
296
|
test("skill with featureFlag is included when override enables it", () => {
|
|
299
|
-
|
|
297
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
|
|
300
298
|
const catalog = [makeSkill(DECLARED_SKILL_ID, "bundled", DECLARED_FLAG_ID)];
|
|
301
299
|
const config = makeConfig();
|
|
302
300
|
|
|
@@ -320,7 +318,7 @@ describe("resolveSkillStates with frontmatter featureFlag", () => {
|
|
|
320
318
|
// This proves the implicit skillId→flag mapping is gone:
|
|
321
319
|
// setting feature_flags.my-skill.enabled = false has no effect
|
|
322
320
|
// when the skill itself does not declare a featureFlag.
|
|
323
|
-
|
|
321
|
+
setOverridesForTesting({
|
|
324
322
|
"my-skill": false,
|
|
325
323
|
});
|
|
326
324
|
const catalog = [makeSkill("my-skill")];
|
|
@@ -6,7 +6,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
|
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { setOverridesForTesting } from "./feature-flag-test-helpers.js";
|
|
10
10
|
|
|
11
11
|
const TEST_DIR = process.env.VELLUM_WORKSPACE_DIR!;
|
|
12
12
|
|
|
@@ -89,11 +89,11 @@ describe("skill_load feature flag enforcement", () => {
|
|
|
89
89
|
beforeEach(() => {
|
|
90
90
|
mkdirSync(join(TEST_DIR, "skills"), { recursive: true });
|
|
91
91
|
currentConfig = {};
|
|
92
|
-
|
|
92
|
+
setOverridesForTesting({});
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
afterEach(() => {
|
|
96
|
-
|
|
96
|
+
setOverridesForTesting({});
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
test("returns deterministic error for flag OFF skill", async () => {
|
|
@@ -104,7 +104,7 @@ describe("skill_load feature flag enforcement", () => {
|
|
|
104
104
|
"Use the feature.",
|
|
105
105
|
);
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
108
108
|
|
|
109
109
|
const result = await executeSkillLoad({ skill: DECLARED_SKILL_ID });
|
|
110
110
|
|
|
@@ -121,7 +121,7 @@ describe("skill_load feature flag enforcement", () => {
|
|
|
121
121
|
"Use the feature.",
|
|
122
122
|
);
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
|
|
125
125
|
|
|
126
126
|
const result = await executeSkillLoad({ skill: DECLARED_SKILL_ID });
|
|
127
127
|
|
|
@@ -45,20 +45,26 @@ mock.module("../config/skill-state.js", () => ({
|
|
|
45
45
|
|
|
46
46
|
// Mock assistant-feature-flags to avoid loading the real module (which
|
|
47
47
|
// triggers file I/O and env-registry imports that hang in test context).
|
|
48
|
+
// The seed-state backdoor is the test-only helper module — we mirror
|
|
49
|
+
// production's design: tests reach into `feature-flag-cache.ts` (or its
|
|
50
|
+
// test-helper wrapper) to seed cached overrides, never through the
|
|
51
|
+
// resolver module itself.
|
|
48
52
|
let _mockOverrides: Record<string, boolean> = {};
|
|
49
53
|
mock.module("../config/assistant-feature-flags.js", () => ({
|
|
50
54
|
isAssistantFeatureFlagEnabled: (key: string, _config: unknown): boolean => {
|
|
51
55
|
const explicit = _mockOverrides[key];
|
|
52
56
|
if (typeof explicit === "boolean") return explicit;
|
|
53
|
-
return
|
|
57
|
+
return false; // undeclared flags default to disabled
|
|
54
58
|
},
|
|
55
59
|
clearFeatureFlagOverridesCache: () => {
|
|
56
60
|
_mockOverrides = {};
|
|
57
61
|
},
|
|
58
|
-
|
|
62
|
+
getAssistantFeatureFlagDefaults: () => ({}),
|
|
63
|
+
}));
|
|
64
|
+
mock.module("./feature-flag-test-helpers.js", () => ({
|
|
65
|
+
setOverridesForTesting: (overrides: Record<string, boolean>) => {
|
|
59
66
|
_mockOverrides = { ...overrides };
|
|
60
67
|
},
|
|
61
|
-
getAssistantFeatureFlagDefaults: () => ({}),
|
|
62
68
|
}));
|
|
63
69
|
|
|
64
70
|
mock.module("../skills/active-skill-tools.js", () => {
|
|
@@ -109,45 +115,35 @@ mock.module("../skills/tool-manifest.js", () => ({
|
|
|
109
115
|
}));
|
|
110
116
|
|
|
111
117
|
mock.module("../tools/skills/skill-tool-factory.js", () => ({
|
|
118
|
+
// Mirrors the real factory: no skillId in/out — ownership is recorded by
|
|
119
|
+
// the registry at `registerSkillTools(skillId, tools)` time.
|
|
112
120
|
createSkillToolsFromManifest: (
|
|
113
121
|
entries: SkillToolManifest["tools"],
|
|
114
|
-
skillId: string,
|
|
115
122
|
_skillDir: string,
|
|
116
|
-
|
|
117
|
-
|
|
123
|
+
_versionHash: string,
|
|
124
|
+
_bundled?: boolean,
|
|
118
125
|
): Tool[] => {
|
|
119
126
|
return entries.map((entry) => ({
|
|
120
127
|
name: entry.name,
|
|
121
128
|
description: entry.description,
|
|
122
129
|
category: entry.category,
|
|
123
130
|
defaultRiskLevel: RiskLevel.Medium,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
ownerSkillVersionHash: versionHash,
|
|
127
|
-
ownerSkillBundled: bundled ?? undefined,
|
|
128
|
-
getDefinition: () => ({
|
|
129
|
-
name: entry.name,
|
|
130
|
-
description: entry.description,
|
|
131
|
-
input_schema: entry.input_schema as object,
|
|
132
|
-
}),
|
|
131
|
+
executionTarget: "sandbox" as const,
|
|
132
|
+
input_schema: entry.input_schema as object,
|
|
133
133
|
execute: async () => ({ content: "", isError: false }),
|
|
134
134
|
}));
|
|
135
135
|
},
|
|
136
136
|
}));
|
|
137
137
|
|
|
138
138
|
mock.module("../tools/registry.js", () => ({
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
for (const id of skillIds) {
|
|
149
|
-
mockSkillRefCount.set(id, (mockSkillRefCount.get(id) ?? 0) + 1);
|
|
150
|
-
}
|
|
139
|
+
// Matches the new signature: `registerSkillTools(skillId, tools)`. The
|
|
140
|
+
// skillId comes from the caller (conversation-skill-tools) and is the
|
|
141
|
+
// sole source of truth for ownership.
|
|
142
|
+
registerSkillTools: (skillId: string, tools: Tool[]) => {
|
|
143
|
+
const existing = mockRegisteredTools.get(skillId) ?? [];
|
|
144
|
+
existing.push(...tools);
|
|
145
|
+
mockRegisteredTools.set(skillId, existing);
|
|
146
|
+
mockSkillRefCount.set(skillId, (mockSkillRefCount.get(skillId) ?? 0) + 1);
|
|
151
147
|
return tools;
|
|
152
148
|
},
|
|
153
149
|
unregisterSkillTools: (skillId: string) => {
|
|
@@ -169,6 +165,23 @@ mock.module("../tools/registry.js", () => ({
|
|
|
169
165
|
}
|
|
170
166
|
return found;
|
|
171
167
|
},
|
|
168
|
+
// Mirrors the registry's `ownersByName` accessor: derives the owning
|
|
169
|
+
// skillId from `mockRegisteredTools` keying so the production
|
|
170
|
+
// `getToolOwner(name)` call in `conversation-skill-tools.ts` resolves to
|
|
171
|
+
// the same shape the real registry would return.
|
|
172
|
+
getToolOwner: (
|
|
173
|
+
name: string,
|
|
174
|
+
): { kind: "skill" | "plugin" | "mcp"; id: string } | undefined => {
|
|
175
|
+
let ownerSkillId: string | undefined;
|
|
176
|
+
for (const [skillId, tools] of mockRegisteredTools.entries()) {
|
|
177
|
+
for (const tool of tools) {
|
|
178
|
+
if (tool.name === name) ownerSkillId = skillId;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return ownerSkillId === undefined
|
|
182
|
+
? undefined
|
|
183
|
+
: { kind: "skill", id: ownerSkillId };
|
|
184
|
+
},
|
|
172
185
|
getSkillToolNames: () => {
|
|
173
186
|
const names: string[] = [];
|
|
174
187
|
for (const tools of mockRegisteredTools.values()) {
|
|
@@ -215,10 +228,8 @@ mock.module("../util/logger.js", () => ({
|
|
|
215
228
|
|
|
216
229
|
const { projectSkillTools, resetSkillToolProjection } =
|
|
217
230
|
await import("../daemon/conversation-skill-tools.js");
|
|
218
|
-
const {
|
|
219
|
-
|
|
220
|
-
_setOverridesForTesting: (o: Record<string, boolean>) => void;
|
|
221
|
-
};
|
|
231
|
+
const { setOverridesForTesting } =
|
|
232
|
+
await import("./feature-flag-test-helpers.js");
|
|
222
233
|
|
|
223
234
|
// ---------------------------------------------------------------------------
|
|
224
235
|
// Helpers
|
|
@@ -292,12 +303,12 @@ describe("projectSkillTools feature flag enforcement", () => {
|
|
|
292
303
|
mockUnregisteredSkillIds = [];
|
|
293
304
|
mockSkillRefCount = new Map();
|
|
294
305
|
currentConfig = {};
|
|
295
|
-
|
|
306
|
+
setOverridesForTesting({});
|
|
296
307
|
resetSkillToolProjection();
|
|
297
308
|
});
|
|
298
309
|
|
|
299
310
|
afterEach(() => {
|
|
300
|
-
|
|
311
|
+
setOverridesForTesting({});
|
|
301
312
|
});
|
|
302
313
|
|
|
303
314
|
test("no skill tools projected for flag OFF skill even with old markers", () => {
|
|
@@ -311,7 +322,7 @@ describe("projectSkillTools feature flag enforcement", () => {
|
|
|
311
322
|
const prevActive = new Map<string, string>();
|
|
312
323
|
|
|
313
324
|
// Feature flag is OFF — use protected directory override
|
|
314
|
-
|
|
325
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
315
326
|
|
|
316
327
|
const result = projectSkillTools(history, {
|
|
317
328
|
previouslyActiveSkillIds: prevActive,
|
|
@@ -332,7 +343,7 @@ describe("projectSkillTools feature flag enforcement", () => {
|
|
|
332
343
|
const prevActive = new Map<string, string>();
|
|
333
344
|
|
|
334
345
|
// Feature flag is ON — use protected directory override
|
|
335
|
-
|
|
346
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: true });
|
|
336
347
|
|
|
337
348
|
const result = projectSkillTools(history, {
|
|
338
349
|
previouslyActiveSkillIds: prevActive,
|
|
@@ -422,8 +433,8 @@ describe("projectSkillTools feature flag enforcement", () => {
|
|
|
422
433
|
];
|
|
423
434
|
const prevActive = new Map<string, string>();
|
|
424
435
|
|
|
425
|
-
// Declared skill is OFF
|
|
426
|
-
|
|
436
|
+
// Declared skill is OFF; plain-skill has no featureFlag so remains ON.
|
|
437
|
+
setOverridesForTesting({ [DECLARED_FLAG_KEY]: false });
|
|
427
438
|
|
|
428
439
|
const result = projectSkillTools(history, {
|
|
429
440
|
previouslyActiveSkillIds: prevActive,
|