@ai-sdk/xai 4.0.49 → 4.0.51

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/xai",
3
- "version": "4.0.49",
3
+ "version": "4.0.51",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -29,8 +29,8 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@ai-sdk/provider": "4.0.8",
33
- "@ai-sdk/provider-utils": "5.0.33"
32
+ "@ai-sdk/provider": "4.0.9",
33
+ "@ai-sdk/provider-utils": "5.0.34"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@ai-sdk/test-server": "2.0.1",
@@ -481,8 +481,8 @@ function convertXaiChatBatchResponse(
481
481
  };
482
482
  }
483
483
 
484
- const choice = response.choices?.[0];
485
- if (choice == null) {
484
+ const choices = response.choices;
485
+ if (choices == null || choices.length === 0) {
486
486
  return {
487
487
  success: false,
488
488
  error: {
@@ -492,19 +492,54 @@ function convertXaiChatBatchResponse(
492
492
  };
493
493
  }
494
494
 
495
- if (choice.message.tool_calls?.length) {
496
- return unsupportedXaiBatchContent('tool_calls');
497
- }
498
-
499
495
  const content: LanguageModelV4Content[] = [];
500
- if (choice.message.content) {
501
- content.push({ type: 'text', text: choice.message.content });
502
- }
503
- if (choice.message.reasoning_content) {
504
- content.push({
505
- type: 'reasoning',
506
- text: choice.message.reasoning_content,
507
- });
496
+ const providerExecutedToolCallIds = new Set(
497
+ choices
498
+ .filter(choice => choice.message.role === 'tool')
499
+ .flatMap(choice =>
500
+ (choice.message.tool_calls ?? []).map(toolCall => toolCall.id),
501
+ ),
502
+ );
503
+ let lastAssistantChoice: (typeof choices)[number] | undefined;
504
+
505
+ for (const choice of choices) {
506
+ if (choice.message.role === 'tool') {
507
+ if (choice.message.content != null) {
508
+ for (const toolCall of choice.message.tool_calls ?? []) {
509
+ content.push({
510
+ type: 'tool-result',
511
+ toolCallId: toolCall.id,
512
+ toolName: toolCall.function.name,
513
+ result: choice.message.content,
514
+ dynamic: true,
515
+ });
516
+ }
517
+ }
518
+ continue;
519
+ }
520
+
521
+ lastAssistantChoice = choice;
522
+
523
+ if (choice.message.content) {
524
+ content.push({ type: 'text', text: choice.message.content });
525
+ }
526
+ if (choice.message.reasoning_content) {
527
+ content.push({
528
+ type: 'reasoning',
529
+ text: choice.message.reasoning_content,
530
+ });
531
+ }
532
+ for (const toolCall of choice.message.tool_calls ?? []) {
533
+ content.push({
534
+ type: 'tool-call',
535
+ toolCallId: toolCall.id,
536
+ toolName: toolCall.function.name,
537
+ input: toolCall.function.arguments,
538
+ ...(providerExecutedToolCallIds.has(toolCall.id)
539
+ ? { providerExecuted: true, dynamic: true }
540
+ : {}),
541
+ });
542
+ }
508
543
  }
509
544
  for (const url of response.citations ?? []) {
510
545
  content.push({
@@ -520,8 +555,8 @@ function convertXaiChatBatchResponse(
520
555
  result: {
521
556
  content,
522
557
  finishReason: {
523
- unified: mapXaiFinishReason(choice.finish_reason),
524
- raw: choice.finish_reason ?? undefined,
558
+ unified: mapXaiFinishReason(lastAssistantChoice?.finish_reason),
559
+ raw: lastAssistantChoice?.finish_reason ?? undefined,
525
560
  },
526
561
  usage: response.usage
527
562
  ? convertXaiChatUsage(response.usage)
@@ -544,15 +579,3 @@ function convertXaiChatBatchResponse(
544
579
  },
545
580
  };
546
581
  }
547
-
548
- function unsupportedXaiBatchContent(type: string): XaiBatchResponseConversion {
549
- return {
550
- success: false,
551
- error: {
552
- message:
553
- `xAI returned "${type}" content, but tool content is not supported ` +
554
- 'in AI SDK text batches.',
555
- code: 'unsupported_content',
556
- },
557
- };
558
- }
@@ -709,7 +709,7 @@ export const xaiChatResponseSchema = z.object({
709
709
  .array(
710
710
  z.object({
711
711
  message: z.object({
712
- role: z.literal('assistant'),
712
+ role: z.enum(['assistant', 'tool']),
713
713
  content: z.string().nullish(),
714
714
  reasoning_content: z.string().nullish(),
715
715
  tool_calls: z