@absolutejs/ai 0.3.4 → 0.4.1

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.
@@ -351,7 +351,7 @@ async function* tapStream(source, params, providerName) {
351
351
  let lastUsage;
352
352
  try {
353
353
  for await (const chunk of source) {
354
- if (chunk.type === "done" && chunk.usage) {
354
+ if ((chunk.type === "done" || chunk.type === "usage_update" && chunk.final) && chunk.usage) {
355
355
  lastUsage = chunk.usage;
356
356
  }
357
357
  yield chunk;
@@ -597,7 +597,6 @@ var API_VERSION = "2023-06-01";
597
597
  var DEFAULT_MAX_TOKENS = 32000;
598
598
  var EVENT_PREFIX_LENGTH = 7;
599
599
  var DATA_PREFIX_LENGTH = 6;
600
- var EMPTY_CHUNKS = [];
601
600
  var isRecord = (val) => typeof val === "object" && val !== null;
602
601
  var mapContentBlock = (block) => {
603
602
  if (block.type === "thinking") {
@@ -876,14 +875,79 @@ var getNumber = (obj, key) => {
876
875
  }
877
876
  return 0;
878
877
  };
878
+ var TOOL_INPUT_PROGRESS_CHARS = 2048;
879
+ var TOOL_INPUT_FIELD_MAX_CHARS = 200;
880
+ var readJsonString = (json, start) => {
881
+ for (let index = start + 1;index < json.length; index += 1) {
882
+ if (json[index] === "\\")
883
+ index += 1;
884
+ else if (json[index] === '"')
885
+ return { end: index + 1, raw: json.slice(start + 1, index) };
886
+ }
887
+ return;
888
+ };
889
+ var decodeJsonString = (raw) => {
890
+ try {
891
+ const value = JSON.parse(`"${raw}"`);
892
+ return typeof value === "string" ? value : undefined;
893
+ } catch {
894
+ return;
895
+ }
896
+ };
897
+ var completeStringFields = (partialJson) => {
898
+ const fields = {};
899
+ let depth = 0;
900
+ let key;
901
+ let index = 0;
902
+ while (index < partialJson.length) {
903
+ const character = partialJson[index];
904
+ if (character === '"') {
905
+ const text = readJsonString(partialJson, index);
906
+ if (!text)
907
+ break;
908
+ if (depth === 1 && key === undefined) {
909
+ const after = partialJson.slice(text.end).trimStart();
910
+ if (after.startsWith(":"))
911
+ key = text.raw;
912
+ } else if (depth === 1 && key !== undefined) {
913
+ const value = decodeJsonString(text.raw);
914
+ if (value !== undefined && value.length <= TOOL_INPUT_FIELD_MAX_CHARS)
915
+ fields[key] = value;
916
+ key = undefined;
917
+ }
918
+ index = text.end;
919
+ continue;
920
+ }
921
+ if (character === "{" || character === "[")
922
+ depth += 1;
923
+ else if (character === "}" || character === "]")
924
+ depth -= 1;
925
+ else if (character === "," && depth === 1)
926
+ key = undefined;
927
+ index += 1;
928
+ }
929
+ return fields;
930
+ };
931
+ var toolInputProgress = (state) => {
932
+ state.toolInputReported = state.toolInputJson.length;
933
+ return {
934
+ fields: completeStringFields(state.toolInputJson),
935
+ id: state.currentToolId,
936
+ name: state.currentToolName,
937
+ receivedChars: state.toolInputJson.length,
938
+ type: "tool_input"
939
+ };
940
+ };
879
941
  var handleContentBlockStart = (parsed, state) => {
880
942
  const block = getRecord(parsed, "content_block");
881
943
  if (block && block.type === "tool_use") {
882
944
  state.currentToolId = getString(block, "id");
883
945
  state.currentToolName = getString(block, "name");
884
946
  state.toolInputJson = "";
947
+ state.toolInputReported = 0;
885
948
  state.isThinkingBlock = false;
886
949
  state.currentProviderBlock = undefined;
950
+ return toolInputProgress(state);
887
951
  } else if (block && block.type === "thinking") {
888
952
  state.isThinkingBlock = true;
889
953
  state.thinkingSignature = "";
@@ -893,6 +957,7 @@ var handleContentBlockStart = (parsed, state) => {
893
957
  state.currentProviderBlock = block && block.type !== "text" ? { ...block } : undefined;
894
958
  state.providerBlockInputJson = "";
895
959
  }
960
+ return;
896
961
  };
897
962
  var handleContentBlockDelta = (parsed, state) => {
898
963
  const delta = getRecord(parsed, "delta");
@@ -927,6 +992,8 @@ var handleContentBlockDelta = (parsed, state) => {
927
992
  state.providerBlockInputJson += getString(delta, "partial_json");
928
993
  } else {
929
994
  state.toolInputJson += getString(delta, "partial_json");
995
+ if (state.toolInputJson.length - state.toolInputReported >= TOOL_INPUT_PROGRESS_CHARS)
996
+ return toolInputProgress(state);
930
997
  }
931
998
  }
932
999
  if (delta.type === "signature_delta") {
@@ -1046,8 +1113,7 @@ var handleError = (parsed, state) => {
1046
1113
  var processEvent = (eventType, parsed, state) => {
1047
1114
  switch (eventType) {
1048
1115
  case "content_block_start": {
1049
- handleContentBlockStart(parsed, state);
1050
- return;
1116
+ return handleContentBlockStart(parsed, state);
1051
1117
  }
1052
1118
  case "content_block_delta": {
1053
1119
  return handleContentBlockDelta(parsed, state);
@@ -1058,11 +1124,21 @@ var processEvent = (eventType, parsed, state) => {
1058
1124
  case "message_delta": {
1059
1125
  handleMessageDelta(parsed, state);
1060
1126
  mergeMetadata(parsed, state);
1061
- return;
1127
+ return state.usage ? {
1128
+ type: "usage_update",
1129
+ usage: state.usage,
1130
+ metadata: state.metadata,
1131
+ final: false
1132
+ } : undefined;
1062
1133
  }
1063
1134
  case "message_start": {
1064
1135
  handleMessageStart(parsed, state);
1065
- return;
1136
+ return state.usage ? {
1137
+ type: "usage_update",
1138
+ usage: state.usage,
1139
+ metadata: state.metadata,
1140
+ final: false
1141
+ } : undefined;
1066
1142
  }
1067
1143
  case "message_stop": {
1068
1144
  mergeMetadata(parsed, state);
@@ -1096,49 +1172,6 @@ var processSingleEvent = (event, state) => {
1096
1172
  }
1097
1173
  return processEvent(eventType, parsed, state);
1098
1174
  };
1099
- var collectChunk = (event, state) => {
1100
- const chunk = processSingleEvent(event, state);
1101
- return chunk ? [chunk] : [];
1102
- };
1103
- var processBufferedEvents = (eventsText, state) => {
1104
- const events = eventsText.split(`
1105
-
1106
- `);
1107
- state.buffer = events.pop() ?? "";
1108
- return events.flatMap((event) => collectChunk(event, state));
1109
- };
1110
- var readNextChunks = async (reader, decoder, state, signal) => {
1111
- if (signal?.aborted) {
1112
- return { chunks: EMPTY_CHUNKS, done: true };
1113
- }
1114
- const { done, value } = await reader.read();
1115
- if (done) {
1116
- return { chunks: EMPTY_CHUNKS, done: true };
1117
- }
1118
- const rawText = state.buffer + decoder.decode(value, { stream: true });
1119
- const chunks = processBufferedEvents(rawText, state);
1120
- return { chunks, done: false };
1121
- };
1122
- var findDoneChunk = (chunks) => chunks.findIndex((c) => c.type === "done");
1123
- var sseStreamLoop = async (reader, decoder, state, signal) => {
1124
- const result = await readNextChunks(reader, decoder, state, signal);
1125
- if (result.done) {
1126
- return { chunks: result.chunks, finished: true };
1127
- }
1128
- const doneIdx = findDoneChunk(result.chunks);
1129
- if (doneIdx >= 0) {
1130
- return { chunks: result.chunks.slice(0, doneIdx + 1), finished: true };
1131
- }
1132
- return { chunks: result.chunks, finished: false };
1133
- };
1134
- async function* streamChunks(reader, decoder, state, signal) {
1135
- let finished = false;
1136
- while (!finished) {
1137
- const result = await sseStreamLoop(reader, decoder, state, signal);
1138
- ({ finished } = result);
1139
- yield* result.chunks;
1140
- }
1141
- }
1142
1175
  async function* parseSSEStream(body, providerName, signal) {
1143
1176
  const reader = body.getReader();
1144
1177
  const decoder = new TextDecoder;
@@ -1150,13 +1183,40 @@ async function* parseSSEStream(body, providerName, signal) {
1150
1183
  stopReason: "",
1151
1184
  thinkingSignature: "",
1152
1185
  toolInputJson: "",
1186
+ toolInputReported: 0,
1153
1187
  usage: undefined,
1154
1188
  providerName,
1155
1189
  providerBlockInputJson: ""
1156
1190
  };
1157
1191
  try {
1158
- yield* streamChunks(reader, decoder, state, signal);
1192
+ while (true) {
1193
+ signal?.throwIfAborted();
1194
+ const { done, value } = await reader.read();
1195
+ if (done)
1196
+ return;
1197
+ const events = (state.buffer + decoder.decode(value, { stream: true })).split(`
1198
+
1199
+ `);
1200
+ state.buffer = events.pop() ?? "";
1201
+ for (const event of events) {
1202
+ const chunk = processSingleEvent(event, state);
1203
+ if (!chunk)
1204
+ continue;
1205
+ if (chunk.type === "tool_input" && chunk.receivedChars === 0)
1206
+ yield {
1207
+ type: "tool_input_start",
1208
+ id: chunk.id,
1209
+ name: chunk.name
1210
+ };
1211
+ yield chunk;
1212
+ if (chunk.type === "done")
1213
+ return;
1214
+ }
1215
+ }
1159
1216
  } finally {
1217
+ await reader.cancel().catch(() => {
1218
+ return;
1219
+ });
1160
1220
  reader.releaseLock();
1161
1221
  }
1162
1222
  }
@@ -1278,5 +1338,5 @@ export {
1278
1338
  anthropic
1279
1339
  };
1280
1340
 
1281
- //# debugId=0F1301D0EAAFB06664756E2164756E21
1341
+ //# debugId=E2C338FD75B8D35664756E2164756E21
1282
1342
  //# sourceMappingURL=anthropic.js.map