@providerprotocol/ai 0.0.22 → 0.0.24

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 (51) hide show
  1. package/README.md +188 -6
  2. package/dist/anthropic/index.d.ts +1 -1
  3. package/dist/anthropic/index.js +95 -36
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/{chunk-7WYBJPJJ.js → chunk-55X3W2MN.js} +4 -3
  6. package/dist/chunk-55X3W2MN.js.map +1 -0
  7. package/dist/{chunk-M4BMM5IB.js → chunk-6AZVUI6H.js} +20 -4
  8. package/dist/chunk-6AZVUI6H.js.map +1 -0
  9. package/dist/chunk-73IIE3QT.js +120 -0
  10. package/dist/chunk-73IIE3QT.js.map +1 -0
  11. package/dist/{chunk-RFWLEFAB.js → chunk-QNJO7DSD.js} +61 -16
  12. package/dist/chunk-QNJO7DSD.js.map +1 -0
  13. package/dist/{chunk-RS7C25LS.js → chunk-SBCATNHA.js} +9 -5
  14. package/dist/chunk-SBCATNHA.js.map +1 -0
  15. package/dist/{chunk-NWS5IKNR.js → chunk-TOJCZMVU.js} +3 -12
  16. package/dist/chunk-TOJCZMVU.js.map +1 -0
  17. package/dist/{chunk-I2VHCGQE.js → chunk-Z6DKC37J.js} +6 -5
  18. package/dist/chunk-Z6DKC37J.js.map +1 -0
  19. package/dist/google/index.d.ts +36 -4
  20. package/dist/google/index.js +98 -53
  21. package/dist/google/index.js.map +1 -1
  22. package/dist/http/index.d.ts +2 -2
  23. package/dist/http/index.js +4 -4
  24. package/dist/index.d.ts +8 -6
  25. package/dist/index.js +92 -122
  26. package/dist/index.js.map +1 -1
  27. package/dist/ollama/index.d.ts +5 -2
  28. package/dist/ollama/index.js +47 -36
  29. package/dist/ollama/index.js.map +1 -1
  30. package/dist/openai/index.d.ts +1 -1
  31. package/dist/openai/index.js +117 -56
  32. package/dist/openai/index.js.map +1 -1
  33. package/dist/openrouter/index.d.ts +1 -1
  34. package/dist/openrouter/index.js +58 -53
  35. package/dist/openrouter/index.js.map +1 -1
  36. package/dist/{provider-DWEAzeM5.d.ts → provider-x4RocsnK.d.ts} +199 -54
  37. package/dist/proxy/index.d.ts +2 -2
  38. package/dist/proxy/index.js +11 -9
  39. package/dist/proxy/index.js.map +1 -1
  40. package/dist/{retry-DmPmqZL6.d.ts → retry-DTfjXXPh.d.ts} +1 -1
  41. package/dist/{stream-DbkLOIbJ.d.ts → stream-ITNFNnO4.d.ts} +95 -38
  42. package/dist/xai/index.d.ts +1 -1
  43. package/dist/xai/index.js +221 -97
  44. package/dist/xai/index.js.map +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-7WYBJPJJ.js.map +0 -1
  47. package/dist/chunk-I2VHCGQE.js.map +0 -1
  48. package/dist/chunk-M4BMM5IB.js.map +0 -1
  49. package/dist/chunk-NWS5IKNR.js.map +0 -1
  50. package/dist/chunk-RFWLEFAB.js.map +0 -1
  51. package/dist/chunk-RS7C25LS.js.map +0 -1
package/dist/xai/index.js CHANGED
@@ -3,7 +3,10 @@ import {
3
3
  } from "../chunk-WAKD3OO5.js";
4
4
  import {
5
5
  parseJsonResponse
6
- } from "../chunk-I2VHCGQE.js";
6
+ } from "../chunk-Z6DKC37J.js";
7
+ import {
8
+ StreamEventType
9
+ } from "../chunk-73IIE3QT.js";
7
10
  import {
8
11
  AssistantMessage,
9
12
  createProvider,
@@ -11,20 +14,22 @@ import {
11
14
  isAssistantMessage,
12
15
  isToolResultMessage,
13
16
  isUserMessage
14
- } from "../chunk-M4BMM5IB.js";
17
+ } from "../chunk-6AZVUI6H.js";
15
18
  import {
16
19
  parseSSEStream
17
- } from "../chunk-NWS5IKNR.js";
20
+ } from "../chunk-TOJCZMVU.js";
18
21
  import {
19
22
  resolveApiKey
20
- } from "../chunk-7WYBJPJJ.js";
23
+ } from "../chunk-55X3W2MN.js";
21
24
  import {
25
+ ErrorCode,
26
+ ModalityType,
22
27
  UPPError,
23
28
  doFetch,
24
29
  doStreamFetch,
25
30
  normalizeHttpError,
26
31
  toError
27
- } from "../chunk-RFWLEFAB.js";
32
+ } from "../chunk-QNJO7DSD.js";
28
33
 
29
34
  // src/providers/xai/transform.completions.ts
30
35
  function transformRequest(request, modelId) {
@@ -65,9 +70,9 @@ function normalizeSystem(system) {
65
70
  if (!Array.isArray(system)) {
66
71
  throw new UPPError(
67
72
  "System prompt must be a string or an array of text blocks",
68
- "INVALID_REQUEST",
73
+ ErrorCode.InvalidRequest,
69
74
  "xai",
70
- "llm"
75
+ ModalityType.LLM
71
76
  );
72
77
  }
73
78
  const texts = [];
@@ -75,18 +80,18 @@ function normalizeSystem(system) {
75
80
  if (!block || typeof block !== "object" || !("text" in block)) {
76
81
  throw new UPPError(
77
82
  "System prompt array must contain objects with a text field",
78
- "INVALID_REQUEST",
83
+ ErrorCode.InvalidRequest,
79
84
  "xai",
80
- "llm"
85
+ ModalityType.LLM
81
86
  );
82
87
  }
83
88
  const textValue = block.text;
84
89
  if (typeof textValue !== "string") {
85
90
  throw new UPPError(
86
91
  "System prompt text must be a string",
87
- "INVALID_REQUEST",
92
+ ErrorCode.InvalidRequest,
88
93
  "xai",
89
- "llm"
94
+ ModalityType.LLM
90
95
  );
91
96
  }
92
97
  if (textValue.length > 0) {
@@ -223,10 +228,13 @@ function transformResponse(data) {
223
228
  if (!choice) {
224
229
  throw new Error("No choices in xAI response");
225
230
  }
226
- const textContent = [];
231
+ const content = [];
227
232
  let structuredData;
233
+ if (choice.message.reasoning_content) {
234
+ content.push({ type: "reasoning", text: choice.message.reasoning_content });
235
+ }
228
236
  if (choice.message.content) {
229
- textContent.push({ type: "text", text: choice.message.content });
237
+ content.push({ type: "text", text: choice.message.content });
230
238
  try {
231
239
  structuredData = JSON.parse(choice.message.content);
232
240
  } catch {
@@ -234,7 +242,7 @@ function transformResponse(data) {
234
242
  }
235
243
  let hadRefusal = false;
236
244
  if (choice.message.refusal) {
237
- textContent.push({ type: "text", text: choice.message.refusal });
245
+ content.push({ type: "text", text: choice.message.refusal });
238
246
  hadRefusal = true;
239
247
  }
240
248
  const toolCalls = [];
@@ -254,7 +262,7 @@ function transformResponse(data) {
254
262
  }
255
263
  const responseId = data.id || generateId();
256
264
  const message = new AssistantMessage(
257
- textContent,
265
+ content,
258
266
  toolCalls.length > 0 ? toolCalls : void 0,
259
267
  {
260
268
  id: responseId,
@@ -306,6 +314,7 @@ function createStreamState() {
306
314
  id: "",
307
315
  model: "",
308
316
  text: "",
317
+ reasoning: "",
309
318
  toolCalls: /* @__PURE__ */ new Map(),
310
319
  finishReason: null,
311
320
  inputTokens: 0,
@@ -318,17 +327,25 @@ function transformStreamEvent(chunk, state) {
318
327
  const events = [];
319
328
  if (chunk.id && !state.id) {
320
329
  state.id = chunk.id;
321
- events.push({ type: "message_start", index: 0, delta: {} });
330
+ events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });
322
331
  }
323
332
  if (chunk.model) {
324
333
  state.model = chunk.model;
325
334
  }
326
335
  const choice = chunk.choices[0];
327
336
  if (choice) {
337
+ if (choice.delta.reasoning_content) {
338
+ state.reasoning += choice.delta.reasoning_content;
339
+ events.push({
340
+ type: StreamEventType.ReasoningDelta,
341
+ index: 0,
342
+ delta: { text: choice.delta.reasoning_content }
343
+ });
344
+ }
328
345
  if (choice.delta.content) {
329
346
  state.text += choice.delta.content;
330
347
  events.push({
331
- type: "text_delta",
348
+ type: StreamEventType.TextDelta,
332
349
  index: 0,
333
350
  delta: { text: choice.delta.content }
334
351
  });
@@ -337,7 +354,7 @@ function transformStreamEvent(chunk, state) {
337
354
  state.hadRefusal = true;
338
355
  state.text += choice.delta.refusal;
339
356
  events.push({
340
- type: "text_delta",
357
+ type: StreamEventType.TextDelta,
341
358
  index: 0,
342
359
  delta: { text: choice.delta.refusal }
343
360
  });
@@ -359,7 +376,7 @@ function transformStreamEvent(chunk, state) {
359
376
  if (toolCallDelta.function?.arguments) {
360
377
  toolCall.arguments += toolCallDelta.function.arguments;
361
378
  events.push({
362
- type: "tool_call_delta",
379
+ type: StreamEventType.ToolCallDelta,
363
380
  index,
364
381
  delta: {
365
382
  toolCallId: toolCall.id,
@@ -372,7 +389,7 @@ function transformStreamEvent(chunk, state) {
372
389
  }
373
390
  if (choice.finish_reason) {
374
391
  state.finishReason = choice.finish_reason;
375
- events.push({ type: "message_stop", index: 0, delta: {} });
392
+ events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
376
393
  }
377
394
  }
378
395
  if (chunk.usage) {
@@ -383,10 +400,13 @@ function transformStreamEvent(chunk, state) {
383
400
  return events;
384
401
  }
385
402
  function buildResponseFromState(state) {
386
- const textContent = [];
403
+ const content = [];
387
404
  let structuredData;
405
+ if (state.reasoning) {
406
+ content.push({ type: "reasoning", text: state.reasoning });
407
+ }
388
408
  if (state.text) {
389
- textContent.push({ type: "text", text: state.text });
409
+ content.push({ type: "text", text: state.text });
390
410
  try {
391
411
  structuredData = JSON.parse(state.text);
392
412
  } catch {
@@ -409,7 +429,7 @@ function buildResponseFromState(state) {
409
429
  }
410
430
  const messageId = state.id || generateId();
411
431
  const message = new AssistantMessage(
412
- textContent,
432
+ content,
413
433
  toolCalls.length > 0 ? toolCalls : void 0,
414
434
  {
415
435
  id: messageId,
@@ -474,9 +494,9 @@ function createCompletionsLLMHandler() {
474
494
  if (!providerRef) {
475
495
  throw new UPPError(
476
496
  "Provider reference not set. Handler must be used with createProvider() or have _setProvider called.",
477
- "INVALID_REQUEST",
497
+ ErrorCode.InvalidRequest,
478
498
  "xai",
479
- "llm"
499
+ ModalityType.LLM
480
500
  );
481
501
  }
482
502
  const model = {
@@ -572,9 +592,9 @@ function createCompletionsLLMHandler() {
572
592
  if (!response.body) {
573
593
  const error = new UPPError(
574
594
  "No response body for streaming request",
575
- "PROVIDER_ERROR",
595
+ ErrorCode.ProviderError,
576
596
  "xai",
577
- "llm"
597
+ ModalityType.LLM
578
598
  );
579
599
  responseReject(error);
580
600
  throw error;
@@ -589,9 +609,9 @@ function createCompletionsLLMHandler() {
589
609
  const errorData = chunk.error;
590
610
  const error = new UPPError(
591
611
  errorData.message ?? "Unknown error",
592
- "PROVIDER_ERROR",
612
+ ErrorCode.ProviderError,
593
613
  "xai",
594
- "llm"
614
+ ModalityType.LLM
595
615
  );
596
616
  responseReject(error);
597
617
  throw error;
@@ -667,9 +687,9 @@ function normalizeSystem2(system) {
667
687
  if (!Array.isArray(system)) {
668
688
  throw new UPPError(
669
689
  "System prompt must be a string or an array of text blocks",
670
- "INVALID_REQUEST",
690
+ ErrorCode.InvalidRequest,
671
691
  "xai",
672
- "llm"
692
+ ModalityType.LLM
673
693
  );
674
694
  }
675
695
  const texts = [];
@@ -677,18 +697,18 @@ function normalizeSystem2(system) {
677
697
  if (!block || typeof block !== "object" || !("text" in block)) {
678
698
  throw new UPPError(
679
699
  "System prompt array must contain objects with a text field",
680
- "INVALID_REQUEST",
700
+ ErrorCode.InvalidRequest,
681
701
  "xai",
682
- "llm"
702
+ ModalityType.LLM
683
703
  );
684
704
  }
685
705
  const textValue = block.text;
686
706
  if (typeof textValue !== "string") {
687
707
  throw new UPPError(
688
708
  "System prompt text must be a string",
689
- "INVALID_REQUEST",
709
+ ErrorCode.InvalidRequest,
690
710
  "xai",
691
- "llm"
711
+ ModalityType.LLM
692
712
  );
693
713
  }
694
714
  if (textValue.length > 0) {
@@ -755,6 +775,23 @@ function transformMessage2(message) {
755
775
  }
756
776
  const xaiMeta = message.metadata?.xai;
757
777
  const functionCallItems = xaiMeta?.functionCallItems;
778
+ if (xaiMeta?.reasoningEncryptedContent) {
779
+ try {
780
+ const reasoningData = JSON.parse(xaiMeta.reasoningEncryptedContent);
781
+ if (reasoningData.encrypted_content) {
782
+ const reasoningItem = {
783
+ type: "reasoning",
784
+ id: reasoningData.id,
785
+ encrypted_content: reasoningData.encrypted_content
786
+ };
787
+ if (Array.isArray(reasoningData.summary)) {
788
+ reasoningItem.summary = reasoningData.summary;
789
+ }
790
+ items.push(reasoningItem);
791
+ }
792
+ } catch {
793
+ }
794
+ }
758
795
  if (functionCallItems && functionCallItems.length > 0) {
759
796
  for (const fc of functionCallItems) {
760
797
  items.push({
@@ -834,25 +871,26 @@ function transformTool2(tool) {
834
871
  };
835
872
  }
836
873
  function transformResponse2(data) {
837
- const textContent = [];
874
+ const content = [];
838
875
  const toolCalls = [];
839
876
  const functionCallItems = [];
840
877
  let hadRefusal = false;
841
878
  let structuredData;
879
+ let reasoningEncryptedContent;
842
880
  for (const item of data.output) {
843
881
  if (item.type === "message") {
844
882
  const messageItem = item;
845
- for (const content of messageItem.content) {
846
- if (content.type === "output_text") {
847
- textContent.push({ type: "text", text: content.text });
883
+ for (const outputContent of messageItem.content) {
884
+ if (outputContent.type === "output_text") {
885
+ content.push({ type: "text", text: outputContent.text });
848
886
  if (structuredData === void 0) {
849
887
  try {
850
- structuredData = JSON.parse(content.text);
888
+ structuredData = JSON.parse(outputContent.text);
851
889
  } catch {
852
890
  }
853
891
  }
854
- } else if (content.type === "refusal") {
855
- textContent.push({ type: "text", text: content.refusal });
892
+ } else if (outputContent.type === "refusal") {
893
+ content.push({ type: "text", text: outputContent.refusal });
856
894
  hadRefusal = true;
857
895
  }
858
896
  }
@@ -874,11 +912,24 @@ function transformResponse2(data) {
874
912
  name: functionCall.name,
875
913
  arguments: functionCall.arguments
876
914
  });
915
+ } else if (item.type === "reasoning") {
916
+ const reasoningItem = item;
917
+ if (reasoningItem.summary) {
918
+ const reasoningText = reasoningItem.summary.filter((s) => s.type === "summary_text").map((s) => s.text).join("");
919
+ if (reasoningText) {
920
+ content.push({ type: "reasoning", text: reasoningText });
921
+ }
922
+ }
923
+ reasoningEncryptedContent = JSON.stringify({
924
+ id: reasoningItem.id,
925
+ summary: reasoningItem.summary,
926
+ encrypted_content: reasoningItem.encrypted_content
927
+ });
877
928
  }
878
929
  }
879
930
  const responseId = data.id || generateId();
880
931
  const message = new AssistantMessage(
881
- textContent,
932
+ content,
882
933
  toolCalls.length > 0 ? toolCalls : void 0,
883
934
  {
884
935
  id: responseId,
@@ -889,7 +940,8 @@ function transformResponse2(data) {
889
940
  response_id: responseId,
890
941
  functionCallItems: functionCallItems.length > 0 ? functionCallItems : void 0,
891
942
  citations: data.citations,
892
- inline_citations: data.inline_citations
943
+ inline_citations: data.inline_citations,
944
+ reasoningEncryptedContent
893
945
  }
894
946
  }
895
947
  }
@@ -924,6 +976,7 @@ function createStreamState2() {
924
976
  id: "",
925
977
  model: "",
926
978
  textByIndex: /* @__PURE__ */ new Map(),
979
+ reasoningByIndex: /* @__PURE__ */ new Map(),
927
980
  toolCalls: /* @__PURE__ */ new Map(),
928
981
  status: "in_progress",
929
982
  inputTokens: 0,
@@ -938,7 +991,7 @@ function transformStreamEvent2(event, state) {
938
991
  case "response.created":
939
992
  state.id = event.response.id;
940
993
  state.model = event.response.model;
941
- events.push({ type: "message_start", index: 0, delta: {} });
994
+ events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });
942
995
  break;
943
996
  case "response.in_progress":
944
997
  state.status = "in_progress";
@@ -950,11 +1003,11 @@ function transformStreamEvent2(event, state) {
950
1003
  state.outputTokens = event.response.usage.output_tokens;
951
1004
  state.cacheReadTokens = event.response.usage.input_tokens_details?.cached_tokens ?? 0;
952
1005
  }
953
- events.push({ type: "message_stop", index: 0, delta: {} });
1006
+ events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
954
1007
  break;
955
1008
  case "response.failed":
956
1009
  state.status = "failed";
957
- events.push({ type: "message_stop", index: 0, delta: {} });
1010
+ events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
958
1011
  break;
959
1012
  case "response.output_item.added":
960
1013
  if (event.item.type === "function_call") {
@@ -971,7 +1024,7 @@ function transformStreamEvent2(event, state) {
971
1024
  state.toolCalls.set(event.output_index, existing);
972
1025
  }
973
1026
  events.push({
974
- type: "content_block_start",
1027
+ type: StreamEventType.ContentBlockStart,
975
1028
  index: event.output_index,
976
1029
  delta: {}
977
1030
  });
@@ -989,9 +1042,16 @@ function transformStreamEvent2(event, state) {
989
1042
  existing.arguments = functionCall.arguments;
990
1043
  }
991
1044
  state.toolCalls.set(event.output_index, existing);
1045
+ } else if (event.item.type === "reasoning") {
1046
+ const reasoningItem = event.item;
1047
+ state.reasoningEncryptedContent = JSON.stringify({
1048
+ id: reasoningItem.id,
1049
+ summary: reasoningItem.summary,
1050
+ encrypted_content: reasoningItem.encrypted_content
1051
+ });
992
1052
  }
993
1053
  events.push({
994
- type: "content_block_stop",
1054
+ type: StreamEventType.ContentBlockStop,
995
1055
  index: event.output_index,
996
1056
  delta: {}
997
1057
  });
@@ -1000,7 +1060,7 @@ function transformStreamEvent2(event, state) {
1000
1060
  const currentText = state.textByIndex.get(event.output_index) ?? "";
1001
1061
  state.textByIndex.set(event.output_index, currentText + event.delta);
1002
1062
  events.push({
1003
- type: "text_delta",
1063
+ type: StreamEventType.TextDelta,
1004
1064
  index: event.output_index,
1005
1065
  delta: { text: event.delta }
1006
1066
  });
@@ -1014,7 +1074,7 @@ function transformStreamEvent2(event, state) {
1014
1074
  const currentRefusal = state.textByIndex.get(event.output_index) ?? "";
1015
1075
  state.textByIndex.set(event.output_index, currentRefusal + event.delta);
1016
1076
  events.push({
1017
- type: "text_delta",
1077
+ type: StreamEventType.TextDelta,
1018
1078
  index: event.output_index,
1019
1079
  delta: { text: event.delta }
1020
1080
  });
@@ -1038,7 +1098,7 @@ function transformStreamEvent2(event, state) {
1038
1098
  }
1039
1099
  toolCall.arguments += event.delta;
1040
1100
  events.push({
1041
- type: "tool_call_delta",
1101
+ type: StreamEventType.ToolCallDelta,
1042
1102
  index: event.output_index,
1043
1103
  delta: {
1044
1104
  toolCallId: toolCall.callId ?? toolCall.itemId ?? "",
@@ -1064,6 +1124,19 @@ function transformStreamEvent2(event, state) {
1064
1124
  toolCall.arguments = event.arguments;
1065
1125
  break;
1066
1126
  }
1127
+ case "response.reasoning_summary_text.delta": {
1128
+ const currentReasoning = state.reasoningByIndex.get(event.output_index) ?? "";
1129
+ state.reasoningByIndex.set(event.output_index, currentReasoning + event.delta);
1130
+ events.push({
1131
+ type: StreamEventType.ReasoningDelta,
1132
+ index: event.output_index,
1133
+ delta: { text: event.delta }
1134
+ });
1135
+ break;
1136
+ }
1137
+ case "response.reasoning_summary_text.done":
1138
+ state.reasoningByIndex.set(event.output_index, event.text);
1139
+ break;
1067
1140
  case "error":
1068
1141
  break;
1069
1142
  default:
@@ -1072,11 +1145,22 @@ function transformStreamEvent2(event, state) {
1072
1145
  return events;
1073
1146
  }
1074
1147
  function buildResponseFromState2(state) {
1075
- const textContent = [];
1148
+ const content = [];
1076
1149
  let structuredData;
1077
- for (const [, text] of state.textByIndex) {
1150
+ const orderedReasoningEntries = [...state.reasoningByIndex.entries()].sort(
1151
+ ([leftIndex], [rightIndex]) => leftIndex - rightIndex
1152
+ );
1153
+ for (const [, reasoning] of orderedReasoningEntries) {
1154
+ if (reasoning) {
1155
+ content.push({ type: "reasoning", text: reasoning });
1156
+ }
1157
+ }
1158
+ const orderedTextEntries = [...state.textByIndex.entries()].sort(
1159
+ ([leftIndex], [rightIndex]) => leftIndex - rightIndex
1160
+ );
1161
+ for (const [, text] of orderedTextEntries) {
1078
1162
  if (text) {
1079
- textContent.push({ type: "text", text });
1163
+ content.push({ type: "text", text });
1080
1164
  if (structuredData === void 0) {
1081
1165
  try {
1082
1166
  structuredData = JSON.parse(text);
@@ -1114,7 +1198,7 @@ function buildResponseFromState2(state) {
1114
1198
  }
1115
1199
  const responseId = state.id || generateId();
1116
1200
  const message = new AssistantMessage(
1117
- textContent,
1201
+ content,
1118
1202
  toolCalls.length > 0 ? toolCalls : void 0,
1119
1203
  {
1120
1204
  id: responseId,
@@ -1123,7 +1207,8 @@ function buildResponseFromState2(state) {
1123
1207
  model: state.model,
1124
1208
  status: state.status,
1125
1209
  response_id: responseId,
1126
- functionCallItems: functionCallItems.length > 0 ? functionCallItems : void 0
1210
+ functionCallItems: functionCallItems.length > 0 ? functionCallItems : void 0,
1211
+ reasoningEncryptedContent: state.reasoningEncryptedContent
1127
1212
  }
1128
1213
  }
1129
1214
  }
@@ -1172,9 +1257,9 @@ function createResponsesLLMHandler() {
1172
1257
  if (!providerRef) {
1173
1258
  throw new UPPError(
1174
1259
  "Provider reference not set. Handler must be used with createProvider() or have _setProvider called.",
1175
- "INVALID_REQUEST",
1260
+ ErrorCode.InvalidRequest,
1176
1261
  "xai",
1177
- "llm"
1262
+ ModalityType.LLM
1178
1263
  );
1179
1264
  }
1180
1265
  const model = {
@@ -1219,9 +1304,9 @@ function createResponsesLLMHandler() {
1219
1304
  if (data.status === "failed" && data.error) {
1220
1305
  throw new UPPError(
1221
1306
  data.error.message,
1222
- "PROVIDER_ERROR",
1307
+ ErrorCode.ProviderError,
1223
1308
  "xai",
1224
- "llm"
1309
+ ModalityType.LLM
1225
1310
  );
1226
1311
  }
1227
1312
  return transformResponse2(data);
@@ -1277,9 +1362,9 @@ function createResponsesLLMHandler() {
1277
1362
  if (!response.body) {
1278
1363
  const error = new UPPError(
1279
1364
  "No response body for streaming request",
1280
- "PROVIDER_ERROR",
1365
+ ErrorCode.ProviderError,
1281
1366
  "xai",
1282
- "llm"
1367
+ ModalityType.LLM
1283
1368
  );
1284
1369
  responseReject(error);
1285
1370
  throw error;
@@ -1294,9 +1379,9 @@ function createResponsesLLMHandler() {
1294
1379
  const errorEvent = event;
1295
1380
  const error = new UPPError(
1296
1381
  errorEvent.error.message,
1297
- "PROVIDER_ERROR",
1382
+ ErrorCode.ProviderError,
1298
1383
  "xai",
1299
- "llm"
1384
+ ModalityType.LLM
1300
1385
  );
1301
1386
  responseReject(error);
1302
1387
  throw error;
@@ -1334,9 +1419,9 @@ function normalizeSystem3(system) {
1334
1419
  if (!Array.isArray(system)) {
1335
1420
  throw new UPPError(
1336
1421
  "System prompt must be a string or an array of text blocks",
1337
- "INVALID_REQUEST",
1422
+ ErrorCode.InvalidRequest,
1338
1423
  "xai",
1339
- "llm"
1424
+ ModalityType.LLM
1340
1425
  );
1341
1426
  }
1342
1427
  const texts = [];
@@ -1344,18 +1429,18 @@ function normalizeSystem3(system) {
1344
1429
  if (!block || typeof block !== "object" || !("text" in block)) {
1345
1430
  throw new UPPError(
1346
1431
  "System prompt array must contain objects with a text field",
1347
- "INVALID_REQUEST",
1432
+ ErrorCode.InvalidRequest,
1348
1433
  "xai",
1349
- "llm"
1434
+ ModalityType.LLM
1350
1435
  );
1351
1436
  }
1352
1437
  const textValue = block.text;
1353
1438
  if (typeof textValue !== "string") {
1354
1439
  throw new UPPError(
1355
1440
  "System prompt text must be a string",
1356
- "INVALID_REQUEST",
1441
+ ErrorCode.InvalidRequest,
1357
1442
  "xai",
1358
- "llm"
1443
+ ModalityType.LLM
1359
1444
  );
1360
1445
  }
1361
1446
  if (textValue.length > 0) {
@@ -1407,7 +1492,19 @@ function transformMessage3(message) {
1407
1492
  }
1408
1493
  if (isAssistantMessage(message)) {
1409
1494
  const validContent = filterValidContent3(message.content);
1410
- const content = validContent.map(transformContentBlock2);
1495
+ const content = [];
1496
+ const xaiMeta = message.metadata?.xai;
1497
+ for (const block of validContent) {
1498
+ if (block.type === "reasoning") {
1499
+ content.push({
1500
+ type: "thinking",
1501
+ thinking: block.text,
1502
+ signature: xaiMeta?.thinkingSignature
1503
+ });
1504
+ } else {
1505
+ content.push(transformContentBlock2(block));
1506
+ }
1507
+ }
1411
1508
  if (message.toolCalls) {
1412
1509
  for (const call of message.toolCalls) {
1413
1510
  content.push({
@@ -1495,12 +1592,18 @@ function transformTool3(tool) {
1495
1592
  };
1496
1593
  }
1497
1594
  function transformResponse3(data) {
1498
- const textContent = [];
1595
+ const content = [];
1499
1596
  const toolCalls = [];
1500
1597
  let structuredData;
1598
+ let thinkingSignature;
1501
1599
  for (const block of data.content) {
1502
1600
  if (block.type === "text") {
1503
- textContent.push({ type: "text", text: block.text });
1601
+ content.push({ type: "text", text: block.text });
1602
+ } else if (block.type === "thinking") {
1603
+ content.push({ type: "reasoning", text: block.thinking });
1604
+ if (block.signature) {
1605
+ thinkingSignature = block.signature;
1606
+ }
1504
1607
  } else if (block.type === "tool_use") {
1505
1608
  if (block.name === "json_response") {
1506
1609
  structuredData = block.input;
@@ -1513,7 +1616,7 @@ function transformResponse3(data) {
1513
1616
  }
1514
1617
  }
1515
1618
  const message = new AssistantMessage(
1516
- textContent,
1619
+ content,
1517
1620
  toolCalls.length > 0 ? toolCalls : void 0,
1518
1621
  {
1519
1622
  id: data.id,
@@ -1521,7 +1624,9 @@ function transformResponse3(data) {
1521
1624
  xai: {
1522
1625
  stop_reason: data.stop_reason,
1523
1626
  stop_sequence: data.stop_sequence,
1524
- model: data.model
1627
+ model: data.model,
1628
+ // Store thinking signature for multi-turn context
1629
+ thinkingSignature
1525
1630
  }
1526
1631
  }
1527
1632
  }
@@ -1561,11 +1666,13 @@ function transformStreamEvent3(event, state) {
1561
1666
  state.inputTokens = event.message.usage.input_tokens;
1562
1667
  state.cacheReadTokens = event.message.usage.cache_read_input_tokens ?? 0;
1563
1668
  state.cacheWriteTokens = event.message.usage.cache_creation_input_tokens ?? 0;
1564
- return { type: "message_start", index: 0, delta: {} };
1669
+ return { type: StreamEventType.MessageStart, index: 0, delta: {} };
1565
1670
  case "content_block_start":
1566
1671
  state.currentIndex = event.index;
1567
1672
  if (event.content_block.type === "text") {
1568
1673
  state.content[event.index] = { type: "text", text: "" };
1674
+ } else if (event.content_block.type === "thinking") {
1675
+ state.content[event.index] = { type: "thinking", thinking: "" };
1569
1676
  } else if (event.content_block.type === "tool_use") {
1570
1677
  state.content[event.index] = {
1571
1678
  type: "tool_use",
@@ -1574,7 +1681,7 @@ function transformStreamEvent3(event, state) {
1574
1681
  input: ""
1575
1682
  };
1576
1683
  }
1577
- return { type: "content_block_start", index: event.index, delta: {} };
1684
+ return { type: StreamEventType.ContentBlockStart, index: event.index, delta: {} };
1578
1685
  case "content_block_delta": {
1579
1686
  const delta = event.delta;
1580
1687
  const index = event.index ?? state.currentIndex;
@@ -1584,7 +1691,7 @@ function transformStreamEvent3(event, state) {
1584
1691
  }
1585
1692
  state.content[index].text = (state.content[index].text ?? "") + delta.text;
1586
1693
  return {
1587
- type: "text_delta",
1694
+ type: StreamEventType.TextDelta,
1588
1695
  index,
1589
1696
  delta: { text: delta.text }
1590
1697
  };
@@ -1595,7 +1702,7 @@ function transformStreamEvent3(event, state) {
1595
1702
  }
1596
1703
  state.content[index].input = (state.content[index].input ?? "") + delta.partial_json;
1597
1704
  return {
1598
- type: "tool_call_delta",
1705
+ type: StreamEventType.ToolCallDelta,
1599
1706
  index,
1600
1707
  delta: {
1601
1708
  argumentsJson: delta.partial_json,
@@ -1605,22 +1712,32 @@ function transformStreamEvent3(event, state) {
1605
1712
  };
1606
1713
  }
1607
1714
  if (delta.type === "thinking_delta") {
1715
+ if (!state.content[index]) {
1716
+ state.content[index] = { type: "thinking", thinking: "" };
1717
+ }
1718
+ state.content[index].thinking = (state.content[index].thinking ?? "") + delta.thinking;
1608
1719
  return {
1609
- type: "reasoning_delta",
1720
+ type: StreamEventType.ReasoningDelta,
1610
1721
  index,
1611
1722
  delta: { text: delta.thinking }
1612
1723
  };
1613
1724
  }
1725
+ if (delta.type === "signature_delta") {
1726
+ if (state.content[index]) {
1727
+ state.content[index].signature = delta.signature;
1728
+ }
1729
+ return null;
1730
+ }
1614
1731
  return null;
1615
1732
  }
1616
1733
  case "content_block_stop":
1617
- return { type: "content_block_stop", index: event.index ?? state.currentIndex, delta: {} };
1734
+ return { type: StreamEventType.ContentBlockStop, index: event.index ?? state.currentIndex, delta: {} };
1618
1735
  case "message_delta":
1619
1736
  state.stopReason = event.delta.stop_reason;
1620
1737
  state.outputTokens = event.usage.output_tokens;
1621
1738
  return null;
1622
1739
  case "message_stop":
1623
- return { type: "message_stop", index: 0, delta: {} };
1740
+ return { type: StreamEventType.MessageStop, index: 0, delta: {} };
1624
1741
  case "ping":
1625
1742
  case "error":
1626
1743
  return null;
@@ -1629,12 +1746,18 @@ function transformStreamEvent3(event, state) {
1629
1746
  }
1630
1747
  }
1631
1748
  function buildResponseFromState3(state) {
1632
- const textContent = [];
1749
+ const content = [];
1633
1750
  const toolCalls = [];
1634
1751
  let structuredData;
1752
+ let thinkingSignature;
1635
1753
  for (const block of state.content) {
1636
1754
  if (block.type === "text" && block.text) {
1637
- textContent.push({ type: "text", text: block.text });
1755
+ content.push({ type: "text", text: block.text });
1756
+ } else if (block.type === "thinking" && block.thinking) {
1757
+ content.push({ type: "reasoning", text: block.thinking });
1758
+ if (block.signature) {
1759
+ thinkingSignature = block.signature;
1760
+ }
1638
1761
  } else if (block.type === "tool_use" && block.id && block.name) {
1639
1762
  let args = {};
1640
1763
  if (block.input) {
@@ -1655,14 +1778,15 @@ function buildResponseFromState3(state) {
1655
1778
  }
1656
1779
  const messageId = state.messageId || generateId();
1657
1780
  const message = new AssistantMessage(
1658
- textContent,
1781
+ content,
1659
1782
  toolCalls.length > 0 ? toolCalls : void 0,
1660
1783
  {
1661
1784
  id: messageId,
1662
1785
  metadata: {
1663
1786
  xai: {
1664
1787
  stop_reason: state.stopReason,
1665
- model: state.model
1788
+ model: state.model,
1789
+ thinkingSignature
1666
1790
  }
1667
1791
  }
1668
1792
  }
@@ -1702,9 +1826,9 @@ function createMessagesLLMHandler() {
1702
1826
  if (!providerRef) {
1703
1827
  throw new UPPError(
1704
1828
  "Provider reference not set. Handler must be used with createProvider() or have _setProvider called.",
1705
- "INVALID_REQUEST",
1829
+ ErrorCode.InvalidRequest,
1706
1830
  "xai",
1707
- "llm"
1831
+ ModalityType.LLM
1708
1832
  );
1709
1833
  }
1710
1834
  const model = {
@@ -1801,9 +1925,9 @@ function createMessagesLLMHandler() {
1801
1925
  if (!response.body) {
1802
1926
  const error = new UPPError(
1803
1927
  "No response body for streaming request",
1804
- "PROVIDER_ERROR",
1928
+ ErrorCode.ProviderError,
1805
1929
  "xai",
1806
- "llm"
1930
+ ModalityType.LLM
1807
1931
  );
1808
1932
  responseReject(error);
1809
1933
  throw error;
@@ -1814,9 +1938,9 @@ function createMessagesLLMHandler() {
1814
1938
  if (event.type === "error") {
1815
1939
  const error = new UPPError(
1816
1940
  event.error.message,
1817
- "PROVIDER_ERROR",
1941
+ ErrorCode.ProviderError,
1818
1942
  "xai",
1819
- "llm"
1943
+ ModalityType.LLM
1820
1944
  );
1821
1945
  responseReject(error);
1822
1946
  throw error;
@@ -1867,9 +1991,9 @@ function createImageHandler() {
1867
1991
  if (!providerRef) {
1868
1992
  throw new UPPError(
1869
1993
  "Provider reference not set. Handler must be used with createProvider().",
1870
- "INVALID_REQUEST",
1994
+ ErrorCode.InvalidRequest,
1871
1995
  "xai",
1872
- "image"
1996
+ ModalityType.Image
1873
1997
  );
1874
1998
  }
1875
1999
  const capabilities = getCapabilities(modelId);
@@ -1935,9 +2059,9 @@ function transformResponse4(data) {
1935
2059
  } else {
1936
2060
  throw new UPPError(
1937
2061
  "No image data in response",
1938
- "PROVIDER_ERROR",
2062
+ ErrorCode.ProviderError,
1939
2063
  "xai",
1940
- "image"
2064
+ ModalityType.Image
1941
2065
  );
1942
2066
  }
1943
2067
  return {