@vellumai/assistant 0.10.4 → 0.10.5-dev.202607022329.d89bf2f
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 +94 -91
- package/Dockerfile +5 -16
- package/README.md +7 -10
- package/bun.lock +0 -4
- package/docs/architecture/security.md +20 -20
- package/docs/stt-provider-onboarding.md +4 -5
- package/docs/trusted-contact-access.md +7 -7
- package/eslint-rules/cli-no-daemon-internals.js +4 -0
- package/eslint.config.mjs +7 -1
- package/knip.json +0 -1
- package/node_modules/@vellumai/gateway-client/src/__tests__/contact-read-contracts.test.ts +36 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/invite-contract.test.ts +233 -0
- package/node_modules/@vellumai/gateway-client/src/__tests__/trust-verdict-contract.test.ts +40 -0
- package/node_modules/@vellumai/gateway-client/src/gateway-ipc-contracts.ts +20 -8
- package/node_modules/@vellumai/gateway-client/src/inbound-contract.ts +10 -0
- package/node_modules/@vellumai/gateway-client/src/index.ts +33 -0
- package/node_modules/@vellumai/gateway-client/src/invite-contract.ts +216 -0
- package/node_modules/@vellumai/gateway-client/src/outbound-contract.ts +91 -0
- package/node_modules/@vellumai/gateway-client/src/trust-verdict-contract.ts +39 -3
- package/node_modules/@vellumai/service-contracts/src/__tests__/ingress.test.ts +0 -8
- package/node_modules/@vellumai/service-contracts/src/__tests__/package-boundary.test.ts +1 -5
- package/node_modules/@vellumai/service-contracts/src/twilio-ingress.ts +3 -14
- package/openapi.yaml +1073 -225
- package/package.json +1 -4
- package/scripts/test.sh +35 -13
- package/src/__tests__/access-request-seed-content-blocks.test.ts +60 -4
- package/src/__tests__/acp-session.test.ts +4 -1
- package/src/__tests__/actor-trust-resolver-address-fallback.test.ts +0 -6
- package/src/__tests__/add-message-preassigned-id.test.ts +56 -0
- package/src/__tests__/agent-loop-set-system-prompt.test.ts +139 -0
- package/src/__tests__/app-conversation-ids-backfill.test.ts +3 -0
- package/src/__tests__/app-source-watcher.test.ts +11 -0
- package/src/__tests__/approval-interception-trust-gates.test.ts +148 -3
- package/src/__tests__/assistant-attachments.test.ts +62 -4
- package/src/__tests__/assistant-id-boundary-guard.test.ts +0 -1
- package/src/__tests__/attachments-store-heic-normalize.test.ts +230 -0
- package/src/__tests__/attachments-store.test.ts +3 -0
- package/src/__tests__/background-shell-bash.test.ts +34 -0
- package/src/__tests__/background-shell-host-bash.test.ts +12 -0
- package/src/__tests__/background-tool-registry.test.ts +97 -0
- package/src/__tests__/background-tool-routes.test.ts +72 -1
- package/src/__tests__/background-workers-disk-pressure.test.ts +2 -1
- package/src/__tests__/btw-routes.test.ts +57 -3
- package/src/__tests__/call-controller.test.ts +474 -84
- package/src/__tests__/call-domain.test.ts +48 -1
- package/src/__tests__/call-pointer-messages.test.ts +57 -19
- package/src/__tests__/call-pointer-no-hardcoded-copy.guard.test.ts +2 -6
- package/src/__tests__/call-routes-http.test.ts +15 -14
- package/src/__tests__/call-setup-flow-invite.test.ts +568 -0
- package/src/__tests__/call-setup-flow-midcall-trust.test.ts +231 -0
- package/src/__tests__/call-setup-flow-name-capture.test.ts +754 -0
- package/src/__tests__/call-setup-flow-verification.test.ts +925 -0
- package/src/__tests__/call-setup-flow.test.ts +311 -0
- package/src/__tests__/cancel-resolves-conversation-key.test.ts +0 -1
- package/src/__tests__/channel-guardian.test.ts +4 -7
- package/src/__tests__/channel-readiness-service.test.ts +0 -6
- package/src/__tests__/channel-readiness-slack-remote.test.ts +0 -4
- package/src/__tests__/channel-retry-sweep.test.ts +76 -64
- package/src/__tests__/channel-setup-panel-ack.test.ts +184 -0
- package/src/__tests__/clear-all-lexical.test.ts +90 -0
- package/src/__tests__/compactor-media-strip.test.ts +177 -0
- package/src/__tests__/config-loader-backfill.test.ts +5 -5
- package/src/__tests__/config-schema.test.ts +17 -0
- package/src/__tests__/contact-store-interaction-info.test.ts +27 -70
- package/src/__tests__/contacts-relay-reads.test.ts +188 -23
- package/src/__tests__/contacts-tools.test.ts +42 -1
- package/src/__tests__/contacts-write.test.ts +181 -0
- package/src/__tests__/context-search-conversations-source.test.ts +220 -81
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +1 -0
- package/src/__tests__/conversation-agent-loop.test.ts +39 -0
- package/src/__tests__/conversation-analysis-routes.test.ts +1 -1
- package/src/__tests__/conversation-app-control-instantiation.test.ts +2 -0
- package/src/__tests__/conversation-clear-safety.test.ts +0 -1
- package/src/__tests__/conversation-crud-enabled-plugins.test.ts +60 -0
- package/src/__tests__/conversation-delete-schedule-cleanup.test.ts +0 -1
- package/src/__tests__/conversation-disk-view.test.ts +1 -0
- package/src/__tests__/conversation-enabledplugins-route.test.ts +184 -0
- package/src/__tests__/conversation-error.test.ts +0 -18
- package/src/__tests__/conversation-fork-crud.test.ts +67 -0
- package/src/__tests__/conversation-history-web-search.test.ts +7 -137
- package/src/__tests__/conversation-initial-prompt.test.ts +110 -0
- package/src/__tests__/conversation-loop-db-lock-resilience.test.ts +191 -0
- package/src/__tests__/conversation-process-callsite.test.ts +37 -0
- package/src/__tests__/conversation-queue.test.ts +149 -0
- package/src/__tests__/conversation-routes-enabled-plugins.test.ts +392 -0
- package/src/__tests__/conversation-routes-guardian-reply.test.ts +84 -0
- package/src/__tests__/conversation-routes-hidden-queue.test.ts +407 -0
- package/src/__tests__/conversation-runtime-assembly.test.ts +36 -16
- package/src/__tests__/conversation-skill-tools.test.ts +73 -0
- package/src/__tests__/conversation-wipe.test.ts +20 -5
- package/src/__tests__/credential-prompt-route.test.ts +69 -0
- package/src/__tests__/credential-security-invariants.test.ts +1 -3
- package/src/__tests__/db-drop-messages-fts.test.ts +115 -0
- package/src/__tests__/deterministic-verification-control-plane.test.ts +1 -62
- package/src/__tests__/edit-propagation.test.ts +56 -2
- package/src/__tests__/empty-state-greeting-cache.test.ts +9 -0
- package/src/__tests__/gateway-only-enforcement.test.ts +15 -110
- package/src/__tests__/guardian-expiry-notifier.test.ts +1 -0
- package/src/__tests__/guardian-question-mode.test.ts +57 -0
- package/src/__tests__/guardian-verification-voice-binding.test.ts +1 -1
- package/src/__tests__/guardian-wait-controller.test.ts +619 -0
- package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +33 -2
- package/src/__tests__/heic-fixture.ts +55 -0
- package/src/__tests__/helpers/seed-contact-channel.ts +0 -2
- package/src/__tests__/http-conversation-lineage.test.ts +6 -1
- package/src/__tests__/image-conversion.test.ts +170 -0
- package/src/__tests__/inbound-invite-redemption.test.ts +72 -341
- package/src/__tests__/introduction-card-resolver.test.ts +354 -0
- package/src/__tests__/invite-redeemed-ipc.test.ts +97 -0
- package/src/__tests__/invite-routes-http.test.ts +246 -420
- package/src/__tests__/job-handler-registration-guard.test.ts +104 -0
- package/src/__tests__/lexical-index-dual-write.test.ts +426 -0
- package/src/__tests__/lifecycle-memory-v2-seed.test.ts +2 -2
- package/src/__tests__/list-messages-attachments.test.ts +159 -0
- package/src/__tests__/list-messages-background-tool-completion.test.ts +141 -0
- package/src/__tests__/list-messages-queued.test.ts +25 -0
- package/src/__tests__/managed-store.test.ts +129 -1
- package/src/__tests__/media-stream-audio-transcode.test.ts +113 -0
- package/src/__tests__/media-stream-output.test.ts +350 -19
- package/src/__tests__/media-stream-server-integration.test.ts +943 -169
- package/src/__tests__/media-stream-stt-session.test.ts +498 -1
- package/src/__tests__/memory-jobs-worker-lanes.test.ts +2 -2
- package/src/__tests__/model-intents.test.ts +1 -1
- package/src/__tests__/mtime-cache.test.ts +19 -0
- package/src/__tests__/non-member-access-request.test.ts +349 -3
- package/src/__tests__/notification-decision-fallback.test.ts +104 -8
- package/src/__tests__/notification-decision-strategy.test.ts +57 -8
- package/src/__tests__/onboarding-template-contract.test.ts +27 -43
- package/src/__tests__/openai-provider.test.ts +33 -0
- package/src/__tests__/openai-responses-provider.test.ts +40 -0
- package/src/__tests__/persistence-layering-guard.test.ts +29 -20
- package/src/__tests__/persona-resolver.test.ts +56 -2
- package/src/__tests__/personal-memory-auth-bypass.test.ts +62 -0
- package/src/__tests__/phone.test.ts +1 -15
- package/src/__tests__/plugin-bootstrap.test.ts +25 -196
- package/src/__tests__/plugin-disabled-state.test.ts +33 -0
- package/src/__tests__/plugin-effective-enabled-set.test.ts +227 -0
- package/src/__tests__/plugin-event-hub-facade.test.ts +323 -0
- package/src/__tests__/plugin-import-boundary-guard.test.ts +156 -42
- package/src/__tests__/plugin-injector-contribution.test.ts +4 -20
- package/src/__tests__/plugin-pipeline.test.ts +63 -1
- package/src/__tests__/plugin-route-contribution.test.ts +62 -115
- package/src/__tests__/plugin-tool-contribution.test.ts +0 -22
- package/src/__tests__/plugin-types.test.ts +0 -1
- package/src/__tests__/pointer-conversation-trust.test.ts +38 -6
- package/src/__tests__/pre-model-call-sanitize.test.ts +1 -1
- package/src/__tests__/prune-old-tool-invocations-job.test.ts +97 -0
- package/src/__tests__/public-ingress-urls.test.ts +0 -48
- package/src/__tests__/qdrant-collection-migration.test.ts +145 -2
- package/src/__tests__/reaction-intercept-member-verdict-warm.test.ts +0 -1
- package/src/__tests__/resolve-trust-class.test.ts +28 -10
- package/src/__tests__/scaffold-managed-skill-tool.test.ts +137 -0
- package/src/__tests__/schedule-retry.test.ts +38 -14
- package/src/__tests__/schedule-routes-workflow-validation.test.ts +3 -3
- package/src/__tests__/schedule-routes.test.ts +14 -6
- package/src/__tests__/schedule-store.test.ts +3 -1
- package/src/__tests__/scheduler-disk-pressure.test.ts +17 -6
- package/src/__tests__/scheduler-recurrence.test.ts +57 -107
- package/src/__tests__/scheduler-reuse-conversation.test.ts +51 -46
- package/src/__tests__/scheduler-wake.test.ts +13 -23
- package/src/__tests__/scheduler-worker-standdown.test.ts +220 -0
- package/src/__tests__/secret-routes-platform-proxy.test.ts +1 -1
- package/src/__tests__/shell-observability.test.ts +1 -0
- package/src/__tests__/skill-boundary-guard.test.ts +3 -4
- package/src/__tests__/skill-load-plugin-scope.test.ts +238 -0
- package/src/__tests__/skill-projection-feature-flag.test.ts +2 -0
- package/src/__tests__/skill-script-runner-host.test.ts +53 -0
- package/src/__tests__/skill-script-runner-sandbox.test.ts +5 -2
- package/src/__tests__/skill-tool-factory.test.ts +73 -1
- package/src/__tests__/slack-app-setup-skill-regression.test.ts +37 -14
- package/src/__tests__/slack-inbound-verification.test.ts +36 -0
- package/src/__tests__/slack-notification-approval-card.test.ts +89 -2
- package/src/__tests__/slack-reaction-canonical-approval.test.ts +51 -1
- package/src/__tests__/stt-hints.test.ts +2 -256
- package/src/__tests__/subagent-allowlist-validation.test.ts +47 -0
- package/src/__tests__/subagent-call-site-routing.test.ts +72 -0
- package/src/__tests__/subagent-fork-notifications.test.ts +14 -2
- package/src/__tests__/subagent-persistence.test.ts +122 -0
- package/src/__tests__/subagent-spawn-and-await.test.ts +1 -0
- package/src/__tests__/subagent-terminal-message.test.ts +99 -0
- package/src/__tests__/subagent-tool-gate-mode.test.ts +78 -1
- package/src/__tests__/system-prompt.test.ts +17 -118
- package/src/__tests__/task-scheduler.test.ts +68 -89
- package/src/__tests__/telephony-credential-preflight.test.ts +312 -0
- package/src/__tests__/telephony-tts-guard.test.ts +538 -0
- package/src/__tests__/title-generate-hook.test.ts +16 -0
- package/src/__tests__/tool-approval-handler.test.ts +87 -1
- package/src/__tests__/tool-approval-seed-content-blocks.test.ts +45 -20
- package/src/__tests__/tool-grant-request-escalation.test.ts +39 -0
- package/src/__tests__/trust-context-guards.test.ts +21 -10
- package/src/__tests__/trusted-contact-multichannel.test.ts +4 -0
- package/src/__tests__/twilio-provider.test.ts +17 -17
- package/src/__tests__/twilio-routes-twiml.test.ts +6 -543
- package/src/__tests__/twilio-routes.test.ts +257 -387
- package/src/__tests__/twilio-validation.test.ts +1 -1
- package/src/__tests__/unified-turn-context-client-os.test.ts +45 -0
- package/src/__tests__/usage-cache-backfill-migration.test.ts +5 -0
- package/src/__tests__/voice-approval-resolver-relay.test.ts +150 -0
- package/src/__tests__/voice-ingress-preflight.test.ts +61 -0
- package/src/__tests__/voice-quality.test.ts +2 -2
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +1 -7
- package/src/__tests__/voice-session-bridge-processing-wait.test.ts +27 -0
- package/src/__tests__/voice-session-bridge.test.ts +1 -10
- package/src/__tests__/workspace-git-service.test.ts +1 -1
- package/src/__tests__/workspace-migration-013-repair-conversation-disk-view.test.ts +1 -0
- package/src/__tests__/workspace-migration-118-seed-now-md.test.ts +120 -0
- package/src/__tests__/workspace-migration-120-revise-onboarding-threads.test.ts +175 -0
- package/src/__tests__/workspace-migration-121-seed-default-user-guardrails.test.ts +118 -0
- package/src/__tests__/workspace-migration-122-relocate-default-user-boundary.test.ts +119 -0
- package/src/__tests__/workspace-migration-123-swap-quality-profile-to-fable.test.ts +191 -0
- package/src/__tests__/workspace-migration-backfill-installation-id.test.ts +235 -241
- package/src/acp/__tests__/prepare-agent-env.test.ts +0 -97
- package/src/acp/__tests__/session-manager-persistence.test.ts +2 -0
- package/src/acp/__tests__/session-manager-resume.test.ts +8 -0
- package/src/acp/__tests__/session-manager-usage.test.ts +6 -0
- package/src/acp/__tests__/session-manager.test.ts +6 -0
- package/src/acp/agent-process.test.ts +116 -0
- package/src/acp/agent-process.ts +71 -0
- package/src/acp/auto-install.ts +12 -8
- package/src/acp/failure-error.test.ts +109 -0
- package/src/acp/failure-error.ts +111 -0
- package/src/acp/prepare-agent-env.ts +0 -12
- package/src/acp/resolve-agent.test.ts +6 -45
- package/src/acp/resolve-agent.ts +2 -4
- package/src/acp/session-manager.test.ts +312 -0
- package/src/acp/session-manager.ts +102 -46
- package/src/agent/ax-tree-compaction.test.ts +4 -1
- package/src/agent/image-optimize.ts +17 -127
- package/src/agent/loop.ts +45 -192
- package/src/api/events/background-tool-completed.test.ts +51 -0
- package/src/api/events/background-tool-completed.ts +29 -0
- package/src/api/events/background-tool-started.test.ts +36 -0
- package/src/api/events/background-tool-started.ts +28 -0
- package/src/api/events/conversation-error.ts +0 -1
- package/src/api/events/open-panel.ts +33 -0
- package/src/api/events/subagent-status-changed.ts +4 -1
- package/src/api/index.ts +19 -0
- package/src/api/responses/conversation-message.ts +34 -0
- package/src/approvals/guardian-decision-primitive.ts +74 -24
- package/src/approvals/guardian-request-resolvers.ts +450 -122
- package/src/apps/app-store.ts +1 -0
- package/src/apps/shared-app-links-store.ts +1 -0
- package/src/avatar/identity-avatar.ts +3 -7
- package/src/background-wake/wake-intent-hooks.test.ts +1 -1
- package/src/calls/__tests__/fish-audio-client.test.ts +73 -0
- package/src/calls/__tests__/gateway-invite-reader.test.ts +170 -0
- package/src/calls/__tests__/relay-setup-router.test.ts +126 -102
- package/src/calls/call-controller.ts +134 -48
- package/src/calls/call-domain.ts +18 -42
- package/src/calls/call-pointer-messages.ts +51 -67
- package/src/calls/call-setup-flow-types.ts +76 -0
- package/src/calls/call-setup-flow.ts +1743 -0
- package/src/calls/call-speech-output.ts +87 -23
- package/src/calls/call-store.ts +4 -0
- package/src/calls/call-transport.ts +22 -36
- package/src/calls/fish-audio-client.ts +3 -0
- package/src/calls/gateway-invite-reader.ts +98 -0
- package/src/calls/guardian-wait-controller.ts +451 -0
- package/src/calls/media-stream-audio-transcode.ts +82 -2
- package/src/calls/media-stream-output.ts +142 -36
- package/src/calls/media-stream-server.ts +297 -178
- package/src/calls/media-stream-stt-session.ts +393 -50
- package/src/calls/media-turn-detector.ts +4 -6
- package/src/calls/relay-access-wait.ts +3 -4
- package/src/calls/relay-setup-router.ts +22 -43
- package/src/calls/relay-verification.ts +17 -24
- package/src/calls/resolve-call-tts-provider.ts +96 -29
- package/src/calls/stt-hints.ts +24 -87
- package/src/calls/telephony-credential-preflight.ts +159 -0
- package/src/calls/telephony-tts-capability.ts +183 -0
- package/src/calls/tts-call-strategy.ts +18 -20
- package/src/calls/twilio-provider.ts +3 -2
- package/src/calls/twilio-routes.ts +47 -351
- package/src/calls/types.ts +5 -3
- package/src/calls/voice-ingress-preflight.ts +9 -0
- package/src/calls/voice-quality.ts +13 -18
- package/src/calls/voice-session-bridge.ts +25 -35
- package/src/channels/__tests__/types.test.ts +28 -0
- package/src/channels/channel-verification-sessions.ts +7 -2
- package/src/channels/config.ts +0 -42
- package/src/channels/slack-thread-store.ts +12 -0
- package/src/channels/types.ts +23 -0
- package/src/cli/commands/__tests__/conversations-slack.test.ts +1 -1
- package/src/cli/commands/__tests__/schedules.test.ts +83 -34
- package/src/cli/commands/__tests__/status.test.ts +42 -2
- package/src/cli/commands/contacts.ts +2 -2
- package/src/cli/commands/credentials.ts +17 -0
- package/src/cli/commands/monitoring.ts +191 -0
- package/src/cli/commands/schedules-worker.ts +175 -0
- package/src/cli/commands/schedules.ts +169 -43
- package/src/cli/commands/status.ts +12 -1
- package/src/cli/commands/tools.ts +5 -1
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +1 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +29 -1
- package/src/cli/lib/__tests__/toggle-plugin.test.ts +7 -0
- package/src/cli/lib/search-plugins.ts +6 -0
- package/src/cli/lib/toggle-plugin.ts +21 -2
- package/src/cli/program.ts +3 -1
- package/src/config/__tests__/deployment-context-defaults.test.ts +23 -0
- package/src/config/acp-defaults.test.ts +0 -10
- package/src/config/acp-defaults.ts +0 -6
- package/src/config/bundled-skills/acp/SKILL.md +13 -45
- package/src/config/bundled-skills/acp/TOOLS.json +3 -3
- package/src/config/bundled-skills/app-builder/SKILL.md +3 -3
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +9 -9
- package/src/config/bundled-skills/contacts/tools/contact-merge.ts +1 -1
- package/src/config/bundled-skills/contacts/tools/contact-search.ts +1 -1
- package/src/config/bundled-skills/phone-calls/SKILL.md +1 -1
- package/src/config/bundled-skills/phone-calls/references/CONFIG.md +9 -9
- package/src/config/bundled-skills/phone-calls/references/TROUBLESHOOTING.md +10 -7
- package/src/config/bundled-skills/skill-management/TOOLS.json +10 -0
- package/src/config/call-site-defaults.ts +0 -2
- package/src/config/feature-flag-registry.json +16 -8
- package/src/config/loader.ts +11 -0
- package/src/config/schema.ts +9 -1
- package/src/config/schemas/__tests__/memory-v2.test.ts +2 -2
- package/src/config/schemas/__tests__/memory-v3.test.ts +64 -0
- package/src/config/schemas/call-site-catalog.ts +0 -12
- package/src/config/schemas/calls.ts +8 -0
- package/src/config/schemas/elevenlabs.ts +1 -1
- package/src/config/schemas/llm.ts +0 -2
- package/src/config/schemas/memory-v2.ts +1 -1
- package/src/config/schemas/memory-v3.ts +82 -0
- package/src/config/schemas/monitoring.ts +61 -0
- package/src/config/schemas/schedules.ts +35 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills-plugin-filter.test.ts +96 -0
- package/src/config/skills.ts +26 -0
- package/src/contacts/__tests__/member-write-relay.test.ts +156 -4
- package/src/contacts/canonical-guardian-store.ts +5 -0
- package/src/contacts/contact-store.ts +81 -35
- package/src/contacts/contacts-write.ts +50 -25
- package/src/contacts/member-write-relay.ts +115 -31
- package/src/contacts/types.ts +0 -8
- package/src/context/compactor.ts +29 -15
- package/src/context/outbound-sanitize.ts +202 -0
- package/src/daemon/__tests__/abort-null-controller.test.ts +167 -0
- package/src/daemon/__tests__/conversation-tool-setup-plugin-scope.test.ts +122 -0
- package/src/daemon/__tests__/embedding-reconcile.test.ts +99 -16
- package/src/daemon/__tests__/wake-conversation-ops-completion.test.ts +107 -0
- package/src/daemon/abort-watchdog.ts +7 -0
- package/src/daemon/app-source-watcher.ts +9 -0
- package/src/daemon/assistant-attachments.ts +42 -0
- package/src/daemon/conversation-agent-loop-handlers.ts +256 -147
- package/src/daemon/conversation-agent-loop.ts +61 -68
- package/src/daemon/conversation-error.ts +1 -15
- package/src/daemon/conversation-history.ts +32 -236
- package/src/daemon/conversation-initial-prompt.ts +77 -0
- package/src/daemon/conversation-lifecycle.ts +25 -1
- package/src/daemon/conversation-messaging.ts +2 -2
- package/src/daemon/conversation-plugin-scope.ts +38 -0
- package/src/daemon/conversation-process.ts +50 -14
- package/src/daemon/conversation-runtime-assembly.ts +36 -6
- package/src/daemon/conversation-skill-tools.ts +19 -3
- package/src/daemon/conversation-store.ts +3 -3
- package/src/daemon/conversation-surfaces.ts +171 -0
- package/src/daemon/conversation-tool-setup.test.ts +95 -0
- package/src/daemon/conversation-tool-setup.ts +116 -1
- package/src/daemon/conversation-turn-finalize.ts +211 -0
- package/src/daemon/conversation.ts +92 -1
- package/src/daemon/disk-pressure-policy.ts +2 -1
- package/src/daemon/event-loop-watchdog.ts +22 -6
- package/src/daemon/external-plugins-bootstrap.ts +47 -134
- package/src/daemon/handlers/__tests__/config-a2a-accept.test.ts +1 -1
- package/src/daemon/handlers/__tests__/config-a2a-complete.test.ts +26 -14
- package/src/daemon/handlers/__tests__/config-a2a-invite.test.ts +27 -14
- package/src/daemon/handlers/__tests__/config-channels.test.ts +0 -5
- package/src/daemon/handlers/config-a2a.ts +7 -14
- package/src/daemon/handlers/config-channels.ts +2 -10
- package/src/daemon/handlers/conversation-history.ts +3 -1
- package/src/daemon/handlers/conversations.ts +0 -52
- package/src/daemon/handlers/shared.ts +4 -24
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-cu-proxy.ts +1 -1
- package/src/daemon/lifecycle.ts +59 -472
- package/src/daemon/message-protocol.ts +3 -3
- package/src/daemon/message-provenance.ts +12 -14
- package/src/daemon/message-types/background-tools.ts +28 -0
- package/src/daemon/message-types/contacts.ts +2 -10
- package/src/daemon/message-types/conversations.ts +10 -0
- package/src/daemon/message-types/integrations.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +1 -0
- package/src/daemon/message-types/sync.ts +1 -0
- package/src/daemon/pointer-conversation-trust.ts +23 -9
- package/src/daemon/pointer-turn-runner.ts +174 -0
- package/src/daemon/providers-setup.ts +16 -0
- package/src/daemon/shutdown-handlers.ts +139 -47
- package/src/daemon/skill-memory-refresh.ts +2 -2
- package/src/daemon/sqlite-corruption-watchdog.test.ts +217 -0
- package/src/daemon/sqlite-corruption-watchdog.ts +155 -0
- package/src/daemon/tool-setup-types.ts +8 -0
- package/src/daemon/trust-context.ts +21 -6
- package/src/daemon/turn-latency-tracker.test.ts +93 -0
- package/src/daemon/turn-latency-tracker.ts +38 -0
- package/src/daemon/wake-conversation-ops.ts +10 -8
- package/src/documents/document-comments-store.test.ts +7 -1
- package/src/documents/document-comments-store.ts +8 -0
- package/src/documents/document-store.ts +15 -0
- package/src/export/__tests__/transcript-formatter.test.ts +11 -0
- package/src/export/transcript-formatter.ts +49 -67
- package/src/home/__tests__/feed-writer.test.ts +247 -1
- package/src/home/conversation-starter-checkpoints.ts +1 -0
- package/src/home/feed-writer.ts +61 -0
- package/src/home/job-handlers/conversation-starters.ts +1 -0
- package/src/hooks/hook-loader.ts +12 -0
- package/src/hooks/registry.ts +32 -4
- package/src/inbound/public-ingress-urls.ts +0 -17
- package/src/ipc/__tests__/contacts-info-ipc.test.ts +285 -0
- package/src/ipc/assistant-server.ts +28 -7
- package/src/ipc/routes/__tests__/contacts-mirror-apply-atomicity.test.ts +62 -0
- package/src/ipc/routes/__tests__/contacts-mirror-apply.test.ts +272 -0
- package/src/ipc/routes/__tests__/contacts-mirror-ipc-routes.test.ts +322 -0
- package/src/ipc/routes/__tests__/invite-ipc-routes.test.ts +60 -4
- package/src/ipc/routes/contacts-info-ipc-routes.ts +239 -0
- package/src/ipc/routes/contacts-mirror-ipc-routes.ts +202 -0
- package/src/ipc/routes/db-proxy.ts +5 -2
- package/src/ipc/routes/invite-ipc-routes.ts +53 -39
- package/src/jobs/worker.ts +9 -2
- package/src/live-voice/__tests__/live-voice-archive.test.ts +10 -1
- package/src/live-voice/live-voice-archive.ts +5 -0
- package/src/messaging/providers/__tests__/transport-dispatch.test.ts +22 -6
- package/src/messaging/providers/channel-transport.ts +6 -0
- package/src/messaging/providers/index.ts +3 -0
- package/src/messaging/providers/slack/api.test.ts +49 -1
- package/src/messaging/providers/slack/api.ts +110 -0
- package/src/messaging/providers/slack/send.test.ts +85 -0
- package/src/messaging/providers/slack/send.ts +100 -28
- package/src/messaging/providers/slack/transport.ts +7 -13
- package/src/messaging/providers/whatsapp/send.ts +29 -9
- package/src/monitoring/__tests__/control.test.ts +235 -0
- package/src/monitoring/__tests__/sample-ring-buffer.test.ts +96 -0
- package/src/monitoring/control.ts +105 -0
- package/src/monitoring/resource-sampler.ts +258 -0
- package/src/monitoring/sample-ring-buffer.ts +108 -0
- package/src/monitoring/worker.ts +94 -0
- package/src/notifications/README.md +1 -1
- package/src/notifications/access-request-copy.ts +94 -23
- package/src/notifications/adapters/slack.ts +89 -21
- package/src/notifications/approval-card-builder.ts +33 -18
- package/src/notifications/approval-card-data.ts +48 -15
- package/src/notifications/broadcaster.ts +25 -16
- package/src/notifications/decision-engine.ts +131 -32
- package/src/notifications/guardian-question-mode.ts +58 -10
- package/src/permissions/approval-policy.ts +8 -1
- package/src/permissions/checker.ts +2 -0
- package/src/permissions/gateway-threshold-reader.ts +7 -6
- package/src/permissions/ipc-risk-types.ts +1 -0
- package/src/permissions/secret-prompter.ts +11 -3
- package/src/permissions/types.ts +2 -2
- package/src/persistence/__tests__/conversation-queries-search.test.ts +397 -0
- package/src/persistence/__tests__/conversation-search-lexical.test.ts +103 -0
- package/src/persistence/__tests__/jobs-worker-memory-disabled.test.ts +95 -0
- package/src/persistence/__tests__/slow-query-log.test.ts +266 -0
- package/src/persistence/__tests__/slow-sync-log.test.ts +155 -0
- package/src/persistence/a2a-invite-store.ts +205 -0
- package/src/persistence/attachments-store.ts +94 -10
- package/src/persistence/checkpoints.ts +45 -0
- package/src/persistence/conversation-crud.ts +453 -260
- package/src/persistence/conversation-display-order-migration.ts +8 -2
- package/src/persistence/conversation-group-migration.test.ts +8 -0
- package/src/persistence/conversation-group-migration.ts +9 -0
- package/src/persistence/conversation-queries.ts +244 -125
- package/src/persistence/conversation-row-batch-delete.ts +9 -5
- package/src/persistence/conversation-search-lexical.ts +49 -0
- package/src/persistence/db-async-query.ts +42 -0
- package/src/persistence/db-connection.ts +13 -0
- package/src/persistence/delivery-channels.ts +0 -82
- package/src/persistence/delivery-crud.ts +27 -6
- package/src/persistence/embeddings/__tests__/embedding-identity.test.ts +18 -5
- package/src/persistence/embeddings/__tests__/messages-lexical-index.test.ts +334 -0
- package/src/persistence/embeddings/embedding-identity.ts +17 -5
- package/src/persistence/embeddings/embedding-runtime-manager.ts +31 -0
- package/src/persistence/embeddings/messages-lexical-index.ts +396 -0
- package/src/persistence/embeddings/qdrant-client.ts +81 -5
- package/src/persistence/group-crud.ts +13 -1
- package/src/persistence/job-handlers/__tests__/message-lexical-backfill.test.ts +506 -0
- package/src/persistence/job-handlers/__tests__/message-lexical-enqueue.test.ts +164 -0
- package/src/persistence/job-handlers/__tests__/message-lexical.test.ts +259 -0
- package/src/persistence/job-handlers/cleanup.ts +57 -9
- package/src/persistence/job-handlers/message-lexical-backfill.ts +187 -0
- package/src/persistence/job-handlers/message-lexical.ts +251 -0
- package/src/persistence/jobs-store.ts +102 -8
- package/src/persistence/jobs-worker.ts +68 -28
- package/src/persistence/llm-request-log-store.ts +35 -19
- package/src/persistence/llm-usage-store.ts +11 -0
- package/src/persistence/memory-lifecycle-hooks.test.ts +65 -0
- package/src/persistence/memory-lifecycle-hooks.ts +55 -1
- package/src/persistence/migrations/028-call-session-mode.ts +1 -1
- package/src/persistence/migrations/116-messages-fts.ts +8 -1
- package/src/persistence/migrations/311-create-subagents-table.ts +50 -0
- package/src/persistence/migrations/312-drop-inbox-conversation-state-table.ts +15 -0
- package/src/persistence/migrations/313-drop-messages-fts.ts +17 -0
- package/src/persistence/migrations/314-add-conversation-enabled-plugins.ts +25 -0
- package/src/persistence/migrations/315-create-a2a-invites.ts +58 -0
- package/src/persistence/migrations/316-drop-contact-channels-invite-id.ts +28 -0
- package/src/persistence/migrations/317-canonical-guardian-requester-signals.ts +24 -0
- package/src/persistence/migrations/318-drop-contact-channel-telemetry.ts +32 -0
- package/src/persistence/migrations/__tests__/315-create-a2a-invites.test.ts +161 -0
- package/src/persistence/migrations/__tests__/316-drop-contact-channels-invite-id.test.ts +156 -0
- package/src/persistence/migrations/__tests__/318-drop-contact-channel-telemetry.test.ts +134 -0
- package/src/persistence/migrations/__tests__/migration-prefix-guard.test.ts +99 -0
- package/src/persistence/raw-query.ts +50 -11
- package/src/persistence/schema/a2a.ts +14 -0
- package/src/persistence/schema/contacts.ts +0 -62
- package/src/persistence/schema/conversation-groups.ts +12 -0
- package/src/persistence/schema/conversations.ts +2 -0
- package/src/persistence/schema/documents.ts +65 -0
- package/src/persistence/schema/guardian.ts +4 -0
- package/src/persistence/schema/index.ts +4 -0
- package/src/persistence/schema/memory-injection.ts +62 -0
- package/src/persistence/schema/workflows.ts +55 -0
- package/src/persistence/slow-query-log.ts +437 -0
- package/src/persistence/slow-sync-log.ts +204 -0
- package/src/persistence/steps.ts +16 -0
- package/src/persistence/subagent-store.ts +125 -0
- package/src/persistence/worker-control.ts +45 -238
- package/src/plugin-api/event-hub-facade.ts +172 -0
- package/src/plugin-api/index.ts +9 -1
- package/src/plugin-api/types.ts +40 -9
- package/src/plugins/defaults/default-plugin-names.ts +60 -0
- package/src/plugins/defaults/index.ts +19 -29
- package/src/plugins/defaults/memory/__tests__/conversation-queries.test.ts +46 -67
- package/src/plugins/defaults/memory/__tests__/db-async-query.test.ts +36 -1
- package/src/plugins/defaults/memory/__tests__/find-most-recent-retrospective-for.test.ts +2 -4
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-graph-trigger-embed.test.ts +2 -2
- package/src/plugins/defaults/memory/__tests__/jobs-worker-v2-schedule.test.ts +9 -0
- package/src/plugins/defaults/memory/__tests__/memory-retrospective-job.test.ts +7 -4
- package/src/plugins/defaults/memory/config.ts +11 -0
- package/src/plugins/defaults/memory/context-search/agent-runner.ts +1 -1
- package/src/plugins/defaults/memory/context-search/sources/conversations.ts +124 -113
- package/src/plugins/defaults/memory/embeddings.ts +77 -0
- package/src/plugins/defaults/memory/find-most-recent-retrospective-for.ts +66 -0
- package/src/plugins/defaults/memory/frontmatter.ts +50 -0
- package/src/plugins/defaults/memory/graph/bootstrap.test.ts +36 -10
- package/src/plugins/defaults/memory/graph/bootstrap.ts +6 -5
- package/src/plugins/defaults/memory/graph/consolidation.ts +3 -5
- package/src/plugins/defaults/memory/graph/extraction.ts +3 -6
- package/src/plugins/defaults/memory/graph/graph-search.ts +12 -23
- package/src/plugins/defaults/memory/graph/narrative.ts +3 -5
- package/src/plugins/defaults/memory/graph/pattern-scan.ts +3 -5
- package/src/plugins/defaults/memory/graph/retriever.test.ts +1 -6
- package/src/plugins/defaults/memory/graph/retriever.ts +5 -10
- package/src/plugins/defaults/memory/graph/tools.ts +1 -1
- package/src/plugins/defaults/memory/hooks/init.ts +31 -5
- package/src/plugins/defaults/memory/indexer.ts +2 -3
- package/src/plugins/defaults/memory/injectors.ts +2 -2
- package/src/plugins/defaults/memory/job-handler-registration.ts +96 -0
- package/src/plugins/defaults/memory/job-handlers/backfill.ts +4 -26
- package/src/plugins/defaults/memory/job-handlers/embedding.test.ts +6 -19
- package/src/plugins/defaults/memory/job-handlers/embedding.ts +9 -22
- package/src/plugins/defaults/memory/job-handlers/index-maintenance.ts +2 -3
- package/src/plugins/defaults/memory/job-handlers.ts +13 -12
- package/src/plugins/defaults/memory/jobs/embed-concept-page.ts +1 -1
- package/src/plugins/defaults/memory/llm-helpers.ts +76 -0
- package/src/plugins/defaults/memory/memory-retrospective-job.ts +8 -5
- package/src/plugins/defaults/memory/memory-retrospective-startup-cleanup.ts +2 -2
- package/src/plugins/defaults/memory/memory-v2-concept-frequency.ts +2 -0
- package/src/plugins/defaults/memory/persistence-hooks.ts +46 -1
- package/src/plugins/defaults/memory/pkb/pkb-index.ts +1 -5
- package/src/plugins/defaults/memory/pkb/pkb-search.ts +2 -2
- package/src/plugins/defaults/memory/routes/__tests__/memory-v2-simulate-route.test.ts +4 -6
- package/src/plugins/defaults/memory/routes/memory-item-routes.ts +1 -1
- package/src/plugins/defaults/memory/search/semantic.ts +2 -2
- package/src/plugins/defaults/memory/startup.ts +244 -0
- package/src/plugins/defaults/memory/task-memory-cleanup.ts +8 -0
- package/src/{daemon → plugins/defaults/memory/v2}/__tests__/memory-v2-startup.test.ts +6 -6
- package/src/plugins/defaults/memory/v2/__tests__/migration.test.ts +2 -13
- package/src/plugins/defaults/memory/v2/__tests__/router.test.ts +4 -5
- package/src/plugins/defaults/memory/v2/__tests__/sweep-job.test.ts +1 -8
- package/src/plugins/defaults/memory/v2/activation.ts +2 -4
- package/src/plugins/defaults/memory/v2/cli-command-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/frontmatter-sweep.ts +1 -1
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.test.ts +8 -8
- package/src/{daemon → plugins/defaults/memory/v2}/memory-v2-startup.ts +20 -22
- package/src/plugins/defaults/memory/v2/migration.ts +2 -5
- package/src/plugins/defaults/memory/v2/page-store.ts +1 -1
- package/src/plugins/defaults/memory/v2/qdrant.ts +2 -3
- package/src/plugins/defaults/memory/v2/router.ts +5 -5
- package/src/plugins/defaults/memory/v2/sim.ts +2 -4
- package/src/plugins/defaults/memory/v2/skill-store.ts +2 -4
- package/src/plugins/defaults/memory/v2/sweep-job.ts +6 -6
- package/src/plugins/defaults/memory/v3/__tests__/carry-integration.test.ts +11 -9
- package/src/plugins/defaults/memory/v3/__tests__/dense.test.ts +107 -2
- package/src/plugins/defaults/memory/v3/__tests__/gate-flag.test.ts +69 -0
- package/src/plugins/defaults/memory/v3/__tests__/gate.test.ts +181 -0
- package/src/plugins/defaults/memory/v3/__tests__/live-integration.test.ts +7 -3
- package/src/plugins/defaults/memory/v3/__tests__/orchestrate.test.ts +345 -8
- package/src/plugins/defaults/memory/v3/__tests__/pool-select.test.ts +1 -4
- package/src/plugins/defaults/memory/v3/__tests__/section-needle.test.ts +64 -0
- package/src/plugins/defaults/memory/v3/__tests__/shadow-integration.test.ts +18 -13
- package/src/plugins/defaults/memory/v3/__tests__/shadow-plugin.test.ts +62 -1
- package/src/plugins/defaults/memory/v3/card.ts +1 -4
- package/src/plugins/defaults/memory/v3/dense.ts +60 -25
- package/src/plugins/defaults/memory/v3/edge.ts +1 -1
- package/src/plugins/defaults/memory/v3/gate-flag.ts +20 -0
- package/src/plugins/defaults/memory/v3/gate.ts +158 -0
- package/src/plugins/defaults/memory/v3/maintain-job.ts +2 -4
- package/src/plugins/defaults/memory/v3/orchestrate.ts +186 -25
- package/src/plugins/defaults/memory/v3/pool-select.test.ts +7 -9
- package/src/plugins/defaults/memory/v3/pool-select.ts +6 -6
- package/src/plugins/defaults/memory/v3/prune.ts +2 -2
- package/src/plugins/defaults/memory/v3/section-dense-store.ts +8 -11
- package/src/plugins/defaults/memory/v3/section-needle.ts +27 -7
- package/src/plugins/defaults/memory/v3/shadow-plugin.ts +10 -0
- package/src/plugins/defaults/memory/v3-eval/eval-packets.ts +1 -4
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +5 -0
- package/src/plugins/defaults/turn-context/injectors.ts +1 -0
- package/src/plugins/defaults/turn-context/unified-turn-context.ts +12 -0
- package/src/plugins/injector-registry.ts +13 -2
- package/src/plugins/mtime-cache.ts +36 -47
- package/src/plugins/pipeline.ts +15 -1
- package/src/plugins/types.ts +14 -23
- package/src/prompts/__tests__/system-prompt.test.ts +170 -32
- package/src/prompts/persona-resolver.ts +13 -9
- package/src/prompts/system-prompt.ts +30 -9
- package/src/prompts/templates/BOOTSTRAP.md +16 -119
- package/src/prompts/templates/SOUL.md +43 -13
- package/src/prompts/templates/system-sections.ts +32 -27
- package/src/prompts/templates/users/default.md +19 -0
- package/src/providers/__tests__/placeholder-sentinels.test.ts +56 -0
- package/src/providers/inference/__tests__/base-url-route-validation.test.ts +96 -1
- package/src/providers/model-intents.ts +2 -2
- package/src/providers/openai/chat-completions-provider.ts +14 -1
- package/src/providers/openai/responses-provider.ts +18 -0
- package/src/providers/placeholder-sentinels.ts +18 -8
- package/src/providers/retry.ts +1 -0
- package/src/providers/speech-to-text/__tests__/provider-catalog.test.ts +0 -64
- package/src/providers/speech-to-text/__tests__/resolve.test.ts +92 -79
- package/src/providers/speech-to-text/deepgram-realtime.test.ts +98 -0
- package/src/providers/speech-to-text/deepgram-realtime.ts +62 -3
- package/src/providers/speech-to-text/provider-catalog.ts +0 -89
- package/src/providers/speech-to-text/resolve.ts +55 -0
- package/src/providers/tool-progress-events.test.ts +50 -0
- package/src/providers/tool-progress-events.ts +99 -0
- package/src/providers/types.ts +1 -1
- package/src/providers/vellum-model-routing.test.ts +51 -0
- package/src/providers/vellum-model-routing.ts +84 -0
- package/src/runtime/AGENTS.md +5 -4
- package/src/runtime/__tests__/agent-wake.test.ts +158 -1
- package/src/runtime/__tests__/channel-verification-service.test.ts +2 -2
- package/src/runtime/__tests__/trust-verdict-consumer.test.ts +37 -8
- package/src/runtime/access-request-helper.ts +154 -3
- package/src/runtime/actor-trust-resolver.ts +7 -21
- package/src/runtime/agent-wake.ts +41 -1
- package/src/runtime/assistant-event.ts +86 -12
- package/src/runtime/auth/__tests__/route-policy.test.ts +31 -0
- package/src/runtime/channel-approval-types.ts +52 -2
- package/src/runtime/channel-approvals.ts +23 -8
- package/src/runtime/channel-invite-transport.ts +2 -2
- package/src/runtime/channel-invite-transports/voice.ts +1 -1
- package/src/runtime/channel-readiness-service.ts +3 -5
- package/src/runtime/channel-retry-sweep.ts +18 -24
- package/src/runtime/channel-verification-service.ts +9 -11
- package/src/runtime/finalize-event-delivery.ts +30 -16
- package/src/runtime/guardian-action-service.ts +10 -11
- package/src/runtime/guardian-reply-router.ts +122 -21
- package/src/runtime/http-server.ts +44 -101
- package/src/runtime/introduction-policy.test.ts +214 -0
- package/src/runtime/introduction-policy.ts +284 -0
- package/src/runtime/invite-service.ts +104 -361
- package/src/runtime/local-actor-identity.test.ts +38 -0
- package/src/runtime/local-actor-identity.ts +14 -0
- package/src/runtime/middleware/__tests__/rate-limiter.test.ts +22 -0
- package/src/runtime/middleware/rate-limiter.ts +30 -0
- package/src/runtime/middleware/twilio-validation.ts +5 -7
- package/src/runtime/migrations/__tests__/gcs-signed-url.test.ts +28 -0
- package/src/runtime/migrations/origin-mode.ts +6 -6
- package/src/runtime/pre-first-message-gate.ts +1 -0
- package/src/runtime/routes/__tests__/channel-verification-revoke.test.ts +6 -35
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +24 -3
- package/src/runtime/routes/__tests__/contact-routes.test.ts +80 -15
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +7 -1
- package/src/runtime/routes/__tests__/global-search-routes.test.ts +0 -3
- package/src/runtime/routes/__tests__/home-feed-routes.test.ts +142 -1
- package/src/runtime/routes/__tests__/invite-relay-routes.test.ts +119 -30
- package/src/runtime/routes/__tests__/migration-import-allowed-hosts-env.test.ts +70 -0
- package/src/runtime/routes/__tests__/monitoring-routes.test.ts +194 -0
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +755 -29
- package/src/runtime/routes/__tests__/retrospective-routes.test.ts +4 -0
- package/src/runtime/routes/__tests__/schedule-routes-create.test.ts +70 -0
- package/src/runtime/routes/__tests__/schedule-worker-routes.test.ts +161 -0
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +1 -1
- package/src/runtime/routes/acp-routes.ts +15 -3
- package/src/runtime/routes/app-management-routes.ts +4 -7
- package/src/runtime/routes/approval-routes.ts +4 -0
- package/src/runtime/routes/attachment-routes.ts +54 -3
- package/src/runtime/routes/avatar-routes.ts +0 -4
- package/src/runtime/routes/background-tool-routes.ts +34 -5
- package/src/runtime/routes/btw-routes.ts +32 -4
- package/src/runtime/routes/channel-route-shared.ts +18 -14
- package/src/runtime/routes/channel-verification-routes.ts +0 -3
- package/src/runtime/routes/contact-routes.ts +298 -117
- package/src/runtime/routes/conversation-list-routes.ts +6 -0
- package/src/runtime/routes/conversation-management-routes.ts +74 -37
- package/src/runtime/routes/conversation-query-routes.ts +5 -2
- package/src/runtime/routes/conversation-routes.ts +222 -82
- package/src/runtime/routes/conversations-import-routes.ts +8 -1
- package/src/runtime/routes/credential-prompt-routes.ts +20 -5
- package/src/runtime/routes/debug-routes.ts +1 -0
- package/src/runtime/routes/documents-routes.ts +5 -2
- package/src/runtime/routes/empty-state-greeting-cache.ts +37 -10
- package/src/runtime/routes/global-search-routes.ts +2 -1
- package/src/runtime/routes/guardian-approval-interception.ts +51 -0
- package/src/runtime/routes/home-feed-routes.ts +60 -1
- package/src/runtime/routes/identity-routes.ts +4 -87
- package/src/runtime/routes/inbound-message-handler.ts +82 -41
- package/src/runtime/routes/inbound-stages/acl-enforcement.test.ts +430 -57
- package/src/runtime/routes/inbound-stages/acl-enforcement.ts +302 -572
- package/src/runtime/routes/inbound-stages/background-dispatch.test.ts +76 -270
- package/src/runtime/routes/inbound-stages/background-dispatch.ts +21 -116
- package/src/runtime/routes/inbound-stages/edit-intercept.ts +9 -1
- package/src/runtime/routes/inbound-stages/escalation-intercept.test.ts +158 -0
- package/src/runtime/routes/inbound-stages/escalation-intercept.ts +22 -1
- package/src/runtime/routes/index.ts +6 -0
- package/src/runtime/routes/inference-provider-connection-routes.ts +22 -16
- package/src/runtime/routes/internal-twilio-routes.ts +0 -15
- package/src/runtime/routes/messages-lexical-routes.ts +75 -0
- package/src/runtime/routes/migration-routes.ts +69 -6
- package/src/runtime/routes/monitoring-routes.ts +237 -0
- package/src/runtime/routes/plugins-routes.ts +329 -8
- package/src/runtime/routes/schedule-routes.ts +49 -8
- package/src/runtime/routes/schedule-worker-routes.ts +210 -0
- package/src/runtime/routes/secret-routes.ts +1 -1
- package/src/runtime/routes/surface-conversation-resolver.ts +1 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +54 -9
- package/src/runtime/services/__tests__/auto-analysis-enqueue.test.ts +30 -6
- package/src/runtime/services/__tests__/conversation-analyze-job.test.ts +43 -8
- package/src/runtime/services/__tests__/conversation-serializer.test.ts +20 -0
- package/src/runtime/services/analyze-conversation.ts +14 -4
- package/src/runtime/services/conversation-serializer.ts +5 -0
- package/src/runtime/slack-no-response.ts +47 -0
- package/src/runtime/slack-reply-session.test.ts +633 -0
- package/src/runtime/slack-reply-session.ts +382 -0
- package/src/runtime/slack-task-progress.ts +95 -0
- package/src/runtime/sync/resource-sync-events.ts +25 -0
- package/src/runtime/tool-grant-request-helper.ts +17 -1
- package/src/runtime/trust-class.test.ts +141 -0
- package/src/runtime/trust-class.ts +121 -0
- package/src/runtime/trust-verdict-consumer.ts +7 -6
- package/src/schedule/__tests__/run-script.test.ts +21 -0
- package/src/schedule/__tests__/worker-control.test.ts +241 -0
- package/src/schedule/run-script.ts +13 -6
- package/src/schedule/schedule-usage-store.ts +1 -0
- package/src/schedule/scheduler.ts +178 -127
- package/src/schedule/worker-control.ts +118 -0
- package/src/schedule/worker.ts +131 -0
- package/src/skills/__tests__/categories-cache.test.ts +38 -0
- package/src/skills/categories-cache.ts +40 -5
- package/src/skills/managed-store.ts +41 -6
- package/src/skills/validate-input.ts +47 -0
- package/src/stt/types.ts +5 -9
- package/src/subagent/manager.ts +267 -39
- package/src/subagent/types.ts +6 -2
- package/src/subagent/validate-allowlists.ts +65 -0
- package/src/telemetry/watchdog-direct-emit.test.ts +109 -0
- package/src/telemetry/watchdog-direct-emit.ts +89 -0
- package/src/tools/acp/list-agents.test.ts +0 -6
- package/src/tools/background-tool-registry.ts +61 -0
- package/src/tools/document/document-comment-tool.test.ts +4 -0
- package/src/tools/host-terminal/host-shell.test.ts +397 -0
- package/src/tools/host-terminal/host-shell.ts +203 -14
- package/src/tools/skills/find-similar-skills.test.ts +152 -1
- package/src/tools/skills/find-similar-skills.ts +30 -4
- package/src/tools/skills/load.ts +36 -0
- package/src/tools/skills/scaffold-managed.ts +66 -34
- package/src/tools/skills/skill-script-runner.ts +17 -0
- package/src/tools/skills/skill-tool-factory.ts +5 -1
- package/src/tools/terminal/safe-env.ts +3 -0
- package/src/tools/terminal/shell.test.ts +177 -0
- package/src/tools/terminal/shell.ts +98 -4
- package/src/tools/tool-approval-handler.ts +106 -29
- package/{node_modules/@vellumai/skill-host-contracts/src → src/tools}/tool-types.ts +16 -17
- package/src/tools/types.ts +29 -17
- package/src/tools/ui-surface/definitions.ts +3 -1
- package/src/tts/__tests__/provider-adapters.test.ts +37 -0
- package/src/tts/__tests__/provider-catalog.test.ts +21 -0
- package/src/tts/provider-catalog.ts +40 -9
- package/src/tts/providers/fish-audio-provider.ts +19 -10
- package/src/tts/types.ts +3 -4
- package/src/util/__tests__/process-tree.test.ts +10 -2
- package/src/util/__tests__/text-spacing.test.ts +53 -0
- package/src/util/cgroup-memory.ts +142 -0
- package/src/util/image-conversion.ts +281 -0
- package/src/util/phone.ts +1 -8
- package/src/util/platform.ts +33 -0
- package/src/util/process-tree.ts +10 -2
- package/src/util/text-spacing.ts +53 -0
- package/src/util/worker-process.ts +271 -0
- package/src/workflows/journal-store.ts +16 -1
- package/src/workflows/library.test.ts +35 -20
- package/src/workflows/library.ts +105 -66
- package/src/workspace/git-service.ts +1 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +83 -31
- package/src/workspace/migrations/041-backfill-google-gmail-settings-scope.ts +41 -22
- package/src/workspace/migrations/070-memory-v2-summary-schema-rebuild.ts +1 -1
- package/src/workspace/migrations/118-seed-now-md.ts +64 -0
- package/src/workspace/migrations/119-strip-persisted-memory-v3-tuning-defaults.ts +169 -0
- package/src/workspace/migrations/120-revise-onboarding-threads.ts +47 -0
- package/src/workspace/migrations/121-seed-default-user-guardrails.ts +82 -0
- package/src/workspace/migrations/122-relocate-default-user-boundary.ts +111 -0
- package/src/workspace/migrations/123-swap-quality-profile-to-fable.ts +85 -0
- package/src/workspace/migrations/__tests__/119-strip-persisted-memory-v3-tuning-defaults.test.ts +181 -0
- package/src/workspace/migrations/registry.ts +12 -0
- package/drizzle/0000_dizzy_maggott.sql +0 -301
- package/drizzle/meta/0000_snapshot.json +0 -1933
- package/drizzle/meta/_journal.json +0 -13
- package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +0 -887
- package/node_modules/@vellumai/skill-host-contracts/bun.lock +0 -24
- package/node_modules/@vellumai/skill-host-contracts/package.json +0 -18
- package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -97
- package/node_modules/@vellumai/skill-host-contracts/src/client.ts +0 -1349
- package/node_modules/@vellumai/skill-host-contracts/src/index.ts +0 -6
- package/node_modules/@vellumai/skill-host-contracts/src/runtime-mode.ts +0 -11
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +0 -32
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +0 -333
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.json +0 -20
- package/node_modules/@vellumai/skill-host-contracts/tsconfig.test.json +0 -12
- package/src/__tests__/invite-redemption-service.test.ts +0 -1180
- package/src/__tests__/invite-service-ipc.test.ts +0 -350
- package/src/__tests__/job-handler-registry-guard.test.ts +0 -125
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +0 -203
- package/src/__tests__/relay-server.test.ts +0 -6153
- package/src/__tests__/telephony-stt-routing.test.ts +0 -329
- package/src/__tests__/voice-invite-redemption.test.ts +0 -702
- package/src/calls/relay-server.ts +0 -2463
- package/src/calls/telephony-stt-routing.ts +0 -145
- package/src/contacts/__tests__/contacts-write-revoke-relay.test.ts +0 -128
- package/src/daemon/__tests__/daemon-skill-host.test.ts +0 -273
- package/src/daemon/daemon-skill-host.ts +0 -262
- package/src/daemon/message-types/meet.ts +0 -143
- package/src/daemon/shutdown-registry.ts +0 -40
- package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -253
- package/src/ipc/__tests__/skill-server.test.ts +0 -182
- package/src/ipc/skill-ipc-types.ts +0 -54
- package/src/ipc/skill-routes/__tests__/config.test.ts +0 -146
- package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +0 -448
- package/src/ipc/skill-routes/__tests__/identity.test.ts +0 -62
- package/src/ipc/skill-routes/__tests__/log.test.ts +0 -133
- package/src/ipc/skill-routes/__tests__/memory.test.ts +0 -203
- package/src/ipc/skill-routes/__tests__/platform.test.ts +0 -111
- package/src/ipc/skill-routes/__tests__/providers.test.ts +0 -265
- package/src/ipc/skill-routes/__tests__/registries.test.ts +0 -400
- package/src/ipc/skill-routes/config.ts +0 -47
- package/src/ipc/skill-routes/events.ts +0 -147
- package/src/ipc/skill-routes/identity.ts +0 -21
- package/src/ipc/skill-routes/index.ts +0 -37
- package/src/ipc/skill-routes/log.ts +0 -40
- package/src/ipc/skill-routes/memory.ts +0 -92
- package/src/ipc/skill-routes/platform.ts +0 -39
- package/src/ipc/skill-routes/providers.ts +0 -162
- package/src/ipc/skill-routes/registries.ts +0 -338
- package/src/ipc/skill-server.ts +0 -831
- package/src/ipc/skill-socket-path.ts +0 -20
- package/src/jobs/register-job-handlers.ts +0 -74
- package/src/persistence/invite-store.ts +0 -481
- package/src/plugins/job-handler-registry.ts +0 -94
- package/src/providers/cache-control.ts +0 -26
- package/src/runtime/__tests__/runtime-mode.test.ts +0 -62
- package/src/runtime/invite-redemption-service.ts +0 -828
- package/src/runtime/invite-redemption-templates.ts +0 -46
- package/src/runtime/runtime-mode.ts +0 -40
- package/src/runtime/slack-dm-text-delivery.ts +0 -177
- package/src/util/voice-code.ts +0 -31
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
|
-
import { createHash } from "node:crypto";
|
|
3
|
-
import {
|
|
4
|
-
existsSync,
|
|
5
|
-
mkdirSync,
|
|
6
|
-
readdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
statSync,
|
|
9
|
-
unlinkSync,
|
|
10
|
-
writeFileSync,
|
|
11
|
-
} from "node:fs";
|
|
12
|
-
import { tmpdir } from "node:os";
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
|
|
15
1
|
import { parseImageDimensions } from "../context/image-dimensions.js";
|
|
2
|
+
import { convertImageToJpeg } from "../util/image-conversion.js";
|
|
16
3
|
|
|
17
4
|
// Anthropic's documented max dimension — images larger than this are scaled
|
|
18
5
|
// down server-side anyway, so pre-scaling is zero quality loss.
|
|
@@ -28,110 +15,6 @@ const MAX_TRANSPORT_BYTES = Math.floor(3.5 * 1024 * 1024); // ~3.5 MB raw
|
|
|
28
15
|
|
|
29
16
|
const JPEG_QUALITY = 80;
|
|
30
17
|
|
|
31
|
-
// Content-addressed disk cache to avoid re-running sips on the same image.
|
|
32
|
-
const CACHE_MAX_ENTRIES = 500;
|
|
33
|
-
|
|
34
|
-
function getCacheDir(): string {
|
|
35
|
-
return join(tmpdir(), "vellum-optimized-images");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function readFromCache(
|
|
39
|
-
key: string,
|
|
40
|
-
): { data: string; mediaType: string } | null {
|
|
41
|
-
try {
|
|
42
|
-
const cachePath = join(getCacheDir(), `${key}.jpg`);
|
|
43
|
-
if (!existsSync(cachePath)) return null;
|
|
44
|
-
const buf = readFileSync(cachePath) as Buffer;
|
|
45
|
-
return { data: buf.toString("base64"), mediaType: "image/jpeg" };
|
|
46
|
-
} catch {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function writeToCache(key: string, optimizedBytes: Buffer): void {
|
|
52
|
-
try {
|
|
53
|
-
const dir = getCacheDir();
|
|
54
|
-
mkdirSync(dir, { recursive: true });
|
|
55
|
-
writeFileSync(join(dir, `${key}.jpg`), optimizedBytes);
|
|
56
|
-
evictIfNeeded(dir);
|
|
57
|
-
} catch {
|
|
58
|
-
// Cache write failure is non-fatal.
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function evictIfNeeded(dir: string): void {
|
|
63
|
-
try {
|
|
64
|
-
const entries = readdirSync(dir)
|
|
65
|
-
.filter((f) => f.endsWith(".jpg"))
|
|
66
|
-
.map((f) => {
|
|
67
|
-
const full = join(dir, f);
|
|
68
|
-
return { path: full, mtimeMs: statSync(full).mtimeMs };
|
|
69
|
-
})
|
|
70
|
-
.sort((a, b) => a.mtimeMs - b.mtimeMs);
|
|
71
|
-
const excess = entries.length - CACHE_MAX_ENTRIES;
|
|
72
|
-
for (let i = 0; i < excess; i++) {
|
|
73
|
-
try {
|
|
74
|
-
unlinkSync(entries[i]!.path);
|
|
75
|
-
} catch {
|
|
76
|
-
/* ignore */
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
} catch {
|
|
80
|
-
/* ignore */
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function runSips(inputBytes: Buffer): Buffer | null {
|
|
85
|
-
const srcPath = join(tmpdir(), `vellum-img-opt-${Date.now()}-src`);
|
|
86
|
-
const outPath = join(tmpdir(), `vellum-img-opt-${Date.now()}-out.jpg`);
|
|
87
|
-
try {
|
|
88
|
-
writeFileSync(srcPath, inputBytes);
|
|
89
|
-
execFileSync(
|
|
90
|
-
"sips",
|
|
91
|
-
[
|
|
92
|
-
"--resampleHeightWidthMax",
|
|
93
|
-
String(MAX_DIMENSION),
|
|
94
|
-
"-s",
|
|
95
|
-
"format",
|
|
96
|
-
"jpeg",
|
|
97
|
-
"-s",
|
|
98
|
-
"formatOptions",
|
|
99
|
-
String(JPEG_QUALITY),
|
|
100
|
-
srcPath,
|
|
101
|
-
"--out",
|
|
102
|
-
outPath,
|
|
103
|
-
],
|
|
104
|
-
{ stdio: "pipe", timeout: 15_000 },
|
|
105
|
-
);
|
|
106
|
-
return readFileSync(outPath) as Buffer;
|
|
107
|
-
} catch {
|
|
108
|
-
return null;
|
|
109
|
-
} finally {
|
|
110
|
-
try {
|
|
111
|
-
unlinkSync(srcPath);
|
|
112
|
-
} catch {
|
|
113
|
-
/* ignore */
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
unlinkSync(outPath);
|
|
117
|
-
} catch {
|
|
118
|
-
/* ignore */
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Downscale a base64 image to fit within Anthropic's recommended dimensions
|
|
125
|
-
* (1568px max side). Returns the original data unchanged if the image is
|
|
126
|
-
* already small enough or if optimization fails.
|
|
127
|
-
*
|
|
128
|
-
* Anthropic applies the same scaling server-side, so this is zero quality
|
|
129
|
-
* loss — we just do it pre-flight to keep request payloads small and avoid
|
|
130
|
-
* 413 "request too large" errors when many images accumulate in context.
|
|
131
|
-
*
|
|
132
|
-
* Results are cached on disk by content hash so repeated sends of the same
|
|
133
|
-
* image (or daemon restarts) skip the sips call entirely.
|
|
134
|
-
*/
|
|
135
18
|
/**
|
|
136
19
|
* Decide whether an image needs to be rescaled before sending.
|
|
137
20
|
*
|
|
@@ -157,6 +40,18 @@ export function shouldRescaleImage(
|
|
|
157
40
|
return byteLength > OPTIMIZE_THRESHOLD_BYTES;
|
|
158
41
|
}
|
|
159
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Downscale a base64 image to fit within Anthropic's recommended dimensions
|
|
45
|
+
* (1568px max side). Returns the original data unchanged if the image is
|
|
46
|
+
* already small enough or if optimization fails.
|
|
47
|
+
*
|
|
48
|
+
* Anthropic applies the same scaling server-side, so this is zero quality
|
|
49
|
+
* loss — we just do it pre-flight to keep request payloads small and avoid
|
|
50
|
+
* 413 "request too large" errors when many images accumulate in context.
|
|
51
|
+
*
|
|
52
|
+
* Conversion (and its content-addressed disk cache) is shared with attachment
|
|
53
|
+
* storage normalization — see `util/image-conversion.ts`.
|
|
54
|
+
*/
|
|
160
55
|
export function optimizeImageForTransport(
|
|
161
56
|
base64Data: string,
|
|
162
57
|
mediaType: string,
|
|
@@ -168,18 +63,13 @@ export function optimizeImageForTransport(
|
|
|
168
63
|
return { data: base64Data, mediaType };
|
|
169
64
|
}
|
|
170
65
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
if (cached) return cached;
|
|
176
|
-
|
|
177
|
-
// Run sips (macOS). On other platforms this gracefully returns null.
|
|
178
|
-
const optimized = runSips(rawBytes);
|
|
66
|
+
const optimized = convertImageToJpeg(rawBytes, {
|
|
67
|
+
maxDimensionPx: MAX_DIMENSION,
|
|
68
|
+
quality: JPEG_QUALITY,
|
|
69
|
+
});
|
|
179
70
|
if (!optimized) {
|
|
180
71
|
return { data: base64Data, mediaType };
|
|
181
72
|
}
|
|
182
73
|
|
|
183
|
-
writeToCache(cacheKey, optimized);
|
|
184
74
|
return { data: optimized.toString("base64"), mediaType: "image/jpeg" };
|
|
185
75
|
}
|
package/src/agent/loop.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { getConfig } from "../config/loader.js";
|
|
|
4
4
|
import { isMemoryV3Live } from "../config/memory-v3-gate.js";
|
|
5
5
|
import type { LLMCallSite } from "../config/schemas/llm.js";
|
|
6
6
|
import { recordEstimate } from "../context/estimator-calibration.js";
|
|
7
|
+
import { preModelCallSanitize } from "../context/outbound-sanitize.js";
|
|
7
8
|
import {
|
|
8
9
|
estimatePromptTokensRaw,
|
|
9
10
|
estimatePromptTokensWithTools,
|
|
@@ -14,7 +15,10 @@ import { spoolAndStubOversizedToolResults } from "../context/tool-result-spool.j
|
|
|
14
15
|
import type { ToolActivityMetadata } from "../daemon/message-types/web-activity.js";
|
|
15
16
|
import { parseActualTokensFromError } from "../daemon/parse-actual-tokens-from-error.js";
|
|
16
17
|
import type { TrustContext } from "../daemon/trust-context.js";
|
|
17
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
timeSyncSection,
|
|
20
|
+
traceAsyncSection,
|
|
21
|
+
} from "../persistence/slow-sync-log.js";
|
|
18
22
|
import { HOOKS } from "../plugin-api/constants.js";
|
|
19
23
|
import type {
|
|
20
24
|
AgentLoopExitReason,
|
|
@@ -818,6 +822,19 @@ export class AgentLoop {
|
|
|
818
822
|
this.compactionCircuit = new CompactionCircuit(this.conversationId);
|
|
819
823
|
}
|
|
820
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Replace the system prompt used by subsequent runs. The conversation pushes
|
|
827
|
+
* a freshly resolved prompt here between turns when its persona context
|
|
828
|
+
* (trust, channel, persona override) changed, so a conversation that binds
|
|
829
|
+
* that context after construction (e.g. a voice call resolving the caller's
|
|
830
|
+
* identity after the loop is built) does not stay pinned to the
|
|
831
|
+
* construction-time persona. An in-flight `run()` keeps its own snapshot
|
|
832
|
+
* (`runSystemPrompt`), so this never changes the prompt mid-run.
|
|
833
|
+
*/
|
|
834
|
+
setSystemPrompt(systemPrompt: string): void {
|
|
835
|
+
this.systemPrompt = systemPrompt;
|
|
836
|
+
}
|
|
837
|
+
|
|
821
838
|
/**
|
|
822
839
|
* Resolve the tool definitions sent to the provider for the given turn.
|
|
823
840
|
*
|
|
@@ -1494,15 +1511,20 @@ export class AgentLoop {
|
|
|
1494
1511
|
// the existing correction) so the calibrator learns the true
|
|
1495
1512
|
// bias against provider ground truth instead of ratcheting a
|
|
1496
1513
|
// feedback loop against its own corrected output.
|
|
1497
|
-
const
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1514
|
+
const preSendEstimatedTokens = timeSyncSection(
|
|
1515
|
+
"agent-loop:estimate-prompt-tokens",
|
|
1516
|
+
() => {
|
|
1517
|
+
const toolTokenBudget =
|
|
1518
|
+
currentTools.length > 0 ? estimateToolsTokens(currentTools) : 0;
|
|
1519
|
+
return estimatePromptTokensRaw(history, runSystemPrompt, {
|
|
1520
|
+
providerName: getCalibrationProviderKey(this.provider),
|
|
1521
|
+
toolTokenBudget,
|
|
1522
|
+
});
|
|
1505
1523
|
},
|
|
1524
|
+
(estimatedTokens) => ({
|
|
1525
|
+
estimatedTokens,
|
|
1526
|
+
messageCount: history.length,
|
|
1527
|
+
}),
|
|
1506
1528
|
);
|
|
1507
1529
|
lastPreSendEstimatedTokens = preSendEstimatedTokens;
|
|
1508
1530
|
rlog.info({ turn: toolUseTurns }, "LLM call start");
|
|
@@ -1510,7 +1532,11 @@ export class AgentLoop {
|
|
|
1510
1532
|
// Sanitize the outbound history right before sending: drop accumulated
|
|
1511
1533
|
// media, collapse old AX-tree snapshots, and convert historical
|
|
1512
1534
|
// web-search results to text. See {@link preModelCallSanitize}.
|
|
1513
|
-
const providerHistory =
|
|
1535
|
+
const providerHistory = timeSyncSection(
|
|
1536
|
+
"agent-loop:pre-model-call-sanitize",
|
|
1537
|
+
() => preModelCallSanitize(history),
|
|
1538
|
+
(sanitized) => ({ messageCount: sanitized.length }),
|
|
1539
|
+
);
|
|
1514
1540
|
|
|
1515
1541
|
// A `pre-model-call` hook (below) can defer this turn's assistant
|
|
1516
1542
|
// output; when set, the live text stream is held so an
|
|
@@ -1621,9 +1647,9 @@ export class AgentLoop {
|
|
|
1621
1647
|
deferAssistantOutput: false,
|
|
1622
1648
|
logger: rlog,
|
|
1623
1649
|
};
|
|
1624
|
-
const finalPreModelCtx = await
|
|
1625
|
-
|
|
1626
|
-
preModelCtx,
|
|
1650
|
+
const finalPreModelCtx = await traceAsyncSection(
|
|
1651
|
+
"agent-loop:pre-model-call-hook",
|
|
1652
|
+
() => runHook(HOOKS.PRE_MODEL_CALL, preModelCtx),
|
|
1627
1653
|
);
|
|
1628
1654
|
// Emit a changed event when the hook mutated the prompt. Compare
|
|
1629
1655
|
// against the pre-hook value from providerOptions, not
|
|
@@ -1692,9 +1718,8 @@ export class AgentLoop {
|
|
|
1692
1718
|
latencyTracker?.mark("request_sent");
|
|
1693
1719
|
let response: ProviderResponse;
|
|
1694
1720
|
try {
|
|
1695
|
-
response = await
|
|
1696
|
-
providerHistory,
|
|
1697
|
-
providerOptions,
|
|
1721
|
+
response = await traceAsyncSection("agent-loop:provider-send", () =>
|
|
1722
|
+
this.provider.sendMessage(providerHistory, providerOptions),
|
|
1698
1723
|
);
|
|
1699
1724
|
} catch (llmCallError) {
|
|
1700
1725
|
// Skip recording on abort — the user cancelled the request and
|
|
@@ -1790,7 +1815,10 @@ export class AgentLoop {
|
|
|
1790
1815
|
decision: "stop",
|
|
1791
1816
|
logger: rlog,
|
|
1792
1817
|
};
|
|
1793
|
-
const result = await
|
|
1818
|
+
const result = await traceAsyncSection(
|
|
1819
|
+
"agent-loop:post-model-call-hook",
|
|
1820
|
+
() => runHook(HOOKS.POST_MODEL_CALL, ctx),
|
|
1821
|
+
);
|
|
1794
1822
|
return {
|
|
1795
1823
|
finalized: { role: "assistant", content: result.content },
|
|
1796
1824
|
decision: result.decision,
|
|
@@ -2492,178 +2520,3 @@ export class AgentLoop {
|
|
|
2492
2520
|
};
|
|
2493
2521
|
}
|
|
2494
2522
|
}
|
|
2495
|
-
|
|
2496
|
-
/** Number of most-recent AX tree snapshots to keep in conversation history. */
|
|
2497
|
-
const MAX_AX_TREES_IN_HISTORY = 2;
|
|
2498
|
-
|
|
2499
|
-
/** Regex that matches the `<ax-tree>...</ax-tree>` markers. */
|
|
2500
|
-
const AX_TREE_PATTERN = /<ax-tree>[\s\S]*?<\/ax-tree>/g;
|
|
2501
|
-
const AX_TREE_PLACEHOLDER = "<ax_tree_omitted />";
|
|
2502
|
-
|
|
2503
|
-
/**
|
|
2504
|
-
* Escapes any literal `</ax-tree>` occurrences inside AX tree content so
|
|
2505
|
-
* that the non-greedy compaction regex (`AX_TREE_PATTERN`) does not stop
|
|
2506
|
-
* prematurely when the user happens to be viewing XML/HTML source that
|
|
2507
|
-
* contains the closing tag. The escaped content does not need to be
|
|
2508
|
-
* unescaped because compaction replaces the entire block with a placeholder.
|
|
2509
|
-
*/
|
|
2510
|
-
export function escapeAxTreeContent(content: string): string {
|
|
2511
|
-
return content.replace(/<\/ax-tree>/gi, "</ax-tree>");
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
/**
|
|
2515
|
-
* Returns a shallow copy of `messages` where all but the most recent
|
|
2516
|
-
* `MAX_AX_TREES_IN_HISTORY` `<ax-tree>` blocks have been replaced with a
|
|
2517
|
-
* short placeholder. This keeps the conversation context small so that
|
|
2518
|
-
* TTFT does not grow linearly with step count in computer-use sessions.
|
|
2519
|
-
*
|
|
2520
|
-
* Counting is per-block, not per-message — a single user message can
|
|
2521
|
-
* contain multiple tool_result blocks each with their own AX tree snapshot.
|
|
2522
|
-
*/
|
|
2523
|
-
export function compactAxTreeHistory(messages: Message[]): Message[] {
|
|
2524
|
-
// Collect (messageIndex, blockIndex) for every tool_result block with <ax-tree>
|
|
2525
|
-
const axBlocks: Array<{ msgIdx: number; blockIdx: number }> = [];
|
|
2526
|
-
for (let i = 0; i < messages.length; i++) {
|
|
2527
|
-
const msg = messages[i];
|
|
2528
|
-
if (msg.role !== "user") continue;
|
|
2529
|
-
for (let j = 0; j < msg.content.length; j++) {
|
|
2530
|
-
const block = msg.content[j];
|
|
2531
|
-
if (
|
|
2532
|
-
block.type === "tool_result" &&
|
|
2533
|
-
typeof block.content === "string" &&
|
|
2534
|
-
block.content.includes("<ax-tree>")
|
|
2535
|
-
) {
|
|
2536
|
-
axBlocks.push({ msgIdx: i, blockIdx: j });
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
|
|
2541
|
-
if (axBlocks.length <= MAX_AX_TREES_IN_HISTORY) {
|
|
2542
|
-
return messages;
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
|
-
// Build a set of "msgIdx:blockIdx" keys for blocks that should be stripped
|
|
2546
|
-
const toStrip = new Set(
|
|
2547
|
-
axBlocks
|
|
2548
|
-
.slice(0, -MAX_AX_TREES_IN_HISTORY)
|
|
2549
|
-
.map((b) => `${b.msgIdx}:${b.blockIdx}`),
|
|
2550
|
-
);
|
|
2551
|
-
|
|
2552
|
-
return messages.map((msg, idx) => {
|
|
2553
|
-
// Quick check: does this message have any blocks to strip?
|
|
2554
|
-
const hasStripTarget = msg.content.some((_, j) =>
|
|
2555
|
-
toStrip.has(`${idx}:${j}`),
|
|
2556
|
-
);
|
|
2557
|
-
if (!hasStripTarget) return msg;
|
|
2558
|
-
|
|
2559
|
-
return {
|
|
2560
|
-
...msg,
|
|
2561
|
-
content: msg.content.map((block, j) => {
|
|
2562
|
-
if (
|
|
2563
|
-
toStrip.has(`${idx}:${j}`) &&
|
|
2564
|
-
block.type === "tool_result" &&
|
|
2565
|
-
typeof block.content === "string"
|
|
2566
|
-
) {
|
|
2567
|
-
return {
|
|
2568
|
-
...block,
|
|
2569
|
-
content: block.content.replace(
|
|
2570
|
-
AX_TREE_PATTERN,
|
|
2571
|
-
AX_TREE_PLACEHOLDER,
|
|
2572
|
-
),
|
|
2573
|
-
};
|
|
2574
|
-
}
|
|
2575
|
-
return block;
|
|
2576
|
-
}),
|
|
2577
|
-
};
|
|
2578
|
-
});
|
|
2579
|
-
}
|
|
2580
|
-
|
|
2581
|
-
/**
|
|
2582
|
-
* Strip image contentBlocks from all tool_result blocks except those in the
|
|
2583
|
-
* most recent user message that contains tool_result blocks. This prevents
|
|
2584
|
-
* screenshots from accumulating in the context window — each image is seen
|
|
2585
|
-
* once by the LLM on the turn it was captured, then replaced with a text
|
|
2586
|
-
* placeholder on subsequent turns.
|
|
2587
|
-
*
|
|
2588
|
-
* We target the last user message with tool_results (not just the last user
|
|
2589
|
-
* message) because a plain-text user message may follow the tool-result
|
|
2590
|
-
* turn. Using the last user message unconditionally would leave the most
|
|
2591
|
-
* recent tool screenshots unprotected from stripping.
|
|
2592
|
-
*/
|
|
2593
|
-
function stripOldMediaBlocks(history: Message[]): Message[] {
|
|
2594
|
-
// Find the last user message that contains tool_result blocks.
|
|
2595
|
-
let lastToolResultUserIdx = -1;
|
|
2596
|
-
for (let i = history.length - 1; i >= 0; i--) {
|
|
2597
|
-
if (
|
|
2598
|
-
history[i].role === "user" &&
|
|
2599
|
-
history[i].content.some((b) => b.type === "tool_result")
|
|
2600
|
-
) {
|
|
2601
|
-
lastToolResultUserIdx = i;
|
|
2602
|
-
break;
|
|
2603
|
-
}
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
return history.map((msg, idx) => {
|
|
2607
|
-
// Keep the most recent tool-result user message intact (current turn)
|
|
2608
|
-
if (idx === lastToolResultUserIdx || msg.role !== "user") return msg;
|
|
2609
|
-
|
|
2610
|
-
// Check if any tool_result blocks carry embedded media (image or audio).
|
|
2611
|
-
const isMedia = (cb: ContentBlock) =>
|
|
2612
|
-
cb.type === "image" || cb.type === "file";
|
|
2613
|
-
const hasMedia = msg.content.some(
|
|
2614
|
-
(b) =>
|
|
2615
|
-
b.type === "tool_result" &&
|
|
2616
|
-
(b as ToolResultContent).contentBlocks?.some(isMedia),
|
|
2617
|
-
);
|
|
2618
|
-
if (!hasMedia) return msg;
|
|
2619
|
-
|
|
2620
|
-
// Strip media from tool_result blocks, replacing with a text marker. The
|
|
2621
|
-
// model already saw/heard the media in the turn it was captured; resending
|
|
2622
|
-
// the bytes every turn (a 12 MB audio clip isn't optimized like images)
|
|
2623
|
-
// bloats the request until compaction.
|
|
2624
|
-
return {
|
|
2625
|
-
...msg,
|
|
2626
|
-
content: msg.content.map((b) => {
|
|
2627
|
-
if (b.type !== "tool_result") return b;
|
|
2628
|
-
const tr = b as ToolResultContent;
|
|
2629
|
-
if (!tr.contentBlocks?.some(isMedia)) return b;
|
|
2630
|
-
return {
|
|
2631
|
-
...tr,
|
|
2632
|
-
contentBlocks: undefined,
|
|
2633
|
-
content:
|
|
2634
|
-
(tr.content || "") +
|
|
2635
|
-
"\n[Media (image/audio) was captured and shown previously — binary data removed to save context.]",
|
|
2636
|
-
};
|
|
2637
|
-
}),
|
|
2638
|
-
};
|
|
2639
|
-
});
|
|
2640
|
-
}
|
|
2641
|
-
|
|
2642
|
-
/**
|
|
2643
|
-
* Sanitize the outbound history immediately before a provider call, bundling
|
|
2644
|
-
* the pre-send transforms the loop applies to every request:
|
|
2645
|
-
* - {@link stripOldMediaBlocks} drops accumulated screenshot/audio bytes from
|
|
2646
|
-
* older tool results — the model saw the media on the turn it was captured.
|
|
2647
|
-
* - {@link compactAxTreeHistory} collapses all but the most recent few
|
|
2648
|
-
* `<ax-tree>` snapshots so TTFT does not grow linearly with step count.
|
|
2649
|
-
* - {@link stripHistoricalWebSearchResults} converts historical
|
|
2650
|
-
* `web_search_tool_result` blocks to text summaries; Anthropic's opaque
|
|
2651
|
-
* `encrypted_content` tokens expire / are route-scoped, and replaying a stale
|
|
2652
|
-
* one is rejected with `Invalid encrypted_content in search_result block`.
|
|
2653
|
-
*
|
|
2654
|
-
* Transforms the outbound copy only — the durable history keeps the rich
|
|
2655
|
-
* originals and each send re-derives the sanitized projection (every transform
|
|
2656
|
-
* is idempotent). Because it runs unconditionally before every provider call,
|
|
2657
|
-
* it is the single place where oversized media and expired web-search tokens
|
|
2658
|
-
* are guaranteed to be removed from a request.
|
|
2659
|
-
*
|
|
2660
|
-
* This is outbound-request preparation and should eventually move to a default
|
|
2661
|
-
* `pre-model-call` plugin hook ({@link HOOKS.PRE_MODEL_CALL}) once that hook's
|
|
2662
|
-
* context carries the outbound message list; for now it lives inline next to
|
|
2663
|
-
* the provider call it guards.
|
|
2664
|
-
*/
|
|
2665
|
-
export function preModelCallSanitize(history: Message[]): Message[] {
|
|
2666
|
-
const mediaStripped = stripOldMediaBlocks(history);
|
|
2667
|
-
const axCompacted = compactAxTreeHistory(mediaStripped);
|
|
2668
|
-
return stripHistoricalWebSearchResults(axCompacted).messages;
|
|
2669
|
-
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { BackgroundToolCompletedEventSchema } from "./background-tool-completed.js";
|
|
4
|
+
|
|
5
|
+
describe("BackgroundToolCompletedEventSchema", () => {
|
|
6
|
+
test("parses a completed event with exit code and output", () => {
|
|
7
|
+
const event = {
|
|
8
|
+
type: "background_tool_completed" as const,
|
|
9
|
+
id: "bg-1a2b3c4d",
|
|
10
|
+
conversationId: "conv-abc",
|
|
11
|
+
status: "completed" as const,
|
|
12
|
+
exitCode: 0,
|
|
13
|
+
output: "done\n",
|
|
14
|
+
completedAt: 1_700_000_001_000,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const result = BackgroundToolCompletedEventSchema.safeParse(event);
|
|
18
|
+
|
|
19
|
+
expect(result.success).toBe(true);
|
|
20
|
+
expect(result.success && result.data).toEqual(event);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("parses a completed event without the optional fields", () => {
|
|
24
|
+
const event = {
|
|
25
|
+
type: "background_tool_completed" as const,
|
|
26
|
+
id: "bg-1a2b3c4d",
|
|
27
|
+
conversationId: "conv-abc",
|
|
28
|
+
status: "cancelled" as const,
|
|
29
|
+
completedAt: 1_700_000_001_000,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const result = BackgroundToolCompletedEventSchema.safeParse(event);
|
|
33
|
+
|
|
34
|
+
expect(result.success).toBe(true);
|
|
35
|
+
expect(result.success && result.data).toEqual(event);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("strips an unrecognized field for forward compatibility", () => {
|
|
39
|
+
const result = BackgroundToolCompletedEventSchema.safeParse({
|
|
40
|
+
type: "background_tool_completed",
|
|
41
|
+
id: "bg-1a2b3c4d",
|
|
42
|
+
conversationId: "conv-abc",
|
|
43
|
+
status: "failed",
|
|
44
|
+
completedAt: 1_700_000_001_000,
|
|
45
|
+
unexpected: true,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
expect(result.success).toBe(true);
|
|
49
|
+
expect(result.success && "unexpected" in result.data).toBe(false);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `background_tool_completed` SSE event.
|
|
3
|
+
*
|
|
4
|
+
* Server → client notification that a background bash/host_bash command
|
|
5
|
+
* has finished. Carries the background-tool identity (`id`), scoping
|
|
6
|
+
* (`conversationId`), the terminal `status`, the optional `exitCode` and
|
|
7
|
+
* captured `output`, and the `completedAt` timestamp.
|
|
8
|
+
*
|
|
9
|
+
* Canonical wire-contract source. Re-exported to external consumers via
|
|
10
|
+
* `@vellumai/assistant-api` (the `api/index.ts` barrel).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
// No `.strict()`: unknown server-added fields are stripped, not rejected, so a
|
|
16
|
+
// future field can't make older clients drop the whole lifecycle event.
|
|
17
|
+
export const BackgroundToolCompletedEventSchema = z.object({
|
|
18
|
+
type: z.literal("background_tool_completed"),
|
|
19
|
+
id: z.string(),
|
|
20
|
+
conversationId: z.string(),
|
|
21
|
+
status: z.enum(["completed", "failed", "cancelled"]),
|
|
22
|
+
exitCode: z.number().nullable().optional(),
|
|
23
|
+
output: z.string().optional(),
|
|
24
|
+
completedAt: z.number(),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type BackgroundToolCompletedEvent = z.infer<
|
|
28
|
+
typeof BackgroundToolCompletedEventSchema
|
|
29
|
+
>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
|
|
3
|
+
import { BackgroundToolStartedEventSchema } from "./background-tool-started.js";
|
|
4
|
+
|
|
5
|
+
describe("BackgroundToolStartedEventSchema", () => {
|
|
6
|
+
test("parses a started event", () => {
|
|
7
|
+
const event = {
|
|
8
|
+
type: "background_tool_started" as const,
|
|
9
|
+
id: "bg-1a2b3c4d",
|
|
10
|
+
toolName: "bash",
|
|
11
|
+
conversationId: "conv-abc",
|
|
12
|
+
command: "sleep 30 && echo done",
|
|
13
|
+
startedAt: 1_700_000_000_000,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const result = BackgroundToolStartedEventSchema.safeParse(event);
|
|
17
|
+
|
|
18
|
+
expect(result.success).toBe(true);
|
|
19
|
+
expect(result.success && result.data).toEqual(event);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("strips an unrecognized field for forward compatibility", () => {
|
|
23
|
+
const result = BackgroundToolStartedEventSchema.safeParse({
|
|
24
|
+
type: "background_tool_started",
|
|
25
|
+
id: "bg-1a2b3c4d",
|
|
26
|
+
toolName: "bash",
|
|
27
|
+
conversationId: "conv-abc",
|
|
28
|
+
command: "echo hi",
|
|
29
|
+
startedAt: 1_700_000_000_000,
|
|
30
|
+
unexpected: true,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(result.success).toBe(true);
|
|
34
|
+
expect(result.success && "unexpected" in result.data).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `background_tool_started` SSE event.
|
|
3
|
+
*
|
|
4
|
+
* Server → client notification that a background bash/host_bash command
|
|
5
|
+
* has started. Carries the background-tool identity (`id`, a `bg-xxxxxxxx`
|
|
6
|
+
* id), the `toolName`, scoping (`conversationId`), the `command` being run,
|
|
7
|
+
* and the `startedAt` timestamp.
|
|
8
|
+
*
|
|
9
|
+
* Canonical wire-contract source. Re-exported to external consumers via
|
|
10
|
+
* `@vellumai/assistant-api` (the `api/index.ts` barrel).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
// No `.strict()`: unknown server-added fields are stripped, not rejected, so a
|
|
16
|
+
// future field can't make older clients drop the whole lifecycle event.
|
|
17
|
+
export const BackgroundToolStartedEventSchema = z.object({
|
|
18
|
+
type: z.literal("background_tool_started"),
|
|
19
|
+
id: z.string(),
|
|
20
|
+
toolName: z.string(),
|
|
21
|
+
conversationId: z.string(),
|
|
22
|
+
command: z.string(),
|
|
23
|
+
startedAt: z.number(),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export type BackgroundToolStartedEvent = z.infer<
|
|
27
|
+
typeof BackgroundToolStartedEventSchema
|
|
28
|
+
>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `open_panel` SSE event.
|
|
3
|
+
*
|
|
4
|
+
* Side-effect-only command: tells the client to open a panel or drawer
|
|
5
|
+
* without rendering anything in the chat transcript. Analogous to
|
|
6
|
+
* `open_url` and `navigate_settings` — the rolling-snapshot reducer
|
|
7
|
+
* has no case for it, so it naturally falls through to "no change."
|
|
8
|
+
*
|
|
9
|
+
* `panelType` identifies which panel to open; `data` carries
|
|
10
|
+
* panel-specific payload (validated by the handler, not the schema).
|
|
11
|
+
*
|
|
12
|
+
* `surfaceId` is the acknowledgment correlation id: the daemon holds the
|
|
13
|
+
* emitting tool call open until the client confirms the panel rendered by
|
|
14
|
+
* POSTing a surface action (`actionId: "ack"` / `"nack"`) with this id.
|
|
15
|
+
* Clients that receive an event without a `surfaceId` have nothing to
|
|
16
|
+
* acknowledge.
|
|
17
|
+
*
|
|
18
|
+
* Canonical wire-contract source. Daemon code imports the type
|
|
19
|
+
* directly from this file; external consumers import via
|
|
20
|
+
* `@vellumai/assistant-api`.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
|
|
25
|
+
export const OpenPanelEventSchema = z.object({
|
|
26
|
+
type: z.literal("open_panel"),
|
|
27
|
+
panelType: z.string(),
|
|
28
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
29
|
+
conversationId: z.string().optional(),
|
|
30
|
+
surfaceId: z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export type OpenPanelEvent = z.infer<typeof OpenPanelEventSchema>;
|
|
@@ -22,7 +22,9 @@ import { z } from "zod";
|
|
|
22
22
|
/**
|
|
23
23
|
* Subagent lifecycle status. Mirrors `SubagentStatus` in
|
|
24
24
|
* `assistant/src/subagent/types.ts`. `aborted` is a terminal state
|
|
25
|
-
* reached via explicit `subagent_abort` request
|
|
25
|
+
* reached via explicit `subagent_abort` request; `interrupted` is a
|
|
26
|
+
* terminal state assigned on daemon restart to a subagent that was
|
|
27
|
+
* still in flight (it is not auto-resumed).
|
|
26
28
|
*/
|
|
27
29
|
export const SubagentStatusSchema = z.enum([
|
|
28
30
|
"pending",
|
|
@@ -31,6 +33,7 @@ export const SubagentStatusSchema = z.enum([
|
|
|
31
33
|
"completed",
|
|
32
34
|
"failed",
|
|
33
35
|
"aborted",
|
|
36
|
+
"interrupted",
|
|
34
37
|
]);
|
|
35
38
|
|
|
36
39
|
export type SubagentStatus = z.infer<typeof SubagentStatusSchema>;
|