@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
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The value returned by every API method. Await it for the parsed body, or call
3
+ * `.withRawResponse()` to also get the HTTP response and request ID.
4
+ */
5
+ export class APIPromise {
6
+ responsePromise;
7
+ parseResponse;
8
+ parsed;
9
+ constructor(responsePromise, parseResponse) {
10
+ this.responsePromise = responsePromise;
11
+ this.parseResponse = parseResponse;
12
+ }
13
+ /** Returns a new promise that transforms the parsed body. */
14
+ _thenUnwrap(transform) {
15
+ return new APIPromise(this.responsePromise, async (props) => transform(await this.parseResponse(props), props));
16
+ }
17
+ withRawResponse() {
18
+ this.parsed ??= this.responsePromise.then(async (props) => ({
19
+ data: await this.parseResponse(props),
20
+ response: props.response,
21
+ requestId: props.response.headers.get('x-request-id'),
22
+ }));
23
+ return this.parsed;
24
+ }
25
+ /** The raw HTTP response, without parsing the body. */
26
+ asResponse() {
27
+ return this.responsePromise.then((props) => props.response);
28
+ }
29
+ then(onfulfilled, onrejected) {
30
+ return this.withRawResponse().then((r) => r.data).then(onfulfilled, onrejected);
31
+ }
32
+ catch(onrejected) {
33
+ return this.then(undefined, onrejected);
34
+ }
35
+ finally(onfinally) {
36
+ return this.then().finally(onfinally);
37
+ }
38
+ }
39
+ //# sourceMappingURL=api-promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-promise.js","sourceRoot":"","sources":["../../src/core/api-promise.ts"],"names":[],"mappings":"AAgBA;;;GAGG;AACH,MAAM,OAAO,UAAU;IAIA;IACA;IAJb,MAAM,CAA0C;IAExD,YACqB,eAA0C,EAC1C,aAAsD;QADtD,oBAAe,GAAf,eAAe,CAA2B;QAC1C,kBAAa,GAAb,aAAa,CAAyC;IACxE,CAAC;IAEJ,6DAA6D;IAC7D,WAAW,CAAI,SAAkD;QAC/D,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAClH,CAAC;IAED,eAAe;QACb,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1D,IAAI,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;YACrC,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;SACtD,CAAC,CAAC,CAAC;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,uDAAuD;IACvD,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CACF,WAAqE,EACrE,UAA2E;QAE3E,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAkB,UAAyE;QAC9F,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,SAA+B;QACrC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,70 @@
1
+ /** Base class for every error thrown by the SDK. */
2
+ export declare class GlexirError extends Error {
3
+ constructor(message?: string, options?: {
4
+ cause?: unknown;
5
+ });
6
+ }
7
+ /** The `error` object inside an API error body (`{ "error": { ... } }`). */
8
+ export interface APIErrorBody {
9
+ message?: string;
10
+ type?: string;
11
+ code?: string | null;
12
+ param?: string | null;
13
+ [key: string]: unknown;
14
+ }
15
+ /**
16
+ * An error returned by the API. `status` is `undefined` for errors that arrive
17
+ * mid-stream (SSE `error` events), so branch on `code`/`type` rather than the class.
18
+ */
19
+ export declare class APIError<TStatus extends number | undefined = number | undefined> extends GlexirError {
20
+ readonly status: TStatus;
21
+ readonly headers: Headers | undefined;
22
+ readonly error: APIErrorBody | undefined;
23
+ readonly code: string | null | undefined;
24
+ readonly param: string | null | undefined;
25
+ readonly type: string | undefined;
26
+ /** The `x-request-id` response header, for support requests. */
27
+ readonly requestID: string | null | undefined;
28
+ constructor(status: TStatus, error: unknown, message: string | undefined, headers: Headers | undefined);
29
+ static generate(status: number | undefined, errorResponse: unknown, message: string | undefined, headers: Headers | undefined): APIError;
30
+ }
31
+ export declare class APIUserAbortError extends APIError<undefined> {
32
+ constructor({ message }?: {
33
+ message?: string;
34
+ });
35
+ }
36
+ export declare class APIConnectionError extends APIError<undefined> {
37
+ constructor({ message, cause }: {
38
+ message?: string | undefined;
39
+ cause?: unknown;
40
+ });
41
+ }
42
+ export declare class APIConnectionTimeoutError extends APIConnectionError {
43
+ constructor({ message }?: {
44
+ message?: string;
45
+ });
46
+ }
47
+ export declare class BadRequestError extends APIError<400> {
48
+ }
49
+ export declare class AuthenticationError extends APIError<401> {
50
+ }
51
+ export declare class PermissionDeniedError extends APIError<403> {
52
+ }
53
+ export declare class NotFoundError extends APIError<404> {
54
+ }
55
+ export declare class ConflictError extends APIError<409> {
56
+ }
57
+ export declare class UnprocessableEntityError extends APIError<422> {
58
+ }
59
+ export declare class RateLimitError extends APIError<429> {
60
+ }
61
+ export declare class InternalServerError extends APIError<number> {
62
+ }
63
+ /** Thrown by `parse()` helpers when the model stopped because it hit the token limit. */
64
+ export declare class LengthFinishReasonError extends GlexirError {
65
+ constructor();
66
+ }
67
+ /** Thrown by `parse()` helpers when the output was cut off by the content filter. */
68
+ export declare class ContentFilterFinishReasonError extends GlexirError {
69
+ constructor();
70
+ }
@@ -0,0 +1,118 @@
1
+ /** Base class for every error thrown by the SDK. */
2
+ export class GlexirError extends Error {
3
+ constructor(message, options) {
4
+ super(message, options);
5
+ this.name = new.target.name;
6
+ }
7
+ }
8
+ function makeMessage(status, error, message) {
9
+ const inner = error && typeof error === 'object' ? error.message : undefined;
10
+ const msg = typeof inner === 'string'
11
+ ? inner
12
+ : inner !== undefined
13
+ ? JSON.stringify(inner)
14
+ : error !== undefined && typeof error !== 'object'
15
+ ? String(error)
16
+ : message;
17
+ if (status && msg)
18
+ return `${status} ${msg}`;
19
+ if (status)
20
+ return `${status} status code (no body)`;
21
+ return msg ?? '(no error message)';
22
+ }
23
+ /**
24
+ * An error returned by the API. `status` is `undefined` for errors that arrive
25
+ * mid-stream (SSE `error` events), so branch on `code`/`type` rather than the class.
26
+ */
27
+ export class APIError extends GlexirError {
28
+ status;
29
+ headers;
30
+ error;
31
+ code;
32
+ param;
33
+ type;
34
+ /** The `x-request-id` response header, for support requests. */
35
+ requestID;
36
+ constructor(status, error, message, headers) {
37
+ super(makeMessage(status, error, message));
38
+ this.status = status;
39
+ this.headers = headers;
40
+ this.requestID = headers?.get('x-request-id');
41
+ const body = error && typeof error === 'object' ? error : undefined;
42
+ this.error = body;
43
+ this.code = body?.code;
44
+ this.param = body?.param;
45
+ this.type = body?.type;
46
+ }
47
+ static generate(status, errorResponse, message, headers) {
48
+ if (!status || !headers) {
49
+ return new APIConnectionError({ message, cause: errorResponse });
50
+ }
51
+ const error = errorResponse?.error ?? errorResponse;
52
+ switch (status) {
53
+ case 400:
54
+ return new BadRequestError(status, error, message, headers);
55
+ case 401:
56
+ return new AuthenticationError(status, error, message, headers);
57
+ case 403:
58
+ return new PermissionDeniedError(status, error, message, headers);
59
+ case 404:
60
+ return new NotFoundError(status, error, message, headers);
61
+ case 409:
62
+ return new ConflictError(status, error, message, headers);
63
+ case 422:
64
+ return new UnprocessableEntityError(status, error, message, headers);
65
+ case 429:
66
+ return new RateLimitError(status, error, message, headers);
67
+ }
68
+ if (status >= 500)
69
+ return new InternalServerError(status, error, message, headers);
70
+ return new APIError(status, error, message, headers);
71
+ }
72
+ }
73
+ export class APIUserAbortError extends APIError {
74
+ constructor({ message } = {}) {
75
+ super(undefined, undefined, message ?? 'Request was aborted.', undefined);
76
+ }
77
+ }
78
+ export class APIConnectionError extends APIError {
79
+ constructor({ message, cause }) {
80
+ super(undefined, undefined, message ?? 'Connection error.', undefined);
81
+ if (cause !== undefined)
82
+ this.cause = cause;
83
+ }
84
+ }
85
+ export class APIConnectionTimeoutError extends APIConnectionError {
86
+ constructor({ message } = {}) {
87
+ super({ message: message ?? 'Request timed out.' });
88
+ }
89
+ }
90
+ export class BadRequestError extends APIError {
91
+ }
92
+ export class AuthenticationError extends APIError {
93
+ }
94
+ export class PermissionDeniedError extends APIError {
95
+ }
96
+ export class NotFoundError extends APIError {
97
+ }
98
+ export class ConflictError extends APIError {
99
+ }
100
+ export class UnprocessableEntityError extends APIError {
101
+ }
102
+ export class RateLimitError extends APIError {
103
+ }
104
+ export class InternalServerError extends APIError {
105
+ }
106
+ /** Thrown by `parse()` helpers when the model stopped because it hit the token limit. */
107
+ export class LengthFinishReasonError extends GlexirError {
108
+ constructor() {
109
+ super('Could not parse response content as the length limit was reached.');
110
+ }
111
+ }
112
+ /** Thrown by `parse()` helpers when the output was cut off by the content filter. */
113
+ export class ContentFilterFinishReasonError extends GlexirError {
114
+ constructor() {
115
+ super('Could not parse response content as the request was rejected by the content filter.');
116
+ }
117
+ }
118
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Anything that can be uploaded as a file. Prefer a `File` (or {@link toFile}) so the filename carries an extension. */
2
+ export type Uploadable = File | Blob | Uint8Array | ArrayBuffer | ReadableStream<Uint8Array> | Response;
3
+ export type ToFileInput = Uploadable | string;
4
+ /**
5
+ * Wraps raw data in a `File` with a name and MIME type. OpenAI detects audio and document
6
+ * formats from the filename extension, so always pass a real one (e.g. `meeting.m4a`).
7
+ */
8
+ export declare function toFile(data: ToFileInput, name?: string, options?: {
9
+ type?: string;
10
+ }): Promise<File>;
11
+ /**
12
+ * Builds a multipart body in the encoding OpenAI expects: arrays as repeated `key[]` parts,
13
+ * objects as `key[sub]` parts. Text fields are written before file parts so a gateway can
14
+ * read routing fields (`model`, `stream`) without buffering the upload.
15
+ */
16
+ export declare function buildMultipartForm(body: Record<string, unknown>): Promise<FormData>;
@@ -0,0 +1,68 @@
1
+ import { GlexirError } from './errors.js';
2
+ /**
3
+ * Wraps raw data in a `File` with a name and MIME type. OpenAI detects audio and document
4
+ * formats from the filename extension, so always pass a real one (e.g. `meeting.m4a`).
5
+ */
6
+ export async function toFile(data, name, options = {}) {
7
+ if (typeof File !== 'undefined' && data instanceof File && !name && !options.type)
8
+ return data;
9
+ const filename = name ?? (data instanceof File ? data.name : undefined);
10
+ if (!filename) {
11
+ throw new GlexirError('toFile() needs a filename with an extension, e.g. toFile(bytes, "audio.mp3").');
12
+ }
13
+ let blob;
14
+ if (data instanceof Blob)
15
+ blob = data;
16
+ else if (typeof data === 'string')
17
+ blob = new Blob([data]);
18
+ else if (data instanceof Uint8Array)
19
+ blob = new Blob([data]);
20
+ else if (data instanceof ArrayBuffer)
21
+ blob = new Blob([data]);
22
+ else if (typeof Response !== 'undefined' && data instanceof Response)
23
+ blob = await data.blob();
24
+ else
25
+ blob = await new Response(data).blob();
26
+ return new File([blob], filename, { type: options.type ?? (blob.type || undefined) });
27
+ }
28
+ const isUploadable = (value) => value instanceof Blob ||
29
+ value instanceof Uint8Array ||
30
+ value instanceof ArrayBuffer ||
31
+ (typeof ReadableStream !== 'undefined' && value instanceof ReadableStream) ||
32
+ (typeof Response !== 'undefined' && value instanceof Response);
33
+ function appendField(form, key, value) {
34
+ if (value === undefined || value === null)
35
+ return;
36
+ if (Array.isArray(value)) {
37
+ for (const entry of value)
38
+ appendField(form, `${key}[]`, entry);
39
+ return;
40
+ }
41
+ if (typeof value === 'object') {
42
+ for (const [sub, entry] of Object.entries(value))
43
+ appendField(form, `${key}[${sub}]`, entry);
44
+ return;
45
+ }
46
+ form.append(key, String(value));
47
+ }
48
+ /**
49
+ * Builds a multipart body in the encoding OpenAI expects: arrays as repeated `key[]` parts,
50
+ * objects as `key[sub]` parts. Text fields are written before file parts so a gateway can
51
+ * read routing fields (`model`, `stream`) without buffering the upload.
52
+ */
53
+ export async function buildMultipartForm(body) {
54
+ const form = new FormData();
55
+ const files = [];
56
+ for (const [key, value] of Object.entries(body)) {
57
+ if (isUploadable(value))
58
+ files.push([key, value]);
59
+ else
60
+ appendField(form, key, value);
61
+ }
62
+ for (const [key, value] of files) {
63
+ const file = value instanceof File ? value : await toFile(value, `${key}.bin`);
64
+ form.append(key, file, file.name);
65
+ }
66
+ return form;
67
+ }
68
+ //# sourceMappingURL=multipart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/core/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAiB,EAAE,IAAa,EAAE,UAA6B,EAAE;IAC5F,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,IAAI,YAAY,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/F,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,YAAY,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,WAAW,CAAC,+EAA+E,CAAC,CAAC;IACzG,CAAC;IAED,IAAI,IAAU,CAAC;IACf,IAAI,IAAI,YAAY,IAAI;QAAE,IAAI,GAAG,IAAI,CAAC;SACjC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SACtD,IAAI,IAAI,YAAY,UAAU;QAAE,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAA+B,CAAC,CAAC,CAAC;SACnF,IAAI,IAAI,YAAY,WAAW;QAAE,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SACzD,IAAI,OAAO,QAAQ,KAAK,WAAW,IAAI,IAAI,YAAY,QAAQ;QAAE,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;;QAC1F,IAAI,GAAG,MAAM,IAAI,QAAQ,CAAC,IAAkC,CAAC,CAAC,IAAI,EAAE,CAAC;IAE1E,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,KAAc,EAAuB,EAAE,CAC3D,KAAK,YAAY,IAAI;IACrB,KAAK,YAAY,UAAU;IAC3B,KAAK,YAAY,WAAW;IAC5B,CAAC,OAAO,cAAc,KAAK,WAAW,IAAI,KAAK,YAAY,cAAc,CAAC;IAC1E,CAAC,OAAO,QAAQ,KAAK,WAAW,IAAI,KAAK,YAAY,QAAQ,CAAC,CAAC;AAEjE,SAAS,WAAW,CAAC,IAAc,EAAE,GAAW,EAAE,KAAc;IAC9D,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAClD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,KAAK;YAAE,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7F,OAAO;IACT,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA6B;IACpE,MAAM,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAgC,EAAE,CAAC;IAE9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,YAAY,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;;YAC7C,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { APIPromise, type APIResponseProps } from './api-promise.js';
2
+ import type { FinalRequestOptions } from './request-options.js';
3
+ export interface CursorPageParams {
4
+ /** Return items after this cursor (an object ID). */
5
+ after?: string;
6
+ /** Page size, typically 1–100. */
7
+ limit?: number;
8
+ }
9
+ export interface PageResponse<Item> {
10
+ object?: 'list';
11
+ data: Item[];
12
+ has_more?: boolean;
13
+ first_id?: string | null;
14
+ last_id?: string | null;
15
+ }
16
+ /** How the next-page cursor is derived. */
17
+ export type CursorStrategy = 'last-item-id' | 'last_id' | 'none';
18
+ export interface PageRequester {
19
+ requestAPIList<Item>(options: FinalRequestOptions, cursor: CursorStrategy): PagePromise<Item>;
20
+ }
21
+ /** One page of a cursor-paginated list. Iterate it with `for await` to walk every page. */
22
+ export declare class CursorPage<Item> implements AsyncIterable<Item> {
23
+ private readonly client;
24
+ private readonly request;
25
+ private readonly cursor;
26
+ readonly data: Item[];
27
+ readonly has_more: boolean;
28
+ readonly first_id: string | null | undefined;
29
+ readonly last_id: string | null | undefined;
30
+ constructor(client: PageRequester, request: FinalRequestOptions, body: PageResponse<Item>, cursor: CursorStrategy);
31
+ private nextCursor;
32
+ hasNextPage(): boolean;
33
+ getNextPage(): Promise<CursorPage<Item>>;
34
+ iterPages(): AsyncGenerator<CursorPage<Item>>;
35
+ [Symbol.asyncIterator](): AsyncGenerator<Item>;
36
+ }
37
+ /** A promise for the first page that can also be iterated directly: `for await (const x of client.files.list())`. */
38
+ export declare class PagePromise<Item> extends APIPromise<CursorPage<Item>> implements AsyncIterable<Item> {
39
+ constructor(client: PageRequester, responsePromise: Promise<APIResponseProps>, parseBody: (props: APIResponseProps) => Promise<PageResponse<Item>>, cursor: CursorStrategy);
40
+ [Symbol.asyncIterator](): AsyncGenerator<Item>;
41
+ }
@@ -0,0 +1,63 @@
1
+ import { APIPromise } from './api-promise.js';
2
+ /** One page of a cursor-paginated list. Iterate it with `for await` to walk every page. */
3
+ export class CursorPage {
4
+ client;
5
+ request;
6
+ cursor;
7
+ data;
8
+ has_more;
9
+ first_id;
10
+ last_id;
11
+ constructor(client, request, body, cursor) {
12
+ this.client = client;
13
+ this.request = request;
14
+ this.cursor = cursor;
15
+ this.data = body.data ?? [];
16
+ this.has_more = body.has_more ?? false;
17
+ this.first_id = body.first_id;
18
+ this.last_id = body.last_id;
19
+ }
20
+ nextCursor() {
21
+ if (this.cursor === 'last_id')
22
+ return this.last_id;
23
+ const last = this.data[this.data.length - 1];
24
+ return last?.id;
25
+ }
26
+ hasNextPage() {
27
+ if (this.cursor === 'none' || !this.has_more || this.data.length === 0)
28
+ return false;
29
+ return Boolean(this.nextCursor());
30
+ }
31
+ async getNextPage() {
32
+ const after = this.nextCursor();
33
+ if (!this.hasNextPage() || !after) {
34
+ throw new Error('No next page; check hasNextPage() before calling getNextPage().');
35
+ }
36
+ return this.client.requestAPIList({ ...this.request, query: { ...this.request.query, after } }, this.cursor);
37
+ }
38
+ async *iterPages() {
39
+ let page = this;
40
+ yield page;
41
+ while (page.hasNextPage()) {
42
+ page = await page.getNextPage();
43
+ yield page;
44
+ }
45
+ }
46
+ async *[Symbol.asyncIterator]() {
47
+ for await (const page of this.iterPages()) {
48
+ for (const item of page.data)
49
+ yield item;
50
+ }
51
+ }
52
+ }
53
+ /** A promise for the first page that can also be iterated directly: `for await (const x of client.files.list())`. */
54
+ export class PagePromise extends APIPromise {
55
+ constructor(client, responsePromise, parseBody, cursor) {
56
+ super(responsePromise, async (props) => new CursorPage(client, props.options, await parseBody(props), cursor));
57
+ }
58
+ async *[Symbol.asyncIterator]() {
59
+ const page = await this;
60
+ yield* page;
61
+ }
62
+ }
63
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../src/core/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AAyBrE,2FAA2F;AAC3F,MAAM,OAAO,UAAU;IAOF;IACA;IAEA;IATV,IAAI,CAAS;IACb,QAAQ,CAAU;IAClB,QAAQ,CAA4B;IACpC,OAAO,CAA4B;IAE5C,YACmB,MAAqB,EACrB,OAA4B,EAC7C,IAAwB,EACP,MAAsB;QAHtB,WAAM,GAAN,MAAM,CAAe;QACrB,YAAO,GAAP,OAAO,CAAqB;QAE5B,WAAM,GAAN,MAAM,CAAgB;QAEvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAgC,CAAC;QAC5E,OAAO,IAAI,EAAE,EAAE,CAAC;IAClB,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACrF,OAAO,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACrH,CAAC;IAED,KAAK,CAAC,CAAC,SAAS;QACd,IAAI,IAAI,GAAqB,IAAI,CAAC;QAClC,MAAM,IAAI,CAAC;QACX,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YAC1B,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC;QACb,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YAC1C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,CAAC;QAC3C,CAAC;IACH,CAAC;CACF;AAED,qHAAqH;AACrH,MAAM,OAAO,WAAkB,SAAQ,UAA4B;IACjE,YACE,MAAqB,EACrB,eAA0C,EAC1C,SAAmE,EACnE,MAAsB;QAEtB,KAAK,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACjH,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;QACxB,KAAK,CAAC,CAAC,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
2
+ /** Options accepted by every API method as its last argument. */
3
+ export interface RequestOptions {
4
+ /** Abort the request (and any retries) when this signal fires. */
5
+ signal?: AbortSignal | null;
6
+ /** Per-attempt timeout in milliseconds. Defaults to the client's `timeout` (10 minutes). */
7
+ timeout?: number;
8
+ /** Overrides the client's `maxRetries` for this call. */
9
+ maxRetries?: number;
10
+ /** Extra headers; a `null` value removes a default header. */
11
+ headers?: Record<string, string | null | undefined>;
12
+ /**
13
+ * Sent as `Idempotency-Key` on non-GET requests. Generated automatically once per call
14
+ * and reused across retries, so a retried request is never billed twice.
15
+ */
16
+ idempotencyKey?: string;
17
+ }
18
+ export interface FinalRequestOptions extends RequestOptions {
19
+ method: HTTPMethod;
20
+ path: string;
21
+ query?: Record<string, unknown> | undefined;
22
+ body?: unknown;
23
+ /** Encode `body` as multipart/form-data. */
24
+ multipart?: boolean;
25
+ /** Parse the response as a server-sent event stream. */
26
+ stream?: boolean;
27
+ /** Return the raw `Response` without reading the body (file downloads). */
28
+ binary?: boolean;
29
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=request-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-options.js","sourceRoot":"","sources":["../../src/core/request-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { Glexir } from '../client.js';
2
+ export declare abstract class APIResource {
3
+ protected readonly client: Glexir;
4
+ constructor(client: Glexir);
5
+ }
@@ -0,0 +1,7 @@
1
+ export class APIResource {
2
+ client;
3
+ constructor(client) {
4
+ this.client = client;
5
+ }
6
+ }
7
+ //# sourceMappingURL=resource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.js","sourceRoot":"","sources":["../../src/core/resource.ts"],"names":[],"mappings":"AAEA,MAAM,OAAgB,WAAW;IACA;IAA/B,YAA+B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;IAAG,CAAC;CAClD"}
@@ -0,0 +1,13 @@
1
+ /** Statuses OpenAI's own SDK retries: request timeout, lock conflict, rate limit, and server errors. */
2
+ export declare function isRetryableStatus(status: number): boolean;
3
+ /** `x-should-retry: true|false` lets the server override the status-based decision. */
4
+ export declare function shouldRetryResponse(response: Response): boolean;
5
+ /**
6
+ * Exponential backoff matching OpenAI's SDK: min(0.5 * 2^n, 8) seconds,
7
+ * reduced by up to 25% jitter. `retriesSoFar` starts at 0.
8
+ */
9
+ export declare function defaultBackoffMs(retriesSoFar: number, random?: () => number): number;
10
+ /** Server-requested delay from `retry-after-ms` / `retry-after`, used only when it is between 0 and 60 seconds. */
11
+ export declare function retryDelayMs(headers: Headers | undefined, retriesSoFar: number, now?: () => number, random?: () => number): number;
12
+ export declare function sleep(ms: number, signal?: AbortSignal | null): Promise<void>;
13
+ export declare function uuid4(): string;
@@ -0,0 +1,65 @@
1
+ /** Statuses OpenAI's own SDK retries: request timeout, lock conflict, rate limit, and server errors. */
2
+ export function isRetryableStatus(status) {
3
+ return status === 408 || status === 409 || status === 429 || status >= 500;
4
+ }
5
+ /** `x-should-retry: true|false` lets the server override the status-based decision. */
6
+ export function shouldRetryResponse(response) {
7
+ const header = response.headers.get('x-should-retry');
8
+ if (header === 'true')
9
+ return true;
10
+ if (header === 'false')
11
+ return false;
12
+ return isRetryableStatus(response.status);
13
+ }
14
+ /**
15
+ * Exponential backoff matching OpenAI's SDK: min(0.5 * 2^n, 8) seconds,
16
+ * reduced by up to 25% jitter. `retriesSoFar` starts at 0.
17
+ */
18
+ export function defaultBackoffMs(retriesSoFar, random = Math.random) {
19
+ const seconds = Math.min(0.5 * Math.pow(2, retriesSoFar), 8);
20
+ const jitter = 1 - random() * 0.25;
21
+ return seconds * jitter * 1000;
22
+ }
23
+ /** Server-requested delay from `retry-after-ms` / `retry-after`, used only when it is between 0 and 60 seconds. */
24
+ export function retryDelayMs(headers, retriesSoFar, now = Date.now, random = Math.random) {
25
+ let ms;
26
+ const retryAfterMs = headers?.get('retry-after-ms');
27
+ if (retryAfterMs) {
28
+ const value = parseFloat(retryAfterMs);
29
+ if (!Number.isNaN(value))
30
+ ms = value;
31
+ }
32
+ const retryAfter = headers?.get('retry-after');
33
+ if (retryAfter && ms === undefined) {
34
+ const seconds = parseFloat(retryAfter);
35
+ ms = Number.isNaN(seconds) ? Date.parse(retryAfter) - now() : seconds * 1000;
36
+ }
37
+ if (ms === undefined || Number.isNaN(ms) || ms < 0 || ms > 60_000) {
38
+ return defaultBackoffMs(retriesSoFar, random);
39
+ }
40
+ return ms;
41
+ }
42
+ export function sleep(ms, signal) {
43
+ return new Promise((resolve, reject) => {
44
+ if (signal?.aborted)
45
+ return reject(signal.reason);
46
+ const timer = setTimeout(() => {
47
+ signal?.removeEventListener('abort', onAbort);
48
+ resolve();
49
+ }, ms);
50
+ const onAbort = () => {
51
+ clearTimeout(timer);
52
+ reject(signal?.reason);
53
+ };
54
+ signal?.addEventListener('abort', onAbort, { once: true });
55
+ });
56
+ }
57
+ export function uuid4() {
58
+ if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function')
59
+ return crypto.randomUUID();
60
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
61
+ const r = (Math.random() * 16) | 0;
62
+ return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
63
+ });
64
+ }
65
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/core/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface ServerSentEvent {
2
+ event: string | null;
3
+ data: string;
4
+ raw: string[];
5
+ }
6
+ /**
7
+ * Splits a byte stream into lines, handling `\n`, `\r` and `\r\n` endings even when
8
+ * a line ending is split across chunks.
9
+ */
10
+ export declare class LineDecoder {
11
+ private buffer;
12
+ private trailingCR;
13
+ private readonly decoder;
14
+ decode(chunk: Uint8Array | string): string[];
15
+ flush(): string[];
16
+ }
17
+ /** Assembles SSE lines into events per the WHATWG EventSource parsing rules (only `event` and `data` are used). */
18
+ export declare class SSEDecoder {
19
+ private data;
20
+ private event;
21
+ private chunks;
22
+ decode(line: string): ServerSentEvent | null;
23
+ }
24
+ export declare function iterSSEMessages(body: ReadableStream<Uint8Array>): AsyncGenerator<ServerSentEvent>;
25
+ /** An async-iterable stream of parsed events. Breaking out of the loop aborts the HTTP request. */
26
+ export declare class Stream<Item> implements AsyncIterable<Item> {
27
+ private readonly iterator;
28
+ readonly controller: AbortController;
29
+ /** The underlying HTTP response, if this stream came from one. */
30
+ readonly response?: Response | undefined;
31
+ private consumed;
32
+ constructor(iterator: () => AsyncIterator<Item>, controller: AbortController,
33
+ /** The underlying HTTP response, if this stream came from one. */
34
+ response?: Response | undefined);
35
+ static fromSSEResponse<Item>(response: Response, controller: AbortController): Stream<Item>;
36
+ /** Re-hydrates a stream produced by {@link Stream.toReadableStream} (newline-delimited JSON). */
37
+ static fromReadableStream<Item>(readable: ReadableStream<Uint8Array>, controller?: AbortController): Stream<Item>;
38
+ [Symbol.asyncIterator](): AsyncIterator<Item>;
39
+ /** Splits the stream into two independent streams that each see every event. */
40
+ tee(): [Stream<Item>, Stream<Item>];
41
+ /** Converts to a byte stream of newline-delimited JSON, e.g. to relay to a browser. */
42
+ toReadableStream(): ReadableStream<Uint8Array>;
43
+ }
44
+ export declare function isAbortError(err: unknown): boolean;