@vellumai/assistant 0.11.6 → 0.11.7-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 +31 -19
- package/Dockerfile +1 -0
- package/docs/architecture/security.md +3 -3
- package/docs/flux-turn-detection-spike.md +8 -7
- package/docs/runbook-trusted-contacts.md +14 -0
- package/docs/stt-provider-onboarding.md +8 -4
- package/knip.json +1 -0
- package/node_modules/@vellumai/avatar-manifest/package.json +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/manifest.test.ts +173 -0
- package/node_modules/@vellumai/avatar-manifest/src/__tests__/read.test.ts +114 -0
- package/node_modules/@vellumai/avatar-manifest/src/index.ts +29 -0
- package/node_modules/@vellumai/avatar-manifest/src/layout.ts +18 -0
- package/node_modules/@vellumai/avatar-manifest/src/manifest.ts +156 -0
- package/node_modules/@vellumai/avatar-manifest/src/read.ts +109 -0
- package/node_modules/@vellumai/avatar-manifest/tsconfig.json +20 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/ces-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/ces-client/src/http-credentials.ts +161 -0
- package/node_modules/@vellumai/ces-client/src/index.ts +1 -0
- package/node_modules/@vellumai/environments/package.json +2 -1
- package/node_modules/@vellumai/environments/src/shell.test.ts +56 -0
- package/node_modules/@vellumai/environments/src/shell.ts +65 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/gateway-client/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +32 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/gateway-client.test.ts +1 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/inbound-event-kind.test.ts +82 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/plugin-admission-denied-contract.test.ts +56 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +18 -0
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +5 -11
- package/node_modules/@vellumai/gateway-client/src/channel-permission-contract.ts +3 -1
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +9 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +4 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-event-kind.ts +75 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +17 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +8 -0
- package/node_modules/@vellumai/gateway-client/src/plugin-admission-denied-contract.ts +47 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +11 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +37 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/remote-web-pairing.test.ts +389 -0
- package/node_modules/@vellumai/service-contracts/src/ingress.ts +22 -0
- package/node_modules/@vellumai/service-contracts/src/remote-web-pairing.ts +508 -18
- package/node_modules/@vellumai/service-contracts/src/rpc.ts +174 -0
- package/openapi.yaml +419 -55
- package/package.json +4 -1
- package/scripts/sync-llm-catalog.ts +6 -0
- package/src/__tests__/approval-card-edit-inbound-handoff.test.ts +199 -0
- package/src/__tests__/approval-card-edit.test.ts +153 -0
- package/src/__tests__/attachments-store-heic-normalize.test.ts +1 -1
- package/src/__tests__/available-skills.test.ts +54 -0
- package/src/__tests__/avatar-identity-sync.test.ts +5 -1
- package/src/__tests__/catalog-install-normalize.test.ts +9 -1
- package/src/__tests__/channel-policy.test.ts +1 -3
- package/src/__tests__/channel-readiness-discord.test.ts +9 -70
- package/src/__tests__/compactor-call-site-logging.test.ts +61 -0
- package/src/__tests__/config-loader-backfill.test.ts +69 -0
- package/src/__tests__/config-schema.test.ts +2 -3
- package/src/__tests__/conversation-agent-loop.test.ts +238 -0
- package/src/__tests__/conversation-attachments.test.ts +0 -1
- package/src/__tests__/conversation-error.test.ts +44 -0
- package/src/__tests__/conversation-evictor.test.ts +19 -0
- package/src/__tests__/conversation-fork-referential.test.ts +73 -63
- package/src/__tests__/conversation-fork-retrospective.test.ts +99 -74
- package/src/__tests__/conversation-runtime-assembly.test.ts +23 -0
- package/src/__tests__/conversation-slash.test.ts +9 -0
- package/src/__tests__/conversation-title-service.test.ts +97 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +16 -0
- package/src/__tests__/credential-broker-server-use.test.ts +0 -218
- package/src/__tests__/credential-broker.test.ts +43 -420
- package/src/__tests__/credential-record-write-through.test.ts +78 -0
- package/src/__tests__/credential-routes.test.ts +17 -1
- package/src/__tests__/credential-security-invariants.test.ts +8 -9
- package/src/__tests__/default-profile-catalog-fallback.test.ts +289 -0
- package/src/__tests__/delete-propagation.test.ts +92 -2
- package/src/__tests__/discord-callback-round-trip.test.ts +93 -0
- package/src/__tests__/discord-channel-config.test.ts +237 -0
- package/src/__tests__/edit-propagation.test.ts +42 -2
- package/src/__tests__/evict-conversations-for-reload.test.ts +51 -1
- package/src/__tests__/fallback-breaker.test.ts +1335 -0
- package/src/__tests__/gateway-threshold-reader-mock.ts +6 -0
- package/src/__tests__/guardian-card-withdrawal.test.ts +30 -0
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +0 -2
- package/src/__tests__/image-conversion.test.ts +38 -4
- package/src/__tests__/install-skill-routing.test.ts +25 -0
- package/src/__tests__/llm-catalog-parity.test.ts +4 -0
- package/src/__tests__/llm-resolver.test.ts +74 -0
- package/src/__tests__/llm-schema-fallback-profile.test.ts +359 -0
- package/src/__tests__/managed-fallback-dispatch.test.ts +430 -0
- package/src/__tests__/managed-profile-guard.test.ts +28 -0
- package/src/__tests__/managed-speech-defaults.test.ts +196 -1
- package/src/__tests__/mcp-cli.test.ts +23 -1
- package/src/__tests__/mcp-tool-annotations-risk.test.ts +43 -34
- package/src/__tests__/media-stream-stt-session.test.ts +2 -0
- package/src/__tests__/notification-decision-fallback.test.ts +106 -0
- package/src/__tests__/notification-discord-adapter.test.ts +162 -0
- package/src/__tests__/oauth-connect-orchestrator.test.ts +95 -0
- package/src/__tests__/persist-unsendable-image-downscale.test.ts +6 -8
- package/src/__tests__/persist-unsendable-image.test.ts +3 -3
- package/src/__tests__/platform.test.ts +19 -1
- package/src/__tests__/plugin-import-boundary-guard.test.ts +5 -1
- package/src/__tests__/provider-catalog-visibility.test.ts +17 -0
- package/src/__tests__/provider-platform-proxy-integration.test.ts +8 -1
- package/src/__tests__/provider-usage-tracking.test.ts +56 -0
- package/src/__tests__/require-fresh-approval.test.ts +5 -2
- package/src/__tests__/retry-fallback-escalation.test.ts +1093 -0
- package/src/__tests__/schedule-retry.test.ts +183 -4
- package/src/__tests__/scheduler-reuse-conversation.test.ts +6 -6
- package/src/__tests__/secret-routes-platform-proxy.test.ts +55 -0
- package/src/__tests__/skill-load-tool.test.ts +34 -0
- package/src/__tests__/skill-tool-factory.test.ts +6 -1
- package/src/__tests__/skill-tool-manifest.test.ts +20 -0
- package/src/__tests__/skills.test.ts +25 -0
- package/src/__tests__/subagent-manager-notify.test.ts +38 -0
- package/src/__tests__/terminal-tools.test.ts +2 -0
- package/src/__tests__/tool-approval-handler.test.ts +146 -2
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +108 -2
- package/src/__tests__/tool-audit.test.ts +111 -40
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +228 -18
- package/src/__tests__/ui-shape-teaching.test.ts +1 -1
- package/src/__tests__/verification-control-plane-policy.test.ts +6 -2
- package/src/__tests__/voice-config-update.test.ts +43 -0
- package/src/__tests__/workspace-migration-147-rename-colliding-backup-profile-names.test.ts +480 -0
- package/src/__tests__/workspace-migration-148-strip-unsupported-fallback-profiles.test.ts +167 -0
- package/src/__tests__/workspace-migration-149-repoint-backup-profile-selections.test.ts +144 -0
- package/src/agent/loop.ts +31 -2
- package/src/approvals/guardian-card-withdrawal.ts +22 -0
- package/src/avatar/__tests__/ensure-raster.test.ts +291 -0
- package/src/avatar/avatar-manifest.ts +48 -100
- package/src/avatar/avatar-store.ts +7 -7
- package/src/avatar/ensure-raster.ts +146 -0
- package/src/avatar/resvg-lazy.test.ts +0 -1
- package/src/avatar/traits-png-sync.ts +9 -10
- package/src/background-wake/wake-intent-hooks.test.ts +0 -1
- package/src/backup/__tests__/paths.test.ts +6 -2
- package/src/backup/paths.ts +6 -4
- package/src/bundler/app-compiler.ts +2 -2
- package/src/bundler/compiler-tools.test.ts +36 -0
- package/src/bundler/compiler-tools.ts +54 -18
- package/src/calls/__tests__/telephony-synthesis-language.test.ts +81 -0
- package/src/calls/__tests__/voice-session-bridge.test.ts +57 -0
- package/src/calls/media-stream-stt-session.ts +2 -1
- package/src/calls/telephony-synthesis-language.ts +13 -5
- package/src/calls/voice-session-bridge.ts +19 -4
- package/src/channels/config.ts +23 -12
- package/src/cli/AGENTS.md +3 -1
- package/src/cli/commands/backup.help.ts +10 -13
- package/src/cli/commands/contacts.help.ts +16 -4
- package/src/cli/commands/contacts.ts +5 -1
- package/src/cli/commands/credentials.help.ts +1 -1
- package/src/cli/commands/inference-providers.ts +18 -53
- package/src/cli/commands/mcp.help.ts +6 -5
- package/src/cli/commands/mcp.ts +1 -1
- package/src/cli/commands/memory/memory-retrospective.ts +1 -0
- package/src/cli/commands/stt.help.ts +2 -2
- package/src/config/__tests__/backup-schema.test.ts +1 -1
- package/src/config/__tests__/default-profile-catalog.test.ts +83 -2
- package/src/config/__tests__/loader-sparse-array-cleanup.test.ts +1 -1
- package/src/config/__tests__/memory-retrospective-schema.test.ts +12 -15
- package/src/config/bundled-skills/computer-use/SKILL.md +6 -6
- package/src/config/bundled-skills/computer-use/TOOLS.json +9 -6
- package/src/config/bundled-skills/media-processing/services/audio-transcribe.ts +3 -1
- package/src/config/bundled-skills/media-processing/services/preprocess.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +16 -15
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +2 -1
- package/src/config/bundled-skills/settings/TOOLS.json +11 -5
- package/src/config/bundled-skills/settings/tools/open-system-settings.test.ts +85 -0
- package/src/config/bundled-skills/settings/tools/open-system-settings.ts +33 -8
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +54 -3
- package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +1 -1
- package/src/config/default-profile-catalog.ts +195 -10
- package/src/config/default-profile-names.ts +41 -0
- package/src/config/feature-flag-registry.json +34 -2
- package/src/config/inference-profile-validation.ts +11 -2
- package/src/config/llm-resolver.ts +25 -0
- package/src/config/loader.ts +3 -0
- package/src/config/managed-speech-defaults.ts +160 -10
- package/src/config/schema.ts +2 -0
- package/src/config/schemas/__tests__/live-voice.test.ts +7 -6
- package/src/config/schemas/__tests__/stt.test.ts +94 -0
- package/src/config/schemas/backup.ts +1 -1
- package/src/config/schemas/channels.ts +32 -0
- package/src/config/schemas/live-voice.ts +13 -4
- package/src/config/schemas/llm.ts +263 -15
- package/src/config/schemas/mcp.ts +10 -2
- package/src/config/schemas/memory-retrospective.ts +1 -19
- package/src/config/schemas/services.ts +24 -0
- package/src/config/schemas/stt.ts +128 -5
- package/src/config/seed-inference-profiles.ts +32 -3
- package/src/config/skill-state.ts +5 -0
- package/src/config/skills.ts +21 -0
- package/src/contacts/notify-contacts-changed.ts +5 -2
- package/src/context/compactor.ts +74 -1
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +138 -1
- package/src/daemon/config-watcher.ts +2 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +27 -0
- package/src/daemon/conversation-agent-loop.ts +86 -10
- package/src/daemon/conversation-error.ts +25 -0
- package/src/daemon/conversation-evictor.ts +2 -4
- package/src/daemon/conversation-runtime-assembly.ts +19 -7
- package/src/daemon/conversation-skill-tools.ts +5 -1
- package/src/daemon/conversation-slash.ts +2 -2
- package/src/daemon/conversation-store.ts +8 -1
- package/src/daemon/conversation-tool-setup.ts +37 -0
- package/src/daemon/conversation.ts +0 -4
- package/src/daemon/handlers/channel-config-result.ts +30 -0
- package/src/daemon/handlers/config-discord-channel.ts +301 -0
- package/src/daemon/handlers/config-ingress.ts +9 -0
- package/src/daemon/handlers/config-slack-channel.ts +13 -15
- package/src/daemon/handlers/config-telegram.ts +2 -5
- package/src/daemon/handlers/conversations.ts +0 -2
- package/src/daemon/handlers/skills.ts +25 -7
- package/src/daemon/lifecycle.ts +3 -1
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/tool-setup-types.ts +5 -3
- package/src/daemon/trust-context-types.test.ts +33 -0
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +0 -1
- package/src/live-voice/__tests__/live-voice-flux-turn-end.test.ts +58 -4
- package/src/live-voice/__tests__/live-voice-managed-speech-fallback.test.ts +8 -3
- package/src/live-voice/__tests__/live-voice-session-manager.test.ts +73 -11
- package/src/live-voice/__tests__/live-voice-session-preflight.test.ts +148 -2
- package/src/live-voice/__tests__/live-voice-session-telemetry.test.ts +64 -0
- package/src/live-voice/__tests__/live-voice-stt.test.ts +3 -0
- package/src/live-voice/__tests__/live-voice-text-turn.test.ts +391 -0
- package/src/live-voice/__tests__/protocol.test.ts +224 -0
- package/src/live-voice/live-voice-credential-preflight.ts +5 -1
- package/src/live-voice/live-voice-session-manager.ts +39 -2
- package/src/live-voice/live-voice-session.ts +224 -9
- package/src/live-voice/protocol.ts +187 -1
- package/src/messaging/providers/discord/api.ts +2 -1
- package/src/messaging/providers/discord/withdraw.ts +62 -0
- package/src/messaging/read-provider-metadata.ts +32 -0
- package/src/monitoring/__tests__/file-descriptors.test.ts +32 -0
- package/src/monitoring/__tests__/process-memory.test.ts +34 -1
- package/src/monitoring/db-integrity-sample.ts +1 -0
- package/src/monitoring/file-descriptors.ts +39 -6
- package/src/monitoring/process-memory.ts +37 -5
- package/src/monitoring/resource-sampler.ts +25 -8
- package/src/notifications/__tests__/activity-failed-dedupe.test.ts +161 -0
- package/src/notifications/__tests__/background-failure-signal.test.ts +107 -0
- package/src/notifications/__tests__/connected-channels.test.ts +12 -0
- package/src/notifications/__tests__/copy-composer.test.ts +83 -0
- package/src/notifications/__tests__/destination-resolver.test.ts +38 -0
- package/src/notifications/activity-failed-dedupe.ts +95 -0
- package/src/notifications/adapters/discord.ts +132 -0
- package/src/notifications/adapters/shared.ts +16 -0
- package/src/notifications/adapters/slack.ts +6 -1
- package/src/notifications/adapters/telegram.ts +5 -8
- package/src/notifications/approval-card-data.ts +94 -1
- package/src/notifications/background-failure-signal.ts +116 -0
- package/src/notifications/broadcaster.ts +3 -9
- package/src/notifications/copy-composer.ts +41 -8
- package/src/notifications/decision-engine.ts +55 -0
- package/src/notifications/destination-resolver.ts +45 -5
- package/src/notifications/emit-signal.ts +19 -5
- package/src/notifications/guardian-question-mode.ts +57 -0
- package/src/notifications/types.ts +2 -8
- package/src/oauth/__tests__/seed-providers-managed.test.ts +18 -0
- package/src/oauth/connect-orchestrator.ts +16 -0
- package/src/oauth/seed-providers.ts +262 -0
- package/src/permissions/checker.test.ts +21 -0
- package/src/permissions/checker.ts +6 -0
- package/src/permissions/gateway-threshold-reader.test.ts +184 -0
- package/src/permissions/gateway-threshold-reader.ts +144 -10
- package/src/permissions/prompter.ts +0 -6
- package/src/permissions/types.ts +5 -4
- package/src/persistence/__tests__/bulk-write-gate.test.ts +0 -38
- package/src/persistence/bulk-write-gate.ts +9 -10
- package/src/persistence/conversation-crud.ts +88 -134
- package/src/persistence/conversation-title-service.ts +43 -29
- package/src/persistence/embeddings/embedding-local.ts +14 -85
- package/src/persistence/embeddings/embedding-runtime-manager.ts +1 -0
- package/src/persistence/lifecycle-events-store.test.ts +50 -0
- package/src/persistence/lifecycle-events-store.ts +75 -5
- package/src/platform/platform-patch-queue.test.ts +368 -0
- package/src/platform/platform-patch-queue.ts +190 -0
- package/src/platform/sync-avatar.test.ts +527 -0
- package/src/platform/sync-avatar.ts +209 -0
- package/src/platform/sync-identity.test.ts +75 -0
- package/src/platform/sync-identity.ts +17 -110
- package/src/plugin-api/model-profiles.test.ts +2 -2
- package/src/plugin-api/model-profiles.ts +7 -7
- package/src/plugin-api/transcription-session.ts +1 -1
- package/src/plugins/defaults/compaction/window-manager.ts +4 -0
- package/src/plugins/defaults/image-recovery/recover.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +133 -34
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-prompt.test.ts +21 -31
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-provider-path.test.ts +13 -9
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-wake-chain.test.ts +31 -4
- package/src/plugins/defaults/memory/memory-retrospective-constants.ts +0 -11
- package/src/plugins/defaults/memory/memory-retrospective-fork-boundary.ts +27 -13
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +183 -113
- package/src/plugins/defaults/memory/memory-retrospective-prompt.ts +13 -13
- package/src/plugins/defaults/memory/src/memory-v2-routes.ts +2 -2
- package/src/plugins/defaults/memory/substrate/__tests__/consolidation-job.test.ts +1 -1
- package/src/plugins/defaults/memory/substrate/consolidation-job.ts +4 -2
- package/src/plugins/defaults/memory/substrate/sweep-job.ts +9 -42
- package/src/plugins/defaults/memory/v2/rerank-local.ts +1 -0
- package/src/plugins/defaults/memory/worker.ts +7 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +55 -0
- package/src/providers/__tests__/vellum-connection-routing.test.ts +21 -3
- package/src/providers/connection-resolution.ts +2 -17
- package/src/providers/fallback-breaker.ts +389 -0
- package/src/providers/inference/__tests__/adapter-factory-opencode.test.ts +92 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +16 -0
- package/src/providers/inference/__tests__/base-url-security.test.ts +12 -0
- package/src/providers/inference/adapter-factory.ts +246 -3
- package/src/providers/inference/auth.ts +15 -14
- package/src/providers/inference/chatgpt-subscription-auth.ts +70 -0
- package/src/providers/inference/chatgpt-subscription-credentials.ts +84 -0
- package/src/providers/inference/resolve-auth.ts +1 -1
- package/src/providers/media-resolve.ts +2 -3
- package/src/providers/model-catalog.ts +100 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +22 -0
- package/src/providers/openai/__tests__/chat-template-flatten.test.ts +198 -0
- package/src/providers/openai/api-error-normalization.ts +13 -0
- package/src/providers/openai/chat-completions-provider.ts +84 -0
- package/src/providers/opencode/client.test.ts +150 -0
- package/src/providers/opencode/client.ts +61 -0
- package/src/providers/platform-proxy/constants.ts +5 -0
- package/src/providers/provider-resolvability.ts +20 -0
- package/src/providers/provider-secret-catalog.ts +3 -2
- package/src/providers/retry.ts +956 -68
- package/src/providers/speech-to-text/__tests__/deepgram-flux-frames.test.ts +42 -0
- package/src/providers/speech-to-text/__tests__/deepgram-flux-realtime.test.ts +136 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +120 -0
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +316 -12
- package/src/providers/speech-to-text/deepgram-flux-frames.ts +83 -3
- package/src/providers/speech-to-text/deepgram-flux-realtime.ts +132 -4
- package/src/providers/speech-to-text/provider-catalog.ts +191 -3
- package/src/providers/speech-to-text/resolve.ts +132 -24
- package/src/providers/speech-to-text/vellum-managed-flux-realtime.ts +296 -0
- package/src/providers/types.ts +39 -0
- package/src/providers/usage-tracking.ts +12 -1
- package/src/providers/vellum/client.ts +29 -0
- package/src/providers/vellum-model-routing.test.ts +2 -0
- package/src/providers/vellum-model-routing.ts +3 -3
- package/src/runtime/AGENTS.md +1 -2
- package/src/runtime/__tests__/agent-wake.test.ts +105 -3
- package/src/runtime/__tests__/background-job-runner.test.ts +89 -3
- package/src/runtime/agent-wake.ts +44 -5
- package/src/runtime/background-job-runner.ts +68 -50
- package/src/runtime/channel-readiness-service.ts +0 -39
- package/src/runtime/http-server.ts +12 -4
- package/src/runtime/routes/__tests__/avatar-state-routes.test.ts +18 -18
- package/src/runtime/routes/__tests__/backup-routes.test.ts +9 -5
- package/src/runtime/routes/__tests__/chatgpt-subscription-auth-routes.test.ts +372 -0
- package/src/runtime/routes/__tests__/contact-routes.test.ts +7 -0
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +96 -0
- package/src/runtime/routes/__tests__/inference-profiles-routes.test.ts +37 -0
- package/src/runtime/routes/__tests__/ingress-status-routes.test.ts +2 -1
- package/src/runtime/routes/__tests__/mcp-add-default-risk.test.ts +87 -0
- package/src/runtime/routes/acp-claude-auth-routes.ts +25 -54
- package/src/runtime/routes/approval-routes.ts +0 -12
- package/src/runtime/routes/avatar-routes.ts +17 -30
- package/src/runtime/routes/backup-routes.ts +2 -2
- package/src/runtime/routes/chatgpt-subscription-auth-routes.ts +296 -113
- package/src/runtime/routes/contact-prompt-routes.ts +65 -6
- package/src/runtime/routes/contact-routes.ts +20 -15
- package/src/runtime/routes/conversation-query-routes.ts +98 -10
- package/src/runtime/routes/conversation-routes.ts +2 -2
- package/src/runtime/routes/credential-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +12 -9
- package/src/runtime/routes/inbound-message-handler.ts +47 -48
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +18 -13
- package/src/runtime/routes/inbound-stages/admission-policy.ts +2 -2
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +20 -2
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +9 -8
- package/src/runtime/routes/inbound-stages/transcribe-audio.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/inference-profile-session-handler.ts +2 -2
- package/src/runtime/routes/inference-profiles-routes.ts +12 -7
- package/src/runtime/routes/inference-provider-connection-routes.ts +2 -2
- package/src/runtime/routes/inference-send-routes.ts +2 -2
- package/src/runtime/routes/ingress-status-routes.ts +2 -2
- package/src/runtime/routes/integrations/discord.ts +119 -0
- package/src/runtime/routes/llm-call-sites-routes.ts +2 -2
- package/src/runtime/routes/mcp-auth-routes.ts +12 -6
- package/src/runtime/routes/migration-routes.ts +3 -1
- package/src/runtime/routes/oauth-pending-flows.ts +136 -0
- package/src/runtime/routes/secret-routes.ts +7 -0
- package/src/runtime/routes/stt-routes.ts +38 -6
- package/src/runtime/routes/wake-conversation-routes.ts +8 -1
- package/src/runtime/routes/watch-routes.ts +9 -5
- package/src/runtime/sync/resource-sync-events.ts +2 -0
- package/src/runtime/trust-verdict-consumer.ts +3 -3
- package/src/schedule/__tests__/worker-feature-flags.test.ts +58 -0
- package/src/schedule/retry-policy.ts +8 -8
- package/src/schedule/run-script.ts +14 -23
- package/src/schedule/schedule-recovery.ts +0 -1
- package/src/schedule/scheduler.ts +89 -51
- package/src/schedule/worker.ts +57 -0
- package/src/security/__tests__/openai-device-auth.test.ts +355 -0
- package/src/security/ces-rpc-record-backend.ts +123 -0
- package/src/security/oauth2.ts +7 -0
- package/src/security/openai-device-auth.ts +364 -0
- package/src/security/secure-keys.ts +15 -0
- package/src/skills/available-skills.ts +10 -1
- package/src/skills/catalog-install.ts +19 -1
- package/src/skills/inline-command-runner.ts +6 -2
- package/src/skills/platform-compatibility.test.ts +49 -0
- package/src/skills/platform-compatibility.ts +65 -0
- package/src/skills/tool-manifest.ts +20 -0
- package/src/stt/__tests__/roles.test.ts +152 -0
- package/src/stt/daemon-batch-transcriber.ts +4 -1
- package/src/stt/roles.ts +180 -0
- package/src/stt/stt-stream-session.ts +3 -2
- package/src/stt/types.ts +33 -3
- package/src/subagent/manager.ts +12 -0
- package/src/telemetry/__tests__/live-voice-funnel.test.ts +34 -0
- package/src/telemetry/live-voice-funnel.ts +12 -2
- package/src/telemetry/telemetry-wire.generated.ts +6 -0
- package/src/telemetry/tool-audit.ts +83 -30
- package/src/telemetry/tool-executed-events-store.test.ts +0 -1
- package/src/telemetry/turn-outcome.ts +75 -4
- package/src/tools/client-os.ts +115 -0
- package/src/tools/computer-use/definitions.ts +11 -7
- package/src/tools/computer-use/skill-proxy-bridge.ts +2 -2
- package/src/tools/credentials/broker-types.ts +0 -71
- package/src/tools/credentials/broker.ts +6 -201
- package/src/tools/credentials/metadata-store.ts +65 -16
- package/src/tools/credentials/store.ts +2 -0
- package/src/tools/executor.ts +2 -8
- package/src/tools/host-shell.test.ts +75 -0
- package/src/tools/host-shell.ts +24 -0
- package/src/tools/host-terminal/host-shell.ts +15 -44
- package/src/tools/mcp/mcp-tool-factory.ts +44 -9
- package/src/tools/permission-checker.ts +73 -21
- package/src/tools/policy-context.ts +1 -0
- package/src/tools/shared/filesystem/image-read.ts +1 -1
- package/src/tools/skills/find-similar-skills.ts +10 -2
- package/src/tools/skills/load.ts +41 -6
- package/src/tools/skills/sandbox-runner.ts +8 -16
- package/src/tools/skills/skill-tool-factory.ts +1 -0
- package/src/tools/terminal/__tests__/safe-env.test.ts +64 -1
- package/src/tools/terminal/safe-env.ts +39 -9
- package/src/tools/terminal/shell.ts +12 -31
- package/src/tools/tool-approval-handler.ts +64 -10
- package/src/tools/tool-types.ts +10 -0
- package/src/tools/types.ts +19 -3
- package/src/tools/ui-surface/surface-shape-docs.ts +4 -3
- package/src/tools/workflows/manage-workflows.ts +2 -2
- package/src/tools/workflows/run-workflow.test.ts +2 -1
- package/src/util/__tests__/file-use.test.ts +61 -0
- package/src/util/__tests__/process-table.test.ts +66 -0
- package/src/util/__tests__/process-tree.test.ts +46 -0
- package/src/util/errors.ts +1 -0
- package/src/util/file-use.ts +91 -0
- package/src/util/host-process.test.ts +17 -0
- package/src/util/host-process.ts +75 -0
- package/src/util/image-conversion.ts +39 -7
- package/src/util/platform.ts +32 -13
- package/src/util/process-table.ts +249 -0
- package/src/util/process-tree.ts +85 -129
- package/src/util/provider-error-patterns.ts +20 -0
- package/src/util/spawn.ts +9 -2
- package/src/watch/__tests__/watch-retro.test.ts +48 -1
- package/src/watch/watch-retro.ts +46 -4
- package/src/workspace/git-service.ts +4 -14
- package/src/workspace/migrations/147-rename-colliding-backup-profile-names.ts +360 -0
- package/src/workspace/migrations/148-strip-unsupported-fallback-profiles.ts +117 -0
- package/src/workspace/migrations/149-repoint-backup-profile-selections.ts +204 -0
- package/src/workspace/migrations/150-stt-flux-provider-to-model-family.ts +139 -0
- package/src/workspace/migrations/__tests__/150-stt-flux-provider-to-model-family.test.ts +160 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/permission-types.test.ts +0 -17
- package/src/channels/gateway-discord-admission.ts +0 -32
- package/src/persistence/fork-message-copy.ts +0 -239
- package/src/plugins/defaults/memory/__tests__/fork-message-copy.test.ts +0 -221
- package/src/security/__tests__/oauth2-device-code.test.ts +0 -431
- package/src/security/oauth2-device-code.ts +0 -312
|
@@ -9,13 +9,17 @@ import { PROVIDER_CATALOG } from "../providers/model-catalog.js";
|
|
|
9
9
|
import { credentialKey } from "../security/credential-key.js";
|
|
10
10
|
import { getLogger } from "../util/logger.js";
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
getEffectiveProfilesForProvider,
|
|
13
13
|
MANAGED_PROFILE_NAMES,
|
|
14
14
|
MANAGED_PROFILE_TEMPLATES,
|
|
15
15
|
} from "./default-profile-catalog.js";
|
|
16
16
|
import { loadRawConfig, saveRawConfig } from "./loader.js";
|
|
17
17
|
import { isDispatchableProfile } from "./profile-dispatchability.js";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
type DefaultProviderConfig,
|
|
20
|
+
isDefaultProviderChoice,
|
|
21
|
+
type ProfileEntry,
|
|
22
|
+
} from "./schemas/llm.js";
|
|
19
23
|
|
|
20
24
|
const log = getLogger("seed-inference-profiles");
|
|
21
25
|
|
|
@@ -141,8 +145,13 @@ export function seedInferenceProfiles(
|
|
|
141
145
|
// Profile lookups below go through the effective view: a default profile
|
|
142
146
|
// resolves from the code catalog whether or not the workspace carries a
|
|
143
147
|
// stub for it, and a stub contributes only its status/label overlays.
|
|
144
|
-
|
|
148
|
+
// Resolved against `llm.defaultProvider` so the managed backups count as
|
|
149
|
+
// available only on the managed column, matching what the schema accepts
|
|
150
|
+
// as a reference: an `activeProfile` naming a backup on a BYOK install is
|
|
151
|
+
// then repaired here rather than preserved as a dangling selection.
|
|
152
|
+
const effectiveProfiles = getEffectiveProfilesForProvider(
|
|
145
153
|
profiles as Record<string, ProfileEntry>,
|
|
154
|
+
seedResolutionDefaultProvider(llm),
|
|
146
155
|
) as Record<string, Record<string, unknown>>;
|
|
147
156
|
|
|
148
157
|
// Active profile resolution.
|
|
@@ -230,6 +239,26 @@ export function seedInferenceProfiles(
|
|
|
230
239
|
saveRawConfig(config);
|
|
231
240
|
}
|
|
232
241
|
|
|
242
|
+
/**
|
|
243
|
+
* The `llm.defaultProvider` to resolve the effective catalog against, read
|
|
244
|
+
* from RAW config. Only a value the matrix can implement is used: a
|
|
245
|
+
* hand-edited or legacy provider outside `DEFAULT_PROVIDER_CHOICES` has no
|
|
246
|
+
* column and no verified intent resolution, so materializing against it
|
|
247
|
+
* could throw and fail the whole boot seed. Such a value falls back to
|
|
248
|
+
* `null`, which resolves the managed column.
|
|
249
|
+
*/
|
|
250
|
+
function seedResolutionDefaultProvider(
|
|
251
|
+
llm: Record<string, unknown>,
|
|
252
|
+
): DefaultProviderConfig | null {
|
|
253
|
+
const raw = readObject(llm.defaultProvider);
|
|
254
|
+
const provider = readString(raw?.provider);
|
|
255
|
+
if (provider === undefined || !isDefaultProviderChoice(provider)) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
const connectionName = readString(raw?.connectionName);
|
|
259
|
+
return { provider, ...(connectionName ? { connectionName } : {}) };
|
|
260
|
+
}
|
|
261
|
+
|
|
233
262
|
export function readObject(value: unknown): Record<string, unknown> | null {
|
|
234
263
|
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
235
264
|
? (value as Record<string, unknown>)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isSkillCompatibleWithPlatform } from "../skills/platform-compatibility.js";
|
|
1
2
|
import { isAssistantFeatureFlagEnabled } from "./assistant-feature-flags.js";
|
|
2
3
|
import type { AssistantConfig, SkillEntryConfig } from "./schema.js";
|
|
3
4
|
import type { SkillSummary } from "./skills.js";
|
|
@@ -31,6 +32,10 @@ export function resolveSkillStates(
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
for (const skill of catalog) {
|
|
35
|
+
if (!isSkillCompatibleWithPlatform(skill)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
|
|
34
39
|
// Assistant feature flag gate: if the skill declares a flag and it's disabled, skip it
|
|
35
40
|
const flagKey = skillFlagKey(skill);
|
|
36
41
|
if (flagKey && !isAssistantFeatureFlagEnabled(flagKey, config)) {
|
package/src/config/skills.ts
CHANGED
|
@@ -18,11 +18,17 @@ import {
|
|
|
18
18
|
|
|
19
19
|
import { z } from "zod";
|
|
20
20
|
|
|
21
|
+
import type { ClientOs } from "../channels/types.js";
|
|
21
22
|
import { getDefaultPluginSkillRoots } from "../plugins/defaults/main.js";
|
|
22
23
|
import { isPluginDisabled } from "../plugins/disabled-state.js";
|
|
23
24
|
import { parseFrontmatterFields } from "../skills/frontmatter.js";
|
|
24
25
|
import type { InlineCommandExpansion } from "../skills/inline-command-expansions.js";
|
|
25
26
|
import { parseInlineCommandExpansions } from "../skills/inline-command-expansions.js";
|
|
27
|
+
import {
|
|
28
|
+
normalizeSkillPlatforms,
|
|
29
|
+
SKILL_PLATFORM_VALUES,
|
|
30
|
+
type SkillPlatform,
|
|
31
|
+
} from "../skills/platform-compatibility.js";
|
|
26
32
|
import { parseToolManifestFile } from "../skills/tool-manifest.js";
|
|
27
33
|
import { computeSkillVersionHash } from "../skills/version-hash.js";
|
|
28
34
|
import type { OwnerInfo } from "../tools/types.js";
|
|
@@ -50,6 +56,7 @@ const VellumMetadataSchema = z
|
|
|
50
56
|
"avoid-when": z.array(z.string()).optional(),
|
|
51
57
|
category: z.string().optional(),
|
|
52
58
|
"always-candidate": z.boolean().optional(),
|
|
59
|
+
platforms: z.array(z.enum(SKILL_PLATFORM_VALUES)).optional(),
|
|
53
60
|
})
|
|
54
61
|
.passthrough();
|
|
55
62
|
|
|
@@ -128,6 +135,8 @@ export interface SkillSummary {
|
|
|
128
135
|
* the model must judge, not embedding similarity.
|
|
129
136
|
*/
|
|
130
137
|
alwaysCandidate?: boolean;
|
|
138
|
+
/** Host operating systems on which this skill may be offered and loaded. */
|
|
139
|
+
platforms?: SkillPlatform[];
|
|
131
140
|
/** Parsed inline command expansion descriptors (`!\`command\``) found in the skill body. */
|
|
132
141
|
inlineCommandExpansions?: InlineCommandExpansion[];
|
|
133
142
|
}
|
|
@@ -184,6 +193,8 @@ export interface SkillToolEntry {
|
|
|
184
193
|
executor: string;
|
|
185
194
|
/** Where the tool script runs. */
|
|
186
195
|
execution_target: "host" | "sandbox";
|
|
196
|
+
/** Client operating systems that may expose this tool. Unset means all. */
|
|
197
|
+
supported_client_os?: ClientOs[];
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
/**
|
|
@@ -251,6 +262,7 @@ interface ParsedFrontmatter {
|
|
|
251
262
|
avoidWhen?: string[];
|
|
252
263
|
category?: string;
|
|
253
264
|
alwaysCandidate?: boolean;
|
|
265
|
+
platforms?: SkillPlatform[];
|
|
254
266
|
inlineCommandExpansions?: InlineCommandExpansion[];
|
|
255
267
|
}
|
|
256
268
|
|
|
@@ -373,6 +385,8 @@ function parseFrontmatter(
|
|
|
373
385
|
? vellum["always-candidate"]
|
|
374
386
|
: undefined;
|
|
375
387
|
|
|
388
|
+
const platforms = normalizeSkillPlatforms(vellum?.platforms);
|
|
389
|
+
|
|
376
390
|
const strippedBody = stripCommentLines(body);
|
|
377
391
|
|
|
378
392
|
// Parse inline command expansions from the body (after frontmatter/comment stripping)
|
|
@@ -398,6 +412,7 @@ function parseFrontmatter(
|
|
|
398
412
|
avoidWhen,
|
|
399
413
|
category,
|
|
400
414
|
alwaysCandidate,
|
|
415
|
+
platforms,
|
|
401
416
|
inlineCommandExpansions,
|
|
402
417
|
};
|
|
403
418
|
}
|
|
@@ -558,6 +573,7 @@ function readSkillFromDirectory(
|
|
|
558
573
|
avoidWhen: parsed.avoidWhen,
|
|
559
574
|
category: parsed.category,
|
|
560
575
|
alwaysCandidate: parsed.alwaysCandidate,
|
|
576
|
+
platforms: parsed.platforms,
|
|
561
577
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
562
578
|
};
|
|
563
579
|
} catch (err) {
|
|
@@ -614,6 +630,7 @@ function readBundledSkillFromDirectory(
|
|
|
614
630
|
avoidWhen: parsed.avoidWhen,
|
|
615
631
|
category: parsed.category,
|
|
616
632
|
alwaysCandidate: parsed.alwaysCandidate,
|
|
633
|
+
platforms: parsed.platforms,
|
|
617
634
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
618
635
|
};
|
|
619
636
|
} catch (err) {
|
|
@@ -682,6 +699,7 @@ function loadBundledSkills(): SkillSummary[] {
|
|
|
682
699
|
avoidWhen: skill.avoidWhen,
|
|
683
700
|
category: skill.category,
|
|
684
701
|
alwaysCandidate: skill.alwaysCandidate,
|
|
702
|
+
platforms: skill.platforms,
|
|
685
703
|
inlineCommandExpansions: skill.inlineCommandExpansions,
|
|
686
704
|
});
|
|
687
705
|
}
|
|
@@ -972,6 +990,7 @@ function skillSummaryFromDefinition(
|
|
|
972
990
|
avoidWhen: skill.avoidWhen,
|
|
973
991
|
category: skill.category,
|
|
974
992
|
alwaysCandidate: skill.alwaysCandidate,
|
|
993
|
+
platforms: skill.platforms,
|
|
975
994
|
inlineCommandExpansions: skill.inlineCommandExpansions,
|
|
976
995
|
};
|
|
977
996
|
}
|
|
@@ -1035,6 +1054,7 @@ export function loadSkillCatalog(
|
|
|
1035
1054
|
avoidWhen: parsed.avoidWhen,
|
|
1036
1055
|
category: parsed.category,
|
|
1037
1056
|
alwaysCandidate: parsed.alwaysCandidate,
|
|
1057
|
+
platforms: parsed.platforms,
|
|
1038
1058
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
1039
1059
|
});
|
|
1040
1060
|
} catch (err) {
|
|
@@ -1182,6 +1202,7 @@ export function loadSkillCatalog(
|
|
|
1182
1202
|
avoidWhen: parsed.avoidWhen,
|
|
1183
1203
|
category: parsed.category,
|
|
1184
1204
|
alwaysCandidate: parsed.alwaysCandidate,
|
|
1205
|
+
platforms: parsed.platforms,
|
|
1185
1206
|
inlineCommandExpansions: parsed.inlineCommandExpansions,
|
|
1186
1207
|
};
|
|
1187
1208
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { invalidateAllContactThresholdCaches } from "../permissions/gateway-threshold-reader.js";
|
|
1
2
|
import { broadcastMessage } from "../runtime/assistant-event-hub.js";
|
|
2
3
|
import { invalidateGuardianContactCache } from "./guardian-contact-reader.js";
|
|
3
4
|
import { invalidateGuardianDeliveryCache } from "./guardian-delivery-reader.js";
|
|
@@ -7,11 +8,13 @@ import { invalidateGuardianDeliveryCache } from "./guardian-delivery-reader.js";
|
|
|
7
8
|
* a successful contact write:
|
|
8
9
|
*
|
|
9
10
|
* - broadcasts `contacts_changed` so connected clients refresh their view, and
|
|
10
|
-
* - drops the guardian-contact
|
|
11
|
-
* refetches from the gateway instead of serving
|
|
11
|
+
* - drops the guardian-contact, guardian-delivery, and contact-threshold
|
|
12
|
+
* caches so the next read refetches from the gateway instead of serving
|
|
13
|
+
* a stale set.
|
|
12
14
|
*/
|
|
13
15
|
export function notifyContactsChanged(): void {
|
|
14
16
|
broadcastMessage({ type: "contacts_changed" });
|
|
15
17
|
invalidateGuardianContactCache();
|
|
16
18
|
invalidateGuardianDeliveryCache();
|
|
19
|
+
invalidateAllContactThresholdCaches();
|
|
17
20
|
}
|
package/src/context/compactor.ts
CHANGED
|
@@ -75,6 +75,40 @@ const COMPACTION_CALL_SITE: LLMCallSite = "mainAgent";
|
|
|
75
75
|
*/
|
|
76
76
|
const COMPACTION_LOG_CALL_SITE: LLMCallSite = "compactionAgent";
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* What actually served a compaction call, for attribution on both the request
|
|
80
|
+
* log and the usage row. A wrapper may reroute the request away from the
|
|
81
|
+
* caller's resolution (`RetryProvider`'s fallback-profile escalation), in
|
|
82
|
+
* which case the response carries the provider and profile that answered.
|
|
83
|
+
*
|
|
84
|
+
* Single source of truth on purpose: the request log and the usage row must
|
|
85
|
+
* never disagree about which provider ran, and every result-construction site
|
|
86
|
+
* below spreads {@link servedAttribution} rather than re-deriving the pair.
|
|
87
|
+
*/
|
|
88
|
+
function servedProvider(
|
|
89
|
+
response: ProviderResponse,
|
|
90
|
+
provider: Provider,
|
|
91
|
+
): string {
|
|
92
|
+
return response.actualProvider ?? provider.name;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function servedAttribution(
|
|
96
|
+
response: ProviderResponse,
|
|
97
|
+
provider: Provider,
|
|
98
|
+
): Pick<
|
|
99
|
+
CompactionRunResult,
|
|
100
|
+
"summaryActualProvider" | "summaryActualInferenceProfile"
|
|
101
|
+
> {
|
|
102
|
+
return {
|
|
103
|
+
summaryActualProvider: servedProvider(response, provider),
|
|
104
|
+
// Only present on a reroute. Absent leaves `summaryOverrideProfile` in
|
|
105
|
+
// charge, which is what the caller resolved and what actually ran.
|
|
106
|
+
...(response.actualInferenceProfile !== undefined
|
|
107
|
+
? { summaryActualInferenceProfile: response.actualInferenceProfile }
|
|
108
|
+
: {}),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
78
112
|
/**
|
|
79
113
|
* Best-effort: persist a successful compaction LLM call into
|
|
80
114
|
* `llm_request_logs` with `call_site = "compactionAgent"`. The compactor
|
|
@@ -100,7 +134,7 @@ function recordCompactionRequestLog(
|
|
|
100
134
|
JSON.stringify(response.rawRequest),
|
|
101
135
|
JSON.stringify(response.rawResponse),
|
|
102
136
|
undefined,
|
|
103
|
-
response
|
|
137
|
+
servedProvider(response, provider),
|
|
104
138
|
COMPACTION_LOG_CALL_SITE,
|
|
105
139
|
);
|
|
106
140
|
} catch (err) {
|
|
@@ -321,6 +355,22 @@ export interface CompactionRunResult {
|
|
|
321
355
|
summaryModel: string;
|
|
322
356
|
summaryCallSite?: LLMCallSite;
|
|
323
357
|
summaryOverrideProfile?: string | null;
|
|
358
|
+
/**
|
|
359
|
+
* Provider that actually served the summary call: the response's
|
|
360
|
+
* `actualProvider` when a wrapper rerouted the request, otherwise the
|
|
361
|
+
* configured provider's name. Set on every path that made a call, so the
|
|
362
|
+
* usage row's `provider` follows a fallback the way its `model` already
|
|
363
|
+
* does. Absent only where no call happened (see {@link emptyResult}), where
|
|
364
|
+
* the caller's own provider stands.
|
|
365
|
+
*/
|
|
366
|
+
summaryActualProvider?: string;
|
|
367
|
+
/**
|
|
368
|
+
* Inference profile that actually governed the summary call, set only when
|
|
369
|
+
* a wrapper rerouted the request away from `summaryOverrideProfile`
|
|
370
|
+
* (`RetryProvider`'s fallback-profile escalation). Absent on the normal
|
|
371
|
+
* path, where `summaryOverrideProfile` is already correct.
|
|
372
|
+
*/
|
|
373
|
+
summaryActualInferenceProfile?: string;
|
|
324
374
|
summaryCacheCreationInputTokens?: number;
|
|
325
375
|
summaryCacheReadInputTokens?: number;
|
|
326
376
|
summaryRawResponses?: unknown[];
|
|
@@ -1052,6 +1102,18 @@ export function buildSummaryMemoryText(
|
|
|
1052
1102
|
// Orchestrator
|
|
1053
1103
|
// ---------------------------------------------------------------------------
|
|
1054
1104
|
|
|
1105
|
+
/**
|
|
1106
|
+
* A result for every path that compacted nothing: the pre-call bail-outs
|
|
1107
|
+
* (disabled, below threshold, no messages, bad boundary) and the two
|
|
1108
|
+
* provider-error paths, which are spread over with `summaryFailed: true`.
|
|
1109
|
+
*
|
|
1110
|
+
* Deliberately carries no `summaryActualProvider` /
|
|
1111
|
+
* `summaryActualInferenceProfile`: no call was served, so there is nothing to
|
|
1112
|
+
* attribute to, and leaving them absent keeps the caller's own provider and
|
|
1113
|
+
* profile in charge. Nothing is billed either way, since the zero token
|
|
1114
|
+
* counts here make `recordUsage` return before it writes a row. The
|
|
1115
|
+
* call-bearing paths below spread {@link servedAttribution} on top.
|
|
1116
|
+
*/
|
|
1055
1117
|
function emptyResult(
|
|
1056
1118
|
args: CompactionRunArgs,
|
|
1057
1119
|
thresholdTokens: number,
|
|
@@ -1340,6 +1402,7 @@ export async function runAssistantDrivenCompaction(
|
|
|
1340
1402
|
summaryInputTokens: response.usage.inputTokens,
|
|
1341
1403
|
summaryOutputTokens: response.usage.outputTokens,
|
|
1342
1404
|
summaryModel: response.model,
|
|
1405
|
+
...servedAttribution(response, args.provider),
|
|
1343
1406
|
summaryCacheCreationInputTokens:
|
|
1344
1407
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
1345
1408
|
summaryCacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
@@ -1378,6 +1441,7 @@ export async function runAssistantDrivenCompaction(
|
|
|
1378
1441
|
summaryInputTokens: response.usage.inputTokens,
|
|
1379
1442
|
summaryOutputTokens: response.usage.outputTokens,
|
|
1380
1443
|
summaryModel: response.model,
|
|
1444
|
+
...servedAttribution(response, args.provider),
|
|
1381
1445
|
summaryCacheCreationInputTokens:
|
|
1382
1446
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
1383
1447
|
summaryCacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
@@ -1548,6 +1612,7 @@ export async function runAssistantDrivenCompaction(
|
|
|
1548
1612
|
summaryInputTokens: response.usage.inputTokens,
|
|
1549
1613
|
summaryOutputTokens: response.usage.outputTokens,
|
|
1550
1614
|
summaryModel: response.model,
|
|
1615
|
+
...servedAttribution(response, args.provider),
|
|
1551
1616
|
summaryCacheCreationInputTokens:
|
|
1552
1617
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
1553
1618
|
summaryCacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
@@ -1623,6 +1688,7 @@ export async function runAssistantDrivenCompaction(
|
|
|
1623
1688
|
summaryModel: response.model,
|
|
1624
1689
|
summaryCallSite: COMPACTION_CALL_SITE,
|
|
1625
1690
|
summaryOverrideProfile: args.overrideProfile ?? null,
|
|
1691
|
+
...servedAttribution(response, args.provider),
|
|
1626
1692
|
summaryCacheCreationInputTokens:
|
|
1627
1693
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
1628
1694
|
summaryCacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
@@ -1808,6 +1874,12 @@ export async function runEmergencyCompaction(
|
|
|
1808
1874
|
summaryInputTokens: response.usage.inputTokens,
|
|
1809
1875
|
summaryOutputTokens: response.usage.outputTokens,
|
|
1810
1876
|
summaryModel: response.model,
|
|
1877
|
+
// This path bills real tokens, so its provider must follow a reroute
|
|
1878
|
+
// like every other call-bearing path. It is the one such path that sets
|
|
1879
|
+
// no `summaryCallSite`/`summaryOverrideProfile`, which leaves its
|
|
1880
|
+
// profile attribution null; that gap predates this change and is not
|
|
1881
|
+
// widened by it.
|
|
1882
|
+
...servedAttribution(response, args.provider),
|
|
1811
1883
|
};
|
|
1812
1884
|
}
|
|
1813
1885
|
|
|
@@ -1855,6 +1927,7 @@ export async function runEmergencyCompaction(
|
|
|
1855
1927
|
summaryModel: response.model,
|
|
1856
1928
|
summaryCallSite: COMPACTION_CALL_SITE,
|
|
1857
1929
|
summaryOverrideProfile: args.overrideProfile ?? null,
|
|
1930
|
+
...servedAttribution(response, args.provider),
|
|
1858
1931
|
summaryCacheCreationInputTokens:
|
|
1859
1932
|
response.usage.cacheCreationInputTokens ?? 0,
|
|
1860
1933
|
summaryCacheReadInputTokens: response.usage.cacheReadInputTokens ?? 0,
|
|
@@ -36,14 +36,28 @@ import type { ChannelCapabilities } from "../conversation-runtime-assembly.js";
|
|
|
36
36
|
|
|
37
37
|
// Control how many capable clients the hub reports per capability.
|
|
38
38
|
const mockClientCountByCapability = new Map<string, number>();
|
|
39
|
+
const mockClientsByCapability = new Map<
|
|
40
|
+
string,
|
|
41
|
+
Array<{
|
|
42
|
+
clientId: string;
|
|
43
|
+
capabilities: string[];
|
|
44
|
+
interfaceId: string;
|
|
45
|
+
actorPrincipalId?: string;
|
|
46
|
+
}>
|
|
47
|
+
>();
|
|
39
48
|
|
|
40
49
|
mock.module("../../runtime/assistant-event-hub.js", () => ({
|
|
41
50
|
assistantEventHub: {
|
|
42
51
|
listClientsByCapability: (cap: string) => {
|
|
52
|
+
const clients = mockClientsByCapability.get(cap);
|
|
53
|
+
if (clients) {
|
|
54
|
+
return clients;
|
|
55
|
+
}
|
|
43
56
|
const count = mockClientCountByCapability.get(cap) ?? 0;
|
|
44
57
|
return Array.from({ length: count }, (_, i) => ({
|
|
45
58
|
clientId: `mock-${cap}-client-${i}`,
|
|
46
59
|
capabilities: [cap],
|
|
60
|
+
interfaceId: "macos",
|
|
47
61
|
}));
|
|
48
62
|
},
|
|
49
63
|
},
|
|
@@ -58,6 +72,9 @@ const {
|
|
|
58
72
|
HOST_TOOL_TO_CAPABILITY,
|
|
59
73
|
isToolActiveForContext,
|
|
60
74
|
} = await import("../conversation-tool-setup.js");
|
|
75
|
+
const { registerSkillTools, unregisterSkillTools } =
|
|
76
|
+
await import("../../tools/registry.js");
|
|
77
|
+
const { finalizeTool } = await import("../../tools/tool-defaults.js");
|
|
61
78
|
type SkillProjectionCache =
|
|
62
79
|
import("../conversation-skill-tools.js").SkillProjectionCache;
|
|
63
80
|
|
|
@@ -76,9 +93,129 @@ function makeCtx(
|
|
|
76
93
|
|
|
77
94
|
beforeEach(() => {
|
|
78
95
|
mockClientCountByCapability.clear();
|
|
96
|
+
mockClientsByCapability.clear();
|
|
79
97
|
});
|
|
80
98
|
|
|
81
|
-
describe("isToolActiveForContext
|
|
99
|
+
describe("isToolActiveForContext - client OS eligibility", () => {
|
|
100
|
+
test("hides a macOS-only skill tool from Windows turns", () => {
|
|
101
|
+
const skillId = "client-os-test-skill";
|
|
102
|
+
registerSkillTools(skillId, [
|
|
103
|
+
finalizeTool({
|
|
104
|
+
name: "client_os_test_tool",
|
|
105
|
+
supportedClientOs: ["macos"],
|
|
106
|
+
}),
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
try {
|
|
110
|
+
expect(
|
|
111
|
+
isToolActiveForContext(
|
|
112
|
+
"client_os_test_tool",
|
|
113
|
+
makeCtx({
|
|
114
|
+
clientOs: "windows",
|
|
115
|
+
currentTurnClientOs: "windows",
|
|
116
|
+
}),
|
|
117
|
+
),
|
|
118
|
+
).toBe(false);
|
|
119
|
+
expect(
|
|
120
|
+
isToolActiveForContext(
|
|
121
|
+
"client_os_test_tool",
|
|
122
|
+
makeCtx({ clientOs: "macos", currentTurnClientOs: "macos" }),
|
|
123
|
+
),
|
|
124
|
+
).toBe(true);
|
|
125
|
+
} finally {
|
|
126
|
+
unregisterSkillTools(skillId);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("uses same-user target desktops for cross-client tool eligibility", () => {
|
|
131
|
+
const skillId = "cross-client-os-test-skill";
|
|
132
|
+
registerSkillTools(skillId, [
|
|
133
|
+
finalizeTool({
|
|
134
|
+
name: "computer_use_platform_test",
|
|
135
|
+
supportedClientOs: ["macos"],
|
|
136
|
+
}),
|
|
137
|
+
]);
|
|
138
|
+
const ctx = makeCtx({
|
|
139
|
+
clientOs: "web",
|
|
140
|
+
currentTurnClientOs: "web",
|
|
141
|
+
transportInterface: "web",
|
|
142
|
+
getTurnActorPrincipalId: () => "actor-1",
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
mockClientsByCapability.set("host_cu", [
|
|
147
|
+
{
|
|
148
|
+
clientId: "mac-client",
|
|
149
|
+
capabilities: ["host_cu"],
|
|
150
|
+
interfaceId: "macos",
|
|
151
|
+
actorPrincipalId: "actor-1",
|
|
152
|
+
},
|
|
153
|
+
]);
|
|
154
|
+
expect(isToolActiveForContext("computer_use_platform_test", ctx)).toBe(
|
|
155
|
+
true,
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
mockClientsByCapability.set("host_cu", [
|
|
159
|
+
{
|
|
160
|
+
clientId: "windows-client",
|
|
161
|
+
capabilities: ["host_cu"],
|
|
162
|
+
interfaceId: "windows",
|
|
163
|
+
actorPrincipalId: "actor-1",
|
|
164
|
+
},
|
|
165
|
+
]);
|
|
166
|
+
expect(isToolActiveForContext("computer_use_platform_test", ctx)).toBe(
|
|
167
|
+
false,
|
|
168
|
+
);
|
|
169
|
+
} finally {
|
|
170
|
+
unregisterSkillTools(skillId);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("uses pinned client OS without falling through to live context", () => {
|
|
175
|
+
const skillId = "pinned-client-os-test-skill";
|
|
176
|
+
registerSkillTools(skillId, [
|
|
177
|
+
finalizeTool({
|
|
178
|
+
name: "client_os_pinned_test_tool",
|
|
179
|
+
supportedClientOs: ["macos"],
|
|
180
|
+
}),
|
|
181
|
+
]);
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
expect(
|
|
185
|
+
isToolActiveForContext(
|
|
186
|
+
"client_os_pinned_test_tool",
|
|
187
|
+
makeCtx({
|
|
188
|
+
clientOs: "windows",
|
|
189
|
+
currentTurnClientOs: "windows",
|
|
190
|
+
toolContextPin: {
|
|
191
|
+
hasNoClient: false,
|
|
192
|
+
transportInterface: "macos",
|
|
193
|
+
clientOs: "macos",
|
|
194
|
+
},
|
|
195
|
+
}),
|
|
196
|
+
),
|
|
197
|
+
).toBe(true);
|
|
198
|
+
expect(
|
|
199
|
+
isToolActiveForContext(
|
|
200
|
+
"client_os_pinned_test_tool",
|
|
201
|
+
makeCtx({
|
|
202
|
+
clientOs: "macos",
|
|
203
|
+
currentTurnClientOs: "macos",
|
|
204
|
+
toolContextPin: {
|
|
205
|
+
hasNoClient: false,
|
|
206
|
+
transportInterface: "windows",
|
|
207
|
+
clientOs: "windows",
|
|
208
|
+
},
|
|
209
|
+
}),
|
|
210
|
+
),
|
|
211
|
+
).toBe(false);
|
|
212
|
+
} finally {
|
|
213
|
+
unregisterSkillTools(skillId);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe("isToolActiveForContext - Slack task_progress UI exception", () => {
|
|
82
219
|
test("ui_show and ui_update are active for Slack task_progress turns", () => {
|
|
83
220
|
const ctx = makeCtx({
|
|
84
221
|
hasNoClient: false,
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
} from "node:fs";
|
|
16
16
|
import { basename, join } from "node:path";
|
|
17
17
|
|
|
18
|
+
import { AVATAR_IMAGE_FILENAME } from "@vellumai/avatar-manifest";
|
|
19
|
+
|
|
18
20
|
import { getConfig, invalidateConfigCache } from "../config/loader.js";
|
|
19
21
|
import type { MemoryCleanupConfig } from "../config/schemas/memory-lifecycle.js";
|
|
20
22
|
import { resetCleanupScheduleThrottle } from "../persistence/cleanup-schedule-state.js";
|
|
@@ -37,7 +39,6 @@ import { WORKSPACE_THEME_RELATIVE_PATH } from "../theme/workspace-theme.js";
|
|
|
37
39
|
import { DebouncerMap } from "../util/debounce.js";
|
|
38
40
|
import { getLogger } from "../util/logger.js";
|
|
39
41
|
import {
|
|
40
|
-
AVATAR_IMAGE_FILENAME,
|
|
41
42
|
getAvatarDir,
|
|
42
43
|
getSignalsDir,
|
|
43
44
|
getSoundsDir,
|
|
@@ -211,6 +211,15 @@ export interface EventHandlerState {
|
|
|
211
211
|
firstAssistantText: string;
|
|
212
212
|
/** Most recent resolved provider for the current exchange's usage accounting. */
|
|
213
213
|
exchangeProviderName: string | undefined;
|
|
214
|
+
/**
|
|
215
|
+
* Inference profile the most recent LLM call actually ran under, set only
|
|
216
|
+
* when a wrapper rerouted that call (`RetryProvider`'s fallback-profile
|
|
217
|
+
* escalation). Overwritten by every call, exactly like
|
|
218
|
+
* `exchangeProviderName` and `model`, so the ledger row's provider, model,
|
|
219
|
+
* and profile all describe the same call. `undefined` means the last call
|
|
220
|
+
* was not rerouted and the conversation's own profile resolution stands.
|
|
221
|
+
*/
|
|
222
|
+
exchangeInferenceProfile: string | undefined;
|
|
214
223
|
exchangeInputTokens: number;
|
|
215
224
|
exchangeCacheCreationInputTokens: number;
|
|
216
225
|
exchangeCacheReadInputTokens: number;
|
|
@@ -236,6 +245,14 @@ export interface EventHandlerState {
|
|
|
236
245
|
* the loop persists the failure as an assistant message.
|
|
237
246
|
*/
|
|
238
247
|
providerErrorCategory: string | null;
|
|
248
|
+
/**
|
|
249
|
+
* Connection and profile attribution of the most recent provider error
|
|
250
|
+
* (`classifyConversationError(...).connectionName` / `.profileName`).
|
|
251
|
+
* Carried into the turn's outcome stamp so failure consumers scope
|
|
252
|
+
* identity by the route the call actually resolved.
|
|
253
|
+
*/
|
|
254
|
+
providerErrorConnection: string | null;
|
|
255
|
+
providerErrorProfile: string | null;
|
|
239
256
|
persistProviderErrorAsAssistantMessage: boolean;
|
|
240
257
|
lastAssistantMessageId: string | undefined;
|
|
241
258
|
/**
|
|
@@ -578,6 +595,7 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
578
595
|
pendingDirectiveDisplayBuffer: "",
|
|
579
596
|
firstAssistantText: "",
|
|
580
597
|
exchangeProviderName: undefined,
|
|
598
|
+
exchangeInferenceProfile: undefined,
|
|
581
599
|
exchangeInputTokens: 0,
|
|
582
600
|
exchangeCacheCreationInputTokens: 0,
|
|
583
601
|
exchangeCacheReadInputTokens: 0,
|
|
@@ -589,6 +607,8 @@ export function createEventHandlerState(): EventHandlerState {
|
|
|
589
607
|
providerErrorUserMessage: null,
|
|
590
608
|
providerErrorCode: null,
|
|
591
609
|
providerErrorCategory: null,
|
|
610
|
+
providerErrorConnection: null,
|
|
611
|
+
providerErrorProfile: null,
|
|
592
612
|
persistProviderErrorAsAssistantMessage: false,
|
|
593
613
|
lastAssistantMessageId: undefined,
|
|
594
614
|
assistantRowAwaitingFinalization: false,
|
|
@@ -2722,6 +2742,8 @@ function handleError(
|
|
|
2722
2742
|
state.providerErrorUserMessage = classified.userMessage;
|
|
2723
2743
|
state.providerErrorCode = classified.code;
|
|
2724
2744
|
state.providerErrorCategory = classified.errorCategory;
|
|
2745
|
+
state.providerErrorConnection = classified.connectionName ?? null;
|
|
2746
|
+
state.providerErrorProfile = classified.profileName ?? null;
|
|
2725
2747
|
state.persistProviderErrorAsAssistantMessage =
|
|
2726
2748
|
shouldPersistProviderErrorAsAssistantMessage(classified);
|
|
2727
2749
|
}
|
|
@@ -3071,6 +3093,11 @@ function handleUsage(
|
|
|
3071
3093
|
): void {
|
|
3072
3094
|
const providerName = event.actualProvider ?? deps.ctx.provider.name;
|
|
3073
3095
|
state.exchangeProviderName = providerName;
|
|
3096
|
+
// Assigned unconditionally, not merged: a later non-rerouted call clearing
|
|
3097
|
+
// this back to `undefined` is correct, because provider and model are being
|
|
3098
|
+
// overwritten from that same call. Keeping a stale profile from an earlier
|
|
3099
|
+
// fallback would reintroduce the very contradiction this field prevents.
|
|
3100
|
+
state.exchangeInferenceProfile = event.actualInferenceProfile;
|
|
3074
3101
|
state.exchangeLlmCallCount += 1;
|
|
3075
3102
|
state.exchangeInputTokens += event.inputTokens;
|
|
3076
3103
|
state.lastCallInputTokens = event.inputTokens;
|