@vellumai/assistant 0.10.2 → 0.10.3-dev.202606252046.9075fd5
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/bun.lock +20 -0
- package/docs/workspace-tools.md +42 -33
- package/eslint-rules/cli-no-daemon-internals.js +6 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/guardian-delivery-contract.test.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +31 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +44 -0
- package/node_modules/@vellumai/gateway-client/src/guardian-delivery-contract.ts +48 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +14 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +17 -0
- package/node_modules/@vellumai/service-contracts/package.json +1 -0
- package/node_modules/@vellumai/service-contracts/src/__tests__/channels.test.ts +28 -0
- package/node_modules/@vellumai/service-contracts/src/channels.ts +41 -0
- package/node_modules/@vellumai/service-contracts/src/index.ts +1 -0
- package/openapi.yaml +196 -56
- package/package.json +4 -1
- package/scripts/test.sh +36 -15
- package/src/__tests__/actor-token-service.test.ts +36 -14
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +83 -31
- package/src/__tests__/agent-loop-override-profile.test.ts +1 -0
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/agent-wake-override-profile.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +2 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -0
- package/src/__tests__/approval-cascade.test.ts +2 -0
- package/src/__tests__/assistant-attachments.test.ts +42 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -0
- package/src/__tests__/btw-routes.test.ts +2 -0
- package/src/__tests__/build-persisted-content.test.ts +2 -0
- package/src/__tests__/call-controller.test.ts +19 -0
- package/src/__tests__/channel-approval-routes.test.ts +21 -26
- package/src/__tests__/channel-delivery-store.test.ts +28 -0
- package/src/__tests__/channel-guardian.test.ts +164 -78
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +11 -19
- package/src/__tests__/channel-reply-delivery.test.ts +2 -0
- package/src/__tests__/code-search-tool.test.ts +585 -0
- package/src/__tests__/compaction-events.test.ts +2 -0
- package/src/__tests__/compaction-ledger-store.test.ts +128 -0
- package/src/__tests__/compaction.benchmark.test.ts +2 -0
- package/src/__tests__/compactor-call-site-logging.test.ts +2 -0
- package/src/__tests__/compactor-low-watermark-cut.test.ts +2 -0
- package/src/__tests__/compactor-preserved-tail-count.test.ts +2 -0
- package/src/__tests__/compactor-summary-call-truncation.test.ts +2 -0
- package/src/__tests__/compactor-web-search-strip.test.ts +2 -0
- package/src/__tests__/config-loader-backfill.test.ts +123 -10
- package/src/__tests__/config-schema.test.ts +1 -0
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +31 -29
- package/src/__tests__/consult-deadline.test.ts +60 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +156 -0
- package/src/__tests__/contact-store-user-file.test.ts +7 -10
- package/src/__tests__/contacts-relay-reads.test.ts +19 -24
- package/src/__tests__/contacts-write.test.ts +0 -2
- package/src/__tests__/conversation-abort-tool-results.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +2 -0
- package/src/__tests__/conversation-agent-loop.test.ts +134 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +2 -0
- package/src/__tests__/conversation-app-control-lifecycle.test.ts +2 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +9 -11
- package/src/__tests__/conversation-confirmation-signals.test.ts +2 -0
- package/src/__tests__/conversation-fork-crud.test.ts +354 -24
- package/src/__tests__/conversation-history-web-search.test.ts +2 -0
- package/src/__tests__/conversation-load-history-repair.test.ts +2 -0
- package/src/__tests__/conversation-load-history-stripped.test.ts +2 -0
- package/src/__tests__/conversation-pairing.test.ts +2 -0
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +2 -0
- package/src/__tests__/conversation-process-callsite.test.ts +2 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +2 -0
- package/src/__tests__/conversation-queue.test.ts +91 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +14 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +14 -0
- package/src/__tests__/conversation-slash-queue.test.ts +2 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +2 -0
- package/src/__tests__/conversation-speed-override.test.ts +2 -0
- package/src/__tests__/conversation-surfaces-task-progress.test.ts +29 -0
- package/src/__tests__/conversation-title-service.test.ts +2 -0
- package/src/__tests__/conversation-tool-setup-attribution.test.ts +47 -0
- package/src/__tests__/conversation-usage.test.ts +2 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +2 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +2 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +2 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -1
- package/src/__tests__/db-compaction-events-migration.test.ts +129 -0
- package/src/__tests__/db-migration-rollback.test.ts +205 -171
- package/src/__tests__/db-test-helpers.ts +5 -4
- package/src/__tests__/delete-propagation.test.ts +5 -3
- package/src/__tests__/deterministic-verification-control-plane.test.ts +4 -2
- package/src/__tests__/disk-pressure-guard.test.ts +41 -0
- package/src/__tests__/dm-backfill.test.ts +6 -4
- package/src/__tests__/dm-persistence.test.ts +2 -0
- package/src/__tests__/emit-signal-routing-intent.test.ts +7 -6
- package/src/__tests__/events-dev-bypass-actor.test.ts +7 -1
- package/src/__tests__/exploration-drift-hook.test.ts +3 -2
- package/src/__tests__/filing-service.test.ts +2 -0
- package/src/__tests__/guardian-binding-drift-heal.test.ts +104 -19
- package/src/__tests__/guardian-dispatch.test.ts +140 -1
- package/src/__tests__/guardian-expiry-notifier.test.ts +282 -0
- package/src/__tests__/guardian-outbound-http.test.ts +13 -0
- package/src/__tests__/guardian-routing-state.test.ts +6 -10
- package/src/__tests__/heartbeat-disk-pressure.test.ts +2 -0
- package/src/__tests__/heartbeat-service.test.ts +2 -0
- package/src/__tests__/helpers/channel-test-adapter.ts +46 -19
- package/src/__tests__/helpers/create-guardian-binding.ts +15 -23
- package/src/__tests__/helpers/mock-logger.ts +1 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +96 -0
- package/src/__tests__/host-app-control-routes.test.ts +24 -30
- package/src/__tests__/host-bash-routes.test.ts +31 -41
- package/src/__tests__/host-browser-routes.test.ts +26 -32
- package/src/__tests__/host-cu-routes-targeted.test.ts +25 -33
- package/src/__tests__/host-file-routes-targeted.test.ts +40 -52
- package/src/__tests__/host-transfer-routes-targeted.test.ts +31 -43
- package/src/__tests__/http-user-message-parity.test.ts +290 -8
- package/src/__tests__/inbound-invite-redemption.test.ts +115 -10
- package/src/__tests__/inbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/invite-redemption-service.test.ts +471 -53
- package/src/__tests__/invite-routes-http.test.ts +34 -0
- package/src/__tests__/invite-service-ipc.test.ts +65 -2
- package/src/__tests__/llm-context-normalization.test.ts +105 -0
- package/src/__tests__/llm-request-log-error-payload.test.ts +71 -9
- package/src/__tests__/llm-usage-store.test.ts +25 -0
- package/src/__tests__/mcp-config-secret-boundary.test.ts +392 -0
- package/src/__tests__/mcp-health-check.test.ts +2 -1
- package/src/__tests__/media-stream-server-integration.test.ts +127 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +2 -0
- package/src/__tests__/messaging-send-tool.test.ts +2 -0
- package/src/__tests__/migration-import-from-url.test.ts +2 -2
- package/src/__tests__/mtime-cache.test.ts +275 -5
- package/src/__tests__/native-web-search.test.ts +2 -0
- package/src/__tests__/non-member-access-request.test.ts +191 -17
- package/src/__tests__/notification-broadcaster.test.ts +4 -0
- package/src/__tests__/notification-decision-recipient-context.test.ts +33 -32
- package/src/__tests__/notification-deep-link.test.ts +6 -0
- package/src/__tests__/notification-guardian-path.test.ts +19 -0
- package/src/__tests__/onboarding-persona-write.test.ts +52 -22
- package/src/__tests__/openai-provider.test.ts +22 -12
- package/src/__tests__/openai-responses-provider.test.ts +12 -2
- package/src/__tests__/outbound-slack-persistence.test.ts +2 -0
- package/src/__tests__/pending-interactions-resolved-event.test.ts +7 -4
- package/src/__tests__/persist-onboarding-artifacts.test.ts +1 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +2 -0
- package/src/__tests__/persona-resolver.test.ts +75 -45
- package/src/__tests__/plugin-bootstrap.test.ts +21 -83
- package/src/__tests__/plugin-disabled-state.test.ts +190 -0
- package/src/__tests__/plugin-pipeline.test.ts +96 -0
- package/src/__tests__/plugin-route-contribution.test.ts +6 -19
- package/src/__tests__/plugin-tool-contribution.test.ts +5 -20
- package/src/__tests__/plugin-types.test.ts +2 -4
- package/src/__tests__/process-message-background-slack.test.ts +2 -0
- package/src/__tests__/process-message-display-content.test.ts +2 -0
- package/src/__tests__/provider-error-scenarios.test.ts +5 -4
- package/src/__tests__/provider-usage-tracking.test.ts +39 -0
- package/src/__tests__/reaction-intercept-cold-cache-warm.test.ts +135 -0
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +158 -0
- package/src/__tests__/reaction-persistence.test.ts +51 -4
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +2 -0
- package/src/__tests__/registry.test.ts +4 -1
- package/src/__tests__/relay-server.test.ts +758 -32
- package/src/__tests__/runtime-attachment-metadata.test.ts +9 -12
- package/src/__tests__/secret-ingress-http.test.ts +14 -0
- package/src/__tests__/send-endpoint-busy.test.ts +30 -8
- package/src/__tests__/settings-routes.test.ts +32 -0
- package/src/__tests__/skills.test.ts +44 -0
- package/src/__tests__/slack-inbound-verification.test.ts +47 -2
- package/src/__tests__/sse-actor-principal-guardian-source.test.ts +79 -0
- package/src/__tests__/steer-on-enqueue-question.test.ts +181 -0
- package/src/__tests__/stt-hints.test.ts +49 -15
- package/src/__tests__/subagent-detail.test.ts +27 -0
- package/src/__tests__/subagent-disposal.test.ts +65 -0
- package/src/__tests__/subagent-fork-prompt-role.test.ts +195 -0
- package/src/__tests__/subagent-fork-spawn.test.ts +6 -7
- package/src/__tests__/subagent-notify-parent.test.ts +2 -0
- package/src/__tests__/subagent-role-registry.test.ts +24 -6
- package/src/__tests__/subagent-spawn-and-await.test.ts +546 -0
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +2 -0
- package/src/__tests__/subagent-tools.test.ts +398 -1
- package/src/__tests__/suggestion-routes.test.ts +2 -0
- package/src/__tests__/thread-backfill.test.ts +3 -3
- package/src/__tests__/title-generate-hook.test.ts +2 -0
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +2 -0
- package/src/__tests__/tool-executor.test.ts +16 -11
- package/src/__tests__/tool-preview-lifecycle.test.ts +2 -0
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +2 -0
- package/src/__tests__/tool-start-timestamp.test.ts +2 -0
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +37 -51
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +12 -12
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +9 -7
- package/src/__tests__/trusted-contact-multichannel.test.ts +16 -7
- package/src/__tests__/trusted-contact-verification.test.ts +79 -54
- package/src/__tests__/twilio-routes.test.ts +96 -0
- package/src/__tests__/ui-file-upload-surface.test.ts +86 -0
- package/src/__tests__/verification-control-plane-policy.test.ts +2 -0
- package/src/__tests__/voice-guardian-cold-cache-warm.test.ts +137 -0
- package/src/__tests__/voice-invite-redemption.test.ts +216 -20
- package/src/__tests__/web-search-backend-failure.test.ts +2 -0
- package/src/__tests__/workspace-migration-102-preserve-heartbeat-enabled-for-existing-workspaces.test.ts +3 -3
- package/src/__tests__/workspace-migration-111-prune-seeded-callsite-defaults.test.ts +208 -0
- package/src/__tests__/workspace-migration-112-remove-advisor-callsite-override.test.ts +170 -0
- package/src/__tests__/workspace-migration-drop-user-md.test.ts +196 -238
- package/src/__tests__/workspace-migration-remove-hooks.test.ts +14 -35
- package/src/__tests__/workspace-tool-loader.test.ts +195 -2
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +35 -47
- package/src/agent/loop-exclusive-tool.test.ts +154 -0
- package/src/agent/loop-native-web-search.test.ts +200 -0
- package/src/agent/loop.ts +164 -1
- package/src/api/constants/sse-replay.ts +41 -0
- package/src/api/events/conversation-notice.ts +26 -0
- package/src/api/index.ts +19 -1
- package/src/api/responses/llm-request-log-entry.ts +29 -0
- package/src/api/responses/subagent-detail.ts +17 -0
- package/src/api/surfaces.ts +39 -3
- package/src/approvals/guardian-channel-delivery.ts +30 -0
- package/src/approvals/guardian-expiry-notifier.ts +148 -0
- package/src/approvals/guardian-request-resolvers.ts +17 -15
- package/src/calls/__tests__/relay-setup-router.test.ts +267 -17
- package/src/calls/call-domain.ts +3 -3
- package/src/calls/guardian-dispatch.ts +14 -9
- package/src/calls/inbound-trust-reader.ts +24 -2
- package/src/calls/media-stream-server.ts +21 -0
- package/src/calls/relay-access-wait.ts +6 -6
- package/src/calls/relay-server.ts +188 -51
- package/src/calls/relay-setup-router.ts +47 -17
- package/src/calls/relay-verification.ts +4 -4
- package/src/calls/stt-hints.ts +9 -12
- package/src/calls/twilio-routes.ts +14 -4
- package/src/channels/types.ts +10 -20
- package/src/cli/commands/__tests__/cache.test.ts +8 -1
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -0
- package/src/cli/commands/cache.ts +194 -181
- package/src/cli/commands/contacts.ts +10 -7
- package/src/cli/commands/db/__tests__/repair.test.ts +6 -5
- package/src/cli/commands/db/status.ts +37 -1
- package/src/cli/commands/mcp.ts +252 -218
- package/src/cli/commands/memory/__tests__/worker.test.ts +432 -0
- package/src/cli/commands/memory/index.ts +2 -0
- package/src/cli/commands/memory/worker.ts +242 -0
- package/src/cli/commands/plugins.ts +125 -13
- package/src/cli/lib/__tests__/install-from-github.test.ts +102 -0
- package/src/cli/lib/__tests__/list-installed-plugins.test.ts +160 -1
- package/src/cli/lib/__tests__/publish-plugin.test.ts +404 -0
- package/src/cli/lib/list-installed-plugins.ts +179 -1
- package/src/cli/lib/publish-plugin.ts +633 -0
- package/src/config/__tests__/loader-callsite-strip-fallback.test.ts +143 -0
- package/src/config/__tests__/sync-gated-profiles.test.ts +16 -10
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +27 -17
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +13 -3
- package/src/config/bundled-skills/subagent/SKILL.md +17 -2
- package/src/config/bundled-skills/subagent/TOOLS.json +5 -4
- package/src/config/call-site-defaults.ts +0 -6
- package/src/config/feature-flag-registry.json +5 -13
- package/src/config/llm-resolver.ts +0 -3
- package/src/config/loader.ts +38 -5
- package/src/config/prune-seeded-callsite-defaults.ts +110 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +0 -7
- package/src/config/schemas/heartbeat.ts +2 -5
- package/src/config/schemas/llm.ts +3 -12
- package/src/config/schemas/memory-lifecycle.ts +12 -0
- package/src/config/schemas/memory-v3.ts +7 -0
- package/src/config/schemas/memory.ts +4 -0
- package/src/config/schemas/timeouts.ts +8 -0
- package/src/config/seed-inference-profiles.ts +30 -34
- package/src/config/skills.ts +27 -5
- package/src/config/sync-gated-profiles.ts +12 -16
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +128 -0
- package/src/contacts/__tests__/guardian-delivery-reader.test.ts +312 -0
- package/src/contacts/__tests__/member-write-relay.test.ts +226 -0
- package/src/contacts/contact-store.ts +27 -237
- package/src/contacts/contacts-write.ts +18 -55
- package/src/contacts/gateway-channel-read.ts +51 -0
- package/src/contacts/guardian-delivery-reader.ts +223 -0
- package/src/contacts/member-write-relay.ts +183 -0
- package/src/contacts/types.ts +3 -15
- package/src/daemon/__tests__/conversation-tool-setup-exclude.test.ts +35 -0
- package/src/daemon/__tests__/conversation-tool-setup.test.ts +0 -44
- package/src/daemon/assistant-attachments.ts +27 -4
- package/src/daemon/conversation-agent-loop.ts +28 -0
- package/src/daemon/conversation-notices.ts +60 -0
- package/src/daemon/conversation-process.ts +35 -16
- package/src/daemon/conversation-surfaces.ts +111 -38
- package/src/daemon/conversation-tool-setup.ts +71 -30
- package/src/daemon/conversation.ts +23 -1
- package/src/daemon/disk-pressure-guard.ts +12 -2
- package/src/daemon/event-loop-watchdog.ts +28 -1
- package/src/daemon/external-plugins-bootstrap.ts +17 -41
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -2
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +25 -2
- package/src/daemon/handlers/__tests__/config-channels.test.ts +220 -0
- package/src/daemon/handlers/config-a2a.ts +6 -14
- package/src/daemon/handlers/config-channels.ts +67 -26
- package/src/daemon/handlers/conversations.ts +77 -0
- package/src/daemon/lifecycle.ts +16 -0
- package/src/daemon/mcp-reload-service.ts +10 -0
- package/src/daemon/memory-v2-startup.test.ts +72 -0
- package/src/daemon/memory-v2-startup.ts +87 -19
- package/src/daemon/message-types/conversations.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +12 -12
- package/src/daemon/server.ts +0 -4
- package/src/daemon/shutdown-handlers.ts +20 -0
- package/src/daemon/tool-setup-types.ts +9 -0
- package/src/heartbeat/heartbeat-service.ts +5 -0
- package/src/home/relationship-state-writer.ts +5 -0
- package/src/hooks/hook-loader.ts +341 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +1 -1
- package/src/ipc/assistant-server.ts +2 -2
- package/src/mcp/__tests__/mcp-auth-orchestrator.test.ts +1 -0
- package/src/mcp/client.ts +15 -1
- package/src/mcp/mcp-auth-orchestrator.ts +6 -1
- package/src/mcp/mcp-header-store.ts +134 -0
- package/src/mcp/mcp-oauth-provider.ts +19 -8
- package/src/memory/__tests__/301-create-watchdog-events.test.ts +110 -0
- package/src/memory/__tests__/memory-retrospective-job.test.ts +8 -0
- package/src/memory/__tests__/prompt-override.test.ts +192 -0
- package/src/memory/__tests__/watchdog-events-store.test.ts +161 -0
- package/src/memory/compaction-ledger-store.ts +107 -0
- package/src/memory/conversation-crud.ts +129 -61
- package/src/memory/db-connection.ts +22 -3
- package/src/memory/db-init.ts +37 -503
- package/src/memory/db-singleton.ts +6 -4
- package/src/memory/jobs-worker.ts +104 -0
- package/src/memory/llm-request-log-store.ts +26 -1
- package/src/memory/llm-usage-store.ts +48 -20
- package/src/memory/memory-retrospective-job.ts +14 -8
- package/src/memory/migrations/209-strip-thinking-from-consolidated.ts +152 -56
- package/src/memory/migrations/300-add-processing-started-at.ts +30 -0
- package/src/memory/migrations/301-create-watchdog-events.ts +45 -0
- package/src/memory/migrations/302-create-compaction-events.ts +107 -0
- package/src/memory/migrations/__tests__/209-strip-thinking-from-consolidated.test.ts +297 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +2 -2
- package/src/memory/migrations/run-migrations.ts +106 -10
- package/src/memory/migrations/validate-migration-state.ts +105 -67
- package/src/memory/prompt-override.ts +129 -0
- package/src/memory/schema/contacts.ts +6 -2
- package/src/memory/schema/conversations.ts +37 -0
- package/src/memory/schema/infrastructure.ts +20 -0
- package/src/memory/steps.ts +1294 -0
- package/src/memory/v2/__tests__/cli-command-store.test.ts +25 -0
- package/src/memory/v2/__tests__/skill-store.test.ts +80 -0
- package/src/memory/v2/cli-command-store.ts +75 -38
- package/src/memory/v2/prompts/consolidation.ts +13 -82
- package/src/memory/v2/prompts/router.ts +21 -93
- package/src/memory/v2/skill-store.ts +68 -31
- package/src/memory/watchdog-events-store.ts +87 -0
- package/src/memory/worker-control.ts +204 -0
- package/src/memory/worker-process.ts +89 -0
- package/src/messaging/channel-binding-metadata.ts +31 -0
- package/src/messaging/provider-types.ts +8 -0
- package/src/messaging/providers/slack/binding-metadata.ts +60 -0
- package/src/notifications/__tests__/broadcaster.test.ts +8 -8
- package/src/notifications/__tests__/connected-channels.test.ts +86 -0
- package/src/notifications/__tests__/decision-engine.test.ts +78 -9
- package/src/notifications/__tests__/destination-resolver.test.ts +151 -0
- package/src/notifications/broadcaster.ts +8 -1
- package/src/notifications/decision-engine.ts +15 -7
- package/src/notifications/destination-resolver.ts +53 -25
- package/src/notifications/emit-signal.ts +34 -15
- package/src/onboarding/checkin-event.test.ts +222 -0
- package/src/onboarding/checkin-event.ts +321 -0
- package/src/onboarding/schedule-checkin.ts +190 -0
- package/src/permissions/question-prompter.test.ts +1 -1
- package/src/permissions/question-prompter.ts +7 -4
- package/src/plugin-api/index.ts +12 -12
- package/src/plugin-api/types.ts +12 -14
- package/src/plugin-api/vision-support.test.ts +28 -4
- package/src/plugin-api/vision-support.ts +66 -31
- package/src/plugins/defaults/empty-response/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/empty-response/hooks/stop.ts +2 -2
- package/src/plugins/defaults/exploration-drift/hooks/post-tool-use.ts +4 -3
- package/src/plugins/defaults/history-repair/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/history-repair/hooks/stop.ts +2 -2
- package/src/plugins/defaults/history-repair/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/image-fallback/__tests__/image-fallback.test.ts +47 -7
- package/src/plugins/defaults/image-fallback/hooks/post-tool-use.ts +12 -13
- package/src/plugins/defaults/image-fallback/hooks/user-prompt-submit.ts +14 -22
- package/src/plugins/defaults/image-fallback/src/caption-blocks.ts +42 -11
- package/src/plugins/defaults/image-recovery/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/image-recovery/hooks/stop.ts +2 -2
- package/src/plugins/defaults/index.ts +0 -35
- package/src/plugins/defaults/max-tokens-continue/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/max-tokens-continue/hooks/stop.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +33 -3
- package/src/plugins/defaults/memory-v3-shadow/__tests__/pool-select.test.ts +48 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +4 -8
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +43 -15
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +11 -2
- package/src/plugins/defaults/memory-v3-shadow/pool-select.test.ts +146 -0
- package/src/plugins/defaults/memory-v3-shadow/pool-select.ts +77 -13
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +12 -11
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +2 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +2 -2
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +2 -2
- package/src/plugins/defaults/title-generate/hooks/stop.ts +2 -2
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +2 -2
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +2 -2
- package/src/plugins/disabled-state.ts +31 -0
- package/src/plugins/external-plugin-loader.ts +2 -2
- package/src/plugins/mtime-cache.ts +186 -330
- package/src/plugins/pipeline.ts +111 -13
- package/src/plugins/registry.ts +59 -16
- package/src/plugins/surface-import.ts +121 -0
- package/src/plugins/types.ts +7 -9
- package/src/prompts/persona-resolver.ts +43 -11
- package/src/providers/anthropic/client.ts +5 -0
- package/src/providers/call-site-routing.ts +45 -0
- package/src/providers/model-catalog.ts +16 -0
- package/src/providers/openai/__tests__/api-error-normalization.test.ts +321 -0
- package/src/providers/openai/api-error-normalization.ts +270 -0
- package/src/providers/openai/chat-completions-provider.ts +37 -83
- package/src/providers/openai/responses-provider.ts +50 -46
- package/src/providers/openrouter/client.ts +5 -0
- package/src/providers/provider-send-message.ts +10 -0
- package/src/providers/ratelimit.ts +10 -0
- package/src/providers/registry.ts +1 -1
- package/src/providers/retry.ts +10 -0
- package/src/providers/types.ts +22 -0
- package/src/providers/usage-tracking.ts +10 -0
- package/src/runtime/__tests__/channel-verification-service.test.ts +133 -0
- package/src/runtime/__tests__/guardian-vellum-migration.test.ts +184 -0
- package/src/runtime/__tests__/is-guardian-bound-for-channel.test.ts +66 -0
- package/src/runtime/__tests__/local-principal-trust.test.ts +162 -0
- package/src/runtime/__tests__/member-verdict-cache.test.ts +119 -0
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +402 -123
- package/src/runtime/access-request-helper.ts +18 -39
- package/src/runtime/actor-trust-resolver.ts +46 -19
- package/src/runtime/anchored-guardian.test.ts +109 -0
- package/src/runtime/anchored-guardian.ts +86 -0
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/assistant-stream-state.ts +9 -2
- package/src/runtime/auth/__tests__/require-bound-guardian.test.ts +99 -0
- package/src/runtime/auth/require-bound-guardian.ts +21 -11
- package/src/runtime/channel-verification-service.ts +56 -31
- package/src/runtime/confirmation-request-guardian-bridge.ts +3 -3
- package/src/runtime/guardian-vellum-migration.ts +69 -8
- package/src/runtime/invite-redemption-service.ts +213 -187
- package/src/runtime/local-actor-identity.test.ts +108 -0
- package/src/runtime/local-actor-identity.ts +85 -13
- package/src/runtime/local-principal-trust.ts +52 -0
- package/src/runtime/member-verdict-cache.ts +0 -0
- package/src/runtime/pending-interactions.ts +11 -1
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +56 -5
- package/src/runtime/routes/__tests__/channel-verification-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/contact-routes.test.ts +305 -0
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +92 -0
- package/src/runtime/routes/__tests__/http-adapter-actor-header.test.ts +129 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +188 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +13 -5
- package/src/runtime/routes/channel-verification-routes.ts +3 -3
- package/src/runtime/routes/contact-routes.ts +48 -57
- package/src/runtime/routes/conversation-cli-routes.ts +4 -5
- package/src/runtime/routes/conversation-list-routes.ts +4 -7
- package/src/runtime/routes/conversation-query-routes.ts +72 -0
- package/src/runtime/routes/conversation-routes.ts +84 -85
- package/src/runtime/routes/events-routes.ts +2 -2
- package/src/runtime/routes/global-search-routes.ts +3 -1
- package/src/runtime/routes/guardian-action-routes.ts +4 -5
- package/src/runtime/routes/host-app-control-routes.ts +5 -4
- package/src/runtime/routes/host-bash-routes.ts +5 -4
- package/src/runtime/routes/host-browser-routes.ts +9 -11
- package/src/runtime/routes/host-cu-routes.ts +5 -4
- package/src/runtime/routes/host-file-routes.ts +5 -4
- package/src/runtime/routes/host-transfer-routes.ts +6 -6
- package/src/runtime/routes/http-adapter.ts +16 -1
- package/src/runtime/routes/identity-routes.ts +3 -2
- package/src/runtime/routes/inbound-message-handler.ts +5 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +97 -5
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +61 -59
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +13 -5
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.test.ts +21 -8
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +14 -3
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +19 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/llm-context-normalization.ts +83 -0
- package/src/runtime/routes/mcp-auth-routes.ts +171 -19
- package/src/runtime/routes/migration-rollback-routes.ts +4 -3
- package/src/runtime/routes/migration-routes.ts +4 -1
- package/src/runtime/routes/onboarding-checkin-routes.ts +86 -0
- package/src/runtime/routes/settings-routes.ts +8 -3
- package/src/runtime/routes/subagents-routes.ts +5 -0
- package/src/runtime/routes/surface-action-routes.ts +42 -56
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +1 -0
- package/src/runtime/services/conversation-serializer.ts +13 -58
- package/src/runtime/tool-grant-request-helper.ts +3 -3
- package/src/runtime/trust-verdict-consumer.ts +111 -40
- package/src/runtime/verification-outbound-actions.ts +18 -18
- package/src/signals/user-message.ts +16 -0
- package/src/subagent/__tests__/consult-prompt.test.ts +35 -0
- package/src/{plugins/defaults/advisor/__tests__/transcript.test.ts → subagent/__tests__/consult-transcript.test.ts} +47 -10
- package/src/{plugins/defaults/advisor/steering.ts → subagent/consult-prompt.ts} +22 -32
- package/src/{plugins/defaults/advisor/transcript.ts → subagent/consult-transcript.ts} +18 -8
- package/src/subagent/index.ts +1 -1
- package/src/subagent/manager.ts +254 -33
- package/src/subagent/types.ts +11 -4
- package/src/telemetry/types.ts +34 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +3 -2
- package/src/telemetry/usage-telemetry-reporter.ts +87 -3
- package/src/tools/ask-question/ask-question-tool.test.ts +29 -0
- package/src/tools/ask-question/ask-question-tool.ts +13 -0
- package/src/tools/executor.ts +4 -4
- package/src/tools/filesystem/search.ts +543 -0
- package/src/tools/registry.ts +38 -0
- package/src/tools/shared/filesystem/path-policy.ts +12 -5
- package/src/tools/subagent/consult-deadline.ts +49 -0
- package/src/tools/subagent/spawn.ts +234 -5
- package/src/tools/tool-approval-handler.ts +1 -1
- package/src/tools/tool-defaults.ts +9 -2
- package/src/tools/tool-manifest.ts +3 -0
- package/src/tools/types.ts +131 -25
- package/src/tools/workspace-tools/loader.ts +348 -244
- package/src/util/errors.ts +26 -1
- package/src/util/logger.ts +9 -0
- package/src/util/platform.ts +19 -0
- package/src/util/telemetry-db-path.ts +24 -0
- package/src/workflows/library.test.ts +140 -0
- package/src/workflows/library.ts +82 -28
- package/src/workspace/migrations/017-seed-persona-dirs.ts +3 -34
- package/src/workspace/migrations/019-scope-journal-to-guardian.ts +3 -24
- package/src/workspace/migrations/031-drop-user-md.ts +232 -148
- package/src/workspace/migrations/048-remove-workspace-hooks.ts +14 -66
- package/src/workspace/migrations/111-prune-seeded-callsite-defaults.ts +134 -0
- package/src/workspace/migrations/112-remove-advisor-callsite-override.ts +64 -0
- package/src/workspace/migrations/registry.ts +4 -0
- package/src/__tests__/workspace-tools-watcher-flag.test.ts +0 -70
- package/src/daemon/workspace-tools-watcher.ts +0 -328
- package/src/memory/migrations/registry.ts +0 -573
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +0 -56
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +0 -43
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +0 -137
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +0 -153
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +0 -138
- package/src/plugins/defaults/advisor/advisor-gate.ts +0 -29
- package/src/plugins/defaults/advisor/advisor-state-store.ts +0 -94
- package/src/plugins/defaults/advisor/config.ts +0 -21
- package/src/plugins/defaults/advisor/consult.ts +0 -93
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +0 -34
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +0 -30
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +0 -19
- package/src/plugins/defaults/advisor/package.json +0 -14
- package/src/plugins/defaults/advisor/tools/advisor.ts +0 -65
- package/src/providers/openai/__tests__/api-error-detail.test.ts +0 -120
|
@@ -300,13 +300,6 @@ const CATALOG_RECORD: CatalogRecord = {
|
|
|
300
300
|
description: "General-purpose LLM inference call site for skill use.",
|
|
301
301
|
domain: "skills",
|
|
302
302
|
},
|
|
303
|
-
advisor: {
|
|
304
|
-
id: "advisor",
|
|
305
|
-
displayName: "Advisor",
|
|
306
|
-
description:
|
|
307
|
-
"Stronger reviewer model consulted mid-task to shape or pressure-test the plan.",
|
|
308
|
-
domain: "skills",
|
|
309
|
-
},
|
|
310
303
|
vision: {
|
|
311
304
|
id: "vision",
|
|
312
305
|
displayName: "Vision",
|
|
@@ -5,10 +5,7 @@ export const HeartbeatConfigSchema = z
|
|
|
5
5
|
.object({
|
|
6
6
|
enabled: z
|
|
7
7
|
.boolean({ error: "heartbeat.enabled must be a boolean" })
|
|
8
|
-
|
|
9
|
-
// the default was true keep their behavior via workspace migration
|
|
10
|
-
// 102-preserve-heartbeat-enabled-for-existing-workspaces.
|
|
11
|
-
.default(false)
|
|
8
|
+
.default(true)
|
|
12
9
|
.describe("Whether periodic heartbeat checks are enabled"),
|
|
13
10
|
intervalMs: z
|
|
14
11
|
.number({ error: "heartbeat.intervalMs must be a number" })
|
|
@@ -64,7 +61,7 @@ export const HeartbeatConfigSchema = z
|
|
|
64
61
|
.int("heartbeat.maxDailyRuns must be an integer")
|
|
65
62
|
.positive("heartbeat.maxDailyRuns must be a positive integer")
|
|
66
63
|
.nullable()
|
|
67
|
-
.default(
|
|
64
|
+
.default(10)
|
|
68
65
|
.describe(
|
|
69
66
|
"Maximum heartbeats that can run per calendar day. Resets at midnight local time. Set to null for unlimited.",
|
|
70
67
|
),
|
|
@@ -79,7 +79,6 @@ export const LLMCallSiteEnum = z.enum([
|
|
|
79
79
|
"meetConsentMonitor",
|
|
80
80
|
"meetChatOpportunity",
|
|
81
81
|
"inference",
|
|
82
|
-
"advisor",
|
|
83
82
|
"vision",
|
|
84
83
|
"trustRuleSuggestion",
|
|
85
84
|
"homeGreeting",
|
|
@@ -442,13 +441,6 @@ export const ProfileEntry = LLMConfigFragment.extend({
|
|
|
442
441
|
* #30362 even though the schema didn't accept it until now.
|
|
443
442
|
*/
|
|
444
443
|
status: ProfileStatusSchema.nullable().optional(),
|
|
445
|
-
/**
|
|
446
|
-
* Whether the advisor is active while this profile is the chat profile.
|
|
447
|
-
* Absent/null means enabled (default on); only an explicit `false` disables
|
|
448
|
-
* it. `.nullable()` matches `status`/`label` so the PUT route's "send null
|
|
449
|
-
* to clear" sentinel resets it back to the default-on state.
|
|
450
|
-
*/
|
|
451
|
-
advisorEnabled: z.boolean().nullable().optional(),
|
|
452
444
|
/**
|
|
453
445
|
* When present, this profile is a "mix": it carries no model config and
|
|
454
446
|
* instead references a weighted list of standard profiles. The resolver
|
|
@@ -492,10 +484,9 @@ export const LLMSchema = z
|
|
|
492
484
|
// schema level, so `LLMSchema.parse({})` yields an empty map.
|
|
493
485
|
callSites: z.partialRecord(LLMCallSiteEnum, LLMCallSiteConfig).default({}),
|
|
494
486
|
activeProfile: z.string().min(1).optional(),
|
|
495
|
-
// The profile the advisor consults
|
|
496
|
-
// excluded from the chat-profile pickers so
|
|
497
|
-
// assistant's chat model.
|
|
498
|
-
// default (`quality-optimized`).
|
|
487
|
+
// The profile the advisor role consults when spawned as a subagent (chosen
|
|
488
|
+
// under Models & Services). It is excluded from the chat-profile pickers so
|
|
489
|
+
// it can't be selected as the assistant's chat model.
|
|
499
490
|
advisorProfile: z.string().min(1).optional(),
|
|
500
491
|
// TTL bounds for inference profile sessions. `defaultTtlSeconds` is read by
|
|
501
492
|
// the CLI to apply when `--ttl` is omitted; the daemon handler itself only
|
|
@@ -78,6 +78,17 @@ export const MemoryJobsConfigSchema = MemoryJobsConfigInputSchema.transform(
|
|
|
78
78
|
},
|
|
79
79
|
).describe("Memory background job processing configuration");
|
|
80
80
|
|
|
81
|
+
export const MemoryWorkerConfigSchema = z
|
|
82
|
+
.object({
|
|
83
|
+
enabled: z
|
|
84
|
+
.boolean({ error: "memory.worker.enabled must be a boolean" })
|
|
85
|
+
.default(false)
|
|
86
|
+
.describe(
|
|
87
|
+
"Whether the memory jobs worker runs as a separate OS process instead of the assistant's synchronous in-process runner. The assistant's worker supervisor re-reads this flag on every poll: while it is set, the in-process runner stands down (the out-of-process worker, spawned at startup when set, owns the queue); while it is unset, the in-process runner drains the queue. `assistant memory worker start`/`stop` flip the flag (and spawn/stop the worker process) to switch modes at runtime without a restart.",
|
|
88
|
+
),
|
|
89
|
+
})
|
|
90
|
+
.describe("Memory jobs worker process configuration");
|
|
91
|
+
|
|
81
92
|
export const MemoryRetentionConfigSchema = z
|
|
82
93
|
.object({
|
|
83
94
|
keepRawForever: z
|
|
@@ -185,6 +196,7 @@ export const MemoryMaintenanceConfigSchema = z
|
|
|
185
196
|
);
|
|
186
197
|
|
|
187
198
|
export type MemoryJobsConfig = z.infer<typeof MemoryJobsConfigSchema>;
|
|
199
|
+
export type MemoryWorkerConfig = z.infer<typeof MemoryWorkerConfigSchema>;
|
|
188
200
|
export type MemoryRetentionConfig = z.infer<typeof MemoryRetentionConfigSchema>;
|
|
189
201
|
export type MemoryCleanupConfig = z.infer<typeof MemoryCleanupConfigSchema>;
|
|
190
202
|
export type MemoryMaintenanceConfig = z.infer<
|
|
@@ -259,6 +259,13 @@ export const MemoryV3ConfigSchema = z
|
|
|
259
259
|
.describe(
|
|
260
260
|
"Per-lane article budget for the reply-query finder pass: needle and dense each re-run over the assistant's previous message as separate queries (never concatenated with the user's message). 0 disables the pass. Deliberately small next to needleK/denseK — the pass adds the assistant-side retrieval signal, not a second full sweep.",
|
|
261
261
|
),
|
|
262
|
+
selectorPromptPath: z
|
|
263
|
+
.string({ error: "memory.v3.selectorPromptPath must be a string" })
|
|
264
|
+
.nullable()
|
|
265
|
+
.default(null)
|
|
266
|
+
.describe(
|
|
267
|
+
"Optional path to a file whose contents replace the bundled per-turn selector system prompt (the instructions that tell the selector which candidate pages to keep). Absolute paths are used as-is, a leading `~/` is expanded to the home directory, otherwise the path is resolved under the workspace root. The selector prompt takes no placeholders — the candidate pool is supplied separately as the user message — so the file is used verbatim. If the file is missing, unreadable, empty, or over 1 MiB, the bundled prompt is used and a warning is logged.",
|
|
268
|
+
),
|
|
262
269
|
edge: MemoryV3EdgeSchema.default(MemoryV3EdgeSchema.parse({})),
|
|
263
270
|
})
|
|
264
271
|
.describe("Memory v3 — section-grain lane retrieval");
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
MemoryJobsConfigSchema,
|
|
6
6
|
MemoryMaintenanceConfigSchema,
|
|
7
7
|
MemoryRetentionConfigSchema,
|
|
8
|
+
MemoryWorkerConfigSchema,
|
|
8
9
|
} from "./memory-lifecycle.js";
|
|
9
10
|
import {
|
|
10
11
|
MemoryExtractionConfigSchema,
|
|
@@ -39,6 +40,9 @@ export const MemoryConfigSchema = z
|
|
|
39
40
|
MemorySegmentationConfigSchema.parse({}),
|
|
40
41
|
),
|
|
41
42
|
jobs: MemoryJobsConfigSchema.default(MemoryJobsConfigSchema.parse({})),
|
|
43
|
+
worker: MemoryWorkerConfigSchema.default(
|
|
44
|
+
MemoryWorkerConfigSchema.parse({}),
|
|
45
|
+
),
|
|
42
46
|
retention: MemoryRetentionConfigSchema.default(
|
|
43
47
|
MemoryRetentionConfigSchema.parse({}),
|
|
44
48
|
),
|
|
@@ -28,6 +28,14 @@ export const TimeoutConfigSchema = z
|
|
|
28
28
|
.describe(
|
|
29
29
|
"How long to wait for user permission approval before timing out (seconds)",
|
|
30
30
|
),
|
|
31
|
+
questionResponseTimeoutSec: z
|
|
32
|
+
.number({ error: "timeouts.questionResponseTimeoutSec must be a number" })
|
|
33
|
+
.finite("timeouts.questionResponseTimeoutSec must be finite")
|
|
34
|
+
.positive("timeouts.questionResponseTimeoutSec must be a positive number")
|
|
35
|
+
.default(1800)
|
|
36
|
+
.describe(
|
|
37
|
+
"Backstop timeout for an unanswered ask_question prompt (seconds). The primary way an interactive user dismisses a prompt is by moving on — enqueuing another message supersedes it — so this only bounds a prompt left open with no response and no follow-up message.",
|
|
38
|
+
),
|
|
31
39
|
toolExecutionTimeoutSec: z
|
|
32
40
|
.number({ error: "timeouts.toolExecutionTimeoutSec must be a number" })
|
|
33
41
|
.finite("timeouts.toolExecutionTimeoutSec must be finite")
|
|
@@ -52,7 +52,7 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
52
52
|
label: "Balanced",
|
|
53
53
|
description: "Good balance of quality, cost, and speed",
|
|
54
54
|
maxTokens: 32000,
|
|
55
|
-
effort: "
|
|
55
|
+
effort: "medium",
|
|
56
56
|
thinking: { enabled: true, streamThinking: true },
|
|
57
57
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
58
58
|
topP: 0.95,
|
|
@@ -84,19 +84,25 @@ const MANAGED_PROFILE_TEMPLATES: Record<string, ManagedProfileTemplate> = {
|
|
|
84
84
|
effort: "high",
|
|
85
85
|
thinking: { enabled: true, streamThinking: true },
|
|
86
86
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
87
|
-
// This is the advisor's own (strongest) profile: when it's also the chat
|
|
88
|
-
// profile there's nothing stronger to consult, so the advisor defaults off.
|
|
89
|
-
advisorEnabled: false,
|
|
90
87
|
},
|
|
88
|
+
// Served by DeepSeek V4 Flash on Fireworks via managed platform inference: a
|
|
89
|
+
// fast, low-cost open model. `model` is pinned explicitly rather than
|
|
90
|
+
// resolved via the `latency-optimized` intent (which still maps to Kimi K2.5
|
|
91
|
+
// on Fireworks and Anthropic Haiku elsewhere).
|
|
92
|
+
//
|
|
93
|
+
// `effort: "none"` (not "low") because Fireworks is not thinking-aware: the
|
|
94
|
+
// disabled `thinking` config is stripped before the request, so a non-"none"
|
|
95
|
+
// effort would be sent as `reasoning_effort` and make this profile pay for
|
|
96
|
+
// reasoning despite thinking being off. "none" keeps Speed non-reasoning.
|
|
91
97
|
"cost-optimized": {
|
|
92
|
-
|
|
93
|
-
provider: "
|
|
94
|
-
connectionName: "
|
|
98
|
+
model: "accounts/fireworks/models/deepseek-v4-flash",
|
|
99
|
+
provider: "fireworks",
|
|
100
|
+
connectionName: "fireworks-managed",
|
|
95
101
|
source: "managed",
|
|
96
102
|
label: "Speed",
|
|
97
|
-
description: "Fastest responses at lower cost",
|
|
103
|
+
description: "Fastest responses at lower cost (DeepSeek V4 Flash)",
|
|
98
104
|
maxTokens: 8192,
|
|
99
|
-
effort: "
|
|
105
|
+
effort: "none",
|
|
100
106
|
thinking: { enabled: false, streamThinking: false },
|
|
101
107
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
102
108
|
},
|
|
@@ -155,19 +161,20 @@ export const OS_BETA_FEATURE_FLAG_KEY = "os-beta";
|
|
|
155
161
|
* Flag-gated managed profile. NOT in MANAGED_PROFILE_TEMPLATES, so the
|
|
156
162
|
* unconditional boot seed never creates it. Reconciled in/out by
|
|
157
163
|
* the flag-gated profile reconcile based on the `os-beta` feature flag.
|
|
158
|
-
* Balanced
|
|
164
|
+
* Balanced defaults, with lower reasoning effort while the profile is in beta.
|
|
159
165
|
*/
|
|
160
166
|
export const OS_BETA_PROFILE_TEMPLATE: ManagedProfileTemplate = {
|
|
161
|
-
|
|
162
|
-
provider: "
|
|
163
|
-
connectionName: "
|
|
167
|
+
intent: "balanced",
|
|
168
|
+
provider: "together",
|
|
169
|
+
connectionName: "together-managed",
|
|
164
170
|
source: "managed",
|
|
165
171
|
label: "OS Beta",
|
|
166
|
-
description: "
|
|
172
|
+
description: "Good balance of quality, cost, and speed, in beta",
|
|
167
173
|
maxTokens: 32000,
|
|
168
|
-
effort: "
|
|
174
|
+
effort: "low",
|
|
169
175
|
thinking: { enabled: true, streamThinking: true },
|
|
170
176
|
contextWindow: { maxInputTokens: DEFAULT_CONTEXT_WINDOW_MAX_INPUT_TOKENS },
|
|
177
|
+
topP: 0.95,
|
|
171
178
|
};
|
|
172
179
|
|
|
173
180
|
// Membership here marks a name as managed. The route layer applies managed
|
|
@@ -214,11 +221,9 @@ export type SeedInferenceProfilesOptions = {
|
|
|
214
221
|
* `cost-optimized`): reconciled from the code templates on every boot —
|
|
215
222
|
* on-platform and off-platform alike — so Vellum can push model/config
|
|
216
223
|
* updates to customers in a release without a workspace migration. The
|
|
217
|
-
* templates own all profile content; `label`, `status`, `
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* allowlist; `advisorEnabled` is edited via the generic config path but is
|
|
221
|
-
* still preserved here so it survives reboots.
|
|
224
|
+
* templates own all profile content; `label`, `status`, and `topP` are user
|
|
225
|
+
* overrides that survive reseeds and are editable through the managed PUT
|
|
226
|
+
* route allowlist.
|
|
222
227
|
* Platform overlays (`preserveProfileNames`) take precedence for the boot
|
|
223
228
|
* they are supplied.
|
|
224
229
|
*
|
|
@@ -273,14 +278,11 @@ export function seedInferenceProfiles(
|
|
|
273
278
|
// as usual.
|
|
274
279
|
//
|
|
275
280
|
// A whitelist of user-editable fields survives the reconcile: `label`
|
|
276
|
-
// (display rename), `status` (active/disabled toggle), `
|
|
277
|
-
// (
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
// `MANAGED_PROFILE_EDITABLE_KEYS`, deliberately excludes `advisorEnabled`,
|
|
282
|
-
// which is set through the generic config path). We honor every one of
|
|
283
|
-
// these overrides across reseeds or they'd silently revert on every boot.
|
|
281
|
+
// (display rename), `status` (active/disabled toggle), and `topP`
|
|
282
|
+
// (sampling override) — the only fields a user may override. The managed
|
|
283
|
+
// PUT route `/v1/config/llm/profiles/:name` lets users patch these on
|
|
284
|
+
// managed profiles without duplicating. We honor every one of these
|
|
285
|
+
// overrides across reseeds or they'd silently revert on every boot.
|
|
284
286
|
// Carry by key-presence rather than truthiness so an explicit `null` (user
|
|
285
287
|
// cleared the field) survives too.
|
|
286
288
|
//
|
|
@@ -352,12 +354,6 @@ export function seedInferenceProfiles(
|
|
|
352
354
|
: previous.label;
|
|
353
355
|
}
|
|
354
356
|
if ("status" in previous) next.status = previous.status;
|
|
355
|
-
// The per-profile advisor toggle is a user override — preserve it across
|
|
356
|
-
// reseeds so a user's choice survives reboots (the template value only
|
|
357
|
-
// seeds the initial default, e.g. off for quality-optimized).
|
|
358
|
-
if ("advisorEnabled" in previous) {
|
|
359
|
-
next.advisorEnabled = previous.advisorEnabled;
|
|
360
|
-
}
|
|
361
357
|
// `topP` is user-editable on managed profiles (see the managed-profile
|
|
362
358
|
// editable allowlist on the PUT route) — preserve a user override across
|
|
363
359
|
// reseeds, including an explicit `null` clear, or it would silently revert
|
package/src/config/skills.ts
CHANGED
|
@@ -688,6 +688,9 @@ function discoverSkillDirectories(skillsDir: string): string[] {
|
|
|
688
688
|
* parseable `package.json` whose `name` equals the directory name. This
|
|
689
689
|
* mirrors the external plugin loader's recognition gate, which skips any
|
|
690
690
|
* directory whose `manifest.name` does not match its directory name.
|
|
691
|
+
*
|
|
692
|
+
* The caller is responsible for the missing-`package.json` case (it emits a
|
|
693
|
+
* diagnostic warning); this function only judges a manifest that is present.
|
|
691
694
|
*/
|
|
692
695
|
function isRecognizedPluginDir(pluginDir: string, dirName: string): boolean {
|
|
693
696
|
const manifestPath = join(pluginDir, "package.json");
|
|
@@ -735,12 +738,31 @@ function discoverPluginResidentSkills(): SkillSummary[] {
|
|
|
735
738
|
for (const entry of entries) {
|
|
736
739
|
if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
|
|
737
740
|
const pluginDir = join(pluginsDir, entry.name);
|
|
741
|
+
|
|
742
|
+
// A directory under `plugins/` with no `package.json` is not a plugin the
|
|
743
|
+
// runtime can load, so its skills are never surfaced. This is an easy
|
|
744
|
+
// footgun — a plugin dropped in without its manifest looks installed but
|
|
745
|
+
// silently contributes nothing — so warn loudly with the path rather than
|
|
746
|
+
// skipping in silence, to make the misconfiguration diagnosable.
|
|
747
|
+
if (!existsSync(join(pluginDir, "package.json"))) {
|
|
748
|
+
log.warn(
|
|
749
|
+
{ pluginDir },
|
|
750
|
+
"Plugin directory is missing package.json — skipping; its skills will not be available. Add a package.json whose `name` matches the directory.",
|
|
751
|
+
);
|
|
752
|
+
continue;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Honor the `.disabled` sentinel the runtime plugin scan checks
|
|
756
|
+
// (`plugins/mtime-cache.ts`): a disabled plugin contributes no hooks or
|
|
757
|
+
// tools, so its resident skills must not be loadable either.
|
|
758
|
+
if (existsSync(join(pluginDir, ".disabled"))) continue;
|
|
759
|
+
|
|
738
760
|
// Mirror the plugin loader's recognition gate: a directory is a real
|
|
739
|
-
// installed plugin only if
|
|
740
|
-
//
|
|
741
|
-
//
|
|
742
|
-
//
|
|
743
|
-
//
|
|
761
|
+
// installed plugin only if its `package.json` `name` matches the directory.
|
|
762
|
+
// This rejects staging dirs and malformed/mismatched clones (e.g. an
|
|
763
|
+
// un-adapted `caveman-installer`) that the loader itself would skip, so the
|
|
764
|
+
// catalog never surfaces skills from a directory the runtime would refuse
|
|
765
|
+
// to load.
|
|
744
766
|
if (!isRecognizedPluginDir(pluginDir, entry.name)) continue;
|
|
745
767
|
|
|
746
768
|
const skillsDir = join(pluginDir, "skills");
|
|
@@ -23,12 +23,12 @@ const log = getLogger("sync-gated-profiles");
|
|
|
23
23
|
* Reconcile flag-gated managed profiles against the current feature-flag state.
|
|
24
24
|
*
|
|
25
25
|
* `seedInferenceProfiles()` runs synchronously at boot before feature flags are
|
|
26
|
-
* available, so the OS Beta profile (
|
|
27
|
-
* here once flags have loaded. When the `os-beta` flag is on, the
|
|
28
|
-
* is created (ordered right after `balanced`); when it is off, a
|
|
29
|
-
* managed entry is removed with `profileOrder` / `activeProfile` /
|
|
30
|
-
* fallbacks. The reconcile is idempotent and never touches a
|
|
31
|
-
* the same name.
|
|
26
|
+
* available, so the OS Beta profile (MiniMax M3 / together-managed) is
|
|
27
|
+
* materialized here once flags have loaded. When the `os-beta` flag is on, the
|
|
28
|
+
* managed profile is created (ordered right after `balanced`); when it is off, a
|
|
29
|
+
* previously managed entry is removed with `profileOrder` / `activeProfile` /
|
|
30
|
+
* `advisorProfile` fallbacks. The reconcile is idempotent and never touches a
|
|
31
|
+
* user-owned profile of the same name.
|
|
32
32
|
*
|
|
33
33
|
* Returns whether the on-disk config changed.
|
|
34
34
|
*/
|
|
@@ -105,23 +105,19 @@ function enableProfile(
|
|
|
105
105
|
OS_BETA_PROFILE_TEMPLATE.connectionName,
|
|
106
106
|
) as Record<string, unknown>;
|
|
107
107
|
|
|
108
|
-
// BYOK installs seed managed profiles disabled: the
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
// later reconciles.
|
|
108
|
+
// BYOK installs seed managed profiles disabled: the managed inference
|
|
109
|
+
// connection backing this profile isn't usable until the user enables it, so a
|
|
110
|
+
// fresh OS Beta entry starts disabled to avoid offering an unusable route. A
|
|
111
|
+
// user's own status override (preserved below) wins on later reconciles.
|
|
113
112
|
if (isByokMode && !previous) {
|
|
114
113
|
next.status = "disabled";
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
if (previous) {
|
|
118
|
-
//
|
|
119
|
-
// by key-presence so an explicit null (user cleared it) survives too.
|
|
117
|
+
// Preserve user-owned overrides across reconciles.
|
|
120
118
|
if ("label" in previous) next.label = previous.label;
|
|
121
119
|
if ("status" in previous) next.status = previous.status;
|
|
122
|
-
if ("
|
|
123
|
-
next.advisorEnabled = previous.advisorEnabled;
|
|
124
|
-
}
|
|
120
|
+
if ("topP" in previous) next.topP = previous.topP;
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
let changed = false;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the gateway-first member-revoke relay.
|
|
3
|
+
*
|
|
4
|
+
* revokeMemberChannel downgrades the channel's ACL status through the gateway
|
|
5
|
+
* (source of truth) via `ipcCallPersistent("mark_channel_revoked", ...)` first,
|
|
6
|
+
* then mirrors the downgrade to the assistant DB best-effort. A local mirror
|
|
7
|
+
* failure is swallowed so the gateway-owned outcome stands.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { beforeEach, describe, expect, mock, test } from "bun:test";
|
|
11
|
+
|
|
12
|
+
import type { ContactWriteResult } from "../types.js";
|
|
13
|
+
|
|
14
|
+
type IpcCall = { method: string; params?: Record<string, unknown> };
|
|
15
|
+
|
|
16
|
+
let ipcCalls: IpcCall[] = [];
|
|
17
|
+
let ipcOk = true;
|
|
18
|
+
|
|
19
|
+
const ipcCallPersistentMock = mock(
|
|
20
|
+
async (method: string, params?: Record<string, unknown>) => {
|
|
21
|
+
ipcCalls.push({ method, params });
|
|
22
|
+
return {
|
|
23
|
+
ok: ipcOk,
|
|
24
|
+
didWrite: ipcOk,
|
|
25
|
+
channel: {
|
|
26
|
+
id: (params?.contactChannelId as string) ?? "ch1",
|
|
27
|
+
contactId: "c1",
|
|
28
|
+
type: "telegram",
|
|
29
|
+
address: "addr",
|
|
30
|
+
status: "revoked",
|
|
31
|
+
revokedReason: (params?.reason as string) ?? null,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
const actualGatewayClient = await import("../../ipc/gateway-client.js");
|
|
37
|
+
mock.module("../../ipc/gateway-client.js", () => ({
|
|
38
|
+
...actualGatewayClient,
|
|
39
|
+
ipcCallPersistent: ipcCallPersistentMock,
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// Local resolver primitive — resolves the native contact/channel by id; the
|
|
44
|
+
// gateway owns the ACL downgrade, so it takes no reason and mutates nothing.
|
|
45
|
+
const revokeMemberResult: ContactWriteResult = {
|
|
46
|
+
contact: { id: "c1" } as ContactWriteResult["contact"],
|
|
47
|
+
channel: { id: "ch1" } as ContactWriteResult["channel"],
|
|
48
|
+
};
|
|
49
|
+
const revokeMemberMock = mock((_memberId: string) => revokeMemberResult);
|
|
50
|
+
const actualContactsWrite = await import("../contacts-write.js");
|
|
51
|
+
mock.module("../contacts-write.js", () => ({
|
|
52
|
+
...actualContactsWrite,
|
|
53
|
+
revokeMember: revokeMemberMock,
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
const { revokeMemberChannel } = await import("../member-write-relay.js");
|
|
57
|
+
|
|
58
|
+
describe("revokeMemberChannel gateway-first relay", () => {
|
|
59
|
+
beforeEach(() => {
|
|
60
|
+
ipcCalls = [];
|
|
61
|
+
ipcOk = true;
|
|
62
|
+
ipcCallPersistentMock.mockClear();
|
|
63
|
+
revokeMemberMock.mockClear();
|
|
64
|
+
revokeMemberMock.mockImplementation(() => revokeMemberResult);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("relays the revoke to the gateway before mirroring locally", async () => {
|
|
68
|
+
const result = await revokeMemberChannel("ch1", "removed");
|
|
69
|
+
|
|
70
|
+
expect(ipcCalls).toEqual([
|
|
71
|
+
{
|
|
72
|
+
method: "mark_channel_revoked",
|
|
73
|
+
params: { contactChannelId: "ch1", reason: "removed" },
|
|
74
|
+
},
|
|
75
|
+
]);
|
|
76
|
+
expect(revokeMemberMock).toHaveBeenCalledTimes(1);
|
|
77
|
+
expect(revokeMemberMock).toHaveBeenCalledWith("ch1");
|
|
78
|
+
expect(result).toBe(revokeMemberResult);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("strips the composite contactId:channelId prefix before the relay", async () => {
|
|
82
|
+
await revokeMemberChannel("c1:ch1");
|
|
83
|
+
|
|
84
|
+
expect(ipcCalls[0]?.params?.contactChannelId).toBe("ch1");
|
|
85
|
+
// The local resolver still receives the original composite id it accepts.
|
|
86
|
+
expect(revokeMemberMock).toHaveBeenCalledWith("c1:ch1");
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("always relays — never skips based on local mirror status", async () => {
|
|
90
|
+
// The gateway owns the ACL outcome; the relay must fire even if the local
|
|
91
|
+
// mirror lags (says revoked) while the gateway row is still active.
|
|
92
|
+
await revokeMemberChannel("ch1");
|
|
93
|
+
|
|
94
|
+
expect(ipcCalls).toEqual([
|
|
95
|
+
{
|
|
96
|
+
method: "mark_channel_revoked",
|
|
97
|
+
params: { contactChannelId: "ch1", reason: undefined },
|
|
98
|
+
},
|
|
99
|
+
]);
|
|
100
|
+
expect(revokeMemberMock).toHaveBeenCalledTimes(1);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("swallows a local-mirror failure without throwing; the gateway revoke stands", async () => {
|
|
104
|
+
revokeMemberMock.mockImplementation(() => {
|
|
105
|
+
throw new Error("local mirror exploded");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const result = await revokeMemberChannel("ch1", "removed");
|
|
109
|
+
|
|
110
|
+
expect(ipcCalls).toHaveLength(1);
|
|
111
|
+
expect(result).toBeNull();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test("throws when the gateway relay returns ok: false", async () => {
|
|
115
|
+
ipcOk = false;
|
|
116
|
+
|
|
117
|
+
let thrown: Error | undefined;
|
|
118
|
+
try {
|
|
119
|
+
await revokeMemberChannel("ch1");
|
|
120
|
+
} catch (err) {
|
|
121
|
+
thrown = err as Error;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
expect(thrown).toBeDefined();
|
|
125
|
+
// Local mirror must not run when the gateway refuses the downgrade.
|
|
126
|
+
expect(revokeMemberMock).not.toHaveBeenCalled();
|
|
127
|
+
});
|
|
128
|
+
});
|