@vellumai/assistant 0.8.7 → 0.8.8-dev.202606052332.17fc8ea
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/Dockerfile +20 -4
- package/bun.lock +2 -2
- package/docker-entrypoint.sh +4 -2
- package/docker-init-apt-root.sh +3 -1
- package/docker-kata-apt-env.sh +3 -1
- package/docker-kata-runtime-family.sh +12 -0
- package/docs/architecture/memory.md +1 -1
- package/examples/plugins/echo/README.md +61 -66
- package/examples/plugins/echo/hooks/post-tool-use.ts +18 -0
- package/examples/plugins/echo/hooks/stop.ts +16 -0
- package/examples/plugins/echo/hooks/user-prompt-submit.ts +18 -0
- package/examples/plugins/echo/package.json +1 -2
- package/examples/plugins/echo/src/emit.ts +19 -0
- package/node_modules/@vellumai/skill-host-contracts/src/server-message.ts +3 -3
- package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +7 -6
- package/openapi.yaml +3378 -335
- package/package.json +2 -2
- package/scripts/generate-openapi.ts +68 -41
- package/src/__tests__/agent-loop-exit-reason.test.ts +35 -93
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +1 -1
- package/src/__tests__/agent-loop.test.ts +37 -87
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +2 -0
- package/src/__tests__/annotate-activity-metadata.test.ts +262 -0
- package/src/__tests__/annotate-risk-options.test.ts +2 -3
- package/src/__tests__/anthropic-provider.test.ts +95 -2
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/assistant-event-hub.test.ts +25 -0
- package/src/__tests__/assistant-events-sse-shed.test.ts +8 -0
- package/src/__tests__/{conversation-stream-state.test.ts → assistant-stream-state.test.ts} +252 -91
- package/src/__tests__/auth-fallback-events-store.test.ts +116 -0
- package/src/__tests__/background-workers-disk-pressure.test.ts +6 -0
- package/src/__tests__/btw-routes.test.ts +62 -3
- package/src/__tests__/build-persisted-content.test.ts +184 -0
- package/src/__tests__/catalog-files.test.ts +1 -1
- package/src/__tests__/channel-approval-routes.test.ts +1 -1
- package/src/__tests__/channel-approvals.test.ts +1 -1
- package/src/__tests__/clawhub-files.test.ts +1 -1
- package/src/__tests__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction.benchmark.test.ts +0 -30
- package/src/__tests__/config-watcher.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +57 -19
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +6 -5
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +10 -7
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +316 -1143
- package/src/__tests__/conversation-agent-loop.test.ts +638 -1655
- package/src/__tests__/conversation-analysis-routes.test.ts +6 -0
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-history-web-search.test.ts +11 -1
- package/src/__tests__/conversation-pairing.test.ts +4 -31
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +6 -0
- package/src/__tests__/conversation-provider-retry-repair.test.ts +30 -10
- package/src/__tests__/conversation-queue.test.ts +2 -0
- package/src/__tests__/conversation-routes-disk-view.test.ts +3 -0
- package/src/__tests__/conversation-routes-slash-commands.test.ts +6 -5
- package/src/__tests__/conversation-runtime-assembly.test.ts +310 -300
- package/src/__tests__/conversation-runtime-workspace.test.ts +105 -45
- package/src/__tests__/conversation-slash-commands.test.ts +8 -42
- package/src/__tests__/conversation-slash-queue.test.ts +6 -1
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-surfaces-action-delivery.test.ts +84 -0
- package/src/__tests__/conversation-sync-tags.test.ts +27 -15
- package/src/__tests__/conversation-title-service.test.ts +135 -2
- package/src/__tests__/conversation-workspace-cache-state.test.ts +17 -16
- package/src/__tests__/conversation-workspace-injection.test.ts +67 -2
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +7 -6
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/cross-provider-web-search.test.ts +214 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/db-schedule-syntax-migration.test.ts +5 -0
- package/src/__tests__/dm-persistence.test.ts +5 -1
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +304 -0
- package/src/__tests__/feature-flag-test-helpers.ts +2 -2
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- package/src/__tests__/gemini-image-service.test.ts +13 -0
- package/src/__tests__/guardian-grant-minting.test.ts +1 -1
- package/src/__tests__/guardian-routing-invariants.test.ts +2 -4
- package/src/__tests__/handlers-user-message-approval-consumption.test.ts +1 -1
- package/src/__tests__/heartbeat-disk-pressure.test.ts +1 -0
- package/src/__tests__/heartbeat-service.test.ts +1 -0
- package/src/__tests__/helpers/mock-provider.ts +110 -0
- package/src/__tests__/helpers/native-web-search-harness.ts +129 -0
- package/src/__tests__/history-repair-hook.test.ts +1 -0
- package/src/__tests__/host-app-control-routes.test.ts +1 -1
- package/src/__tests__/host-cu-routes-targeted.test.ts +3 -3
- package/src/__tests__/identity-intro-cache.test.ts +12 -100
- package/src/__tests__/identity-routes.test.ts +248 -7
- package/src/__tests__/inbound-slack-persistence.test.ts +5 -1
- package/src/__tests__/injector-background-turn.test.ts +3 -9
- package/src/__tests__/injector-chain.test.ts +139 -275
- package/src/__tests__/injector-disk-pressure.test.ts +75 -41
- package/src/__tests__/injector-document-comments.test.ts +3 -3
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +30 -22
- package/src/__tests__/injector-v3-suppression.test.ts +31 -37
- package/src/__tests__/internal-telemetry-routes.test.ts +109 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/list-messages-page-latest.test.ts +60 -0
- package/src/__tests__/list-messages-tool-merge.test.ts +20 -0
- package/src/__tests__/llm-usage-store.test.ts +223 -1
- package/src/__tests__/memory-retrieval-hook.test.ts +297 -0
- package/src/__tests__/memory-v2-static-injector.test.ts +103 -35
- package/src/__tests__/native-web-search.test.ts +191 -0
- package/src/__tests__/onboarding-template-contract.test.ts +2 -0
- package/src/__tests__/openai-image-service.test.ts +17 -0
- package/src/__tests__/openai-provider.test.ts +31 -1
- package/src/__tests__/{overflow-reduce-pipeline.test.ts → overflow-reduction-loop.test.ts} +64 -284
- package/src/__tests__/persist-unsendable-image.test.ts +215 -0
- package/src/__tests__/persistence-secret-redaction.test.ts +1 -0
- package/src/__tests__/pkb-autoinject.test.ts +2 -5
- package/src/__tests__/plugin-api-shim.test.ts +3 -6
- package/src/__tests__/plugin-bootstrap.test.ts +14 -40
- package/src/__tests__/plugin-registry.test.ts +3 -76
- package/src/__tests__/plugin-types.test.ts +0 -193
- package/src/__tests__/process-message-display-content.test.ts +6 -2
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +5 -1
- package/src/__tests__/resolve-trust-class.test.ts +4 -4
- package/src/__tests__/runtime-events-sse-reconnect.test.ts +60 -23
- package/src/__tests__/schedule-routes.test.ts +603 -2
- package/src/__tests__/schedule-store.test.ts +41 -0
- package/src/__tests__/schedule-tools.test.ts +35 -0
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/server-history-render.test.ts +314 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/skillssh-files.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-fork-notifications.test.ts +1 -3
- package/src/__tests__/subagent-fork-spawn.test.ts +1 -1
- package/src/__tests__/subagent-manager-notify.test.ts +1 -3
- package/src/__tests__/subagent-notify-parent.test.ts +1 -3
- package/src/__tests__/subagent-spawn-tool-fork.test.ts +1 -1
- package/src/__tests__/system-prompt.test.ts +20 -0
- package/src/__tests__/task-scheduler.test.ts +162 -1
- package/src/__tests__/terminal-tools.test.ts +6 -1
- package/src/__tests__/title-generate-hook.test.ts +319 -0
- package/src/__tests__/tool-error-hook.test.ts +278 -0
- package/src/__tests__/tool-preview-lifecycle.test.ts +468 -5
- package/src/__tests__/tool-result-metadata-plumbing.test.ts +1 -0
- package/src/__tests__/tool-result-truncate-hook.test.ts +127 -0
- package/src/__tests__/tool-result-truncation.test.ts +0 -2
- package/src/__tests__/ui-choice-copy-surfaces.test.ts +254 -0
- package/src/__tests__/ui-work-result-surface.test.ts +159 -0
- package/src/__tests__/usage-routes.test.ts +285 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- package/src/__tests__/voice-session-bridge.test.ts +6 -3
- package/src/__tests__/web-search-backend-failure.test.ts +166 -0
- package/src/acp/__tests__/agent-process.test.ts +161 -0
- package/src/acp/__tests__/client-handler.test.ts +40 -0
- package/src/acp/__tests__/helpers/acp-history-db.ts +82 -0
- package/src/acp/__tests__/helpers/exec-file-stub.ts +101 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +137 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +736 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +196 -0
- package/src/acp/auto-install.ts +177 -0
- package/src/acp/client-handler.ts +31 -0
- package/src/acp/feature-gate.test.ts +48 -0
- package/src/acp/feature-gate.ts +34 -0
- package/src/acp/prepare-agent-env.ts +83 -29
- package/src/acp/resolve-agent.test.ts +320 -7
- package/src/acp/resolve-agent.ts +182 -18
- package/src/acp/resume-hint.ts +25 -0
- package/src/acp/session-manager.ts +495 -73
- package/src/acp/types.ts +8 -0
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +362 -485
- package/src/api/events/assistant-thinking-delta.ts +33 -0
- package/src/api/events/tool-output-chunk.ts +45 -0
- package/src/api/events/tool-use-preview-start.ts +32 -0
- package/src/api/events/trace-event.ts +69 -0
- package/src/api/index.ts +48 -13
- package/src/api/responses/conversation-message.ts +374 -0
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/avatar/__tests__/avatar-store.test.ts +34 -29
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/__tests__/notifications.test.ts +58 -14
- package/src/cli/commands/notifications.ts +112 -60
- package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
- package/src/config/acp-defaults.test.ts +10 -0
- package/src/config/acp-defaults.ts +6 -0
- package/src/config/assistant-feature-flags.ts +22 -11
- package/src/config/bundled-skills/acp/SKILL.md +83 -31
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -398
- package/src/config/bundled-skills/app-builder/TOOLS.json +29 -0
- package/src/config/bundled-skills/app-builder/references/DESIGN_SYSTEM.md +48 -0
- package/src/config/bundled-skills/app-builder/references/RESPONSIVE.md +57 -0
- package/src/config/bundled-skills/app-builder/references/SLIDES.md +38 -0
- package/src/config/bundled-skills/app-builder/references/examples/README.md +17 -0
- package/src/config/bundled-skills/app-builder/references/examples/expense-tracker.md +515 -0
- package/src/config/bundled-skills/app-builder/references/examples/focus-timer.md +342 -0
- package/src/config/bundled-skills/app-builder/references/examples/habit-tracker.md +490 -0
- package/src/config/bundled-skills/app-builder/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/document-editor/SKILL.md +28 -23
- package/src/config/bundled-skills/document-editor/TOOLS.json +1 -1
- package/src/config/bundled-skills/messaging/SKILL.md +0 -7
- package/src/config/bundled-tool-registry.ts +2 -0
- package/src/config/feature-flag-cache.ts +3 -3
- package/src/config/feature-flag-registry.json +48 -7
- package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
- package/src/config/schemas/__tests__/memory-v3.test.ts +25 -0
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +1 -0
- package/src/config/schemas/memory-v2.ts +8 -0
- package/src/config/schemas/memory-v3.ts +8 -0
- package/src/config/schemas/platform.ts +8 -0
- package/src/config/seed-inference-profiles.ts +2 -2
- package/src/config/skills.ts +13 -0
- package/src/context/compactor.ts +1 -1
- package/src/context/strip-injections.ts +128 -0
- package/src/context/token-estimator.ts +23 -0
- package/src/context/tool-result-truncation.ts +0 -23
- package/src/context/window-manager.ts +5 -7
- package/src/credential-execution/executable-discovery.ts +16 -0
- package/src/daemon/__tests__/conversation-lifecycle-auto-analyze.test.ts +6 -0
- package/src/daemon/__tests__/inference-profile-notification.test.ts +153 -0
- package/src/daemon/__tests__/native-web-search-metadata.test.ts +10 -8
- package/src/daemon/assistant-attachments.ts +1 -1
- package/src/daemon/config-watcher.ts +2 -2
- package/src/daemon/context-overflow-reducer.ts +0 -1
- package/src/daemon/conversation-agent-loop-handlers.ts +594 -153
- package/src/daemon/conversation-agent-loop.ts +301 -997
- package/src/daemon/conversation-history.ts +5 -4
- package/src/daemon/conversation-lifecycle.ts +3 -4
- package/src/daemon/conversation-messaging.ts +7 -6
- package/src/daemon/conversation-process.ts +11 -16
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +218 -398
- package/src/daemon/conversation-slash.ts +6 -25
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +222 -4
- package/src/daemon/conversation-tool-setup.ts +2 -29
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +32 -20
- package/src/daemon/external-plugins-bootstrap.ts +17 -18
- package/src/daemon/handlers/config-a2a.ts +51 -36
- package/src/daemon/handlers/config-slack-channel.ts +20 -14
- package/src/daemon/handlers/config-telegram.ts +16 -2
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/shared.ts +156 -84
- package/src/daemon/handlers/skills.ts +42 -10
- package/src/daemon/lifecycle.ts +25 -0
- package/src/daemon/message-types/apps.ts +1 -29
- package/src/daemon/message-types/messages.ts +9 -57
- package/src/daemon/message-types/skills.ts +2 -0
- package/src/daemon/message-types/surfaces.ts +136 -3
- package/src/daemon/now-scratchpad.ts +21 -0
- package/src/daemon/orphan-reaper.test.ts +210 -0
- package/src/daemon/orphan-reaper.ts +240 -0
- package/src/daemon/overflow-reduction-loop.ts +230 -0
- package/src/daemon/persist-unsendable-image.ts +117 -0
- package/src/daemon/process-message.ts +1 -3
- package/src/daemon/server.ts +2 -0
- package/src/daemon/trace-emitter.ts +6 -4
- package/src/daemon/trust-context.ts +19 -0
- package/src/daemon/wake-target-adapter.ts +3 -1
- package/src/heartbeat/__tests__/heartbeat-service.test.ts +3 -0
- package/src/heartbeat/heartbeat-run-store.ts +23 -1
- package/src/heartbeat/heartbeat-service.ts +26 -0
- package/src/home/home-greeting-cache.ts +24 -1
- package/src/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.ts +3 -3
- package/src/ipc/gateway-client.test.ts +2 -2
- package/src/ipc/gateway-client.ts +3 -3
- package/src/ipc/skill-routes/__tests__/memory.test.ts +15 -0
- package/src/ipc/skill-routes/memory.ts +4 -2
- package/src/media/gemini-image-service.ts +15 -0
- package/src/media/openai-image-service.ts +14 -0
- package/src/media/types.ts +34 -0
- package/src/memory/__tests__/jobs-worker-v2-schedule.test.ts +56 -0
- package/src/memory/auth-fallback-events-store.ts +94 -0
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/conversation-title-service.ts +65 -41
- package/src/memory/db-init.ts +6 -0
- package/src/memory/graph/__tests__/conversation-graph-memory-registry.test.ts +119 -0
- package/src/memory/graph/conversation-graph-memory.ts +65 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs-store.ts +33 -0
- package/src/memory/jobs-worker.ts +32 -5
- package/src/memory/llm-usage-store.ts +224 -50
- package/src/memory/migrations/222-strip-placeholder-sentinels-from-messages.ts +6 -5
- package/src/memory/migrations/270-schedule-source-conversation.ts +13 -0
- package/src/memory/migrations/271-create-auth-fallback-events.ts +21 -0
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +3 -0
- package/src/memory/pkb/autoinject.ts +61 -0
- package/src/memory/pkb/context.ts +50 -0
- package/src/memory/pkb/types.ts +14 -0
- package/src/memory/schedule-attribution-sql.ts +104 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/schema/infrastructure.ts +16 -0
- package/src/memory/usage-grouped-buckets.ts +6 -1
- package/src/memory/v2/__tests__/consolidation-job.test.ts +4 -4
- package/src/memory/v2/consolidation-job.ts +14 -5
- package/src/notifications/conversation-pairing.ts +8 -15
- package/src/notifications/decision-engine.ts +6 -3
- package/src/notifications/home-feed-side-effect.ts +12 -1
- package/src/permissions/prompter.ts +4 -0
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +7 -5
- package/src/plugin-api/types.ts +151 -1
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/plugins/defaults/compaction/package.json +1 -1
- package/src/plugins/defaults/compaction/register.ts +8 -19
- package/src/plugins/defaults/empty-response/hooks/stop.ts +126 -0
- package/src/plugins/defaults/empty-response/register.ts +8 -13
- package/src/plugins/defaults/index.ts +2 -18
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +95 -0
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +216 -0
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +35 -0
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +288 -81
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/assign.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/health.test.ts +16 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/live-integration.test.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/maintain-job.test.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/orchestrate.test.ts +48 -12
- package/src/plugins/defaults/memory-v3-shadow/__tests__/provider-blocks.test.ts +13 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/reconcile.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/render-injection.test.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/router.test.ts +104 -32
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selection-log-store.test.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/selector.test.ts +96 -30
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +34 -16
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/health.ts +0 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/post-compact.ts +14 -0
- package/src/plugins/defaults/memory-v3-shadow/hooks/user-prompt-submit.ts +19 -0
- package/src/plugins/defaults/memory-v3-shadow/injector.ts +75 -0
- package/src/plugins/defaults/memory-v3-shadow/llm-retry.ts +32 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +8 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +26 -14
- package/src/plugins/defaults/{llm-call → memory-v3-shadow}/package.json +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/provider-blocks.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +3 -3
- package/src/plugins/defaults/memory-v3-shadow/register.ts +26 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/render-injection.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/router.ts +51 -45
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selection-log-store.ts +4 -4
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/selector.ts +61 -46
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +69 -99
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +8 -0
- package/src/plugins/defaults/title-generate/hooks/stop.ts +75 -0
- package/src/plugins/defaults/title-generate/hooks/user-prompt-submit.ts +35 -0
- package/src/plugins/defaults/title-generate/package.json +1 -1
- package/src/plugins/defaults/title-generate/register.ts +18 -18
- package/src/plugins/defaults/tool-error/hooks/post-tool-use.ts +118 -0
- package/src/plugins/defaults/tool-error/package.json +1 -1
- package/src/plugins/defaults/tool-error/register.ts +9 -21
- package/src/plugins/defaults/tool-result-truncate/hooks/post-tool-use.ts +32 -0
- package/src/plugins/defaults/tool-result-truncate/register.ts +10 -21
- package/src/plugins/defaults/tool-result-truncate/terminal.ts +37 -18
- package/src/plugins/external-api.ts +2 -2
- package/src/plugins/pipeline.ts +6 -305
- package/src/plugins/registry.ts +10 -55
- package/src/plugins/types.ts +62 -797
- package/src/plugins/user-loader.ts +30 -127
- package/src/proactive-artifact/aux-message-injector.ts +4 -4
- package/src/proactive-artifact/job.test.ts +8 -13
- package/src/prompts/__tests__/system-prompt.test.ts +42 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +64 -0
- package/src/prompts/templates/BOOTSTRAP.md +2 -2
- package/src/prompts/templates/system-sections.ts +15 -0
- package/src/providers/anthropic/client.ts +37 -29
- package/src/providers/openai/__tests__/chat-completions-provider-reasoning.test.ts +112 -0
- package/src/providers/openai/chat-completions-provider.ts +44 -0
- package/src/providers/openrouter/client.ts +1 -0
- package/src/providers/placeholder-sentinels.ts +35 -0
- package/src/runtime/__tests__/agent-wake.test.ts +10 -6
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +2 -5
- package/src/runtime/assistant-event-hub.ts +37 -7
- package/src/runtime/{conversation-stream-state.ts → assistant-stream-state.ts} +132 -58
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/http-router.ts +16 -21
- package/src/runtime/http-types.ts +16 -70
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/pending-interactions.ts +1 -0
- package/src/runtime/routes/__tests__/acp-routes.test.ts +283 -55
- package/src/runtime/routes/__tests__/consolidation-routes.test.ts +265 -2
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +31 -1
- package/src/runtime/routes/__tests__/memory-v2-routes.test.ts +6 -2
- package/src/runtime/routes/__tests__/surface-action-routes.test.ts +5 -4
- package/src/runtime/routes/__tests__/surface-content-routes.test.ts +4 -1
- package/src/runtime/routes/__tests__/tts-routes.test.ts +6 -2
- package/src/runtime/routes/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/app-management-routes.ts +6 -117
- package/src/runtime/routes/app-routes.ts +13 -15
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/attachment-routes.ts +26 -15
- package/src/runtime/routes/avatar-routes.ts +26 -0
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- package/src/runtime/routes/btw-routes.ts +29 -23
- package/src/runtime/routes/consolidation-routes.ts +120 -20
- package/src/runtime/routes/conversation-cli-routes.ts +1 -1
- package/src/runtime/routes/conversation-list-routes.ts +1 -1
- package/src/runtime/routes/conversation-query-routes.ts +3 -1
- package/src/runtime/routes/conversation-routes.ts +372 -185
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- package/src/runtime/routes/documents-routes.ts +4 -0
- package/src/runtime/routes/domain-routes.ts +51 -37
- package/src/runtime/routes/epoch-millis-range.ts +34 -0
- package/src/runtime/routes/events-routes.ts +28 -34
- package/src/runtime/routes/gateway-log-routes.ts +26 -4
- package/src/runtime/routes/heartbeat-routes.ts +32 -12
- package/src/runtime/routes/host-app-control-routes.ts +1 -1
- package/src/runtime/routes/host-cu-routes.ts +1 -1
- package/src/runtime/routes/identity-intro-cache.ts +11 -34
- package/src/runtime/routes/identity-routes.ts +224 -18
- package/src/runtime/routes/image-generation-routes.ts +40 -2
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/index.ts +2 -0
- package/src/runtime/routes/integrations/a2a.ts +12 -10
- package/src/runtime/routes/integrations/slack/__tests__/channel.test.ts +16 -0
- package/src/runtime/routes/integrations/slack/channel.ts +4 -0
- package/src/runtime/routes/integrations/slack/share.ts +27 -6
- package/src/runtime/routes/integrations/telegram.ts +6 -0
- package/src/runtime/routes/integrations/twilio.ts +42 -0
- package/src/runtime/routes/internal-telemetry-routes.ts +88 -0
- package/src/runtime/routes/log-export-routes.ts +8 -0
- package/src/runtime/routes/memory-v2-routes.ts +15 -8
- package/src/runtime/routes/memory-v3-routes.ts +66 -34
- package/src/runtime/routes/oauth-apps.ts +66 -12
- package/src/runtime/routes/oauth-providers.ts +44 -5
- package/src/runtime/routes/platform-routes.ts +81 -5
- package/src/runtime/routes/playground/__tests__/force-compact.test.ts +6 -4
- package/src/runtime/routes/playground/force-compact.ts +1 -1
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/rename-conversation-routes.ts +5 -0
- package/src/runtime/routes/schedule-routes.ts +152 -42
- package/src/runtime/routes/secret-routes.ts +14 -2
- package/src/runtime/routes/skills-routes.ts +43 -14
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/tool-call-confirmation-enrichment.test.ts +161 -0
- package/src/runtime/routes/tool-call-confirmation-enrichment.ts +107 -0
- package/src/runtime/routes/trust-rules-routes.ts +26 -2
- package/src/runtime/routes/tts-routes.ts +35 -0
- package/src/runtime/routes/types.ts +66 -8
- package/src/runtime/routes/usage-routes.ts +47 -39
- package/src/runtime/routes/webhook-routes.ts +41 -2
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/routes/workspace-routes.ts +4 -0
- package/src/runtime/services/__tests__/analyze-conversation.test.ts +6 -0
- package/src/runtime/services/analyze-conversation.ts +2 -2
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/schedule/schedule-store.ts +20 -1
- package/src/schedule/schedule-usage-store.ts +83 -0
- package/src/schedule/scheduler.ts +12 -5
- package/src/signals/cancel.ts +2 -4
- package/src/skills/catalog-files.ts +2 -2
- package/src/skills/catalog-install.ts +3 -0
- package/src/skills/categories-cache.ts +118 -0
- package/src/skills/clawhub-files.ts +1 -2
- package/src/skills/skillssh-files.ts +1 -2
- package/src/subagent/manager.ts +17 -5
- package/src/telemetry/types.ts +29 -1
- package/src/telemetry/usage-telemetry-reporter.test.ts +112 -3
- package/src/telemetry/usage-telemetry-reporter.ts +57 -2
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +7 -1
- package/src/tools/acp/spawn.test.ts +158 -55
- package/src/tools/acp/spawn.ts +47 -72
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +13 -8
- package/src/tools/executor.ts +1 -53
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/network/__tests__/web-search-metadata.test.ts +7 -1
- package/src/tools/network/__tests__/web-search.test.ts +11 -3
- package/src/tools/network/web-search-error.test.ts +248 -0
- package/src/tools/network/web-search-error.ts +267 -0
- package/src/tools/network/web-search.ts +207 -48
- package/src/tools/schedule/create.ts +2 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/terminal/safe-env.ts +10 -1
- package/src/tools/ui-surface/definitions.ts +34 -5
- package/src/tts/__tests__/provider-catalog-consistency.test.ts +85 -1
- package/src/tts/provider-catalog.ts +76 -1
- package/src/util/mutex.ts +47 -0
- package/src/workspace/git-service.ts +1 -42
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/095-bump-heartbeat-interval-30m-to-60m.ts +51 -0
- package/src/workspace/migrations/096-reduce-quality-profile-effort.ts +72 -0
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +117 -0
- package/src/workspace/migrations/registry.ts +6 -0
- package/docs/plugins.md +0 -836
- package/examples/plugins/echo/register.ts +0 -184
- package/src/__tests__/bootstrap-turn-cleanup.test.ts +0 -44
- package/src/__tests__/circuit-breaker-pipeline.test.ts +0 -405
- package/src/__tests__/compaction-pipeline.test.ts +0 -210
- package/src/__tests__/compaction-timeout-recovery.test.ts +0 -251
- package/src/__tests__/empty-response-pipeline.test.ts +0 -423
- package/src/__tests__/llm-call-pipeline.test.ts +0 -287
- package/src/__tests__/memory-retrieval-pipeline.test.ts +0 -418
- package/src/__tests__/persistence-pipeline.test.ts +0 -503
- package/src/__tests__/pipeline-runner.test.ts +0 -564
- package/src/__tests__/title-generate-pipeline.test.ts +0 -211
- package/src/__tests__/token-estimate-pipeline.test.ts +0 -479
- package/src/__tests__/tool-error-pipeline.test.ts +0 -241
- package/src/__tests__/tool-execute-pipeline.test.ts +0 -417
- package/src/__tests__/tool-result-truncate-pipeline.test.ts +0 -341
- package/src/daemon/bootstrap-turn-cleanup.ts +0 -45
- package/src/gallery/default-gallery.ts +0 -1359
- package/src/gallery/gallery-manifest.ts +0 -28
- package/src/home/feature-gate.ts +0 -22
- package/src/memory/v3/provider-blocks.ts +0 -16
- package/src/plugins/defaults/circuit-breaker/middlewares/circuitBreaker.ts +0 -93
- package/src/plugins/defaults/circuit-breaker/package.json +0 -15
- package/src/plugins/defaults/circuit-breaker/register.ts +0 -39
- package/src/plugins/defaults/compaction/middlewares/compaction.ts +0 -25
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/middlewares/emptyResponse.ts +0 -22
- package/src/plugins/defaults/empty-response/terminal.ts +0 -106
- package/src/plugins/defaults/injectors/package.json +0 -15
- package/src/plugins/defaults/llm-call/middlewares/llmCall.ts +0 -17
- package/src/plugins/defaults/llm-call/register.ts +0 -45
- package/src/plugins/defaults/memory-retrieval/middlewares/memoryRetrieval.ts +0 -17
- package/src/plugins/defaults/memory-retrieval/package.json +0 -15
- package/src/plugins/defaults/memory-retrieval/register.ts +0 -181
- package/src/plugins/defaults/overflow-reduce/middlewares/overflowReduce.ts +0 -126
- package/src/plugins/defaults/overflow-reduce/package.json +0 -15
- package/src/plugins/defaults/overflow-reduce/register.ts +0 -42
- package/src/plugins/defaults/persistence/middlewares/persistence.ts +0 -19
- package/src/plugins/defaults/persistence/package.json +0 -15
- package/src/plugins/defaults/persistence/register.ts +0 -38
- package/src/plugins/defaults/persistence/terminal.ts +0 -83
- package/src/plugins/defaults/title-generate/terminal.ts +0 -31
- package/src/plugins/defaults/token-estimate/middlewares/tokenEstimate.ts +0 -23
- package/src/plugins/defaults/token-estimate/package.json +0 -15
- package/src/plugins/defaults/token-estimate/register.ts +0 -34
- package/src/plugins/defaults/token-estimate/terminal.ts +0 -40
- package/src/plugins/defaults/tool-error/middlewares/toolError.ts +0 -21
- package/src/plugins/defaults/tool-error/terminal.ts +0 -47
- package/src/plugins/defaults/tool-execute/middlewares/toolExecute.ts +0 -23
- package/src/plugins/defaults/tool-execute/package.json +0 -15
- package/src/plugins/defaults/tool-execute/register.ts +0 -49
- package/src/plugins/defaults/tool-result-truncate/middlewares/toolResultTruncate.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/types.ts +0 -22
- package/src/skills/category-inference.ts +0 -111
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/capabilities.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/core.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/eval-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/fixtures/live-turns.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/needle.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/snapshot.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/tree.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-eviction.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/working-set-skeleton.test.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/core.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/README.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/assignments.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/core.json +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-x.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-a/topic-y.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/data/leaves/domain-b/topic-z.md +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/needle.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/snapshot.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/working-set.ts +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vellumai/assistant",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.8-dev.202606052332.17fc8ea",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"prepack": "node ../scripts/prepack-bundled-deps.mjs"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@agentclientprotocol/sdk": "0.
|
|
36
|
+
"@agentclientprotocol/sdk": "0.25.0",
|
|
37
37
|
"@anthropic-ai/sdk": "0.78.0",
|
|
38
38
|
"@google/genai": "1.45.0",
|
|
39
39
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
@@ -56,12 +56,24 @@ const RouteBodySchemaSchema = z.any().refine(
|
|
|
56
56
|
{ message: "Expected a Zod schema or a plain JSON Schema object" },
|
|
57
57
|
);
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
/** Explicit `{ contentType, schema }` body for non-JSON media types. */
|
|
60
|
+
const RouteBodyWithContentTypeSchema = z.object({
|
|
60
61
|
contentType: z.string(),
|
|
61
62
|
/** Zod schema OR plain JSON Schema fragment. */
|
|
62
63
|
schema: z.any(),
|
|
63
64
|
});
|
|
64
65
|
|
|
66
|
+
/**
|
|
67
|
+
* A route's request or success-response body: either a bare Zod/JSON schema
|
|
68
|
+
* (advertised as `application/json`) or an explicit `{ contentType, schema }`
|
|
69
|
+
* pair for non-JSON media (e.g. an `application/octet-stream` upload or binary
|
|
70
|
+
* download).
|
|
71
|
+
*/
|
|
72
|
+
const RouteContentBodySchema = z.union([
|
|
73
|
+
RouteBodyWithContentTypeSchema,
|
|
74
|
+
RouteBodySchemaSchema,
|
|
75
|
+
]);
|
|
76
|
+
|
|
65
77
|
const RouteAdditionalResponseSchema = z.object({
|
|
66
78
|
description: z.string(),
|
|
67
79
|
schema: z.any().optional(),
|
|
@@ -79,12 +91,10 @@ const RouteEntrySchema = z.object({
|
|
|
79
91
|
tags: z.array(z.string()).optional(),
|
|
80
92
|
/** Query parameter definitions. */
|
|
81
93
|
queryParams: z.array(RouteQueryParamSchema).optional(),
|
|
82
|
-
/** JSON
|
|
83
|
-
requestBody:
|
|
84
|
-
/**
|
|
85
|
-
|
|
86
|
-
/** JSON Schema for the success response body. */
|
|
87
|
-
responseBody: RouteBodySchemaSchema.optional(),
|
|
94
|
+
/** Request body: a bare Zod/JSON schema (JSON) or `{ contentType, schema }`. */
|
|
95
|
+
requestBody: RouteContentBodySchema.optional(),
|
|
96
|
+
/** Success response body: a bare Zod/JSON schema (JSON) or `{ contentType, schema }`. */
|
|
97
|
+
responseBody: RouteContentBodySchema.optional(),
|
|
88
98
|
/** HTTP status code for the success response. Defaults to "200".
|
|
89
99
|
* Callable responseStatus values (used at runtime) are ignored here. */
|
|
90
100
|
responseStatus: z.preprocess(
|
|
@@ -292,6 +302,11 @@ interface OpenApiParameter {
|
|
|
292
302
|
description?: string;
|
|
293
303
|
}
|
|
294
304
|
|
|
305
|
+
interface OpenApiResponse {
|
|
306
|
+
description: string;
|
|
307
|
+
content?: Record<string, { schema: JSONSchemaObject }>;
|
|
308
|
+
}
|
|
309
|
+
|
|
295
310
|
interface OpenApiOperation {
|
|
296
311
|
operationId: string;
|
|
297
312
|
summary?: string;
|
|
@@ -302,13 +317,27 @@ interface OpenApiOperation {
|
|
|
302
317
|
required: boolean;
|
|
303
318
|
content: Record<string, { schema: JSONSchemaObject }>;
|
|
304
319
|
};
|
|
305
|
-
responses: Record<
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
320
|
+
responses: Record<string, OpenApiResponse>;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Resolve a body declaration (request or success response) into its media type
|
|
325
|
+
* and the schema source to convert. A bare Zod/JSON schema is advertised as
|
|
326
|
+
* `application/json`; the explicit `{ contentType, schema }` form carries its
|
|
327
|
+
* own media type (e.g. `application/octet-stream` for binary bodies).
|
|
328
|
+
*/
|
|
329
|
+
function resolveBodyContent(body: unknown): {
|
|
330
|
+
contentType: string;
|
|
331
|
+
schemaSource: unknown;
|
|
332
|
+
} {
|
|
333
|
+
const hasContentType =
|
|
334
|
+
typeof body === "object" && body !== null && "contentType" in body;
|
|
335
|
+
return {
|
|
336
|
+
contentType: hasContentType
|
|
337
|
+
? (body as { contentType: string }).contentType
|
|
338
|
+
: "application/json",
|
|
339
|
+
schemaSource: hasContentType ? (body as { schema: unknown }).schema : body,
|
|
340
|
+
};
|
|
312
341
|
}
|
|
313
342
|
|
|
314
343
|
interface OpenApiPathItem {
|
|
@@ -420,22 +449,27 @@ function buildSpec(
|
|
|
420
449
|
// that enqueue a job and return immediately set responseStatus: "202"
|
|
421
450
|
// so the generated spec matches the handler's actual response code.
|
|
422
451
|
const successStatus = entry.responseStatus ?? "200";
|
|
452
|
+
let successResponse: OpenApiResponse = {
|
|
453
|
+
description: "Successful response",
|
|
454
|
+
};
|
|
455
|
+
if (entry.responseBody) {
|
|
456
|
+
const { contentType, schemaSource } = resolveBodyContent(
|
|
457
|
+
entry.responseBody,
|
|
458
|
+
);
|
|
459
|
+
successResponse = {
|
|
460
|
+
description: "Successful response",
|
|
461
|
+
content: {
|
|
462
|
+
[contentType]: { schema: toJSONSchemaObject(schemaSource) },
|
|
463
|
+
},
|
|
464
|
+
};
|
|
465
|
+
}
|
|
423
466
|
const operation: OpenApiOperation = {
|
|
424
467
|
operationId,
|
|
425
468
|
...(entry.summary ? { summary: entry.summary } : {}),
|
|
426
469
|
...(entry.description ? { description: entry.description } : {}),
|
|
427
470
|
...(tags ? { tags } : {}),
|
|
428
471
|
responses: {
|
|
429
|
-
[successStatus]:
|
|
430
|
-
? {
|
|
431
|
-
description: "Successful response",
|
|
432
|
-
content: {
|
|
433
|
-
"application/json": {
|
|
434
|
-
schema: toJSONSchemaObject(entry.responseBody),
|
|
435
|
-
},
|
|
436
|
-
},
|
|
437
|
-
}
|
|
438
|
-
: { description: "Successful response" },
|
|
472
|
+
[successStatus]: successResponse,
|
|
439
473
|
},
|
|
440
474
|
};
|
|
441
475
|
|
|
@@ -443,26 +477,19 @@ function buildSpec(
|
|
|
443
477
|
operation.parameters = parameters;
|
|
444
478
|
}
|
|
445
479
|
|
|
446
|
-
//
|
|
447
|
-
//
|
|
448
|
-
//
|
|
449
|
-
//
|
|
450
|
-
if (entry.
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
schema: toJSONSchemaObject(variant.schema, {
|
|
455
|
-
stripRequiredDefaults: true,
|
|
456
|
-
}),
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
operation.requestBody = { required: true, content };
|
|
460
|
-
} else if (entry.requestBody) {
|
|
480
|
+
// A bare Zod/JSON schema is advertised as `application/json`; the
|
|
481
|
+
// explicit `{ contentType, schema }` form lets a route declare a non-JSON
|
|
482
|
+
// body (e.g. a raw `application/octet-stream` upload) so the generated SDK
|
|
483
|
+
// describes a real body type instead of `never`.
|
|
484
|
+
if (entry.requestBody) {
|
|
485
|
+
const { contentType, schemaSource } = resolveBodyContent(
|
|
486
|
+
entry.requestBody,
|
|
487
|
+
);
|
|
461
488
|
operation.requestBody = {
|
|
462
489
|
required: true,
|
|
463
490
|
content: {
|
|
464
|
-
|
|
465
|
-
schema: toJSONSchemaObject(
|
|
491
|
+
[contentType]: {
|
|
492
|
+
schema: toJSONSchemaObject(schemaSource, {
|
|
466
493
|
stripRequiredDefaults: true,
|
|
467
494
|
}),
|
|
468
495
|
},
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Tests for the `agent_loop_exit` instrumentation
|
|
2
|
+
* Tests for the `agent_loop_exit` instrumentation.
|
|
3
3
|
*
|
|
4
4
|
* Coverage targets:
|
|
5
|
-
* 1. **One emit per run** — the idempotency guard fires once, even
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* 1. **One emit per run** — the idempotency guard fires once, even when
|
|
6
|
+
* multiple exit conditions stack and the code path would otherwise
|
|
7
|
+
* reach a second emit site.
|
|
8
8
|
* 2. **Reason matches break site** — for each reachable break site, the
|
|
9
9
|
* emitted reason is the one documented in `AgentLoopExitReason`.
|
|
10
10
|
* 3. **Always the last AgentEvent of terminal runs** — consumers can rely on
|
|
11
11
|
* positional ordering to find it when a run reaches a terminal state.
|
|
12
12
|
*
|
|
13
|
-
* Sites not exercised here (`
|
|
14
|
-
*
|
|
15
|
-
* once we wire up the empty-response pipeline mock.
|
|
13
|
+
* Sites not exercised here (`aborted_via_error`) require deeper provider
|
|
14
|
+
* fakery and are best covered by integration tests.
|
|
16
15
|
*/
|
|
17
|
-
import { describe, expect,
|
|
16
|
+
import { describe, expect, test } from "bun:test";
|
|
18
17
|
|
|
19
18
|
import type {
|
|
20
19
|
AgentEvent,
|
|
@@ -24,7 +23,6 @@ import type {
|
|
|
24
23
|
} from "../agent/loop.js";
|
|
25
24
|
import { AgentLoop, isMaxTokensStopReason } from "../agent/loop.js";
|
|
26
25
|
import type { TurnContext } from "../plugins/types.js";
|
|
27
|
-
import { PluginTimeoutError } from "../plugins/types.js";
|
|
28
26
|
import type {
|
|
29
27
|
Message,
|
|
30
28
|
Provider,
|
|
@@ -103,8 +101,8 @@ const userMessage: Message = {
|
|
|
103
101
|
};
|
|
104
102
|
|
|
105
103
|
// A turn context whose `contextWindowManager.maybeCompact` returns a canned
|
|
106
|
-
// result, so the loop's
|
|
107
|
-
//
|
|
104
|
+
// result, so the loop's compaction call runs without the real orchestrator
|
|
105
|
+
// machinery.
|
|
108
106
|
function fakeCompactionTurnContext(result: {
|
|
109
107
|
compacted: boolean;
|
|
110
108
|
exhausted: boolean;
|
|
@@ -120,22 +118,6 @@ function fakeCompactionTurnContext(result: {
|
|
|
120
118
|
} as unknown as TurnContext;
|
|
121
119
|
}
|
|
122
120
|
|
|
123
|
-
// A turn context whose compaction call times out, exercising the loop's
|
|
124
|
-
// PluginTimeoutError handling.
|
|
125
|
-
function timeoutCompactionTurnContext(): TurnContext {
|
|
126
|
-
return {
|
|
127
|
-
requestId: "req-compact",
|
|
128
|
-
conversationId: "conv-compact",
|
|
129
|
-
turnIndex: 0,
|
|
130
|
-
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
131
|
-
contextWindowManager: {
|
|
132
|
-
maybeCompact: async () => {
|
|
133
|
-
throw new PluginTimeoutError("compaction", "default-compaction", 1);
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
} as unknown as TurnContext;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
121
|
function lastExitEvent(
|
|
140
122
|
events: AgentEvent[],
|
|
141
123
|
): Extract<AgentEvent, { type: "agent_loop_exit" }> | undefined {
|
|
@@ -379,82 +361,44 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
379
361
|
toolExecutor: toolExecutor,
|
|
380
362
|
});
|
|
381
363
|
|
|
382
|
-
let prepared = false;
|
|
383
|
-
let appliedResult = false;
|
|
384
364
|
let reinjected = false;
|
|
365
|
+
const events: AgentEvent[] = [];
|
|
385
366
|
const compaction: MidLoopCompaction = {
|
|
386
|
-
|
|
387
|
-
prepared = true;
|
|
388
|
-
return { rawHistory: history, options: undefined };
|
|
389
|
-
},
|
|
390
|
-
applyResult: async () => {
|
|
391
|
-
appliedResult = true;
|
|
392
|
-
},
|
|
393
|
-
reinject: async () => {
|
|
367
|
+
postCompactionHook: async () => {
|
|
394
368
|
reinjected = true;
|
|
395
369
|
return [userMessage];
|
|
396
370
|
},
|
|
397
371
|
};
|
|
398
372
|
|
|
399
373
|
// WHEN the in-loop budget gate trips at the checkpoint
|
|
400
|
-
const result = await loop.run(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
374
|
+
const result = await loop.run(
|
|
375
|
+
[userMessage],
|
|
376
|
+
(event) => {
|
|
377
|
+
events.push(event);
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
resolveContextWindow: () => ({
|
|
381
|
+
maxInputTokens: 10,
|
|
382
|
+
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
383
|
+
}),
|
|
384
|
+
compaction,
|
|
385
|
+
turnContext: fakeCompactionTurnContext({
|
|
386
|
+
compacted: true,
|
|
387
|
+
exhausted: false,
|
|
388
|
+
}),
|
|
389
|
+
},
|
|
390
|
+
);
|
|
411
391
|
|
|
412
392
|
// THEN the loop runs the compaction ceremony in place and continues to a
|
|
413
|
-
// clean exit instead of yielding for budget.
|
|
414
|
-
|
|
415
|
-
expect(
|
|
393
|
+
// clean exit instead of yielding for budget. The durable commit is
|
|
394
|
+
// signalled via a `compaction_completed` event rather than an injected hook.
|
|
395
|
+
expect(events.some((event) => event.type === "compaction_completed")).toBe(
|
|
396
|
+
true,
|
|
397
|
+
);
|
|
416
398
|
expect(reinjected).toBe(true);
|
|
417
399
|
expect(result.exitReason).not.toBe("budget");
|
|
418
400
|
});
|
|
419
401
|
|
|
420
|
-
test("yields 'budget' when inline compaction times out", async () => {
|
|
421
|
-
const { provider } = createMockProvider([
|
|
422
|
-
toolUseResponse("t1", "read_file", { path: "/a.txt" }),
|
|
423
|
-
textResponse("never reached"),
|
|
424
|
-
]);
|
|
425
|
-
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
426
|
-
const loop = new AgentLoop(provider, "system", {
|
|
427
|
-
tools: dummyTools,
|
|
428
|
-
toolExecutor: toolExecutor,
|
|
429
|
-
});
|
|
430
|
-
|
|
431
|
-
const compaction: MidLoopCompaction = {
|
|
432
|
-
prepare: (history) => ({ rawHistory: history, options: undefined }),
|
|
433
|
-
applyResult: async () => {},
|
|
434
|
-
reinject: async () => {
|
|
435
|
-
throw new Error("reinject must not run after a timeout");
|
|
436
|
-
},
|
|
437
|
-
};
|
|
438
|
-
const recordOutcomeSpy = spyOn(loop.compactionCircuit, "recordOutcome");
|
|
439
|
-
|
|
440
|
-
// WHEN the compaction pipeline throws a PluginTimeoutError
|
|
441
|
-
const result = await loop.run([userMessage], () => {}, {
|
|
442
|
-
resolveContextWindow: () => ({
|
|
443
|
-
maxInputTokens: 10,
|
|
444
|
-
overflowRecovery: { enabled: true, safetyMarginRatio: 0 },
|
|
445
|
-
}),
|
|
446
|
-
compaction,
|
|
447
|
-
turnContext: timeoutCompactionTurnContext(),
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
// THEN the loop records the timeout as a compaction failure against its
|
|
451
|
-
// own circuit breaker, and yields for budget so the orchestrator can
|
|
452
|
-
// escalate.
|
|
453
|
-
expect(recordOutcomeSpy).toHaveBeenCalledTimes(1);
|
|
454
|
-
expect(recordOutcomeSpy.mock.calls[0]?.[1]).toBe(true);
|
|
455
|
-
expect(result.exitReason).toBe("budget");
|
|
456
|
-
});
|
|
457
|
-
|
|
458
402
|
test("yields 'budget' when inline compaction reports exhausted", async () => {
|
|
459
403
|
const { provider } = createMockProvider([
|
|
460
404
|
toolUseResponse("t1", "read_file", { path: "/a.txt" }),
|
|
@@ -467,10 +411,8 @@ describe("AgentLoop exit-reason instrumentation", () => {
|
|
|
467
411
|
});
|
|
468
412
|
|
|
469
413
|
const compaction: MidLoopCompaction = {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
reinject: async () => {
|
|
473
|
-
throw new Error("reinject must not run when exhausted");
|
|
414
|
+
postCompactionHook: async () => {
|
|
415
|
+
throw new Error("postCompactionHook must not run when exhausted");
|
|
474
416
|
},
|
|
475
417
|
};
|
|
476
418
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Integration tests for the agent loop's `provider_error` recording path.
|
|
3
3
|
*
|
|
4
|
-
* When the
|
|
4
|
+
* When the provider call throws (provider rejected the request before
|
|
5
5
|
* returning a usable response), the loop must emit a `provider_error` event
|
|
6
6
|
* carrying the loop-level raw request and the thrown error so downstream
|
|
7
7
|
* consumers can persist an `llm_request_logs` row. Without this, rejected
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
1
|
+
import { beforeEach, describe, expect, test } from "bun:test";
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
AgentEvent,
|
|
@@ -6,90 +6,24 @@ import type {
|
|
|
6
6
|
CheckpointInfo,
|
|
7
7
|
} from "../agent/loop.js";
|
|
8
8
|
import { AgentLoop } from "../agent/loop.js";
|
|
9
|
+
import { resetPluginRegistryAndRegisterDefaults } from "../plugins/defaults/index.js";
|
|
9
10
|
import type {
|
|
10
11
|
ContentBlock,
|
|
11
12
|
Message,
|
|
12
13
|
Provider,
|
|
13
14
|
ProviderResponse,
|
|
14
|
-
SendMessageOptions,
|
|
15
15
|
ToolDefinition,
|
|
16
16
|
} from "../providers/types.js";
|
|
17
|
+
import {
|
|
18
|
+
createMockProvider,
|
|
19
|
+
textResponse,
|
|
20
|
+
toolUseResponse,
|
|
21
|
+
} from "./helpers/mock-provider.js";
|
|
17
22
|
|
|
18
23
|
// ---------------------------------------------------------------------------
|
|
19
24
|
// Helpers
|
|
20
25
|
// ---------------------------------------------------------------------------
|
|
21
26
|
|
|
22
|
-
/** A mock provider that returns pre-configured responses in sequence. */
|
|
23
|
-
function createMockProvider(responses: ProviderResponse[]): {
|
|
24
|
-
provider: Provider;
|
|
25
|
-
calls: {
|
|
26
|
-
messages: Message[];
|
|
27
|
-
tools?: ToolDefinition[];
|
|
28
|
-
systemPrompt?: string;
|
|
29
|
-
options?: SendMessageOptions;
|
|
30
|
-
}[];
|
|
31
|
-
} {
|
|
32
|
-
const calls: {
|
|
33
|
-
messages: Message[];
|
|
34
|
-
tools?: ToolDefinition[];
|
|
35
|
-
systemPrompt?: string;
|
|
36
|
-
options?: SendMessageOptions;
|
|
37
|
-
}[] = [];
|
|
38
|
-
let callIndex = 0;
|
|
39
|
-
|
|
40
|
-
const provider: Provider = {
|
|
41
|
-
name: "mock",
|
|
42
|
-
async sendMessage(
|
|
43
|
-
messages: Message[],
|
|
44
|
-
options?: SendMessageOptions,
|
|
45
|
-
): Promise<ProviderResponse> {
|
|
46
|
-
calls.push({
|
|
47
|
-
messages: [...messages],
|
|
48
|
-
tools: options?.tools,
|
|
49
|
-
systemPrompt: options?.systemPrompt,
|
|
50
|
-
options,
|
|
51
|
-
});
|
|
52
|
-
const response = responses[callIndex] ?? responses[responses.length - 1];
|
|
53
|
-
callIndex++;
|
|
54
|
-
|
|
55
|
-
// Emit streaming events if the response has text blocks
|
|
56
|
-
if (options?.onEvent) {
|
|
57
|
-
for (const block of response.content) {
|
|
58
|
-
if (block.type === "text") {
|
|
59
|
-
options.onEvent({ type: "text_delta", text: block.text });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return response;
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
return { provider, calls };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function textResponse(text: string): ProviderResponse {
|
|
72
|
-
return {
|
|
73
|
-
content: [{ type: "text", text }],
|
|
74
|
-
model: "mock-model",
|
|
75
|
-
usage: { inputTokens: 10, outputTokens: 5 },
|
|
76
|
-
stopReason: "end_turn",
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function toolUseResponse(
|
|
81
|
-
id: string,
|
|
82
|
-
name: string,
|
|
83
|
-
input: Record<string, unknown>,
|
|
84
|
-
): ProviderResponse {
|
|
85
|
-
return {
|
|
86
|
-
content: [{ type: "tool_use", id, name, input }],
|
|
87
|
-
model: "mock-model",
|
|
88
|
-
usage: { inputTokens: 10, outputTokens: 5 },
|
|
89
|
-
stopReason: "tool_use",
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
|
|
93
27
|
const dummyTools: ToolDefinition[] = [
|
|
94
28
|
{
|
|
95
29
|
name: "read_file",
|
|
@@ -112,6 +46,13 @@ function collectEvents(events: AgentEvent[]): (event: AgentEvent) => void {
|
|
|
112
46
|
// ---------------------------------------------------------------------------
|
|
113
47
|
|
|
114
48
|
describe("AgentLoop", () => {
|
|
49
|
+
// The agent loop fires the `post-tool-use` hook for tool-result
|
|
50
|
+
// truncation, which only runs when the default plugin is registered.
|
|
51
|
+
// Register the defaults so the loop behaves as it does in production.
|
|
52
|
+
beforeEach(() => {
|
|
53
|
+
resetPluginRegistryAndRegisterDefaults();
|
|
54
|
+
});
|
|
55
|
+
|
|
115
56
|
// 1. Basic text response
|
|
116
57
|
test("returns history with assistant message for simple text response", async () => {
|
|
117
58
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
@@ -1569,9 +1510,11 @@ describe("AgentLoop", () => {
|
|
|
1569
1510
|
expect(textBlock!.text).toBe("Normal response with no placeholders.");
|
|
1570
1511
|
});
|
|
1571
1512
|
|
|
1572
|
-
// Tool error retry
|
|
1573
|
-
//
|
|
1574
|
-
|
|
1513
|
+
// Tool error retry coaching — when a tool returns isError: true, the coaching
|
|
1514
|
+
// notice is appended as a separate text block in the tool-result user message
|
|
1515
|
+
// (not into the tool_result content), nudging the LLM to retry instead of
|
|
1516
|
+
// ending the turn while keeping the tool's actual output clean.
|
|
1517
|
+
test("appends retry coaching as a separate block when a tool returns an error", async () => {
|
|
1575
1518
|
const { provider, calls } = createMockProvider([
|
|
1576
1519
|
// First turn: LLM calls a tool that errors
|
|
1577
1520
|
toolUseResponse("t1", "read_file", { path: "/missing.txt" }),
|
|
@@ -1606,7 +1549,8 @@ describe("AgentLoop", () => {
|
|
|
1606
1549
|
// Provider should have been called 3 times (error -> retry -> final text)
|
|
1607
1550
|
expect(calls).toHaveLength(3);
|
|
1608
1551
|
|
|
1609
|
-
// The second call's messages should
|
|
1552
|
+
// The second call's messages should carry the retry coaching as a separate
|
|
1553
|
+
// text block, with the tool_result's own content left untouched.
|
|
1610
1554
|
const secondCallMessages = calls[1].messages;
|
|
1611
1555
|
const toolResultMessage = secondCallMessages[secondCallMessages.length - 1];
|
|
1612
1556
|
expect(toolResultMessage.role).toBe("user");
|
|
@@ -1617,7 +1561,14 @@ describe("AgentLoop", () => {
|
|
|
1617
1561
|
);
|
|
1618
1562
|
expect(retryNudge).toBeDefined();
|
|
1619
1563
|
|
|
1620
|
-
// The
|
|
1564
|
+
// The errored tool_result itself stays the tool's actual output.
|
|
1565
|
+
const erroredToolResult = toolResultMessage.content.find(
|
|
1566
|
+
(b): b is Extract<ContentBlock, { type: "tool_result" }> =>
|
|
1567
|
+
b.type === "tool_result",
|
|
1568
|
+
);
|
|
1569
|
+
expect(erroredToolResult?.content).not.toContain("looks recoverable");
|
|
1570
|
+
|
|
1571
|
+
// The third call should NOT have the retry coaching (successful tool result)
|
|
1621
1572
|
const thirdCallMessages = calls[2].messages;
|
|
1622
1573
|
const thirdToolResultMessage =
|
|
1623
1574
|
thirdCallMessages[thirdCallMessages.length - 1];
|
|
@@ -1628,8 +1579,9 @@ describe("AgentLoop", () => {
|
|
|
1628
1579
|
expect(noRetryNudge).toBeUndefined();
|
|
1629
1580
|
});
|
|
1630
1581
|
|
|
1631
|
-
// Retry
|
|
1632
|
-
|
|
1582
|
+
// Retry coaching stops after a tool fails 3 times in a row — past that the
|
|
1583
|
+
// error is likely unrecoverable and further coaching only burns tokens.
|
|
1584
|
+
test("stops appending retry coaching after 3 consecutive failures of a tool", async () => {
|
|
1633
1585
|
const { provider, calls } = createMockProvider([
|
|
1634
1586
|
// 4 consecutive error turns, then final text
|
|
1635
1587
|
toolUseResponse("t1", "read_file", { path: "/a" }),
|
|
@@ -1654,23 +1606,21 @@ describe("AgentLoop", () => {
|
|
|
1654
1606
|
|
|
1655
1607
|
expect(calls).toHaveLength(5);
|
|
1656
1608
|
|
|
1657
|
-
// Helper to check if a call's last user message has the retry
|
|
1609
|
+
// Helper to check if a call's last user message has the retry coaching
|
|
1610
|
+
// (a separate text block, not part of the tool_result content).
|
|
1658
1611
|
const hasRetryNudge = (callIndex: number): boolean => {
|
|
1659
1612
|
const msgs = calls[callIndex].messages;
|
|
1660
1613
|
const lastMsg = msgs[msgs.length - 1];
|
|
1661
1614
|
return lastMsg.content.some(
|
|
1662
|
-
(b) =>
|
|
1663
|
-
b.type === "text" &&
|
|
1664
|
-
"text" in b &&
|
|
1665
|
-
(b as { text: string }).text.includes("looks recoverable"),
|
|
1615
|
+
(b) => b.type === "text" && b.text.includes("looks recoverable"),
|
|
1666
1616
|
);
|
|
1667
1617
|
};
|
|
1668
1618
|
|
|
1669
|
-
// Turns 1-3 should have the
|
|
1619
|
+
// Turns 1-3 should have the coaching
|
|
1670
1620
|
expect(hasRetryNudge(1)).toBe(true);
|
|
1671
1621
|
expect(hasRetryNudge(2)).toBe(true);
|
|
1672
1622
|
expect(hasRetryNudge(3)).toBe(true);
|
|
1673
|
-
// Turn 4 should NOT have the
|
|
1623
|
+
// Turn 4 should NOT have the coaching (exceeded limit)
|
|
1674
1624
|
expect(hasRetryNudge(4)).toBe(false);
|
|
1675
1625
|
});
|
|
1676
1626
|
|