@ag-ui/aws-strands 0.1.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/LICENSE +21 -0
- package/README.md +314 -0
- package/dist/agent-B2EYZvns.d.ts +310 -0
- package/dist/agent-B2EYZvns.d.ts.map +1 -0
- package/dist/agent-Dp45JIaO.d.mts +310 -0
- package/dist/agent-Dp45JIaO.d.mts.map +1 -0
- package/dist/index.d.mts +51 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server.d.mts +136 -0
- package/dist/server.d.mts.map +1 -0
- package/dist/server.d.ts +136 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/server.mjs +2 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { Agent, AgentConfig, Plugin, SessionManager } from "@strands-agents/sdk";
|
|
2
|
+
import { BaseEvent, Message as Message$1, RunAgentInput } from "@ag-ui/core";
|
|
3
|
+
|
|
4
|
+
//#region src/logger.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Injectable logger for the AWS Strands adapter.
|
|
7
|
+
*
|
|
8
|
+
* The Python sibling uses `logging.getLogger(__name__)` and emits warnings /
|
|
9
|
+
* errors to stderr at `WARNING` and up, with `DEBUG` opt-in. This module
|
|
10
|
+
* mirrors that behaviour: by default the adapter is silent below `warn`,
|
|
11
|
+
* surfaces warnings via `console.warn`, and lets callers redirect output by
|
|
12
|
+
* passing a `Logger` in `StrandsAgentConfig.logger`.
|
|
13
|
+
*
|
|
14
|
+
* Signature `(message: string, ...args: unknown[])` intentionally matches the
|
|
15
|
+
* `console` method shape so existing `vi.spyOn(console, "warn")` test
|
|
16
|
+
* scaffolding keeps working with the default logger in place, and so wiring
|
|
17
|
+
* in pino / winston / bunyan is a one-liner.
|
|
18
|
+
*/
|
|
19
|
+
interface Logger {
|
|
20
|
+
debug(message: string, ...args: unknown[]): void;
|
|
21
|
+
warn(message: string, ...args: unknown[]): void;
|
|
22
|
+
error(message: string, ...args: unknown[]): void;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/config.d.ts
|
|
26
|
+
type StatePayload = Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Free-form key/value map carried on `RunAgentInput.context[]` and
|
|
29
|
+
* `RunAgentInput.forwardedProps`. Exposed on hook contexts so behaviors can
|
|
30
|
+
* react to e.g. per-request auth tokens or locale without re-parsing
|
|
31
|
+
* `inputData`.
|
|
32
|
+
*
|
|
33
|
+
* TypeScript-only: the Python adapter passes `input_data` directly to hooks
|
|
34
|
+
* and callers pull these fields off themselves.
|
|
35
|
+
*/
|
|
36
|
+
interface ToolCallContextExtras {
|
|
37
|
+
/**
|
|
38
|
+
* `RunAgentInput.context[]` flattened by `description` → `value`.
|
|
39
|
+
* Duplicates: later entries overwrite earlier ones. Keys `__proto__`,
|
|
40
|
+
* `constructor`, and `prototype` are dropped to prevent prototype-pollution
|
|
41
|
+
* surprises in downstream `Object.assign(target, ctx.context)` usage.
|
|
42
|
+
*/
|
|
43
|
+
context: Readonly<Record<string, string>>;
|
|
44
|
+
/**
|
|
45
|
+
* `RunAgentInput.forwardedProps` as an opaque record. Shape is defined by
|
|
46
|
+
* the frontend; the adapter does not introspect it.
|
|
47
|
+
*/
|
|
48
|
+
forwardedProps: Readonly<Record<string, unknown>>;
|
|
49
|
+
}
|
|
50
|
+
/** Context passed to tool call hooks. */
|
|
51
|
+
interface ToolCallContext extends ToolCallContextExtras {
|
|
52
|
+
inputData: RunAgentInput;
|
|
53
|
+
toolName: string;
|
|
54
|
+
toolUseId: string;
|
|
55
|
+
toolInput: unknown;
|
|
56
|
+
argsStr: string;
|
|
57
|
+
}
|
|
58
|
+
/** Context passed to tool result hooks. */
|
|
59
|
+
interface ToolResultContext extends ToolCallContext {
|
|
60
|
+
resultData: unknown;
|
|
61
|
+
messageId: string;
|
|
62
|
+
}
|
|
63
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
64
|
+
type ArgsStreamer = (ctx: ToolCallContext) => AsyncIterable<string>;
|
|
65
|
+
type StateFromArgs = (ctx: ToolCallContext) => MaybePromise<StatePayload | null | undefined>;
|
|
66
|
+
type StateFromResult = (ctx: ToolResultContext) => MaybePromise<StatePayload | null | undefined>;
|
|
67
|
+
type CustomResultHandler = (ctx: ToolResultContext) => AsyncIterable<BaseEvent | null | undefined>;
|
|
68
|
+
type StateContextBuilder = (inputData: RunAgentInput, prompt: string, /** Convenience view over `inputData.context[]` + `inputData.forwardedProps`. */
|
|
69
|
+
|
|
70
|
+
extras?: ToolCallContextExtras) => string;
|
|
71
|
+
type SessionManagerProvider = (inputData: RunAgentInput) => MaybePromise<SessionManager | null | undefined>;
|
|
72
|
+
/** Declarative mapping telling the UI how to predict state from tool args. */
|
|
73
|
+
interface PredictStateMapping {
|
|
74
|
+
stateKey: string;
|
|
75
|
+
tool: string;
|
|
76
|
+
toolArgument: string;
|
|
77
|
+
}
|
|
78
|
+
/** Declarative configuration for tool-specific handling. */
|
|
79
|
+
interface ToolBehavior {
|
|
80
|
+
/**
|
|
81
|
+
* Suppress the `MessagesSnapshotEvent` that would normally follow this
|
|
82
|
+
* tool's `TOOL_CALL_END` / `TOOL_CALL_RESULT`. Useful when
|
|
83
|
+
* `customResultHandler` emits its own snapshot.
|
|
84
|
+
*/
|
|
85
|
+
skipMessagesSnapshot?: boolean;
|
|
86
|
+
/** Keep the stream alive after emitting a frontend tool call. */
|
|
87
|
+
continueAfterFrontendCall?: boolean;
|
|
88
|
+
/** Close text streaming and halt the agent after a tool result arrives. */
|
|
89
|
+
stopStreamingAfterResult?: boolean;
|
|
90
|
+
/** `PredictStateMapping[]` that inform the UI how to project tool args into state. */
|
|
91
|
+
predictState?: PredictStateMapping | Iterable<PredictStateMapping>;
|
|
92
|
+
/** Async generator controlling how tool arguments are streamed to the frontend. */
|
|
93
|
+
argsStreamer?: ArgsStreamer;
|
|
94
|
+
/** Derive a `StateSnapshotEvent` from the tool call arguments. */
|
|
95
|
+
stateFromArgs?: StateFromArgs;
|
|
96
|
+
/** Derive a `StateSnapshotEvent` from the tool result. */
|
|
97
|
+
stateFromResult?: StateFromResult;
|
|
98
|
+
/** Async iterator that can emit arbitrary AG-UI events in response to a result. */
|
|
99
|
+
customResultHandler?: CustomResultHandler;
|
|
100
|
+
}
|
|
101
|
+
/** Top-level configuration for the Strands agent adapter. */
|
|
102
|
+
interface StrandsAgentConfig {
|
|
103
|
+
/** Per-tool overrides keyed by the Strands tool name. */
|
|
104
|
+
toolBehaviors?: Record<string, ToolBehavior>;
|
|
105
|
+
/** Callable that enriches the outgoing prompt with the current shared state. */
|
|
106
|
+
stateContextBuilder?: StateContextBuilder;
|
|
107
|
+
/**
|
|
108
|
+
* Optional factory for creating per-thread `SessionManager` instances.
|
|
109
|
+
*
|
|
110
|
+
* Called exactly once per `threadId` the first time that thread is seen.
|
|
111
|
+
* Subsequent requests on the same thread reuse the cached agent (and its
|
|
112
|
+
* SessionManager). If the provider depends on per-request data (e.g. auth
|
|
113
|
+
* tokens in `forwardedProps`), only the first request's data is used.
|
|
114
|
+
*
|
|
115
|
+
* If the provider throws, the run yields `RUN_ERROR` and returns early;
|
|
116
|
+
* the thread is NOT cached so the provider will be retried on the next
|
|
117
|
+
* request.
|
|
118
|
+
*
|
|
119
|
+
* If the provider returns `null` or `undefined`, a warning is logged and
|
|
120
|
+
* the agent runs without session persistence; the thread IS cached.
|
|
121
|
+
*/
|
|
122
|
+
sessionManagerProvider?: SessionManagerProvider;
|
|
123
|
+
/**
|
|
124
|
+
* Emit `MessagesSnapshotEvent` at lifecycle boundaries (after the initial
|
|
125
|
+
* `STATE_SNAPSHOT`, after each `TOOL_CALL_END` / `TOOL_CALL_RESULT`, and
|
|
126
|
+
* after each terminal `TEXT_MESSAGE_END`).
|
|
127
|
+
*
|
|
128
|
+
* Required for CopilotKit v2 frontends; set to `false` for raw AG-UI
|
|
129
|
+
* consumers that reconstruct messages themselves. Default: `true`.
|
|
130
|
+
*/
|
|
131
|
+
emitMessagesSnapshot?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* When `true` (and the cached Strands agent has no `sessionManager`),
|
|
134
|
+
* reconcile the per-thread `Agent.messages` list with
|
|
135
|
+
* `RunAgentInput.messages` before invoking `stream()`.
|
|
136
|
+
*
|
|
137
|
+
* Prevents the LLM from re-firing frontend tools every turn because
|
|
138
|
+
* Strands' internal history was missing the tool result the frontend
|
|
139
|
+
* produced. Disable only if you manage Strands history yourself.
|
|
140
|
+
* Default: `true`.
|
|
141
|
+
*/
|
|
142
|
+
replayHistoryIntoStrands?: boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Emit the self-expanding AG-UI chunk events (`TEXT_MESSAGE_CHUNK`,
|
|
145
|
+
* `TOOL_CALL_CHUNK`, `REASONING_MESSAGE_CHUNK`) instead of the explicit
|
|
146
|
+
* `*_START` / `*_CONTENT` / `*_END` triples. Halves the event count on
|
|
147
|
+
* high-frequency deltas; useful for bandwidth-constrained transports.
|
|
148
|
+
* TypeScript-only. Default: `false`.
|
|
149
|
+
*/
|
|
150
|
+
emitChunkEvents?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Optional injectable logger. Mirrors the Python adapter's
|
|
153
|
+
* `logging.getLogger("ag_ui_strands")`: the default surfaces `warn` / `error`
|
|
154
|
+
* via the `console` and drops `debug`, matching Python's stdlib default
|
|
155
|
+
* (WARNING-and-up to stderr). Pass `{ debug: console.debug, warn:
|
|
156
|
+
* console.warn, error: console.error }` to enable verbose traces, `{ debug()
|
|
157
|
+
* {}, warn() {}, error() {} }` to silence everything, or wire in pino /
|
|
158
|
+
* winston / bunyan directly — the `Logger` shape matches the `console`
|
|
159
|
+
* methods.
|
|
160
|
+
*
|
|
161
|
+
* Debug messages match the Python adapter's message strings field-for-field
|
|
162
|
+
* (modulo camelCase / snake_case) so cross-SDK log diffs are straightforward.
|
|
163
|
+
*/
|
|
164
|
+
logger?: Logger;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Flatten `RunAgentInput.context[]` into a plain key/value record and ensure
|
|
168
|
+
* `forwardedProps` is a record. Exported so hook implementations can call it
|
|
169
|
+
* when they have an `inputData` but not a fully-populated hook context.
|
|
170
|
+
*/
|
|
171
|
+
declare function buildContextExtras(inputData: RunAgentInput): ToolCallContextExtras;
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/agent.d.ts
|
|
174
|
+
/**
|
|
175
|
+
* Structural interface for a Strands multi-agent orchestrator (Graph/Swarm).
|
|
176
|
+
* TypeScript-only: the Python SDK currently has no orchestrator equivalent.
|
|
177
|
+
*/
|
|
178
|
+
interface StrandsOrchestrator {
|
|
179
|
+
readonly id?: string;
|
|
180
|
+
stream(input: string): AsyncGenerator<unknown, unknown, unknown>;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Convert ``RunAgentInput.messages`` to AG-UI message objects.
|
|
184
|
+
*
|
|
185
|
+
* Used to seed the running ``MessagesSnapshotEvent`` payload so each snapshot
|
|
186
|
+
* carries the full thread history.
|
|
187
|
+
*/
|
|
188
|
+
declare function buildSnapshotMessages(input_messages: Message$1[]): Message$1[];
|
|
189
|
+
/** Options accepted by `StrandsAgent`. */
|
|
190
|
+
interface StrandsAgentOptions {
|
|
191
|
+
/**
|
|
192
|
+
* Either an `Agent` (the template — adapter clones it per thread and syncs
|
|
193
|
+
* proxy tools) OR a multi-agent orchestrator (`Graph`, `Swarm`).
|
|
194
|
+
* Orchestrators are stateless per invocation so the same instance serves
|
|
195
|
+
* every thread.
|
|
196
|
+
*/
|
|
197
|
+
agent: Agent | StrandsOrchestrator;
|
|
198
|
+
name: string;
|
|
199
|
+
description?: string;
|
|
200
|
+
config?: StrandsAgentConfig;
|
|
201
|
+
/**
|
|
202
|
+
* Plugins forwarded to every per-thread Strands agent created by this
|
|
203
|
+
* adapter (observability, loop caps, policy checks, ...). Mirrors the
|
|
204
|
+
* Python adapter's `hooks=` kwarg. Ignored when `agent` is a multi-agent
|
|
205
|
+
* orchestrator.
|
|
206
|
+
*/
|
|
207
|
+
plugins?: Plugin[];
|
|
208
|
+
}
|
|
209
|
+
/** AWS Strands Agent wrapper for AG-UI integration. */
|
|
210
|
+
declare class StrandsAgent {
|
|
211
|
+
readonly name: string;
|
|
212
|
+
readonly description: string;
|
|
213
|
+
readonly config: StrandsAgentConfig;
|
|
214
|
+
private readonly _templateFields;
|
|
215
|
+
/**
|
|
216
|
+
* Hook providers forwarded to each per-thread StrandsAgentCore.
|
|
217
|
+
*
|
|
218
|
+
* Taken directly from the caller rather than read off the template because
|
|
219
|
+
* Strands' `Agent.hooks` is a `HookRegistry` containing only registered
|
|
220
|
+
* callbacks — the original list of provider objects is not retained, and
|
|
221
|
+
* the registry also contains callbacks bound to internal Strands objects
|
|
222
|
+
* that must not be cross-wired into per-thread agents.
|
|
223
|
+
*/
|
|
224
|
+
private readonly _plugins;
|
|
225
|
+
private readonly _agentsByThread;
|
|
226
|
+
private readonly _proxyToolNamesByThread;
|
|
227
|
+
/**
|
|
228
|
+
* Guards first-time thread initialization. The sessionManagerProvider call
|
|
229
|
+
* introduces an async yield point between the "is this thread new?" check
|
|
230
|
+
* and the map assignment, so concurrent requests for the same new threadId
|
|
231
|
+
* could otherwise both create an agent and one would clobber the other.
|
|
232
|
+
*/
|
|
233
|
+
private readonly _threadInitLock;
|
|
234
|
+
/**
|
|
235
|
+
* Threads with an in-flight run. Strands `Agent.stream()` throws if a
|
|
236
|
+
* second invocation is started on a busy agent; we detect the collision
|
|
237
|
+
* up front and emit a protocol-shaped RUN_ERROR/THREAD_BUSY instead.
|
|
238
|
+
* TypeScript-only: the Python adapter has no equivalent guard.
|
|
239
|
+
*/
|
|
240
|
+
private readonly _activeRunsByThread;
|
|
241
|
+
/** Outstanding Strands interrupt IDs per thread, used to validate
|
|
242
|
+
* incoming `RunAgentInput.resume[]` (interrupts.mdx rule 4). */
|
|
243
|
+
private readonly _pendingInterruptsByThread;
|
|
244
|
+
/**
|
|
245
|
+
* When non-null, the adapter bypasses per-thread cloning and invokes
|
|
246
|
+
* the orchestrator directly. See `StrandsAgentOptions.agent`.
|
|
247
|
+
*/
|
|
248
|
+
private readonly _orchestrator;
|
|
249
|
+
/**
|
|
250
|
+
* Injectable logger. Defaults to console `warn`/`error` with `debug`
|
|
251
|
+
* suppressed, matching Python's stdlib `logging.getLogger(__name__)`.
|
|
252
|
+
*/
|
|
253
|
+
private readonly _log;
|
|
254
|
+
constructor(options: StrandsAgentOptions);
|
|
255
|
+
/** Run the Strands agent and yield AG-UI events. */
|
|
256
|
+
run(inputData: RunAgentInput): AsyncGenerator<BaseEvent, void, void>;
|
|
257
|
+
protected _runRaw(inputData: RunAgentInput): AsyncGenerator<BaseEvent, void, void>;
|
|
258
|
+
private _runSingleAgent;
|
|
259
|
+
/**
|
|
260
|
+
* Legacy burst path for tool calls — invoked when the Strands SDK delivers
|
|
261
|
+
* a complete `ToolUseBlock` or when a `ToolBehavior.argsStreamer` takes
|
|
262
|
+
* over args emission at contentBlockStop.
|
|
263
|
+
*
|
|
264
|
+
* The streaming path inside `_runSingleAgent` handles the common case
|
|
265
|
+
* directly; this helper handles continuation turns and custom streamers.
|
|
266
|
+
*
|
|
267
|
+
* Getters/setters surface the caller's local variables because JS closures
|
|
268
|
+
* capture by reference only for `const` / `let` in scope — an object of
|
|
269
|
+
* mutable fields would work but would require threading `state` through
|
|
270
|
+
* `_runSingleAgent`'s long body.
|
|
271
|
+
*/
|
|
272
|
+
private _emitToolCall;
|
|
273
|
+
/**
|
|
274
|
+
* Orchestrator-mode run loop. TypeScript-only: drives a `Graph` or `Swarm`
|
|
275
|
+
* `.stream()` call and translates multi-agent events. Per-thread caching,
|
|
276
|
+
* session managers, and proxy-tool sync don't apply.
|
|
277
|
+
*/
|
|
278
|
+
private _runOrchestrator;
|
|
279
|
+
private _buildThreadAgentConfig;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Build the message-history seed handed to `AgentConfig.messages` on
|
|
283
|
+
* cold-cache agent creation. TypeScript-only: the Python SDK mutates
|
|
284
|
+
* `Agent.messages` in place after construction via
|
|
285
|
+
* `_buildStrandsHistory`, whereas the TS SDK consumes a seed at
|
|
286
|
+
* construction time.
|
|
287
|
+
*
|
|
288
|
+
* - Normal run (tail is a `user` turn): seed everything except the final
|
|
289
|
+
* user turn; the final turn is passed to `agent.stream(...)` as the
|
|
290
|
+
* fresh prompt.
|
|
291
|
+
* - Continuation run (tail is a `tool` message) or orphan tail: seed the
|
|
292
|
+
* entire history so the agent sees its own tool call + result before the
|
|
293
|
+
* synthetic continuation prompt fires.
|
|
294
|
+
*
|
|
295
|
+
* Returns `undefined` when the resulting seed would be empty or would
|
|
296
|
+
* start with an `assistant` turn (Bedrock rejects assistant-first history).
|
|
297
|
+
*/
|
|
298
|
+
declare function buildStrandsSeed(messages: Message$1[], log?: Logger): Promise<AgentConfig["messages"]>;
|
|
299
|
+
/**
|
|
300
|
+
* Convert AG-UI messages into the `MessageData` shape `AgentConfig.messages`
|
|
301
|
+
* accepts on cold-cache agent construction. Similar in spirit to
|
|
302
|
+
* `_buildStrandsHistory` but drops orphan tool turns (Bedrock rejects them).
|
|
303
|
+
*/
|
|
304
|
+
declare function convertMessagesForStrandsSeed(messages: Message$1[], log?: Logger): Promise<Array<{
|
|
305
|
+
role: "user" | "assistant";
|
|
306
|
+
content: unknown[];
|
|
307
|
+
}>>;
|
|
308
|
+
//#endregion
|
|
309
|
+
export { ToolCallContext as _, convertMessagesForStrandsSeed as a, buildContextExtras as b, MaybePromise as c, StateContextBuilder as d, StateFromArgs as f, ToolBehavior as g, StrandsAgentConfig as h, buildStrandsSeed as i, PredictStateMapping as l, StatePayload as m, StrandsAgentOptions as n, ArgsStreamer as o, StateFromResult as p, buildSnapshotMessages as r, CustomResultHandler as s, StrandsAgent as t, SessionManagerProvider as u, ToolCallContextExtras as v, Logger as x, ToolResultContext as y };
|
|
310
|
+
//# sourceMappingURL=agent-Dp45JIaO.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-Dp45JIaO.d.mts","names":[],"sources":["../src/logger.ts","../src/config.ts","../src/agent.ts"],"mappings":";;;;;;;;AAcA;;;;;;;;;;UAAiB,MAAA;EACf,KAAA,CAAM,OAAA,aAAoB,IAAA;EAC1B,IAAA,CAAK,OAAA,aAAoB,IAAA;EACzB,KAAA,CAAM,OAAA,aAAoB,IAAA;AAAA;;;KCVhB,YAAA,GAAe,MAAA;;;;;;;;;;UAWV,qBAAA;EDDT;;;;;;ECQN,OAAA,EAAS,QAAA,CAAS,MAAA;EAlBR;;;;EAuBV,cAAA,EAAgB,QAAA,CAAS,MAAA;AAAA;;UAIV,eAAA,SAAwB,qBAAA;EACvC,SAAA,EAAW,aAAA;EACX,QAAA;EACA,SAAA;EACA,SAAA;EACA,OAAA;AAAA;;UAIe,iBAAA,SAA0B,eAAA;EACzC,UAAA;EACA,SAAA;AAAA;AAAA,KAGU,YAAA,MAAkB,CAAA,GAAI,OAAA,CAAQ,CAAA;AAAA,KAE9B,YAAA,IAAgB,GAAA,EAAK,eAAA,KAAoB,aAAA;AAAA,KACzC,aAAA,IACV,GAAA,EAAK,eAAA,KACF,YAAA,CAAa,YAAA;AAAA,KACN,eAAA,IACV,GAAA,EAAK,iBAAA,KACF,YAAA,CAAa,YAAA;AAAA,KACN,mBAAA,IACV,GAAA,EAAK,iBAAA,KACF,aAAA,CAAc,SAAA;AAAA,KACP,mBAAA,IACV,SAAA,EAAW,aAAA,EACX,MAAA;;AAEA,MAAA,GAAS,qBAAA;AAAA,KAEC,sBAAA,IACV,SAAA,EAAW,aAAA,KACR,YAAA,CAAa,cAAA;;UAGD,mBAAA;EACf,QAAA;EACA,IAAA;EACA,YAAA;AAAA;;UAgBe,YAAA;EA7Cf;;;AAGF;;EAgDE,oBAAA;EAhD4B;EAkD5B,yBAAA;EAlDgC;EAoDhC,wBAAA;EApDuC;EAsDvC,YAAA,GAAe,mBAAA,GAAsB,QAAA,CAAS,mBAAA;EAtDlB;EAwD5B,YAAA,GAAe,YAAA;EAxDyB;EA0DxC,aAAA,GAAgB,aAAA;EA1DyB;EA4DzC,eAAA,GAAkB,eAAA;EA1DI;EA4DtB,mBAAA,GAAsB,mBAAA;AAAA;;UAIP,kBAAA;EAhEoC;EAkEnD,aAAA,GAAgB,MAAA,SAAe,YAAA;EAlEiC;EAoEhE,mBAAA,GAAsB,mBAAA;EAnEC;;;;;;;;;;;;;AAGzB;;EAgFE,sBAAA,GAAyB,sBAAA;EA/EpB;;;;;;;;EAwFL,oBAAA;EAvF4B;;AAC9B;;;;;;;;EAiGE,wBAAA;EAhGA;;;;;AAEF;;EAsGE,eAAA;EAlG8B;;;;;;;;AAEhC;;;;;EA8GE,MAAA,GAAS,MAAA;AAAA;;;;;;iBAuBK,kBAAA,CACd,SAAA,EAAW,aAAA,GACV,qBAAA;;;;;;;UC7IO,mBAAA;EAAA,SACC,EAAA;EACT,MAAA,CAAO,KAAA,WAAgB,cAAA;AAAA;;;;;;ADvDzB;iBCuNgB,qBAAA,CACd,cAAA,EAAgB,SAAA,KACf,SAAA;;UAiKc,mBAAA;ED1XgB;AAWjC;;;;;ECsXE,KAAA,EAAO,KAAA,GAAmB,mBAAA;EAC1B,IAAA;EACA,WAAA;EACA,MAAA,GAAS,kBAAA;EDlXT;;;;;;ECyXA,OAAA,GAAU,MAAA;AAAA;ADhXZ;AAAA,cCoXa,YAAA;EAAA,SACF,IAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,EAAQ,kBAAA;EAAA,iBAGA,eAAA;EDzXN;;;;;;;AAQb;;EARa,iBCoYM,QAAA;EAAA,iBAEA,eAAA;EAAA,iBACA,uBAAA;ED9XjB;;;;AAIF;;EAJE,iBCqYiB,eAAA;EDjYW;;;;;;EAAA,iBCwYX,mBAAA;EDxYe;;EAAA,iBC2Yf,0BAAA;ED3YwB;AAE3C;;;EAF2C,iBCgZxB,aAAA;ED9Yc;;;;EAAA,iBCmZd,IAAA;cAEL,OAAA,EAAS,mBAAA;EDpZE;ECmdhB,GAAA,CAAI,SAAA,EAAW,aAAA,GAAgB,cAAA,CAAe,SAAA;EAAA,UAwCpC,OAAA,CACf,SAAA,EAAW,aAAA,GACV,cAAA,CAAe,SAAA;EAAA,QA0BH,eAAA;EDrhBZ;;;;;;;;;AACL;;;;EADK,QC0wDY,aAAA;EDvwDZ;;;;;EAAA,QC09DY,gBAAA;EAAA,QAsLP,uBAAA;AAAA;;AD/oEV;;;;;;;;;;;;;;AAGA;;iBCw3EsB,gBAAA,CACpB,QAAA,EAAU,SAAA,IACV,GAAA,GAAM,MAAA,GACL,OAAA,CAAQ,WAAA;;;;;;iBA2BW,6BAAA,CACpB,QAAA,EAAU,SAAA,IACV,GAAA,GAAM,MAAA,GACL,OAAA,CAAQ,KAAA;EAAQ,IAAA;EAA4B,OAAA;AAAA"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { _ as ToolCallContext, a as convertMessagesForStrandsSeed, b as buildContextExtras, c as MaybePromise, d as StateContextBuilder, f as StateFromArgs, g as ToolBehavior, h as StrandsAgentConfig, i as buildStrandsSeed, l as PredictStateMapping, m as StatePayload, n as StrandsAgentOptions, o as ArgsStreamer, p as StateFromResult, r as buildSnapshotMessages, s as CustomResultHandler, t as StrandsAgent, u as SessionManagerProvider, v as ToolCallContextExtras, x as Logger, y as ToolResultContext } from "./agent-Dp45JIaO.mjs";
|
|
2
|
+
import { Agent, ContentBlock, Tool } from "@strands-agents/sdk";
|
|
3
|
+
import { InputContent, Tool as Tool$1 } from "@ag-ui/core";
|
|
4
|
+
import { HttpAgent } from "@ag-ui/client";
|
|
5
|
+
|
|
6
|
+
//#region src/client-proxy-tool.d.ts
|
|
7
|
+
/** Derived from `Agent.toolRegistry` because Strands doesn't re-export the type. */
|
|
8
|
+
type StrandsToolRegistry = Agent["toolRegistry"];
|
|
9
|
+
/**
|
|
10
|
+
* Convert an AG-UI `Tool` into a Strands proxy `Tool`.
|
|
11
|
+
*
|
|
12
|
+
* When invoked server-side the proxy returns a placeholder result — the real
|
|
13
|
+
* execution happens on the client. Proxy tools are distinguishable from
|
|
14
|
+
* tools registered at server startup via an internal symbol marker.
|
|
15
|
+
*/
|
|
16
|
+
declare function createProxyTool(tool: Tool$1): Tool;
|
|
17
|
+
/** Returns `true` if `tool` was created by `createProxyTool`. */
|
|
18
|
+
declare function isProxyTool(tool: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Synchronise proxy tools in `toolRegistry` with `aguiTools`.
|
|
21
|
+
*
|
|
22
|
+
* - New tools present in `aguiTools` but absent from the registry are
|
|
23
|
+
* registered (unless a native, non-proxy tool with the same name exists).
|
|
24
|
+
* - Stale proxy tools in `trackedNames` but absent from `aguiTools` are
|
|
25
|
+
* removed.
|
|
26
|
+
*
|
|
27
|
+
* Returns the updated set of proxy tool names currently registered.
|
|
28
|
+
*/
|
|
29
|
+
declare function syncProxyTools(toolRegistry: StrandsToolRegistry, aguiTools: Tool$1[], trackedNames: Set<string>, log?: Logger): Set<string>;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/utils.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Convert an AG-UI `InputContent` list to Strands `ContentBlock` values.
|
|
34
|
+
*
|
|
35
|
+
* Supported types:
|
|
36
|
+
* - `TextInputContent` -> `TextBlock`
|
|
37
|
+
* - `ImageInputContent` -> `ImageBlock` (png, jpeg, gif, webp)
|
|
38
|
+
* - `DocumentInputContent` -> `DocumentBlock` (pdf, csv, doc, docx, xls, xlsx, html, txt, md)
|
|
39
|
+
* - `VideoInputContent` -> `VideoBlock` (flv, mkv, mov, mpeg, mpg, mp4, three_gp, webm, wmv)
|
|
40
|
+
* - `AudioInputContent` — skipped (Strands has no audio support).
|
|
41
|
+
* - Unresolvable items (bad MIME, fetch failure) — skipped.
|
|
42
|
+
*/
|
|
43
|
+
declare function convertAguiContentToStrands(content: InputContent[], log?: Logger): Promise<ContentBlock[]>;
|
|
44
|
+
/** Extract plain text from AG-UI message content or Strands content blocks. */
|
|
45
|
+
declare function flattenContentToText(content: unknown): string;
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/index.d.ts
|
|
48
|
+
declare class AWSStrandsAgent extends HttpAgent {}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { AWSStrandsAgent, type ArgsStreamer, type CustomResultHandler, type Logger, type MaybePromise, type PredictStateMapping, type SessionManagerProvider, type StateContextBuilder, type StateFromArgs, type StateFromResult, type StatePayload, StrandsAgent, type StrandsAgentConfig, type StrandsAgentOptions, type StrandsToolRegistry, type ToolBehavior, type ToolCallContext, type ToolCallContextExtras, type ToolResultContext, buildContextExtras, buildSnapshotMessages, buildStrandsSeed, convertAguiContentToStrands, convertMessagesForStrandsSeed, createProxyTool, flattenContentToText, isProxyTool, syncProxyTools };
|
|
51
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/client-proxy-tool.ts","../src/utils.ts","../src/index.ts"],"mappings":";;;;;;;KAkBY,mBAAA,GAAsB,KAAA;AAAlC;;;;;AAgBA;;AAhBA,iBAgBgB,eAAA,CAAgB,IAAA,EAAM,MAAA,GAAW,IAAA;;iBAqCjC,WAAA,CAAY,IAAA;;;;;AAA5B;;;;;AAkBA;iBAAgB,cAAA,CACd,YAAA,EAAc,mBAAA,EACd,SAAA,EAAW,MAAA,IACX,YAAA,EAAc,GAAA,UACd,GAAA,GAAK,MAAA,GACJ,GAAA;;;;;AA5EH;;;;;AAgBA;;;;iBCoGsB,2BAAA,CACpB,OAAA,EAAS,YAAA,IACT,GAAA,GAAK,MAAA,GACJ,OAAA,CAAQ,YAAA;;iBAkGK,oBAAA,CAAqB,OAAA;;;cC3LxB,eAAA,SAAwB,SAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { _ as ToolCallContext, a as convertMessagesForStrandsSeed, b as buildContextExtras, c as MaybePromise, d as StateContextBuilder, f as StateFromArgs, g as ToolBehavior, h as StrandsAgentConfig, i as buildStrandsSeed, l as PredictStateMapping, m as StatePayload, n as StrandsAgentOptions, o as ArgsStreamer, p as StateFromResult, r as buildSnapshotMessages, s as CustomResultHandler, t as StrandsAgent, u as SessionManagerProvider, v as ToolCallContextExtras, x as Logger, y as ToolResultContext } from "./agent-B2EYZvns.js";
|
|
2
|
+
import { Agent, ContentBlock, Tool } from "@strands-agents/sdk";
|
|
3
|
+
import { InputContent, Tool as Tool$1 } from "@ag-ui/core";
|
|
4
|
+
import { HttpAgent } from "@ag-ui/client";
|
|
5
|
+
|
|
6
|
+
//#region src/client-proxy-tool.d.ts
|
|
7
|
+
/** Derived from `Agent.toolRegistry` because Strands doesn't re-export the type. */
|
|
8
|
+
type StrandsToolRegistry = Agent["toolRegistry"];
|
|
9
|
+
/**
|
|
10
|
+
* Convert an AG-UI `Tool` into a Strands proxy `Tool`.
|
|
11
|
+
*
|
|
12
|
+
* When invoked server-side the proxy returns a placeholder result — the real
|
|
13
|
+
* execution happens on the client. Proxy tools are distinguishable from
|
|
14
|
+
* tools registered at server startup via an internal symbol marker.
|
|
15
|
+
*/
|
|
16
|
+
declare function createProxyTool(tool: Tool$1): Tool;
|
|
17
|
+
/** Returns `true` if `tool` was created by `createProxyTool`. */
|
|
18
|
+
declare function isProxyTool(tool: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Synchronise proxy tools in `toolRegistry` with `aguiTools`.
|
|
21
|
+
*
|
|
22
|
+
* - New tools present in `aguiTools` but absent from the registry are
|
|
23
|
+
* registered (unless a native, non-proxy tool with the same name exists).
|
|
24
|
+
* - Stale proxy tools in `trackedNames` but absent from `aguiTools` are
|
|
25
|
+
* removed.
|
|
26
|
+
*
|
|
27
|
+
* Returns the updated set of proxy tool names currently registered.
|
|
28
|
+
*/
|
|
29
|
+
declare function syncProxyTools(toolRegistry: StrandsToolRegistry, aguiTools: Tool$1[], trackedNames: Set<string>, log?: Logger): Set<string>;
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/utils.d.ts
|
|
32
|
+
/**
|
|
33
|
+
* Convert an AG-UI `InputContent` list to Strands `ContentBlock` values.
|
|
34
|
+
*
|
|
35
|
+
* Supported types:
|
|
36
|
+
* - `TextInputContent` -> `TextBlock`
|
|
37
|
+
* - `ImageInputContent` -> `ImageBlock` (png, jpeg, gif, webp)
|
|
38
|
+
* - `DocumentInputContent` -> `DocumentBlock` (pdf, csv, doc, docx, xls, xlsx, html, txt, md)
|
|
39
|
+
* - `VideoInputContent` -> `VideoBlock` (flv, mkv, mov, mpeg, mpg, mp4, three_gp, webm, wmv)
|
|
40
|
+
* - `AudioInputContent` — skipped (Strands has no audio support).
|
|
41
|
+
* - Unresolvable items (bad MIME, fetch failure) — skipped.
|
|
42
|
+
*/
|
|
43
|
+
declare function convertAguiContentToStrands(content: InputContent[], log?: Logger): Promise<ContentBlock[]>;
|
|
44
|
+
/** Extract plain text from AG-UI message content or Strands content blocks. */
|
|
45
|
+
declare function flattenContentToText(content: unknown): string;
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/index.d.ts
|
|
48
|
+
declare class AWSStrandsAgent extends HttpAgent {}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { AWSStrandsAgent, type ArgsStreamer, type CustomResultHandler, type Logger, type MaybePromise, type PredictStateMapping, type SessionManagerProvider, type StateContextBuilder, type StateFromArgs, type StateFromResult, type StatePayload, StrandsAgent, type StrandsAgentConfig, type StrandsAgentOptions, type StrandsToolRegistry, type ToolBehavior, type ToolCallContext, type ToolCallContextExtras, type ToolResultContext, buildContextExtras, buildSnapshotMessages, buildStrandsSeed, convertAguiContentToStrands, convertMessagesForStrandsSeed, createProxyTool, flattenContentToText, isProxyTool, syncProxyTools };
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/client-proxy-tool.ts","../src/utils.ts","../src/index.ts"],"mappings":";;;;;;;KAkBY,mBAAA,GAAsB,KAAA;AAAlC;;;;;AAgBA;;AAhBA,iBAgBgB,eAAA,CAAgB,IAAA,EAAM,MAAA,GAAW,IAAA;;iBAqCjC,WAAA,CAAY,IAAA;;;;;AAA5B;;;;;AAkBA;iBAAgB,cAAA,CACd,YAAA,EAAc,mBAAA,EACd,SAAA,EAAW,MAAA,IACX,YAAA,EAAc,GAAA,UACd,GAAA,GAAK,MAAA,GACJ,GAAA;;;;;AA5EH;;;;;AAgBA;;;;iBCoGsB,2BAAA,CACpB,OAAA,EAAS,YAAA,IACT,GAAA,GAAK,MAAA,GACJ,OAAA,CAAQ,YAAA;;iBAkGK,oBAAA,CAAqB,OAAA;;;cC3LxB,eAAA,SAAwB,SAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let e=require(`crypto`),t=require(`@strands-agents/sdk`),n=require(`@ag-ui/core`),r=require(`@ag-ui/client`);function i(e){return{state_key:e.stateKey,tool:e.tool,tool_argument:e.toolArgument}}const a=new Set([`__proto__`,`constructor`,`prototype`]);function o(e){return typeof e==`object`&&!!e&&`stateKey`in e&&`tool`in e&&`toolArgument`in e}function s(e){let t=Object.create(null),n=e.context;if(Array.isArray(n))for(let e of n){if(!e||typeof e!=`object`)continue;let n=e;typeof n.description!=`string`||n.description.length===0||a.has(n.description)||(t[n.description]=typeof n.value==`string`?n.value:String(n.value??``))}let r=e.forwardedProps;return{context:t,forwardedProps:r&&typeof r==`object`&&!Array.isArray(r)?r:{}}}async function c(e){return await Promise.resolve(e)}function l(e){return e===void 0?[]:o(e)?[e]:Array.from(e)}const u={debug(){},warn:(e,...t)=>console.warn(e,...t),error:(e,...t)=>console.error(e,...t)};function d(e){return e??u}const f=`[@ag-ui/aws-strands]`,p=Symbol.for(`@ag-ui/aws-strands.proxyTool`);function m(e){let n=e.description&&e.description.length>0?e.description:`Client-side tool: ${e.name}`,r={name:e.name,description:n,inputSchema:e.parameters??{type:`object`,properties:{}}};return{name:r.name,description:n,toolSpec:r,[p]:!0,async*stream(e){return new t.ToolResultBlock({toolUseId:e.toolUse.toolUseId,status:`success`,content:[new t.TextBlock(`Forwarded to client`)]})}}}function h(e){return typeof e==`object`&&!!e&&e[p]===!0}function g(e,t,n,r=u){let i=new Set;for(let e of t)e.name&&i.add(e.name);for(let t of n){if(i.has(t))continue;let n=e.get(t);n&&h(n)&&(e.remove(t),r.debug(`${f} Removed stale proxy tool: ${t}`))}let a=new Set;for(let n of t){if(!n.name)continue;let t=e.get(n.name);if(t&&!h(t)){r.warn(`${f} Native tool "${n.name}" shadows client-declared tool with the same name; client tool will not be registered`);continue}t&&e.remove(n.name),e.add(m(n)),a.add(n.name),r.debug(`${f} Registered proxy tool: ${n.name}`)}return a}const _=`[@ag-ui/aws-strands]`,v=new Set([`png`,`jpeg`,`gif`,`webp`]),y=new Set([`pdf`,`csv`,`doc`,`docx`,`xls`,`xlsx`,`html`,`txt`,`md`]),b=new Set([`flv`,`mkv`,`mov`,`mpeg`,`mpg`,`mp4`,`three_gp`,`webm`,`wmv`]);function x(e,t,n){if(!e)return n.warn(`${_} No MIME type provided, cannot determine format`),null;let r=e.split(`/`).pop()?.toLowerCase()??``;return t.has(r)?r:(n.warn(`${_} Unsupported MIME type '${e}' (parsed format '${r}' not in ${JSON.stringify([...t].sort())})`),null)}async function S(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),3e4);try{let r=await fetch(e,{signal:n.signal});if(!r.ok)return t.warn(`${_} Failed to fetch URL ${e}: HTTP ${r.status}`),null;let i=await r.arrayBuffer();return new Uint8Array(i)}catch(n){return t.warn(`${_} Failed to fetch URL ${e}:`,n),null}finally{clearTimeout(r)}}function C(e,t){try{let t=globalThis.atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}catch(e){return t.warn(`${_} Failed to decode base64 content:`,e),null}}async function w(e,t){return e.type===`data`?C(e.value,t):e.type===`url`?await S(e.value,t):(t.warn(`${_} Unknown content source type: ${e.type}, cannot resolve bytes`),null)}async function T(e,n=u){let r=[];for(let i of e){if(i.type===`text`){r.push(new t.TextBlock(i.text));continue}if(i.type===`image`){let e=i,a=await w(e.source,n);if(!a)continue;let o=x(e.source.mimeType,v,n);if(!o)continue;r.push(new t.ImageBlock({format:o,source:{bytes:a}}));continue}if(i.type===`document`){let e=i,a=await w(e.source,n);if(!a)continue;let o=x(e.source.mimeType,y,n);if(!o)continue;r.push(new t.DocumentBlock({format:o,name:`document`,source:{bytes:a}}));continue}if(i.type===`video`){let e=i,a=await w(e.source,n);if(!a)continue;let o=x(e.source.mimeType,b,n);if(!o)continue;r.push(new t.VideoBlock({format:o,source:{bytes:a}}));continue}if(i.type===`audio`){n.warn(`${_} Skipping audio content: Strands has no audio support`);continue}if(i.type===`binary`){let e=i,a=null;if(e.data?a=C(e.data,n):e.url&&(a=await S(e.url,n)),!a){n.warn(`${_} Skipping binary content: could not resolve bytes`);continue}let o=x(e.mimeType,v,n);if(!o){n.warn(`${_} Skipping binary content: unsupported MIME type '${e.mimeType}'`);continue}r.push(new t.ImageBlock({format:o,source:{bytes:a}}));continue}n.warn(`${_} Skipping unknown content type: ${i.type}`)}return r}function E(e){if(e==null)return``;if(typeof e==`string`)return e;if(Array.isArray(e)){let t=[];for(let n of e){if(!n||typeof n!=`object`)continue;let e=n;e.type===`text`&&typeof e.text==`string`&&t.push(e.text),e.type===`textBlock`&&typeof e.text==`string`&&t.push(e.text)}return t.join(` `)}return``}const D=`[@ag-ui/aws-strands]`,O=()=>(0,e.randomUUID)();function k(e){let t={model:e.model,tools:e.tools.slice()};e.systemPrompt!==void 0&&(t.systemPrompt=e.systemPrompt),e.name!==void 0&&(t.name=e.name),e.id!==void 0&&(t.id=e.id),e.description!==void 0&&(t.description=e.description);let n=e.appState?.getAll?.();n&&Object.keys(n).length>0&&(t.appState=n);let r=e.modelState?.getAll?.();r&&Object.keys(r).length>0&&(t.modelState=r);let i=e;return i.traceAttributes!==void 0&&(t.traceAttributes=i.traceAttributes),i.structuredOutputSchema!==void 0&&(t.structuredOutputSchema=i.structuredOutputSchema),i.toolExecutor!==void 0&&(t.toolExecutor=i.toolExecutor),t}function A(e){return typeof e==`string`?e:e==null?``:Array.isArray(e)?E(e):String(e)}function j(e){let t=A(e),n=t.trim();if(n.length===0)return{text:t};let r=n[0];if(r!==`{`&&r!==`[`)return{text:t};try{let e=JSON.parse(n);if(typeof e==`object`&&e)return{json:e}}catch{}return{text:t}}function M(e){return typeof e==`string`&&e.length>0?e:O()}function N(e){return e instanceof Error?e.message:String(e)}function P(e,t,n){for(let[n,r]of e)if(r.strandsToolId===t)return n;return n?O():t||O()}function F(e){let t=[];for(let n of e??[]){let e=n.role;if(e!==`user`&&e!==`assistant`&&e!==`tool`)continue;let r=M(n.id);if(e===`user`)t.push({id:r,role:`user`,content:A(n.content)});else if(e===`assistant`){let e=n.toolCalls,i;e&&e.length>0&&(i=e.map(e=>{let t=e.function;return{id:M(e.id),type:`function`,function:{name:t?.name??`unknown`,arguments:t?.arguments??`{}`}}}));let a={id:r,role:`assistant`,content:A(n.content)};i&&(a.toolCalls=i),t.push(a)}else{let e=n.toolCallId??``;t.push({id:r,role:`tool`,content:A(n.content),toolCallId:e})}}return t}async function I(e,n){let r=[];for(let i of e??[]){let e=i.role;if(e===`user`){let e=[],a=i.content;if(Array.isArray(a))if(a.some(e=>[`image`,`audio`,`video`,`document`].includes(e.type??``))){try{let r=await T(a,n);for(let n of r)if(n instanceof t.TextBlock)e.push({text:n.text});else{let t=typeof n.toJSON==`function`?n.toJSON():n;e.push(t)}}catch(e){n.warn(`${D} history replay multimodal conversion failed; falling back to text`,e)}e.length===0&&e.push({text:E(a)||``})}else e.push({text:E(a)});else e.push({text:A(a)});r.push({role:`user`,content:e})}else if(e===`assistant`){let e=[],t=A(i.content);t&&e.push({text:t});let a=i.toolCalls??[];for(let t of a){let r=t.function,i=r?.name||`unknown`,a=r?.arguments||`{}`,o;try{o=JSON.parse(a)}catch(e){n.warn(`${D} history tool args JSON parse failed for ${i}; falling back to {}`,e),o={}}(typeof o!=`object`||!o||Array.isArray(o))&&(o={}),e.push({toolUse:{toolUseId:t.id,name:i,input:o}})}e.length===0&&e.push({text:``}),r.push({role:`assistant`,content:e})}else if(e===`tool`){let e=i.toolCallId||``;r.push({role:`user`,content:[{toolResult:{toolUseId:e,content:[j(i.content)],status:`success`}}]})}}return r}var L=class{constructor(e){this._agentsByThread=new Map,this._proxyToolNamesByThread=new Map,this._threadInitLock=new R,this._activeRunsByThread=new Set,this._pendingInterruptsByThread=new Map;let{agent:t,name:n,description:r=``,config:i={},plugins:a}=e,o=t.model===void 0||t.model===null;if(this.name=n,this.description=r,this.config=i,this._log=d(i.logger),o){this._orchestrator=t,this._templateFields={model:void 0,tools:[]},this._plugins=[];return}this._orchestrator=null;let s=t;this._templateFields=k(s),this._plugins=a?[...a]:[],s.sessionManager&&!this.config.sessionManagerProvider&&this._log.warn(`${D} sessionManager was set on the template Agent but will be ignored: forwarding it would cause every AG-UI thread to share the same session_id. Construct per-thread session managers via StrandsAgentConfig.sessionManagerProvider instead.`);for(let e of this._templateFields.tools??[])e!=null&&typeof e.connect==`function`&&typeof e.name!=`string`&&this._log.warn(`${D} an entry in the template Agent's \`tools\` looks like an unconnected McpClient — its tools will not be available to the model. Call \`await client.connect()\` and spread the resolved tool list into \`tools: [...]\` before constructing the Agent.`)}async*run(e){let t=e.threadId||`default`;if(Array.isArray(e.resume)&&e.resume.length>0){let n=this._pendingInterruptsByThread.get(t),r=e.resume.map(e=>e.interruptId).filter(e=>!n?.has(e));if(r.length>0){yield z(e),yield B(`This agent did not issue any interrupts to resume: ${r.slice(0,4).join(`, `)}. Resume entries must reference an outstanding interruptId.`,`UNKNOWN_INTERRUPT`);return}}else this._pendingInterruptsByThread.delete(t);let n=this._runRaw(e);if(this.config.emitChunkEvents){yield*K(n);return}yield*n}async*_runRaw(e){let t=e.threadId||`default`;if(this._activeRunsByThread.has(t)){yield z(e),yield B(`Another run is already in progress on thread "${t}". Wait for RUN_FINISHED before starting a new run on the same thread.`,`THREAD_BUSY`);return}this._activeRunsByThread.add(t);try{this._orchestrator===null?yield*this._runSingleAgent(e,t):yield*this._runOrchestrator(e)}finally{this._activeRunsByThread.delete(t)}}async*_runSingleAgent(e,r){yield z(e);let a=this._agentsByThread.get(r);if(!a){let n;if(!this.config.sessionManagerProvider)try{n=await q(e.messages??[],this._log)}catch(e){this._log.error(`${D} buildStrandsSeed failed for thread ${r}: ${N(e)}`,e),yield B(`Failed to build conversation seed: `+N(e),`SEED_BUILD_ERROR`);return}let i=await this._threadInitLock.acquire();try{if(a=this._agentsByThread.get(r),!a){let i;if(this.config.sessionManagerProvider){try{i=await c(this.config.sessionManagerProvider(e))}catch(e){let t=N(e);this._log.error(`${D} sessionManagerProvider failed: ${t}`,e),yield B(`Failed to initialize session manager: ${t}`,`SESSION_MANAGER_ERROR`);return}if(i!=null&&!(i instanceof t.SessionManager)){let e=i?.constructor?.name??typeof i;this._log.error(`${D} sessionManagerProvider returned ${e}; expected a SessionManager instance.`),yield B(`sessionManagerProvider returned ${e}; expected a SessionManager instance`,`SESSION_MANAGER_INVALID_TYPE`);return}i||this._log.warn(`${D} sessionManagerProvider returned null/undefined for threadId=${r}; agent will run without session persistence`)}let o=i?void 0:n;a=new t.Agent(this._buildThreadAgentConfig(i??void 0,o)),this._agentsByThread.set(r,a)}}finally{i()}}if(e.tools&&e.tools.length>0){let t=g(a.toolRegistry,e.tools,this._proxyToolNamesByThread.get(r)??new Set,this._log);this._proxyToolNamesByThread.set(r,t)}else{let e=this._proxyToolNamesByThread.get(r);e&&e.size>0&&(g(a.toolRegistry,[],e,this._log),this._proxyToolNamesByThread.set(r,new Set))}try{let o=this.config.emitMessagesSnapshot!==!1,u=o?F(e.messages??[]):[];if(e.state&&typeof e.state==`object`){let t={};for(let[n,r]of Object.entries(e.state))n!==`messages`&&(t[n]=r);yield{type:n.EventType.STATE_SNAPSHOT,snapshot:t}}o&&u.length>0&&(yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()});let d=new Set;for(let t of e.tools??[])t.name&&d.add(t.name);let f=new Set;if(e.messages){for(let t=e.messages.length-1;t>=0;t--){let n=e.messages[t];if(!n)break;if(n.role===`tool`){let e=n.toolCallId;e&&f.add(e)}else break}f.size>0&&this._log.debug(`${D} Has pending tool results detected: toolCallIds=${JSON.stringify([...f])}, threadId=${e.threadId}`)}let p=new Map;for(let t of e.messages??[]){if(t.role!==`assistant`)continue;let e=t.toolCalls;if(e)for(let t of e){let e=t.function;t.id&&e?.name&&p.set(t.id,e.name)}}let m=`Hello`;if(f.size>0&&e.messages)for(let t=e.messages.length-1;t>=0;t--){let n=e.messages[t];if(!n)break;if(n.role===`tool`){let e=n.toolCallId;if(e){let t=p.get(e);t&&d.has(t)&&(m=`${t} executed successfully with no return value.`)}break}}else if(e.messages)for(let t=e.messages.length-1;t>=0;t--){let n=e.messages[t];if(!n)break;if((n.role===`user`||n.role===`tool`)&&n.content!=null){if(Array.isArray(n.content))if(n.content.some(e=>[`image`,`audio`,`video`,`document`].includes(e.type??``))){let e=await T(n.content,this._log);if(e.length>0)m=e;else{let e=E(n.content);if(e)m=e,this._log.warn(`${D} all media content blocks failed conversion; falling back to text`);else{yield B(`All media content blocks failed conversion and no text fallback is available`,`MEDIA_RESOLUTION_FAILED`);return}}}else m=E(n.content);else m=n.content;break}}if(this.config.stateContextBuilder)try{let t=Array.isArray(m)?E(m):m,n=this.config.stateContextBuilder(e,t,s(e));Array.isArray(m)||(m=n)}catch(e){this._log.error(`${D} stateContextBuilder failed:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateContextBuilder`,tool:`__prompt__`,error:N(e)}}}let h=O(),g=!1,_=``,v=new Map,y={...e.state??{}},b=!1,x=!1,S=!1,C=!1,w,k=null,A=this.config.replayHistoryIntoStrands!==!1&&!a.sessionManager,j=m,M=V(e);if(M.length>0&&(j=M.map(e=>new t.InterruptResponseContent({interruptId:e.interruptId,response:H(e)})),this._pendingInterruptsByThread.delete(r)),A&&M.length===0){let r=await I(e.messages??[],this._log);if(r.length>0){if(this.config.stateContextBuilder)for(let t=r.length-1;t>=0;t--){let i=r[t];if(!i||i.role!==`user`)continue;let a=i.content[0];if(a&&typeof a.text==`string`){try{let t=this.config.stateContextBuilder(e,a.text,s(e));typeof t==`string`&&(a.text=t)}catch(e){this._log.error(`${D} stateContextBuilder failed:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateContextBuilder`,tool:`__prompt__`,error:N(e)}}}break}}a.messages=r.map(e=>t.Message.fromMessageData({role:e.role,content:e.content})),j=void 0}}this._log.debug(`${D} Starting agent run: threadId=${e.threadId}, runId=${e.runId}, pendingToolResultIds=${JSON.stringify([...f])}, messageCount=${e.messages?.length??0}`);let L=new AbortController,R=a.stream(j,{cancelSignal:L.signal}),z;try{for(;;){let r;try{r=await R.next()}catch(e){if(S||x){if(e instanceof TypeError||e instanceof ReferenceError)throw e;x=!0;break}throw e}if(r.done){z=r.value;break}if(x)continue;let a=G(r.value),p=W(a);if(p===`modelContentBlockDeltaEvent`){let t=a.delta;if(t.type===`textDelta`&&t.text){if(b)continue;g||=(yield{type:n.EventType.TEXT_MESSAGE_START,messageId:h,role:`assistant`},!0),_+=t.text,yield{type:n.EventType.TEXT_MESSAGE_CONTENT,messageId:h,delta:t.text};continue}if(t.type===`reasoningContentDelta`){t.text?(C||=(w=O(),yield{type:n.EventType.REASONING_START,messageId:w},yield{type:n.EventType.REASONING_MESSAGE_START,messageId:w,role:`reasoning`},!0),yield{type:n.EventType.REASONING_MESSAGE_CONTENT,messageId:w,delta:t.text}):t.redactedContent&&(C||=(w=O(),yield{type:n.EventType.REASONING_START,messageId:w},yield{type:n.EventType.REASONING_MESSAGE_START,messageId:w,role:`reasoning`},!0),yield{type:n.EventType.REASONING_ENCRYPTED_VALUE,subtype:`message`,entityId:w,encryptedValue:Buffer.from(t.redactedContent).toString(`base64`)});continue}if(t.type===`toolUseInputDelta`&&k){k.inputChunks.push(t.input);let{name:r,toolUseId:a}=k,s=d.has(r),c=P(v,a,s),p=v.get(c);if(!p){let t=f.has(c),d=this.config.toolBehaviors?.[r];this._log.debug(`${D} Tool call event received: toolName=${r}, toolUseId=${c}, strandsId=${a}, isFrontend=${s}, threadId=${e.threadId}`);let m=!t&&!d?.argsStreamer;if(p={name:r,args:``,input:{},raw:``,emitted:!1,startEmitted:!1,endEmitted:!1,lastEmittedRawLen:0,isPending:t,isFrontend:s,useStreaming:m,strandsToolId:a},v.set(c,p),m){if(g&&(yield{type:n.EventType.TEXT_MESSAGE_END,messageId:h},o&&_&&(u.push({id:h,role:`assistant`,content:_}),_=``,yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()}),g=!1,h=O()),d){let e=l(d.predictState).map(i);e.length>0&&(yield{type:n.EventType.CUSTOM,name:`PredictState`,value:e})}yield{type:n.EventType.TOOL_CALL_START,toolCallId:c,toolCallName:r,parentMessageId:h},p.startEmitted=!0}}let m=k.inputChunks.join(``);p.raw=m;try{p.input=JSON.parse(m)}catch{p.input=m}if(p.args=typeof p.input==`string`?p.input:JSON.stringify(p.input),p.startEmitted&&p.useStreaming){let e=p.lastEmittedRawLen??0;m.length>e&&(yield{type:n.EventType.TOOL_CALL_ARGS,toolCallId:c,delta:m.slice(e)},p.lastEmittedRawLen=m.length)}}continue}if(p===`reasoningSignatureEvent`)continue;if(p===`modelContentBlockStartEvent`){let e=a.start;e?.type===`toolUseStart`&&e.name&&(k={name:e.name,toolUseId:e.toolUseId??O(),inputChunks:[]});continue}if(p===`modelContentBlockStopEvent`){if(C&&(yield{type:n.EventType.REASONING_MESSAGE_END,messageId:w},yield{type:n.EventType.REASONING_END,messageId:w},C=!1,w=void 0),k){let{name:t,toolUseId:r,inputChunks:i}=k;k=null;let a=i.join(``),l={};if(a)try{l=JSON.parse(a)}catch(e){this._log.warn(`${D} tool args JSON parse failed for ${t}; using raw string`,e),l=a}let p=d.has(t),m=P(v,r,p),b=typeof l==`string`?l:JSON.stringify(l);if(!v.has(m))v.set(m,{name:t,args:b,input:l,emitted:!1,strandsToolId:r,raw:a});else{let e=v.get(m);e.args=b,e.input=l,e.raw=a}let x=v.get(m),C=this.config.toolBehaviors?.[t];if(this._log.debug(`${D} contentBlockStop close: toolName=${t}, toolUseId=${m}, isFrontendTool=${p}, isPending=${x.isPending??!1}, useStreaming=${x.useStreaming??!1}, threadId=${e.threadId}`),x.startEmitted&&x.useStreaming){let r=x.lastEmittedRawLen??0;if(a.length>r&&(yield{type:n.EventType.TOOL_CALL_ARGS,toolCallId:m,delta:a.slice(r)},x.lastEmittedRawLen=a.length),C?.stateFromArgs){let r={inputData:e,toolName:t,toolUseId:m,toolInput:l,argsStr:b,...s(e)};try{let e=await c(C.stateFromArgs(r));e&&(Object.assign(y,e),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:e})}catch(e){this._log.error(`${D} stateFromArgs failed for ${t}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateFromArgs`,tool:t,error:N(e)}}}}yield{type:n.EventType.TOOL_CALL_END,toolCallId:m},x.endEmitted=!0,x.emitted=!0,o&&!C?.skipMessagesSnapshot&&(u.push({id:h,role:`assistant`,content:``,toolCalls:[{id:m,type:`function`,function:{name:t||`unknown`,arguments:b||`{}`}}]}),yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()},h=O()),p&&!C?.continueAfterFrontendCall&&(this._log.debug(`${D} Deferring halt after frontend tool call: toolName=${t}, toolCallId=${m}, threadId=${e.threadId}`),S=!0)}else yield*this._emitToolCall({inputData:e,toolUseId:m,isFrontendTool:p,pendingToolResultIds:f,getMessageId:()=>h,setMessageId:e=>{h=e},getMessageStarted:()=>g,setMessageStarted:e=>{g=e},getAccumulatedText:()=>_,setAccumulatedText:e=>{_=e},snapshotMessages:u,emitMessagesSnapshot:o,toolCallsSeen:v,currentState:y,onPendingHalt:()=>{S=!0}})}continue}if(p===`toolUseBlock`){let t=a,n=d.has(t.name),r=P(v,t.toolUseId,n),i=typeof t.input==`string`?t.input:JSON.stringify(t.input);if(!v.has(r))v.set(r,{name:t.name,args:i,input:t.input,emitted:!1,strandsToolId:t.toolUseId});else{let e=v.get(r);e.args=i,e.input=t.input}yield*this._emitToolCall({inputData:e,toolUseId:r,isFrontendTool:n,pendingToolResultIds:f,getMessageId:()=>h,setMessageId:e=>{h=e},getMessageStarted:()=>g,setMessageStarted:e=>{g=e},getAccumulatedText:()=>_,setAccumulatedText:e=>{_=e},snapshotMessages:u,emitMessagesSnapshot:o,toolCallsSeen:v,currentState:y,onPendingHalt:()=>{S=!0}});continue}if(p===`afterToolCallEvent`){if(S){x=!0;try{L.abort()}catch{}break}let r=a,i=r.toolUse.toolUseId,l=r.toolUse.name;if(d.has(l))continue;let f=null,p=r.result?.content;if(Array.isArray(p))for(let e of p){if(e instanceof t.TextBlock){try{f=JSON.parse(e.text)}catch{try{f=JSON.parse(e.text.replace(/'/g,`"`))}catch(t){this._log.warn(`${D} tool result JSON parse failed for ${l}; using raw text`,t),f=e.text}}break}let n=e.json;if(n!==void 0){f=n;break}}if(!i)continue;let m=v.get(i),C=m?.args,w=m?.input,T=this.config.toolBehaviors?.[l];this._log.debug(`${D} Processing tool result: toolName=${l}, resultToolId=${i}, threadId=${e.threadId}`);let E=O(),k=f==null?``:JSON.stringify(f);yield{type:n.EventType.TOOL_CALL_RESULT,toolCallId:i,messageId:E,content:k},o&&!T?.skipMessagesSnapshot&&(u.push({id:E,role:`tool`,content:k,toolCallId:i}),yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()});let A={inputData:e,toolName:l,toolUseId:i,toolInput:w,argsStr:C??`{}`,resultData:f,messageId:h,...s(e)};if(T?.stateFromResult)try{let e=await c(T.stateFromResult(A));e&&(Object.assign(y,e),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:e})}catch(e){this._log.error(`${D} stateFromResult failed for ${l}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateFromResult`,tool:l,error:N(e)}}}if(T?.customResultHandler)try{for await(let e of T.customResultHandler(A))e&&(yield e)}catch(e){this._log.error(`${D} customResultHandler failed for ${l}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`customResultHandler`,tool:l,error:N(e)}}}if(T?.stopStreamingAfterResult){b=!0,g&&(yield{type:n.EventType.TEXT_MESSAGE_END,messageId:h},g=!1,o&&_&&(u.push({id:h,role:`assistant`,content:_}),_=``,yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()})),this._log.debug(`${D} Breaking event stream: stopStreamingAfterResult behavior triggered (threadId=${e.threadId}, toolName=${l})`),x=!0;break}continue}if(p===`toolStreamEvent`){let e=a.data;e&&typeof e==`object`&&`state`in e&&(yield{type:n.EventType.STATE_SNAPSHOT,snapshot:e.state});continue}let m=a;if(m?.type===`beforeNodeCallEvent`){yield{type:n.EventType.STEP_STARTED,stepName:`${m.nodeType??`agent`}:${m.nodeId??`unknown`}`};continue}if(m?.type===`afterNodeCallEvent`){yield{type:n.EventType.STEP_FINISHED,stepName:`${m.nodeType??`agent`}:${m.nodeId??`unknown`}`};continue}if(m?.type===`multiAgentHandoffEvent`){let e=m.message;yield{type:n.EventType.CUSTOM,name:`MultiAgentHandoff`,value:{from_nodes:m.source?[m.source]:[],to_nodes:m.targets??[],message:e}};continue}}}finally{try{L.abort()}catch{}try{await R.return(void 0)}catch{}}if(C&&(yield{type:n.EventType.REASONING_MESSAGE_END,messageId:w},yield{type:n.EventType.REASONING_END,messageId:w}),g&&(yield{type:n.EventType.TEXT_MESSAGE_END,messageId:h},o&&_&&(u.push({id:h,role:`assistant`,content:_}),_=``,yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:u.slice()})),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:y},z?.stopReason===`interrupt`){let t=z.interrupts??[];if(t.length>0){let i=t.map(e=>e.id);this._pendingInterruptsByThread.set(r,new Set(i)),yield{type:n.EventType.RUN_FINISHED,threadId:e.threadId,runId:e.runId,outcome:{type:`interrupt`,interrupts:t.map(U)}};return}}yield{type:n.EventType.RUN_FINISHED,threadId:e.threadId,runId:e.runId}}catch(e){let t=e instanceof TypeError||e instanceof ReferenceError?`ADAPTER_BUG`:`STRANDS_ERROR`;this._log.error(`${D} _runSingleAgent failed:`,e),yield B(N(e),t)}}async*_emitToolCall(e){let t=e.toolCallsSeen.get(e.toolUseId);if(!t||t.emitted)return;t.emitted=!0;let r=t.name,a=t.args,o=t.input,u=this.config.toolBehaviors?.[r],d=e.pendingToolResultIds.has(e.toolUseId),f={inputData:e.inputData,toolName:r,toolUseId:e.toolUseId,toolInput:o,argsStr:a,...s(e.inputData)};if(d){if(u?.stateFromArgs)try{let t=await c(u.stateFromArgs(f));t&&(Object.assign(e.currentState,t),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:t})}catch(e){this._log.error(`${D} stateFromArgs failed for ${r}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateFromArgs`,tool:r,error:N(e)}}}return}if(u?.stateFromArgs)try{let t=await c(u.stateFromArgs(f));t&&(Object.assign(e.currentState,t),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:t})}catch(e){this._log.error(`${D} stateFromArgs failed for ${r}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`stateFromArgs`,tool:r,error:N(e)}}}if(u){let e=l(u.predictState).map(i);e.length>0&&(yield{type:n.EventType.CUSTOM,name:`PredictState`,value:e})}if(e.getMessageStarted()){yield{type:n.EventType.TEXT_MESSAGE_END,messageId:e.getMessageId()};let t=e.getAccumulatedText();e.emitMessagesSnapshot&&t&&(e.snapshotMessages.push({id:e.getMessageId(),role:`assistant`,content:t}),e.setAccumulatedText(``),yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:e.snapshotMessages.slice()}),e.setMessageStarted(!1),e.setMessageId(O())}yield{type:n.EventType.TOOL_CALL_START,toolCallId:e.toolUseId,toolCallName:r,parentMessageId:e.getMessageId()};let p=!1;if(u?.argsStreamer)try{for await(let t of u.argsStreamer(f))t!=null&&(yield{type:n.EventType.TOOL_CALL_ARGS,toolCallId:e.toolUseId,delta:String(t)})}catch(e){p=!0,this._log.error(`${D} argsStreamer failed for ${r}:`,e),yield{type:n.EventType.CUSTOM,name:`hook_error`,value:{hook:`argsStreamer`,tool:r,error:N(e)}}}else yield{type:n.EventType.TOOL_CALL_ARGS,toolCallId:e.toolUseId,delta:a};if(p){yield{type:n.EventType.TOOL_CALL_END,toolCallId:e.toolUseId};return}yield{type:n.EventType.TOOL_CALL_END,toolCallId:e.toolUseId},e.emitMessagesSnapshot&&!u?.skipMessagesSnapshot&&(e.snapshotMessages.push({id:e.getMessageId(),role:`assistant`,content:``,toolCalls:[{id:e.toolUseId,type:`function`,function:{name:r||`unknown`,arguments:a||`{}`}}]}),yield{type:n.EventType.MESSAGES_SNAPSHOT,messages:e.snapshotMessages.slice()},e.setMessageId(O())),e.isFrontendTool&&!u?.continueAfterFrontendCall&&(this._log.debug(`${D} Deferring halt after frontend tool call: toolName=${r}, toolCallId=${e.toolUseId}, threadId=${e.inputData.threadId}`),e.onPendingHalt())}async*_runOrchestrator(e){yield z(e);try{if(e.state&&typeof e.state==`object`){let t={};for(let[n,r]of Object.entries(e.state))n!==`messages`&&(t[n]=r);yield{type:n.EventType.STATE_SNAPSHOT,snapshot:t}}let t=`Hello`;if(e.messages)for(let n=e.messages.length-1;n>=0;n--){let r=e.messages[n];if(!r)break;if((r.role===`user`||r.role===`tool`)&&r.content!=null){t=typeof r.content==`string`?r.content:E(r.content);break}}let r=O(),i=!1,a=!1,o,s=this._orchestrator.stream(t);try{for await(let e of s){let t=G(e),s=W(t);if(s===`beforeNodeCallEvent`){let e=t;yield{type:n.EventType.STEP_STARTED,stepName:`${e.nodeType??`agent`}:${e.nodeId??`unknown`}`};continue}if(s===`afterNodeCallEvent`){let e=t;i&&(yield{type:n.EventType.TEXT_MESSAGE_END,messageId:r},i=!1,r=O()),a&&(yield{type:n.EventType.REASONING_MESSAGE_END,messageId:o},yield{type:n.EventType.REASONING_END,messageId:o},a=!1,o=void 0),yield{type:n.EventType.STEP_FINISHED,stepName:`${e.nodeType??`agent`}:${e.nodeId??`unknown`}`};continue}if(s===`multiAgentHandoffEvent`){let e=t;yield{type:n.EventType.CUSTOM,name:`MultiAgentHandoff`,value:{from_nodes:e.source?[e.source]:[],to_nodes:e.targets??[],message:e.message}};continue}if(s===`nodeStreamUpdateEvent`){let e=t,s=e.inner?.event?G(e.inner.event):void 0;if(W(s)===`modelContentBlockDeltaEvent`){let e=s.delta;e?.type===`textDelta`&&e.text?(i||=(yield{type:n.EventType.TEXT_MESSAGE_START,messageId:r,role:`assistant`},!0),yield{type:n.EventType.TEXT_MESSAGE_CONTENT,messageId:r,delta:e.text}):e?.type===`reasoningContentDelta`&&e.text&&(a||=(o=O(),yield{type:n.EventType.REASONING_START,messageId:o},yield{type:n.EventType.REASONING_MESSAGE_START,messageId:o,role:`reasoning`},!0),yield{type:n.EventType.REASONING_MESSAGE_CONTENT,messageId:o,delta:e.text})}continue}}}finally{try{await s.return(void 0)}catch{}}i&&(yield{type:n.EventType.TEXT_MESSAGE_END,messageId:r}),a&&(yield{type:n.EventType.REASONING_MESSAGE_END,messageId:o},yield{type:n.EventType.REASONING_END,messageId:o}),yield{type:n.EventType.STATE_SNAPSHOT,snapshot:{}},yield{type:n.EventType.RUN_FINISHED,threadId:e.threadId,runId:e.runId}}catch(e){let t=e instanceof TypeError||e instanceof ReferenceError?`ADAPTER_BUG`:`STRANDS_ERROR`;this._log.error(`${D} _runOrchestrator failed:`,e),yield B(N(e),t)}}_buildThreadAgentConfig(e,t){let n=this._templateFields,r={model:n.model,tools:n.tools.slice(),printer:!1};return n.systemPrompt!==void 0&&(r.systemPrompt=n.systemPrompt),n.name!==void 0&&(r.name=n.name),n.description!==void 0&&(r.description=n.description),n.id!==void 0&&(r.id=n.id),n.appState!==void 0&&(r.appState=n.appState),n.modelState!==void 0&&(r.modelState=n.modelState),n.traceAttributes!==void 0&&(r.traceAttributes=n.traceAttributes),n.structuredOutputSchema!==void 0&&(r.structuredOutputSchema=n.structuredOutputSchema),n.toolExecutor!==void 0&&(r.toolExecutor=n.toolExecutor),e&&(r.sessionManager=e),t&&t.length>0&&(r.messages=t),this._plugins.length>0&&(r.plugins=[...this._plugins]),r}},R=class{constructor(){this._tail=Promise.resolve()}async acquire(){let e,t=new Promise(t=>{e=t}),n=this._tail;return this._tail=t,await n,e}};function z(e){return{type:n.EventType.RUN_STARTED,threadId:e.threadId,runId:e.runId}}function B(e,t){return{type:n.EventType.RUN_ERROR,message:e,code:t}}function V(e){let t=e.resume;return Array.isArray(t)&&t.length>0?t:[]}function H(e){return e.status===`cancelled`?{status:`cancelled`}:e.payload}function U(e){let t=e.reason,n=typeof t==`string`&&t.length>0?t:`confirmation`,r={id:e.id,reason:n};if(typeof t==`string`&&t.length>0)r.message=t;else if(t!=null)try{r.message=JSON.stringify(t)}catch{}return r.metadata={strandsName:e.name},r}function W(e){if(e&&typeof e==`object`&&`type`in e){let t=e.type;return typeof t==`string`?t:void 0}}function G(e){if(!e||typeof e!=`object`)return e;let t=e.type;return t===`modelStreamUpdateEvent`&&`event`in e||t===`toolStreamUpdateEvent`&&`event`in e?e.event:t===`contentBlockEvent`&&`contentBlock`in e?e.contentBlock:e}async function*K(e){for await(let t of e)switch(t.type){case n.EventType.TEXT_MESSAGE_START:{let e=t;yield{type:n.EventType.TEXT_MESSAGE_CHUNK,messageId:e.messageId,role:e.role};break}case n.EventType.TEXT_MESSAGE_CONTENT:{let e=t;yield{type:n.EventType.TEXT_MESSAGE_CHUNK,messageId:e.messageId,delta:e.delta};break}case n.EventType.TEXT_MESSAGE_END:break;case n.EventType.TOOL_CALL_START:{let e=t;yield{type:n.EventType.TOOL_CALL_CHUNK,toolCallId:e.toolCallId,toolCallName:e.toolCallName,parentMessageId:e.parentMessageId};break}case n.EventType.TOOL_CALL_ARGS:{let e=t;yield{type:n.EventType.TOOL_CALL_CHUNK,toolCallId:e.toolCallId,delta:e.delta};break}case n.EventType.TOOL_CALL_END:break;case n.EventType.REASONING_MESSAGE_START:{let e=t;yield{type:n.EventType.REASONING_MESSAGE_CHUNK,messageId:e.messageId};break}case n.EventType.REASONING_MESSAGE_CONTENT:{let e=t;yield{type:n.EventType.REASONING_MESSAGE_CHUNK,messageId:e.messageId,delta:e.delta};break}case n.EventType.REASONING_MESSAGE_END:break;default:yield t}}async function q(e,t){if(e.length===0)return;let n=e.length;if(e[e.length-1]?.role===`user`&&(n=e.length-1),n<=0)return;let r=await J(e.slice(0,n),t);if(r.length!==0){for(;r.length>0&&r[0]?.role!==`user`;)r.shift();if(r.length!==0)return r}}async function J(e,n){let r=[],i=null,a=null,o=()=>{a&&a.length>0&&r.push({role:`user`,content:a}),a=null,i=null};for(let s of e){let e=s.role;if(e===`system`||e===`developer`)continue;if(e===`assistant`){o();let e=s.toolCalls,t=[];if(typeof s.content==`string`&&s.content.length>0)t.push({text:s.content});else if(Array.isArray(s.content))for(let e of s.content)e&&typeof e==`object`&&`text`in e&&t.push({text:e.text});if(e&&e.length>0){i=new Map;for(let r of e){if(!r?.id||!r.function?.name)continue;let e={};try{e=r.function.arguments?JSON.parse(r.function.arguments):{}}catch(t){n?.warn(`${D} seed tool args JSON parse failed for ${r.function.name}; using raw string`,t),e=r.function.arguments??{}}t.push({toolUse:{name:r.function.name,toolUseId:r.id,input:e}}),i.set(r.id,r.function.name)}}if(t.length===0)continue;r.push({role:`assistant`,content:t});continue}if(e===`tool`){let e=s.toolCallId;if(!e||!i||!i.has(e))continue;let t=s.content,n=typeof t==`string`?t:Array.isArray(t)?t.map(e=>e&&typeof e==`object`&&`text`in e?e.text??``:``).join(``):``;a??=[],a.push({toolResult:{toolUseId:e,status:`success`,content:[{text:n}]}});continue}o();let c=[],l=s.content;if(typeof l==`string`)l.length>0&&c.push({text:l});else if(Array.isArray(l))if(l.some(e=>{if(!e||typeof e!=`object`)return!1;let t=e.type;return t===`image`||t===`audio`||t===`video`||t===`document`}))try{let e=await T(l,n);for(let n of e)if(n instanceof t.TextBlock)c.push({text:n.text});else{let e=typeof n.toJSON==`function`?n.toJSON():n;c.push(e)}}catch(e){(n??u).warn(`${D} seed multimodal conversion failed; dropping attachments for this turn`,e);let t=E(l);t.length>0&&c.push({text:t})}else for(let e of l)e&&typeof e==`object`&&`text`in e&&c.push({text:e.text});c.length!==0&&r.push({role:`user`,content:c})}return o(),r}var Y=class extends r.HttpAgent{};exports.AWSStrandsAgent=Y,exports.StrandsAgent=L,exports.buildContextExtras=s,exports.buildSnapshotMessages=F,exports.buildStrandsSeed=q,exports.convertAguiContentToStrands=T,exports.convertMessagesForStrandsSeed=J,exports.createProxyTool=m,exports.flattenContentToText=E,exports.isProxyTool=h,exports.syncProxyTools=g;
|
|
2
|
+
//# sourceMappingURL=index.js.map
|