190proof 1.0.96 → 1.0.98

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.js CHANGED
@@ -139,7 +139,6 @@ function isHeicImage(name, mime) {
139
139
  }
140
140
 
141
141
  // index.ts
142
- var import_genai = require("@google/genai");
143
142
  var sharp = require("sharp");
144
143
  var decode = require("heic-decode");
145
144
  async function withRetries(identifier, apiName, fn, options = {}) {
@@ -170,9 +169,10 @@ async function withRetries(identifier, apiName, fn, options = {}) {
170
169
  error2.cause = lastError;
171
170
  throw error2;
172
171
  }
173
- function parseStreamedResponse(identifier, paragraph, toolCallAccumulators, allowedFunctionNames) {
172
+ function parseStreamedResponse(identifier, paragraph, toolCallAccumulators, allowedFunctionNames, reasoning) {
174
173
  const functionCalls = [];
175
- for (const acc of toolCallAccumulators) {
174
+ for (let i = 0; i < toolCallAccumulators.length; i++) {
175
+ const acc = toolCallAccumulators[i];
176
176
  if (!acc.name || !acc.arguments)
177
177
  continue;
178
178
  if (allowedFunctionNames && !allowedFunctionNames.has(acc.name)) {
@@ -182,6 +182,7 @@ function parseStreamedResponse(identifier, paragraph, toolCallAccumulators, allo
182
182
  }
183
183
  try {
184
184
  functionCalls.push({
185
+ id: acc.id || `call_${i}`,
185
186
  name: acc.name,
186
187
  arguments: JSON.parse(acc.arguments)
187
188
  });
@@ -210,6 +211,7 @@ function parseStreamedResponse(identifier, paragraph, toolCallAccumulators, allo
210
211
  function_call: functionCalls[0] || null,
211
212
  function_calls: functionCalls,
212
213
  files: [],
214
+ reasoning: reasoning || void 0,
213
215
  usage: null
214
216
  };
215
217
  }
@@ -311,7 +313,7 @@ function buildOpenAIRequestConfig(identifier, model, config) {
311
313
  };
312
314
  }
313
315
  async function prepareOpenAIPayload(identifier, payload) {
314
- var _a;
316
+ var _a, _b;
315
317
  const preparedPayload = {
316
318
  model: payload.model,
317
319
  messages: [],
@@ -322,6 +324,16 @@ async function prepareOpenAIPayload(identifier, payload) {
322
324
  tool_choice: payload.function_call ? typeof payload.function_call === "string" ? payload.function_call : { type: "function", function: payload.function_call } : void 0
323
325
  };
324
326
  for (const message of payload.messages) {
327
+ if (message.role === "tool") {
328
+ for (const tr of message.toolResults || []) {
329
+ preparedPayload.messages.push({
330
+ role: "tool",
331
+ tool_call_id: tr.toolCallId,
332
+ content: tr.content
333
+ });
334
+ }
335
+ continue;
336
+ }
325
337
  const contentBlocks = [];
326
338
  if (message.content) {
327
339
  contentBlocks.push({ type: "text", text: message.content });
@@ -347,15 +359,34 @@ async function prepareOpenAIPayload(identifier, payload) {
347
359
  });
348
360
  }
349
361
  }
350
- preparedPayload.messages.push({
362
+ const outMessage = {
351
363
  role: message.role,
352
- content: contentBlocks
353
- });
364
+ // OpenAI wants null (not []) content on a tool-call-only assistant turn.
365
+ content: contentBlocks.length ? contentBlocks : null
366
+ };
367
+ if ((_b = message.functionCalls) == null ? void 0 : _b.length) {
368
+ outMessage.tool_calls = message.functionCalls.map((fc, i) => {
369
+ var _a2;
370
+ return {
371
+ id: (_a2 = fc.id) != null ? _a2 : `call_${i}`,
372
+ type: "function",
373
+ function: {
374
+ name: fc.name,
375
+ arguments: JSON.stringify(fc.arguments)
376
+ }
377
+ };
378
+ });
379
+ }
380
+ if (message.reasoning)
381
+ outMessage.reasoning = message.reasoning;
382
+ if (message.reasoningDetails)
383
+ outMessage.reasoning_details = message.reasoningDetails;
384
+ preparedPayload.messages.push(outMessage);
354
385
  }
355
386
  return preparedPayload;
356
387
  }
357
388
  async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs) {
358
- var _a, _b, _c, _d, _e, _f, _g, _h;
389
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
359
390
  const functionNames = openAiPayload.tools ? new Set(openAiPayload.tools.map((fn) => fn.function.name)) : null;
360
391
  const { endpoint, headers } = buildOpenAIRequestConfig(
361
392
  id,
@@ -373,6 +404,7 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
373
404
  throw new Error("Stream error: no response body");
374
405
  }
375
406
  let paragraph = "";
407
+ let reasoning = "";
376
408
  const toolCallAccumulators = [];
377
409
  const reader = response.body.getReader();
378
410
  let partialChunk = "";
@@ -407,7 +439,8 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
407
439
  id,
408
440
  paragraph,
409
441
  toolCallAccumulators,
410
- functionNames
442
+ functionNames,
443
+ reasoning
411
444
  );
412
445
  }
413
446
  let json;
@@ -437,6 +470,8 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
437
470
  while (toolCallAccumulators.length <= idx) {
438
471
  toolCallAccumulators.push({ name: "", arguments: "" });
439
472
  }
473
+ if (toolCall.id)
474
+ toolCallAccumulators[idx].id = toolCall.id;
440
475
  if ((_e = toolCall.function) == null ? void 0 : _e.name)
441
476
  toolCallAccumulators[idx].name += toolCall.function.name;
442
477
  if ((_f = toolCall.function) == null ? void 0 : _f.arguments)
@@ -446,11 +481,14 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
446
481
  const text = (_h = (_g = json.choices[0]) == null ? void 0 : _g.delta) == null ? void 0 : _h.content;
447
482
  if (text)
448
483
  paragraph += text;
484
+ const reasoningDelta = (_j = (_i = json.choices[0]) == null ? void 0 : _i.delta) == null ? void 0 : _j.reasoning;
485
+ if (reasoningDelta)
486
+ reasoning += reasoningDelta;
449
487
  }
450
488
  }
451
489
  }
452
490
  async function callOpenAI(id, openAiPayload, openAiConfig) {
453
- var _a, _b, _c, _d, _e;
491
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
454
492
  const { endpoint, headers } = buildOpenAIRequestConfig(
455
493
  id,
456
494
  openAiPayload.model,
@@ -478,19 +516,22 @@ async function callOpenAI(id, openAiPayload, openAiConfig) {
478
516
  const toolCalls = (_b = choice.message) == null ? void 0 : _b.tool_calls;
479
517
  const functionCalls = [];
480
518
  if (toolCalls == null ? void 0 : toolCalls.length) {
481
- for (const tc of toolCalls) {
519
+ for (let i = 0; i < toolCalls.length; i++) {
520
+ const tc = toolCalls[i];
482
521
  functionCalls.push({
522
+ id: (_c = tc.id) != null ? _c : `call_${i}`,
483
523
  name: tc.function.name,
484
524
  arguments: JSON.parse(tc.function.arguments)
485
525
  });
486
526
  }
487
527
  } else if (choice.function_call) {
488
528
  functionCalls.push({
529
+ id: "call_0",
489
530
  name: choice.function_call.name,
490
531
  arguments: JSON.parse(choice.function_call.arguments)
491
532
  });
492
533
  }
493
- if (!((_c = choice.message) == null ? void 0 : _c.content) && !functionCalls.length) {
534
+ if (!((_d = choice.message) == null ? void 0 : _d.content) && !functionCalls.length) {
494
535
  logger_default.error(
495
536
  id,
496
537
  "OpenAI: received message without content or function_call:",
@@ -506,11 +547,13 @@ async function callOpenAI(id, openAiPayload, openAiConfig) {
506
547
  function_call: functionCalls[0] || null,
507
548
  function_calls: functionCalls,
508
549
  files: [],
550
+ reasoning: (_f = (_e = choice.message) == null ? void 0 : _e.reasoning) != null ? _f : void 0,
551
+ reasoningDetails: (_h = (_g = choice.message) == null ? void 0 : _g.reasoning_details) != null ? _h : void 0,
509
552
  usage: data.usage ? {
510
553
  prompt_tokens: data.usage.prompt_tokens,
511
554
  completion_tokens: data.usage.completion_tokens,
512
555
  total_tokens: data.usage.total_tokens,
513
- cached_tokens: (_e = (_d = data.usage.prompt_tokens_details) == null ? void 0 : _d.cached_tokens) != null ? _e : 0
556
+ cached_tokens: (_j = (_i = data.usage.prompt_tokens_details) == null ? void 0 : _i.cached_tokens) != null ? _j : 0
514
557
  } : null
515
558
  };
516
559
  }
@@ -563,7 +606,8 @@ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries =
563
606
  );
564
607
  }
565
608
  function jigAnthropicMessages(messages) {
566
- var _a, _b;
609
+ var _a;
610
+ const hasToolBlock = (content) => Array.isArray(content) && content.some((b) => b.type === "tool_use" || b.type === "tool_result");
567
611
  let jiggedMessages = messages.slice();
568
612
  if (((_a = jiggedMessages[0]) == null ? void 0 : _a.role) !== "user") {
569
613
  jiggedMessages = [
@@ -578,11 +622,8 @@ function jigAnthropicMessages(messages) {
578
622
  if (lastMessage.role === message.role) {
579
623
  const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
580
624
  const newContent = Array.isArray(message.content) ? message.content : [{ type: "text", text: message.content }];
581
- lastMessage.content = [
582
- ...lastContent,
583
- { type: "text", text: "\n\n---\n\n" },
584
- ...newContent
585
- ];
625
+ const separator = hasToolBlock(lastMessage.content) || hasToolBlock(message.content) ? [] : [{ type: "text", text: "\n\n---\n\n" }];
626
+ lastMessage.content = [...lastContent, ...separator, ...newContent];
586
627
  return acc;
587
628
  }
588
629
  if (typeof message.content === "string") {
@@ -590,7 +631,8 @@ function jigAnthropicMessages(messages) {
590
631
  }
591
632
  return [...acc, message];
592
633
  }, []);
593
- if (((_b = jiggedMessages[jiggedMessages.length - 1]) == null ? void 0 : _b.role) === "assistant") {
634
+ const last = jiggedMessages[jiggedMessages.length - 1];
635
+ if ((last == null ? void 0 : last.role) === "assistant" && !hasToolBlock(last.content)) {
594
636
  jiggedMessages.push({ role: "user", content: "..." });
595
637
  }
596
638
  return jiggedMessages;
@@ -607,6 +649,17 @@ async function prepareAnthropicPayload(_identifier, payload) {
607
649
  preparedPayload.system = message.content;
608
650
  continue;
609
651
  }
652
+ if (message.role === "tool") {
653
+ preparedPayload.messages.push({
654
+ role: "user",
655
+ content: (message.toolResults || []).map((tr) => ({
656
+ type: "tool_result",
657
+ tool_use_id: tr.toolCallId,
658
+ content: tr.content
659
+ }))
660
+ });
661
+ continue;
662
+ }
610
663
  const contentBlocks = [];
611
664
  if (message.content) {
612
665
  contentBlocks.push({ type: "text", text: message.content });
@@ -644,9 +697,19 @@ async function prepareAnthropicPayload(_identifier, payload) {
644
697
  });
645
698
  }
646
699
  }
700
+ const leadingBlocks = message.role === "assistant" && Array.isArray(message.reasoningDetails) ? message.reasoningDetails : [];
701
+ const toolUseBlocks = (message.functionCalls || []).map((fc, i) => {
702
+ var _a;
703
+ return {
704
+ type: "tool_use",
705
+ id: (_a = fc.id) != null ? _a : `call_${i}`,
706
+ name: fc.name,
707
+ input: fc.arguments
708
+ };
709
+ });
647
710
  preparedPayload.messages.push({
648
711
  role: message.role,
649
- content: contentBlocks
712
+ content: [...leadingBlocks, ...contentBlocks, ...toolUseBlocks]
650
713
  });
651
714
  }
652
715
  return preparedPayload;
@@ -713,6 +776,7 @@ async function callAnthropic(id, payload, config) {
713
776
  }
714
777
  let textResponse = "";
715
778
  const functionCalls = [];
779
+ const reasoningBlocks = [];
716
780
  for (const answer of answers) {
717
781
  if (!answer.type) {
718
782
  logger_default.error(id, "Missing answer type in Anthropic API response:", data);
@@ -732,9 +796,12 @@ async function callAnthropic(id, payload, config) {
732
796
  ${text}` : text;
733
797
  } else if (answer.type === "tool_use") {
734
798
  functionCalls.push({
799
+ id: answer.id,
735
800
  name: answer.name,
736
801
  arguments: answer.input
737
802
  });
803
+ } else if (answer.type === "thinking" || answer.type === "redacted_thinking") {
804
+ reasoningBlocks.push(answer);
738
805
  }
739
806
  }
740
807
  if (!textResponse && !functionCalls.length) {
@@ -763,6 +830,7 @@ ${text}` : text;
763
830
  function_call: functionCalls[0] || null,
764
831
  function_calls: functionCalls,
765
832
  files: [],
833
+ reasoningDetails: reasoningBlocks.length ? reasoningBlocks : void 0,
766
834
  usage
767
835
  };
768
836
  }
@@ -777,7 +845,8 @@ async function callAnthropicWithRetries(id, payload, config, retries = 5) {
777
845
  );
778
846
  }
779
847
  function jigGoogleMessages(messages) {
780
- var _a, _b;
848
+ var _a;
849
+ const hasFunctionPart = (parts) => parts.some((p) => "functionCall" in p || "functionResponse" in p);
781
850
  let jiggedMessages = messages.slice();
782
851
  if (((_a = jiggedMessages[0]) == null ? void 0 : _a.role) === "model") {
783
852
  jiggedMessages = [
@@ -795,7 +864,8 @@ function jigGoogleMessages(messages) {
795
864
  }
796
865
  return [...acc, message];
797
866
  }, []);
798
- if (((_b = jiggedMessages[jiggedMessages.length - 1]) == null ? void 0 : _b.role) === "model") {
867
+ const last = jiggedMessages[jiggedMessages.length - 1];
868
+ if ((last == null ? void 0 : last.role) === "model" && !hasFunctionPart(last.parts)) {
799
869
  jiggedMessages.push({ role: "user", parts: [{ text: "..." }] });
800
870
  }
801
871
  return jiggedMessages;
@@ -804,6 +874,7 @@ async function prepareGoogleAIPayload(_identifier, payload) {
804
874
  const preparedPayload = {
805
875
  model: payload.model,
806
876
  messages: [],
877
+ requestTimeoutMs: payload.requestTimeoutMs,
807
878
  tools: payload.functions ? {
808
879
  functionDeclarations: payload.functions.map((fn) => ({
809
880
  name: fn.name,
@@ -814,11 +885,34 @@ async function prepareGoogleAIPayload(_identifier, payload) {
814
885
  }))
815
886
  } : void 0
816
887
  };
888
+ const toolNameById = /* @__PURE__ */ new Map();
889
+ for (const m of payload.messages) {
890
+ for (const fc of m.functionCalls || []) {
891
+ if (fc.id)
892
+ toolNameById.set(fc.id, fc.name);
893
+ }
894
+ }
817
895
  for (const message of payload.messages) {
818
896
  if (message.role === "system") {
819
897
  preparedPayload.systemInstruction = message.content;
820
898
  continue;
821
899
  }
900
+ if (message.role === "tool") {
901
+ preparedPayload.messages.push({
902
+ role: "user",
903
+ parts: (message.toolResults || []).map((tr) => {
904
+ var _a, _b;
905
+ return {
906
+ functionResponse: {
907
+ id: tr.toolCallId,
908
+ name: (_b = (_a = tr.name) != null ? _a : toolNameById.get(tr.toolCallId)) != null ? _b : "",
909
+ response: { output: tr.content }
910
+ }
911
+ };
912
+ })
913
+ });
914
+ continue;
915
+ }
822
916
  const parts = [];
823
917
  if (message.content) {
824
918
  parts.push({ text: message.content });
@@ -847,6 +941,17 @@ async function prepareGoogleAIPayload(_identifier, payload) {
847
941
  });
848
942
  }
849
943
  }
944
+ for (const fc of message.functionCalls || []) {
945
+ parts.push({
946
+ functionCall: {
947
+ id: fc.id,
948
+ name: fc.name,
949
+ args: fc.arguments
950
+ },
951
+ // Gemini requires its thoughtSignature echoed back on the call part.
952
+ ...fc.thoughtSignature ? { thoughtSignature: fc.thoughtSignature } : {}
953
+ });
954
+ }
850
955
  preparedPayload.messages.push({
851
956
  role: message.role === "assistant" ? "model" : message.role,
852
957
  parts
@@ -855,39 +960,73 @@ async function prepareGoogleAIPayload(_identifier, payload) {
855
960
  return preparedPayload;
856
961
  }
857
962
  async function callGoogleAI(id, payload) {
858
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
859
- const googleMessages = jigGoogleMessages(payload.messages);
860
- const history = googleMessages.slice(0, -1);
861
- const lastMessage = googleMessages.slice(-1)[0];
862
- const genAI = new import_genai.GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
863
- const chat = genAI.chats.create({
864
- model: payload.model,
865
- history,
866
- config: {
867
- responseModalities: ["Text"],
868
- tools: payload.tools ? [payload.tools] : void 0,
869
- systemInstruction: payload.systemInstruction
870
- }
871
- });
872
- const response = await chat.sendMessage({ message: lastMessage.parts });
963
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
964
+ const contents = jigGoogleMessages(payload.messages);
965
+ const requestBody = {
966
+ contents,
967
+ generationConfig: { responseModalities: ["TEXT"] }
968
+ };
969
+ if (payload.tools)
970
+ requestBody.tools = [payload.tools];
971
+ if (payload.systemInstruction) {
972
+ requestBody.systemInstruction = {
973
+ parts: [{ text: payload.systemInstruction }]
974
+ };
975
+ }
976
+ let response;
977
+ try {
978
+ const httpResponse = await import_axios.default.post(
979
+ `https://generativelanguage.googleapis.com/v1beta/models/${payload.model}:generateContent`,
980
+ requestBody,
981
+ {
982
+ headers: {
983
+ "content-type": "application/json",
984
+ "x-goog-api-key": process.env.GEMINI_API_KEY
985
+ },
986
+ // Per-attempt timeout. Defaults to 60s; callers pass a larger value via
987
+ // payload.requestTimeoutMs for slow, large generations (e.g. single-file
988
+ // app codegen) so a long-but-valid response isn't cut short.
989
+ timeout: (_a = payload.requestTimeoutMs) != null ? _a : 6e4
990
+ }
991
+ );
992
+ response = httpResponse.data;
993
+ } catch (err) {
994
+ const apiError = (_c = (_b = err == null ? void 0 : err.response) == null ? void 0 : _b.data) == null ? void 0 : _c.error;
995
+ const wrapped = new Error(
996
+ (apiError == null ? void 0 : apiError.message) || (err == null ? void 0 : err.message) || "Google AI API request failed"
997
+ );
998
+ wrapped.status = (_e = apiError == null ? void 0 : apiError.status) != null ? _e : (_d = err == null ? void 0 : err.response) == null ? void 0 : _d.status;
999
+ wrapped.code = apiError == null ? void 0 : apiError.code;
1000
+ wrapped.details = apiError == null ? void 0 : apiError.details;
1001
+ wrapped.promptFeedback = (_g = (_f = err == null ? void 0 : err.response) == null ? void 0 : _f.data) == null ? void 0 : _g.promptFeedback;
1002
+ throw wrapped;
1003
+ }
873
1004
  let text = "";
874
1005
  const files = [];
875
- for (const part of ((_c = (_b = (_a = response.candidates) == null ? void 0 : _a[0]) == null ? void 0 : _b.content) == null ? void 0 : _c.parts) || []) {
1006
+ const reasoningParts = [];
1007
+ const functionCalls = [];
1008
+ for (const part of ((_j = (_i = (_h = response.candidates) == null ? void 0 : _h[0]) == null ? void 0 : _i.content) == null ? void 0 : _j.parts) || []) {
1009
+ if (part.thought) {
1010
+ reasoningParts.push(part);
1011
+ continue;
1012
+ }
1013
+ if (part.functionCall) {
1014
+ functionCalls.push({
1015
+ id: (_k = part.functionCall.id) != null ? _k : `call_${functionCalls.length}`,
1016
+ name: (_l = part.functionCall.name) != null ? _l : "",
1017
+ arguments: (_m = part.functionCall.args) != null ? _m : {},
1018
+ thoughtSignature: part.thoughtSignature
1019
+ });
1020
+ continue;
1021
+ }
876
1022
  if (part.text)
877
1023
  text += part.text;
878
- if ((_d = part.inlineData) == null ? void 0 : _d.data) {
1024
+ if ((_n = part.inlineData) == null ? void 0 : _n.data) {
879
1025
  files.push({ mimeType: "image/png", data: part.inlineData.data });
880
1026
  }
881
1027
  }
882
- const functionCalls = (_e = response.functionCalls) == null ? void 0 : _e.map((fc) => {
883
- var _a2, _b2;
884
- return {
885
- name: (_a2 = fc.name) != null ? _a2 : "",
886
- arguments: (_b2 = fc.args) != null ? _b2 : {}
887
- };
888
- });
889
- if (!text && !(functionCalls == null ? void 0 : functionCalls.length) && !files.length) {
890
- const candidate = (_f = response.candidates) == null ? void 0 : _f[0];
1028
+ if (!text && !functionCalls.length && !files.length) {
1029
+ const candidate = (_o = response.candidates) == null ? void 0 : _o[0];
891
1030
  const finishReason = candidate == null ? void 0 : candidate.finishReason;
892
1031
  logger_default.error(id, "Missing text & functions in Google AI API response:", {
893
1032
  finishReason,
@@ -918,13 +1057,14 @@ async function callGoogleAI(id, payload) {
918
1057
  role: "assistant",
919
1058
  content: text || null,
920
1059
  files,
921
- function_call: (functionCalls == null ? void 0 : functionCalls[0]) || null,
922
- function_calls: functionCalls || [],
1060
+ function_call: functionCalls[0] || null,
1061
+ function_calls: functionCalls,
1062
+ reasoningDetails: reasoningParts.length ? reasoningParts : void 0,
923
1063
  usage: response.usageMetadata ? {
924
- prompt_tokens: (_g = response.usageMetadata.promptTokenCount) != null ? _g : 0,
925
- completion_tokens: (_h = response.usageMetadata.candidatesTokenCount) != null ? _h : 0,
926
- total_tokens: (_i = response.usageMetadata.totalTokenCount) != null ? _i : 0,
927
- cached_tokens: (_j = response.usageMetadata.cachedContentTokenCount) != null ? _j : 0
1064
+ prompt_tokens: (_p = response.usageMetadata.promptTokenCount) != null ? _p : 0,
1065
+ completion_tokens: (_q = response.usageMetadata.candidatesTokenCount) != null ? _q : 0,
1066
+ total_tokens: (_r = response.usageMetadata.totalTokenCount) != null ? _r : 0,
1067
+ cached_tokens: (_s = response.usageMetadata.cachedContentTokenCount) != null ? _s : 0
928
1068
  } : null
929
1069
  };
930
1070
  }
@@ -1020,14 +1160,52 @@ async function callGoogleAIWithRetries(id, payload, retries = 5) {
1020
1160
  function normalizeMessageContent(content) {
1021
1161
  return Array.isArray(content) ? content.map((c) => c.type === "text" ? c.text : `[${c.type}]`).join("\n") : content;
1022
1162
  }
1163
+ function prepareOpenAICompatMessages(messages) {
1164
+ var _a;
1165
+ const out = [];
1166
+ for (const message of messages) {
1167
+ if (message.role === "tool") {
1168
+ for (const tr of message.toolResults || []) {
1169
+ out.push({
1170
+ role: "tool",
1171
+ tool_call_id: tr.toolCallId,
1172
+ content: tr.content
1173
+ });
1174
+ }
1175
+ continue;
1176
+ }
1177
+ const outMessage = {
1178
+ role: message.role,
1179
+ content: normalizeMessageContent(message.content)
1180
+ };
1181
+ if ((_a = message.functionCalls) == null ? void 0 : _a.length) {
1182
+ outMessage.tool_calls = message.functionCalls.map((fc, i) => {
1183
+ var _a2;
1184
+ return {
1185
+ id: (_a2 = fc.id) != null ? _a2 : `call_${i}`,
1186
+ type: "function",
1187
+ function: {
1188
+ name: fc.name,
1189
+ arguments: JSON.stringify(fc.arguments)
1190
+ }
1191
+ };
1192
+ });
1193
+ if (!message.content)
1194
+ outMessage.content = null;
1195
+ }
1196
+ if (message.reasoning)
1197
+ outMessage.reasoning = message.reasoning;
1198
+ if (message.reasoningDetails)
1199
+ outMessage.reasoning_details = message.reasoningDetails;
1200
+ out.push(outMessage);
1201
+ }
1202
+ return out;
1203
+ }
1023
1204
  function prepareGroqPayload(payload) {
1024
1205
  var _a;
1025
1206
  return {
1026
1207
  model: payload.model,
1027
- messages: payload.messages.map((message) => ({
1028
- role: message.role,
1029
- content: normalizeMessageContent(message.content)
1030
- })),
1208
+ messages: prepareOpenAICompatMessages(payload.messages),
1031
1209
  tools: (_a = payload.functions) == null ? void 0 : _a.map((fn) => ({
1032
1210
  type: "function",
1033
1211
  function: fn
@@ -1037,7 +1215,7 @@ function prepareGroqPayload(payload) {
1037
1215
  };
1038
1216
  }
1039
1217
  async function callGroq(id, payload) {
1040
- var _a, _b, _c, _d;
1218
+ var _a, _b, _c, _d, _e, _f, _g;
1041
1219
  const response = await import_axios.default.post(
1042
1220
  "https://api.groq.com/openai/v1/chat/completions",
1043
1221
  payload,
@@ -1048,15 +1226,21 @@ async function callGroq(id, payload) {
1048
1226
  }
1049
1227
  }
1050
1228
  );
1051
- const answer = (_a = response.data.choices[0]) == null ? void 0 : _a.message;
1229
+ if (response.data.error) {
1230
+ logger_default.error(id, "Groq error:", response.data.error);
1231
+ throw new Error(`Groq error: ${response.data.error.message}`);
1232
+ }
1233
+ const answer = (_b = (_a = response.data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.message;
1052
1234
  if (!answer) {
1053
1235
  logger_default.error(id, "Missing answer in Groq API response:", response.data);
1054
1236
  throw new Error("Missing answer in Groq API");
1055
1237
  }
1056
1238
  const functionCalls = [];
1057
- if ((_b = answer.tool_calls) == null ? void 0 : _b.length) {
1058
- for (const tc of answer.tool_calls) {
1239
+ if ((_c = answer.tool_calls) == null ? void 0 : _c.length) {
1240
+ for (let i = 0; i < answer.tool_calls.length; i++) {
1241
+ const tc = answer.tool_calls[i];
1059
1242
  functionCalls.push({
1243
+ id: (_d = tc.id) != null ? _d : `call_${i}`,
1060
1244
  name: tc.function.name,
1061
1245
  arguments: JSON.parse(tc.function.arguments)
1062
1246
  });
@@ -1078,11 +1262,12 @@ async function callGroq(id, payload) {
1078
1262
  function_call: functionCalls[0] || null,
1079
1263
  function_calls: functionCalls,
1080
1264
  files: [],
1265
+ reasoning: (_e = answer.reasoning) != null ? _e : void 0,
1081
1266
  usage: response.data.usage ? {
1082
1267
  prompt_tokens: response.data.usage.prompt_tokens,
1083
1268
  completion_tokens: response.data.usage.completion_tokens,
1084
1269
  total_tokens: response.data.usage.total_tokens,
1085
- cached_tokens: (_d = (_c = response.data.usage.prompt_tokens_details) == null ? void 0 : _c.cached_tokens) != null ? _d : 0
1270
+ cached_tokens: (_g = (_f = response.data.usage.prompt_tokens_details) == null ? void 0 : _f.cached_tokens) != null ? _g : 0
1086
1271
  } : null
1087
1272
  };
1088
1273
  }
@@ -1093,10 +1278,7 @@ function prepareOpenRouterPayload(payload) {
1093
1278
  var _a;
1094
1279
  return {
1095
1280
  model: payload.model,
1096
- messages: payload.messages.map((message) => ({
1097
- role: message.role,
1098
- content: normalizeMessageContent(message.content)
1099
- })),
1281
+ messages: prepareOpenAICompatMessages(payload.messages),
1100
1282
  tools: (_a = payload.functions) == null ? void 0 : _a.map((fn) => ({
1101
1283
  type: "function",
1102
1284
  function: fn
@@ -1107,7 +1289,7 @@ function prepareOpenRouterPayload(payload) {
1107
1289
  };
1108
1290
  }
1109
1291
  async function callOpenRouter(id, payload) {
1110
- var _a, _b, _c, _d;
1292
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1111
1293
  const response = await import_axios.default.post(
1112
1294
  "https://openrouter.ai/api/v1/chat/completions",
1113
1295
  payload,
@@ -1118,15 +1300,21 @@ async function callOpenRouter(id, payload) {
1118
1300
  }
1119
1301
  }
1120
1302
  );
1121
- const answer = (_a = response.data.choices[0]) == null ? void 0 : _a.message;
1303
+ if (response.data.error) {
1304
+ logger_default.error(id, "OpenRouter error:", response.data.error);
1305
+ throw new Error(`OpenRouter error: ${response.data.error.message}`);
1306
+ }
1307
+ const answer = (_b = (_a = response.data.choices) == null ? void 0 : _a[0]) == null ? void 0 : _b.message;
1122
1308
  if (!answer) {
1123
1309
  logger_default.error(id, "Missing answer in OpenRouter API response:", response.data);
1124
1310
  throw new Error("Missing answer in OpenRouter API");
1125
1311
  }
1126
1312
  const functionCalls = [];
1127
- if ((_b = answer.tool_calls) == null ? void 0 : _b.length) {
1128
- for (const tc of answer.tool_calls) {
1313
+ if ((_c = answer.tool_calls) == null ? void 0 : _c.length) {
1314
+ for (let i = 0; i < answer.tool_calls.length; i++) {
1315
+ const tc = answer.tool_calls[i];
1129
1316
  functionCalls.push({
1317
+ id: (_d = tc.id) != null ? _d : `call_${i}`,
1130
1318
  name: tc.function.name,
1131
1319
  arguments: JSON.parse(tc.function.arguments)
1132
1320
  });
@@ -1148,11 +1336,13 @@ async function callOpenRouter(id, payload) {
1148
1336
  function_call: functionCalls[0] || null,
1149
1337
  function_calls: functionCalls,
1150
1338
  files: [],
1339
+ reasoning: (_e = answer.reasoning) != null ? _e : void 0,
1340
+ reasoningDetails: (_f = answer.reasoning_details) != null ? _f : void 0,
1151
1341
  usage: response.data.usage ? {
1152
1342
  prompt_tokens: response.data.usage.prompt_tokens,
1153
1343
  completion_tokens: response.data.usage.completion_tokens,
1154
1344
  total_tokens: response.data.usage.total_tokens,
1155
- cached_tokens: (_d = (_c = response.data.usage.prompt_tokens_details) == null ? void 0 : _c.cached_tokens) != null ? _d : 0
1345
+ cached_tokens: (_h = (_g = response.data.usage.prompt_tokens_details) == null ? void 0 : _g.cached_tokens) != null ? _h : 0
1156
1346
  } : null
1157
1347
  };
1158
1348
  }