@vellumai/assistant 0.9.0 → 0.10.0-dev.202606192226.8ed8a6a
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 +19 -35
- 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 +1128 -119
- 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__/agent-loop-pushes-post-hook-prompt.test.ts +306 -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__/approval-cascade.test.ts +6 -0
- package/src/__tests__/approval-routes-http.test.ts +128 -0
- 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__/compaction-events.test.ts +6 -0
- 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-abort-tool-results.test.ts +6 -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-confirmation-signals.test.ts +6 -0
- package/src/__tests__/conversation-lifecycle.test.ts +7 -9
- package/src/__tests__/conversation-load-history-repair.test.ts +101 -0
- package/src/__tests__/conversation-process-callsite.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +6 -0
- package/src/__tests__/conversation-queue.test.ts +6 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +15 -12
- package/src/__tests__/conversation-slash-queue.test.ts +6 -0
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -0
- package/src/__tests__/conversation-speed-override.test.ts +6 -0
- package/src/__tests__/conversation-surfaces-activation-emit.test.ts +6 -3
- package/src/__tests__/conversation-title-service.test.ts +62 -0
- package/src/__tests__/conversation-workspace-cache-state.test.ts +6 -0
- package/src/__tests__/conversation-workspace-injection.test.ts +6 -0
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +6 -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-pressure-tools.test.ts +41 -1
- package/src/__tests__/disk-usage.test.ts +65 -0
- package/src/__tests__/document-tool-security.test.ts +9 -6
- package/src/__tests__/document-update-default-surface.test.ts +202 -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__/gemini-count-tokens.test.ts +70 -0
- 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-disk-pressure.test.ts +10 -5
- 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__/secret-response-routing.test.ts +35 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +16 -2
- package/src/__tests__/skill-execute-input.test.ts +177 -1
- package/src/__tests__/skill-load-tool.test.ts +72 -0
- 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__/system-storage-cleanup-skill.test.ts +56 -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 +75 -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/db/status.ts +37 -3
- 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 +400 -14
- 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__/install-from-github.test.ts +31 -0
- package/src/cli/lib/__tests__/merge-plugin-tree.test.ts +443 -0
- package/src/cli/lib/__tests__/plugin-pin-history.test.ts +162 -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 +128 -19
- package/src/cli/lib/merge-plugin-tree.ts +328 -0
- package/src/cli/lib/plugin-fingerprint.ts +14 -0
- package/src/cli/lib/plugin-marketplace.ts +11 -0
- package/src/cli/lib/plugin-pin-history.ts +257 -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/document-editor/SKILL.md +3 -3
- package/src/config/bundled-skills/document-editor/TOOLS.json +2 -2
- 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/system-storage-cleanup/SKILL.md +74 -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/__tests__/conversation-tool-setup.test.ts +44 -0
- 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 +53 -19
- package/src/daemon/conversation.ts +131 -20
- 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/memory-v2-startup.test.ts +131 -0
- package/src/daemon/memory-v2-startup.ts +100 -1
- 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/daemon/wake-conversation-ops.ts +1 -0
- 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__/db-logs-attach.test.ts +122 -0
- 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-async-query.ts +20 -2
- package/src/memory/db-connection.ts +49 -5
- 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/permissions/secret-prompter.ts +15 -1
- 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/compaction/window-manager.ts +18 -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/injectors.ts +4 -4
- 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__/count-tokens-forwarding.test.ts +98 -0
- 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/anthropic/client.ts +230 -175
- package/src/providers/atlascloud/client.ts +85 -0
- package/src/providers/call-site-routing.ts +10 -0
- package/src/providers/fetch-provider-catalog.ts +85 -0
- package/src/providers/gemini/client.ts +43 -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/ratelimit.ts +9 -0
- package/src/providers/retry.ts +62 -12
- package/src/providers/search-provider-catalog.ts +10 -0
- package/src/providers/types.ts +16 -0
- package/src/providers/usage-tracking.ts +7 -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 +227 -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 +71 -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 +126 -0
- package/src/runtime/migrations/vbundle-builder.ts +49 -20
- package/src/runtime/pending-interactions.ts +35 -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 +383 -1
- package/src/runtime/routes/app-routes.ts +1 -1
- package/src/runtime/routes/approval-routes.ts +40 -9
- 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 +366 -11
- package/src/runtime/routes/schedule-routes.ts +0 -22
- package/src/runtime/routes/secret-routes.ts +15 -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 +30 -6
- 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 +99 -2
- package/src/tools/skills/load.ts +43 -2
- package/src/tools/subagent/spawn.ts +64 -15
- 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 +10 -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/logs-db-path.ts +22 -0
- 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
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for descriptor hygiene in the vbundle export path.
|
|
3
|
+
*
|
|
4
|
+
* `streamExportVBundle` opens every file in the workspace twice — once to hash
|
|
5
|
+
* it (Pass 1) and once to stream it into the tar (Pass 2). This test pins the
|
|
6
|
+
* invariant that those reads release their descriptors: the number of open
|
|
7
|
+
* descriptors held by the process must not grow proportionally to the number
|
|
8
|
+
* of files exported. Without that guarantee a workspace-sized export exhausts
|
|
9
|
+
* the daemon's descriptor limit (EMFILE) and every subsequent subprocess spawn
|
|
10
|
+
* fails.
|
|
11
|
+
*
|
|
12
|
+
* Descriptor counting uses `/proc/self/fd`, which only exists on Linux. The
|
|
13
|
+
* assertion is skipped on platforms without it (e.g. macOS dev machines); CI
|
|
14
|
+
* runs on Linux, so the regression stays covered there.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
existsSync,
|
|
19
|
+
mkdirSync,
|
|
20
|
+
readdirSync,
|
|
21
|
+
rmSync,
|
|
22
|
+
writeFileSync,
|
|
23
|
+
} from "node:fs";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
import { describe, expect, test } from "bun:test";
|
|
27
|
+
|
|
28
|
+
import { assertNotLiveDb } from "../../../__tests__/assert-not-live-db.js";
|
|
29
|
+
import { streamExportVBundle } from "../vbundle-builder.js";
|
|
30
|
+
import { defaultV1Options } from "./v1-test-helpers.js";
|
|
31
|
+
|
|
32
|
+
const PROC_SELF_FD = "/proc/self/fd";
|
|
33
|
+
const hasProcFd = existsSync(PROC_SELF_FD);
|
|
34
|
+
|
|
35
|
+
/** Count the descriptors currently open by this process. */
|
|
36
|
+
function openFdCount(): number {
|
|
37
|
+
return readdirSync(PROC_SELF_FD).length;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build a workspace with enough distinct files (across nested directories) that
|
|
42
|
+
* a per-file descriptor leak would be obvious against the assertion bound.
|
|
43
|
+
*/
|
|
44
|
+
function createPopulatedWorkspace(fileCount: number): {
|
|
45
|
+
dir: string;
|
|
46
|
+
cleanup: () => void;
|
|
47
|
+
} {
|
|
48
|
+
const dir = join(
|
|
49
|
+
tmpdir(),
|
|
50
|
+
`vbundle-fd-leak-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
51
|
+
);
|
|
52
|
+
mkdirSync(dir, { recursive: true });
|
|
53
|
+
writeFileSync(join(dir, "config.json"), JSON.stringify({ test: true }));
|
|
54
|
+
const dbDir = join(dir, "data", "db");
|
|
55
|
+
mkdirSync(dbDir, { recursive: true });
|
|
56
|
+
writeFileSync(join(dbDir, "assistant.db"), "fake-db-content");
|
|
57
|
+
|
|
58
|
+
// A spread of files under a few nested directories, each with non-trivial
|
|
59
|
+
// (multi-chunk) content so the read loop iterates more than once.
|
|
60
|
+
const filler = "x".repeat(200 * 1024);
|
|
61
|
+
for (let i = 0; i < fileCount; i++) {
|
|
62
|
+
const sub = join(dir, "data", "files", `dir-${i % 5}`);
|
|
63
|
+
mkdirSync(sub, { recursive: true });
|
|
64
|
+
writeFileSync(join(sub, `file-${i}.txt`), `${filler}\n${i}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
dir,
|
|
69
|
+
cleanup: () => {
|
|
70
|
+
assertNotLiveDb(dir);
|
|
71
|
+
rmSync(dir, { recursive: true, force: true });
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
describe("streamExportVBundle — descriptor lifecycle", () => {
|
|
77
|
+
test.skipIf(!hasProcFd)(
|
|
78
|
+
"does not leak a file descriptor per exported file",
|
|
79
|
+
async () => {
|
|
80
|
+
const fileCount = 60;
|
|
81
|
+
const workspace = createPopulatedWorkspace(fileCount);
|
|
82
|
+
|
|
83
|
+
// Warm-up export: first run can open and cache descriptors that legitimately
|
|
84
|
+
// persist (loggers, the daemon DB, etc.). Measuring the delta around a
|
|
85
|
+
// second export isolates per-file leakage from one-time setup.
|
|
86
|
+
let warmup: Awaited<ReturnType<typeof streamExportVBundle>> | undefined;
|
|
87
|
+
try {
|
|
88
|
+
warmup = await streamExportVBundle({
|
|
89
|
+
workspaceDir: workspace.dir,
|
|
90
|
+
...defaultV1Options(),
|
|
91
|
+
});
|
|
92
|
+
} finally {
|
|
93
|
+
await warmup?.cleanup();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const before = openFdCount();
|
|
97
|
+
|
|
98
|
+
let result: Awaited<ReturnType<typeof streamExportVBundle>> | undefined;
|
|
99
|
+
try {
|
|
100
|
+
result = await streamExportVBundle({
|
|
101
|
+
workspaceDir: workspace.dir,
|
|
102
|
+
...defaultV1Options(),
|
|
103
|
+
});
|
|
104
|
+
// Manifest covers every file we wrote — proves the walk actually read
|
|
105
|
+
// them (otherwise a no-op export would trivially leak nothing).
|
|
106
|
+
expect(result.manifest.contents.length).toBeGreaterThanOrEqual(
|
|
107
|
+
fileCount,
|
|
108
|
+
);
|
|
109
|
+
} finally {
|
|
110
|
+
await result?.cleanup();
|
|
111
|
+
workspace.cleanup();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const after = openFdCount();
|
|
115
|
+
const delta = after - before;
|
|
116
|
+
|
|
117
|
+
// Each export reads 2×fileCount files (hash pass + tar pass). A per-file
|
|
118
|
+
// leak would push the delta past `fileCount`. Allow a small constant for
|
|
119
|
+
// incidental descriptors (temp output file already cleaned up, jitter).
|
|
120
|
+
expect(delta).toBeLessThan(8);
|
|
121
|
+
},
|
|
122
|
+
// Two full exports of a multi-megabyte workspace (hash pass + tar pass each)
|
|
123
|
+
// do real disk I/O; the default 5s budget is tight under loaded CI runners.
|
|
124
|
+
30_000,
|
|
125
|
+
);
|
|
126
|
+
});
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
import { createHash, randomUUID } from "node:crypto";
|
|
12
12
|
import {
|
|
13
13
|
closeSync,
|
|
14
|
-
createReadStream,
|
|
15
14
|
createWriteStream,
|
|
16
15
|
existsSync,
|
|
17
16
|
lstatSync,
|
|
@@ -21,7 +20,7 @@ import {
|
|
|
21
20
|
readSync,
|
|
22
21
|
realpathSync,
|
|
23
22
|
} from "node:fs";
|
|
24
|
-
import { stat, unlink } from "node:fs/promises";
|
|
23
|
+
import { type FileHandle, open, stat, unlink } from "node:fs/promises";
|
|
25
24
|
import { tmpdir } from "node:os";
|
|
26
25
|
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
27
26
|
import { Readable } from "node:stream";
|
|
@@ -886,9 +885,10 @@ export function walkDirectoryForMetadata(
|
|
|
886
885
|
}
|
|
887
886
|
|
|
888
887
|
/**
|
|
889
|
-
* Compute SHA-256 hex digest of a file by
|
|
890
|
-
* entire file in memory. When `size` is provided, only
|
|
891
|
-
* `size` bytes to match what will be archived in the tar
|
|
888
|
+
* Compute SHA-256 hex digest of a file by reading it in bounded chunks —
|
|
889
|
+
* never buffers the entire file in memory. When `size` is provided, only
|
|
890
|
+
* hashes the first `size` bytes to match what will be archived in the tar
|
|
891
|
+
* entry.
|
|
892
892
|
*/
|
|
893
893
|
async function computeFileSha256(
|
|
894
894
|
filePath: string,
|
|
@@ -896,11 +896,28 @@ async function computeFileSha256(
|
|
|
896
896
|
): Promise<string> {
|
|
897
897
|
const hash = createHash("sha256");
|
|
898
898
|
if (size === 0) return hash.digest("hex");
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
899
|
+
|
|
900
|
+
// Read through an explicitly-managed FileHandle so the descriptor is
|
|
901
|
+
// always released in `finally`. This pass opens every file in the
|
|
902
|
+
// workspace, so any per-file descriptor leak here would exhaust the
|
|
903
|
+
// daemon's file-descriptor limit (EMFILE). A bounded read loop keeps peak
|
|
904
|
+
// memory flat regardless of file size.
|
|
905
|
+
const readChunkBytes = 64 * 1024;
|
|
906
|
+
const handle = await open(filePath, "r");
|
|
907
|
+
try {
|
|
908
|
+
const chunk = Buffer.allocUnsafe(readChunkBytes);
|
|
909
|
+
let position = 0;
|
|
910
|
+
for (;;) {
|
|
911
|
+
const remaining = size !== undefined ? size - position : Infinity;
|
|
912
|
+
if (remaining <= 0) break;
|
|
913
|
+
const toRead = Math.min(chunk.length, remaining);
|
|
914
|
+
const { bytesRead } = await handle.read(chunk, 0, toRead, position);
|
|
915
|
+
if (bytesRead === 0) break;
|
|
916
|
+
hash.update(chunk.subarray(0, bytesRead));
|
|
917
|
+
position += bytesRead;
|
|
918
|
+
}
|
|
919
|
+
} finally {
|
|
920
|
+
await handle.close();
|
|
904
921
|
}
|
|
905
922
|
return hash.digest("hex");
|
|
906
923
|
}
|
|
@@ -1056,21 +1073,33 @@ async function* generateTarStream(
|
|
|
1056
1073
|
// alignment. The WAL checkpoint before export is the primary
|
|
1057
1074
|
// consistency mechanism for the database.
|
|
1058
1075
|
let bytesWritten = 0;
|
|
1059
|
-
if (
|
|
1076
|
+
if (entrySize > 0) {
|
|
1077
|
+
// Read through an explicitly-managed FileHandle so the descriptor is
|
|
1078
|
+
// released in `finally` even when the consumer abandons the generator
|
|
1079
|
+
// mid-file. Each read uses a fresh buffer so a yielded chunk is never
|
|
1080
|
+
// overwritten by the next read before the consumer drains it.
|
|
1081
|
+
let handle: FileHandle | undefined;
|
|
1060
1082
|
try {
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1083
|
+
handle = await open(file.diskPath, "r");
|
|
1084
|
+
const readChunkBytes = 64 * 1024;
|
|
1085
|
+
while (bytesWritten < entrySize) {
|
|
1086
|
+
const toRead = Math.min(readChunkBytes, entrySize - bytesWritten);
|
|
1087
|
+
const buf = Buffer.allocUnsafe(toRead);
|
|
1088
|
+
const { bytesRead } = await handle.read(
|
|
1089
|
+
buf,
|
|
1090
|
+
0,
|
|
1091
|
+
toRead,
|
|
1092
|
+
bytesWritten,
|
|
1093
|
+
);
|
|
1094
|
+
if (bytesRead === 0) break;
|
|
1095
|
+
bytesWritten += bytesRead;
|
|
1096
|
+
yield bytesRead === buf.length ? buf : buf.subarray(0, bytesRead);
|
|
1070
1097
|
}
|
|
1071
1098
|
} catch {
|
|
1072
1099
|
// File was deleted or rotated between passes — emit zeros for
|
|
1073
1100
|
// the full declared size so the tar structure stays valid
|
|
1101
|
+
} finally {
|
|
1102
|
+
if (handle) await handle.close();
|
|
1074
1103
|
}
|
|
1075
1104
|
}
|
|
1076
1105
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
import type { InteractionResolutionState } from "../api/events/interaction-resolved.js";
|
|
22
|
+
import type { QuestionEntry } from "../api/events/question-request.js";
|
|
22
23
|
import type { UserDecision } from "../permissions/types.js";
|
|
23
24
|
import { getLogger } from "../util/logger.js";
|
|
24
25
|
import { broadcastMessage } from "./assistant-event-hub.js";
|
|
@@ -50,6 +51,36 @@ export interface ConfirmationDetails {
|
|
|
50
51
|
}>;
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Full batched question payload carried on a pending `question` interaction, so
|
|
56
|
+
* a history-load render can stamp the outstanding prompt back onto its tool
|
|
57
|
+
* call and rehydrate the question card on a cold reconnect. Mirrors the
|
|
58
|
+
* `question_request` event's `questions[]` — `metadata` only retains the
|
|
59
|
+
* `orderedIds`/`optionsById` the response route needs to validate submissions,
|
|
60
|
+
* which is insufficient to reconstruct the card.
|
|
61
|
+
*/
|
|
62
|
+
export interface QuestionDetails {
|
|
63
|
+
entries: QuestionEntry[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Public prompt metadata for a pending `secret` interaction, retained so a
|
|
68
|
+
* cold conversation load can rehydrate the secret prompt with its full
|
|
69
|
+
* descriptive context. SECURITY: never carries the secret value — only the
|
|
70
|
+
* public fields already broadcast on the `secret_request` event.
|
|
71
|
+
*/
|
|
72
|
+
export interface SecretDetails {
|
|
73
|
+
service: string;
|
|
74
|
+
field: string;
|
|
75
|
+
label: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
placeholder?: string;
|
|
78
|
+
purpose?: string;
|
|
79
|
+
allowedTools?: string[];
|
|
80
|
+
allowedDomains?: string[];
|
|
81
|
+
allowOneTimeSend?: boolean;
|
|
82
|
+
}
|
|
83
|
+
|
|
53
84
|
export interface PendingInteraction {
|
|
54
85
|
/**
|
|
55
86
|
* Owning conversation, when the interaction was raised inside one. Absent
|
|
@@ -69,6 +100,10 @@ export interface PendingInteraction {
|
|
|
69
100
|
| "host_transfer"
|
|
70
101
|
| "acp_confirmation";
|
|
71
102
|
confirmationDetails?: ConfirmationDetails;
|
|
103
|
+
/** For a pending `question`: the full batched entries, so a history-load render can rehydrate the question card. */
|
|
104
|
+
questionDetails?: QuestionDetails;
|
|
105
|
+
/** For a pending `secret`: the public prompt metadata, so a cold load can rehydrate the secret prompt. */
|
|
106
|
+
secretDetails?: SecretDetails;
|
|
72
107
|
/** For ACP permissions: resolves directly without a Conversation object. */
|
|
73
108
|
directResolve?: (decision: UserDecision) => void;
|
|
74
109
|
/** When set, the host_bash request should be routed to this specific client. */
|
|
@@ -51,6 +51,7 @@ type ListClientsResponse = {
|
|
|
51
51
|
machineName?: string;
|
|
52
52
|
connectedAt: string;
|
|
53
53
|
lastActiveAt: string;
|
|
54
|
+
degraded?: boolean;
|
|
54
55
|
}>;
|
|
55
56
|
};
|
|
56
57
|
|
|
@@ -152,4 +153,16 @@ describe("list_clients route — same-user filter", () => {
|
|
|
152
153
|
const ids = result.clients.map((c) => c.clientId).sort();
|
|
153
154
|
expect(ids).toEqual(["client-A1", "client-B1", "client-noprincipal"]);
|
|
154
155
|
});
|
|
156
|
+
|
|
157
|
+
test("includes a degraded flag (false for a freshly connected client)", () => {
|
|
158
|
+
registerClient({ clientId: "client-A1", actorPrincipalId: "user-A" });
|
|
159
|
+
|
|
160
|
+
const handler = findHandler("list_clients");
|
|
161
|
+
const result = handler({
|
|
162
|
+
headers: { "x-vellum-actor-principal-id": "user-A" },
|
|
163
|
+
}) as ListClientsResponse;
|
|
164
|
+
|
|
165
|
+
expect(result.clients).toHaveLength(1);
|
|
166
|
+
expect(result.clients[0].degraded).toBe(false);
|
|
167
|
+
});
|
|
155
168
|
});
|
|
@@ -26,6 +26,8 @@ mock.module("../../assistant-event-hub.js", () => ({
|
|
|
26
26
|
broadcastMessage: () => {},
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
+
import { eq } from "drizzle-orm";
|
|
30
|
+
|
|
29
31
|
import { getDb } from "../../../memory/db-connection.js";
|
|
30
32
|
import { initializeDb } from "../../../memory/db-init.js";
|
|
31
33
|
import { conversations } from "../../../memory/schema.js";
|
|
@@ -71,6 +73,10 @@ function findHandler(routes: RouteDefinition[], operationId: string) {
|
|
|
71
73
|
return route.handler;
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
const createHandler = findHandler(
|
|
77
|
+
CONVERSATION_MANAGEMENT_ROUTES,
|
|
78
|
+
"createConversation",
|
|
79
|
+
);
|
|
74
80
|
const putHandler = findHandler(
|
|
75
81
|
CONVERSATION_MANAGEMENT_ROUTES,
|
|
76
82
|
"setConversationInferenceProfile",
|
|
@@ -112,6 +118,67 @@ function seedConversation(id: string): void {
|
|
|
112
118
|
// Tests
|
|
113
119
|
// ---------------------------------------------------------------------------
|
|
114
120
|
|
|
121
|
+
describe("POST /v1/conversations (createConversation)", () => {
|
|
122
|
+
beforeEach(() => {
|
|
123
|
+
clearConversations();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
function readConversation(id: string) {
|
|
127
|
+
return getDb()
|
|
128
|
+
.select({
|
|
129
|
+
title: conversations.title,
|
|
130
|
+
isAutoTitle: conversations.isAutoTitle,
|
|
131
|
+
})
|
|
132
|
+
.from(conversations)
|
|
133
|
+
.where(eq(conversations.id, id))
|
|
134
|
+
.get();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
test("with a title → persists it as a user-set title (isAutoTitle = 0)", async () => {
|
|
138
|
+
const result = (await createHandler({
|
|
139
|
+
body: { conversationType: "standard", title: "Setting up your check-in" },
|
|
140
|
+
})) as { id: string; created: boolean };
|
|
141
|
+
|
|
142
|
+
expect(result.created).toBe(true);
|
|
143
|
+
const row = readConversation(result.id);
|
|
144
|
+
expect(row?.title).toBe("Setting up your check-in");
|
|
145
|
+
// isAutoTitle = 0 keeps the async LLM titler from overwriting it.
|
|
146
|
+
expect(row?.isAutoTitle).toBe(0);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("blank title falls back to the replaceable 'New Conversation' placeholder", async () => {
|
|
150
|
+
const result = (await createHandler({
|
|
151
|
+
body: { conversationType: "standard", title: " " },
|
|
152
|
+
})) as { id: string; created: boolean };
|
|
153
|
+
|
|
154
|
+
expect(result.created).toBe(true);
|
|
155
|
+
const row = readConversation(result.id);
|
|
156
|
+
expect(row?.title).toBe("New Conversation");
|
|
157
|
+
// Default auto-title flag (1) leaves it replaceable by the auto-titler.
|
|
158
|
+
expect(row?.isAutoTitle).toBe(1);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("no title → 'New Conversation' placeholder", async () => {
|
|
162
|
+
const result = (await createHandler({
|
|
163
|
+
body: { conversationType: "standard" },
|
|
164
|
+
})) as { id: string; created: boolean };
|
|
165
|
+
|
|
166
|
+
expect(result.created).toBe(true);
|
|
167
|
+
const row = readConversation(result.id);
|
|
168
|
+
expect(row?.title).toBe("New Conversation");
|
|
169
|
+
expect(row?.isAutoTitle).toBe(1);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test("non-string title → BadRequestError (not a 500), no row created", () => {
|
|
173
|
+
// The shared route adapter doesn't runtime-validate the body, so the
|
|
174
|
+
// handler must reject a malformed title before `.trim()` throws.
|
|
175
|
+
expect(() =>
|
|
176
|
+
createHandler({ body: { conversationType: "standard", title: 123 } }),
|
|
177
|
+
).toThrow(/title must be a string/);
|
|
178
|
+
expect(getDb().select().from(conversations).all()).toHaveLength(0);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
115
182
|
describe("PUT /v1/conversations/:id/inference-profile", () => {
|
|
116
183
|
beforeEach(() => {
|
|
117
184
|
clearConversations();
|