@vellumai/assistant 0.8.8 → 0.8.9-staging.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +6 -6
- package/bun.lock +2 -2
- package/examples/plugins/echo/README.md +61 -60
- 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/skill-host.ts +7 -6
- package/openapi.yaml +235 -6
- package/package.json +2 -2
- package/src/__tests__/agent-loop-callsite-precedence.test.ts +69 -14
- package/src/__tests__/agent-loop-exit-reason.test.ts +204 -144
- package/src/__tests__/agent-loop-mutable-latest-user-message.test.ts +50 -35
- package/src/__tests__/agent-loop-output-hooks.test.ts +357 -0
- package/src/__tests__/agent-loop-override-profile.test.ts +25 -6
- package/src/__tests__/agent-loop-provider-error-recording.test.ts +41 -21
- package/src/__tests__/agent-loop-thinking.test.ts +36 -20
- package/src/__tests__/agent-loop.test.ts +441 -96
- package/src/__tests__/agent-wake-disk-pressure-callsite.test.ts +14 -14
- package/src/__tests__/agent-wake-override-profile.test.ts +17 -21
- package/src/__tests__/anthropic-provider.test.ts +1 -1
- package/src/__tests__/app-builder-tool-scripts.test.ts +21 -0
- package/src/__tests__/app-control-flow.test.ts +1 -1
- package/src/__tests__/app-dir-path-guard.test.ts +1 -0
- package/src/__tests__/app-executors.test.ts +132 -0
- package/src/__tests__/approval-cascade.test.ts +5 -4
- package/src/__tests__/approval-routes-http.test.ts +4 -1
- package/src/__tests__/background-workers-disk-pressure.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__/compaction-circuit.test.ts +258 -0
- package/src/__tests__/compaction-direct.test.ts +132 -0
- package/src/__tests__/compaction-events.test.ts +5 -5
- package/src/__tests__/compactor-web-search-strip.test.ts +213 -0
- package/src/__tests__/context-overflow-reducer.test.ts +1 -1
- package/src/__tests__/conversation-abort-tool-results.test.ts +6 -4
- package/src/__tests__/conversation-agent-loop-disk-pressure.test.ts +7 -10
- package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +78 -119
- package/src/__tests__/conversation-agent-loop-overflow.test.ts +142 -218
- package/src/__tests__/conversation-agent-loop.test.ts +297 -586
- package/src/__tests__/conversation-clean-command.test.ts +5 -2
- package/src/__tests__/conversation-confirmation-signals.test.ts +5 -4
- package/src/__tests__/conversation-crud-inference-profile.test.ts +7 -9
- package/src/__tests__/conversation-history-web-search.test.ts +1 -1
- package/src/__tests__/conversation-process-app-control-preactivation.test.ts +4 -4
- package/src/__tests__/conversation-process-callsite.test.ts +14 -14
- package/src/__tests__/conversation-provider-retry-repair.test.ts +70 -65
- package/src/__tests__/conversation-queue.test.ts +9 -9
- package/src/__tests__/conversation-runtime-assembly.test.ts +923 -231
- package/src/__tests__/conversation-runtime-workspace.test.ts +115 -20
- package/src/__tests__/conversation-slash-queue.test.ts +6 -4
- package/src/__tests__/conversation-slash-unknown.test.ts +6 -4
- package/src/__tests__/conversation-speed-override.test.ts +10 -9
- package/src/__tests__/conversation-starter-routes.test.ts +14 -6
- package/src/__tests__/conversation-workspace-cache-state.test.ts +23 -20
- package/src/__tests__/conversation-workspace-injection.test.ts +68 -6
- package/src/__tests__/conversation-workspace-tool-tracking.test.ts +14 -11
- package/src/__tests__/conversations-import-system-filter.test.ts +101 -0
- package/src/__tests__/credential-security-invariants.test.ts +0 -1
- package/src/__tests__/db-acp-history.test.ts +101 -0
- package/src/__tests__/dynamic-page-surface.test.ts +31 -0
- package/src/__tests__/empty-response-hook.test.ts +1 -1
- package/src/__tests__/file-write-tool.test.ts +63 -0
- package/src/__tests__/gateway-only-guard.test.ts +12 -2
- 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__/history-repair-hook.test.ts +1 -1
- 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__/inference-profile-reaper.test.ts +62 -0
- package/src/__tests__/inference-profile-session-handler.test.ts +86 -0
- package/src/__tests__/injector-background-turn.test.ts +13 -23
- package/src/__tests__/injector-chain.test.ts +268 -44
- package/src/__tests__/injector-disk-pressure.test.ts +210 -52
- package/src/__tests__/injector-document-comments.test.ts +97 -114
- package/src/__tests__/injector-pkb-v2-silenced.test.ts +2 -2
- package/src/__tests__/injector-v3-suppression.test.ts +4 -4
- package/src/__tests__/list-messages-client-message-id.test.ts +91 -0
- package/src/__tests__/list-messages-hidden-metadata.test.ts +38 -0
- package/src/__tests__/memory-retrieval-hook.test.ts +131 -26
- package/src/__tests__/memory-v2-static-injector.test.ts +86 -8
- package/src/__tests__/parallel-tool.benchmark.test.ts +35 -8
- package/src/__tests__/plugin-api-shim.test.ts +6 -9
- package/src/__tests__/plugin-bootstrap.test.ts +12 -23
- package/src/__tests__/plugin-registry.test.ts +3 -49
- package/src/__tests__/plugin-types.test.ts +0 -70
- package/src/__tests__/pre-model-call-sanitize.test.ts +109 -0
- package/src/__tests__/reaction-persistence.test.ts +1 -1
- package/src/__tests__/send-endpoint-busy.test.ts +4 -1
- package/src/__tests__/skill-feature-flags-integration.test.ts +33 -0
- package/src/__tests__/steer-tool-repair.test.ts +1 -1
- package/src/__tests__/subagent-call-site-routing.test.ts +1 -1
- package/src/__tests__/subagent-detail.test.ts +25 -7
- 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__/title-generate-hook.test.ts +1 -1
- package/src/__tests__/tool-error-hook.test.ts +1 -1
- package/src/__tests__/tool-result-truncate-hook.test.ts +1 -1
- package/src/__tests__/user-plugin-loader.test.ts +54 -286
- 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 +106 -0
- package/src/acp/__tests__/prepare-agent-env.test.ts +97 -0
- package/src/acp/__tests__/session-manager-persistence.test.ts +95 -28
- package/src/acp/__tests__/session-manager-resume.test.ts +888 -0
- package/src/acp/agent-process.ts +61 -1
- package/src/acp/auto-install.test.ts +280 -0
- package/src/acp/auto-install.ts +232 -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 +80 -27
- package/src/acp/resolve-agent.test.ts +225 -9
- package/src/acp/resolve-agent.ts +122 -17
- package/src/acp/resume-hint.ts +23 -0
- package/src/acp/session-manager.ts +507 -73
- package/src/agent/compaction-circuit.ts +60 -102
- package/src/agent/loop.ts +414 -248
- package/src/api/responses/conversation-message.ts +14 -1
- package/src/approvals/guardian-request-resolvers.ts +1 -1
- package/src/background-wake/next-wake.ts +1 -0
- package/src/cli/commands/db/__tests__/repair.test.ts +3 -1
- package/src/cli/commands/plugins.ts +43 -37
- package/src/cli/lib/__tests__/install-from-github.test.ts +429 -111
- package/src/cli/lib/__tests__/plugin-catalog-cache.test.ts +196 -0
- package/src/cli/lib/__tests__/plugin-details.test.ts +372 -0
- package/src/cli/lib/__tests__/plugin-marketplace.test.ts +220 -0
- package/src/cli/lib/__tests__/search-plugins.test.ts +226 -32
- package/src/cli/lib/install-from-github.ts +464 -55
- package/src/cli/lib/plugin-catalog-cache.ts +84 -0
- package/src/cli/lib/plugin-details.ts +409 -0
- package/src/cli/lib/plugin-marketplace.ts +197 -0
- package/src/cli/lib/search-plugins.ts +195 -29
- 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/bundled-skills/acp/SKILL.md +85 -33
- package/src/config/bundled-skills/acp/TOOLS.json +4 -4
- package/src/config/bundled-skills/app-builder/SKILL.md +224 -381
- package/src/config/bundled-skills/app-builder/TOOLS.json +72 -2
- 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/tools/app-list.ts +62 -0
- package/src/config/bundled-skills/app-builder/tools/app-update.ts +18 -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-tool-registry.ts +4 -0
- package/src/config/call-site-defaults.ts +0 -2
- package/src/config/feature-flag-registry.json +15 -6
- package/src/config/schemas/call-site-catalog.ts +0 -14
- package/src/config/schemas/heartbeat.ts +9 -0
- package/src/config/schemas/llm.ts +0 -2
- package/src/context/compactor.ts +22 -4
- package/src/context/strip-injections.ts +8 -2
- package/src/context/window-manager.ts +27 -13
- package/src/daemon/conversation-agent-loop-handlers.ts +10 -35
- package/src/daemon/conversation-agent-loop.ts +175 -1055
- package/src/daemon/conversation-lifecycle.ts +11 -255
- package/src/daemon/conversation-process.ts +8 -136
- package/src/daemon/conversation-registry.ts +159 -0
- package/src/daemon/conversation-runtime-assembly.ts +293 -392
- package/src/daemon/conversation-store.ts +9 -90
- package/src/daemon/conversation-surfaces.ts +24 -8
- package/src/daemon/conversation-workspace.ts +17 -0
- package/src/daemon/conversation.ts +404 -57
- package/src/daemon/disk-pressure-policy.ts +0 -1
- package/src/daemon/external-plugins-bootstrap.ts +14 -19
- package/src/daemon/handlers/conversations.ts +3 -1
- package/src/daemon/handlers/skills.ts +4 -1
- package/src/daemon/host-proxy-preactivation.ts +1 -3
- package/src/daemon/lifecycle.ts +21 -7
- package/src/daemon/server.ts +2 -0
- package/src/daemon/wake-conversation-ops.ts +269 -0
- package/src/embedded/plugin-api.ts +2 -2
- package/src/export/__tests__/transcript-formatter.test.ts +5 -0
- 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/ipc/__tests__/browser-ipc.test.ts +1 -1
- package/src/ipc/__tests__/ui-request-route.test.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/memory/__tests__/jobs-worker-v2-schedule.test.ts +87 -0
- package/src/memory/conversation-crud.ts +29 -19
- package/src/memory/conversation-starter-checkpoints.ts +1 -0
- package/src/memory/db-init.ts +2 -0
- package/src/memory/job-handlers/conversation-starters.ts +13 -2
- package/src/memory/jobs/__tests__/embed-concept-page.test.ts +5 -4
- package/src/memory/jobs-worker.ts +25 -1
- package/src/memory/migrations/272-acp-session-history-cwd.ts +36 -0
- package/src/memory/migrations/index.ts +1 -0
- package/src/memory/schema/acp.ts +4 -0
- package/src/memory/v2/__tests__/consolidation-job.test.ts +3 -3
- package/src/memory/v2/consolidation-job.ts +13 -4
- package/src/plugin-api/constants.ts +4 -0
- package/src/plugin-api/index.ts +6 -5
- package/src/plugin-api/types.ts +75 -0
- package/src/plugins/defaults/compaction/compact.ts +59 -0
- package/src/{daemon → plugins/defaults/compaction}/context-overflow-reducer.ts +7 -7
- package/src/plugins/defaults/compaction/manager-store.ts +57 -0
- package/src/plugins/defaults/compaction/package.json +1 -2
- package/src/plugins/defaults/empty-response/package.json +0 -1
- package/src/plugins/defaults/history-repair/package.json +0 -1
- package/src/plugins/defaults/index.ts +135 -26
- package/src/plugins/defaults/memory-retrieval/hooks/post-compact.ts +100 -52
- package/src/plugins/defaults/memory-retrieval/hooks/user-prompt-submit-temp.ts +184 -74
- package/src/plugins/defaults/memory-retrieval/injector-chain.ts +2 -2
- package/src/plugins/defaults/{injectors/register.ts → memory-retrieval/injectors.ts} +148 -73
- package/src/plugins/defaults/memory-retrieval/unified-turn-context.ts +223 -0
- 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__/live-integration.test.ts +9 -6
- 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 +8 -5
- 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 +10 -5
- 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 +5 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/shadow-plugin.test.ts +16 -17
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/__tests__/types.test.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/assign.ts +9 -5
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/capabilities.ts +5 -2
- 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/{memory/v3 → plugins/defaults/memory-v3-shadow}/maintain-job.ts +15 -8
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/orchestrate.ts +2 -2
- package/src/plugins/defaults/memory-v3-shadow/package.json +14 -0
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/page-content.ts +2 -2
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/provider-blocks.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/reconcile.ts +7 -3
- 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 +5 -5
- 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 +7 -7
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/shadow-plugin.ts +32 -94
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/tree.ts +1 -1
- package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/types.ts +1 -1
- package/src/plugins/defaults/title-generate/package.json +0 -1
- package/src/plugins/defaults/tool-error/package.json +0 -1
- package/src/plugins/defaults/tool-result-truncate/package.json +0 -1
- package/src/plugins/pipeline.ts +6 -293
- package/src/plugins/registry.ts +9 -37
- package/src/plugins/types.ts +76 -381
- package/src/plugins/user-loader.ts +30 -127
- package/src/prompts/__tests__/system-prompt.test.ts +6 -0
- package/src/prompts/templates/BOOTSTRAP-ACTIVATION-RAIL.md +35 -3
- package/src/runtime/__tests__/agent-wake.test.ts +555 -691
- package/src/runtime/__tests__/interactive-ui.test.ts +1 -1
- package/src/runtime/agent-wake.ts +108 -209
- package/src/runtime/assistant-event-hub.ts +1 -1
- package/src/runtime/channel-approvals.ts +1 -1
- package/src/runtime/interactive-ui.ts +1 -1
- package/src/runtime/routes/__tests__/acp-routes.test.ts +315 -55
- package/src/runtime/routes/__tests__/conversation-list-routes.test.ts +1 -1
- package/src/runtime/routes/__tests__/plugins-routes.test.ts +423 -73
- 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/acp-routes.test.ts +89 -25
- package/src/runtime/routes/acp-routes.ts +81 -29
- package/src/runtime/routes/approval-routes.ts +1 -1
- package/src/runtime/routes/browser-routes.ts +1 -1
- package/src/runtime/routes/browser-tabs-routes.ts +6 -10
- 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 +1 -1
- package/src/runtime/routes/conversation-routes.ts +28 -2
- package/src/runtime/routes/conversation-starter-routes.ts +13 -7
- package/src/runtime/routes/conversations-import-routes.ts +24 -7
- 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-routes.ts +18 -3
- package/src/runtime/routes/inbound-message-handler.ts +1 -1
- package/src/runtime/routes/inference-profile-session-handler.ts +11 -0
- package/src/runtime/routes/inference-profile-session-reaper.ts +6 -0
- package/src/runtime/routes/memory-v3-routes.ts +16 -6
- package/src/runtime/routes/playground/helpers.ts +1 -1
- package/src/runtime/routes/plugins-routes.ts +337 -35
- package/src/runtime/routes/surface-conversation-resolver.ts +4 -3
- package/src/runtime/routes/work-items-routes.ts +2 -4
- package/src/runtime/services/conversation-serializer.ts +1 -1
- package/src/signals/cancel.ts +2 -4
- package/src/subagent/manager.ts +21 -5
- package/src/tools/acp/context.ts +20 -0
- package/src/tools/acp/list-agents.test.ts +8 -2
- package/src/tools/acp/spawn.test.ts +176 -195
- package/src/tools/acp/spawn.ts +37 -172
- package/src/tools/acp/steer.test.ts +105 -8
- package/src/tools/acp/steer.ts +48 -17
- package/src/tools/apps/executors.ts +166 -50
- package/src/tools/filesystem/write.ts +34 -0
- package/src/tools/subagent/spawn.ts +2 -4
- package/src/tools/ui-surface/definitions.ts +25 -5
- package/src/workspace/migrations/051-seed-conversation-summarization-callsite.ts +4 -5
- package/src/workspace/migrations/097-enable-adaptive-thinking-managed-profiles.ts +69 -45
- package/docs/plugins.md +0 -832
- package/examples/plugins/echo/register.ts +0 -143
- 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__/overflow-reduce-pipeline.test.ts +0 -667
- package/src/__tests__/pipeline-runner.test.ts +0 -554
- package/src/__tests__/plugin-external-api.test.ts +0 -68
- package/src/daemon/wake-target-adapter.ts +0 -253
- 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/register.ts +0 -35
- package/src/plugins/defaults/compaction/terminal.ts +0 -73
- package/src/plugins/defaults/empty-response/register.ts +0 -23
- package/src/plugins/defaults/history-repair/register.ts +0 -24
- 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/title-generate/register.ts +0 -35
- package/src/plugins/defaults/tool-error/register.ts +0 -23
- package/src/plugins/defaults/tool-result-truncate/register.ts +0 -24
- package/src/plugins/external-api.ts +0 -104
- package/src/proactive-artifact/aux-message-injector.ts +0 -97
- package/src/proactive-artifact/decision.test.ts +0 -226
- package/src/proactive-artifact/decision.ts +0 -165
- package/src/proactive-artifact/index.ts +0 -7
- package/src/proactive-artifact/job.test.ts +0 -962
- package/src/proactive-artifact/job.ts +0 -372
- package/src/proactive-artifact/message-copy.ts +0 -58
- package/src/proactive-artifact/trigger-state.test.ts +0 -286
- package/src/proactive-artifact/trigger-state.ts +0 -123
- /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__/health.test.ts +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__/provider-blocks.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__/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}/health.ts +0 -0
- /package/src/{memory/v3 → plugins/defaults/memory-v3-shadow}/llm-retry.ts +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
|
@@ -56,10 +56,18 @@ describe("AgentLoop", () => {
|
|
|
56
56
|
// 1. Basic text response
|
|
57
57
|
test("returns history with assistant message for simple text response", async () => {
|
|
58
58
|
const { provider } = createMockProvider([textResponse("Hi there!")]);
|
|
59
|
-
const loop = new AgentLoop(
|
|
59
|
+
const loop = new AgentLoop({
|
|
60
|
+
provider: provider,
|
|
61
|
+
systemPrompt: "system prompt",
|
|
62
|
+
conversationId: "test-conversation",
|
|
63
|
+
});
|
|
60
64
|
|
|
61
65
|
const events: AgentEvent[] = [];
|
|
62
|
-
const { history } = await loop.run(
|
|
66
|
+
const { history } = await loop.run({
|
|
67
|
+
messages: [userMessage],
|
|
68
|
+
onEvent: collectEvents(events),
|
|
69
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
70
|
+
});
|
|
63
71
|
|
|
64
72
|
// History should contain original user message + assistant response
|
|
65
73
|
expect(history).toHaveLength(2);
|
|
@@ -85,12 +93,19 @@ describe("AgentLoop", () => {
|
|
|
85
93
|
return { content: "file data here", isError: false };
|
|
86
94
|
};
|
|
87
95
|
|
|
88
|
-
const loop = new AgentLoop(
|
|
96
|
+
const loop = new AgentLoop({
|
|
97
|
+
provider: provider,
|
|
98
|
+
systemPrompt: "system",
|
|
99
|
+
conversationId: "test-conversation",
|
|
89
100
|
tools: dummyTools,
|
|
90
101
|
toolExecutor: toolExecutor,
|
|
91
102
|
});
|
|
92
103
|
const events: AgentEvent[] = [];
|
|
93
|
-
const { history } = await loop.run(
|
|
104
|
+
const { history } = await loop.run({
|
|
105
|
+
messages: [userMessage],
|
|
106
|
+
onEvent: collectEvents(events),
|
|
107
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
108
|
+
});
|
|
94
109
|
|
|
95
110
|
// Tool executor was called with correct args
|
|
96
111
|
expect(toolCalls).toHaveLength(1);
|
|
@@ -134,12 +149,18 @@ describe("AgentLoop", () => {
|
|
|
134
149
|
overrideProfile = "quality-optimized";
|
|
135
150
|
return { content: "ok", isError: false };
|
|
136
151
|
};
|
|
137
|
-
const loop = new AgentLoop(
|
|
152
|
+
const loop = new AgentLoop({
|
|
153
|
+
provider: provider,
|
|
154
|
+
systemPrompt: "system",
|
|
155
|
+
conversationId: "test-conversation",
|
|
138
156
|
tools: dummyTools,
|
|
139
157
|
toolExecutor: toolExecutor,
|
|
140
158
|
});
|
|
141
159
|
|
|
142
|
-
await loop.run(
|
|
160
|
+
await loop.run({
|
|
161
|
+
messages: [userMessage],
|
|
162
|
+
onEvent: collectEvents([]),
|
|
163
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
143
164
|
requestId: "req-1",
|
|
144
165
|
callSite: "mainAgent",
|
|
145
166
|
resolveOverrideProfile: () => overrideProfile,
|
|
@@ -163,12 +184,18 @@ describe("AgentLoop", () => {
|
|
|
163
184
|
maxInputTokens = 10_000;
|
|
164
185
|
return { content: toolOutput, isError: false };
|
|
165
186
|
};
|
|
166
|
-
const loop = new AgentLoop(
|
|
187
|
+
const loop = new AgentLoop({
|
|
188
|
+
provider: provider,
|
|
189
|
+
systemPrompt: "system",
|
|
190
|
+
conversationId: "test-conversation",
|
|
167
191
|
tools: dummyTools,
|
|
168
192
|
toolExecutor: toolExecutor,
|
|
169
193
|
});
|
|
170
194
|
|
|
171
|
-
await loop.run(
|
|
195
|
+
await loop.run({
|
|
196
|
+
messages: [userMessage],
|
|
197
|
+
onEvent: collectEvents([]),
|
|
198
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
172
199
|
requestId: "req-1",
|
|
173
200
|
callSite: "mainAgent",
|
|
174
201
|
resolveContextWindow: () => ({
|
|
@@ -204,11 +231,18 @@ describe("AgentLoop", () => {
|
|
|
204
231
|
};
|
|
205
232
|
};
|
|
206
233
|
|
|
207
|
-
const loop = new AgentLoop(
|
|
234
|
+
const loop = new AgentLoop({
|
|
235
|
+
provider: provider,
|
|
236
|
+
systemPrompt: "system",
|
|
237
|
+
conversationId: "test-conversation",
|
|
208
238
|
tools: dummyTools,
|
|
209
239
|
toolExecutor: toolExecutor,
|
|
210
240
|
});
|
|
211
|
-
const { history } = await loop.run(
|
|
241
|
+
const { history } = await loop.run({
|
|
242
|
+
messages: [userMessage],
|
|
243
|
+
onEvent: () => {},
|
|
244
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
245
|
+
});
|
|
212
246
|
|
|
213
247
|
// Provider called 3 times (two tool rounds + final text)
|
|
214
248
|
expect(calls).toHaveLength(3);
|
|
@@ -227,8 +261,17 @@ describe("AgentLoop", () => {
|
|
|
227
261
|
]);
|
|
228
262
|
|
|
229
263
|
// No tool executor provided
|
|
230
|
-
const loop = new AgentLoop(
|
|
231
|
-
|
|
264
|
+
const loop = new AgentLoop({
|
|
265
|
+
provider: provider,
|
|
266
|
+
systemPrompt: "system",
|
|
267
|
+
conversationId: "test-conversation",
|
|
268
|
+
tools: dummyTools,
|
|
269
|
+
});
|
|
270
|
+
const { history } = await loop.run({
|
|
271
|
+
messages: [userMessage],
|
|
272
|
+
onEvent: () => {},
|
|
273
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
274
|
+
});
|
|
232
275
|
|
|
233
276
|
// Should stop after first response (no executor to handle tool use)
|
|
234
277
|
expect(history).toHaveLength(2);
|
|
@@ -245,9 +288,17 @@ describe("AgentLoop", () => {
|
|
|
245
288
|
},
|
|
246
289
|
};
|
|
247
290
|
|
|
248
|
-
const loop = new AgentLoop(
|
|
291
|
+
const loop = new AgentLoop({
|
|
292
|
+
provider: provider,
|
|
293
|
+
systemPrompt: "system",
|
|
294
|
+
conversationId: "test-conversation",
|
|
295
|
+
});
|
|
249
296
|
const events: AgentEvent[] = [];
|
|
250
|
-
const { history } = await loop.run(
|
|
297
|
+
const { history } = await loop.run({
|
|
298
|
+
messages: [userMessage],
|
|
299
|
+
onEvent: collectEvents(events),
|
|
300
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
301
|
+
});
|
|
251
302
|
|
|
252
303
|
// Only the original message remains (no assistant message added on error)
|
|
253
304
|
expect(history).toHaveLength(1);
|
|
@@ -266,8 +317,15 @@ describe("AgentLoop", () => {
|
|
|
266
317
|
controller.abort(); // abort immediately
|
|
267
318
|
|
|
268
319
|
const { provider } = createMockProvider([textResponse("Should not reach")]);
|
|
269
|
-
const loop = new AgentLoop(
|
|
270
|
-
|
|
320
|
+
const loop = new AgentLoop({
|
|
321
|
+
provider: provider,
|
|
322
|
+
systemPrompt: "system",
|
|
323
|
+
conversationId: "test-conversation",
|
|
324
|
+
});
|
|
325
|
+
const { history } = await loop.run({
|
|
326
|
+
messages: [userMessage],
|
|
327
|
+
onEvent: () => {},
|
|
328
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
271
329
|
signal: controller.signal,
|
|
272
330
|
});
|
|
273
331
|
|
|
@@ -294,11 +352,17 @@ describe("AgentLoop", () => {
|
|
|
294
352
|
return { content: "data", isError: false };
|
|
295
353
|
};
|
|
296
354
|
|
|
297
|
-
const loop = new AgentLoop(
|
|
355
|
+
const loop = new AgentLoop({
|
|
356
|
+
provider: provider,
|
|
357
|
+
systemPrompt: "system",
|
|
358
|
+
conversationId: "test-conversation",
|
|
298
359
|
tools: dummyTools,
|
|
299
360
|
toolExecutor: toolExecutor,
|
|
300
361
|
});
|
|
301
|
-
const { history } = await loop.run(
|
|
362
|
+
const { history } = await loop.run({
|
|
363
|
+
messages: [userMessage],
|
|
364
|
+
onEvent: () => {},
|
|
365
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
302
366
|
signal: controller.signal,
|
|
303
367
|
});
|
|
304
368
|
|
|
@@ -340,12 +404,18 @@ describe("AgentLoop", () => {
|
|
|
340
404
|
return { content: "should never return", isError: false };
|
|
341
405
|
};
|
|
342
406
|
|
|
343
|
-
const loop = new AgentLoop(
|
|
407
|
+
const loop = new AgentLoop({
|
|
408
|
+
provider: provider,
|
|
409
|
+
systemPrompt: "system",
|
|
410
|
+
conversationId: "test-conversation",
|
|
344
411
|
tools: dummyTools,
|
|
345
412
|
toolExecutor: toolExecutor,
|
|
346
413
|
});
|
|
347
414
|
const start = Date.now();
|
|
348
|
-
const { history } = await loop.run(
|
|
415
|
+
const { history } = await loop.run({
|
|
416
|
+
messages: [userMessage],
|
|
417
|
+
onEvent: () => {},
|
|
418
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
349
419
|
signal: controller.signal,
|
|
350
420
|
});
|
|
351
421
|
const elapsed = Date.now() - start;
|
|
@@ -384,10 +454,18 @@ describe("AgentLoop", () => {
|
|
|
384
454
|
// 7. Events — verify text_delta and other events are emitted
|
|
385
455
|
test("emits text_delta events during streaming", async () => {
|
|
386
456
|
const { provider } = createMockProvider([textResponse("Hello world")]);
|
|
387
|
-
const loop = new AgentLoop(
|
|
457
|
+
const loop = new AgentLoop({
|
|
458
|
+
provider: provider,
|
|
459
|
+
systemPrompt: "system",
|
|
460
|
+
conversationId: "test-conversation",
|
|
461
|
+
});
|
|
388
462
|
|
|
389
463
|
const events: AgentEvent[] = [];
|
|
390
|
-
await loop.run(
|
|
464
|
+
await loop.run({
|
|
465
|
+
messages: [userMessage],
|
|
466
|
+
onEvent: collectEvents(events),
|
|
467
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
468
|
+
});
|
|
391
469
|
|
|
392
470
|
const textDeltas = events.filter((e) => e.type === "text_delta");
|
|
393
471
|
expect(textDeltas).toHaveLength(1);
|
|
@@ -398,10 +476,18 @@ describe("AgentLoop", () => {
|
|
|
398
476
|
|
|
399
477
|
test("emits usage events", async () => {
|
|
400
478
|
const { provider } = createMockProvider([textResponse("Hi")]);
|
|
401
|
-
const loop = new AgentLoop(
|
|
479
|
+
const loop = new AgentLoop({
|
|
480
|
+
provider: provider,
|
|
481
|
+
systemPrompt: "system",
|
|
482
|
+
conversationId: "test-conversation",
|
|
483
|
+
});
|
|
402
484
|
|
|
403
485
|
const events: AgentEvent[] = [];
|
|
404
|
-
await loop.run(
|
|
486
|
+
await loop.run({
|
|
487
|
+
messages: [userMessage],
|
|
488
|
+
onEvent: collectEvents(events),
|
|
489
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
490
|
+
});
|
|
405
491
|
|
|
406
492
|
const usageEvents = events.filter((e) => e.type === "usage");
|
|
407
493
|
expect(usageEvents).toHaveLength(1);
|
|
@@ -416,10 +502,18 @@ describe("AgentLoop", () => {
|
|
|
416
502
|
|
|
417
503
|
test("emits message_complete events", async () => {
|
|
418
504
|
const { provider } = createMockProvider([textResponse("Done")]);
|
|
419
|
-
const loop = new AgentLoop(
|
|
505
|
+
const loop = new AgentLoop({
|
|
506
|
+
provider: provider,
|
|
507
|
+
systemPrompt: "system",
|
|
508
|
+
conversationId: "test-conversation",
|
|
509
|
+
});
|
|
420
510
|
|
|
421
511
|
const events: AgentEvent[] = [];
|
|
422
|
-
await loop.run(
|
|
512
|
+
await loop.run({
|
|
513
|
+
messages: [userMessage],
|
|
514
|
+
onEvent: collectEvents(events),
|
|
515
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
516
|
+
});
|
|
423
517
|
|
|
424
518
|
const completeEvents = events.filter((e) => e.type === "message_complete");
|
|
425
519
|
expect(completeEvents).toHaveLength(1);
|
|
@@ -436,13 +530,20 @@ describe("AgentLoop", () => {
|
|
|
436
530
|
]);
|
|
437
531
|
|
|
438
532
|
const toolExecutor = async () => ({ content: "file data", isError: false });
|
|
439
|
-
const loop = new AgentLoop(
|
|
533
|
+
const loop = new AgentLoop({
|
|
534
|
+
provider: provider,
|
|
535
|
+
systemPrompt: "system",
|
|
536
|
+
conversationId: "test-conversation",
|
|
440
537
|
tools: dummyTools,
|
|
441
538
|
toolExecutor: toolExecutor,
|
|
442
539
|
});
|
|
443
540
|
|
|
444
541
|
const events: AgentEvent[] = [];
|
|
445
|
-
await loop.run(
|
|
542
|
+
await loop.run({
|
|
543
|
+
messages: [userMessage],
|
|
544
|
+
onEvent: collectEvents(events),
|
|
545
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
546
|
+
});
|
|
446
547
|
|
|
447
548
|
const toolUseEvents = events.filter((e) => e.type === "tool_use");
|
|
448
549
|
expect(toolUseEvents).toHaveLength(1);
|
|
@@ -480,12 +581,19 @@ describe("AgentLoop", () => {
|
|
|
480
581
|
content: "ENOENT: file not found",
|
|
481
582
|
isError: true,
|
|
482
583
|
});
|
|
483
|
-
const loop = new AgentLoop(
|
|
584
|
+
const loop = new AgentLoop({
|
|
585
|
+
provider: provider,
|
|
586
|
+
systemPrompt: "system",
|
|
587
|
+
conversationId: "test-conversation",
|
|
484
588
|
tools: dummyTools,
|
|
485
589
|
toolExecutor: toolExecutor,
|
|
486
590
|
});
|
|
487
591
|
|
|
488
|
-
await loop.run(
|
|
592
|
+
await loop.run({
|
|
593
|
+
messages: [userMessage],
|
|
594
|
+
onEvent: () => {},
|
|
595
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
596
|
+
});
|
|
489
597
|
|
|
490
598
|
const secondCallMessages = calls[1].messages;
|
|
491
599
|
const lastMsg = secondCallMessages[secondCallMessages.length - 1];
|
|
@@ -515,12 +623,19 @@ describe("AgentLoop", () => {
|
|
|
515
623
|
return { content: "full output", isError: false };
|
|
516
624
|
};
|
|
517
625
|
|
|
518
|
-
const loop = new AgentLoop(
|
|
626
|
+
const loop = new AgentLoop({
|
|
627
|
+
provider: provider,
|
|
628
|
+
systemPrompt: "system",
|
|
629
|
+
conversationId: "test-conversation",
|
|
519
630
|
tools: dummyTools,
|
|
520
631
|
toolExecutor: toolExecutor,
|
|
521
632
|
});
|
|
522
633
|
const events: AgentEvent[] = [];
|
|
523
|
-
await loop.run(
|
|
634
|
+
await loop.run({
|
|
635
|
+
messages: [userMessage],
|
|
636
|
+
onEvent: collectEvents(events),
|
|
637
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
638
|
+
});
|
|
524
639
|
|
|
525
640
|
const chunkEvents = events.filter((e) => e.type === "tool_output_chunk");
|
|
526
641
|
expect(chunkEvents).toHaveLength(2);
|
|
@@ -537,11 +652,18 @@ describe("AgentLoop", () => {
|
|
|
537
652
|
// 11. System prompt and tools are passed to provider
|
|
538
653
|
test("passes system prompt and tools to provider", async () => {
|
|
539
654
|
const { provider, calls } = createMockProvider([textResponse("Hi")]);
|
|
540
|
-
const loop = new AgentLoop(
|
|
655
|
+
const loop = new AgentLoop({
|
|
656
|
+
provider: provider,
|
|
657
|
+
systemPrompt: "My system prompt",
|
|
658
|
+
conversationId: "test-conversation",
|
|
541
659
|
tools: dummyTools,
|
|
542
660
|
});
|
|
543
661
|
|
|
544
|
-
await loop.run(
|
|
662
|
+
await loop.run({
|
|
663
|
+
messages: [userMessage],
|
|
664
|
+
onEvent: () => {},
|
|
665
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
666
|
+
});
|
|
545
667
|
|
|
546
668
|
expect(calls[0].systemPrompt).toBe("My system prompt");
|
|
547
669
|
expect(calls[0].tools).toEqual(dummyTools);
|
|
@@ -550,9 +672,17 @@ describe("AgentLoop", () => {
|
|
|
550
672
|
// 12. No tools configured — tools are not passed to provider
|
|
551
673
|
test("does not pass tools to provider when none are configured", async () => {
|
|
552
674
|
const { provider, calls } = createMockProvider([textResponse("Hi")]);
|
|
553
|
-
const loop = new AgentLoop(
|
|
675
|
+
const loop = new AgentLoop({
|
|
676
|
+
provider: provider,
|
|
677
|
+
systemPrompt: "system",
|
|
678
|
+
conversationId: "test-conversation",
|
|
679
|
+
});
|
|
554
680
|
|
|
555
|
-
await loop.run(
|
|
681
|
+
await loop.run({
|
|
682
|
+
messages: [userMessage],
|
|
683
|
+
onEvent: () => {},
|
|
684
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
685
|
+
});
|
|
556
686
|
|
|
557
687
|
expect(calls[0].tools).toBeUndefined();
|
|
558
688
|
});
|
|
@@ -605,12 +735,19 @@ describe("AgentLoop", () => {
|
|
|
605
735
|
};
|
|
606
736
|
};
|
|
607
737
|
|
|
608
|
-
const loop = new AgentLoop(
|
|
738
|
+
const loop = new AgentLoop({
|
|
739
|
+
provider: provider,
|
|
740
|
+
systemPrompt: "system",
|
|
741
|
+
conversationId: "test-conversation",
|
|
609
742
|
tools: dummyTools,
|
|
610
743
|
toolExecutor: toolExecutor,
|
|
611
744
|
});
|
|
612
745
|
const events: AgentEvent[] = [];
|
|
613
|
-
const { history } = await loop.run(
|
|
746
|
+
const { history } = await loop.run({
|
|
747
|
+
messages: [userMessage],
|
|
748
|
+
onEvent: collectEvents(events),
|
|
749
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
750
|
+
});
|
|
614
751
|
|
|
615
752
|
// All 3 tools should have been called
|
|
616
753
|
expect(executionLog).toHaveLength(3);
|
|
@@ -699,12 +836,18 @@ describe("AgentLoop", () => {
|
|
|
699
836
|
return { content: "data", isError: false };
|
|
700
837
|
};
|
|
701
838
|
|
|
702
|
-
const loop = new AgentLoop(
|
|
839
|
+
const loop = new AgentLoop({
|
|
840
|
+
provider: provider,
|
|
841
|
+
systemPrompt: "system",
|
|
842
|
+
conversationId: "test-conversation",
|
|
703
843
|
tools: dummyTools,
|
|
704
844
|
toolExecutor: toolExecutor,
|
|
705
845
|
});
|
|
706
846
|
const events: AgentEvent[] = [];
|
|
707
|
-
const { history } = await loop.run(
|
|
847
|
+
const { history } = await loop.run({
|
|
848
|
+
messages: [userMessage],
|
|
849
|
+
onEvent: collectEvents(events),
|
|
850
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
708
851
|
signal: controller.signal,
|
|
709
852
|
});
|
|
710
853
|
|
|
@@ -773,12 +916,19 @@ describe("AgentLoop", () => {
|
|
|
773
916
|
return { content: `contents of ${path}`, isError: false };
|
|
774
917
|
};
|
|
775
918
|
|
|
776
|
-
const loop = new AgentLoop(
|
|
919
|
+
const loop = new AgentLoop({
|
|
920
|
+
provider: provider,
|
|
921
|
+
systemPrompt: "system",
|
|
922
|
+
conversationId: "test-conversation",
|
|
777
923
|
tools: dummyTools,
|
|
778
924
|
toolExecutor: toolExecutor,
|
|
779
925
|
});
|
|
780
926
|
const events: AgentEvent[] = [];
|
|
781
|
-
await loop.run(
|
|
927
|
+
await loop.run({
|
|
928
|
+
messages: [userMessage],
|
|
929
|
+
onEvent: collectEvents(events),
|
|
930
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
931
|
+
});
|
|
782
932
|
|
|
783
933
|
// Collect tool_result events in order
|
|
784
934
|
const toolResultEvents = events.filter(
|
|
@@ -805,7 +955,10 @@ describe("AgentLoop", () => {
|
|
|
805
955
|
]);
|
|
806
956
|
|
|
807
957
|
const toolExecutor = async () => ({ content: "file data", isError: false });
|
|
808
|
-
const loop = new AgentLoop(
|
|
958
|
+
const loop = new AgentLoop({
|
|
959
|
+
provider: provider,
|
|
960
|
+
systemPrompt: "system",
|
|
961
|
+
conversationId: "test-conversation",
|
|
809
962
|
tools: dummyTools,
|
|
810
963
|
toolExecutor: toolExecutor,
|
|
811
964
|
});
|
|
@@ -816,7 +969,12 @@ describe("AgentLoop", () => {
|
|
|
816
969
|
return "continue";
|
|
817
970
|
};
|
|
818
971
|
|
|
819
|
-
await loop.run(
|
|
972
|
+
await loop.run({
|
|
973
|
+
messages: [userMessage],
|
|
974
|
+
onEvent: () => {},
|
|
975
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
976
|
+
onCheckpoint,
|
|
977
|
+
});
|
|
820
978
|
|
|
821
979
|
expect(checkpoints).toHaveLength(1);
|
|
822
980
|
expect(checkpoints[0]).toMatchObject({
|
|
@@ -837,14 +995,20 @@ describe("AgentLoop", () => {
|
|
|
837
995
|
]);
|
|
838
996
|
|
|
839
997
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
840
|
-
const loop = new AgentLoop(
|
|
998
|
+
const loop = new AgentLoop({
|
|
999
|
+
provider: provider,
|
|
1000
|
+
systemPrompt: "system",
|
|
1001
|
+
conversationId: "test-conversation",
|
|
841
1002
|
tools: dummyTools,
|
|
842
1003
|
toolExecutor: toolExecutor,
|
|
843
1004
|
});
|
|
844
1005
|
|
|
845
1006
|
const onCheckpoint = (): CheckpointDecision => "continue";
|
|
846
1007
|
|
|
847
|
-
const { history } = await loop.run(
|
|
1008
|
+
const { history } = await loop.run({
|
|
1009
|
+
messages: [userMessage],
|
|
1010
|
+
onEvent: () => {},
|
|
1011
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
848
1012
|
onCheckpoint,
|
|
849
1013
|
});
|
|
850
1014
|
|
|
@@ -864,14 +1028,20 @@ describe("AgentLoop", () => {
|
|
|
864
1028
|
]);
|
|
865
1029
|
|
|
866
1030
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
867
|
-
const loop = new AgentLoop(
|
|
1031
|
+
const loop = new AgentLoop({
|
|
1032
|
+
provider: provider,
|
|
1033
|
+
systemPrompt: "system",
|
|
1034
|
+
conversationId: "test-conversation",
|
|
868
1035
|
tools: dummyTools,
|
|
869
1036
|
toolExecutor: toolExecutor,
|
|
870
1037
|
});
|
|
871
1038
|
|
|
872
1039
|
const onCheckpoint = (): CheckpointDecision => "budget";
|
|
873
1040
|
|
|
874
|
-
const { history } = await loop.run(
|
|
1041
|
+
const { history } = await loop.run({
|
|
1042
|
+
messages: [userMessage],
|
|
1043
|
+
onEvent: () => {},
|
|
1044
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
875
1045
|
onCheckpoint,
|
|
876
1046
|
});
|
|
877
1047
|
|
|
@@ -891,12 +1061,19 @@ describe("AgentLoop", () => {
|
|
|
891
1061
|
]);
|
|
892
1062
|
|
|
893
1063
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
894
|
-
const loop = new AgentLoop(
|
|
1064
|
+
const loop = new AgentLoop({
|
|
1065
|
+
provider: provider,
|
|
1066
|
+
systemPrompt: "system",
|
|
1067
|
+
conversationId: "test-conversation",
|
|
895
1068
|
tools: dummyTools,
|
|
896
1069
|
toolExecutor: toolExecutor,
|
|
897
1070
|
});
|
|
898
1071
|
|
|
899
|
-
const { history } = await loop.run(
|
|
1072
|
+
const { history } = await loop.run({
|
|
1073
|
+
messages: [userMessage],
|
|
1074
|
+
onEvent: () => {},
|
|
1075
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1076
|
+
});
|
|
900
1077
|
|
|
901
1078
|
// Normal behavior: 2 provider calls, full history
|
|
902
1079
|
expect(calls).toHaveLength(2);
|
|
@@ -914,7 +1091,10 @@ describe("AgentLoop", () => {
|
|
|
914
1091
|
]);
|
|
915
1092
|
|
|
916
1093
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
917
|
-
const loop = new AgentLoop(
|
|
1094
|
+
const loop = new AgentLoop({
|
|
1095
|
+
provider: provider,
|
|
1096
|
+
systemPrompt: "system",
|
|
1097
|
+
conversationId: "test-conversation",
|
|
918
1098
|
tools: dummyTools,
|
|
919
1099
|
toolExecutor: toolExecutor,
|
|
920
1100
|
});
|
|
@@ -925,7 +1105,12 @@ describe("AgentLoop", () => {
|
|
|
925
1105
|
return "continue";
|
|
926
1106
|
};
|
|
927
1107
|
|
|
928
|
-
await loop.run(
|
|
1108
|
+
await loop.run({
|
|
1109
|
+
messages: [userMessage],
|
|
1110
|
+
onEvent: () => {},
|
|
1111
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1112
|
+
onCheckpoint,
|
|
1113
|
+
});
|
|
929
1114
|
|
|
930
1115
|
expect(checkpoints).toHaveLength(3);
|
|
931
1116
|
expect(checkpoints[0].turnIndex).toBe(0);
|
|
@@ -938,7 +1123,12 @@ describe("AgentLoop", () => {
|
|
|
938
1123
|
const { provider } = createMockProvider([
|
|
939
1124
|
textResponse("Just a text response"),
|
|
940
1125
|
]);
|
|
941
|
-
const loop = new AgentLoop(
|
|
1126
|
+
const loop = new AgentLoop({
|
|
1127
|
+
provider: provider,
|
|
1128
|
+
systemPrompt: "system",
|
|
1129
|
+
conversationId: "test-conversation",
|
|
1130
|
+
tools: dummyTools,
|
|
1131
|
+
});
|
|
942
1132
|
|
|
943
1133
|
const checkpoints: CheckpointInfo[] = [];
|
|
944
1134
|
const onCheckpoint = (checkpoint: CheckpointInfo): CheckpointDecision => {
|
|
@@ -946,7 +1136,10 @@ describe("AgentLoop", () => {
|
|
|
946
1136
|
return "continue";
|
|
947
1137
|
};
|
|
948
1138
|
|
|
949
|
-
const { history } = await loop.run(
|
|
1139
|
+
const { history } = await loop.run({
|
|
1140
|
+
messages: [userMessage],
|
|
1141
|
+
onEvent: () => {},
|
|
1142
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
950
1143
|
onCheckpoint,
|
|
951
1144
|
});
|
|
952
1145
|
|
|
@@ -991,7 +1184,10 @@ describe("AgentLoop", () => {
|
|
|
991
1184
|
]);
|
|
992
1185
|
|
|
993
1186
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
994
|
-
const loop = new AgentLoop(
|
|
1187
|
+
const loop = new AgentLoop({
|
|
1188
|
+
provider: provider,
|
|
1189
|
+
systemPrompt: "system",
|
|
1190
|
+
conversationId: "test-conversation",
|
|
995
1191
|
tools: dummyTools,
|
|
996
1192
|
toolExecutor: toolExecutor,
|
|
997
1193
|
});
|
|
@@ -1002,7 +1198,12 @@ describe("AgentLoop", () => {
|
|
|
1002
1198
|
return "continue";
|
|
1003
1199
|
};
|
|
1004
1200
|
|
|
1005
|
-
await loop.run(
|
|
1201
|
+
await loop.run({
|
|
1202
|
+
messages: [userMessage],
|
|
1203
|
+
onEvent: () => {},
|
|
1204
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1205
|
+
onCheckpoint,
|
|
1206
|
+
});
|
|
1006
1207
|
|
|
1007
1208
|
expect(checkpoints).toHaveLength(1);
|
|
1008
1209
|
expect(checkpoints[0].toolCount).toBe(3);
|
|
@@ -1022,7 +1223,10 @@ describe("AgentLoop", () => {
|
|
|
1022
1223
|
|
|
1023
1224
|
const { provider, calls } = createMockProvider(responses);
|
|
1024
1225
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1025
|
-
const loop = new AgentLoop(
|
|
1226
|
+
const loop = new AgentLoop({
|
|
1227
|
+
provider: provider,
|
|
1228
|
+
systemPrompt: "system",
|
|
1229
|
+
conversationId: "test-conversation",
|
|
1026
1230
|
tools: dummyTools,
|
|
1027
1231
|
toolExecutor: toolExecutor,
|
|
1028
1232
|
});
|
|
@@ -1035,7 +1239,10 @@ describe("AgentLoop", () => {
|
|
|
1035
1239
|
};
|
|
1036
1240
|
|
|
1037
1241
|
const events: AgentEvent[] = [];
|
|
1038
|
-
const { history } = await loop.run(
|
|
1242
|
+
const { history } = await loop.run({
|
|
1243
|
+
messages: [userMessage],
|
|
1244
|
+
onEvent: collectEvents(events),
|
|
1245
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1039
1246
|
onCheckpoint,
|
|
1040
1247
|
});
|
|
1041
1248
|
|
|
@@ -1091,7 +1298,10 @@ describe("AgentLoop", () => {
|
|
|
1091
1298
|
]);
|
|
1092
1299
|
|
|
1093
1300
|
const toolExecutor = async () => ({ content: "data", isError: false });
|
|
1094
|
-
const loop = new AgentLoop(
|
|
1301
|
+
const loop = new AgentLoop({
|
|
1302
|
+
provider: provider,
|
|
1303
|
+
systemPrompt: "system",
|
|
1304
|
+
conversationId: "test-conversation",
|
|
1095
1305
|
tools: dummyTools,
|
|
1096
1306
|
toolExecutor: toolExecutor,
|
|
1097
1307
|
});
|
|
@@ -1101,7 +1311,10 @@ describe("AgentLoop", () => {
|
|
|
1101
1311
|
return checkpoint.turnIndex === 1 ? "budget" : "continue";
|
|
1102
1312
|
};
|
|
1103
1313
|
|
|
1104
|
-
const { history } = await loop.run(
|
|
1314
|
+
const { history } = await loop.run({
|
|
1315
|
+
messages: [userMessage],
|
|
1316
|
+
onEvent: () => {},
|
|
1317
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1105
1318
|
onCheckpoint,
|
|
1106
1319
|
});
|
|
1107
1320
|
|
|
@@ -1118,9 +1331,18 @@ describe("AgentLoop", () => {
|
|
|
1118
1331
|
// 25. Without resolveTools, static tools are used
|
|
1119
1332
|
test("without resolveTools, static tools are passed to provider", async () => {
|
|
1120
1333
|
const { provider, calls } = createMockProvider([textResponse("Hi")]);
|
|
1121
|
-
const loop = new AgentLoop(
|
|
1334
|
+
const loop = new AgentLoop({
|
|
1335
|
+
provider: provider,
|
|
1336
|
+
systemPrompt: "system",
|
|
1337
|
+
conversationId: "test-conversation",
|
|
1338
|
+
tools: dummyTools,
|
|
1339
|
+
});
|
|
1122
1340
|
|
|
1123
|
-
await loop.run(
|
|
1341
|
+
await loop.run({
|
|
1342
|
+
messages: [userMessage],
|
|
1343
|
+
onEvent: () => {},
|
|
1344
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1345
|
+
});
|
|
1124
1346
|
|
|
1125
1347
|
expect(calls[0].tools).toEqual(dummyTools);
|
|
1126
1348
|
});
|
|
@@ -1151,11 +1373,18 @@ describe("AgentLoop", () => {
|
|
|
1151
1373
|
return resolvedTools;
|
|
1152
1374
|
};
|
|
1153
1375
|
|
|
1154
|
-
const loop = new AgentLoop(
|
|
1376
|
+
const loop = new AgentLoop({
|
|
1377
|
+
provider: provider,
|
|
1378
|
+
systemPrompt: "system",
|
|
1379
|
+
conversationId: "test-conversation",
|
|
1155
1380
|
toolExecutor: toolExecutor,
|
|
1156
1381
|
resolveTools: resolveTools,
|
|
1157
1382
|
});
|
|
1158
|
-
await loop.run(
|
|
1383
|
+
await loop.run({
|
|
1384
|
+
messages: [userMessage],
|
|
1385
|
+
onEvent: () => {},
|
|
1386
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1387
|
+
});
|
|
1159
1388
|
|
|
1160
1389
|
// resolveTools should be called once per provider turn (2 turns total)
|
|
1161
1390
|
expect(resolverCalls).toHaveLength(2);
|
|
@@ -1183,11 +1412,18 @@ describe("AgentLoop", () => {
|
|
|
1183
1412
|
const resolveTools = (): ToolDefinition[] => dynamicTools;
|
|
1184
1413
|
|
|
1185
1414
|
// Pass different static tools to verify they are overridden
|
|
1186
|
-
const loop = new AgentLoop(
|
|
1415
|
+
const loop = new AgentLoop({
|
|
1416
|
+
provider: provider,
|
|
1417
|
+
systemPrompt: "system",
|
|
1418
|
+
conversationId: "test-conversation",
|
|
1187
1419
|
tools: dummyTools,
|
|
1188
1420
|
resolveTools: resolveTools,
|
|
1189
1421
|
});
|
|
1190
|
-
await loop.run(
|
|
1422
|
+
await loop.run({
|
|
1423
|
+
messages: [userMessage],
|
|
1424
|
+
onEvent: () => {},
|
|
1425
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1426
|
+
});
|
|
1191
1427
|
|
|
1192
1428
|
// Provider should receive the dynamically resolved tools, not the static ones
|
|
1193
1429
|
expect(calls[0].tools).toEqual(dynamicTools);
|
|
@@ -1240,11 +1476,18 @@ describe("AgentLoop", () => {
|
|
|
1240
1476
|
]);
|
|
1241
1477
|
|
|
1242
1478
|
const toolExecutor = async () => ({ content: "ok", isError: false });
|
|
1243
|
-
const loop = new AgentLoop(
|
|
1479
|
+
const loop = new AgentLoop({
|
|
1480
|
+
provider: provider,
|
|
1481
|
+
systemPrompt: "system",
|
|
1482
|
+
conversationId: "test-conversation",
|
|
1244
1483
|
toolExecutor: toolExecutor,
|
|
1245
1484
|
resolveTools: resolveTools,
|
|
1246
1485
|
});
|
|
1247
|
-
await loop.run(
|
|
1486
|
+
await loop.run({
|
|
1487
|
+
messages: [userMessage],
|
|
1488
|
+
onEvent: () => {},
|
|
1489
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1490
|
+
});
|
|
1248
1491
|
|
|
1249
1492
|
// Provider should have been called 3 times
|
|
1250
1493
|
expect(calls).toHaveLength(3);
|
|
@@ -1263,11 +1506,18 @@ describe("AgentLoop", () => {
|
|
|
1263
1506
|
textResponse("No tools available"),
|
|
1264
1507
|
]);
|
|
1265
1508
|
|
|
1266
|
-
const loop = new AgentLoop(
|
|
1509
|
+
const loop = new AgentLoop({
|
|
1510
|
+
provider: provider,
|
|
1511
|
+
systemPrompt: "system",
|
|
1512
|
+
conversationId: "test-conversation",
|
|
1267
1513
|
tools: dummyTools,
|
|
1268
1514
|
resolveTools: resolveTools,
|
|
1269
1515
|
});
|
|
1270
|
-
await loop.run(
|
|
1516
|
+
await loop.run({
|
|
1517
|
+
messages: [userMessage],
|
|
1518
|
+
onEvent: () => {},
|
|
1519
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1520
|
+
});
|
|
1271
1521
|
|
|
1272
1522
|
// Empty array should result in undefined tools (same as no-tools behavior)
|
|
1273
1523
|
expect(calls[0].tools).toBeUndefined();
|
|
@@ -1291,13 +1541,20 @@ describe("AgentLoop", () => {
|
|
|
1291
1541
|
return { content: largeContent, isError: false };
|
|
1292
1542
|
};
|
|
1293
1543
|
|
|
1294
|
-
const loop = new AgentLoop(
|
|
1544
|
+
const loop = new AgentLoop({
|
|
1545
|
+
provider: provider,
|
|
1546
|
+
systemPrompt: "system",
|
|
1547
|
+
conversationId: "test-conversation",
|
|
1295
1548
|
config: { maxInputTokens: 180_000 },
|
|
1296
1549
|
tools: dummyTools,
|
|
1297
1550
|
toolExecutor: toolExecutor,
|
|
1298
1551
|
});
|
|
1299
1552
|
const events: AgentEvent[] = [];
|
|
1300
|
-
const { history } = await loop.run(
|
|
1553
|
+
const { history } = await loop.run({
|
|
1554
|
+
messages: [userMessage],
|
|
1555
|
+
onEvent: collectEvents(events),
|
|
1556
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1557
|
+
});
|
|
1301
1558
|
|
|
1302
1559
|
// The tool result user message is at index 2 in history
|
|
1303
1560
|
const toolResultMsg = history[2];
|
|
@@ -1340,13 +1597,20 @@ describe("AgentLoop", () => {
|
|
|
1340
1597
|
return { content: smallContent, isError: false };
|
|
1341
1598
|
};
|
|
1342
1599
|
|
|
1343
|
-
const loop = new AgentLoop(
|
|
1600
|
+
const loop = new AgentLoop({
|
|
1601
|
+
provider: provider,
|
|
1602
|
+
systemPrompt: "system",
|
|
1603
|
+
conversationId: "test-conversation",
|
|
1344
1604
|
config: { maxInputTokens: 180_000 },
|
|
1345
1605
|
tools: dummyTools,
|
|
1346
1606
|
toolExecutor: toolExecutor,
|
|
1347
1607
|
});
|
|
1348
1608
|
const events: AgentEvent[] = [];
|
|
1349
|
-
const { history } = await loop.run(
|
|
1609
|
+
const { history } = await loop.run({
|
|
1610
|
+
messages: [userMessage],
|
|
1611
|
+
onEvent: collectEvents(events),
|
|
1612
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1613
|
+
});
|
|
1350
1614
|
|
|
1351
1615
|
// The tool result user message is at index 2 in history
|
|
1352
1616
|
const toolResultMsg = history[2];
|
|
@@ -1398,12 +1662,19 @@ describe("AgentLoop", () => {
|
|
|
1398
1662
|
],
|
|
1399
1663
|
});
|
|
1400
1664
|
|
|
1401
|
-
const loop = new AgentLoop(
|
|
1665
|
+
const loop = new AgentLoop({
|
|
1666
|
+
provider: provider,
|
|
1667
|
+
systemPrompt: "system",
|
|
1668
|
+
conversationId: "test-conversation",
|
|
1402
1669
|
tools: dummyTools,
|
|
1403
1670
|
toolExecutor: toolExecutor,
|
|
1404
1671
|
});
|
|
1405
1672
|
const events: AgentEvent[] = [];
|
|
1406
|
-
const { history } = await loop.run(
|
|
1673
|
+
const { history } = await loop.run({
|
|
1674
|
+
messages: [userMessage],
|
|
1675
|
+
onEvent: collectEvents(events),
|
|
1676
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1677
|
+
});
|
|
1407
1678
|
|
|
1408
1679
|
// The final assistant message in HISTORY should retain placeholders
|
|
1409
1680
|
// (so the model never sees real values on subsequent turns)
|
|
@@ -1464,12 +1735,19 @@ describe("AgentLoop", () => {
|
|
|
1464
1735
|
],
|
|
1465
1736
|
});
|
|
1466
1737
|
|
|
1467
|
-
const loop = new AgentLoop(
|
|
1738
|
+
const loop = new AgentLoop({
|
|
1739
|
+
provider: provider,
|
|
1740
|
+
systemPrompt: "system",
|
|
1741
|
+
conversationId: "test-conversation",
|
|
1468
1742
|
tools: dummyTools,
|
|
1469
1743
|
toolExecutor: toolExecutor,
|
|
1470
1744
|
});
|
|
1471
1745
|
const events: AgentEvent[] = [];
|
|
1472
|
-
await loop.run(
|
|
1746
|
+
await loop.run({
|
|
1747
|
+
messages: [userMessage],
|
|
1748
|
+
onEvent: collectEvents(events),
|
|
1749
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1750
|
+
});
|
|
1473
1751
|
|
|
1474
1752
|
// Collect all text_delta events from the final turn (after tool result)
|
|
1475
1753
|
const textDeltas = events.filter(
|
|
@@ -1496,12 +1774,19 @@ describe("AgentLoop", () => {
|
|
|
1496
1774
|
// No sensitiveBindings
|
|
1497
1775
|
});
|
|
1498
1776
|
|
|
1499
|
-
const loop = new AgentLoop(
|
|
1777
|
+
const loop = new AgentLoop({
|
|
1778
|
+
provider: provider,
|
|
1779
|
+
systemPrompt: "system",
|
|
1780
|
+
conversationId: "test-conversation",
|
|
1500
1781
|
tools: dummyTools,
|
|
1501
1782
|
toolExecutor: toolExecutor,
|
|
1502
1783
|
});
|
|
1503
1784
|
const events: AgentEvent[] = [];
|
|
1504
|
-
const { history } = await loop.run(
|
|
1785
|
+
const { history } = await loop.run({
|
|
1786
|
+
messages: [userMessage],
|
|
1787
|
+
onEvent: collectEvents(events),
|
|
1788
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1789
|
+
});
|
|
1505
1790
|
|
|
1506
1791
|
const lastAssistant = history[history.length - 1];
|
|
1507
1792
|
const textBlock = lastAssistant.content.find(
|
|
@@ -1540,11 +1825,18 @@ describe("AgentLoop", () => {
|
|
|
1540
1825
|
return { content: "file contents", isError: false };
|
|
1541
1826
|
};
|
|
1542
1827
|
|
|
1543
|
-
const loop = new AgentLoop(
|
|
1828
|
+
const loop = new AgentLoop({
|
|
1829
|
+
provider: provider,
|
|
1830
|
+
systemPrompt: "system",
|
|
1831
|
+
conversationId: "test-conversation",
|
|
1544
1832
|
tools: dummyTools,
|
|
1545
1833
|
toolExecutor: toolExecutor,
|
|
1546
1834
|
});
|
|
1547
|
-
await loop.run(
|
|
1835
|
+
await loop.run({
|
|
1836
|
+
messages: [userMessage],
|
|
1837
|
+
onEvent: () => {},
|
|
1838
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1839
|
+
});
|
|
1548
1840
|
|
|
1549
1841
|
// Provider should have been called 3 times (error -> retry -> final text)
|
|
1550
1842
|
expect(calls).toHaveLength(3);
|
|
@@ -1598,11 +1890,18 @@ describe("AgentLoop", () => {
|
|
|
1598
1890
|
return { content: "service unavailable", isError: true };
|
|
1599
1891
|
};
|
|
1600
1892
|
|
|
1601
|
-
const loop = new AgentLoop(
|
|
1893
|
+
const loop = new AgentLoop({
|
|
1894
|
+
provider: provider,
|
|
1895
|
+
systemPrompt: "system",
|
|
1896
|
+
conversationId: "test-conversation",
|
|
1602
1897
|
tools: dummyTools,
|
|
1603
1898
|
toolExecutor: toolExecutor,
|
|
1604
1899
|
});
|
|
1605
|
-
await loop.run(
|
|
1900
|
+
await loop.run({
|
|
1901
|
+
messages: [userMessage],
|
|
1902
|
+
onEvent: () => {},
|
|
1903
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1904
|
+
});
|
|
1606
1905
|
|
|
1607
1906
|
expect(calls).toHaveLength(5);
|
|
1608
1907
|
|
|
@@ -1644,12 +1943,19 @@ describe("AgentLoop", () => {
|
|
|
1644
1943
|
isError: false,
|
|
1645
1944
|
});
|
|
1646
1945
|
|
|
1647
|
-
const loop = new AgentLoop(
|
|
1946
|
+
const loop = new AgentLoop({
|
|
1947
|
+
provider: provider,
|
|
1948
|
+
systemPrompt: "system",
|
|
1949
|
+
conversationId: "test-conversation",
|
|
1648
1950
|
tools: dummyTools,
|
|
1649
1951
|
toolExecutor: toolExecutor,
|
|
1650
1952
|
});
|
|
1651
1953
|
const events: AgentEvent[] = [];
|
|
1652
|
-
const { history } = await loop.run(
|
|
1954
|
+
const { history } = await loop.run({
|
|
1955
|
+
messages: [userMessage],
|
|
1956
|
+
onEvent: collectEvents(events),
|
|
1957
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
1958
|
+
});
|
|
1653
1959
|
|
|
1654
1960
|
// Provider should be called 3 times: initial, empty response, retry
|
|
1655
1961
|
expect(calls).toHaveLength(3);
|
|
@@ -1719,12 +2025,19 @@ describe("AgentLoop", () => {
|
|
|
1719
2025
|
isError: false,
|
|
1720
2026
|
});
|
|
1721
2027
|
|
|
1722
|
-
const loop = new AgentLoop(
|
|
2028
|
+
const loop = new AgentLoop({
|
|
2029
|
+
provider: provider,
|
|
2030
|
+
systemPrompt: "system",
|
|
2031
|
+
conversationId: "test-conversation",
|
|
1723
2032
|
tools: dummyTools,
|
|
1724
2033
|
toolExecutor: toolExecutor,
|
|
1725
2034
|
});
|
|
1726
2035
|
const events: AgentEvent[] = [];
|
|
1727
|
-
const { history } = await loop.run(
|
|
2036
|
+
const { history } = await loop.run({
|
|
2037
|
+
messages: [userMessage],
|
|
2038
|
+
onEvent: collectEvents(events),
|
|
2039
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
2040
|
+
});
|
|
1728
2041
|
|
|
1729
2042
|
// Provider called exactly 2 times: initial [text+tool_use], then empty.
|
|
1730
2043
|
// No third (retry) call because the prior turn had visible text.
|
|
@@ -1778,12 +2091,19 @@ describe("AgentLoop", () => {
|
|
|
1778
2091
|
isError: false,
|
|
1779
2092
|
});
|
|
1780
2093
|
|
|
1781
|
-
const loop = new AgentLoop(
|
|
2094
|
+
const loop = new AgentLoop({
|
|
2095
|
+
provider: provider,
|
|
2096
|
+
systemPrompt: "system",
|
|
2097
|
+
conversationId: "test-conversation",
|
|
1782
2098
|
tools: dummyTools,
|
|
1783
2099
|
toolExecutor: toolExecutor,
|
|
1784
2100
|
});
|
|
1785
2101
|
const events: AgentEvent[] = [];
|
|
1786
|
-
const { history } = await loop.run(
|
|
2102
|
+
const { history } = await loop.run({
|
|
2103
|
+
messages: [userMessage],
|
|
2104
|
+
onEvent: collectEvents(events),
|
|
2105
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
2106
|
+
});
|
|
1787
2107
|
|
|
1788
2108
|
// Provider called 3 times: initial, empty, retry (also empty)
|
|
1789
2109
|
expect(calls).toHaveLength(3);
|
|
@@ -1812,9 +2132,17 @@ describe("AgentLoop", () => {
|
|
|
1812
2132
|
|
|
1813
2133
|
const { provider, calls } = createMockProvider([emptyResponse]);
|
|
1814
2134
|
|
|
1815
|
-
const loop = new AgentLoop(
|
|
2135
|
+
const loop = new AgentLoop({
|
|
2136
|
+
provider: provider,
|
|
2137
|
+
systemPrompt: "system",
|
|
2138
|
+
conversationId: "test-conversation",
|
|
2139
|
+
});
|
|
1816
2140
|
const events: AgentEvent[] = [];
|
|
1817
|
-
const { history } = await loop.run(
|
|
2141
|
+
const { history } = await loop.run({
|
|
2142
|
+
messages: [userMessage],
|
|
2143
|
+
onEvent: collectEvents(events),
|
|
2144
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
2145
|
+
});
|
|
1818
2146
|
|
|
1819
2147
|
// Should NOT retry — this is the first turn with no tool use history
|
|
1820
2148
|
expect(calls).toHaveLength(1);
|
|
@@ -1827,8 +2155,17 @@ describe("AgentLoop", () => {
|
|
|
1827
2155
|
test("threads callSite from AgentLoop.run() into per-call provider config", async () => {
|
|
1828
2156
|
const { provider, calls } = createMockProvider([textResponse("ok")]);
|
|
1829
2157
|
|
|
1830
|
-
const loop = new AgentLoop(
|
|
1831
|
-
|
|
2158
|
+
const loop = new AgentLoop({
|
|
2159
|
+
provider: provider,
|
|
2160
|
+
systemPrompt: "system",
|
|
2161
|
+
conversationId: "test-conversation",
|
|
2162
|
+
});
|
|
2163
|
+
await loop.run({
|
|
2164
|
+
messages: [userMessage],
|
|
2165
|
+
onEvent: () => {},
|
|
2166
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
2167
|
+
callSite: "heartbeatAgent",
|
|
2168
|
+
});
|
|
1832
2169
|
|
|
1833
2170
|
expect(calls).toHaveLength(1);
|
|
1834
2171
|
expect(calls[0].options?.config?.callSite).toBe("heartbeatAgent");
|
|
@@ -1837,8 +2174,16 @@ describe("AgentLoop", () => {
|
|
|
1837
2174
|
test("omits callSite from provider config when not supplied", async () => {
|
|
1838
2175
|
const { provider, calls } = createMockProvider([textResponse("ok")]);
|
|
1839
2176
|
|
|
1840
|
-
const loop = new AgentLoop(
|
|
1841
|
-
|
|
2177
|
+
const loop = new AgentLoop({
|
|
2178
|
+
provider: provider,
|
|
2179
|
+
systemPrompt: "system",
|
|
2180
|
+
conversationId: "test-conversation",
|
|
2181
|
+
});
|
|
2182
|
+
await loop.run({
|
|
2183
|
+
messages: [userMessage],
|
|
2184
|
+
onEvent: () => {},
|
|
2185
|
+
trust: { sourceChannel: "vellum", trustClass: "unknown" },
|
|
2186
|
+
});
|
|
1842
2187
|
|
|
1843
2188
|
expect(calls).toHaveLength(1);
|
|
1844
2189
|
expect(calls[0].options?.config?.callSite).toBeUndefined();
|