@skailar-ai/sdk 0.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.
@@ -0,0 +1,1254 @@
1
+ /**
2
+ * Shared primitive types used across multiple Skailar API resources.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * A string union that keeps IDE autocomplete for known members while still
8
+ * accepting any arbitrary string.
9
+ *
10
+ * TypeScript collapses `"a" | "b" | string` down to `string`, which destroys
11
+ * editor suggestions. Intersecting the open end with `Record<never, never>`
12
+ * (spelled `string & {}`) prevents that collapse, so known literals are offered
13
+ * as completions yet any string remains assignable. Used for model identifiers,
14
+ * whose catalog evolves faster than this SDK is released.
15
+ *
16
+ * @typeParam Known - The union of literal strings to surface as autocomplete hints.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * type ModelId = LiteralUnion<"gpt-5" | "claude-opus-4-8">;
21
+ * const a: ModelId = "gpt-5"; // autocompleted
22
+ * const b: ModelId = "some-new-model"; // still allowed
23
+ * ```
24
+ */
25
+ type LiteralUnion<Known extends string> = Known | (string & Record<never, never>);
26
+ /**
27
+ * Token accounting returned with every completion, streamed or not.
28
+ *
29
+ * Mirrors the OpenAI `usage` object. On a stream each chunk carries the running
30
+ * totals observed so far rather than a per-chunk delta.
31
+ */
32
+ interface Usage {
33
+ /** Tokens consumed by the prompt (input side). */
34
+ prompt_tokens: number;
35
+ /** Tokens produced by the model (output side). */
36
+ completion_tokens: number;
37
+ /** Sum of {@link Usage.prompt_tokens} and {@link Usage.completion_tokens}. */
38
+ total_tokens: number;
39
+ }
40
+
41
+ /**
42
+ * Types for the chat completions resource (`POST /v1/chat/completions`),
43
+ * modelled on the OpenAI wire format so the SDK is a drop-in replacement for
44
+ * `openai` for these calls.
45
+ *
46
+ * @packageDocumentation
47
+ */
48
+
49
+ /**
50
+ * Identifiers of models known to the gateway at the time this SDK was cut, used
51
+ * to power editor autocomplete.
52
+ *
53
+ * This is intentionally a {@link LiteralUnion}: the list is a convenience hint,
54
+ * not an enforced enum. The authoritative, always-current catalog is
55
+ * `GET /v1/models`; new models work immediately without an SDK upgrade.
56
+ */
57
+ type KnownModelId = "epoch-mini" | "claude-opus-4-8" | "claude-opus-4-7" | "claude-sonnet-4-6" | "claude-opus-4-6" | "claude-haiku-4-5" | "claude-sonnet-4-5" | "o3" | "o4-mini" | "gpt-5" | "gpt-5-mini" | "gpt-5.1" | "gpt-5.4" | "gpt-5.4-nano" | "gpt-5.4-mini" | "gpt-5.5" | "gemini-2.5-flash" | "gemini-2.5-pro" | "gemini-2.5-flash-lite" | "gemini-3-flash-preview" | "gemini-3.1-pro-preview" | "gemini-3.5-flash" | "deepseek-v4-flash" | "deepseek-v4-pro" | "grok-4.20-non-reasoning" | "grok-4.20-reasoning" | "grok-4.3" | "grok-build-0.1" | "gpt-image-1";
58
+ /** A model identifier: any known id (with autocomplete) or any other string. */
59
+ type ModelId = LiteralUnion<KnownModelId>;
60
+ /** The conversational role attached to a {@link ChatMessage}. */
61
+ type ChatRole = "system" | "user" | "assistant" | "tool";
62
+ /** A plain-text fragment of multi-part message content. */
63
+ interface TextContentPart {
64
+ type: "text";
65
+ /** The literal text contributed by this part. */
66
+ text: string;
67
+ }
68
+ /**
69
+ * An image fragment of multi-part message content, used for vision input.
70
+ *
71
+ * The `url` may be an inline `data:` URI (base64) or an HTTPS URL, for instance
72
+ * one returned by `POST /v1/uploads/images`.
73
+ */
74
+ interface ImageContentPart {
75
+ type: "image_url";
76
+ image_url: {
77
+ /** A `data:` URI or HTTPS URL pointing at the image. */
78
+ url: string;
79
+ /**
80
+ * Requested analysis fidelity: `low` is cheaper/faster, `high` preserves
81
+ * detail, `auto` lets the upstream provider decide.
82
+ */
83
+ detail?: "low" | "high" | "auto";
84
+ };
85
+ }
86
+ /** A single fragment of structured message content. */
87
+ type ContentPart = TextContentPart | ImageContentPart;
88
+ /**
89
+ * Message content: a simple string, an ordered array of parts (for mixed text +
90
+ * vision), or `null` (e.g. an assistant turn that only carries tool calls).
91
+ */
92
+ type MessageContent = string | ContentPart[] | null;
93
+ /**
94
+ * One message in a chat conversation.
95
+ *
96
+ * For `role: "tool"`, {@link ChatMessage.tool_call_id} is required and must
97
+ * reference the `id` of the assistant tool call being answered.
98
+ */
99
+ interface ChatMessage {
100
+ role: ChatRole;
101
+ /** The message payload; optional for assistant tool-call-only turns. */
102
+ content?: MessageContent;
103
+ /** Tool calls requested by the assistant on this turn, if any. */
104
+ tool_calls?: ToolCall[];
105
+ /** Identifier of the tool call this message responds to; required when `role` is `"tool"`. */
106
+ tool_call_id?: string;
107
+ }
108
+ /**
109
+ * A function-calling tool definition, OpenAI-compatible.
110
+ *
111
+ * @remarks
112
+ * Tools use the OpenAI shape (`type: "function"`, `function.parameters` as JSON
113
+ * Schema). The gateway translates this into each provider's native format —
114
+ * e.g. Anthropic's `input_schema` — so provider-native tool shapes are not
115
+ * exposed by the SDK in this version.
116
+ */
117
+ interface Tool {
118
+ type: "function";
119
+ function: {
120
+ /** Unique function name the model may invoke. */
121
+ name: string;
122
+ /** Natural-language description guiding when to call it. */
123
+ description?: string;
124
+ /**
125
+ * JSON Schema describing the function's arguments. Left as an open record
126
+ * because the SDK ships no runtime schema validator.
127
+ */
128
+ parameters?: Record<string, unknown>;
129
+ };
130
+ }
131
+ /**
132
+ * Controls whether and how the model may call tools: `"auto"` lets the model
133
+ * decide, `"none"` forbids tool use, `"required"` forces at least one call, and
134
+ * the object form pins a specific function by name.
135
+ */
136
+ type ToolChoice = "auto" | "none" | "required" | {
137
+ type: "function";
138
+ function: {
139
+ /** Name of the function to force. */
140
+ name: string;
141
+ };
142
+ };
143
+ /** A tool invocation emitted by the assistant. */
144
+ interface ToolCall {
145
+ /** Stable identifier correlating this call with its tool result. */
146
+ id: string;
147
+ type: "function";
148
+ function: {
149
+ /** Name of the invoked function. */
150
+ name: string;
151
+ /**
152
+ * JSON-encoded argument object, as a string. Per the OpenAI contract this is
153
+ * a string of JSON, not a parsed object — callers must `JSON.parse` it.
154
+ */
155
+ arguments: string;
156
+ };
157
+ }
158
+ /**
159
+ * Reasoning budget for reasoning-capable models (Claude extended thinking,
160
+ * OpenAI o-series, DeepSeek-R1, Gemini thinking). Ignored by other models.
161
+ */
162
+ type ReasoningEffort = "low" | "medium" | "high";
163
+ /**
164
+ * Requested output structure, OpenAI-compatible. Honored only when the selected
165
+ * upstream model supports it. Use `{ type: "json_object" }` for free-form JSON
166
+ * or `{ type: "json_schema", json_schema: {...} }` for constrained output.
167
+ */
168
+ interface ResponseFormat {
169
+ type: "text" | "json_object" | "json_schema";
170
+ /** Schema descriptor, present when {@link ResponseFormat.type} is `"json_schema"`. */
171
+ json_schema?: Record<string, unknown>;
172
+ }
173
+ /**
174
+ * Request body for `POST /v1/chat/completions`. Field names and semantics match
175
+ * the OpenAI Chat Completions API. The `stream` field narrows the method's
176
+ * return type at compile time via overloads on the resource.
177
+ */
178
+ interface ChatCompletionRequest {
179
+ /** Model identifier or alias to route the request to. */
180
+ model: ModelId;
181
+ /** The ordered conversation history. */
182
+ messages: ChatMessage[];
183
+ /** When `true`, responses arrive incrementally as SSE chunks. */
184
+ stream?: boolean;
185
+ /** Hard cap on tokens generated for the completion. */
186
+ max_tokens?: number;
187
+ /** Sampling temperature in `[0, 2]`; higher is more random. */
188
+ temperature?: number;
189
+ /** Nucleus sampling probability mass in `[0, 1]`. */
190
+ top_p?: number;
191
+ /** Reasoning budget for reasoning-capable models. */
192
+ reasoning_effort?: ReasoningEffort;
193
+ /** Tool definitions the model may call. */
194
+ tools?: Tool[];
195
+ /** Constraint on whether/which tools may be called. */
196
+ tool_choice?: ToolChoice;
197
+ /** Requested output structure. */
198
+ response_format?: ResponseFormat;
199
+ /** Number of independent completions to generate (default `1`). */
200
+ n?: number;
201
+ /** Penalty in `[-2, 2]` discouraging repeated topics. */
202
+ presence_penalty?: number;
203
+ /** Penalty in `[-2, 2]` discouraging repeated tokens. */
204
+ frequency_penalty?: number;
205
+ /** Per-token logit bias map keyed by token id. */
206
+ logit_bias?: Record<string, number>;
207
+ /** Opaque stable end-user identifier for abuse monitoring. */
208
+ user?: string;
209
+ /** Seed for best-effort deterministic sampling. */
210
+ seed?: number;
211
+ /** One or more stop sequences that halt generation. */
212
+ stop?: string | string[];
213
+ }
214
+ /**
215
+ * Reason the model stopped generating a choice: `"stop"` natural end,
216
+ * `"length"` hit the token cap, `"tool_calls"` paused to call tools,
217
+ * `"content_filter"` blocked by moderation.
218
+ */
219
+ type FinishReason = "stop" | "length" | "tool_calls" | "content_filter";
220
+ /** A single completed choice within a non-streamed {@link ChatCompletion}. */
221
+ interface ChatCompletionChoice {
222
+ /** Zero-based position of this choice when `n > 1`. */
223
+ index: number;
224
+ message: {
225
+ role: "assistant";
226
+ /** The generated text; may be empty when only tool calls are present. */
227
+ content: string;
228
+ /** Reasoning trace for models that expose their thinking (e.g. DeepSeek). */
229
+ reasoning_content?: string;
230
+ /** Tool calls the assistant requested, if any. */
231
+ tool_calls?: ToolCall[];
232
+ };
233
+ /** Why generation stopped for this choice. */
234
+ finish_reason: FinishReason;
235
+ }
236
+ /** A complete, non-streamed chat completion (`object: "chat.completion"`). */
237
+ interface ChatCompletion {
238
+ id: string;
239
+ object: "chat.completion";
240
+ /** Creation time as Unix epoch seconds. */
241
+ created: number;
242
+ /** The model that actually served the request. */
243
+ model: string;
244
+ /** One entry per requested choice. */
245
+ choices: ChatCompletionChoice[];
246
+ usage: Usage;
247
+ }
248
+ /**
249
+ * Incremental tool-call fragment carried by a streamed delta.
250
+ *
251
+ * Streaming assembles a tool call across chunks: the first chunk for a given
252
+ * `index` carries `id`/`name`, subsequent chunks append to `arguments`.
253
+ */
254
+ interface ChatCompletionChunkToolCall {
255
+ /** Position of the tool call being assembled. */
256
+ index: number;
257
+ /** Tool call id, present on the opening fragment. */
258
+ id?: string;
259
+ type?: "function";
260
+ function?: {
261
+ /** Function name, present on the opening fragment. */
262
+ name?: string;
263
+ /** A slice of the JSON-encoded arguments string to append. */
264
+ arguments?: string;
265
+ };
266
+ }
267
+ /** A single choice slice within a streamed {@link ChatCompletionChunk}. */
268
+ interface ChatCompletionChunkChoice {
269
+ /** Zero-based position of this choice when `n > 1`. */
270
+ index: number;
271
+ delta: {
272
+ /** Present only on the first delta of the choice. */
273
+ role?: "assistant";
274
+ /** The text fragment to append to the running content. */
275
+ content?: string;
276
+ /** The reasoning-trace fragment to append, if any. */
277
+ reasoning_content?: string;
278
+ /** Tool-call fragments to merge by index. */
279
+ tool_calls?: ChatCompletionChunkToolCall[];
280
+ };
281
+ /** Stop reason, present on the terminal slice; may be `null` on intermediate chunks. */
282
+ finish_reason?: FinishReason | null;
283
+ }
284
+ /** One streamed delta of a chat completion (`object: "chat.completion.chunk"`). */
285
+ interface ChatCompletionChunk {
286
+ id: string;
287
+ object: "chat.completion.chunk";
288
+ /** Creation time as Unix epoch seconds. */
289
+ created: number;
290
+ model: string;
291
+ /** Incremental choice slices for this chunk. */
292
+ choices: ChatCompletionChunkChoice[];
293
+ /**
294
+ * Running token accounting. The Skailar gateway reports cumulative
295
+ * {@link Usage} on each chunk; treat it as the latest snapshot, not an increment.
296
+ */
297
+ usage?: Usage;
298
+ }
299
+
300
+ /**
301
+ * A dependency-free Server-Sent Events parser and the {@link ChatCompletionStream}
302
+ * wrapper that exposes a chat completion SSE response as an abortable async iterable.
303
+ *
304
+ * @packageDocumentation
305
+ */
306
+
307
+ /**
308
+ * Incrementally decode a byte stream into SSE `data:` payload strings, in
309
+ * arrival order, excluding the terminal `[DONE]` sentinel.
310
+ *
311
+ * Implements just the slice of the SSE grammar the gateway emits: UTF-8 `data:`
312
+ * lines separated by `\n`, events delimited by blank lines, terminated by a
313
+ * literal `data: [DONE]`. A partial line left in the buffer across reads is
314
+ * preserved and completed by the next chunk. Comment lines (`:` prefix) and
315
+ * non-`data:` fields are ignored. Yielding stops at `[DONE]`; reaching
316
+ * end-of-stream without `[DONE]` simply ends the generator.
317
+ *
318
+ * On any exit — normal completion, `[DONE]`, an error, or the consumer
319
+ * abandoning the `for await` early — the reader is cancelled before its lock is
320
+ * released, so the underlying fetch connection is torn down instead of leaving
321
+ * bytes streaming from the network.
322
+ *
323
+ * @param stream - The response body as a stream of UTF-8 encoded bytes.
324
+ * @param signal - Optional abort signal; aborting rejects the iteration.
325
+ * @returns An async generator yielding the raw string after each `data:` field.
326
+ * @throws {@link SkailarConnectionError} If the underlying read is aborted or fails.
327
+ */
328
+ declare function parseSSE(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): AsyncGenerator<string, void, unknown>;
329
+ /**
330
+ * An abortable async iterable of {@link ChatCompletionChunk} values, returned by
331
+ * `chat.completions.create({ stream: true })`.
332
+ *
333
+ * Iterate it with `for await`; each iteration yields one decoded chunk. Mirrors
334
+ * the ergonomics of `openai-node`'s stream, including the {@link ChatCompletionStream.controller}
335
+ * for cancellation.
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * const stream = await client.chat.completions.create({
340
+ * model: "gemini-2.5-flash-lite",
341
+ * messages: [{ role: "user", content: "hi" }],
342
+ * stream: true,
343
+ * });
344
+ * for await (const chunk of stream) {
345
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
346
+ * }
347
+ * ```
348
+ */
349
+ declare class ChatCompletionStream implements AsyncIterable<ChatCompletionChunk> {
350
+ /**
351
+ * The {@link AbortController} governing the underlying HTTP request. Call
352
+ * `stream.controller.abort()` to cancel an in-flight stream; the active
353
+ * `for await` loop then terminates promptly.
354
+ */
355
+ readonly controller: AbortController;
356
+ /** The raw SSE byte stream backing this iterator. */
357
+ private readonly body;
358
+ /**
359
+ * @param body - The response body stream of SSE bytes.
360
+ * @param controller - The abort controller tied to the originating request.
361
+ */
362
+ constructor(body: ReadableStream<Uint8Array>, controller: AbortController);
363
+ /**
364
+ * Decode the SSE byte stream into typed chunks.
365
+ *
366
+ * Each `data:` payload is `JSON.parse`d. If a payload carries an `error` field
367
+ * (the gateway's in-band failure signal), iteration throws the corresponding
368
+ * {@link SkailarAPIError} instead of yielding. Malformed JSON payloads are
369
+ * skipped defensively.
370
+ *
371
+ * @returns An async generator over {@link ChatCompletionChunk} values.
372
+ * @throws {@link SkailarAPIError} When the stream delivers an in-band error event.
373
+ * @throws {@link SkailarConnectionError} When the stream is aborted or read fails.
374
+ */
375
+ private decode;
376
+ /**
377
+ * Iterate the decoded chunks. Abandoning the iteration early (a `break` or
378
+ * `return` inside a `for await`) invokes the returned iterator's `return()`,
379
+ * which aborts {@link ChatCompletionStream.controller} so the underlying fetch
380
+ * request is cancelled — not merely the body reader — and then runs the
381
+ * generator's own cleanup ({@link parseSSE}'s `finally`: reader cancel +
382
+ * lock release). Normal completion and thrown errors are unaffected.
383
+ *
384
+ * @returns An async iterator over {@link ChatCompletionChunk} values.
385
+ */
386
+ [Symbol.asyncIterator](): AsyncIterator<ChatCompletionChunk>;
387
+ }
388
+
389
+ /**
390
+ * The chat resource, exposing `client.chat.completions.create(...)` with the
391
+ * same call shape as `openai`'s chat completions.
392
+ *
393
+ * @packageDocumentation
394
+ */
395
+
396
+ /** A chat completion request that explicitly opts into streaming. */
397
+ interface StreamingRequest extends ChatCompletionRequest {
398
+ stream: true;
399
+ }
400
+ /** A chat completion request that does not stream. */
401
+ interface NonStreamingRequest extends ChatCompletionRequest {
402
+ stream?: false;
403
+ }
404
+ /**
405
+ * The `completions` sub-namespace of the chat resource. Holds
406
+ * {@link ChatCompletions.create}, whose return type is narrowed by the `stream`
407
+ * field of the request via overloads.
408
+ */
409
+ declare class ChatCompletions {
410
+ /** The owning client used to dispatch requests. */
411
+ private readonly client;
412
+ /** @param client - The owning {@link Skailar} client. */
413
+ constructor(client: Skailar);
414
+ /**
415
+ * Create a buffered (non-streamed) chat completion.
416
+ *
417
+ * @param body - The request with `stream` omitted or `false`.
418
+ * @param options - Optional per-call signal, timeout and headers.
419
+ * @returns The fully-formed {@link ChatCompletion}.
420
+ */
421
+ create(body: NonStreamingRequest, options?: RequestOptions): Promise<ChatCompletion>;
422
+ /**
423
+ * Create a streamed chat completion.
424
+ *
425
+ * @param body - The request with `stream: true`.
426
+ * @param options - Optional per-call signal, timeout and headers. The stream
427
+ * is also cancellable via its `.controller`.
428
+ * @returns A {@link ChatCompletionStream} async-iterable of chunks, exposing
429
+ * `.controller` for cancellation.
430
+ */
431
+ create(body: StreamingRequest, options?: RequestOptions): Promise<ChatCompletionStream>;
432
+ /**
433
+ * Create a chat completion whose mode is chosen at runtime. Use this form when
434
+ * `stream` is a non-literal `boolean` (e.g. `stream: shouldStream`), where the
435
+ * concrete return type cannot be known at compile time; narrow the result with
436
+ * `instanceof ChatCompletionStream` or by checking the `stream` flag yourself.
437
+ *
438
+ * @param body - The request with a dynamic `stream` boolean.
439
+ * @param options - Optional per-call signal, timeout and headers.
440
+ * @returns Either a {@link ChatCompletion} or a {@link ChatCompletionStream}.
441
+ */
442
+ create(body: ChatCompletionRequest & {
443
+ stream?: boolean;
444
+ }, options?: RequestOptions): Promise<ChatCompletion | ChatCompletionStream>;
445
+ }
446
+ /** The chat resource root, mirroring `openai`'s `client.chat`. */
447
+ declare class ChatResource {
448
+ /** The chat completions namespace. */
449
+ readonly completions: ChatCompletions;
450
+ /** @param client - The owning {@link Skailar} client. */
451
+ constructor(client: Skailar);
452
+ }
453
+
454
+ /**
455
+ * Types for the models resource (`GET /v1/models` and `GET /v1/models/{id}`).
456
+ *
457
+ * @packageDocumentation
458
+ */
459
+
460
+ /**
461
+ * The provider that owns/serves a model. Kept as a {@link LiteralUnion} rather
462
+ * than a closed enum so the gateway may onboard new providers without an SDK release.
463
+ */
464
+ type ModelOwner = LiteralUnion<"skailar" | "anthropic" | "openai" | "google" | "deepseek" | "xai">;
465
+ /**
466
+ * Lifecycle status of a model. The live gateway returns values such as
467
+ * `"available"` and `"beta"`; modelled as a {@link LiteralUnion} so any
468
+ * server-side value parses without breaking the client.
469
+ */
470
+ type ModelStatus = LiteralUnion<"available" | "beta" | "active" | "preview" | "deprecated">;
471
+ /** Capability flags describing what a model can do. */
472
+ interface ModelCapabilities {
473
+ /** Whether the model supports incremental SSE streaming. */
474
+ streaming: boolean;
475
+ /** Whether the model can emit function/tool calls. */
476
+ tool_calls: boolean;
477
+ /** Whether the model accepts image input (vision). */
478
+ vision: boolean;
479
+ /** Whether the model honors structured JSON output modes. */
480
+ json_mode: boolean;
481
+ /** Whether the model exposes a reasoning/thinking mode; `null` if unclassified. */
482
+ reasoning?: boolean | null;
483
+ }
484
+ /** Per-token pricing for a model. */
485
+ interface ModelPricing {
486
+ /** Cost per one million input tokens, in {@link ModelPricing.currency}. */
487
+ input_per_mtok: number;
488
+ /** Cost per one million output tokens, in {@link ModelPricing.currency}. */
489
+ output_per_mtok: number;
490
+ /** ISO 4217 currency code (e.g. `"USD"`). */
491
+ currency: string;
492
+ }
493
+ /** Summary card for a model as returned by `GET /v1/models`. */
494
+ interface ModelSummary {
495
+ id: string;
496
+ object: "model";
497
+ /** Creation/registration time as Unix epoch seconds. */
498
+ created: number;
499
+ owned_by: ModelOwner;
500
+ /** Human-friendly display name. */
501
+ display_name: string;
502
+ /** Maximum context window size in tokens. */
503
+ context_window: number;
504
+ /** Maximum tokens the model may generate in one response. */
505
+ max_output_tokens: number;
506
+ capabilities: ModelCapabilities;
507
+ pricing: ModelPricing;
508
+ status: ModelStatus;
509
+ }
510
+ /**
511
+ * Full detail card for a model as returned by `GET /v1/models/{id}`. Extends
512
+ * {@link ModelSummary} with descriptive and routing metadata; all extended
513
+ * fields are optional because availability varies by provider.
514
+ */
515
+ interface Model extends ModelSummary {
516
+ /** Long-form description of the model. */
517
+ description?: string;
518
+ modalities?: {
519
+ /** Accepted input modalities (e.g. `["text", "image"]`). */
520
+ input?: string[];
521
+ /** Produced output modalities (e.g. `["text"]`). */
522
+ output?: string[];
523
+ };
524
+ /** Names of request parameters the model honors. */
525
+ supported_parameters?: string[];
526
+ /** Training knowledge cutoff, as a date-like string. */
527
+ knowledge_cutoff?: string;
528
+ /** Public release date, as a date-like string. */
529
+ released_at?: string;
530
+ /** URL of upstream provider documentation. */
531
+ documentation_url?: string;
532
+ /** Alternate identifiers that resolve to this model. */
533
+ aliases?: string[];
534
+ }
535
+ /** Envelope returned by `GET /v1/models`. */
536
+ interface ModelList {
537
+ object: "list";
538
+ data: ModelSummary[];
539
+ }
540
+
541
+ /**
542
+ * The models resource, exposing `client.models.list()` and
543
+ * `client.models.retrieve(id)`.
544
+ *
545
+ * @packageDocumentation
546
+ */
547
+
548
+ /** Model discovery operations. */
549
+ declare class ModelsResource {
550
+ /** The owning client used to dispatch requests. */
551
+ private readonly client;
552
+ /** @param client - The owning {@link Skailar} client. */
553
+ constructor(client: Skailar);
554
+ /**
555
+ * List every model the gateway can route to. Unwraps the
556
+ * `{ object: "list", data }` envelope and returns just `data` as a plain array.
557
+ *
558
+ * @param options - Optional per-call signal, timeout and headers.
559
+ * @returns A promise resolving to the array of {@link ModelSummary} cards.
560
+ */
561
+ list(options?: RequestOptions): Promise<ModelSummary[]>;
562
+ /**
563
+ * Retrieve the full detail card for a single model.
564
+ *
565
+ * @param id - The model identifier; may contain slashes (e.g.
566
+ * `"google/gemini-2.5-pro"`), which are preserved in the path.
567
+ * @param options - Optional per-call signal, timeout and headers.
568
+ * @returns A promise resolving to the {@link Model} detail.
569
+ * @throws {@link SkailarNotFoundError} If no model matches the id.
570
+ */
571
+ retrieve(id: string, options?: RequestOptions): Promise<Model>;
572
+ }
573
+
574
+ /**
575
+ * Types for the image generation resource (`POST /v1/images/generations`).
576
+ *
577
+ * @packageDocumentation
578
+ */
579
+
580
+ /** Request body for `POST /v1/images/generations`. */
581
+ interface ImageGenerationRequest {
582
+ /** Image model identifier (e.g. `"gpt-image-1"`). */
583
+ model: ModelId;
584
+ /** Natural-language description of the desired image. */
585
+ prompt: string;
586
+ /** Number of images to generate, in `[1, 10]` (default `1`). */
587
+ n?: number;
588
+ /** Output resolution, e.g. `"1024x1024"`; accepted values depend on the provider. */
589
+ size?: string;
590
+ /** Provider-specific quality hint (e.g. `"standard"`, `"hd"`). */
591
+ quality?: string;
592
+ /** Provider-specific background hint (e.g. `"transparent"`). */
593
+ background?: string;
594
+ }
595
+ /**
596
+ * A single generated image. Exactly one of {@link GeneratedImage.url} or
597
+ * {@link GeneratedImage.b64_json} is populated, depending on the provider's
598
+ * delivery mode.
599
+ */
600
+ interface GeneratedImage {
601
+ /** HTTPS URL of the generated image, when delivered by reference. */
602
+ url?: string;
603
+ /** Base64-encoded image bytes, when delivered inline. */
604
+ b64_json?: string;
605
+ /** The prompt after any provider-side rewriting, if applicable. */
606
+ revised_prompt?: string;
607
+ }
608
+ /** Response body for `POST /v1/images/generations`. */
609
+ interface ImageGenerationResponse {
610
+ /** Creation time as Unix epoch seconds. */
611
+ created: number;
612
+ data: GeneratedImage[];
613
+ }
614
+
615
+ /**
616
+ * The images resource, exposing `client.images.generate(...)`.
617
+ *
618
+ * @packageDocumentation
619
+ */
620
+
621
+ /** Image generation operations. */
622
+ declare class ImagesResource {
623
+ /** The owning client used to dispatch requests. */
624
+ private readonly client;
625
+ /** @param client - The owning {@link Skailar} client. */
626
+ constructor(client: Skailar);
627
+ /**
628
+ * Generate one or more images from a text prompt. Named `generate` to match
629
+ * `openai`'s `images.generate(...)`.
630
+ *
631
+ * @param body - The generation request; see {@link ImageGenerationRequest}.
632
+ * @param options - Optional per-call signal, timeout and headers.
633
+ * @returns A promise resolving to the {@link ImageGenerationResponse}, whose
634
+ * `data` entries carry either a `url` or inline `b64_json`.
635
+ * @throws {@link SkailarBadRequestError} On HTTP 400.
636
+ * @throws {@link SkailarRateLimitError} On HTTP 429 (after exhausting retries).
637
+ */
638
+ generate(body: ImageGenerationRequest, options?: RequestOptions): Promise<ImageGenerationResponse>;
639
+ }
640
+
641
+ /**
642
+ * Types for the audio resource: transcription (`POST /v1/audio/transcriptions`)
643
+ * and speech synthesis (`POST /v1/audio/speech`).
644
+ *
645
+ * @packageDocumentation
646
+ */
647
+ /**
648
+ * Binary payload accepted by SDK methods that upload bytes. The SDK normalizes
649
+ * any of these into the base64 string the gateway expects, so callers may pass
650
+ * whichever representation they already hold.
651
+ *
652
+ * A `string` is treated as **already-encoded** base64 (no `data:` prefix) and is
653
+ * forwarded without validation — pass a `Uint8Array`/`ArrayBuffer`/`Blob` for
654
+ * raw bytes, since raw text passed as a string decodes to corrupt data server-side.
655
+ */
656
+ type BinaryInput = Uint8Array | ArrayBuffer | Blob | string;
657
+ /** Audio MIME types accepted by the transcription endpoint. */
658
+ type TranscriptionMime = "audio/wav" | "audio/webm" | "audio/mp4" | "audio/m4a" | "audio/mpeg" | "audio/mp3";
659
+ /**
660
+ * Parameters for {@link AudioTranscriptions.create}. Callers pass the raw audio
661
+ * as `file`; the SDK base64-encodes it into the wire field.
662
+ */
663
+ interface TranscriptionCreateParams {
664
+ /** The audio to transcribe, in any {@link BinaryInput} form. */
665
+ file: BinaryInput;
666
+ /**
667
+ * MIME type of the supplied audio (default `"audio/wav"`). If `file` is a
668
+ * {@link Blob} with a `type`, that type is used when this is omitted.
669
+ */
670
+ mime?: TranscriptionMime;
671
+ }
672
+ /** Wire request body for `POST /v1/audio/transcriptions`. */
673
+ interface TranscriptionRequest {
674
+ /** Base64-encoded audio bytes with no `data:` prefix. */
675
+ base64: string;
676
+ mime?: TranscriptionMime;
677
+ }
678
+ /** Response body for `POST /v1/audio/transcriptions`. */
679
+ interface TranscriptionResponse {
680
+ /** The transcribed text. */
681
+ text: string;
682
+ }
683
+ /** Voices available for speech synthesis. */
684
+ type SpeechVoice = "alloy" | "ash" | "ballad" | "coral" | "echo" | "fable" | "nova" | "onyx" | "sage" | "shimmer";
685
+ /** Parameters for {@link AudioSpeech.create}. */
686
+ interface SpeechCreateParams {
687
+ /** Text to synthesize; limited to 4000 characters by the gateway. */
688
+ input: string;
689
+ /** Voice to speak with (default `"nova"`). */
690
+ voice?: SpeechVoice;
691
+ }
692
+ /** Wire request body for `POST /v1/audio/speech`. */
693
+ interface SpeechRequest {
694
+ /** Text to synthesize (max 4000 characters). */
695
+ input: string;
696
+ voice?: SpeechVoice;
697
+ }
698
+
699
+ /**
700
+ * The audio resource, exposing `client.audio.transcriptions.create(...)` and
701
+ * `client.audio.speech.create(...)`.
702
+ *
703
+ * @packageDocumentation
704
+ */
705
+
706
+ /** Audio transcription operations (speech-to-text, Whisper-backed). */
707
+ declare class AudioTranscriptions {
708
+ /** The owning client used to dispatch requests. */
709
+ private readonly client;
710
+ /** @param client - The owning {@link Skailar} client. */
711
+ constructor(client: Skailar);
712
+ /**
713
+ * Transcribe an audio clip to text. The supplied bytes are base64-encoded
714
+ * client-side into the gateway's `base64` field. When `mime` is omitted and
715
+ * `file` is a {@link Blob} carrying a `type`, that type is used; otherwise the
716
+ * gateway default (`audio/wav`) applies.
717
+ *
718
+ * @param params - The audio and its MIME type; see {@link TranscriptionCreateParams}.
719
+ * `file` may be a {@link Uint8Array}, {@link ArrayBuffer}, {@link Blob} or a
720
+ * pre-encoded base64 string.
721
+ * @param options - Optional per-call signal, timeout and headers.
722
+ * @returns A promise resolving to the {@link TranscriptionResponse}.
723
+ */
724
+ create(params: TranscriptionCreateParams, options?: RequestOptions): Promise<TranscriptionResponse>;
725
+ }
726
+ /** Speech synthesis operations (text-to-speech). */
727
+ declare class AudioSpeech {
728
+ /** The owning client used to dispatch requests. */
729
+ private readonly client;
730
+ /** @param client - The owning {@link Skailar} client. */
731
+ constructor(client: Skailar);
732
+ /**
733
+ * Synthesize speech and return the raw MP3 audio stream. Unlike the JSON
734
+ * endpoints, this returns the response body stream directly so large audio
735
+ * payloads need not be buffered in memory.
736
+ *
737
+ * Pass `options.signal` to cancel the request: aborting it before the response
738
+ * arrives rejects this call, and aborting it while the MP3 is still downloading
739
+ * tears down the underlying connection so the body stops mid-stream.
740
+ *
741
+ * @param params - The text and voice; see {@link SpeechCreateParams}.
742
+ * @param options - Optional per-call signal, timeout and headers.
743
+ * @returns A promise resolving to a `ReadableStream<Uint8Array>` of
744
+ * `audio/mpeg` bytes, suitable for piping to a file, an HTTP response, or an
745
+ * audio element.
746
+ * @throws {@link SkailarConnectionError} If the response unexpectedly lacks a body.
747
+ * @throws {@link SkailarBadRequestError} On HTTP 400 (e.g. text exceeding 4000 chars).
748
+ */
749
+ create(params: SpeechCreateParams, options?: RequestOptions): Promise<ReadableStream<Uint8Array>>;
750
+ }
751
+ /** The audio resource root, grouping transcription and speech. */
752
+ declare class AudioResource {
753
+ /** Speech-to-text operations. */
754
+ readonly transcriptions: AudioTranscriptions;
755
+ /** Text-to-speech operations. */
756
+ readonly speech: AudioSpeech;
757
+ /** @param client - The owning {@link Skailar} client. */
758
+ constructor(client: Skailar);
759
+ }
760
+
761
+ /**
762
+ * Types for the uploads resource: image uploads (`POST /v1/uploads/images`) and
763
+ * file uploads (`POST /v1/uploads/files`).
764
+ *
765
+ * @packageDocumentation
766
+ */
767
+
768
+ /** Content types accepted by `POST /v1/uploads/images`. */
769
+ type ImageContentType = "image/png" | "image/jpeg" | "image/gif" | "image/webp";
770
+ /** Content types accepted by `POST /v1/uploads/files`. */
771
+ type FileContentType = "application/pdf" | "text/plain";
772
+ /**
773
+ * Parameters for `client.uploads.images.create`. Callers pass raw bytes as
774
+ * `data`; the SDK base64-encodes them into the wire `base64` field.
775
+ */
776
+ interface ImageUploadCreateParams {
777
+ /** The image bytes, in any {@link BinaryInput} form. */
778
+ data: BinaryInput;
779
+ /** MIME type of the image being uploaded. */
780
+ contentType: ImageContentType;
781
+ }
782
+ /** Parameters for `client.uploads.files.create`. */
783
+ interface FileUploadCreateParams {
784
+ /** The document bytes, in any {@link BinaryInput} form. */
785
+ data: BinaryInput;
786
+ /** MIME type of the document being uploaded. */
787
+ contentType: FileContentType;
788
+ }
789
+ /** Wire request body shared by both upload endpoints. */
790
+ interface UploadRequest {
791
+ /** Base64-encoded payload with no `data:` prefix. */
792
+ base64: string;
793
+ /** MIME type of the encoded payload. */
794
+ content_type: string;
795
+ }
796
+ /** Response body for the upload endpoints. */
797
+ interface UploadResponse {
798
+ /**
799
+ * URL of the stored asset, ready to embed in subsequent calls — for example
800
+ * as the `url` of a vision {@link ImageContentPart}.
801
+ */
802
+ url: string;
803
+ /** MIME type the asset was stored as. */
804
+ content_type: string;
805
+ }
806
+
807
+ /**
808
+ * The uploads resource, exposing `client.uploads.images.create(...)` and
809
+ * `client.uploads.files.create(...)` for storing assets in Skailar storage and
810
+ * receiving an embeddable URL.
811
+ *
812
+ * @packageDocumentation
813
+ */
814
+
815
+ /** Image upload operations (`POST /v1/uploads/images`). */
816
+ declare class ImageUploads {
817
+ /** The owning client used to dispatch requests. */
818
+ private readonly client;
819
+ /** @param client - The owning {@link Skailar} client. */
820
+ constructor(client: Skailar);
821
+ /**
822
+ * Upload an image and obtain a URL usable as vision input. `data` may be a
823
+ * {@link Uint8Array}, {@link ArrayBuffer}, {@link Blob} or a pre-encoded base64
824
+ * string; it is base64-encoded client-side into the gateway's `base64` field.
825
+ *
826
+ * @param params - The image bytes and content type; see {@link ImageUploadCreateParams}.
827
+ * @returns A promise resolving to the {@link UploadResponse} whose `url` can be
828
+ * embedded in a chat completion as an `image_url` content part.
829
+ */
830
+ create(params: ImageUploadCreateParams): Promise<UploadResponse>;
831
+ }
832
+ /** File upload operations (`POST /v1/uploads/files`). */
833
+ declare class FileUploads {
834
+ /** The owning client used to dispatch requests. */
835
+ private readonly client;
836
+ /** @param client - The owning {@link Skailar} client. */
837
+ constructor(client: Skailar);
838
+ /**
839
+ * Upload a document (`application/pdf` or `text/plain`). `data` accepts the
840
+ * same forms as image upload and is base64-encoded client-side.
841
+ *
842
+ * @param params - The document bytes and content type; see {@link FileUploadCreateParams}.
843
+ * @returns A promise resolving to the {@link UploadResponse} with the stored asset URL.
844
+ */
845
+ create(params: FileUploadCreateParams): Promise<UploadResponse>;
846
+ }
847
+ /** The uploads resource root, grouping image and file uploads. */
848
+ declare class UploadsResource {
849
+ /** Image upload operations. */
850
+ readonly images: ImageUploads;
851
+ /** File/document upload operations. */
852
+ readonly files: FileUploads;
853
+ /** @param client - The owning {@link Skailar} client. */
854
+ constructor(client: Skailar);
855
+ }
856
+
857
+ /**
858
+ * Barrel re-exporting every public type of the Skailar SDK.
859
+ *
860
+ * @packageDocumentation
861
+ */
862
+
863
+ /** Response body for `GET /v1/ping-key`. */
864
+ interface PingKeyResponse {
865
+ /** Always `"ok"` when the key is valid. */
866
+ status: "ok";
867
+ /** UUID of the account that owns the validated key. */
868
+ user_id: string;
869
+ }
870
+
871
+ /**
872
+ * The {@link Skailar} client: configuration, the shared fetch dispatch pipeline
873
+ * (timeout, retry with backoff, error mapping) and the resource namespaces hung
874
+ * off it.
875
+ *
876
+ * @packageDocumentation
877
+ */
878
+
879
+ /**
880
+ * Configuration accepted by the {@link Skailar} constructor. Every field is
881
+ * optional; omitted fields fall back to environment variables or library
882
+ * defaults as documented per property.
883
+ */
884
+ interface SkailarOptions {
885
+ /**
886
+ * Skailar API key of the form `skl_live_<43 url-safe base64 chars>`. Defaults
887
+ * to `process.env.SKAILAR_API_KEY`; if neither is provided the constructor throws.
888
+ *
889
+ * @remarks
890
+ * The format is **not** validated locally — only emptiness is checked. A
891
+ * malformed or wrong-provider key (e.g. an OpenAI `sk-...` key passed by
892
+ * mistake) is accepted here and rejected at the first request with a
893
+ * {@link SkailarAuthError} (HTTP 401).
894
+ */
895
+ apiKey?: string;
896
+ /**
897
+ * Base URL of the gateway, without a trailing `/v1` (default
898
+ * `"https://api.skailar.com"`). The `/v1/...` path is appended by the SDK.
899
+ * Point this at `http://localhost:8080` for a local gateway.
900
+ */
901
+ baseURL?: string;
902
+ /**
903
+ * Per-request timeout in milliseconds (default `60000`). Applies to each
904
+ * attempt independently; a timed-out attempt becomes a
905
+ * {@link SkailarConnectionError} and is eligible for retry.
906
+ */
907
+ timeout?: number;
908
+ /**
909
+ * Maximum automatic retries for transient failures (default `2`). Retries
910
+ * apply only to HTTP 429, HTTP 5xx, and connection errors; non-429 4xx
911
+ * responses are never retried.
912
+ */
913
+ maxRetries?: number;
914
+ /**
915
+ * Custom `fetch` implementation, primarily for testing (default global
916
+ * `fetch`). No binding is applied; pass an already-bound function if your
917
+ * implementation requires a specific receiver.
918
+ */
919
+ fetch?: typeof fetch;
920
+ /**
921
+ * Headers merged into every request. The SDK's own `Authorization`,
922
+ * `Content-Type` and `Accept`, plus explicit per-call headers, take precedence.
923
+ */
924
+ defaultHeaders?: Record<string, string>;
925
+ }
926
+ /**
927
+ * Per-call request options accepted as the trailing argument of every resource
928
+ * method (e.g. `chat.completions.create(body, options)`). Mirrors the
929
+ * `openai-node` convention so the wire body stays separate from transport
930
+ * concerns. Every field is optional and overrides the client-level default for
931
+ * this one call.
932
+ */
933
+ interface RequestOptions {
934
+ /**
935
+ * Signal to cancel this call. Aborting before the response arrives rejects the
936
+ * call with a {@link SkailarConnectionError}; for streaming/audio bodies,
937
+ * aborting mid-transfer tears down the connection.
938
+ */
939
+ signal?: AbortSignal;
940
+ /**
941
+ * Per-call timeout in milliseconds, overriding {@link SkailarOptions.timeout}
942
+ * for this request only.
943
+ */
944
+ timeout?: number;
945
+ /** Extra headers merged into this request, overriding client defaults. */
946
+ headers?: Record<string, string>;
947
+ }
948
+ /** Internal description of a single HTTP request to dispatch. */
949
+ interface InternalRequest {
950
+ method: "GET" | "POST";
951
+ /** Path beginning with `/v1/...`, relative to {@link SkailarOptions.baseURL}. */
952
+ path: string;
953
+ /** Optional JSON body; serialized with `JSON.stringify`. */
954
+ body?: unknown;
955
+ /** Extra headers for this request only. */
956
+ headers?: Record<string, string>;
957
+ /** Expected response handling: parsed JSON, raw `Response`, or SSE stream. */
958
+ expect: "json" | "response" | "stream";
959
+ /**
960
+ * External abort signal composed with the timeout. Used for streaming, where
961
+ * the caller-visible {@link ChatCompletionStream.controller} drives cancellation.
962
+ */
963
+ signal?: AbortSignal;
964
+ /** Per-call timeout override in ms; falls back to {@link Skailar.timeout}. */
965
+ timeout?: number;
966
+ }
967
+ /**
968
+ * The official Skailar API client. Construct once and reuse. Resource namespaces
969
+ * ({@link Skailar.chat}, {@link Skailar.models}, etc.) provide the
970
+ * OpenAI-compatible and Skailar-native operations. All network access flows
971
+ * through {@link Skailar.request}, which centralizes authentication, timeouts,
972
+ * retries and error mapping.
973
+ *
974
+ * @example
975
+ * ```ts
976
+ * import Skailar from "@skailar-ai/sdk";
977
+ * const client = new Skailar({ apiKey: "skl_live_..." });
978
+ * const res = await client.chat.completions.create({
979
+ * model: "claude-sonnet-4-6",
980
+ * messages: [{ role: "user", content: "Hello!" }],
981
+ * });
982
+ * console.log(res.choices[0]?.message.content);
983
+ * ```
984
+ */
985
+ declare class Skailar {
986
+ /** Resolved API key sent as the bearer token. */
987
+ readonly apiKey: string;
988
+ /** Resolved base URL with any trailing slash removed. */
989
+ readonly baseURL: string;
990
+ /** Resolved per-attempt timeout in milliseconds. */
991
+ readonly timeout: number;
992
+ /** Resolved maximum retry count. */
993
+ readonly maxRetries: number;
994
+ /** Default headers merged into every request. */
995
+ readonly defaultHeaders: Record<string, string>;
996
+ /** The `fetch` implementation used for all requests. */
997
+ private readonly fetchImpl;
998
+ /** Chat completions (OpenAI-compatible). */
999
+ readonly chat: ChatResource;
1000
+ /** Model discovery. */
1001
+ readonly models: ModelsResource;
1002
+ /** Image generation. */
1003
+ readonly images: ImagesResource;
1004
+ /** Speech synthesis and transcription. */
1005
+ readonly audio: AudioResource;
1006
+ /** Direct uploads to Skailar storage. */
1007
+ readonly uploads: UploadsResource;
1008
+ /**
1009
+ * @param options - Client configuration; see {@link SkailarOptions}.
1010
+ * @throws If no API key is resolvable (neither `options.apiKey` nor
1011
+ * `SKAILAR_API_KEY`). A key that is present but malformed is **not** rejected
1012
+ * here; it fails at the first request with a {@link SkailarAuthError}.
1013
+ */
1014
+ constructor(options?: SkailarOptions);
1015
+ /**
1016
+ * Verify the configured API key against `GET /v1/ping-key`.
1017
+ *
1018
+ * @param options - Optional per-call signal, timeout and headers.
1019
+ * @returns The `{ status, user_id }` payload when the key is valid.
1020
+ * @throws {@link SkailarAuthError} If the key is missing, invalid or revoked.
1021
+ */
1022
+ ping(options?: RequestOptions): Promise<PingKeyResponse>;
1023
+ /**
1024
+ * Dispatch a request expecting a JSON body, with retries.
1025
+ *
1026
+ * @typeParam T - The expected shape of the parsed JSON response.
1027
+ * @param options - The request description.
1028
+ * @returns The parsed JSON response body typed as `T`.
1029
+ */
1030
+ request<T>(options: InternalRequest & {
1031
+ expect: "json";
1032
+ }): Promise<T>;
1033
+ /**
1034
+ * Dispatch a request expecting the raw {@link Response}, with retries.
1035
+ *
1036
+ * @param options - The request description.
1037
+ * @returns The successful `Response`, body unread (e.g. for audio streams).
1038
+ */
1039
+ request(options: InternalRequest & {
1040
+ expect: "response";
1041
+ }): Promise<Response>;
1042
+ /**
1043
+ * Dispatch a streaming request, returning a chat completion stream.
1044
+ *
1045
+ * @param options - The request description with `expect: "stream"`.
1046
+ * @returns A {@link ChatCompletionStream} over the SSE response.
1047
+ */
1048
+ request(options: InternalRequest & {
1049
+ expect: "stream";
1050
+ }): Promise<ChatCompletionStream>;
1051
+ /**
1052
+ * Assemble the outgoing header set for a request, applying defaults, auth,
1053
+ * content-type and accept in precedence order.
1054
+ *
1055
+ * @param options - The request description.
1056
+ * @returns The header record to send.
1057
+ */
1058
+ private buildHeaders;
1059
+ /**
1060
+ * Convert a non-2xx {@link Response} into the most specific
1061
+ * {@link SkailarAPIError} subclass. Reads the body once, attempting JSON first
1062
+ * and falling back to raw text, then defers classification to
1063
+ * {@link SkailarAPIError.from}.
1064
+ *
1065
+ * @param response - The failed HTTP response.
1066
+ * @returns The mapped error.
1067
+ */
1068
+ private toApiError;
1069
+ /**
1070
+ * Whether a status code is eligible for automatic retry (429 and any 5xx).
1071
+ *
1072
+ * @param status - The HTTP status code.
1073
+ * @returns `true` if retryable.
1074
+ */
1075
+ private isRetryableStatus;
1076
+ /**
1077
+ * Whether another attempt remains within the retry budget.
1078
+ *
1079
+ * @param attempt - The count of attempts already made (before increment).
1080
+ * @returns `true` if a retry is permitted.
1081
+ */
1082
+ private shouldRetry;
1083
+ /**
1084
+ * Compute a full-jitter exponential backoff delay: a random value in
1085
+ * `[0, min(cap, base * 2^attempt))`, capped at 8000ms. Jitter spreads retries
1086
+ * from many clients to avoid synchronized thundering-herd load on the gateway.
1087
+ *
1088
+ * @param attempt - The retry number, starting at 1 for the first retry.
1089
+ * @returns A randomized delay in milliseconds.
1090
+ */
1091
+ private backoff;
1092
+ }
1093
+
1094
+ /**
1095
+ * The typed error hierarchy thrown by the Skailar SDK.
1096
+ *
1097
+ * Every failure surfaces as a subclass of {@link SkailarError}, so a single
1098
+ * `catch (err) { if (err instanceof SkailarError) ... }` covers the whole SDK.
1099
+ * Transport/network failures become {@link SkailarConnectionError}; any non-2xx
1100
+ * HTTP response becomes the most specific {@link SkailarAPIError} subclass for
1101
+ * its status code.
1102
+ *
1103
+ * @packageDocumentation
1104
+ */
1105
+ /**
1106
+ * Normalized shape extracted from a Skailar error response body.
1107
+ *
1108
+ * The gateway has been observed to return a flat body
1109
+ * (`{ "error": "invalid_api_key", "message": "..." }`) and, inside streams, a
1110
+ * nested body (`{ "error": { "type": "...", "message": "..." } }`).
1111
+ * {@link parseErrorBody} collapses both into this structure.
1112
+ */
1113
+ interface ParsedErrorBody {
1114
+ /** Machine-readable error code, e.g. `"invalid_api_key"`. */
1115
+ code: string | undefined;
1116
+ /** Human-readable error message. */
1117
+ message: string | undefined;
1118
+ }
1119
+ /** Fields shared by the constructors of every concrete SDK error. */
1120
+ interface SkailarErrorOptions {
1121
+ /** Human-readable message; falls back to a per-class default. */
1122
+ message?: string | undefined;
1123
+ /** Machine-readable error code from the response body, if any. */
1124
+ code?: string | undefined;
1125
+ /** Value of the response `x-request-id` header, if present. */
1126
+ requestId?: string | undefined;
1127
+ /** The raw response body (parsed JSON or raw text) for diagnostics. */
1128
+ raw?: unknown;
1129
+ /** Underlying cause, e.g. the original network error. */
1130
+ cause?: unknown;
1131
+ }
1132
+ /**
1133
+ * Abstract base class for all errors thrown by the Skailar SDK.
1134
+ *
1135
+ * Not thrown directly; serves as the common `instanceof` target. The `abstract`
1136
+ * marker forbids `new SkailarError()` while still allowing subclasses to call `super`.
1137
+ */
1138
+ declare abstract class SkailarError extends Error {
1139
+ /** HTTP status code, or `null` for non-HTTP failures (e.g. network). */
1140
+ readonly status: number | null;
1141
+ /** Machine-readable error code from the body, if any. */
1142
+ readonly code: string | undefined;
1143
+ /** Correlation id from the `x-request-id` response header, if any. */
1144
+ readonly requestId: string | undefined;
1145
+ /** The raw response body captured for debugging. */
1146
+ readonly raw: unknown;
1147
+ /**
1148
+ * @param status - HTTP status, or `null` when not applicable.
1149
+ * @param options - Message, code, request id, raw body and cause.
1150
+ */
1151
+ protected constructor(status: number | null, options?: SkailarErrorOptions);
1152
+ }
1153
+ /**
1154
+ * Raised when the request never produced an HTTP response: DNS failures,
1155
+ * connection resets, TLS errors, and client-side timeouts/aborts driven by the
1156
+ * configured `timeout`. Its {@link SkailarError.status} is always `null`.
1157
+ */
1158
+ declare class SkailarConnectionError extends SkailarError {
1159
+ /** @param options - Message and originating cause. */
1160
+ constructor(options?: {
1161
+ message?: string;
1162
+ cause?: unknown;
1163
+ });
1164
+ }
1165
+ /**
1166
+ * Base class for any non-2xx HTTP response from the gateway.
1167
+ * {@link SkailarAPIError.from} is the factory that inspects the status code and
1168
+ * returns the most specific subclass.
1169
+ */
1170
+ declare class SkailarAPIError extends SkailarError {
1171
+ /**
1172
+ * @param status - The HTTP status code of the response.
1173
+ * @param options - Message, code, request id and raw body.
1174
+ */
1175
+ constructor(status: number, options?: SkailarErrorOptions);
1176
+ /**
1177
+ * Build the most specific {@link SkailarAPIError} subclass for a status code.
1178
+ *
1179
+ * @param status - The HTTP status code returned by the gateway.
1180
+ * @param parsed - The normalized `{ code, message }` from {@link parseErrorBody}.
1181
+ * @param requestId - The `x-request-id` header value, if present.
1182
+ * @param raw - The raw response body for diagnostics.
1183
+ * @param retryAfter - Seconds from a `Retry-After` header, for 429 responses.
1184
+ * @returns A {@link SkailarAuthError}, {@link SkailarBadRequestError},
1185
+ * {@link SkailarNotFoundError}, {@link SkailarRateLimitError},
1186
+ * {@link SkailarUpstreamError}, or a plain {@link SkailarAPIError}.
1187
+ */
1188
+ static from(status: number, parsed: ParsedErrorBody, requestId: string | undefined, raw: unknown, retryAfter?: number | undefined): SkailarAPIError;
1189
+ }
1190
+ /** HTTP 401 — the API key is missing, malformed, or revoked. */
1191
+ declare class SkailarAuthError extends SkailarAPIError {
1192
+ /** @param options - Error details. */
1193
+ constructor(options?: SkailarErrorOptions);
1194
+ }
1195
+ /** HTTP 400 — the request was malformed or failed validation. */
1196
+ declare class SkailarBadRequestError extends SkailarAPIError {
1197
+ /** @param options - Error details. */
1198
+ constructor(options?: SkailarErrorOptions);
1199
+ }
1200
+ /** HTTP 404 — the requested resource (e.g. a model id) does not exist. */
1201
+ declare class SkailarNotFoundError extends SkailarAPIError {
1202
+ /** @param options - Error details. */
1203
+ constructor(options?: SkailarErrorOptions);
1204
+ }
1205
+ /**
1206
+ * HTTP 429 — the account exceeded its rate limit.
1207
+ *
1208
+ * When the gateway provides a `Retry-After` header, its value (in seconds) is
1209
+ * exposed as {@link SkailarRateLimitError.retryAfter} and honored by the
1210
+ * client's automatic retry logic.
1211
+ */
1212
+ declare class SkailarRateLimitError extends SkailarAPIError {
1213
+ /** Seconds to wait before retrying, parsed from `Retry-After`; `undefined` if absent/unparseable. */
1214
+ readonly retryAfter: number | undefined;
1215
+ /** @param options - Error details plus the optional `retryAfter` seconds. */
1216
+ constructor(options?: SkailarErrorOptions & {
1217
+ retryAfter?: number | undefined;
1218
+ });
1219
+ }
1220
+ /**
1221
+ * HTTP 5xx — the upstream model provider failed or timed out. The gateway
1222
+ * propagates provider 5xx failures (502/503/504) with a structured body. These
1223
+ * are transient and are retried automatically.
1224
+ */
1225
+ declare class SkailarUpstreamError extends SkailarAPIError {
1226
+ /**
1227
+ * @param status - The specific 5xx status code.
1228
+ * @param options - Error details.
1229
+ */
1230
+ constructor(status: number, options?: SkailarErrorOptions);
1231
+ }
1232
+
1233
+ /**
1234
+ * Public entry point of the Skailar TypeScript SDK.
1235
+ *
1236
+ * Exports {@link Skailar} as both the default and a named export, the full typed
1237
+ * error hierarchy, the {@link ChatCompletionStream} helper, and every public
1238
+ * request/response type.
1239
+ *
1240
+ * @example Default import
1241
+ * ```ts
1242
+ * import Skailar from "@skailar-ai/sdk";
1243
+ * const client = new Skailar({ apiKey: "skl_live_..." });
1244
+ * ```
1245
+ *
1246
+ * @example Named imports
1247
+ * ```ts
1248
+ * import { Skailar, SkailarError, SkailarRateLimitError } from "@skailar-ai/sdk";
1249
+ * ```
1250
+ *
1251
+ * @packageDocumentation
1252
+ */
1253
+
1254
+ export { type BinaryInput, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionChunk, type ChatCompletionChunkChoice, type ChatCompletionChunkToolCall, type ChatCompletionRequest, ChatCompletionStream, type ChatMessage, type ChatRole, type ContentPart, type FileContentType, type FileUploadCreateParams, type FinishReason, type GeneratedImage, type ImageContentPart, type ImageContentType, type ImageGenerationRequest, type ImageGenerationResponse, type ImageUploadCreateParams, type KnownModelId, type LiteralUnion, type MessageContent, type Model, type ModelCapabilities, type ModelId, type ModelList, type ModelOwner, type ModelPricing, type ModelStatus, type ModelSummary, type ParsedErrorBody, type PingKeyResponse, type ReasoningEffort, type RequestOptions, type ResponseFormat, Skailar, SkailarAPIError, SkailarAuthError, SkailarBadRequestError, SkailarConnectionError, SkailarError, SkailarNotFoundError, type SkailarOptions, SkailarRateLimitError, SkailarUpstreamError, type SpeechCreateParams, type SpeechRequest, type SpeechVoice, type TextContentPart, type Tool, type ToolCall, type ToolChoice, type TranscriptionCreateParams, type TranscriptionMime, type TranscriptionRequest, type TranscriptionResponse, type UploadRequest, type UploadResponse, type Usage, Skailar as default, parseSSE };