@ai-sdk/xai 4.0.0-beta.36 → 4.0.0-beta.37

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.0-beta.36",
3
+ "version": "4.0.0-beta.37",
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/openai-compatible": "3.0.0-beta.25",
33
32
  "@ai-sdk/provider-utils": "5.0.0-beta.20",
33
+ "@ai-sdk/openai-compatible": "3.0.0-beta.25",
34
34
  "@ai-sdk/provider": "4.0.0-beta.12"
35
35
  },
36
36
  "devDependencies": {
@@ -135,7 +135,48 @@ export async function convertToXaiResponsesInput({
135
135
  break;
136
136
  }
137
137
 
138
- case 'reasoning':
138
+ case 'reasoning': {
139
+ const itemId =
140
+ typeof part.providerOptions?.xai?.itemId === 'string'
141
+ ? part.providerOptions.xai.itemId
142
+ : undefined;
143
+ const encryptedContent =
144
+ typeof part.providerOptions?.xai?.reasoningEncryptedContent ===
145
+ 'string'
146
+ ? part.providerOptions.xai.reasoningEncryptedContent
147
+ : undefined;
148
+
149
+ if (itemId != null || encryptedContent != null) {
150
+ const summaryParts: Array<{
151
+ type: 'summary_text';
152
+ text: string;
153
+ }> = [];
154
+ if (part.text.length > 0) {
155
+ summaryParts.push({
156
+ type: 'summary_text',
157
+ text: part.text,
158
+ });
159
+ }
160
+
161
+ input.push({
162
+ type: 'reasoning',
163
+ id: itemId ?? '',
164
+ summary: summaryParts,
165
+ status: 'completed',
166
+ ...(encryptedContent != null && {
167
+ encrypted_content: encryptedContent,
168
+ }),
169
+ });
170
+ } else {
171
+ inputWarnings.push({
172
+ type: 'other',
173
+ message:
174
+ 'Reasoning parts without itemId or encrypted content cannot be sent back to xAI. Skipping.',
175
+ });
176
+ }
177
+ break;
178
+ }
179
+
139
180
  case 'reasoning-file':
140
181
  case 'custom':
141
182
  case 'file': {
@@ -130,7 +130,7 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
130
130
 
131
131
  const { input, inputWarnings } = await convertToXaiResponsesInput({
132
132
  prompt,
133
- store: true,
133
+ store: options.store ?? true,
134
134
  });
135
135
  warnings.push(...inputWarnings);
136
136
 
@@ -417,11 +417,13 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
417
417
  .filter(text => text && text.length > 0)
418
418
  .join('');
419
419
 
420
- if (reasoningText) {
421
- if (part.encrypted_content || part.id) {
422
- content.push({
423
- type: 'reasoning',
424
- text: reasoningText,
420
+ // condition changed here since encrypted content can now come with empty reasoning text
421
+ if (reasoningText || part.encrypted_content) {
422
+ const hasMetadata = part.encrypted_content || part.id;
423
+ content.push({
424
+ type: 'reasoning',
425
+ text: reasoningText,
426
+ ...(hasMetadata && {
425
427
  providerMetadata: {
426
428
  xai: {
427
429
  ...(part.encrypted_content && {
@@ -430,13 +432,8 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
430
432
  ...(part.id && { itemId: part.id }),
431
433
  },
432
434
  },
433
- });
434
- } else {
435
- content.push({
436
- type: 'reasoning',
437
- text: reasoningText,
438
- });
439
- }
435
+ }),
436
+ });
440
437
  }
441
438
  break;
442
439
  }
@@ -25,6 +25,8 @@ export const xaiLanguageModelResponsesOptions = z.object({
25
25
  topLogprobs: z.number().int().min(0).max(8).optional(),
26
26
  /**
27
27
  * Whether to store the input message(s) and model response for later retrieval.
28
+ * Must be set to `false` for teams with Zero Data Retention (ZDR) enabled,
29
+ * otherwise the API will return an error.
28
30
  * @default true
29
31
  */
30
32
  store: z.boolean().optional(),