@absolutejs/ai 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -567,7 +567,7 @@ async function* tapStream(source, params, providerName) {
567
567
  let lastUsage;
568
568
  try {
569
569
  for await (const chunk of source) {
570
- if (chunk.type === "done" && chunk.usage) {
570
+ if ((chunk.type === "done" || chunk.type === "usage_update" && chunk.final) && chunk.usage) {
571
571
  lastUsage = chunk.usage;
572
572
  }
573
573
  yield chunk;
@@ -870,7 +870,10 @@ var convertToolBlock = (block) => {
870
870
  if (block.type === "tool_result") {
871
871
  return {
872
872
  call_id: block.tool_use_id,
873
- output: typeof block.content === "string" ? block.content : "",
873
+ output: block.images?.length ? [
874
+ { text: block.content, type: "input_text" },
875
+ ...block.images.map((source) => mapBlockToResponsesFormat({ source, type: "image" }))
876
+ ] : block.content,
874
877
  type: "function_call_output"
875
878
  };
876
879
  }
@@ -1180,6 +1183,8 @@ var processCompleted = function* (parsed) {
1180
1183
  const { response } = parsed;
1181
1184
  const usage = extractUsage(response);
1182
1185
  const metadata = extractResponseMetadata(response);
1186
+ if (usage)
1187
+ yield { type: "usage_update", usage, metadata, final: true };
1183
1188
  if (isRecordArray(response.output)) {
1184
1189
  yield* extractCitationsFromOutput(response.output);
1185
1190
  yield* extractImageFromOutput(response.output);
@@ -1218,6 +1223,15 @@ var processSSEEvent = function* (eventType, parsed, pendingCalls, providerName)
1218
1223
  break;
1219
1224
  case "response.output_item.added":
1220
1225
  processOutputItemAdded(parsed, pendingCalls);
1226
+ if (isRecord(parsed.item) && parsed.item.type === "function_call" && typeof parsed.item.name === "string") {
1227
+ const id = typeof parsed.item.call_id === "string" ? parsed.item.call_id : parsed.item.id;
1228
+ if (typeof id === "string")
1229
+ yield {
1230
+ type: "tool_input_start",
1231
+ id,
1232
+ name: parsed.item.name
1233
+ };
1234
+ }
1221
1235
  break;
1222
1236
  case "response.output_item.done":
1223
1237
  yield* processOutputItemDone(parsed);
@@ -1234,8 +1248,19 @@ var processSSEEvent = function* (eventType, parsed, pendingCalls, providerName)
1234
1248
  case "response.failed":
1235
1249
  case "response.incomplete":
1236
1250
  case "response.error":
1237
- case "error":
1251
+ case "error": {
1252
+ if (isRecord(parsed.response)) {
1253
+ const usage = extractUsage(parsed.response);
1254
+ if (usage)
1255
+ yield {
1256
+ type: "usage_update",
1257
+ usage,
1258
+ metadata: extractResponseMetadata(parsed.response),
1259
+ final: false
1260
+ };
1261
+ }
1238
1262
  throw responseFailure(eventType, parsed, providerName);
1263
+ }
1239
1264
  }
1240
1265
  };
1241
1266
  var flushSSEBuffer = function* (state) {
@@ -1378,6 +1403,7 @@ var NOT_FOUND = -1;
1378
1403
  var isRecord2 = (value) => typeof value === "object" && value !== null;
1379
1404
  var isRecordArray2 = (value) => Array.isArray(value) && value.length > 0 && isRecord2(value[0]);
1380
1405
  var hasArrayContent = (msg) => typeof msg.content !== "string" && Array.isArray(msg.content);
1406
+ var imageUrl = (source) => source.type === "url" ? source.url : `data:${source.media_type};base64,${source.data}`;
1381
1407
  var buildToolMessages = (blocks) => {
1382
1408
  const toolUseBlocks = blocks.filter((block) => block.type === "tool_use");
1383
1409
  const toolResultBlocks = blocks.filter((block) => block.type === "tool_result");
@@ -1403,6 +1429,18 @@ var buildToolMessages = (blocks) => {
1403
1429
  tool_call_id: result.tool_use_id
1404
1430
  });
1405
1431
  }
1432
+ const images = toolResultBlocks.flatMap((result) => result.images ?? []);
1433
+ if (images.length > 0)
1434
+ messages.push({
1435
+ content: [
1436
+ { text: "Images returned by the tool calls above:", type: "text" },
1437
+ ...images.map((source) => ({
1438
+ image_url: { url: imageUrl(source) },
1439
+ type: "image_url"
1440
+ }))
1441
+ ],
1442
+ role: "user"
1443
+ });
1406
1444
  return messages;
1407
1445
  };
1408
1446
  var mapToolDefinitions = (tools) => tools.map((tool) => ({
@@ -1416,9 +1454,7 @@ var mapToolDefinitions = (tools) => tools.map((tool) => ({
1416
1454
  var mapContentBlockToOpenAI = (block) => {
1417
1455
  if (block.type === "image") {
1418
1456
  return {
1419
- image_url: {
1420
- url: block.source.type === "url" ? block.source.url : `data:${block.source.media_type};base64,${block.source.data}`
1421
- },
1457
+ image_url: { url: imageUrl(block.source) },
1422
1458
  type: "image_url"
1423
1459
  };
1424
1460
  }
@@ -1657,6 +1693,14 @@ var processDelta = function* (delta, pendingToolCalls) {
1657
1693
  }
1658
1694
  if (isRecordArray2(delta.tool_calls)) {
1659
1695
  processToolCallDeltas(delta.tool_calls, pendingToolCalls);
1696
+ for (const call of delta.tool_calls) {
1697
+ if (isRecord2(call.function) && typeof call.function.name === "string" && call.function.name)
1698
+ yield {
1699
+ type: "tool_input_start",
1700
+ id: typeof call.id === "string" ? call.id : String(call.index),
1701
+ name: call.function.name
1702
+ };
1703
+ }
1660
1704
  }
1661
1705
  if (Array.isArray(delta.annotations)) {
1662
1706
  for (const annotation of delta.annotations) {
@@ -1755,7 +1799,12 @@ var processSSELine2 = function* (line, pendingToolCalls, providerName) {
1755
1799
  }
1756
1800
  const usageUpdate = narrowUsageRecord(parsed);
1757
1801
  if (usageUpdate) {
1758
- yield { type: "usage_update", usage: usageUpdate };
1802
+ yield {
1803
+ type: "usage_update",
1804
+ usage: usageUpdate,
1805
+ final: Array.isArray(parsed.choices) && parsed.choices.length === 0,
1806
+ metadata: narrowResponseMetadata(parsed)
1807
+ };
1759
1808
  }
1760
1809
  const metadata = narrowResponseMetadata(parsed);
1761
1810
  if (metadata) {
@@ -1784,10 +1833,9 @@ var processSSELine2 = function* (line, pendingToolCalls, providerName) {
1784
1833
  }
1785
1834
  yield* processChoice(firstChoice, pendingToolCalls);
1786
1835
  };
1787
- var isUsageUpdate = (chunk) => chunk.type === "usage_update";
1788
1836
  var collectYieldableChunks = (line, pendingToolCalls, usageRef, metadataRef, providerName) => {
1789
1837
  const allChunks = Array.from(processSSELine2(line, pendingToolCalls, providerName));
1790
- const usageChunks = allChunks.filter(isUsageUpdate);
1838
+ const usageChunks = allChunks.filter((chunk) => chunk.type === "usage_update");
1791
1839
  const lastUsage = usageChunks.at(NOT_FOUND);
1792
1840
  if (lastUsage) {
1793
1841
  usageRef.current = lastUsage.usage;
@@ -1804,7 +1852,7 @@ var collectYieldableChunks = (line, pendingToolCalls, usageRef, metadataRef, pro
1804
1852
  }
1805
1853
  };
1806
1854
  }
1807
- return allChunks.filter((chunk) => !isUsageUpdate(chunk) && chunk.type !== "response_metadata");
1855
+ return allChunks.filter((chunk) => chunk.type !== "response_metadata").map((chunk) => chunk.type === "usage_update" ? { ...chunk, metadata: metadataRef.current } : chunk);
1808
1856
  };
1809
1857
  var processSSELines2 = function* (lines, pendingToolCalls, usageRef, metadataRef, providerName) {
1810
1858
  for (const line of lines) {
@@ -1922,7 +1970,6 @@ var API_VERSION = "2023-06-01";
1922
1970
  var DEFAULT_MAX_TOKENS = 32000;
1923
1971
  var EVENT_PREFIX_LENGTH2 = 7;
1924
1972
  var DATA_PREFIX_LENGTH2 = 6;
1925
- var EMPTY_CHUNKS = [];
1926
1973
  var isRecord3 = (val) => typeof val === "object" && val !== null;
1927
1974
  var mapContentBlock = (block) => {
1928
1975
  if (block.type === "thinking") {
@@ -1946,7 +1993,10 @@ var mapContentBlock = (block) => {
1946
1993
  }
1947
1994
  if (block.type === "tool_result") {
1948
1995
  return {
1949
- content: block.content,
1996
+ content: block.images?.length ? [
1997
+ { text: block.content, type: "text" },
1998
+ ...block.images.map((source) => ({ source, type: "image" }))
1999
+ ] : block.content,
1950
2000
  tool_use_id: block.tool_use_id,
1951
2001
  type: "tool_result"
1952
2002
  };
@@ -2450,11 +2500,21 @@ var processEvent = (eventType, parsed, state) => {
2450
2500
  case "message_delta": {
2451
2501
  handleMessageDelta(parsed, state);
2452
2502
  mergeMetadata(parsed, state);
2453
- return;
2503
+ return state.usage ? {
2504
+ type: "usage_update",
2505
+ usage: state.usage,
2506
+ metadata: state.metadata,
2507
+ final: false
2508
+ } : undefined;
2454
2509
  }
2455
2510
  case "message_start": {
2456
2511
  handleMessageStart(parsed, state);
2457
- return;
2512
+ return state.usage ? {
2513
+ type: "usage_update",
2514
+ usage: state.usage,
2515
+ metadata: state.metadata,
2516
+ final: false
2517
+ } : undefined;
2458
2518
  }
2459
2519
  case "message_stop": {
2460
2520
  mergeMetadata(parsed, state);
@@ -2488,49 +2548,6 @@ var processSingleEvent = (event, state) => {
2488
2548
  }
2489
2549
  return processEvent(eventType, parsed, state);
2490
2550
  };
2491
- var collectChunk = (event, state) => {
2492
- const chunk = processSingleEvent(event, state);
2493
- return chunk ? [chunk] : [];
2494
- };
2495
- var processBufferedEvents = (eventsText, state) => {
2496
- const events = eventsText.split(`
2497
-
2498
- `);
2499
- state.buffer = events.pop() ?? "";
2500
- return events.flatMap((event) => collectChunk(event, state));
2501
- };
2502
- var readNextChunks = async (reader, decoder, state, signal) => {
2503
- if (signal?.aborted) {
2504
- return { chunks: EMPTY_CHUNKS, done: true };
2505
- }
2506
- const { done, value } = await reader.read();
2507
- if (done) {
2508
- return { chunks: EMPTY_CHUNKS, done: true };
2509
- }
2510
- const rawText = state.buffer + decoder.decode(value, { stream: true });
2511
- const chunks = processBufferedEvents(rawText, state);
2512
- return { chunks, done: false };
2513
- };
2514
- var findDoneChunk = (chunks) => chunks.findIndex((c) => c.type === "done");
2515
- var sseStreamLoop = async (reader, decoder, state, signal) => {
2516
- const result = await readNextChunks(reader, decoder, state, signal);
2517
- if (result.done) {
2518
- return { chunks: result.chunks, finished: true };
2519
- }
2520
- const doneIdx = findDoneChunk(result.chunks);
2521
- if (doneIdx >= 0) {
2522
- return { chunks: result.chunks.slice(0, doneIdx + 1), finished: true };
2523
- }
2524
- return { chunks: result.chunks, finished: false };
2525
- };
2526
- async function* streamChunks(reader, decoder, state, signal) {
2527
- let finished = false;
2528
- while (!finished) {
2529
- const result = await sseStreamLoop(reader, decoder, state, signal);
2530
- ({ finished } = result);
2531
- yield* result.chunks;
2532
- }
2533
- }
2534
2551
  async function* parseSSEStream3(body, providerName, signal) {
2535
2552
  const reader = body.getReader();
2536
2553
  const decoder = new TextDecoder;
@@ -2548,8 +2565,34 @@ async function* parseSSEStream3(body, providerName, signal) {
2548
2565
  providerBlockInputJson: ""
2549
2566
  };
2550
2567
  try {
2551
- yield* streamChunks(reader, decoder, state, signal);
2568
+ while (true) {
2569
+ signal?.throwIfAborted();
2570
+ const { done, value } = await reader.read();
2571
+ if (done)
2572
+ return;
2573
+ const events = (state.buffer + decoder.decode(value, { stream: true })).split(`
2574
+
2575
+ `);
2576
+ state.buffer = events.pop() ?? "";
2577
+ for (const event of events) {
2578
+ const chunk = processSingleEvent(event, state);
2579
+ if (!chunk)
2580
+ continue;
2581
+ if (chunk.type === "tool_input" && chunk.receivedChars === 0)
2582
+ yield {
2583
+ type: "tool_input_start",
2584
+ id: chunk.id,
2585
+ name: chunk.name
2586
+ };
2587
+ yield chunk;
2588
+ if (chunk.type === "done")
2589
+ return;
2590
+ }
2591
+ }
2552
2592
  } finally {
2593
+ await reader.cancel().catch(() => {
2594
+ return;
2595
+ });
2553
2596
  reader.releaseLock();
2554
2597
  }
2555
2598
  }
@@ -3586,5 +3629,5 @@ export {
3586
3629
  verifyOpenRouterWebhookSignature
3587
3630
  };
3588
3631
 
3589
- //# debugId=28EECE403772185564756E2164756E21
3632
+ //# debugId=C9DE38070AD183BF64756E2164756E21
3590
3633
  //# sourceMappingURL=openrouter.js.map