@vellumai/assistant 0.8.3 → 0.8.5
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/ARCHITECTURE.md +2 -2
- package/docker-entrypoint.sh +0 -1
- package/docs/browser-use-architecture-phase2.md +1 -1
- package/knip.json +2 -1
- package/node_modules/@vellumai/gateway-client/src/types.ts +2 -0
- package/openapi.yaml +1492 -100
- package/package.json +1 -1
- package/src/__tests__/agent-loop-exit-reason.test.ts +4 -5
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +88 -3
- package/src/__tests__/anthropic-provider.test.ts +302 -33
- package/src/__tests__/approval-cascade.test.ts +1 -1
- package/src/__tests__/assistant-event-hub-self-exclusion.test.ts +293 -0
- package/src/__tests__/assistant-feature-flags-integration.test.ts +3 -3
- package/src/__tests__/audit-log-rotation.test.ts +70 -16
- package/src/__tests__/background-workers-disk-pressure.test.ts +4 -3
- package/src/__tests__/btw-routes.test.ts +2 -3
- package/src/__tests__/call-controller.test.ts +0 -1
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +1 -1
- package/src/__tests__/channel-delivery-store.test.ts +193 -0
- package/src/__tests__/channel-guardian.test.ts +3 -3
- package/src/__tests__/channel-reply-delivery.test.ts +284 -5
- package/src/__tests__/channel-retry-sweep.test.ts +274 -1
- package/src/__tests__/checker.test.ts +6 -15
- package/src/__tests__/compaction-events.test.ts +2 -1
- package/src/__tests__/compactor-call-site-logging.test.ts +214 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +110 -0
- package/src/__tests__/computer-use-skill-manifest-regression.test.ts +5 -11
- package/src/__tests__/computer-use-tools.test.ts +2 -4
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +0 -1
- package/src/__tests__/context-token-estimator.test.ts +91 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -1
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +55 -4
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +228 -8
- package/src/__tests__/conversation-agent-loop.test.ts +188 -129
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -5
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +1 -1
- package/src/__tests__/conversation-clean-command.test.ts +137 -0
- package/src/__tests__/conversation-clear-safety.test.ts +25 -25
- package/src/__tests__/conversation-confirmation-signals.test.ts +1 -1
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +1 -1
- package/src/__tests__/conversation-disk-view-integration.test.ts +2 -2
- package/src/__tests__/conversation-error.test.ts +31 -0
- package/src/__tests__/conversation-fork-crud.test.ts +324 -0
- package/src/__tests__/conversation-lifecycle.test.ts +53 -12
- package/src/__tests__/conversation-load-history-repair.test.ts +1 -1
- package/src/__tests__/conversation-load-history-stripped.test.ts +279 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -2
- package/src/__tests__/conversation-process-callsite.test.ts +1 -1
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -1
- package/src/__tests__/conversation-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-disk-view.test.ts +109 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +35 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +264 -81
- package/src/__tests__/conversation-seed-composer.test.ts +66 -4
- package/src/__tests__/conversation-skill-tools.test.ts +2 -5
- package/src/__tests__/conversation-slash-commands.test.ts +36 -8
- package/src/__tests__/conversation-slash-queue.test.ts +1 -1
- package/src/__tests__/conversation-slash-unknown.test.ts +1 -1
- package/src/__tests__/conversation-speed-override.test.ts +1 -1
- package/src/__tests__/conversation-store.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +220 -0
- package/src/__tests__/conversation-sync-tags.test.ts +99 -32
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -1
- package/src/__tests__/conversation-workspace-injection.test.ts +5 -1
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +5 -1
- package/src/__tests__/credential-execution-feature-gates.test.ts +9 -7
- package/src/__tests__/credential-execution-tools.test.ts +6 -6
- package/src/__tests__/credential-security-invariants.test.ts +7 -0
- package/src/__tests__/credential-vault-unit.test.ts +2 -2
- package/src/__tests__/cu-unified-flow.test.ts +10 -1
- package/src/__tests__/dm-backfill.test.ts +64 -0
- package/src/__tests__/dm-persistence.test.ts +33 -0
- package/src/__tests__/document-find-replace.test.ts +501 -0
- package/src/__tests__/dynamic-page-surface.test.ts +2 -2
- package/src/__tests__/email-html-renderer.test.ts +12 -0
- package/src/__tests__/first-greeting.test.ts +23 -2
- package/src/__tests__/gateway-flag-listener.test.ts +237 -0
- package/src/__tests__/gemini-provider.test.ts +78 -0
- package/src/__tests__/guardian-dispatch.test.ts +0 -1
- package/src/__tests__/guardian-outbound-http.test.ts +7 -5
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/headless-browser-navigate.test.ts +172 -0
- package/src/__tests__/heartbeat-disk-pressure.test.ts +4 -0
- package/src/__tests__/heartbeat-service.test.ts +4 -0
- package/src/__tests__/host-bash-proxy.test.ts +6 -0
- package/src/__tests__/host-browser-proxy.test.ts +10 -0
- package/src/__tests__/host-cu-proxy.test.ts +8 -1
- package/src/__tests__/host-file-proxy.test.ts +8 -1
- package/src/__tests__/host-shell-tool.test.ts +1 -1
- package/src/__tests__/host-transfer-proxy.test.ts +8 -1
- package/src/__tests__/identity-routes.test.ts +57 -0
- package/src/__tests__/inbound-slack-persistence.test.ts +3 -0
- package/src/__tests__/init-feature-flag-overrides.test.ts +5 -6
- package/src/__tests__/injector-chain.test.ts +2 -0
- package/src/__tests__/injector-document-comments.test.ts +378 -0
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +4 -25
- package/src/__tests__/list-messages-attachments.test.ts +21 -17
- package/src/__tests__/list-messages-hidden-metadata.test.ts +217 -0
- package/src/__tests__/list-messages-page-latest.test.ts +130 -14
- package/src/__tests__/list-messages-tool-merge.test.ts +77 -17
- package/src/__tests__/llm-context-normalization.test.ts +0 -2
- package/src/__tests__/llm-request-log-call-site.test.ts +136 -0
- package/src/__tests__/llm-request-log-source-clickhouse.test.ts +26 -0
- package/src/__tests__/llm-resolver.test.ts +161 -9
- package/src/__tests__/llm-usage-store.test.ts +66 -0
- package/src/__tests__/log-export-routes.test.ts +99 -2
- package/src/__tests__/logger.test.ts +89 -0
- package/src/__tests__/mcp-abort-signal.test.ts +2 -2
- package/src/__tests__/media-generate-image.test.ts +31 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +7 -7
- package/src/__tests__/message-queue-steer.test.ts +114 -0
- package/src/__tests__/model-intents.test.ts +2 -4
- package/src/__tests__/notification-guardian-path.test.ts +0 -1
- package/src/__tests__/onboarding-template-contract.test.ts +1 -1
- package/src/__tests__/openai-provider.test.ts +151 -0
- package/src/__tests__/openai-responses-provider.test.ts +118 -16
- package/src/__tests__/outbound-slack-persistence.test.ts +187 -20
- package/src/__tests__/pending-interactions-resolved-event.test.ts +189 -0
- package/src/__tests__/platform-bash-auto-approve.test.ts +2 -2
- package/src/__tests__/platform.test.ts +2 -5
- package/src/__tests__/plugin-api-tool-definition.test.ts +92 -0
- package/src/__tests__/plugin-bootstrap.test.ts +2 -2
- package/src/__tests__/plugin-source-watcher.test.ts +302 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +13 -6
- package/src/__tests__/plugin-types.test.ts +3 -2
- package/src/__tests__/prechat-onboarding-contract.test.ts +131 -98
- package/src/__tests__/pricing.test.ts +12 -0
- package/src/__tests__/process-message-background-slack.test.ts +1 -51
- package/src/__tests__/process-message-display-content.test.ts +21 -16
- package/src/__tests__/prune-jobs-changes-parser.test.ts +61 -0
- package/src/__tests__/registry.test.ts +2 -8
- package/src/__tests__/require-fresh-approval.test.ts +2 -2
- package/src/__tests__/runtime-events-sse-bilingual.test.ts +154 -0
- package/src/__tests__/server-history-render.test.ts +83 -4
- package/src/__tests__/shell-tool-proxy-mode.test.ts +1 -1
- package/src/__tests__/skill-feature-flags.test.ts +2 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +4 -7
- package/src/__tests__/skill-projection.benchmark.test.ts +2 -6
- package/src/__tests__/skill-tool-factory.test.ts +1 -1
- package/src/__tests__/steer-tool-repair.test.ts +249 -0
- package/src/__tests__/subagent-notify-parent.test.ts +1 -1
- package/src/__tests__/suggestion-routes.test.ts +1 -0
- package/src/__tests__/sync-message-contract.test.ts +59 -0
- package/src/__tests__/system-prompt.test.ts +161 -124
- package/src/__tests__/terminal-tools.test.ts +12 -2
- package/src/__tests__/thinking-block-replay.test.ts +113 -0
- package/src/__tests__/thread-backfill.test.ts +370 -22
- package/src/__tests__/tool-approval-handler.test.ts +1 -5
- package/src/__tests__/tool-execute-pipeline.test.ts +2 -2
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +2 -5
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +15 -5
- package/src/__tests__/tool-executor.test.ts +89 -53
- package/src/__tests__/tool-grant-request-escalation.test.ts +1 -6
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +167 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +0 -1
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +1 -6
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -1
- package/src/__tests__/twilio-routes.test.ts +1 -1
- package/src/__tests__/ui-file-upload-surface.test.ts +2 -2
- package/src/__tests__/usage-routes.test.ts +3 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -2
- package/src/__tests__/web-fetch.test.ts +2 -2
- package/src/__tests__/workspace-git-service.test.ts +94 -10
- package/src/__tests__/workspace-migration-088-deprecate-background-conversation-override.test.ts +158 -0
- package/src/__tests__/workspace-migration-089-move-memory-tree-out-of-v3.test.ts +86 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +146 -0
- package/src/acp/prepare-agent-env.ts +78 -0
- package/src/acp/session-manager.ts +1 -1
- package/src/agent/attachments.ts +1 -0
- package/src/agent/loop.ts +65 -20
- package/src/api/README.md +5 -0
- package/src/api/index.ts +4 -0
- package/src/api/package.json +10 -0
- package/src/background-wake/background-wake-routes.test.ts +233 -0
- package/src/background-wake/next-wake.test.ts +289 -0
- package/src/background-wake/next-wake.ts +172 -0
- package/src/background-wake/runtime-registry.ts +24 -0
- package/src/browser/operations.ts +15 -0
- package/src/cli/commands/__tests__/browser.test.ts +23 -5
- package/src/cli/commands/__tests__/conversations-slack.test.ts +572 -0
- package/src/cli/commands/__tests__/domain-register.test.ts +110 -0
- package/src/cli/commands/__tests__/domain-status.test.ts +33 -33
- package/src/cli/commands/__tests__/inference-send.test.ts +108 -5
- package/src/cli/commands/__tests__/memory-v2-compare-render.test.ts +98 -0
- package/src/cli/commands/__tests__/memory-v2.test.ts +10 -12
- package/src/cli/commands/__tests__/memory-v3-render.test.ts +340 -0
- package/src/cli/commands/browser.ts +247 -0
- package/src/cli/commands/conversations.ts +128 -1
- package/src/cli/commands/domain.ts +91 -41
- package/src/cli/commands/inference-providers.ts +147 -1
- package/src/cli/commands/inference.ts +93 -40
- package/src/cli/commands/memory-v2-compare-render.ts +115 -0
- package/src/cli/commands/memory-v2.ts +483 -0
- package/src/cli/commands/memory-v3-render.ts +344 -0
- package/src/cli/commands/memory-v3.ts +316 -0
- package/src/cli/commands/notifications.ts +24 -2
- package/src/cli/program.ts +2 -0
- package/src/cli/utils/conversation-id.ts +17 -5
- package/src/config/assistant-feature-flags.ts +21 -9
- package/src/config/bundled-skills/app-builder/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/SKILL.md +124 -0
- package/src/config/bundled-skills/document-editor/TOOLS.json +258 -0
- package/src/config/bundled-skills/document-editor/tools/comment-list.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-reply.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/comment-resolve.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-find.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-open.ts +12 -0
- package/src/config/bundled-skills/document-editor/tools/document-replace-text.ts +12 -0
- package/src/config/bundled-skills/image-studio/SKILL.md +4 -0
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +2 -2
- package/src/config/bundled-skills/media-processing/SKILL.md +8 -0
- package/src/config/bundled-skills/media-processing/tools/ingest-media.ts +13 -8
- package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +10 -3
- package/src/config/bundled-skills/phone-calls/references/TRANSCRIPTS.md +16 -14
- package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +7 -2
- package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +7 -2
- package/src/config/bundled-skills/schedule/SKILL.md +8 -0
- package/src/config/bundled-tool-registry.ts +24 -12
- package/src/config/call-site-defaults.ts +20 -0
- package/src/config/feature-flag-registry.json +115 -3
- package/src/config/llm-resolver.ts +16 -2
- package/src/config/schemas/__tests__/memory-v2.test.ts +217 -1
- package/src/config/schemas/call-site-catalog.ts +35 -0
- package/src/config/schemas/llm.ts +14 -0
- package/src/config/schemas/memory-v2.ts +294 -1
- package/src/config/schemas/memory.ts +2 -1
- package/src/context/compactor.ts +60 -1
- package/src/context/token-estimator.ts +47 -4
- package/src/context/window-manager.ts +25 -0
- package/src/conversations/__tests__/message-consolidation.test.ts +350 -0
- package/src/conversations/message-consolidation.ts +404 -0
- package/src/credential-health/credential-health-service.ts +34 -19
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +1 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +66 -6
- package/src/daemon/__tests__/meet-manifest-loader.test.ts +1 -1
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +357 -0
- package/src/daemon/__tests__/web-search-status-text.test.ts +287 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +155 -36
- package/src/daemon/conversation-agent-loop.ts +307 -88
- package/src/daemon/conversation-error.ts +31 -1
- package/src/daemon/conversation-lifecycle.ts +149 -118
- package/src/daemon/conversation-messaging.ts +3 -0
- package/src/daemon/conversation-process.ts +273 -0
- package/src/daemon/conversation-queue-manager.ts +14 -0
- package/src/daemon/conversation-runtime-assembly.ts +145 -84
- package/src/daemon/conversation-slash.ts +37 -5
- package/src/daemon/conversation-surfaces.ts +45 -2
- package/src/daemon/conversation-tool-setup.ts +70 -3
- package/src/daemon/conversation-usage.ts +2 -0
- package/src/daemon/conversation.ts +54 -32
- package/src/daemon/disk-pressure-guard.ts +14 -2
- package/src/daemon/first-greeting.ts +10 -0
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +498 -0
- package/src/daemon/handlers/config-a2a.ts +160 -0
- package/src/daemon/handlers/config-model.test.ts +2 -0
- package/src/daemon/handlers/conversations.ts +90 -3
- package/src/daemon/handlers/shared.ts +92 -29
- package/src/daemon/host-bash-proxy.ts +1 -1
- package/src/daemon/host-browser-proxy.ts +5 -5
- package/src/daemon/host-cu-proxy.ts +5 -5
- package/src/daemon/host-file-proxy.ts +5 -5
- package/src/daemon/host-proxy-base.ts +4 -4
- package/src/daemon/host-transfer-proxy.ts +11 -11
- package/src/daemon/lifecycle.ts +40 -23
- package/src/daemon/meet-manifest-loader.ts +1 -7
- package/src/daemon/message-protocol.ts +4 -0
- package/src/daemon/message-types/conversations.ts +14 -9
- package/src/daemon/message-types/document-comments.ts +50 -0
- package/src/daemon/message-types/home.ts +1 -13
- package/src/daemon/message-types/messages.ts +66 -7
- package/src/daemon/message-types/surfaces.ts +3 -1
- package/src/daemon/message-types/sync.ts +14 -0
- package/src/daemon/message-types/web-activity.ts +57 -0
- package/src/daemon/plugin-source-watcher.ts +135 -3
- package/src/daemon/process-message.ts +69 -12
- package/src/daemon/shutdown-handlers.ts +24 -5
- package/src/daemon/switch-inference-profile-tool.ts +52 -0
- package/src/daemon/tool-setup-types.ts +13 -0
- package/src/daemon/trust-context.ts +6 -0
- package/src/documents/document-comments-store.test.ts +338 -0
- package/src/documents/document-comments-store.ts +237 -0
- package/src/documents/document-store.ts +202 -0
- package/src/events/relationship-state-updated.ts +25 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +1 -2
- package/src/heartbeat/heartbeat-service.ts +1 -0
- package/src/home/__tests__/suggested-prompts.test.ts +33 -2
- package/src/home/feed-types.ts +6 -1
- package/src/home/home-content-refresh.ts +52 -0
- package/src/home/home-greeting-cache.ts +69 -0
- package/src/home/home-greeting.ts +85 -0
- package/src/home/suggested-prompts.ts +168 -9
- package/src/ipc/gateway-flag-listener.ts +123 -0
- package/src/ipc/skill-routes/registries.ts +8 -12
- package/src/memory/__tests__/db-async-query.test.ts +165 -0
- package/src/memory/__tests__/db-maintenance.test.ts +115 -0
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +241 -0
- package/src/memory/__tests__/jobs-store-job-classes.test.ts +28 -1
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +135 -2
- package/src/memory/__tests__/memory-retrospective-job.test.ts +327 -6
- package/src/memory/auto-analysis-enqueue.ts +5 -1
- package/src/memory/conversation-crud.ts +191 -100
- package/src/memory/conversation-starters-cadence.ts +3 -1
- package/src/memory/conversation-title-service.ts +19 -3
- package/src/memory/db-async-query.ts +214 -0
- package/src/memory/db-init.ts +26 -0
- package/src/memory/db-maintenance.ts +30 -21
- package/src/memory/delivery-crud.ts +41 -0
- package/src/memory/delivery-status.ts +141 -15
- package/src/memory/external-conversation-store.ts +32 -1
- package/src/memory/graph/bootstrap.ts +8 -1
- package/src/memory/graph/capability-seed.ts +7 -3
- package/src/memory/graph/conversation-graph-memory.ts +100 -17
- package/src/memory/graph/extraction.ts +1 -5
- package/src/memory/graph/graph-search.ts +7 -1
- package/src/memory/indexer.ts +28 -18
- package/src/memory/job-handlers/cleanup.ts +76 -18
- package/src/memory/job-handlers/conversation-starters.ts +1 -4
- package/src/memory/jobs/embed-pkb-file.ts +6 -1
- package/src/memory/jobs-store.ts +14 -0
- package/src/memory/jobs-worker.ts +68 -15
- package/src/memory/llm-request-log-source-clickhouse.ts +42 -2
- package/src/memory/llm-request-log-source-local.ts +7 -0
- package/src/memory/llm-request-log-source.ts +9 -2
- package/src/memory/llm-request-log-store.ts +43 -1
- package/src/memory/llm-usage-store.ts +24 -0
- package/src/memory/memory-retrospective-constants.ts +28 -0
- package/src/memory/memory-retrospective-enqueue.ts +11 -3
- package/src/memory/memory-retrospective-job.ts +413 -18
- package/src/memory/memory-retrospective-startup-cleanup.ts +3 -3
- package/src/memory/memory-v2-activation-log-store.ts +41 -14
- package/src/memory/migrations/100-core-tables.ts +1 -0
- package/src/memory/migrations/109-external-conversation-bindings.ts +1 -0
- package/src/memory/migrations/253-conversation-last-notified-profile.ts +15 -0
- package/src/memory/migrations/253-document-comments.ts +47 -0
- package/src/memory/migrations/254-external-conversation-binding-chat-name.ts +43 -0
- package/src/memory/migrations/255-channel-inbound-delivery-attempts.ts +24 -0
- package/src/memory/migrations/256-memory-v2-injection-events.ts +113 -0
- package/src/memory/migrations/257-strip-base-url-non-openai-compatible.ts +22 -0
- package/src/memory/migrations/258-onboarding-events-prior-assistants.ts +13 -0
- package/src/memory/migrations/259-conversation-cleaned-at.ts +33 -0
- package/src/memory/migrations/260-rename-cleaned-at.ts +44 -0
- package/src/memory/migrations/261-llm-usage-add-raw-usage.ts +36 -0
- package/src/memory/migrations/262-memory-v3-coactivation.ts +57 -0
- package/src/memory/migrations/263-memory-v3-auto-edges.ts +50 -0
- package/src/memory/migrations/264-llm-request-log-call-site.ts +29 -0
- package/src/memory/migrations/index.ts +34 -0
- package/src/memory/migrations/registry.ts +58 -0
- package/src/memory/onboarding-events-store.ts +7 -0
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/conversations.ts +3 -0
- package/src/memory/schema/infrastructure.ts +22 -0
- package/src/memory/tool-usage-store.ts +36 -8
- package/src/memory/v2/__tests__/consolidation-job.test.ts +1 -0
- package/src/memory/v2/__tests__/harness-compare.test.ts +186 -0
- package/src/memory/v2/__tests__/harness-metrics.test.ts +74 -0
- package/src/memory/v2/__tests__/harness-oracle.test.ts +257 -0
- package/src/memory/v2/__tests__/harness-replay-input.test.ts +225 -0
- package/src/memory/v2/__tests__/harness-runner.test.ts +109 -0
- package/src/memory/v2/__tests__/injection-events.test.ts +318 -0
- package/src/memory/v2/__tests__/injection.test.ts +158 -112
- package/src/memory/v2/__tests__/page-index.test.ts +365 -1
- package/src/memory/v2/__tests__/qdrant.test.ts +36 -0
- package/src/memory/v2/__tests__/router.test.ts +660 -4
- package/src/memory/v2/consolidation-job.ts +14 -0
- package/src/memory/v2/harness/compare.ts +57 -0
- package/src/memory/v2/harness/metrics.ts +124 -0
- package/src/memory/v2/harness/oracle.ts +145 -0
- package/src/memory/v2/harness/replay-input.ts +224 -0
- package/src/memory/v2/harness/retriever.ts +74 -0
- package/src/memory/v2/harness/router-retriever.ts +43 -0
- package/src/memory/v2/harness/runner.ts +106 -0
- package/src/memory/v2/harness/trace.ts +58 -0
- package/src/memory/v2/injection-events.ts +101 -0
- package/src/memory/v2/injection.ts +42 -25
- package/src/memory/v2/page-index.ts +209 -7
- package/src/memory/v2/page-store.ts +18 -0
- package/src/memory/v2/prompts/router.ts +26 -1
- package/src/memory/v2/qdrant.ts +14 -2
- package/src/memory/v2/router.ts +369 -62
- package/src/memory/v3/__tests__/coactivation-store.test.ts +422 -0
- package/src/memory/v3/__tests__/consolidation-job.test.ts +468 -0
- package/src/memory/v3/__tests__/edge-learning-job.test.ts +324 -0
- package/src/memory/v3/__tests__/edges.test.ts +563 -0
- package/src/memory/v3/__tests__/filter.test.ts +512 -0
- package/src/memory/v3/__tests__/gate.test.ts +574 -0
- package/src/memory/v3/__tests__/index-composition.test.ts +233 -0
- package/src/memory/v3/__tests__/loop.test.ts +530 -0
- package/src/memory/v3/__tests__/retriever.test.ts +226 -0
- package/src/memory/v3/__tests__/scouts.test.ts +440 -0
- package/src/memory/v3/__tests__/shadow-middleware.test.ts +312 -0
- package/src/memory/v3/__tests__/system-prompts.test.ts +154 -0
- package/src/memory/v3/__tests__/traversal.test.ts +469 -0
- package/src/memory/v3/__tests__/tree-index.test.ts +280 -0
- package/src/memory/v3/__tests__/tree-store.test.ts +529 -0
- package/src/memory/v3/__tests__/tree-walk.test.ts +707 -0
- package/src/memory/v3/__tests__/validate.test.ts +245 -0
- package/src/memory/v3/auto-edges.ts +223 -0
- package/src/memory/v3/coactivation-store.ts +124 -0
- package/src/memory/v3/consolidation-job.ts +323 -0
- package/src/memory/v3/edge-learning-job.ts +160 -0
- package/src/memory/v3/edges.ts +249 -0
- package/src/memory/v3/filter.ts +281 -0
- package/src/memory/v3/gate.ts +334 -0
- package/src/memory/v3/index-composition.ts +113 -0
- package/src/memory/v3/llm-capture.ts +46 -0
- package/src/memory/v3/loop.ts +382 -0
- package/src/memory/v3/maintenance.ts +144 -0
- package/src/memory/v3/prompt-context.ts +33 -0
- package/src/memory/v3/prompts/consolidation.ts +458 -0
- package/src/memory/v3/prompts/system-prompts.ts +196 -0
- package/src/memory/v3/retriever.ts +33 -0
- package/src/memory/v3/scouts.ts +420 -0
- package/src/memory/v3/shadow-middleware.ts +305 -0
- package/src/memory/v3/traversal.ts +206 -0
- package/src/memory/v3/tree-index.ts +237 -0
- package/src/memory/v3/tree-store.ts +394 -0
- package/src/memory/v3/tree-walk.ts +351 -0
- package/src/memory/v3/types.ts +65 -0
- package/src/memory/v3/validate.ts +300 -0
- package/src/messaging/providers/index.ts +7 -1
- package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +329 -3
- package/src/messaging/providers/slack/__tests__/adapter-token-routing.test.ts +34 -1
- package/src/messaging/providers/slack/adapter.ts +178 -25
- package/src/messaging/providers/slack/api.test.ts +54 -0
- package/src/messaging/providers/slack/api.ts +119 -3
- package/src/messaging/providers/slack/client.ts +12 -0
- package/src/messaging/providers/slack/deep-link.ts +20 -1
- package/src/messaging/providers/slack/message-metadata.test.ts +48 -0
- package/src/messaging/providers/slack/message-metadata.ts +156 -0
- package/src/messaging/providers/slack/render-transcript.test.ts +107 -75
- package/src/messaging/providers/slack/render-transcript.ts +176 -49
- package/src/messaging/providers/slack/send.test.ts +77 -0
- package/src/messaging/providers/slack/send.ts +8 -2
- package/src/messaging/providers/slack/types.ts +14 -0
- package/src/notifications/__tests__/emit-signal-home-feed.test.ts +4 -1
- package/src/notifications/__tests__/home-feed-side-effect.test.ts +116 -54
- package/src/notifications/adapters/macos.ts +18 -1
- package/src/notifications/adapters/platform.ts +1 -1
- package/src/notifications/conversation-seed-composer.ts +14 -2
- package/src/notifications/decision-engine.ts +1 -4
- package/src/notifications/deferred-emit.ts +135 -0
- package/src/notifications/emit-signal.ts +38 -50
- package/src/notifications/home-feed-side-effect.ts +60 -30
- package/src/oauth/connect-orchestrator.ts +3 -0
- package/src/oauth/credential-token-resolver.ts +2 -0
- package/src/oauth/manual-token-connection.ts +19 -0
- package/src/oauth/oauth-store.ts +12 -0
- package/src/oauth/seed-providers.ts +22 -0
- package/src/permissions/prompter.ts +8 -5
- package/src/permissions/question-prompter.ts +5 -2
- package/src/permissions/secret-prompter.ts +6 -3
- package/src/plugin-api/index.ts +4 -0
- package/src/plugin-api/types.ts +7 -33
- package/src/plugins/defaults/index.ts +6 -0
- package/src/plugins/defaults/injectors.ts +100 -20
- package/src/plugins/external-plugin-loader.ts +5 -68
- package/src/plugins/types.ts +11 -16
- package/src/proactive-artifact/aux-message-injector.ts +17 -4
- package/src/prompts/__tests__/system-prompt.test.ts +46 -2
- package/src/prompts/__tests__/task-progress-hint-section.test.ts +3 -9
- package/src/prompts/normalize-onboarding.ts +40 -0
- package/src/prompts/persona-resolver.ts +36 -21
- package/src/prompts/sections.ts +69 -19
- package/src/prompts/system-prompt.ts +118 -216
- package/src/prompts/template-detection.ts +37 -0
- package/src/prompts/templates/BOOTSTRAP-CONTENT-AUTOMATION.md +141 -0
- package/src/prompts/templates/BOOTSTRAP.md +10 -2
- package/src/prompts/templates/VOICE.md +3 -0
- package/src/prompts/templates/system-sections.ts +281 -9
- package/src/providers/__tests__/connection-model-compat.test.ts +234 -0
- package/src/providers/__tests__/retry-callsite.test.ts +85 -5
- package/src/providers/anthropic/client.ts +159 -66
- package/src/providers/call-site-routing.ts +14 -2
- package/src/providers/connection-model-compat.ts +38 -0
- package/src/providers/connection-resolution.ts +16 -2
- package/src/providers/fireworks/client.ts +20 -2
- package/src/providers/gemini/client.ts +49 -6
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +342 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +189 -0
- package/src/providers/inference/__tests__/codex-token-refresh.test.ts +254 -0
- package/src/providers/inference/adapter-factory.ts +18 -1
- package/src/providers/inference/auth.ts +3 -3
- package/src/providers/inference/codex-token-refresh.ts +128 -0
- package/src/providers/inference/resolve-auth.ts +49 -6
- package/src/providers/minimax/client.ts +106 -0
- package/src/providers/model-catalog.ts +91 -1
- package/src/providers/model-intents.ts +1 -1
- package/src/providers/openai/chat-completions-provider.ts +63 -23
- package/src/providers/openai/codex-models.ts +18 -0
- package/src/providers/openai/responses-provider.ts +86 -23
- package/src/providers/openrouter/client.ts +5 -1
- package/src/providers/provider-send-message.ts +7 -1
- package/src/providers/retry.ts +34 -3
- package/src/providers/thinking-config.ts +26 -1
- package/src/providers/types.ts +25 -0
- package/src/providers/usage-tracking.ts +2 -0
- package/src/runtime/AGENTS.md +2 -2
- package/src/runtime/__tests__/agent-wake.test.ts +214 -0
- package/src/runtime/__tests__/background-job-runner.test.ts +128 -0
- package/src/runtime/agent-wake.ts +152 -56
- package/src/runtime/assistant-event-hub.ts +76 -6
- package/src/runtime/auth/route-policy.ts +43 -3
- package/src/runtime/background-job-runner.ts +26 -0
- package/src/runtime/btw-sidechain.ts +0 -6
- package/src/runtime/channel-reply-delivery.ts +182 -47
- package/src/runtime/channel-retry-sweep.ts +141 -16
- package/src/runtime/http-types.ts +7 -6
- package/src/runtime/migrations/vbundle-builder.ts +10 -3
- package/src/runtime/pending-interactions.ts +50 -8
- package/src/runtime/routes/__tests__/content-source-routes.test.ts +162 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +161 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +14 -0
- package/src/runtime/routes/__tests__/memory-v2-simulate-route.test.ts +290 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +512 -0
- package/src/runtime/routes/__tests__/sanity-routes.test.ts +280 -0
- package/src/runtime/routes/__tests__/slack-channel-routes.test.ts +266 -0
- package/src/runtime/routes/acp-routes.test.ts +255 -6
- package/src/runtime/routes/acp-routes.ts +8 -1
- package/src/runtime/routes/approval-routes.ts +4 -1
- package/src/runtime/routes/avatar-routes.ts +10 -10
- package/src/runtime/routes/background-wake-routes.ts +188 -0
- package/src/runtime/routes/browser-tabs-routes.ts +200 -0
- package/src/runtime/routes/btw-routes.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +246 -0
- package/src/runtime/routes/content-source-routes.ts +78 -0
- package/src/runtime/routes/conversation-cli-routes.ts +147 -2
- package/src/runtime/routes/conversation-list-routes.ts +12 -4
- package/src/runtime/routes/conversation-management-routes.ts +77 -20
- package/src/runtime/routes/conversation-query-routes.ts +196 -31
- package/src/runtime/routes/conversation-routes.ts +472 -425
- package/src/runtime/routes/conversation-starter-routes.ts +6 -3
- package/src/runtime/routes/disk-pressure-routes.ts +1 -1
- package/src/runtime/routes/document-comments-routes.ts +287 -0
- package/src/runtime/routes/documents-routes.ts +33 -0
- package/src/runtime/routes/domain-routes.ts +60 -10
- package/src/runtime/routes/email-routes.ts +5 -2
- package/src/runtime/routes/events-routes.ts +54 -10
- package/src/runtime/routes/group-routes.ts +24 -8
- package/src/runtime/routes/home-feed-routes.ts +6 -3
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-browser-routes.ts +17 -2
- package/src/runtime/routes/host-cu-routes.ts +2 -2
- package/src/runtime/routes/identity-routes.ts +21 -0
- package/src/runtime/routes/inbound-message-handler.ts +288 -58
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +96 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +365 -6
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +283 -82
- package/src/runtime/routes/index.ts +20 -4
- package/src/runtime/routes/inference-profile-session-handler.ts +22 -12
- package/src/runtime/routes/inference-profile-session-routes.ts +7 -1
- package/src/runtime/routes/inference-provider-connection-routes.ts +63 -7
- package/src/runtime/routes/integrations/a2a.ts +60 -1
- package/src/runtime/routes/llm-call-sites-routes.ts +32 -5
- package/src/runtime/routes/log-export-routes.ts +39 -0
- package/src/runtime/routes/memory-item-routes.ts +8 -3
- package/src/runtime/routes/memory-v2-routes.ts +427 -0
- package/src/runtime/routes/memory-v3-routes.ts +316 -0
- package/src/runtime/routes/migration-routes.ts +21 -24
- package/src/runtime/routes/notification-routes.ts +19 -2
- package/src/runtime/routes/plugins-routes.ts +337 -0
- package/src/runtime/routes/question-routes.ts +4 -1
- package/src/runtime/routes/rename-conversation-routes.ts +6 -2
- package/src/runtime/routes/sanity-routes.ts +159 -0
- package/src/runtime/routes/secret-routes.ts +25 -5
- package/src/runtime/routes/settings-routes.ts +12 -11
- package/src/runtime/routes/slack-channel-routes.ts +188 -0
- package/src/runtime/routes/workspace-routes.ts +25 -10
- package/src/runtime/services/conversation-serializer.ts +30 -4
- package/src/runtime/sync/resource-sync-events.ts +106 -38
- package/src/runtime/sync/sync-publisher.test.ts +49 -0
- package/src/runtime/sync/sync-publisher.ts +2 -1
- package/src/runtime/verification-outbound-actions.ts +73 -1
- package/src/schedule/integration-status.ts +3 -1
- package/src/security/__tests__/oauth2-device-code.test.ts +479 -0
- package/src/security/oauth2-device-code.ts +307 -0
- package/src/security/oauth2.ts +26 -9
- package/src/security/secure-keys.ts +5 -0
- package/src/skills/catalog-install.ts +6 -2
- package/src/telemetry/types.ts +12 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +48 -0
- package/src/telemetry/usage-telemetry-reporter.ts +1 -0
- package/src/tools/acp/spawn.test.ts +119 -0
- package/src/tools/acp/spawn.ts +15 -2
- package/src/tools/apps/definitions.ts +2 -8
- package/src/tools/ask-question/ask-question-tool.test.ts +3 -3
- package/src/tools/ask-question/ask-question-tool.ts +38 -45
- package/src/tools/browser/__tests__/pinned-tabs.test.ts +150 -0
- package/src/tools/browser/browser-execution.ts +106 -0
- package/src/tools/browser/cdp-client/__tests__/browser-tabs-factory.test.ts +402 -0
- package/src/tools/browser/cdp-client/__tests__/factory.test.ts +28 -0
- package/src/tools/browser/cdp-client/__tests__/types.test.ts +4 -0
- package/src/tools/browser/cdp-client/cdp-inspect-client.ts +22 -0
- package/src/tools/browser/cdp-client/extension-cdp-client.ts +42 -2
- package/src/tools/browser/cdp-client/factory.ts +171 -4
- package/src/tools/browser/cdp-client/local-cdp-client.ts +21 -0
- package/src/tools/browser/cdp-client/types.ts +101 -0
- package/src/tools/browser/pinned-tabs.ts +146 -0
- package/src/tools/computer-use/definitions.ts +22 -78
- package/src/tools/credential-execution/make-authenticated-request.ts +3 -9
- package/src/tools/credential-execution/manage-secure-command-tool.ts +3 -9
- package/src/tools/credential-execution/run-authenticated-command.ts +3 -9
- package/src/tools/credentials/vault.ts +3 -9
- package/src/tools/document/document-comment-tool.test.ts +379 -0
- package/src/tools/document/document-comment-tool.ts +156 -0
- package/src/tools/document/document-tool.ts +187 -2
- package/src/tools/execution-target.ts +21 -23
- package/src/tools/executor.ts +6 -1
- package/src/tools/filesystem/edit.ts +3 -9
- package/src/tools/filesystem/list.ts +3 -9
- package/src/tools/filesystem/read.ts +3 -9
- package/src/tools/filesystem/write.ts +3 -9
- package/src/tools/host-filesystem/edit.ts +3 -9
- package/src/tools/host-filesystem/read.ts +3 -9
- package/src/tools/host-filesystem/transfer.ts +3 -9
- package/src/tools/host-filesystem/write.ts +3 -9
- package/src/tools/host-terminal/host-shell.ts +3 -9
- package/src/tools/mcp/mcp-tool-factory.ts +1 -8
- package/src/tools/memory/register.test.ts +1 -1
- package/src/tools/memory/register.ts +4 -9
- package/src/tools/network/__tests__/web-fetch-metadata.test.ts +229 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +346 -0
- package/src/tools/network/domain-normalize.ts +17 -0
- package/src/tools/network/web-fetch.ts +216 -73
- package/src/tools/network/web-search.ts +216 -98
- package/src/tools/registry.ts +7 -23
- package/src/tools/schema-transforms.ts +1 -1
- package/src/tools/skills/execute.ts +3 -9
- package/src/tools/skills/load.ts +3 -9
- package/src/tools/skills/skill-tool-factory.ts +1 -8
- package/src/tools/subagent/notify-parent.ts +3 -9
- package/src/tools/system/request-permission.ts +3 -9
- package/src/tools/terminal/safe-env.ts +3 -2
- package/src/tools/terminal/shell.ts +3 -9
- package/src/tools/tool-approval-handler.ts +19 -12
- package/src/tools/tool-defaults.ts +94 -0
- package/src/tools/types.ts +31 -98
- package/src/tools/ui-surface/definitions.ts +9 -23
- package/src/types/onboarding-context.ts +4 -0
- package/src/usage/pricing.ts +23 -0
- package/src/usage/types.ts +12 -0
- package/src/util/__tests__/favicon.test.ts +84 -0
- package/src/util/favicon.ts +40 -0
- package/src/util/logger.ts +16 -7
- package/src/util/platform.ts +7 -7
- package/src/util/sqlite3-runtime.ts +65 -0
- package/src/workspace/git-service.ts +75 -4
- package/src/workspace/migrations/086-revert-stale-gemini-mis-rewrites.ts +1 -0
- package/src/workspace/migrations/088-deprecate-background-conversation-override.ts +103 -0
- package/src/workspace/migrations/089-move-memory-tree-out-of-v3.ts +86 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/compaction-strip-metadata-clear.test.ts +0 -206
- package/src/__tests__/message-complete-display-id.test.ts +0 -175
- package/src/config/bundled-skills/document/SKILL.md +0 -54
- package/src/config/bundled-skills/document/TOOLS.json +0 -106
- package/src/daemon/seed-files.ts +0 -18
- package/src/prompts/cache-boundary.ts +0 -8
- package/src/runtime/routes/interface-routes.ts +0 -43
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-create.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-delete.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-list.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-read.ts +0 -0
- /package/src/config/bundled-skills/{document → document-editor}/tools/document-update.ts +0 -0
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
unregisterPluginTools,
|
|
60
60
|
} from "../tools/registry.js";
|
|
61
61
|
import type {
|
|
62
|
-
|
|
62
|
+
LoadedTool,
|
|
63
63
|
ToolContext,
|
|
64
64
|
ToolExecutionResult,
|
|
65
65
|
} from "../tools/types.js";
|
|
@@ -81,12 +81,13 @@ const fakeCtx: DaemonContext = {
|
|
|
81
81
|
|
|
82
82
|
function makeFakeTool(
|
|
83
83
|
name: string,
|
|
84
|
-
extras: Partial<
|
|
85
|
-
):
|
|
84
|
+
extras: Partial<LoadedTool> = {},
|
|
85
|
+
): LoadedTool {
|
|
86
86
|
return {
|
|
87
87
|
name,
|
|
88
88
|
description: `Fake ${name}`,
|
|
89
89
|
defaultRiskLevel: RiskLevel.Low,
|
|
90
|
+
executionTarget: "sandbox",
|
|
90
91
|
input_schema: { type: "object", properties: {}, required: [] },
|
|
91
92
|
async execute(
|
|
92
93
|
_input: Record<string, unknown>,
|
|
@@ -281,7 +282,7 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
|
|
|
281
282
|
expect(alias).toMatch(/^[a-zA-Z0-9_-]{1,64}$/);
|
|
282
283
|
expect(alias.startsWith("Stripe_Link_CLI__")).toBe(true);
|
|
283
284
|
expect(getTool(alias)).toBeDefined();
|
|
284
|
-
expect(accepted[0]!.
|
|
285
|
+
expect(accepted[0]!.name).toBe(alias);
|
|
285
286
|
|
|
286
287
|
await accepted[0]!.execute(
|
|
287
288
|
{},
|
|
@@ -320,12 +321,18 @@ describe("registerPluginTools / unregisterPluginTools helpers", () => {
|
|
|
320
321
|
// ownerMcpServerId / ownerSkillBundled / ownerSkillVersionHash) so the
|
|
321
322
|
// stamped tool cannot leak across namespaces or spoof bundled-skill
|
|
322
323
|
// auto-allow.
|
|
323
|
-
|
|
324
|
+
//
|
|
325
|
+
// The narrow `ToolDefinition` shape doesn't expose these ownership
|
|
326
|
+
// fields, so the cast through `unknown` simulates a hostile or
|
|
327
|
+
// transpiled artifact that arrives with spoofed fields baked in —
|
|
328
|
+
// the bootstrap-side defense is the second layer that must hold.
|
|
329
|
+
const spoofed = {
|
|
330
|
+
...makeFakeTool("pt_spoof"),
|
|
324
331
|
origin: "skill",
|
|
325
332
|
ownerSkillId: "some-other-skill",
|
|
326
333
|
ownerSkillBundled: true,
|
|
327
334
|
ownerSkillVersionHash: "deadbeef",
|
|
328
|
-
}
|
|
335
|
+
} as unknown as LoadedTool;
|
|
329
336
|
registerPluginTools("my-plugin", [spoofed]);
|
|
330
337
|
const retrieved = getTool("pt_spoof");
|
|
331
338
|
expect(retrieved?.origin).toBe("plugin");
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
type ToolResultTruncateResult,
|
|
47
47
|
type TurnContext,
|
|
48
48
|
} from "../plugins/types.js";
|
|
49
|
-
import type {
|
|
49
|
+
import type { LoadedTool } from "../tools/types.js";
|
|
50
50
|
|
|
51
51
|
const sampleTrust: TrustContext = {
|
|
52
52
|
sourceChannel: "vellum",
|
|
@@ -207,10 +207,11 @@ describe("plugin core types", () => {
|
|
|
207
207
|
},
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
-
const sampleTool:
|
|
210
|
+
const sampleTool: LoadedTool = {
|
|
211
211
|
name: "sample-tool",
|
|
212
212
|
description: "Sample plugin tool",
|
|
213
213
|
defaultRiskLevel: RiskLevel.Low,
|
|
214
|
+
executionTarget: "sandbox",
|
|
214
215
|
input_schema: { type: "object", properties: {}, required: [] },
|
|
215
216
|
async execute() {
|
|
216
217
|
return { content: "ok", isError: false };
|
|
@@ -61,22 +61,43 @@ mock.module("../prompts/user-reference.js", () => ({
|
|
|
61
61
|
resolveUserPronouns: () => null,
|
|
62
62
|
}));
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// Stub persona-resolver so tests can dictate the slug `buildSystemPrompt`
|
|
65
|
+
// sees without writing contact rows to the test DB. User and channel
|
|
66
|
+
// persona content now flows through bundled sections that read files
|
|
67
|
+
// directly, so tests write the persona file under TEST_DIR rather than
|
|
68
|
+
// stubbing the content here.
|
|
69
|
+
const mockPersona: {
|
|
70
|
+
userSlug: string | null;
|
|
71
|
+
guardianPersona: string | null;
|
|
72
|
+
} = { userSlug: null, guardianPersona: null };
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
74
|
+
const realPersonaResolver = require("../prompts/persona-resolver.js");
|
|
75
|
+
mock.module("../prompts/persona-resolver.js", () => ({
|
|
76
|
+
...realPersonaResolver,
|
|
77
|
+
resolveUserSlug: () => mockPersona.userSlug,
|
|
78
|
+
resolveGuardianPersona: () => mockPersona.guardianPersona,
|
|
79
|
+
}));
|
|
80
|
+
|
|
81
|
+
const { buildSystemPrompt } = await import("../prompts/system-prompt.js");
|
|
66
82
|
|
|
67
83
|
/**
|
|
68
|
-
*
|
|
84
|
+
* Slice the assembled system prompt from the `# First-Run Ritual`
|
|
85
|
+
* marker through the end of the prompt, returning just the
|
|
86
|
+
* `13-bootstrap` section's rendered payload. Returns "" when the
|
|
87
|
+
* section isn't rendered (no BOOTSTRAP.md, `excludeBootstrap: true`,
|
|
88
|
+
* etc.).
|
|
69
89
|
*/
|
|
70
|
-
function
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
: result;
|
|
90
|
+
function bootstrapBlock(result: string): string {
|
|
91
|
+
const ritualIdx = result.indexOf("# First-Run Ritual");
|
|
92
|
+
if (ritualIdx < 0) return "";
|
|
93
|
+
return result.slice(ritualIdx);
|
|
75
94
|
}
|
|
76
95
|
|
|
77
96
|
describe("pre-chat onboarding contract", () => {
|
|
78
97
|
beforeEach(() => {
|
|
79
98
|
mkdirSync(TEST_DIR, { recursive: true });
|
|
99
|
+
mockPersona.userSlug = null;
|
|
100
|
+
mockPersona.guardianPersona = null;
|
|
80
101
|
});
|
|
81
102
|
|
|
82
103
|
afterEach(() => {
|
|
@@ -87,6 +108,8 @@ describe("pre-chat onboarding contract", () => {
|
|
|
87
108
|
"BOOTSTRAP.md",
|
|
88
109
|
"BOOTSTRAP-REFERENCE.md",
|
|
89
110
|
"UPDATES.md",
|
|
111
|
+
"users",
|
|
112
|
+
"channels",
|
|
90
113
|
]) {
|
|
91
114
|
const p = join(TEST_DIR, name);
|
|
92
115
|
if (existsSync(p)) rmSync(p, { recursive: true, force: true });
|
|
@@ -151,20 +174,20 @@ describe("pre-chat onboarding contract", () => {
|
|
|
151
174
|
};
|
|
152
175
|
|
|
153
176
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
154
|
-
const
|
|
177
|
+
const bootstrap = bootstrapBlock(result);
|
|
155
178
|
|
|
156
|
-
expect(
|
|
157
|
-
expect(
|
|
179
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
180
|
+
expect(bootstrap).toContain(
|
|
158
181
|
"The user completed setup before this conversation.",
|
|
159
182
|
);
|
|
160
|
-
expect(
|
|
161
|
-
expect(
|
|
162
|
-
expect(
|
|
163
|
-
expect(
|
|
164
|
-
expect(
|
|
183
|
+
expect(bootstrap).toContain("- Daily tools: Slack, Linear");
|
|
184
|
+
expect(bootstrap).toContain("- Common work: builds code, apps, or tools");
|
|
185
|
+
expect(bootstrap).toContain("- Name: Alex");
|
|
186
|
+
expect(bootstrap).toContain("- Chosen assistant name: Nova");
|
|
187
|
+
expect(bootstrap).toContain("Apply this context quietly.");
|
|
165
188
|
|
|
166
189
|
// Raw JSON must NOT be present
|
|
167
|
-
expect(
|
|
190
|
+
expect(bootstrap).not.toContain("```json");
|
|
168
191
|
});
|
|
169
192
|
|
|
170
193
|
test("does NOT inject onboarding context when BOOTSTRAP.md does not exist", () => {
|
|
@@ -177,11 +200,11 @@ describe("pre-chat onboarding contract", () => {
|
|
|
177
200
|
};
|
|
178
201
|
|
|
179
202
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
180
|
-
const
|
|
203
|
+
const bootstrap = bootstrapBlock(result);
|
|
181
204
|
|
|
182
|
-
expect(
|
|
183
|
-
expect(
|
|
184
|
-
expect(
|
|
205
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
206
|
+
expect(bootstrap).not.toContain("First-Run User Context");
|
|
207
|
+
expect(bootstrap).not.toContain("- Daily tools:");
|
|
185
208
|
});
|
|
186
209
|
|
|
187
210
|
test("does NOT inject onboarding context when excludeBootstrap is true", () => {
|
|
@@ -200,10 +223,10 @@ describe("pre-chat onboarding contract", () => {
|
|
|
200
223
|
onboardingContext: context,
|
|
201
224
|
excludeBootstrap: true,
|
|
202
225
|
});
|
|
203
|
-
const
|
|
226
|
+
const bootstrap = bootstrapBlock(result);
|
|
204
227
|
|
|
205
|
-
expect(
|
|
206
|
-
expect(
|
|
228
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
229
|
+
expect(bootstrap).not.toContain("First-Run Ritual");
|
|
207
230
|
});
|
|
208
231
|
|
|
209
232
|
test("omits onboarding section when context is undefined", () => {
|
|
@@ -213,12 +236,12 @@ describe("pre-chat onboarding contract", () => {
|
|
|
213
236
|
);
|
|
214
237
|
|
|
215
238
|
const result = buildSystemPrompt({ onboardingContext: undefined });
|
|
216
|
-
const
|
|
239
|
+
const bootstrap = bootstrapBlock(result);
|
|
217
240
|
|
|
218
241
|
// Bootstrap should still be present
|
|
219
|
-
expect(
|
|
242
|
+
expect(bootstrap).toContain("First-Run Ritual");
|
|
220
243
|
// But no onboarding context section
|
|
221
|
-
expect(
|
|
244
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
222
245
|
});
|
|
223
246
|
|
|
224
247
|
test("accepts all four personality tones", () => {
|
|
@@ -238,10 +261,10 @@ describe("pre-chat onboarding contract", () => {
|
|
|
238
261
|
};
|
|
239
262
|
|
|
240
263
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
241
|
-
const
|
|
264
|
+
const bootstrap = bootstrapBlock(result);
|
|
242
265
|
|
|
243
|
-
expect(
|
|
244
|
-
expect(
|
|
266
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
267
|
+
expect(bootstrap).toContain(`- Preferred initial voice: ${tone}`);
|
|
245
268
|
}
|
|
246
269
|
});
|
|
247
270
|
|
|
@@ -260,20 +283,20 @@ describe("pre-chat onboarding contract", () => {
|
|
|
260
283
|
};
|
|
261
284
|
|
|
262
285
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
263
|
-
const
|
|
286
|
+
const bootstrap = bootstrapBlock(result);
|
|
264
287
|
|
|
265
288
|
// Should contain compact markdown lines
|
|
266
|
-
expect(
|
|
267
|
-
expect(
|
|
268
|
-
expect(
|
|
269
|
-
expect(
|
|
270
|
-
expect(
|
|
271
|
-
expect(
|
|
289
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
290
|
+
expect(bootstrap).toContain("- Name: Jane");
|
|
291
|
+
expect(bootstrap).toContain("- Common work: plans and coordinates work");
|
|
292
|
+
expect(bootstrap).toContain("- Daily tools: Notion");
|
|
293
|
+
expect(bootstrap).toContain("- Chosen assistant name: Kit");
|
|
294
|
+
expect(bootstrap).toContain("- Preferred initial voice: warm");
|
|
272
295
|
|
|
273
296
|
// Must NOT contain JSON output
|
|
274
|
-
expect(
|
|
297
|
+
expect(bootstrap).not.toContain("```json");
|
|
275
298
|
const expectedJson = JSON.stringify(context, null, 2);
|
|
276
|
-
expect(
|
|
299
|
+
expect(bootstrap).not.toContain(expectedJson);
|
|
277
300
|
});
|
|
278
301
|
|
|
279
302
|
test("empty tools/tasks arrays result in no Daily tools / Common work lines", () => {
|
|
@@ -290,12 +313,12 @@ describe("pre-chat onboarding contract", () => {
|
|
|
290
313
|
};
|
|
291
314
|
|
|
292
315
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
293
|
-
const
|
|
316
|
+
const bootstrap = bootstrapBlock(result);
|
|
294
317
|
|
|
295
|
-
expect(
|
|
296
|
-
expect(
|
|
297
|
-
expect(
|
|
298
|
-
expect(
|
|
318
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
319
|
+
expect(bootstrap).toContain("- Name: Alex");
|
|
320
|
+
expect(bootstrap).not.toContain("- Daily tools:");
|
|
321
|
+
expect(bootstrap).not.toContain("- Common work:");
|
|
299
322
|
});
|
|
300
323
|
|
|
301
324
|
test("absent userName results in no Name line", () => {
|
|
@@ -311,16 +334,16 @@ describe("pre-chat onboarding contract", () => {
|
|
|
311
334
|
};
|
|
312
335
|
|
|
313
336
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
314
|
-
const
|
|
337
|
+
const bootstrap = bootstrapBlock(result);
|
|
315
338
|
|
|
316
|
-
expect(
|
|
317
|
-
expect(
|
|
339
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
340
|
+
expect(bootstrap).not.toContain("- Name:");
|
|
318
341
|
// Other fields should still be present
|
|
319
|
-
expect(
|
|
320
|
-
expect(
|
|
342
|
+
expect(bootstrap).toContain("- Daily tools: Slack");
|
|
343
|
+
expect(bootstrap).toContain(
|
|
321
344
|
"- Common work: writes docs, emails, or content",
|
|
322
345
|
);
|
|
323
|
-
expect(
|
|
346
|
+
expect(bootstrap).toContain("- Preferred initial voice: warm");
|
|
324
347
|
});
|
|
325
348
|
});
|
|
326
349
|
|
|
@@ -356,26 +379,26 @@ describe("pre-chat onboarding contract", () => {
|
|
|
356
379
|
};
|
|
357
380
|
|
|
358
381
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
359
|
-
const
|
|
382
|
+
const bootstrap = bootstrapBlock(result);
|
|
360
383
|
|
|
361
384
|
// Heading is present
|
|
362
|
-
expect(
|
|
385
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
363
386
|
|
|
364
387
|
// Normalized labels appear (capitalised tool names, human-readable task descriptions)
|
|
365
|
-
expect(
|
|
366
|
-
expect(
|
|
367
|
-
expect(
|
|
368
|
-
expect(
|
|
388
|
+
expect(bootstrap).toContain("- Daily tools: Slack, Notion, Linear");
|
|
389
|
+
expect(bootstrap).toContain("- Name: Alice");
|
|
390
|
+
expect(bootstrap).toContain("- Chosen assistant name: Pax");
|
|
391
|
+
expect(bootstrap).toContain("- Preferred initial voice: grounded");
|
|
369
392
|
// Common work descriptions are normalised from task IDs
|
|
370
|
-
expect(
|
|
371
|
-
|
|
372
|
-
// No raw JSON anywhere in the
|
|
373
|
-
expect(
|
|
374
|
-
expect(
|
|
375
|
-
expect(
|
|
376
|
-
expect(
|
|
377
|
-
expect(
|
|
378
|
-
expect(
|
|
393
|
+
expect(bootstrap).toContain("- Common work:");
|
|
394
|
+
|
|
395
|
+
// No raw JSON anywhere in the bootstrap block
|
|
396
|
+
expect(bootstrap).not.toContain("```json");
|
|
397
|
+
expect(bootstrap).not.toContain('"tools"');
|
|
398
|
+
expect(bootstrap).not.toContain('"tasks"');
|
|
399
|
+
expect(bootstrap).not.toContain('"tone"');
|
|
400
|
+
expect(bootstrap).not.toContain('"userName"');
|
|
401
|
+
expect(bootstrap).not.toContain('"assistantName"');
|
|
379
402
|
});
|
|
380
403
|
|
|
381
404
|
test("without BOOTSTRAP.md, onboarding context does NOT appear in system prompt", () => {
|
|
@@ -389,15 +412,15 @@ describe("pre-chat onboarding contract", () => {
|
|
|
389
412
|
};
|
|
390
413
|
|
|
391
414
|
const result = buildSystemPrompt({ onboardingContext: context });
|
|
392
|
-
const
|
|
415
|
+
const bootstrap = bootstrapBlock(result);
|
|
393
416
|
|
|
394
417
|
// Onboarding section must be absent
|
|
395
|
-
expect(
|
|
396
|
-
expect(
|
|
397
|
-
expect(
|
|
398
|
-
expect(
|
|
399
|
-
expect(
|
|
400
|
-
expect(
|
|
418
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
419
|
+
expect(bootstrap).not.toContain("First-Run Ritual");
|
|
420
|
+
expect(bootstrap).not.toContain("- Daily tools:");
|
|
421
|
+
expect(bootstrap).not.toContain("- Name: Bob");
|
|
422
|
+
expect(bootstrap).not.toContain("- Chosen assistant name:");
|
|
423
|
+
expect(bootstrap).not.toContain("Apply this context quietly.");
|
|
401
424
|
});
|
|
402
425
|
|
|
403
426
|
test("excludeBootstrap suppresses both bootstrap and onboarding sections", () => {
|
|
@@ -418,34 +441,38 @@ describe("pre-chat onboarding contract", () => {
|
|
|
418
441
|
onboardingContext: context,
|
|
419
442
|
excludeBootstrap: true,
|
|
420
443
|
});
|
|
421
|
-
const
|
|
444
|
+
const bootstrap = bootstrapBlock(result);
|
|
422
445
|
|
|
423
446
|
// Both bootstrap and onboarding must be suppressed
|
|
424
|
-
expect(
|
|
425
|
-
expect(
|
|
426
|
-
expect(
|
|
427
|
-
expect(
|
|
428
|
-
expect(
|
|
447
|
+
expect(bootstrap).not.toContain("First-Run Ritual");
|
|
448
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
449
|
+
expect(bootstrap).not.toContain("- Daily tools:");
|
|
450
|
+
expect(bootstrap).not.toContain("- Name: Charlie");
|
|
451
|
+
expect(bootstrap).not.toContain("Apply this context quietly.");
|
|
429
452
|
});
|
|
430
453
|
|
|
431
454
|
test("userPersona is included independently of onboarding context", () => {
|
|
432
|
-
// No BOOTSTRAP.md — the durable persona path after bootstrap is deleted
|
|
433
|
-
|
|
434
|
-
|
|
455
|
+
// No BOOTSTRAP.md — the durable persona path after bootstrap is deleted.
|
|
456
|
+
// User persona content now lives in `users/<slug>.md` and renders
|
|
457
|
+
// via the `10-user-persona` bundled section in the static prefix.
|
|
458
|
+
mkdirSync(join(TEST_DIR, "users"), { recursive: true });
|
|
459
|
+
writeFileSync(
|
|
460
|
+
join(TEST_DIR, "users", "default.md"),
|
|
461
|
+
"# User Persona\n\nPrefers concise answers. Works in fintech.",
|
|
462
|
+
);
|
|
435
463
|
|
|
436
464
|
const result = buildSystemPrompt({
|
|
437
|
-
userPersona: personaContent,
|
|
438
465
|
// No onboardingContext — simulates post-onboarding conversation
|
|
439
466
|
});
|
|
440
|
-
const dynamic = dynamicBlock(result);
|
|
441
467
|
|
|
442
468
|
// Persona content appears in prompt even without bootstrap or onboarding
|
|
443
|
-
expect(
|
|
444
|
-
expect(
|
|
469
|
+
expect(result).toContain("# User Persona");
|
|
470
|
+
expect(result).toContain("Prefers concise answers. Works in fintech.");
|
|
445
471
|
|
|
446
472
|
// No onboarding section should be present
|
|
447
|
-
|
|
448
|
-
expect(
|
|
473
|
+
const bootstrap = bootstrapBlock(result);
|
|
474
|
+
expect(bootstrap).not.toContain("## First-Run User Context");
|
|
475
|
+
expect(bootstrap).not.toContain("First-Run Ritual");
|
|
449
476
|
});
|
|
450
477
|
|
|
451
478
|
test("userPersona appears alongside onboarding context during first run", () => {
|
|
@@ -454,8 +481,14 @@ describe("pre-chat onboarding contract", () => {
|
|
|
454
481
|
"# Bootstrap\n\nOnboarding flow.",
|
|
455
482
|
);
|
|
456
483
|
|
|
457
|
-
|
|
458
|
-
|
|
484
|
+
// User persona file renders via the `10-user-persona` section
|
|
485
|
+
// and the First-Run Ritual + onboarding context render via the
|
|
486
|
+
// `13-bootstrap` section — both in the static prefix.
|
|
487
|
+
mkdirSync(join(TEST_DIR, "users"), { recursive: true });
|
|
488
|
+
writeFileSync(
|
|
489
|
+
join(TEST_DIR, "users", "default.md"),
|
|
490
|
+
"# User Persona\n\nEarly-stage startup founder. Likes bullet points.",
|
|
491
|
+
);
|
|
459
492
|
const context: OnboardingContext = {
|
|
460
493
|
tools: ["slack"],
|
|
461
494
|
tasks: ["writing"],
|
|
@@ -464,17 +497,17 @@ describe("pre-chat onboarding contract", () => {
|
|
|
464
497
|
};
|
|
465
498
|
|
|
466
499
|
const result = buildSystemPrompt({
|
|
467
|
-
userPersona: personaContent,
|
|
468
500
|
onboardingContext: context,
|
|
469
501
|
});
|
|
470
|
-
const
|
|
471
|
-
|
|
472
|
-
// Both persona and onboarding context appear
|
|
473
|
-
|
|
474
|
-
expect(
|
|
475
|
-
expect(
|
|
476
|
-
expect(
|
|
477
|
-
expect(
|
|
502
|
+
const bootstrap = bootstrapBlock(result);
|
|
503
|
+
|
|
504
|
+
// Both persona and onboarding context appear in the static prefix
|
|
505
|
+
// (`10-user-persona` and `13-bootstrap` respectively)
|
|
506
|
+
expect(result).toContain("# User Persona");
|
|
507
|
+
expect(result).toContain("Likes bullet points.");
|
|
508
|
+
expect(bootstrap).toContain("## First-Run User Context");
|
|
509
|
+
expect(bootstrap).toContain("- Name: Dana");
|
|
510
|
+
expect(bootstrap).toContain("- Daily tools: Slack");
|
|
478
511
|
});
|
|
479
512
|
});
|
|
480
513
|
});
|
|
@@ -216,6 +216,17 @@ describe("resolvePricing", () => {
|
|
|
216
216
|
expect(result.estimatedCostUsd).toBe(0.25 + 1.5);
|
|
217
217
|
});
|
|
218
218
|
|
|
219
|
+
test("returns priced for gemini-3.1-flash-lite", () => {
|
|
220
|
+
const result = resolvePricing(
|
|
221
|
+
"gemini",
|
|
222
|
+
"gemini-3.1-flash-lite",
|
|
223
|
+
1_000_000,
|
|
224
|
+
1_000_000,
|
|
225
|
+
);
|
|
226
|
+
expect(result.pricingStatus).toBe("priced");
|
|
227
|
+
expect(result.estimatedCostUsd).toBe(0.25 + 1.5);
|
|
228
|
+
});
|
|
229
|
+
|
|
219
230
|
test("prices gemini-2.5-pro at the low-context tier through 200k input tokens", () => {
|
|
220
231
|
const result = resolvePricing(
|
|
221
232
|
"gemini",
|
|
@@ -489,6 +500,7 @@ describe("resolvePricingForUsage", () => {
|
|
|
489
500
|
const cases = [
|
|
490
501
|
["gemini-3-flash-preview", 0.05],
|
|
491
502
|
["gemini-3.1-flash-lite-preview", 0.025],
|
|
503
|
+
["gemini-3.1-flash-lite", 0.025],
|
|
492
504
|
["gemini-2.5-flash", 0.03],
|
|
493
505
|
["gemini-2.5-flash-lite", 0.01],
|
|
494
506
|
["gemini-2.5-pro", 0.625],
|
|
@@ -95,7 +95,6 @@ type PersistUserMessageMock = ReturnType<
|
|
|
95
95
|
type RunAgentLoopMock = ReturnType<
|
|
96
96
|
typeof mock<(...args: unknown[]) => Promise<void>>
|
|
97
97
|
>;
|
|
98
|
-
type NoticeMock = ReturnType<typeof mock<(notice: string | undefined) => void>>;
|
|
99
98
|
interface TestConversation {
|
|
100
99
|
conversationId: string;
|
|
101
100
|
trustContext: unknown;
|
|
@@ -123,13 +122,10 @@ interface TestConversation {
|
|
|
123
122
|
estimatedCost: number;
|
|
124
123
|
};
|
|
125
124
|
persistUserMessage: PersistUserMessageMock;
|
|
126
|
-
setSlackRuntimeContextNotice: NoticeMock;
|
|
127
125
|
runAgentLoop: RunAgentLoopMock;
|
|
128
126
|
updateClient: (sender: (...args: unknown[]) => void) => void;
|
|
129
127
|
getCurrentSender: () => ((...args: unknown[]) => void) | undefined;
|
|
130
128
|
__loopDeferred: Deferred<void>;
|
|
131
|
-
__noticeCalls: Array<string | undefined>;
|
|
132
|
-
__loopNotices: Array<string | undefined>;
|
|
133
129
|
__clientSenders: Array<((...args: unknown[]) => void) | undefined>;
|
|
134
130
|
}
|
|
135
131
|
|
|
@@ -171,11 +167,8 @@ async function waitForRunAgentLoopCall(): Promise<void> {
|
|
|
171
167
|
function makeConversation(): TestConversation {
|
|
172
168
|
let turnChannelContext: TurnChannelContext | null = null;
|
|
173
169
|
let turnInterfaceContext: TurnInterfaceContext | null = null;
|
|
174
|
-
let slackNotice: string | undefined;
|
|
175
170
|
let currentSender: ((...args: unknown[]) => void) | undefined;
|
|
176
|
-
const noticeCalls: Array<string | undefined> = [];
|
|
177
171
|
const loopDeferred = createDeferred<void>();
|
|
178
|
-
const loopNotices: Array<string | undefined> = [];
|
|
179
172
|
const clientSenders: Array<((...args: unknown[]) => void) | undefined> = [];
|
|
180
173
|
const messages: unknown[] = [];
|
|
181
174
|
|
|
@@ -223,12 +216,7 @@ function makeConversation(): TestConversation {
|
|
|
223
216
|
_metadata?: Record<string, unknown>,
|
|
224
217
|
) => "persisted-user-message-id",
|
|
225
218
|
),
|
|
226
|
-
setSlackRuntimeContextNotice: mock((notice: string | undefined) => {
|
|
227
|
-
slackNotice = notice;
|
|
228
|
-
noticeCalls.push(notice);
|
|
229
|
-
}),
|
|
230
219
|
runAgentLoop: mock(async (..._args: unknown[]) => {
|
|
231
|
-
loopNotices.push(slackNotice);
|
|
232
220
|
await loopDeferred.promise;
|
|
233
221
|
}),
|
|
234
222
|
updateClient: (sender: (...args: unknown[]) => void) => {
|
|
@@ -237,8 +225,6 @@ function makeConversation(): TestConversation {
|
|
|
237
225
|
},
|
|
238
226
|
getCurrentSender: () => currentSender,
|
|
239
227
|
__loopDeferred: loopDeferred,
|
|
240
|
-
__noticeCalls: noticeCalls,
|
|
241
|
-
__loopNotices: loopNotices,
|
|
242
228
|
__clientSenders: clientSenders,
|
|
243
229
|
};
|
|
244
230
|
|
|
@@ -252,15 +238,13 @@ describe("processMessageInBackground Slack option propagation", () => {
|
|
|
252
238
|
broadcastMessages.length = 0;
|
|
253
239
|
});
|
|
254
240
|
|
|
255
|
-
test("passes Slack inbound metadata to persistence
|
|
241
|
+
test("passes Slack inbound metadata to persistence during background processing", async () => {
|
|
256
242
|
const slackInbound = {
|
|
257
243
|
channelId: "C0123CHANNEL",
|
|
258
244
|
channelTs: "1700000001.111111",
|
|
259
245
|
threadTs: "1700000000.000001",
|
|
260
246
|
displayName: "Alice",
|
|
261
247
|
};
|
|
262
|
-
const notice =
|
|
263
|
-
"Slack context note: this turn joined an existing thread. 2 earlier messages were backfilled.";
|
|
264
248
|
|
|
265
249
|
const result = await processMessageInBackground(
|
|
266
250
|
"conv-background-slack",
|
|
@@ -268,7 +252,6 @@ describe("processMessageInBackground Slack option propagation", () => {
|
|
|
268
252
|
undefined,
|
|
269
253
|
{
|
|
270
254
|
slackInbound,
|
|
271
|
-
slackRuntimeContextNotice: notice,
|
|
272
255
|
},
|
|
273
256
|
"slack",
|
|
274
257
|
"slack",
|
|
@@ -280,43 +263,10 @@ describe("processMessageInBackground Slack option propagation", () => {
|
|
|
280
263
|
slackInbound,
|
|
281
264
|
});
|
|
282
265
|
expect(activeConversation.runAgentLoop).toHaveBeenCalledTimes(1);
|
|
283
|
-
expect(activeConversation.__loopNotices).toEqual([notice]);
|
|
284
266
|
|
|
285
267
|
activeConversation.__loopDeferred.resolve();
|
|
286
268
|
await activeConversation.__loopDeferred.promise;
|
|
287
269
|
await Promise.resolve();
|
|
288
|
-
|
|
289
|
-
expect(activeConversation.__noticeCalls).toEqual([notice, undefined]);
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
test("clears the Slack runtime notice after normal message processing", async () => {
|
|
293
|
-
const notice =
|
|
294
|
-
"Slack context note: this turn joined an existing thread. 2 earlier messages were backfilled.";
|
|
295
|
-
|
|
296
|
-
const processing = processMessage(
|
|
297
|
-
"conv-background-slack",
|
|
298
|
-
"Reply from Slack",
|
|
299
|
-
undefined,
|
|
300
|
-
{
|
|
301
|
-
slackRuntimeContextNotice: notice,
|
|
302
|
-
isInteractive: true,
|
|
303
|
-
},
|
|
304
|
-
"slack",
|
|
305
|
-
"slack",
|
|
306
|
-
);
|
|
307
|
-
|
|
308
|
-
await waitForRunAgentLoopCall();
|
|
309
|
-
|
|
310
|
-
expect(activeConversation.runAgentLoop).toHaveBeenCalledTimes(1);
|
|
311
|
-
expect(activeConversation.__loopNotices).toEqual([notice]);
|
|
312
|
-
|
|
313
|
-
activeConversation.__loopDeferred.resolve();
|
|
314
|
-
await expect(processing).resolves.toEqual({
|
|
315
|
-
messageId: "persisted-user-message-id",
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
expect(activeConversation.__noticeCalls).toEqual([notice, undefined]);
|
|
319
|
-
expect(activeConversation.__clientSenders).toHaveLength(2);
|
|
320
270
|
});
|
|
321
271
|
|
|
322
272
|
test("observes live agent events without replacing the broadcast emitter", async () => {
|