@vellumai/assistant 0.11.3 → 0.11.4-staging.2
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 +11 -6
- package/docs/architecture/memory.md +11 -0
- package/docs/architecture/turn-actor.md +70 -0
- package/docs/flux-turn-detection-spike.md +243 -0
- package/docs/stt-provider-onboarding.md +3 -1
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/openapi.yaml +139 -37
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- package/src/__tests__/app-compiler.test.ts +38 -3
- package/src/__tests__/attachments-store.test.ts +21 -12
- package/src/__tests__/byok-default-profile-ensure.test.ts +17 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +0 -1
- package/src/__tests__/call-site-routing-provider.test.ts +1 -1
- package/src/__tests__/channel-availability-routes.test.ts +14 -1
- package/src/__tests__/channel-capabilities-dedupe.test.ts +214 -0
- package/src/__tests__/channel-delivery-store.test.ts +14 -14
- package/src/__tests__/config-loader-backfill.test.ts +3 -3
- package/src/__tests__/config-schema.test.ts +25 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +8 -11
- package/src/__tests__/conversation-agent-loop.test.ts +28 -20
- package/src/__tests__/conversation-attention-store.test.ts +63 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -4
- package/src/__tests__/conversation-fork-crud.test.ts +69 -0
- package/src/__tests__/conversation-fork-referential.test.ts +67 -0
- package/src/__tests__/conversation-fork-retrospective.test.ts +24 -0
- package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
- package/src/__tests__/conversation-queue.test.ts +177 -4
- package/src/__tests__/conversation-runtime-assembly.test.ts +134 -102
- package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
- package/src/__tests__/credential-prompt-route.test.ts +7 -10
- package/src/__tests__/custom-profile-ensure.test.ts +5 -1
- package/src/__tests__/discord-access-request-privacy.test.ts +5 -1
- package/src/__tests__/discord-requester-notice-privacy.test.ts +3 -3
- package/src/__tests__/document-append-idempotency.test.ts +233 -0
- package/src/__tests__/edit-propagation.test.ts +0 -7
- package/src/__tests__/helpers/mock-actor-context.ts +49 -0
- package/src/__tests__/helpers/mock-conversation.ts +13 -1
- package/src/__tests__/injector-chain.test.ts +63 -41
- package/src/__tests__/injector-disk-pressure.test.ts +11 -23
- package/src/__tests__/llm-context-resolution.test.ts +73 -1
- package/src/__tests__/llm-schema.test.ts +5 -2
- package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +6 -5
- package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
- package/src/__tests__/mtime-cache.test.ts +1 -1
- package/src/__tests__/non-member-access-request.test.ts +0 -20
- package/src/__tests__/outbound-slack-persistence.test.ts +40 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -0
- package/src/__tests__/plugin-secret-pattern-contribution.test.ts +1 -1
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +14 -7
- package/src/__tests__/provider-commit-message-generator.test.ts +20 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +434 -105
- package/src/__tests__/scoped-approval-grants.test.ts +11 -6
- package/src/__tests__/secret-ingress-channel.test.ts +0 -1
- package/src/__tests__/skills.test.ts +32 -0
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
- package/src/__tests__/subagent-spawn-and-await.test.ts +14 -10
- package/src/__tests__/turn-events-store.test.ts +43 -0
- package/src/__tests__/ui-shape-teaching.test.ts +33 -0
- package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
- package/src/__tests__/user-plugin-loader.test.ts +1 -1
- package/src/__tests__/visible-app-context.test.ts +16 -9
- package/src/__tests__/voice-config-update.test.ts +40 -0
- package/src/__tests__/worker-entrypoint-guards.test.ts +54 -0
- package/src/__tests__/worker-plugin-surface.test.ts +77 -0
- package/src/__tests__/workspace-migration-142-consolidate-voice-front-door.test.ts +158 -0
- package/src/__tests__/workspace-migration-143-repair-deprecated-codex-model-id.test.ts +133 -0
- package/src/__tests__/workspace-migration-144-convert-stranded-subscription-openai-profiles.test.ts +316 -0
- package/src/__tests__/workspace-migration-145-collapse-profile-bindings-to-entries.test.ts +325 -0
- package/src/__tests__/workspace-migration-146-repair-retired-fireworks-deepseek-flash-model-id.test.ts +235 -0
- package/src/acp/__tests__/acp-claude-oauth.test.ts +10 -2
- package/src/acp/__tests__/auth-required.test.ts +161 -0
- package/src/acp/acp-claude-oauth.ts +19 -2
- package/src/acp/agent-process.test.ts +100 -0
- package/src/acp/agent-process.ts +29 -26
- package/src/acp/auth-required.ts +102 -0
- package/src/acp/session-manager.test.ts +119 -0
- package/src/acp/session-manager.ts +68 -2
- package/src/api/events/acp-auth-required.ts +55 -0
- package/src/api/index.ts +7 -0
- package/src/api/surfaces.ts +7 -3
- package/src/apps/app-store.ts +3 -0
- package/src/bundler/package-resolver.ts +2 -30
- package/src/calls/__tests__/voice-session-bridge.test.ts +173 -1
- package/src/calls/__tests__/voice-triage-escalate.test.ts +94 -0
- package/src/calls/call-controller.ts +19 -3
- package/src/calls/call-setup-flow.ts +0 -1
- package/src/calls/media-stream-stt-session.ts +15 -0
- package/src/calls/voice-session-bridge.ts +71 -16
- package/src/calls/voice-triage-escalate.ts +104 -2
- package/src/channels/__tests__/plugin-channel-declarations.test.ts +161 -0
- package/src/channels/config.ts +13 -0
- package/src/channels/plugin-channel-declarations.ts +108 -0
- package/src/channels/types.ts +30 -0
- package/src/cli/AGENTS.md +5 -2
- package/src/cli/commands/credentials.help.ts +2 -2
- package/src/cli/commands/inference-providers.ts +1 -1
- package/src/cli/commands/mcp.help.ts +13 -4
- package/src/cli/commands/mcp.ts +9 -0
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
- package/src/cli/commands/memory/index.help.ts +43 -1
- package/src/cli/commands/memory/memory-v3.ts +64 -0
- package/src/cli/commands/stt.help.ts +27 -2
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
- package/src/cli/lib/bundled-marketplace.json +13 -0
- package/src/cli/lib/upgrade-plugin.ts +42 -0
- package/src/config/__tests__/default-profile-catalog.test.ts +34 -2
- package/src/config/__tests__/default-provider.test.ts +6 -1
- package/src/config/__tests__/profile-materialization.test.ts +75 -19
- package/src/config/bundled-skills/acp/SKILL.md +6 -7
- package/src/config/bundled-skills/document-editor/SKILL.md +2 -2
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +14 -4
- package/src/config/bundled-skills/settings/TOOLS.json +3 -3
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.test.ts +65 -0
- package/src/config/bundled-skills/settings/tools/navigate-settings-tab.ts +7 -1
- package/src/config/bundled-skills/settings/tools/shared.ts +16 -0
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +19 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.test.ts +22 -1
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +9 -2
- package/src/config/call-site-defaults.ts +4 -5
- package/src/config/default-profile-catalog.ts +83 -12
- package/src/config/default-profile-names.ts +4 -1
- package/src/config/default-provider-resolution.ts +4 -0
- package/src/config/llm-context-resolution.ts +11 -3
- package/src/config/llm-resolver.ts +28 -1
- package/src/config/profile-materialization.ts +70 -22
- package/src/config/schemas/__tests__/live-voice.test.ts +107 -4
- package/src/config/schemas/call-site-catalog.ts +4 -4
- package/src/config/schemas/live-voice.ts +57 -23
- package/src/config/schemas/llm.ts +59 -32
- package/src/config/schemas/mcp.ts +23 -0
- package/src/config/schemas/plugin-updates.ts +6 -2
- package/src/config/schemas/stt.ts +1 -0
- package/src/context/outbound-sanitize.ts +96 -1
- package/src/daemon/__tests__/plugin-mcp-reconcile.test.ts +82 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +15 -10
- package/src/daemon/conversation-agent-loop.ts +17 -6
- package/src/daemon/conversation-messaging.ts +5 -1
- package/src/daemon/conversation-notifiers.ts +9 -1
- package/src/daemon/conversation-process.ts +36 -6
- package/src/daemon/conversation-runtime-assembly.ts +3 -4
- package/src/daemon/conversation-surfaces.ts +27 -5
- package/src/daemon/conversation-tool-setup.ts +1 -2
- package/src/daemon/conversation.ts +48 -0
- package/src/daemon/interactive-turn-sender.ts +59 -0
- package/src/daemon/mcp-reload-service.ts +36 -6
- package/src/daemon/process-message.ts +24 -24
- package/src/daemon/providers-setup.ts +6 -3
- package/src/daemon/trust-context-types.ts +29 -0
- package/src/daemon/wake-conversation-ops.ts +3 -2
- package/src/documents/document-store.ts +138 -5
- package/src/hooks/hook-loader.ts +3 -3
- package/src/hooks/registry.ts +50 -6
- package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- package/src/live-voice/__tests__/live-voice-agent-turn.test.ts +1 -104
- package/src/live-voice/__tests__/live-voice-events.test.ts +7 -8
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +932 -0
- package/src/live-voice/__tests__/live-voice-metrics.test.ts +115 -8
- package/src/live-voice/__tests__/live-voice-photo.test.ts +100 -0
- package/src/live-voice/__tests__/live-voice-progress.test.ts +60 -194
- package/src/live-voice/__tests__/live-voice-stt.test.ts +14 -0
- package/src/live-voice/__tests__/live-voice-triage-escalate.test.ts +29 -0
- package/src/live-voice/__tests__/live-voice-tts-session.test.ts +0 -483
- package/src/live-voice/__tests__/live-voice-vad.test.ts +0 -16
- package/src/live-voice/__tests__/progress-narration.test.ts +214 -0
- package/src/live-voice/live-voice-archive.ts +2 -0
- package/src/live-voice/live-voice-metrics.ts +57 -32
- package/src/live-voice/live-voice-photo.ts +1 -2
- package/src/live-voice/live-voice-session.ts +535 -314
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/protocol.ts +21 -1
- package/src/mcp/__tests__/effective-config.test.ts +238 -0
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +0 -1
- package/src/mcp/__tests__/mcp-oauth-client-registration.test.ts +200 -0
- package/src/mcp/__tests__/mcp-oauth-provider.test.ts +9 -9
- package/src/mcp/__tests__/plugin-server-credential-isolation.test.ts +95 -0
- package/src/mcp/client.ts +16 -11
- package/src/mcp/effective-config.ts +113 -0
- package/src/mcp/manager.ts +11 -6
- package/src/mcp/mcp-auth-orchestrator.ts +13 -22
- package/src/mcp/mcp-oauth-provider.ts +205 -240
- package/src/monitoring/__tests__/plugin-auto-update.test.ts +166 -3
- package/src/monitoring/plugin-auto-update.ts +128 -24
- package/src/notifications/signal.ts +1 -0
- package/src/permissions/confirmation-guardian-request.test.ts +15 -11
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/question-guardian-request.test.ts +14 -6
- package/src/permissions/question-guardian-request.ts +1 -2
- package/src/persistence/attachments-store.ts +8 -1
- package/src/persistence/bookmark-crud.ts +3 -7
- package/src/persistence/conversation-attention-store.ts +16 -45
- package/src/persistence/conversation-crud.ts +33 -4
- package/src/persistence/conversation-lineage.ts +9 -0
- package/src/persistence/conversation-queries.ts +108 -41
- package/src/persistence/delivery-crud.ts +38 -29
- package/src/persistence/external-conversation-store.ts +32 -4
- package/src/persistence/llm-request-log-store.ts +4 -10
- package/src/persistence/llm-usage-store.ts +8 -3
- package/src/persistence/message-reads.test.ts +197 -0
- package/src/persistence/message-reads.ts +211 -0
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.test.ts +120 -0
- package/src/persistence/migrations/366-chatgpt-subscription-row-identity.ts +62 -0
- package/src/persistence/real-user-turn-filter.ts +27 -3
- package/src/persistence/steps.ts +9 -0
- package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/conversation-turn.ts +168 -5
- package/src/plugin-api/index.ts +21 -5
- package/src/plugin-api/vision-support.test.ts +1 -1
- package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
- package/src/plugins/defaults/memory/AGENTS.md +4 -0
- package/src/plugins/defaults/memory/__tests__/buffer-format.test.ts +204 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-accounting.test.ts +72 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +4 -1
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +4 -1
- package/src/plugins/defaults/memory/buffer-format.ts +165 -0
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +6 -0
- package/src/plugins/defaults/memory/graph/image-ref-utils.ts +3 -0
- package/src/plugins/defaults/memory/graph/tool-handlers.ts +1 -30
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.test.ts +34 -0
- package/src/plugins/defaults/memory/graph-topology/pending-buffer.ts +8 -12
- package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
- package/src/plugins/defaults/memory/indexer.ts +3 -1
- package/src/plugins/defaults/memory/memory-retrospective-accounting.ts +19 -7
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +33 -0
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +199 -2
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +25 -18
- package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
- package/src/plugins/defaults/memory/substrate/static-context.ts +160 -4
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +2 -4
- package/src/plugins/defaults/memory/v1/graph/extraction.ts +3 -1
- package/src/plugins/defaults/memory/v3/prune.ts +2 -0
- package/src/plugins/defaults/memory/v3/selection-log-store.ts +2 -0
- package/src/plugins/defaults/memory/worker.ts +6 -3
- package/src/plugins/external-plugin-loader.ts +47 -0
- package/src/plugins/mcp-servers.ts +361 -0
- package/src/plugins/mtime-cache.ts +23 -49
- package/src/plugins/worker-plugin-surface.ts +33 -0
- package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
- package/src/providers/__tests__/dispatch-connection-routing.test.ts +214 -2
- package/src/providers/__tests__/preflight-resolved-config.test.ts +57 -0
- package/src/providers/__tests__/retry-callsite.test.ts +5 -2
- package/src/providers/call-site-routing.ts +30 -3
- package/src/providers/connection-resolution.ts +194 -11
- package/src/providers/inference/auth.ts +6 -0
- package/src/providers/inference/connection-availability.ts +24 -2
- package/src/providers/inference/connections.ts +2 -0
- package/src/providers/model-catalog.ts +3 -3
- package/src/providers/model-intents.ts +28 -8
- package/src/providers/openai/chat-completions-provider.ts +5 -6
- package/src/providers/openai/codex-models.ts +2 -1
- package/src/providers/provider-send-message.ts +32 -3
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +433 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +620 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +34 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +285 -6
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +395 -0
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +719 -0
- package/src/providers/speech-to-text/provider-catalog.ts +99 -8
- package/src/providers/speech-to-text/resolve.ts +25 -2
- package/src/routes/worker.ts +17 -5
- package/src/runtime/access-request-helper.ts +9 -12
- package/src/runtime/agent-wake.ts +3 -3
- package/src/runtime/pre-first-message-gate.ts +4 -0
- package/src/runtime/routes/__tests__/acp-claude-auth-routes.test.ts +12 -4
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +219 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +52 -0
- package/src/runtime/routes/__tests__/default-provider-routes.test.ts +61 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +44 -0
- package/src/runtime/routes/__tests__/inference-provider-connection-routes.test.ts +102 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +44 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +62 -1
- package/src/runtime/routes/channel-availability-routes.ts +32 -14
- package/src/runtime/routes/channel-route-shared.ts +0 -6
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +6 -6
- package/src/runtime/routes/conversation-list-routes.ts +112 -1
- package/src/runtime/routes/conversation-query-routes.ts +40 -27
- package/src/runtime/routes/credential-prompt-routes.ts +4 -7
- package/src/runtime/routes/default-provider-routes.ts +15 -0
- package/src/runtime/routes/inbound-message-handler.ts +17 -41
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +0 -9
- package/src/runtime/routes/inbound-stages/admission-policy.ts +1 -17
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/bootstrap-intercept.ts +2 -3
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +1 -3
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +3 -4
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +11 -20
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +2 -3
- package/src/runtime/routes/inference-profiles-routes.ts +20 -11
- package/src/runtime/routes/inference-provider-connection-routes.ts +77 -15
- package/src/runtime/routes/log-export-routes.ts +3 -0
- package/src/runtime/routes/mcp-auth-routes.ts +148 -57
- package/src/runtime/routes/plugins-routes.ts +21 -3
- package/src/runtime/routes/stt-routes.ts +31 -25
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
- package/src/runtime/routes/user-route-dispatcher.ts +39 -14
- package/src/runtime/routes/user-route-import.ts +108 -0
- package/src/schedule/worker.ts +6 -0
- package/src/security/oauth2.ts +6 -22
- package/src/stt/__tests__/daemon-batch-transcriber.test.ts +22 -0
- package/src/stt/__tests__/types.test.ts +94 -0
- package/src/stt/daemon-batch-transcriber.ts +10 -0
- package/src/stt/stt-stream-session.ts +8 -4
- package/src/stt/types.ts +103 -0
- package/src/subagent/manager.ts +1 -3
- package/src/subagent/types.ts +7 -6
- package/src/tools/acp/spawn.test.ts +97 -0
- package/src/tools/acp/spawn.ts +32 -0
- package/src/tools/document/document-tool.ts +12 -3
- package/src/tools/registry.ts +2 -1
- package/src/tools/ui-surface/surface-shape-docs.ts +11 -0
- package/src/tools/workflows/run-workflow.ts +1 -2
- package/src/tts/__tests__/reasoning-tag-filter.test.ts +78 -0
- package/src/tts/reasoning-tag-filter.ts +89 -0
- package/src/util/think-tag-stream.ts +95 -0
- package/src/workspace/byok-default-profile-ensure.ts +76 -24
- package/src/workspace/custom-profile-ensure.ts +4 -24
- package/src/workspace/migrations/142-consolidate-voice-front-door.ts +70 -0
- package/src/workspace/migrations/143-repair-deprecated-codex-model-id.ts +134 -0
- package/src/workspace/migrations/144-convert-stranded-subscription-openai-profiles.ts +265 -0
- package/src/workspace/migrations/145-collapse-profile-bindings-to-entries.ts +328 -0
- package/src/workspace/migrations/146-repair-retired-fireworks-deepseek-flash-model-id.ts +195 -0
- package/src/workspace/migrations/__tests__/141-stt-english-default-to-multilingual.test.ts +0 -10
- package/src/workspace/migrations/registry.ts +10 -0
- package/src/workspace/provider-commit-message-generator.ts +7 -5
- package/src/live-voice/__tests__/front-decision.test.ts +0 -645
- package/src/live-voice/front-decision.ts +0 -476
|
@@ -103,6 +103,7 @@ mock.module("../daemon/date-context.js", () => ({
|
|
|
103
103
|
formatTurnTimestamp: () => FIXED_TURN_TIMESTAMP,
|
|
104
104
|
}));
|
|
105
105
|
|
|
106
|
+
import type { SurfaceDataByType } from "../api/surfaces.js";
|
|
106
107
|
import { resolveCallSiteConfig } from "../config/llm-resolver.js";
|
|
107
108
|
import { LLMSchema } from "../config/schemas/llm.js";
|
|
108
109
|
import { REFUSAL_FALLBACK_TEXT } from "../context/refusal-quarantine.js";
|
|
@@ -136,7 +137,7 @@ import {
|
|
|
136
137
|
stripInjectionsForCompaction,
|
|
137
138
|
stripNowScratchpad,
|
|
138
139
|
} from "../daemon/conversation-runtime-assembly.js";
|
|
139
|
-
import type {
|
|
140
|
+
import type { SurfaceStateEntry } from "../daemon/conversation-surface-state.js";
|
|
140
141
|
import { buildPkbReminder } from "../daemon/pkb-reminder-builder.js";
|
|
141
142
|
import type { TrustContext } from "../daemon/trust-context-types.js";
|
|
142
143
|
import {
|
|
@@ -161,6 +162,7 @@ import { wrapUntrustedContent } from "../security/untrusted-content.js";
|
|
|
161
162
|
import { getSubagentManager } from "../subagent/index.js";
|
|
162
163
|
import type { SubagentState } from "../subagent/types.js";
|
|
163
164
|
import { getWorkspacePromptPath } from "../util/platform.js";
|
|
165
|
+
import { asConversation } from "./helpers/mock-conversation.js";
|
|
164
166
|
|
|
165
167
|
// `applyRuntimeInjections` self-resolves the Slack active-thread focus block by
|
|
166
168
|
// reading the live conversation's persisted message rows, so the schema must
|
|
@@ -215,27 +217,30 @@ function seedActiveSurfaceConversation(
|
|
|
215
217
|
conversationId: string,
|
|
216
218
|
workspaceText: string,
|
|
217
219
|
surfaceId: string,
|
|
218
|
-
data:
|
|
220
|
+
data: SurfaceDataByType["dynamic_page"],
|
|
219
221
|
channelCapabilities?: ChannelCapabilities,
|
|
220
222
|
commandIntent?: { type: string; payload?: string; languageCode?: string },
|
|
221
223
|
currentTurnTemporalSnapshot?: {
|
|
222
224
|
clientTimezone: string | null;
|
|
225
|
+
timeSinceLastMessage: string | null;
|
|
223
226
|
},
|
|
224
227
|
): void {
|
|
225
|
-
setConversation(
|
|
228
|
+
setConversation(
|
|
226
229
|
conversationId,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
230
|
+
asConversation({
|
|
231
|
+
conversationId,
|
|
232
|
+
workingDir: "/sandbox",
|
|
233
|
+
workspaceTopLevelContext: workspaceText,
|
|
234
|
+
workspaceTopLevelDirty: false,
|
|
235
|
+
currentActiveSurfaceId: surfaceId,
|
|
236
|
+
surfaceState: new Map<string, SurfaceStateEntry>([
|
|
237
|
+
[surfaceId, { surfaceType: "dynamic_page", data }],
|
|
238
|
+
]),
|
|
239
|
+
channelCapabilities: channelCapabilities ?? undefined,
|
|
240
|
+
commandIntent,
|
|
241
|
+
currentTurnTemporalSnapshot,
|
|
242
|
+
}),
|
|
243
|
+
);
|
|
239
244
|
}
|
|
240
245
|
|
|
241
246
|
function clearWorkspaceContext(): void {
|
|
@@ -252,15 +257,18 @@ function seedChannelCapabilitiesConversation(
|
|
|
252
257
|
caps: ChannelCapabilities | null,
|
|
253
258
|
transportHints?: string[],
|
|
254
259
|
): void {
|
|
255
|
-
setConversation(
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
260
|
+
setConversation(
|
|
261
|
+
"runtime-assembly-fallback",
|
|
262
|
+
asConversation({
|
|
263
|
+
conversationId: "runtime-assembly-fallback",
|
|
264
|
+
workingDir: "/sandbox",
|
|
265
|
+
workspaceTopLevelContext: "",
|
|
266
|
+
workspaceTopLevelDirty: false,
|
|
267
|
+
surfaceState: new Map(),
|
|
268
|
+
channelCapabilities: caps ?? undefined,
|
|
269
|
+
transportHints,
|
|
270
|
+
}),
|
|
271
|
+
);
|
|
264
272
|
}
|
|
265
273
|
|
|
266
274
|
// ---------------------------------------------------------------------------
|
|
@@ -986,6 +994,7 @@ describe("applyRuntimeInjections — injection mode", () => {
|
|
|
986
994
|
{ type: "start" },
|
|
987
995
|
{
|
|
988
996
|
clientTimezone: null,
|
|
997
|
+
timeSinceLastMessage: null,
|
|
989
998
|
},
|
|
990
999
|
);
|
|
991
1000
|
});
|
|
@@ -1023,15 +1032,18 @@ describe("applyRuntimeInjections — injection mode", () => {
|
|
|
1023
1032
|
// rehydration-order tests in conversation-lifecycle.test.ts). background-turn
|
|
1024
1033
|
// fires only for a background/scheduled live conversation, so register one
|
|
1025
1034
|
// under the turn's conversation id.
|
|
1026
|
-
setConversation(
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
+
setConversation(
|
|
1036
|
+
"injection-mode-conv",
|
|
1037
|
+
asConversation({
|
|
1038
|
+
conversationId: "injection-mode-conv",
|
|
1039
|
+
workingDir: "/sandbox",
|
|
1040
|
+
workspaceTopLevelContext: "",
|
|
1041
|
+
workspaceTopLevelDirty: false,
|
|
1042
|
+
surfaceState: new Map(),
|
|
1043
|
+
channelCapabilities,
|
|
1044
|
+
conversationType: "background",
|
|
1045
|
+
}),
|
|
1046
|
+
);
|
|
1035
1047
|
|
|
1036
1048
|
const { blocks } = await applyRuntimeInjections(baseMessages, fullOptions);
|
|
1037
1049
|
|
|
@@ -2227,20 +2239,24 @@ describe("applyRuntimeInjections with unifiedTurnContext", () => {
|
|
|
2227
2239
|
// context (so the injector sources the interface label to match
|
|
2228
2240
|
// `sampleOptions.interfaceName`).
|
|
2229
2241
|
function seedTemporalSnapshot(): void {
|
|
2230
|
-
setConversation(
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2242
|
+
setConversation(
|
|
2243
|
+
"runtime-assembly-fallback",
|
|
2244
|
+
asConversation({
|
|
2245
|
+
conversationId: "runtime-assembly-fallback",
|
|
2246
|
+
workingDir: "/sandbox",
|
|
2247
|
+
workspaceTopLevelContext: "",
|
|
2248
|
+
workspaceTopLevelDirty: false,
|
|
2249
|
+
surfaceState: new Map(),
|
|
2250
|
+
currentTurnTemporalSnapshot: {
|
|
2251
|
+
clientTimezone: null,
|
|
2252
|
+
timeSinceLastMessage: null,
|
|
2253
|
+
},
|
|
2254
|
+
currentTurnInterfaceContext: {
|
|
2255
|
+
userMessageInterface: "macos",
|
|
2256
|
+
assistantMessageInterface: "macos",
|
|
2257
|
+
},
|
|
2258
|
+
}),
|
|
2259
|
+
);
|
|
2244
2260
|
}
|
|
2245
2261
|
|
|
2246
2262
|
test("injects the turn-context block when the inputs are provided", async () => {
|
|
@@ -2327,17 +2343,20 @@ describe("applyRuntimeInjections timezone resolution", () => {
|
|
|
2327
2343
|
clientTimezone: string | null,
|
|
2328
2344
|
timeSinceLastMessage: string | null = null,
|
|
2329
2345
|
): void {
|
|
2330
|
-
setConversation(
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2346
|
+
setConversation(
|
|
2347
|
+
"runtime-assembly-fallback",
|
|
2348
|
+
asConversation({
|
|
2349
|
+
conversationId: "runtime-assembly-fallback",
|
|
2350
|
+
workingDir: "/sandbox",
|
|
2351
|
+
workspaceTopLevelContext: "",
|
|
2352
|
+
workspaceTopLevelDirty: false,
|
|
2353
|
+
surfaceState: new Map(),
|
|
2354
|
+
currentTurnTemporalSnapshot: {
|
|
2355
|
+
clientTimezone,
|
|
2356
|
+
timeSinceLastMessage,
|
|
2357
|
+
},
|
|
2358
|
+
}),
|
|
2359
|
+
);
|
|
2341
2360
|
}
|
|
2342
2361
|
|
|
2343
2362
|
function injectedText(result: { messages: Message[] }): string {
|
|
@@ -2491,20 +2510,24 @@ describe("applyRuntimeInjections blocks.unifiedTurnContext", () => {
|
|
|
2491
2510
|
// context (so the injector sources the interface label to match
|
|
2492
2511
|
// `sampleOptions.interfaceName`).
|
|
2493
2512
|
function seedTemporalSnapshot(): void {
|
|
2494
|
-
setConversation(
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2513
|
+
setConversation(
|
|
2514
|
+
"runtime-assembly-fallback",
|
|
2515
|
+
asConversation({
|
|
2516
|
+
conversationId: "runtime-assembly-fallback",
|
|
2517
|
+
workingDir: "/sandbox",
|
|
2518
|
+
workspaceTopLevelContext: "",
|
|
2519
|
+
workspaceTopLevelDirty: false,
|
|
2520
|
+
surfaceState: new Map(),
|
|
2521
|
+
currentTurnTemporalSnapshot: {
|
|
2522
|
+
clientTimezone: null,
|
|
2523
|
+
timeSinceLastMessage: null,
|
|
2524
|
+
},
|
|
2525
|
+
currentTurnInterfaceContext: {
|
|
2526
|
+
userMessageInterface: "macos",
|
|
2527
|
+
assistantMessageInterface: "macos",
|
|
2528
|
+
},
|
|
2529
|
+
}),
|
|
2530
|
+
);
|
|
2508
2531
|
}
|
|
2509
2532
|
|
|
2510
2533
|
test("captures unifiedTurnContext when tail is a user message", async () => {
|
|
@@ -2688,15 +2711,18 @@ describe("applyRuntimeInjections — subagent status", () => {
|
|
|
2688
2711
|
// a fallback fake carrying that delegation for the seeded children to
|
|
2689
2712
|
// surface.
|
|
2690
2713
|
beforeEach(() => {
|
|
2691
|
-
setConversation(
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2714
|
+
setConversation(
|
|
2715
|
+
FALLBACK_CONVERSATION_ID,
|
|
2716
|
+
asConversation({
|
|
2717
|
+
conversationId: FALLBACK_CONVERSATION_ID,
|
|
2718
|
+
workingDir: "/sandbox",
|
|
2719
|
+
workspaceTopLevelContext: "",
|
|
2720
|
+
workspaceTopLevelDirty: false,
|
|
2721
|
+
surfaceState: new Map(),
|
|
2722
|
+
getSubagentChildren: () =>
|
|
2723
|
+
getSubagentManager().getChildrenOf(FALLBACK_CONVERSATION_ID),
|
|
2724
|
+
}),
|
|
2725
|
+
);
|
|
2700
2726
|
});
|
|
2701
2727
|
|
|
2702
2728
|
afterEach(() => {
|
|
@@ -2750,14 +2776,17 @@ describe("applyRuntimeInjections — subagent status", () => {
|
|
|
2750
2776
|
|
|
2751
2777
|
test("skips subagent status when the conversation is itself a subagent", async () => {
|
|
2752
2778
|
// GIVEN the live conversation is itself a subagent (no nesting)
|
|
2753
|
-
setConversation(
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2779
|
+
setConversation(
|
|
2780
|
+
"runtime-assembly-fallback",
|
|
2781
|
+
asConversation({
|
|
2782
|
+
conversationId: "runtime-assembly-fallback",
|
|
2783
|
+
workingDir: "/sandbox",
|
|
2784
|
+
workspaceTopLevelContext: "",
|
|
2785
|
+
workspaceTopLevelDirty: false,
|
|
2786
|
+
surfaceState: new Map(),
|
|
2787
|
+
isSubagent: true,
|
|
2788
|
+
}),
|
|
2789
|
+
);
|
|
2761
2790
|
// AND a child is registered under its id
|
|
2762
2791
|
seedSubagentChild(
|
|
2763
2792
|
"runtime-assembly-fallback",
|
|
@@ -4317,19 +4346,22 @@ describe("Slack channel chronological rendering — multi-thread", () => {
|
|
|
4317
4346
|
)
|
|
4318
4347
|
.run();
|
|
4319
4348
|
}
|
|
4320
|
-
setConversation(
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4349
|
+
setConversation(
|
|
4350
|
+
"runtime-assembly-fallback",
|
|
4351
|
+
asConversation({
|
|
4352
|
+
conversationId: "runtime-assembly-fallback",
|
|
4353
|
+
workingDir: "/sandbox",
|
|
4354
|
+
workspaceTopLevelContext: "",
|
|
4355
|
+
workspaceTopLevelDirty: false,
|
|
4356
|
+
surfaceState: new Map(),
|
|
4357
|
+
channelCapabilities: caps,
|
|
4358
|
+
trustContext: { trustClass: "guardian", sourceChannel: "vellum" },
|
|
4359
|
+
slackContextCompactionWatermarkTs:
|
|
4360
|
+
compaction.slackContextCompactionWatermarkTs ?? null,
|
|
4361
|
+
contextCompactedMessageCount:
|
|
4362
|
+
compaction.contextCompactedMessageCount ?? 0,
|
|
4363
|
+
}),
|
|
4364
|
+
);
|
|
4333
4365
|
}
|
|
4334
4366
|
|
|
4335
4367
|
// Re-run a Slack-channel turn through the public assembly path. The
|
|
@@ -9,6 +9,7 @@ import { applyRuntimeInjections } from "../daemon/conversation-runtime-assembly.
|
|
|
9
9
|
import type { SurfaceData, SurfaceType } from "../daemon/message-protocol.js";
|
|
10
10
|
import { registerDefaultPluginInjectors } from "../plugins/defaults/index.js";
|
|
11
11
|
import type { Message } from "../providers/types.js";
|
|
12
|
+
import { asConversation } from "./helpers/mock-conversation.js";
|
|
12
13
|
|
|
13
14
|
// Populate the injector registry with the default plugins' injectors the way
|
|
14
15
|
// bootstrap does in production, so `applyRuntimeInjections` walks a non-empty
|
|
@@ -33,16 +34,19 @@ const FALLBACK_CONVERSATION_ID = "runtime-assembly-fallback";
|
|
|
33
34
|
// injectors resolve their blocks from it (the orchestrator no longer threads
|
|
34
35
|
// workspace or active-surface content as options).
|
|
35
36
|
function registerFallbackConversation(fields: Record<string, unknown>): void {
|
|
36
|
-
setConversation(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
setConversation(
|
|
38
|
+
FALLBACK_CONVERSATION_ID,
|
|
39
|
+
asConversation({
|
|
40
|
+
conversationId: FALLBACK_CONVERSATION_ID,
|
|
41
|
+
workingDir: "/sandbox",
|
|
42
|
+
// Non-dirty empty workspace by default so the workspace-context injector
|
|
43
|
+
// skips both the filesystem rescan and the DB refresh unless a test
|
|
44
|
+
// explicitly seeds a block via `workspaceTopLevelContext`.
|
|
45
|
+
workspaceTopLevelContext: "",
|
|
46
|
+
workspaceTopLevelDirty: false,
|
|
47
|
+
...fields,
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
// Seed the live conversation registry with a pre-rendered top-level block. The
|
|
@@ -209,8 +209,8 @@ describe("credentials/prompt route", () => {
|
|
|
209
209
|
test("stores a non-slack credential to secure storage and reports the value as received", async () => {
|
|
210
210
|
/**
|
|
211
211
|
* The default delivery persists the value to secure storage and runs the
|
|
212
|
-
* manual-token connection sync. The message must name the outcome
|
|
213
|
-
* value is in hand
|
|
212
|
+
* manual-token connection sync. The message must name the outcome (the
|
|
213
|
+
* value is in hand) so a bare `ok: true` cannot be misread as "the prompt
|
|
214
214
|
* opened".
|
|
215
215
|
*/
|
|
216
216
|
// GIVEN a standard store-delivery prompt for a non-slack credential
|
|
@@ -236,15 +236,12 @@ describe("credentials/prompt route", () => {
|
|
|
236
236
|
|
|
237
237
|
test("every successful outcome states that the prompt has closed", async () => {
|
|
238
238
|
/**
|
|
239
|
-
* The prompt blocks until answered, so a caller reads the result only
|
|
240
|
-
* the secure input is gone.
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* the Aug 2026 Claude Code auth feedback. Every success path must say so,
|
|
244
|
-
* not just the plain vault write.
|
|
239
|
+
* The prompt blocks until answered, so a caller reads the result only once
|
|
240
|
+
* the secure input is gone. Every success path states the close, not just
|
|
241
|
+
* the plain vault write, so the result cannot be read as "the prompt is
|
|
242
|
+
* open, paste it there".
|
|
245
243
|
*/
|
|
246
|
-
const closed =
|
|
247
|
-
"The secure prompt has closed — do not ask the user to enter this value again.";
|
|
244
|
+
const closed = "The secure prompt has closed.";
|
|
248
245
|
|
|
249
246
|
// GIVEN a plain vault write
|
|
250
247
|
const stored = (await promptRoute!.handler({
|
|
@@ -53,6 +53,10 @@ describe("ensureCompleteCustomProfiles", () => {
|
|
|
53
53
|
ensureCompleteCustomProfiles(workspaceDir);
|
|
54
54
|
const saved = readProfiles().partial;
|
|
55
55
|
expect(saved.model).toBe("claude-haiku-4-5-20251001");
|
|
56
|
+
// This workspace has no connection rows, so the binding is unverifiable
|
|
57
|
+
// and passes through in the legacy field for the collapse migration to
|
|
58
|
+
// judge; with a verified row it would fold into the provider value (see
|
|
59
|
+
// profile-materialization.test.ts).
|
|
56
60
|
expect(saved.provider).toBe("anthropic");
|
|
57
61
|
expect(saved.provider_connection).toBe("anthropic-personal");
|
|
58
62
|
expect(saved.maxTokens).toBe(12345);
|
|
@@ -91,7 +95,7 @@ describe("ensureCompleteCustomProfiles", () => {
|
|
|
91
95
|
},
|
|
92
96
|
});
|
|
93
97
|
ensureCompleteCustomProfiles(workspaceDir);
|
|
94
|
-
expect(readProfiles().gpt.provider_connection).
|
|
98
|
+
expect(readProfiles().gpt.provider_connection).toBeUndefined();
|
|
95
99
|
expect(readProfiles().router.provider_connection).toBeUndefined();
|
|
96
100
|
});
|
|
97
101
|
|
|
@@ -342,7 +342,11 @@ describe("Discord access-request decisions stay out of the guild channel", () =>
|
|
|
342
342
|
test("no Discord delivery is ever addressed to the originating conversation", async () => {
|
|
343
343
|
// The umbrella invariant, swept across every decision this resolver takes,
|
|
344
344
|
// so a newly added action cannot quietly reintroduce the leak.
|
|
345
|
-
for (const action of [
|
|
345
|
+
for (const action of [
|
|
346
|
+
"verify_code",
|
|
347
|
+
"block",
|
|
348
|
+
"leave_unverified",
|
|
349
|
+
] as const) {
|
|
346
350
|
resetState();
|
|
347
351
|
const req = makeDiscordAccessRequest();
|
|
348
352
|
|
|
@@ -27,9 +27,9 @@ describe("the dm-marked Discord route", () => {
|
|
|
27
27
|
// regressed, the notice would fall through to the HTTP proxy, which cannot
|
|
28
28
|
// fetch a base-less URL: the delivery would vanish rather than error, and
|
|
29
29
|
// every behavioural assertion about where it landed would still pass.
|
|
30
|
-
expect(
|
|
31
|
-
"discord",
|
|
32
|
-
);
|
|
30
|
+
expect(
|
|
31
|
+
channelForCallback(resolveDeliverCallbackUrlForChannel("discord")!),
|
|
32
|
+
).toBe("discord");
|
|
33
33
|
});
|
|
34
34
|
});
|
|
35
35
|
|