@ai-sdk/xai 2.0.0-canary.9 → 2.0.1

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.mjs CHANGED
@@ -1,47 +1,741 @@
1
1
  // src/xai-provider.ts
2
2
  import {
3
- OpenAICompatibleChatLanguageModel,
4
3
  OpenAICompatibleImageModel
5
4
  } from "@ai-sdk/openai-compatible";
6
5
  import {
7
6
  NoSuchModelError
8
7
  } from "@ai-sdk/provider";
9
8
  import {
9
+ generateId,
10
10
  loadApiKey,
11
11
  withoutTrailingSlash
12
12
  } from "@ai-sdk/provider-utils";
13
13
 
14
- // src/xai-chat-settings.ts
15
- function supportsStructuredOutputs(modelId) {
16
- return [
17
- "grok-3",
18
- "grok-3-beta",
19
- "grok-3-latest",
20
- "grok-3-fast",
21
- "grok-3-fast-beta",
22
- "grok-3-fast-latest",
23
- "grok-3-mini",
24
- "grok-3-mini-beta",
25
- "grok-3-mini-latest",
26
- "grok-3-mini-fast",
27
- "grok-3-mini-fast-beta",
28
- "grok-3-mini-fast-latest",
29
- "grok-2-1212",
30
- "grok-2-vision-1212"
31
- ].includes(modelId);
14
+ // src/xai-chat-language-model.ts
15
+ import {
16
+ combineHeaders,
17
+ createEventSourceResponseHandler,
18
+ createJsonResponseHandler,
19
+ parseProviderOptions,
20
+ postJsonToApi
21
+ } from "@ai-sdk/provider-utils";
22
+ import { z as z3 } from "zod/v4";
23
+
24
+ // src/convert-to-xai-chat-messages.ts
25
+ import {
26
+ UnsupportedFunctionalityError
27
+ } from "@ai-sdk/provider";
28
+ import { convertToBase64 } from "@ai-sdk/provider-utils";
29
+ function convertToXaiChatMessages(prompt) {
30
+ const messages = [];
31
+ const warnings = [];
32
+ for (const { role, content } of prompt) {
33
+ switch (role) {
34
+ case "system": {
35
+ messages.push({ role: "system", content });
36
+ break;
37
+ }
38
+ case "user": {
39
+ if (content.length === 1 && content[0].type === "text") {
40
+ messages.push({ role: "user", content: content[0].text });
41
+ break;
42
+ }
43
+ messages.push({
44
+ role: "user",
45
+ content: content.map((part) => {
46
+ switch (part.type) {
47
+ case "text": {
48
+ return { type: "text", text: part.text };
49
+ }
50
+ case "file": {
51
+ if (part.mediaType.startsWith("image/")) {
52
+ const mediaType = part.mediaType === "image/*" ? "image/jpeg" : part.mediaType;
53
+ return {
54
+ type: "image_url",
55
+ image_url: {
56
+ url: part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${convertToBase64(part.data)}`
57
+ }
58
+ };
59
+ } else {
60
+ throw new UnsupportedFunctionalityError({
61
+ functionality: `file part media type ${part.mediaType}`
62
+ });
63
+ }
64
+ }
65
+ }
66
+ })
67
+ });
68
+ break;
69
+ }
70
+ case "assistant": {
71
+ let text = "";
72
+ const toolCalls = [];
73
+ for (const part of content) {
74
+ switch (part.type) {
75
+ case "text": {
76
+ text += part.text;
77
+ break;
78
+ }
79
+ case "tool-call": {
80
+ toolCalls.push({
81
+ id: part.toolCallId,
82
+ type: "function",
83
+ function: {
84
+ name: part.toolName,
85
+ arguments: JSON.stringify(part.input)
86
+ }
87
+ });
88
+ break;
89
+ }
90
+ }
91
+ }
92
+ messages.push({
93
+ role: "assistant",
94
+ content: text,
95
+ tool_calls: toolCalls.length > 0 ? toolCalls : void 0
96
+ });
97
+ break;
98
+ }
99
+ case "tool": {
100
+ for (const toolResponse of content) {
101
+ const output = toolResponse.output;
102
+ let contentValue;
103
+ switch (output.type) {
104
+ case "text":
105
+ case "error-text":
106
+ contentValue = output.value;
107
+ break;
108
+ case "content":
109
+ case "json":
110
+ case "error-json":
111
+ contentValue = JSON.stringify(output.value);
112
+ break;
113
+ }
114
+ messages.push({
115
+ role: "tool",
116
+ tool_call_id: toolResponse.toolCallId,
117
+ content: contentValue
118
+ });
119
+ }
120
+ break;
121
+ }
122
+ default: {
123
+ const _exhaustiveCheck = role;
124
+ throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
125
+ }
126
+ }
127
+ }
128
+ return { messages, warnings };
129
+ }
130
+
131
+ // src/get-response-metadata.ts
132
+ function getResponseMetadata({
133
+ id,
134
+ model,
135
+ created
136
+ }) {
137
+ return {
138
+ id: id != null ? id : void 0,
139
+ modelId: model != null ? model : void 0,
140
+ timestamp: created != null ? new Date(created * 1e3) : void 0
141
+ };
32
142
  }
33
143
 
144
+ // src/map-xai-finish-reason.ts
145
+ function mapXaiFinishReason(finishReason) {
146
+ switch (finishReason) {
147
+ case "stop":
148
+ return "stop";
149
+ case "length":
150
+ return "length";
151
+ case "tool_calls":
152
+ case "function_call":
153
+ return "tool-calls";
154
+ case "content_filter":
155
+ return "content-filter";
156
+ default:
157
+ return "unknown";
158
+ }
159
+ }
160
+
161
+ // src/xai-chat-options.ts
162
+ import { z } from "zod/v4";
163
+ var webSourceSchema = z.object({
164
+ type: z.literal("web"),
165
+ country: z.string().length(2).optional(),
166
+ excludedWebsites: z.array(z.string()).max(5).optional(),
167
+ allowedWebsites: z.array(z.string()).max(5).optional(),
168
+ safeSearch: z.boolean().optional()
169
+ });
170
+ var xSourceSchema = z.object({
171
+ type: z.literal("x"),
172
+ xHandles: z.array(z.string()).optional()
173
+ });
174
+ var newsSourceSchema = z.object({
175
+ type: z.literal("news"),
176
+ country: z.string().length(2).optional(),
177
+ excludedWebsites: z.array(z.string()).max(5).optional(),
178
+ safeSearch: z.boolean().optional()
179
+ });
180
+ var rssSourceSchema = z.object({
181
+ type: z.literal("rss"),
182
+ links: z.array(z.string().url()).max(1)
183
+ // currently only supports one RSS link
184
+ });
185
+ var searchSourceSchema = z.discriminatedUnion("type", [
186
+ webSourceSchema,
187
+ xSourceSchema,
188
+ newsSourceSchema,
189
+ rssSourceSchema
190
+ ]);
191
+ var xaiProviderOptions = z.object({
192
+ /**
193
+ * reasoning effort for reasoning models
194
+ * only supported by grok-3-mini and grok-3-mini-fast models
195
+ */
196
+ reasoningEffort: z.enum(["low", "high"]).optional(),
197
+ searchParameters: z.object({
198
+ /**
199
+ * search mode preference
200
+ * - "off": disables search completely
201
+ * - "auto": model decides whether to search (default)
202
+ * - "on": always enables search
203
+ */
204
+ mode: z.enum(["off", "auto", "on"]),
205
+ /**
206
+ * whether to return citations in the response
207
+ * defaults to true
208
+ */
209
+ returnCitations: z.boolean().optional(),
210
+ /**
211
+ * start date for search data (ISO8601 format: YYYY-MM-DD)
212
+ */
213
+ fromDate: z.string().optional(),
214
+ /**
215
+ * end date for search data (ISO8601 format: YYYY-MM-DD)
216
+ */
217
+ toDate: z.string().optional(),
218
+ /**
219
+ * maximum number of search results to consider
220
+ * defaults to 20
221
+ */
222
+ maxSearchResults: z.number().min(1).max(50).optional(),
223
+ /**
224
+ * data sources to search from
225
+ * defaults to ["web", "x"] if not specified
226
+ */
227
+ sources: z.array(searchSourceSchema).optional()
228
+ }).optional()
229
+ });
230
+
34
231
  // src/xai-error.ts
35
- import { z } from "zod";
36
- var xaiErrorSchema = z.object({
37
- code: z.string(),
38
- error: z.string()
232
+ import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils";
233
+ import { z as z2 } from "zod/v4";
234
+ var xaiErrorDataSchema = z2.object({
235
+ error: z2.object({
236
+ message: z2.string(),
237
+ type: z2.string().nullish(),
238
+ param: z2.any().nullish(),
239
+ code: z2.union([z2.string(), z2.number()]).nullish()
240
+ })
241
+ });
242
+ var xaiFailedResponseHandler = createJsonErrorResponseHandler({
243
+ errorSchema: xaiErrorDataSchema,
244
+ errorToMessage: (data) => data.error.message
245
+ });
246
+
247
+ // src/xai-prepare-tools.ts
248
+ import {
249
+ UnsupportedFunctionalityError as UnsupportedFunctionalityError2
250
+ } from "@ai-sdk/provider";
251
+ function prepareTools({
252
+ tools,
253
+ toolChoice
254
+ }) {
255
+ tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
256
+ const toolWarnings = [];
257
+ if (tools == null) {
258
+ return { tools: void 0, toolChoice: void 0, toolWarnings };
259
+ }
260
+ const xaiTools = [];
261
+ for (const tool of tools) {
262
+ if (tool.type === "provider-defined") {
263
+ toolWarnings.push({ type: "unsupported-tool", tool });
264
+ } else {
265
+ xaiTools.push({
266
+ type: "function",
267
+ function: {
268
+ name: tool.name,
269
+ description: tool.description,
270
+ parameters: tool.inputSchema
271
+ }
272
+ });
273
+ }
274
+ }
275
+ if (toolChoice == null) {
276
+ return { tools: xaiTools, toolChoice: void 0, toolWarnings };
277
+ }
278
+ const type = toolChoice.type;
279
+ switch (type) {
280
+ case "auto":
281
+ case "none":
282
+ return { tools: xaiTools, toolChoice: type, toolWarnings };
283
+ case "required":
284
+ return { tools: xaiTools, toolChoice: "required", toolWarnings };
285
+ case "tool":
286
+ return {
287
+ tools: xaiTools,
288
+ toolChoice: {
289
+ type: "function",
290
+ function: { name: toolChoice.toolName }
291
+ },
292
+ toolWarnings
293
+ };
294
+ default: {
295
+ const _exhaustiveCheck = type;
296
+ throw new UnsupportedFunctionalityError2({
297
+ functionality: `tool choice type: ${_exhaustiveCheck}`
298
+ });
299
+ }
300
+ }
301
+ }
302
+
303
+ // src/xai-chat-language-model.ts
304
+ var XaiChatLanguageModel = class {
305
+ constructor(modelId, config) {
306
+ this.specificationVersion = "v2";
307
+ this.supportedUrls = {
308
+ "image/*": [/^https?:\/\/.*$/]
309
+ };
310
+ this.modelId = modelId;
311
+ this.config = config;
312
+ }
313
+ get provider() {
314
+ return this.config.provider;
315
+ }
316
+ async getArgs({
317
+ prompt,
318
+ maxOutputTokens,
319
+ temperature,
320
+ topP,
321
+ topK,
322
+ frequencyPenalty,
323
+ presencePenalty,
324
+ stopSequences,
325
+ seed,
326
+ responseFormat,
327
+ providerOptions,
328
+ tools,
329
+ toolChoice
330
+ }) {
331
+ var _a, _b, _c;
332
+ const warnings = [];
333
+ const options = (_a = await parseProviderOptions({
334
+ provider: "xai",
335
+ providerOptions,
336
+ schema: xaiProviderOptions
337
+ })) != null ? _a : {};
338
+ if (topK != null) {
339
+ warnings.push({
340
+ type: "unsupported-setting",
341
+ setting: "topK"
342
+ });
343
+ }
344
+ if (frequencyPenalty != null) {
345
+ warnings.push({
346
+ type: "unsupported-setting",
347
+ setting: "frequencyPenalty"
348
+ });
349
+ }
350
+ if (presencePenalty != null) {
351
+ warnings.push({
352
+ type: "unsupported-setting",
353
+ setting: "presencePenalty"
354
+ });
355
+ }
356
+ if (stopSequences != null) {
357
+ warnings.push({
358
+ type: "unsupported-setting",
359
+ setting: "stopSequences"
360
+ });
361
+ }
362
+ if (responseFormat != null && responseFormat.type === "json" && responseFormat.schema != null) {
363
+ warnings.push({
364
+ type: "unsupported-setting",
365
+ setting: "responseFormat",
366
+ details: "JSON response format schema is not supported"
367
+ });
368
+ }
369
+ const { messages, warnings: messageWarnings } = convertToXaiChatMessages(prompt);
370
+ warnings.push(...messageWarnings);
371
+ const {
372
+ tools: xaiTools,
373
+ toolChoice: xaiToolChoice,
374
+ toolWarnings
375
+ } = prepareTools({
376
+ tools,
377
+ toolChoice
378
+ });
379
+ warnings.push(...toolWarnings);
380
+ const baseArgs = {
381
+ // model id
382
+ model: this.modelId,
383
+ // standard generation settings
384
+ max_tokens: maxOutputTokens,
385
+ temperature,
386
+ top_p: topP,
387
+ seed,
388
+ reasoning_effort: options.reasoningEffort,
389
+ // response format
390
+ response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? responseFormat.schema != null ? {
391
+ type: "json_schema",
392
+ json_schema: {
393
+ name: (_b = responseFormat.name) != null ? _b : "response",
394
+ schema: responseFormat.schema,
395
+ strict: true
396
+ }
397
+ } : { type: "json_object" } : void 0,
398
+ // search parameters
399
+ search_parameters: options.searchParameters ? {
400
+ mode: options.searchParameters.mode,
401
+ return_citations: options.searchParameters.returnCitations,
402
+ from_date: options.searchParameters.fromDate,
403
+ to_date: options.searchParameters.toDate,
404
+ max_search_results: options.searchParameters.maxSearchResults,
405
+ sources: (_c = options.searchParameters.sources) == null ? void 0 : _c.map((source) => ({
406
+ type: source.type,
407
+ ...source.type === "web" && {
408
+ country: source.country,
409
+ excluded_websites: source.excludedWebsites,
410
+ allowed_websites: source.allowedWebsites,
411
+ safe_search: source.safeSearch
412
+ },
413
+ ...source.type === "x" && {
414
+ x_handles: source.xHandles
415
+ },
416
+ ...source.type === "news" && {
417
+ country: source.country,
418
+ excluded_websites: source.excludedWebsites,
419
+ safe_search: source.safeSearch
420
+ },
421
+ ...source.type === "rss" && {
422
+ links: source.links
423
+ }
424
+ }))
425
+ } : void 0,
426
+ // messages in xai format
427
+ messages,
428
+ // tools in xai format
429
+ tools: xaiTools,
430
+ tool_choice: xaiToolChoice
431
+ };
432
+ return {
433
+ args: baseArgs,
434
+ warnings
435
+ };
436
+ }
437
+ async doGenerate(options) {
438
+ var _a, _b, _c;
439
+ const { args: body, warnings } = await this.getArgs(options);
440
+ const {
441
+ responseHeaders,
442
+ value: response,
443
+ rawValue: rawResponse
444
+ } = await postJsonToApi({
445
+ url: `${(_a = this.config.baseURL) != null ? _a : "https://api.x.ai/v1"}/chat/completions`,
446
+ headers: combineHeaders(this.config.headers(), options.headers),
447
+ body,
448
+ failedResponseHandler: xaiFailedResponseHandler,
449
+ successfulResponseHandler: createJsonResponseHandler(
450
+ xaiChatResponseSchema
451
+ ),
452
+ abortSignal: options.abortSignal,
453
+ fetch: this.config.fetch
454
+ });
455
+ const choice = response.choices[0];
456
+ const content = [];
457
+ if (choice.message.content != null && choice.message.content.length > 0) {
458
+ let text = choice.message.content;
459
+ const lastMessage = body.messages[body.messages.length - 1];
460
+ if ((lastMessage == null ? void 0 : lastMessage.role) === "assistant" && text === lastMessage.content) {
461
+ text = "";
462
+ }
463
+ if (text.length > 0) {
464
+ content.push({ type: "text", text });
465
+ }
466
+ }
467
+ if (choice.message.reasoning_content != null && choice.message.reasoning_content.length > 0) {
468
+ content.push({
469
+ type: "reasoning",
470
+ text: choice.message.reasoning_content
471
+ });
472
+ }
473
+ if (choice.message.tool_calls != null) {
474
+ for (const toolCall of choice.message.tool_calls) {
475
+ content.push({
476
+ type: "tool-call",
477
+ toolCallId: toolCall.id,
478
+ toolName: toolCall.function.name,
479
+ input: toolCall.function.arguments
480
+ });
481
+ }
482
+ }
483
+ if (response.citations != null) {
484
+ for (const url of response.citations) {
485
+ content.push({
486
+ type: "source",
487
+ sourceType: "url",
488
+ id: this.config.generateId(),
489
+ url
490
+ });
491
+ }
492
+ }
493
+ return {
494
+ content,
495
+ finishReason: mapXaiFinishReason(choice.finish_reason),
496
+ usage: {
497
+ inputTokens: response.usage.prompt_tokens,
498
+ outputTokens: response.usage.completion_tokens,
499
+ totalTokens: response.usage.total_tokens,
500
+ reasoningTokens: (_c = (_b = response.usage.completion_tokens_details) == null ? void 0 : _b.reasoning_tokens) != null ? _c : void 0
501
+ },
502
+ request: { body },
503
+ response: {
504
+ ...getResponseMetadata(response),
505
+ headers: responseHeaders,
506
+ body: rawResponse
507
+ },
508
+ warnings
509
+ };
510
+ }
511
+ async doStream(options) {
512
+ var _a;
513
+ const { args, warnings } = await this.getArgs(options);
514
+ const body = {
515
+ ...args,
516
+ stream: true,
517
+ stream_options: {
518
+ include_usage: true
519
+ }
520
+ };
521
+ const { responseHeaders, value: response } = await postJsonToApi({
522
+ url: `${(_a = this.config.baseURL) != null ? _a : "https://api.x.ai/v1"}/chat/completions`,
523
+ headers: combineHeaders(this.config.headers(), options.headers),
524
+ body,
525
+ failedResponseHandler: xaiFailedResponseHandler,
526
+ successfulResponseHandler: createEventSourceResponseHandler(xaiChatChunkSchema),
527
+ abortSignal: options.abortSignal,
528
+ fetch: this.config.fetch
529
+ });
530
+ let finishReason = "unknown";
531
+ const usage = {
532
+ inputTokens: void 0,
533
+ outputTokens: void 0,
534
+ totalTokens: void 0
535
+ };
536
+ let isFirstChunk = true;
537
+ const contentBlocks = {};
538
+ const lastReasoningDeltas = {};
539
+ const self = this;
540
+ return {
541
+ stream: response.pipeThrough(
542
+ new TransformStream({
543
+ start(controller) {
544
+ controller.enqueue({ type: "stream-start", warnings });
545
+ },
546
+ transform(chunk, controller) {
547
+ var _a2, _b;
548
+ if (options.includeRawChunks) {
549
+ controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
550
+ }
551
+ if (!chunk.success) {
552
+ controller.enqueue({ type: "error", error: chunk.error });
553
+ return;
554
+ }
555
+ const value = chunk.value;
556
+ if (isFirstChunk) {
557
+ controller.enqueue({
558
+ type: "response-metadata",
559
+ ...getResponseMetadata(value)
560
+ });
561
+ isFirstChunk = false;
562
+ }
563
+ if (value.citations != null) {
564
+ for (const url of value.citations) {
565
+ controller.enqueue({
566
+ type: "source",
567
+ sourceType: "url",
568
+ id: self.config.generateId(),
569
+ url
570
+ });
571
+ }
572
+ }
573
+ if (value.usage != null) {
574
+ usage.inputTokens = value.usage.prompt_tokens;
575
+ usage.outputTokens = value.usage.completion_tokens;
576
+ usage.totalTokens = value.usage.total_tokens;
577
+ usage.reasoningTokens = (_b = (_a2 = value.usage.completion_tokens_details) == null ? void 0 : _a2.reasoning_tokens) != null ? _b : void 0;
578
+ }
579
+ const choice = value.choices[0];
580
+ if ((choice == null ? void 0 : choice.finish_reason) != null) {
581
+ finishReason = mapXaiFinishReason(choice.finish_reason);
582
+ }
583
+ if ((choice == null ? void 0 : choice.delta) == null) {
584
+ return;
585
+ }
586
+ const delta = choice.delta;
587
+ const choiceIndex = choice.index;
588
+ if (delta.content != null && delta.content.length > 0) {
589
+ const textContent = delta.content;
590
+ const lastMessage = body.messages[body.messages.length - 1];
591
+ if ((lastMessage == null ? void 0 : lastMessage.role) === "assistant" && textContent === lastMessage.content) {
592
+ return;
593
+ }
594
+ const blockId = `text-${value.id || choiceIndex}`;
595
+ if (contentBlocks[blockId] == null) {
596
+ contentBlocks[blockId] = { type: "text" };
597
+ controller.enqueue({
598
+ type: "text-start",
599
+ id: blockId
600
+ });
601
+ }
602
+ controller.enqueue({
603
+ type: "text-delta",
604
+ id: blockId,
605
+ delta: textContent
606
+ });
607
+ }
608
+ if (delta.reasoning_content != null && delta.reasoning_content.length > 0) {
609
+ const blockId = `reasoning-${value.id || choiceIndex}`;
610
+ if (lastReasoningDeltas[blockId] === delta.reasoning_content) {
611
+ return;
612
+ }
613
+ lastReasoningDeltas[blockId] = delta.reasoning_content;
614
+ if (contentBlocks[blockId] == null) {
615
+ contentBlocks[blockId] = { type: "reasoning" };
616
+ controller.enqueue({
617
+ type: "reasoning-start",
618
+ id: blockId
619
+ });
620
+ }
621
+ controller.enqueue({
622
+ type: "reasoning-delta",
623
+ id: blockId,
624
+ delta: delta.reasoning_content
625
+ });
626
+ }
627
+ if (delta.tool_calls != null) {
628
+ for (const toolCall of delta.tool_calls) {
629
+ const toolCallId = toolCall.id;
630
+ controller.enqueue({
631
+ type: "tool-input-start",
632
+ id: toolCallId,
633
+ toolName: toolCall.function.name
634
+ });
635
+ controller.enqueue({
636
+ type: "tool-input-delta",
637
+ id: toolCallId,
638
+ delta: toolCall.function.arguments
639
+ });
640
+ controller.enqueue({
641
+ type: "tool-input-end",
642
+ id: toolCallId
643
+ });
644
+ controller.enqueue({
645
+ type: "tool-call",
646
+ toolCallId,
647
+ toolName: toolCall.function.name,
648
+ input: toolCall.function.arguments
649
+ });
650
+ }
651
+ }
652
+ },
653
+ flush(controller) {
654
+ for (const [blockId, block] of Object.entries(contentBlocks)) {
655
+ controller.enqueue({
656
+ type: block.type === "text" ? "text-end" : "reasoning-end",
657
+ id: blockId
658
+ });
659
+ }
660
+ controller.enqueue({ type: "finish", finishReason, usage });
661
+ }
662
+ })
663
+ ),
664
+ request: { body },
665
+ response: { headers: responseHeaders }
666
+ };
667
+ }
668
+ };
669
+ var xaiUsageSchema = z3.object({
670
+ prompt_tokens: z3.number(),
671
+ completion_tokens: z3.number(),
672
+ total_tokens: z3.number(),
673
+ completion_tokens_details: z3.object({
674
+ reasoning_tokens: z3.number().nullish()
675
+ }).nullish()
676
+ });
677
+ var xaiChatResponseSchema = z3.object({
678
+ id: z3.string().nullish(),
679
+ created: z3.number().nullish(),
680
+ model: z3.string().nullish(),
681
+ choices: z3.array(
682
+ z3.object({
683
+ message: z3.object({
684
+ role: z3.literal("assistant"),
685
+ content: z3.string().nullish(),
686
+ reasoning_content: z3.string().nullish(),
687
+ tool_calls: z3.array(
688
+ z3.object({
689
+ id: z3.string(),
690
+ type: z3.literal("function"),
691
+ function: z3.object({
692
+ name: z3.string(),
693
+ arguments: z3.string()
694
+ })
695
+ })
696
+ ).nullish()
697
+ }),
698
+ index: z3.number(),
699
+ finish_reason: z3.string().nullish()
700
+ })
701
+ ),
702
+ object: z3.literal("chat.completion"),
703
+ usage: xaiUsageSchema,
704
+ citations: z3.array(z3.string().url()).nullish()
705
+ });
706
+ var xaiChatChunkSchema = z3.object({
707
+ id: z3.string().nullish(),
708
+ created: z3.number().nullish(),
709
+ model: z3.string().nullish(),
710
+ choices: z3.array(
711
+ z3.object({
712
+ delta: z3.object({
713
+ role: z3.enum(["assistant"]).optional(),
714
+ content: z3.string().nullish(),
715
+ reasoning_content: z3.string().nullish(),
716
+ tool_calls: z3.array(
717
+ z3.object({
718
+ id: z3.string(),
719
+ type: z3.literal("function"),
720
+ function: z3.object({
721
+ name: z3.string(),
722
+ arguments: z3.string()
723
+ })
724
+ })
725
+ ).nullish()
726
+ }),
727
+ finish_reason: z3.string().nullish(),
728
+ index: z3.number()
729
+ })
730
+ ),
731
+ usage: xaiUsageSchema.nullish(),
732
+ citations: z3.array(z3.string().url()).nullish()
39
733
  });
40
734
 
41
735
  // src/xai-provider.ts
42
736
  var xaiErrorStructure = {
43
- errorSchema: xaiErrorSchema,
44
- errorToMessage: (data) => data.error
737
+ errorSchema: xaiErrorDataSchema,
738
+ errorToMessage: (data) => data.error.message
45
739
  };
46
740
  function createXai(options = {}) {
47
741
  var _a;
@@ -57,18 +751,16 @@ function createXai(options = {}) {
57
751
  ...options.headers
58
752
  });
59
753
  const createLanguageModel = (modelId) => {
60
- const structuredOutputs = supportsStructuredOutputs(modelId);
61
- return new OpenAICompatibleChatLanguageModel(modelId, {
754
+ return new XaiChatLanguageModel(modelId, {
62
755
  provider: "xai.chat",
63
- url: ({ path }) => `${baseURL}${path}`,
756
+ baseURL,
64
757
  headers: getHeaders,
65
- fetch: options.fetch,
66
- errorStructure: xaiErrorStructure,
67
- supportsStructuredOutputs: structuredOutputs
758
+ generateId,
759
+ fetch: options.fetch
68
760
  });
69
761
  };
70
- const createImageModel = (modelId, settings = {}) => {
71
- return new OpenAICompatibleImageModel(modelId, settings, {
762
+ const createImageModel = (modelId) => {
763
+ return new OpenAICompatibleImageModel(modelId, {
72
764
  provider: "xai.image",
73
765
  url: ({ path }) => `${baseURL}${path}`,
74
766
  headers: getHeaders,