190proof 1.0.8 → 1.0.9

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.
package/dist/index.mjs CHANGED
@@ -31418,8 +31418,15 @@ var {
31418
31418
  function timeout(ms) {
31419
31419
  return new Promise((resolve) => setTimeout(resolve, ms));
31420
31420
  }
31421
+ function isHeicImage(name, mime) {
31422
+ var _a3;
31423
+ const extension = ((_a3 = name.split(".").pop()) == null ? void 0 : _a3.toLowerCase()) || "";
31424
+ return ["heic", "heif", "heics"].includes(extension) || !!(mime && ["image/heic", "image/heif", "image/heic-sequence"].includes(mime));
31425
+ }
31421
31426
 
31422
31427
  // index.ts
31428
+ var sharp = __require("sharp");
31429
+ var decode = __require("heic-decode");
31423
31430
  function parseStreamedResponse(identifier, paragraph, functionCallName, functionCallArgs, allowedFunctionNames) {
31424
31431
  let functionCall = null;
31425
31432
  if (functionCallName && functionCallArgs) {
@@ -31863,7 +31870,7 @@ async function callWithRetries(identifier, aiPayload, aiConfig, retries = 5, chu
31863
31870
  console.log(identifier, "Delegating call to Anthropic API");
31864
31871
  return await callAnthropicWithRetries(
31865
31872
  identifier,
31866
- prepareAnthropicPayload(aiPayload),
31873
+ await prepareAnthropicPayload(aiPayload),
31867
31874
  aiConfig,
31868
31875
  retries
31869
31876
  );
@@ -31871,14 +31878,17 @@ async function callWithRetries(identifier, aiPayload, aiConfig, retries = 5, chu
31871
31878
  console.log(identifier, "Delegating call to OpenAI API");
31872
31879
  return await callOpenAiWithRetries(
31873
31880
  identifier,
31874
- prepareOpenAIPayload(aiPayload),
31881
+ await prepareOpenAIPayload(aiPayload),
31875
31882
  aiConfig,
31876
31883
  retries,
31877
31884
  chunkTimeoutMs
31878
31885
  );
31879
31886
  } else if (isGroqPayload(aiPayload)) {
31880
31887
  console.log(identifier, "Delegating call to Groq API");
31881
- return await callGroqWithRetries(identifier, prepareGroqPayload(aiPayload));
31888
+ return await callGroqWithRetries(
31889
+ identifier,
31890
+ await prepareGroqPayload(aiPayload)
31891
+ );
31882
31892
  } else {
31883
31893
  throw new Error("Invalid AI payload: Unknown model type.");
31884
31894
  }
@@ -31886,31 +31896,110 @@ async function callWithRetries(identifier, aiPayload, aiConfig, retries = 5, chu
31886
31896
  function isAnthropicPayload(payload) {
31887
31897
  return Object.values(ClaudeModel).includes(payload.model);
31888
31898
  }
31889
- function prepareAnthropicPayload(payload) {
31890
- return {
31899
+ async function prepareAnthropicPayload(payload) {
31900
+ const preparedPayload = {
31891
31901
  model: payload.model,
31892
- messages: payload.messages.map((message) => ({
31893
- role: message.role,
31894
- content: message.content
31895
- // TODO: Handle files
31896
- })),
31902
+ messages: [],
31897
31903
  functions: payload.functions
31898
31904
  };
31905
+ for (const message of payload.messages) {
31906
+ const anthropicContentBlocks = [];
31907
+ if (message.content) {
31908
+ anthropicContentBlocks.push({
31909
+ type: "text",
31910
+ text: message.content
31911
+ });
31912
+ }
31913
+ for (const file of message.files || []) {
31914
+ if (!file.mimetype.startsWith("image")) {
31915
+ console.warn(
31916
+ "Anthropic API does not support non-image file types. Skipping file."
31917
+ );
31918
+ continue;
31919
+ }
31920
+ if (file.url) {
31921
+ anthropicContentBlocks.push({
31922
+ type: "image",
31923
+ source: {
31924
+ type: "base64",
31925
+ media_type: "image/png",
31926
+ data: await getNormalizedBase64PNG(file.url, file.mimetype)
31927
+ }
31928
+ });
31929
+ } else if (file.data) {
31930
+ if (!["image/png", "image/jpeg", "image/gif", "image/webp"].includes(
31931
+ file.mimetype
31932
+ )) {
31933
+ throw new Error(
31934
+ "Invalid image mimetype. Supported types are: image/png, image/jpeg, image/gif, image/webp"
31935
+ );
31936
+ }
31937
+ anthropicContentBlocks.push({
31938
+ type: "image",
31939
+ source: {
31940
+ type: "base64",
31941
+ media_type: file.mimetype,
31942
+ data: file.data
31943
+ }
31944
+ });
31945
+ }
31946
+ }
31947
+ preparedPayload.messages.push({
31948
+ role: message.role,
31949
+ content: anthropicContentBlocks
31950
+ });
31951
+ }
31952
+ return preparedPayload;
31899
31953
  }
31900
31954
  function isOpenAiPayload(payload) {
31901
31955
  return Object.values(GPTModel).includes(payload.model);
31902
31956
  }
31903
- function prepareOpenAIPayload(payload) {
31904
- return {
31957
+ async function prepareOpenAIPayload(payload) {
31958
+ const preparedPayload = {
31905
31959
  model: payload.model,
31906
- messages: payload.messages.map((message) => ({
31907
- role: message.role,
31908
- content: normalizeMessageContent(message.content)
31909
- // TODO: Handle files
31910
- })),
31911
- functions: payload.functions,
31912
- function_call: payload.function_call
31960
+ messages: [],
31961
+ functions: payload.functions
31913
31962
  };
31963
+ for (const message of payload.messages) {
31964
+ const openAIContentBlocks = [];
31965
+ if (message.content) {
31966
+ openAIContentBlocks.push({
31967
+ type: "text",
31968
+ text: message.content
31969
+ });
31970
+ }
31971
+ for (const file of message.files || []) {
31972
+ if (!file.mimetype.startsWith("image")) {
31973
+ console.warn(
31974
+ "OpenAI API does not support non-image file types. Skipping file."
31975
+ );
31976
+ continue;
31977
+ }
31978
+ if (file.url) {
31979
+ openAIContentBlocks.push({
31980
+ type: "image_url",
31981
+ image_url: {
31982
+ url: `data:image/png;base64,${await getNormalizedBase64PNG(
31983
+ file.url,
31984
+ file.mimetype
31985
+ )}`
31986
+ }
31987
+ });
31988
+ } else if (file.data) {
31989
+ openAIContentBlocks.push({
31990
+ type: "image_url",
31991
+ image_url: {
31992
+ url: `data:${file.mimetype};base64,${file.data}`
31993
+ }
31994
+ });
31995
+ }
31996
+ }
31997
+ preparedPayload.messages.push({
31998
+ role: message.role,
31999
+ content: openAIContentBlocks
32000
+ });
32001
+ }
32002
+ return preparedPayload;
31914
32003
  }
31915
32004
  function isGroqPayload(payload) {
31916
32005
  return Object.values(GroqModel).includes(payload.model);
@@ -31992,6 +32081,25 @@ async function callGroqWithRetries(identifier, payload, retries = 5) {
31992
32081
  error.response = lastResponse;
31993
32082
  throw error;
31994
32083
  }
32084
+ async function getNormalizedBase64PNG(url2, mime) {
32085
+ console.log("Normalizing image", url2);
32086
+ const response = await axios_default.get(url2, { responseType: "arraybuffer" });
32087
+ let imageBuffer = Buffer.from(response.data);
32088
+ let sharpOptions = {};
32089
+ if (isHeicImage(url2, mime)) {
32090
+ const imageData = await decode({ buffer: imageBuffer });
32091
+ imageBuffer = Buffer.from(imageData.data);
32092
+ sharpOptions = {
32093
+ raw: {
32094
+ width: imageData.width,
32095
+ height: imageData.height,
32096
+ channels: 4
32097
+ }
32098
+ };
32099
+ }
32100
+ const resizedBuffer = await sharp(imageBuffer, sharpOptions).withMetadata().resize(1024, 1024, { fit: "inside", withoutEnlargement: true }).png().toBuffer();
32101
+ return resizedBuffer.toString("base64");
32102
+ }
31995
32103
  export {
31996
32104
  ClaudeModel,
31997
32105
  GPTModel,