@vellumai/assistant 0.8.5 → 0.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +33 -1
- package/ARCHITECTURE.md +1 -1
- package/Dockerfile +1 -0
- package/bun.lock +11 -2
- package/bunfig.toml +6 -1
- package/docker-entrypoint.sh +8 -6
- package/docs/credential-execution-service.md +6 -6
- package/docs/plugins.md +67 -31
- package/examples/plugins/echo/register.ts +4 -7
- package/knip.json +1 -0
- package/node_modules/@vellumai/environments/bun.lock +24 -0
- package/node_modules/@vellumai/environments/package.json +18 -0
- package/node_modules/@vellumai/environments/src/__tests__/package-boundary.test.ts +95 -0
- package/node_modules/@vellumai/environments/src/index.ts +11 -0
- package/node_modules/@vellumai/environments/src/seeds.ts +73 -0
- package/node_modules/@vellumai/environments/src/types.ts +70 -0
- package/node_modules/@vellumai/environments/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +11 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +15 -17
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +10 -3
- package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +16 -14
- package/openapi.yaml +5585 -469
- package/package.json +7 -3
- package/scripts/generate-openapi.ts +20 -13
- package/src/__tests__/actor-token-service.test.ts +3 -2
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +42 -80
- package/src/__tests__/agent-loop-exit-reason.test.ts +336 -42
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +141 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +21 -33
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +6 -4
- package/src/__tests__/agent-loop-thinking.test.ts +17 -12
- package/src/__tests__/agent-loop.test.ts +207 -341
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +5 -2
- package/src/__tests__/agent-wake-override-profile.test.ts +23 -40
- 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 +201 -55
- package/src/__tests__/app-builder-skill-instructions.test.ts +22 -0
- package/src/__tests__/app-control-flow.test.ts +5 -0
- package/src/__tests__/approval-cascade.test.ts +5 -11
- package/src/__tests__/approval-routes-http.test.ts +13 -15
- package/src/__tests__/assert-not-live-db.ts +79 -0
- package/src/__tests__/assistant-event.test.ts +15 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +11 -27
- package/src/__tests__/audit-log-rotation.test.ts +2 -2
- package/src/__tests__/auto-analysis-end-to-end.test.ts +6 -6
- package/src/__tests__/avatar-e2e.test.ts +7 -37
- package/src/__tests__/avatar-generator.test.ts +12 -42
- package/src/__tests__/avatar-identity-sync.test.ts +28 -3
- package/src/__tests__/background-shell-bash.test.ts +3 -7
- package/src/__tests__/background-workers-disk-pressure.test.ts +5 -8
- package/src/__tests__/browser-skill-endstate.test.ts +3 -3
- package/src/__tests__/btw-routes.test.ts +10 -14
- package/src/__tests__/call-controller.test.ts +3 -2
- package/src/__tests__/call-pointer-messages.test.ts +5 -3
- package/src/__tests__/call-site-routing-provider.test.ts +22 -40
- package/src/__tests__/catalog-files.test.ts +1 -0
- package/src/__tests__/channel-approval-routes.test.ts +51 -22
- package/src/__tests__/channel-approvals.test.ts +3 -1
- package/src/__tests__/channel-guardian.test.ts +3 -2
- package/src/__tests__/channel-invite-transport.test.ts +1 -5
- package/src/__tests__/channel-readiness-routes.test.ts +0 -4
- package/src/__tests__/channel-readiness-slack-remote.test.ts +170 -0
- package/src/__tests__/channel-reply-delivery.test.ts +35 -0
- package/src/__tests__/channel-retry-sweep.test.ts +388 -79
- package/src/__tests__/checker.test.ts +12 -12
- package/src/__tests__/circuit-breaker-pipeline.test.ts +3 -3
- package/src/__tests__/clawhub-files.test.ts +1 -0
- package/src/__tests__/compaction-events.test.ts +6 -17
- package/src/__tests__/compaction-pipeline.test.ts +1 -1
- package/src/__tests__/compaction-timeout-recovery.test.ts +37 -48
- package/src/__tests__/compaction-trail-store.test.ts +186 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +1 -0
- package/src/__tests__/compactor-image-manifest-trust.test.ts +112 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +1 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +7 -5
- package/src/__tests__/computer-use-tools.test.ts +14 -16
- 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__/config-watcher.test.ts +28 -0
- package/src/__tests__/connection-model-compat.test.ts +83 -0
- package/src/__tests__/contacts-tools.test.ts +3 -2
- package/src/__tests__/context-search-agent-runner.test.ts +6 -3
- package/src/__tests__/context-token-estimator.test.ts +56 -0
- package/src/__tests__/context-window-manager-compact-retry.test.ts +291 -0
- package/src/__tests__/conversation-abort-tool-results.test.ts +19 -7
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +4 -2
- package/src/__tests__/conversation-agent-loop-handlers-max-tokens.test.ts +55 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +13 -27
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +464 -90
- package/src/__tests__/conversation-agent-loop.test.ts +1069 -64
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -3
- package/src/__tests__/conversation-app-control-instantiation.test.ts +29 -19
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -1
- 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 +20 -10
- package/src/__tests__/conversation-confirmation-signals.test.ts +16 -45
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-disk-view.test.ts +10 -17
- package/src/__tests__/conversation-error.test.ts +30 -0
- package/src/__tests__/conversation-fork-crud.test.ts +132 -157
- package/src/__tests__/conversation-fork-route.test.ts +19 -16
- 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-init.benchmark.test.ts +6 -6
- package/src/__tests__/conversation-lifecycle.test.ts +4 -2
- package/src/__tests__/conversation-list-source.test.ts +3 -2
- package/src/__tests__/conversation-load-history-repair.test.ts +5 -3
- package/src/__tests__/conversation-load-history-stripped.test.ts +2 -1
- package/src/__tests__/conversation-message-sync-tags.test.ts +3 -4
- package/src/__tests__/conversation-pairing.test.ts +87 -4
- package/src/__tests__/conversation-pre-run-repair.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +30 -7
- package/src/__tests__/conversation-process-callsite.test.ts +28 -30
- package/src/__tests__/conversation-provider-retry-repair.test.ts +58 -44
- package/src/__tests__/conversation-queue.test.ts +603 -455
- package/src/__tests__/conversation-routes-disk-view.test.ts +6 -20
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +35 -10
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +98 -22
- package/src/__tests__/conversation-runtime-workspace.test.ts +19 -1
- package/src/__tests__/conversation-skill-tools.test.ts +38 -142
- package/src/__tests__/conversation-slash-queue.test.ts +120 -62
- package/src/__tests__/conversation-slash-unknown.test.ts +18 -15
- package/src/__tests__/conversation-speed-override.test.ts +9 -22
- package/src/__tests__/conversation-stream-state.test.ts +484 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +52 -15
- package/src/__tests__/conversation-surfaces-app-control.test.ts +32 -4
- 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 +8 -5
- package/src/__tests__/conversation-surfaces-table-action.test.ts +13 -32
- package/src/__tests__/conversation-sync-tags.test.ts +128 -12
- package/src/__tests__/conversation-title-service.test.ts +1 -0
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +53 -11
- package/src/__tests__/conversation-unread-route.test.ts +14 -2
- package/src/__tests__/conversation-usage.test.ts +1 -2
- package/src/__tests__/conversation-wipe.test.ts +1 -1
- package/src/__tests__/conversation-workspace-cache-state.test.ts +4 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +53 -22
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +32 -7
- package/src/__tests__/credential-broker-browser-fill.test.ts +3 -3
- package/src/__tests__/credential-broker-server-use.test.ts +5 -5
- package/src/__tests__/credential-execution-client.test.ts +72 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +10 -12
- package/src/__tests__/credential-execution-tools.test.ts +1 -2
- package/src/__tests__/credential-health-service.test.ts +252 -3
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/credential-vault-unit.test.ts +19 -19
- package/src/__tests__/credential-vault.test.ts +5 -5
- package/src/__tests__/cross-provider-web-search.test.ts +61 -3
- package/src/__tests__/cu-unified-flow.test.ts +26 -1
- 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-schedule-syntax-migration.test.ts +11 -0
- package/src/__tests__/db-test-helpers.ts +58 -0
- package/src/__tests__/disk-pressure-guard.test.ts +119 -36
- package/src/__tests__/disk-pressure-lifecycle.test.ts +13 -10
- package/src/__tests__/disk-pressure-routes.test.ts +9 -35
- package/src/__tests__/disk-pressure-tools.test.ts +0 -4
- package/src/__tests__/dm-persistence.test.ts +33 -42
- 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 +68 -0
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +5 -4
- package/src/__tests__/edit-propagation.test.ts +1 -2
- package/src/__tests__/empty-response-pipeline.test.ts +127 -5
- 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 +3 -2
- package/src/__tests__/first-greeting.test.ts +103 -12
- package/src/__tests__/gateway-flag-listener.test.ts +0 -1
- package/src/__tests__/gemini-inline-media.test.ts +78 -0
- package/src/__tests__/gemini-provider.test.ts +375 -26
- package/src/__tests__/guardian-action-sweep.test.ts +3 -2
- package/src/__tests__/guardian-outbound-http.test.ts +3 -2
- package/src/__tests__/guardian-routing-state.test.ts +60 -71
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +48 -3
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +10 -7
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +3 -1
- package/src/__tests__/helpers/mock-logger.ts +26 -0
- package/src/__tests__/history-repair-hook.test.ts +161 -0
- package/src/__tests__/history-repair-observability.test.ts +1 -1
- package/src/__tests__/history-repair.test.ts +2 -1
- package/src/__tests__/host-app-control-proxy.test.ts +2 -0
- package/src/__tests__/host-bash-routes.test.ts +1 -0
- package/src/__tests__/host-cu-proxy.test.ts +2 -0
- package/src/__tests__/host-cu-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-edit-tool.test.ts +4 -2
- package/src/__tests__/host-file-proxy.test.ts +31 -0
- package/src/__tests__/host-file-read-tool.test.ts +4 -2
- package/src/__tests__/host-file-routes-targeted.test.ts +1 -0
- package/src/__tests__/host-file-write-tool.test.ts +9 -3
- package/src/__tests__/host-proxy-preactivation.test.ts +53 -14
- package/src/__tests__/host-shell-tool.test.ts +11 -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 +31 -9
- package/src/__tests__/identity-intro-cache.test.ts +154 -22
- package/src/__tests__/inbound-slack-persistence.test.ts +51 -74
- package/src/__tests__/inference-profile-reaper.test.ts +3 -2
- package/src/__tests__/inference-profile-session-ipc.test.ts +3 -2
- package/src/__tests__/injector-background-turn.test.ts +1 -1
- package/src/__tests__/injector-chain.test.ts +1 -1
- package/src/__tests__/injector-disk-pressure.test.ts +4 -18
- package/src/__tests__/injector-document-comments.test.ts +1 -1
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +1 -1
- package/src/__tests__/injector-v3-suppression.test.ts +220 -0
- package/src/__tests__/inline-skill-load-permissions.test.ts +4 -4
- package/src/__tests__/list-messages-attachments.test.ts +7 -8
- package/src/__tests__/list-messages-hidden-metadata.test.ts +93 -11
- package/src/__tests__/list-messages-page-latest.test.ts +0 -1
- package/src/__tests__/list-messages-tool-merge.test.ts +36 -6
- package/src/__tests__/llm-call-pipeline.test.ts +21 -15
- package/src/__tests__/llm-context-normalization.test.ts +42 -0
- package/src/__tests__/llm-request-log-turn-query.test.ts +42 -86
- package/src/__tests__/llm-resolver.test.ts +346 -39
- package/src/__tests__/llm-schema.test.ts +1 -1
- package/src/__tests__/llm-usage-store.test.ts +45 -0
- package/src/__tests__/log-export-routes.test.ts +59 -0
- package/src/__tests__/managed-skill-lifecycle.test.ts +1 -8
- package/src/__tests__/manual-token-reconciliation.test.ts +76 -1
- package/src/__tests__/mcp-abort-signal.test.ts +14 -0
- package/src/__tests__/mcp-auth-routes.test.ts +15 -10
- package/src/__tests__/mcp-client-auth.test.ts +14 -0
- package/src/__tests__/mcp-health-check.test.ts +18 -13
- package/src/__tests__/memory-retrieval-pipeline.test.ts +1 -1
- package/src/__tests__/memory-v2-static-injector.test.ts +1 -1
- package/src/__tests__/messaging-send-tool.test.ts +9 -4
- package/src/__tests__/migration-export-http.test.ts +12 -12
- package/src/__tests__/migration-import-commit-http.test.ts +8 -8
- package/src/__tests__/migration-import-from-url.test.ts +3 -3
- package/src/__tests__/migration-import-preflight-http.test.ts +7 -7
- package/src/__tests__/migration-validate-http.test.ts +3 -3
- package/src/__tests__/mock-gateway-ipc.ts +18 -2
- package/src/__tests__/model-intents.test.ts +3 -3
- package/src/__tests__/native-web-search.test.ts +44 -22
- package/src/__tests__/notification-decision-identity.test.ts +9 -18
- package/src/__tests__/notification-decision-recipient-context.test.ts +3 -6
- package/src/__tests__/notification-deep-link.test.ts +62 -0
- package/src/__tests__/oauth-commands-routes.test.ts +38 -1
- 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 +13 -2
- package/src/__tests__/openai-provider.test.ts +74 -79
- package/src/__tests__/openai-responses-provider.test.ts +90 -86
- package/src/__tests__/openrouter-provider-only.test.ts +27 -5
- package/src/__tests__/outbound-slack-persistence.test.ts +48 -2
- package/src/__tests__/overflow-reduce-pipeline.test.ts +2 -4
- package/src/__tests__/parallel-tool.benchmark.test.ts +24 -36
- package/src/__tests__/persistence-pipeline.test.ts +154 -27
- package/src/__tests__/persistence-secret-redaction.test.ts +85 -13
- package/src/__tests__/pipeline-runner.test.ts +2 -3
- package/src/__tests__/plugin-bootstrap.test.ts +60 -36
- package/src/__tests__/plugin-route-contribution.test.ts +6 -16
- package/src/__tests__/plugin-skill-contribution.test.ts +7 -17
- package/src/__tests__/plugin-tool-contribution.test.ts +51 -64
- package/src/__tests__/plugin-types.test.ts +7 -14
- package/src/__tests__/prechat-onboarding-contract.test.ts +23 -0
- package/src/__tests__/process-message-background-slack.test.ts +38 -32
- package/src/__tests__/process-message-display-content.test.ts +49 -64
- package/src/__tests__/provider-catalog-visibility.test.ts +9 -9
- package/src/__tests__/provider-commit-message-generator.test.ts +19 -14
- package/src/__tests__/provider-error-scenarios.test.ts +7 -6
- package/src/__tests__/provider-platform-proxy-integration.test.ts +215 -8
- package/src/__tests__/provider-registry-ollama.test.ts +45 -22
- package/src/__tests__/provider-send-message-override-profile.test.ts +9 -25
- package/src/__tests__/provider-streaming.benchmark.test.ts +12 -22
- package/src/__tests__/provider-usage-tracking.test.ts +0 -6
- package/src/__tests__/ratelimit.test.ts +9 -4
- package/src/__tests__/recording-handler.test.ts +1 -0
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +1 -0
- package/src/__tests__/registry.test.ts +82 -76
- package/src/__tests__/relay-server.test.ts +30 -23
- package/src/__tests__/retry-openrouter-only-normalization.test.ts +5 -8
- package/src/__tests__/retry-thinking-tool-choice.test.ts +10 -13
- package/src/__tests__/retry-verbosity-normalization.test.ts +5 -8
- package/src/__tests__/runtime-attachment-metadata.test.ts +3 -2
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +353 -0
- package/src/__tests__/schedule-routes.test.ts +80 -10
- package/src/__tests__/schedule-store.test.ts +83 -1
- package/src/__tests__/schedule-tools.test.ts +125 -0
- package/src/__tests__/scheduler-reuse-conversation.test.ts +48 -3
- package/src/__tests__/secret-ingress-http.test.ts +7 -3
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +11 -7
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +11 -9
- package/src/__tests__/secret-response-routing.test.ts +13 -11
- package/src/__tests__/secure-keys.test.ts +3 -3
- package/src/__tests__/send-endpoint-busy.test.ts +83 -43
- package/src/__tests__/server-history-render.test.ts +4 -1
- package/src/__tests__/shell-observability.test.ts +249 -0
- package/src/__tests__/skill-feature-flags-integration.test.ts +19 -21
- package/src/__tests__/skill-feature-flags.test.ts +20 -22
- package/src/__tests__/skill-load-feature-flag.test.ts +15 -15
- package/src/__tests__/skill-projection-feature-flag.test.ts +44 -30
- package/src/__tests__/skill-projection.benchmark.test.ts +5 -7
- package/src/__tests__/skill-tool-factory.test.ts +96 -95
- package/src/__tests__/skills-files-catalog-fallback.test.ts +10 -0
- package/src/__tests__/skillssh-files.test.ts +1 -0
- package/src/__tests__/slack-channel-config.test.ts +3 -3
- package/src/__tests__/starter-task-flow.test.ts +6 -6
- package/src/__tests__/strip-memory-injections.test.ts +102 -14
- package/src/__tests__/subagent-call-site-routing.test.ts +13 -5
- package/src/__tests__/subagent-disposal.test.ts +27 -8
- package/src/__tests__/subagent-fork-notifications.test.ts +24 -9
- package/src/__tests__/subagent-fork-spawn.test.ts +13 -4
- package/src/__tests__/subagent-manager-notify.test.ts +20 -8
- package/src/__tests__/subagent-notify-parent.test.ts +5 -4
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +58 -0
- package/src/__tests__/subagent-tools.test.ts +2 -1
- package/src/__tests__/suggestion-routes.test.ts +4 -3
- package/src/__tests__/sync-message-contract.test.ts +19 -16
- package/src/__tests__/system-prompt.test.ts +92 -0
- package/src/__tests__/terminal-tools.test.ts +3 -24
- package/src/__tests__/test-preload-verifier.ts +68 -0
- package/src/__tests__/test-preload.ts +32 -39
- package/src/__tests__/thread-backfill.test.ts +4 -9
- package/src/__tests__/title-generate-pipeline.test.ts +1 -1
- package/src/__tests__/token-estimate-pipeline.test.ts +2 -4
- package/src/__tests__/tool-error-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execute-pipeline.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +20 -7
- package/src/__tests__/tool-executor.test.ts +55 -10
- package/src/__tests__/tool-preview-lifecycle.test.ts +14 -11
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +9 -12
- package/src/__tests__/tool-result-truncation.test.ts +3 -1
- package/src/__tests__/tools-audio-read.test.ts +113 -0
- package/src/__tests__/turn-boundary-resolution.test.ts +44 -84
- package/src/__tests__/turn-events-store.test.ts +11 -7
- package/src/__tests__/twilio-routes.test.ts +3 -2
- package/src/__tests__/validate-input.test.ts +381 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +1 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +10 -7
- package/src/__tests__/voice-session-bridge.test.ts +50 -35
- 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 +143 -31
- package/src/acp/prepare-agent-env.ts +52 -11
- package/src/acp/session-manager.ts +5 -6
- package/src/agent/compaction-circuit.ts +140 -0
- package/src/agent/loop.ts +489 -85
- package/src/api/README.md +126 -2
- package/src/api/constants/call-sites.ts +27 -0
- package/src/api/constants/tool-execution.ts +21 -0
- package/src/api/events/assistant-activity-state.ts +75 -0
- package/src/api/events/assistant-outbound-attachment.ts +49 -0
- package/src/api/events/assistant-text-delta.ts +30 -0
- package/src/api/events/assistant-turn-start.ts +31 -0
- package/src/api/events/avatar-updated.ts +24 -0
- package/src/api/events/compaction-circuit-closed.ts +26 -0
- package/src/api/events/compaction-circuit-open.ts +28 -0
- package/src/api/events/confirmation-request.ts +114 -0
- package/src/api/events/contact-request.ts +33 -0
- package/src/api/events/conversation-error.ts +77 -0
- package/src/api/events/conversation-list-invalidated.ts +38 -0
- package/src/api/events/conversation-title-updated.ts +24 -0
- package/src/api/events/disk-pressure-status-changed.ts +61 -0
- package/src/api/events/document-comment-created.ts +44 -0
- package/src/api/events/document-comment-deleted.ts +22 -0
- package/src/api/events/document-comment-reopened.ts +23 -0
- package/src/api/events/document-comment-resolved.ts +25 -0
- package/src/api/events/document-editor-update.ts +27 -0
- package/src/api/events/error.ts +32 -0
- package/src/api/events/generation-cancelled.ts +22 -0
- package/src/api/events/generation-handoff.ts +39 -0
- package/src/api/events/home-feed-updated.ts +26 -0
- package/src/api/events/identity-changed.ts +32 -0
- package/src/api/events/interaction-resolved.ts +50 -0
- package/src/api/events/message-complete.ts +40 -0
- package/src/api/events/message-dequeued.ts +21 -0
- package/src/api/events/message-queued-deleted.ts +23 -0
- package/src/api/events/message-queued.ts +22 -0
- package/src/api/events/message-request-complete.ts +29 -0
- package/src/api/events/navigate-settings.ts +20 -0
- package/src/api/events/notification-intent.ts +33 -0
- package/src/api/events/open-url.ts +28 -0
- package/src/api/events/question-request.ts +67 -0
- package/src/{events → api/events}/relationship-state-updated.ts +6 -8
- package/src/api/events/secret-request.ts +42 -0
- package/src/api/events/subagent-event.ts +79 -0
- package/src/api/events/subagent-spawned.ts +40 -0
- package/src/api/events/subagent-status-changed.ts +65 -0
- package/src/api/events/sync-changed.ts +29 -0
- package/src/api/events/tool-result.ts +129 -0
- package/src/api/events/tool-use-start.ts +30 -0
- package/src/api/events/turn-profile-auto-routed.ts +28 -0
- package/src/api/events/ui-surface-complete.ts +30 -0
- package/src/api/events/ui-surface-dismiss.ts +22 -0
- package/src/api/events/ui-surface-show.ts +67 -0
- package/src/api/events/ui-surface-update.ts +26 -0
- package/src/api/events/usage-update.ts +34 -0
- package/src/api/events/user-message-echo.ts +35 -0
- package/src/api/index.ts +482 -3
- package/src/api/requests/dictation.ts +45 -0
- package/src/api/responses/disk-pressure-status.ts +26 -0
- package/src/api/responses/home.ts +217 -0
- package/src/api/responses/llm-context-response.ts +41 -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/api/responses/memory-v3-selection-log.ts +50 -0
- package/src/api/responses/subagent-detail.ts +48 -0
- package/src/approvals/guardian-decision-primitive.ts +7 -15
- package/src/approvals/guardian-request-resolvers.ts +6 -9
- package/src/avatar/__tests__/avatar-manifest.test.ts +236 -0
- package/src/avatar/__tests__/avatar-store.test.ts +193 -0
- package/src/avatar/avatar-manifest.ts +195 -0
- package/src/avatar/avatar-store.ts +113 -0
- package/src/avatar/traits-png-sync.ts +8 -2
- package/src/background-wake/background-wake-routes.test.ts +687 -52
- package/src/background-wake/next-wake.test.ts +31 -1
- package/src/background-wake/next-wake.ts +4 -1
- package/src/background-wake/platform-client.test.ts +308 -0
- package/src/background-wake/platform-client.ts +167 -0
- package/src/background-wake/publisher.ts +91 -0
- package/src/background-wake/runtime-registry.ts +2 -2
- package/src/background-wake/wake-intent-hooks.test.ts +282 -0
- package/src/calls/call-conversation-messages.ts +6 -4
- package/src/calls/guardian-action-sweep.ts +6 -4
- package/src/calls/guardian-dispatch.ts +1 -0
- package/src/calls/relay-server.ts +12 -8
- package/src/calls/voice-session-bridge.ts +17 -31
- package/src/cli/commands/__tests__/conversations-slack.test.ts +16 -0
- package/src/cli/commands/__tests__/memory-v3.test.ts +245 -0
- package/src/cli/commands/__tests__/notifications.test.ts +184 -40
- package/src/cli/commands/avatar.ts +17 -11
- package/src/cli/commands/channels/__tests__/channels.test.ts +143 -0
- package/src/cli/commands/channels/index.ts +229 -0
- package/src/cli/commands/conversations.ts +15 -1
- package/src/cli/commands/db/__tests__/repair.test.ts +540 -0
- package/src/cli/commands/db/__tests__/status.test.ts +253 -0
- package/src/cli/commands/db/format.ts +48 -0
- package/src/cli/commands/db/index.ts +29 -0
- package/src/cli/commands/db/repair-step-conversation-backfill.ts +345 -0
- package/src/cli/commands/db/repair-step-integrity.ts +146 -0
- package/src/cli/commands/db/repair-steps.ts +164 -0
- package/src/cli/commands/db/repair.ts +141 -0
- package/src/cli/commands/db/status.ts +366 -0
- package/src/cli/commands/memory-v3.ts +168 -203
- package/src/cli/commands/notifications.ts +365 -55
- package/src/cli/lib/cli-colors.ts +24 -6
- package/src/cli/lib/open-browser.ts +7 -2
- package/src/cli/program.ts +6 -5
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/assistant-feature-flags.ts +25 -44
- package/src/config/bundled-skills/app-builder/SKILL.md +14 -3
- package/src/config/bundled-skills/document-editor/SKILL.md +5 -1
- package/src/config/bundled-skills/media-processing/services/reduce.ts +6 -9
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +2 -2
- package/src/config/bundled-skills/schedule/TOOLS.json +10 -2
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +1 -0
- package/src/config/call-site-defaults.ts +3 -8
- package/src/config/feature-flag-cache.ts +86 -0
- package/src/config/feature-flag-registry.json +42 -26
- 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 +1 -211
- package/src/config/schemas/call-site-catalog.ts +8 -15
- package/src/config/schemas/heartbeat.ts +1 -1
- package/src/config/schemas/llm.ts +92 -4
- package/src/config/schemas/memory-lifecycle.ts +24 -0
- package/src/config/schemas/memory-v2.ts +0 -227
- package/src/config/schemas/memory-v3.ts +39 -0
- package/src/config/schemas/memory.ts +6 -1
- package/src/config/schemas/services.ts +6 -2
- package/src/config/schemas/timeouts.ts +3 -1
- package/src/config/seed-inference-profiles.ts +36 -16
- package/src/context/compactor.ts +54 -31
- package/src/context/token-estimator.ts +29 -5
- package/src/context/tool-result-truncation.ts +1 -43
- package/src/context/window-manager.ts +138 -20
- 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 +15 -17
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -2
- package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -0
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +25 -12
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +1 -0
- package/src/daemon/__tests__/switch-inference-profile-tool.test.ts +107 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +11 -6
- package/src/daemon/approval-generators.ts +4 -4
- package/src/daemon/config-watcher.ts +7 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +613 -155
- package/src/daemon/conversation-agent-loop.ts +409 -605
- package/src/daemon/conversation-error.ts +40 -12
- package/src/daemon/conversation-history.ts +22 -6
- package/src/daemon/conversation-launch.ts +4 -8
- package/src/daemon/conversation-lifecycle.ts +10 -38
- package/src/daemon/conversation-messaging.ts +83 -44
- package/src/daemon/conversation-notifiers.ts +7 -5
- package/src/daemon/conversation-process.ts +174 -116
- package/src/daemon/conversation-runtime-assembly.ts +76 -30
- package/src/daemon/conversation-skill-tools.ts +14 -30
- package/src/daemon/conversation-store.ts +6 -5
- package/src/daemon/conversation-surfaces.ts +124 -103
- package/src/daemon/conversation-tool-setup.ts +36 -48
- package/src/daemon/conversation.ts +111 -166
- package/src/daemon/daemon-control.ts +1 -1
- package/src/daemon/daemon-skill-host.ts +7 -4
- package/src/daemon/disk-pressure-guard.ts +54 -50
- package/src/daemon/external-plugins-bootstrap.ts +46 -24
- package/src/daemon/first-greeting.ts +53 -13
- package/src/daemon/guardian-action-generators.ts +2 -2
- package/src/daemon/handlers/conversations.ts +6 -22
- package/src/daemon/handlers/shared.ts +10 -1
- package/src/daemon/handlers/skills.ts +15 -14
- package/src/daemon/host-app-control-proxy.ts +54 -1
- package/src/daemon/host-cu-proxy.ts +46 -22
- package/src/daemon/host-file-proxy.ts +25 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -6
- package/src/daemon/lifecycle.ts +40 -67
- package/src/daemon/mcp-reload-service.ts +1 -1
- package/src/daemon/meet-manifest-loader.ts +10 -17
- package/src/daemon/message-protocol.ts +2 -3
- package/src/daemon/message-provenance.ts +49 -0
- package/src/daemon/message-types/contacts.ts +3 -20
- package/src/daemon/message-types/conversations.ts +25 -125
- package/src/daemon/message-types/document-comments.ts +8 -44
- package/src/daemon/message-types/documents.ts +3 -9
- package/src/daemon/message-types/home.ts +5 -18
- package/src/daemon/message-types/integrations.ts +4 -13
- package/src/daemon/message-types/messages.ts +47 -377
- package/src/daemon/message-types/notifications.ts +2 -32
- package/src/daemon/message-types/settings.ts +3 -8
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/subagents.ts +6 -0
- package/src/daemon/message-types/surfaces.ts +2 -0
- package/src/daemon/message-types/sync.ts +12 -25
- package/src/daemon/message-types/workspace.ts +3 -11
- package/src/daemon/process-message.ts +58 -55
- package/src/daemon/providers-setup.ts +1 -1
- package/src/daemon/server.ts +28 -0
- package/src/daemon/switch-inference-profile-tool.ts +13 -3
- package/src/daemon/tool-setup-types.ts +0 -6
- package/src/daemon/tool-side-effects.ts +10 -7
- package/src/daemon/trust-context.ts +13 -0
- package/src/daemon/wake-target-adapter.ts +21 -1
- 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 +31 -0
- package/src/heartbeat/heartbeat-run-store.ts +31 -0
- package/src/heartbeat/heartbeat-service.ts +79 -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/feature-gate.ts +22 -0
- package/src/home/feed-types.ts +36 -221
- package/src/home/feed-writer.ts +146 -7
- package/src/home/suggested-prompts.ts +27 -145
- package/src/ipc/__tests__/cli-ipc.test.ts +1 -0
- package/src/ipc/__tests__/email-ipc.test.ts +0 -9
- package/src/ipc/gateway-client.test.ts +4 -1
- package/src/ipc/routes/__tests__/route-adapter.test.ts +244 -0
- package/src/ipc/routes/route-adapter.ts +45 -6
- package/src/ipc/skill-routes/__tests__/memory.test.ts +19 -9
- package/src/ipc/skill-routes/__tests__/providers.test.ts +10 -10
- package/src/ipc/skill-routes/__tests__/registries.test.ts +59 -20
- package/src/ipc/skill-routes/memory.ts +27 -13
- package/src/ipc/skill-routes/providers.ts +5 -6
- package/src/ipc/skill-routes/registries.ts +39 -88
- package/src/live-voice/__tests__/live-voice-archive.test.ts +24 -11
- package/src/memory/__tests__/conversation-queries.test.ts +192 -8
- package/src/memory/__tests__/db-maintenance.test.ts +128 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +1 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +5 -4
- 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 +11 -6
- 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/__tests__/memory-v3-selections-migration.test.ts +103 -0
- package/src/memory/context-search/agent-runner.ts +2 -4
- package/src/memory/conversation-attention-store.ts +17 -3
- package/src/memory/conversation-crud.ts +386 -115
- package/src/memory/conversation-queries.ts +78 -22
- package/src/memory/db-connection.ts +29 -19
- package/src/memory/db-init.ts +12 -0
- package/src/memory/db-maintenance.ts +18 -2
- 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/consolidation.ts +8 -11
- package/src/memory/graph/conversation-graph-memory.ts +41 -8
- package/src/memory/graph/extraction.ts +6 -9
- package/src/memory/graph/narrative.ts +2 -2
- package/src/memory/graph/pattern-scan.ts +2 -2
- package/src/memory/graph/retriever.test.ts +3 -3
- package/src/memory/graph/retriever.ts +20 -26
- package/src/memory/graph/tools.ts +4 -4
- package/src/memory/job-handlers/conversation-starters.ts +32 -32
- package/src/memory/job-handlers/embedding.test.ts +3 -2
- package/src/memory/job-handlers/summarization.ts +1 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -2
- package/src/memory/jobs-store.ts +3 -1
- package/src/memory/jobs-worker.ts +63 -40
- package/src/memory/llm-request-log-source-clickhouse.ts +55 -1
- package/src/memory/llm-request-log-source-local.ts +13 -0
- package/src/memory/llm-request-log-source.ts +21 -6
- package/src/memory/llm-request-log-store.ts +147 -3
- package/src/memory/llm-usage-store.ts +10 -0
- package/src/memory/memory-marker.ts +17 -0
- package/src/memory/memory-retrospective-job.ts +6 -2
- package/src/memory/memory-v2-activation-log-store.ts +13 -1
- package/src/memory/migrations/265-drop-provider-connection-status.ts +26 -0
- package/src/memory/migrations/266-messages-client-message-id.ts +43 -0
- package/src/memory/migrations/267-llm-usage-events-add-assistant-version.ts +46 -0
- package/src/memory/migrations/268-add-memory-v3-selections.ts +28 -0
- package/src/memory/migrations/269-schedule-script-timeout.ts +11 -0
- package/src/memory/migrations/270-messages-role-created-at-index.ts +18 -0
- package/src/memory/migrations/__tests__/267-llm-usage-events-add-assistant-version.test.ts +117 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/schema/conversations.ts +9 -1
- package/src/memory/schema/inference.ts +0 -1
- package/src/memory/schema/infrastructure.ts +11 -0
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +5 -2
- package/src/memory/v2/__tests__/consolidation-job.test.ts +124 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +9 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +9 -4
- package/src/memory/v2/__tests__/harness-runner.test.ts +26 -0
- package/src/memory/v2/__tests__/migration.test.ts +11 -3
- package/src/memory/v2/__tests__/page-index.test.ts +37 -1
- package/src/memory/v2/__tests__/router.test.ts +14 -4
- package/src/memory/v2/__tests__/sweep-job.test.ts +9 -5
- package/src/memory/v2/backfill-jobs.ts +6 -0
- package/src/memory/v2/consolidation-job.ts +89 -9
- package/src/memory/v2/harness/metrics.ts +5 -1
- package/src/memory/v2/harness/replay-input.ts +19 -3
- package/src/memory/v2/harness/runner.ts +6 -0
- package/src/memory/v2/harness/trace.ts +6 -0
- package/src/memory/v2/migration.ts +5 -3
- package/src/memory/v2/page-index.ts +11 -0
- package/src/memory/v2/router.ts +8 -11
- package/src/memory/v2/sweep-job.ts +8 -11
- package/src/memory/v2/types.ts +1 -0
- package/src/memory/v3/__tests__/assign.test.ts +242 -0
- package/src/memory/v3/__tests__/capabilities.test.ts +118 -0
- package/src/memory/v3/__tests__/core.test.ts +39 -0
- package/src/memory/v3/__tests__/fixtures/eval-turns.json +36 -0
- package/src/memory/v3/__tests__/fixtures/live-turns.json +37 -0
- package/src/memory/v3/__tests__/health.test.ts +203 -0
- package/src/memory/v3/__tests__/live-integration.test.ts +330 -0
- package/src/memory/v3/__tests__/maintain-job.test.ts +288 -0
- package/src/memory/v3/__tests__/needle.test.ts +107 -0
- package/src/memory/v3/__tests__/orchestrate.test.ts +400 -0
- package/src/memory/v3/__tests__/reconcile.test.ts +274 -0
- package/src/memory/v3/__tests__/render-injection.test.ts +61 -0
- package/src/memory/v3/__tests__/router.test.ts +260 -0
- package/src/memory/v3/__tests__/selection-log-store.test.ts +179 -0
- package/src/memory/v3/__tests__/selector.test.ts +404 -0
- package/src/memory/v3/__tests__/shadow-plugin.test.ts +414 -0
- package/src/memory/v3/__tests__/snapshot.test.ts +168 -0
- package/src/memory/v3/__tests__/tree.test.ts +192 -0
- package/src/memory/v3/__tests__/types.test.ts +54 -0
- package/src/memory/v3/__tests__/working-set-eviction.test.ts +106 -0
- package/src/memory/v3/__tests__/working-set-skeleton.test.ts +44 -0
- package/src/memory/v3/assign.ts +268 -0
- package/src/memory/v3/capabilities.ts +124 -0
- package/src/memory/v3/core.ts +26 -0
- package/src/memory/v3/data/README.md +84 -0
- package/src/memory/v3/data/assignments.json +5 -0
- package/src/memory/v3/data/core.json +1 -0
- package/src/memory/v3/data/leaves/domain-a/topic-x.md +9 -0
- package/src/memory/v3/data/leaves/domain-a/topic-y.md +9 -0
- package/src/memory/v3/data/leaves/domain-b/topic-z.md +9 -0
- package/src/memory/v3/health.ts +0 -0
- package/src/memory/v3/maintain-job.ts +314 -0
- package/src/memory/v3/needle.ts +115 -0
- package/src/memory/v3/orchestrate.ts +114 -0
- package/src/memory/v3/page-content.ts +34 -0
- package/src/memory/v3/provider-blocks.ts +16 -0
- package/src/memory/v3/reconcile.ts +523 -0
- package/src/memory/v3/render-injection.ts +32 -0
- package/src/memory/v3/router.ts +184 -0
- package/src/memory/v3/selection-log-store.ts +84 -0
- package/src/memory/v3/selector.ts +211 -0
- package/src/memory/v3/shadow-plugin.ts +379 -0
- package/src/memory/v3/snapshot.ts +209 -0
- package/src/memory/v3/tree.ts +174 -0
- package/src/memory/v3/types.ts +46 -60
- package/src/memory/v3/working-set.ts +88 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +1 -1
- package/src/messaging/providers/slack/render-transcript.ts +2 -2
- package/src/messaging/style-analyzer.ts +8 -11
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +1 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +1 -0
- package/src/notifications/adapters/slack.ts +45 -11
- package/src/notifications/broadcaster.ts +114 -63
- package/src/notifications/conversation-pairing.ts +30 -8
- package/src/notifications/decision-engine.ts +10 -13
- package/src/notifications/decisions-store.ts +32 -1
- package/src/notifications/deliveries-store.ts +45 -0
- package/src/notifications/edit-notification.ts +201 -0
- package/src/notifications/emit-signal.ts +11 -1
- package/src/notifications/preference-extractor.ts +11 -14
- 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 +42 -36
- package/src/permissions/question-prompter.test.ts +35 -26
- package/src/permissions/question-prompter.ts +6 -10
- 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 +2 -0
- package/src/plugin-api/types.ts +25 -3
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +93 -0
- package/src/plugins/defaults/circuit-breaker/package.json +15 -0
- package/src/plugins/defaults/circuit-breaker/register.ts +39 -0
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +25 -0
- package/src/plugins/defaults/compaction/package.json +15 -0
- package/src/plugins/defaults/compaction/register.ts +35 -0
- package/src/plugins/defaults/compaction/terminal.ts +73 -0
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +22 -0
- package/src/plugins/defaults/empty-response/package.json +15 -0
- package/src/plugins/defaults/empty-response/register.ts +28 -0
- package/src/plugins/defaults/empty-response/terminal.ts +106 -0
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/history-repair/package.json +15 -0
- package/src/plugins/defaults/history-repair/register.ts +24 -0
- package/src/{daemon/history-repair.ts → plugins/defaults/history-repair/terminal.ts} +48 -35
- package/src/plugins/defaults/index.ts +29 -40
- package/src/plugins/defaults/injectors/package.json +15 -0
- package/src/plugins/defaults/{injectors.ts → injectors/register.ts} +16 -46
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +17 -0
- package/src/plugins/defaults/llm-call/package.json +15 -0
- package/src/plugins/defaults/{llm-call.ts → llm-call/register.ts} +6 -38
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +17 -0
- package/src/plugins/defaults/memory-retrieval/package.json +15 -0
- package/src/plugins/defaults/{memory-retrieval.ts → memory-retrieval/register.ts} +10 -48
- package/src/plugins/defaults/{overflow-reduce.ts → overflow-reduce/middlewares/overflowReduce.ts} +18 -77
- package/src/plugins/defaults/overflow-reduce/package.json +15 -0
- package/src/plugins/defaults/overflow-reduce/register.ts +42 -0
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +19 -0
- package/src/plugins/defaults/persistence/package.json +15 -0
- package/src/plugins/defaults/persistence/register.ts +38 -0
- package/src/plugins/defaults/persistence/terminal.ts +83 -0
- package/src/plugins/defaults/title-generate/package.json +15 -0
- package/src/plugins/defaults/title-generate/register.ts +35 -0
- package/src/plugins/defaults/title-generate/terminal.ts +31 -0
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +23 -0
- package/src/plugins/defaults/token-estimate/package.json +15 -0
- package/src/plugins/defaults/token-estimate/register.ts +34 -0
- package/src/plugins/defaults/token-estimate/terminal.ts +40 -0
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +21 -0
- package/src/plugins/defaults/tool-error/package.json +15 -0
- package/src/plugins/defaults/tool-error/register.ts +35 -0
- package/src/plugins/defaults/tool-error/terminal.ts +47 -0
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +23 -0
- package/src/plugins/defaults/tool-execute/package.json +15 -0
- package/src/plugins/defaults/{tool-execute.ts → tool-execute/register.ts} +8 -46
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +23 -0
- package/src/plugins/defaults/tool-result-truncate/package.json +15 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +35 -0
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +113 -0
- package/src/plugins/defaults/tool-result-truncate/types.ts +22 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/pipeline.ts +0 -12
- package/src/plugins/types.ts +107 -102
- package/src/plugins/user-loader.ts +4 -3
- package/src/proactive-artifact/aux-message-injector.ts +0 -1
- package/src/proactive-artifact/job.test.ts +21 -8
- package/src/proactive-artifact/job.ts +3 -1
- package/src/prompts/__tests__/system-prompt.test.ts +4 -4
- package/src/prompts/sections.ts +20 -7
- package/src/prompts/system-prompt.ts +38 -40
- package/src/prompts/template-detection.ts +10 -4
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +2 -2
- package/src/prompts/templates/BOOTSTRAP.md +10 -10
- package/src/prompts/templates/IDENTITY.md +0 -2
- package/src/prompts/templates/system-sections.ts +6 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +3 -4
- package/src/providers/__tests__/registry-native-web-search.test.ts +122 -0
- package/src/providers/__tests__/retry-callsite.test.ts +25 -25
- package/src/providers/__tests__/satellite-connection-routing.test.ts +7 -21
- package/src/providers/anthropic/client.ts +24 -5
- package/src/providers/call-site-routing.ts +34 -18
- package/src/providers/connection-model-compat.ts +23 -0
- package/src/providers/connection-resolution.ts +39 -20
- package/src/providers/fireworks/client.ts +1 -0
- package/src/providers/gemini/client.ts +176 -37
- package/src/providers/gemini/inline-media.ts +74 -0
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +0 -2
- package/src/providers/inference/__tests__/base-url-security.test.ts +2 -3
- package/src/providers/inference/__tests__/{connections-status-label.test.ts → connections-label.test.ts} +12 -111
- package/src/providers/inference/auth.ts +0 -8
- package/src/providers/inference/connections.ts +3 -66
- package/src/providers/inference/resolve-auth.ts +2 -3
- package/src/providers/model-catalog.ts +35 -1
- package/src/providers/model-intents.ts +3 -3
- package/src/providers/openai/__tests__/api-error-detail.test.ts +120 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +157 -7
- package/src/providers/openai/chat-completions-provider.ts +111 -16
- package/src/providers/openai/codex-models.ts +2 -0
- package/src/providers/openai/responses-provider.ts +54 -57
- package/src/providers/openrouter/client.ts +14 -14
- package/src/providers/provider-send-message.ts +23 -14
- package/src/providers/ratelimit.ts +1 -9
- package/src/providers/registry.ts +48 -8
- package/src/providers/retry.ts +16 -9
- package/src/providers/search-provider-catalog.ts +17 -9
- package/src/providers/types.ts +20 -2
- package/src/providers/usage-tracking.ts +1 -9
- package/src/runtime/__tests__/agent-wake.test.ts +132 -26
- package/src/runtime/__tests__/background-job-runner.test.ts +2 -3
- package/src/runtime/access-request-helper.ts +1 -0
- package/src/runtime/agent-wake.ts +93 -18
- package/src/runtime/assistant-event-hub.ts +2 -2
- package/src/runtime/auth/__tests__/guard-tests.test.ts +75 -109
- package/src/runtime/auth/__tests__/route-policy.test.ts +153 -170
- package/src/runtime/auth/route-policy.ts +42 -1069
- package/src/runtime/background-job-runner.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -1
- package/src/runtime/channel-approvals.ts +3 -14
- package/src/runtime/channel-invite-transport.ts +5 -6
- package/src/runtime/channel-readiness-service.ts +70 -5
- package/src/runtime/channel-reply-delivery.ts +23 -0
- package/src/runtime/channel-retry-sweep.ts +59 -30
- package/src/runtime/confirmation-request-guardian-bridge.ts +1 -1
- package/src/runtime/conversation-stream-state.ts +294 -0
- package/src/runtime/http-router.ts +19 -22
- package/src/runtime/http-types.ts +12 -6
- package/src/runtime/invite-instruction-generator.ts +3 -3
- package/src/runtime/migrations/vbundle-builder.ts +3 -2
- package/src/runtime/pending-interactions.ts +2 -2
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +565 -0
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +1 -0
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +4 -4
- package/src/runtime/routes/__tests__/conversation-compaction-routes.test.ts +436 -0
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +237 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +98 -0
- package/src/runtime/routes/__tests__/heartbeat-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +209 -1
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +26 -72
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +58 -5
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +6 -6
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +3 -2
- package/src/runtime/routes/__tests__/stt-routes.test.ts +3 -3
- package/src/runtime/routes/__tests__/suggest-trust-rule-routes.test.ts +5 -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/__tests__/tts-routes.test.ts +3 -3
- package/src/runtime/routes/acp-routes-list.test.ts +3 -0
- package/src/runtime/routes/acp-routes.test.ts +97 -75
- package/src/runtime/routes/acp-routes.ts +29 -6
- package/src/runtime/routes/app-management-routes.ts +208 -28
- package/src/runtime/routes/app-routes.ts +25 -5
- package/src/runtime/routes/approval-routes.ts +16 -4
- package/src/runtime/routes/attachment-routes.ts +25 -1
- package/src/runtime/routes/audio-routes.ts +1 -0
- package/src/runtime/routes/audit-routes.ts +5 -0
- package/src/runtime/routes/auth-routes.ts +5 -0
- package/src/runtime/routes/avatar-routes.ts +238 -59
- package/src/runtime/routes/background-tool-routes.ts +9 -0
- package/src/runtime/routes/background-wake-routes.ts +201 -23
- package/src/runtime/routes/backup-routes.ts +45 -0
- package/src/runtime/routes/bookmark-routes.ts +13 -0
- package/src/runtime/routes/brain-graph-routes.ts +9 -0
- package/src/runtime/routes/browser-routes.ts +5 -0
- package/src/runtime/routes/browser-tabs-routes.ts +5 -0
- package/src/runtime/routes/btw-routes.ts +9 -5
- package/src/runtime/routes/cache-routes.ts +13 -0
- package/src/runtime/routes/call-routes.ts +21 -10
- package/src/runtime/routes/channel-availability-routes.ts +5 -1
- package/src/runtime/routes/channel-readiness-routes.ts +37 -4
- package/src/runtime/routes/channel-route-definitions.ts +21 -0
- package/src/runtime/routes/channel-verification-routes.ts +21 -0
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +9 -2
- package/src/runtime/routes/client-routes.ts +9 -0
- package/src/runtime/routes/consolidation-routes.ts +13 -5
- package/src/runtime/routes/contact-prompt-routes.ts +9 -0
- package/src/runtime/routes/contact-routes.ts +90 -23
- package/src/runtime/routes/content-source-routes.ts +5 -1
- package/src/runtime/routes/conversation-analysis-routes.ts +11 -1
- package/src/runtime/routes/conversation-attention-routes.ts +5 -0
- package/src/runtime/routes/conversation-cli-routes.ts +54 -7
- package/src/runtime/routes/conversation-compaction-routes.ts +292 -0
- package/src/runtime/routes/conversation-list-routes.ts +225 -9
- package/src/runtime/routes/conversation-management-routes.ts +96 -28
- package/src/runtime/routes/conversation-query-routes.ts +148 -51
- package/src/runtime/routes/conversation-routes.ts +259 -158
- package/src/runtime/routes/conversation-starter-routes.ts +22 -13
- package/src/runtime/routes/conversations-import-routes.ts +25 -7
- package/src/runtime/routes/credential-prompt-routes.ts +5 -0
- package/src/runtime/routes/credential-routes.ts +25 -6
- package/src/runtime/routes/debug-bash-routes.ts +5 -0
- package/src/runtime/routes/debug-routes.ts +11 -2
- package/src/runtime/routes/defer-routes.ts +13 -0
- package/src/runtime/routes/diagnostics-routes.ts +37 -46
- package/src/runtime/routes/disk-pressure-routes.ts +17 -31
- package/src/runtime/routes/document-comments-routes.ts +46 -27
- package/src/runtime/routes/documents-routes.ts +31 -11
- package/src/runtime/routes/domain-routes.ts +61 -28
- package/src/runtime/routes/email-routes.ts +33 -0
- package/src/runtime/routes/events-routes.ts +114 -9
- package/src/runtime/routes/filing-routes.ts +9 -4
- package/src/runtime/routes/gateway-log-routes.ts +5 -0
- package/src/runtime/routes/global-search-routes.ts +53 -50
- package/src/runtime/routes/group-routes.ts +32 -5
- package/src/runtime/routes/guardian-action-routes.ts +9 -0
- package/src/runtime/routes/guardian-approval-interception.ts +0 -31
- package/src/runtime/routes/heartbeat-routes.ts +25 -9
- package/src/runtime/routes/home-feed-routes.ts +149 -16
- package/src/runtime/routes/home-state-routes.ts +8 -40
- package/src/runtime/routes/host-app-control-routes.ts +5 -0
- package/src/runtime/routes/host-bash-routes.ts +5 -0
- package/src/runtime/routes/host-browser-routes.ts +13 -0
- package/src/runtime/routes/host-cu-routes.ts +5 -0
- package/src/runtime/routes/host-file-routes.ts +26 -6
- package/src/runtime/routes/host-transfer-routes.ts +13 -2
- package/src/runtime/routes/http-adapter.ts +1 -2
- package/src/runtime/routes/identity-intro-cache.ts +72 -16
- package/src/runtime/routes/identity-routes.ts +42 -11
- package/src/runtime/routes/image-generation-routes.ts +5 -0
- package/src/runtime/routes/inbound-message-handler.ts +15 -11
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +524 -12
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +72 -27
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +13 -3
- package/src/runtime/routes/inference-provider-connection-routes.ts +26 -31
- package/src/runtime/routes/inference-send-routes.ts +11 -11
- package/src/runtime/routes/integrations/a2a.ts +30 -7
- package/src/runtime/routes/integrations/slack/channel.ts +19 -3
- package/src/runtime/routes/integrations/slack/share.ts +9 -2
- package/src/runtime/routes/integrations/telegram.ts +28 -9
- package/src/runtime/routes/integrations/twilio.ts +35 -7
- package/src/runtime/routes/integrations/vercel.ts +18 -3
- package/src/runtime/routes/internal-oauth-routes.ts +5 -0
- package/src/runtime/routes/internal-twilio-routes.ts +13 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +39 -4
- package/src/runtime/routes/llm-context-normalization.ts +7 -2
- package/src/runtime/routes/log-export-routes.ts +28 -10
- package/src/runtime/routes/mcp-auth-routes.ts +25 -0
- package/src/runtime/routes/memory-item-routes.ts +21 -10
- package/src/runtime/routes/memory-v2-routes.ts +90 -36
- package/src/runtime/routes/memory-v3-routes.ts +283 -259
- package/src/runtime/routes/migration-rollback-routes.ts +5 -1
- package/src/runtime/routes/migration-routes.ts +49 -13
- package/src/runtime/routes/notification-routes.ts +80 -2
- package/src/runtime/routes/oauth-apps.ts +33 -11
- package/src/runtime/routes/oauth-commands-routes.ts +43 -15
- package/src/runtime/routes/oauth-connect-routes.ts +9 -0
- package/src/runtime/routes/oauth-lifecycle-routes.ts +5 -1
- package/src/runtime/routes/oauth-providers.ts +35 -10
- package/src/runtime/routes/platform-routes.ts +21 -0
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +3 -2
- package/src/runtime/routes/playground/__tests__/inject-failures.test.ts +37 -16
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +7 -3
- package/src/runtime/routes/playground/__tests__/state.test.ts +10 -3
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +0 -1
- package/src/runtime/routes/playground/inject-failures.ts +13 -8
- package/src/runtime/routes/playground/reset-circuit.ts +14 -9
- package/src/runtime/routes/playground/seed-conversation.ts +1 -1
- package/src/runtime/routes/playground/seeded-conversations.ts +3 -3
- package/src/runtime/routes/playground/state.ts +4 -3
- package/src/runtime/routes/plugins-routes.ts +22 -19
- package/src/runtime/routes/profiler-routes.ts +17 -4
- package/src/runtime/routes/ps-routes.ts +5 -0
- package/src/runtime/routes/publish-routes.ts +13 -3
- package/src/runtime/routes/question-routes.ts +5 -0
- package/src/runtime/routes/recording-routes.ts +25 -12
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/sanity-routes.ts +9 -2
- package/src/runtime/routes/schedule-routes.ts +137 -47
- package/src/runtime/routes/secret-routes.ts +17 -4
- package/src/runtime/routes/sequence-routes.ts +33 -0
- package/src/runtime/routes/settings-routes.ts +65 -19
- package/src/runtime/routes/skills-routes.ts +133 -69
- package/src/runtime/routes/slack-channel-routes.ts +5 -0
- package/src/runtime/routes/stt-routes.ts +13 -6
- package/src/runtime/routes/subagents-routes.ts +24 -18
- package/src/runtime/routes/suggest-trust-rule-routes.ts +7 -2
- package/src/runtime/routes/surface-action-routes.ts +10 -38
- package/src/runtime/routes/surface-content-routes.ts +21 -6
- package/src/runtime/routes/surface-conversation-resolver.ts +65 -0
- package/src/runtime/routes/task-routes.ts +37 -0
- package/src/runtime/routes/telemetry-routes.ts +9 -0
- package/src/runtime/routes/trace-event-routes.ts +42 -1
- package/src/runtime/routes/trust-rules-routes.ts +5 -0
- package/src/runtime/routes/tts-routes.ts +13 -6
- package/src/runtime/routes/types.ts +17 -8
- package/src/runtime/routes/ui-request-routes.ts +5 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +5 -0
- package/src/runtime/routes/usage-routes.ts +71 -3
- package/src/runtime/routes/user-routes-cli.ts +9 -0
- package/src/runtime/routes/user-routes.ts +5 -1
- package/src/runtime/routes/wake-conversation-routes.ts +5 -0
- package/src/runtime/routes/watcher-routes.ts +21 -0
- package/src/runtime/routes/webhook-routes.ts +9 -0
- package/src/runtime/routes/wipe-conversation-routes.ts +8 -0
- package/src/runtime/routes/work-items-routes.ts +47 -19
- package/src/runtime/routes/workspace-commit-routes.ts +5 -0
- package/src/runtime/routes/workspace-routes.test.ts +42 -0
- package/src/runtime/routes/workspace-routes.ts +120 -9
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +4 -4
- package/src/runtime/services/analyze-conversation.ts +3 -6
- package/src/runtime/services/conversation-serializer.ts +24 -2
- package/src/runtime/slack-dm-text-delivery.ts +177 -0
- package/src/runtime/sync/resource-sync-events.ts +17 -3
- package/src/runtime/sync/sync-publisher.ts +2 -2
- package/src/runtime/tool-grant-request-helper.ts +1 -0
- package/src/schedule/run-script.ts +28 -3
- package/src/schedule/schedule-store.ts +16 -1
- package/src/schedule/scheduler.ts +114 -16
- 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 +10 -16
- package/src/skills/catalog-files.ts +4 -1
- package/src/skills/clawhub-files.ts +2 -0
- package/src/skills/skillssh-files.ts +2 -0
- package/src/skills/validate-input.ts +177 -0
- package/src/subagent/manager.ts +16 -19
- package/src/subagent/types.ts +6 -0
- package/src/tasks/tool-sanitizer.ts +2 -2
- package/src/telemetry/types.ts +26 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +138 -1
- package/src/telemetry/usage-telemetry-reporter.ts +31 -0
- package/src/tools/acp/spawn.test.ts +88 -38
- package/src/tools/apps/definitions.ts +42 -24
- package/src/tools/ask-question/ask-question-tool.test.ts +120 -105
- package/src/tools/ask-question/ask-question-tool.ts +85 -90
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +2 -8
- package/src/tools/computer-use/definitions.ts +295 -289
- package/src/tools/credential-execution/make-authenticated-request.ts +56 -51
- package/src/tools/credential-execution/manage-secure-command-tool.ts +2 -2
- package/src/tools/credential-execution/run-authenticated-command.ts +82 -77
- package/src/tools/credentials/vault.ts +112 -111
- package/src/tools/document/document-tool.ts +131 -8
- package/src/tools/execution-target.ts +3 -6
- package/src/tools/execution-timeout.ts +3 -4
- package/src/tools/executor.ts +18 -55
- package/src/tools/filesystem/edit.ts +45 -42
- package/src/tools/filesystem/list.ts +33 -30
- package/src/tools/filesystem/read.ts +54 -35
- package/src/tools/filesystem/write.ts +34 -31
- package/src/tools/host-filesystem/edit.test.ts +1 -0
- package/src/tools/host-filesystem/edit.ts +44 -42
- package/src/tools/host-filesystem/read.test.ts +1 -0
- package/src/tools/host-filesystem/read.ts +49 -35
- package/src/tools/host-filesystem/transfer.test.ts +31 -6
- package/src/tools/host-filesystem/transfer.ts +121 -108
- package/src/tools/host-filesystem/write.test.ts +1 -0
- package/src/tools/host-filesystem/write.ts +33 -31
- package/src/tools/host-terminal/host-shell.ts +50 -48
- package/src/tools/mcp/mcp-tool-factory.ts +0 -2
- package/src/tools/memory/register.ts +23 -24
- 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 +49 -46
- package/src/tools/network/web-search.ts +215 -57
- package/src/tools/policy-context.ts +3 -1
- package/src/tools/registry.ts +184 -118
- package/src/tools/schedule/create.ts +12 -1
- package/src/tools/schedule/update.ts +16 -0
- package/src/tools/shared/filesystem/audio-read.ts +122 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/execute.ts +34 -31
- package/src/tools/skills/load.ts +29 -23
- package/src/tools/skills/skill-tool-factory.ts +17 -36
- package/src/tools/subagent/notify-parent.ts +35 -32
- package/src/tools/subagent/spawn.ts +3 -0
- package/src/tools/system/avatar-generator.ts +13 -22
- package/src/tools/system/request-permission.ts +30 -27
- package/src/tools/terminal/shell.ts +190 -61
- package/src/tools/tool-approval-handler.ts +10 -4
- package/src/tools/tool-defaults.ts +20 -9
- package/src/tools/tool-manifest.ts +4 -4
- package/src/tools/tool-name-aliases.ts +72 -14
- package/src/tools/types.ts +86 -33
- package/src/tools/ui-surface/definitions.ts +166 -94
- package/src/types/onboarding-context.ts +6 -0
- package/src/usage/attribution.ts +32 -1
- package/src/usage/types.ts +10 -0
- package/src/util/browser.ts +7 -2
- package/src/util/errors.ts +2 -2
- package/src/util/map-limit.ts +27 -0
- package/src/util/platform.ts +15 -12
- package/src/work-items/work-item-runner.ts +7 -2
- package/src/workspace/migrations/028-recover-conversations-from-disk-view.ts +7 -20
- 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/092-backfill-v3-leaves.ts +169 -0
- package/src/workspace/migrations/093-backfill-leaf-ids.ts +144 -0
- package/src/workspace/migrations/094-seed-avatar-manifest.ts +155 -0
- package/src/workspace/migrations/__tests__/094-seed-avatar-manifest.test.ts +136 -0
- package/src/workspace/migrations/__tests__/backfill-leaf-ids.test.ts +175 -0
- package/src/workspace/migrations/__tests__/backfill-v3-leaves.test.ts +124 -0
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/provider-commit-message-generator.ts +15 -17
- package/tsconfig.json +4 -1
- package/src/__tests__/history-repair-pipeline.test.ts +0 -396
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +0 -340
- package/src/cli/commands/memory-v3-render.ts +0 -344
- package/src/daemon/message-types/disk-pressure.ts +0 -9
- package/src/email/feature-gate.ts +0 -23
- package/src/memory/v3/__tests__/coactivation-store.test.ts +0 -422
- package/src/memory/v3/__tests__/consolidation-job.test.ts +0 -468
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +0 -324
- package/src/memory/v3/__tests__/edges.test.ts +0 -563
- package/src/memory/v3/__tests__/filter.test.ts +0 -512
- package/src/memory/v3/__tests__/gate.test.ts +0 -574
- package/src/memory/v3/__tests__/index-composition.test.ts +0 -233
- package/src/memory/v3/__tests__/loop.test.ts +0 -530
- package/src/memory/v3/__tests__/retriever.test.ts +0 -226
- package/src/memory/v3/__tests__/scouts.test.ts +0 -440
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +0 -312
- package/src/memory/v3/__tests__/system-prompts.test.ts +0 -154
- package/src/memory/v3/__tests__/traversal.test.ts +0 -469
- package/src/memory/v3/__tests__/tree-index.test.ts +0 -280
- package/src/memory/v3/__tests__/tree-store.test.ts +0 -529
- package/src/memory/v3/__tests__/tree-walk.test.ts +0 -707
- package/src/memory/v3/__tests__/validate.test.ts +0 -245
- package/src/memory/v3/auto-edges.ts +0 -223
- package/src/memory/v3/coactivation-store.ts +0 -124
- package/src/memory/v3/consolidation-job.ts +0 -323
- package/src/memory/v3/edge-learning-job.ts +0 -160
- package/src/memory/v3/edges.ts +0 -249
- package/src/memory/v3/filter.ts +0 -281
- package/src/memory/v3/gate.ts +0 -334
- package/src/memory/v3/index-composition.ts +0 -113
- package/src/memory/v3/llm-capture.ts +0 -46
- package/src/memory/v3/loop.ts +0 -382
- package/src/memory/v3/maintenance.ts +0 -144
- package/src/memory/v3/prompt-context.ts +0 -33
- package/src/memory/v3/prompts/consolidation.ts +0 -458
- package/src/memory/v3/prompts/system-prompts.ts +0 -196
- package/src/memory/v3/retriever.ts +0 -33
- package/src/memory/v3/scouts.ts +0 -420
- package/src/memory/v3/shadow-middleware.ts +0 -305
- package/src/memory/v3/traversal.ts +0 -206
- package/src/memory/v3/tree-index.ts +0 -237
- package/src/memory/v3/tree-store.ts +0 -394
- package/src/memory/v3/tree-walk.ts +0 -351
- package/src/memory/v3/validate.ts +0 -300
- package/src/plugins/defaults/circuit-breaker.ts +0 -141
- package/src/plugins/defaults/compaction.ts +0 -141
- package/src/plugins/defaults/empty-response.ts +0 -124
- package/src/plugins/defaults/history-repair.ts +0 -83
- package/src/plugins/defaults/persistence.ts +0 -127
- package/src/plugins/defaults/title-generate.ts +0 -90
- package/src/plugins/defaults/token-estimate.ts +0 -101
- package/src/plugins/defaults/tool-error.ts +0 -119
- package/src/plugins/defaults/tool-result-truncate.ts +0 -84
|
@@ -76,8 +76,7 @@ async function seedSlackMessage(opts: {
|
|
|
76
76
|
inboundResult.conversationId,
|
|
77
77
|
"user",
|
|
78
78
|
initialContent,
|
|
79
|
-
{ userMessageChannel: "slack" },
|
|
80
|
-
{ skipIndexing: true },
|
|
79
|
+
{ metadata: { userMessageChannel: "slack" }, skipIndexing: true },
|
|
81
80
|
);
|
|
82
81
|
|
|
83
82
|
linkMessage(inboundResult.eventId, inserted.id);
|
|
@@ -19,10 +19,8 @@
|
|
|
19
19
|
import { beforeEach, describe, expect, test } from "bun:test";
|
|
20
20
|
|
|
21
21
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
defaultEmptyResponseTerminal,
|
|
25
|
-
} from "../plugins/defaults/empty-response.js";
|
|
22
|
+
import { defaultEmptyResponsePlugin } from "../plugins/defaults/empty-response/register.js";
|
|
23
|
+
import { defaultEmptyResponseTerminal } from "../plugins/defaults/empty-response/terminal.js";
|
|
26
24
|
import { DEFAULT_TIMEOUTS, runPipeline } from "../plugins/pipeline.js";
|
|
27
25
|
import {
|
|
28
26
|
getMiddlewaresFor,
|
|
@@ -73,10 +71,21 @@ function makeArgs(
|
|
|
73
71
|
emptyResponseRetries: 0,
|
|
74
72
|
maxEmptyResponseRetries: 1,
|
|
75
73
|
priorAssistantHadVisibleText: false,
|
|
74
|
+
// Default to `null` (no stop reason reported) so existing fixtures
|
|
75
|
+
// exercise the "organic empty turn" path. The refusal branch
|
|
76
|
+
// dedicated tests below set this to `"refusal"` explicitly.
|
|
77
|
+
stopReason: null,
|
|
76
78
|
...overrides,
|
|
77
79
|
};
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Refusal-specific nudge text — keep in sync with `register.ts`. Clients
|
|
84
|
+
* (and the model) may match on this exact text.
|
|
85
|
+
*/
|
|
86
|
+
const CANONICAL_REFUSAL_NUDGE_TEXT =
|
|
87
|
+
'<system_notice>Your previous response was empty because the upstream provider returned stop_reason="refusal". Please answer the user\'s last message directly with a plain-text response. Do not use any tools — just respond with text.</system_notice>';
|
|
88
|
+
|
|
80
89
|
async function runEmpty(
|
|
81
90
|
args: EmptyResponseArgs,
|
|
82
91
|
): Promise<EmptyResponseDecision> {
|
|
@@ -167,15 +176,128 @@ describe("emptyResponse pipeline — default decisions", () => {
|
|
|
167
176
|
|
|
168
177
|
test("no prior tool-use turn (toolUseTurns === 0) → accept", async () => {
|
|
169
178
|
// Empty first assistant response with no tools is not the pattern the
|
|
170
|
-
// nudge guards against. Default accepts
|
|
179
|
+
// organic-empty-turn nudge guards against. Default accepts (unless the
|
|
180
|
+
// stop reason is `"refusal"` — see the refusal-specific tests below).
|
|
181
|
+
const decision = await runEmpty(
|
|
182
|
+
makeArgs({
|
|
183
|
+
responseContent: [],
|
|
184
|
+
toolUseTurns: 0,
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
187
|
+
expect(decision.action).toBe("accept");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// ─── Refusal stop ────────────────────────────────────────────────────────
|
|
191
|
+
|
|
192
|
+
test("stopReason='refusal' on turn 0 with no content → nudge with refusal text", async () => {
|
|
193
|
+
// The canonical failure mode this branch exists to catch: Anthropic's
|
|
194
|
+
// safety classifier zeros the response on the very first model call,
|
|
195
|
+
// returning a single thinking block and `stopReason: "refusal"`. Without
|
|
196
|
+
// this branch, the terminal would `accept` and the loop would persist
|
|
197
|
+
// an empty assistant bubble to the user.
|
|
198
|
+
const decision = await runEmpty(
|
|
199
|
+
makeArgs({
|
|
200
|
+
stopReason: "refusal",
|
|
201
|
+
responseContent: [],
|
|
202
|
+
toolUseBlocksLength: 0,
|
|
203
|
+
toolUseTurns: 0,
|
|
204
|
+
emptyResponseRetries: 0,
|
|
205
|
+
priorAssistantHadVisibleText: false,
|
|
206
|
+
}),
|
|
207
|
+
);
|
|
208
|
+
expect(decision.action).toBe("nudge");
|
|
209
|
+
expect(decision.nudgeText).toBe(CANONICAL_REFUSAL_NUDGE_TEXT);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
test("stopReason='refusal' with a thinking-only block still nudges", async () => {
|
|
213
|
+
// Thinking blocks aren't visible text — the user sees nothing. A
|
|
214
|
+
// refusal with only thinking content matches the same shape the
|
|
215
|
+
// production log captured (`contentBlocks: 1, toolUseCount: 0`).
|
|
216
|
+
const decision = await runEmpty(
|
|
217
|
+
makeArgs({
|
|
218
|
+
stopReason: "refusal",
|
|
219
|
+
responseContent: [
|
|
220
|
+
{
|
|
221
|
+
type: "thinking",
|
|
222
|
+
thinking: "...",
|
|
223
|
+
signature: "sig",
|
|
224
|
+
} as ContentBlock,
|
|
225
|
+
],
|
|
226
|
+
toolUseBlocksLength: 0,
|
|
227
|
+
toolUseTurns: 0,
|
|
228
|
+
}),
|
|
229
|
+
);
|
|
230
|
+
expect(decision.action).toBe("nudge");
|
|
231
|
+
expect(decision.nudgeText).toBe(CANONICAL_REFUSAL_NUDGE_TEXT);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test("stopReason='refusal' but visible text present → accept (model recovered)", async () => {
|
|
235
|
+
// The classifier can flag a partial response; if the model already
|
|
236
|
+
// delivered some visible text before refusing, the user has something
|
|
237
|
+
// to see. Accept.
|
|
238
|
+
const decision = await runEmpty(
|
|
239
|
+
makeArgs({
|
|
240
|
+
stopReason: "refusal",
|
|
241
|
+
responseContent: [{ type: "text", text: "partial answer" }],
|
|
242
|
+
}),
|
|
243
|
+
);
|
|
244
|
+
expect(decision.action).toBe("accept");
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("stopReason='refusal' but tool_use blocks present → accept", async () => {
|
|
248
|
+
// A refusal with tool_use blocks is unusual (the model wouldn't normally
|
|
249
|
+
// issue tools after a classifier hit) but we still shouldn't nudge —
|
|
250
|
+
// the loop will execute the tools and the model will get another shot.
|
|
171
251
|
const decision = await runEmpty(
|
|
172
252
|
makeArgs({
|
|
253
|
+
stopReason: "refusal",
|
|
254
|
+
responseContent: [
|
|
255
|
+
{
|
|
256
|
+
type: "tool_use",
|
|
257
|
+
id: "tu-1",
|
|
258
|
+
name: "read",
|
|
259
|
+
input: { path: "/tmp/x" },
|
|
260
|
+
} as ContentBlock,
|
|
261
|
+
],
|
|
262
|
+
toolUseBlocksLength: 1,
|
|
263
|
+
}),
|
|
264
|
+
);
|
|
265
|
+
expect(decision.action).toBe("accept");
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
test("stopReason='refusal' but retries exhausted → accept (no infinite loop)", async () => {
|
|
269
|
+
// Persistent classifier hit shouldn't burn turns indefinitely. Once
|
|
270
|
+
// we've used our retry budget, accept (the user will see an empty
|
|
271
|
+
// bubble, but the loop terminates).
|
|
272
|
+
const decision = await runEmpty(
|
|
273
|
+
makeArgs({
|
|
274
|
+
stopReason: "refusal",
|
|
173
275
|
responseContent: [],
|
|
174
276
|
toolUseTurns: 0,
|
|
277
|
+
emptyResponseRetries: 1,
|
|
278
|
+
maxEmptyResponseRetries: 1,
|
|
175
279
|
}),
|
|
176
280
|
);
|
|
177
281
|
expect(decision.action).toBe("accept");
|
|
178
282
|
});
|
|
283
|
+
|
|
284
|
+
test("stopReason='refusal' beats post-tool-empty nudge text (refusal-specific wording)", async () => {
|
|
285
|
+
// When both branches would fire, refusal wins because the refusal
|
|
286
|
+
// text is more accurate ("safety classifier zeroed the response"
|
|
287
|
+
// vs. "summary of what you found or did"). This guards against a
|
|
288
|
+
// future refactor that orders the branches differently.
|
|
289
|
+
const decision = await runEmpty(
|
|
290
|
+
makeArgs({
|
|
291
|
+
stopReason: "refusal",
|
|
292
|
+
responseContent: [],
|
|
293
|
+
toolUseBlocksLength: 0,
|
|
294
|
+
toolUseTurns: 2, // would trip the post-tool branch too
|
|
295
|
+
priorAssistantHadVisibleText: false,
|
|
296
|
+
}),
|
|
297
|
+
);
|
|
298
|
+
expect(decision.action).toBe("nudge");
|
|
299
|
+
expect(decision.nudgeText).toBe(CANONICAL_REFUSAL_NUDGE_TEXT);
|
|
300
|
+
});
|
|
179
301
|
});
|
|
180
302
|
|
|
181
303
|
describe("emptyResponse pipeline — custom middleware overrides", () => {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only utilities for overriding the encrypted credential store paths.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the removed `_setStorePath` and `_setStoreKeyPath` exports
|
|
5
|
+
* from `encrypted-store.ts`. Lives here (not in the source module)
|
|
6
|
+
* because production modules should not expose test backdoors.
|
|
7
|
+
*
|
|
8
|
+
* No source-module imports
|
|
9
|
+
* ------------------------
|
|
10
|
+
* This file has ZERO imports from `src/`. It accesses the store-path
|
|
11
|
+
* override state via the shared `globalThis.vellumAssistant.storePathOverride`
|
|
12
|
+
* slot that `src/security/store-path-override.ts` also reads/writes. The
|
|
13
|
+
* slot shape is duplicated here on purpose: keeping this file off the
|
|
14
|
+
* production import graph is what protects the test preload from a
|
|
15
|
+
* broken `node_modules` symlink (DB ghost #3). The two declarations MUST
|
|
16
|
+
* stay in sync — if you change one, change the other.
|
|
17
|
+
*
|
|
18
|
+
* Most tests no longer need these overrides: the test preload places
|
|
19
|
+
* `VELLUM_WORKSPACE_DIR` at `<tmpRoot>/workspace`, so `getProtectedDir()`
|
|
20
|
+
* resolves to `<tmpRoot>/protected` per process. The setters here exist
|
|
21
|
+
* for the small set of tests that exercise specific path scenarios
|
|
22
|
+
* (env-var fallbacks, migration corner cases, etc.).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// Mirrors `src/security/store-path-override.ts`. Duplicated by design — see
|
|
26
|
+
// the "No source-module imports" section above.
|
|
27
|
+
type PathSlot = {
|
|
28
|
+
storePath: string | null;
|
|
29
|
+
storeKeyPath: string | null;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type VellumAssistantNamespace = {
|
|
33
|
+
storePathOverride?: PathSlot;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function pathSlot(): PathSlot {
|
|
37
|
+
const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
|
|
38
|
+
const ns = (g.vellumAssistant ??= {});
|
|
39
|
+
return (ns.storePathOverride ??= { storePath: null, storeKeyPath: null });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Override the encrypted store file path. Pass `null` to reset to the
|
|
44
|
+
* default (`<protectedDir>/keys.enc`).
|
|
45
|
+
*/
|
|
46
|
+
export function setStorePathForTesting(path: string | null): void {
|
|
47
|
+
pathSlot().storePath = path;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Override the store-key file path. Pass `null` to reset to the default
|
|
52
|
+
* (`<dirname(storePath)>/store.key`).
|
|
53
|
+
*/
|
|
54
|
+
export function setStoreKeyPathForTesting(path: string | null): void {
|
|
55
|
+
pathSlot().storeKeyPath = path;
|
|
56
|
+
}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "bun:test";
|
|
25
25
|
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
|
-
// Mock only the logger (not platform -- we use
|
|
27
|
+
// Mock only the logger (not platform -- we use setStorePathForTesting instead)
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
29
|
|
|
30
30
|
mock.module("../util/logger.js", () => ({
|
|
@@ -35,13 +35,15 @@ mock.module("../util/logger.js", () => ({
|
|
|
35
35
|
}));
|
|
36
36
|
|
|
37
37
|
import {
|
|
38
|
-
_setStoreKeyPath,
|
|
39
|
-
_setStorePath,
|
|
40
38
|
deleteKey,
|
|
41
39
|
getKey,
|
|
42
40
|
listKeys,
|
|
43
41
|
setKey,
|
|
44
42
|
} from "../security/encrypted-store.js";
|
|
43
|
+
import {
|
|
44
|
+
setStoreKeyPathForTesting,
|
|
45
|
+
setStorePathForTesting,
|
|
46
|
+
} from "./encrypted-store-test-helpers.js";
|
|
45
47
|
|
|
46
48
|
// ---------------------------------------------------------------------------
|
|
47
49
|
// Use a temp directory so tests don't touch the real ~/.vellum
|
|
@@ -141,13 +143,13 @@ describe("encrypted-store", () => {
|
|
|
141
143
|
for (const entry of readdirSync(TEST_DIR)) {
|
|
142
144
|
rmSync(join(TEST_DIR, entry), { recursive: true, force: true });
|
|
143
145
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
setStorePathForTesting(STORE_PATH);
|
|
147
|
+
setStoreKeyPathForTesting(STORE_KEY_PATH);
|
|
146
148
|
});
|
|
147
149
|
|
|
148
150
|
afterEach(() => {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
setStorePathForTesting(null);
|
|
152
|
+
setStoreKeyPathForTesting(null);
|
|
151
153
|
});
|
|
152
154
|
|
|
153
155
|
afterAll(() => {
|
|
@@ -508,8 +510,8 @@ describe("encrypted-store", () => {
|
|
|
508
510
|
// Point to a path in a non-existent subdirectory
|
|
509
511
|
const nestedPath = join(TEST_DIR, "sub", "dir", "keys.enc");
|
|
510
512
|
const nestedKeyPath = join(TEST_DIR, "sub", "dir", "store.key");
|
|
511
|
-
|
|
512
|
-
|
|
513
|
+
setStorePathForTesting(nestedPath);
|
|
514
|
+
setStoreKeyPathForTesting(nestedKeyPath);
|
|
513
515
|
const result = setKey("test", "value");
|
|
514
516
|
expect(result).toBe(true);
|
|
515
517
|
expect(getKey("test")).toBe("value");
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only utilities for seeding the feature flag override cache.
|
|
3
|
+
*
|
|
4
|
+
* Replaces the removed `_setOverridesForTesting` export from
|
|
5
|
+
* `assistant-feature-flags.ts`. Lives here (not in the source module)
|
|
6
|
+
* because production modules should not expose test backdoors.
|
|
7
|
+
*
|
|
8
|
+
* No source-module imports
|
|
9
|
+
* ------------------------
|
|
10
|
+
* This file has ZERO imports from `src/`. It accesses the feature flag
|
|
11
|
+
* cache's state via the shared `globalThis.vellumAssistant.featureFlagCache`
|
|
12
|
+
* slot that `src/config/feature-flag-cache.ts` also reads/writes. The slot
|
|
13
|
+
* shape is duplicated here on purpose: keeping this file off the
|
|
14
|
+
* production import graph is what protects the test preload from a
|
|
15
|
+
* broken `node_modules` symlink (DB ghost #3). The two declarations MUST
|
|
16
|
+
* stay in sync — if you change one, change the other.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Mirrors `src/config/feature-flag-cache.ts`. Duplicated by design — see
|
|
20
|
+
// the "No source-module imports" section above.
|
|
21
|
+
type FlagSlot = {
|
|
22
|
+
overrides: Record<string, boolean> | null;
|
|
23
|
+
fromGateway: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type VellumAssistantNamespace = {
|
|
27
|
+
featureFlagCache?: FlagSlot;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
function flagSlot(): FlagSlot {
|
|
31
|
+
const g = globalThis as { vellumAssistant?: VellumAssistantNamespace };
|
|
32
|
+
const ns = (g.vellumAssistant ??= {});
|
|
33
|
+
return (ns.featureFlagCache ??= { overrides: null, fromGateway: false });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Synchronously seed the feature flag override cache for the current test.
|
|
38
|
+
*
|
|
39
|
+
* Sets the cache to a clone of `overrides` and marks it as
|
|
40
|
+
* gateway-populated, so subsequent `initFeatureFlagOverrides()` calls are
|
|
41
|
+
* no-ops (preventing the production retry loop from running during tests).
|
|
42
|
+
*
|
|
43
|
+
* Tests that want the gateway IPC retry path to actually run should not
|
|
44
|
+
* call this — they should leave the cache empty or call
|
|
45
|
+
* `clearFeatureFlagOverridesCache()` from `assistant-feature-flags.ts`.
|
|
46
|
+
*/
|
|
47
|
+
export function setOverridesForTesting(
|
|
48
|
+
overrides: Record<string, boolean>,
|
|
49
|
+
): void {
|
|
50
|
+
const s = flagSlot();
|
|
51
|
+
s.overrides = { ...overrides };
|
|
52
|
+
s.fromGateway = true;
|
|
53
|
+
}
|
|
@@ -83,6 +83,7 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
83
83
|
createdConversations.push(opts);
|
|
84
84
|
return { id: `conv-${++conversationIdCounter}`, ...opts };
|
|
85
85
|
},
|
|
86
|
+
reserveMessage: mock(async () => ({ id: "msg-reserve" })),
|
|
86
87
|
}));
|
|
87
88
|
|
|
88
89
|
// Mock logger
|
|
@@ -154,7 +155,7 @@ describe("FilingService", () => {
|
|
|
154
155
|
conversationId: args[0] as string,
|
|
155
156
|
content: args[1] as string,
|
|
156
157
|
options:
|
|
157
|
-
(args[
|
|
158
|
+
(args[2] as { speed?: string; callSite?: string } | undefined) ??
|
|
158
159
|
undefined,
|
|
159
160
|
});
|
|
160
161
|
return { messageId: "msg-1" };
|
|
@@ -318,7 +319,7 @@ describe("FilingService", () => {
|
|
|
318
319
|
let compactionCalls = 0;
|
|
319
320
|
|
|
320
321
|
setTestProcessMessage((...args: unknown[]) => {
|
|
321
|
-
const callSite = (args[
|
|
322
|
+
const callSite = (args[2] as { callSite?: string } | undefined)
|
|
322
323
|
?.callSite;
|
|
323
324
|
if (callSite === "filingAgent") {
|
|
324
325
|
filingCalls += 1;
|
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
isWakeUpGreeting,
|
|
9
9
|
getCannedFirstGreeting,
|
|
10
10
|
buildScanFirstMessage,
|
|
11
|
+
buildSelfIntroMessage,
|
|
11
12
|
CANNED_FIRST_GREETING,
|
|
12
13
|
} = await import("../daemon/first-greeting.js");
|
|
13
14
|
import type { OnboardingGreetingContext } from "../daemon/first-greeting.js";
|
|
@@ -96,7 +97,7 @@ describe("first-greeting", () => {
|
|
|
96
97
|
assistantName: "Pax",
|
|
97
98
|
});
|
|
98
99
|
expect(greeting).toBe(
|
|
99
|
-
"Hey Alice, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
100
|
+
"Hey Alice, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll learn from it fast. Best head start you can give me.",
|
|
100
101
|
);
|
|
101
102
|
});
|
|
102
103
|
|
|
@@ -108,7 +109,7 @@ describe("first-greeting", () => {
|
|
|
108
109
|
assistantName: "Remy",
|
|
109
110
|
});
|
|
110
111
|
expect(greeting).toBe(
|
|
111
|
-
"Hey Alice, I'm Remy. Good to meet you.\n\nWe can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here.",
|
|
112
|
+
"Hey Alice, I'm Remy. Good to meet you.\n\nWe can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here. And you don't have to start me from scratch — if there's a ChatGPT or Claude that already knows you, bring it over and I'll get up to speed fast. Honestly, it's the best head start you could give me.",
|
|
112
113
|
);
|
|
113
114
|
});
|
|
114
115
|
|
|
@@ -119,7 +120,7 @@ describe("first-greeting", () => {
|
|
|
119
120
|
assistantName: "Pax",
|
|
120
121
|
});
|
|
121
122
|
expect(greeting).toBe(
|
|
122
|
-
"Hey, I'm Pax. Let's see what you've got.\n\nWe can jump straight into whatever you've got, or take a few minutes to just talk first.
|
|
123
|
+
"Hey, I'm Pax. Let's see what you've got.\n\nWe can jump straight into whatever you've got, or take a few minutes to just talk first. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll get up to speed fast. Best head start you can give me — want to start there?",
|
|
123
124
|
);
|
|
124
125
|
});
|
|
125
126
|
|
|
@@ -131,7 +132,7 @@ describe("first-greeting", () => {
|
|
|
131
132
|
assistantName: "Pax",
|
|
132
133
|
});
|
|
133
134
|
expect(greeting).toBe(
|
|
134
|
-
"Hey Alice, I'm Pax.\n\nWe can start with whatever's in front of you, or just talk for a bit first. Either way.",
|
|
135
|
+
"Hey Alice, I'm Pax.\n\nWe can start with whatever's in front of you, or just talk for a bit first. Either way. And you don't have to start me from nothing — if there's a ChatGPT or Claude that already knows you, bring it over and I'll learn from it. The best head start you could give me.",
|
|
135
136
|
);
|
|
136
137
|
});
|
|
137
138
|
|
|
@@ -142,7 +143,7 @@ describe("first-greeting", () => {
|
|
|
142
143
|
userName: "Alice",
|
|
143
144
|
});
|
|
144
145
|
expect(greeting).toBe(
|
|
145
|
-
"Hey Alice,\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
146
|
+
"Hey Alice,\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll learn from it fast. Best head start you can give me.",
|
|
146
147
|
);
|
|
147
148
|
});
|
|
148
149
|
|
|
@@ -153,7 +154,7 @@ describe("first-greeting", () => {
|
|
|
153
154
|
assistantName: "Pax",
|
|
154
155
|
});
|
|
155
156
|
expect(greeting).toBe(
|
|
156
|
-
"Hey, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
157
|
+
"Hey, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll learn from it fast. Best head start you can give me.",
|
|
157
158
|
);
|
|
158
159
|
});
|
|
159
160
|
|
|
@@ -173,7 +174,7 @@ describe("first-greeting", () => {
|
|
|
173
174
|
tone: "warm",
|
|
174
175
|
});
|
|
175
176
|
expect(greeting).toBe(
|
|
176
|
-
"Hey,\n\nWe can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here.",
|
|
177
|
+
"Hey,\n\nWe can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here. And you don't have to start me from scratch — if there's a ChatGPT or Claude that already knows you, bring it over and I'll get up to speed fast. Honestly, it's the best head start you could give me.",
|
|
177
178
|
);
|
|
178
179
|
});
|
|
179
180
|
|
|
@@ -185,6 +186,17 @@ describe("first-greeting", () => {
|
|
|
185
186
|
expect(unique.size).toBe(4);
|
|
186
187
|
});
|
|
187
188
|
|
|
189
|
+
it("google-connected greeting points to Gmail only", () => {
|
|
190
|
+
const greeting = getCannedFirstGreeting({
|
|
191
|
+
...base,
|
|
192
|
+
tone: "grounded",
|
|
193
|
+
googleConnected: true,
|
|
194
|
+
});
|
|
195
|
+
expect(greeting).toContain("scan Gmail");
|
|
196
|
+
expect(greeting).not.toContain("calendar");
|
|
197
|
+
expect(greeting).not.toContain("drive");
|
|
198
|
+
});
|
|
199
|
+
|
|
188
200
|
it("unknown tone falls back to grounded defaults", () => {
|
|
189
201
|
const greeting = getCannedFirstGreeting({
|
|
190
202
|
...base,
|
|
@@ -193,7 +205,7 @@ describe("first-greeting", () => {
|
|
|
193
205
|
assistantName: "Pax",
|
|
194
206
|
});
|
|
195
207
|
expect(greeting).toBe(
|
|
196
|
-
"Hey Alice, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
208
|
+
"Hey Alice, I'm Pax.\n\nWe can get into whatever you've got, or just talk first — that tends to go better. Up to you. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll learn from it fast. Best head start you can give me.",
|
|
197
209
|
);
|
|
198
210
|
});
|
|
199
211
|
|
|
@@ -223,7 +235,7 @@ describe("first-greeting", () => {
|
|
|
223
235
|
const [intro, invite] = greeting.split("\n\n");
|
|
224
236
|
expect(intro).toBe("Hey Bob, I'm Pax.");
|
|
225
237
|
expect(invite).toBe(
|
|
226
|
-
"We can get into whatever you've got, or just talk first — that tends to go better. Up to you.",
|
|
238
|
+
"We can get into whatever you've got, or just talk first — that tends to go better. Up to you. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll learn from it fast. Best head start you can give me.",
|
|
227
239
|
);
|
|
228
240
|
});
|
|
229
241
|
|
|
@@ -232,7 +244,7 @@ describe("first-greeting", () => {
|
|
|
232
244
|
const [intro, invite] = greeting.split("\n\n");
|
|
233
245
|
expect(intro).toBe("Hey Bob, I'm Pax. Good to meet you.");
|
|
234
246
|
expect(invite).toBe(
|
|
235
|
-
"We can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here.",
|
|
247
|
+
"We can start on something specific, or just talk for a bit first — honestly that tends to work out better. Either way, I'm here. And you don't have to start me from scratch — if there's a ChatGPT or Claude that already knows you, bring it over and I'll get up to speed fast. Honestly, it's the best head start you could give me.",
|
|
236
248
|
);
|
|
237
249
|
});
|
|
238
250
|
|
|
@@ -241,7 +253,7 @@ describe("first-greeting", () => {
|
|
|
241
253
|
const [intro, invite] = greeting.split("\n\n");
|
|
242
254
|
expect(intro).toBe("Hey Bob, I'm Pax. Let's see what you've got.");
|
|
243
255
|
expect(invite).toBe(
|
|
244
|
-
"We can jump straight into whatever you've got, or take a few minutes to just talk first.
|
|
256
|
+
"We can jump straight into whatever you've got, or take a few minutes to just talk first. And you don't have to start me from scratch — if you've built up a ChatGPT or Claude, bring it over and I'll get up to speed fast. Best head start you can give me — want to start there?",
|
|
245
257
|
);
|
|
246
258
|
});
|
|
247
259
|
|
|
@@ -250,7 +262,7 @@ describe("first-greeting", () => {
|
|
|
250
262
|
const [intro, invite] = greeting.split("\n\n");
|
|
251
263
|
expect(intro).toBe("Hey Bob, I'm Pax.");
|
|
252
264
|
expect(invite).toBe(
|
|
253
|
-
"We can start with whatever's in front of you, or just talk for a bit first. Either way.",
|
|
265
|
+
"We can start with whatever's in front of you, or just talk for a bit first. Either way. And you don't have to start me from nothing — if there's a ChatGPT or Claude that already knows you, bring it over and I'll learn from it. The best head start you could give me.",
|
|
254
266
|
);
|
|
255
267
|
});
|
|
256
268
|
|
|
@@ -274,6 +286,45 @@ describe("first-greeting", () => {
|
|
|
274
286
|
});
|
|
275
287
|
});
|
|
276
288
|
|
|
289
|
+
describe("migration offer is present in every variant", () => {
|
|
290
|
+
const MIGRATION_MARKER = "head start";
|
|
291
|
+
|
|
292
|
+
it("no-onboarding greeting includes the migration offer", () => {
|
|
293
|
+
expect(getCannedFirstGreeting(undefined)).toContain(MIGRATION_MARKER);
|
|
294
|
+
expect(CANNED_FIRST_GREETING).toContain(MIGRATION_MARKER);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("minimal onboarding (falls back to CANNED) includes the migration offer", () => {
|
|
298
|
+
expect(
|
|
299
|
+
getCannedFirstGreeting({ tools: [], tasks: [], tone: "" }),
|
|
300
|
+
).toContain(MIGRATION_MARKER);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("every tone variant includes the migration offer", () => {
|
|
304
|
+
for (const tone of ["grounded", "warm", "energetic", "poetic"]) {
|
|
305
|
+
const greeting = getCannedFirstGreeting({
|
|
306
|
+
tools: [],
|
|
307
|
+
tasks: [],
|
|
308
|
+
tone,
|
|
309
|
+
userName: "Alice",
|
|
310
|
+
assistantName: "Pax",
|
|
311
|
+
});
|
|
312
|
+
expect(greeting).toContain(MIGRATION_MARKER);
|
|
313
|
+
expect(greeting).toContain("ChatGPT or Claude");
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it("google-connected greeting still includes the migration offer", () => {
|
|
318
|
+
const greeting = getCannedFirstGreeting({
|
|
319
|
+
tools: [],
|
|
320
|
+
tasks: [],
|
|
321
|
+
tone: "warm",
|
|
322
|
+
googleConnected: true,
|
|
323
|
+
});
|
|
324
|
+
expect(greeting).toContain(MIGRATION_MARKER);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
277
328
|
describe("buildScanFirstMessage", () => {
|
|
278
329
|
it("website variant includes 'my website' and the URL", () => {
|
|
279
330
|
const msg = buildScanFirstMessage("https://acme.com", "website");
|
|
@@ -325,4 +376,44 @@ describe("first-greeting", () => {
|
|
|
325
376
|
expect(greeting).not.toContain("personal");
|
|
326
377
|
});
|
|
327
378
|
});
|
|
379
|
+
|
|
380
|
+
describe("buildSelfIntroMessage", () => {
|
|
381
|
+
const ctx = (
|
|
382
|
+
over: Partial<OnboardingGreetingContext> = {},
|
|
383
|
+
): OnboardingGreetingContext => ({
|
|
384
|
+
tools: [],
|
|
385
|
+
tasks: [],
|
|
386
|
+
tone: "grounded",
|
|
387
|
+
...over,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
it("uses both names when present", () => {
|
|
391
|
+
expect(
|
|
392
|
+
buildSelfIntroMessage(ctx({ assistantName: "Vela", userName: "alex" })),
|
|
393
|
+
).toBe("Hi Vela, I'm alex. Nice to meet you.");
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it("drops the missing user name", () => {
|
|
397
|
+
expect(buildSelfIntroMessage(ctx({ assistantName: "Vela" }))).toBe(
|
|
398
|
+
"Hi Vela. Nice to meet you.",
|
|
399
|
+
);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
it("drops the missing assistant name", () => {
|
|
403
|
+
expect(buildSelfIntroMessage(ctx({ userName: "alex" }))).toBe(
|
|
404
|
+
"Hi, I'm alex. Nice to meet you.",
|
|
405
|
+
);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it("treats whitespace-only names as missing", () => {
|
|
409
|
+
expect(
|
|
410
|
+
buildSelfIntroMessage(ctx({ assistantName: " ", userName: " " })),
|
|
411
|
+
).toBeUndefined();
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it("returns undefined when neither name is known (caller keeps canned greeting)", () => {
|
|
415
|
+
expect(buildSelfIntroMessage(ctx())).toBeUndefined();
|
|
416
|
+
expect(buildSelfIntroMessage(undefined)).toBeUndefined();
|
|
417
|
+
});
|
|
418
|
+
});
|
|
328
419
|
});
|
|
@@ -33,7 +33,6 @@ mock.module("../config/assistant-feature-flags.js", () => ({
|
|
|
33
33
|
initFeatureFlagOverrides: async () => {},
|
|
34
34
|
clearFeatureFlagOverridesCache: () => {},
|
|
35
35
|
isAssistantFeatureFlagEnabled: () => true,
|
|
36
|
-
_setOverridesForTesting: () => {},
|
|
37
36
|
}));
|
|
38
37
|
|
|
39
38
|
// ---------------------------------------------------------------------------
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
base64ByteLength,
|
|
5
|
+
estimateGeminiAudioTokens,
|
|
6
|
+
GEMINI_MAX_INLINE_AUDIO_BYTES,
|
|
7
|
+
normalizeGeminiAudioMime,
|
|
8
|
+
} from "../providers/gemini/inline-media.js";
|
|
9
|
+
|
|
10
|
+
describe("normalizeGeminiAudioMime", () => {
|
|
11
|
+
test("maps audio/mpeg onto Gemini's audio/mp3 spelling", () => {
|
|
12
|
+
expect(normalizeGeminiAudioMime("audio/mpeg")).toBe("audio/mp3");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("passes supported audio types through unchanged", () => {
|
|
16
|
+
for (const mime of [
|
|
17
|
+
"audio/wav",
|
|
18
|
+
"audio/mp3",
|
|
19
|
+
"audio/aiff",
|
|
20
|
+
"audio/aac",
|
|
21
|
+
"audio/ogg",
|
|
22
|
+
"audio/flac",
|
|
23
|
+
]) {
|
|
24
|
+
expect(normalizeGeminiAudioMime(mime)).toBe(mime);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("is case-insensitive and strips parameters", () => {
|
|
29
|
+
expect(normalizeGeminiAudioMime("AUDIO/MPEG")).toBe("audio/mp3");
|
|
30
|
+
expect(normalizeGeminiAudioMime("audio/ogg; codecs=opus")).toBe(
|
|
31
|
+
"audio/ogg",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("returns null for types Gemini cannot take inline", () => {
|
|
36
|
+
for (const mime of [
|
|
37
|
+
"audio/x-m4a",
|
|
38
|
+
"audio/mp4",
|
|
39
|
+
"audio/opus",
|
|
40
|
+
"application/pdf",
|
|
41
|
+
"image/png",
|
|
42
|
+
"",
|
|
43
|
+
]) {
|
|
44
|
+
expect(normalizeGeminiAudioMime(mime)).toBeNull();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe("base64ByteLength", () => {
|
|
50
|
+
test("approximates raw bytes from base64 length", () => {
|
|
51
|
+
// 8 base64 chars → 6 raw bytes
|
|
52
|
+
expect(base64ByteLength("QUJDREVG")).toBe(6);
|
|
53
|
+
expect(base64ByteLength("")).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("estimateGeminiAudioTokens", () => {
|
|
58
|
+
test("scales with payload size and stays far below the base64-as-text count", () => {
|
|
59
|
+
// ~3 MB of base64 ≈ ~2.25 MB raw ≈ ~140s at 16 KB/s ≈ ~4.5k tokens.
|
|
60
|
+
const data = "A".repeat(3 * 1024 * 1024);
|
|
61
|
+
const tokens = estimateGeminiAudioTokens(data);
|
|
62
|
+
expect(tokens).toBeGreaterThan(1_000);
|
|
63
|
+
// Must be a small fraction of the naive base64-length/4 estimate (~786k).
|
|
64
|
+
expect(tokens).toBeLessThan(data.length / 40);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("returns zero for empty data", () => {
|
|
68
|
+
expect(estimateGeminiAudioTokens("")).toBe(0);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("inline audio cap leaves headroom under Gemini's 20 MB request limit", () => {
|
|
73
|
+
expect(GEMINI_MAX_INLINE_AUDIO_BYTES).toBe(12 * 1024 * 1024);
|
|
74
|
+
// Base64 of the cap (~16 MB) must stay under the 20 MB wire limit.
|
|
75
|
+
expect(GEMINI_MAX_INLINE_AUDIO_BYTES * (4 / 3)).toBeLessThan(
|
|
76
|
+
20 * 1024 * 1024,
|
|
77
|
+
);
|
|
78
|
+
});
|