@vellumai/assistant 0.7.3 → 0.8.1
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 +11 -0
- package/ARCHITECTURE.md +29 -28
- package/Dockerfile +6 -4
- package/README.md +2 -2
- package/__tests__/permissions/gateway-threshold-reader.test.ts +236 -9
- package/bun.lock +3 -0
- package/docker-entrypoint.sh +16 -0
- package/eslint-rules/__tests__/cli-no-daemon-internals.test.ts +420 -0
- package/eslint-rules/cli-no-daemon-internals.js +283 -0
- package/eslint.config.mjs +12 -0
- package/knip.json +3 -1
- package/node_modules/@vellumai/ipc-server-utils/bun.lock +24 -0
- package/node_modules/@vellumai/ipc-server-utils/package.json +18 -0
- package/node_modules/@vellumai/ipc-server-utils/src/index.ts +6 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.test.ts +430 -0
- package/node_modules/@vellumai/ipc-server-utils/src/socket-watchdog.ts +221 -0
- package/node_modules/@vellumai/ipc-server-utils/tsconfig.json +20 -0
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -1
- package/openapi.yaml +4126 -959
- package/package.json +5 -1
- package/scripts/generate-openapi.ts +52 -4
- package/scripts/sync-llm-catalog.ts +165 -0
- package/scripts/sync-web-search-catalog.ts +107 -0
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +169 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +26 -1
- package/src/__tests__/annotate-risk-options.test.ts +291 -0
- package/src/__tests__/anthropic-provider.test.ts +92 -2
- package/src/__tests__/app-control-flow.test.ts +7 -0
- package/src/__tests__/approval-cascade.test.ts +8 -16
- package/src/__tests__/approval-routes-http.test.ts +6 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +232 -0
- package/src/__tests__/auto-analysis-end-to-end.test.ts +12 -25
- package/src/__tests__/avatar-identity-sync.test.ts +87 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +11 -22
- package/src/__tests__/btw-routes.test.ts +1 -0
- package/src/__tests__/call-constants.test.ts +10 -1
- package/src/__tests__/call-controller.test.ts +127 -0
- package/src/__tests__/call-site-routing-provider.test.ts +172 -45
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +44 -3
- package/src/__tests__/channel-policy.test.ts +12 -0
- package/src/__tests__/checker.test.ts +89 -0
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +88 -30
- package/src/__tests__/compact-event-conversation-id-guard.test.ts +33 -5
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +26 -1
- package/src/__tests__/config-loader-backfill.test.ts +526 -102
- package/src/__tests__/config-loader-corrupt.test.ts +68 -0
- package/src/__tests__/config-loader-platform-defaults.test.ts +345 -8
- package/src/__tests__/config-schema-cmd.test.ts +63 -29
- package/src/__tests__/config-schema.test.ts +14 -3
- package/src/__tests__/config-set-platform-guard.test.ts +75 -152
- package/src/__tests__/config-set-route.test.ts +198 -0
- package/src/__tests__/config-watcher.test.ts +6 -0
- package/src/__tests__/contacts-tools.test.ts +51 -199
- package/src/__tests__/context-search-agent-protocol.test.ts +21 -2
- package/src/__tests__/context-search-agent-runner.test.ts +22 -138
- package/src/__tests__/context-search-conversations-source.test.ts +42 -16
- package/src/__tests__/context-search-fanout.test.ts +20 -157
- package/src/__tests__/context-search-memory-source.test.ts +3 -26
- package/src/__tests__/context-search-memory-v2-source.test.ts +3 -3
- package/src/__tests__/context-search-types.test.ts +7 -2
- package/src/__tests__/context-window-manager.test.ts +389 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -6
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -1
- package/src/__tests__/conversation-agent-loop.test.ts +3 -3
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -13
- package/src/__tests__/conversation-crud-inference-profile.test.ts +100 -0
- package/src/__tests__/conversation-error.test.ts +38 -0
- package/src/__tests__/conversation-fork-crud.test.ts +241 -1
- package/src/__tests__/conversation-inference-profile-route.test.ts +14 -14
- package/src/__tests__/conversation-init.benchmark.test.ts +2 -1
- package/src/__tests__/conversation-lifecycle.test.ts +124 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +100 -1
- package/src/__tests__/conversation-process-callsite.test.ts +22 -7
- package/src/__tests__/conversation-provider-retry-repair.test.ts +1 -6
- package/src/__tests__/conversation-runtime-assembly.test.ts +19 -10
- package/src/__tests__/conversation-slash-commands.test.ts +194 -2
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +170 -9
- package/src/__tests__/conversation-surfaces-app-control.test.ts +323 -3
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +73 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +59 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +1 -7
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +1 -7
- package/src/__tests__/credential-security-invariants.test.ts +5 -6
- package/src/__tests__/daemon-credential-client.test.ts +56 -1
- package/src/__tests__/db-activation-state-fk-cascade.test.ts +132 -0
- package/src/__tests__/db-conversation-inference-profile-migration.test.ts +37 -0
- package/src/__tests__/db-memory-graph-event-date-repair.test.ts +43 -20
- package/src/__tests__/db-proxy-transaction.test.ts +206 -0
- package/src/__tests__/external-plugin-loader.test.ts +458 -0
- package/src/__tests__/filing-service.test.ts +25 -22
- package/src/__tests__/fixtures/mock-chrome-extension.ts +5 -0
- package/src/__tests__/gateway-only-guard.test.ts +0 -1
- package/src/__tests__/graph-extraction-event-date.test.ts +34 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +10 -34
- package/src/__tests__/heartbeat-disk-pressure.test.ts +21 -8
- package/src/__tests__/heartbeat-service.test.ts +50 -233
- package/src/__tests__/history-repair.test.ts +89 -0
- package/src/__tests__/host-app-control-proxy.test.ts +109 -1
- package/src/__tests__/host-app-control-routes.test.ts +247 -1
- package/src/__tests__/host-browser-proxy.test.ts +416 -20
- package/src/__tests__/host-browser-routes.test.ts +325 -33
- package/src/__tests__/host-proxy-preactivation.test.ts +211 -0
- package/src/__tests__/inference-no-mode-boot-e2e.test.ts +246 -0
- package/src/__tests__/inference-profile-reaper.test.ts +154 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +398 -0
- package/src/__tests__/inference-profile-session-ipc.test.ts +236 -0
- package/src/__tests__/injector-chain.test.ts +24 -16
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +10 -7
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -1
- package/src/__tests__/install-skill-routing.test.ts +2 -2
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +169 -67
- package/src/__tests__/llm-callsite-catalog.test.ts +20 -1
- package/src/__tests__/llm-catalog-parity.test.ts +146 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +188 -0
- package/src/__tests__/llm-request-log-source-factory.test.ts +124 -0
- package/src/__tests__/llm-resolver.test.ts +46 -0
- package/src/__tests__/managed-profile-guard.test.ts +131 -2
- package/src/__tests__/mcp-auth-routes.test.ts +1 -0
- package/src/__tests__/mcp-cli.test.ts +182 -220
- package/src/__tests__/mcp-health-check.test.ts +56 -27
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +18 -11
- package/src/__tests__/message-complete-display-id.test.ts +175 -0
- package/src/__tests__/notification-decision-fallback.test.ts +91 -0
- package/src/__tests__/notification-decision-strategy.test.ts +22 -0
- package/src/__tests__/notification-platform-adapter.test.ts +229 -0
- package/src/__tests__/oauth-cli.test.ts +38 -1888
- package/src/__tests__/oauth-commands-routes.test.ts +711 -0
- package/src/__tests__/oauth-connect-routes.test.ts +174 -11
- package/src/__tests__/oauth-providers-routes.test.ts +14 -10
- package/src/__tests__/openai-responses-cutover-guard.test.ts +33 -12
- package/src/__tests__/openai-responses-provider.test.ts +17 -0
- package/src/__tests__/plugin-bootstrap.test.ts +31 -2
- package/src/__tests__/plugin-route-contribution.test.ts +31 -3
- package/src/__tests__/plugin-tool-contribution.test.ts +31 -3
- package/src/__tests__/plugin-types.test.ts +13 -11
- package/src/__tests__/process-message-background-slack.test.ts +46 -0
- package/src/__tests__/profile-entry-status.test.ts +43 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +12 -4
- package/src/__tests__/provider-registry-ollama.test.ts +12 -4
- package/src/__tests__/provider-send-message-override-profile.test.ts +10 -4
- package/src/__tests__/relay-server.test.ts +164 -2
- package/src/__tests__/retry-thinking-tool-choice.test.ts +15 -0
- package/src/__tests__/schedule-retry.test.ts +56 -4
- package/src/__tests__/schedule-routes.test.ts +104 -0
- package/src/__tests__/scheduler-disk-pressure.test.ts +0 -4
- package/src/__tests__/scheduler-recurrence.test.ts +87 -34
- package/src/__tests__/scheduler-reuse-conversation.test.ts +161 -5
- package/src/__tests__/scheduler-wake.test.ts +0 -63
- package/src/__tests__/secret-allowlist.test.ts +1 -0
- package/src/__tests__/secret-prompt-log-hygiene.test.ts +7 -5
- package/src/__tests__/secret-prompter-channel-fallback.test.ts +7 -5
- package/src/__tests__/secret-response-routing.test.ts +7 -5
- package/src/__tests__/secret-routes-managed-proxy.test.ts +12 -4
- package/src/__tests__/server-history-render.test.ts +82 -0
- package/src/__tests__/shell-credential-ref.test.ts +95 -3
- package/src/__tests__/shell-tool-proxy-mode.test.ts +14 -0
- package/src/__tests__/skill-include-graph.test.ts +31 -0
- package/src/__tests__/skill-load-feature-flag.test.ts +1 -0
- package/src/__tests__/skill-load-tool.test.ts +42 -16
- package/src/__tests__/skills.test.ts +39 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +78 -16
- package/src/__tests__/suggestion-routes.test.ts +3 -3
- package/src/__tests__/sync-message-contract.test.ts +63 -0
- package/src/__tests__/task-scheduler.test.ts +88 -23
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +0 -42
- package/src/__tests__/tool-executor.test.ts +155 -0
- package/src/__tests__/update-bulletin-job.test.ts +96 -193
- package/src/__tests__/usage-cli.test.ts +11 -73
- package/src/__tests__/user-plugin-loader.test.ts +145 -0
- package/src/__tests__/vercel-config.test.ts +168 -0
- package/src/__tests__/voice-session-bridge.test.ts +3 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +86 -0
- package/src/__tests__/web-search.test.ts +303 -2
- package/src/__tests__/workspace-migration-039-drop-legacy-llm-keys.test.ts +1 -21
- package/src/__tests__/workspace-migration-057-repair-stale-gemini-model-ids.test.ts +58 -0
- package/src/__tests__/workspace-migration-069-seed-onboarding-threads.test.ts +153 -0
- package/src/__tests__/workspace-migration-071-remove-safe-storage-release-note.test.ts +206 -0
- package/src/__tests__/workspace-migration-072-seed-reply-suggestion-callsite.test.ts +191 -0
- package/src/__tests__/workspace-migration-076-drop-services-inference-mode.test.ts +211 -0
- package/src/__tests__/workspace-migration-077-seed-memory-router-callsite.test.ts +174 -0
- package/src/__tests__/workspace-migration-079-home-feed-notification-only.test.ts +323 -0
- package/src/__tests__/workspace-migration-080-restrict-vercel-api-token-metadata.test.ts +299 -0
- package/src/__tests__/workspace-migration-081-backfill-bash-allowed-tools.test.ts +410 -0
- package/src/__tests__/workspace-migration-082-backfill-managed-profile-labels.test.ts +268 -0
- package/src/__tests__/workspace-migration-safe-storage-limits-release.test.ts +15 -27
- package/src/__tests__/workspace-migration-unify-llm-callsite-configs.test.ts +3 -3
- package/src/__tests__/workspace-release-notes-feature-flag-guard.test.ts +115 -0
- package/src/acp/__tests__/helpers/which-stub.ts +4 -2
- package/src/acp/resolve-agent.test.ts +25 -0
- package/src/acp/resolve-agent.ts +13 -2
- package/src/acp/session-manager.ts +14 -0
- package/src/agent/loop.ts +11 -0
- package/src/approvals/guardian-decision-primitive.ts +0 -13
- package/src/approvals/guardian-request-resolvers.ts +19 -102
- package/src/calls/call-constants.ts +5 -8
- package/src/calls/call-controller.ts +130 -67
- package/src/calls/relay-server.ts +42 -1
- package/src/calls/relay-setup-router.ts +36 -0
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-session-bridge.ts +24 -5
- package/src/channels/config.ts +14 -1
- package/src/channels/types.ts +1 -0
- package/src/cli/AGENTS.md +164 -4
- package/src/cli/__tests__/notifications.test.ts +54 -0
- package/src/cli/commands/__tests__/avatar.test.ts +540 -0
- package/src/cli/commands/__tests__/backup.test.ts +236 -776
- package/src/cli/commands/__tests__/cache.test.ts +1 -1
- package/src/cli/commands/__tests__/changelog.test.ts +593 -0
- package/src/cli/commands/__tests__/channel-verification-sessions.test.ts +503 -0
- package/src/cli/commands/__tests__/conversations-import.test.ts +515 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +140 -167
- package/src/cli/commands/__tests__/domain-status.test.ts +137 -76
- package/src/cli/commands/__tests__/email-attachment.test.ts +314 -337
- package/src/cli/commands/__tests__/email-core.test.ts +579 -0
- package/src/cli/commands/__tests__/image-generation.test.ts +87 -824
- package/src/cli/commands/__tests__/inference-send.test.ts +30 -266
- package/src/cli/commands/__tests__/inference-session.test.ts +423 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +81 -110
- package/src/cli/commands/__tests__/skills.test.ts +563 -0
- package/src/cli/commands/__tests__/status.test.ts +249 -0
- package/src/cli/commands/__tests__/stt.test.ts +320 -0
- package/src/cli/commands/__tests__/tts-synthesize.test.ts +4 -603
- package/src/cli/commands/__tests__/tts.test.ts +321 -0
- package/src/cli/commands/__tests__/webhooks.test.ts +86 -511
- package/src/cli/commands/attachment.ts +8 -3
- package/src/cli/commands/audit.ts +95 -64
- package/src/cli/commands/auth.ts +61 -58
- package/src/cli/commands/avatar.ts +276 -390
- package/src/cli/commands/backup.ts +409 -505
- package/src/cli/commands/bash.ts +9 -5
- package/src/cli/commands/browser.ts +28 -9
- package/src/cli/commands/cache.ts +9 -4
- package/src/cli/commands/changelog.ts +414 -0
- package/src/cli/commands/channel-verification-sessions.ts +238 -317
- package/src/cli/commands/clients.ts +8 -3
- package/src/cli/commands/completions.ts +9 -9
- package/src/cli/commands/config.ts +102 -72
- package/src/cli/commands/contacts.ts +575 -696
- package/src/cli/commands/conversations-defer.ts +17 -69
- package/src/cli/commands/conversations-import.ts +90 -253
- package/src/cli/commands/conversations.ts +346 -436
- package/src/cli/commands/credential-execution.ts +9 -6
- package/src/cli/commands/credentials.ts +456 -736
- package/src/cli/commands/domain.ts +128 -206
- package/src/cli/commands/email.ts +606 -794
- package/src/cli/commands/gateway.ts +8 -1
- package/src/cli/commands/image-generation.ts +157 -205
- package/src/cli/commands/inference-providers.ts +352 -0
- package/src/cli/commands/inference-session.ts +415 -0
- package/src/cli/commands/inference.ts +87 -65
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.ts +103 -287
- package/src/cli/commands/memory-v2.ts +163 -517
- package/src/cli/commands/notifications.ts +33 -7
- package/src/cli/commands/oauth/apps.ts +292 -261
- package/src/cli/commands/oauth/connect.ts +182 -345
- package/src/cli/commands/oauth/disconnect.ts +16 -215
- package/src/cli/commands/oauth/index.ts +49 -45
- package/src/cli/commands/oauth/mode.ts +43 -199
- package/src/cli/commands/oauth/ping.ts +17 -125
- package/src/cli/commands/oauth/providers.ts +732 -921
- package/src/cli/commands/oauth/request.ts +60 -350
- package/src/cli/commands/oauth/shared.ts +11 -121
- package/src/cli/commands/oauth/status.ts +31 -121
- package/src/cli/commands/oauth/token.ts +13 -55
- package/src/cli/commands/pending.ts +19 -10
- package/src/cli/commands/platform/__tests__/callback-routes-list.test.ts +133 -183
- package/src/cli/commands/platform/__tests__/connect.test.ts +66 -181
- package/src/cli/commands/platform/__tests__/disconnect.test.ts +71 -227
- package/src/cli/commands/platform/__tests__/status.test.ts +169 -287
- package/src/cli/commands/platform/connect.ts +16 -80
- package/src/cli/commands/platform/disconnect.ts +14 -112
- package/src/cli/commands/platform/index.ts +177 -246
- package/src/cli/commands/routes.ts +153 -336
- package/src/cli/commands/sequence.ts +316 -360
- package/src/cli/commands/skills.ts +449 -671
- package/src/cli/commands/status.ts +58 -37
- package/src/cli/commands/stt.ts +94 -262
- package/src/cli/commands/task.ts +14 -40
- package/src/cli/commands/trust.ts +8 -3
- package/src/cli/commands/tts.ts +162 -167
- package/src/cli/commands/ui.ts +35 -42
- package/src/cli/commands/usage.ts +188 -126
- package/src/cli/commands/watchers.ts +8 -3
- package/src/cli/commands/webhooks.ts +99 -193
- package/src/cli/lib/__tests__/register-command.test.ts +85 -0
- package/src/cli/lib/daemon-credential-client.ts +4 -5
- package/src/cli/lib/nested-value.ts +44 -0
- package/src/cli/lib/open-browser.ts +36 -0
- package/src/cli/lib/register-command.ts +19 -0
- package/src/cli/lib/time-ago.ts +34 -0
- package/src/cli/program.ts +2 -4
- package/src/cli/utils/__tests__/conversation-id.test.ts +66 -0
- package/src/cli/utils/__tests__/parse-duration.test.ts +49 -0
- package/src/cli/utils/conversation-id.ts +30 -0
- package/src/cli/utils/parse-duration.ts +41 -0
- package/src/config/acp-defaults.test.ts +5 -1
- package/src/config/acp-defaults.ts +11 -4
- package/src/config/bundled-skills/acp/TOOLS.json +2 -2
- package/src/config/bundled-skills/app-builder/SKILL.md +1 -3
- package/src/config/bundled-skills/app-control/TOOLS.json +32 -0
- package/src/config/bundled-skills/contacts/SKILL.md +12 -45
- package/src/config/bundled-skills/contacts/TOOLS.json +0 -57
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +0 -12
- package/src/config/bundled-skills/messaging/tools/messaging-send.ts +0 -58
- package/src/config/bundled-tool-registry.ts +0 -2
- package/src/config/feature-flag-registry.json +17 -17
- package/src/config/llm-resolver.ts +16 -1
- package/src/config/loader.ts +148 -33
- package/src/config/raw-config-utils.ts +2 -30
- package/src/config/schema.ts +4 -0
- package/src/config/schemas/__tests__/memory-v2.test.ts +49 -0
- package/src/config/schemas/call-site-catalog.ts +29 -7
- package/src/config/schemas/llm-request-logs.ts +57 -0
- package/src/config/schemas/llm.ts +52 -2
- package/src/config/schemas/memory-retrospective.ts +48 -0
- package/src/config/schemas/memory-v2.ts +33 -2
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/services.ts +15 -12
- package/src/config/seed-inference-profiles.ts +195 -134
- package/src/contacts/contact-store.ts +0 -61
- package/src/context/window-manager.ts +191 -5
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +111 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +109 -4
- package/src/daemon/__tests__/daemon-skill-host.test.ts +10 -4
- package/src/daemon/approval-generators.ts +23 -29
- package/src/daemon/config-watcher.ts +2 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +56 -0
- package/src/daemon/conversation-agent-loop.ts +140 -107
- package/src/daemon/conversation-error.ts +21 -0
- package/src/daemon/conversation-lifecycle.ts +68 -13
- package/src/daemon/conversation-process.ts +36 -19
- package/src/daemon/conversation-runtime-assembly.ts +14 -5
- package/src/daemon/conversation-slash.ts +175 -23
- package/src/daemon/conversation-store.ts +17 -10
- package/src/daemon/conversation-surfaces.ts +92 -26
- package/src/daemon/conversation-tool-setup.ts +33 -19
- package/src/daemon/conversation.ts +49 -10
- package/src/daemon/external-plugins-bootstrap.ts +18 -8
- package/src/daemon/guardian-action-generators.ts +7 -22
- package/src/daemon/handlers/config-model.ts +8 -126
- package/src/daemon/handlers/config-slack-channel.ts +10 -7
- package/src/daemon/handlers/config-vercel.ts +3 -1
- package/src/daemon/handlers/shared.ts +26 -0
- package/src/daemon/handlers/skills.ts +84 -5
- package/src/daemon/history-repair.ts +33 -6
- package/src/daemon/host-app-control-proxy.ts +44 -19
- package/src/daemon/host-bash-proxy.ts +85 -158
- package/src/daemon/host-browser-proxy.ts +97 -36
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/host-file-proxy.ts +1 -1
- package/src/daemon/host-proxy-base.ts +13 -1
- package/src/daemon/host-proxy-preactivation.ts +25 -1
- package/src/daemon/host-transfer-proxy.ts +2 -2
- package/src/daemon/identity-helpers.ts +19 -0
- package/src/daemon/lifecycle.ts +128 -114
- package/src/daemon/meet-host-supervisor.ts +15 -15
- package/src/daemon/memory-v2-startup.ts +62 -14
- package/src/daemon/message-protocol.ts +6 -0
- package/src/daemon/message-types/bookmarks.ts +18 -0
- package/src/daemon/message-types/conversations.ts +12 -9
- package/src/daemon/message-types/messages.ts +28 -2
- package/src/daemon/message-types/sync.ts +60 -0
- package/src/daemon/pkb-reminder-builder.test.ts +54 -13
- package/src/daemon/pkb-reminder-builder.ts +21 -7
- package/src/daemon/process-message.ts +56 -23
- package/src/daemon/server.ts +23 -18
- package/src/daemon/shutdown-handlers.ts +0 -2
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/daemon/tool-side-effects.ts +6 -4
- package/src/daemon/wake-target-adapter.ts +11 -0
- package/src/documents/document-store.ts +35 -1
- package/src/export/transcript-formatter.ts +61 -2
- package/src/filing/filing-service.ts +42 -56
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +359 -0
- package/src/heartbeat/heartbeat-run-store.ts +2 -1
- package/src/heartbeat/heartbeat-service.ts +149 -128
- package/src/home/__tests__/feed-types.test.ts +63 -131
- package/src/home/__tests__/feed-writer.test.ts +77 -278
- package/src/home/__tests__/post-connect-feed.test.ts +9 -12
- package/src/home/feed-types.ts +19 -73
- package/src/home/feed-writer.ts +25 -156
- package/src/home/post-connect-feed.ts +1 -3
- package/src/ipc/__tests__/cli-ipc.test.ts +2 -0
- package/src/ipc/__tests__/email-ipc.test.ts +506 -0
- package/src/ipc/__tests__/exit-helper.test.ts +104 -0
- package/src/ipc/__tests__/streaming-client.test.ts +237 -0
- package/src/ipc/__tests__/streaming-framing.test.ts +142 -0
- package/src/ipc/assistant-server.ts +148 -42
- package/src/ipc/cli-client.ts +370 -50
- package/src/ipc/routes/db-proxy-transaction.ts +151 -0
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +60 -0
- package/src/ipc/skill-routes/events.ts +30 -3
- package/src/ipc/skill-server.ts +99 -42
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +46 -0
- package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +1 -0
- package/src/live-voice/live-voice-session-manager.ts +11 -4
- package/src/live-voice/live-voice-session.ts +14 -6
- package/src/memory/__tests__/bookmark-crud.test.ts +258 -0
- package/src/memory/__tests__/bookmark-schema.test.ts +181 -0
- package/src/memory/__tests__/conversation-types.test.ts +36 -0
- package/src/memory/__tests__/find-most-recent-retrospective-for.test.ts +130 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +10 -57
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +177 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +328 -0
- package/src/memory/__tests__/memory-retrospective-startup-cleanup.test.ts +213 -0
- package/src/memory/__tests__/memory-retrospective-trigger-check.test.ts +90 -0
- package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +69 -0
- package/src/memory/__tests__/memory-v2-concept-frequency.test.ts +3 -0
- package/src/memory/bookmark-crud.ts +179 -0
- package/src/memory/context-search/__tests__/agent-runner-redaction.test.ts +31 -9
- package/src/memory/context-search/agent-protocol.ts +5 -1
- package/src/memory/context-search/agent-runner.ts +60 -85
- package/src/memory/context-search/limits.ts +1 -4
- package/src/memory/context-search/search.ts +23 -113
- package/src/memory/context-search/sources/conversations.ts +18 -6
- package/src/memory/context-search/sources/memory-v2.ts +40 -31
- package/src/memory/context-search/sources/memory.ts +9 -2
- package/src/memory/context-search/sources/workspace.ts +13 -10
- package/src/memory/context-search/types.ts +1 -1
- package/src/memory/conversation-bootstrap.ts +11 -0
- package/src/memory/conversation-crud.ts +312 -10
- package/src/memory/conversation-queries.ts +9 -5
- package/src/memory/conversation-title-service.ts +1 -0
- package/src/memory/conversation-types.ts +16 -0
- package/src/memory/db-init.ts +14 -0
- package/src/memory/embedding-backend.ts +2 -1
- package/src/memory/embedding-runtime-manager.ts +1 -2
- package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +104 -61
- package/src/memory/graph/__tests__/handle-remember-v2.test.ts +11 -26
- package/src/memory/graph/__tests__/remember-description.test.ts +55 -0
- package/src/memory/graph/conversation-graph-memory.ts +108 -14
- package/src/memory/graph/extraction.ts +4 -0
- package/src/memory/graph/graph-memory-state-store.ts +16 -3
- package/src/memory/graph/graph-search.test.ts +6 -5
- package/src/memory/graph/graph-search.ts +3 -4
- package/src/memory/graph/retriever.test.ts +12 -7
- package/src/memory/graph/retriever.ts +4 -5
- package/src/memory/graph/tool-handlers.ts +20 -11
- package/src/memory/graph/tools.ts +48 -9
- package/src/memory/indexer.ts +18 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +120 -6
- package/src/memory/jobs/embed-concept-page.ts +261 -89
- package/src/memory/jobs-store.ts +51 -1
- package/src/memory/jobs-worker.ts +60 -7
- package/src/memory/llm-request-log-source-clickhouse.ts +317 -0
- package/src/memory/llm-request-log-source-local.ts +26 -0
- package/src/memory/llm-request-log-source.ts +97 -0
- package/src/memory/llm-request-log-store.ts +1 -1
- package/src/memory/memory-retrospective-constants.ts +13 -0
- package/src/memory/memory-retrospective-enqueue.ts +114 -0
- package/src/memory/memory-retrospective-job.ts +351 -0
- package/src/memory/memory-retrospective-startup-cleanup.ts +108 -0
- package/src/memory/memory-retrospective-state.ts +162 -0
- package/src/memory/memory-retrospective-trigger-check.ts +91 -0
- package/src/memory/memory-v2-activation-log-store.ts +49 -5
- package/src/memory/memory-v2-concept-frequency.ts +4 -0
- package/src/memory/message-content.ts +38 -1
- package/src/memory/migrations/227-add-conversation-inference-profile.ts +6 -1
- package/src/memory/migrations/228-rename-inference-profile-snake-case.ts +20 -7
- package/src/memory/migrations/229-delete-private-conversations.test.ts +70 -1
- package/src/memory/migrations/229-delete-private-conversations.ts +12 -0
- package/src/memory/migrations/231-repair-memory-graph-event-dates.ts +16 -2
- package/src/memory/migrations/240-conversation-inference-profile-session.ts +25 -0
- package/src/memory/migrations/241-activation-state-fk-cascade.ts +50 -0
- package/src/memory/migrations/242-message-bookmarks.ts +38 -0
- package/src/memory/migrations/243-provider-connections.ts +68 -0
- package/src/memory/migrations/244-provider-connection-status-label.ts +23 -0
- package/src/memory/migrations/245-memory-retrospective-state.ts +36 -0
- package/src/memory/migrations/246-backfill-provider-connection-label.ts +81 -0
- package/src/memory/migrations/__tests__/244-provider-connection-status-label.test.ts +84 -0
- package/src/memory/migrations/__tests__/245-memory-retrospective-state.test.ts +125 -0
- package/src/memory/migrations/__tests__/246-backfill-provider-connection-label.test.ts +192 -0
- package/src/memory/migrations/index.ts +7 -0
- package/src/memory/pkb/pkb-search.test.ts +6 -5
- package/src/memory/pkb/pkb-search.ts +4 -5
- package/src/memory/published-pages-store.ts +16 -0
- package/src/memory/qdrant-client.ts +3 -0
- package/src/memory/schema/bookmarks.ts +38 -0
- package/src/memory/schema/conversations.ts +2 -0
- package/src/memory/schema/index.ts +2 -0
- package/src/memory/schema/inference.ts +29 -0
- package/src/memory/schema/memory-core.ts +9 -0
- package/src/memory/search/semantic.ts +5 -9
- package/src/memory/v2/__tests__/__snapshots__/prompts-router.test.ts.snap +27 -0
- package/src/memory/v2/__tests__/activation-store.test.ts +5 -5
- package/src/memory/v2/__tests__/activation.test.ts +46 -9
- package/src/memory/v2/__tests__/backfill-jobs.test.ts +38 -21
- package/src/memory/v2/__tests__/consolidation-job.test.ts +140 -163
- package/src/memory/v2/__tests__/edge-index.test.ts +1 -1
- package/src/memory/v2/__tests__/frontmatter-sweep.test.ts +111 -0
- package/src/memory/v2/__tests__/injection.test.ts +768 -33
- package/src/memory/v2/__tests__/migration.test.ts +7 -3
- package/src/memory/v2/__tests__/page-index.test.ts +277 -0
- package/src/memory/v2/__tests__/page-store.test.ts +14 -1
- package/src/memory/v2/__tests__/prompts-router.test.ts +257 -0
- package/src/memory/v2/__tests__/qdrant.test.ts +382 -9
- package/src/memory/v2/__tests__/reranker.test.ts +4 -4
- package/src/memory/v2/__tests__/router.test.ts +516 -0
- package/src/memory/v2/__tests__/sim.test.ts +163 -8
- package/src/memory/v2/__tests__/skill-store.test.ts +58 -3
- package/src/memory/v2/__tests__/static-context.test.ts +8 -35
- package/src/memory/v2/__tests__/sweep-job.test.ts +114 -33
- package/src/memory/v2/activation-store.ts +34 -5
- package/src/memory/v2/activation.ts +40 -27
- package/src/memory/v2/backfill-jobs.ts +17 -84
- package/src/memory/v2/consolidation-job.ts +92 -86
- package/src/memory/v2/frontmatter-sweep.ts +91 -0
- package/src/memory/v2/injection.ts +466 -115
- package/src/memory/v2/migration.ts +117 -20
- package/src/memory/v2/page-index.ts +191 -0
- package/src/memory/v2/page-store.ts +42 -0
- package/src/memory/v2/prompts/consolidation.ts +14 -7
- package/src/memory/v2/prompts/router.ts +192 -0
- package/src/memory/v2/qdrant.ts +307 -133
- package/src/memory/v2/reranker.ts +14 -7
- package/src/memory/v2/router.ts +322 -0
- package/src/memory/v2/sim.ts +88 -34
- package/src/memory/v2/skill-store.ts +118 -29
- package/src/memory/v2/static-context.ts +20 -17
- package/src/memory/v2/sweep-job.ts +127 -102
- package/src/memory/v2/types.ts +16 -5
- package/src/memory/validation.ts +13 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +182 -0
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +199 -0
- package/src/notifications/__tests__/signal-registry.test.ts +17 -0
- package/src/notifications/adapters/platform.ts +171 -0
- package/src/notifications/conversation-pairing.ts +2 -2
- package/src/notifications/copy-composer.ts +61 -12
- package/src/notifications/decision-engine.ts +46 -0
- package/src/notifications/destination-resolver.ts +21 -0
- package/src/notifications/emit-signal.ts +28 -1
- package/src/notifications/home-feed-side-effect.ts +111 -0
- package/src/notifications/signal.ts +5 -0
- package/src/permissions/checker.ts +12 -0
- package/src/permissions/gateway-threshold-reader.ts +116 -8
- package/src/permissions/ipc-risk-types.ts +2 -0
- package/src/permissions/prompter.ts +86 -96
- package/src/permissions/secret-prompter.ts +31 -31
- package/src/plugin-api/index.ts +13 -0
- package/src/plugin-api/package.json +12 -0
- package/src/plugin-api/types.ts +62 -0
- package/src/plugins/defaults/injectors.ts +20 -5
- package/src/plugins/external-plugin-loader.ts +294 -0
- package/src/plugins/types.ts +46 -30
- package/src/plugins/user-loader.ts +64 -41
- package/src/proactive-artifact/job.test.ts +63 -8
- package/src/proactive-artifact/job.ts +20 -2
- package/src/proactive-artifact/message-copy.ts +18 -1
- package/src/proactive-artifact/trigger-state.test.ts +9 -0
- package/src/proactive-artifact/trigger-state.ts +4 -0
- package/src/prompts/__tests__/system-prompt.test.ts +105 -0
- package/src/prompts/system-prompt.ts +22 -1
- package/src/prompts/templates/SOUL.md +13 -28
- package/src/prompts/update-bulletin-job.ts +61 -73
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +279 -0
- package/src/providers/__tests__/inference.test.ts +288 -0
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +6 -0
- package/src/providers/__tests__/retry-callsite.test.ts +14 -32
- package/src/providers/__tests__/satellite-connection-routing.test.ts +510 -0
- package/src/providers/__tests__/search-provider-catalog.test.ts +80 -0
- package/src/providers/anthropic/client.ts +95 -26
- package/src/providers/call-site-routing.ts +94 -16
- package/src/providers/connection-resolution.ts +163 -0
- package/src/providers/inference/__tests__/connections-status-label.test.ts +250 -0
- package/src/providers/inference/adapter-factory.ts +173 -0
- package/src/providers/inference/auth.ts +112 -0
- package/src/providers/inference/backfill.ts +196 -0
- package/src/providers/inference/connections.ts +356 -0
- package/src/providers/inference/resolve-auth.ts +65 -0
- package/src/providers/model-catalog.ts +104 -6
- package/src/providers/openai/responses-provider.ts +4 -2
- package/src/providers/provider-env-vars.ts +17 -7
- package/src/providers/provider-secret-catalog.ts +49 -30
- package/src/providers/provider-send-message.ts +41 -20
- package/src/providers/registry.ts +143 -159
- package/src/providers/retry.ts +18 -10
- package/src/providers/search-provider-catalog.ts +121 -0
- package/src/runtime/AGENTS.md +18 -5
- package/src/runtime/__tests__/background-job-runner.test.ts +357 -0
- package/src/runtime/__tests__/pre-first-message-gate.test.ts +82 -0
- package/src/runtime/actor-trust-resolver.ts +32 -10
- package/src/runtime/agent-wake.ts +35 -6
- package/src/runtime/assistant-event-hub.ts +3 -85
- package/src/runtime/auth/route-policy.ts +304 -8
- package/src/runtime/auth/same-actor.ts +2 -0
- package/src/runtime/background-job-runner.ts +339 -0
- package/src/runtime/btw-sidechain.ts +1 -0
- package/src/runtime/channel-approvals.ts +3 -2
- package/src/runtime/guardian-reply-router.ts +0 -10
- package/src/runtime/http-router.ts +36 -1
- package/src/runtime/http-server.ts +31 -5
- package/src/runtime/http-types.ts +2 -0
- package/src/runtime/middleware/__tests__/request-logger.test.ts +162 -0
- package/src/runtime/middleware/request-logger.ts +62 -1
- package/src/runtime/pending-interactions.ts +19 -15
- package/src/runtime/pre-first-message-gate.ts +83 -0
- package/src/runtime/routes/__tests__/backup-routes.test.ts +8 -1
- package/src/runtime/routes/__tests__/bookmark-routes.test.ts +251 -0
- package/src/runtime/routes/__tests__/connection-routes-vs-cli-parity.test.ts +142 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +315 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +189 -0
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +15 -136
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +736 -0
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +147 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +5 -1
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +384 -0
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.ts +10 -8
- package/src/runtime/routes/app-management-routes.ts +228 -3
- package/src/runtime/routes/approval-routes.ts +7 -21
- package/src/runtime/routes/audit-routes.ts +43 -0
- package/src/runtime/routes/auth-routes.ts +72 -0
- package/src/runtime/routes/avatar-routes.ts +273 -20
- package/src/runtime/routes/backup-routes.ts +406 -2
- package/src/runtime/routes/bookmark-routes.ts +154 -0
- package/src/runtime/routes/channel-verification-routes.ts +2 -1
- package/src/runtime/routes/consolidation-routes.ts +8 -9
- package/src/runtime/routes/contact-routes.ts +0 -160
- package/src/runtime/routes/conversation-cli-routes.ts +192 -0
- package/src/runtime/routes/conversation-management-routes.ts +30 -43
- package/src/runtime/routes/conversation-query-routes.ts +373 -82
- package/src/runtime/routes/conversation-routes.ts +31 -10
- package/src/runtime/routes/conversations-import-routes.ts +229 -0
- package/src/runtime/routes/credential-routes.ts +540 -0
- package/src/runtime/routes/debug-bash-routes.ts +2 -0
- package/src/runtime/routes/debug-routes.ts +2 -2
- package/src/runtime/routes/document-pdf-renderer.ts +5 -1
- package/src/runtime/routes/domain-routes.ts +167 -0
- package/src/runtime/routes/email-routes.ts +603 -0
- package/src/runtime/routes/errors.ts +2 -2
- package/src/runtime/routes/events-routes.ts +192 -0
- package/src/runtime/routes/filing-routes.ts +2 -3
- package/src/runtime/routes/home-feed-routes.ts +6 -78
- package/src/runtime/routes/host-app-control-routes.ts +44 -2
- package/src/runtime/routes/host-browser-routes.ts +103 -22
- package/src/runtime/routes/http-adapter.ts +2 -0
- package/src/runtime/routes/identity-routes.ts +5 -0
- package/src/runtime/routes/image-generation-routes.ts +99 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +137 -1
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +87 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +156 -0
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +22 -7
- package/src/runtime/routes/index.ts +36 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +312 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +98 -0
- package/src/runtime/routes/inference-profile-session-routes.ts +146 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +317 -0
- package/src/runtime/routes/inference-send-routes.ts +115 -0
- package/src/runtime/routes/integrations/twilio.ts +1 -0
- package/src/runtime/routes/mcp-auth-routes.ts +283 -9
- package/src/runtime/routes/memory-item-routes.test.ts +3 -9
- package/src/runtime/routes/memory-item-routes.ts +5 -6
- package/src/runtime/routes/memory-v2-routes.ts +105 -404
- package/src/runtime/routes/notification-routes.ts +2 -0
- package/src/runtime/routes/oauth-apps.ts +112 -7
- package/src/runtime/routes/oauth-commands-routes.ts +1007 -0
- package/src/runtime/routes/oauth-connect-routes.ts +67 -5
- package/src/runtime/routes/oauth-providers.ts +298 -8
- package/src/runtime/routes/platform-routes.ts +336 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -1
- package/src/runtime/routes/playground/reset-circuit.ts +2 -1
- package/src/runtime/routes/playground/state.ts +2 -1
- package/src/runtime/routes/publish-routes.ts +221 -0
- package/src/runtime/routes/schedule-routes.ts +82 -0
- package/src/runtime/routes/sequence-routes.ts +291 -0
- package/src/runtime/routes/settings-routes.ts +2 -10
- package/src/runtime/routes/skills-routes.ts +31 -1
- package/src/runtime/routes/stt-routes.ts +240 -3
- package/src/runtime/routes/surface-action-routes.ts +43 -7
- package/src/runtime/routes/tts-routes.ts +67 -0
- package/src/runtime/routes/types.ts +32 -0
- package/src/runtime/routes/user-routes-cli.ts +243 -0
- package/src/runtime/routes/webhook-routes.ts +165 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/sync/sync-publisher.test.ts +105 -0
- package/src/runtime/sync/sync-publisher.ts +21 -0
- package/src/schedule/scheduler.ts +200 -123
- package/src/security/__tests__/provider-key-env-fallback.test.ts +12 -6
- package/src/security/secret-patterns.ts +3 -0
- package/src/sequence/engine.ts +38 -40
- package/src/skills/include-graph.ts +35 -13
- package/src/subagent/manager.ts +20 -15
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +206 -0
- package/src/tools/browser/browser-execution.ts +15 -4
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +174 -0
- package/src/tools/browser/cdp-client/cdp-inspect/__tests__/ws-transport.test.ts +16 -13
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +24 -1
- package/src/tools/browser/cdp-client/factory.ts +66 -5
- package/src/tools/browser/runtime-check.ts +77 -0
- package/src/tools/document/document-tool.ts +20 -0
- package/src/tools/executor.ts +18 -2
- package/src/tools/memory/register.test.ts +10 -8
- package/src/tools/memory/register.ts +9 -1
- package/src/tools/network/__tests__/web-search.test.ts +156 -0
- package/src/tools/network/web-search.ts +280 -37
- package/src/tools/permission-checker.ts +28 -5
- package/src/tools/skills/load.ts +24 -20
- package/src/tools/subagent/spawn.ts +3 -3
- package/src/tools/terminal/shell.ts +44 -0
- package/src/tools/tool-name-aliases.ts +19 -0
- package/src/tools/types.ts +19 -1
- package/src/usage/attribution.ts +3 -2
- package/src/util/pricing.ts +86 -160
- package/src/watcher/__tests__/engine.test.ts +301 -0
- package/src/watcher/constants.ts +7 -0
- package/src/watcher/engine.ts +90 -90
- package/src/workspace/migrations/046-seed-conversation-starters-callsite.ts +6 -9
- package/src/workspace/migrations/054-seed-recall-callsite.ts +10 -1
- package/src/workspace/migrations/057-repair-stale-gemini-model-ids.ts +28 -4
- package/src/workspace/migrations/067-release-notes-safe-storage-limits.ts +4 -62
- package/src/workspace/migrations/069-seed-onboarding-threads.ts +34 -0
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +31 -0
- package/src/workspace/migrations/071-remove-safe-storage-release-note.ts +111 -0
- package/src/workspace/migrations/072-seed-reply-suggestion-callsite.ts +104 -0
- package/src/workspace/migrations/073-repair-recall-callsite-empty-profile.ts +93 -0
- package/src/workspace/migrations/074-drop-deprecated-secret-detection-keys.ts +117 -0
- package/src/workspace/migrations/075-memory-v2-bm25-b-default-reembed.ts +61 -0
- package/src/workspace/migrations/076-drop-services-inference-mode.ts +62 -0
- package/src/workspace/migrations/077-seed-memory-router-callsite.ts +89 -0
- package/src/workspace/migrations/078-release-notes-tavily-web-search.ts +66 -0
- package/src/workspace/migrations/079-home-feed-notification-only.ts +197 -0
- package/src/workspace/migrations/080-restrict-vercel-api-token-metadata.ts +182 -0
- package/src/workspace/migrations/081-backfill-bash-allowed-tools-for-injection-credentials.ts +160 -0
- package/src/workspace/migrations/082-backfill-managed-profile-labels.ts +154 -0
- package/src/workspace/migrations/registry.ts +28 -0
- package/src/workspace/migrations/runner.ts +13 -2
- package/src/workspace/migrations/types.ts +13 -3
- package/src/workspace/provider-commit-message-generator.ts +3 -2
- package/src/__tests__/context-search-pkb-source.test.ts +0 -492
- package/src/__tests__/credentials-cli.test.ts +0 -1225
- package/src/__tests__/memory-admin-recall.test.ts +0 -213
- package/src/approvals/__tests__/guardian-feed-event.test.ts +0 -303
- package/src/cli/commands/__tests__/email-download.test.ts +0 -260
- package/src/cli/commands/__tests__/email-list.test.ts +0 -216
- package/src/cli/commands/__tests__/email-register.test.ts +0 -186
- package/src/cli/commands/__tests__/email-send.test.ts +0 -416
- package/src/cli/commands/__tests__/email-status.test.ts +0 -185
- package/src/cli/commands/__tests__/email-unregister.test.ts +0 -168
- package/src/cli/commands/__tests__/routes.test.ts +0 -562
- package/src/cli/commands/__tests__/stt-transcribe.test.ts +0 -454
- package/src/cli/commands/autonomy.ts +0 -365
- package/src/cli/commands/memory.ts +0 -424
- package/src/cli/commands/oauth/__tests__/connect.test.ts +0 -1201
- package/src/cli/commands/oauth/__tests__/disconnect.test.ts +0 -686
- package/src/cli/commands/oauth/__tests__/mode.test.ts +0 -632
- package/src/cli/commands/oauth/__tests__/ping.test.ts +0 -631
- package/src/cli/commands/oauth/__tests__/providers-delete.test.ts +0 -573
- package/src/cli/commands/oauth/__tests__/providers-register.test.ts +0 -330
- package/src/cli/commands/oauth/__tests__/providers-update.test.ts +0 -521
- package/src/cli/commands/oauth/__tests__/status.test.ts +0 -551
- package/src/cli/commands/oauth/__tests__/token.test.ts +0 -420
- package/src/cli/lib/daemon-avatar-client.ts +0 -37
- package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +0 -87
- package/src/config/bundled-skills/messaging/tools/__tests__/messaging-feed-events.test.ts +0 -207
- package/src/daemon/__tests__/conversation-feed-event.test.ts +0 -304
- package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +0 -233
- package/src/home/__tests__/assistant-feed-authoring.test.ts +0 -156
- package/src/home/__tests__/emit-feed-event.test.ts +0 -169
- package/src/home/__tests__/feed-population-integration.test.ts +0 -312
- package/src/home/__tests__/feed-scheduler.test.ts +0 -222
- package/src/home/__tests__/phase5-exit-criteria.test.ts +0 -229
- package/src/home/__tests__/platform-gmail-digest.test.ts +0 -222
- package/src/home/__tests__/rollup-producer.test.ts +0 -507
- package/src/home/assistant-feed-authoring.ts +0 -135
- package/src/home/emit-feed-event.ts +0 -169
- package/src/home/feed-scheduler.ts +0 -281
- package/src/home/platform-gmail-digest.ts +0 -163
- package/src/home/rewrite-command-preview.ts +0 -66
- package/src/home/rewrite-feed-title.ts +0 -58
- package/src/home/rollup-producer.ts +0 -426
- package/src/memory/admin.ts +0 -326
- package/src/memory/context-search/sources/pkb.ts +0 -477
- package/src/memory/graph/compaction.ts +0 -299
- /package/src/cli/{commands → lib}/cache-fs.ts +0 -0
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
* One representative call site (the `installSkill` bundled branch) is
|
|
6
6
|
* exercised — all 5 sites share the same delegation to
|
|
7
7
|
* `maybeSeedMemoryV2Skills`, so a single suite covers behavior. Validates:
|
|
8
|
-
* -
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* - config.memory.v2.enabled off → helper still invoked, seed short-circuits
|
|
8
|
+
* - config on → helper invoked after seedSkillGraphNodes and the seed
|
|
9
|
+
* observed (callOrder picks up "v2")
|
|
10
|
+
* - config off → helper still invoked, but the seed short-circuits
|
|
12
11
|
*
|
|
13
12
|
* The handler delegates to `maybeSeedMemoryV2Skills` from
|
|
14
13
|
* `daemon/memory-v2-startup.ts`. We mock that module directly so the test
|
|
15
14
|
* does not have to drain the dynamic-import microtask chain. The helper's
|
|
16
|
-
* gate semantics
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* gate semantics are covered by `lifecycle-memory-v2-seed.test.ts`; here
|
|
16
|
+
* we only verify that the handler invokes the helper synchronously with
|
|
17
|
+
* the live config.
|
|
19
18
|
*/
|
|
20
19
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
21
20
|
|
|
@@ -23,7 +22,7 @@ import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
|
23
22
|
// Programmable test state
|
|
24
23
|
// ---------------------------------------------------------------------------
|
|
25
24
|
|
|
26
|
-
const flagsState = {
|
|
25
|
+
const flagsState = { configV2Enabled: true };
|
|
27
26
|
|
|
28
27
|
const callOrder: string[] = [];
|
|
29
28
|
|
|
@@ -55,10 +54,7 @@ mock.module("../config/skills.js", () => ({
|
|
|
55
54
|
}));
|
|
56
55
|
|
|
57
56
|
mock.module("../config/assistant-feature-flags.js", () => ({
|
|
58
|
-
isAssistantFeatureFlagEnabled: (
|
|
59
|
-
if (key === "memory-v2-enabled") return flagsState.flagEnabled;
|
|
60
|
-
return true;
|
|
61
|
-
},
|
|
57
|
+
isAssistantFeatureFlagEnabled: () => true,
|
|
62
58
|
}));
|
|
63
59
|
|
|
64
60
|
// Stub both `getConfig` and `loadConfig`. `loadConfig` is reached by code
|
|
@@ -220,18 +216,17 @@ const { installSkill } = await import("../daemon/handlers/skills.js");
|
|
|
220
216
|
|
|
221
217
|
describe("v2 skill re-seed gating in skill handlers", () => {
|
|
222
218
|
beforeEach(() => {
|
|
223
|
-
flagsState.flagEnabled = true;
|
|
224
219
|
flagsState.configV2Enabled = true;
|
|
225
220
|
callOrder.length = 0;
|
|
226
221
|
mockSeedSkillGraphNodes.mockClear();
|
|
227
222
|
mockMaybeSeedMemoryV2Skills.mockClear();
|
|
228
223
|
mockMaybeSeedMemoryV2Skills.mockImplementation((config) => {
|
|
229
|
-
if (!
|
|
224
|
+
if (!config.memory.v2.enabled) return;
|
|
230
225
|
callOrder.push("v2");
|
|
231
226
|
});
|
|
232
227
|
});
|
|
233
228
|
|
|
234
|
-
test("
|
|
229
|
+
test("config on → maybeSeedMemoryV2Skills invoked after seedSkillGraphNodes", async () => {
|
|
235
230
|
const result = await installSkill({ slug: "bundled-skill" });
|
|
236
231
|
|
|
237
232
|
expect(result.success).toBe(true);
|
|
@@ -240,17 +235,6 @@ describe("v2 skill re-seed gating in skill handlers", () => {
|
|
|
240
235
|
expect(callOrder).toEqual(["v1", "v2"]);
|
|
241
236
|
});
|
|
242
237
|
|
|
243
|
-
test("flag off → seed mock observes the disabled flag and skips", async () => {
|
|
244
|
-
flagsState.flagEnabled = false;
|
|
245
|
-
|
|
246
|
-
const result = await installSkill({ slug: "bundled-skill" });
|
|
247
|
-
|
|
248
|
-
expect(result.success).toBe(true);
|
|
249
|
-
expect(mockSeedSkillGraphNodes).toHaveBeenCalledTimes(1);
|
|
250
|
-
expect(mockMaybeSeedMemoryV2Skills).toHaveBeenCalledTimes(1);
|
|
251
|
-
expect(callOrder).toEqual(["v1"]);
|
|
252
|
-
});
|
|
253
|
-
|
|
254
238
|
test("config.memory.v2.enabled off → seed mock observes config and skips", async () => {
|
|
255
239
|
flagsState.configV2Enabled = false;
|
|
256
240
|
|
|
@@ -261,12 +245,4 @@ describe("v2 skill re-seed gating in skill handlers", () => {
|
|
|
261
245
|
expect(mockMaybeSeedMemoryV2Skills).toHaveBeenCalledTimes(1);
|
|
262
246
|
expect(callOrder).toEqual(["v1"]);
|
|
263
247
|
});
|
|
264
|
-
|
|
265
|
-
// Note: "seed rejection swallowed" is now an internal concern of
|
|
266
|
-
// `maybeSeedMemoryV2Skills` — it dispatches the seed call as a
|
|
267
|
-
// fire-and-forget promise with `.catch(log.warn)`. That behavior is
|
|
268
|
-
// covered by `lifecycle-memory-v2-seed.test.ts`. From the handler's
|
|
269
|
-
// perspective, we only need to verify the helper is invoked
|
|
270
|
-
// synchronously with the correct config — which the cases above already
|
|
271
|
-
// exercise.
|
|
272
248
|
});
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
2
2
|
|
|
3
|
+
// Default the warm-pool gate to OPEN — these tests probe disk-pressure
|
|
4
|
+
// behavior, not the pre-first-message guard.
|
|
5
|
+
mock.module("../runtime/pre-first-message-gate.js", () => ({
|
|
6
|
+
hasReceivedUserMessage: () => true,
|
|
7
|
+
_resetPreFirstMessageGateCacheForTests: () => {},
|
|
8
|
+
}));
|
|
9
|
+
|
|
3
10
|
mock.module("../util/logger.js", () => ({
|
|
4
11
|
getLogger: () => ({
|
|
5
12
|
info: () => {},
|
|
@@ -63,6 +70,10 @@ mock.module("../memory/conversation-crud.js", () => ({
|
|
|
63
70
|
createdConversations.push(opts);
|
|
64
71
|
return { id: "conv-1", ...opts };
|
|
65
72
|
},
|
|
73
|
+
// runBackgroundJob (loaded transitively via heartbeat-service) imports
|
|
74
|
+
// addMessage. Disk-pressure short-circuits before addMessage ever runs,
|
|
75
|
+
// but the mock module must still expose every name the real module does.
|
|
76
|
+
addMessage: () => Promise.resolve({ id: "mock-msg-id" }),
|
|
66
77
|
}));
|
|
67
78
|
|
|
68
79
|
const mockProcessMessage = mock(() => Promise.resolve({ messageId: "msg-1" }));
|
|
@@ -70,9 +81,11 @@ mock.module("../daemon/process-message.js", () => ({
|
|
|
70
81
|
processMessage: mockProcessMessage,
|
|
71
82
|
}));
|
|
72
83
|
|
|
73
|
-
const
|
|
74
|
-
mock.module("../
|
|
75
|
-
|
|
84
|
+
const emittedNotificationSignals: Array<{ sourceEventName?: string }> = [];
|
|
85
|
+
mock.module("../notifications/emit-signal.js", () => ({
|
|
86
|
+
emitNotificationSignal: async (opts: { sourceEventName?: string }) => {
|
|
87
|
+
emittedNotificationSignals.push({ sourceEventName: opts.sourceEventName });
|
|
88
|
+
},
|
|
76
89
|
}));
|
|
77
90
|
|
|
78
91
|
mock.module("../prompts/persona-resolver.js", () => ({
|
|
@@ -131,10 +144,10 @@ describe("HeartbeatService disk pressure gate", () => {
|
|
|
131
144
|
mockMarkStaleRunningAsError.mockClear();
|
|
132
145
|
mockMarkStaleRunningAsError.mockImplementation(() => 0);
|
|
133
146
|
mockProcessMessage.mockClear();
|
|
134
|
-
|
|
147
|
+
emittedNotificationSignals.length = 0;
|
|
135
148
|
});
|
|
136
149
|
|
|
137
|
-
test("skips without creating heartbeat rows, conversations, or
|
|
150
|
+
test("skips without creating heartbeat rows, conversations, or notifications", async () => {
|
|
138
151
|
const service = new HeartbeatService({
|
|
139
152
|
alerter: () => {},
|
|
140
153
|
});
|
|
@@ -148,7 +161,7 @@ describe("HeartbeatService disk pressure gate", () => {
|
|
|
148
161
|
expect(mockSkipHeartbeatRun).not.toHaveBeenCalled();
|
|
149
162
|
expect(createdConversations).toHaveLength(0);
|
|
150
163
|
expect(mockProcessMessage).not.toHaveBeenCalled();
|
|
151
|
-
expect(
|
|
164
|
+
expect(emittedNotificationSignals).toHaveLength(0);
|
|
152
165
|
});
|
|
153
166
|
|
|
154
167
|
test("allows forced user-initiated heartbeat runs while locked", async () => {
|
|
@@ -168,7 +181,7 @@ describe("HeartbeatService disk pressure gate", () => {
|
|
|
168
181
|
expect(mockProcessMessage).toHaveBeenCalledTimes(1);
|
|
169
182
|
});
|
|
170
183
|
|
|
171
|
-
test("start recovery skips missed-run
|
|
184
|
+
test("start recovery skips missed-run notifications while locked", async () => {
|
|
172
185
|
mockMarkStaleRunsAsMissed.mockImplementationOnce(() => 1);
|
|
173
186
|
const service = new HeartbeatService({
|
|
174
187
|
alerter: () => {},
|
|
@@ -178,6 +191,6 @@ describe("HeartbeatService disk pressure gate", () => {
|
|
|
178
191
|
await service.stop();
|
|
179
192
|
|
|
180
193
|
expect(mockMarkStaleRunsAsMissed).toHaveBeenCalledTimes(1);
|
|
181
|
-
expect(
|
|
194
|
+
expect(emittedNotificationSignals).toHaveLength(0);
|
|
182
195
|
});
|
|
183
196
|
});
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
afterEach,
|
|
5
|
-
beforeEach,
|
|
6
|
-
describe,
|
|
7
|
-
expect,
|
|
8
|
-
jest,
|
|
9
|
-
mock,
|
|
10
|
-
test,
|
|
11
|
-
} from "bun:test";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
|
|
12
4
|
|
|
13
5
|
const testWorkspaceDir = process.env.VELLUM_WORKSPACE_DIR!;
|
|
14
6
|
|
|
7
|
+
// Default the warm-pool gate to OPEN for existing tests — they predate
|
|
8
|
+
// the gate and expect heartbeat/filing/etc. to run on every tick. Tests
|
|
9
|
+
// that specifically exercise the gate path override this mock locally.
|
|
10
|
+
mock.module("../runtime/pre-first-message-gate.js", () => ({
|
|
11
|
+
hasReceivedUserMessage: () => true,
|
|
12
|
+
_resetPreFirstMessageGateCacheForTests: () => {},
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
15
|
// ── Heartbeat run store mock ───────────────────────────────────────
|
|
16
16
|
const mockInsertPendingHeartbeatRun = mock(() => "mock-run-id");
|
|
17
17
|
const mockStartHeartbeatRun = mock(() => true);
|
|
@@ -34,12 +34,6 @@ mock.module("../heartbeat/heartbeat-run-store.js", () => ({
|
|
|
34
34
|
countCompletedHeartbeatRuns: mockCountCompletedHeartbeatRuns,
|
|
35
35
|
}));
|
|
36
36
|
|
|
37
|
-
// ── Feed event mock ───────────────────────────────────────────────
|
|
38
|
-
const mockEmitFeedEvent = mock(() => Promise.resolve());
|
|
39
|
-
mock.module("../home/emit-feed-event.js", () => ({
|
|
40
|
-
emitFeedEvent: mockEmitFeedEvent,
|
|
41
|
-
}));
|
|
42
|
-
|
|
43
37
|
// Mock config loader
|
|
44
38
|
let mockConfig = {
|
|
45
39
|
heartbeat: {
|
|
@@ -383,8 +377,6 @@ describe("HeartbeatService", () => {
|
|
|
383
377
|
mockListHeartbeatRuns.mockImplementation(() => []);
|
|
384
378
|
mockCountCompletedHeartbeatRuns.mockClear();
|
|
385
379
|
mockCountCompletedHeartbeatRuns.mockImplementation(() => 10);
|
|
386
|
-
mockEmitFeedEvent.mockClear();
|
|
387
|
-
mockEmitFeedEvent.mockImplementation(() => Promise.resolve());
|
|
388
380
|
|
|
389
381
|
mockConfig = {
|
|
390
382
|
heartbeat: {
|
|
@@ -848,15 +840,11 @@ describe("HeartbeatService", () => {
|
|
|
848
840
|
await service.runOnce();
|
|
849
841
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
850
842
|
|
|
851
|
-
|
|
843
|
+
// The conversation surfaces to the sidebar via the runner's bootstrap
|
|
844
|
+
// callback for *every* heartbeat — "silent OK" means no notification
|
|
845
|
+
// signal is emitted, not that the conversation is hidden.
|
|
846
|
+
expect(conversationCreatedCalls).toHaveLength(1);
|
|
852
847
|
expect(emittedNotificationSignals).toHaveLength(0);
|
|
853
|
-
const successFeedCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
854
|
-
(call: unknown[]) => {
|
|
855
|
-
const opts = call[0] as { dedupKey?: string };
|
|
856
|
-
return opts.dedupKey?.startsWith("heartbeat:ok:");
|
|
857
|
-
},
|
|
858
|
-
);
|
|
859
|
-
expect(successFeedCalls).toHaveLength(0);
|
|
860
848
|
});
|
|
861
849
|
|
|
862
850
|
test("HEARTBEAT_OK stays silent when earlier content mentions HEARTBEAT_ALERT", async () => {
|
|
@@ -897,7 +885,9 @@ describe("HeartbeatService", () => {
|
|
|
897
885
|
await service.runOnce();
|
|
898
886
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
899
887
|
|
|
900
|
-
|
|
888
|
+
// Conversation surfaces via the runner bootstrap, but no notification
|
|
889
|
+
// is emitted since the disposition is OK.
|
|
890
|
+
expect(conversationCreatedCalls).toHaveLength(1);
|
|
901
891
|
expect(emittedNotificationSignals).toHaveLength(0);
|
|
902
892
|
});
|
|
903
893
|
|
|
@@ -1564,7 +1554,10 @@ describe("HeartbeatService", () => {
|
|
|
1564
1554
|
await service.runOnce();
|
|
1565
1555
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1566
1556
|
|
|
1567
|
-
|
|
1557
|
+
// The bootstrap-time surface fires regardless of CAS (it happens
|
|
1558
|
+
// before completeHeartbeatRun). CAS-false suppresses the alert
|
|
1559
|
+
// notification emit but not the sidebar entry.
|
|
1560
|
+
expect(conversationCreatedCalls).toHaveLength(1);
|
|
1568
1561
|
expect(emittedNotificationSignals).toHaveLength(0);
|
|
1569
1562
|
});
|
|
1570
1563
|
|
|
@@ -1581,15 +1574,6 @@ describe("HeartbeatService", () => {
|
|
|
1581
1574
|
|
|
1582
1575
|
// completeHeartbeatRun returned false, so alerter should NOT be called
|
|
1583
1576
|
expect(alerterCalls).toHaveLength(0);
|
|
1584
|
-
|
|
1585
|
-
// No failure feed event either
|
|
1586
|
-
const failCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1587
|
-
(call: unknown[]) => {
|
|
1588
|
-
const opts = call[0] as { dedupKey?: string };
|
|
1589
|
-
return opts.dedupKey?.startsWith("heartbeat:fail:");
|
|
1590
|
-
},
|
|
1591
|
-
);
|
|
1592
|
-
expect(failCalls).toHaveLength(0);
|
|
1593
1577
|
});
|
|
1594
1578
|
|
|
1595
1579
|
test("active-hours skip calls skipHeartbeatRun", async () => {
|
|
@@ -1738,39 +1722,14 @@ describe("HeartbeatService", () => {
|
|
|
1738
1722
|
expect(mockSupersedePendingRun).toHaveBeenCalledWith("mock-run-id");
|
|
1739
1723
|
});
|
|
1740
1724
|
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
});
|
|
1748
|
-
|
|
1749
|
-
const service = createService({
|
|
1750
|
-
processMessage: async () => {
|
|
1751
|
-
await runPromise;
|
|
1752
|
-
return { messageId: "msg-1" };
|
|
1753
|
-
},
|
|
1754
|
-
});
|
|
1755
|
-
|
|
1756
|
-
const runOncePromise = service.runOnce();
|
|
1757
|
-
// Advance past the 30-minute timeout
|
|
1758
|
-
jest.advanceTimersByTime(30 * 60 * 1000 + 1000);
|
|
1759
|
-
await runOncePromise;
|
|
1760
|
-
|
|
1761
|
-
expect(mockCompleteHeartbeatRun).toHaveBeenCalledWith("mock-run-id", {
|
|
1762
|
-
status: "timeout",
|
|
1763
|
-
error: "Heartbeat execution exceeded the 30-minute timeout",
|
|
1764
|
-
});
|
|
1765
|
-
|
|
1766
|
-
// Clean up — resolve the hanging promise so it doesn't leak
|
|
1767
|
-
resolveRun!();
|
|
1768
|
-
} finally {
|
|
1769
|
-
jest.useRealTimers();
|
|
1770
|
-
}
|
|
1771
|
-
});
|
|
1725
|
+
// Note: the heartbeat-specific behavior on timeout is the trivial
|
|
1726
|
+
// `errorKind === "timeout" ? "timeout" : "error"` mapping. The runner
|
|
1727
|
+
// owns the actual timeout race (covered in
|
|
1728
|
+
// `background-job-runner.test.ts`), so we don't reproduce its
|
|
1729
|
+
// setTimeout-based timing here — fake timers don't reliably propagate
|
|
1730
|
+
// into the runner's module scope across bun versions.
|
|
1772
1731
|
|
|
1773
|
-
test("failure
|
|
1732
|
+
test("failure emits activity.failed notification with errorKind exception", async () => {
|
|
1774
1733
|
const service = createService({
|
|
1775
1734
|
processMessage: async () => {
|
|
1776
1735
|
throw new Error("web_search outage");
|
|
@@ -1779,192 +1738,50 @@ describe("HeartbeatService", () => {
|
|
|
1779
1738
|
|
|
1780
1739
|
await service.runOnce();
|
|
1781
1740
|
|
|
1782
|
-
const
|
|
1783
|
-
(
|
|
1784
|
-
const opts = call[0] as { title?: string };
|
|
1785
|
-
return opts.title === "Heartbeat Failed";
|
|
1786
|
-
},
|
|
1787
|
-
);
|
|
1788
|
-
expect(failCalls).toHaveLength(1);
|
|
1789
|
-
const opts = (failCalls as any[][])[0][0] as {
|
|
1790
|
-
urgency?: string;
|
|
1791
|
-
summary?: string;
|
|
1792
|
-
};
|
|
1793
|
-
expect(opts.urgency).toBe("high");
|
|
1794
|
-
expect(opts.summary).toContain("web_search outage");
|
|
1795
|
-
});
|
|
1796
|
-
|
|
1797
|
-
test("CAS false on complete suppresses failure feed event", async () => {
|
|
1798
|
-
mockCompleteHeartbeatRun.mockImplementation(() => false);
|
|
1799
|
-
|
|
1800
|
-
const service = createService({
|
|
1801
|
-
processMessage: async () => {
|
|
1802
|
-
throw new Error("some error");
|
|
1803
|
-
},
|
|
1804
|
-
});
|
|
1805
|
-
|
|
1806
|
-
await service.runOnce();
|
|
1807
|
-
|
|
1808
|
-
const failCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1809
|
-
(call: unknown[]) => {
|
|
1810
|
-
const opts = call[0] as { title?: string };
|
|
1811
|
-
return opts.title === "Heartbeat Failed";
|
|
1812
|
-
},
|
|
1741
|
+
const failSignals = emittedNotificationSignals.filter(
|
|
1742
|
+
(s) => s.sourceEventName === "activity.failed",
|
|
1813
1743
|
);
|
|
1814
|
-
expect(
|
|
1744
|
+
expect(failSignals).toHaveLength(1);
|
|
1745
|
+
const signal = failSignals[0]!;
|
|
1746
|
+
expect(signal.contextPayload.jobName).toBe("heartbeat");
|
|
1747
|
+
expect(signal.contextPayload.errorKind).toBe("exception");
|
|
1748
|
+
expect(signal.contextPayload.errorMessage).toContain("web_search outage");
|
|
1749
|
+
expect(signal.attentionHints?.urgency).toBe("medium");
|
|
1750
|
+
expect(signal.attentionHints?.isAsyncBackground).toBe(true);
|
|
1815
1751
|
});
|
|
1816
1752
|
|
|
1817
|
-
test("
|
|
1818
|
-
jest.useFakeTimers();
|
|
1819
|
-
try {
|
|
1820
|
-
let resolveRun: () => void;
|
|
1821
|
-
const runPromise = new Promise<void>((r) => {
|
|
1822
|
-
resolveRun = r;
|
|
1823
|
-
});
|
|
1824
|
-
|
|
1825
|
-
const service = createService({
|
|
1826
|
-
processMessage: async () => {
|
|
1827
|
-
await runPromise;
|
|
1828
|
-
return { messageId: "msg-1" };
|
|
1829
|
-
},
|
|
1830
|
-
});
|
|
1831
|
-
|
|
1832
|
-
const runOncePromise = service.runOnce();
|
|
1833
|
-
jest.advanceTimersByTime(30 * 60 * 1000 + 1000);
|
|
1834
|
-
await runOncePromise;
|
|
1835
|
-
|
|
1836
|
-
const timeoutCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1837
|
-
(call: unknown[]) => {
|
|
1838
|
-
const opts = call[0] as { title?: string };
|
|
1839
|
-
return opts.title === "Heartbeat Timed Out";
|
|
1840
|
-
},
|
|
1841
|
-
);
|
|
1842
|
-
expect(timeoutCalls).toHaveLength(1);
|
|
1843
|
-
const opts = (timeoutCalls as any[][])[0][0] as {
|
|
1844
|
-
urgency?: string;
|
|
1845
|
-
};
|
|
1846
|
-
expect(opts.urgency).toBe("high");
|
|
1847
|
-
|
|
1848
|
-
resolveRun!();
|
|
1849
|
-
} finally {
|
|
1850
|
-
jest.useRealTimers();
|
|
1851
|
-
}
|
|
1852
|
-
});
|
|
1853
|
-
|
|
1854
|
-
test("CAS false on timeout suppresses timeout feed event", async () => {
|
|
1855
|
-
jest.useFakeTimers();
|
|
1856
|
-
try {
|
|
1857
|
-
mockCompleteHeartbeatRun.mockImplementation(() => false);
|
|
1858
|
-
|
|
1859
|
-
let resolveRun: () => void;
|
|
1860
|
-
const runPromise = new Promise<void>((r) => {
|
|
1861
|
-
resolveRun = r;
|
|
1862
|
-
});
|
|
1863
|
-
|
|
1864
|
-
const service = createService({
|
|
1865
|
-
processMessage: async () => {
|
|
1866
|
-
await runPromise;
|
|
1867
|
-
return { messageId: "msg-1" };
|
|
1868
|
-
},
|
|
1869
|
-
});
|
|
1870
|
-
|
|
1871
|
-
const runOncePromise = service.runOnce();
|
|
1872
|
-
jest.advanceTimersByTime(30 * 60 * 1000 + 1000);
|
|
1873
|
-
await runOncePromise;
|
|
1874
|
-
|
|
1875
|
-
// completeHeartbeatRun returned false, so no timeout feed event
|
|
1876
|
-
const timeoutCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1877
|
-
(call: unknown[]) => {
|
|
1878
|
-
const opts = call[0] as { title?: string };
|
|
1879
|
-
return opts.title === "Heartbeat Timed Out";
|
|
1880
|
-
},
|
|
1881
|
-
);
|
|
1882
|
-
expect(timeoutCalls).toHaveLength(0);
|
|
1883
|
-
|
|
1884
|
-
resolveRun!();
|
|
1885
|
-
} finally {
|
|
1886
|
-
jest.useRealTimers();
|
|
1887
|
-
}
|
|
1888
|
-
});
|
|
1889
|
-
|
|
1890
|
-
test("late run emits late feed event", async () => {
|
|
1891
|
-
const service = createService();
|
|
1892
|
-
service.start();
|
|
1893
|
-
|
|
1894
|
-
// Set the pending run to be 10 minutes in the past
|
|
1895
|
-
(service as any)._nextRunAt = Date.now() - 10 * 60 * 1000;
|
|
1896
|
-
(service as any)._pendingRunId = "late-run-id";
|
|
1897
|
-
|
|
1898
|
-
await service.runOnce();
|
|
1899
|
-
|
|
1900
|
-
const lateCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1901
|
-
(call: unknown[]) => {
|
|
1902
|
-
const opts = call[0] as { title?: string };
|
|
1903
|
-
return opts.title === "Heartbeat Ran Late";
|
|
1904
|
-
},
|
|
1905
|
-
);
|
|
1906
|
-
expect(lateCalls).toHaveLength(1);
|
|
1907
|
-
const opts = (lateCalls as any[][])[0][0] as {
|
|
1908
|
-
urgency?: string;
|
|
1909
|
-
summary?: string;
|
|
1910
|
-
};
|
|
1911
|
-
expect(opts.urgency).toBe("medium");
|
|
1912
|
-
expect(opts.summary).toContain("10 minutes late");
|
|
1913
|
-
|
|
1914
|
-
await service.stop();
|
|
1915
|
-
});
|
|
1916
|
-
|
|
1917
|
-
test("on-time run does not emit late feed event", async () => {
|
|
1918
|
-
const service = createService();
|
|
1919
|
-
await service.runOnce();
|
|
1920
|
-
|
|
1921
|
-
const lateCalls = mockEmitFeedEvent.mock.calls.filter(
|
|
1922
|
-
(call: unknown[]) => {
|
|
1923
|
-
const opts = call[0] as { title?: string };
|
|
1924
|
-
return opts.title === "Heartbeat Ran Late";
|
|
1925
|
-
},
|
|
1926
|
-
);
|
|
1927
|
-
expect(lateCalls).toHaveLength(0);
|
|
1928
|
-
});
|
|
1929
|
-
|
|
1930
|
-
test("start() emits missed-run feed event when stale rows exist", () => {
|
|
1753
|
+
test("start() emits activity.failed notification when stale rows exist", () => {
|
|
1931
1754
|
mockMarkStaleRunsAsMissed.mockImplementation(() => 2);
|
|
1932
1755
|
mockMarkStaleRunningAsError.mockImplementation(() => 1);
|
|
1933
1756
|
|
|
1934
1757
|
const service = createService();
|
|
1935
1758
|
service.start();
|
|
1936
1759
|
|
|
1937
|
-
const
|
|
1938
|
-
(
|
|
1939
|
-
const opts = call[0] as { title?: string };
|
|
1940
|
-
return opts.title === "Heartbeat Runs Missed";
|
|
1941
|
-
},
|
|
1760
|
+
const missedSignals = emittedNotificationSignals.filter(
|
|
1761
|
+
(s) => s.sourceEventName === "activity.failed",
|
|
1942
1762
|
);
|
|
1943
|
-
expect(
|
|
1944
|
-
const
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
expect(
|
|
1949
|
-
expect(
|
|
1763
|
+
expect(missedSignals).toHaveLength(1);
|
|
1764
|
+
const signal = missedSignals[0]!;
|
|
1765
|
+
expect(signal.dedupeKey).toContain("activity-failed:heartbeat-missed:");
|
|
1766
|
+
expect(signal.contextPayload.jobName).toBe("heartbeat");
|
|
1767
|
+
const errorMessage = signal.contextPayload.errorMessage as string;
|
|
1768
|
+
expect(errorMessage).toContain("3");
|
|
1769
|
+
expect(signal.attentionHints?.urgency).toBe("medium");
|
|
1950
1770
|
|
|
1951
1771
|
service.stop();
|
|
1952
1772
|
});
|
|
1953
1773
|
|
|
1954
|
-
test("start() does not emit
|
|
1774
|
+
test("start() does not emit notification when counts are 0", () => {
|
|
1955
1775
|
mockMarkStaleRunsAsMissed.mockImplementation(() => 0);
|
|
1956
1776
|
mockMarkStaleRunningAsError.mockImplementation(() => 0);
|
|
1957
1777
|
|
|
1958
1778
|
const service = createService();
|
|
1959
1779
|
service.start();
|
|
1960
1780
|
|
|
1961
|
-
const
|
|
1962
|
-
(
|
|
1963
|
-
const opts = call[0] as { title?: string };
|
|
1964
|
-
return opts.title === "Heartbeat Runs Missed";
|
|
1965
|
-
},
|
|
1781
|
+
const missedSignals = emittedNotificationSignals.filter(
|
|
1782
|
+
(s) => s.sourceEventName === "activity.failed",
|
|
1966
1783
|
);
|
|
1967
|
-
expect(
|
|
1784
|
+
expect(missedSignals).toHaveLength(0);
|
|
1968
1785
|
service.stop();
|
|
1969
1786
|
});
|
|
1970
1787
|
});
|
|
@@ -724,6 +724,95 @@ describe("repairHistory", () => {
|
|
|
724
724
|
expect(userMsg.content.every((b) => b.type !== "tool_result")).toBe(true);
|
|
725
725
|
});
|
|
726
726
|
|
|
727
|
+
test("downgrades orphan web_search_tool_result in assistant message to text", () => {
|
|
728
|
+
// Inverse of the orphan-server_tool_use case. A web_search_tool_result
|
|
729
|
+
// in an assistant message whose tool_use_id has no preceding
|
|
730
|
+
// server_tool_use in the same message would 400 at the API. Downgrade
|
|
731
|
+
// to text so the model still sees the search results.
|
|
732
|
+
const messages: Message[] = [
|
|
733
|
+
{ role: "user", content: [{ type: "text", text: "search" }] },
|
|
734
|
+
{
|
|
735
|
+
role: "assistant",
|
|
736
|
+
content: [
|
|
737
|
+
{ type: "text", text: "Here's what I found." },
|
|
738
|
+
{
|
|
739
|
+
type: "web_search_tool_result",
|
|
740
|
+
tool_use_id: "srvtoolu_orphan",
|
|
741
|
+
content: [
|
|
742
|
+
{
|
|
743
|
+
type: "web_search_result",
|
|
744
|
+
url: "https://example.com",
|
|
745
|
+
title: "Example",
|
|
746
|
+
encrypted_content: "enc_abc",
|
|
747
|
+
},
|
|
748
|
+
],
|
|
749
|
+
},
|
|
750
|
+
],
|
|
751
|
+
},
|
|
752
|
+
];
|
|
753
|
+
|
|
754
|
+
const { messages: repaired, stats } = repairHistory(messages);
|
|
755
|
+
|
|
756
|
+
expect(stats.orphanToolResultsDowngraded).toBe(1);
|
|
757
|
+
expect(stats.missingToolResultsInserted).toBe(0);
|
|
758
|
+
|
|
759
|
+
const assistantMsg = repaired[1];
|
|
760
|
+
expect(
|
|
761
|
+
assistantMsg.content.every((b) => b.type !== "web_search_tool_result"),
|
|
762
|
+
).toBe(true);
|
|
763
|
+
const downgraded = assistantMsg.content.find(
|
|
764
|
+
(b) =>
|
|
765
|
+
b.type === "text" &&
|
|
766
|
+
(b as { text: string }).text.includes("srvtoolu_orphan"),
|
|
767
|
+
);
|
|
768
|
+
expect(downgraded).toBeDefined();
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
test("repairs both orphan directions within the same assistant message", () => {
|
|
772
|
+
// server_tool_use without a result AND a stray wsr from a different id —
|
|
773
|
+
// both must be repaired in one pass.
|
|
774
|
+
const messages: Message[] = [
|
|
775
|
+
{ role: "user", content: [{ type: "text", text: "go" }] },
|
|
776
|
+
{
|
|
777
|
+
role: "assistant",
|
|
778
|
+
content: [
|
|
779
|
+
{
|
|
780
|
+
type: "server_tool_use",
|
|
781
|
+
id: "stu_missing_result",
|
|
782
|
+
name: "web_search",
|
|
783
|
+
input: { query: "alpha" },
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
type: "web_search_tool_result",
|
|
787
|
+
tool_use_id: "stu_no_use",
|
|
788
|
+
content: [
|
|
789
|
+
{ type: "web_search_result", url: "https://x.test", title: "X" },
|
|
790
|
+
],
|
|
791
|
+
},
|
|
792
|
+
],
|
|
793
|
+
},
|
|
794
|
+
];
|
|
795
|
+
|
|
796
|
+
const { messages: repaired, stats } = repairHistory(messages);
|
|
797
|
+
|
|
798
|
+
expect(stats.missingToolResultsInserted).toBe(1);
|
|
799
|
+
expect(stats.orphanToolResultsDowngraded).toBe(1);
|
|
800
|
+
|
|
801
|
+
const assistantMsg = repaired[1];
|
|
802
|
+
// Synthetic result inserted immediately after the orphan server_tool_use.
|
|
803
|
+
const blockTypes = assistantMsg.content.map((b) => b.type);
|
|
804
|
+
expect(blockTypes[0]).toBe("server_tool_use");
|
|
805
|
+
expect(blockTypes[1]).toBe("web_search_tool_result");
|
|
806
|
+
expect(
|
|
807
|
+
(assistantMsg.content[1] as { tool_use_id: string }).tool_use_id,
|
|
808
|
+
).toBe("stu_missing_result");
|
|
809
|
+
// The orphan wsr is downgraded to text.
|
|
810
|
+
expect(blockTypes[2]).toBe("text");
|
|
811
|
+
expect((assistantMsg.content[2] as { text: string }).text).toContain(
|
|
812
|
+
"stu_no_use",
|
|
813
|
+
);
|
|
814
|
+
});
|
|
815
|
+
|
|
727
816
|
test("downgrades type-mismatched web_search_tool_result for tool_use", () => {
|
|
728
817
|
// A web_search_tool_result paired with a regular tool_use ID is a type mismatch
|
|
729
818
|
const messages: Message[] = [
|