@apicity/xai 0.1.0-alpha.0
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/LICENSE +21 -0
- package/README.md +862 -0
- package/dist/src/example.d.ts +8 -0
- package/dist/src/example.d.ts.map +1 -0
- package/dist/src/example.js +230 -0
- package/dist/src/example.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/middleware.d.ts +56 -0
- package/dist/src/middleware.d.ts.map +1 -0
- package/dist/src/middleware.js +226 -0
- package/dist/src/middleware.js.map +1 -0
- package/dist/src/types.d.ts +812 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +14 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/xai.d.ts +3 -0
- package/dist/src/xai.d.ts.map +1 -0
- package/dist/src/xai.js +759 -0
- package/dist/src/xai.js.map +1 -0
- package/dist/src/zod.d.ts +2458 -0
- package/dist/src/zod.d.ts.map +1 -0
- package/dist/src/zod.js +434 -0
- package/dist/src/zod.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
# @apicity/xai
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@apicity/xai)
|
|
4
|
+
[](package.json)
|
|
5
|
+
[](tsconfig.json)
|
|
6
|
+
|
|
7
|
+
X.AI / Grok provider for chat and search.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @apicity/xai
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @apicity/xai
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { xai as createXai } from "@apicity/xai";
|
|
21
|
+
|
|
22
|
+
const xai = createXai({ apiKey: process.env.XAI_API_KEY! });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Real-world example: structured vision analysis with Grok-4
|
|
26
|
+
|
|
27
|
+
Hand Grok-4 a portrait, a system prompt that nails down the output schema,
|
|
28
|
+
and `text.format.type: "json_object"` — get back a reproduction-ready
|
|
29
|
+
JSON description with deterministic shot/pose vocabulary. The flow below
|
|
30
|
+
is taken verbatim from
|
|
31
|
+
[`tests/integration/xai-vision-json.test.ts`](../../../tests/integration/xai-vision-json.test.ts)
|
|
32
|
+
and replays against
|
|
33
|
+
[`tests/recordings/xai_3613880225/vision-analysis-json_243984103/recording.har`](../../../tests/recordings/xai_3613880225/vision-analysis-json_243984103/recording.har),
|
|
34
|
+
so the response shapes match what xAI actually returns.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { readFile } from "node:fs/promises";
|
|
38
|
+
import { xai as createXai } from "@apicity/xai";
|
|
39
|
+
|
|
40
|
+
const xai = createXai({ apiKey: process.env.XAI_API_KEY! });
|
|
41
|
+
|
|
42
|
+
// 1. Load the image and inline it as a data URL. xAI also accepts
|
|
43
|
+
// https:// URLs, but inlining keeps the call self-contained and
|
|
44
|
+
// works against private hosts.
|
|
45
|
+
const image = await readFile("./portrait.jpg");
|
|
46
|
+
const base64 = image.toString("base64");
|
|
47
|
+
|
|
48
|
+
// 2. The system prompt enumerates the legal vocabulary for `shot` and
|
|
49
|
+
// constrains `pose` to body geometry only. Combined with
|
|
50
|
+
// `text.format.type: "json_object"` this gives Grok no room to drift
|
|
51
|
+
// off-schema — temperature 0 keeps the result reproducible.
|
|
52
|
+
const SYSTEM_PROMPT = [
|
|
53
|
+
"You are an expert image-to-prompt analyst.",
|
|
54
|
+
"Return only a JSON object with keys prompt, shot, and pose.",
|
|
55
|
+
"prompt: a single-paragraph reproduction-ready image prompt, 1900 characters or fewer, with no line breaks.",
|
|
56
|
+
'shot: exactly "<size>, <angle>" where size is one of extreme close-up, close-up, medium close-up, medium shot, medium long shot, long shot, or extreme long shot, and angle is one of eye-level, low-angle, high-angle, overhead, or dutch.',
|
|
57
|
+
"pose: only body geometry for human figures, with no clothing, hair, background, or lighting details.",
|
|
58
|
+
].join(" ");
|
|
59
|
+
|
|
60
|
+
// 3. Multimodal Responses request: system turn + a user turn whose
|
|
61
|
+
// content is an array of `input_image` + `input_text` parts.
|
|
62
|
+
const result = await xai.post.v1.responses({
|
|
63
|
+
model: "grok-4",
|
|
64
|
+
input: [
|
|
65
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
66
|
+
{
|
|
67
|
+
role: "user",
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: "input_image",
|
|
71
|
+
image_url: `data:image/jpeg;base64,${base64}`,
|
|
72
|
+
detail: "high",
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "input_text",
|
|
76
|
+
text: 'Analyze this image and produce a reproduction-ready JSON description with keys "prompt", "shot", and "pose".',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
text: { format: { type: "json_object" } },
|
|
82
|
+
store: false,
|
|
83
|
+
temperature: 0,
|
|
84
|
+
max_output_tokens: 300,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 4. The Responses API wraps output in a typed item array. Find the
|
|
88
|
+
// assistant message, then the first `output_text` part inside it.
|
|
89
|
+
// Discriminated unions narrow `item.type === "message"` so
|
|
90
|
+
// `item.content` is statically typed.
|
|
91
|
+
const message = result.output.find((item) => item.type === "message");
|
|
92
|
+
const outputText =
|
|
93
|
+
message?.type === "message"
|
|
94
|
+
? message.content.find((part) => part.type === "output_text")?.text
|
|
95
|
+
: undefined;
|
|
96
|
+
|
|
97
|
+
if (!outputText) throw new Error("Grok did not return output_text");
|
|
98
|
+
|
|
99
|
+
const analysis = JSON.parse(outputText) as {
|
|
100
|
+
prompt: string;
|
|
101
|
+
shot: string;
|
|
102
|
+
pose: string;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
console.log(analysis.shot);
|
|
106
|
+
// → "medium close-up, eye-level"
|
|
107
|
+
|
|
108
|
+
console.log(analysis.pose);
|
|
109
|
+
// → "upright torso facing forward, head straight and centered, shoulders squared, arms relaxed downward (implied)"
|
|
110
|
+
|
|
111
|
+
// 5. Reasoning-token accounting. Grok-4 spent 623 of its 728 output
|
|
112
|
+
// tokens reasoning before emitting the 105-token JSON answer —
|
|
113
|
+
// surfaced in `usage.output_tokens_details.reasoning_tokens`.
|
|
114
|
+
console.log(result.usage);
|
|
115
|
+
// → {
|
|
116
|
+
// input_tokens: 2684,
|
|
117
|
+
// input_tokens_details: { cached_tokens: 679 },
|
|
118
|
+
// output_tokens: 728,
|
|
119
|
+
// output_tokens_details: { reasoning_tokens: 623 },
|
|
120
|
+
// total_tokens: 3412,
|
|
121
|
+
// }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Notes**
|
|
125
|
+
|
|
126
|
+
- `store: false` keeps the response off xAI's history surface. Flip to
|
|
127
|
+
`true` to chain follow-ups via `previous_response_id` — useful for
|
|
128
|
+
multi-turn refinement ("now describe the wardrobe") without re-uploading
|
|
129
|
+
the image each time.
|
|
130
|
+
- The Responses output array also carries reasoning items and tool calls
|
|
131
|
+
when present. Always discriminate on `item.type` before reading content;
|
|
132
|
+
TypeScript's narrowing keeps you honest.
|
|
133
|
+
- For raw chat-style usage without the Responses wrapping, use
|
|
134
|
+
`xai.post.v1.chat.completions` instead — same auth, same model catalog,
|
|
135
|
+
just OpenAI-compatible request/response shapes.
|
|
136
|
+
- Errors surface as `XaiError` with `status` and the parsed body attached,
|
|
137
|
+
so `try { ... } catch (e) { if (e instanceof XaiError) ... }` gives you
|
|
138
|
+
the upstream error directly.
|
|
139
|
+
|
|
140
|
+
## API Reference
|
|
141
|
+
|
|
142
|
+
39 endpoints across 17 groups. Each method mirrors an upstream URL path.
|
|
143
|
+
|
|
144
|
+
### batches
|
|
145
|
+
|
|
146
|
+
<details>
|
|
147
|
+
<summary><code>GET</code> <b><code>xai.v1.batches</code></b></summary>
|
|
148
|
+
|
|
149
|
+
<code>GET https://api.x.ai/v1/batches/{paramsOrIdOrSignal}</code>
|
|
150
|
+
|
|
151
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
const res = await xai.v1.batches({ /* ... */ });
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
158
|
+
|
|
159
|
+
</details>
|
|
160
|
+
|
|
161
|
+
<details>
|
|
162
|
+
<summary><code>GET</code> <b><code>xai.v1.batches.requests</code></b></summary>
|
|
163
|
+
|
|
164
|
+
<code>GET https://api.x.ai/v1/batches/{batchId}/requests{query}</code>
|
|
165
|
+
|
|
166
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
const res = await xai.v1.batches.requests({ /* ... */ });
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
173
|
+
|
|
174
|
+
</details>
|
|
175
|
+
|
|
176
|
+
<details>
|
|
177
|
+
<summary><code>GET</code> <b><code>xai.v1.batches.results</code></b></summary>
|
|
178
|
+
|
|
179
|
+
<code>GET https://api.x.ai/v1/batches/{batchId}/results{query}</code>
|
|
180
|
+
|
|
181
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const res = await xai.v1.batches.results({ /* ... */ });
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
188
|
+
|
|
189
|
+
</details>
|
|
190
|
+
|
|
191
|
+
<details>
|
|
192
|
+
<summary><code>POST</code> <b><code>xai.v1.batches</code></b></summary>
|
|
193
|
+
|
|
194
|
+
<code>POST https://api.x.ai/v1/batches</code>
|
|
195
|
+
|
|
196
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
const res = await xai.v1.batches({ /* ... */ });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
203
|
+
|
|
204
|
+
</details>
|
|
205
|
+
|
|
206
|
+
<details>
|
|
207
|
+
<summary><code>POST</code> <b><code>xai.v1.batches.cancel</code></b></summary>
|
|
208
|
+
|
|
209
|
+
<code>POST https://api.x.ai/v1/batches/{batchId}:cancel</code>
|
|
210
|
+
|
|
211
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const res = await xai.v1.batches.cancel({ /* ... */ });
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
218
|
+
|
|
219
|
+
</details>
|
|
220
|
+
|
|
221
|
+
<details>
|
|
222
|
+
<summary><code>POST</code> <b><code>xai.v1.batches.requests</code></b></summary>
|
|
223
|
+
|
|
224
|
+
<code>POST https://api.x.ai/v1/batches/{batchId}/requests</code>
|
|
225
|
+
|
|
226
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
const res = await xai.v1.batches.requests({ /* ... */ });
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
233
|
+
|
|
234
|
+
</details>
|
|
235
|
+
|
|
236
|
+
### chat
|
|
237
|
+
|
|
238
|
+
<details>
|
|
239
|
+
<summary><code>GET</code> <b><code>xai.v1.chat.deferredCompletion</code></b></summary>
|
|
240
|
+
|
|
241
|
+
<code>GET https://api.x.ai/v1/chat/deferred-completion/{requestId}</code>
|
|
242
|
+
|
|
243
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
const res = await xai.v1.chat.deferredCompletion({ /* ... */ });
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
250
|
+
|
|
251
|
+
</details>
|
|
252
|
+
|
|
253
|
+
<details>
|
|
254
|
+
<summary><code>POST</code> <b><code>xai.v1.chat.completions</code></b></summary>
|
|
255
|
+
|
|
256
|
+
<code>POST https://api.x.ai/v1/chat/completions</code>
|
|
257
|
+
|
|
258
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const res = await xai.v1.chat.completions({ /* ... */ });
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
265
|
+
|
|
266
|
+
</details>
|
|
267
|
+
|
|
268
|
+
### collections
|
|
269
|
+
|
|
270
|
+
<details>
|
|
271
|
+
<summary><code>DELETE</code> <b><code>xai.v1.collections</code></b></summary>
|
|
272
|
+
|
|
273
|
+
<code>DELETE https://api.x.ai/v1/collections/{collectionId}</code>
|
|
274
|
+
|
|
275
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
const res = await xai.v1.collections({ /* ... */ });
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
282
|
+
|
|
283
|
+
</details>
|
|
284
|
+
|
|
285
|
+
<details>
|
|
286
|
+
<summary><code>DELETE</code> <b><code>xai.v1.collections.documents</code></b></summary>
|
|
287
|
+
|
|
288
|
+
<code>DELETE https://api.x.ai/v1/collections/{collectionId}/documents/{fileId}</code>
|
|
289
|
+
|
|
290
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
const res = await xai.v1.collections.documents({ /* ... */ });
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
297
|
+
|
|
298
|
+
</details>
|
|
299
|
+
|
|
300
|
+
<details>
|
|
301
|
+
<summary><code>GET</code> <b><code>xai.v1.collections</code></b></summary>
|
|
302
|
+
|
|
303
|
+
<code>GET https://api.x.ai/v1/collections/{paramsOrIdOrSignal}</code>
|
|
304
|
+
|
|
305
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
const res = await xai.v1.collections({ /* ... */ });
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
312
|
+
|
|
313
|
+
</details>
|
|
314
|
+
|
|
315
|
+
<details>
|
|
316
|
+
<summary><code>GET</code> <b><code>xai.v1.collections.documents</code></b></summary>
|
|
317
|
+
|
|
318
|
+
<code>GET https://api.x.ai/v1/collections/{collectionId}/documents/{paramsOrFileId}</code>
|
|
319
|
+
|
|
320
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
const res = await xai.v1.collections.documents({ /* ... */ });
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
327
|
+
|
|
328
|
+
</details>
|
|
329
|
+
|
|
330
|
+
<details>
|
|
331
|
+
<summary><code>GET</code> <b><code>xai.v1.collections.documents.batchGet</code></b></summary>
|
|
332
|
+
|
|
333
|
+
<code>GET https://api.x.ai/v1/collections/{collectionId}/documents:batchGet{query}</code>
|
|
334
|
+
|
|
335
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
const res = await xai.v1.collections.documents.batchGet({ /* ... */ });
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
342
|
+
|
|
343
|
+
</details>
|
|
344
|
+
|
|
345
|
+
<details>
|
|
346
|
+
<summary><code>PATCH</code> <b><code>xai.v1.collections.documents</code></b></summary>
|
|
347
|
+
|
|
348
|
+
<code>PATCH https://api.x.ai/v1/collections/{collectionId}/documents/{fileId}</code>
|
|
349
|
+
|
|
350
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
const res = await xai.v1.collections.documents({ /* ... */ });
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
357
|
+
|
|
358
|
+
</details>
|
|
359
|
+
|
|
360
|
+
<details>
|
|
361
|
+
<summary><code>POST</code> <b><code>xai.v1.collections</code></b></summary>
|
|
362
|
+
|
|
363
|
+
<code>POST https://api.x.ai/v1/collections</code>
|
|
364
|
+
|
|
365
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
const res = await xai.v1.collections({ /* ... */ });
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
372
|
+
|
|
373
|
+
</details>
|
|
374
|
+
|
|
375
|
+
<details>
|
|
376
|
+
<summary><code>POST</code> <b><code>xai.v1.collections.documents</code></b></summary>
|
|
377
|
+
|
|
378
|
+
<code>POST https://api.x.ai/v1/collections/{collectionId}/documents/{fileId}</code>
|
|
379
|
+
|
|
380
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
const res = await xai.v1.collections.documents({ /* ... */ });
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
387
|
+
|
|
388
|
+
</details>
|
|
389
|
+
|
|
390
|
+
<details>
|
|
391
|
+
<summary><code>PUT</code> <b><code>xai.v1.collections</code></b></summary>
|
|
392
|
+
|
|
393
|
+
<code>PUT https://api.x.ai/v1/collections/{collectionId}</code>
|
|
394
|
+
|
|
395
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
const res = await xai.v1.collections({ /* ... */ });
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
402
|
+
|
|
403
|
+
</details>
|
|
404
|
+
|
|
405
|
+
### customVoices
|
|
406
|
+
|
|
407
|
+
<details>
|
|
408
|
+
<summary><code>POST</code> <b><code>xai.v1.customVoices</code></b></summary>
|
|
409
|
+
|
|
410
|
+
<code>POST https://api.x.ai/v1/custom-voices</code>
|
|
411
|
+
|
|
412
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
const res = await xai.v1.customVoices({ /* ... */ });
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
419
|
+
|
|
420
|
+
</details>
|
|
421
|
+
|
|
422
|
+
### documents
|
|
423
|
+
|
|
424
|
+
<details>
|
|
425
|
+
<summary><code>POST</code> <b><code>xai.v1.documents.search</code></b></summary>
|
|
426
|
+
|
|
427
|
+
<code>POST https://api.x.ai/v1/documents/search</code>
|
|
428
|
+
|
|
429
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
const res = await xai.v1.documents.search({ /* ... */ });
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
436
|
+
|
|
437
|
+
</details>
|
|
438
|
+
|
|
439
|
+
### files
|
|
440
|
+
|
|
441
|
+
<details>
|
|
442
|
+
<summary><code>DELETE</code> <b><code>xai.v1.files</code></b></summary>
|
|
443
|
+
|
|
444
|
+
<code>DELETE https://api.x.ai/v1/files/{fileId}</code>
|
|
445
|
+
|
|
446
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
const res = await xai.v1.files({ /* ... */ });
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
453
|
+
|
|
454
|
+
</details>
|
|
455
|
+
|
|
456
|
+
<details>
|
|
457
|
+
<summary><code>GET</code> <b><code>xai.v1.files</code></b></summary>
|
|
458
|
+
|
|
459
|
+
<code>GET https://api.x.ai/v1/files/{fileIdOrSignal}</code>
|
|
460
|
+
|
|
461
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
const res = await xai.v1.files({ /* ... */ });
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
468
|
+
|
|
469
|
+
</details>
|
|
470
|
+
|
|
471
|
+
<details>
|
|
472
|
+
<summary><code>POST</code> <b><code>xai.v1.files</code></b></summary>
|
|
473
|
+
|
|
474
|
+
<code>POST https://api.x.ai/v1/files</code>
|
|
475
|
+
|
|
476
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
477
|
+
|
|
478
|
+
```typescript
|
|
479
|
+
const res = await xai.v1.files({ /* ... */ });
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
483
|
+
|
|
484
|
+
</details>
|
|
485
|
+
|
|
486
|
+
### imageGenerationModels
|
|
487
|
+
|
|
488
|
+
<details>
|
|
489
|
+
<summary><code>GET</code> <b><code>xai.v1.imageGenerationModels</code></b></summary>
|
|
490
|
+
|
|
491
|
+
<code>GET https://api.x.ai/v1/image-generation-models/{modelIdOrSignal}</code>
|
|
492
|
+
|
|
493
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
const res = await xai.v1.imageGenerationModels({ /* ... */ });
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
500
|
+
|
|
501
|
+
</details>
|
|
502
|
+
|
|
503
|
+
### images
|
|
504
|
+
|
|
505
|
+
<details>
|
|
506
|
+
<summary><code>POST</code> <b><code>xai.v1.images.edits</code></b></summary>
|
|
507
|
+
|
|
508
|
+
<code>POST https://api.x.ai/v1/images/edits</code>
|
|
509
|
+
|
|
510
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
const res = await xai.v1.images.edits({ /* ... */ });
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
517
|
+
|
|
518
|
+
</details>
|
|
519
|
+
|
|
520
|
+
<details>
|
|
521
|
+
<summary><code>POST</code> <b><code>xai.v1.images.generations</code></b></summary>
|
|
522
|
+
|
|
523
|
+
<code>POST https://api.x.ai/v1/images/generations</code>
|
|
524
|
+
|
|
525
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
const res = await xai.v1.images.generations({ /* ... */ });
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
532
|
+
|
|
533
|
+
</details>
|
|
534
|
+
|
|
535
|
+
### languageModels
|
|
536
|
+
|
|
537
|
+
<details>
|
|
538
|
+
<summary><code>GET</code> <b><code>xai.v1.languageModels</code></b></summary>
|
|
539
|
+
|
|
540
|
+
<code>GET https://api.x.ai/v1/language-models/{modelIdOrSignal}</code>
|
|
541
|
+
|
|
542
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
const res = await xai.v1.languageModels({ /* ... */ });
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
549
|
+
|
|
550
|
+
</details>
|
|
551
|
+
|
|
552
|
+
### models
|
|
553
|
+
|
|
554
|
+
<details>
|
|
555
|
+
<summary><code>GET</code> <b><code>xai.v1.models</code></b></summary>
|
|
556
|
+
|
|
557
|
+
<code>GET https://api.x.ai/v1/models/{modelIdOrSignal}</code>
|
|
558
|
+
|
|
559
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
const res = await xai.v1.models({ /* ... */ });
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
566
|
+
|
|
567
|
+
</details>
|
|
568
|
+
|
|
569
|
+
### realtime
|
|
570
|
+
|
|
571
|
+
<details>
|
|
572
|
+
<summary><code>POST</code> <b><code>xai.v1.realtime.clientSecrets</code></b></summary>
|
|
573
|
+
|
|
574
|
+
<code>POST https://api.x.ai/v1/realtime/client_secrets</code>
|
|
575
|
+
|
|
576
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
577
|
+
|
|
578
|
+
```typescript
|
|
579
|
+
const res = await xai.v1.realtime.clientSecrets({ /* ... */ });
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
583
|
+
|
|
584
|
+
</details>
|
|
585
|
+
|
|
586
|
+
### responses
|
|
587
|
+
|
|
588
|
+
<details>
|
|
589
|
+
<summary><code>DELETE</code> <b><code>xai.v1.responses</code></b></summary>
|
|
590
|
+
|
|
591
|
+
<code>DELETE https://api.x.ai/v1/responses/{id}</code>
|
|
592
|
+
|
|
593
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
594
|
+
|
|
595
|
+
```typescript
|
|
596
|
+
const res = await xai.v1.responses({ /* ... */ });
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
600
|
+
|
|
601
|
+
</details>
|
|
602
|
+
|
|
603
|
+
<details>
|
|
604
|
+
<summary><code>GET</code> <b><code>xai.v1.responses</code></b></summary>
|
|
605
|
+
|
|
606
|
+
<code>GET https://api.x.ai/v1/responses/{id}</code>
|
|
607
|
+
|
|
608
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
609
|
+
|
|
610
|
+
```typescript
|
|
611
|
+
const res = await xai.v1.responses({ /* ... */ });
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
615
|
+
|
|
616
|
+
</details>
|
|
617
|
+
|
|
618
|
+
<details>
|
|
619
|
+
<summary><code>POST</code> <b><code>xai.v1.responses</code></b></summary>
|
|
620
|
+
|
|
621
|
+
<code>POST https://api.x.ai/v1/responses</code>
|
|
622
|
+
|
|
623
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
const res = await xai.v1.responses({ /* ... */ });
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
630
|
+
|
|
631
|
+
</details>
|
|
632
|
+
|
|
633
|
+
### stt
|
|
634
|
+
|
|
635
|
+
<details>
|
|
636
|
+
<summary><code>POST</code> <b><code>xai.v1.stt</code></b></summary>
|
|
637
|
+
|
|
638
|
+
<code>POST https://api.x.ai/v1/stt</code>
|
|
639
|
+
|
|
640
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
const res = await xai.v1.stt({ /* ... */ });
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
647
|
+
|
|
648
|
+
</details>
|
|
649
|
+
|
|
650
|
+
### tokenizeText
|
|
651
|
+
|
|
652
|
+
<details>
|
|
653
|
+
<summary><code>POST</code> <b><code>xai.v1.tokenizeText</code></b></summary>
|
|
654
|
+
|
|
655
|
+
<code>POST https://api.x.ai/v1/tokenize-text</code>
|
|
656
|
+
|
|
657
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
const res = await xai.v1.tokenizeText({ /* ... */ });
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
664
|
+
|
|
665
|
+
</details>
|
|
666
|
+
|
|
667
|
+
### tts
|
|
668
|
+
|
|
669
|
+
<details>
|
|
670
|
+
<summary><code>POST</code> <b><code>xai.v1.tts</code></b></summary>
|
|
671
|
+
|
|
672
|
+
<code>POST https://api.x.ai/v1/tts</code>
|
|
673
|
+
|
|
674
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
const res = await xai.v1.tts({ /* ... */ });
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
681
|
+
|
|
682
|
+
</details>
|
|
683
|
+
|
|
684
|
+
### videoGenerationModels
|
|
685
|
+
|
|
686
|
+
<details>
|
|
687
|
+
<summary><code>GET</code> <b><code>xai.v1.videoGenerationModels</code></b></summary>
|
|
688
|
+
|
|
689
|
+
<code>GET https://api.x.ai/v1/video-generation-models/{modelIdOrSignal}</code>
|
|
690
|
+
|
|
691
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
692
|
+
|
|
693
|
+
```typescript
|
|
694
|
+
const res = await xai.v1.videoGenerationModels({ /* ... */ });
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
698
|
+
|
|
699
|
+
</details>
|
|
700
|
+
|
|
701
|
+
### videos
|
|
702
|
+
|
|
703
|
+
<details>
|
|
704
|
+
<summary><code>GET</code> <b><code>xai.v1.videos</code></b></summary>
|
|
705
|
+
|
|
706
|
+
<code>GET https://api.x.ai/v1/videos/{requestId}</code>
|
|
707
|
+
|
|
708
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
709
|
+
|
|
710
|
+
```typescript
|
|
711
|
+
const res = await xai.v1.videos({ /* ... */ });
|
|
712
|
+
```
|
|
713
|
+
|
|
714
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
715
|
+
|
|
716
|
+
</details>
|
|
717
|
+
|
|
718
|
+
<details>
|
|
719
|
+
<summary><code>POST</code> <b><code>xai.v1.videos.edits</code></b></summary>
|
|
720
|
+
|
|
721
|
+
<code>POST https://api.x.ai/v1/videos/edits</code>
|
|
722
|
+
|
|
723
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
const res = await xai.v1.videos.edits({ /* ... */ });
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
730
|
+
|
|
731
|
+
</details>
|
|
732
|
+
|
|
733
|
+
<details>
|
|
734
|
+
<summary><code>POST</code> <b><code>xai.v1.videos.extensions</code></b></summary>
|
|
735
|
+
|
|
736
|
+
<code>POST https://api.x.ai/v1/videos/extensions</code>
|
|
737
|
+
|
|
738
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
739
|
+
|
|
740
|
+
```typescript
|
|
741
|
+
const res = await xai.v1.videos.extensions({ /* ... */ });
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
745
|
+
|
|
746
|
+
</details>
|
|
747
|
+
|
|
748
|
+
<details>
|
|
749
|
+
<summary><code>POST</code> <b><code>xai.v1.videos.generations</code></b></summary>
|
|
750
|
+
|
|
751
|
+
<code>POST https://api.x.ai/v1/videos/generations</code>
|
|
752
|
+
|
|
753
|
+
[Upstream docs ↗](https://docs.x.ai/docs/api-reference)
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
const res = await xai.v1.videos.generations({ /* ... */ });
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
Source: [`packages/provider/xai/src/xai.ts`](src/xai.ts)
|
|
760
|
+
|
|
761
|
+
</details>
|
|
762
|
+
|
|
763
|
+
## Middleware
|
|
764
|
+
|
|
765
|
+
```typescript
|
|
766
|
+
import { xai as createXai, withRetry } from "@apicity/xai";
|
|
767
|
+
|
|
768
|
+
const xai = createXai({ apiKey: process.env.XAI_API_KEY! });
|
|
769
|
+
const models = withRetry(xai.get.v1.models, { retries: 3 });
|
|
770
|
+
```
|
|
771
|
+
|
|
772
|
+
## Rate Limiting
|
|
773
|
+
|
|
774
|
+
Client-side rate limiting that queues requests to stay within xAI API limits.
|
|
775
|
+
|
|
776
|
+
```typescript
|
|
777
|
+
import {
|
|
778
|
+
xai as createXai,
|
|
779
|
+
withRateLimit,
|
|
780
|
+
withRetry,
|
|
781
|
+
createRateLimiter,
|
|
782
|
+
XAI_RATE_LIMITS,
|
|
783
|
+
} from "@apicity/xai";
|
|
784
|
+
|
|
785
|
+
const xai = createXai({ apiKey: process.env.XAI_API_KEY! });
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
### Using xAI tier presets
|
|
789
|
+
|
|
790
|
+
```typescript
|
|
791
|
+
// Use built-in tier presets (free, tier1, tier2, tier3, tier4)
|
|
792
|
+
const limiter = createRateLimiter(XAI_RATE_LIMITS.tier1);
|
|
793
|
+
// => { rpm: 60, concurrent: 10 }
|
|
794
|
+
|
|
795
|
+
const chat = withRateLimit(xai.post.v1.chat.completions, limiter);
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
### Custom limits
|
|
799
|
+
|
|
800
|
+
```typescript
|
|
801
|
+
const limiter = createRateLimiter({ rpm: 30, concurrent: 5 });
|
|
802
|
+
const chat = withRateLimit(xai.post.v1.chat.completions, limiter);
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Shared limiter across endpoints
|
|
806
|
+
|
|
807
|
+
RPM limits apply globally, so share a single limiter across all endpoints:
|
|
808
|
+
|
|
809
|
+
```typescript
|
|
810
|
+
const limiter = createRateLimiter(XAI_RATE_LIMITS.tier2);
|
|
811
|
+
|
|
812
|
+
const chat = withRateLimit(xai.post.v1.chat.completions, limiter);
|
|
813
|
+
const responses = withRateLimit(xai.post.v1.responses, limiter);
|
|
814
|
+
const images = withRateLimit(xai.post.v1.images.generations, limiter);
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Composing with retry
|
|
818
|
+
|
|
819
|
+
Place `withRateLimit` innermost so retries count against the limit:
|
|
820
|
+
|
|
821
|
+
```typescript
|
|
822
|
+
const limiter = createRateLimiter(XAI_RATE_LIMITS.tier1);
|
|
823
|
+
|
|
824
|
+
const chat = withRetry(
|
|
825
|
+
withRateLimit(xai.post.v1.chat.completions, limiter),
|
|
826
|
+
{ retries: 2 }
|
|
827
|
+
);
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
### Batch processing
|
|
831
|
+
|
|
832
|
+
Fire requests in parallel — the limiter handles pacing automatically:
|
|
833
|
+
|
|
834
|
+
```typescript
|
|
835
|
+
const limiter = createRateLimiter(XAI_RATE_LIMITS.tier1);
|
|
836
|
+
const chat = withRateLimit(xai.post.v1.chat.completions, limiter);
|
|
837
|
+
|
|
838
|
+
const results = await Promise.all(
|
|
839
|
+
prompts.map((p) =>
|
|
840
|
+
chat({
|
|
841
|
+
model: "grok-3",
|
|
842
|
+
messages: [{ role: "user", content: p }],
|
|
843
|
+
})
|
|
844
|
+
)
|
|
845
|
+
);
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
### xAI rate limit tiers
|
|
849
|
+
|
|
850
|
+
| Preset | RPM | Concurrent | Spend threshold |
|
|
851
|
+
|--------|-----|------------|-----------------|
|
|
852
|
+
| `free` | 5 | 2 | $0 |
|
|
853
|
+
| `tier1` | 60 | 10 | $0+ |
|
|
854
|
+
| `tier2` | 200 | 25 | $100+ |
|
|
855
|
+
| `tier3` | 500 | 50 | $500+ |
|
|
856
|
+
| `tier4` | 1000 | 100 | $1,000+ |
|
|
857
|
+
|
|
858
|
+
Part of the [apicity](https://github.com/justintanner/apicity) monorepo.
|
|
859
|
+
|
|
860
|
+
## License
|
|
861
|
+
|
|
862
|
+
MIT — see [LICENSE](LICENSE).
|