@vellumai/assistant 0.11.3 → 0.11.4-dev.202608190019.b94dbf2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +9 -3
- package/ARCHITECTURE.md +32 -10
- package/docs/architecture/memory.md +43 -5
- package/docs/architecture/security.md +96 -152
- package/docs/architecture/turn-actor.md +70 -0
- package/docs/browser-use-architecture-phase2.md +128 -56
- package/docs/flux-turn-detection-spike.md +248 -0
- package/docs/guardian-request-flow.md +35 -0
- package/docs/stt-provider-onboarding.md +3 -1
- package/knip.json +3 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +34 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +166 -1
- package/node_modules/@vellumai/gateway-client/src/index.ts +2 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/url-normalization.test.ts +135 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +60 -0
- package/node_modules/@vellumai/service-contracts/src/url-normalization.ts +107 -0
- package/openapi.yaml +289 -113
- package/package.json +1 -1
- package/scripts/voice-ttft-spike.ts +3 -3
- package/scripts/write-plugin-api-shim.ts +10 -0
- package/src/__tests__/app-compiler.test.ts +38 -3
- package/src/__tests__/app-control-flow.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +2 -2
- package/src/__tests__/assistant-feature-flag-guard.test.ts +25 -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__/channel-inbound-disk-pressure.test.ts +4 -4
- package/src/__tests__/channel-setup-panel-ack.test.ts +1 -1
- package/src/__tests__/checker.test.ts +20 -314
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +6 -2
- package/src/__tests__/compaction-events.test.ts +8 -10
- package/src/__tests__/config-loader-backfill.test.ts +3 -3
- package/src/__tests__/config-schema.test.ts +25 -10
- package/src/__tests__/context-search-memory-v2-source.test.ts +0 -1
- 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 +32 -21
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-attention-store.test.ts +63 -0
- package/src/__tests__/conversation-confirmation-signals.test.ts +112 -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-load-history-repair.test.ts +209 -0
- package/src/__tests__/conversation-notifiers-provenance.test.ts +59 -0
- package/src/__tests__/conversation-queue.test.ts +154 -4
- package/src/__tests__/conversation-routes-disk-view.test.ts +1 -1
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +1 -1
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +9 -9
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +1 -1
- package/src/__tests__/conversation-routes-slash-commands.test.ts +1 -1
- package/src/__tests__/conversation-runtime-assembly.test.ts +187 -102
- package/src/__tests__/conversation-runtime-workspace.test.ts +14 -10
- package/src/__tests__/conversation-slash-queue.test.ts +3 -0
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-control.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-app-open.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-data-persist.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-history-restored-completion.test.ts +21 -14
- package/src/__tests__/conversation-surfaces-queued-emit.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-standalone.test.ts +1 -0
- package/src/__tests__/conversation-surfaces-state-update.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-table-action.test.ts +1 -1
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +1 -1
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +1 -1
- package/src/__tests__/credential-prompt-route.test.ts +7 -10
- package/src/__tests__/credential-security-invariants.test.ts +1 -0
- package/src/__tests__/cu-unified-flow.test.ts +1 -0
- package/src/__tests__/custom-profile-ensure.test.ts +5 -1
- package/src/__tests__/default-plugin-names-guard.test.ts +12 -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__/document-sync-tags.test.ts +0 -75
- package/src/__tests__/dynamic-skill-background-guard.test.ts +0 -2
- package/src/__tests__/edit-propagation.test.ts +107 -11
- package/src/__tests__/file-ops-service.test.ts +163 -30
- package/src/__tests__/filesystem-tools.test.ts +23 -24
- package/src/__tests__/gateway-only-guard.test.ts +2 -5
- package/src/__tests__/helpers/gateway-classify-mock.ts +27 -6
- package/src/__tests__/helpers/mock-actor-context.ts +49 -0
- package/src/__tests__/helpers/mock-conversation.ts +13 -1
- package/src/__tests__/host-file-read-tool.test.ts +16 -19
- package/src/__tests__/http-user-message-parity.test.ts +1 -1
- package/src/__tests__/init-feature-flag-overrides.test.ts +49 -0
- package/src/__tests__/injector-chain.test.ts +63 -41
- package/src/__tests__/injector-disk-pressure.test.ts +11 -23
- package/src/__tests__/inline-skill-load-permissions.test.ts +47 -36
- package/src/__tests__/llm-context-resolution.test.ts +73 -1
- package/src/__tests__/llm-schema.test.ts +5 -2
- package/src/__tests__/managed-skill-lifecycle.test.ts +7 -0
- package/src/__tests__/mcp-list-plugin-servers.test.ts +250 -0
- package/src/__tests__/media-generate-image.test.ts +131 -21
- package/src/__tests__/memory-retrieval-hook.test.ts +100 -7
- package/src/__tests__/messages-read-boundary-guard.test.ts +134 -0
- package/src/__tests__/mtime-cache.test.ts +3 -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__/platform-bash-auto-approve.test.ts +0 -4
- package/src/__tests__/plugin-api-store-credential.test.ts +261 -0
- package/src/__tests__/plugin-api-webhook-url.test.ts +10 -7
- package/src/__tests__/plugin-disabled-state.test.ts +2 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +55 -3
- package/src/__tests__/plugin-execution-context.test.ts +73 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
- package/src/__tests__/plugin-import-boundary-reverse-guard.test.ts +7 -4
- 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__/proxy-approval-callback.test.ts +1 -0
- package/src/__tests__/qdrant-manager.test.ts +14 -1
- package/src/__tests__/reaction-persistence.test.ts +200 -7
- package/src/__tests__/require-fresh-approval.test.ts +0 -4
- package/src/__tests__/risk-classification-boundary-guard.test.ts +115 -0
- package/src/__tests__/run-conversation-turn-persistence.test.ts +460 -105
- package/src/__tests__/run-due-schedules.test.ts +21 -0
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +187 -18
- package/src/__tests__/schedule-routes.test.ts +23 -0
- package/src/__tests__/schedule-store.test.ts +17 -0
- package/src/__tests__/scoped-approval-grants.test.ts +11 -6
- package/src/__tests__/secret-ingress-channel.test.ts +0 -1
- package/src/__tests__/secret-ingress-http.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +3 -3
- package/src/__tests__/skills.test.ts +32 -0
- package/src/__tests__/slack-edit-ordering-characterization.test.ts +0 -1
- package/src/__tests__/starter-task-flow.test.ts +5 -4
- package/src/__tests__/subagent-call-site-routing.test.ts +31 -19
- package/src/__tests__/subagent-fork-prompt-role.test.ts +1 -1
- package/src/__tests__/subagent-spawn-and-await.test.ts +18 -17
- package/src/__tests__/subagent-tool-gate-mode.test.ts +1 -1
- package/src/__tests__/subagent-tools.test.ts +81 -101
- package/src/__tests__/surface-completion-in-flight-snapshot.test.ts +1 -0
- package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +1 -1
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +132 -5
- package/src/__tests__/tool-executor.test.ts +68 -39
- package/src/__tests__/turn-events-store.test.ts +43 -0
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +1 -1
- package/src/__tests__/ui-shape-teaching.test.ts +33 -0
- package/src/__tests__/ui-visual-surface.test.ts +1 -1
- package/src/__tests__/ui-voice-picker-surface.test.ts +128 -0
- package/src/__tests__/ui-work-result-surface.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +3 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +0 -2
- package/src/__tests__/visible-app-context.test.ts +16 -9
- package/src/__tests__/voice-config-update.test.ts +40 -0
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +5 -3
- package/src/__tests__/voice-session-bridge.test.ts +85 -29
- 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 +76 -3
- package/src/api/events/acp-auth-required.ts +55 -0
- package/src/api/events/host-file.ts +2 -2
- package/src/api/index.ts +7 -0
- package/src/api/surfaces.ts +12 -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 +194 -11
- package/src/calls/__tests__/voice-triage-escalate.test.ts +102 -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 +115 -41
- package/src/calls/voice-triage-escalate.ts +105 -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/bundled-modules.ts +29 -0
- package/src/cli/commands/credentials.help.ts +2 -2
- package/src/cli/commands/db/repair.ts +4 -8
- package/src/cli/commands/domain.ts +6 -3
- package/src/cli/commands/email.ts +6 -3
- package/src/cli/commands/inference-providers.ts +1 -1
- package/src/cli/commands/keys.ts +8 -3
- package/src/cli/commands/mcp.help.ts +13 -4
- package/src/cli/commands/mcp.ts +9 -0
- package/src/cli/commands/memory/__tests__/memory-v2.test.ts +57 -7
- package/src/cli/commands/memory/__tests__/memory-v3.test.ts +128 -5
- package/src/cli/commands/memory/index.help.ts +84 -28
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/memory-v2.ts +58 -54
- package/src/cli/commands/memory/memory-v3.ts +64 -0
- package/src/cli/commands/memory/memory-validate.ts +18 -0
- package/src/cli/commands/plugins.ts +85 -36
- package/src/cli/commands/schedules.ts +35 -1
- package/src/cli/commands/stt.help.ts +27 -2
- package/src/cli/commands/trust.ts +3 -14
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +39 -0
- package/src/cli/lib/bundled-marketplace.json +14 -1
- package/src/cli/lib/upgrade-plugin.ts +42 -0
- package/src/config/__tests__/balanced-model-experiment.test.ts +278 -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/assistant-feature-flags.ts +36 -15
- package/src/config/balanced-model-experiment.ts +35 -0
- 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/image-studio/SKILL.md +5 -4
- package/src/config/bundled-skills/image-studio/TOOLS.json +1 -1
- package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +101 -0
- 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/skill-management/TOOLS.json +9 -3
- package/src/config/bundled-skills/subagent/SKILL.md +17 -12
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -4
- 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 +11 -5
- package/src/config/default-profile-catalog.ts +179 -16
- package/src/config/default-profile-names.ts +4 -1
- package/src/config/default-provider-resolution.ts +4 -0
- package/src/config/feature-flag-registry.json +12 -12
- 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/config/skills.ts +9 -2
- package/src/context/outbound-sanitize.ts +96 -1
- package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +1 -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 +31 -19
- package/src/daemon/conversation-messaging.ts +5 -1
- package/src/daemon/conversation-notifiers.ts +20 -10
- package/src/daemon/conversation-process.ts +20 -6
- package/src/daemon/conversation-runtime-assembly.ts +12 -6
- package/src/daemon/conversation-store.ts +14 -4
- package/src/daemon/conversation-surfaces.ts +75 -26
- package/src/daemon/conversation-tool-setup.ts +3 -6
- package/src/daemon/conversation.ts +154 -51
- package/src/daemon/doordash-steps.ts +2 -2
- package/src/daemon/lifecycle.ts +14 -1
- package/src/daemon/mcp-reload-service.ts +36 -6
- package/src/daemon/process-message.ts +13 -26
- package/src/daemon/providers-setup.ts +6 -3
- package/src/daemon/trust-context-types.ts +29 -0
- package/src/daemon/trust-context.ts +12 -7
- package/src/daemon/wake-conversation-ops.ts +3 -2
- package/src/daemon/windows-compiled-entry.ts +4 -0
- package/src/documents/document-store.ts +143 -240
- package/src/hooks/hook-loader.ts +3 -3
- package/src/hooks/registry.ts +103 -45
- package/src/hooks/types.ts +5 -0
- package/src/inbound/__tests__/oauth-callback-url.test.ts +83 -0
- package/src/inbound/oauth-callback-url.ts +61 -0
- package/src/ipc/gateway-client.test.ts +1 -1
- package/src/ipc/gateway-client.ts +14 -21
- package/src/ipc/gateway-flag-listener.ts +17 -3
- 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 +1050 -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-manager.ts +16 -3
- 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 +598 -323
- package/src/live-voice/progress-narration.ts +277 -0
- package/src/live-voice/protocol.ts +21 -1
- package/src/live-voice/windows-compiled-live-voice.ts +4 -0
- 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/control.ts +1 -0
- package/src/monitoring/db-integrity-sample.ts +4 -5
- package/src/monitoring/plugin-auto-update.ts +128 -24
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/approval-card-data.ts +33 -0
- package/src/notifications/signal.ts +1 -0
- package/src/permissions/AGENTS.md +16 -0
- package/src/permissions/checker.test.ts +75 -122
- package/src/permissions/checker.ts +44 -560
- package/src/permissions/confirmation-guardian-request.test.ts +15 -11
- package/src/permissions/confirmation-guardian-request.ts +2 -2
- package/src/permissions/prompter.ts +1 -5
- 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 +182 -52
- package/src/persistence/delivery-crud.ts +150 -36
- package/src/persistence/embeddings/qdrant-manager.ts +84 -49
- 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/360-add-document-workspace-path.ts +5 -14
- 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/schema/documents.ts +4 -4
- package/src/persistence/steps.ts +9 -0
- package/src/plugin-api/__tests__/oauth-callback-url-export.test.ts +29 -0
- package/src/plugin-api/constants.ts +8 -0
- package/src/plugin-api/conversation-turn.ts +195 -5
- package/src/plugin-api/index.ts +38 -6
- package/src/plugin-api/resolve-credential.ts +3 -2
- package/src/plugin-api/store-credential.ts +146 -0
- package/src/plugin-api/vision-support.test.ts +1 -1
- package/src/plugin-api/webhook-url.ts +13 -11
- package/src/plugins/__tests__/mcp-servers.test.ts +371 -0
- package/src/plugins/defaults/main.ts +21 -7
- package/src/plugins/defaults/memory/AGENTS.md +15 -3
- 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/__tests__/memory-tier-boundary-guard.test.ts +0 -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/__tests__/conversation-graph-memory-v2-routing.test.ts +77 -0
- package/src/plugins/defaults/memory/graph/conversation-graph-memory.ts +24 -6
- 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 +17 -24
- package/src/plugins/defaults/memory/hooks/post-compact.ts +1 -4
- package/src/plugins/defaults/memory/hooks/user-prompt-submit.ts +53 -5
- 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/memory-retrospective-job.ts +4 -4
- package/src/plugins/defaults/memory/src/__tests__/memory-v3-gate-stats.test.ts +281 -0
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +12 -10
- package/src/plugins/defaults/memory/src/memory-v3-routes.ts +207 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +147 -0
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-prompt-flag-gating-guard.test.ts +8 -0
- package/src/plugins/defaults/memory/substrate/__tests__/edge-index.test.ts +0 -30
- package/src/plugins/defaults/memory/substrate/__tests__/ingest.test.ts +73 -1
- package/src/plugins/defaults/memory/substrate/__tests__/page-index.test.ts +37 -0
- package/src/plugins/defaults/memory/substrate/__tests__/page-links.test.ts +208 -0
- package/src/plugins/defaults/memory/substrate/__tests__/prompts-consolidation.test.ts +158 -1
- package/src/plugins/defaults/memory/substrate/__tests__/static-context.test.ts +195 -58
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +93 -24
- package/src/plugins/defaults/memory/substrate/edge-index.ts +0 -31
- package/src/plugins/defaults/memory/substrate/ingest.ts +59 -0
- package/src/plugins/defaults/memory/substrate/page-index.ts +35 -8
- package/src/plugins/defaults/memory/substrate/page-links.ts +133 -0
- package/src/plugins/defaults/memory/substrate/page-store.ts +10 -0
- package/src/plugins/defaults/memory/substrate/prompts/consolidation.ts +124 -34
- package/src/plugins/defaults/memory/substrate/skill-content.ts +8 -1
- package/src/plugins/defaults/memory/substrate/static-context.ts +160 -33
- 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/__tests__/injection.test.ts +18 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +66 -1
- package/src/plugins/defaults/memory/v3/card.ts +9 -9
- package/src/plugins/defaults/memory/v3/core-set.test.ts +7 -0
- package/src/plugins/defaults/memory/v3/core-set.ts +5 -1
- package/src/plugins/defaults/memory/v3/edge.ts +13 -57
- package/src/plugins/defaults/memory/v3/injector.ts +8 -0
- 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/v3/shadow-plugin.ts +23 -9
- package/src/plugins/defaults/memory/worker-control.ts +1 -0
- package/src/plugins/defaults/memory/worker.ts +6 -3
- package/src/plugins/defaults/worker-entrypoints.ts +3 -0
- package/src/plugins/external-plugin-loader.ts +47 -0
- package/src/plugins/mcp-servers.ts +361 -0
- package/src/plugins/mtime-cache.ts +37 -46
- package/src/plugins/pipeline.ts +14 -7
- package/src/plugins/plugin-execution-context.ts +35 -11
- package/src/plugins/worker-plugin-surface.ts +33 -0
- package/src/prompts/templates/system-sections.ts +0 -7
- package/src/providers/__tests__/connection-model-compat.test.ts +1 -1
- package/src/providers/__tests__/context-overflow-error.test.ts +24 -0
- 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 +25 -2
- package/src/providers/anthropic/__tests__/pause-turn-continuation.test.ts +170 -0
- package/src/providers/anthropic/client.ts +332 -241
- package/src/providers/call-site-routing.ts +30 -3
- package/src/providers/connection-resolution.ts +194 -11
- package/src/providers/inference/__tests__/adapter-factory-openai-compatible.test.ts +4 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- 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/__tests__/chat-completions-provider-reasoning.test.ts +163 -40
- package/src/providers/openai/__tests__/tool-choice-mapping.test.ts +125 -2
- package/src/providers/openai/chat-completions-provider.ts +133 -36
- 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 +625 -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 +679 -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/control.ts +1 -0
- package/src/routes/route-host-client.ts +1 -0
- package/src/routes/route-host-protocol.ts +7 -0
- package/src/routes/worker.ts +48 -15
- package/src/runtime/AGENTS.md +16 -17
- package/src/runtime/access-request-helper.ts +9 -12
- package/src/runtime/agent-wake.ts +18 -15
- package/src/runtime/effective-capabilities.test.ts +43 -0
- package/src/runtime/effective-capabilities.ts +27 -0
- package/src/runtime/guardian-reply-router.ts +6 -2
- 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 +522 -2
- 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 +132 -35
- package/src/runtime/routes/__tests__/schedule-routes-disarm-reason.test.ts +215 -0
- package/src/runtime/routes/__tests__/stt-routes.test.ts +25 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +55 -6
- package/src/runtime/routes/__tests__/user-route-dispatcher-host.test.ts +52 -1
- package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +133 -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 +181 -23
- package/src/runtime/routes/conversation-management-routes.ts +17 -12
- package/src/runtime/routes/conversation-query-routes.ts +40 -27
- package/src/runtime/routes/conversation-routes.ts +43 -29
- package/src/runtime/routes/credential-prompt-routes.ts +4 -7
- package/src/runtime/routes/credential-routes.ts +26 -82
- package/src/runtime/routes/default-provider-routes.ts +15 -0
- package/src/runtime/routes/documents-routes.ts +3 -222
- package/src/runtime/routes/inbound-message-handler.ts +21 -45
- 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 +101 -79
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +0 -1
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +12 -7
- package/src/runtime/routes/inbound-stages/reaction-intercept.test.ts +91 -8
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +72 -79
- 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/playground/__tests__/inject-failures.test.ts +2 -0
- package/src/runtime/routes/playground/__tests__/reset-circuit.test.ts +3 -0
- package/src/runtime/routes/playground/inject-failures.ts +2 -2
- package/src/runtime/routes/playground/reset-circuit.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +38 -8
- package/src/runtime/routes/schedule-routes.ts +94 -7
- package/src/runtime/routes/settings-routes.ts +6 -6
- package/src/runtime/routes/stt-routes.ts +31 -25
- package/src/runtime/routes/surface-action-routes.ts +20 -19
- package/src/runtime/routes/surface-conversation-resolver.ts +3 -0
- package/src/runtime/routes/user-route-dispatcher.ts +69 -15
- package/src/runtime/routes/user-route-import.ts +108 -0
- package/src/runtime/routes/user-route-resolution.ts +18 -1
- package/src/runtime/routes/workspace-routes.ts +0 -9
- package/src/runtime/routes/workspace-utils.ts +3 -13
- package/src/runtime/services/conversation-serializer.ts +7 -2
- package/src/schedule/__tests__/plugin-schedule-declarations.test.ts +68 -5
- package/src/schedule/__tests__/plugin-schedule-reconciler.test.ts +81 -0
- package/src/schedule/plugin-schedule-availability.ts +58 -0
- package/src/schedule/plugin-schedule-declarations.ts +23 -27
- package/src/schedule/plugin-schedule-reconciler.ts +12 -3
- package/src/schedule/schedule-store.ts +5 -1
- package/src/schedule/scheduler.ts +9 -4
- package/src/schedule/worker-control.ts +1 -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/__tests__/consult-prompt.test.ts +26 -15
- package/src/subagent/consult-context.ts +11 -11
- package/src/subagent/consult-prompt.ts +26 -35
- package/src/subagent/manager.ts +21 -40
- package/src/subagent/notify.ts +7 -1
- package/src/subagent/types.ts +15 -12
- package/src/tools/__tests__/tool-input-schemas.test.ts +7 -7
- package/src/tools/acp/spawn.test.ts +97 -0
- package/src/tools/acp/spawn.ts +38 -4
- package/src/tools/credentials/ref-parse.ts +35 -0
- package/src/tools/credentials/resolve.ts +4 -10
- package/src/tools/credentials/store.ts +168 -0
- package/src/tools/document/document-tool.ts +12 -3
- package/src/tools/executor.ts +53 -15
- package/src/tools/filesystem/read.ts +27 -10
- package/src/tools/host-filesystem/read.ts +27 -15
- package/src/tools/network/url-safety.ts +9 -16
- package/src/tools/permission-checker.ts +43 -52
- package/src/tools/registry.ts +2 -1
- package/src/tools/shared/filesystem/file-ops-service.ts +63 -35
- package/src/tools/shared/filesystem/legacy-read-args.ts +22 -0
- package/src/tools/shared/filesystem/types.ts +5 -5
- package/src/tools/skills/scaffold-managed.ts +25 -7
- package/src/tools/subagent/spawn.ts +28 -88
- package/src/tools/tool-types.ts +26 -13
- package/src/tools/types.ts +6 -6
- package/src/tools/ui-surface/surface-shape-docs.ts +12 -1
- 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/__tests__/worker-process-command.test.ts +37 -0
- package/src/util/logger.ts +16 -0
- package/src/util/think-tag-stream.ts +95 -0
- package/src/util/worker-process.ts +37 -4
- package/src/windows-compiled-cli.ts +32 -0
- package/src/windows-compiled-entry.ts +4 -0
- package/src/windows-compiled-logger.ts +6 -0
- package/src/windows-compiled-worker-entry.ts +29 -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/__tests__/document-workspace-file.test.ts +0 -467
- package/src/live-voice/__tests__/front-decision.test.ts +0 -645
- package/src/live-voice/front-decision.ts +0 -476
- package/src/permissions/ipc-risk-types.ts +0 -143
- package/src/permissions/risk-types.ts +0 -76
- package/src/subagent/__tests__/consult-transcript.test.ts +0 -184
- package/src/subagent/consult-transcript.ts +0 -90
|
@@ -39,6 +39,7 @@ mock.module("../util/logger.js", () => ({
|
|
|
39
39
|
|
|
40
40
|
import {
|
|
41
41
|
installIpcMock,
|
|
42
|
+
lastIpcParams,
|
|
42
43
|
mockIpcResponse,
|
|
43
44
|
} from "./helpers/gateway-classify-mock.js";
|
|
44
45
|
installIpcMock();
|
|
@@ -53,7 +54,8 @@ function mockRisk(
|
|
|
53
54
|
mockIpcResponse("classify_risk", {
|
|
54
55
|
risk,
|
|
55
56
|
reason: "test fixture",
|
|
56
|
-
matchType: "
|
|
57
|
+
matchType: "registry",
|
|
58
|
+
scopeOptions: [],
|
|
57
59
|
...extras,
|
|
58
60
|
});
|
|
59
61
|
}
|
|
@@ -82,8 +84,6 @@ import * as envRegistry from "../config/env-registry.js";
|
|
|
82
84
|
import {
|
|
83
85
|
check,
|
|
84
86
|
classifyRisk,
|
|
85
|
-
clearRiskCache,
|
|
86
|
-
generateAllowlistOptions,
|
|
87
87
|
generateScopeOptions,
|
|
88
88
|
SCOPE_AWARE_TOOLS,
|
|
89
89
|
} from "../permissions/checker.js";
|
|
@@ -180,8 +180,6 @@ describe("Permission Checker", () => {
|
|
|
180
180
|
mockIpcResponse("get_global_thresholds", DEFAULT_GATEWAY_THRESHOLDS);
|
|
181
181
|
// Clear the gateway threshold cache so each test gets a fresh threshold read
|
|
182
182
|
_clearGlobalCacheForTesting();
|
|
183
|
-
// Reset trust-store state and risk classification cache between tests
|
|
184
|
-
clearRiskCache();
|
|
185
183
|
// Reset guardian persona mock so each test opts in explicitly
|
|
186
184
|
mockGuardianPersonaPath = null;
|
|
187
185
|
loggerWarnCalls.length = 0;
|
|
@@ -447,268 +445,6 @@ describe("Permission Checker", () => {
|
|
|
447
445
|
});
|
|
448
446
|
});
|
|
449
447
|
|
|
450
|
-
// ── generateAllowlistOptions ───────────────────────────────────
|
|
451
|
-
|
|
452
|
-
describe("generateAllowlistOptions", () => {
|
|
453
|
-
test("file_write: generates prefixed file, ancestor directory wildcards, and tool wildcard", async () => {
|
|
454
|
-
const options = await generateAllowlistOptions("file_write", {
|
|
455
|
-
path: "/home/user/project/file.ts",
|
|
456
|
-
});
|
|
457
|
-
expect(options).toHaveLength(5);
|
|
458
|
-
// Patterns are prefixed with tool name to match check()'s "tool:path" format
|
|
459
|
-
expect(options[0].pattern).toBe("file_write:/home/user/project/file.ts");
|
|
460
|
-
expect(options[1].pattern).toBe("file_write:/home/user/project/**");
|
|
461
|
-
expect(options[2].pattern).toBe("file_write:/home/user/**");
|
|
462
|
-
expect(options[3].pattern).toBe("file_write:/home/**");
|
|
463
|
-
expect(options[4].pattern).toBe("file_write:*");
|
|
464
|
-
// Labels stay user-friendly
|
|
465
|
-
expect(options[0].label).toBe("/home/user/project/file.ts");
|
|
466
|
-
expect(options[1].label).toBe("/home/user/project/**");
|
|
467
|
-
});
|
|
468
|
-
|
|
469
|
-
test("file_read: generates prefixed file, directory, and tool wildcard", async () => {
|
|
470
|
-
const options = await generateAllowlistOptions("file_read", {
|
|
471
|
-
path: "/tmp/data.json",
|
|
472
|
-
});
|
|
473
|
-
expect(options).toHaveLength(3);
|
|
474
|
-
expect(options[0].pattern).toBe("file_read:/tmp/data.json");
|
|
475
|
-
expect(options[1].pattern).toBe("file_read:/tmp/**");
|
|
476
|
-
expect(options[2].pattern).toBe("file_read:*");
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
test("host_file_read: generates prefixed file, directory, and tool wildcard", async () => {
|
|
480
|
-
const options = await generateAllowlistOptions("host_file_read", {
|
|
481
|
-
path: "/etc/hosts",
|
|
482
|
-
});
|
|
483
|
-
expect(options).toHaveLength(3);
|
|
484
|
-
expect(options[0].pattern).toBe("host_file_read:/etc/hosts");
|
|
485
|
-
expect(options[1].pattern).toBe("host_file_read:/etc/**");
|
|
486
|
-
expect(options[2].pattern).toBe("host_file_read:*");
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
test("host_file_write with file_path key", async () => {
|
|
490
|
-
const options = await generateAllowlistOptions("host_file_write", {
|
|
491
|
-
file_path: "/tmp/out.txt",
|
|
492
|
-
});
|
|
493
|
-
expect(options[0].pattern).toBe("host_file_write:/tmp/out.txt");
|
|
494
|
-
expect(options[1].pattern).toBe("host_file_write:/tmp/**");
|
|
495
|
-
expect(options[2].pattern).toBe("host_file_write:*");
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
test("file_write with file_path key", async () => {
|
|
499
|
-
const options = await generateAllowlistOptions("file_write", {
|
|
500
|
-
file_path: "/tmp/out.txt",
|
|
501
|
-
});
|
|
502
|
-
expect(options[0].pattern).toBe("file_write:/tmp/out.txt");
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
test("unknown tool returns wildcard", async () => {
|
|
506
|
-
const options = await generateAllowlistOptions("other_tool", {
|
|
507
|
-
foo: "bar",
|
|
508
|
-
});
|
|
509
|
-
expect(options).toHaveLength(1);
|
|
510
|
-
expect(options[0].pattern).toBe("*");
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
test("web_fetch: generates exact url, origin wildcard, and tool wildcard", async () => {
|
|
514
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
515
|
-
url: "https://example.com/docs/page",
|
|
516
|
-
});
|
|
517
|
-
expect(options).toHaveLength(3);
|
|
518
|
-
expect(options[0].pattern).toBe(
|
|
519
|
-
"web_fetch:https://example.com/docs/page",
|
|
520
|
-
);
|
|
521
|
-
expect(options[1].pattern).toBe("web_fetch:https://example.com/*");
|
|
522
|
-
expect(options[2].pattern).toBe("**");
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
test("web_fetch: strips fragments when generating allowlist options", async () => {
|
|
526
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
527
|
-
url: "https://example.com/docs/page#section-1",
|
|
528
|
-
});
|
|
529
|
-
expect(options).toHaveLength(3);
|
|
530
|
-
expect(options[0].pattern).toBe(
|
|
531
|
-
"web_fetch:https://example.com/docs/page",
|
|
532
|
-
);
|
|
533
|
-
expect(options[1].pattern).toBe("web_fetch:https://example.com/*");
|
|
534
|
-
expect(options[2].pattern).toBe("**");
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
test("web_fetch: strips trailing-dot hostnames when generating allowlist options", async () => {
|
|
538
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
539
|
-
url: "https://example.com./docs/page",
|
|
540
|
-
});
|
|
541
|
-
expect(options).toHaveLength(3);
|
|
542
|
-
expect(options[0].pattern).toBe(
|
|
543
|
-
"web_fetch:https://example.com/docs/page",
|
|
544
|
-
);
|
|
545
|
-
expect(options[1].pattern).toBe("web_fetch:https://example.com/*");
|
|
546
|
-
expect(options[2].pattern).toBe("**");
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
test("web_fetch: strips userinfo when generating allowlist options", async () => {
|
|
550
|
-
const username = "demo";
|
|
551
|
-
const credential = ["c", "r", "e", "d", "1", "2", "3"].join("");
|
|
552
|
-
const credentialedUrl = new URL("https://example.com/docs/page");
|
|
553
|
-
credentialedUrl.username = username;
|
|
554
|
-
credentialedUrl.password = credential;
|
|
555
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
556
|
-
url: credentialedUrl.href,
|
|
557
|
-
});
|
|
558
|
-
expect(options).toHaveLength(3);
|
|
559
|
-
expect(options[0].pattern).toBe(
|
|
560
|
-
"web_fetch:https://example.com/docs/page",
|
|
561
|
-
);
|
|
562
|
-
expect(options[1].pattern).toBe("web_fetch:https://example.com/*");
|
|
563
|
-
expect(options[2].pattern).toBe("**");
|
|
564
|
-
expect(options[0].pattern).not.toContain("demo:cred123@");
|
|
565
|
-
});
|
|
566
|
-
|
|
567
|
-
test("web_fetch: normalizes scheme-less host:port for allowlist options", async () => {
|
|
568
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
569
|
-
url: "example.com:8443/docs/page",
|
|
570
|
-
});
|
|
571
|
-
expect(options).toHaveLength(3);
|
|
572
|
-
expect(options[0].pattern).toBe(
|
|
573
|
-
"web_fetch:https://example.com:8443/docs/page",
|
|
574
|
-
);
|
|
575
|
-
expect(options[1].pattern).toBe("web_fetch:https://example.com:8443/*");
|
|
576
|
-
expect(options[2].pattern).toBe("**");
|
|
577
|
-
});
|
|
578
|
-
|
|
579
|
-
test("web_fetch: does not coerce path-only urls to https hostnames in allowlist options", async () => {
|
|
580
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
581
|
-
url: "/docs/getting-started",
|
|
582
|
-
});
|
|
583
|
-
expect(options).toHaveLength(2);
|
|
584
|
-
expect(options[0].pattern).toBe("web_fetch:/docs/getting-started");
|
|
585
|
-
expect(options[1].pattern).toBe("**");
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
test("scaffold_managed_skill: generates per-skill and wildcard options", async () => {
|
|
589
|
-
const options = await generateAllowlistOptions("scaffold_managed_skill", {
|
|
590
|
-
skill_id: "my-tool",
|
|
591
|
-
});
|
|
592
|
-
expect(options).toHaveLength(2);
|
|
593
|
-
expect(options[0].label).toBe("my-tool");
|
|
594
|
-
expect(options[0].pattern).toBe("scaffold_managed_skill:my-tool");
|
|
595
|
-
expect(options[0].description).toBe("This skill only");
|
|
596
|
-
expect(options[1].label).toBe("scaffold_managed_skill:*");
|
|
597
|
-
expect(options[1].pattern).toBe("scaffold_managed_skill:*");
|
|
598
|
-
expect(options[1].description).toBe("All managed skill scaffolds");
|
|
599
|
-
});
|
|
600
|
-
|
|
601
|
-
test("delete_managed_skill: generates per-skill and wildcard options", async () => {
|
|
602
|
-
const options = await generateAllowlistOptions("delete_managed_skill", {
|
|
603
|
-
skill_id: "doomed",
|
|
604
|
-
});
|
|
605
|
-
expect(options).toHaveLength(2);
|
|
606
|
-
expect(options[0].pattern).toBe("delete_managed_skill:doomed");
|
|
607
|
-
expect(options[1].pattern).toBe("delete_managed_skill:*");
|
|
608
|
-
expect(options[1].description).toBe("All managed skill deletes");
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
test("scaffold_managed_skill with empty skill_id: only wildcard option", async () => {
|
|
612
|
-
const options = await generateAllowlistOptions("scaffold_managed_skill", {
|
|
613
|
-
skill_id: "",
|
|
614
|
-
});
|
|
615
|
-
expect(options).toHaveLength(1);
|
|
616
|
-
expect(options[0].pattern).toBe("scaffold_managed_skill:*");
|
|
617
|
-
});
|
|
618
|
-
|
|
619
|
-
test("web_fetch: escapes minimatch metacharacters in generated exact and origin patterns", async () => {
|
|
620
|
-
const options = await generateAllowlistOptions("web_fetch", {
|
|
621
|
-
url: "https://[2001:db8::1]/search?q=test",
|
|
622
|
-
});
|
|
623
|
-
expect(options).toHaveLength(3);
|
|
624
|
-
expect(options[0].label).toBe("https://[2001:db8::1]/search?q=test");
|
|
625
|
-
expect(options[0].pattern).toBe(
|
|
626
|
-
"web_fetch:https://\\[2001:db8::1\\]/search\\?q=test",
|
|
627
|
-
);
|
|
628
|
-
expect(options[1].pattern).toBe("web_fetch:https://\\[2001:db8::1\\]/*");
|
|
629
|
-
expect(options[2].pattern).toBe("**");
|
|
630
|
-
});
|
|
631
|
-
|
|
632
|
-
// ── network_request allowlist options ─────────────────────────
|
|
633
|
-
|
|
634
|
-
test("network_request: generates exact url, origin wildcard, and tool wildcard", async () => {
|
|
635
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
636
|
-
url: "https://api.example.com/v1/data",
|
|
637
|
-
});
|
|
638
|
-
expect(options).toHaveLength(3);
|
|
639
|
-
expect(options[0].pattern).toBe(
|
|
640
|
-
"network_request:https://api.example.com/v1/data",
|
|
641
|
-
);
|
|
642
|
-
expect(options[1].pattern).toBe(
|
|
643
|
-
"network_request:https://api.example.com/*",
|
|
644
|
-
);
|
|
645
|
-
expect(options[2].pattern).toBe("**");
|
|
646
|
-
expect(options[2].label).toBe("network_request:*");
|
|
647
|
-
expect(options[2].description).toBe("All network requests");
|
|
648
|
-
});
|
|
649
|
-
|
|
650
|
-
test("network_request: origin wildcard uses friendly hostname", async () => {
|
|
651
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
652
|
-
url: "https://www.example.com/path",
|
|
653
|
-
});
|
|
654
|
-
expect(options[1].description).toBe("Any page on example.com");
|
|
655
|
-
});
|
|
656
|
-
|
|
657
|
-
test("network_request: normalizes scheme-less host:port input", async () => {
|
|
658
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
659
|
-
url: "api.example.com:8443/v1/data",
|
|
660
|
-
});
|
|
661
|
-
expect(options).toHaveLength(3);
|
|
662
|
-
expect(options[0].pattern).toBe(
|
|
663
|
-
"network_request:https://api.example.com:8443/v1/data",
|
|
664
|
-
);
|
|
665
|
-
expect(options[1].pattern).toBe(
|
|
666
|
-
"network_request:https://api.example.com:8443/*",
|
|
667
|
-
);
|
|
668
|
-
expect(options[2].pattern).toBe("**");
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
test("network_request: strips fragments and userinfo", async () => {
|
|
672
|
-
const username = "demo";
|
|
673
|
-
const credential = ["c", "r", "e", "d", "1", "2", "3"].join("");
|
|
674
|
-
const credentialedUrl = new URL(
|
|
675
|
-
"https://api.example.com/v1/data#section",
|
|
676
|
-
);
|
|
677
|
-
credentialedUrl.username = username;
|
|
678
|
-
credentialedUrl.password = credential;
|
|
679
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
680
|
-
url: credentialedUrl.href,
|
|
681
|
-
});
|
|
682
|
-
expect(options).toHaveLength(3);
|
|
683
|
-
expect(options[0].pattern).toBe(
|
|
684
|
-
"network_request:https://api.example.com/v1/data",
|
|
685
|
-
);
|
|
686
|
-
expect(options[0].pattern).not.toContain("demo:cred123@");
|
|
687
|
-
expect(options[0].pattern).not.toContain("#section");
|
|
688
|
-
});
|
|
689
|
-
|
|
690
|
-
test("network_request: escapes minimatch metacharacters", async () => {
|
|
691
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
692
|
-
url: "https://[2001:db8::1]/api?key=val",
|
|
693
|
-
});
|
|
694
|
-
expect(options).toHaveLength(3);
|
|
695
|
-
expect(options[0].pattern).toBe(
|
|
696
|
-
"network_request:https://\\[2001:db8::1\\]/api\\?key=val",
|
|
697
|
-
);
|
|
698
|
-
expect(options[1].pattern).toBe(
|
|
699
|
-
"network_request:https://\\[2001:db8::1\\]/*",
|
|
700
|
-
);
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
test("network_request: empty url produces only tool wildcard", async () => {
|
|
704
|
-
const options = await generateAllowlistOptions("network_request", {
|
|
705
|
-
url: "",
|
|
706
|
-
});
|
|
707
|
-
expect(options).toHaveLength(1);
|
|
708
|
-
expect(options[0].pattern).toBe("**");
|
|
709
|
-
});
|
|
710
|
-
});
|
|
711
|
-
|
|
712
448
|
// ── generateScopeOptions ───────────────────────────────────────
|
|
713
449
|
|
|
714
450
|
describe("generateScopeOptions", () => {
|
|
@@ -1287,65 +1023,39 @@ describe("Permission Checker", () => {
|
|
|
1287
1023
|
// pattern (skillId@hash) and an any-version pattern (bare skillId).
|
|
1288
1024
|
// Input-supplied version_hash is always ignored to prevent spoofing.
|
|
1289
1025
|
|
|
1290
|
-
describe("
|
|
1026
|
+
describe("skill metadata sent to the gateway", () => {
|
|
1291
1027
|
function ensureSkillsDir(): void {
|
|
1292
1028
|
mkdirSync(join(checkerTestDir, "skills"), { recursive: true });
|
|
1293
1029
|
}
|
|
1294
1030
|
|
|
1295
|
-
test("
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
const options = await generateAllowlistOptions("skill_load", {
|
|
1300
|
-
skill: "test-opts-skill",
|
|
1301
|
-
});
|
|
1302
|
-
|
|
1303
|
-
// Should have only the version-specific option
|
|
1304
|
-
expect(options).toHaveLength(1);
|
|
1305
|
-
expect(options[0].pattern).toMatch(/^skill_load:test-opts-skill@v1:/);
|
|
1306
|
-
expect(options[0].description).toBe("This exact version");
|
|
1307
|
-
});
|
|
1308
|
-
|
|
1309
|
-
test("allowlist options ignore input version_hash and use disk-computed hash (regression)", async () => {
|
|
1031
|
+
test("the version hash comes from disk, never from the model's input", async () => {
|
|
1032
|
+
// The gateway builds the version-pinned trust-rule option from the hash
|
|
1033
|
+
// the daemon sends; taking it from the invocation would let a caller pin
|
|
1034
|
+
// a rule to a version that was never on disk.
|
|
1310
1035
|
ensureSkillsDir();
|
|
1311
1036
|
writeSkill("test-opts-explicit", "Test Opts Explicit");
|
|
1312
1037
|
|
|
1313
|
-
|
|
1314
|
-
// options must use the disk-computed hash, not the input value.
|
|
1315
|
-
const options = await generateAllowlistOptions("skill_load", {
|
|
1038
|
+
await classifyRisk("skill_load", {
|
|
1316
1039
|
skill: "test-opts-explicit",
|
|
1317
1040
|
version_hash: "v1:customhash123",
|
|
1318
1041
|
});
|
|
1319
1042
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
expect(
|
|
1324
|
-
|
|
1325
|
-
);
|
|
1326
|
-
expect(options[0].description).toBe("This exact version");
|
|
1043
|
+
const metadata = lastIpcParams("classify_risk")?.skillMetadata as
|
|
1044
|
+
| { skillId: string; versionHash: string }
|
|
1045
|
+
| undefined;
|
|
1046
|
+
expect(metadata?.skillId).toBe("test-opts-explicit");
|
|
1047
|
+
expect(metadata?.versionHash).toMatch(/^v1:/);
|
|
1048
|
+
expect(metadata?.versionHash).not.toBe("v1:customhash123");
|
|
1327
1049
|
});
|
|
1328
1050
|
|
|
1329
|
-
test("
|
|
1051
|
+
test("an unresolvable selector is sent with no metadata", async () => {
|
|
1330
1052
|
ensureSkillsDir();
|
|
1331
1053
|
|
|
1332
|
-
|
|
1333
|
-
skill: "no-such-skill",
|
|
1334
|
-
});
|
|
1335
|
-
|
|
1336
|
-
// Should have only the raw selector
|
|
1337
|
-
expect(options).toHaveLength(1);
|
|
1338
|
-
expect(options[0].pattern).toBe("skill_load:no-such-skill");
|
|
1339
|
-
expect(options[0].description).toBe("This skill");
|
|
1340
|
-
});
|
|
1341
|
-
|
|
1342
|
-
test("allowlist options for empty skill selector only has wildcard", async () => {
|
|
1343
|
-
const options = await generateAllowlistOptions("skill_load", {
|
|
1344
|
-
skill: "",
|
|
1345
|
-
});
|
|
1054
|
+
await classifyRisk("skill_load", { skill: "no-such-skill" });
|
|
1346
1055
|
|
|
1347
|
-
|
|
1348
|
-
expect(
|
|
1056
|
+
const params = lastIpcParams("classify_risk");
|
|
1057
|
+
expect(params?.skill).toBe("no-such-skill");
|
|
1058
|
+
expect(params?.skillMetadata).toBeUndefined();
|
|
1349
1059
|
});
|
|
1350
1060
|
});
|
|
1351
1061
|
|
|
@@ -1514,7 +1224,6 @@ describe("bash network_mode=proxied — risk capped at medium", () => {
|
|
|
1514
1224
|
mockRisk("low");
|
|
1515
1225
|
mockIpcResponse("get_global_thresholds", DEFAULT_GATEWAY_THRESHOLDS);
|
|
1516
1226
|
_clearGlobalCacheForTesting();
|
|
1517
|
-
clearRiskCache();
|
|
1518
1227
|
});
|
|
1519
1228
|
|
|
1520
1229
|
test("proxied bash follows risk-based policy (medium risk → prompt outside container)", async () => {
|
|
@@ -1562,7 +1271,6 @@ describe("credentialed proxied bash — high risk escalation", () => {
|
|
|
1562
1271
|
mockRisk("low");
|
|
1563
1272
|
mockIpcResponse("get_global_thresholds", DEFAULT_GATEWAY_THRESHOLDS);
|
|
1564
1273
|
_clearGlobalCacheForTesting();
|
|
1565
|
-
clearRiskCache();
|
|
1566
1274
|
});
|
|
1567
1275
|
|
|
1568
1276
|
test("proxied bash with credential_ids sends credentialRefCount in IPC params", async () => {
|
|
@@ -1652,7 +1360,6 @@ describe("workspace mode — auto-allow workspace-scoped operations", () => {
|
|
|
1652
1360
|
mockRisk("low");
|
|
1653
1361
|
mockIpcResponse("get_global_thresholds", DEFAULT_GATEWAY_THRESHOLDS);
|
|
1654
1362
|
_clearGlobalCacheForTesting();
|
|
1655
|
-
clearRiskCache();
|
|
1656
1363
|
try {
|
|
1657
1364
|
rmSync(join(checkerTestDir, "protected", "trust.json"));
|
|
1658
1365
|
} catch {
|
|
@@ -1796,7 +1503,6 @@ describe("integration regressions (PR 11)", () => {
|
|
|
1796
1503
|
mockRisk("low");
|
|
1797
1504
|
mockIpcResponse("get_global_thresholds", DEFAULT_GATEWAY_THRESHOLDS);
|
|
1798
1505
|
_clearGlobalCacheForTesting();
|
|
1799
|
-
clearRiskCache();
|
|
1800
1506
|
// Delete the trust file to prevent stale default rules from prior tests
|
|
1801
1507
|
try {
|
|
1802
1508
|
rmSync(join(checkerTestDir, "protected", "trust.json"));
|
|
@@ -45,6 +45,10 @@ mock.module("../plugins/defaults/memory/substrate/skill-store.js", () => ({
|
|
|
45
45
|
seedV2SkillEntries: async () => {
|
|
46
46
|
seedCallCount += 1;
|
|
47
47
|
},
|
|
48
|
+
// The validate route builds the page index, which reads the seeded
|
|
49
|
+
// skill catalog; an empty catalog keeps that walk inert here.
|
|
50
|
+
listSkillEntries: () => [],
|
|
51
|
+
SKILL_SLUG_PREFIX: "skills/",
|
|
48
52
|
}));
|
|
49
53
|
|
|
50
54
|
// ---------------------------------------------------------------------------
|
|
@@ -254,7 +258,7 @@ describe("all memory v2 routes — MEMORY_V2_DISABLED gate", () => {
|
|
|
254
258
|
const result = (await route!.handler({ body: {} })) as {
|
|
255
259
|
pageCount: number;
|
|
256
260
|
edgeCount: number;
|
|
257
|
-
|
|
261
|
+
danglingLinks: unknown[];
|
|
258
262
|
oversizedPages: unknown[];
|
|
259
263
|
parseFailures: unknown[];
|
|
260
264
|
};
|
|
@@ -263,7 +267,7 @@ describe("all memory v2 routes — MEMORY_V2_DISABLED gate", () => {
|
|
|
263
267
|
// returned at all (no MEMORY_V2_DISABLED throw).
|
|
264
268
|
expect(result.pageCount).toBe(0);
|
|
265
269
|
expect(result.edgeCount).toBe(0);
|
|
266
|
-
expect(result.
|
|
270
|
+
expect(result.danglingLinks).toEqual([]);
|
|
267
271
|
expect(result.oversizedPages).toEqual([]);
|
|
268
272
|
expect(result.parseFailures).toEqual([]);
|
|
269
273
|
});
|
|
@@ -436,12 +436,11 @@ describe("forceCompact context-window usage push", () => {
|
|
|
436
436
|
expect(usageEvent.maxTokens).toBe(200_000);
|
|
437
437
|
});
|
|
438
438
|
|
|
439
|
-
test("pushes to the caller's sink
|
|
440
|
-
// A `/compact` draining
|
|
441
|
-
//
|
|
442
|
-
//
|
|
443
|
-
|
|
444
|
-
const stranded: AssistantEvent[] = [];
|
|
439
|
+
test("pushes to the caller's sink instead of the conversation sink when one is given", async () => {
|
|
440
|
+
// A `/compact` draining from the queue carries the queued item's own
|
|
441
|
+
// sink, the one its result card streams on. The push has to follow the
|
|
442
|
+
// card so the two can never be delivered to different places.
|
|
443
|
+
const conversationSink: AssistantEvent[] = [];
|
|
445
444
|
const cardSink: AssistantEvent[] = [];
|
|
446
445
|
mockCompactResult = {
|
|
447
446
|
messages: [],
|
|
@@ -460,11 +459,10 @@ describe("forceCompact context-window usage push", () => {
|
|
|
460
459
|
};
|
|
461
460
|
|
|
462
461
|
const conversation = makeConversation(
|
|
463
|
-
|
|
464
|
-
"conv-compact-
|
|
462
|
+
conversationSink,
|
|
463
|
+
"conv-compact-caller-sink",
|
|
465
464
|
[56_000, 18_000],
|
|
466
465
|
);
|
|
467
|
-
conversation.updateClient(() => {}, true);
|
|
468
466
|
|
|
469
467
|
const result = await conversation.forceCompact((msg) => cardSink.push(msg));
|
|
470
468
|
|
|
@@ -475,7 +473,7 @@ describe("forceCompact context-window usage push", () => {
|
|
|
475
473
|
.tokens,
|
|
476
474
|
).toBe(result.estimatedInputTokens);
|
|
477
475
|
expect(
|
|
478
|
-
|
|
476
|
+
conversationSink.filter((m) => m.type === "context_window_usage").length,
|
|
479
477
|
).toBe(0);
|
|
480
478
|
});
|
|
481
479
|
|
|
@@ -877,13 +877,13 @@ describe("loadConfig startup behavior", () => {
|
|
|
877
877
|
raw.llm.defaultProvider,
|
|
878
878
|
);
|
|
879
879
|
expect(effective.balanced?.provider).toBe("openai");
|
|
880
|
-
expect(effective.balanced?.model).toBe("gpt-5.
|
|
880
|
+
expect(effective.balanced?.model).toBe("gpt-5.6-luna");
|
|
881
881
|
expect(effective.balanced?.provider_connection).toBe("openai-personal");
|
|
882
882
|
expect(effective.balanced?.source).toBe("managed");
|
|
883
883
|
expect(effective["quality-optimized"]?.provider).toBe("openai");
|
|
884
|
-
expect(effective["quality-optimized"]?.model).toBe("gpt-5.
|
|
884
|
+
expect(effective["quality-optimized"]?.model).toBe("gpt-5.6-sol");
|
|
885
885
|
expect(effective["cost-optimized"]?.provider).toBe("openai");
|
|
886
|
-
expect(effective["cost-optimized"]?.model).toBe("gpt-5.
|
|
886
|
+
expect(effective["cost-optimized"]?.model).toBe("gpt-5.6-luna");
|
|
887
887
|
});
|
|
888
888
|
|
|
889
889
|
test("off-platform hatch with a provider outside the named matrix columns resolves through the shared BYOK templates", () => {
|
|
@@ -398,11 +398,19 @@ describe("AssistantConfigSchema", () => {
|
|
|
398
398
|
}
|
|
399
399
|
});
|
|
400
400
|
|
|
401
|
-
test("
|
|
401
|
+
test("parses an unknown provider (read tolerance for entry names)", () => {
|
|
402
|
+
// The provider schema is an open string: a stored value outside the
|
|
403
|
+
// known set parses instead of stripping its profile, and dispatch
|
|
404
|
+
// resolves it as a connection entry name (or fails explainably).
|
|
405
|
+
// Write-time membership is enforced at the profiles route and the
|
|
406
|
+
// config-write choke point.
|
|
402
407
|
const result = AssistantConfigSchema.safeParse({
|
|
403
|
-
llm: { profiles: { custom: { provider: "
|
|
408
|
+
llm: { profiles: { custom: { provider: "anthropic-work" } } },
|
|
404
409
|
});
|
|
405
|
-
expect(result.success).toBe(
|
|
410
|
+
expect(result.success).toBe(true);
|
|
411
|
+
if (result.success) {
|
|
412
|
+
expect(result.data.llm.profiles.custom?.provider).toBe("anthropic-work");
|
|
413
|
+
}
|
|
406
414
|
});
|
|
407
415
|
|
|
408
416
|
test("accepts the vellum and chatgpt routing identities with a routable model", () => {
|
|
@@ -940,8 +948,6 @@ describe("AssistantConfigSchema", () => {
|
|
|
940
948
|
endpointDecisionTimeoutMs: 1200,
|
|
941
949
|
endpointExtensionMs: 1500,
|
|
942
950
|
endpointMaxExtensions: 2,
|
|
943
|
-
ackFirstDeltaTimeoutMs: 2500,
|
|
944
|
-
ackGenerationTimeoutMs: 600,
|
|
945
951
|
progress: {
|
|
946
952
|
enabled: true,
|
|
947
953
|
opsThreshold: 3,
|
|
@@ -952,6 +958,12 @@ describe("AssistantConfigSchema", () => {
|
|
|
952
958
|
generationTimeoutMs: 1500,
|
|
953
959
|
},
|
|
954
960
|
},
|
|
961
|
+
flux: {
|
|
962
|
+
turnEnd: { enabled: false },
|
|
963
|
+
model: "flux-general-en",
|
|
964
|
+
eotThreshold: 0.7,
|
|
965
|
+
eotTimeoutMs: 5000,
|
|
966
|
+
},
|
|
955
967
|
maxSessionDurationSeconds: 1800,
|
|
956
968
|
archiveAudio: false,
|
|
957
969
|
});
|
|
@@ -976,6 +988,8 @@ describe("AssistantConfigSchema", () => {
|
|
|
976
988
|
// Unspecified vad fields still get defaults
|
|
977
989
|
expect(result.liveVoice.vad.maxTurnDurationMs).toBe(30000);
|
|
978
990
|
expect(result.liveVoice.maxSessionDurationSeconds).toBe(900);
|
|
991
|
+
// A partial liveVoice override leaves Flux turn-end disabled by default.
|
|
992
|
+
expect(result.liveVoice.flux.turnEnd.enabled).toBe(false);
|
|
979
993
|
});
|
|
980
994
|
|
|
981
995
|
test("accepts a liveVoice.vad.bargeInMinSpeechMs of 0 (guard disabled)", () => {
|
|
@@ -2340,16 +2354,17 @@ describe("loadConfig with schema validation", () => {
|
|
|
2340
2354
|
expect(config.llm.callSites?.mainAgent?.maxTokens).toBe(4096);
|
|
2341
2355
|
});
|
|
2342
2356
|
|
|
2343
|
-
test("
|
|
2344
|
-
//
|
|
2345
|
-
//
|
|
2357
|
+
test("keeps an unknown provider on load (read tolerance for entry names)", () => {
|
|
2358
|
+
// The open provider schema keeps the whole profile: an unknown value is
|
|
2359
|
+
// resolved as a connection entry name at dispatch (or fails there
|
|
2360
|
+
// explainably) rather than being leaf-stripped on read.
|
|
2346
2361
|
writeConfig({
|
|
2347
2362
|
llm: {
|
|
2348
|
-
profiles: { custom: { provider: "
|
|
2363
|
+
profiles: { custom: { provider: "unknown-provider", model: "gpt-4" } },
|
|
2349
2364
|
},
|
|
2350
2365
|
});
|
|
2351
2366
|
const config = loadConfig();
|
|
2352
|
-
expect(config.llm.profiles.custom?.provider).
|
|
2367
|
+
expect(config.llm.profiles.custom?.provider).toBe("unknown-provider");
|
|
2353
2368
|
expect(config.llm.profiles.custom?.model).toBe("gpt-4");
|
|
2354
2369
|
});
|
|
2355
2370
|
|
|
@@ -71,7 +71,6 @@ mock.module("../plugins/defaults/memory/substrate/edge-index.js", () => ({
|
|
|
71
71
|
getEdgeIndex: async (): Promise<EdgeIndex> => edgeIndex,
|
|
72
72
|
invalidateEdgeIndex: () => {},
|
|
73
73
|
getReachable: () => new Set<string>(),
|
|
74
|
-
validateEdgeTargets: () => ({ ok: true, missing: [] }),
|
|
75
74
|
totalEdgeCount: () => 0,
|
|
76
75
|
}));
|
|
77
76
|
|
|
@@ -325,6 +325,8 @@ mock.module("../persistence/llm-request-log-store.js", () => ({
|
|
|
325
325
|
|
|
326
326
|
import type { Conversation } from "../daemon/conversation.js";
|
|
327
327
|
import { runAgentLoopImpl } from "../daemon/conversation-agent-loop.js";
|
|
328
|
+
import type { QueueDrainReason } from "../daemon/conversation-queue-manager.js";
|
|
329
|
+
import { asConversation } from "./helpers/mock-conversation.js";
|
|
328
330
|
|
|
329
331
|
// ── Test helpers ─────────────────────────────────────────────────────
|
|
330
332
|
|
|
@@ -363,7 +365,7 @@ function makeCtx(
|
|
|
363
365
|
];
|
|
364
366
|
};
|
|
365
367
|
|
|
366
|
-
return {
|
|
368
|
+
return asConversation({
|
|
367
369
|
conversationId: "test-conv",
|
|
368
370
|
messages: [
|
|
369
371
|
{ role: "user", content: [{ type: "text", text: "Hello" }] },
|
|
@@ -433,12 +435,7 @@ function makeCtx(
|
|
|
433
435
|
skillProjectionCache:
|
|
434
436
|
new Map() as unknown as Conversation["skillProjectionCache"],
|
|
435
437
|
|
|
436
|
-
usageStats: {
|
|
437
|
-
totalInputTokens: 0,
|
|
438
|
-
totalOutputTokens: 0,
|
|
439
|
-
totalEstimatedCost: 0,
|
|
440
|
-
model: "",
|
|
441
|
-
},
|
|
438
|
+
usageStats: { inputTokens: 0, outputTokens: 0, estimatedCost: 0 },
|
|
442
439
|
turnCount: 0,
|
|
443
440
|
|
|
444
441
|
lastAssistantAttachments: [],
|
|
@@ -456,12 +453,12 @@ function makeCtx(
|
|
|
456
453
|
getQueueDepth: () => 0,
|
|
457
454
|
hasQueuedMessages: () => false,
|
|
458
455
|
canHandoffAtCheckpoint: () => false,
|
|
459
|
-
drainQueue: (_reason?:
|
|
456
|
+
drainQueue: async (_reason?: QueueDrainReason) => {},
|
|
460
457
|
// Forwards to drainQueue so tests that spy the drain observe the agent
|
|
461
458
|
// loop's post-turn kick through the guarded entry point.
|
|
462
459
|
kickDrainQueue(
|
|
463
|
-
this: { drainQueue: (reason?:
|
|
464
|
-
reason:
|
|
460
|
+
this: { drainQueue: (reason?: QueueDrainReason) => Promise<void> },
|
|
461
|
+
reason: QueueDrainReason = "loop_complete",
|
|
465
462
|
_origin?: string,
|
|
466
463
|
) {
|
|
467
464
|
return this.drainQueue(reason);
|
|
@@ -493,7 +490,7 @@ function makeCtx(
|
|
|
493
490
|
} as unknown as Conversation["graphMemory"],
|
|
494
491
|
|
|
495
492
|
...overrides,
|
|
496
|
-
}
|
|
493
|
+
});
|
|
497
494
|
}
|
|
498
495
|
|
|
499
496
|
// ── Tests ────────────────────────────────────────────────────────────
|