@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
|
@@ -69,51 +69,37 @@ mock.module("../prompts/user-reference.js", () => ({
|
|
|
69
69
|
resolveUserPronouns: () => null,
|
|
70
70
|
}));
|
|
71
71
|
|
|
72
|
+
// Stub persona-resolver so tests can dictate the slug `buildSystemPrompt`
|
|
73
|
+
// sees without needing to write contact rows to the test DB. The user
|
|
74
|
+
// and channel persona files themselves now flow through bundled sections
|
|
75
|
+
// (`10-user-persona` / `11-channel-persona`) that read from disk, so
|
|
76
|
+
// persona *content* is exercised by writing the file under TEST_DIR
|
|
77
|
+
// rather than mocking it here. Tests mutate `mockPersona` in place;
|
|
78
|
+
// the default (all-null) matches a fresh workspace with no contacts
|
|
79
|
+
// and no `users/default.md`.
|
|
80
|
+
const mockPersona: {
|
|
81
|
+
userSlug: string | null;
|
|
82
|
+
guardianPersona: string | null;
|
|
83
|
+
} = { userSlug: null, guardianPersona: null };
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
85
|
+
const realPersonaResolver = require("../prompts/persona-resolver.js");
|
|
86
|
+
mock.module("../prompts/persona-resolver.js", () => ({
|
|
87
|
+
...realPersonaResolver,
|
|
88
|
+
resolveUserSlug: () => mockPersona.userSlug,
|
|
89
|
+
resolveGuardianPersona: () => mockPersona.guardianPersona,
|
|
90
|
+
}));
|
|
91
|
+
|
|
72
92
|
// Import after mock
|
|
73
|
-
const {
|
|
74
|
-
|
|
75
|
-
ensurePromptFiles,
|
|
76
|
-
stripCommentLines,
|
|
77
|
-
SYSTEM_PROMPT_CACHE_BOUNDARY,
|
|
78
|
-
} = await import("../prompts/system-prompt.js");
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Extract BOOTSTRAP.md content + the user persona from the dynamic block
|
|
82
|
-
* of the system prompt, stripping configuration, skills catalog, and
|
|
83
|
-
* connected services.
|
|
84
|
-
*
|
|
85
|
-
* Neither SOUL.md nor IDENTITY.md flows through this helper — they
|
|
86
|
-
* render as the `09-soul` and `08-identity` workspace-backed sections in
|
|
87
|
-
* the static (cached) prefix. Tests that assert on their content slice
|
|
88
|
-
* the static block directly.
|
|
89
|
-
*/
|
|
90
|
-
function basePrompt(result: string): string {
|
|
91
|
-
// The workspace files are in the dynamic block after the cache boundary.
|
|
92
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
93
|
-
let s =
|
|
94
|
-
boundaryIdx >= 0
|
|
95
|
-
? result.slice(boundaryIdx + SYSTEM_PROMPT_CACHE_BOUNDARY.length)
|
|
96
|
-
: result;
|
|
97
|
-
for (const heading of [
|
|
98
|
-
"## Configuration",
|
|
99
|
-
"## Skills Catalog",
|
|
100
|
-
"## External Communications Identity",
|
|
101
|
-
"# Connected Services",
|
|
102
|
-
"## Dynamic Skill Authoring Workflow",
|
|
103
|
-
]) {
|
|
104
|
-
if (s.startsWith(heading)) {
|
|
105
|
-
s = "";
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
const idx = s.indexOf(`\n\n${heading}`);
|
|
109
|
-
if (idx !== -1) s = s.slice(0, idx);
|
|
110
|
-
}
|
|
111
|
-
return s;
|
|
112
|
-
}
|
|
93
|
+
const { buildSystemPrompt, ensurePromptFiles, stripCommentLines } =
|
|
94
|
+
await import("../prompts/system-prompt.js");
|
|
113
95
|
|
|
114
96
|
describe("buildSystemPrompt", () => {
|
|
115
97
|
beforeEach(() => {
|
|
116
98
|
mkdirSync(TEST_DIR, { recursive: true });
|
|
99
|
+
// Reset persona stub so each test starts from a fresh
|
|
100
|
+
// no-guardian baseline.
|
|
101
|
+
mockPersona.userSlug = null;
|
|
102
|
+
mockPersona.guardianPersona = null;
|
|
117
103
|
});
|
|
118
104
|
|
|
119
105
|
afterEach(() => {
|
|
@@ -123,8 +109,10 @@ describe("buildSystemPrompt", () => {
|
|
|
123
109
|
"USER.md",
|
|
124
110
|
"BOOTSTRAP.md",
|
|
125
111
|
"UPDATES.md",
|
|
112
|
+
"VOICE.md",
|
|
126
113
|
"skills",
|
|
127
114
|
"users",
|
|
115
|
+
"channels",
|
|
128
116
|
]) {
|
|
129
117
|
const p = join(TEST_DIR, name);
|
|
130
118
|
if (existsSync(p)) rmSync(p, { recursive: true, force: true });
|
|
@@ -134,19 +122,11 @@ describe("buildSystemPrompt", () => {
|
|
|
134
122
|
}
|
|
135
123
|
});
|
|
136
124
|
|
|
137
|
-
test("returns empty string when no files exist", () => {
|
|
138
|
-
const result = buildSystemPrompt();
|
|
139
|
-
expect(basePrompt(result)).toBe("");
|
|
140
|
-
});
|
|
141
|
-
|
|
142
125
|
test("uses SOUL.md when it exists", () => {
|
|
143
126
|
writeFileSync(join(TEST_DIR, "SOUL.md"), "# My Soul\n\nBe awesome.");
|
|
144
127
|
const result = buildSystemPrompt();
|
|
145
|
-
// SOUL.md renders as the `09-soul` workspace-backed section
|
|
146
|
-
|
|
147
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
148
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
149
|
-
expect(result.slice(0, boundaryIdx)).toContain("# My Soul\n\nBe awesome.");
|
|
128
|
+
// SOUL.md renders as the `09-soul` workspace-backed section.
|
|
129
|
+
expect(result).toContain("# My Soul\n\nBe awesome.");
|
|
150
130
|
});
|
|
151
131
|
|
|
152
132
|
test("uses IDENTITY.md when it exists", () => {
|
|
@@ -155,42 +135,78 @@ describe("buildSystemPrompt", () => {
|
|
|
155
135
|
"# My Identity\n\nI am Vellum.",
|
|
156
136
|
);
|
|
157
137
|
const result = buildSystemPrompt();
|
|
158
|
-
// IDENTITY.md renders as the `08-identity` workspace-backed section
|
|
159
|
-
|
|
160
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
161
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
162
|
-
expect(result.slice(0, boundaryIdx)).toContain(
|
|
163
|
-
"# My Identity\n\nI am Vellum.",
|
|
164
|
-
);
|
|
138
|
+
// IDENTITY.md renders as the `08-identity` workspace-backed section.
|
|
139
|
+
expect(result).toContain("# My Identity\n\nI am Vellum.");
|
|
165
140
|
});
|
|
166
141
|
|
|
167
142
|
test("composes IDENTITY.md + SOUL.md when both exist", () => {
|
|
168
143
|
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "# Identity\n\nI am Vellum.");
|
|
169
144
|
writeFileSync(join(TEST_DIR, "SOUL.md"), "# Soul\n\nBe thoughtful.");
|
|
170
145
|
const result = buildSystemPrompt();
|
|
171
|
-
//
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
expect(
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
expect(staticBlock).toContain("# Soul\n\nBe thoughtful.");
|
|
178
|
-
const identityIdx = staticBlock.indexOf("# Identity\n\nI am Vellum.");
|
|
179
|
-
const soulIdx = staticBlock.indexOf("# Soul\n\nBe thoughtful.");
|
|
146
|
+
// IDENTITY renders before SOUL (sections `08-identity` then
|
|
147
|
+
// `09-soul`).
|
|
148
|
+
expect(result).toContain("# Identity\n\nI am Vellum.");
|
|
149
|
+
expect(result).toContain("# Soul\n\nBe thoughtful.");
|
|
150
|
+
const identityIdx = result.indexOf("# Identity\n\nI am Vellum.");
|
|
151
|
+
const soulIdx = result.indexOf("# Soul\n\nBe thoughtful.");
|
|
180
152
|
expect(identityIdx).toBeLessThan(soulIdx);
|
|
181
|
-
expect(basePrompt(result)).toBe("");
|
|
182
153
|
});
|
|
183
154
|
|
|
184
155
|
test("ignores empty SOUL.md", () => {
|
|
185
156
|
writeFileSync(join(TEST_DIR, "SOUL.md"), " \n \n ");
|
|
157
|
+
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "# Identity\n\nI am Vellum.");
|
|
186
158
|
const result = buildSystemPrompt();
|
|
187
|
-
|
|
159
|
+
// IDENTITY renders but SOUL is gated off by the renderer's
|
|
160
|
+
// empty-body check; no SOUL content should appear.
|
|
161
|
+
expect(result).toContain("# Identity\n\nI am Vellum.");
|
|
162
|
+
expect(result).not.toContain(" \n \n ");
|
|
188
163
|
});
|
|
189
164
|
|
|
190
165
|
test("ignores empty IDENTITY.md", () => {
|
|
191
166
|
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "");
|
|
167
|
+
writeFileSync(join(TEST_DIR, "SOUL.md"), "# Soul\n\nBe thoughtful.");
|
|
192
168
|
const result = buildSystemPrompt();
|
|
193
|
-
|
|
169
|
+
// SOUL renders but IDENTITY's empty file is gated off by the
|
|
170
|
+
// renderer's empty-body check.
|
|
171
|
+
expect(result).toContain("# Soul\n\nBe thoughtful.");
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("gates off the unmodified bundled IDENTITY.md template when no BOOTSTRAP.md is present", () => {
|
|
175
|
+
// Regression: the seeded IDENTITY.md ships with `_`-comment lines, so
|
|
176
|
+
// the raw workspace body never equals the comment-stripped bundled
|
|
177
|
+
// template. `isTemplateContent` must comment-strip BOTH sides — otherwise
|
|
178
|
+
// detection fails and the `08-identity` transform leaks the blank
|
|
179
|
+
// template scaffolding into every fresh post-onboarding prompt.
|
|
180
|
+
const bundledIdentity = readFileSync(
|
|
181
|
+
join(import.meta.dirname, "..", "prompts", "templates", "IDENTITY.md"),
|
|
182
|
+
"utf-8",
|
|
183
|
+
);
|
|
184
|
+
writeFileSync(join(TEST_DIR, "IDENTITY.md"), bundledIdentity);
|
|
185
|
+
writeFileSync(join(TEST_DIR, "SOUL.md"), "# Soul\n\nBe thoughtful.");
|
|
186
|
+
const result = buildSystemPrompt();
|
|
187
|
+
// SOUL still renders; the template scaffolding must not.
|
|
188
|
+
expect(result).toContain("# Soul\n\nBe thoughtful.");
|
|
189
|
+
expect(result).not.toContain("(not yet chosen)");
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("includes the unmodified bundled IDENTITY.md template during bootstrap", () => {
|
|
193
|
+
// The mirror case: when BOOTSTRAP.md is active the template is included
|
|
194
|
+
// verbatim so the model can see the field structure and produce a valid
|
|
195
|
+
// file_write on the first turn.
|
|
196
|
+
const bundledIdentity = readFileSync(
|
|
197
|
+
join(import.meta.dirname, "..", "prompts", "templates", "IDENTITY.md"),
|
|
198
|
+
"utf-8",
|
|
199
|
+
);
|
|
200
|
+
writeFileSync(join(TEST_DIR, "IDENTITY.md"), bundledIdentity);
|
|
201
|
+
writeFileSync(
|
|
202
|
+
join(TEST_DIR, "BOOTSTRAP.md"),
|
|
203
|
+
"# First run\n\nGet started.",
|
|
204
|
+
);
|
|
205
|
+
const result = buildSystemPrompt();
|
|
206
|
+
// The bundled template's placeholder scaffolding (the `(not yet chosen)`
|
|
207
|
+
// field markers) renders verbatim during bootstrap — the mirror of the
|
|
208
|
+
// gating test above, which asserts it is absent without BOOTSTRAP.md.
|
|
209
|
+
expect(result).toContain("(not yet chosen)");
|
|
194
210
|
});
|
|
195
211
|
|
|
196
212
|
test("trims whitespace from file content", () => {
|
|
@@ -198,10 +214,8 @@ describe("buildSystemPrompt", () => {
|
|
|
198
214
|
const result = buildSystemPrompt();
|
|
199
215
|
// SOUL.md renders via the `09-soul` workspace-backed section;
|
|
200
216
|
// stripCommentLines + trim run inside the section renderer.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
expect(staticBlock).toContain("Be kind");
|
|
204
|
-
expect(staticBlock).not.toContain("\n Be kind \n");
|
|
217
|
+
expect(result).toContain("Be kind");
|
|
218
|
+
expect(result).not.toContain("\n Be kind \n");
|
|
205
219
|
});
|
|
206
220
|
|
|
207
221
|
test("does not include skills catalog in system prompt", () => {
|
|
@@ -274,9 +288,6 @@ describe("buildSystemPrompt", () => {
|
|
|
274
288
|
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "Identity");
|
|
275
289
|
writeFileSync(join(TEST_DIR, "SOUL.md"), "Soul");
|
|
276
290
|
const result = buildSystemPrompt();
|
|
277
|
-
// Both IDENTITY and SOUL render in the static (cached) prefix; the
|
|
278
|
-
// dynamic block sliced by basePrompt is empty here.
|
|
279
|
-
expect(basePrompt(result)).toBe("");
|
|
280
291
|
expect(result).toContain("Identity");
|
|
281
292
|
expect(result).toContain("Soul");
|
|
282
293
|
});
|
|
@@ -292,54 +303,117 @@ describe("buildSystemPrompt", () => {
|
|
|
292
303
|
const result = buildSystemPrompt();
|
|
293
304
|
expect(result).not.toContain("stale user content");
|
|
294
305
|
expect(result).toContain("Identity");
|
|
295
|
-
expect(basePrompt(result)).toBe("");
|
|
296
306
|
});
|
|
297
307
|
|
|
298
|
-
test("
|
|
308
|
+
test("includes resolved user persona in the static prefix", () => {
|
|
309
|
+
// User persona flows through the `10-user-persona` bundled section,
|
|
310
|
+
// which reads from `users/<userSlug>.md` (or `users/default.md` as
|
|
311
|
+
// a fallback). Set the slug + write the file to exercise both.
|
|
312
|
+
mockPersona.userSlug = "alice";
|
|
313
|
+
mkdirSync(join(TEST_DIR, "users"), { recursive: true });
|
|
314
|
+
writeFileSync(
|
|
315
|
+
join(TEST_DIR, "users", "alice.md"),
|
|
316
|
+
"# User persona\n\nName: Alice",
|
|
317
|
+
);
|
|
299
318
|
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "Identity");
|
|
300
319
|
writeFileSync(join(TEST_DIR, "SOUL.md"), "Soul");
|
|
301
|
-
const result = buildSystemPrompt(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
// IDENTITY and SOUL both render in the static (cached) prefix; only
|
|
305
|
-
// the user persona ends up in the dynamic block.
|
|
306
|
-
expect(basePrompt(result)).toBe("# User persona\n\nName: Alice");
|
|
320
|
+
const result = buildSystemPrompt();
|
|
321
|
+
// IDENTITY, SOUL, and the user persona all render as workspace-backed
|
|
322
|
+
// bundled sections in the assembled prompt.
|
|
307
323
|
expect(result).toContain("Identity");
|
|
308
324
|
expect(result).toContain("Soul");
|
|
325
|
+
expect(result).toContain("# User persona");
|
|
326
|
+
expect(result).toContain("Name: Alice");
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test("user persona falls back to users/default.md when the slug's file is missing", () => {
|
|
330
|
+
// The `10-user-persona` section's workspacePath is
|
|
331
|
+
// `["users/{{userSlug}}.md", "users/default.md"]` — when the
|
|
332
|
+
// primary file doesn't exist the renderer falls through to default.
|
|
333
|
+
mockPersona.userSlug = "alice";
|
|
334
|
+
mkdirSync(join(TEST_DIR, "users"), { recursive: true });
|
|
335
|
+
writeFileSync(
|
|
336
|
+
join(TEST_DIR, "users", "default.md"),
|
|
337
|
+
"# Default persona\n\nNo contact bound.",
|
|
338
|
+
);
|
|
339
|
+
const result = buildSystemPrompt();
|
|
340
|
+
expect(result).toContain("# Default persona");
|
|
341
|
+
expect(result).toContain("No contact bound.");
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
test("includes channel persona from channels/<channelSlug>.md", () => {
|
|
345
|
+
// Channel persona flows through the `11-channel-persona` section.
|
|
346
|
+
// Default channel is "vellum" when no channelCapabilities passed.
|
|
347
|
+
mkdirSync(join(TEST_DIR, "channels"), { recursive: true });
|
|
348
|
+
writeFileSync(
|
|
349
|
+
join(TEST_DIR, "channels", "vellum.md"),
|
|
350
|
+
"# Channel persona\n\nThis is the Vellum channel.",
|
|
351
|
+
);
|
|
352
|
+
const result = buildSystemPrompt();
|
|
353
|
+
expect(result).toContain("# Channel persona");
|
|
354
|
+
expect(result).toContain("This is the Vellum channel.");
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
test("includes VOICE.md as the 12-voice section with prepended heading", () => {
|
|
358
|
+
// VOICE.md flows through the `12-voice` bundled section. The
|
|
359
|
+
// section transform prepends `# Voice Profile` so the file itself
|
|
360
|
+
// stays heading-free; the model writes voice markers as plain
|
|
361
|
+
// bullets / lines.
|
|
362
|
+
writeFileSync(
|
|
363
|
+
join(TEST_DIR, "VOICE.md"),
|
|
364
|
+
"- Prefers lowercase. Replies tightly. Skips greetings.",
|
|
365
|
+
);
|
|
366
|
+
const result = buildSystemPrompt();
|
|
367
|
+
expect(result).toContain("# Voice Profile");
|
|
368
|
+
expect(result).toContain("Prefers lowercase");
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
test("omits the 12-voice section when VOICE.md is missing", () => {
|
|
372
|
+
const result = buildSystemPrompt();
|
|
373
|
+
expect(result).not.toContain("# Voice Profile");
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
test("omits the 12-voice section when VOICE.md is empty / whitespace-only", () => {
|
|
377
|
+
writeFileSync(join(TEST_DIR, "VOICE.md"), " \n\n \n");
|
|
378
|
+
const result = buildSystemPrompt();
|
|
379
|
+
expect(result).not.toContain("# Voice Profile");
|
|
309
380
|
});
|
|
310
381
|
|
|
311
382
|
describe("BOOTSTRAP.md user persona placeholder", () => {
|
|
312
|
-
test("substitutes {{
|
|
383
|
+
test("substitutes {{userSlug}} with the resolved slug when a guardian slug is resolvable", () => {
|
|
384
|
+
// Simulate a guardian contact whose userFile resolves to alice.md.
|
|
385
|
+
mockPersona.userSlug = "alice";
|
|
313
386
|
writeFileSync(
|
|
314
387
|
join(TEST_DIR, "BOOTSTRAP.md"),
|
|
315
|
-
"# First run\n\nSave facts to users/{{
|
|
388
|
+
"# First run\n\nSave facts to users/{{userSlug}}.md immediately.",
|
|
316
389
|
);
|
|
317
|
-
const result = buildSystemPrompt(
|
|
390
|
+
const result = buildSystemPrompt();
|
|
318
391
|
expect(result).toContain("users/alice.md");
|
|
319
|
-
expect(result).not.toContain("{{
|
|
392
|
+
expect(result).not.toContain("{{userSlug}}");
|
|
320
393
|
});
|
|
321
394
|
|
|
322
|
-
test("falls back to users/default.md when
|
|
395
|
+
test("falls back to users/default.md when no slug is resolvable", () => {
|
|
323
396
|
writeFileSync(
|
|
324
397
|
join(TEST_DIR, "BOOTSTRAP.md"),
|
|
325
|
-
"# First run\n\nSave facts to users/{{
|
|
398
|
+
"# First run\n\nSave facts to users/{{userSlug}}.md immediately.",
|
|
326
399
|
);
|
|
327
400
|
const result = buildSystemPrompt();
|
|
328
401
|
expect(result).toContain("users/default.md");
|
|
329
|
-
expect(result).not.toContain("{{
|
|
402
|
+
expect(result).not.toContain("{{userSlug}}");
|
|
330
403
|
});
|
|
331
404
|
|
|
332
405
|
test("substitutes the unmodified bundled BOOTSTRAP.md template", () => {
|
|
333
406
|
// Copy the real bundled BOOTSTRAP.md into the test workspace so we
|
|
334
407
|
// verify substitution against the actual template the daemon ships.
|
|
408
|
+
mockPersona.userSlug = "alice";
|
|
335
409
|
const bundled = readFileSync(
|
|
336
410
|
join(import.meta.dirname, "..", "prompts", "templates", "BOOTSTRAP.md"),
|
|
337
411
|
"utf-8",
|
|
338
412
|
);
|
|
339
413
|
writeFileSync(join(TEST_DIR, "BOOTSTRAP.md"), bundled);
|
|
340
|
-
const result = buildSystemPrompt(
|
|
414
|
+
const result = buildSystemPrompt();
|
|
341
415
|
expect(result).toContain("users/alice.md");
|
|
342
|
-
expect(result).not.toContain("{{
|
|
416
|
+
expect(result).not.toContain("{{userSlug}}");
|
|
343
417
|
});
|
|
344
418
|
});
|
|
345
419
|
|
|
@@ -513,8 +587,14 @@ describe("buildSystemPrompt", () => {
|
|
|
513
587
|
|
|
514
588
|
test("file with only comment lines is treated as empty", () => {
|
|
515
589
|
writeFileSync(join(TEST_DIR, "SOUL.md"), "_ All comments\n_ Nothing else");
|
|
590
|
+
writeFileSync(join(TEST_DIR, "IDENTITY.md"), "# Identity\n\nI am Vellum.");
|
|
516
591
|
const result = buildSystemPrompt();
|
|
517
|
-
|
|
592
|
+
// Comment-only SOUL.md gets stripped down to "" by
|
|
593
|
+
// `stripCommentLines` and is then gated off by the renderer's
|
|
594
|
+
// empty-body check; only IDENTITY contributes content here.
|
|
595
|
+
expect(result).toContain("# Identity\n\nI am Vellum.");
|
|
596
|
+
expect(result).not.toContain("_ All comments");
|
|
597
|
+
expect(result).not.toContain("_ Nothing else");
|
|
518
598
|
});
|
|
519
599
|
|
|
520
600
|
describe("workspace system prompt sections", () => {
|
|
@@ -547,11 +627,7 @@ describe("buildSystemPrompt", () => {
|
|
|
547
627
|
);
|
|
548
628
|
const result = buildSystemPrompt();
|
|
549
629
|
expect(result.startsWith("You are operating in demo mode.")).toBe(true);
|
|
550
|
-
|
|
551
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
552
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
553
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
554
|
-
expect(staticBlock).toContain("You are operating in demo mode.");
|
|
630
|
+
expect(result).toContain("You are operating in demo mode.");
|
|
555
631
|
});
|
|
556
632
|
|
|
557
633
|
test("workspace file without frontmatter is rendered as-is (always-on)", () => {
|
|
@@ -627,13 +703,10 @@ describe("buildSystemPrompt", () => {
|
|
|
627
703
|
expect(result.startsWith("Custom prefix")).toBe(true);
|
|
628
704
|
// IDENTITY.md renders via 08-identity in the static prefix after
|
|
629
705
|
// the 00-prefix slot.
|
|
630
|
-
const
|
|
631
|
-
const
|
|
632
|
-
const prefixIdx = staticBlock.indexOf("Custom prefix");
|
|
633
|
-
const identityIdx = staticBlock.indexOf("I am Vellum.");
|
|
706
|
+
const prefixIdx = result.indexOf("Custom prefix");
|
|
707
|
+
const identityIdx = result.indexOf("I am Vellum.");
|
|
634
708
|
expect(prefixIdx).toBeGreaterThan(-1);
|
|
635
709
|
expect(identityIdx).toBeGreaterThan(prefixIdx);
|
|
636
|
-
expect(basePrompt(result)).toBe("");
|
|
637
710
|
});
|
|
638
711
|
|
|
639
712
|
test("parallel tool calls section is sourced from workspace when present", () => {
|
|
@@ -809,11 +882,7 @@ describe("buildSystemPrompt", () => {
|
|
|
809
882
|
expect(result).toContain(
|
|
810
883
|
"Run `assistant --help` to discover commands.",
|
|
811
884
|
);
|
|
812
|
-
|
|
813
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
814
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
815
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
816
|
-
expect(staticBlock).toContain("## Assistant CLI");
|
|
885
|
+
expect(result).toContain("## Assistant CLI");
|
|
817
886
|
});
|
|
818
887
|
|
|
819
888
|
test("bundled cli-reference default renders when no workspace override", () => {
|
|
@@ -854,11 +923,7 @@ describe("buildSystemPrompt", () => {
|
|
|
854
923
|
// The no-client body (em-dash separator after sandbox `bash`) must
|
|
855
924
|
// not leak when the with-client variant is active.
|
|
856
925
|
expect(result).not.toContain("install tools yourself; (2) browser");
|
|
857
|
-
|
|
858
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
859
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
860
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
861
|
-
expect(staticBlock).toContain("## External Service Access");
|
|
926
|
+
expect(result).toContain("## External Service Access");
|
|
862
927
|
});
|
|
863
928
|
|
|
864
929
|
test("hasNoClient=true renders the two-tier (no host_bash) priority list", () => {
|
|
@@ -967,8 +1032,7 @@ describe("buildSystemPrompt", () => {
|
|
|
967
1032
|
|
|
968
1033
|
test("paired {{#flag}} + {{^flag}} acts as if/else", () => {
|
|
969
1034
|
// Use long unique markers — single letters collide with substrings
|
|
970
|
-
// in the rest of the system prompt (e.g. "
|
|
971
|
-
// SYSTEM_PROMPT_CACHE_BOUNDARY, "A" inside "API keys").
|
|
1035
|
+
// in the rest of the system prompt (e.g. "A" inside "API keys").
|
|
972
1036
|
mkdirSync(SYSTEM_PROMPTS_DIR, { recursive: true });
|
|
973
1037
|
writeFileSync(
|
|
974
1038
|
SECTION_FILE,
|
|
@@ -1033,11 +1097,7 @@ describe("buildSystemPrompt", () => {
|
|
|
1033
1097
|
const result = buildSystemPrompt();
|
|
1034
1098
|
expect(result).toContain("## Sending Files to the User");
|
|
1035
1099
|
expect(result).toContain("Use the `<vellum-attachment />` tag.");
|
|
1036
|
-
|
|
1037
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
1038
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
1039
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
1040
|
-
expect(staticBlock).toContain("## Sending Files to the User");
|
|
1100
|
+
expect(result).toContain("## Sending Files to the User");
|
|
1041
1101
|
});
|
|
1042
1102
|
|
|
1043
1103
|
test("renders after the cli-reference section to preserve original order", () => {
|
|
@@ -1083,11 +1143,7 @@ describe("buildSystemPrompt", () => {
|
|
|
1083
1143
|
const result = buildSystemPrompt();
|
|
1084
1144
|
expect(result).toContain("## Credential Security");
|
|
1085
1145
|
expect(result).toContain("Workspace override marker BRAVO_TANGO_7.");
|
|
1086
|
-
|
|
1087
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
1088
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
1089
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
1090
|
-
expect(staticBlock).toContain("## Credential Security");
|
|
1146
|
+
expect(result).toContain("## Credential Security");
|
|
1091
1147
|
});
|
|
1092
1148
|
|
|
1093
1149
|
test("bundled credential-security default renders when no workspace override", () => {
|
|
@@ -1127,11 +1183,7 @@ describe("buildSystemPrompt", () => {
|
|
|
1127
1183
|
const result = buildSystemPrompt();
|
|
1128
1184
|
expect(result).toContain("## External Content");
|
|
1129
1185
|
expect(result).toContain("Workspace override marker NEBULA_9X.");
|
|
1130
|
-
|
|
1131
|
-
const boundaryIdx = result.indexOf(SYSTEM_PROMPT_CACHE_BOUNDARY);
|
|
1132
|
-
expect(boundaryIdx).toBeGreaterThan(-1);
|
|
1133
|
-
const staticBlock = result.slice(0, boundaryIdx);
|
|
1134
|
-
expect(staticBlock).toContain("## External Content");
|
|
1186
|
+
expect(result).toContain("## External Content");
|
|
1135
1187
|
});
|
|
1136
1188
|
|
|
1137
1189
|
test("bundled external-content default renders when no workspace override", () => {
|
|
@@ -288,7 +288,7 @@ describe("Shell tool input validation", () => {
|
|
|
288
288
|
});
|
|
289
289
|
|
|
290
290
|
test("tool definition includes required schema fields", () => {
|
|
291
|
-
const def = shellTool
|
|
291
|
+
const def = shellTool;
|
|
292
292
|
const schema = def.input_schema as {
|
|
293
293
|
required: string[];
|
|
294
294
|
properties: Record<string, unknown>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test preload verifier — runs immediately after test-preload.ts.
|
|
3
|
+
*
|
|
4
|
+
* Bun already exits with code 1 when a preload throws, has an unresolvable
|
|
5
|
+
* import, or doesn't exist on disk (verified empirically). This file is
|
|
6
|
+
* the explicit check for the remaining failure mode: the main preload
|
|
7
|
+
* ran successfully but didn't actually isolate workspace state (e.g. a
|
|
8
|
+
* future refactor of test-preload.ts introduces a logic bug that no-ops
|
|
9
|
+
* the env override).
|
|
10
|
+
*
|
|
11
|
+
* Without this verifier, that failure mode would silently let tests
|
|
12
|
+
* resolve `VELLUM_WORKSPACE_DIR` to the real `/workspace` and potentially
|
|
13
|
+
* destroy live data.
|
|
14
|
+
*
|
|
15
|
+
* Order matters: bunfig.toml lists this AFTER test-preload.ts so the
|
|
16
|
+
* main preload's env writes are observable here.
|
|
17
|
+
*
|
|
18
|
+
* No source-module imports — only node stdlib (matches the same rule
|
|
19
|
+
* test-preload.ts enforces).
|
|
20
|
+
*
|
|
21
|
+
* Positive assertion: `VELLUM_WORKSPACE_DIR` MUST resolve under
|
|
22
|
+
* `os.tmpdir()`. This mirrors exactly what test-preload.ts does
|
|
23
|
+
* (`mkdtempSync(join(tmpdir(), "vellum-test-"))`), so any other value
|
|
24
|
+
* indicates the preload either didn't run or didn't take effect.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { realpathSync } from "node:fs";
|
|
28
|
+
import { tmpdir } from "node:os";
|
|
29
|
+
import { sep } from "node:path";
|
|
30
|
+
|
|
31
|
+
function fail(reason: string): never {
|
|
32
|
+
throw new Error(
|
|
33
|
+
[
|
|
34
|
+
`Test preload verifier failed: ${reason}.`,
|
|
35
|
+
"",
|
|
36
|
+
"test-preload.ts ran but did not isolate workspace state. Common",
|
|
37
|
+
"causes:",
|
|
38
|
+
" - a logic bug in test-preload.ts (env override removed/reordered)",
|
|
39
|
+
" - a preload phase threw silently and the verifier still picked up",
|
|
40
|
+
" partial state",
|
|
41
|
+
].join("\n"),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function canonicalize(p: string): string {
|
|
46
|
+
try {
|
|
47
|
+
return realpathSync(p);
|
|
48
|
+
} catch {
|
|
49
|
+
return p;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const workspaceDir = process.env.VELLUM_WORKSPACE_DIR?.trim();
|
|
54
|
+
if (!workspaceDir) {
|
|
55
|
+
fail("VELLUM_WORKSPACE_DIR is not set after main preload");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const resolvedWorkspace = canonicalize(workspaceDir);
|
|
59
|
+
const tmpRoot = canonicalize(tmpdir());
|
|
60
|
+
|
|
61
|
+
if (
|
|
62
|
+
resolvedWorkspace !== tmpRoot &&
|
|
63
|
+
!resolvedWorkspace.startsWith(tmpRoot + sep)
|
|
64
|
+
) {
|
|
65
|
+
fail(
|
|
66
|
+
`VELLUM_WORKSPACE_DIR resolves to ${resolvedWorkspace}, which is not under ${tmpRoot}`,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
@@ -1,56 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared test preload — runs before every test file.
|
|
3
3
|
*
|
|
4
|
-
* Creates a per-
|
|
5
|
-
* all workspace-derived helpers (getDataDir, getDbPath,
|
|
6
|
-
* resolve under the temp dir
|
|
7
|
-
*
|
|
8
|
-
* Individual test files can retrieve the workspace dir via getWorkspaceDir()
|
|
9
|
-
* from platform.ts, or directly from process.env.VELLUM_WORKSPACE_DIR.
|
|
4
|
+
* Creates a per-process temporary directory and sets VELLUM_WORKSPACE_DIR so
|
|
5
|
+
* that all workspace-derived helpers (getDataDir, getDbPath,
|
|
6
|
+
* getConversationsDir, getProtectedDir, …) resolve under the temp dir
|
|
7
|
+
* instead of the real $VELLUM_WORKSPACE_DIR.
|
|
10
8
|
*
|
|
11
9
|
* Cleanup: the temp dir is removed after all tests in the file complete.
|
|
10
|
+
*
|
|
11
|
+
* No source-module imports
|
|
12
|
+
* ------------------------
|
|
13
|
+
* The only static imports in this file are node stdlib (`node:fs`,
|
|
14
|
+
* `node:os`, `node:path`), `bun:test`, and helpers in this same directory.
|
|
15
|
+
* Importing from the assistant directly runs the risk of triggering import
|
|
16
|
+
* time side effects and import from node modules that may not exist in
|
|
17
|
+
* some environments.
|
|
12
18
|
*/
|
|
13
19
|
|
|
14
|
-
import { mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
20
|
+
import { mkdirSync, mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
15
21
|
import { tmpdir } from "node:os";
|
|
16
22
|
import { join } from "node:path";
|
|
17
23
|
import { afterAll } from "bun:test";
|
|
18
24
|
|
|
19
|
-
import { installGatewayIpcMock } from "
|
|
20
|
-
import { _setOverridesForTesting } from "../config/assistant-feature-flags.js";
|
|
21
|
-
import { resetDb } from "../memory/db-connection.js";
|
|
22
|
-
import { _setStorePath } from "../security/encrypted-store.js";
|
|
25
|
+
import { installGatewayIpcMock } from "./mock-gateway-ipc.js";
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
// --- Phase 1: env override (zero source-module imports above this point) ---
|
|
28
|
+
|
|
29
|
+
// Layout: <tmpRoot>/workspace as VELLUM_WORKSPACE_DIR. The parent of
|
|
30
|
+
// VELLUM_WORKSPACE_DIR is what `vellumRoot()` resolves to, so a separate
|
|
31
|
+
// tmpRoot per process gives `getProtectedDir()` and friends per-process
|
|
32
|
+
// isolation without needing an explicit `setStorePathForTesting()`.
|
|
33
|
+
const tmpRoot = realpathSync(mkdtempSync(join(tmpdir(), "vellum-test-")));
|
|
34
|
+
const testDir = join(tmpRoot, "workspace");
|
|
35
|
+
mkdirSync(testDir);
|
|
27
36
|
process.env.VELLUM_WORKSPACE_DIR = testDir;
|
|
28
37
|
process.env.VELLUM_PLATFORM_URL = "https://test-platform.vellum.ai";
|
|
29
38
|
process.exitCode = 0;
|
|
30
39
|
|
|
31
|
-
// Isolate the encrypted credential store per test file. Without this,
|
|
32
|
-
// parallel test processes all read/write the same ~/.vellum/protected/keys.enc,
|
|
33
|
-
// causing races when one file deletes a key while another sets it.
|
|
34
|
-
_setStorePath(join(testDir, "keys.enc"));
|
|
35
|
-
|
|
36
|
-
// Mock gateway IPC so no test accidentally connects to a real gateway socket.
|
|
37
|
-
// Tests that need to control IPC responses use mockGatewayIpc() / resetMockGatewayIpc().
|
|
38
|
-
installGatewayIpcMock();
|
|
39
|
-
|
|
40
|
-
// Pre-populate the feature-flag override cache so `initFeatureFlagOverrides()`
|
|
41
|
-
// short-circuits its retry loop — there is no real gateway in tests, and the
|
|
42
|
-
// retry backoff would otherwise exceed the per-test timeout for any test that
|
|
43
|
-
// builds the CLI program. Tests exercising the retry behavior call
|
|
44
|
-
// `clearFeatureFlagOverridesCache()` first.
|
|
45
|
-
_setOverridesForTesting({});
|
|
46
|
-
|
|
47
|
-
// Force-close any DB connection inherited from the parent process (e.g. when
|
|
48
|
-
// the test runner is spawned by the running assistant via a pre-push hook).
|
|
49
|
-
// Without this, the db singleton in db-connection.ts may still point at the
|
|
50
|
-
// real ~/.vellum/workspace database, and test cleanup (DELETE FROM …) would
|
|
51
|
-
// wipe production data — contacts, channels, credentials, etc.
|
|
52
|
-
resetDb();
|
|
53
|
-
|
|
54
40
|
// Prevent tests from routing credential writes through the real CES
|
|
55
41
|
// (Credential Execution Service). Without this, setSecureKeyAsync() in
|
|
56
42
|
// containerized environments writes to the live credential store.
|
|
@@ -59,8 +45,15 @@ const savedCesCredentialUrl = process.env.CES_CREDENTIAL_URL;
|
|
|
59
45
|
delete process.env.IS_CONTAINERIZED;
|
|
60
46
|
delete process.env.CES_CREDENTIAL_URL;
|
|
61
47
|
|
|
48
|
+
// --- Phase 2: install the IPC mock (no source-module imports) ---
|
|
49
|
+
|
|
50
|
+
// Mock gateway IPC so no test accidentally connects to a real gateway socket.
|
|
51
|
+
// The mock returns a sentinel for `get_feature_flags` to short-circuit the
|
|
52
|
+
// retry loop in `initFeatureFlagOverrides()`. Tests that need specific IPC
|
|
53
|
+
// responses use `mockGatewayIpc()` / `resetMockGatewayIpc()`.
|
|
54
|
+
installGatewayIpcMock();
|
|
55
|
+
|
|
62
56
|
afterAll(() => {
|
|
63
|
-
resetDb();
|
|
64
57
|
process.exitCode = 0;
|
|
65
58
|
delete process.env.VELLUM_WORKSPACE_DIR;
|
|
66
59
|
delete process.env.VELLUM_PLATFORM_URL;
|
|
@@ -71,7 +64,7 @@ afterAll(() => {
|
|
|
71
64
|
process.env.CES_CREDENTIAL_URL = savedCesCredentialUrl;
|
|
72
65
|
}
|
|
73
66
|
try {
|
|
74
|
-
rmSync(
|
|
67
|
+
rmSync(tmpRoot, { recursive: true, force: true });
|
|
75
68
|
} catch {
|
|
76
69
|
/* best-effort cleanup */
|
|
77
70
|
}
|