@ai-sdk/xai 4.0.6 → 4.0.8

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.6",
3
+ "version": "4.0.8",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -25,6 +25,7 @@ import {
25
25
  } from '@ai-sdk/provider-utils';
26
26
  import type { z } from 'zod/v4';
27
27
  import { getResponseMetadata } from '../get-response-metadata';
28
+ import { supportsReasoningEffort } from '../supports-reasoning-effort';
28
29
  import { xaiFailedResponseHandler } from '../xai-error';
29
30
  import { convertToXaiResponsesInput } from './convert-to-xai-responses-input';
30
31
  import { convertXaiResponsesUsage } from './convert-xai-responses-usage';
@@ -164,23 +165,30 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
164
165
  }
165
166
  }
166
167
 
167
- const resolvedReasoningEffort =
168
- options.reasoningEffort ??
169
- (isCustomReasoning(reasoning)
170
- ? reasoning === 'none'
171
- ? undefined
172
- : mapReasoningToProviderEffort({
173
- reasoning,
174
- effortMap: {
175
- minimal: 'low',
176
- low: 'low',
177
- medium: 'medium',
178
- high: 'high',
179
- xhigh: 'high',
180
- },
181
- warnings,
182
- })
183
- : undefined);
168
+ let resolvedReasoningEffort = options.reasoningEffort;
169
+ if (resolvedReasoningEffort == null && isCustomReasoning(reasoning)) {
170
+ if (!supportsReasoningEffort(this.modelId)) {
171
+ warnings.push({
172
+ type: 'unsupported',
173
+ feature: 'reasoning',
174
+ details: `reasoning "${reasoning}" is not supported by this model.`,
175
+ });
176
+ } else if (reasoning === 'none') {
177
+ resolvedReasoningEffort = 'none';
178
+ } else {
179
+ resolvedReasoningEffort = mapReasoningToProviderEffort({
180
+ reasoning,
181
+ effortMap: {
182
+ minimal: 'low',
183
+ low: 'low',
184
+ medium: 'medium',
185
+ high: 'high',
186
+ xhigh: 'high',
187
+ },
188
+ warnings,
189
+ });
190
+ }
191
+ }
184
192
 
185
193
  const baseArgs: Record<string, unknown> = {
186
194
  model: this.modelId,
@@ -956,6 +964,15 @@ export class XaiResponsesLanguageModel implements LanguageModelV4 {
956
964
  });
957
965
  }
958
966
 
967
+ if (event.type === 'response.output_item.done') {
968
+ controller.enqueue({
969
+ type: 'tool-result',
970
+ toolCallId: part.id,
971
+ toolName,
972
+ result: {},
973
+ });
974
+ }
975
+
959
976
  return;
960
977
  }
961
978
 
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The grok-4.20 reasoning and non-reasoning models (including dated variants
3
+ * such as `grok-4.20-0309-reasoning`) reject the reasoning effort parameter
4
+ * with an invalid-argument error for every value, including `none`.
5
+ * Other models such as `grok-4.3`, `grok-latest`, and
6
+ * `grok-4.20-multi-agent` accept it.
7
+ */
8
+ const modelsWithoutReasoningEffort = /^grok-4\.20(-\d{4})?-(non-)?reasoning$/;
9
+
10
+ export function supportsReasoningEffort(modelId: string): boolean {
11
+ return !modelsWithoutReasoningEffort.test(modelId);
12
+ }
@@ -31,6 +31,7 @@ import { convertToXaiChatMessages } from './convert-to-xai-chat-messages';
31
31
  import { convertXaiChatUsage } from './convert-xai-chat-usage';
32
32
  import { getResponseMetadata } from './get-response-metadata';
33
33
  import { mapXaiFinishReason } from './map-xai-finish-reason';
34
+ import { supportsReasoningEffort } from './supports-reasoning-effort';
34
35
  import {
35
36
  xaiLanguageModelChatOptions,
36
37
  type XaiChatModelId,
@@ -139,6 +140,31 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
139
140
  });
140
141
  warnings.push(...toolWarnings);
141
142
 
143
+ let reasoningEffort = options.reasoningEffort;
144
+ if (reasoningEffort == null && isCustomReasoning(reasoning)) {
145
+ if (!supportsReasoningEffort(this.modelId)) {
146
+ warnings.push({
147
+ type: 'unsupported',
148
+ feature: 'reasoning',
149
+ details: `reasoning "${reasoning}" is not supported by this model.`,
150
+ });
151
+ } else if (reasoning === 'none') {
152
+ reasoningEffort = 'none';
153
+ } else {
154
+ reasoningEffort = mapReasoningToProviderEffort({
155
+ reasoning,
156
+ effortMap: {
157
+ minimal: 'low',
158
+ low: 'low',
159
+ medium: 'medium',
160
+ high: 'high',
161
+ xhigh: 'high',
162
+ },
163
+ warnings,
164
+ });
165
+ }
166
+ }
167
+
142
168
  const baseArgs = {
143
169
  // model id
144
170
  model: this.modelId,
@@ -153,23 +179,7 @@ export class XaiChatLanguageModel implements LanguageModelV4 {
153
179
  temperature,
154
180
  top_p: topP,
155
181
  seed,
156
- reasoning_effort:
157
- options.reasoningEffort ??
158
- (isCustomReasoning(reasoning)
159
- ? reasoning === 'none'
160
- ? undefined
161
- : mapReasoningToProviderEffort({
162
- reasoning,
163
- effortMap: {
164
- minimal: 'low',
165
- low: 'low',
166
- medium: 'medium',
167
- high: 'high',
168
- xhigh: 'high',
169
- },
170
- warnings,
171
- })
172
- : undefined),
182
+ reasoning_effort: reasoningEffort,
173
183
 
174
184
  // parallel function calling
175
185
  parallel_function_calling: options.parallel_function_calling,