@measyai/sdk 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MeasyAI
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 ADDED
@@ -0,0 +1,130 @@
1
+ # @measyai/sdk
2
+
3
+ Typed TypeScript client for the [MeasyAI API](https://docs.measyai.com).
4
+
5
+ ```bash
6
+ npm install @measyai/sdk
7
+ ```
8
+
9
+ Requires Node 18+ (uses the built-in `fetch` and Web Crypto). Ships ESM and
10
+ CommonJS builds with type declarations.
11
+
12
+ ## Quick start
13
+
14
+ ```ts
15
+ import { MeasyAI } from "@measyai/sdk";
16
+
17
+ const client = new MeasyAI({ apiKey: process.env.MEASYAI_API_KEY! });
18
+
19
+ const completion = await client.chat.create({
20
+ model: "measyai/meridian",
21
+ messages: [{ role: "user", content: "Explain HTTP/3 in two sentences." }],
22
+ });
23
+
24
+ console.log(completion.choices[0].message.content);
25
+ ```
26
+
27
+ ## Streaming
28
+
29
+ `stream()` yields text deltas. `streamChunks()` yields the raw chunks when you
30
+ need finish reasons or token usage.
31
+
32
+ ```ts
33
+ for await (const delta of client.chat.stream({
34
+ messages: [{ role: "user", content: "Why is Postgres MVCC useful?" }],
35
+ })) {
36
+ process.stdout.write(delta);
37
+ }
38
+ ```
39
+
40
+ Pass an `AbortSignal` to stop early — the underlying connection is released
41
+ rather than left dangling:
42
+
43
+ ```ts
44
+ const controller = new AbortController();
45
+ setTimeout(() => controller.abort(), 5000);
46
+
47
+ for await (const delta of client.chat.stream(params, { signal: controller.signal })) {
48
+ process.stdout.write(delta);
49
+ }
50
+ ```
51
+
52
+ ## Batches
53
+
54
+ ```ts
55
+ const batch = await client.batches.create([
56
+ { custom_id: "row-1", body: { messages: [{ role: "user", content: "Summarise: …" }] } },
57
+ { custom_id: "row-2", body: { messages: [{ role: "user", content: "Summarise: …" }] } },
58
+ ]);
59
+
60
+ const done = await client.batches.waitUntilComplete(batch.id);
61
+ console.log(`${done.completed} completed, ${done.failed} failed`);
62
+ ```
63
+
64
+ ## Webhooks
65
+
66
+ Verify against the **raw** request body. Re-serializing parsed JSON will not
67
+ reproduce the same bytes and the check will fail.
68
+
69
+ ```ts
70
+ import { verifyWebhook } from "@measyai/sdk";
71
+
72
+ const valid = await verifyWebhook({
73
+ secret: process.env.MEASYAI_WEBHOOK_SECRET!,
74
+ signature: req.headers["x-measyai-signature"] as string,
75
+ timestamp: req.headers["x-measyai-timestamp"] as string,
76
+ rawBody,
77
+ });
78
+ ```
79
+
80
+ The timestamp is part of the signed string and is checked against a tolerance,
81
+ so a captured delivery cannot be replayed later. Comparison is constant-time.
82
+
83
+ ## Errors
84
+
85
+ Every failure throws a `MeasyAIError` carrying a stable `code`, the HTTP
86
+ `status`, and the `requestId` worth quoting in a bug report.
87
+
88
+ ```ts
89
+ import { MeasyAIError } from "@measyai/sdk";
90
+
91
+ try {
92
+ await client.chat.create(params);
93
+ } catch (err) {
94
+ if (err instanceof MeasyAIError && err.isRetryable) {
95
+ // 429 or 5xx — worth backing off and trying again
96
+ }
97
+ }
98
+ ```
99
+
100
+ ## Using the OpenAI SDK instead
101
+
102
+ The `/v1` surface is OpenAI-compatible, so the official OpenAI SDK works by
103
+ changing the base URL:
104
+
105
+ ```ts
106
+ const client = new OpenAI({
107
+ apiKey: process.env.MEASYAI_API_KEY,
108
+ baseURL: "https://api.measyai.com/v1",
109
+ });
110
+ ```
111
+
112
+ Use this package when you also want the endpoints OpenAI has no equivalent
113
+ for — batches, analytics and webhook verification — typed.
114
+
115
+ ## Configuration
116
+
117
+ | Option | Default | Notes |
118
+ | --- | --- | --- |
119
+ | `apiKey` | — | Required. Create one in the dashboard. |
120
+ | `baseUrl` | `https://api.measyai.com` | Point at your own instance when self-hosting. |
121
+ | `timeoutMs` | `120000` | Applies to unary calls; streaming requests are exempt. |
122
+ | `fetch` | global `fetch` | Inject your own for testing or proxying. |
123
+
124
+ ## Links
125
+
126
+ - [Documentation](https://docs.measyai.com)
127
+ - [Status](https://status.measyai.com)
128
+ - [OpenAPI spec](https://api.measyai.com/openapi.yaml)
129
+
130
+ MIT licensed.
@@ -0,0 +1,264 @@
1
+ "use strict";
2
+ /**
3
+ * MeasyAI TypeScript SDK.
4
+ *
5
+ * The request/response *types* under ./generated are produced from the
6
+ * OpenAPI document by `make gen-sdk`. This file is the hand-written runtime
7
+ * on top of them: a few hundred bytes of fetch, streaming and error
8
+ * handling that a generator has no way to get right.
9
+ *
10
+ * ```ts
11
+ * import { MeasyAI } from "@measyai/sdk";
12
+ *
13
+ * const client = new MeasyAI({ apiKey: process.env.MEASYAI_API_KEY! });
14
+ *
15
+ * for await (const delta of client.chat.stream({
16
+ * messages: [{ role: "user", content: "Explain HTTP/3" }],
17
+ * })) {
18
+ * process.stdout.write(delta);
19
+ * }
20
+ * ```
21
+ *
22
+ * The `/v1` surface is OpenAI-compatible, so the official OpenAI SDK also
23
+ * works — point its `baseURL` at `https://api.measyai.com/v1`. Use this
24
+ * package when you want MeasyAI's own endpoints (batches, analytics)
25
+ * typed too.
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.MeasyAI = exports.MeasyAIError = void 0;
29
+ exports.verifyWebhook = verifyWebhook;
30
+ /** Every non-2xx response arrives as one of these. */
31
+ class MeasyAIError extends Error {
32
+ status;
33
+ code;
34
+ type;
35
+ param;
36
+ requestId;
37
+ constructor(status, body) {
38
+ super(body.error?.message ?? `Request failed with status ${status}`);
39
+ this.name = "MeasyAIError";
40
+ this.status = status;
41
+ this.code = body.error?.code ?? "unknown_error";
42
+ this.type = body.error?.type;
43
+ this.param = body.error?.param;
44
+ this.requestId = body.request_id;
45
+ }
46
+ /** True when retrying later might succeed. */
47
+ get isRetryable() {
48
+ return this.status === 429 || this.status >= 500;
49
+ }
50
+ }
51
+ exports.MeasyAIError = MeasyAIError;
52
+ const DEFAULT_BASE_URL = "https://api.measyai.com";
53
+ class MeasyAI {
54
+ chat;
55
+ batches;
56
+ models;
57
+ apiKey;
58
+ baseUrl;
59
+ timeoutMs;
60
+ fetchImpl;
61
+ constructor(options) {
62
+ if (!options.apiKey) {
63
+ throw new Error("MeasyAI: apiKey is required");
64
+ }
65
+ this.apiKey = options.apiKey;
66
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
67
+ this.timeoutMs = options.timeoutMs ?? 120_000;
68
+ this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
69
+ this.chat = new ChatResource(this);
70
+ this.batches = new BatchResource(this);
71
+ this.models = new ModelResource(this);
72
+ }
73
+ /** @internal */
74
+ async request(path, init = {}) {
75
+ const { method = "GET", body, signal, stream = false } = init;
76
+ // A streaming response has no meaningful overall duration, so the
77
+ // timeout applies only to unary calls.
78
+ const controller = new AbortController();
79
+ const timer = stream
80
+ ? undefined
81
+ : setTimeout(() => controller.abort(), this.timeoutMs);
82
+ signal?.addEventListener("abort", () => controller.abort(), { once: true });
83
+ try {
84
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
85
+ method,
86
+ headers: {
87
+ Authorization: `Bearer ${this.apiKey}`,
88
+ Accept: stream ? "text/event-stream" : "application/json",
89
+ ...(body === undefined ? {} : { "Content-Type": "application/json" }),
90
+ },
91
+ body: body === undefined ? undefined : JSON.stringify(body),
92
+ signal: controller.signal,
93
+ });
94
+ if (!res.ok) {
95
+ let payload = {};
96
+ try {
97
+ payload = (await res.json());
98
+ }
99
+ catch {
100
+ // A proxy error page is not JSON; the status still tells the story.
101
+ }
102
+ throw new MeasyAIError(res.status, payload);
103
+ }
104
+ return stream ? res : (await res.json());
105
+ }
106
+ finally {
107
+ if (timer !== undefined)
108
+ clearTimeout(timer);
109
+ }
110
+ }
111
+ }
112
+ exports.MeasyAI = MeasyAI;
113
+ class ChatResource {
114
+ client;
115
+ constructor(client) {
116
+ this.client = client;
117
+ }
118
+ /** One-shot completion. */
119
+ async create(params) {
120
+ return (await this.client.request("/v1/chat/completions", {
121
+ method: "POST",
122
+ body: { ...params, stream: false },
123
+ }));
124
+ }
125
+ /** Streams the reply, yielding text deltas as they arrive. */
126
+ async *stream(params, options = {}) {
127
+ for await (const chunk of this.streamChunks(params, options)) {
128
+ const delta = chunk.choices[0]?.delta?.content;
129
+ if (delta)
130
+ yield delta;
131
+ }
132
+ }
133
+ /** Streams raw chunks, for callers that need finish reasons or usage. */
134
+ async *streamChunks(params, options = {}) {
135
+ const res = (await this.client.request("/v1/chat/completions", {
136
+ method: "POST",
137
+ body: { ...params, stream: true },
138
+ signal: options.signal,
139
+ stream: true,
140
+ }));
141
+ if (!res.body) {
142
+ throw new Error("MeasyAI: the response carried no body to stream");
143
+ }
144
+ const reader = res.body.getReader();
145
+ const decoder = new TextDecoder();
146
+ let buffer = "";
147
+ try {
148
+ while (true) {
149
+ const { done, value } = await reader.read();
150
+ if (done)
151
+ break;
152
+ buffer += decoder.decode(value, { stream: true });
153
+ // Events are separated by a blank line. A partial event stays in
154
+ // the buffer until the rest of it arrives.
155
+ const events = buffer.split("\n\n");
156
+ buffer = events.pop() ?? "";
157
+ for (const event of events) {
158
+ for (const line of event.split("\n")) {
159
+ if (!line.startsWith("data:"))
160
+ continue;
161
+ const data = line.slice(5).trim();
162
+ if (data === "[DONE]")
163
+ return;
164
+ if (!data)
165
+ continue;
166
+ try {
167
+ yield JSON.parse(data);
168
+ }
169
+ catch {
170
+ // Skip a frame we cannot parse rather than killing the stream.
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+ finally {
177
+ // Releases the connection when a consumer breaks out of the loop early.
178
+ await reader.cancel().catch(() => { });
179
+ }
180
+ }
181
+ }
182
+ class BatchResource {
183
+ client;
184
+ constructor(client) {
185
+ this.client = client;
186
+ }
187
+ async create(requests) {
188
+ return (await this.client.request("/v1/batches", {
189
+ method: "POST",
190
+ body: { endpoint: "/v1/chat/completions", requests },
191
+ }));
192
+ }
193
+ async retrieve(batchId) {
194
+ return (await this.client.request(`/v1/batches/${batchId}`));
195
+ }
196
+ async list(limit = 20) {
197
+ return (await this.client.request(`/v1/batches?limit=${limit}`));
198
+ }
199
+ /** Polls until the batch closes. */
200
+ async waitUntilComplete(batchId, { intervalMs = 5_000, timeoutMs = 3_600_000 } = {}) {
201
+ const deadline = Date.now() + timeoutMs;
202
+ for (;;) {
203
+ const batch = await this.retrieve(batchId);
204
+ if (batch.status === "completed" || batch.status === "failed" || batch.status === "canceled") {
205
+ return batch;
206
+ }
207
+ if (Date.now() > deadline) {
208
+ throw new Error(`MeasyAI: batch ${batchId} did not finish within ${timeoutMs}ms`);
209
+ }
210
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
211
+ }
212
+ }
213
+ }
214
+ class ModelResource {
215
+ client;
216
+ constructor(client) {
217
+ this.client = client;
218
+ }
219
+ async list() {
220
+ return (await this.client.request("/v1/models"));
221
+ }
222
+ }
223
+ /**
224
+ * Verifies a webhook signature.
225
+ *
226
+ * Compute over the **raw** request body — re-serializing parsed JSON will
227
+ * not reproduce the same bytes and the check will fail.
228
+ *
229
+ * ```ts
230
+ * const valid = await verifyWebhook({
231
+ * secret: process.env.MEASYAI_WEBHOOK_SECRET!,
232
+ * signature: req.headers["x-measyai-signature"],
233
+ * timestamp: req.headers["x-measyai-timestamp"],
234
+ * rawBody,
235
+ * });
236
+ * ```
237
+ */
238
+ async function verifyWebhook({ secret, signature, timestamp, rawBody, toleranceSeconds = 300, }) {
239
+ const sent = Number.parseInt(timestamp, 10);
240
+ if (!Number.isFinite(sent))
241
+ return false;
242
+ // Reject stale deliveries: without this, a captured request could be
243
+ // replayed forever with its original, still-valid signature.
244
+ if (Math.abs(Date.now() / 1000 - sent) > toleranceSeconds)
245
+ return false;
246
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
247
+ const mac = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`${sent}.${rawBody}`));
248
+ const expected = "v1=" +
249
+ Array.from(new Uint8Array(mac))
250
+ .map((b) => b.toString(16).padStart(2, "0"))
251
+ .join("");
252
+ return timingSafeEqual(expected, signature);
253
+ }
254
+ /** Constant-time string comparison — a fast `!==` leaks the signature byte by byte. */
255
+ function timingSafeEqual(a, b) {
256
+ if (a.length !== b.length)
257
+ return false;
258
+ let diff = 0;
259
+ for (let i = 0; i < a.length; i++) {
260
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
261
+ }
262
+ return diff === 0;
263
+ }
264
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * MeasyAI TypeScript SDK.
3
+ *
4
+ * The request/response *types* under ./generated are produced from the
5
+ * OpenAPI document by `make gen-sdk`. This file is the hand-written runtime
6
+ * on top of them: a few hundred bytes of fetch, streaming and error
7
+ * handling that a generator has no way to get right.
8
+ *
9
+ * ```ts
10
+ * import { MeasyAI } from "@measyai/sdk";
11
+ *
12
+ * const client = new MeasyAI({ apiKey: process.env.MEASYAI_API_KEY! });
13
+ *
14
+ * for await (const delta of client.chat.stream({
15
+ * messages: [{ role: "user", content: "Explain HTTP/3" }],
16
+ * })) {
17
+ * process.stdout.write(delta);
18
+ * }
19
+ * ```
20
+ *
21
+ * The `/v1` surface is OpenAI-compatible, so the official OpenAI SDK also
22
+ * works — point its `baseURL` at `https://api.measyai.com/v1`. Use this
23
+ * package when you want MeasyAI's own endpoints (batches, analytics)
24
+ * typed too.
25
+ */
26
+ export interface MeasyAIOptions {
27
+ apiKey: string;
28
+ /** Defaults to the hosted API. */
29
+ baseUrl?: string;
30
+ /** Per-request timeout in ms. Streaming requests are exempt. */
31
+ timeoutMs?: number;
32
+ fetch?: typeof globalThis.fetch;
33
+ }
34
+ export type Role = "system" | "user" | "assistant" | "tool";
35
+ export interface ChatMessage {
36
+ role: Role;
37
+ content: string;
38
+ name?: string;
39
+ }
40
+ export interface ChatCompletionParams {
41
+ messages: ChatMessage[];
42
+ model?: string;
43
+ /** Any additional field is forwarded to the provider unchanged. */
44
+ [key: string]: unknown;
45
+ }
46
+ export interface Usage {
47
+ prompt_tokens: number;
48
+ completion_tokens: number;
49
+ total_tokens: number;
50
+ }
51
+ export interface ChatCompletion {
52
+ id: string;
53
+ object: "chat.completion";
54
+ created: number;
55
+ model: string;
56
+ choices: Array<{
57
+ index: number;
58
+ message: ChatMessage;
59
+ finish_reason: string;
60
+ }>;
61
+ usage?: Usage;
62
+ }
63
+ export interface ChatCompletionChunk {
64
+ id: string;
65
+ object: "chat.completion.chunk";
66
+ created: number;
67
+ model: string;
68
+ choices: Array<{
69
+ index: number;
70
+ delta: {
71
+ role?: Role;
72
+ content?: string;
73
+ };
74
+ finish_reason: string | null;
75
+ }>;
76
+ usage?: Usage;
77
+ }
78
+ export type ErrorType = "invalid_request_error" | "authentication_error" | "permission_error" | "not_found_error" | "conflict_error" | "rate_limit_error" | "api_error";
79
+ /** Every non-2xx response arrives as one of these. */
80
+ export declare class MeasyAIError extends Error {
81
+ readonly status: number;
82
+ readonly code: string;
83
+ readonly type?: ErrorType;
84
+ readonly param?: string;
85
+ readonly requestId?: string;
86
+ constructor(status: number, body: {
87
+ error?: {
88
+ code?: string;
89
+ message?: string;
90
+ type?: ErrorType;
91
+ param?: string;
92
+ };
93
+ request_id?: string;
94
+ });
95
+ /** True when retrying later might succeed. */
96
+ get isRetryable(): boolean;
97
+ }
98
+ export declare class MeasyAI {
99
+ readonly chat: ChatResource;
100
+ readonly batches: BatchResource;
101
+ readonly models: ModelResource;
102
+ private readonly apiKey;
103
+ private readonly baseUrl;
104
+ private readonly timeoutMs;
105
+ private readonly fetchImpl;
106
+ constructor(options: MeasyAIOptions);
107
+ /** @internal */
108
+ request<T>(path: string, init?: {
109
+ method?: string;
110
+ body?: unknown;
111
+ signal?: AbortSignal;
112
+ stream?: boolean;
113
+ }): Promise<Response | T>;
114
+ }
115
+ declare class ChatResource {
116
+ private readonly client;
117
+ constructor(client: MeasyAI);
118
+ /** One-shot completion. */
119
+ create(params: ChatCompletionParams): Promise<ChatCompletion>;
120
+ /** Streams the reply, yielding text deltas as they arrive. */
121
+ stream(params: ChatCompletionParams, options?: {
122
+ signal?: AbortSignal;
123
+ }): AsyncGenerator<string, void, unknown>;
124
+ /** Streams raw chunks, for callers that need finish reasons or usage. */
125
+ streamChunks(params: ChatCompletionParams, options?: {
126
+ signal?: AbortSignal;
127
+ }): AsyncGenerator<ChatCompletionChunk, void, unknown>;
128
+ }
129
+ export interface Batch {
130
+ id: string;
131
+ object: "batch";
132
+ status: "queued" | "in_progress" | "completed" | "failed" | "canceled";
133
+ total: number;
134
+ completed: number;
135
+ failed: number;
136
+ created_at: string;
137
+ completed_at?: string;
138
+ }
139
+ declare class BatchResource {
140
+ private readonly client;
141
+ constructor(client: MeasyAI);
142
+ create(requests: Array<{
143
+ custom_id?: string;
144
+ body: ChatCompletionParams;
145
+ }>): Promise<Batch>;
146
+ retrieve(batchId: string): Promise<Batch & {
147
+ items: unknown[];
148
+ }>;
149
+ list(limit?: number): Promise<{
150
+ object: "list";
151
+ data: Batch[];
152
+ }>;
153
+ /** Polls until the batch closes. */
154
+ waitUntilComplete(batchId: string, { intervalMs, timeoutMs }?: {
155
+ intervalMs?: number;
156
+ timeoutMs?: number;
157
+ }): Promise<Batch>;
158
+ }
159
+ declare class ModelResource {
160
+ private readonly client;
161
+ constructor(client: MeasyAI);
162
+ list(): Promise<{
163
+ object: "list";
164
+ data: Array<{
165
+ id: string;
166
+ name?: string;
167
+ }>;
168
+ }>;
169
+ }
170
+ /**
171
+ * Verifies a webhook signature.
172
+ *
173
+ * Compute over the **raw** request body — re-serializing parsed JSON will
174
+ * not reproduce the same bytes and the check will fail.
175
+ *
176
+ * ```ts
177
+ * const valid = await verifyWebhook({
178
+ * secret: process.env.MEASYAI_WEBHOOK_SECRET!,
179
+ * signature: req.headers["x-measyai-signature"],
180
+ * timestamp: req.headers["x-measyai-timestamp"],
181
+ * rawBody,
182
+ * });
183
+ * ```
184
+ */
185
+ export declare function verifyWebhook({ secret, signature, timestamp, rawBody, toleranceSeconds, }: {
186
+ secret: string;
187
+ signature: string;
188
+ timestamp: string;
189
+ rawBody: string;
190
+ toleranceSeconds?: number;
191
+ }): Promise<boolean>;
192
+ export {};
193
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,258 @@
1
+ /**
2
+ * MeasyAI TypeScript SDK.
3
+ *
4
+ * The request/response *types* under ./generated are produced from the
5
+ * OpenAPI document by `make gen-sdk`. This file is the hand-written runtime
6
+ * on top of them: a few hundred bytes of fetch, streaming and error
7
+ * handling that a generator has no way to get right.
8
+ *
9
+ * ```ts
10
+ * import { MeasyAI } from "@measyai/sdk";
11
+ *
12
+ * const client = new MeasyAI({ apiKey: process.env.MEASYAI_API_KEY! });
13
+ *
14
+ * for await (const delta of client.chat.stream({
15
+ * messages: [{ role: "user", content: "Explain HTTP/3" }],
16
+ * })) {
17
+ * process.stdout.write(delta);
18
+ * }
19
+ * ```
20
+ *
21
+ * The `/v1` surface is OpenAI-compatible, so the official OpenAI SDK also
22
+ * works — point its `baseURL` at `https://api.measyai.com/v1`. Use this
23
+ * package when you want MeasyAI's own endpoints (batches, analytics)
24
+ * typed too.
25
+ */
26
+ /** Every non-2xx response arrives as one of these. */
27
+ export class MeasyAIError extends Error {
28
+ status;
29
+ code;
30
+ type;
31
+ param;
32
+ requestId;
33
+ constructor(status, body) {
34
+ super(body.error?.message ?? `Request failed with status ${status}`);
35
+ this.name = "MeasyAIError";
36
+ this.status = status;
37
+ this.code = body.error?.code ?? "unknown_error";
38
+ this.type = body.error?.type;
39
+ this.param = body.error?.param;
40
+ this.requestId = body.request_id;
41
+ }
42
+ /** True when retrying later might succeed. */
43
+ get isRetryable() {
44
+ return this.status === 429 || this.status >= 500;
45
+ }
46
+ }
47
+ const DEFAULT_BASE_URL = "https://api.measyai.com";
48
+ export class MeasyAI {
49
+ chat;
50
+ batches;
51
+ models;
52
+ apiKey;
53
+ baseUrl;
54
+ timeoutMs;
55
+ fetchImpl;
56
+ constructor(options) {
57
+ if (!options.apiKey) {
58
+ throw new Error("MeasyAI: apiKey is required");
59
+ }
60
+ this.apiKey = options.apiKey;
61
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
62
+ this.timeoutMs = options.timeoutMs ?? 120_000;
63
+ this.fetchImpl = options.fetch ?? globalThis.fetch.bind(globalThis);
64
+ this.chat = new ChatResource(this);
65
+ this.batches = new BatchResource(this);
66
+ this.models = new ModelResource(this);
67
+ }
68
+ /** @internal */
69
+ async request(path, init = {}) {
70
+ const { method = "GET", body, signal, stream = false } = init;
71
+ // A streaming response has no meaningful overall duration, so the
72
+ // timeout applies only to unary calls.
73
+ const controller = new AbortController();
74
+ const timer = stream
75
+ ? undefined
76
+ : setTimeout(() => controller.abort(), this.timeoutMs);
77
+ signal?.addEventListener("abort", () => controller.abort(), { once: true });
78
+ try {
79
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
80
+ method,
81
+ headers: {
82
+ Authorization: `Bearer ${this.apiKey}`,
83
+ Accept: stream ? "text/event-stream" : "application/json",
84
+ ...(body === undefined ? {} : { "Content-Type": "application/json" }),
85
+ },
86
+ body: body === undefined ? undefined : JSON.stringify(body),
87
+ signal: controller.signal,
88
+ });
89
+ if (!res.ok) {
90
+ let payload = {};
91
+ try {
92
+ payload = (await res.json());
93
+ }
94
+ catch {
95
+ // A proxy error page is not JSON; the status still tells the story.
96
+ }
97
+ throw new MeasyAIError(res.status, payload);
98
+ }
99
+ return stream ? res : (await res.json());
100
+ }
101
+ finally {
102
+ if (timer !== undefined)
103
+ clearTimeout(timer);
104
+ }
105
+ }
106
+ }
107
+ class ChatResource {
108
+ client;
109
+ constructor(client) {
110
+ this.client = client;
111
+ }
112
+ /** One-shot completion. */
113
+ async create(params) {
114
+ return (await this.client.request("/v1/chat/completions", {
115
+ method: "POST",
116
+ body: { ...params, stream: false },
117
+ }));
118
+ }
119
+ /** Streams the reply, yielding text deltas as they arrive. */
120
+ async *stream(params, options = {}) {
121
+ for await (const chunk of this.streamChunks(params, options)) {
122
+ const delta = chunk.choices[0]?.delta?.content;
123
+ if (delta)
124
+ yield delta;
125
+ }
126
+ }
127
+ /** Streams raw chunks, for callers that need finish reasons or usage. */
128
+ async *streamChunks(params, options = {}) {
129
+ const res = (await this.client.request("/v1/chat/completions", {
130
+ method: "POST",
131
+ body: { ...params, stream: true },
132
+ signal: options.signal,
133
+ stream: true,
134
+ }));
135
+ if (!res.body) {
136
+ throw new Error("MeasyAI: the response carried no body to stream");
137
+ }
138
+ const reader = res.body.getReader();
139
+ const decoder = new TextDecoder();
140
+ let buffer = "";
141
+ try {
142
+ while (true) {
143
+ const { done, value } = await reader.read();
144
+ if (done)
145
+ break;
146
+ buffer += decoder.decode(value, { stream: true });
147
+ // Events are separated by a blank line. A partial event stays in
148
+ // the buffer until the rest of it arrives.
149
+ const events = buffer.split("\n\n");
150
+ buffer = events.pop() ?? "";
151
+ for (const event of events) {
152
+ for (const line of event.split("\n")) {
153
+ if (!line.startsWith("data:"))
154
+ continue;
155
+ const data = line.slice(5).trim();
156
+ if (data === "[DONE]")
157
+ return;
158
+ if (!data)
159
+ continue;
160
+ try {
161
+ yield JSON.parse(data);
162
+ }
163
+ catch {
164
+ // Skip a frame we cannot parse rather than killing the stream.
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+ finally {
171
+ // Releases the connection when a consumer breaks out of the loop early.
172
+ await reader.cancel().catch(() => { });
173
+ }
174
+ }
175
+ }
176
+ class BatchResource {
177
+ client;
178
+ constructor(client) {
179
+ this.client = client;
180
+ }
181
+ async create(requests) {
182
+ return (await this.client.request("/v1/batches", {
183
+ method: "POST",
184
+ body: { endpoint: "/v1/chat/completions", requests },
185
+ }));
186
+ }
187
+ async retrieve(batchId) {
188
+ return (await this.client.request(`/v1/batches/${batchId}`));
189
+ }
190
+ async list(limit = 20) {
191
+ return (await this.client.request(`/v1/batches?limit=${limit}`));
192
+ }
193
+ /** Polls until the batch closes. */
194
+ async waitUntilComplete(batchId, { intervalMs = 5_000, timeoutMs = 3_600_000 } = {}) {
195
+ const deadline = Date.now() + timeoutMs;
196
+ for (;;) {
197
+ const batch = await this.retrieve(batchId);
198
+ if (batch.status === "completed" || batch.status === "failed" || batch.status === "canceled") {
199
+ return batch;
200
+ }
201
+ if (Date.now() > deadline) {
202
+ throw new Error(`MeasyAI: batch ${batchId} did not finish within ${timeoutMs}ms`);
203
+ }
204
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
205
+ }
206
+ }
207
+ }
208
+ class ModelResource {
209
+ client;
210
+ constructor(client) {
211
+ this.client = client;
212
+ }
213
+ async list() {
214
+ return (await this.client.request("/v1/models"));
215
+ }
216
+ }
217
+ /**
218
+ * Verifies a webhook signature.
219
+ *
220
+ * Compute over the **raw** request body — re-serializing parsed JSON will
221
+ * not reproduce the same bytes and the check will fail.
222
+ *
223
+ * ```ts
224
+ * const valid = await verifyWebhook({
225
+ * secret: process.env.MEASYAI_WEBHOOK_SECRET!,
226
+ * signature: req.headers["x-measyai-signature"],
227
+ * timestamp: req.headers["x-measyai-timestamp"],
228
+ * rawBody,
229
+ * });
230
+ * ```
231
+ */
232
+ export async function verifyWebhook({ secret, signature, timestamp, rawBody, toleranceSeconds = 300, }) {
233
+ const sent = Number.parseInt(timestamp, 10);
234
+ if (!Number.isFinite(sent))
235
+ return false;
236
+ // Reject stale deliveries: without this, a captured request could be
237
+ // replayed forever with its original, still-valid signature.
238
+ if (Math.abs(Date.now() / 1000 - sent) > toleranceSeconds)
239
+ return false;
240
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
241
+ const mac = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`${sent}.${rawBody}`));
242
+ const expected = "v1=" +
243
+ Array.from(new Uint8Array(mac))
244
+ .map((b) => b.toString(16).padStart(2, "0"))
245
+ .join("");
246
+ return timingSafeEqual(expected, signature);
247
+ }
248
+ /** Constant-time string comparison — a fast `!==` leaks the signature byte by byte. */
249
+ function timingSafeEqual(a, b) {
250
+ if (a.length !== b.length)
251
+ return false;
252
+ let diff = 0;
253
+ for (let i = 0; i < a.length; i++) {
254
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
255
+ }
256
+ return diff === 0;
257
+ }
258
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@measyai/sdk",
3
+ "version": "2.0.0",
4
+ "description": "Typed TypeScript client for the MeasyAI API — OpenAI-compatible chat completions, streaming, batches and webhook verification.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "./dist/cjs/index.js",
8
+ "module": "./dist/esm/index.js",
9
+ "types": "./dist/esm/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/esm/index.d.ts",
13
+ "import": "./dist/esm/index.js",
14
+ "require": "./dist/cjs/index.js",
15
+ "default": "./dist/esm/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "scripts": {
25
+ "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
26
+ "build:esm": "tsc -p tsconfig.build.json",
27
+ "build:cjs": "tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json',JSON.stringify({type:'commonjs'}))\"",
28
+ "build": "npm run clean && npm run build:esm && npm run build:cjs",
29
+ "typecheck": "tsc -p tsconfig.build.json --noEmit",
30
+ "prepublishOnly": "npm run build"
31
+ },
32
+ "keywords": [
33
+ "measyai",
34
+ "ai",
35
+ "llm",
36
+ "chat",
37
+ "streaming",
38
+ "openai-compatible",
39
+ "api-client"
40
+ ],
41
+ "homepage": "https://docs.measyai.com",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/measyai/measyai.git",
45
+ "directory": "sdk/typescript"
46
+ },
47
+ "bugs": {
48
+ "url": "https://github.com/measyai/measyai/issues"
49
+ },
50
+ "license": "MIT",
51
+ "engines": {
52
+ "node": ">=18"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ },
57
+ "devDependencies": {
58
+ "typescript": "^5.7.3"
59
+ }
60
+ }