@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.
@@ -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":"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"}
@@ -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"}
@@ -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