@vellumai/assistant 0.9.0 → 0.10.0-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 +18 -34
- package/bun.lock +7 -8
- package/docs/activation-funnel-telemetry.md +28 -22
- package/docs/architecture/security.md +29 -28
- package/docs/stt-provider-onboarding.md +3 -5
- package/docs/workflows-testing.md +13 -44
- package/docs/workflows.md +3 -5
- package/node_modules/@vellumai/ces-client/src/__tests__/ces-client.test.ts +47 -0
- package/node_modules/@vellumai/ces-client/src/rpc-client.ts +28 -5
- package/node_modules/@vellumai/environments/src/seeds.ts +2 -5
- package/node_modules/@vellumai/gateway-client/src/admission-policy-contract.ts +97 -0
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +32 -6
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +119 -0
- package/node_modules/@vellumai/gateway-client/src/types.ts +15 -84
- package/openapi.yaml +976 -63
- package/package.json +2 -1
- package/scripts/sync-llm-catalog.ts +6 -15
- package/scripts/sync-web-search-catalog.ts +3 -11
- package/src/__tests__/access-request-card-view.test.ts +98 -0
- package/src/__tests__/access-request-seed-content-blocks.test.ts +2 -4
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +72 -32
- package/src/__tests__/agent-loop-compaction-strip.test.ts +241 -0
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +16 -13
- package/src/__tests__/agent-loop-output-hooks.test.ts +69 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -0
- package/src/__tests__/always-loaded-tools-guard.test.ts +2 -3
- package/src/__tests__/app-compiler.test.ts +15 -1
- package/src/__tests__/app-dir-path-guard.test.ts +0 -1
- package/src/__tests__/assistant-feature-flag-guard.test.ts +1 -4
- package/src/__tests__/assistant-feature-flag-guardrails.test.ts +0 -2
- package/src/__tests__/auth-fallback-events-store.test.ts +6 -14
- package/src/__tests__/avatar-identity-sync.test.ts +2 -27
- package/src/__tests__/btw-routes.test.ts +6 -8
- package/src/__tests__/call-pointer-messages.test.ts +28 -0
- package/src/__tests__/cancel-clears-processing.test.ts +89 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -4
- package/src/__tests__/channel-inbound-disk-pressure.test.ts +5 -15
- package/src/__tests__/checker.test.ts +0 -3
- package/src/__tests__/cli-memory-v2-reembed-skills.test.ts +3 -4
- package/src/__tests__/compactor-image-manifest-trust.test.ts +21 -1
- package/src/__tests__/compactor-summary-call-truncation.test.ts +223 -0
- package/src/__tests__/config-loader-backfill.test.ts +268 -27
- package/src/__tests__/config-schema.test.ts +35 -0
- package/src/__tests__/config-watcher.test.ts +0 -18
- package/src/__tests__/confirmation-request-guardian-bridge.test.ts +2 -2
- package/src/__tests__/contact-store-user-file.test.ts +0 -6
- package/src/__tests__/contacts-tools.test.ts +29 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +22 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +58 -0
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -1
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/credential-broker.test.ts +449 -1
- package/src/__tests__/credential-execution-shell-lockdown.test.ts +18 -11
- package/src/__tests__/credential-execution-tools.test.ts +0 -1
- package/src/__tests__/credential-prompt-route.test.ts +4 -4
- package/src/__tests__/credential-routes.test.ts +360 -0
- package/src/__tests__/credential-security-invariants.test.ts +4 -13
- package/src/__tests__/disk-pressure-policy.test.ts +12 -0
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/dynamic-page-surface.test.ts +152 -1
- package/src/__tests__/fixtures/credential-security-fixtures.ts +2 -33
- package/src/__tests__/gateway-flag-listener.test.ts +110 -1
- package/src/__tests__/gateway-only-guard.test.ts +3 -7
- package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
- package/src/__tests__/guardian-card-withdrawal.test.ts +403 -0
- package/src/__tests__/guardian-decision-primitive-canonical.test.ts +5 -3
- package/src/__tests__/guardian-grant-minting.test.ts +3 -35
- package/src/__tests__/guardian-routing-invariants.test.ts +64 -26
- package/src/__tests__/guardian-routing-state.test.ts +0 -1
- package/src/__tests__/headless-browser-mode.test.ts +10 -0
- package/src/__tests__/headless-browser-navigate.test.ts +8 -3
- package/src/__tests__/helpers/create-guardian-binding.ts +0 -1
- package/src/__tests__/host-browser-proxy.test.ts +87 -0
- package/src/__tests__/identity-routes.test.ts +0 -189
- package/src/__tests__/inbound-invite-redemption.test.ts +4 -4
- package/src/__tests__/injector-v3-suppression.test.ts +27 -20
- package/src/__tests__/internal-telemetry-routes.test.ts +6 -14
- package/src/__tests__/invite-redemption-service.test.ts +4 -7
- package/src/__tests__/llm-callsite-catalog.test.ts +5 -6
- package/src/__tests__/llm-catalog-parity.test.ts +30 -23
- package/src/__tests__/llm-resolver.test.ts +70 -24
- package/src/__tests__/llm-schema.test.ts +1 -0
- package/src/__tests__/managed-profile-guard.test.ts +163 -4
- package/src/__tests__/mcp-health-check.test.ts +6 -7
- package/src/__tests__/media-stream-server-integration.test.ts +317 -13
- package/src/__tests__/oauth-provider-seed-logos.test.ts +4 -6
- package/src/__tests__/onboarding-persona-write.test.ts +1 -1
- package/src/__tests__/path-policy.test.ts +34 -0
- package/src/__tests__/persona-resolver.test.ts +49 -14
- package/src/__tests__/plugin-api-model-profiles.test.ts +178 -0
- package/src/__tests__/plugin-api-provider.test.ts +24 -0
- package/src/__tests__/plugin-tool-contribution.test.ts +6 -3
- package/src/__tests__/post-compaction-reinjection-idempotency.test.ts +214 -0
- package/src/__tests__/provider-send-message-override-profile.test.ts +76 -0
- package/src/__tests__/reaction-persistence.test.ts +150 -29
- package/src/__tests__/registry.test.ts +2 -7
- package/src/__tests__/relay-server.test.ts +285 -0
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -1
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +1 -10
- package/src/__tests__/schedule-routes.test.ts +0 -30
- package/src/__tests__/schedule-tools.test.ts +2 -18
- package/src/__tests__/scheduler-reuse-conversation.test.ts +8 -5
- package/src/__tests__/skill-execute-input.test.ts +51 -1
- package/src/__tests__/skill-runtime-path.test.ts +2 -3
- package/src/__tests__/skills.test.ts +51 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +176 -0
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +285 -0
- package/src/__tests__/subagent-tools.test.ts +266 -0
- package/src/__tests__/surface-completion-nudge-hook.test.ts +367 -0
- package/src/__tests__/task-progress-nudge-hook.test.ts +1 -1
- package/src/__tests__/title-generate-hook.test.ts +100 -3
- package/src/__tests__/token-estimator-accuracy.benchmark.test.ts +1 -29
- package/src/__tests__/token-manager.test.ts +519 -0
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +1 -1
- package/src/__tests__/tool-audit-listener.test.ts +7 -7
- package/src/__tests__/tool-executor-lifecycle-events.test.ts +6 -3
- package/src/__tests__/tool-executor.test.ts +0 -79
- package/src/__tests__/trusted-contact-approval-notifier.test.ts +4 -2
- package/src/__tests__/trusted-contact-inline-approval-integration.test.ts +220 -3
- package/src/__tests__/trusted-contact-multichannel.test.ts +3 -3
- package/src/__tests__/trusted-contact-verification.test.ts +8 -10
- package/src/__tests__/twilio-routes.test.ts +81 -1
- package/src/__tests__/voice-invite-redemption.test.ts +2 -3
- package/src/__tests__/weak-open-model.test.ts +30 -0
- package/src/__tests__/web-search-catalog-parity.test.ts +6 -25
- package/src/__tests__/workspace-greetings.test.ts +152 -0
- package/src/__tests__/workspace-migration-105-enable-memory-v3-live-for-new-workspaces.test.ts +149 -0
- package/src/__tests__/workspace-migration-108-drop-balanced-economy-profile.test.ts +285 -0
- package/src/__tests__/workspace-migration-add-send-diagnostics.test.ts +1 -1
- package/src/__tests__/workspace-migration-drop-collect-usage-data.test.ts +118 -0
- package/src/__tests__/workspace-migration-drop-send-diagnostics.test.ts +118 -0
- package/src/a2a/__tests__/e2e-a2a-channel.test.ts +0 -4
- package/src/agent/loop.ts +49 -29
- package/src/api/README.md +6 -6
- package/src/api/events/tool-result.ts +6 -0
- package/src/api/events/workflow-completed.ts +53 -0
- package/src/api/events/workflow-leaf-finished.ts +38 -0
- package/src/api/events/workflow-leaf-started.ts +35 -0
- package/src/api/events/workflow-progress.ts +32 -0
- package/src/api/events/workflow-started.ts +31 -0
- package/src/api/index.ts +40 -0
- package/src/api/responses/conversation-message.ts +28 -4
- package/src/api/responses/home.ts +26 -4
- package/src/api/responses/workflow-journal.ts +53 -0
- package/src/approvals/guardian-card-withdrawal.ts +145 -0
- package/src/approvals/guardian-decision-primitive.ts +26 -3
- package/src/approvals/guardian-request-resolvers.ts +183 -80
- package/src/calls/__tests__/channel-admission-reader.test.ts +132 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +350 -0
- package/src/calls/call-pointer-messages.ts +10 -4
- package/src/calls/channel-admission-reader.ts +104 -0
- package/src/calls/guardian-dispatch.ts +17 -45
- package/src/calls/media-stream-server.ts +84 -2
- package/src/calls/relay-access-wait.ts +1 -1
- package/src/calls/relay-server.ts +66 -0
- package/src/calls/relay-setup-router.ts +82 -1
- package/src/calls/twilio-routes.ts +17 -8
- package/src/calls/voice-session-bridge.ts +2 -2
- package/src/cli/commands/clients.ts +3 -0
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2-compare-render.test.ts +1 -1
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v2.test.ts +8 -7
- package/src/cli/commands/{__tests__ → memory/__tests__}/memory-v3.test.ts +5 -4
- package/src/cli/commands/memory/index.ts +30 -0
- package/src/cli/commands/{memory-v2-compare-render.ts → memory/memory-v2-compare-render.ts} +1 -1
- package/src/cli/commands/{memory-v2.ts → memory/memory-v2.ts} +6 -15
- package/src/cli/commands/{memory-v3.ts → memory/memory-v3.ts} +97 -11
- package/src/cli/commands/oauth/status.test.ts +36 -0
- package/src/cli/commands/oauth/status.ts +23 -3
- package/src/cli/commands/plugins.ts +197 -4
- package/src/cli/lib/__tests__/diff-plugin.test.ts +443 -0
- package/src/cli/lib/__tests__/inspect-plugin.test.ts +54 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-surfaces.test.ts +111 -0
- package/src/cli/lib/__tests__/upgrade-plugin.test.ts +295 -2
- package/src/cli/lib/diff-plugin.ts +346 -0
- package/src/cli/lib/inspect-plugin.ts +12 -1
- package/src/cli/lib/install-from-github.ts +105 -17
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-surfaces.ts +104 -0
- package/src/cli/lib/upgrade-plugin.ts +298 -10
- package/src/cli/program.ts +2 -6
- package/src/config/__tests__/sync-gated-profiles.test.ts +368 -0
- package/src/config/assistant-feature-flags.ts +22 -7
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +0 -1
- package/src/config/bundled-skills/messaging/SKILL.md +6 -4
- package/src/config/bundled-skills/messaging/tools/messaging-archive-by-sender.ts +9 -8
- package/src/config/bundled-skills/subagent/SKILL.md +4 -0
- package/src/config/bundled-skills/subagent/TOOLS.json +4 -0
- package/src/config/bundled-skills/workflows/SKILL.md +14 -8
- package/src/config/bundled-tool-registry.ts +2 -7
- package/src/config/call-site-defaults.ts +15 -2
- package/src/config/feature-flag-registry.json +46 -31
- package/src/config/inference-profile-validation.ts +26 -0
- package/src/config/llm-resolver.ts +3 -0
- package/src/config/loader.ts +4 -0
- package/src/config/memory-v3-gate.ts +11 -0
- package/src/config/profile-order.ts +28 -0
- package/src/config/schema.ts +8 -6
- package/src/config/schemas/__tests__/memory-v3.test.ts +1 -0
- package/src/config/schemas/call-site-catalog.ts +7 -0
- package/src/config/schemas/channels.ts +11 -0
- package/src/config/schemas/elevenlabs.ts +0 -1
- package/src/config/schemas/llm.ts +31 -0
- package/src/config/schemas/memory-lifecycle.ts +3 -7
- package/src/config/schemas/memory-v3.ts +6 -0
- package/src/config/schemas/platform.ts +0 -8
- package/src/config/schemas/services.ts +18 -0
- package/src/config/seed-inference-profiles.ts +109 -44
- package/src/config/skills.ts +21 -0
- package/src/config/sync-gated-profiles.ts +220 -0
- package/src/contacts/contact-store.ts +89 -106
- package/src/contacts/contacts-write.ts +5 -22
- package/src/contacts/types.ts +0 -1
- package/src/context/compactor.ts +88 -54
- package/src/context/strip-injections.ts +58 -10
- package/src/context/token-estimator.ts +1 -1
- package/src/credential-execution/process-manager.ts +55 -14
- package/src/credential-execution/prompted-credential.ts +2 -3
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +3 -2
- package/src/daemon/config-watcher.ts +0 -4
- package/src/daemon/conversation-agent-loop-handlers.ts +2 -0
- package/src/daemon/conversation-agent-loop.ts +114 -22
- package/src/daemon/conversation-history.ts +1 -1
- package/src/daemon/conversation-lifecycle.ts +3 -5
- package/src/daemon/conversation-process.ts +13 -5
- package/src/daemon/conversation-runtime-assembly.ts +13 -15
- package/src/daemon/conversation-slash.ts +2 -23
- package/src/daemon/conversation-surfaces.ts +26 -0
- package/src/daemon/conversation-tool-setup.ts +27 -14
- package/src/daemon/conversation.ts +66 -14
- package/src/daemon/disk-pressure-policy.ts +5 -3
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +0 -1
- package/src/daemon/handlers/__tests__/config-a2a-redeem.test.ts +0 -1
- package/src/daemon/handlers/config-a2a.ts +0 -2
- package/src/daemon/handlers/config-channels.ts +15 -16
- package/src/daemon/handlers/config-slack-channel.ts +22 -3
- package/src/daemon/handlers/conversations.ts +107 -0
- package/src/daemon/host-browser-proxy.ts +41 -0
- package/src/daemon/lifecycle.ts +55 -27
- package/src/daemon/message-provenance.ts +2 -0
- package/src/daemon/message-types/contacts.ts +0 -1
- package/src/daemon/message-types/conversations.ts +3 -3
- package/src/daemon/message-types/sync.ts +0 -1
- package/src/daemon/message-types/web-activity.ts +7 -1
- package/src/daemon/message-types/workflows.ts +83 -1
- package/src/daemon/orphan-reaper.test.ts +0 -19
- package/src/daemon/orphan-reaper.ts +2 -24
- package/src/daemon/server.ts +0 -10
- package/src/daemon/tool-setup-types.ts +4 -0
- package/src/daemon/trust-context.ts +1 -1
- package/src/events/tool-audit-listener.ts +2 -2
- package/src/home/feed-source-enrichment.test.ts +151 -0
- package/src/home/feed-source-enrichment.ts +176 -0
- package/src/home/relationship-state.ts +2 -4
- package/src/instrument.ts +18 -6
- package/src/ipc/__tests__/binary-result-ipc.test.ts +81 -0
- package/src/ipc/__tests__/clients-list-ipc.test.ts +20 -0
- package/src/ipc/assistant-server.ts +37 -4
- package/src/ipc/gateway-flag-listener.ts +18 -2
- package/src/memory/__tests__/auto-analysis-enqueue.test.ts +5 -16
- package/src/memory/__tests__/jobs-store-enqueue-gate.test.ts +7 -11
- package/src/memory/__tests__/memory-retrospective-enqueue.test.ts +37 -7
- package/src/memory/__tests__/memory-retrospective-job.test.ts +229 -401
- package/src/memory/__tests__/onboarding-events-store.test.ts +7 -7
- package/src/memory/auth-fallback-events-store.ts +2 -2
- package/src/memory/auto-analysis-enqueue.ts +3 -5
- package/src/memory/bookmark-crud.ts +1 -2
- package/src/memory/canonical-guardian-store.ts +39 -1
- package/src/memory/conversation-crud.ts +9 -4
- package/src/memory/conversation-key-store.ts +17 -2
- package/src/memory/conversation-title-service.ts +64 -7
- package/src/memory/db-init.ts +17 -17
- package/src/memory/embedding-backend.ts +38 -1
- package/src/memory/embedding-billing-breaker.ts +96 -0
- package/src/memory/jobs-store.ts +25 -13
- package/src/memory/jobs-worker.ts +54 -1
- package/src/memory/lifecycle-events-store.ts +2 -2
- package/src/memory/memory-retrospective-constants.ts +4 -4
- package/src/memory/memory-retrospective-enqueue.ts +31 -6
- package/src/memory/memory-retrospective-job.ts +28 -227
- package/src/memory/migrations/129-contact-channels-access-fields.ts +18 -9
- package/src/memory/migrations/131-drop-legacy-member-guardian-tables.ts +14 -2
- package/src/memory/migrations/289-contact-channels-unique-ext-user.ts +10 -0
- package/src/memory/migrations/291-contact-channels-renormalize-addresses.ts +72 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.test.ts +67 -0
- package/src/memory/migrations/292-schedule-default-no-reuse-conversation.ts +25 -0
- package/src/memory/migrations/293-workflow-journal-leaf-tokens.ts +32 -0
- package/src/memory/migrations/294-drop-external-user-id.ts +31 -0
- package/src/memory/migrations/295-drop-approval-prompt-ts-tracker.ts +20 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.test.ts +110 -0
- package/src/memory/migrations/296-rewrite-balanced-economy-profile-pins.ts +68 -0
- package/src/memory/migrations/__tests__/131-drop-legacy-member-guardian-tables.test.ts +154 -0
- package/src/memory/migrations/__tests__/289-contact-channels-unique-ext-user.test.ts +31 -0
- package/src/memory/migrations/__tests__/291-contact-channels-renormalize-addresses.test.ts +341 -0
- package/src/memory/migrations/__tests__/run-migrations.test.ts +52 -0
- package/src/memory/migrations/index.ts +6 -0
- package/src/memory/migrations/run-migrations.ts +41 -0
- package/src/memory/migrations/validate-migration-state.ts +1 -1
- package/src/memory/onboarding-events-store.ts +3 -3
- package/src/memory/schema/contacts.ts +0 -5
- package/src/memory/skill-loaded-events-store.test.ts +7 -15
- package/src/memory/skill-loaded-events-store.ts +2 -2
- package/src/memory/tool-executed-events-store.test.ts +7 -7
- package/src/memory/turn-trace-store.test.ts +736 -0
- package/src/memory/turn-trace-store.ts +364 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +8 -0
- package/src/memory/v2/__tests__/skill-content.test.ts +30 -0
- package/src/memory/v2/consolidation-job.ts +2 -2
- package/src/memory/v2/skill-content.ts +25 -7
- package/src/memory/v2/skill-store.ts +7 -1
- package/src/memory/v3-eval/__tests__/eval-packets.test.ts +248 -0
- package/src/memory/v3-eval/eval-packets.ts +546 -0
- package/src/messaging/providers/slack/adapter.ts +1 -1
- package/src/messaging/providers/slack/api.ts +31 -0
- package/src/messaging/providers/slack/send.test.ts +114 -2
- package/src/messaging/providers/slack/send.ts +30 -7
- package/src/messaging/providers/slack/withdraw.test.ts +200 -0
- package/src/messaging/providers/slack/withdraw.ts +161 -0
- package/src/notifications/AGENTS.md +2 -0
- package/src/notifications/access-request-copy.ts +72 -59
- package/src/notifications/adapters/shared.ts +29 -0
- package/src/notifications/adapters/slack.ts +58 -103
- package/src/notifications/adapters/telegram.ts +2 -20
- package/src/notifications/approval-card-data.ts +333 -0
- package/src/notifications/broadcaster.ts +16 -3
- package/src/notifications/canonical-delivery-recorder.ts +139 -0
- package/src/notifications/copy-composer.ts +3 -3
- package/src/notifications/decision-engine.ts +4 -2
- package/src/notifications/destination-resolver.ts +4 -6
- package/src/notifications/guardian-question-mode.ts +10 -0
- package/src/notifications/home-feed-side-effect.ts +7 -16
- package/src/notifications/notification-utils.ts +19 -20
- package/src/notifications/signal.ts +79 -43
- package/src/notifications/types.ts +98 -121
- package/src/oauth/AGENTS.md +5 -24
- package/src/permissions/checker.test.ts +51 -0
- package/src/permissions/checker.ts +185 -26
- package/src/permissions/ipc-risk-types.ts +24 -0
- package/src/permissions/question-prompter.test.ts +27 -0
- package/src/permissions/question-prompter.ts +4 -0
- package/src/platform/client.test.ts +119 -0
- package/src/platform/client.ts +66 -0
- package/src/platform/consent-cache.test.ts +267 -0
- package/src/platform/consent-cache.ts +174 -0
- package/src/plugin-api/constants.ts +1 -1
- package/src/plugin-api/index.ts +33 -1
- package/src/plugin-api/model-profiles.ts +33 -0
- package/src/plugin-api/types.ts +50 -2
- package/src/plugins/defaults/advisor/__tests__/advisor-gate.test.ts +56 -0
- package/src/plugins/defaults/advisor/__tests__/advisor-state-store.test.ts +43 -0
- package/src/plugins/defaults/advisor/__tests__/agent-loop-integration.test.ts +137 -0
- package/src/plugins/defaults/advisor/__tests__/consult.test.ts +153 -0
- package/src/plugins/defaults/advisor/__tests__/hooks.test.ts +138 -0
- package/src/plugins/defaults/advisor/__tests__/transcript.test.ts +147 -0
- package/src/plugins/defaults/advisor/advisor-gate.ts +29 -0
- package/src/plugins/defaults/advisor/advisor-state-store.ts +94 -0
- package/src/plugins/defaults/advisor/config.ts +21 -0
- package/src/plugins/defaults/advisor/consult.ts +93 -0
- package/src/plugins/defaults/advisor/hooks/post-model-call.ts +34 -0
- package/src/plugins/defaults/advisor/hooks/pre-model-call.ts +30 -0
- package/src/plugins/defaults/advisor/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/advisor/package.json +14 -0
- package/src/plugins/defaults/advisor/steering.ts +67 -0
- package/src/plugins/defaults/advisor/tools/advisor.ts +65 -0
- package/src/plugins/defaults/advisor/transcript.ts +76 -0
- package/src/plugins/defaults/index.ts +60 -0
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +22 -9
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit.ts +2 -2
- package/src/plugins/defaults/memory-retrieval/tail-reinjection-strip.ts +64 -0
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +29 -21
- package/src/plugins/defaults/memory-v3-shadow/__tests__/carry-integration.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/injection.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/__tests__/maintain-job.test.ts +129 -9
- package/src/plugins/defaults/memory-v3-shadow/__tests__/orchestrate.test.ts +31 -4
- package/src/plugins/defaults/memory-v3-shadow/__tests__/selection-log-store.test.ts +77 -2
- package/src/plugins/defaults/memory-v3-shadow/__tests__/shadow-plugin.test.ts +1 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +7 -10
- package/src/plugins/defaults/memory-v3-shadow/maintain-job.ts +144 -11
- package/src/plugins/defaults/memory-v3-shadow/orchestrate.ts +32 -20
- package/src/plugins/defaults/memory-v3-shadow/selection-log-store.ts +56 -3
- package/src/plugins/defaults/memory-v3-shadow/shadow-plugin.ts +23 -2
- package/src/plugins/defaults/surface-completion-nudge/hooks/post-model-call.ts +276 -0
- package/src/plugins/defaults/surface-completion-nudge/hooks/stop.ts +22 -0
- package/src/plugins/defaults/surface-completion-nudge/nudge-state-store.ts +46 -0
- package/src/plugins/defaults/surface-completion-nudge/package.json +14 -0
- package/src/plugins/defaults/task-progress-nudge/hooks/post-tool-use.ts +3 -13
- package/src/plugins/defaults/title-generate/hooks/stop.ts +56 -21
- package/src/prompts/persona-resolver.ts +14 -4
- package/src/prompts/templates/system-sections.ts +7 -2
- package/src/providers/__tests__/provider-env-vars.test.ts +6 -0
- package/src/providers/__tests__/provider-secret-catalog.test.ts +1 -0
- package/src/providers/__tests__/retry-callsite.test.ts +176 -0
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/inference/adapter-factory.ts +3 -0
- package/src/providers/model-catalog.ts +58 -0
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +33 -0
- package/src/providers/openai/chat-completions-provider.ts +7 -0
- package/src/providers/openai/responses-provider.ts +10 -0
- package/src/providers/provider-send-message.ts +11 -3
- package/src/providers/retry.ts +53 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/weak-open-model.ts +22 -0
- package/src/runtime/AGENTS.md +0 -1
- package/src/runtime/__tests__/agent-wake.test.ts +181 -0
- package/src/runtime/__tests__/client-health.test.ts +44 -0
- package/src/runtime/access-request-helper.ts +21 -53
- package/src/runtime/actor-trust-resolver.ts +59 -63
- package/src/runtime/agent-wake.ts +52 -0
- package/src/runtime/assistant-event-hub.ts +18 -4
- package/src/runtime/auth/__tests__/route-policy.test.ts +12 -0
- package/src/runtime/auth/require-bound-guardian.ts +1 -4
- package/src/runtime/btw-sidechain.ts +3 -6
- package/src/runtime/capabilities.test.ts +120 -0
- package/src/runtime/capabilities.ts +197 -0
- package/src/runtime/channel-approval-types.ts +22 -45
- package/src/runtime/channel-invite-transports/telegram.ts +4 -4
- package/src/runtime/channel-retry-sweep.ts +1 -0
- package/src/runtime/channel-verification-service.ts +3 -3
- package/src/runtime/client-health.ts +26 -0
- package/src/runtime/confirmation-request-guardian-bridge.ts +38 -29
- package/src/runtime/effective-capabilities.test.ts +128 -0
- package/src/runtime/effective-capabilities.ts +84 -0
- package/src/runtime/guardian-reply-router.ts +106 -21
- package/src/runtime/invite-redemption-service.ts +9 -25
- package/src/runtime/migrations/__tests__/vbundle-builder-fd-leak.test.ts +123 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +15 -0
- package/src/runtime/routes/__tests__/client-routes.test.ts +13 -0
- package/src/runtime/routes/__tests__/conversation-management-routes.test.ts +67 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +240 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-strategies/guardian-callback-strategy.ts +2 -2
- package/src/runtime/routes/assets/vellum-design-system.css +1959 -0
- package/src/runtime/routes/browser-tabs-routes.ts +9 -0
- package/src/runtime/routes/btw-routes.ts +1 -27
- package/src/runtime/routes/canonical-guardian-expiry-sweep.ts +17 -8
- package/src/runtime/routes/client-routes.ts +10 -0
- package/src/runtime/routes/contact-routes.ts +31 -8
- package/src/runtime/routes/conversation-compaction-routes.ts +1 -1
- package/src/runtime/routes/conversation-management-routes.ts +80 -1
- package/src/runtime/routes/conversation-query-routes.ts +68 -22
- package/src/runtime/routes/conversation-routes.ts +39 -14
- package/src/runtime/routes/credential-routes.ts +40 -16
- package/src/runtime/routes/empty-state-greeting-cache.ts +1 -2
- package/src/runtime/routes/events-routes.ts +1 -3
- package/src/runtime/routes/guardian-approval-interception.ts +14 -73
- package/src/runtime/routes/guardian-approval-prompt.ts +22 -4
- package/src/runtime/routes/home-feed-routes.ts +8 -3
- package/src/runtime/routes/identity-routes.ts +1 -296
- package/src/runtime/routes/inbound-message-handler.ts +214 -228
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +89 -7
- package/src/runtime/routes/inbound-stages/admission-policy.test.ts +154 -0
- package/src/runtime/routes/inbound-stages/admission-policy.ts +140 -0
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +3 -3
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +11 -6
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-activation-intercept.ts +1 -2
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.test.ts +7 -7
- package/src/runtime/routes/inbound-stages/guardian-reply-intercept.ts +47 -28
- package/src/runtime/routes/inbound-stages/reaction-intercept.ts +358 -0
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +8 -0
- package/src/runtime/routes/integrations/slack/channel.ts +36 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +1 -1
- package/src/runtime/routes/mcp-auth-routes.ts +233 -41
- package/src/runtime/routes/memory-eval-routes.ts +87 -0
- package/src/runtime/routes/notification-routes.ts +122 -133
- package/src/runtime/routes/platform-routes.ts +2 -2
- package/src/runtime/routes/plugins-routes.ts +202 -3
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +10 -0
- package/src/runtime/routes/surface-action-routes.ts +2 -1
- package/src/runtime/routes/tool-call-question-enrichment.test.ts +146 -0
- package/src/runtime/routes/tool-call-question-enrichment.ts +66 -0
- package/src/runtime/routes/workflow-routes.test.ts +229 -44
- package/src/runtime/routes/workflow-routes.ts +131 -29
- package/src/runtime/routes/workspace-greetings.ts +55 -0
- package/src/runtime/sync/resource-sync-events.ts +1 -11
- package/src/runtime/tool-grant-request-helper.ts +18 -16
- package/src/runtime/trust-context-resolver.ts +8 -5
- package/src/schedule/inference-profile.ts +2 -14
- package/src/schedule/schedule-store.ts +1 -1
- package/src/schedule/scheduler-types.ts +5 -1
- package/src/security/__tests__/provider-key-env-fallback.test.ts +6 -0
- package/src/security/secret-patterns.ts +3 -0
- package/src/subagent/manager.ts +17 -4
- package/src/subagent/types.ts +6 -0
- package/src/telemetry/trace-collection-policy.test.ts +28 -0
- package/src/telemetry/trace-collection-policy.ts +30 -0
- package/src/telemetry/types.ts +89 -0
- package/src/telemetry/usage-telemetry-reporter.test.ts +586 -36
- package/src/telemetry/usage-telemetry-reporter.ts +148 -41
- package/src/tools/AGENTS.md +3 -3
- package/src/tools/browser/__tests__/browser-execution-acquire.test.ts +31 -0
- package/src/tools/browser/browser-execution.ts +30 -19
- package/src/tools/document/document-tool.ts +2 -3
- package/src/tools/executor.ts +5 -3
- package/src/tools/host-terminal/host-shell.ts +5 -4
- package/src/tools/memory/register.ts +2 -2
- package/src/tools/network/__tests__/web-fetch-firecrawl.test.ts +360 -0
- package/src/tools/network/__tests__/web-search.test.ts +143 -0
- package/src/tools/network/web-fetch.ts +372 -1
- package/src/tools/network/web-search-error.ts +1 -1
- package/src/tools/network/web-search.ts +213 -10
- package/src/tools/permission-checker.ts +4 -3
- package/src/tools/registry.ts +20 -0
- package/src/tools/schedule/create.ts +7 -12
- package/src/tools/schedule/update.ts +4 -11
- package/src/tools/shared/filesystem/path-policy.ts +39 -13
- package/src/tools/side-effects.ts +2 -17
- package/src/tools/skills/execute.ts +33 -0
- package/src/tools/subagent/spawn.ts +61 -12
- package/src/tools/terminal/shell.ts +10 -4
- package/src/tools/tool-approval-handler.ts +18 -13
- package/src/tools/tool-manifest.ts +0 -2
- package/src/tools/types.ts +9 -0
- package/src/tools/ui-surface/definitions.ts +64 -3
- package/src/tools/verification-control-plane-policy.ts +3 -1
- package/src/tools/workflows/run-workflow.test.ts +8 -18
- package/src/tools/workflows/run-workflow.ts +1 -0
- package/src/util/disk-usage.ts +78 -23
- package/src/util/platform.ts +10 -3
- package/src/watcher/telemetry.ts +2 -2
- package/src/workflows/capabilities.ts +2 -3
- package/src/workflows/engine.test.ts +175 -1
- package/src/workflows/engine.ts +82 -0
- package/src/workflows/journal-store.test.ts +70 -0
- package/src/workflows/journal-store.ts +18 -3
- package/src/workflows/run-manager.test.ts +171 -28
- package/src/workflows/run-manager.ts +66 -24
- package/src/workspace/migrations/105-enable-memory-v3-live-for-new-workspaces.ts +63 -0
- package/src/workspace/migrations/106-drop-collect-usage-data.ts +47 -0
- package/src/workspace/migrations/107-drop-send-diagnostics.ts +47 -0
- package/src/workspace/migrations/108-drop-balanced-economy-profile.ts +129 -0
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/__tests__/app-control-no-global-cgevent.test.ts +0 -98
- package/src/__tests__/credential-security-e2e.test.ts +0 -362
- package/src/__tests__/credential-vault-unit.test.ts +0 -1528
- package/src/__tests__/credential-vault.test.ts +0 -1706
- package/src/__tests__/identity-intro-cache.test.ts +0 -315
- package/src/__tests__/secret-onetime-send.test.ts +0 -182
- package/src/cli/commands/__tests__/task.test.ts +0 -914
- package/src/cli/commands/task.ts +0 -771
- package/src/config/bundled-skills/personal-page/SKILL.md +0 -57
- package/src/config/bundled-skills/personal-page/TOOLS.json +0 -27
- package/src/config/bundled-skills/personal-page/tools/app-refresh.ts +0 -17
- package/src/config/preloaded-apps/personal-page/src/components/About.tsx +0 -22
- package/src/config/preloaded-apps/personal-page/src/components/App.tsx +0 -16
- package/src/config/preloaded-apps/personal-page/src/components/Features.tsx +0 -77
- package/src/config/preloaded-apps/personal-page/src/components/Hero.tsx +0 -57
- package/src/config/preloaded-apps/personal-page/src/components/Pending.tsx +0 -28
- package/src/config/preloaded-apps/personal-page/src/components/animations.tsx +0 -234
- package/src/config/preloaded-apps/personal-page/src/components/icons.tsx +0 -48
- package/src/config/preloaded-apps/personal-page/src/components/media.ts +0 -16
- package/src/config/preloaded-apps/personal-page/src/index.html +0 -20
- package/src/config/preloaded-apps/personal-page/src/main.tsx +0 -7
- package/src/config/preloaded-apps/personal-page/src/profile-data.ts +0 -82
- package/src/config/preloaded-apps/personal-page/src/styles.css +0 -759
- package/src/memory/__tests__/preloaded-apps.test.ts +0 -85
- package/src/memory/preloaded-apps.ts +0 -116
- package/src/notifications/tool-approval-copy.ts +0 -142
- package/src/runtime/routes/approval-prompt-ts-tracker.ts +0 -78
- package/src/runtime/routes/identity-intro-cache.ts +0 -172
- package/src/tools/credentials/vault.ts +0 -712
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { validateInferenceProfileKey } from "../../config/inference-profile-validation.js";
|
|
2
|
+
import { resolveDefaultProfileKey } from "../../config/llm-resolver.js";
|
|
3
|
+
import { getConfig } from "../../config/loader.js";
|
|
4
|
+
import { AUTO_PROFILE_KEY } from "../../config/seed-inference-profiles.js";
|
|
1
5
|
import { findConversation } from "../../daemon/conversation-registry.js";
|
|
2
6
|
import { getConversationOverrideProfile } from "../../memory/conversation-crud.js";
|
|
3
7
|
import type { Message } from "../../providers/types.js";
|
|
@@ -14,6 +18,7 @@ export async function executeSubagentSpawn(
|
|
|
14
18
|
const extraContext = input.context as string | undefined;
|
|
15
19
|
const fork = input.fork === true;
|
|
16
20
|
const role = (input.role as string | undefined) ?? undefined;
|
|
21
|
+
const inferenceProfile = input.inference_profile;
|
|
17
22
|
|
|
18
23
|
// For fork mode, sendResultToUser defaults to false unless explicitly set to true.
|
|
19
24
|
// For regular mode, sendResultToUser defaults to true (existing behavior).
|
|
@@ -28,6 +33,26 @@ export async function executeSubagentSpawn(
|
|
|
28
33
|
};
|
|
29
34
|
}
|
|
30
35
|
|
|
36
|
+
let requestedOverrideProfile: string | undefined;
|
|
37
|
+
let forceOverrideProfile = false;
|
|
38
|
+
if (inferenceProfile !== undefined) {
|
|
39
|
+
if (typeof inferenceProfile !== "string") {
|
|
40
|
+
return {
|
|
41
|
+
content: "Error: inference_profile must be a string",
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const profileError = validateInferenceProfileKey(inferenceProfile);
|
|
46
|
+
if (profileError) {
|
|
47
|
+
return {
|
|
48
|
+
content: `Error: ${profileError}`,
|
|
49
|
+
isError: true,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
requestedOverrideProfile = inferenceProfile;
|
|
53
|
+
forceOverrideProfile = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
31
56
|
const manager = getSubagentManager();
|
|
32
57
|
const sendToClient = context.sendToClient as
|
|
33
58
|
| ((msg: { type: string; [key: string]: unknown }) => void)
|
|
@@ -75,18 +100,41 @@ export async function executeSubagentSpawn(
|
|
|
75
100
|
// `SubagentManager.spawn` forwards it back into the subagent's
|
|
76
101
|
// `runAgentLoop` call as `options.overrideProfile`.
|
|
77
102
|
//
|
|
78
|
-
//
|
|
79
|
-
// `
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
103
|
+
// Resolution order: an explicit spawn-time profile, then the per-turn
|
|
104
|
+
// `context.overrideProfile` (populated by `runAgentLoopImpl` from its
|
|
105
|
+
// resolved `turnOverrideProfile`, covering per-conversation overrides and
|
|
106
|
+
// tool-routed switches), then a row read, and finally the resolved DEFAULT
|
|
107
|
+
// profile of the call site that invoked us. That last fallback is what makes
|
|
108
|
+
// a subagent match its invoker when the invoking turn ran purely on its
|
|
109
|
+
// call-site default — the workspace `activeProfile` for `mainAgent`, or the
|
|
110
|
+
// call site's own catalog default (e.g. `cost-optimized`) for a
|
|
111
|
+
// heartbeat/background invoker. `resolveDefaultProfileKey` does not reflect a
|
|
112
|
+
// static `llm.callSites.<callSite>` profile override (only the
|
|
113
|
+
// activeProfile-for-mainAgent path plus the catalog default), a narrow gap
|
|
114
|
+
// that only surfaces with no `activeProfile` set and a hand-tuned call-site
|
|
115
|
+
// profile.
|
|
116
|
+
//
|
|
117
|
+
// The fallback is forwarded NON-forced, so an explicit
|
|
118
|
+
// `llm.callSites.subagentSpawn` profile still wins; an explicit
|
|
119
|
+
// `inference_profile` argument keeps `forceOverrideProfile` and wins
|
|
120
|
+
// outright. (The row read short-circuits to `undefined` for the background
|
|
121
|
+
// subagent conversation and for tool calls outside an agent-loop turn.)
|
|
122
|
+
let inheritedOverrideProfile = requestedOverrideProfile;
|
|
123
|
+
if (inheritedOverrideProfile === undefined) {
|
|
124
|
+
const inheritedCandidate =
|
|
125
|
+
context.overrideProfile ??
|
|
126
|
+
getConversationOverrideProfile(context.conversationId) ??
|
|
127
|
+
resolveDefaultProfileKey(
|
|
128
|
+
context.invokingCallSite ?? "mainAgent",
|
|
129
|
+
getConfig().llm,
|
|
130
|
+
);
|
|
131
|
+
// Skip the metadata-only "auto" key: forwarding it collapses the child to
|
|
132
|
+
// `llm.default`, whereas the invoker's own auto base IS the `subagentSpawn`
|
|
133
|
+
// default — so leaving this undefined keeps the child on that default.
|
|
134
|
+
if (inheritedCandidate !== AUTO_PROFILE_KEY) {
|
|
135
|
+
inheritedOverrideProfile = inheritedCandidate;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
90
138
|
|
|
91
139
|
try {
|
|
92
140
|
const subagentId = await manager.spawn(
|
|
@@ -102,6 +150,7 @@ export async function executeSubagentSpawn(
|
|
|
102
150
|
...(inheritedOverrideProfile
|
|
103
151
|
? { overrideProfile: inheritedOverrideProfile }
|
|
104
152
|
: {}),
|
|
153
|
+
...(forceOverrideProfile ? { forceOverrideProfile: true } : {}),
|
|
105
154
|
...(context.toolUseId ? { parentToolUseId: context.toolUseId } : {}),
|
|
106
155
|
...forkFields,
|
|
107
156
|
},
|
|
@@ -4,8 +4,8 @@ import { spawn } from "node:child_process";
|
|
|
4
4
|
import { getConfig } from "../../config/loader.js";
|
|
5
5
|
import { isCesShellLockdownEnabled } from "../../credential-execution/feature-gates.js";
|
|
6
6
|
import { RiskLevel } from "../../permissions/types.js";
|
|
7
|
-
import { isUntrustedTrustClass } from "../../runtime/actor-trust-resolver.js";
|
|
8
7
|
import { wakeAgentForOpportunity } from "../../runtime/agent-wake.js";
|
|
8
|
+
import { isUntrustedShellLockdownActive } from "../../runtime/effective-capabilities.js";
|
|
9
9
|
import { redactSecrets } from "../../security/secret-scanner.js";
|
|
10
10
|
import { getLogger } from "../../util/logger.js";
|
|
11
11
|
import { getDataDir } from "../../util/platform.js";
|
|
@@ -117,9 +117,10 @@ export const shellTool = {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
const config = getConfig();
|
|
120
|
-
const shellLockdownActive =
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
const shellLockdownActive = isUntrustedShellLockdownActive({
|
|
121
|
+
trustClass: context.trustClass,
|
|
122
|
+
lockdownEnabled: isCesShellLockdownEnabled(config),
|
|
123
|
+
});
|
|
123
124
|
|
|
124
125
|
const networkMode: "off" | "proxied" =
|
|
125
126
|
input.network_mode === "proxied" ? "proxied" : "off";
|
|
@@ -307,6 +308,11 @@ export const shellTool = {
|
|
|
307
308
|
|
|
308
309
|
const env = buildSanitizedEnv();
|
|
309
310
|
env.__CONVERSATION_ID = context.conversationId;
|
|
311
|
+
// Surface the resolving model to assistant CLI commands so they can tailor
|
|
312
|
+
// remediation guidance for weak open models (see isWeakOpenModel).
|
|
313
|
+
if (context.attribution?.resolvedModel) {
|
|
314
|
+
env.__RESOLVED_MODEL = context.attribution.resolvedModel;
|
|
315
|
+
}
|
|
310
316
|
if (proxyEnv) {
|
|
311
317
|
Object.assign(env, proxyEnv);
|
|
312
318
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isUnparseableToolArgs,
|
|
10
10
|
unparseableToolArgsMessage,
|
|
11
11
|
} from "../providers/unparseable-tool-args.js";
|
|
12
|
-
import {
|
|
12
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
13
13
|
import { createOrReuseToolGrantRequest } from "../runtime/tool-grant-request-helper.js";
|
|
14
14
|
import { redactSecrets } from "../security/secret-scanner.js";
|
|
15
15
|
import { computeToolApprovalDigest } from "../security/tool-approval-digest.js";
|
|
@@ -157,7 +157,6 @@ const UI_SURFACE_TOOLS = new Set(["ui_show", "ui_update", "ui_dismiss"]);
|
|
|
157
157
|
|
|
158
158
|
function requiresGuardianApprovalForActor(
|
|
159
159
|
toolName: string,
|
|
160
|
-
input: Record<string, unknown>,
|
|
161
160
|
executionTarget: ExecutionTarget,
|
|
162
161
|
): boolean {
|
|
163
162
|
// UI surface tools are passive, user-visible operations (cards, forms,
|
|
@@ -170,14 +169,14 @@ function requiresGuardianApprovalForActor(
|
|
|
170
169
|
// Side-effect tools always require guardian approval for untrusted actors.
|
|
171
170
|
// Read-only host execution is also blocked because it can leak sensitive
|
|
172
171
|
// local information (e.g. shell/file reads).
|
|
173
|
-
return isSideEffectTool(toolName
|
|
172
|
+
return isSideEffectTool(toolName) || executionTarget === "host";
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
function guardianApprovalDeniedMessage(
|
|
177
176
|
trustClass: ToolContext["trustClass"],
|
|
178
177
|
toolName: string,
|
|
179
178
|
): string {
|
|
180
|
-
if (trustClass === "
|
|
179
|
+
if (resolveCapabilities(trustClass).sensitiveToolApproval === "deny") {
|
|
181
180
|
return `Permission denied for "${toolName}": this action requires guardian approval from a verified channel identity.`;
|
|
182
181
|
}
|
|
183
182
|
return `Permission denied for "${toolName}": this action requires guardian approval and the current actor is not the guardian.`;
|
|
@@ -320,11 +319,14 @@ export class ToolApprovalHandler {
|
|
|
320
319
|
|
|
321
320
|
const guardianApprovalRequired = requiresGuardianApprovalForActor(
|
|
322
321
|
name,
|
|
323
|
-
input,
|
|
324
322
|
executionTarget,
|
|
325
323
|
);
|
|
326
324
|
|
|
327
|
-
if (
|
|
325
|
+
if (
|
|
326
|
+
resolveCapabilities(context.trustClass).sensitiveToolApproval !==
|
|
327
|
+
"self" &&
|
|
328
|
+
guardianApprovalRequired
|
|
329
|
+
) {
|
|
328
330
|
const inputDigest = computeToolApprovalDigest(name, input);
|
|
329
331
|
needsGrantConsumption = true;
|
|
330
332
|
deferredConsumeParams = {
|
|
@@ -532,15 +534,18 @@ export class ToolApprovalHandler {
|
|
|
532
534
|
|
|
533
535
|
// No matching grant or race condition - deny or wait inline.
|
|
534
536
|
//
|
|
535
|
-
// For
|
|
536
|
-
// context, escalate to the
|
|
537
|
-
//
|
|
538
|
-
// available - this lets the tool call
|
|
539
|
-
// approval without the requester having
|
|
537
|
+
// For non-guardian actors with established identity (trusted_contact
|
|
538
|
+
// or unverified_contact) and sufficient context, escalate to the
|
|
539
|
+
// guardian by creating a canonical tool_grant_request. Then wait
|
|
540
|
+
// bounded for the grant to become available - this lets the tool call
|
|
541
|
+
// succeed inline after guardian approval without the requester having
|
|
542
|
+
// to retry manually.
|
|
540
543
|
//
|
|
541
|
-
//
|
|
544
|
+
// Actors with no identity (unknown) remain fail-closed with no
|
|
545
|
+
// escalation or wait.
|
|
542
546
|
if (
|
|
543
|
-
context.trustClass ===
|
|
547
|
+
resolveCapabilities(context.trustClass).sensitiveToolApproval ===
|
|
548
|
+
"escalate-and-wait" &&
|
|
544
549
|
context.assistantId &&
|
|
545
550
|
context.executionChannel &&
|
|
546
551
|
context.requesterExternalUserId
|
|
@@ -15,7 +15,6 @@ import { askQuestionTool } from "./ask-question/ask-question-tool.js";
|
|
|
15
15
|
import { makeAuthenticatedRequestTool } from "./credential-execution/make-authenticated-request.js";
|
|
16
16
|
import { manageSecureCommandTool } from "./credential-execution/manage-secure-command-tool.js";
|
|
17
17
|
import { runAuthenticatedCommandTool } from "./credential-execution/run-authenticated-command.js";
|
|
18
|
-
import { credentialStoreTool } from "./credentials/vault.js";
|
|
19
18
|
import { fileEditTool } from "./filesystem/edit.js";
|
|
20
19
|
import { fileListTool } from "./filesystem/list.js";
|
|
21
20
|
import { fileReadTool } from "./filesystem/read.js";
|
|
@@ -90,7 +89,6 @@ export const explicitTools: ToolDefinition[] = [
|
|
|
90
89
|
// Always-explicit tools
|
|
91
90
|
rememberTool,
|
|
92
91
|
recallTool,
|
|
93
|
-
credentialStoreTool,
|
|
94
92
|
notifyParentTool,
|
|
95
93
|
askQuestionTool,
|
|
96
94
|
// NOTE: external skill tools (registered via registerExternalTools in
|
package/src/tools/types.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { RiskLevel } from "@vellumai/skill-host-contracts";
|
|
|
13
13
|
import { z } from "zod";
|
|
14
14
|
|
|
15
15
|
import type { InterfaceId } from "../channels/types.js";
|
|
16
|
+
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
16
17
|
import type { ToolActivityMetadata } from "../daemon/message-types/web-activity.js";
|
|
17
18
|
import type { SecretPromptResult } from "../permissions/secret-prompter.js";
|
|
18
19
|
import type { ContentBlock } from "../providers/types.js";
|
|
@@ -363,6 +364,14 @@ export interface ToolContext {
|
|
|
363
364
|
* `executeSubagentSpawn` in tools/subagent/spawn.ts.
|
|
364
365
|
*/
|
|
365
366
|
overrideProfile?: string;
|
|
367
|
+
/**
|
|
368
|
+
* The LLM call site of the turn currently executing this tool (`mainAgent`,
|
|
369
|
+
* `heartbeatAgent`, scheduled work, etc.). `subagent_spawn` reads it to
|
|
370
|
+
* default a spawned subagent's inference profile to the profile the invoking
|
|
371
|
+
* turn resolved to, so subagents match whatever agent invoked them rather
|
|
372
|
+
* than always falling back to the static `subagentSpawn` call-site default.
|
|
373
|
+
*/
|
|
374
|
+
invokingCallSite?: LLMCallSite;
|
|
366
375
|
/**
|
|
367
376
|
* Canonical principal ID of the actor on whose behalf this tool invocation
|
|
368
377
|
* is running. Sourced from `conversation.trustContext.guardianPrincipalId`.
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { RiskLevel } from "../../permissions/types.js";
|
|
11
|
+
import { isWeakOpenModel } from "../../providers/weak-open-model.js";
|
|
11
12
|
import { ACTIVATION_MOMENT_PARAMS } from "../../telemetry/activation-funnel.js";
|
|
12
13
|
import type {
|
|
13
14
|
ToolContext,
|
|
@@ -37,8 +38,9 @@ function proxyExecute(toolName: string) {
|
|
|
37
38
|
): Promise<ToolExecutionResult> => {
|
|
38
39
|
if (toolName === "ui_show" && isEmptyDynamicPage(input)) {
|
|
39
40
|
return {
|
|
40
|
-
content:
|
|
41
|
-
|
|
41
|
+
content: isWeakOpenModel(context.attribution?.resolvedModel)
|
|
42
|
+
? EMPTY_DYNAMIC_PAGE_DECLARATIVE_REDIRECT
|
|
43
|
+
: EMPTY_DYNAMIC_PAGE_HTML_HINT,
|
|
42
44
|
isError: true,
|
|
43
45
|
};
|
|
44
46
|
}
|
|
@@ -59,6 +61,14 @@ function proxyExecute(toolName: string) {
|
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
if (toolName === "ui_update" && isEmptyUpdate(input)) {
|
|
65
|
+
return {
|
|
66
|
+
content:
|
|
67
|
+
'Error: ui_update received an empty `data` payload, so the surface was unchanged — the user still sees its previous state. The provided data is merged into the surface\'s current data, and merging nothing is a no-op. To advance a task_progress card, send the full step list: ui_update { surface_id: "<id>", data: { templateData: { steps: [{ label: "<step>", status: "completed" }, { label: "<step>", status: "in_progress" }] } } }. Resend ui_update with the fields you intend to change under `data`.',
|
|
68
|
+
isError: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
if (!context.proxyToolResolver) {
|
|
63
73
|
return {
|
|
64
74
|
content: `No proxy resolver configured for proxy tool "${toolName}". This tool requires an external resolver (e.g. a connected macOS client).`,
|
|
@@ -81,6 +91,27 @@ function proxyExecute(toolName: string) {
|
|
|
81
91
|
};
|
|
82
92
|
}
|
|
83
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Rejection envelope for an empty `dynamic_page` ui_show from a capable model:
|
|
96
|
+
* the surface carried no `data.html`, so it would render as a blank box. These
|
|
97
|
+
* models reliably author HTML, so the fix is simply to resend it inline.
|
|
98
|
+
*/
|
|
99
|
+
const EMPTY_DYNAMIC_PAGE_HTML_HINT =
|
|
100
|
+
"Error: ui_show dynamic_page requires non-empty HTML in `data.html`. The surface was not displayed because no content was provided — the user would see a blank box. Resend ui_show with the full HTML markup in `data.html`.";
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Rejection envelope for an empty `dynamic_page` ui_show from a weak open model.
|
|
104
|
+
* Authoring full HTML inline is the generation task these models fail at (an
|
|
105
|
+
* empty `data: {}` here, or broken markup otherwise), so steering them to
|
|
106
|
+
* "resend the HTML" just repeats the failure. Most widget requests are really
|
|
107
|
+
* structured data — comparisons, results, metrics — which render reliably via a
|
|
108
|
+
* field-based surface the model populates without writing any HTML, and which
|
|
109
|
+
* cannot render blank. dynamic_page stays available for genuinely custom visual
|
|
110
|
+
* HTML.
|
|
111
|
+
*/
|
|
112
|
+
const EMPTY_DYNAMIC_PAGE_DECLARATIVE_REDIRECT =
|
|
113
|
+
'Error: ui_show dynamic_page was not displayed — `data.html` was empty, so the user would see a blank box. Authoring full HTML inline is error-prone; for data, comparisons, results, or metrics prefer a structured surface, which you fill with fields (no HTML) and which never renders blank. Re-show the content as one of: a `table` (ui_show { surface_type: "table", data: { columns: [{ id, label }], rows: [{ id, cells: { <columnId>: "<value>" } }] } }), a `card` ({ title, body, metadata: [{ label, value }] }), or `work_result` ({ summary, metrics: [{ label, value }] }). Only use dynamic_page when you genuinely need custom visual HTML, in which case include the complete markup in `data.html` now.';
|
|
114
|
+
|
|
84
115
|
/**
|
|
85
116
|
* Worked ui_update example, appended to a successful task_progress `ui_show`
|
|
86
117
|
* result so the model learns the update pattern at the point of use (with the
|
|
@@ -98,6 +129,36 @@ function isTaskProgressCardShow(input: Record<string, unknown>): boolean {
|
|
|
98
129
|
return data?.template === "task_progress";
|
|
99
130
|
}
|
|
100
131
|
|
|
132
|
+
/**
|
|
133
|
+
* A `ui_update` whose `data` merge would change nothing: missing, not an
|
|
134
|
+
* object, or containing only (recursively) empty objects. Merging such a
|
|
135
|
+
* payload is a silent no-op — the surface keeps its prior state while the
|
|
136
|
+
* client still reports "Surface updated" — so the model never learns its
|
|
137
|
+
* update was hollow and a live card (e.g. task_progress) appears frozen.
|
|
138
|
+
* Arrays (e.g. `templateData.steps`) and any non-empty primitive leaf count
|
|
139
|
+
* as content.
|
|
140
|
+
*/
|
|
141
|
+
function isEmptyUpdate(input: Record<string, unknown>): boolean {
|
|
142
|
+
const data = asRecord(input.data);
|
|
143
|
+
return data === null || !hasContent(data);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function hasContent(value: unknown): boolean {
|
|
147
|
+
if (value === null || value === undefined) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (Array.isArray(value)) {
|
|
151
|
+
return value.length > 0;
|
|
152
|
+
}
|
|
153
|
+
if (typeof value === "object") {
|
|
154
|
+
return Object.values(value).some(hasContent);
|
|
155
|
+
}
|
|
156
|
+
if (typeof value === "string") {
|
|
157
|
+
return value.trim().length > 0;
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
101
162
|
function isEmptyDynamicPage(input: Record<string, unknown>): boolean {
|
|
102
163
|
if (input.surface_type !== "dynamic_page") {
|
|
103
164
|
return false;
|
|
@@ -311,7 +372,7 @@ export const uiShowTool = {
|
|
|
311
372
|
// ui_update
|
|
312
373
|
// ---------------------------------------------------------------------------
|
|
313
374
|
|
|
314
|
-
const uiUpdateTool = {
|
|
375
|
+
export const uiUpdateTool = {
|
|
315
376
|
name: "ui_update",
|
|
316
377
|
description:
|
|
317
378
|
"Update an existing surface's data. The provided data object is merged into the surface's current data.\n" +
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* /v1/channel-verification-sessions/revoke
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
import { resolveCapabilities } from "../runtime/capabilities.js";
|
|
14
|
+
|
|
13
15
|
const VERIFICATION_ENDPOINT_PATHS = [
|
|
14
16
|
"/v1/channel-verification-sessions",
|
|
15
17
|
"/v1/channel-verification-sessions/resend",
|
|
@@ -128,7 +130,7 @@ export function enforceVerificationControlPlanePolicy(
|
|
|
128
130
|
return { denied: false };
|
|
129
131
|
}
|
|
130
132
|
|
|
131
|
-
if (trustClass
|
|
133
|
+
if (resolveCapabilities(trustClass).canUseVerificationControlPlane) {
|
|
132
134
|
return { denied: false };
|
|
133
135
|
}
|
|
134
136
|
|
|
@@ -11,11 +11,9 @@ mock.module("../../util/logger.js", () => ({
|
|
|
11
11
|
}));
|
|
12
12
|
|
|
13
13
|
// ── Mutable mock state ────────────────────────────────────────────────
|
|
14
|
-
// `
|
|
15
|
-
//
|
|
16
|
-
// records the args of the last `start()` call for assertion.
|
|
14
|
+
// `configThrows` simulates config not yet loaded (test-setup race). The
|
|
15
|
+
// run-manager mock records the args of the last `start()` call for assertion.
|
|
17
16
|
|
|
18
|
-
let flagEnabled = true;
|
|
19
17
|
let configThrows = false;
|
|
20
18
|
|
|
21
19
|
const realLoader = await import("../../config/loader.js");
|
|
@@ -35,13 +33,6 @@ mock.module("../../config/loader.js", () => ({
|
|
|
35
33
|
}) as unknown as ReturnType<typeof realLoader.loadConfig>,
|
|
36
34
|
}));
|
|
37
35
|
|
|
38
|
-
const realFlags = await import("../../config/assistant-feature-flags.js");
|
|
39
|
-
mock.module("../../config/assistant-feature-flags.js", () => ({
|
|
40
|
-
...realFlags,
|
|
41
|
-
isAssistantFeatureFlagEnabled: (key: string) =>
|
|
42
|
-
key === "workflows" ? flagEnabled : false,
|
|
43
|
-
}));
|
|
44
|
-
|
|
45
36
|
// No live conversation in tests — the tool falls back to a synthetic trust
|
|
46
37
|
// context built from the tool context's trustClass.
|
|
47
38
|
const realRegistry = await import("../../daemon/conversation-registry.js");
|
|
@@ -92,7 +83,6 @@ function makeContext(): Parameters<typeof executeRunWorkflow>[1] {
|
|
|
92
83
|
}
|
|
93
84
|
|
|
94
85
|
beforeEach(() => {
|
|
95
|
-
flagEnabled = true;
|
|
96
86
|
configThrows = false;
|
|
97
87
|
startThrows = null;
|
|
98
88
|
lastStartArgs = null;
|
|
@@ -105,10 +95,10 @@ beforeEach(() => {
|
|
|
105
95
|
});
|
|
106
96
|
|
|
107
97
|
describe("workflow tools are served by the workflows skill", () => {
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
98
|
+
// run_workflow / manage_workflows are served by the `workflows` bundled skill
|
|
99
|
+
// (loaded via skill_load, invoked via skill_execute), not the always-on tool
|
|
100
|
+
// manifest. The skill manifest is the source of truth; assert it declares both
|
|
101
|
+
// as in-process host tools.
|
|
112
102
|
test("the workflows skill TOOLS.json declares both host-executed tools", async () => {
|
|
113
103
|
const { readFileSync } = await import("node:fs");
|
|
114
104
|
const { join } = await import("node:path");
|
|
@@ -211,13 +201,13 @@ describe("run_workflow launch", () => {
|
|
|
211
201
|
});
|
|
212
202
|
|
|
213
203
|
test("surfaces a run-manager start error as a tool error", async () => {
|
|
214
|
-
startThrows = new Error("
|
|
204
|
+
startThrows = new Error("run manager exploded");
|
|
215
205
|
const res = await executeRunWorkflow(
|
|
216
206
|
{ script: "export const meta = {};" },
|
|
217
207
|
makeContext(),
|
|
218
208
|
);
|
|
219
209
|
expect(res.isError).toBe(true);
|
|
220
|
-
expect(res.content).toContain("
|
|
210
|
+
expect(res.content).toContain("run manager exploded");
|
|
221
211
|
});
|
|
222
212
|
});
|
|
223
213
|
|
package/src/util/disk-usage.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
2
|
import { existsSync, statfsSync } from "node:fs";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getIsContainerized,
|
|
6
|
+
getIsPlatform,
|
|
7
|
+
getMinikubeStorageSize,
|
|
8
|
+
} from "../config/env-registry.js";
|
|
5
9
|
import { getWorkspaceDir } from "./platform.js";
|
|
6
10
|
|
|
7
11
|
export interface DiskUsageInfo {
|
|
@@ -58,6 +62,57 @@ export function __resetDiskUsageCacheForTests(): void {
|
|
|
58
62
|
duCachePaths = null;
|
|
59
63
|
}
|
|
60
64
|
|
|
65
|
+
/**
|
|
66
|
+
* How the workspace volume's capacity should be reported when statfsSync
|
|
67
|
+
* cannot see the volume directly.
|
|
68
|
+
*
|
|
69
|
+
* - `fixed-cap`: minikube hostPath PVC — the PVC request is the hard
|
|
70
|
+
* capacity, so usage is measured with `du` and free space is whatever
|
|
71
|
+
* remains within the quota.
|
|
72
|
+
* - `host-free`: local Docker named volume — the volume is backed by the
|
|
73
|
+
* host (or Colima VM) filesystem and can grow into its free space, so
|
|
74
|
+
* usage is measured with `du` and the effective capacity is current usage
|
|
75
|
+
* plus the host's remaining headroom.
|
|
76
|
+
* - `none`: statfsSync already reports the volume accurately (bare metal, or
|
|
77
|
+
* a platform-managed instance on a CSI-backed PVC), so use it directly.
|
|
78
|
+
*/
|
|
79
|
+
type WorkspaceVolumeReporting =
|
|
80
|
+
| { kind: "none" }
|
|
81
|
+
| { kind: "fixed-cap"; totalBytes: number }
|
|
82
|
+
| { kind: "host-free" };
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Decide how to report the workspace volume's capacity. Both minikube
|
|
86
|
+
* hostPath PVCs and local Docker named volumes are backed by the host
|
|
87
|
+
* filesystem, so statfsSync reports the host's entire disk rather than the
|
|
88
|
+
* workspace volume — in both cases we measure actual usage with `du` instead.
|
|
89
|
+
*/
|
|
90
|
+
function classifyWorkspaceVolume(
|
|
91
|
+
fsTotalBytes: number,
|
|
92
|
+
): WorkspaceVolumeReporting {
|
|
93
|
+
// Minikube mode: the platform passes the PVC storage size so we can report
|
|
94
|
+
// accurate capacity. Detect the hostPath case by comparing filesystem size
|
|
95
|
+
// against the PVC size — if the filesystem is larger, statfsSync is seeing
|
|
96
|
+
// the host disk and we should measure the directory instead.
|
|
97
|
+
const storageSizeRaw = getMinikubeStorageSize();
|
|
98
|
+
if (storageSizeRaw) {
|
|
99
|
+
const pvcTotalBytes = parseK8sMemoryBytes(storageSizeRaw);
|
|
100
|
+
if (pvcTotalBytes !== null && fsTotalBytes > pvcTotalBytes * 1.1) {
|
|
101
|
+
return { kind: "fixed-cap", totalBytes: pvcTotalBytes };
|
|
102
|
+
}
|
|
103
|
+
return { kind: "none" };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Local Docker hatch: the workspace is a Docker named volume backed by the
|
|
107
|
+
// host filesystem. Platform-managed remote instances run on CSI-backed PVCs
|
|
108
|
+
// where statfsSync already reports the volume, so they are excluded.
|
|
109
|
+
if (getIsContainerized() && !getIsPlatform()) {
|
|
110
|
+
return { kind: "host-free" };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return { kind: "none" };
|
|
114
|
+
}
|
|
115
|
+
|
|
61
116
|
export function getDiskUsageInfo(): DiskUsageInfo | null {
|
|
62
117
|
try {
|
|
63
118
|
const wsDir = getWorkspaceDir();
|
|
@@ -68,28 +123,28 @@ export function getDiskUsageInfo(): DiskUsageInfo | null {
|
|
|
68
123
|
const bytesToMb = (b: number) =>
|
|
69
124
|
Math.round((b / (1024 * 1024)) * 100) / 100;
|
|
70
125
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
126
|
+
const reporting = classifyWorkspaceVolume(fsTotalBytes);
|
|
127
|
+
if (reporting.kind !== "none") {
|
|
128
|
+
const volumePaths = [diskPath];
|
|
129
|
+
if (diskPath !== "/data" && existsSync("/data")) {
|
|
130
|
+
volumePaths.push("/data");
|
|
131
|
+
}
|
|
132
|
+
const usedBytes = getCachedDirectorySizeBytes(volumePaths);
|
|
133
|
+
if (usedBytes !== null) {
|
|
134
|
+
const totalBytes =
|
|
135
|
+
reporting.kind === "fixed-cap"
|
|
136
|
+
? reporting.totalBytes
|
|
137
|
+
: usedBytes + fsFreeBytes;
|
|
138
|
+
const freeBytes =
|
|
139
|
+
reporting.kind === "fixed-cap"
|
|
140
|
+
? Math.max(0, reporting.totalBytes - usedBytes)
|
|
141
|
+
: fsFreeBytes;
|
|
142
|
+
return {
|
|
143
|
+
path: diskPath,
|
|
144
|
+
totalMb: bytesToMb(totalBytes),
|
|
145
|
+
usedMb: bytesToMb(usedBytes),
|
|
146
|
+
freeMb: bytesToMb(freeBytes),
|
|
147
|
+
};
|
|
93
148
|
}
|
|
94
149
|
}
|
|
95
150
|
|
package/src/util/platform.ts
CHANGED
|
@@ -314,7 +314,14 @@ export function getWorkspaceToolsDir(): string {
|
|
|
314
314
|
return join(getWorkspaceDir(), "tools");
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
/**
|
|
317
|
+
/**
|
|
318
|
+
* Returns $VELLUM_WORKSPACE_DIR/routes — user-defined HTTP route handlers.
|
|
319
|
+
*
|
|
320
|
+
* Handler modules under this directory are dynamic-imported by the user-route
|
|
321
|
+
* dispatcher and their exported HTTP-method functions are executed on the
|
|
322
|
+
* next matching request, so the file risk classifier escalates writes under
|
|
323
|
+
* this path to High for the same reason `plugins/` and `tools/` are escalated.
|
|
324
|
+
*/
|
|
318
325
|
export function getWorkspaceRoutesDir(): string {
|
|
319
326
|
return join(getWorkspaceDir(), "routes");
|
|
320
327
|
}
|
|
@@ -402,8 +409,8 @@ export function getSkillRuntimePath(
|
|
|
402
409
|
*
|
|
403
410
|
* Resolution order:
|
|
404
411
|
*
|
|
405
|
-
* 1. macOS `.app` bundle: `Contents/Resources/bun` —
|
|
406
|
-
*
|
|
412
|
+
* 1. macOS `.app` bundle: `Contents/Resources/bun` — bundled at a version
|
|
413
|
+
* that matches `.tool-versions`.
|
|
407
414
|
* 2. Next-to-binary: `<execDir>/bun` for Docker/generic compiled layouts
|
|
408
415
|
* that stage a bun binary alongside the daemon (PR 29 wires this up).
|
|
409
416
|
*
|
package/src/watcher/telemetry.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* ahead of the planned watcher → skills-and-schedules migration.
|
|
5
5
|
*
|
|
6
6
|
* Both event shapes ship through the existing lifecycle-event telemetry
|
|
7
|
-
* pipeline, so they inherit its `
|
|
8
|
-
* no wire-contract or platform-side changes:
|
|
7
|
+
* pipeline, so they inherit its platform `share_analytics` consent gate and
|
|
8
|
+
* need no wire-contract or platform-side changes:
|
|
9
9
|
*
|
|
10
10
|
* - `watcher_enabled:<providerId>` — one per enabled watcher, at most
|
|
11
11
|
* once per 24h per daemon. Counts devices that have watchers
|
|
@@ -29,9 +29,8 @@
|
|
|
29
29
|
* (If host execution is ever wanted, the deliberate path is to thread the
|
|
30
30
|
* originating tool context through the engine — not to relax this gate.)
|
|
31
31
|
*
|
|
32
|
-
* This module is pure logic: it performs no
|
|
33
|
-
*
|
|
34
|
-
* callers, not this code.
|
|
32
|
+
* This module is pure logic: it performs no I/O beyond the synchronous
|
|
33
|
+
* tool-registry lookup.
|
|
35
34
|
*/
|
|
36
35
|
|
|
37
36
|
import { z } from "zod";
|