promptlayer 1.0.60 → 1.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.
Files changed (37) hide show
  1. package/README.md +9 -0
  2. package/dist/esm/chunk-SWBNW72U.js +2 -0
  3. package/dist/esm/chunk-SWBNW72U.js.map +1 -0
  4. package/dist/esm/index.js +2 -2
  5. package/dist/esm/index.js.map +1 -1
  6. package/dist/esm/openai-agents.js +3 -0
  7. package/dist/esm/openai-agents.js.map +1 -0
  8. package/dist/index.d.mts +229 -9
  9. package/dist/index.d.ts +229 -9
  10. package/dist/index.js +2 -2
  11. package/dist/index.js.map +1 -1
  12. package/dist/openai-agents.d.mts +42 -0
  13. package/dist/openai-agents.d.ts +42 -0
  14. package/dist/openai-agents.js +3 -0
  15. package/dist/openai-agents.js.map +1 -0
  16. package/package.json +24 -3
  17. package/src/integrations/openai-agents/helpers.test.ts +254 -0
  18. package/src/integrations/openai-agents/ids.ts +27 -0
  19. package/src/integrations/openai-agents/index.ts +8 -0
  20. package/src/integrations/openai-agents/instrumentation.test.ts +46 -0
  21. package/src/integrations/openai-agents/instrumentation.ts +47 -0
  22. package/src/integrations/openai-agents/mapping.ts +714 -0
  23. package/src/integrations/openai-agents/otlp-json.ts +120 -0
  24. package/src/integrations/openai-agents/processor.test.ts +509 -0
  25. package/src/integrations/openai-agents/processor.ts +388 -0
  26. package/src/integrations/openai-agents/time.ts +56 -0
  27. package/src/integrations/openai-agents/types.ts +49 -0
  28. package/src/integrations/openai-agents/url.ts +9 -0
  29. package/src/openai-agents.ts +1 -0
  30. package/src/types.ts +302 -9
  31. package/src/utils/blueprint-builder.test.ts +727 -0
  32. package/src/utils/blueprint-builder.ts +957 -126
  33. package/src/utils/streaming.test.ts +498 -0
  34. package/src/utils/streaming.ts +471 -43
  35. package/src/utils/utils.ts +4 -0
  36. package/tsup.config.ts +4 -1
  37. package/vitest.config.ts +3 -0
@@ -1,17 +1,41 @@
1
- const _buildToolCall = (id: string, name: string, input: any, tool_id?: string) => {
2
- const toolCall = {
3
- id,
4
- function: {
5
- name,
6
- input,
7
- },
8
- };
9
- if (tool_id) {
10
- (toolCall as any).tool_id = tool_id;
11
- }
12
- return toolCall;
1
+ import type {
2
+ Annotation,
3
+ AssistantMessage,
4
+ ChatPromptTemplate,
5
+ CompletionPromptTemplate,
6
+ Content,
7
+ FileAnnotation,
8
+ MapAnnotation,
9
+ Metadata,
10
+ PromptBlueprint,
11
+ ToolCall,
12
+ WebAnnotation,
13
+ } from "../types";
14
+
15
+ const OUTPUT_FORMAT_TO_MIME: Record<string, string> = {
16
+ png: "image/png",
17
+ webp: "image/webp",
18
+ jpeg: "image/jpeg",
19
+ jpg: "image/jpeg",
20
+ gif: "image/gif",
21
+ url: "image/png",
13
22
  };
14
23
 
24
+ const _buildToolCall = (
25
+ id: string,
26
+ name: string,
27
+ args: unknown,
28
+ tool_id?: string
29
+ ): ToolCall => ({
30
+ id,
31
+ type: "function",
32
+ function: {
33
+ name,
34
+ arguments: typeof args === "string" ? args : JSON.stringify(args),
35
+ },
36
+ ...(tool_id ? { tool_id } : {}),
37
+ });
38
+
15
39
  const _buildContentBlock = ({
16
40
  type,
17
41
  item_id,
@@ -20,33 +44,35 @@ const _buildContentBlock = ({
20
44
  type: string;
21
45
  item_id?: string;
22
46
  [key: string]: any;
23
- }) => {
24
- const contentBlock: any = {
47
+ }): Content => {
48
+ const contentBlock: Record<string, any> = {
25
49
  type,
26
50
  ...rest,
27
51
  };
28
52
  if (item_id) {
29
- contentBlock.item_id = item_id;
53
+ contentBlock.id = item_id;
30
54
  }
31
- return contentBlock;
55
+ return contentBlock as Content;
32
56
  };
33
57
 
34
- const _buildAssistantMessage = (content: any[], tool_calls: any[]) => {
35
- return {
36
- input_variables: [],
37
- template_format: "f-string" as const,
38
- content: content,
39
- role: "assistant" as const,
40
- function_call: null,
41
- name: null,
42
- tool_calls: tool_calls,
43
- };
44
- };
58
+ const _buildAssistantMessage = (
59
+ content: Content[],
60
+ tool_calls: ToolCall[]
61
+ ): AssistantMessage => ({
62
+ role: "assistant",
63
+ input_variables: [],
64
+ template_format: "f-string",
65
+ content,
66
+ tool_calls,
67
+ });
45
68
 
46
- const _buildPromptTemplate = (assistantMessage: any, metadata: any) => {
47
- const promptTemplate = {
69
+ const _buildPromptTemplate = (
70
+ assistantMessage: AssistantMessage,
71
+ metadata: Metadata
72
+ ): PromptBlueprint => {
73
+ const promptTemplate: ChatPromptTemplate = {
48
74
  messages: [assistantMessage],
49
- type: "chat" as const,
75
+ type: "chat",
50
76
  input_variables: [],
51
77
  };
52
78
 
@@ -56,64 +82,203 @@ const _buildPromptTemplate = (assistantMessage: any, metadata: any) => {
56
82
  };
57
83
  };
58
84
 
85
+ function _parseAnthropicWebAnnotation(c: Record<string, unknown>): WebAnnotation {
86
+ return {
87
+ type: "url_citation",
88
+ url: (c.url as string) ?? "",
89
+ title: (c.title as string) ?? "",
90
+ start_index: (c.start_index as number) ?? 0,
91
+ end_index: (c.end_index as number) ?? 0,
92
+ ...(c.cited_text != null ? { cited_text: c.cited_text as string } : {}),
93
+ ...(c.encrypted_index != null ? { encrypted_index: c.encrypted_index as string } : {}),
94
+ };
95
+ }
96
+
59
97
  export const buildPromptBlueprintFromAnthropicEvent = (
60
98
  event: any,
61
- metadata: any
62
- ) => {
63
- const assistantContent: any[] = [];
64
- const tool_calls: any[] = [];
99
+ metadata: Metadata,
100
+ blockTypeByIndex?: Record<number, string>
101
+ ): PromptBlueprint => {
102
+ const assistantContent: Content[] = [];
103
+ const tool_calls: ToolCall[] = [];
65
104
 
105
+ // Merged message (from anthropicStreamMessage): event.content is array of blocks
106
+ if (Array.isArray(event.content)) {
107
+ for (const block of event.content) {
108
+ if (!block || typeof block !== "object") continue;
109
+ const blockType = block.type;
110
+ if (blockType === "text") {
111
+ const text = block.text ?? "";
112
+ const rawCitations = block.citations ?? block.annotations ?? [];
113
+ const annotations: WebAnnotation[] = [];
114
+ for (const c of rawCitations) {
115
+ if (c && typeof c === "object") annotations.push(_parseAnthropicWebAnnotation(c as Record<string, unknown>));
116
+ }
117
+ assistantContent.push(
118
+ _buildContentBlock({
119
+ type: "text",
120
+ text,
121
+ ...(annotations.length > 0 ? { annotations } : {}),
122
+ })
123
+ );
124
+ } else if (blockType === "thinking") {
125
+ assistantContent.push(
126
+ _buildContentBlock({
127
+ type: "thinking",
128
+ thinking: block.thinking ?? "",
129
+ signature: block.signature ?? "",
130
+ })
131
+ );
132
+ } else if (blockType === "tool_use") {
133
+ tool_calls.push(
134
+ _buildToolCall(
135
+ block.id ?? "",
136
+ block.name ?? "",
137
+ block.input ?? {}
138
+ )
139
+ );
140
+ } else if (blockType === "server_tool_use") {
141
+ assistantContent.push(
142
+ _buildContentBlock({
143
+ type: "server_tool_use",
144
+ id: block.id ?? "",
145
+ name: block.name ?? "",
146
+ input: block.input ?? {},
147
+ })
148
+ );
149
+ } else if (blockType === "web_search_tool_result") {
150
+ const contentList = block.content ?? [];
151
+ const searchResults: Array<{ type: "web_search_result"; url?: string; title?: string; encrypted_content?: string; page_age?: string }> = [];
152
+ for (const r of contentList) {
153
+ if (r && typeof r === "object" && (r as Record<string, unknown>).type === "web_search_result") {
154
+ const rr = r as Record<string, unknown>;
155
+ searchResults.push({
156
+ type: "web_search_result",
157
+ url: rr.url as string | undefined,
158
+ title: rr.title as string | undefined,
159
+ encrypted_content: rr.encrypted_content as string | undefined,
160
+ page_age: rr.page_age as string | undefined,
161
+ });
162
+ }
163
+ }
164
+ assistantContent.push(
165
+ _buildContentBlock({
166
+ type: "web_search_tool_result",
167
+ tool_use_id: block.tool_use_id ?? "",
168
+ content: searchResults,
169
+ })
170
+ );
171
+ } else if (blockType === "bash_code_execution_tool_result") {
172
+ assistantContent.push(
173
+ _buildContentBlock({
174
+ type: "bash_code_execution_tool_result",
175
+ tool_use_id: block.tool_use_id ?? "",
176
+ content: (block.content as Record<string, unknown>) ?? {},
177
+ })
178
+ );
179
+ }
180
+ }
181
+ const assistantMessage = _buildAssistantMessage(assistantContent, tool_calls);
182
+ return _buildPromptTemplate(assistantMessage, metadata);
183
+ }
184
+
185
+ // Single stream events (content_block_start / content_block_delta)
66
186
  if (event.type === "content_block_start") {
67
- if (event.content_block.type === "thinking") {
187
+ if (event.content_block?.type === "thinking") {
188
+ assistantContent.push(
189
+ _buildContentBlock({ type: "thinking", thinking: "", signature: "" })
190
+ );
191
+ } else if (event.content_block?.type === "text") {
192
+ assistantContent.push(_buildContentBlock({ type: "text", text: "" }));
193
+ } else if (event.content_block?.type === "tool_use") {
194
+ tool_calls.push(
195
+ _buildToolCall(
196
+ event.content_block.id ?? "",
197
+ event.content_block.name ?? "",
198
+ {}
199
+ )
200
+ );
201
+ } else if (event.content_block?.type === "server_tool_use") {
68
202
  assistantContent.push(
69
203
  _buildContentBlock({
70
- type: "thinking",
71
- thinking: "",
72
- signature: "",
204
+ type: "server_tool_use",
205
+ id: event.content_block.id ?? "",
206
+ name: event.content_block.name ?? "",
207
+ input: event.content_block.input ?? {},
73
208
  })
74
209
  );
75
- } else if (event.content_block.type === "text") {
210
+ } else if (event.content_block?.type === "web_search_tool_result") {
211
+ const contentList = event.content_block.content ?? [];
212
+ const searchResults: Array<{ type: "web_search_result"; url?: string; title?: string; encrypted_content?: string; page_age?: string }> = [];
213
+ for (const r of contentList) {
214
+ if (r && typeof r === "object" && (r as Record<string, unknown>).type === "web_search_result") {
215
+ const rr = r as Record<string, unknown>;
216
+ searchResults.push({
217
+ type: "web_search_result",
218
+ url: rr.url as string | undefined,
219
+ title: rr.title as string | undefined,
220
+ encrypted_content: rr.encrypted_content as string | undefined,
221
+ page_age: rr.page_age as string | undefined,
222
+ });
223
+ }
224
+ }
76
225
  assistantContent.push(
77
226
  _buildContentBlock({
78
- type: "text",
79
- text: "",
227
+ type: "web_search_tool_result",
228
+ tool_use_id: event.content_block.tool_use_id ?? "",
229
+ content: searchResults,
80
230
  })
81
231
  );
82
- } else if (event.content_block.type === "tool_use") {
83
- tool_calls.push(
84
- _buildToolCall(
85
- event.content_block.id || "",
86
- event.content_block.name || "",
87
- {}
88
- )
232
+ } else if (event.content_block?.type === "bash_code_execution_tool_result") {
233
+ assistantContent.push(
234
+ _buildContentBlock({
235
+ type: "bash_code_execution_tool_result",
236
+ tool_use_id: event.content_block.tool_use_id ?? "",
237
+ content: (event.content_block.content as Record<string, unknown>) ?? {},
238
+ })
89
239
  );
90
240
  }
91
241
  } else if (event.type === "content_block_delta") {
92
- if (event.delta.type === "thinking_delta") {
242
+ if (event.delta?.type === "thinking_delta") {
93
243
  assistantContent.push(
94
244
  _buildContentBlock({
95
245
  type: "thinking",
96
- thinking: event.delta.thinking || "",
246
+ thinking: event.delta.thinking ?? "",
97
247
  signature: "",
98
248
  })
99
249
  );
100
- } else if (event.delta.type === "text_delta") {
250
+ } else if (event.delta?.type === "text_delta") {
101
251
  assistantContent.push(
102
- _buildContentBlock({
103
- type: "text",
104
- text: event.delta.text || "",
105
- })
252
+ _buildContentBlock({ type: "text", text: event.delta.text ?? "" })
106
253
  );
107
- } else if (event.delta.type === "signature_delta") {
254
+ } else if (event.delta?.type === "signature_delta") {
108
255
  assistantContent.push(
109
256
  _buildContentBlock({
110
257
  type: "thinking",
111
258
  thinking: "",
112
- signature: event.delta.signature || "",
259
+ signature: event.delta.signature ?? "",
113
260
  })
114
261
  );
115
- } else if (event.delta.type === "input_json_delta") {
116
- tool_calls.push(_buildToolCall("", "", event.delta.partial_json));
262
+ } else if (event.delta?.type === "input_json_delta") {
263
+ const blockType = blockTypeByIndex?.[event.index];
264
+ if (blockType === "server_tool_use") {
265
+ assistantContent.push(
266
+ _buildContentBlock({
267
+ type: "server_tool_use",
268
+ id: "",
269
+ name: "",
270
+ input: event.delta.partial_json ?? {} as Record<string, unknown>,
271
+ })
272
+ );
273
+ } else {
274
+ tool_calls.push(_buildToolCall("", "", event.delta.partial_json ?? ""));
275
+ }
276
+ } else if (event.delta?.type === "citations_delta" && event.delta.citation) {
277
+ const citation = event.delta.citation as Record<string, unknown>;
278
+ const annotations: WebAnnotation[] = [_parseAnthropicWebAnnotation(citation)];
279
+ assistantContent.push(
280
+ _buildContentBlock({ type: "text", text: "", annotations })
281
+ );
117
282
  }
118
283
  }
119
284
 
@@ -121,27 +286,236 @@ export const buildPromptBlueprintFromAnthropicEvent = (
121
286
  return _buildPromptTemplate(assistantMessage, metadata);
122
287
  };
123
288
 
289
+ const _isImageMimeType = (mimeType: string): boolean =>
290
+ typeof mimeType === "string" && mimeType.startsWith("image/");
291
+
292
+ function _getChunkWebInfo(chunk: Record<string, unknown>): { uri: string; title: string } {
293
+ const web = chunk.web as Record<string, unknown> | undefined;
294
+ if (web && typeof web === "object") {
295
+ return {
296
+ uri: (web.uri as string) ?? "",
297
+ title: (web.title as string) ?? "",
298
+ };
299
+ }
300
+ return {
301
+ uri: (chunk.uri as string) ?? "",
302
+ title: (chunk.title as string) ?? "",
303
+ };
304
+ }
305
+
306
+ function _getFullResponseTextFromCandidate(candidate: Record<string, unknown> | null | undefined): string | undefined {
307
+ if (!candidate || typeof candidate !== "object") return undefined;
308
+ const content = candidate.content as { parts?: Array<{ text?: string }> } | undefined;
309
+ const partList = content?.parts;
310
+ if (!Array.isArray(partList)) return undefined;
311
+ const texts: string[] = [];
312
+ for (const part of partList) {
313
+ if (part && typeof part === "object" && typeof part.text === "string") {
314
+ texts.push(part.text);
315
+ }
316
+ }
317
+ return texts.length > 0 ? texts.join("") : undefined;
318
+ }
319
+
320
+ function _citationMetadataToAnnotations(citationMetadata: Record<string, unknown> | null | undefined): WebAnnotation[] {
321
+ if (!citationMetadata || typeof citationMetadata !== "object") return [];
322
+ const citations = (citationMetadata.citations as Record<string, unknown>[]) ?? [];
323
+ const annotations: WebAnnotation[] = [];
324
+ for (const c of citations) {
325
+ if (!c || typeof c !== "object") continue;
326
+ const uri = (c.uri as string) ?? "";
327
+ if (!uri) continue;
328
+ const startIndex = (c.startIndex as number) ?? 0;
329
+ const endIndex = (c.endIndex as number) ?? 0;
330
+ annotations.push({
331
+ type: "url_citation",
332
+ url: uri,
333
+ title: uri,
334
+ start_index: startIndex,
335
+ end_index: endIndex,
336
+ });
337
+ }
338
+ return annotations;
339
+ }
340
+
341
+ function _candidateToAnnotations(
342
+ candidate: Record<string, unknown> | null | undefined,
343
+ fullResponseText?: string
344
+ ): Annotation[] {
345
+ if (!candidate || typeof candidate !== "object") return [];
346
+ const groundingMetadata = candidate.groundingMetadata as Record<string, unknown> | undefined;
347
+ const citationMetadata = candidate.citationMetadata as Record<string, unknown> | undefined;
348
+ const fromGrounding = _groundingMetadataToAnnotations(groundingMetadata, fullResponseText);
349
+ const fromCitation = _citationMetadataToAnnotations(citationMetadata);
350
+ return [...fromGrounding, ...fromCitation];
351
+ }
352
+
353
+ function _groundingMetadataToAnnotations(
354
+ groundingMetadata: Record<string, unknown> | null | undefined,
355
+ fullResponseText?: string
356
+ ): Annotation[] {
357
+ const chunks = groundingMetadata && typeof groundingMetadata === "object"
358
+ ? ((groundingMetadata.groundingChunks as Record<string, unknown>[]) ?? [])
359
+ : [];
360
+ const supports = groundingMetadata && typeof groundingMetadata === "object"
361
+ ? ((groundingMetadata.groundingSupports as Record<string, unknown>[]) ?? [])
362
+ : [];
363
+
364
+ function citedTextForSegment(segment: Record<string, unknown>, startIndex: number, endIndex: number): string | undefined {
365
+ const segmentText = segment.text as string | undefined;
366
+ if (segmentText != null && segmentText !== "") return segmentText;
367
+ if (fullResponseText != null && endIndex > startIndex) {
368
+ return fullResponseText.slice(startIndex, endIndex) || undefined;
369
+ }
370
+ return undefined;
371
+ }
372
+
373
+ // Map chunks to supports by matching indices (same as backend): only chunk_idx < chunks.length
374
+ if (supports.length > 0 && chunks.length > 0) {
375
+ const annotations: Annotation[] = [];
376
+ const seenFileIds = new Set<string>();
377
+ for (const support of supports) {
378
+ if (!support || typeof support !== "object") continue;
379
+ const segment = (support.segment as Record<string, unknown>) ?? {};
380
+ const chunkIndices = (support.groundingChunkIndices as number[]) ?? [];
381
+ const startIndex = (segment.startIndex as number) ?? 0;
382
+ const endIndex = (segment.endIndex as number) ?? 0;
383
+ const citedText = citedTextForSegment(segment, startIndex, endIndex);
384
+
385
+ for (const chunkIdx of chunkIndices) {
386
+ if (typeof chunkIdx !== "number" || chunkIdx >= chunks.length) continue;
387
+ const chunk = chunks[chunkIdx] as Record<string, unknown>;
388
+ if (!chunk || typeof chunk !== "object") continue;
389
+
390
+ const maps = chunk.maps as Record<string, unknown> | undefined;
391
+ if (maps && typeof maps === "object") {
392
+ const uri = (maps.uri as string) ?? "";
393
+ const title = (maps.title as string) ?? "";
394
+ const placeId = maps.placeId as string | undefined;
395
+ if (uri || title) {
396
+ annotations.push({
397
+ type: "map_citation",
398
+ url: uri,
399
+ title: title || uri,
400
+ ...(placeId != null ? { place_id: placeId } : {}),
401
+ start_index: startIndex,
402
+ end_index: endIndex,
403
+ ...(citedText != null ? { cited_text: citedText } : {}),
404
+ } as MapAnnotation);
405
+ }
406
+ continue;
407
+ }
408
+
409
+ const retrieved = chunk.retrievedContext as Record<string, unknown> | undefined;
410
+ if (retrieved && typeof retrieved === "object") {
411
+ const title = (retrieved.title as string) ?? "";
412
+ if (title && !seenFileIds.has(title)) {
413
+ seenFileIds.add(title);
414
+ annotations.push({
415
+ type: "file_citation",
416
+ file_id: title,
417
+ filename: title,
418
+ index: chunkIdx,
419
+ } as FileAnnotation);
420
+ }
421
+ continue;
422
+ }
423
+
424
+ const { uri, title } = _getChunkWebInfo(chunk);
425
+ if (uri) {
426
+ annotations.push({
427
+ type: "url_citation",
428
+ url: uri,
429
+ title: title || uri,
430
+ start_index: startIndex,
431
+ end_index: endIndex,
432
+ ...(citedText != null ? { cited_text: citedText } : {}),
433
+ } as WebAnnotation);
434
+ }
435
+ }
436
+ }
437
+ return annotations;
438
+ }
439
+
440
+ if (!groundingMetadata || typeof groundingMetadata !== "object") {
441
+ return [];
442
+ }
443
+
444
+ // Fallback: annotations from chunks only (no segment info)
445
+ const annotations: Annotation[] = [];
446
+ const seenFileIds = new Set<string>();
447
+ chunks.forEach((chunk, idx) => {
448
+ if (!chunk || typeof chunk !== "object") return;
449
+ const c = chunk as Record<string, unknown>;
450
+
451
+ const maps = c.maps as Record<string, unknown> | undefined;
452
+ if (maps && typeof maps === "object") {
453
+ const uri = (maps.uri as string) ?? "";
454
+ const title = (maps.title as string) ?? "";
455
+ const placeId = maps.placeId as string | undefined;
456
+ if (uri || title) {
457
+ annotations.push({
458
+ type: "map_citation",
459
+ url: uri,
460
+ title: title || uri,
461
+ ...(placeId != null ? { place_id: placeId } : {}),
462
+ start_index: 0,
463
+ end_index: 0,
464
+ } as MapAnnotation);
465
+ }
466
+ return;
467
+ }
468
+
469
+ const retrieved = c.retrievedContext as Record<string, unknown> | undefined;
470
+ if (retrieved && typeof retrieved === "object") {
471
+ const title = (retrieved.title as string) ?? "";
472
+ if (title && !seenFileIds.has(title)) {
473
+ seenFileIds.add(title);
474
+ annotations.push({
475
+ type: "file_citation",
476
+ file_id: title,
477
+ filename: title,
478
+ index: idx,
479
+ } as FileAnnotation);
480
+ }
481
+ return;
482
+ }
483
+
484
+ const { uri, title } = _getChunkWebInfo(c);
485
+ if (uri) {
486
+ annotations.push({
487
+ type: "url_citation",
488
+ url: uri,
489
+ title: title || uri,
490
+ start_index: 0,
491
+ end_index: 0,
492
+ } as WebAnnotation);
493
+ }
494
+ });
495
+ return annotations;
496
+ }
497
+
124
498
  export const buildPromptBlueprintFromGoogleEvent = (
125
499
  event: any,
126
- metadata: any
127
- ) => {
128
- const assistantContent: any[] = [];
129
- const tool_calls: any[] = [];
500
+ metadata: Metadata
501
+ ): PromptBlueprint => {
502
+ const assistantContent: Content[] = [];
503
+ const tool_calls: ToolCall[] = [];
130
504
 
131
- for (const candidate of event.candidates) {
505
+ for (const candidate of event.candidates ?? []) {
132
506
  if (
133
507
  candidate.content &&
134
508
  candidate.content.parts &&
135
509
  Array.isArray(candidate.content.parts)
136
510
  ) {
137
511
  for (const part of candidate.content.parts) {
138
- if (part.text) {
512
+ if (part.text != null) {
139
513
  if (part.thought === true) {
140
514
  assistantContent.push(
141
515
  _buildContentBlock({
142
516
  type: "thinking",
143
517
  thinking: part.text,
144
- signature: part.thoughtSignature || "",
518
+ signature: part.thoughtSignature ?? "",
145
519
  })
146
520
  );
147
521
  } else {
@@ -149,6 +523,7 @@ export const buildPromptBlueprintFromGoogleEvent = (
149
523
  _buildContentBlock({
150
524
  type: "text",
151
525
  text: part.text,
526
+ ...(part.thoughtSignature ? { thought_signature: part.thoughtSignature } : {}),
152
527
  })
153
528
  );
154
529
  }
@@ -160,21 +535,73 @@ export const buildPromptBlueprintFromGoogleEvent = (
160
535
  part.functionCall.args || {}
161
536
  )
162
537
  );
538
+ } else if (part.executableCode) {
539
+ const exec = part.executableCode;
540
+ assistantContent.push(
541
+ _buildContentBlock({
542
+ type: "code",
543
+ code: exec.code ?? "",
544
+ ...(exec.language != null ? { language: exec.language } : {}),
545
+ })
546
+ );
547
+ } else if (part.codeExecutionResult) {
548
+ const result = part.codeExecutionResult;
549
+ assistantContent.push(
550
+ _buildContentBlock({
551
+ type: "code_execution_result",
552
+ output: result.output ?? "",
553
+ outcome: result.outcome ?? "OUTCOME_OK",
554
+ })
555
+ );
556
+ } else {
557
+ const inlineData = part.inlineData;
558
+ if (inlineData && part.thought !== true) {
559
+ const mimeType = inlineData.mimeType ?? "image/png";
560
+ const data = inlineData.data ?? "";
561
+ if (_isImageMimeType(mimeType) && data) {
562
+ const providerMetadata: Record<string, unknown> = {};
563
+ if (part.thoughtSignature) providerMetadata.thought_signature = part.thoughtSignature;
564
+ if (part.aspectRatio != null) providerMetadata.aspect_ratio = part.aspectRatio;
565
+ if (part.imageSize != null) providerMetadata.image_size = part.imageSize;
566
+ assistantContent.push(
567
+ _buildContentBlock({
568
+ type: "output_media",
569
+ url: data,
570
+ mime_type: mimeType,
571
+ media_type: "image",
572
+ ...(Object.keys(providerMetadata).length ? { provider_metadata: providerMetadata } : {}),
573
+ })
574
+ );
575
+ }
576
+ }
163
577
  }
164
578
  }
165
579
  }
166
580
  }
167
581
 
582
+ const firstCandidate = event.candidates?.[0] as Record<string, unknown> | undefined;
583
+ const fullResponseText = _getFullResponseTextFromCandidate(firstCandidate);
584
+ const allAnnotations = _candidateToAnnotations(firstCandidate, fullResponseText);
585
+ if (allAnnotations.length > 0) {
586
+ for (let i = 0; i < assistantContent.length; i++) {
587
+ const block = assistantContent[i];
588
+ if (block && typeof block === "object" && (block as Content).type === "text") {
589
+ const existing = (block as { annotations?: Annotation[] }).annotations ?? [];
590
+ assistantContent[i] = { ...block, annotations: [...existing, ...allAnnotations] } as Content;
591
+ }
592
+ }
593
+ }
594
+
168
595
  const assistantMessage = _buildAssistantMessage(assistantContent, tool_calls);
169
596
  return _buildPromptTemplate(assistantMessage, metadata);
170
597
  };
171
598
 
172
599
  export const buildPromptBlueprintFromOpenAIEvent = (
173
600
  event: any,
174
- metadata: any
175
- ) => {
176
- const assistantContent: any[] = [];
177
- const tool_calls: any[] = [];
601
+ metadata: Metadata
602
+ ): PromptBlueprint => {
603
+ const assistantContent: Content[] = [];
604
+ const tool_calls: ToolCall[] = [];
178
605
 
179
606
  for (const choice of event.choices) {
180
607
  if (choice.delta) {
@@ -209,10 +636,10 @@ export const buildPromptBlueprintFromOpenAIEvent = (
209
636
 
210
637
  export const buildPromptBlueprintFromOpenAIResponsesEvent = (
211
638
  event: any,
212
- metadata: any
213
- ) => {
214
- const assistantContent: any[] = [];
215
- const tool_calls: any[] = [];
639
+ metadata: Metadata
640
+ ): PromptBlueprint => {
641
+ const assistantContent: Content[] = [];
642
+ const tool_calls: ToolCall[] = [];
216
643
 
217
644
  const event_type: string | undefined = event?.type;
218
645
 
@@ -319,6 +746,88 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
319
746
  container_id: item?.container_id ?? "",
320
747
  })
321
748
  );
749
+ } else if (item_type === "image_generation_call") {
750
+ assistantContent.push(
751
+ _buildContentBlock({
752
+ type: "output_media",
753
+ item_id: item_id,
754
+ url: "",
755
+ mime_type: "image/png",
756
+ media_type: "image",
757
+ })
758
+ );
759
+ } else if (item_type === "mcp_list_tools") {
760
+ assistantContent.push(
761
+ _buildContentBlock({
762
+ type: "mcp_list_tools",
763
+ item_id: item_id,
764
+ server_label: item?.server_label ?? "",
765
+ tools: item?.tools ?? [],
766
+ })
767
+ );
768
+ } else if (item_type === "mcp_call") {
769
+ assistantContent.push(
770
+ _buildContentBlock({
771
+ type: "mcp_call",
772
+ item_id: item_id,
773
+ name: item?.name ?? "",
774
+ server_label: item?.server_label ?? "",
775
+ arguments: item?.arguments ?? "",
776
+ output: item?.output,
777
+ error: item?.error,
778
+ approval_request_id: item?.approval_request_id,
779
+ })
780
+ );
781
+ } else if (item_type === "mcp_approval_request") {
782
+ assistantContent.push(
783
+ _buildContentBlock({
784
+ type: "mcp_approval_request",
785
+ item_id: item_id,
786
+ name: item?.name ?? "",
787
+ arguments: item?.arguments ?? "",
788
+ server_label: item?.server_label ?? "",
789
+ })
790
+ );
791
+ } else if (item_type === "shell_call") {
792
+ assistantContent.push(
793
+ _buildContentBlock({
794
+ type: "shell_call",
795
+ item_id: item_id,
796
+ call_id: item?.call_id ?? "",
797
+ action: item?.action ?? {},
798
+ status: item?.status ?? "in_progress",
799
+ })
800
+ );
801
+ } else if (item_type === "shell_call_output") {
802
+ assistantContent.push(
803
+ _buildContentBlock({
804
+ type: "shell_call_output",
805
+ item_id: item_id,
806
+ call_id: item?.call_id ?? "",
807
+ output: item?.output ?? [],
808
+ status: item?.status ?? "in_progress",
809
+ })
810
+ );
811
+ } else if (item_type === "apply_patch_call") {
812
+ assistantContent.push(
813
+ _buildContentBlock({
814
+ type: "apply_patch_call",
815
+ item_id: item_id,
816
+ call_id: item?.call_id ?? "",
817
+ operation: item?.operation ?? {},
818
+ status: item?.status ?? "in_progress",
819
+ })
820
+ );
821
+ } else if (item_type === "apply_patch_call_output") {
822
+ assistantContent.push(
823
+ _buildContentBlock({
824
+ type: "apply_patch_call_output",
825
+ item_id: item_id,
826
+ call_id: item?.call_id ?? "",
827
+ output: item?.output ?? "",
828
+ status: item?.status ?? "in_progress",
829
+ })
830
+ );
322
831
  }
323
832
  } else if (event_type === "response.content_part.added") {
324
833
  const part = event?.part ?? {};
@@ -331,7 +840,7 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
331
840
  type: "text",
332
841
  item_id: item_id,
333
842
  text: part?.text ?? "",
334
- annotations: part?.annotations || [],
843
+ annotations: (part?.annotations || []) as Annotation[],
335
844
  })
336
845
  );
337
846
  }
@@ -345,34 +854,34 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
345
854
  type: "text",
346
855
  item_id: item_id,
347
856
  text: part?.text ?? "",
348
- annotations: part?.annotations || [],
857
+ annotations: (part?.annotations || []) as Annotation[],
349
858
  })
350
859
  );
351
860
  }
352
861
  } else if (event_type === "response.output_text.annotation.added") {
353
862
  const annotation = event?.annotation || {};
354
863
  const atype = annotation?.type;
355
- let mapped_annotation = null;
864
+ let mapped_annotation: Annotation | null = null;
356
865
 
357
866
  if (atype === "url_citation") {
358
867
  mapped_annotation = {
359
868
  type: "url_citation",
360
- title: annotation?.title,
361
- url: annotation?.url,
362
- start_index: annotation?.start_index,
363
- end_index: annotation?.end_index,
364
- }
869
+ title: annotation?.title ?? "",
870
+ url: annotation?.url ?? "",
871
+ start_index: annotation?.start_index ?? 0,
872
+ end_index: annotation?.end_index ?? 0,
873
+ } as WebAnnotation;
365
874
  }
366
- else if (atype == "file_citation") {
875
+ else if (atype === "file_citation") {
367
876
  mapped_annotation = {
368
877
  type: "file_citation",
369
- index: annotation?.index,
370
- file_id: annotation?.file_id,
371
- filename: annotation?.filename,
372
- }
878
+ index: annotation?.index ?? 0,
879
+ file_id: annotation?.file_id ?? "",
880
+ filename: annotation?.filename ?? "",
881
+ } as FileAnnotation;
373
882
  }
374
883
  else {
375
- mapped_annotation = annotation
884
+ mapped_annotation = annotation as Annotation;
376
885
  }
377
886
 
378
887
  assistantContent.push(
@@ -414,17 +923,13 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
414
923
  );
415
924
  }
416
925
  } else if (event_type === "response.output_text.done") {
417
- const final_text: string = event?.text ?? "";
418
-
419
- if (final_text) {
420
- assistantContent.push(
421
- _buildContentBlock({
422
- type: "text",
423
- item_id: event?.item_id ?? "",
424
- text: final_text,
425
- })
426
- );
427
- }
926
+ assistantContent.push(
927
+ _buildContentBlock({
928
+ type: "text",
929
+ item_id: event?.item_id ?? "",
930
+ text: event?.text ?? "",
931
+ })
932
+ );
428
933
  } else if (event_type === "response.output_item.done") {
429
934
  const item = event?.item ?? {};
430
935
  const item_type: string | undefined = item?.type;
@@ -432,7 +937,7 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
432
937
 
433
938
  if (item_type === "reasoning") {
434
939
  const summary: any[] = item?.summary ?? [];
435
- const summary_text: string = summary.map(summary_part => summary_part?.text ?? "").join("");
940
+ const summary_text: string = summary.map((summary_part: any) => summary_part?.text ?? "").join("");
436
941
  assistantContent.push(
437
942
  _buildContentBlock({
438
943
  type: "thinking",
@@ -454,16 +959,13 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
454
959
  const content: any[] = item?.content ?? [];
455
960
  for (const content_part of content) {
456
961
  if (content_part?.type === "output_text") {
457
- const text: string = content_part?.text ?? "";
458
- if (text) {
459
- assistantContent.push(
460
- _buildContentBlock({
461
- type: "text",
462
- item_id: item_id,
463
- text,
464
- })
465
- );
466
- }
962
+ assistantContent.push(
963
+ _buildContentBlock({
964
+ type: "text",
965
+ item_id: item_id,
966
+ text: content_part?.text ?? "",
967
+ })
968
+ );
467
969
  }
468
970
  }
469
971
  } else if (item_type === "code_interpreter_call") {
@@ -475,6 +977,97 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
475
977
  container_id: item?.container_id ?? "",
476
978
  })
477
979
  );
980
+ } else if (item_type === "image_generation_call") {
981
+ const result = item?.result ?? "";
982
+ const output_format = item?.output_format ?? "png";
983
+ const mime_type = output_format === "webp" ? "image/webp" : "image/png";
984
+ const provider_metadata: Record<string, unknown> = {};
985
+ for (const key of ["revised_prompt", "background", "size", "quality", "output_format"]) {
986
+ if (item?.[key] != null) provider_metadata[key] = item[key];
987
+ }
988
+ assistantContent.push(
989
+ _buildContentBlock({
990
+ type: "output_media",
991
+ item_id: item_id,
992
+ url: result,
993
+ mime_type,
994
+ media_type: "image",
995
+ ...(Object.keys(provider_metadata).length ? { provider_metadata } : {}),
996
+ })
997
+ );
998
+ } else if (item_type === "mcp_list_tools") {
999
+ assistantContent.push(
1000
+ _buildContentBlock({
1001
+ type: "mcp_list_tools",
1002
+ item_id: item_id,
1003
+ server_label: item?.server_label ?? "",
1004
+ tools: item?.tools ?? [],
1005
+ error: item?.error,
1006
+ })
1007
+ );
1008
+ } else if (item_type === "mcp_call") {
1009
+ assistantContent.push(
1010
+ _buildContentBlock({
1011
+ type: "mcp_call",
1012
+ item_id: item_id,
1013
+ name: item?.name ?? "",
1014
+ server_label: item?.server_label ?? "",
1015
+ arguments: item?.arguments ?? "",
1016
+ output: item?.output,
1017
+ error: item?.error,
1018
+ approval_request_id: item?.approval_request_id,
1019
+ })
1020
+ );
1021
+ } else if (item_type === "mcp_approval_request") {
1022
+ assistantContent.push(
1023
+ _buildContentBlock({
1024
+ type: "mcp_approval_request",
1025
+ item_id: item_id,
1026
+ name: item?.name ?? "",
1027
+ arguments: item?.arguments ?? "",
1028
+ server_label: item?.server_label ?? "",
1029
+ })
1030
+ );
1031
+ } else if (item_type === "shell_call") {
1032
+ assistantContent.push(
1033
+ _buildContentBlock({
1034
+ type: "shell_call",
1035
+ item_id: item_id,
1036
+ call_id: item?.call_id ?? "",
1037
+ action: item?.action ?? {},
1038
+ status: item?.status ?? "completed",
1039
+ })
1040
+ );
1041
+ } else if (item_type === "shell_call_output") {
1042
+ assistantContent.push(
1043
+ _buildContentBlock({
1044
+ type: "shell_call_output",
1045
+ item_id: item_id,
1046
+ call_id: item?.call_id ?? "",
1047
+ output: item?.output ?? [],
1048
+ status: item?.status ?? "completed",
1049
+ })
1050
+ );
1051
+ } else if (item_type === "apply_patch_call") {
1052
+ assistantContent.push(
1053
+ _buildContentBlock({
1054
+ type: "apply_patch_call",
1055
+ item_id: item_id,
1056
+ call_id: item?.call_id ?? "",
1057
+ operation: item?.operation ?? {},
1058
+ status: item?.status ?? "completed",
1059
+ })
1060
+ );
1061
+ } else if (item_type === "apply_patch_call_output") {
1062
+ assistantContent.push(
1063
+ _buildContentBlock({
1064
+ type: "apply_patch_call_output",
1065
+ item_id: item_id,
1066
+ call_id: item?.call_id ?? "",
1067
+ output: item?.output ?? "",
1068
+ status: item?.status ?? "completed",
1069
+ })
1070
+ );
478
1071
  }
479
1072
  } else if (event_type === "response.code_interpreter_call_code.done") {
480
1073
  assistantContent.push(
@@ -503,6 +1096,96 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
503
1096
  container_id: event?.container_id ?? "",
504
1097
  })
505
1098
  );
1099
+ } else if (event_type === "response.image_generation_call.in_progress") {
1100
+ assistantContent.push(
1101
+ _buildContentBlock({
1102
+ type: "output_media",
1103
+ item_id: event?.item_id ?? "",
1104
+ url: "",
1105
+ mime_type: "image/png",
1106
+ media_type: "image",
1107
+ })
1108
+ );
1109
+ } else if (event_type === "response.image_generation_call.generating") {
1110
+ assistantContent.push(
1111
+ _buildContentBlock({
1112
+ type: "output_media",
1113
+ item_id: event?.item_id ?? "",
1114
+ url: "",
1115
+ mime_type: "image/png",
1116
+ media_type: "image",
1117
+ })
1118
+ );
1119
+ } else if (event_type === "response.image_generation_call.partial_image") {
1120
+ const output_format = event?.output_format ?? "png";
1121
+ const mime_type = output_format === "webp" ? "image/webp" : "image/png";
1122
+ const provider_metadata: Record<string, unknown> = {};
1123
+ for (const key of ["background", "size", "quality", "output_format"]) {
1124
+ if (event?.[key] != null) provider_metadata[key] = event[key];
1125
+ }
1126
+ assistantContent.push(
1127
+ _buildContentBlock({
1128
+ type: "output_media",
1129
+ item_id: event?.item_id ?? "",
1130
+ url: event?.partial_image_b64 ?? "",
1131
+ mime_type,
1132
+ media_type: "image",
1133
+ ...(Object.keys(provider_metadata).length ? { provider_metadata } : {}),
1134
+ })
1135
+ );
1136
+ } else if (event_type === "response.shell_call_command.added") {
1137
+ assistantContent.push(
1138
+ _buildContentBlock({
1139
+ type: "shell_call",
1140
+ action: { command: event?.command ?? "" },
1141
+ })
1142
+ );
1143
+ } else if (event_type === "response.shell_call_command.delta") {
1144
+ assistantContent.push(
1145
+ _buildContentBlock({
1146
+ type: "shell_call",
1147
+ action: { command: event?.delta ?? "" },
1148
+ })
1149
+ );
1150
+ } else if (event_type === "response.shell_call_command.done") {
1151
+ assistantContent.push(
1152
+ _buildContentBlock({
1153
+ type: "shell_call",
1154
+ action: { command: event?.command ?? "" },
1155
+ })
1156
+ );
1157
+ } else if (event_type === "response.shell_call_output_content.delta") {
1158
+ assistantContent.push(
1159
+ _buildContentBlock({
1160
+ type: "shell_call_output",
1161
+ item_id: event?.item_id ?? "",
1162
+ output: [event?.delta ?? {}],
1163
+ })
1164
+ );
1165
+ } else if (event_type === "response.shell_call_output_content.done") {
1166
+ assistantContent.push(
1167
+ _buildContentBlock({
1168
+ type: "shell_call_output",
1169
+ item_id: event?.item_id ?? "",
1170
+ output: event?.output ?? [],
1171
+ })
1172
+ );
1173
+ } else if (event_type === "response.apply_patch_call_operation_diff.delta") {
1174
+ assistantContent.push(
1175
+ _buildContentBlock({
1176
+ type: "apply_patch_call",
1177
+ item_id: event?.item_id ?? "",
1178
+ operation: { diff: event?.delta ?? "" },
1179
+ })
1180
+ );
1181
+ } else if (event_type === "response.apply_patch_call_operation_diff.done") {
1182
+ assistantContent.push(
1183
+ _buildContentBlock({
1184
+ type: "apply_patch_call",
1185
+ item_id: event?.item_id ?? "",
1186
+ operation: { diff: event?.diff ?? "" },
1187
+ })
1188
+ );
506
1189
  } else if (event_type === "response.completed") {
507
1190
  const response = event?.response ?? {};
508
1191
  const output: any[] = response?.output ?? [];
@@ -513,7 +1196,7 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
513
1196
 
514
1197
  if (item_type === "reasoning") {
515
1198
  const summary: any[] = item?.summary ?? [];
516
- const summary_text: string = summary.map(summary_part => summary_part?.text ?? "").join("");
1199
+ const summary_text: string = summary.map((summary_part: any) => summary_part?.text ?? "").join("");
517
1200
  assistantContent.push(
518
1201
  _buildContentBlock({
519
1202
  type: "thinking",
@@ -535,17 +1218,14 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
535
1218
  const content: any[] = item?.content ?? [];
536
1219
  for (const content_part of content) {
537
1220
  if (content_part?.type === "output_text") {
538
- const text: string = content_part?.text ?? "";
539
- if (text) {
540
- assistantContent.push(
541
- _buildContentBlock({
542
- type: "text",
543
- item_id: item_id,
544
- text: text,
545
- annotations: content_part?.annotations || [],
546
- })
547
- );
548
- }
1221
+ assistantContent.push(
1222
+ _buildContentBlock({
1223
+ type: "text",
1224
+ item_id: item_id,
1225
+ text: content_part?.text ?? "",
1226
+ annotations: (content_part?.annotations || []) as Annotation[],
1227
+ })
1228
+ );
549
1229
  }
550
1230
  }
551
1231
  } else if (item_type === "code_interpreter_call") {
@@ -557,6 +1237,97 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
557
1237
  container_id: item?.container_id ?? "",
558
1238
  })
559
1239
  );
1240
+ } else if (item_type === "image_generation_call") {
1241
+ const result = item?.result ?? "";
1242
+ const output_format = item?.output_format ?? "png";
1243
+ const mime_type = output_format === "webp" ? "image/webp" : "image/png";
1244
+ const provider_metadata: Record<string, unknown> = {};
1245
+ for (const key of ["revised_prompt", "background", "size", "quality", "output_format"]) {
1246
+ if (item?.[key] != null) provider_metadata[key] = item[key];
1247
+ }
1248
+ assistantContent.push(
1249
+ _buildContentBlock({
1250
+ type: "output_media",
1251
+ item_id: item_id,
1252
+ url: result,
1253
+ mime_type,
1254
+ media_type: "image",
1255
+ ...(Object.keys(provider_metadata).length ? { provider_metadata } : {}),
1256
+ })
1257
+ );
1258
+ } else if (item_type === "mcp_list_tools") {
1259
+ assistantContent.push(
1260
+ _buildContentBlock({
1261
+ type: "mcp_list_tools",
1262
+ item_id: item_id,
1263
+ server_label: item?.server_label ?? "",
1264
+ tools: item?.tools ?? [],
1265
+ error: item?.error,
1266
+ })
1267
+ );
1268
+ } else if (item_type === "mcp_call") {
1269
+ assistantContent.push(
1270
+ _buildContentBlock({
1271
+ type: "mcp_call",
1272
+ item_id: item_id,
1273
+ name: item?.name ?? "",
1274
+ server_label: item?.server_label ?? "",
1275
+ arguments: item?.arguments ?? "",
1276
+ output: item?.output,
1277
+ error: item?.error,
1278
+ approval_request_id: item?.approval_request_id,
1279
+ })
1280
+ );
1281
+ } else if (item_type === "mcp_approval_request") {
1282
+ assistantContent.push(
1283
+ _buildContentBlock({
1284
+ type: "mcp_approval_request",
1285
+ item_id: item_id,
1286
+ name: item?.name ?? "",
1287
+ arguments: item?.arguments ?? "",
1288
+ server_label: item?.server_label ?? "",
1289
+ })
1290
+ );
1291
+ } else if (item_type === "shell_call") {
1292
+ assistantContent.push(
1293
+ _buildContentBlock({
1294
+ type: "shell_call",
1295
+ item_id: item_id,
1296
+ call_id: item?.call_id ?? "",
1297
+ action: item?.action ?? {},
1298
+ status: item?.status ?? "completed",
1299
+ })
1300
+ );
1301
+ } else if (item_type === "shell_call_output") {
1302
+ assistantContent.push(
1303
+ _buildContentBlock({
1304
+ type: "shell_call_output",
1305
+ item_id: item_id,
1306
+ call_id: item?.call_id ?? "",
1307
+ output: item?.output ?? [],
1308
+ status: item?.status ?? "completed",
1309
+ })
1310
+ );
1311
+ } else if (item_type === "apply_patch_call") {
1312
+ assistantContent.push(
1313
+ _buildContentBlock({
1314
+ type: "apply_patch_call",
1315
+ item_id: item_id,
1316
+ call_id: item?.call_id ?? "",
1317
+ operation: item?.operation ?? {},
1318
+ status: item?.status ?? "completed",
1319
+ })
1320
+ );
1321
+ } else if (item_type === "apply_patch_call_output") {
1322
+ assistantContent.push(
1323
+ _buildContentBlock({
1324
+ type: "apply_patch_call_output",
1325
+ item_id: item_id,
1326
+ call_id: item?.call_id ?? "",
1327
+ output: item?.output ?? "",
1328
+ status: item?.status ?? "completed",
1329
+ })
1330
+ );
560
1331
  }
561
1332
  }
562
1333
  }
@@ -567,10 +1338,10 @@ export const buildPromptBlueprintFromOpenAIResponsesEvent = (
567
1338
 
568
1339
  export const buildPromptBlueprintFromBedrockEvent = (
569
1340
  event: any,
570
- metadata: any
571
- ) => {
572
- const assistantContent: any[] = [];
573
- const tool_calls: any[] = [];
1341
+ metadata: Metadata
1342
+ ): PromptBlueprint => {
1343
+ const assistantContent: Content[] = [];
1344
+ const tool_calls: ToolCall[] = [];
574
1345
 
575
1346
  if ("contentBlockDelta" in event) {
576
1347
  const delta = event.contentBlockDelta?.delta || {};
@@ -620,3 +1391,63 @@ export const buildPromptBlueprintFromBedrockEvent = (
620
1391
  const assistantMessage = _buildAssistantMessage(assistantContent, tool_calls);
621
1392
  return _buildPromptTemplate(assistantMessage, metadata);
622
1393
  };
1394
+
1395
+ const _RESPONSE_METADATA_KEYS = ["size", "quality", "background", "output_format"] as const;
1396
+
1397
+ export const buildPromptBlueprintFromOpenAIImagesEvent = (
1398
+ event: any,
1399
+ metadata: Metadata
1400
+ ): PromptBlueprint => {
1401
+ const content: Content[] = [];
1402
+ const event_type: string = event?.type ?? "";
1403
+
1404
+ if (event_type === "image_generation.partial_image") {
1405
+ const b64 = event?.b64_json ?? "";
1406
+ if (b64) {
1407
+ const output_format: string = event?.output_format ?? "png";
1408
+ const mime_type = OUTPUT_FORMAT_TO_MIME[output_format] ?? "image/png";
1409
+ const provider_metadata: Record<string, unknown> = {};
1410
+ const partial_image_index = event?.partial_image_index;
1411
+ if (partial_image_index != null) {
1412
+ provider_metadata.partial_image_index = partial_image_index;
1413
+ }
1414
+ content.push(
1415
+ _buildContentBlock({
1416
+ type: "output_media",
1417
+ url: b64,
1418
+ mime_type,
1419
+ media_type: "image",
1420
+ ...(Object.keys(provider_metadata).length ? { provider_metadata } : {}),
1421
+ })
1422
+ );
1423
+ }
1424
+ } else if (event_type === "image_generation.completed") {
1425
+ const b64 = event?.b64_json ?? "";
1426
+ const output_format: string = event?.output_format ?? "png";
1427
+ const mime_type = OUTPUT_FORMAT_TO_MIME[output_format] ?? "image/png";
1428
+ const provider_metadata: Record<string, unknown> = {};
1429
+ for (const key of _RESPONSE_METADATA_KEYS) {
1430
+ if (event?.[key] != null) provider_metadata[key] = event[key];
1431
+ }
1432
+ content.push(
1433
+ _buildContentBlock({
1434
+ type: "output_media",
1435
+ url: b64,
1436
+ mime_type,
1437
+ media_type: "image",
1438
+ ...(Object.keys(provider_metadata).length ? { provider_metadata } : {}),
1439
+ })
1440
+ );
1441
+ }
1442
+
1443
+ const promptTemplate: CompletionPromptTemplate = {
1444
+ type: "completion",
1445
+ content,
1446
+ input_variables: [],
1447
+ };
1448
+
1449
+ return {
1450
+ prompt_template: promptTemplate,
1451
+ metadata,
1452
+ };
1453
+ };