@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
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message consolidation — shared logic that maps the raw DB row sequence
|
|
3
|
+
* onto the displayed transcript.
|
|
4
|
+
*
|
|
5
|
+
* A single "display turn" in the UI can span multiple DB rows. During
|
|
6
|
+
* streaming the agent loop persists each API call as a separate
|
|
7
|
+
* assistant row (deferred consolidation, for prefix-cache stability),
|
|
8
|
+
* and intervening user rows often carry only tool_result blocks that
|
|
9
|
+
* are suppressed at display time. The two-pass collapse here is what
|
|
10
|
+
* turns the raw sequence into the rows the user actually sees.
|
|
11
|
+
*
|
|
12
|
+
* Pass 1 — `mergeToolResultsIntoAssistantMessages`
|
|
13
|
+
* For each user row, lift its `tool_result` (and `web_search_tool_result`)
|
|
14
|
+
* blocks onto the preceding assistant row. If the user row had
|
|
15
|
+
* nothing else (only tool_result + system_notice blocks), drop the
|
|
16
|
+
* row entirely. Otherwise keep its non-tool-result content as a
|
|
17
|
+
* real user message.
|
|
18
|
+
*
|
|
19
|
+
* Pass 2 — `mergeConsecutiveAssistantMessages`
|
|
20
|
+
* After pass 1 removes tool-result-only user separators, fold runs
|
|
21
|
+
* of adjacent assistant rows onto the first row of the run
|
|
22
|
+
* ("anchor"). Anchors keep their id, createdAt, and metadata;
|
|
23
|
+
* subagent-notification metadata is promoted from later rows when
|
|
24
|
+
* the anchor lacks it.
|
|
25
|
+
*
|
|
26
|
+
* `findDisplayTurnEndIndex` is the primitive any write-path needs when
|
|
27
|
+
* it has a single DB-row id and wants to know "which DB rows make up
|
|
28
|
+
* the display turn that this row anchors". It uses the same
|
|
29
|
+
* `isToolResultOnlyUserMessage` predicate that pass 1 uses to decide
|
|
30
|
+
* which user rows are suppressed, so the read-path and write-path
|
|
31
|
+
* agree on cluster boundaries without duplicating the merge code.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import type { MessageRow } from "../memory/conversation-crud.js";
|
|
35
|
+
import { getLogger } from "../util/logger.js";
|
|
36
|
+
|
|
37
|
+
const log = getLogger("message-consolidation");
|
|
38
|
+
|
|
39
|
+
// ── Block predicates ────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
function isToolResultType(type: string): boolean {
|
|
42
|
+
return type === "tool_result" || type === "web_search_tool_result";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isSystemNoticeText(block: Record<string, unknown>): boolean {
|
|
46
|
+
if (block.type !== "text") return false;
|
|
47
|
+
const text = typeof block.text === "string" ? block.text : "";
|
|
48
|
+
return (
|
|
49
|
+
text.startsWith("<system_notice>") && text.endsWith("</system_notice>")
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* True when a user row's content is exclusively tool_result blocks
|
|
55
|
+
* (and optional system_notice text). Such rows are suppressed by the
|
|
56
|
+
* read-path collapse — they exist in the DB to satisfy the LLM's
|
|
57
|
+
* tool_use ↔ tool_result pairing requirement but are never displayed
|
|
58
|
+
* to the user. Any write-path that walks DB rows in display order
|
|
59
|
+
* must treat them as part of the surrounding assistant turn.
|
|
60
|
+
*/
|
|
61
|
+
export function isToolResultOnlyUserMessage(msg: MessageRow): boolean {
|
|
62
|
+
if (msg.role !== "user") return false;
|
|
63
|
+
let blocks: unknown[];
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(msg.content);
|
|
66
|
+
if (!Array.isArray(parsed)) return false;
|
|
67
|
+
blocks = parsed;
|
|
68
|
+
} catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let sawToolResult = false;
|
|
73
|
+
for (const block of blocks) {
|
|
74
|
+
if (
|
|
75
|
+
typeof block !== "object" ||
|
|
76
|
+
block === null ||
|
|
77
|
+
typeof (block as Record<string, unknown>).type !== "string"
|
|
78
|
+
) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const rec = block as Record<string, unknown>;
|
|
82
|
+
if (isToolResultType(rec.type as string)) {
|
|
83
|
+
sawToolResult = true;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (isSystemNoticeText(rec)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return sawToolResult;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── Display-turn boundary lookup ────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Returns the inclusive DB-row index where the display turn that
|
|
98
|
+
* contains `messages[startIdx]` ends.
|
|
99
|
+
*
|
|
100
|
+
* For non-assistant rows, returns `startIdx` unchanged — only assistant
|
|
101
|
+
* turns can span multiple rows.
|
|
102
|
+
*
|
|
103
|
+
* For assistant rows, advances past any consecutive rows that the
|
|
104
|
+
* read-path collapse would fold into the same display turn:
|
|
105
|
+
* - another assistant row → part of the consecutive-assistant run, OR
|
|
106
|
+
* - a tool-result-only user row → suppressed at display time, sits
|
|
107
|
+
* between two halves of the same assistant turn.
|
|
108
|
+
*
|
|
109
|
+
* Stops at the first real user message (or any non-collapsible row),
|
|
110
|
+
* end-of-array, or invalid index.
|
|
111
|
+
*
|
|
112
|
+
* Mirror of the cluster boundary that `mergeConsecutiveAssistantMessages`
|
|
113
|
+
* (post pass-1) would produce — without paying the cost of parsing
|
|
114
|
+
* every content block.
|
|
115
|
+
*/
|
|
116
|
+
export function findDisplayTurnEndIndex(
|
|
117
|
+
messages: MessageRow[],
|
|
118
|
+
startIdx: number,
|
|
119
|
+
): number {
|
|
120
|
+
if (startIdx < 0 || startIdx >= messages.length) return startIdx;
|
|
121
|
+
if (messages[startIdx]?.role !== "assistant") return startIdx;
|
|
122
|
+
|
|
123
|
+
let endIdx = startIdx;
|
|
124
|
+
while (endIdx + 1 < messages.length) {
|
|
125
|
+
const next = messages[endIdx + 1];
|
|
126
|
+
if (!next) break;
|
|
127
|
+
if (next.role === "assistant") {
|
|
128
|
+
endIdx += 1;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (next.role === "user" && isToolResultOnlyUserMessage(next)) {
|
|
132
|
+
endIdx += 1;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
return endIdx;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ── Pass 1: tool-result merging ─────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Merge tool_result blocks from user messages into the preceding assistant
|
|
144
|
+
* message's content array. This lets renderHistoryContent's pendingToolUses
|
|
145
|
+
* map pair tool_use and tool_result blocks, preventing "unknown" tool names.
|
|
146
|
+
*
|
|
147
|
+
* User messages that consist entirely of tool_result blocks (and optional
|
|
148
|
+
* system_notice text) are removed from the output. Mixed messages (tool_result
|
|
149
|
+
* + real user text) keep only the non-tool-result blocks.
|
|
150
|
+
*/
|
|
151
|
+
export function mergeToolResultsIntoAssistantMessages(
|
|
152
|
+
messages: MessageRow[],
|
|
153
|
+
): MessageRow[] {
|
|
154
|
+
// Index of the most recent assistant message in the output array.
|
|
155
|
+
let lastAssistantIdx = -1;
|
|
156
|
+
// Parsed content caches — lazily populated per assistant message.
|
|
157
|
+
const parsedAssistantContent = new Map<number, unknown[]>();
|
|
158
|
+
|
|
159
|
+
const result: MessageRow[] = [];
|
|
160
|
+
|
|
161
|
+
for (const msg of messages) {
|
|
162
|
+
if (msg.role === "assistant") {
|
|
163
|
+
lastAssistantIdx = result.length;
|
|
164
|
+
result.push(msg);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Only process user messages — other roles pass through.
|
|
169
|
+
if (msg.role !== "user") {
|
|
170
|
+
result.push(msg);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
let blocks: unknown[];
|
|
175
|
+
try {
|
|
176
|
+
const parsed = JSON.parse(msg.content);
|
|
177
|
+
if (!Array.isArray(parsed)) {
|
|
178
|
+
result.push(msg);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
blocks = parsed;
|
|
182
|
+
} catch {
|
|
183
|
+
result.push(msg);
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Separate tool-result blocks from real user content.
|
|
188
|
+
const toolResultBlocks: unknown[] = [];
|
|
189
|
+
const otherBlocks: unknown[] = [];
|
|
190
|
+
for (const block of blocks) {
|
|
191
|
+
if (
|
|
192
|
+
typeof block === "object" &&
|
|
193
|
+
block !== null &&
|
|
194
|
+
typeof (block as Record<string, unknown>).type === "string"
|
|
195
|
+
) {
|
|
196
|
+
const rec = block as Record<string, unknown>;
|
|
197
|
+
if (isToolResultType(rec.type as string)) {
|
|
198
|
+
toolResultBlocks.push(block);
|
|
199
|
+
} else if (isSystemNoticeText(rec)) {
|
|
200
|
+
// System notices don't count as user content — drop them when
|
|
201
|
+
// the message is otherwise tool-result-only.
|
|
202
|
+
otherBlocks.push(block);
|
|
203
|
+
} else {
|
|
204
|
+
otherBlocks.push(block);
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
otherBlocks.push(block);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// No tool results → pass through unchanged. System notices are only
|
|
212
|
+
// injected alongside tool results in the agent loop, so a pure user
|
|
213
|
+
// message (no tool_result blocks) should never be filtered — even if
|
|
214
|
+
// the user's text happens to look like a system_notice tag.
|
|
215
|
+
if (toolResultBlocks.length === 0) {
|
|
216
|
+
result.push(msg);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Append tool_result blocks to the preceding assistant message's content.
|
|
221
|
+
// No-op at pagination boundaries (lastAssistantIdx < 0); orphan tool_results
|
|
222
|
+
// are silently dropped by renderHistoryContent downstream either way.
|
|
223
|
+
if (lastAssistantIdx >= 0) {
|
|
224
|
+
const assistant = result[lastAssistantIdx];
|
|
225
|
+
let assistantContent = parsedAssistantContent.get(lastAssistantIdx);
|
|
226
|
+
if (!assistantContent) {
|
|
227
|
+
try {
|
|
228
|
+
const parsed = JSON.parse(assistant.content);
|
|
229
|
+
assistantContent = Array.isArray(parsed) ? parsed : [parsed];
|
|
230
|
+
} catch {
|
|
231
|
+
assistantContent = [];
|
|
232
|
+
}
|
|
233
|
+
parsedAssistantContent.set(lastAssistantIdx, assistantContent);
|
|
234
|
+
}
|
|
235
|
+
assistantContent.push(...toolResultBlocks);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// If the user message had only tool_result (+ system_notice) blocks,
|
|
239
|
+
// suppress it entirely. Otherwise keep the non-tool-result content.
|
|
240
|
+
const realUserContent = otherBlocks.filter(
|
|
241
|
+
(b) =>
|
|
242
|
+
!(
|
|
243
|
+
typeof b === "object" &&
|
|
244
|
+
b !== null &&
|
|
245
|
+
isSystemNoticeText(b as Record<string, unknown>)
|
|
246
|
+
),
|
|
247
|
+
);
|
|
248
|
+
if (realUserContent.length > 0) {
|
|
249
|
+
result.push({ ...msg, content: JSON.stringify(otherBlocks) });
|
|
250
|
+
}
|
|
251
|
+
// else: tool-result-only → suppressed
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Write back any modified assistant message content.
|
|
255
|
+
for (const [idx, content] of parsedAssistantContent) {
|
|
256
|
+
result[idx] = { ...result[idx], content: JSON.stringify(content) };
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return result;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ── Pass 2: consecutive-assistant merging ───────────────────────────
|
|
263
|
+
|
|
264
|
+
/** Parse a message's JSON content into an array of content blocks. */
|
|
265
|
+
function parseContentBlocks(content: string): unknown[] {
|
|
266
|
+
try {
|
|
267
|
+
const parsed = JSON.parse(content);
|
|
268
|
+
return Array.isArray(parsed) ? parsed : [parsed];
|
|
269
|
+
} catch (err) {
|
|
270
|
+
log.warn(
|
|
271
|
+
{ err },
|
|
272
|
+
"Failed to parse content blocks during assistant message merge",
|
|
273
|
+
);
|
|
274
|
+
return [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Append content blocks from a donor message onto a target block array.
|
|
280
|
+
* Parses the donor's JSON content and pushes each block into `target`.
|
|
281
|
+
*/
|
|
282
|
+
function appendContentBlocks(target: unknown[], donorContent: string): void {
|
|
283
|
+
try {
|
|
284
|
+
const parsed = JSON.parse(donorContent);
|
|
285
|
+
if (Array.isArray(parsed)) {
|
|
286
|
+
target.push(...parsed);
|
|
287
|
+
} else {
|
|
288
|
+
target.push(parsed);
|
|
289
|
+
}
|
|
290
|
+
} catch (err) {
|
|
291
|
+
log.warn(
|
|
292
|
+
{ err },
|
|
293
|
+
"Failed to parse donor content blocks during assistant message merge",
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Promote metadata fields from a donor message to the surviving message
|
|
300
|
+
* when the survivor lacks them. Currently promotes `subagentNotification`.
|
|
301
|
+
* Returns a new MessageRow if promotion occurred, otherwise the original.
|
|
302
|
+
*/
|
|
303
|
+
function promoteMetadata(survivor: MessageRow, donor: MessageRow): MessageRow {
|
|
304
|
+
if (donor.metadata && survivor.metadata) {
|
|
305
|
+
try {
|
|
306
|
+
const survivorMeta = JSON.parse(survivor.metadata);
|
|
307
|
+
const donorMeta = JSON.parse(donor.metadata);
|
|
308
|
+
if (
|
|
309
|
+
!survivorMeta.subagentNotification &&
|
|
310
|
+
donorMeta.subagentNotification
|
|
311
|
+
) {
|
|
312
|
+
survivorMeta.subagentNotification = donorMeta.subagentNotification;
|
|
313
|
+
return { ...survivor, metadata: JSON.stringify(survivorMeta) };
|
|
314
|
+
}
|
|
315
|
+
} catch (err) {
|
|
316
|
+
log.warn(
|
|
317
|
+
{ err },
|
|
318
|
+
"Failed to parse metadata during assistant message merge",
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
} else if (donor.metadata && !survivor.metadata) {
|
|
322
|
+
return { ...survivor, metadata: donor.metadata };
|
|
323
|
+
}
|
|
324
|
+
return survivor;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Merge consecutive assistant messages into a single message at query time.
|
|
329
|
+
*
|
|
330
|
+
* During streaming, all assistant turns within one agent loop accumulate on
|
|
331
|
+
* a single client-side message. In the DB, each API turn is stored as a
|
|
332
|
+
* separate assistant row (consolidation is deferred to compaction for
|
|
333
|
+
* prefix-cache stability). This produces N separate assistant messages that
|
|
334
|
+
* the client would otherwise render as N individual rows — each showing
|
|
335
|
+
* "Completed 1 step" instead of one grouped "Completed N steps" accordion.
|
|
336
|
+
*
|
|
337
|
+
* This function concatenates the content block arrays of consecutive
|
|
338
|
+
* assistant messages (no intervening user messages after tool-result
|
|
339
|
+
* merging) into the first message of each run. The merged messages are
|
|
340
|
+
* removed from the output. This is query-time only — the DB is not
|
|
341
|
+
* modified.
|
|
342
|
+
*
|
|
343
|
+
* The first message in each run keeps its id, createdAt, and metadata so
|
|
344
|
+
* that attachment lookups, display timestamps, and subagent notifications
|
|
345
|
+
* continue to work. Metadata from later messages in the run (e.g.
|
|
346
|
+
* subagentNotification) is preserved by promoting it to the surviving
|
|
347
|
+
* message when the surviving message has no metadata of its own for that
|
|
348
|
+
* field.
|
|
349
|
+
*/
|
|
350
|
+
export function mergeConsecutiveAssistantMessages(messages: MessageRow[]): {
|
|
351
|
+
messages: MessageRow[];
|
|
352
|
+
/** Maps each surviving message ID → all original message IDs merged into it. */
|
|
353
|
+
mergedIdMap: Map<string, string[]>;
|
|
354
|
+
} {
|
|
355
|
+
const result: MessageRow[] = [];
|
|
356
|
+
// Key = index in `result`, value = accumulated content blocks.
|
|
357
|
+
const pendingMerges = new Map<number, unknown[]>();
|
|
358
|
+
// Key = index in `result`, value = IDs of messages merged into the target.
|
|
359
|
+
const mergedIds = new Map<number, string[]>();
|
|
360
|
+
|
|
361
|
+
for (const msg of messages) {
|
|
362
|
+
const lastIdx = result.length - 1;
|
|
363
|
+
const isConsecutiveAssistant =
|
|
364
|
+
msg.role === "assistant" &&
|
|
365
|
+
lastIdx >= 0 &&
|
|
366
|
+
result[lastIdx].role === "assistant";
|
|
367
|
+
|
|
368
|
+
if (!isConsecutiveAssistant) {
|
|
369
|
+
result.push(msg);
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Track the donor message ID.
|
|
374
|
+
let ids = mergedIds.get(lastIdx);
|
|
375
|
+
if (!ids) {
|
|
376
|
+
ids = [];
|
|
377
|
+
mergedIds.set(lastIdx, ids);
|
|
378
|
+
}
|
|
379
|
+
ids.push(msg.id);
|
|
380
|
+
|
|
381
|
+
// Lazily parse the target's content on first merge.
|
|
382
|
+
let targetContent = pendingMerges.get(lastIdx);
|
|
383
|
+
if (!targetContent) {
|
|
384
|
+
targetContent = parseContentBlocks(result[lastIdx].content);
|
|
385
|
+
pendingMerges.set(lastIdx, targetContent);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
appendContentBlocks(targetContent, msg.content);
|
|
389
|
+
result[lastIdx] = promoteMetadata(result[lastIdx], msg);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Write back merged content for any messages that were targets.
|
|
393
|
+
for (const [idx, content] of pendingMerges) {
|
|
394
|
+
result[idx] = { ...result[idx], content: JSON.stringify(content) };
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// Build the merged ID map keyed by surviving message ID.
|
|
398
|
+
const mergedIdMap = new Map<string, string[]>();
|
|
399
|
+
for (const [idx, ids] of mergedIds) {
|
|
400
|
+
mergedIdMap.set(result[idx].id, ids);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return { messages: result, mergedIdMap };
|
|
404
|
+
}
|
|
@@ -315,9 +315,11 @@ async function checkManagedProvider(
|
|
|
315
315
|
const client = await VellumPlatformClient.create();
|
|
316
316
|
if (!client?.platformAssistantId) return results;
|
|
317
317
|
|
|
318
|
+
// Query without a status filter so we can distinguish "never
|
|
319
|
+
// connected" (empty result) from "previously connected but now
|
|
320
|
+
// inactive" (non-empty result with no ACTIVE entries).
|
|
318
321
|
const params = new URLSearchParams();
|
|
319
322
|
params.set("provider", providerRow.provider);
|
|
320
|
-
params.set("status", "ACTIVE");
|
|
321
323
|
|
|
322
324
|
const path = `/v1/assistants/${encodeURIComponent(client.platformAssistantId)}/oauth/connections/?${params.toString()}`;
|
|
323
325
|
const response = await client.fetch(path);
|
|
@@ -331,19 +333,30 @@ async function checkManagedProvider(
|
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
const body = (await response.json()) as unknown;
|
|
334
|
-
const
|
|
336
|
+
const allConnections = (
|
|
335
337
|
Array.isArray(body)
|
|
336
338
|
? body
|
|
337
339
|
: ((body as Record<string, unknown>).results ?? [])
|
|
338
|
-
) as Array<{ id: string; account_label?: string }>;
|
|
340
|
+
) as Array<{ id: string; account_label?: string; status?: string }>;
|
|
341
|
+
|
|
342
|
+
if (allConnections.length === 0) {
|
|
343
|
+
// No connections of any status — the user has never connected this
|
|
344
|
+
// provider. The suggested-prompts system handles prompting them to
|
|
345
|
+
// connect; this is not a health issue.
|
|
346
|
+
return results;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const connections = allConnections.filter(
|
|
350
|
+
(c) => (c.status ?? "ACTIVE").toUpperCase() === "ACTIVE",
|
|
351
|
+
);
|
|
339
352
|
|
|
340
353
|
if (connections.length === 0) {
|
|
341
|
-
//
|
|
342
|
-
//
|
|
354
|
+
// Connections exist but none are active — the user previously
|
|
355
|
+
// connected and the connection was revoked/deactivated.
|
|
343
356
|
results.push({
|
|
344
357
|
connectionId: `managed:${providerRow.provider}`,
|
|
345
358
|
provider: providerRow.provider,
|
|
346
|
-
accountInfo: null,
|
|
359
|
+
accountInfo: allConnections[0]?.account_label ?? null,
|
|
347
360
|
status: "missing_token",
|
|
348
361
|
details: `No active managed connection for ${providerRow.provider}. Reconnect on the Vellum platform.`,
|
|
349
362
|
missingScopes: [],
|
|
@@ -550,9 +563,20 @@ export async function checkAllCredentials(): Promise<CredentialHealthReport> {
|
|
|
550
563
|
for (const providerRow of providers) {
|
|
551
564
|
if (!(await isManagedProvider(providerRow))) continue;
|
|
552
565
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
566
|
+
let managedResults: CredentialHealthResult[] = [];
|
|
567
|
+
try {
|
|
568
|
+
managedResults = await checkManagedProvider(providerRow);
|
|
569
|
+
} catch (err) {
|
|
570
|
+
log.warn(
|
|
571
|
+
{ err, provider: providerRow.provider },
|
|
572
|
+
"Failed to check managed provider health",
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// Only replace BYO results with managed results when the managed
|
|
577
|
+
// check returned something. If managed returned empty (user never
|
|
578
|
+
// connected via managed mode), keep any existing BYO results.
|
|
579
|
+
if (managedResults.length > 0 && byoProviders.has(providerRow.provider)) {
|
|
556
580
|
const beforeLen = results.length;
|
|
557
581
|
const filtered = results.filter(
|
|
558
582
|
(r) => r.provider !== providerRow.provider,
|
|
@@ -562,16 +586,7 @@ export async function checkAllCredentials(): Promise<CredentialHealthReport> {
|
|
|
562
586
|
results.push(...filtered);
|
|
563
587
|
}
|
|
564
588
|
}
|
|
565
|
-
|
|
566
|
-
try {
|
|
567
|
-
const managedResults = await checkManagedProvider(providerRow);
|
|
568
|
-
results.push(...managedResults);
|
|
569
|
-
} catch (err) {
|
|
570
|
-
log.warn(
|
|
571
|
-
{ err, provider: providerRow.provider },
|
|
572
|
-
"Failed to check managed provider health",
|
|
573
|
-
);
|
|
574
|
-
}
|
|
589
|
+
results.push(...managedResults);
|
|
575
590
|
}
|
|
576
591
|
|
|
577
592
|
const unhealthy = results.filter((r) => r.status !== "healthy");
|
|
@@ -49,11 +49,8 @@ mock.module("../../runtime/assistant-event-hub.js", () => ({
|
|
|
49
49
|
|
|
50
50
|
// Dynamic imports after mock.module calls so the stubs take effect
|
|
51
51
|
// before the modules under test are loaded.
|
|
52
|
-
const {
|
|
53
|
-
|
|
54
|
-
HOST_TOOL_TO_CAPABILITY,
|
|
55
|
-
isToolActiveForContext,
|
|
56
|
-
} = await import("../conversation-tool-setup.js");
|
|
52
|
+
const { HOST_TOOL_NAMES, HOST_TOOL_TO_CAPABILITY, isToolActiveForContext } =
|
|
53
|
+
await import("../conversation-tool-setup.js");
|
|
57
54
|
type SkillProjectionContext =
|
|
58
55
|
import("../conversation-tool-setup.js").SkillProjectionContext;
|
|
59
56
|
type SkillProjectionCache =
|
|
@@ -75,6 +72,66 @@ beforeEach(() => {
|
|
|
75
72
|
mockClientCountByCapability.clear();
|
|
76
73
|
});
|
|
77
74
|
|
|
75
|
+
describe("isToolActiveForContext — Slack task_progress UI exception", () => {
|
|
76
|
+
test("ui_show and ui_update are active for Slack task_progress turns", () => {
|
|
77
|
+
const ctx = makeCtx({
|
|
78
|
+
hasNoClient: false,
|
|
79
|
+
channelCapabilities: {
|
|
80
|
+
channel: "slack",
|
|
81
|
+
supportsDynamicUi: false,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(isToolActiveForContext("ui_show", ctx)).toBe(true);
|
|
86
|
+
expect(isToolActiveForContext("ui_update", ctx)).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("ui_dismiss remains hidden for Slack without dynamic UI support", () => {
|
|
90
|
+
expect(
|
|
91
|
+
isToolActiveForContext(
|
|
92
|
+
"ui_dismiss",
|
|
93
|
+
makeCtx({
|
|
94
|
+
hasNoClient: false,
|
|
95
|
+
channelCapabilities: {
|
|
96
|
+
channel: "slack",
|
|
97
|
+
supportsDynamicUi: false,
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
),
|
|
101
|
+
).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("Slack task_progress UI tools still require a connected client path", () => {
|
|
105
|
+
expect(
|
|
106
|
+
isToolActiveForContext(
|
|
107
|
+
"ui_show",
|
|
108
|
+
makeCtx({
|
|
109
|
+
hasNoClient: true,
|
|
110
|
+
channelCapabilities: {
|
|
111
|
+
channel: "slack",
|
|
112
|
+
supportsDynamicUi: false,
|
|
113
|
+
},
|
|
114
|
+
}),
|
|
115
|
+
),
|
|
116
|
+
).toBe(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test("other non-dynamic channels still hide UI surface tools", () => {
|
|
120
|
+
expect(
|
|
121
|
+
isToolActiveForContext(
|
|
122
|
+
"ui_show",
|
|
123
|
+
makeCtx({
|
|
124
|
+
hasNoClient: false,
|
|
125
|
+
channelCapabilities: {
|
|
126
|
+
channel: "telegram",
|
|
127
|
+
supportsDynamicUi: false,
|
|
128
|
+
},
|
|
129
|
+
}),
|
|
130
|
+
),
|
|
131
|
+
).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
78
135
|
describe("isToolActiveForContext — host tool capability gating", () => {
|
|
79
136
|
// macOS transport: SSE-based interactive approval required.
|
|
80
137
|
test("host_bash is active for macOS with a connected client", () => {
|
|
@@ -331,7 +388,10 @@ describe("isToolActiveForContext — cross-client exposure for host_file_*", ()
|
|
|
331
388
|
expect(
|
|
332
389
|
isToolActiveForContext(
|
|
333
390
|
tool,
|
|
334
|
-
makeCtx({
|
|
391
|
+
makeCtx({
|
|
392
|
+
hasNoClient: true,
|
|
393
|
+
transportInterface: "chrome-extension",
|
|
394
|
+
}),
|
|
335
395
|
),
|
|
336
396
|
).toBe(false);
|
|
337
397
|
});
|
|
@@ -183,7 +183,7 @@ describe("loadMeetManifestProxies", () => {
|
|
|
183
183
|
expect(t.ownerSkillId).toBe("meet-join");
|
|
184
184
|
expect(t.ownerSkillBundled).toBe(true);
|
|
185
185
|
expect(t.ownerSkillVersionHash).toBe(FIXTURE_MANIFEST.sourceHash);
|
|
186
|
-
expect(t.
|
|
186
|
+
expect(t.input_schema).toEqual(
|
|
187
187
|
FIXTURE_MANIFEST.tools[0]!.input_schema,
|
|
188
188
|
);
|
|
189
189
|
});
|