@glexir/sdk 0.0.0-stage → 0.2.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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +292 -2
  3. package/dist/client.d.ts +61 -0
  4. package/dist/client.js +245 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/core/api-promise.d.ts +31 -0
  7. package/dist/core/api-promise.js +39 -0
  8. package/dist/core/api-promise.js.map +1 -0
  9. package/dist/core/errors.d.ts +70 -0
  10. package/dist/core/errors.js +118 -0
  11. package/dist/core/errors.js.map +1 -0
  12. package/dist/core/multipart.d.ts +16 -0
  13. package/dist/core/multipart.js +68 -0
  14. package/dist/core/multipart.js.map +1 -0
  15. package/dist/core/pagination.d.ts +41 -0
  16. package/dist/core/pagination.js +63 -0
  17. package/dist/core/pagination.js.map +1 -0
  18. package/dist/core/request-options.d.ts +29 -0
  19. package/dist/core/request-options.js +2 -0
  20. package/dist/core/request-options.js.map +1 -0
  21. package/dist/core/resource.d.ts +5 -0
  22. package/dist/core/resource.js +7 -0
  23. package/dist/core/resource.js.map +1 -0
  24. package/dist/core/retry.d.ts +13 -0
  25. package/dist/core/retry.js +65 -0
  26. package/dist/core/retry.js.map +1 -0
  27. package/dist/core/streaming.d.ts +44 -0
  28. package/dist/core/streaming.js +238 -0
  29. package/dist/core/streaming.js.map +1 -0
  30. package/dist/index.d.ts +20 -0
  31. package/dist/index.js +12 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lib/chat-completion-stream.d.ts +26 -0
  34. package/dist/lib/chat-completion-stream.js +161 -0
  35. package/dist/lib/chat-completion-stream.js.map +1 -0
  36. package/dist/lib/output-text.d.ts +4 -0
  37. package/dist/lib/output-text.js +22 -0
  38. package/dist/lib/output-text.js.map +1 -0
  39. package/dist/lib/response-stream.d.ts +30 -0
  40. package/dist/lib/response-stream.js +122 -0
  41. package/dist/lib/response-stream.js.map +1 -0
  42. package/dist/lib/strict-schema.d.ts +11 -0
  43. package/dist/lib/strict-schema.js +116 -0
  44. package/dist/lib/strict-schema.js.map +1 -0
  45. package/dist/resources/audio.d.ts +46 -0
  46. package/dist/resources/audio.js +24 -0
  47. package/dist/resources/audio.js.map +1 -0
  48. package/dist/resources/batches.d.ts +20 -0
  49. package/dist/resources/batches.js +24 -0
  50. package/dist/resources/batches.js.map +1 -0
  51. package/dist/resources/chat.d.ts +63 -0
  52. package/dist/resources/chat.js +79 -0
  53. package/dist/resources/chat.js.map +1 -0
  54. package/dist/resources/conversations.d.ts +23 -0
  55. package/dist/resources/conversations.js +38 -0
  56. package/dist/resources/conversations.js.map +1 -0
  57. package/dist/resources/embeddings.d.ts +12 -0
  58. package/dist/resources/embeddings.js +34 -0
  59. package/dist/resources/embeddings.js.map +1 -0
  60. package/dist/resources/files.d.ts +15 -0
  61. package/dist/resources/files.js +27 -0
  62. package/dist/resources/files.js.map +1 -0
  63. package/dist/resources/models.d.ts +10 -0
  64. package/dist/resources/models.js +11 -0
  65. package/dist/resources/models.js.map +1 -0
  66. package/dist/resources/responses.d.ts +61 -0
  67. package/dist/resources/responses.js +85 -0
  68. package/dist/resources/responses.js.map +1 -0
  69. package/dist/types/audio.d.ts +172 -0
  70. package/dist/types/audio.js +2 -0
  71. package/dist/types/audio.js.map +1 -0
  72. package/dist/types/chat.d.ts +316 -0
  73. package/dist/types/chat.js +2 -0
  74. package/dist/types/chat.js.map +1 -0
  75. package/dist/types/conversations.d.ts +46 -0
  76. package/dist/types/conversations.js +2 -0
  77. package/dist/types/conversations.js.map +1 -0
  78. package/dist/types/platform.d.ts +151 -0
  79. package/dist/types/platform.js +2 -0
  80. package/dist/types/platform.js.map +1 -0
  81. package/dist/types/responses.d.ts +640 -0
  82. package/dist/types/responses.js +2 -0
  83. package/dist/types/responses.js.map +1 -0
  84. package/dist/types/shared.d.ts +108 -0
  85. package/dist/types/shared.js +2 -0
  86. package/dist/types/shared.js.map +1 -0
  87. package/dist/version.d.ts +1 -0
  88. package/dist/version.js +2 -0
  89. package/dist/version.js.map +1 -0
  90. package/package.json +37 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Glexir
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,293 @@
1
- # Temporary Holding Version
1
+ # @glexir/sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The official TypeScript SDK for the Glexir API. It works with OpenAI's text LLMs, speech-to-text, embeddings, files and batches, and uses the same request and response format as OpenAI's API, so code written for OpenAI's SDK ports over easily.
4
+
5
+ - No runtime dependencies. Runs on Node 20+, Deno, Bun, edge runtimes and browsers (anywhere with `fetch`).
6
+ - Retries automatically. Every non-GET request sends an `Idempotency-Key`, so a retry is never billed twice.
7
+ - Typed streaming helpers, structured-output parsing, and lists you can page through with `for await`.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ pnpm add @glexir/sdk
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```ts
18
+ import Glexir from '@glexir/sdk';
19
+
20
+ const glexir = new Glexir({
21
+ apiKey: process.env.GLEXIR_API_KEY, // the default
22
+ baseURL: 'https://<your-glexir-gateway>/v1', // or set GLEXIR_BASE_URL
23
+ });
24
+
25
+ const response = await glexir.responses.create({
26
+ model: 'gpt-6-luna',
27
+ instructions: 'You are terse.',
28
+ input: 'Name three planets.',
29
+ });
30
+ console.log(response.output_text);
31
+ ```
32
+
33
+ ## Client options
34
+
35
+ | Option | Default | |
36
+ | --- | --- | --- |
37
+ | `apiKey` | `GLEXIR_API_KEY` | Your Glexir key (`glx_...`). |
38
+ | `baseURL` | `GLEXIR_BASE_URL`, then `https://api.glexir.com/v1` | Gateway URL. For a local gateway, use `http://localhost:8787/v1`. |
39
+ | `timeout` | 10 minutes | Per attempt. Once a stream has started, it has no timeout. |
40
+ | `maxRetries` | 2 | Retries connection errors and 408/409/429/5xx responses. Waits 0.5s, then 1s, 2s and so on up to 8s, with jitter. Uses the server's `retry-after` delay when it is 60s or less. |
41
+ | `fetch` | `globalThis.fetch` | Supply your own (proxies, tests). |
42
+ | `defaultHeaders` | | Sent on every request. |
43
+
44
+ Every method also takes request options as its last argument: `{ signal, timeout, maxRetries, headers, idempotencyKey }`.
45
+
46
+ ## Responses API (recommended)
47
+
48
+ ```ts
49
+ // Multi-turn without server-side storage: replay the output items yourself.
50
+ const first = await glexir.responses.create({ model: 'gpt-6-luna', input: 'Pick a number', store: false });
51
+ const second = await glexir.responses.create({
52
+ model: 'gpt-6-luna',
53
+ store: false,
54
+ input: [...first.output, { role: 'user', content: 'Double it' }],
55
+ });
56
+
57
+ // Images and PDFs as input
58
+ await glexir.responses.create({
59
+ model: 'gpt-6-luna',
60
+ input: [
61
+ {
62
+ role: 'user',
63
+ content: [
64
+ { type: 'input_text', text: 'What is in this image?' },
65
+ { type: 'input_image', detail: 'auto', image_url: 'https://example.com/cat.png' },
66
+ { type: 'input_file', file_url: 'https://example.com/report.pdf' },
67
+ ],
68
+ },
69
+ ],
70
+ });
71
+ ```
72
+
73
+ ### Streaming
74
+
75
+ ```ts
76
+ const stream = glexir.responses.stream({ model: 'gpt-6-luna', input: 'Write a haiku' });
77
+ for await (const event of stream) {
78
+ if (event.type === 'response.output_text.delta') process.stdout.write(event.delta);
79
+ }
80
+ const final = await stream.finalResponse(); // full Response including usage
81
+ ```
82
+
83
+ Use `glexir.responses.create({ ..., stream: true })` to get the raw event `Stream` instead. If a background response was created with `stream: true`, you can resume its stream with `glexir.responses.stream({ response_id, starting_after })`.
84
+
85
+ ### Function calling
86
+
87
+ ```ts
88
+ const res = await glexir.responses.create({
89
+ model: 'gpt-6-luna',
90
+ input: 'Weather in Lagos?',
91
+ tools: [
92
+ {
93
+ type: 'function',
94
+ name: 'get_weather',
95
+ parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'], additionalProperties: false },
96
+ strict: true,
97
+ },
98
+ ],
99
+ });
100
+ for (const item of res.output) {
101
+ if (item.type === 'function_call') console.log(item.name, JSON.parse(item.arguments));
102
+ }
103
+ ```
104
+
105
+ Glexir supports `function`, `custom` and `namespace` tools. The gateway rejects OpenAI-hosted tools: web search, file search, code interpreter, MCP, image generation, shell and computer use.
106
+
107
+ ### Structured outputs
108
+
109
+ ```ts
110
+ import { toStrictJsonSchema } from '@glexir/sdk';
111
+
112
+ const schema = toStrictJsonSchema({
113
+ type: 'object',
114
+ properties: { name: { type: 'string' }, age: { type: ['integer', 'null'] } },
115
+ required: ['name'],
116
+ });
117
+
118
+ const res = await glexir.responses.parse(
119
+ { model: 'gpt-6-luna', input: 'Ada Lovelace, 36', text: { format: { type: 'json_schema', name: 'person', schema, strict: true } } },
120
+ { validate: (value) => PersonSchema.parse(value) }, // optional, e.g. zod
121
+ );
122
+ res.output_parsed; // { name: 'Ada Lovelace', age: 36 }
123
+ ```
124
+
125
+ `toStrictJsonSchema` applies the strict-mode rules for you:
126
+
127
+ - It adds `additionalProperties: false` to every object.
128
+ - It makes every property required. If an optional property isn't nullable, it throws instead.
129
+ - It throws on keywords strict mode doesn't support, such as `oneOf`, `if` or `patternProperties`.
130
+
131
+ `parse()` throws `LengthFinishReasonError` or `ContentFilterFinishReasonError` when the output was cut off.
132
+
133
+ ### Other Responses endpoints
134
+
135
+ ```ts
136
+ await glexir.responses.retrieve('resp_123');
137
+ await glexir.responses.cancel('resp_123'); // background responses
138
+ await glexir.responses.delete('resp_123');
139
+ await glexir.responses.inputTokens.count({ model: 'gpt-6-luna', input: 'How many tokens?' });
140
+ await glexir.responses.compact({ model: 'gpt-6-luna', input: longHistory });
141
+ for await (const item of glexir.responses.inputItems.list('resp_123')) console.log(item.type);
142
+ ```
143
+
144
+ ## Conversations
145
+
146
+ ```ts
147
+ const conversation = await glexir.conversations.create({ metadata: { topic: 'support' } });
148
+ await glexir.responses.create({ model: 'gpt-6-luna', conversation: conversation.id, input: 'Hi!' });
149
+ for await (const item of glexir.conversations.items.list(conversation.id, { order: 'asc' })) console.log(item);
150
+ ```
151
+
152
+ ## Chat Completions
153
+
154
+ Chat Completions works the same as on OpenAI. On GPT-5.4 and later it only supports tool calling when `reasoning_effort` is `none`. `gpt-6-astra` and `gpt-6.1-sol` need the Responses API for tool calling.
155
+
156
+ ```ts
157
+ const completion = await glexir.chat.completions.create({
158
+ model: 'gpt-6-luna',
159
+ messages: [
160
+ { role: 'developer', content: 'You are terse.' },
161
+ { role: 'user', content: 'Hello' },
162
+ ],
163
+ });
164
+
165
+ const stream = glexir.chat.completions.stream({ model: 'gpt-6-luna', messages: [{ role: 'user', content: 'Count to 5' }] });
166
+ for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta.content ?? '');
167
+ const final = await stream.finalChatCompletion(); // tool-call fragments merged by index
168
+
169
+ await glexir.chat.completions.parse({
170
+ model: 'gpt-6-luna',
171
+ messages: [{ role: 'user', content: 'Extract' }],
172
+ response_format: { type: 'json_schema', json_schema: { name: 'out', schema, strict: true } },
173
+ });
174
+ ```
175
+
176
+ Completions stored with `store: true` have their own endpoints: `retrieve`, `update`, `list`, `delete` and `messages.list`.
177
+
178
+ ## Transcription
179
+
180
+ ```ts
181
+ import { toFile } from '@glexir/sdk';
182
+ import { readFile } from 'node:fs/promises';
183
+
184
+ const transcript = await glexir.audio.transcriptions.create({
185
+ file: await toFile(await readFile('call.m4a'), 'call.m4a'),
186
+ model: 'gpt-transcribe',
187
+ languages: ['en'],
188
+ keywords: ['Glexir'],
189
+ });
190
+ transcript.text;
191
+
192
+ // Subtitles come back as a string
193
+ const srt = await glexir.audio.transcriptions.create({ file, model: 'whisper-1', response_format: 'srt' });
194
+
195
+ // Speaker labels
196
+ const diarized = await glexir.audio.transcriptions.create({
197
+ file,
198
+ model: 'gpt-4o-transcribe-diarize',
199
+ response_format: 'diarized_json',
200
+ chunking_strategy: 'auto',
201
+ });
202
+ diarized.segments.map((s) => `${s.speaker}: ${s.text}`);
203
+
204
+ // Streaming
205
+ const events = await glexir.audio.transcriptions.create({ file, model: 'gpt-transcribe', stream: true });
206
+ for await (const event of events) if (event.type === 'transcript.text.delta') process.stdout.write(event.delta);
207
+ ```
208
+
209
+ Files can be up to 25 MB, in flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav or webm. OpenAI detects the format from the filename, so pass a `File` or use `toFile(data, 'name.ext')`.
210
+
211
+ `whisper-1`, the `gpt-4o-*-transcribe` models and `audio.translations` all shut down on **2027-02-26**. Use `gpt-transcribe`.
212
+
213
+ ## Embeddings
214
+
215
+ ```ts
216
+ const { data } = await glexir.embeddings.create({ model: 'text-embedding-3-small', input: ['first', 'second'] });
217
+ data[0].embedding; // number[]
218
+ ```
219
+
220
+ If you leave out `encoding_format`, the SDK requests compact base64 over the wire and decodes it to `number[]` for you.
221
+
222
+ ## Files and batches
223
+
224
+ Batch jobs cost 50% less and complete within 24 hours.
225
+
226
+ ```ts
227
+ import { toBatchJSONL } from '@glexir/sdk';
228
+
229
+ const input = await glexir.files.create({
230
+ purpose: 'batch',
231
+ file: toBatchJSONL([
232
+ { custom_id: 'q1', url: '/v1/responses', body: { model: 'gpt-6-luna', input: 'Hello' } },
233
+ { custom_id: 'q2', url: '/v1/responses', body: { model: 'gpt-6-luna', input: 'Bonjour' } },
234
+ ]),
235
+ });
236
+ const batch = await glexir.batches.create({ input_file_id: input.id, endpoint: '/v1/responses', completion_window: '24h' });
237
+
238
+ // later
239
+ const done = await glexir.batches.retrieve(batch.id);
240
+ if (done.output_file_id) {
241
+ const text = await (await glexir.files.content(done.output_file_id)).text();
242
+ // one JSON object per line; join on custom_id (order is not preserved)
243
+ }
244
+ ```
245
+
246
+ For PDFs and images used as model input, upload with `purpose: 'user_data'` and reference the file by `file_id`.
247
+
248
+ ## Models
249
+
250
+ ```ts
251
+ for await (const model of glexir.models.list()) console.log(model.id, model.shutdown_date);
252
+ ```
253
+
254
+ ## Errors
255
+
256
+ Every API error is an `APIError` with `status`, `code`, `type`, `param` and `requestID`. Each status code has its own subclass:
257
+
258
+ | Status | Class |
259
+ | --- | --- |
260
+ | 400 | `BadRequestError` |
261
+ | 401 | `AuthenticationError` |
262
+ | 403 | `PermissionDeniedError` |
263
+ | 404 | `NotFoundError` |
264
+ | 409 | `ConflictError` |
265
+ | 422 | `UnprocessableEntityError` |
266
+ | 429 | `RateLimitError` |
267
+ | 5xx | `InternalServerError` |
268
+
269
+ Network failures throw `APIConnectionError` or `APIConnectionTimeoutError`, and an aborted request throws `APIUserAbortError`. An error that arrives in the middle of a stream is an `APIError` with `status === undefined`, so check `err.code` rather than the class.
270
+
271
+ ```ts
272
+ import { APIError, RateLimitError } from '@glexir/sdk';
273
+
274
+ try {
275
+ await glexir.responses.create({ model: 'gpt-6-luna', input: 'hi' });
276
+ } catch (err) {
277
+ if (err instanceof RateLimitError) console.log('slow down', err.requestID);
278
+ else if (err instanceof APIError) console.log(err.status, err.code, err.message);
279
+ else throw err;
280
+ }
281
+ ```
282
+
283
+ ## Raw responses and request IDs
284
+
285
+ Parsed objects carry the gateway request ID as `_request_id`. To also get the HTTP response, call `.withRawResponse()`:
286
+
287
+ ```ts
288
+ const { data, response, requestId } = await glexir.responses.create({ model: 'gpt-6-luna', input: 'hi' }).withRawResponse();
289
+ ```
290
+
291
+ ## Not included
292
+
293
+ Glexir covers text LLMs and speech-to-text. The SDK doesn't include images, text-to-speech, realtime/WebSocket, video, assistants, fine-tuning, vector stores, uploads or decisions.
@@ -0,0 +1,61 @@
1
+ import { APIPromise, type APIResponseProps } from './core/api-promise.js';
2
+ import { PagePromise, type CursorStrategy } from './core/pagination.js';
3
+ import type { FinalRequestOptions, RequestOptions } from './core/request-options.js';
4
+ import { Audio } from './resources/audio.js';
5
+ import { Batches } from './resources/batches.js';
6
+ import { Chat } from './resources/chat.js';
7
+ import { Conversations } from './resources/conversations.js';
8
+ import { Embeddings } from './resources/embeddings.js';
9
+ import { Files } from './resources/files.js';
10
+ import { Models } from './resources/models.js';
11
+ import { Responses } from './resources/responses.js';
12
+ export declare const DEFAULT_BASE_URL = "https://api.glexir.com/v1";
13
+ export interface ClientOptions {
14
+ /** Defaults to `process.env.GLEXIR_API_KEY`. */
15
+ apiKey?: string;
16
+ /** Defaults to `process.env.GLEXIR_BASE_URL`, then the production gateway at `https://api.glexir.com/v1`. */
17
+ baseURL?: string;
18
+ /** Per-attempt timeout in milliseconds. Default 10 minutes. */
19
+ timeout?: number;
20
+ /** Retries for connection errors and 408/409/429/5xx responses. Default 2. */
21
+ maxRetries?: number;
22
+ /** Custom `fetch` implementation (e.g. for proxies or tests). */
23
+ fetch?: typeof fetch;
24
+ /** Headers sent with every request. */
25
+ defaultHeaders?: Record<string, string>;
26
+ /** @internal Override the retry sleep (tests). */
27
+ sleep?: (ms: number, signal?: AbortSignal | null) => Promise<void>;
28
+ }
29
+ /**
30
+ * The Glexir API client. Wire-compatible with OpenAI's API for text LLMs, transcription,
31
+ * embeddings, files and batches.
32
+ */
33
+ export declare class Glexir {
34
+ readonly apiKey: string;
35
+ readonly baseURL: string;
36
+ readonly timeout: number;
37
+ readonly maxRetries: number;
38
+ readonly responses: Responses;
39
+ readonly conversations: Conversations;
40
+ readonly chat: Chat;
41
+ readonly audio: Audio;
42
+ readonly embeddings: Embeddings;
43
+ readonly files: Files;
44
+ readonly batches: Batches;
45
+ readonly models: Models;
46
+ private readonly fetchImpl;
47
+ private readonly defaultHeaders;
48
+ private readonly sleep;
49
+ constructor(options?: ClientOptions);
50
+ get<T>(path: string, options?: Partial<FinalRequestOptions>): APIPromise<T>;
51
+ post<T>(path: string, options?: Partial<FinalRequestOptions>): APIPromise<T>;
52
+ delete<T>(path: string, options?: Partial<FinalRequestOptions>): APIPromise<T>;
53
+ request<T>(options: FinalRequestOptions, parse?: (props: APIResponseProps) => Promise<T>): APIPromise<T>;
54
+ /** @internal */
55
+ requestAPIList<Item>(options: FinalRequestOptions, cursor: CursorStrategy): PagePromise<Item>;
56
+ buildURL(path: string, query?: Record<string, unknown>): string;
57
+ private buildHeaders;
58
+ private sleepOrAbort;
59
+ private makeRequest;
60
+ }
61
+ export type { RequestOptions };
package/dist/client.js ADDED
@@ -0,0 +1,245 @@
1
+ import { APIPromise } from './core/api-promise.js';
2
+ import { APIConnectionError, APIConnectionTimeoutError, APIError, APIUserAbortError, GlexirError, } from './core/errors.js';
3
+ import { buildMultipartForm } from './core/multipart.js';
4
+ import { PagePromise } from './core/pagination.js';
5
+ import { defaultBackoffMs, retryDelayMs, shouldRetryResponse, sleep, uuid4 } from './core/retry.js';
6
+ import { Stream } from './core/streaming.js';
7
+ import { Audio } from './resources/audio.js';
8
+ import { Batches } from './resources/batches.js';
9
+ import { Chat } from './resources/chat.js';
10
+ import { Conversations } from './resources/conversations.js';
11
+ import { Embeddings } from './resources/embeddings.js';
12
+ import { Files } from './resources/files.js';
13
+ import { Models } from './resources/models.js';
14
+ import { Responses } from './resources/responses.js';
15
+ import { VERSION } from './version.js';
16
+ export const DEFAULT_BASE_URL = 'https://api.glexir.com/v1';
17
+ const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;
18
+ const DEFAULT_MAX_RETRIES = 2;
19
+ function readEnv(name) {
20
+ const env = globalThis.process?.env;
21
+ return env?.[name]?.trim() || undefined;
22
+ }
23
+ function appendQuery(params, key, value) {
24
+ if (value === undefined || value === null)
25
+ return;
26
+ if (Array.isArray(value)) {
27
+ for (const entry of value)
28
+ appendQuery(params, `${key}[]`, entry);
29
+ }
30
+ else if (typeof value === 'object') {
31
+ for (const [sub, entry] of Object.entries(value))
32
+ appendQuery(params, `${key}[${sub}]`, entry);
33
+ }
34
+ else {
35
+ params.append(key, String(value));
36
+ }
37
+ }
38
+ /** Attaches the `x-request-id` header as a non-enumerable `_request_id` property. */
39
+ function addRequestID(value, response) {
40
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
41
+ Object.defineProperty(value, '_request_id', {
42
+ value: response.headers.get('x-request-id'),
43
+ enumerable: false,
44
+ configurable: true,
45
+ writable: true,
46
+ });
47
+ }
48
+ return value;
49
+ }
50
+ async function defaultParseResponse(props) {
51
+ const { response, options, controller } = props;
52
+ if (options.stream)
53
+ return Stream.fromSSEResponse(response, controller);
54
+ if (options.binary)
55
+ return response;
56
+ if (response.status === 204)
57
+ return undefined;
58
+ const contentType = response.headers.get('content-type') ?? '';
59
+ if (contentType.includes('application/json') || contentType.includes('+json')) {
60
+ const text = await response.text();
61
+ if (!text)
62
+ return undefined;
63
+ return addRequestID(JSON.parse(text), response);
64
+ }
65
+ return (await response.text());
66
+ }
67
+ /** Buffers a body inside the timeout window so slow bodies count against `timeout`. */
68
+ async function bufferResponse(response) {
69
+ const nullBody = response.status === 204 || response.status === 205 || response.status === 304;
70
+ const body = nullBody ? null : await response.arrayBuffer();
71
+ return new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
72
+ }
73
+ /**
74
+ * The Glexir API client. Wire-compatible with OpenAI's API for text LLMs, transcription,
75
+ * embeddings, files and batches.
76
+ */
77
+ export class Glexir {
78
+ apiKey;
79
+ baseURL;
80
+ timeout;
81
+ maxRetries;
82
+ responses = new Responses(this);
83
+ conversations = new Conversations(this);
84
+ chat = new Chat(this);
85
+ audio = new Audio(this);
86
+ embeddings = new Embeddings(this);
87
+ files = new Files(this);
88
+ batches = new Batches(this);
89
+ models = new Models(this);
90
+ fetchImpl;
91
+ defaultHeaders;
92
+ sleep;
93
+ constructor(options = {}) {
94
+ const apiKey = options.apiKey ?? readEnv('GLEXIR_API_KEY');
95
+ if (!apiKey) {
96
+ throw new GlexirError('Missing API key. Pass `new Glexir({ apiKey })` or set the GLEXIR_API_KEY environment variable.');
97
+ }
98
+ this.apiKey = apiKey;
99
+ this.baseURL = (options.baseURL ?? readEnv('GLEXIR_BASE_URL') ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
100
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT_MS;
101
+ this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
102
+ this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
103
+ this.defaultHeaders = options.defaultHeaders ?? {};
104
+ this.sleep = options.sleep ?? sleep;
105
+ }
106
+ get(path, options) {
107
+ return this.request({ ...options, method: 'get', path });
108
+ }
109
+ post(path, options) {
110
+ return this.request({ ...options, method: 'post', path });
111
+ }
112
+ delete(path, options) {
113
+ return this.request({ ...options, method: 'delete', path });
114
+ }
115
+ request(options, parse = defaultParseResponse) {
116
+ return new APIPromise(this.makeRequest(options), parse);
117
+ }
118
+ /** @internal */
119
+ requestAPIList(options, cursor) {
120
+ return new PagePromise(this, this.makeRequest(options), (props) => defaultParseResponse(props), cursor);
121
+ }
122
+ buildURL(path, query) {
123
+ const url = new URL(this.baseURL + (path.startsWith('/') ? path : `/${path}`));
124
+ if (query) {
125
+ const params = new URLSearchParams();
126
+ for (const [key, value] of Object.entries(query))
127
+ appendQuery(params, key, value);
128
+ const search = params.toString();
129
+ if (search)
130
+ url.search = search;
131
+ }
132
+ return url.toString();
133
+ }
134
+ buildHeaders(options, retryCount, idempotencyKey, isJSON) {
135
+ const headers = new Headers();
136
+ headers.set('accept', options.stream ? 'text/event-stream' : 'application/json');
137
+ headers.set('authorization', `Bearer ${this.apiKey}`);
138
+ headers.set('x-glexir-sdk', `js/${VERSION}`);
139
+ headers.set('x-glexir-retry-count', String(retryCount));
140
+ if (isJSON)
141
+ headers.set('content-type', 'application/json');
142
+ if (idempotencyKey)
143
+ headers.set('idempotency-key', idempotencyKey);
144
+ for (const [key, value] of Object.entries(this.defaultHeaders))
145
+ headers.set(key, value);
146
+ for (const [key, value] of Object.entries(options.headers ?? {})) {
147
+ if (value === null)
148
+ headers.delete(key);
149
+ else if (value !== undefined)
150
+ headers.set(key, value);
151
+ }
152
+ return headers;
153
+ }
154
+ async sleepOrAbort(ms, signal) {
155
+ try {
156
+ await this.sleep(ms, signal);
157
+ }
158
+ catch {
159
+ throw new APIUserAbortError();
160
+ }
161
+ }
162
+ async makeRequest(options) {
163
+ const maxRetries = options.maxRetries ?? this.maxRetries;
164
+ const idempotencyKey = options.method === 'get' ? undefined : (options.idempotencyKey ?? uuid4());
165
+ const url = this.buildURL(options.path, options.query);
166
+ let body;
167
+ let isJSON = false;
168
+ if (options.multipart) {
169
+ body = await buildMultipartForm((options.body ?? {}));
170
+ }
171
+ else if (options.body !== undefined) {
172
+ body = JSON.stringify(options.body);
173
+ isJSON = true;
174
+ }
175
+ // Bodies we cannot replay are never retried.
176
+ const canRetryBody = !(typeof ReadableStream !== 'undefined' && body instanceof ReadableStream);
177
+ const userSignal = options.signal ?? undefined;
178
+ for (let attempt = 0;; attempt++) {
179
+ const retriesRemaining = maxRetries - attempt;
180
+ if (userSignal?.aborted)
181
+ throw new APIUserAbortError();
182
+ const controller = new AbortController();
183
+ const onUserAbort = () => controller.abort(userSignal?.reason);
184
+ userSignal?.addEventListener('abort', onUserAbort, { once: true });
185
+ let timedOut = false;
186
+ const timer = setTimeout(() => {
187
+ timedOut = true;
188
+ controller.abort();
189
+ }, options.timeout ?? this.timeout);
190
+ const cleanup = () => {
191
+ clearTimeout(timer);
192
+ userSignal?.removeEventListener('abort', onUserAbort);
193
+ };
194
+ let response;
195
+ try {
196
+ response = await this.fetchImpl(url, {
197
+ method: options.method.toUpperCase(),
198
+ headers: this.buildHeaders(options, attempt, idempotencyKey, isJSON),
199
+ body,
200
+ signal: controller.signal,
201
+ });
202
+ if (response.ok && !options.stream && !options.binary) {
203
+ response = await bufferResponse(response);
204
+ }
205
+ }
206
+ catch (err) {
207
+ cleanup();
208
+ if (userSignal?.aborted)
209
+ throw new APIUserAbortError();
210
+ if (retriesRemaining > 0 && canRetryBody) {
211
+ await this.sleepOrAbort(defaultBackoffMs(attempt), userSignal);
212
+ continue;
213
+ }
214
+ if (timedOut)
215
+ throw new APIConnectionTimeoutError();
216
+ throw new APIConnectionError({ cause: err });
217
+ }
218
+ if (!response.ok) {
219
+ if (retriesRemaining > 0 && canRetryBody && shouldRetryResponse(response)) {
220
+ await response.body?.cancel().catch(() => { });
221
+ cleanup();
222
+ await this.sleepOrAbort(retryDelayMs(response.headers, attempt), userSignal);
223
+ continue;
224
+ }
225
+ const text = await response.text().catch(() => '');
226
+ cleanup();
227
+ let json;
228
+ try {
229
+ json = text ? JSON.parse(text) : undefined;
230
+ }
231
+ catch {
232
+ json = undefined;
233
+ }
234
+ throw APIError.generate(response.status, json, json === undefined ? text || undefined : undefined, response.headers);
235
+ }
236
+ // Streams have no overall timeout once headers arrive; the user's signal still cancels them.
237
+ if (options.stream || options.binary)
238
+ clearTimeout(timer);
239
+ else
240
+ cleanup();
241
+ return { response, controller, options, retryCount: attempt };
242
+ }
243
+ }
244
+ }
245
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { FinalRequestOptions } from './request-options.js';
2
+ export interface APIResponseProps {
3
+ response: Response;
4
+ controller: AbortController;
5
+ options: FinalRequestOptions;
6
+ retryCount: number;
7
+ }
8
+ export interface WithRawResponse<T> {
9
+ data: T;
10
+ response: Response;
11
+ /** The `x-request-id` header; quote it in support requests. */
12
+ requestId: string | null;
13
+ }
14
+ /**
15
+ * The value returned by every API method. Await it for the parsed body, or call
16
+ * `.withRawResponse()` to also get the HTTP response and request ID.
17
+ */
18
+ export declare class APIPromise<T> implements PromiseLike<T> {
19
+ protected readonly responsePromise: Promise<APIResponseProps>;
20
+ protected readonly parseResponse: (props: APIResponseProps) => Promise<T>;
21
+ private parsed;
22
+ constructor(responsePromise: Promise<APIResponseProps>, parseResponse: (props: APIResponseProps) => Promise<T>);
23
+ /** Returns a new promise that transforms the parsed body. */
24
+ _thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U>;
25
+ withRawResponse(): Promise<WithRawResponse<T>>;
26
+ /** The raw HTTP response, without parsing the body. */
27
+ asResponse(): Promise<Response>;
28
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
29
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
30
+ finally(onfinally?: (() => void) | null): Promise<T>;
31
+ }