@telemetry-dev/bedrock 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,1201 @@
1
+ import { startSpan } from "@telemetry-dev/sdk";
2
+ //#region src/internal.ts
3
+ const PROVIDER = "amazon-bedrock";
4
+ const STREAM_FINALIZER = typeof FinalizationRegistry === "function" ? new FinalizationRegistry((finish) => finish()) : void 0;
5
+ function createInstrumentedSend(originalSend, options, handlers) {
6
+ return function instrumentedSend(command, ...rest) {
7
+ const name = command?.constructor?.name;
8
+ const handler = typeof name === "string" ? handlers[name] : void 0;
9
+ if (!handler) return originalSend.apply(this, [command, ...rest]);
10
+ const input = commandInput(command);
11
+ const t0 = performance.now();
12
+ const spanType = safe(() => handler.spanType(input)) ?? "span";
13
+ const span = startSpan(safe(() => handler.spanName(input)) ?? name ?? "bedrock", {
14
+ type: spanType,
15
+ ...safe(() => handler.requestFields(input, options)) ?? {}
16
+ });
17
+ const callbackIndex = rest.findIndex((arg) => typeof arg === "function");
18
+ if (callbackIndex !== -1) {
19
+ const callback = rest[callbackIndex];
20
+ const wrappedRest = [...rest];
21
+ wrappedRest[callbackIndex] = (error, data) => {
22
+ if (error != null) {
23
+ endSpan(span, {
24
+ ...awsMetadataFields(metadataOf(error)),
25
+ error
26
+ });
27
+ callback(error, data);
28
+ return;
29
+ }
30
+ let nextData = data;
31
+ try {
32
+ nextData = handler.onResult(data, span, t0, input, options);
33
+ } catch {
34
+ endSpan(span, awsMetadataFields(metadataOf(data)));
35
+ }
36
+ callback(error, nextData);
37
+ };
38
+ try {
39
+ return originalSend.apply(this, [command, ...wrappedRest]);
40
+ } catch (error) {
41
+ endSpan(span, {
42
+ ...awsMetadataFields(metadataOf(error)),
43
+ error
44
+ });
45
+ throw error;
46
+ }
47
+ }
48
+ let result;
49
+ try {
50
+ result = originalSend.apply(this, [command, ...rest]);
51
+ } catch (error) {
52
+ endSpan(span, {
53
+ ...awsMetadataFields(metadataOf(error)),
54
+ error
55
+ });
56
+ throw error;
57
+ }
58
+ return Promise.resolve(result).then((resolved) => {
59
+ try {
60
+ return handler.onResult(resolved, span, t0, input, options);
61
+ } catch {
62
+ endSpan(span, awsMetadataFields(metadataOf(resolved)));
63
+ return resolved;
64
+ }
65
+ }, (error) => {
66
+ endSpan(span, {
67
+ ...awsMetadataFields(metadataOf(error)),
68
+ error
69
+ });
70
+ throw error;
71
+ });
72
+ };
73
+ }
74
+ function commandInput(command) {
75
+ const value = command?.input;
76
+ return isRecord(value) ? value : {};
77
+ }
78
+ function isRecord(value) {
79
+ return value !== null && typeof value === "object" && !Array.isArray(value);
80
+ }
81
+ function safe(fn) {
82
+ try {
83
+ return fn();
84
+ } catch {
85
+ return;
86
+ }
87
+ }
88
+ function endSpan(span, fields) {
89
+ try {
90
+ span.end(fields);
91
+ } catch {}
92
+ }
93
+ function updateSpan(span, fields) {
94
+ try {
95
+ span.update(fields);
96
+ } catch {}
97
+ }
98
+ function metadataOf(value) {
99
+ if (isRecord(value) && isRecord(value.$metadata)) return value.$metadata;
100
+ return value?.$metadata;
101
+ }
102
+ function modeledStreamError(event) {
103
+ for (const [key, name] of Object.entries({
104
+ accessDeniedException: "AccessDeniedException",
105
+ badGatewayException: "BadGatewayException",
106
+ conflictException: "ConflictException",
107
+ dependencyFailedException: "DependencyFailedException",
108
+ internalServerException: "InternalServerException",
109
+ modelNotReadyException: "ModelNotReadyException",
110
+ modelStreamErrorException: "ModelStreamErrorException",
111
+ modelTimeoutException: "ModelTimeoutException",
112
+ resourceNotFoundException: "ResourceNotFoundException",
113
+ serviceQuotaExceededException: "ServiceQuotaExceededException",
114
+ serviceUnavailableException: "ServiceUnavailableException",
115
+ throttlingException: "ThrottlingException",
116
+ validationException: "ValidationException"
117
+ })) {
118
+ const exception = isRecord(event[key]) ? event[key] : void 0;
119
+ if (!exception) continue;
120
+ const error = new Error(stringValue(exception.message) ?? stringValue(exception.originalMessage) ?? name);
121
+ error.name = stringValue(exception.name) ?? name;
122
+ return {
123
+ error,
124
+ fields: awsMetadataFields(exception.$metadata)
125
+ };
126
+ }
127
+ }
128
+ function awsMetadataFields(metadata) {
129
+ if (!isRecord(metadata)) return {};
130
+ const requestId = stringValue(metadata.requestId);
131
+ const attempts = numberValue(metadata.attempts);
132
+ const httpStatusCode = numberValue(metadata.httpStatusCode);
133
+ const totalRetryDelay = numberValue(metadata.totalRetryDelay);
134
+ const attributes = {};
135
+ if (httpStatusCode !== void 0) attributes["aws.http.status_code"] = httpStatusCode;
136
+ if (attempts !== void 0 && attempts > 1) attributes["aws.request.attempts"] = attempts;
137
+ if (totalRetryDelay !== void 0) attributes["aws.request.total_retry_delay_ms"] = totalRetryDelay;
138
+ return omitUndefined({
139
+ responseId: requestId,
140
+ attributes: Object.keys(attributes).length > 0 ? attributes : void 0
141
+ });
142
+ }
143
+ function mergeFields(...fields) {
144
+ const merged = {};
145
+ for (const field of fields) {
146
+ if (!field) continue;
147
+ const { metadata, attributes, usage, ...rest } = field;
148
+ Object.assign(merged, omitUndefined(rest));
149
+ if (usage) merged.usage = {
150
+ ...merged.usage,
151
+ ...usage
152
+ };
153
+ if (metadata) merged.metadata = {
154
+ ...merged.metadata,
155
+ ...metadata
156
+ };
157
+ if (attributes) merged.attributes = {
158
+ ...merged.attributes,
159
+ ...attributes
160
+ };
161
+ }
162
+ return merged;
163
+ }
164
+ function omitUndefined(value) {
165
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
166
+ }
167
+ function stringValue(value) {
168
+ return typeof value === "string" && value.length > 0 ? value : void 0;
169
+ }
170
+ function numberValue(value) {
171
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
172
+ }
173
+ function arrayValue(value) {
174
+ return Array.isArray(value) ? value : void 0;
175
+ }
176
+ function bytesToString(value) {
177
+ if (typeof value === "string") return value;
178
+ if (value instanceof Uint8Array) return new TextDecoder().decode(value);
179
+ if (ArrayBuffer.isView(value)) return new TextDecoder().decode(value);
180
+ }
181
+ function parseJson(value) {
182
+ const text = bytesToString(value);
183
+ if (text === void 0) return void 0;
184
+ try {
185
+ return JSON.parse(text);
186
+ } catch {
187
+ return;
188
+ }
189
+ }
190
+ function wrapAsyncIterable(iterable, state, span, t0, baseFields) {
191
+ if (!iterable || typeof iterable[Symbol.asyncIterator] !== "function") {
192
+ endSpan(span, baseFields);
193
+ return iterable;
194
+ }
195
+ let ended = false;
196
+ let first = false;
197
+ const unregisterToken = {};
198
+ const endOnce = (fields) => {
199
+ if (ended) return;
200
+ ended = true;
201
+ STREAM_FINALIZER?.unregister(unregisterToken);
202
+ endSpan(span, mergeFields(baseFields, fields));
203
+ };
204
+ const source = iterable;
205
+ const generator = async function* () {
206
+ let completed = false;
207
+ try {
208
+ for await (const event of source) {
209
+ if (!first) {
210
+ first = true;
211
+ updateSpan(span, { timeToFirstChunkMs: performance.now() - t0 });
212
+ }
213
+ safe(() => state.feed(event));
214
+ yield event;
215
+ }
216
+ completed = true;
217
+ } catch (error) {
218
+ endOnce(mergeFields(state.finish(true), awsMetadataFields(metadataOf(error)), { error }));
219
+ throw error;
220
+ } finally {
221
+ if (!ended) endOnce(state.finish(!completed));
222
+ }
223
+ };
224
+ const wrapped = {};
225
+ if (isRecord(iterable)) for (const key of Reflect.ownKeys(iterable)) wrapped[key] = iterable[key];
226
+ const finishAbandoned = () => endOnce(safe(() => state.finish(true)));
227
+ wrapped[Symbol.asyncIterator] = () => {
228
+ const iterator = generator();
229
+ STREAM_FINALIZER?.register(iterator, finishAbandoned, unregisterToken);
230
+ return iterator;
231
+ };
232
+ STREAM_FINALIZER?.register(wrapped, finishAbandoned, unregisterToken);
233
+ return wrapped;
234
+ }
235
+ function basenameArn(value) {
236
+ const text = stringValue(value);
237
+ if (!text) return void 0;
238
+ return text.split(/[/:]/).filter(Boolean).at(-1) ?? text;
239
+ }
240
+ //#endregion
241
+ //#region src/agent-handlers.ts
242
+ function agentInputMessages(inputText) {
243
+ const text = stringValue(inputText);
244
+ return text ? [{
245
+ role: "user",
246
+ parts: [{
247
+ type: "text",
248
+ content: text
249
+ }]
250
+ }] : void 0;
251
+ }
252
+ function agentRequestFields(input) {
253
+ return omitUndefined({
254
+ provider: PROVIDER,
255
+ input: agentInputMessages(input.inputText),
256
+ agentId: stringValue(input.agentId),
257
+ metadata: omitUndefined({
258
+ bedrock_agent_alias_id: stringValue(input.agentAliasId),
259
+ bedrock_session_id: stringValue(input.sessionId),
260
+ bedrock_memory_id: stringValue(input.memoryId)
261
+ })
262
+ });
263
+ }
264
+ function inlineAgentRequestFields(input) {
265
+ return omitUndefined({
266
+ input: agentInputMessages(input.inputText),
267
+ model: stringValue(input.foundationModel),
268
+ provider: PROVIDER,
269
+ agentName: stringValue(input.agentName),
270
+ metadata: omitUndefined({ bedrock_session_id: stringValue(input.sessionId) })
271
+ });
272
+ }
273
+ var AgentStreamState = class {
274
+ text = "";
275
+ usage = {};
276
+ traceEventCount = 0;
277
+ failureReason;
278
+ guardrailAction;
279
+ returnControl;
280
+ traces = [];
281
+ error;
282
+ errorFields;
283
+ citationCount = 0;
284
+ outputFiles = [];
285
+ constructor(options) {
286
+ this.options = options;
287
+ }
288
+ feed(event) {
289
+ if (!isRecord(event)) return;
290
+ const streamError = modeledStreamError(event);
291
+ if (streamError) {
292
+ this.error = streamError.error;
293
+ this.errorFields = streamError.fields;
294
+ return;
295
+ }
296
+ const chunk = isRecord(event.chunk) ? event.chunk : void 0;
297
+ const bytes = chunk?.bytes;
298
+ if (bytes !== void 0) this.text += bytesToString(bytes) ?? "";
299
+ const citations = arrayValue((isRecord(chunk?.attribution) ? chunk.attribution : void 0)?.citations);
300
+ if (citations) this.citationCount += citations.length;
301
+ const files = isRecord(event.files) ? arrayValue(event.files.files) : void 0;
302
+ if (files) this.outputFiles.push(...files.map(sanitizeOutputFile));
303
+ const returnControl = isRecord(event.returnControl) ? event.returnControl : void 0;
304
+ if (returnControl) this.returnControl = returnControl;
305
+ const traceEvent = isRecord(event.trace) ? event.trace : void 0;
306
+ if (traceEvent) {
307
+ this.traceEventCount += 1;
308
+ if (this.options.captureAgentTrace) this.traces.push(traceEvent);
309
+ collectTrace(traceEvent, (usage) => this.addUsage(usage));
310
+ const failure = findKey(traceEvent, "failureTrace");
311
+ if (isRecord(failure)) this.failureReason = stringValue(failure.failureReason) ?? this.failureReason;
312
+ const guardrail = findKey(traceEvent, "guardrailTrace");
313
+ if (isRecord(guardrail)) this.guardrailAction = stringValue(guardrail.action) ?? this.guardrailAction;
314
+ }
315
+ }
316
+ finish() {
317
+ const metadata = omitUndefined({
318
+ trace_event_count: this.traceEventCount || void 0,
319
+ failure_reason: this.failureReason,
320
+ guardrail_action: this.guardrailAction,
321
+ return_control: this.returnControl ? true : void 0,
322
+ citation_count: this.citationCount || void 0,
323
+ output_files: this.outputFiles.length > 0 ? this.outputFiles : void 0,
324
+ agent_trace: this.options.captureAgentTrace && this.traces.length > 0 ? this.traces : void 0
325
+ });
326
+ return mergeFields(omitUndefined({
327
+ output: this.returnControl ? { returnControl: this.returnControl } : this.text ? [{
328
+ role: "assistant",
329
+ parts: [{
330
+ type: "text",
331
+ content: this.text
332
+ }]
333
+ }] : void 0,
334
+ usage: Object.keys(this.usage).length > 0 ? this.usage : void 0,
335
+ metadata,
336
+ error: this.error
337
+ }), this.errorFields);
338
+ }
339
+ addUsage(value) {
340
+ if (!isRecord(value)) return;
341
+ const inputTokens = numberValue(value.inputTokens);
342
+ const outputTokens = numberValue(value.outputTokens);
343
+ const totalTokens = numberValue(value.totalTokens);
344
+ if (inputTokens !== void 0) this.usage.inputTokens = (this.usage.inputTokens ?? 0) + inputTokens;
345
+ if (outputTokens !== void 0) this.usage.outputTokens = (this.usage.outputTokens ?? 0) + outputTokens;
346
+ if (totalTokens !== void 0) this.usage.totalTokens = (this.usage.totalTokens ?? 0) + totalTokens;
347
+ else if (inputTokens !== void 0 || outputTokens !== void 0) this.usage.totalTokens = (this.usage.inputTokens ?? 0) + (this.usage.outputTokens ?? 0);
348
+ }
349
+ };
350
+ function sanitizeOutputFile(value) {
351
+ if (!isRecord(value)) return value;
352
+ return omitUndefined({
353
+ name: stringValue(value.name),
354
+ type: stringValue(value.type)
355
+ });
356
+ }
357
+ function retrieveRequestFields(input) {
358
+ return omitUndefined({
359
+ provider: PROVIDER,
360
+ input: isRecord(input.retrievalQuery) ? input.retrievalQuery : void 0,
361
+ metadata: { knowledge_base_id: stringValue(input.knowledgeBaseId) }
362
+ });
363
+ }
364
+ function retrieveResponseFields(output) {
365
+ const result = isRecord(output) ? output : {};
366
+ const retrievalResults = arrayValue(result.retrievalResults);
367
+ return mergeFields(awsMetadataFields(result.$metadata), {
368
+ output: retrievalResults,
369
+ metadata: omitUndefined({
370
+ citation_count: retrievalResults?.length,
371
+ guardrail_action: stringValue(result.guardrailAction)
372
+ })
373
+ });
374
+ }
375
+ function ragModel(input) {
376
+ const config = isRecord(input.retrieveAndGenerateConfiguration) ? input.retrieveAndGenerateConfiguration : void 0;
377
+ const kb = isRecord(config?.knowledgeBaseConfiguration) ? config?.knowledgeBaseConfiguration : void 0;
378
+ const external = isRecord(config?.externalSourcesConfiguration) ? config?.externalSourcesConfiguration : void 0;
379
+ return stringValue(kb?.modelArn) ?? stringValue(external?.modelArn);
380
+ }
381
+ function ragRequestFields(input) {
382
+ const text = isRecord(input.input) ? stringValue(input.input.text) : void 0;
383
+ return omitUndefined({
384
+ provider: PROVIDER,
385
+ model: ragModel(input),
386
+ input: text ? [{
387
+ role: "user",
388
+ parts: [{
389
+ type: "text",
390
+ content: text
391
+ }]
392
+ }] : void 0,
393
+ metadata: omitUndefined({ bedrock_session_id: stringValue(input.sessionId) })
394
+ });
395
+ }
396
+ function ragResponseFields(output) {
397
+ const result = isRecord(output) ? output : {};
398
+ const text = isRecord(result.output) ? stringValue(result.output.text) : void 0;
399
+ return mergeFields(awsMetadataFields(result.$metadata), {
400
+ output: text ? [{
401
+ role: "assistant",
402
+ parts: [{
403
+ type: "text",
404
+ content: text
405
+ }]
406
+ }] : void 0,
407
+ metadata: omitUndefined({
408
+ citation_count: arrayValue(result.citations)?.length,
409
+ guardrail_action: stringValue(result.guardrailAction),
410
+ bedrock_session_id: stringValue(result.sessionId)
411
+ })
412
+ });
413
+ }
414
+ var RagStreamState = class {
415
+ text = "";
416
+ citationCount = 0;
417
+ guardrailAction;
418
+ error;
419
+ errorFields;
420
+ feed(event) {
421
+ if (!isRecord(event)) return;
422
+ const streamError = modeledStreamError(event);
423
+ if (streamError) {
424
+ this.error = streamError.error;
425
+ this.errorFields = streamError.fields;
426
+ return;
427
+ }
428
+ const output = isRecord(event.output) ? event.output : void 0;
429
+ this.text += stringValue(output?.text) ?? "";
430
+ if (event.citation) this.citationCount += 1;
431
+ const guardrail = isRecord(event.guardrail) ? event.guardrail : void 0;
432
+ this.guardrailAction = stringValue(guardrail?.action) ?? this.guardrailAction;
433
+ }
434
+ finish() {
435
+ return mergeFields(omitUndefined({
436
+ output: this.text ? [{
437
+ role: "assistant",
438
+ parts: [{
439
+ type: "text",
440
+ content: this.text
441
+ }]
442
+ }] : void 0,
443
+ metadata: omitUndefined({
444
+ citation_count: this.citationCount || void 0,
445
+ guardrail_action: this.guardrailAction
446
+ }),
447
+ error: this.error
448
+ }), this.errorFields);
449
+ }
450
+ };
451
+ function flowRequestFields(input) {
452
+ return omitUndefined({
453
+ provider: PROVIDER,
454
+ input: input.inputs,
455
+ agentId: stringValue(input.flowIdentifier)
456
+ });
457
+ }
458
+ var FlowStreamState = class {
459
+ outputs = [];
460
+ completionReason;
461
+ error;
462
+ errorFields;
463
+ feed(event) {
464
+ if (!isRecord(event)) return;
465
+ const streamError = modeledStreamError(event);
466
+ if (streamError) {
467
+ this.error = streamError.error;
468
+ this.errorFields = streamError.fields;
469
+ return;
470
+ }
471
+ const output = isRecord(event.flowOutputEvent) ? event.flowOutputEvent : void 0;
472
+ if (output) this.outputs.push(output.content);
473
+ const inputRequest = isRecord(event.flowMultiTurnInputRequestEvent) ? event.flowMultiTurnInputRequestEvent : void 0;
474
+ if (inputRequest) this.outputs.push(inputRequest.content);
475
+ const completion = isRecord(event.flowCompletionEvent) ? event.flowCompletionEvent : void 0;
476
+ this.completionReason = stringValue(completion?.completionReason) ?? this.completionReason;
477
+ }
478
+ finish() {
479
+ return mergeFields(omitUndefined({
480
+ output: this.outputs.length > 0 ? this.outputs : void 0,
481
+ finishReason: this.completionReason,
482
+ error: this.error
483
+ }), this.errorFields);
484
+ }
485
+ };
486
+ function flowName(input) {
487
+ return `invoke_flow ${stringValue(input.flowIdentifier) ?? "unknown"}`;
488
+ }
489
+ function ragName(input) {
490
+ return `retrieve_and_generate ${basenameArn(ragModel(input)) ?? "knowledge-base"}`;
491
+ }
492
+ function collectTrace(value, onUsage) {
493
+ if (!isRecord(value)) return;
494
+ const output = isRecord(value.modelInvocationOutput) ? value.modelInvocationOutput : void 0;
495
+ if (output) onUsage((isRecord(output.metadata) ? output.metadata : void 0)?.usage);
496
+ for (const child of Object.values(value)) if (isRecord(child)) collectTrace(child, onUsage);
497
+ else if (Array.isArray(child)) child.forEach((item) => collectTrace(item, onUsage));
498
+ }
499
+ function findKey(value, key) {
500
+ if (!isRecord(value)) return void 0;
501
+ if (value[key] !== void 0) return value[key];
502
+ for (const child of Object.values(value)) {
503
+ const found = findKey(child, key);
504
+ if (found !== void 0) return found;
505
+ }
506
+ }
507
+ //#endregion
508
+ //#region src/converse.ts
509
+ function converseRequestFields(input) {
510
+ const inference = isRecord(input.inferenceConfig) ? input.inferenceConfig : {};
511
+ const guardrail = isRecord(input.guardrailConfig) ? input.guardrailConfig : void 0;
512
+ return omitUndefined({
513
+ provider: PROVIDER,
514
+ model: stringValue(input.modelId),
515
+ input: normalizeMessages(input.messages),
516
+ systemInstructions: normalizeSystem(input.system),
517
+ temperature: numberValue(inference.temperature),
518
+ topP: numberValue(inference.topP),
519
+ maxTokens: numberValue(inference.maxTokens),
520
+ stopSequences: arrayValue(inference.stopSequences),
521
+ metadata: guardrail ? omitUndefined({
522
+ guardrail_id: stringValue(guardrail.guardrailIdentifier),
523
+ guardrail_version: stringValue(guardrail.guardrailVersion)
524
+ }) : void 0
525
+ });
526
+ }
527
+ function converseResponseFields(output) {
528
+ const result = isRecord(output) ? output : {};
529
+ const usage = usageFromConverse(result.usage);
530
+ const metrics = isRecord(result.metrics) ? result.metrics : void 0;
531
+ const trace = isRecord(result.trace) ? result.trace : void 0;
532
+ const promptRouter = isRecord(trace?.promptRouter) ? trace?.promptRouter : void 0;
533
+ const guardrail = isRecord(trace?.guardrail) ? trace?.guardrail : void 0;
534
+ const stopReason = stringValue(result.stopReason);
535
+ const message = isRecord(result.output) ? result.output.message : void 0;
536
+ return mergeFields(awsMetadataFields(result.$metadata), {
537
+ output: normalizeOutputMessage(message, stopReason),
538
+ usage,
539
+ finishReason: stopReason,
540
+ responseModel: stringValue(promptRouter?.invokedModelId),
541
+ metadata: omitUndefined({
542
+ server_latency_ms: numberValue(metrics?.latencyMs),
543
+ guardrail_action: stringValue(result.guardrailAction) ?? stringValue(guardrail?.action),
544
+ guardrail_action_reason: stringValue(guardrail?.actionReason)
545
+ })
546
+ });
547
+ }
548
+ function usageFromConverse(value) {
549
+ if (!isRecord(value)) return void 0;
550
+ return omitUndefined({
551
+ inputTokens: numberValue(value.inputTokens),
552
+ outputTokens: numberValue(value.outputTokens),
553
+ totalTokens: numberValue(value.totalTokens),
554
+ cacheReadInputTokens: numberValue(value.cacheReadInputTokens),
555
+ cacheCreationInputTokens: numberValue(value.cacheWriteInputTokens)
556
+ });
557
+ }
558
+ function normalizeMessages(value) {
559
+ const messages = arrayValue(value);
560
+ if (!messages) return void 0;
561
+ return messages.map((message) => ({
562
+ role: stringValue(message.role),
563
+ parts: normalizeContentList(message.content)
564
+ }));
565
+ }
566
+ function normalizeOutputMessage(value, finishReason) {
567
+ if (!isRecord(value)) return void 0;
568
+ return [omitUndefined({
569
+ role: stringValue(value.role),
570
+ parts: normalizeContentList(value.content),
571
+ finish_reason: finishReason
572
+ })];
573
+ }
574
+ function normalizeSystem(value) {
575
+ const blocks = arrayValue(value);
576
+ if (!blocks) return void 0;
577
+ const parts = blocks.flatMap((block) => normalizeContentBlock(block));
578
+ return parts.length > 0 ? parts : void 0;
579
+ }
580
+ function normalizeContentList(value) {
581
+ const blocks = arrayValue(value);
582
+ if (!blocks) return [];
583
+ return blocks.flatMap((block) => normalizeContentBlock(block));
584
+ }
585
+ function normalizeContentBlock(block) {
586
+ const text = stringValue(block.text);
587
+ if (text !== void 0) return [omitUndefined({
588
+ type: "text",
589
+ content: text,
590
+ citations: arrayValue(block.citations)
591
+ })];
592
+ const toolUse = isRecord(block.toolUse) ? block.toolUse : void 0;
593
+ if (toolUse) return [omitUndefined({
594
+ type: "tool_call",
595
+ id: stringValue(toolUse.toolUseId),
596
+ name: stringValue(toolUse.name),
597
+ arguments: toolUse.input
598
+ })];
599
+ const toolResult = isRecord(block.toolResult) ? block.toolResult : void 0;
600
+ if (toolResult) return [omitUndefined({
601
+ type: "tool_call_response",
602
+ id: stringValue(toolResult.toolUseId),
603
+ response: simplifyToolResult(toolResult.content)
604
+ })];
605
+ const reasoning = isRecord(block.reasoningContent) ? block.reasoningContent : void 0;
606
+ if (reasoning) return [{
607
+ type: "reasoning",
608
+ content: stringValue((isRecord(reasoning.reasoningText) ? reasoning.reasoningText : void 0)?.text) ?? (reasoning.redactedContent ? "[redacted]" : "")
609
+ }];
610
+ for (const modality of [
611
+ "image",
612
+ "document",
613
+ "video",
614
+ "audio"
615
+ ]) {
616
+ const media = isRecord(block[modality]) ? block[modality] : void 0;
617
+ if (!media) continue;
618
+ const format = stringValue(media.format);
619
+ const source = isRecord(media.source) ? media.source : void 0;
620
+ if (source?.bytes !== void 0) return [omitUndefined({
621
+ type: "blob",
622
+ modality,
623
+ mime_type: format ? `${modality}/${format}` : void 0
624
+ })];
625
+ const s3 = isRecord(source?.s3Location) ? source?.s3Location : void 0;
626
+ const uri = stringValue(source?.uri) ?? stringValue(s3?.uri) ?? s3Uri(s3);
627
+ if (uri) return [omitUndefined({
628
+ type: "uri",
629
+ uri,
630
+ modality,
631
+ mime_type: format
632
+ })];
633
+ }
634
+ const citationsContent = isRecord(block.citationsContent) ? block.citationsContent : void 0;
635
+ if (citationsContent) {
636
+ const contentBlocks = arrayValue(citationsContent.content) ?? [];
637
+ const citations = arrayValue(citationsContent.citations);
638
+ return contentBlocks.flatMap((contentBlock) => normalizeContentBlock(citations ? {
639
+ ...contentBlock,
640
+ citations
641
+ } : contentBlock));
642
+ }
643
+ const guardContent = isRecord(block.guardContent) ? block.guardContent : void 0;
644
+ if (guardContent) {
645
+ const content = stringValue((isRecord(guardContent.text) ? guardContent.text : void 0)?.text) ?? stringValue(guardContent.text);
646
+ if (content) return [{
647
+ type: "text",
648
+ content
649
+ }];
650
+ }
651
+ try {
652
+ return [{
653
+ type: "text",
654
+ content: JSON.stringify(block)
655
+ }];
656
+ } catch {
657
+ return [{
658
+ type: "text",
659
+ content: "[unsupported content block]"
660
+ }];
661
+ }
662
+ }
663
+ function simplifyToolResult(content) {
664
+ const blocks = arrayValue(content);
665
+ if (!blocks) return content;
666
+ if (blocks.length === 1 && typeof blocks[0]?.text === "string") return blocks[0].text;
667
+ return blocks.flatMap((block) => normalizeContentBlock(block));
668
+ }
669
+ function s3Uri(value) {
670
+ const bucket = stringValue(value?.bucket);
671
+ const key = stringValue(value?.key);
672
+ return bucket && key ? `s3://${bucket}/${key}` : void 0;
673
+ }
674
+ var ConverseStreamState = class {
675
+ role = "assistant";
676
+ blocks = /* @__PURE__ */ new Map();
677
+ stopReason;
678
+ usage;
679
+ metadata = {};
680
+ responseModel;
681
+ error;
682
+ errorFields;
683
+ feed(event) {
684
+ if (!isRecord(event)) return;
685
+ const streamError = modeledStreamError(event);
686
+ if (streamError) {
687
+ this.error = streamError.error;
688
+ this.errorFields = streamError.fields;
689
+ return;
690
+ }
691
+ const messageStart = isRecord(event.messageStart) ? event.messageStart : void 0;
692
+ if (messageStart) this.role = stringValue(messageStart.role) ?? this.role;
693
+ const blockStart = isRecord(event.contentBlockStart) ? event.contentBlockStart : void 0;
694
+ if (blockStart) {
695
+ const index = numberValue(blockStart.contentBlockIndex) ?? this.blocks.size;
696
+ const start = isRecord(blockStart.start) ? blockStart.start : void 0;
697
+ const toolUse = isRecord(start?.toolUse) ? start?.toolUse : void 0;
698
+ const toolResult = isRecord(start?.toolResult) ? start?.toolResult : void 0;
699
+ const image = isRecord(start?.image) ? start?.image : void 0;
700
+ this.blocks.set(index, toolUse ? {
701
+ kind: "tool",
702
+ toolUseId: stringValue(toolUse.toolUseId),
703
+ name: stringValue(toolUse.name),
704
+ input: ""
705
+ } : toolResult ? {
706
+ kind: "content",
707
+ content: { toolResult: omitUndefined({
708
+ toolUseId: stringValue(toolResult.toolUseId),
709
+ status: stringValue(toolResult.status),
710
+ content: []
711
+ }) }
712
+ } : image ? {
713
+ kind: "content",
714
+ content: { image }
715
+ } : {
716
+ kind: "text",
717
+ text: ""
718
+ });
719
+ }
720
+ const deltaEvent = isRecord(event.contentBlockDelta) ? event.contentBlockDelta : void 0;
721
+ if (deltaEvent) {
722
+ const index = numberValue(deltaEvent.contentBlockIndex) ?? 0;
723
+ const delta = isRecord(deltaEvent.delta) ? deltaEvent.delta : {};
724
+ const block = this.blocks.get(index) ?? {
725
+ kind: "text",
726
+ text: ""
727
+ };
728
+ if (typeof delta.text === "string") {
729
+ block.kind = "text";
730
+ block.text = `${block.text ?? ""}${delta.text}`;
731
+ }
732
+ const toolUse = isRecord(delta.toolUse) ? delta.toolUse : void 0;
733
+ if (toolUse && typeof toolUse.input === "string") {
734
+ block.kind = "tool";
735
+ block.input = `${block.input ?? ""}${toolUse.input}`;
736
+ }
737
+ const reasoning = isRecord(delta.reasoningContent) ? delta.reasoningContent : void 0;
738
+ if (reasoning) {
739
+ block.kind = "reasoning";
740
+ block.text = `${block.text ?? ""}${stringValue(reasoning.text) ?? (reasoning.redactedContent ? "[redacted]" : "")}`;
741
+ }
742
+ const image = isRecord(delta.image) ? delta.image : void 0;
743
+ if (image) {
744
+ const content = isRecord(block.content) ? block.content : {};
745
+ const current = isRecord(content.image) ? content.image : {};
746
+ block.kind = "content";
747
+ block.content = { image: {
748
+ ...current,
749
+ ...image
750
+ } };
751
+ }
752
+ const toolResult = arrayValue(delta.toolResult);
753
+ if (toolResult) {
754
+ const content = isRecord(block.content) ? block.content : {};
755
+ const current = isRecord(content.toolResult) ? content.toolResult : {};
756
+ const currentContent = arrayValue(current.content) ?? [];
757
+ block.kind = "content";
758
+ block.content = { toolResult: {
759
+ ...current,
760
+ content: [...currentContent, ...toolResult]
761
+ } };
762
+ }
763
+ if (isRecord(delta.citation)) block.citations = [...block.citations ?? [], delta.citation];
764
+ this.blocks.set(index, block);
765
+ }
766
+ const stop = isRecord(event.messageStop) ? event.messageStop : void 0;
767
+ if (stop) this.stopReason = stringValue(stop.stopReason) ?? this.stopReason;
768
+ const metadata = isRecord(event.metadata) ? event.metadata : void 0;
769
+ if (metadata) {
770
+ this.usage = usageFromConverse(metadata.usage) ?? this.usage;
771
+ const metrics = isRecord(metadata.metrics) ? metadata.metrics : void 0;
772
+ const trace = isRecord(metadata.trace) ? metadata.trace : void 0;
773
+ const promptRouter = isRecord(trace?.promptRouter) ? trace?.promptRouter : void 0;
774
+ const guardrail = isRecord(trace?.guardrail) ? trace?.guardrail : void 0;
775
+ this.responseModel = stringValue(promptRouter?.invokedModelId) ?? this.responseModel;
776
+ this.metadata = {
777
+ ...this.metadata,
778
+ ...omitUndefined({
779
+ server_latency_ms: numberValue(metrics?.latencyMs),
780
+ guardrail_action: stringValue(guardrail?.action),
781
+ guardrail_action_reason: stringValue(guardrail?.actionReason)
782
+ })
783
+ };
784
+ }
785
+ }
786
+ finish(partial) {
787
+ const parts = [...this.blocks.entries()].sort(([left], [right]) => left - right).map(([, block]) => blockToPart(block));
788
+ return mergeFields(omitUndefined({
789
+ output: parts.length > 0 ? [omitUndefined({
790
+ role: this.role,
791
+ parts,
792
+ finish_reason: partial ? void 0 : this.stopReason
793
+ })] : void 0,
794
+ finishReason: partial ? void 0 : this.stopReason,
795
+ usage: this.usage,
796
+ responseModel: this.responseModel,
797
+ metadata: Object.keys(this.metadata).length > 0 ? this.metadata : void 0,
798
+ error: this.error
799
+ }), this.errorFields);
800
+ }
801
+ };
802
+ function blockToPart(block) {
803
+ if (block.kind === "tool") return omitUndefined({
804
+ type: "tool_call",
805
+ id: block.toolUseId,
806
+ name: block.name,
807
+ arguments: parseJson(block.input) ?? block.input ?? ""
808
+ });
809
+ if (block.kind === "reasoning") return {
810
+ type: "reasoning",
811
+ content: block.text ?? ""
812
+ };
813
+ if (block.kind === "content" && block.content) return normalizeContentBlock(block.content)[0] ?? {};
814
+ return omitUndefined({
815
+ type: "text",
816
+ content: block.text ?? "",
817
+ citations: block.citations && block.citations.length > 0 ? block.citations : void 0
818
+ });
819
+ }
820
+ //#endregion
821
+ //#region src/invoke-model.ts
822
+ function isEmbeddingModel(modelId) {
823
+ const model = stringValue(modelId)?.toLowerCase() ?? "";
824
+ return model.includes("titan-embed") || model.includes("cohere.embed") || model.includes("-embedding");
825
+ }
826
+ function invokeModelSpanName(input) {
827
+ const model = stringValue(input.modelId) ?? "unknown";
828
+ return `${isEmbeddingModel(model) ? "embeddings" : "chat"} ${model}`;
829
+ }
830
+ function invokeModelRequestFields(input) {
831
+ const model = stringValue(input.modelId);
832
+ const body = parseBody(input.body, input.contentType);
833
+ return omitUndefined({
834
+ provider: PROVIDER,
835
+ model,
836
+ input: body,
837
+ outputType: isEmbeddingModel(model) ? "embedding" : void 0,
838
+ ...nativeSamplingFields(model, body)
839
+ });
840
+ }
841
+ function invokeModelResponseFields(input, output) {
842
+ const model = stringValue(input.modelId);
843
+ const body = isRecord(output) ? parseBody(output.body, output.contentType) : void 0;
844
+ const metadata = isRecord(output) ? output.$metadata : void 0;
845
+ return mergeFields(awsMetadataFields(metadata), nativeResponseFields(model, body, metadata));
846
+ }
847
+ function parseBody(body, contentType) {
848
+ if (!(stringValue(contentType) ?? "application/json").includes("json")) return void 0;
849
+ return parseJson(body);
850
+ }
851
+ function nativeSamplingFields(model, body) {
852
+ if (!isRecord(body)) return {};
853
+ const lower = model?.toLowerCase() ?? "";
854
+ if (lower.includes("amazon.titan")) {
855
+ const cfg = isRecord(body.textGenerationConfig) ? body.textGenerationConfig : {};
856
+ return omitUndefined({
857
+ temperature: numberValue(cfg.temperature),
858
+ topP: numberValue(cfg.topP),
859
+ maxTokens: numberValue(cfg.maxTokenCount),
860
+ stopSequences: Array.isArray(cfg.stopSequences) ? cfg.stopSequences : void 0
861
+ });
862
+ }
863
+ if (lower.includes("amazon.nova")) {
864
+ const cfg = isRecord(body.inferenceConfig) ? body.inferenceConfig : {};
865
+ return omitUndefined({
866
+ temperature: numberValue(cfg.temperature),
867
+ topP: numberValue(cfg.topP) ?? numberValue(cfg.top_p),
868
+ topK: numberValue(cfg.topK),
869
+ maxTokens: numberValue(cfg.maxTokens) ?? numberValue(cfg.max_new_tokens),
870
+ stopSequences: Array.isArray(cfg.stopSequences) ? cfg.stopSequences : void 0
871
+ });
872
+ }
873
+ if (lower.includes("anthropic.claude")) return omitUndefined({
874
+ temperature: numberValue(body.temperature),
875
+ topP: numberValue(body.top_p),
876
+ topK: numberValue(body.top_k),
877
+ maxTokens: numberValue(body.max_tokens),
878
+ stopSequences: Array.isArray(body.stop_sequences) ? body.stop_sequences : void 0
879
+ });
880
+ if (lower.includes("meta.llama")) return omitUndefined({
881
+ temperature: numberValue(body.temperature),
882
+ topP: numberValue(body.top_p),
883
+ maxTokens: numberValue(body.max_gen_len)
884
+ });
885
+ return omitUndefined({
886
+ temperature: numberValue(body.temperature),
887
+ topP: numberValue(body.top_p) ?? numberValue(body.topP),
888
+ maxTokens: numberValue(body.max_tokens) ?? numberValue(body.maxTokens)
889
+ });
890
+ }
891
+ function nativeResponseFields(model, body, metadata) {
892
+ if (!isRecord(body)) return headerUsageFields(metadata);
893
+ const lower = model?.toLowerCase() ?? "";
894
+ if (isEmbeddingModel(model)) return withHeaderUsage({
895
+ output: body,
896
+ outputType: "embedding",
897
+ usage: omitUndefined({ inputTokens: numberValue(body.inputTextTokenCount) })
898
+ }, metadata);
899
+ if (lower.includes("amazon.titan")) {
900
+ const first = Array.isArray(body.results) && isRecord(body.results[0]) ? body.results[0] : {};
901
+ return omitUndefined({
902
+ output: body,
903
+ finishReason: stringValue(first.completionReason),
904
+ usage: omitUndefined({
905
+ inputTokens: numberValue(body.inputTextTokenCount),
906
+ outputTokens: numberValue(first.tokenCount)
907
+ })
908
+ });
909
+ }
910
+ if (lower.includes("amazon.nova")) {
911
+ const usage = isRecord(body.usage) ? body.usage : {};
912
+ return omitUndefined({
913
+ output: body,
914
+ finishReason: stringValue(body.stopReason),
915
+ usage: omitUndefined({
916
+ inputTokens: numberValue(usage.inputTokens),
917
+ outputTokens: numberValue(usage.outputTokens),
918
+ totalTokens: numberValue(usage.totalTokens)
919
+ })
920
+ });
921
+ }
922
+ if (lower.includes("anthropic.claude")) {
923
+ const usage = isRecord(body.usage) ? body.usage : {};
924
+ return withHeaderUsage({
925
+ output: body,
926
+ finishReason: stringValue(body.stop_reason),
927
+ usage: omitUndefined({
928
+ inputTokens: numberValue(usage.input_tokens),
929
+ outputTokens: numberValue(usage.output_tokens),
930
+ cacheReadInputTokens: numberValue(usage.cache_read_input_tokens),
931
+ cacheCreationInputTokens: numberValue(usage.cache_creation_input_tokens)
932
+ })
933
+ }, metadata);
934
+ }
935
+ if (lower.includes("meta.llama")) return omitUndefined({
936
+ output: body,
937
+ finishReason: stringValue(body.stop_reason),
938
+ usage: omitUndefined({
939
+ inputTokens: numberValue(body.prompt_token_count),
940
+ outputTokens: numberValue(body.generation_token_count)
941
+ })
942
+ });
943
+ if (lower.includes("mistral")) return withHeaderUsage({
944
+ output: body,
945
+ finishReason: stringValue((Array.isArray(body.outputs) && isRecord(body.outputs[0]) ? body.outputs[0] : {}).stop_reason)
946
+ }, metadata);
947
+ if (lower.includes("cohere.command-r")) return withHeaderUsage({
948
+ output: body,
949
+ finishReason: stringValue(body.finish_reason)
950
+ }, metadata);
951
+ if (lower.includes("cohere.command")) return withHeaderUsage({
952
+ output: body,
953
+ finishReason: stringValue((Array.isArray(body.generations) && isRecord(body.generations[0]) ? body.generations[0] : {}).finish_reason)
954
+ }, metadata);
955
+ return withHeaderUsage({ output: body }, metadata);
956
+ }
957
+ function withHeaderUsage(fields, metadata) {
958
+ if (fields.usage && Object.keys(fields.usage).length > 0) return fields;
959
+ return mergeFields(fields, headerUsageFields(metadata));
960
+ }
961
+ function headerUsageFields(metadata) {
962
+ const headers = isRecord(metadata) ? isRecord(metadata.httpHeaders) ? metadata.httpHeaders : isRecord(metadata.HTTPHeaders) ? metadata.HTTPHeaders : void 0 : void 0;
963
+ const usage = omitUndefined({
964
+ inputTokens: headerNumber(headers?.["x-amzn-bedrock-input-token-count"]),
965
+ outputTokens: headerNumber(headers?.["x-amzn-bedrock-output-token-count"])
966
+ });
967
+ return { usage: Object.keys(usage).length > 0 ? usage : void 0 };
968
+ }
969
+ function headerNumber(value) {
970
+ if (typeof value === "string") {
971
+ const parsed = Number.parseInt(value, 10);
972
+ return Number.isFinite(parsed) ? parsed : void 0;
973
+ }
974
+ return numberValue(value);
975
+ }
976
+ var InvokeModelStreamState = class {
977
+ chunks = [];
978
+ text = "";
979
+ usage;
980
+ finishReason;
981
+ error;
982
+ errorFields;
983
+ feed(event) {
984
+ if (!isRecord(event)) return;
985
+ const streamError = modeledStreamError(event);
986
+ if (streamError) {
987
+ this.error = streamError.error;
988
+ this.errorFields = streamError.fields;
989
+ return;
990
+ }
991
+ const parsed = parseJson((isRecord(event.chunk) ? event.chunk : void 0)?.bytes);
992
+ if (parsed === void 0) return;
993
+ this.chunks.push(parsed);
994
+ this.text += textFromProviderChunk(parsed);
995
+ if (isRecord(parsed)) {
996
+ const delta = isRecord(parsed.delta) ? parsed.delta : void 0;
997
+ const message = isRecord(parsed.message) ? parsed.message : void 0;
998
+ const messageUsage = isRecord(message?.usage) ? message?.usage : void 0;
999
+ const usage = isRecord(parsed.usage) ? parsed.usage : void 0;
1000
+ const metrics = isRecord(parsed["amazon-bedrock-invocationMetrics"]) ? parsed["amazon-bedrock-invocationMetrics"] : void 0;
1001
+ const outputs = Array.isArray(parsed.outputs) && isRecord(parsed.outputs[0]) ? parsed.outputs[0] : void 0;
1002
+ const generation = Array.isArray(parsed.generations) && isRecord(parsed.generations[0]) ? parsed.generations[0] : void 0;
1003
+ this.finishReason = stringValue(delta?.stop_reason) ?? stringValue(parsed.stop_reason) ?? stringValue(outputs?.stop_reason) ?? stringValue(generation?.finish_reason) ?? stringValue(parsed.completionReason) ?? this.finishReason;
1004
+ this.usage = omitUndefined({
1005
+ ...this.usage,
1006
+ inputTokens: numberValue(messageUsage?.input_tokens) ?? numberValue(metrics?.inputTokenCount) ?? numberValue(parsed.inputTextTokenCount) ?? this.usage?.inputTokens,
1007
+ outputTokens: numberValue(usage?.output_tokens) ?? numberValue(metrics?.outputTokenCount) ?? numberValue(parsed.totalOutputTextTokenCount) ?? this.usage?.outputTokens,
1008
+ cacheReadInputTokens: numberValue(messageUsage?.cache_read_input_tokens) ?? this.usage?.cacheReadInputTokens,
1009
+ cacheCreationInputTokens: numberValue(messageUsage?.cache_creation_input_tokens) ?? this.usage?.cacheCreationInputTokens
1010
+ });
1011
+ }
1012
+ }
1013
+ finish() {
1014
+ return mergeFields(omitUndefined({
1015
+ output: this.text ? [{
1016
+ role: "assistant",
1017
+ parts: [{
1018
+ type: "text",
1019
+ content: this.text
1020
+ }],
1021
+ finish_reason: this.finishReason
1022
+ }] : this.chunks,
1023
+ finishReason: this.finishReason,
1024
+ usage: this.usage,
1025
+ error: this.error
1026
+ }), this.errorFields);
1027
+ }
1028
+ };
1029
+ function textFromProviderChunk(value) {
1030
+ if (!isRecord(value)) return "";
1031
+ const delta = isRecord(value.delta) ? value.delta : void 0;
1032
+ const contentBlockDelta = isRecord(value.contentBlockDelta) ? value.contentBlockDelta : isRecord(value.content_block_delta) ? value.content_block_delta : void 0;
1033
+ const nestedDelta = isRecord(contentBlockDelta?.delta) ? contentBlockDelta?.delta : void 0;
1034
+ const generation = Array.isArray(value.generations) && isRecord(value.generations[0]) ? value.generations[0] : void 0;
1035
+ return stringValue(value.outputText) ?? stringValue(value.generation) ?? stringValue(value.completion) ?? stringValue(value.text) ?? stringValue(delta?.text) ?? stringValue(nestedDelta?.text) ?? (Array.isArray(value.outputs) && isRecord(value.outputs[0]) ? stringValue(value.outputs[0].text) : void 0) ?? stringValue(generation?.text) ?? "";
1036
+ }
1037
+ //#endregion
1038
+ //#region src/internal-handlers.ts
1039
+ const RUNTIME_HANDLERS = {
1040
+ ConverseCommand: {
1041
+ spanName: (input) => `chat ${stringValue(input.modelId) ?? "unknown"}`,
1042
+ spanType: () => "generation",
1043
+ requestFields: converseRequestFields,
1044
+ onResult(result, span) {
1045
+ endSpan(span, converseResponseFields(result));
1046
+ return result;
1047
+ }
1048
+ },
1049
+ ConverseStreamCommand: {
1050
+ spanName: (input) => `chat ${stringValue(input.modelId) ?? "unknown"}`,
1051
+ spanType: () => "generation",
1052
+ requestFields: converseRequestFields,
1053
+ onResult(result, span, t0) {
1054
+ const response = result;
1055
+ if (!response.stream) {
1056
+ endSpan(span, awsMetadataFields(response.$metadata));
1057
+ return result;
1058
+ }
1059
+ return {
1060
+ ...response,
1061
+ stream: wrapAsyncIterable(response.stream, new ConverseStreamState(), span, t0, awsMetadataFields(response.$metadata))
1062
+ };
1063
+ }
1064
+ },
1065
+ InvokeModelCommand: {
1066
+ spanName: invokeModelSpanName,
1067
+ spanType: (input) => isEmbeddingModel(input.modelId) ? "embedding" : "generation",
1068
+ requestFields: invokeModelRequestFields,
1069
+ onResult(result, span, _t0, input) {
1070
+ endSpan(span, invokeModelResponseFields(input, result));
1071
+ return result;
1072
+ }
1073
+ },
1074
+ InvokeModelWithResponseStreamCommand: {
1075
+ spanName: invokeModelSpanName,
1076
+ spanType: (input) => isEmbeddingModel(input.modelId) ? "embedding" : "generation",
1077
+ requestFields: invokeModelRequestFields,
1078
+ onResult(result, span, t0) {
1079
+ const response = result;
1080
+ if (!response.body) {
1081
+ endSpan(span, awsMetadataFields(response.$metadata));
1082
+ return result;
1083
+ }
1084
+ return {
1085
+ ...response,
1086
+ body: wrapAsyncIterable(response.body, new InvokeModelStreamState(), span, t0, awsMetadataFields(response.$metadata))
1087
+ };
1088
+ }
1089
+ },
1090
+ ApplyGuardrailCommand: {
1091
+ spanName: (input) => `apply_guardrail ${stringValue(input.guardrailIdentifier) ?? "unknown"}`,
1092
+ spanType: () => "span",
1093
+ requestFields: (input) => ({
1094
+ provider: PROVIDER,
1095
+ input: omitUndefined({
1096
+ source: input.source,
1097
+ content: input.content,
1098
+ guardrailIdentifier: input.guardrailIdentifier,
1099
+ guardrailVersion: input.guardrailVersion
1100
+ })
1101
+ }),
1102
+ onResult(result, span) {
1103
+ const response = result;
1104
+ endSpan(span, mergeFields(awsMetadataFields(response.$metadata), {
1105
+ output: omitUndefined({
1106
+ outputs: response.outputs,
1107
+ assessments: response.assessments
1108
+ }),
1109
+ metadata: omitUndefined({
1110
+ guardrail_action: stringValue(response.action),
1111
+ guardrail_action_reason: stringValue(response.actionReason)
1112
+ })
1113
+ }));
1114
+ return result;
1115
+ }
1116
+ }
1117
+ };
1118
+ const AGENT_HANDLERS = {
1119
+ InvokeAgentCommand: {
1120
+ spanName: (input) => `invoke_agent ${stringValue(input.agentId) ?? "unknown"}`,
1121
+ spanType: () => "agent",
1122
+ requestFields: agentRequestFields,
1123
+ onResult: streamAgentResult("completion")
1124
+ },
1125
+ InvokeInlineAgentCommand: {
1126
+ spanName: (input) => `invoke_agent ${stringValue(input.agentName) ?? "inline-agent"}`,
1127
+ spanType: () => "agent",
1128
+ requestFields: inlineAgentRequestFields,
1129
+ onResult: streamAgentResult("completion")
1130
+ },
1131
+ RetrieveCommand: {
1132
+ spanName: (input) => `retrieve ${stringValue(input.knowledgeBaseId) ?? "unknown"}`,
1133
+ spanType: () => "span",
1134
+ requestFields: retrieveRequestFields,
1135
+ onResult(result, span) {
1136
+ endSpan(span, retrieveResponseFields(result));
1137
+ return result;
1138
+ }
1139
+ },
1140
+ RetrieveAndGenerateCommand: {
1141
+ spanName: ragName,
1142
+ spanType: () => "generation",
1143
+ requestFields: ragRequestFields,
1144
+ onResult(result, span) {
1145
+ endSpan(span, ragResponseFields(result));
1146
+ return result;
1147
+ }
1148
+ },
1149
+ RetrieveAndGenerateStreamCommand: {
1150
+ spanName: ragName,
1151
+ spanType: () => "generation",
1152
+ requestFields: ragRequestFields,
1153
+ onResult(result, span, t0) {
1154
+ const response = result;
1155
+ const base = mergeFields(awsMetadataFields(response.$metadata), { metadata: omitUndefined({ bedrock_session_id: stringValue(response.sessionId) }) });
1156
+ if (!response.stream) {
1157
+ endSpan(span, base);
1158
+ return result;
1159
+ }
1160
+ return {
1161
+ ...response,
1162
+ stream: wrapAsyncIterable(response.stream, new RagStreamState(), span, t0, base)
1163
+ };
1164
+ }
1165
+ },
1166
+ InvokeFlowCommand: {
1167
+ spanName: flowName,
1168
+ spanType: () => "agent",
1169
+ requestFields: flowRequestFields,
1170
+ onResult(result, span, t0) {
1171
+ const response = result;
1172
+ if (!response.responseStream) {
1173
+ endSpan(span, awsMetadataFields(response.$metadata));
1174
+ return result;
1175
+ }
1176
+ return {
1177
+ ...response,
1178
+ responseStream: wrapAsyncIterable(response.responseStream, new FlowStreamState(), span, t0, awsMetadataFields(response.$metadata))
1179
+ };
1180
+ }
1181
+ }
1182
+ };
1183
+ function streamAgentResult(key) {
1184
+ return (result, span, t0, _input, options) => {
1185
+ const response = result;
1186
+ const base = mergeFields(awsMetadataFields(response.$metadata), { metadata: omitUndefined({
1187
+ bedrock_session_id: stringValue(response.sessionId),
1188
+ bedrock_memory_id: stringValue(response.memoryId)
1189
+ }) });
1190
+ if (!response[key]) {
1191
+ endSpan(span, base);
1192
+ return result;
1193
+ }
1194
+ return {
1195
+ ...response,
1196
+ [key]: wrapAsyncIterable(response[key], new AgentStreamState(options), span, t0, base)
1197
+ };
1198
+ };
1199
+ }
1200
+ //#endregion
1201
+ export { RUNTIME_HANDLERS as n, createInstrumentedSend as r, AGENT_HANDLERS as t };