@strands-agents/sdk 1.3.0 → 1.5.0
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/README.md +16 -16
- package/dist/src/__fixtures__/agent-helpers.d.ts.map +1 -1
- package/dist/src/__fixtures__/agent-helpers.js +6 -0
- package/dist/src/__fixtures__/agent-helpers.js.map +1 -1
- package/dist/src/__fixtures__/register-node-defaults.d.ts +2 -0
- package/dist/src/__fixtures__/register-node-defaults.d.ts.map +1 -0
- package/dist/src/__fixtures__/register-node-defaults.js +6 -0
- package/dist/src/__fixtures__/register-node-defaults.js.map +1 -0
- package/dist/src/__fixtures__/test-sandbox.node.d.ts +15 -0
- package/dist/src/__fixtures__/test-sandbox.node.d.ts.map +1 -0
- package/dist/src/__fixtures__/test-sandbox.node.js +23 -0
- package/dist/src/__fixtures__/test-sandbox.node.js.map +1 -0
- package/dist/src/__tests__/default-slot.test.d.ts +2 -0
- package/dist/src/__tests__/default-slot.test.d.ts.map +1 -0
- package/dist/src/__tests__/default-slot.test.js +33 -0
- package/dist/src/__tests__/default-slot.test.js.map +1 -0
- package/dist/src/__tests__/mcp.test.js +14 -14
- package/dist/src/__tests__/mcp.test.js.map +1 -1
- package/dist/src/a2a/__tests__/async-lock.test.d.ts +2 -0
- package/dist/src/a2a/__tests__/async-lock.test.d.ts.map +1 -0
- package/dist/src/a2a/__tests__/async-lock.test.js +137 -0
- package/dist/src/a2a/__tests__/async-lock.test.js.map +1 -0
- package/dist/src/a2a/__tests__/executor.test.js +146 -8
- package/dist/src/a2a/__tests__/executor.test.js.map +1 -1
- package/dist/src/a2a/__tests__/server.test.js +20 -0
- package/dist/src/a2a/__tests__/server.test.js.map +1 -1
- package/dist/src/a2a/async-lock.d.ts +22 -0
- package/dist/src/a2a/async-lock.d.ts.map +1 -0
- package/dist/src/a2a/async-lock.js +38 -0
- package/dist/src/a2a/async-lock.js.map +1 -0
- package/dist/src/a2a/executor.d.ts +59 -24
- package/dist/src/a2a/executor.d.ts.map +1 -1
- package/dist/src/a2a/executor.js +209 -32
- package/dist/src/a2a/executor.js.map +1 -1
- package/dist/src/a2a/index.d.ts +1 -1
- package/dist/src/a2a/index.d.ts.map +1 -1
- package/dist/src/a2a/index.js +1 -1
- package/dist/src/a2a/index.js.map +1 -1
- package/dist/src/a2a/server.d.ts +18 -2
- package/dist/src/a2a/server.d.ts.map +1 -1
- package/dist/src/a2a/server.js +13 -2
- package/dist/src/a2a/server.js.map +1 -1
- package/dist/src/agent/__tests__/agent.context-manager.test.d.ts +2 -0
- package/dist/src/agent/__tests__/agent.context-manager.test.d.ts.map +1 -0
- package/dist/src/agent/__tests__/agent.context-manager.test.js +107 -0
- package/dist/src/agent/__tests__/agent.context-manager.test.js.map +1 -0
- package/dist/src/agent/__tests__/agent.test.js +195 -0
- package/dist/src/agent/__tests__/agent.test.js.map +1 -1
- package/dist/src/agent/__tests__/agent.tracer.test.node.js +14 -0
- package/dist/src/agent/__tests__/agent.tracer.test.node.js.map +1 -1
- package/dist/src/agent/__tests__/tool-caller.test.d.ts +2 -0
- package/dist/src/agent/__tests__/tool-caller.test.d.ts.map +1 -0
- package/dist/src/agent/__tests__/tool-caller.test.js +459 -0
- package/dist/src/agent/__tests__/tool-caller.test.js.map +1 -0
- package/dist/src/agent/agent.d.ts +194 -4
- package/dist/src/agent/agent.d.ts.map +1 -1
- package/dist/src/agent/agent.js +599 -253
- package/dist/src/agent/agent.js.map +1 -1
- package/dist/src/agent/tool-caller.d.ts +149 -0
- package/dist/src/agent/tool-caller.d.ts.map +1 -0
- package/dist/src/agent/tool-caller.js +198 -0
- package/dist/src/agent/tool-caller.js.map +1 -0
- package/dist/src/conversation-manager/__tests__/pin.test.d.ts +2 -0
- package/dist/src/conversation-manager/__tests__/pin.test.d.ts.map +1 -0
- package/dist/src/conversation-manager/__tests__/pin.test.js +119 -0
- package/dist/src/conversation-manager/__tests__/pin.test.js.map +1 -0
- package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js +49 -0
- package/dist/src/conversation-manager/__tests__/sliding-window-conversation-manager.test.js.map +1 -1
- package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js +58 -0
- package/dist/src/conversation-manager/__tests__/summarizing-conversation-manager.test.js.map +1 -1
- package/dist/src/conversation-manager/pin-message.d.ts +45 -0
- package/dist/src/conversation-manager/pin-message.d.ts.map +1 -0
- package/dist/src/conversation-manager/pin-message.js +106 -0
- package/dist/src/conversation-manager/pin-message.js.map +1 -0
- package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts +7 -0
- package/dist/src/conversation-manager/sliding-window-conversation-manager.d.ts.map +1 -1
- package/dist/src/conversation-manager/sliding-window-conversation-manager.js +27 -4
- package/dist/src/conversation-manager/sliding-window-conversation-manager.js.map +1 -1
- package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts +7 -0
- package/dist/src/conversation-manager/summarizing-conversation-manager.d.ts.map +1 -1
- package/dist/src/conversation-manager/summarizing-conversation-manager.js +18 -4
- package/dist/src/conversation-manager/summarizing-conversation-manager.js.map +1 -1
- package/dist/src/default-slot.d.ts +6 -0
- package/dist/src/default-slot.d.ts.map +1 -0
- package/dist/src/default-slot.js +18 -0
- package/dist/src/default-slot.js.map +1 -0
- package/dist/src/errors.d.ts +25 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +32 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +15 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +10 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.node.d.ts +2 -0
- package/dist/src/index.node.d.ts.map +1 -0
- package/dist/src/index.node.js +9 -0
- package/dist/src/index.node.js.map +1 -0
- package/dist/src/interrupt.d.ts +5 -1
- package/dist/src/interrupt.d.ts.map +1 -1
- package/dist/src/interrupt.js +6 -0
- package/dist/src/interrupt.js.map +1 -1
- package/dist/src/interventions/handler.d.ts +1 -2
- package/dist/src/interventions/handler.d.ts.map +1 -1
- package/dist/src/interventions/registry.d.ts +2 -0
- package/dist/src/interventions/registry.d.ts.map +1 -1
- package/dist/src/interventions/registry.js +4 -0
- package/dist/src/interventions/registry.js.map +1 -1
- package/dist/src/mcp.d.ts +20 -15
- package/dist/src/mcp.d.ts.map +1 -1
- package/dist/src/mcp.js +15 -8
- package/dist/src/mcp.js.map +1 -1
- package/dist/src/memory/__tests__/memory-manager.test.d.ts +2 -0
- package/dist/src/memory/__tests__/memory-manager.test.d.ts.map +1 -0
- package/dist/src/memory/__tests__/memory-manager.test.js +493 -0
- package/dist/src/memory/__tests__/memory-manager.test.js.map +1 -0
- package/dist/src/memory/extraction/__tests__/extraction.test.d.ts +2 -0
- package/dist/src/memory/extraction/__tests__/extraction.test.d.ts.map +1 -0
- package/dist/src/memory/extraction/__tests__/extraction.test.js +637 -0
- package/dist/src/memory/extraction/__tests__/extraction.test.js.map +1 -0
- package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts +2 -0
- package/dist/src/memory/extraction/__tests__/model-extractor.test.d.ts.map +1 -0
- package/dist/src/memory/extraction/__tests__/model-extractor.test.js +68 -0
- package/dist/src/memory/extraction/__tests__/model-extractor.test.js.map +1 -0
- package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts +2 -0
- package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.d.ts.map +1 -0
- package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js +81 -0
- package/dist/src/memory/extraction/__tests__/resolve-extraction-config.test.js.map +1 -0
- package/dist/src/memory/extraction/coordinator.d.ts +128 -0
- package/dist/src/memory/extraction/coordinator.d.ts.map +1 -0
- package/dist/src/memory/extraction/coordinator.js +245 -0
- package/dist/src/memory/extraction/coordinator.js.map +1 -0
- package/dist/src/memory/extraction/model-extractor.d.ts +32 -0
- package/dist/src/memory/extraction/model-extractor.d.ts.map +1 -0
- package/dist/src/memory/extraction/model-extractor.js +118 -0
- package/dist/src/memory/extraction/model-extractor.js.map +1 -0
- package/dist/src/memory/extraction/resolve-extraction-config.d.ts +46 -0
- package/dist/src/memory/extraction/resolve-extraction-config.d.ts.map +1 -0
- package/dist/src/memory/extraction/resolve-extraction-config.js +59 -0
- package/dist/src/memory/extraction/resolve-extraction-config.js.map +1 -0
- package/dist/src/memory/extraction/triggers.d.ts +41 -0
- package/dist/src/memory/extraction/triggers.d.ts.map +1 -0
- package/dist/src/memory/extraction/triggers.js +59 -0
- package/dist/src/memory/extraction/triggers.js.map +1 -0
- package/dist/src/memory/extraction/types.d.ts +133 -0
- package/dist/src/memory/extraction/types.d.ts.map +1 -0
- package/dist/src/memory/extraction/types.js +19 -0
- package/dist/src/memory/extraction/types.js.map +1 -0
- package/dist/src/memory/index.d.ts +9 -0
- package/dist/src/memory/index.d.ts.map +1 -0
- package/dist/src/memory/index.js +5 -0
- package/dist/src/memory/index.js.map +1 -0
- package/dist/src/memory/memory-manager.d.ts +131 -0
- package/dist/src/memory/memory-manager.d.ts.map +1 -0
- package/dist/src/memory/memory-manager.js +404 -0
- package/dist/src/memory/memory-manager.js.map +1 -0
- package/dist/src/memory/types.d.ts +213 -0
- package/dist/src/memory/types.d.ts.map +1 -0
- package/dist/src/memory/types.js +2 -0
- package/dist/src/memory/types.js.map +1 -0
- package/dist/src/middleware/__tests__/agent-middleware.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/agent-middleware.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/agent-middleware.test.js +1207 -0
- package/dist/src/middleware/__tests__/agent-middleware.test.js.map +1 -0
- package/dist/src/middleware/__tests__/custom-stages.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/custom-stages.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/custom-stages.test.js +97 -0
- package/dist/src/middleware/__tests__/custom-stages.test.js.map +1 -0
- package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/middleware-interrupts.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/middleware-interrupts.test.js +267 -0
- package/dist/src/middleware/__tests__/middleware-interrupts.test.js.map +1 -0
- package/dist/src/middleware/__tests__/registry.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/registry.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/registry.test.js +525 -0
- package/dist/src/middleware/__tests__/registry.test.js.map +1 -0
- package/dist/src/middleware/index.d.ts +5 -0
- package/dist/src/middleware/index.d.ts.map +1 -0
- package/dist/src/middleware/index.js +3 -0
- package/dist/src/middleware/index.js.map +1 -0
- package/dist/src/middleware/registry.d.ts +58 -0
- package/dist/src/middleware/registry.d.ts.map +1 -0
- package/dist/src/middleware/registry.js +107 -0
- package/dist/src/middleware/registry.js.map +1 -0
- package/dist/src/middleware/stages.d.ts +138 -0
- package/dist/src/middleware/stages.d.ts.map +1 -0
- package/dist/src/middleware/stages.js +31 -0
- package/dist/src/middleware/stages.js.map +1 -0
- package/dist/src/middleware/types.d.ts +88 -0
- package/dist/src/middleware/types.d.ts.map +1 -0
- package/dist/src/middleware/types.js +2 -0
- package/dist/src/middleware/types.js.map +1 -0
- package/dist/src/models/__tests__/anthropic.test.js +37 -7
- package/dist/src/models/__tests__/anthropic.test.js.map +1 -1
- package/dist/src/models/__tests__/bedrock.test.js +181 -0
- package/dist/src/models/__tests__/bedrock.test.js.map +1 -1
- package/dist/src/models/__tests__/model.test.js +46 -3
- package/dist/src/models/__tests__/model.test.js.map +1 -1
- package/dist/src/models/anthropic.d.ts.map +1 -1
- package/dist/src/models/anthropic.js +7 -4
- package/dist/src/models/anthropic.js.map +1 -1
- package/dist/src/models/bedrock.d.ts +26 -1
- package/dist/src/models/bedrock.d.ts.map +1 -1
- package/dist/src/models/bedrock.js +34 -9
- package/dist/src/models/bedrock.js.map +1 -1
- package/dist/src/models/defaults.d.ts.map +1 -1
- package/dist/src/models/defaults.js +2 -0
- package/dist/src/models/defaults.js.map +1 -1
- package/dist/src/models/model.d.ts.map +1 -1
- package/dist/src/models/model.js +7 -3
- package/dist/src/models/model.js.map +1 -1
- package/dist/src/models/openai/__tests__/chat.test.js +2 -10
- package/dist/src/models/openai/__tests__/chat.test.js.map +1 -1
- package/dist/src/models/openai/__tests__/errors.test.d.ts +2 -0
- package/dist/src/models/openai/__tests__/errors.test.d.ts.map +1 -0
- package/dist/src/models/openai/__tests__/errors.test.js +30 -0
- package/dist/src/models/openai/__tests__/errors.test.js.map +1 -0
- package/dist/src/models/openai/__tests__/responses.test.js +8 -33
- package/dist/src/models/openai/__tests__/responses.test.js.map +1 -1
- package/dist/src/models/openai/errors.d.ts.map +1 -1
- package/dist/src/models/openai/errors.js +5 -3
- package/dist/src/models/openai/errors.js.map +1 -1
- package/dist/src/multiagent/__tests__/nodes.test.js +50 -0
- package/dist/src/multiagent/__tests__/nodes.test.js.map +1 -1
- package/dist/src/multiagent/nodes.d.ts +23 -2
- package/dist/src/multiagent/nodes.d.ts.map +1 -1
- package/dist/src/multiagent/nodes.js +18 -4
- package/dist/src/multiagent/nodes.js.map +1 -1
- package/dist/src/registry/__tests__/tool-registry.test.js +50 -1
- package/dist/src/registry/__tests__/tool-registry.test.js.map +1 -1
- package/dist/src/registry/tool-registry.d.ts +13 -0
- package/dist/src/registry/tool-registry.d.ts.map +1 -1
- package/dist/src/registry/tool-registry.js +35 -1
- package/dist/src/registry/tool-registry.js.map +1 -1
- package/dist/src/sandbox/__tests__/default.test.browser.d.ts +2 -0
- package/dist/src/sandbox/__tests__/default.test.browser.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/default.test.browser.js +11 -0
- package/dist/src/sandbox/__tests__/default.test.browser.js.map +1 -0
- package/dist/src/sandbox/__tests__/default.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/default.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/default.test.node.js +23 -0
- package/dist/src/sandbox/__tests__/default.test.node.js.map +1 -0
- package/dist/src/sandbox/__tests__/docker.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/docker.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/docker.test.node.js +89 -0
- package/dist/src/sandbox/__tests__/docker.test.node.js.map +1 -0
- package/dist/src/sandbox/__tests__/errors.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/errors.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/errors.test.node.js +33 -0
- package/dist/src/sandbox/__tests__/errors.test.node.js.map +1 -0
- package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js +124 -0
- package/dist/src/sandbox/__tests__/not-a-sandbox-local-environment.test.node.js.map +1 -0
- package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/posix-shell.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/posix-shell.test.node.js +298 -0
- package/dist/src/sandbox/__tests__/posix-shell.test.node.js.map +1 -0
- package/dist/src/sandbox/__tests__/ssh.test.node.d.ts +2 -0
- package/dist/src/sandbox/__tests__/ssh.test.node.d.ts.map +1 -0
- package/dist/src/sandbox/__tests__/ssh.test.node.js +262 -0
- package/dist/src/sandbox/__tests__/ssh.test.node.js.map +1 -0
- package/dist/src/sandbox/base.d.ts +156 -0
- package/dist/src/sandbox/base.d.ts.map +1 -0
- package/dist/src/sandbox/base.js +97 -0
- package/dist/src/sandbox/base.js.map +1 -0
- package/dist/src/sandbox/constants.d.ts +25 -0
- package/dist/src/sandbox/constants.d.ts.map +1 -0
- package/dist/src/sandbox/constants.js +27 -0
- package/dist/src/sandbox/constants.js.map +1 -0
- package/dist/src/sandbox/default.d.ts +3 -0
- package/dist/src/sandbox/default.d.ts.map +1 -0
- package/dist/src/sandbox/default.js +3 -0
- package/dist/src/sandbox/default.js.map +1 -0
- package/dist/src/sandbox/docker.d.ts +38 -0
- package/dist/src/sandbox/docker.d.ts.map +1 -0
- package/dist/src/sandbox/docker.js +59 -0
- package/dist/src/sandbox/docker.js.map +1 -0
- package/dist/src/sandbox/errors.d.ts +26 -0
- package/dist/src/sandbox/errors.d.ts.map +1 -0
- package/dist/src/sandbox/errors.js +35 -0
- package/dist/src/sandbox/errors.js.map +1 -0
- package/dist/src/sandbox/index.d.ts +5 -0
- package/dist/src/sandbox/index.d.ts.map +1 -0
- package/dist/src/sandbox/index.js +4 -0
- package/dist/src/sandbox/index.js.map +1 -0
- package/dist/src/sandbox/not-a-sandbox-local-environment.d.ts +16 -0
- package/dist/src/sandbox/not-a-sandbox-local-environment.d.ts.map +1 -0
- package/dist/src/sandbox/not-a-sandbox-local-environment.js +83 -0
- package/dist/src/sandbox/not-a-sandbox-local-environment.js.map +1 -0
- package/dist/src/sandbox/posix-shell.d.ts +53 -0
- package/dist/src/sandbox/posix-shell.d.ts.map +1 -0
- package/dist/src/sandbox/posix-shell.js +116 -0
- package/dist/src/sandbox/posix-shell.js.map +1 -0
- package/dist/src/sandbox/ssh.d.ts +56 -0
- package/dist/src/sandbox/ssh.d.ts.map +1 -0
- package/dist/src/sandbox/ssh.js +119 -0
- package/dist/src/sandbox/ssh.js.map +1 -0
- package/dist/src/sandbox/stream-process.d.ts +32 -0
- package/dist/src/sandbox/stream-process.d.ts.map +1 -0
- package/dist/src/sandbox/stream-process.js +161 -0
- package/dist/src/sandbox/stream-process.js.map +1 -0
- package/dist/src/sandbox/types.d.ts +57 -0
- package/dist/src/sandbox/types.d.ts.map +1 -0
- package/dist/src/sandbox/types.js +8 -0
- package/dist/src/sandbox/types.js.map +1 -0
- package/dist/src/telemetry/__tests__/meter.test.js +11 -0
- package/dist/src/telemetry/__tests__/meter.test.js.map +1 -1
- package/dist/src/telemetry/meter.d.ts +10 -6
- package/dist/src/telemetry/meter.d.ts.map +1 -1
- package/dist/src/telemetry/meter.js +16 -3
- package/dist/src/telemetry/meter.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/types/__tests__/messages.test.js +28 -0
- package/dist/src/types/__tests__/messages.test.js.map +1 -1
- package/dist/src/types/agent.d.ts +72 -0
- package/dist/src/types/agent.d.ts.map +1 -1
- package/dist/src/types/agent.js.map +1 -1
- package/dist/src/types/lifecycle-observer.d.ts +18 -0
- package/dist/src/types/lifecycle-observer.d.ts.map +1 -0
- package/dist/src/types/lifecycle-observer.js +2 -0
- package/dist/src/types/lifecycle-observer.js.map +1 -0
- package/dist/src/types/messages.d.ts +19 -3
- package/dist/src/types/messages.d.ts.map +1 -1
- package/dist/src/types/messages.js +9 -0
- package/dist/src/types/messages.js.map +1 -1
- package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts +2 -0
- package/dist/src/vended-interventions/hitl/__tests__/hitl.test.d.ts.map +1 -0
- package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js +358 -0
- package/dist/src/vended-interventions/hitl/__tests__/hitl.test.js.map +1 -0
- package/dist/src/vended-interventions/hitl/hitl.d.ts +115 -0
- package/dist/src/vended-interventions/hitl/hitl.d.ts.map +1 -0
- package/dist/src/vended-interventions/hitl/hitl.js +138 -0
- package/dist/src/vended-interventions/hitl/hitl.js.map +1 -0
- package/dist/src/vended-interventions/hitl/index.d.ts +24 -0
- package/dist/src/vended-interventions/hitl/index.d.ts.map +1 -0
- package/dist/src/vended-interventions/hitl/index.js +23 -0
- package/dist/src/vended-interventions/hitl/index.js.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts +2 -0
- package/dist/src/vended-interventions/steering/__tests__/handler.test.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/handler.test.js +163 -0
- package/dist/src/vended-interventions/steering/__tests__/handler.test.js.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts +2 -0
- package/dist/src/vended-interventions/steering/__tests__/llm.test.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/llm.test.js +60 -0
- package/dist/src/vended-interventions/steering/__tests__/llm.test.js.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts +2 -0
- package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js +94 -0
- package/dist/src/vended-interventions/steering/__tests__/tool-ledger.test.js.map +1 -0
- package/dist/src/vended-interventions/steering/handlers/handler.d.ts +64 -0
- package/dist/src/vended-interventions/steering/handlers/handler.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/handlers/handler.js +71 -0
- package/dist/src/vended-interventions/steering/handlers/handler.js.map +1 -0
- package/dist/src/vended-interventions/steering/handlers/llm.d.ts +72 -0
- package/dist/src/vended-interventions/steering/handlers/llm.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/handlers/llm.js +177 -0
- package/dist/src/vended-interventions/steering/handlers/llm.js.map +1 -0
- package/dist/src/vended-interventions/steering/index.d.ts +31 -0
- package/dist/src/vended-interventions/steering/index.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/index.js +32 -0
- package/dist/src/vended-interventions/steering/index.js.map +1 -0
- package/dist/src/vended-interventions/steering/providers/context-provider.d.ts +55 -0
- package/dist/src/vended-interventions/steering/providers/context-provider.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/providers/context-provider.js +8 -0
- package/dist/src/vended-interventions/steering/providers/context-provider.js.map +1 -0
- package/dist/src/vended-interventions/steering/providers/tool-ledger.d.ts +49 -0
- package/dist/src/vended-interventions/steering/providers/tool-ledger.d.ts.map +1 -0
- package/dist/src/vended-interventions/steering/providers/tool-ledger.js +75 -0
- package/dist/src/vended-interventions/steering/providers/tool-ledger.js.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts +2 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.d.ts.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.js +611 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/__tests__/bedrock-knowledge-base-store.test.js.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts +2 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.d.ts.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.js +2 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/index.js.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts +230 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.d.ts.map +1 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js +370 -0
- package/dist/src/vended-memory-stores/bedrock-knowledge-base/store.js.map +1 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts +2 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.d.ts.map +1 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js +68 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/file-storage-sandbox.test.node.js.map +1 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts +2 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.d.ts.map +1 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js +93 -0
- package/dist/src/vended-plugins/context-offloader/__tests__/plugin.test.node.js.map +1 -0
- package/dist/src/vended-plugins/context-offloader/index.d.ts +1 -1
- package/dist/src/vended-plugins/context-offloader/index.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/plugin.d.ts +4 -1
- package/dist/src/vended-plugins/context-offloader/plugin.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/plugin.js +29 -7
- package/dist/src/vended-plugins/context-offloader/plugin.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/search.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/search.js +3 -5
- package/dist/src/vended-plugins/context-offloader/search.js.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.d.ts +29 -5
- package/dist/src/vended-plugins/context-offloader/storage.d.ts.map +1 -1
- package/dist/src/vended-plugins/context-offloader/storage.js +75 -11
- package/dist/src/vended-plugins/context-offloader/storage.js.map +1 -1
- package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts +2 -0
- package/dist/src/vended-plugins/goal/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/src/vended-plugins/goal/__tests__/plugin.test.js +736 -0
- package/dist/src/vended-plugins/goal/__tests__/plugin.test.js.map +1 -0
- package/dist/src/vended-plugins/goal/index.d.ts +21 -0
- package/dist/src/vended-plugins/goal/index.d.ts.map +1 -0
- package/dist/src/vended-plugins/goal/index.js +20 -0
- package/dist/src/vended-plugins/goal/index.js.map +1 -0
- package/dist/src/vended-plugins/goal/judge.d.ts +41 -0
- package/dist/src/vended-plugins/goal/judge.d.ts.map +1 -0
- package/dist/src/vended-plugins/goal/judge.js +92 -0
- package/dist/src/vended-plugins/goal/judge.js.map +1 -0
- package/dist/src/vended-plugins/goal/plugin.d.ts +214 -0
- package/dist/src/vended-plugins/goal/plugin.d.ts.map +1 -0
- package/dist/src/vended-plugins/goal/plugin.js +287 -0
- package/dist/src/vended-plugins/goal/plugin.js.map +1 -0
- package/dist/src/vended-plugins/index.d.ts +12 -0
- package/dist/src/vended-plugins/index.d.ts.map +1 -0
- package/dist/src/vended-plugins/index.js +12 -0
- package/dist/src/vended-plugins/index.js.map +1 -0
- package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js +17 -7
- package/dist/src/vended-plugins/skills/__tests__/agent-skills.test.node.js.map +1 -1
- package/dist/src/vended-plugins/skills/agent-skills.d.ts +21 -7
- package/dist/src/vended-plugins/skills/agent-skills.d.ts.map +1 -1
- package/dist/src/vended-plugins/skills/agent-skills.js +144 -77
- package/dist/src/vended-plugins/skills/agent-skills.js.map +1 -1
- package/dist/src/vended-tools/bash/__tests__/bash.test.node.js +44 -4
- package/dist/src/vended-tools/bash/__tests__/bash.test.node.js.map +1 -1
- package/dist/src/vended-tools/bash/bash.d.ts +3 -24
- package/dist/src/vended-tools/bash/bash.d.ts.map +1 -1
- package/dist/src/vended-tools/bash/bash.js +9 -9
- package/dist/src/vended-tools/bash/bash.js.map +1 -1
- package/dist/src/vended-tools/bash/index.d.ts +3 -1
- package/dist/src/vended-tools/bash/index.d.ts.map +1 -1
- package/dist/src/vended-tools/bash/index.js +2 -1
- package/dist/src/vended-tools/bash/index.js.map +1 -1
- package/dist/src/vended-tools/bash/make-bash.d.ts +22 -0
- package/dist/src/vended-tools/bash/make-bash.d.ts.map +1 -0
- package/dist/src/vended-tools/bash/make-bash.js +40 -0
- package/dist/src/vended-tools/bash/make-bash.js.map +1 -0
- package/dist/src/vended-tools/bash/types.d.ts +1 -0
- package/dist/src/vended-tools/bash/types.d.ts.map +1 -1
- package/dist/src/vended-tools/bash/types.js +2 -0
- package/dist/src/vended-tools/bash/types.js.map +1 -1
- package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js +83 -1
- package/dist/src/vended-tools/file-editor/__tests__/file-editor.test.node.js.map +1 -1
- package/dist/src/vended-tools/file-editor/file-editor.d.ts +19 -10
- package/dist/src/vended-tools/file-editor/file-editor.d.ts.map +1 -1
- package/dist/src/vended-tools/file-editor/file-editor.js +188 -218
- package/dist/src/vended-tools/file-editor/file-editor.js.map +1 -1
- package/dist/src/vended-tools/file-editor/index.d.ts +2 -1
- package/dist/src/vended-tools/file-editor/index.d.ts.map +1 -1
- package/dist/src/vended-tools/file-editor/index.js +1 -1
- package/dist/src/vended-tools/file-editor/index.js.map +1 -1
- package/dist/src/vended-tools/index.d.ts +17 -0
- package/dist/src/vended-tools/index.d.ts.map +1 -0
- package/dist/src/vended-tools/index.js +17 -0
- package/dist/src/vended-tools/index.js.map +1 -0
- package/package.json +66 -15
package/dist/src/agent/agent.js
CHANGED
|
@@ -1,55 +1,3 @@
|
|
|
1
|
-
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
-
if (value !== null && value !== void 0) {
|
|
3
|
-
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
-
var dispose, inner;
|
|
5
|
-
if (async) {
|
|
6
|
-
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
-
dispose = value[Symbol.asyncDispose];
|
|
8
|
-
}
|
|
9
|
-
if (dispose === void 0) {
|
|
10
|
-
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
-
dispose = value[Symbol.dispose];
|
|
12
|
-
if (async) inner = dispose;
|
|
13
|
-
}
|
|
14
|
-
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
-
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
-
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
-
}
|
|
18
|
-
else if (async) {
|
|
19
|
-
env.stack.push({ async: true });
|
|
20
|
-
}
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
-
return function (env) {
|
|
25
|
-
function fail(e) {
|
|
26
|
-
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
-
env.hasError = true;
|
|
28
|
-
}
|
|
29
|
-
var r, s = 0;
|
|
30
|
-
function next() {
|
|
31
|
-
while (r = env.stack.pop()) {
|
|
32
|
-
try {
|
|
33
|
-
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
-
if (r.dispose) {
|
|
35
|
-
var result = r.dispose.call(r.value);
|
|
36
|
-
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
-
}
|
|
38
|
-
else s |= 1;
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
fail(e);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
-
if (env.hasError) throw env.error;
|
|
46
|
-
}
|
|
47
|
-
return next();
|
|
48
|
-
};
|
|
49
|
-
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
-
var e = new Error(message);
|
|
51
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
-
});
|
|
53
1
|
import { AgentResult, } from '../types/agent.js';
|
|
54
2
|
import { BedrockModel } from '../models/bedrock.js';
|
|
55
3
|
import { contentBlockFromData, Message, TextBlock, ToolResultBlock, ToolUseBlock, } from '../types/messages.js';
|
|
@@ -66,12 +14,18 @@ import { AgentPrinter, getDefaultAppender } from './printer.js';
|
|
|
66
14
|
import { InterventionRegistry } from '../interventions/registry.js';
|
|
67
15
|
import { PluginRegistry } from '../plugins/registry.js';
|
|
68
16
|
import { SlidingWindowConversationManager } from '../conversation-manager/sliding-window-conversation-manager.js';
|
|
17
|
+
import { SummarizingConversationManager } from '../conversation-manager/summarizing-conversation-manager.js';
|
|
69
18
|
import { NullConversationManager } from '../conversation-manager/null-conversation-manager.js';
|
|
70
19
|
import { ConversationManager } from '../conversation-manager/conversation-manager.js';
|
|
20
|
+
import { ContextOffloader } from '../vended-plugins/context-offloader/plugin.js';
|
|
21
|
+
import { InMemoryStorage } from '../vended-plugins/context-offloader/storage.js';
|
|
71
22
|
import { HookRegistryImplementation } from '../hooks/registry.js';
|
|
23
|
+
import { MiddlewareRegistry, InvokeModelStage, ExecuteToolStage, AgentStreamStage } from '../middleware/index.js';
|
|
72
24
|
import { InitializedEvent, AfterInvocationEvent, AfterModelCallEvent, AfterToolCallEvent, AfterToolsEvent, BeforeInvocationEvent, BeforeModelCallEvent, BeforeToolCallEvent, BeforeToolsEvent, HookableEvent, MessageAddedEvent, ModelStreamUpdateEvent, ContentBlockEvent, ModelMessageEvent, ToolResultEvent, AgentResultEvent, ToolStreamUpdateEvent, InterruptEvent, } from '../hooks/events.js';
|
|
73
25
|
import { StructuredOutputTool, STRUCTURED_OUTPUT_TOOL_NAME } from '../tools/structured-output-tool.js';
|
|
74
26
|
import { AgentAsTool } from './agent-as-tool.js';
|
|
27
|
+
import { ToolCaller } from './tool-caller.js';
|
|
28
|
+
import { MemoryManager } from '../memory/memory-manager.js';
|
|
75
29
|
import { SessionManager } from '../session/session-manager.js';
|
|
76
30
|
import { Tracer } from '../telemetry/tracer.js';
|
|
77
31
|
import { Meter } from '../telemetry/meter.js';
|
|
@@ -79,13 +33,69 @@ import { logger } from '../logging/logger.js';
|
|
|
79
33
|
import { CancelledError } from '../errors.js';
|
|
80
34
|
import { DefaultModelRetryStrategy } from '../retry/default-model-retry-strategy.js';
|
|
81
35
|
import { warnOnDuplicateRetryStrategyTypes } from '../retry/retry-strategy.js';
|
|
82
|
-
import { InterruptError, InterruptState, interruptFromAgent } from '../interrupt.js';
|
|
36
|
+
import { Interrupt, InterruptError, InterruptState, interruptFromAgent } from '../interrupt.js';
|
|
83
37
|
import { isInterruptResponseContent } from '../types/interrupt.js';
|
|
84
38
|
import { takeSnapshot as takeSnapshotInternal, loadSnapshot as loadSnapshotInternal } from './snapshot.js';
|
|
39
|
+
import { defaultSandbox } from '../sandbox/default.js';
|
|
40
|
+
/** Benchmark-validated token threshold for offloading tool results. */
|
|
41
|
+
const CONTEXT_MANAGER_MAX_RESULT_TOKENS = 1_500;
|
|
42
|
+
/** Benchmark-validated preview token count for offloaded results. */
|
|
43
|
+
const CONTEXT_MANAGER_PREVIEW_TOKENS = 750;
|
|
44
|
+
/** Benchmark-validated ratio of messages to summarize on overflow. */
|
|
45
|
+
const CONTEXT_MANAGER_SUMMARY_RATIO = 0.3;
|
|
46
|
+
/** Benchmark-validated context window ratio that triggers proactive compression. */
|
|
47
|
+
const CONTEXT_MANAGER_COMPRESSION_THRESHOLD = 0.85;
|
|
48
|
+
/**
|
|
49
|
+
* Resolve the contextManager facade into a concrete ConversationManager.
|
|
50
|
+
*
|
|
51
|
+
* When contextManager is undefined, falls back to the default SlidingWindowConversationManager.
|
|
52
|
+
* When "auto", uses SummarizingConversationManager with benchmark-validated defaults,
|
|
53
|
+
* unless the user already provided a conversationManager.
|
|
54
|
+
*/
|
|
55
|
+
function resolveConversationManager(contextManager, conversationManager) {
|
|
56
|
+
if (contextManager !== undefined && contextManager !== 'auto') {
|
|
57
|
+
throw new Error(`Unsupported contextManager value: "${contextManager}". Supported values: "auto"`);
|
|
58
|
+
}
|
|
59
|
+
if (contextManager === 'auto') {
|
|
60
|
+
return (conversationManager ??
|
|
61
|
+
new SummarizingConversationManager({
|
|
62
|
+
summaryRatio: CONTEXT_MANAGER_SUMMARY_RATIO,
|
|
63
|
+
proactiveCompression: { compressionThreshold: CONTEXT_MANAGER_COMPRESSION_THRESHOLD },
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
return conversationManager ?? new SlidingWindowConversationManager({ windowSize: 40 });
|
|
67
|
+
}
|
|
85
68
|
/** Default name assigned to agents when none is provided. */
|
|
86
69
|
const DEFAULT_AGENT_NAME = 'Strands Agent';
|
|
87
70
|
/** Default identifier assigned to agents when none is provided. */
|
|
88
71
|
const DEFAULT_AGENT_ID = 'agent';
|
|
72
|
+
/**
|
|
73
|
+
* Creates a non-mutating interrupt function for middleware contexts.
|
|
74
|
+
* Reads existing responses from state (resume case) but never writes to it.
|
|
75
|
+
* On first run (no response), throws InterruptError with a locally-created Interrupt.
|
|
76
|
+
*
|
|
77
|
+
* @param interruptState - The agent's interrupt state (read-only access)
|
|
78
|
+
* @param idPrefix - Prefix for the interrupt ID (e.g., 'middleware:agentStream')
|
|
79
|
+
*/
|
|
80
|
+
function createMiddlewareInterrupt(interruptState, idPrefix) {
|
|
81
|
+
return (params) => {
|
|
82
|
+
const interruptId = `${idPrefix}:${params.name}`;
|
|
83
|
+
const existing = interruptState.interrupts[interruptId];
|
|
84
|
+
if (existing?.response !== undefined) {
|
|
85
|
+
return { response: existing.response };
|
|
86
|
+
}
|
|
87
|
+
if (params.response !== undefined) {
|
|
88
|
+
return { response: params.response };
|
|
89
|
+
}
|
|
90
|
+
const interrupt = new Interrupt({
|
|
91
|
+
id: interruptId,
|
|
92
|
+
name: params.name,
|
|
93
|
+
...(params.reason !== undefined && { reason: params.reason }),
|
|
94
|
+
source: 'middleware',
|
|
95
|
+
});
|
|
96
|
+
throw new InterruptError(interrupt);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
89
99
|
/**
|
|
90
100
|
* Orchestrates the interaction between a model, a set of tools, and MCP clients.
|
|
91
101
|
* The Agent is responsible for managing the lifecycle of tools and clients
|
|
@@ -132,7 +142,22 @@ export class Agent {
|
|
|
132
142
|
* The session manager for saving and restoring agent sessions, if configured.
|
|
133
143
|
*/
|
|
134
144
|
sessionManager;
|
|
145
|
+
/**
|
|
146
|
+
* The memory manager for cross-session memory retrieval and storage, if configured.
|
|
147
|
+
*/
|
|
148
|
+
memoryManager;
|
|
149
|
+
_sandbox;
|
|
150
|
+
/**
|
|
151
|
+
* Execution environment for running commands, code, and file operations.
|
|
152
|
+
*
|
|
153
|
+
* @throws DefaultNotConfiguredError if no sandbox is configured for this
|
|
154
|
+
* environment (e.g. browsers, where no host default is registered).
|
|
155
|
+
*/
|
|
156
|
+
get sandbox() {
|
|
157
|
+
return this._sandbox || defaultSandbox.get();
|
|
158
|
+
}
|
|
135
159
|
_hooksRegistry;
|
|
160
|
+
_middlewareRegistry;
|
|
136
161
|
_pluginRegistry;
|
|
137
162
|
_interventionRegistry;
|
|
138
163
|
_toolRegistry;
|
|
@@ -151,6 +176,8 @@ export class Agent {
|
|
|
151
176
|
_interruptState;
|
|
152
177
|
/** Strategy for executing tool calls from a single assistant turn. */
|
|
153
178
|
_toolExecutor;
|
|
179
|
+
/** Direct tool caller — created via {@link ToolCaller.create} factory. */
|
|
180
|
+
_toolCaller;
|
|
154
181
|
/**
|
|
155
182
|
* Creates an instance of the Agent.
|
|
156
183
|
* @param config - The configuration for the agent.
|
|
@@ -165,6 +192,13 @@ export class Agent {
|
|
|
165
192
|
if (config?.description !== undefined)
|
|
166
193
|
this.description = config.description;
|
|
167
194
|
this.sessionManager = config?.sessionManager;
|
|
195
|
+
this.memoryManager =
|
|
196
|
+
config?.memoryManager instanceof MemoryManager
|
|
197
|
+
? config.memoryManager
|
|
198
|
+
: config?.memoryManager
|
|
199
|
+
? new MemoryManager(config.memoryManager)
|
|
200
|
+
: undefined;
|
|
201
|
+
this._sandbox = config?.sandbox;
|
|
168
202
|
if (typeof config?.model === 'string') {
|
|
169
203
|
this.model = new BedrockModel({ modelId: config.model });
|
|
170
204
|
}
|
|
@@ -173,14 +207,13 @@ export class Agent {
|
|
|
173
207
|
}
|
|
174
208
|
// Validate and assign conversation manager
|
|
175
209
|
if (this.model.stateful) {
|
|
176
|
-
if (config?.conversationManager) {
|
|
177
|
-
throw new Error('
|
|
210
|
+
if (config?.conversationManager || config?.contextManager) {
|
|
211
|
+
throw new Error('contextManager and conversationManager cannot be used with a stateful model. The model manages conversation state server-side.');
|
|
178
212
|
}
|
|
179
213
|
this._conversationManager = new NullConversationManager();
|
|
180
214
|
}
|
|
181
215
|
else {
|
|
182
|
-
this._conversationManager =
|
|
183
|
-
config?.conversationManager ?? new SlidingWindowConversationManager({ windowSize: 40 });
|
|
216
|
+
this._conversationManager = resolveConversationManager(config?.contextManager, config?.conversationManager);
|
|
184
217
|
}
|
|
185
218
|
const { tools, mcpClients } = flattenTools(config?.tools ?? []);
|
|
186
219
|
this._toolRegistry = new ToolRegistry(tools);
|
|
@@ -188,6 +221,8 @@ export class Agent {
|
|
|
188
221
|
// Initialize hooks registry
|
|
189
222
|
this._hooksRegistry = new HookRegistryImplementation();
|
|
190
223
|
this._interventionRegistry = new InterventionRegistry(config?.interventions ?? [], this._hooksRegistry);
|
|
224
|
+
// Initialize middleware registry
|
|
225
|
+
this._middlewareRegistry = new MiddlewareRegistry();
|
|
191
226
|
// `undefined` (omitted) → install the default; `null`/`[]` → explicit opt-out.
|
|
192
227
|
const retryStrategies = config?.retryStrategy === null
|
|
193
228
|
? []
|
|
@@ -205,10 +240,21 @@ export class Agent {
|
|
|
205
240
|
// - Retry-strategy ordering is not load-bearing for correctness: `DefaultModelRetryStrategy`
|
|
206
241
|
// guards on `event.retry`, so a user hook that already set it short-circuits
|
|
207
242
|
// the strategy regardless of registration order.
|
|
243
|
+
const hasOffloader = (config?.plugins ?? []).some((p) => p.name === 'strands:context-offloader');
|
|
208
244
|
this._pluginRegistry = new PluginRegistry([
|
|
209
245
|
this._conversationManager,
|
|
210
246
|
...retryStrategies,
|
|
211
247
|
...(config?.plugins ?? []),
|
|
248
|
+
...(config?.contextManager === 'auto' && !hasOffloader
|
|
249
|
+
? [
|
|
250
|
+
new ContextOffloader({
|
|
251
|
+
storage: new InMemoryStorage(),
|
|
252
|
+
maxResultTokens: CONTEXT_MANAGER_MAX_RESULT_TOKENS,
|
|
253
|
+
previewTokens: CONTEXT_MANAGER_PREVIEW_TOKENS,
|
|
254
|
+
}),
|
|
255
|
+
]
|
|
256
|
+
: []),
|
|
257
|
+
...(this.memoryManager ? [this.memoryManager] : []),
|
|
212
258
|
...(config?.sessionManager ? [config.sessionManager] : []),
|
|
213
259
|
new ModelPlugin(this.model),
|
|
214
260
|
]);
|
|
@@ -229,6 +275,9 @@ export class Agent {
|
|
|
229
275
|
// Initialize interrupt state for human-in-the-loop workflows
|
|
230
276
|
this._interruptState = new InterruptState();
|
|
231
277
|
this._toolExecutor = config?.toolExecutor ?? 'concurrent';
|
|
278
|
+
// Pass a private helper into ToolCaller so message append + hook firing
|
|
279
|
+
// remains an internal concern of Agent (not exposed as a public method).
|
|
280
|
+
this._toolCaller = ToolCaller.create(this, (message, invocationState) => this._appendMessageAndFireHooks(message, invocationState));
|
|
232
281
|
this._initialized = false;
|
|
233
282
|
}
|
|
234
283
|
/**
|
|
@@ -254,6 +303,33 @@ export class Agent {
|
|
|
254
303
|
addHook(eventType, callback, options) {
|
|
255
304
|
return this._hooksRegistry.addCallback(eventType, callback, options);
|
|
256
305
|
}
|
|
306
|
+
addMiddleware(stageOrPhase, handler) {
|
|
307
|
+
if ('_phase' in stageOrPhase) {
|
|
308
|
+
const phase = stageOrPhase;
|
|
309
|
+
const stage = phase._stage;
|
|
310
|
+
switch (phase._phase) {
|
|
311
|
+
case 'input': {
|
|
312
|
+
const adapted = this._middlewareRegistry.addInput(stageOrPhase, handler);
|
|
313
|
+
return () => this._middlewareRegistry.remove(stage, adapted);
|
|
314
|
+
}
|
|
315
|
+
case 'output': {
|
|
316
|
+
const adapted = this._middlewareRegistry.addOutput(stageOrPhase, handler);
|
|
317
|
+
return () => this._middlewareRegistry.remove(stage, adapted);
|
|
318
|
+
}
|
|
319
|
+
case 'wrap': {
|
|
320
|
+
const wrapHandler = handler;
|
|
321
|
+
this._middlewareRegistry.add(stage, wrapHandler);
|
|
322
|
+
return () => this._middlewareRegistry.remove(stage, wrapHandler);
|
|
323
|
+
}
|
|
324
|
+
default:
|
|
325
|
+
throw new Error(`Unknown middleware phase: ${phase._phase}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const stage = stageOrPhase;
|
|
329
|
+
const wrapHandler = handler;
|
|
330
|
+
this._middlewareRegistry.add(stage, wrapHandler);
|
|
331
|
+
return () => this._middlewareRegistry.remove(stage, wrapHandler);
|
|
332
|
+
}
|
|
257
333
|
async initialize() {
|
|
258
334
|
if (this._initialized) {
|
|
259
335
|
return;
|
|
@@ -267,24 +343,44 @@ export class Agent {
|
|
|
267
343
|
this._toolRegistry.addOrReplace(newTools);
|
|
268
344
|
};
|
|
269
345
|
}));
|
|
346
|
+
// Register tools vended by an explicitly-configured sandbox, applying the sandbox's
|
|
347
|
+
// toolPrefix to names (like MCP's prefix for server-vended tools).
|
|
348
|
+
if (this._sandbox) {
|
|
349
|
+
const prefix = this._sandbox.toolPrefix;
|
|
350
|
+
for (const tool of this._sandbox.getTools()) {
|
|
351
|
+
const prefixed = prefix
|
|
352
|
+
? Object.create(tool, {
|
|
353
|
+
name: { value: `${prefix}_${tool.name}` },
|
|
354
|
+
toolSpec: { value: { ...tool.toolSpec, name: `${prefix}_${tool.name}` } },
|
|
355
|
+
})
|
|
356
|
+
: tool;
|
|
357
|
+
if (this._toolRegistry.get(prefixed.name)) {
|
|
358
|
+
logger.debug(`tool_name=<${prefixed.name}> | sandbox-vended tool skipped, user has already registered tool with this name`);
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
this._toolRegistry.add(prefixed);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
270
365
|
await this._pluginRegistry.initialize(this);
|
|
366
|
+
for (const handler of this._interventionRegistry.handlers) {
|
|
367
|
+
const observer = handler;
|
|
368
|
+
if (typeof observer.observeAgent === 'function') {
|
|
369
|
+
await observer.observeAgent(this);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
271
372
|
await this._hooksRegistry.invokeCallbacks(new InitializedEvent({ agent: this }));
|
|
272
373
|
this._initialized = true;
|
|
273
374
|
}
|
|
274
375
|
/**
|
|
275
|
-
* Acquires
|
|
276
|
-
*
|
|
376
|
+
* Acquires the invocation lock. Throws if an invocation is already in progress.
|
|
377
|
+
* Callers must release via try/finally with `this._isInvoking = false`.
|
|
277
378
|
*/
|
|
278
379
|
acquireLock() {
|
|
279
380
|
if (this._isInvoking) {
|
|
280
381
|
throw new ConcurrentInvocationError('Agent is already processing an invocation. Wait for the current invoke() or stream() call to complete before invoking again.');
|
|
281
382
|
}
|
|
282
383
|
this._isInvoking = true;
|
|
283
|
-
return {
|
|
284
|
-
[Symbol.dispose]: () => {
|
|
285
|
-
this._isInvoking = false;
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
384
|
}
|
|
289
385
|
/**
|
|
290
386
|
* Throws {@link CancelledError} if cancellation has been requested.
|
|
@@ -295,6 +391,63 @@ export class Agent {
|
|
|
295
391
|
throw new CancelledError();
|
|
296
392
|
}
|
|
297
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Validates the per-invocation budget caps in {@link InvokeOptions.limits}.
|
|
396
|
+
* Called once at the top of `_stream` so bad inputs fail fast with a clear
|
|
397
|
+
* error instead of silently no-op'ing (`NaN`, `Infinity`) or tripping
|
|
398
|
+
* pathologically (zero swallows the user input; negative trips immediately).
|
|
399
|
+
*
|
|
400
|
+
* Each cap, when set, must be a positive finite number. Fractional values
|
|
401
|
+
* are accepted — harmless, and useful for token budgets derived from
|
|
402
|
+
* arithmetic.
|
|
403
|
+
*/
|
|
404
|
+
_validateLimits(options) {
|
|
405
|
+
if (!options?.limits)
|
|
406
|
+
return;
|
|
407
|
+
const assertPositive = (name, value) => {
|
|
408
|
+
if (value !== undefined && (!Number.isFinite(value) || value <= 0)) {
|
|
409
|
+
throw new TypeError(`${name} must be a positive finite number, got ${value}`);
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
assertPositive('limits.turns', options.limits.turns);
|
|
413
|
+
assertPositive('limits.outputTokens', options.limits.outputTokens);
|
|
414
|
+
assertPositive('limits.totalTokens', options.limits.totalTokens);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Evaluates the per-invocation budget caps in {@link InvokeOptions.limits}
|
|
418
|
+
* against the current invocation's metrics. Called at the top of each
|
|
419
|
+
* agent-loop iteration, after `_throwIfCancelled` and before `startCycle`.
|
|
420
|
+
*
|
|
421
|
+
* Reads from {@link AgentMetrics.latestAgentInvocation} (scoped to the
|
|
422
|
+
* current invocation) — not `cycleCount` / `accumulatedUsage`, which are
|
|
423
|
+
* lifetime accumulators that would cause caps to fire prematurely on the
|
|
424
|
+
* second `invoke()` call against a reused agent.
|
|
425
|
+
*
|
|
426
|
+
* Priority on simultaneous trip: turns → totalTokens → outputTokens.
|
|
427
|
+
*
|
|
428
|
+
* Returns the {@link StopReason} the loop should terminate with, or
|
|
429
|
+
* `undefined` if every configured cap is still within budget.
|
|
430
|
+
*/
|
|
431
|
+
_checkLimits(options) {
|
|
432
|
+
const limits = options?.limits;
|
|
433
|
+
if (!limits)
|
|
434
|
+
return undefined;
|
|
435
|
+
const invocation = this._meter.metrics.latestAgentInvocation;
|
|
436
|
+
if (!invocation)
|
|
437
|
+
return undefined;
|
|
438
|
+
const cycleCount = invocation.cycles.length;
|
|
439
|
+
const { outputTokens, totalTokens } = invocation.usage;
|
|
440
|
+
if (limits.turns !== undefined && cycleCount >= limits.turns) {
|
|
441
|
+
return 'limitTurns';
|
|
442
|
+
}
|
|
443
|
+
if (limits.totalTokens !== undefined && totalTokens >= limits.totalTokens) {
|
|
444
|
+
return 'limitTotalTokens';
|
|
445
|
+
}
|
|
446
|
+
if (limits.outputTokens !== undefined && outputTokens >= limits.outputTokens) {
|
|
447
|
+
return 'limitOutputTokens';
|
|
448
|
+
}
|
|
449
|
+
return undefined;
|
|
450
|
+
}
|
|
298
451
|
/**
|
|
299
452
|
* The tools this agent can use.
|
|
300
453
|
*/
|
|
@@ -307,6 +460,32 @@ export class Agent {
|
|
|
307
460
|
get toolRegistry() {
|
|
308
461
|
return this._toolRegistry;
|
|
309
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Whether the agent is currently processing an invocation.
|
|
465
|
+
*/
|
|
466
|
+
get isInvoking() {
|
|
467
|
+
return this._isInvoking;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Direct tool calling accessor.
|
|
471
|
+
*
|
|
472
|
+
* Returns a proxy where each property is a {@link ToolHandle} with
|
|
473
|
+
* `.invoke()` and `.stream()` methods:
|
|
474
|
+
* ```typescript
|
|
475
|
+
* const result = await agent.tool.calculator!.invoke({ a: 5, b: 3 })
|
|
476
|
+
*
|
|
477
|
+
* for await (const event of agent.tool.calculator!.stream({ a: 5, b: 3 })) {
|
|
478
|
+
* console.log('progress:', event)
|
|
479
|
+
* }
|
|
480
|
+
* ```
|
|
481
|
+
*
|
|
482
|
+
* Supports underscore-to-hyphen and case-insensitive name resolution.
|
|
483
|
+
* Results are recorded in message history by default (pass
|
|
484
|
+
* `{ recordDirectToolCall: false }` to skip).
|
|
485
|
+
*/
|
|
486
|
+
get tool() {
|
|
487
|
+
return this._toolCaller;
|
|
488
|
+
}
|
|
310
489
|
/**
|
|
311
490
|
* The cancellation signal for the current invocation.
|
|
312
491
|
*
|
|
@@ -413,97 +592,185 @@ export class Agent {
|
|
|
413
592
|
* ```
|
|
414
593
|
*/
|
|
415
594
|
async *stream(args, options) {
|
|
416
|
-
|
|
595
|
+
this.acquireLock();
|
|
417
596
|
try {
|
|
418
|
-
const _lock = __addDisposableResource(env_1, this.acquireLock(), false);
|
|
419
597
|
await this.initialize();
|
|
598
|
+
// Thread the resolved invocationState so all layers share the same reference.
|
|
599
|
+
const invocationState = options?.invocationState ?? {};
|
|
600
|
+
const resolvedOptions = options?.invocationState ? options : { ...options, invocationState };
|
|
420
601
|
let currentArgs = args;
|
|
421
|
-
// Outer loop: re-enters _stream when a hook sets AfterInvocationEvent.resume.
|
|
422
|
-
// One invocation lock spans the whole resume chain.
|
|
423
602
|
while (true) {
|
|
424
|
-
// Fresh AbortController per
|
|
603
|
+
// Fresh AbortController per iteration, composed with any external signal.
|
|
425
604
|
this._abortController = new AbortController();
|
|
426
|
-
this._abortSignal =
|
|
427
|
-
? AbortSignal.any([this._abortController.signal,
|
|
605
|
+
this._abortSignal = resolvedOptions?.cancelSignal
|
|
606
|
+
? AbortSignal.any([this._abortController.signal, resolvedOptions.cancelSignal])
|
|
428
607
|
: this._abortController.signal;
|
|
429
|
-
|
|
608
|
+
// Process interrupt responses before middleware runs so context.interrupt() can find them
|
|
609
|
+
const interruptResponses = this._extractInterruptResponses(currentArgs);
|
|
610
|
+
if (interruptResponses.length > 0) {
|
|
611
|
+
this._interruptState.resume(interruptResponses);
|
|
612
|
+
}
|
|
613
|
+
// Hooks fire outside middleware — always, even on short-circuit.
|
|
614
|
+
const beforeInvocationEvent = new BeforeInvocationEvent({ agent: this, invocationState });
|
|
615
|
+
yield await this._invokeCallbacks(beforeInvocationEvent);
|
|
616
|
+
if (beforeInvocationEvent.cancel) {
|
|
617
|
+
const cancelText = typeof beforeInvocationEvent.cancel === 'string'
|
|
618
|
+
? beforeInvocationEvent.cancel
|
|
619
|
+
: 'invocation denied by hook';
|
|
620
|
+
const message = new Message({ role: 'assistant', content: [new TextBlock(cancelText)] });
|
|
621
|
+
yield this._appendMessage(message, invocationState);
|
|
622
|
+
const afterEvent = new AfterInvocationEvent({ agent: this, invocationState });
|
|
623
|
+
await this._invokeCallbacks(afterEvent);
|
|
624
|
+
yield afterEvent;
|
|
625
|
+
return new AgentResult({
|
|
626
|
+
stopReason: 'endTurn',
|
|
627
|
+
lastMessage: message,
|
|
628
|
+
traces: this._tracer.localTraces,
|
|
629
|
+
metrics: this._meter.metrics,
|
|
630
|
+
invocationState,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
let result;
|
|
430
634
|
let caughtError;
|
|
431
|
-
|
|
432
|
-
let iterationResult;
|
|
635
|
+
const afterInvocationEvent = new AfterInvocationEvent({ agent: this, invocationState });
|
|
433
636
|
try {
|
|
434
|
-
|
|
435
|
-
while (!iterationResult.done) {
|
|
436
|
-
try {
|
|
437
|
-
const processed = await this._invokeCallbacks(iterationResult.value);
|
|
438
|
-
if (processed instanceof AfterInvocationEvent) {
|
|
439
|
-
lastAfterInvocation = processed;
|
|
440
|
-
}
|
|
441
|
-
yield processed;
|
|
442
|
-
iterationResult = await streamGenerator.next();
|
|
443
|
-
}
|
|
444
|
-
catch (error) {
|
|
445
|
-
// Throw interrupt errors back into _stream so executeTools can store the
|
|
446
|
-
// assistant message as pending execution state for resume.
|
|
447
|
-
if (error instanceof InterruptError) {
|
|
448
|
-
iterationResult = await streamGenerator.throw(error);
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
throw error;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
// Suppress AgentResultEvent for resumed iterations — only the final
|
|
456
|
-
// invocation in a resume chain reports an agent result.
|
|
457
|
-
if (lastAfterInvocation?.resume === undefined) {
|
|
458
|
-
yield await this._invokeCallbacks(new AgentResultEvent({
|
|
459
|
-
agent: this,
|
|
460
|
-
result: iterationResult.value,
|
|
461
|
-
invocationState: iterationResult.value.invocationState,
|
|
462
|
-
}));
|
|
463
|
-
}
|
|
637
|
+
result = yield* this._streamWithMiddleware(currentArgs, resolvedOptions, invocationState);
|
|
464
638
|
}
|
|
465
639
|
catch (error) {
|
|
466
640
|
caughtError = error;
|
|
467
|
-
throw error;
|
|
468
641
|
}
|
|
469
642
|
finally {
|
|
470
|
-
//
|
|
471
|
-
//
|
|
472
|
-
//
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
catch (error) {
|
|
484
|
-
logger.warn(`event_type=<${drainResult.value.type}>, error=<${error}> | error invoking callbacks during cleanup`);
|
|
485
|
-
}
|
|
486
|
-
drainResult = await streamGenerator.next();
|
|
487
|
-
}
|
|
488
|
-
// Reset controller and signal for next iteration / invocation
|
|
489
|
-
this._abortController = new AbortController();
|
|
490
|
-
this._abortSignal = this._abortController.signal;
|
|
643
|
+
// AfterInvocationEvent always fires — even on error or consumer break. Outside middleware.
|
|
644
|
+
// Invoke hooks (so .resume can be set) but don't yield in finally (yields in finally
|
|
645
|
+
// suspend the generator on consumer break instead of completing cleanup).
|
|
646
|
+
await this._invokeCallbacks(afterInvocationEvent);
|
|
647
|
+
}
|
|
648
|
+
// Yield outside finally — in JS, a `yield` inside `finally` suspends the generator
|
|
649
|
+
// mid-cleanup when the consumer breaks, preventing subsequent cleanup code from running.
|
|
650
|
+
// This line is only reached on normal completion or caught error, never on consumer break.
|
|
651
|
+
yield afterInvocationEvent;
|
|
652
|
+
// Re-throw after hooks have fired
|
|
653
|
+
if (caughtError) {
|
|
654
|
+
throw caughtError;
|
|
491
655
|
}
|
|
492
656
|
// Resume only on a clean invocation — errors propagate above.
|
|
493
|
-
if (
|
|
494
|
-
currentArgs =
|
|
657
|
+
if (afterInvocationEvent.resume !== undefined) {
|
|
658
|
+
currentArgs = afterInvocationEvent.resume;
|
|
495
659
|
continue;
|
|
496
660
|
}
|
|
497
|
-
|
|
661
|
+
// Only emit AgentResultEvent on the final iteration (not on resumed ones).
|
|
662
|
+
yield await this._invokeCallbacks(new AgentResultEvent({
|
|
663
|
+
agent: this,
|
|
664
|
+
result: result,
|
|
665
|
+
invocationState,
|
|
666
|
+
}));
|
|
667
|
+
return result;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
finally {
|
|
671
|
+
this._isInvoking = false;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Invokes the AgentStreamStage middleware chain.
|
|
676
|
+
* Hooks fire outside this method (in stream()'s resume loop).
|
|
677
|
+
*/
|
|
678
|
+
async *_streamWithMiddleware(args, options, invocationState) {
|
|
679
|
+
const context = {
|
|
680
|
+
agent: this,
|
|
681
|
+
args,
|
|
682
|
+
...(options !== undefined && { options }),
|
|
683
|
+
interrupt: createMiddlewareInterrupt(this._interruptState, 'middleware:agentStream'),
|
|
684
|
+
};
|
|
685
|
+
// async function* doesn't bind lexical `this`; capture for the terminal callback.
|
|
686
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
687
|
+
const self = this;
|
|
688
|
+
try {
|
|
689
|
+
const { result } = yield* this._middlewareRegistry.invoke(AgentStreamStage, context, async function* (ctx) {
|
|
690
|
+
const result = yield* self._streamCore(ctx.args, ctx.options);
|
|
691
|
+
return { result };
|
|
692
|
+
});
|
|
693
|
+
return result;
|
|
694
|
+
}
|
|
695
|
+
catch (error) {
|
|
696
|
+
if (error instanceof InterruptError) {
|
|
697
|
+
for (const interrupt of error.interrupts) {
|
|
698
|
+
this._interruptState.registerInterrupt(interrupt);
|
|
699
|
+
}
|
|
700
|
+
this._interruptState.activate();
|
|
701
|
+
for (const interrupt of error.interrupts) {
|
|
702
|
+
yield new InterruptEvent({ agent: this, interrupt, invocationState });
|
|
703
|
+
}
|
|
704
|
+
return new AgentResult({
|
|
705
|
+
stopReason: 'interrupt',
|
|
706
|
+
lastMessage: this.messages.length > 0
|
|
707
|
+
? this.messages[this.messages.length - 1]
|
|
708
|
+
: new Message({ role: 'assistant', content: [new TextBlock('Interrupted')] }),
|
|
709
|
+
traces: this._tracer.localTraces,
|
|
710
|
+
metrics: this._meter.metrics,
|
|
711
|
+
interrupts: this._interruptState.getUnansweredInterrupts(),
|
|
712
|
+
invocationState,
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Single-pass stream through _stream() with event processing.
|
|
720
|
+
* No resume loop, no lifecycle events — those are handled by stream()'s resume loop.
|
|
721
|
+
*/
|
|
722
|
+
async *_streamCore(args, options) {
|
|
723
|
+
const streamGenerator = this._stream(args, options);
|
|
724
|
+
let caughtError;
|
|
725
|
+
let iterationResult;
|
|
726
|
+
try {
|
|
727
|
+
iterationResult = await streamGenerator.next();
|
|
728
|
+
while (!iterationResult.done) {
|
|
729
|
+
try {
|
|
730
|
+
const processed = await this._invokeCallbacks(iterationResult.value);
|
|
731
|
+
yield processed;
|
|
732
|
+
iterationResult = await streamGenerator.next();
|
|
733
|
+
}
|
|
734
|
+
catch (error) {
|
|
735
|
+
// Throw interrupt errors back into _stream so executeTools can store the
|
|
736
|
+
// assistant message as pending execution state for resume.
|
|
737
|
+
if (error instanceof InterruptError) {
|
|
738
|
+
iterationResult = await streamGenerator.throw(error);
|
|
739
|
+
}
|
|
740
|
+
else {
|
|
741
|
+
throw error;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
498
744
|
}
|
|
499
745
|
}
|
|
500
|
-
catch (
|
|
501
|
-
|
|
502
|
-
|
|
746
|
+
catch (error) {
|
|
747
|
+
caughtError = error;
|
|
748
|
+
throw error;
|
|
503
749
|
}
|
|
504
750
|
finally {
|
|
505
|
-
|
|
751
|
+
// Drain _stream() so cleanup hooks and printer still fire.
|
|
752
|
+
// Yield only on error (consumer may still be iterating); on a consumer
|
|
753
|
+
// break, yielding would suspend the generator and leak the lock.
|
|
754
|
+
let drainResult = await streamGenerator.return(undefined);
|
|
755
|
+
while (!drainResult.done) {
|
|
756
|
+
try {
|
|
757
|
+
if (caughtError) {
|
|
758
|
+
yield await this._invokeCallbacks(drainResult.value);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
await this._invokeCallbacks(drainResult.value);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
catch (error) {
|
|
765
|
+
logger.warn(`event_type=<${drainResult.value.type}>, error=<${error}> | error invoking callbacks during cleanup`);
|
|
766
|
+
}
|
|
767
|
+
drainResult = await streamGenerator.next();
|
|
768
|
+
}
|
|
769
|
+
// Reset controller and signal for next iteration / invocation
|
|
770
|
+
this._abortController = new AbortController();
|
|
771
|
+
this._abortSignal = this._abortController.signal;
|
|
506
772
|
}
|
|
773
|
+
return iterationResult.value;
|
|
507
774
|
}
|
|
508
775
|
/**
|
|
509
776
|
* Returns a {@link Tool} that wraps this agent, allowing it to be used
|
|
@@ -618,6 +885,7 @@ export class Agent {
|
|
|
618
885
|
async *_stream(args, options) {
|
|
619
886
|
let currentArgs = args;
|
|
620
887
|
let result;
|
|
888
|
+
this._validateLimits(options);
|
|
621
889
|
// Resolve structured output schema from per-invocation options or constructor config
|
|
622
890
|
const structuredOutputSchema = options?.structuredOutputSchema ?? this._structuredOutputSchema;
|
|
623
891
|
const structuredOutputTool = structuredOutputSchema ? new StructuredOutputTool(structuredOutputSchema) : undefined;
|
|
@@ -627,30 +895,14 @@ export class Agent {
|
|
|
627
895
|
// AgentResult. Mutations by hooks/tools are visible across all recursive
|
|
628
896
|
// agent loop cycles within this invocation.
|
|
629
897
|
const invocationState = options?.invocationState ?? {};
|
|
630
|
-
//
|
|
898
|
+
// Interrupt responses are already consumed in stream() before middleware
|
|
899
|
+
// runs (so middleware-level interrupt() can find them). Re-extract here
|
|
900
|
+
// to gate the "non-interrupt input while interrupted" check below.
|
|
631
901
|
const interruptResponses = this._extractInterruptResponses(args);
|
|
632
|
-
if (interruptResponses.length > 0) {
|
|
633
|
-
this._interruptState.resume(interruptResponses);
|
|
634
|
-
}
|
|
635
902
|
// Reject non-interrupt input while in interrupted state
|
|
636
903
|
if (this._interruptState.activated && interruptResponses.length === 0) {
|
|
637
904
|
throw new TypeError('Agent is in an interrupted state. Resume by invoking with interruptResponse content blocks.');
|
|
638
905
|
}
|
|
639
|
-
const beforeInvocationEvent = new BeforeInvocationEvent({ agent: this, invocationState });
|
|
640
|
-
yield beforeInvocationEvent;
|
|
641
|
-
if (beforeInvocationEvent.cancel) {
|
|
642
|
-
const cancelText = typeof beforeInvocationEvent.cancel === 'string' ? beforeInvocationEvent.cancel : 'invocation denied by hook';
|
|
643
|
-
const message = new Message({ role: 'assistant', content: [new TextBlock(cancelText)] });
|
|
644
|
-
yield this._appendMessage(message, invocationState);
|
|
645
|
-
yield new AfterInvocationEvent({ agent: this, invocationState });
|
|
646
|
-
return new AgentResult({
|
|
647
|
-
stopReason: 'endTurn',
|
|
648
|
-
lastMessage: message,
|
|
649
|
-
traces: this._tracer.localTraces,
|
|
650
|
-
metrics: this._meter.metrics,
|
|
651
|
-
invocationState,
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
906
|
// Normalize input to get the user messages for telemetry
|
|
655
907
|
const inputMessages = this._normalizeInput(args);
|
|
656
908
|
// Start agent trace span
|
|
@@ -676,6 +928,17 @@ export class Agent {
|
|
|
676
928
|
// Main agent loop - continues until model stops without requesting tools
|
|
677
929
|
while (true) {
|
|
678
930
|
this._throwIfCancelled();
|
|
931
|
+
const limitStopReason = this._checkLimits(options);
|
|
932
|
+
if (limitStopReason) {
|
|
933
|
+
result = new AgentResult({
|
|
934
|
+
stopReason: limitStopReason,
|
|
935
|
+
lastMessage: this.messages.at(-1),
|
|
936
|
+
traces: this._tracer.localTraces,
|
|
937
|
+
metrics: this._meter.metrics,
|
|
938
|
+
invocationState,
|
|
939
|
+
});
|
|
940
|
+
return result;
|
|
941
|
+
}
|
|
679
942
|
// Start metrics cycle tracking
|
|
680
943
|
const { cycleId, startTime: cycleStartTime } = this._meter.startCycle();
|
|
681
944
|
// Create agent loop cycle span within agent span context
|
|
@@ -839,6 +1102,11 @@ export class Agent {
|
|
|
839
1102
|
return result;
|
|
840
1103
|
}
|
|
841
1104
|
if (error instanceof InterruptError) {
|
|
1105
|
+
// Handles interrupts from tools/hooks that propagated up through the agent loop.
|
|
1106
|
+
// AgentStreamStage middleware interrupts are caught separately in _streamWithMiddleware().
|
|
1107
|
+
for (const interrupt of error.interrupts) {
|
|
1108
|
+
this._interruptState.registerInterrupt(interrupt);
|
|
1109
|
+
}
|
|
842
1110
|
// Fan out one event per interrupt. Each event exposes `interrupt.source` so
|
|
843
1111
|
// consumers can filter by origin (tool callback vs hook callback) without
|
|
844
1112
|
// subscribing to separate event types.
|
|
@@ -872,8 +1140,6 @@ export class Agent {
|
|
|
872
1140
|
if (structuredOutputTool) {
|
|
873
1141
|
this._toolRegistry.remove(STRUCTURED_OUTPUT_TOOL_NAME);
|
|
874
1142
|
}
|
|
875
|
-
// Always emit final event
|
|
876
|
-
yield new AfterInvocationEvent({ agent: this, invocationState });
|
|
877
1143
|
}
|
|
878
1144
|
}
|
|
879
1145
|
/**
|
|
@@ -1050,26 +1316,10 @@ export class Agent {
|
|
|
1050
1316
|
}
|
|
1051
1317
|
return { message, stopReason: 'endTurn' };
|
|
1052
1318
|
}
|
|
1053
|
-
// Start model span within loop span context
|
|
1054
|
-
const modelId = this.model.modelId;
|
|
1055
|
-
const modelSpan = this._tracer.startModelInvokeSpan({
|
|
1056
|
-
messages: this.messages,
|
|
1057
|
-
...(modelId && { modelId }),
|
|
1058
|
-
...(this.systemPrompt !== undefined && { systemPrompt: this.systemPrompt }),
|
|
1059
|
-
});
|
|
1060
1319
|
try {
|
|
1061
|
-
const result = yield* this.
|
|
1320
|
+
const result = yield* this._invokeModelWithMiddleware(invocationState, toolChoice);
|
|
1062
1321
|
// Accumulate token usage and model latency metrics
|
|
1063
1322
|
this._meter.updateCycle(result.metadata);
|
|
1064
|
-
// End model span with usage
|
|
1065
|
-
const usage = result.metadata?.usage;
|
|
1066
|
-
const metrics = result.metadata?.metrics;
|
|
1067
|
-
this._tracer.endModelInvokeSpan(modelSpan, {
|
|
1068
|
-
output: result.message,
|
|
1069
|
-
stopReason: result.stopReason,
|
|
1070
|
-
...(usage && { usage }),
|
|
1071
|
-
...(metrics && { metrics }),
|
|
1072
|
-
});
|
|
1073
1323
|
yield new ModelMessageEvent({
|
|
1074
1324
|
agent: this,
|
|
1075
1325
|
message: result.message,
|
|
@@ -1101,8 +1351,6 @@ export class Agent {
|
|
|
1101
1351
|
}
|
|
1102
1352
|
catch (error) {
|
|
1103
1353
|
const modelError = normalizeError(error);
|
|
1104
|
-
// End model span with error
|
|
1105
|
-
this._tracer.endModelInvokeSpan(modelSpan, { error: modelError });
|
|
1106
1354
|
// Create error event
|
|
1107
1355
|
const errorEvent = new AfterModelCallEvent({
|
|
1108
1356
|
agent: this,
|
|
@@ -1128,6 +1376,66 @@ export class Agent {
|
|
|
1128
1376
|
}
|
|
1129
1377
|
}
|
|
1130
1378
|
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Invokes the model through the InvokeModelStage middleware chain.
|
|
1381
|
+
* Builds an InvokeModelContext from current agent state and composes the
|
|
1382
|
+
* middleware chain with a terminal function that calls _streamFromModel
|
|
1383
|
+
* using context fields directly (not re-derived from the agent).
|
|
1384
|
+
*
|
|
1385
|
+
* @param invocationState - Per-invocation state shared across hooks and tools
|
|
1386
|
+
* @param toolChoice - Optional tool choice to force specific tool usage
|
|
1387
|
+
* @returns StreamAggregatedResult from the model (or middleware short-circuit)
|
|
1388
|
+
*/
|
|
1389
|
+
async *_invokeModelWithMiddleware(invocationState, toolChoice) {
|
|
1390
|
+
const context = {
|
|
1391
|
+
agent: this,
|
|
1392
|
+
messages: this.messages,
|
|
1393
|
+
...(this.systemPrompt !== undefined && { systemPrompt: this.systemPrompt }),
|
|
1394
|
+
toolSpecs: this._toolRegistry.list().map((tool) => tool.toolSpec),
|
|
1395
|
+
...(toolChoice !== undefined && { toolChoice }),
|
|
1396
|
+
modelState: this.modelState,
|
|
1397
|
+
invocationState,
|
|
1398
|
+
};
|
|
1399
|
+
// async function* doesn't bind lexical `this`; capture for the terminal callback.
|
|
1400
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1401
|
+
const self = this;
|
|
1402
|
+
const middlewareResult = yield* this._middlewareRegistry.invoke(InvokeModelStage, context, async function* (ctx) {
|
|
1403
|
+
const modelId = self.model.modelId;
|
|
1404
|
+
const modelSpan = self._tracer.startModelInvokeSpan({
|
|
1405
|
+
messages: ctx.messages,
|
|
1406
|
+
...(modelId && { modelId }),
|
|
1407
|
+
...(ctx.systemPrompt !== undefined && { systemPrompt: ctx.systemPrompt }),
|
|
1408
|
+
});
|
|
1409
|
+
try {
|
|
1410
|
+
const streamOptions = {
|
|
1411
|
+
toolSpecs: ctx.toolSpecs,
|
|
1412
|
+
modelState: ctx.modelState,
|
|
1413
|
+
...(ctx.systemPrompt !== undefined && { systemPrompt: ctx.systemPrompt }),
|
|
1414
|
+
...(ctx.toolChoice && { toolChoice: ctx.toolChoice }),
|
|
1415
|
+
};
|
|
1416
|
+
const gen = self._streamFromModel(ctx.messages, streamOptions, ctx.invocationState);
|
|
1417
|
+
let iterResult = await gen.next();
|
|
1418
|
+
while (!iterResult.done) {
|
|
1419
|
+
yield iterResult.value;
|
|
1420
|
+
iterResult = await gen.next();
|
|
1421
|
+
}
|
|
1422
|
+
const usage = iterResult.value.metadata?.usage;
|
|
1423
|
+
const metrics = iterResult.value.metadata?.metrics;
|
|
1424
|
+
self._tracer.endModelInvokeSpan(modelSpan, {
|
|
1425
|
+
output: iterResult.value.message,
|
|
1426
|
+
stopReason: iterResult.value.stopReason,
|
|
1427
|
+
...(usage && { usage }),
|
|
1428
|
+
...(metrics && { metrics }),
|
|
1429
|
+
});
|
|
1430
|
+
return { result: iterResult.value };
|
|
1431
|
+
}
|
|
1432
|
+
catch (error) {
|
|
1433
|
+
self._tracer.endModelInvokeSpan(modelSpan, { error: normalizeError(error) });
|
|
1434
|
+
throw error;
|
|
1435
|
+
}
|
|
1436
|
+
});
|
|
1437
|
+
return middlewareResult.result;
|
|
1438
|
+
}
|
|
1131
1439
|
/**
|
|
1132
1440
|
* Streams events from the model and dispatches appropriate events for each.
|
|
1133
1441
|
*
|
|
@@ -1484,86 +1792,9 @@ export class Agent {
|
|
|
1484
1792
|
}
|
|
1485
1793
|
return afterToolCallEvent.result;
|
|
1486
1794
|
}
|
|
1487
|
-
//
|
|
1488
|
-
const
|
|
1489
|
-
|
|
1490
|
-
});
|
|
1491
|
-
// Track tool execution time for metrics
|
|
1492
|
-
const toolStartTime = Date.now();
|
|
1493
|
-
let toolResult;
|
|
1494
|
-
let error;
|
|
1495
|
-
if (!effectiveTool) {
|
|
1496
|
-
// Tool not found
|
|
1497
|
-
toolResult = new ToolResultBlock({
|
|
1498
|
-
toolUseId: toolUse.toolUseId,
|
|
1499
|
-
status: 'error',
|
|
1500
|
-
content: [new TextBlock(`Tool '${toolUse.name}' not found in registry`)],
|
|
1501
|
-
});
|
|
1502
|
-
}
|
|
1503
|
-
else {
|
|
1504
|
-
// Execute tool within the tool span context
|
|
1505
|
-
const toolContext = {
|
|
1506
|
-
toolUse: {
|
|
1507
|
-
name: toolUse.name,
|
|
1508
|
-
toolUseId: toolUse.toolUseId,
|
|
1509
|
-
input: toolUse.input,
|
|
1510
|
-
},
|
|
1511
|
-
agent: this,
|
|
1512
|
-
invocationState,
|
|
1513
|
-
interrupt: (params) => {
|
|
1514
|
-
return interruptFromAgent(this, `tool:${toolUseBlock.toolUseId}:${params.name}`, params, 'tool');
|
|
1515
|
-
},
|
|
1516
|
-
};
|
|
1517
|
-
try {
|
|
1518
|
-
// Manually iterate tool stream to wrap each ToolStreamEvent in ToolStreamUpdateEvent.
|
|
1519
|
-
// This keeps the tool authoring interface unchanged — tools construct ToolStreamEvent
|
|
1520
|
-
// without knowledge of agents or hooks, and we wrap at the boundary.
|
|
1521
|
-
// Tool execution is ran within the tool span's context so that
|
|
1522
|
-
// downstream calls (e.g., MCP clients) can propagate trace context
|
|
1523
|
-
const toolGenerator = this._tracer.withSpanContext(toolSpan, () => effectiveTool.stream(toolContext));
|
|
1524
|
-
let toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
|
|
1525
|
-
while (!toolNext.done) {
|
|
1526
|
-
yield new ToolStreamUpdateEvent({ agent: this, event: toolNext.value, invocationState });
|
|
1527
|
-
toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
|
|
1528
|
-
}
|
|
1529
|
-
const result = toolNext.value;
|
|
1530
|
-
if (!result) {
|
|
1531
|
-
// Tool didn't return a result
|
|
1532
|
-
toolResult = new ToolResultBlock({
|
|
1533
|
-
toolUseId: toolUse.toolUseId,
|
|
1534
|
-
status: 'error',
|
|
1535
|
-
content: [new TextBlock(`Tool '${toolUse.name}' did not return a result`)],
|
|
1536
|
-
});
|
|
1537
|
-
}
|
|
1538
|
-
else {
|
|
1539
|
-
toolResult = result;
|
|
1540
|
-
error = result.error;
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
catch (e) {
|
|
1544
|
-
// Re-throw InterruptError to allow interrupt handling
|
|
1545
|
-
if (e instanceof InterruptError) {
|
|
1546
|
-
throw e;
|
|
1547
|
-
}
|
|
1548
|
-
// Tool execution failed with error
|
|
1549
|
-
error = normalizeError(e);
|
|
1550
|
-
toolResult = new ToolResultBlock({
|
|
1551
|
-
toolUseId: toolUse.toolUseId,
|
|
1552
|
-
status: 'error',
|
|
1553
|
-
content: [new TextBlock(error.message)],
|
|
1554
|
-
error,
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
// End tool span with the raw tool result — telemetry reflects what the
|
|
1559
|
-
// tool actually returned, independent of AfterToolCallEvent mutations.
|
|
1560
|
-
this._tracer.endToolCallSpan(toolSpan, { toolResult, ...(error && { error }) });
|
|
1561
|
-
// End tool metrics tracking
|
|
1562
|
-
this._meter.endToolCall({
|
|
1563
|
-
tool: toolUse,
|
|
1564
|
-
duration: Date.now() - toolStartTime,
|
|
1565
|
-
success: toolResult.status === 'success',
|
|
1566
|
-
});
|
|
1795
|
+
// Execute tool core logic through middleware chain
|
|
1796
|
+
const toolResult = yield* this._executeToolWithMiddleware(effectiveTool, toolUse, invocationState);
|
|
1797
|
+
const error = toolResult.error;
|
|
1567
1798
|
// Single point for AfterToolCallEvent
|
|
1568
1799
|
const afterToolCallEvent = new AfterToolCallEvent({
|
|
1569
1800
|
agent: this,
|
|
@@ -1582,6 +1813,110 @@ export class Agent {
|
|
|
1582
1813
|
return afterToolCallEvent.result;
|
|
1583
1814
|
}
|
|
1584
1815
|
}
|
|
1816
|
+
async *_executeToolWithMiddleware(tool, toolUse, invocationState) {
|
|
1817
|
+
const context = {
|
|
1818
|
+
agent: this,
|
|
1819
|
+
tool,
|
|
1820
|
+
toolUse: {
|
|
1821
|
+
name: toolUse.name,
|
|
1822
|
+
toolUseId: toolUse.toolUseId,
|
|
1823
|
+
input: toolUse.input,
|
|
1824
|
+
},
|
|
1825
|
+
invocationState,
|
|
1826
|
+
interrupt: createMiddlewareInterrupt(this._interruptState, `middleware:executeTool:${toolUse.toolUseId}`),
|
|
1827
|
+
};
|
|
1828
|
+
// async function* doesn't bind lexical `this`; capture for the terminal callback.
|
|
1829
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1830
|
+
const self = this;
|
|
1831
|
+
const middlewareResult = yield* this._middlewareRegistry.invoke(ExecuteToolStage, context, async function* (ctx) {
|
|
1832
|
+
const result = yield* self._executeToolCore(ctx.tool, ctx.toolUse, ctx.invocationState);
|
|
1833
|
+
return { result };
|
|
1834
|
+
});
|
|
1835
|
+
return middlewareResult.result;
|
|
1836
|
+
}
|
|
1837
|
+
async *_executeToolCore(effectiveTool, toolUse, invocationState) {
|
|
1838
|
+
// Start tool span within loop span context
|
|
1839
|
+
const toolSpan = this._tracer.startToolCallSpan({
|
|
1840
|
+
tool: toolUse,
|
|
1841
|
+
});
|
|
1842
|
+
// Track tool execution time for metrics
|
|
1843
|
+
const toolStartTime = Date.now();
|
|
1844
|
+
let toolResult;
|
|
1845
|
+
let error;
|
|
1846
|
+
if (!effectiveTool) {
|
|
1847
|
+
// Tool not found
|
|
1848
|
+
toolResult = new ToolResultBlock({
|
|
1849
|
+
toolUseId: toolUse.toolUseId,
|
|
1850
|
+
status: 'error',
|
|
1851
|
+
content: [new TextBlock(`Tool '${toolUse.name}' not found in registry`)],
|
|
1852
|
+
});
|
|
1853
|
+
}
|
|
1854
|
+
else {
|
|
1855
|
+
// Execute tool within the tool span context
|
|
1856
|
+
const toolContext = {
|
|
1857
|
+
toolUse: {
|
|
1858
|
+
name: toolUse.name,
|
|
1859
|
+
toolUseId: toolUse.toolUseId,
|
|
1860
|
+
input: toolUse.input,
|
|
1861
|
+
},
|
|
1862
|
+
agent: this,
|
|
1863
|
+
invocationState,
|
|
1864
|
+
interrupt: (params) => {
|
|
1865
|
+
return interruptFromAgent(this, `tool:${toolUse.toolUseId}:${params.name}`, params, 'tool');
|
|
1866
|
+
},
|
|
1867
|
+
};
|
|
1868
|
+
try {
|
|
1869
|
+
// Manually iterate tool stream to wrap each ToolStreamEvent in ToolStreamUpdateEvent.
|
|
1870
|
+
// This keeps the tool authoring interface unchanged — tools construct ToolStreamEvent
|
|
1871
|
+
// without knowledge of agents or hooks, and we wrap at the boundary.
|
|
1872
|
+
// Tool execution is ran within the tool span's context so that
|
|
1873
|
+
// downstream calls (e.g., MCP clients) can propagate trace context
|
|
1874
|
+
const toolGenerator = this._tracer.withSpanContext(toolSpan, () => effectiveTool.stream(toolContext));
|
|
1875
|
+
let toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
|
|
1876
|
+
while (!toolNext.done) {
|
|
1877
|
+
yield new ToolStreamUpdateEvent({ agent: this, event: toolNext.value, invocationState });
|
|
1878
|
+
toolNext = await this._tracer.withSpanContext(toolSpan, () => toolGenerator.next());
|
|
1879
|
+
}
|
|
1880
|
+
const result = toolNext.value;
|
|
1881
|
+
if (!result) {
|
|
1882
|
+
// Tool didn't return a result
|
|
1883
|
+
toolResult = new ToolResultBlock({
|
|
1884
|
+
toolUseId: toolUse.toolUseId,
|
|
1885
|
+
status: 'error',
|
|
1886
|
+
content: [new TextBlock(`Tool '${toolUse.name}' did not return a result`)],
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1889
|
+
else {
|
|
1890
|
+
toolResult = result;
|
|
1891
|
+
error = result.error;
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
catch (e) {
|
|
1895
|
+
// Re-throw InterruptError to allow interrupt handling
|
|
1896
|
+
if (e instanceof InterruptError) {
|
|
1897
|
+
throw e;
|
|
1898
|
+
}
|
|
1899
|
+
// Tool execution failed with error
|
|
1900
|
+
error = normalizeError(e);
|
|
1901
|
+
toolResult = new ToolResultBlock({
|
|
1902
|
+
toolUseId: toolUse.toolUseId,
|
|
1903
|
+
status: 'error',
|
|
1904
|
+
content: [new TextBlock(error.message)],
|
|
1905
|
+
error,
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
// End tool span with the raw tool result — telemetry reflects what the
|
|
1910
|
+
// tool actually returned, independent of AfterToolCallEvent mutations.
|
|
1911
|
+
this._tracer.endToolCallSpan(toolSpan, { toolResult, ...(error && { error }) });
|
|
1912
|
+
// End tool metrics tracking
|
|
1913
|
+
this._meter.endToolCall({
|
|
1914
|
+
tool: toolUse,
|
|
1915
|
+
duration: Date.now() - toolStartTime,
|
|
1916
|
+
success: toolResult.status === 'success',
|
|
1917
|
+
});
|
|
1918
|
+
return toolResult;
|
|
1919
|
+
}
|
|
1585
1920
|
/**
|
|
1586
1921
|
* Redacts the last message in the conversation history.
|
|
1587
1922
|
* Called when guardrails block user input and redaction is enabled.
|
|
@@ -1668,6 +2003,17 @@ export class Agent {
|
|
|
1668
2003
|
}
|
|
1669
2004
|
return estimate;
|
|
1670
2005
|
}
|
|
2006
|
+
/**
|
|
2007
|
+
* Appends a message to the conversation history and fires MessageAddedEvent hooks.
|
|
2008
|
+
*
|
|
2009
|
+
* Used by {@link ToolCaller} (via the helper passed to `ToolCaller.create`) for
|
|
2010
|
+
* direct tool calls that cannot yield events into the agent stream. This stays
|
|
2011
|
+
* private — callers outside the agent should never directly mutate messages.
|
|
2012
|
+
*/
|
|
2013
|
+
async _appendMessageAndFireHooks(message, invocationState = {}) {
|
|
2014
|
+
this.messages.push(message);
|
|
2015
|
+
await this._hooksRegistry.invokeCallbacks(new MessageAddedEvent({ agent: this, message, invocationState }));
|
|
2016
|
+
}
|
|
1671
2017
|
/**
|
|
1672
2018
|
* Appends a message to the conversation history and returns the event for yielding.
|
|
1673
2019
|
*
|