@company786/meridian-blue-sdk 0.1.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/README.md ADDED
@@ -0,0 +1,378 @@
1
+ # @meridian-blue-SDK
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@company786/meridian-blue-sdk)](https://www.npmjs.com/package/@company786/meridian-blue-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org/)
6
+
7
+ Official TypeScript/JavaScript SDK for the **MeridianBlue API** — a unified AI proxy that routes your requests across multiple providers (OpenAI, Groq, Mistral, and more) through a single API key, with automatic fallback, billing, and rate limiting built in.
8
+
9
+ ---
10
+
11
+ ## Table of Contents
12
+
13
+ - [Features](#features)
14
+ - [Requirements](#requirements)
15
+ - [Installation](#installation)
16
+ - [Quick Start](#quick-start)
17
+ - [Configuration](#configuration)
18
+ - [Chat Completions](#chat-completions)
19
+ - [Basic Usage](#basic-usage)
20
+ - [With System Prompt](#with-system-prompt)
21
+ - [With Parameters](#with-parameters)
22
+ - [Multi-turn Conversation](#multi-turn-conversation)
23
+ - [Response Shape](#response-shape)
24
+ - [Error Handling](#error-handling)
25
+ - [Error Classes](#error-classes)
26
+ - [Full Error Handling Example](#full-error-handling-example)
27
+ - [TypeScript Support](#typescript-support)
28
+ - [How It Works](#how-it-works)
29
+ - [Contributing](#contributing)
30
+ - [License](#license)
31
+
32
+ ---
33
+
34
+ ## Features
35
+
36
+ - ✅ **Single API key** — access OpenAI, Groq, Mistral, and more through one key
37
+ - ✅ **Automatic fallback** — if your primary provider fails, the next one picks up silently
38
+ - ✅ **Built-in billing** — every response includes cost and balance information
39
+ - ✅ **TypeScript-first** — full type definitions included.
40
+ - ✅ **Typed errors** — every HTTP error maps to a specific error class
41
+ - ✅ **Lightweight** — single dependency (axios)
42
+
43
+ ---
44
+
45
+ ## Requirements
46
+
47
+ - Node.js **18.0.0** or higher
48
+ - An MeridianBlue API key (`kp_live_...`)
49
+
50
+ ---
51
+
52
+ ## Installation
53
+
54
+ ```bash
55
+ # npm
56
+ npm install @company786/meridian-blue-sdk
57
+
58
+ # yarn
59
+ yarn add @company786/meridian-blue-sdk
60
+
61
+ # pnpm
62
+ pnpm add @company786/meridian-blue-sdk
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quick Start
68
+
69
+ ```typescript
70
+ import { MeridianBlue } from '@company786/meridian-blue-sdk';
71
+
72
+ const meridianBlue = new MeridianBlue({
73
+ apiKey: 'kp_live_your_key_here',
74
+ });
75
+
76
+ const response = await meridianBlue.chat.completions({
77
+ slug: 'omni/gpt-4o',
78
+ messages: [
79
+ { role: 'user', content: 'What is the capital of Pakistan?' }
80
+ ],
81
+ });
82
+
83
+ console.log(response.choices[0].message.content);
84
+ // → "The capital of Pakistan is Islamabad."
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Configuration
90
+
91
+ Create an `MeridianBlue` instance with your configuration:
92
+
93
+ ```typescript
94
+ import { MeridianBlue } from '@company786/meridian-blue-sdk';
95
+
96
+ const meridianBlue = new MeridianBlue({
97
+ apiKey: 'kp_live_...', // Required — your MeridianBlue API key
98
+ baseUrl: 'https://...', // Optional — defaults to https://api.omniprompt.dev
99
+ timeout: 30000, // Optional — request timeout in ms (default: 30000)
100
+ });
101
+ ```
102
+
103
+ ### Configuration Options
104
+
105
+ | Option | Type | Required | Default | Description |
106
+ |--------|------|----------|---------|-------------|
107
+ | `apiKey` | `string` | ✅ Yes | — | Your `kp_live_` API key |
108
+ | `baseUrl` | `string` | No | `https://api.omniprompt.dev` | MeridianBlue server URL |
109
+ | `timeout` | `number` | No | `30000` | Request timeout in milliseconds |
110
+
111
+ ---
112
+
113
+ ## Chat Completions
114
+
115
+ ### Basic Usage
116
+
117
+ ```typescript
118
+ const response = await meridianBlue.chat.completions({
119
+ slug: 'omni/gpt-4o',
120
+ messages: [
121
+ { role: 'user', content: 'Hello!' }
122
+ ],
123
+ });
124
+
125
+ console.log(response.choices[0].message.content);
126
+ ```
127
+
128
+ ### With System Prompt
129
+
130
+ ```typescript
131
+ const response = await meridianBlue.chat.completions({
132
+ slug: 'omni/gpt-4o',
133
+ messages: [
134
+ { role: 'system', content: 'You are a helpful coding assistant.' },
135
+ { role: 'user', content: 'Write a function to reverse a string in Python.' },
136
+ ],
137
+ });
138
+ ```
139
+
140
+ ### With Parameters
141
+
142
+ ```typescript
143
+ const response = await meridianBlue.chat.completions({
144
+ slug: 'omni/gpt-4o',
145
+ messages: [
146
+ { role: 'user', content: 'Write a short poem about the ocean.' }
147
+ ],
148
+ temperature: 0.9, // 0.0 – 2.0 — higher = more creative
149
+ max_tokens: 200, // limit response length
150
+ });
151
+ ```
152
+
153
+ ### Multi-turn Conversation
154
+
155
+ ```typescript
156
+ const messages = [
157
+ { role: 'system', content: 'You are a helpful assistant.' },
158
+ { role: 'user', content: 'My name is Ali.' },
159
+ ];
160
+
161
+ const first = await meridianBlue.chat.completions({ slug: 'omni/gpt-4o', messages });
162
+
163
+ // Append assistant reply and continue the conversation
164
+ messages.push(first.choices[0].message);
165
+ messages.push({ role: 'user', content: 'What is my name?' });
166
+
167
+ const second = await meridianBlue.chat.completions({ slug: 'omni/gpt-4o', messages });
168
+ console.log(second.choices[0].message.content);
169
+ // → "Your name is Ali."
170
+ ```
171
+
172
+ ### Response Shape
173
+
174
+ Every `chat.completions()` call returns a `ChatCompletionResponse`:
175
+
176
+ ```typescript
177
+ {
178
+ id: "64f3a...", // Conversation ID for debugging
179
+ model: "omni/gpt-4o", // The slug that was routed
180
+
181
+ choices: [
182
+ {
183
+ index: 0,
184
+ message: {
185
+ role: "assistant",
186
+ content: "The capital of Pakistan is Islamabad."
187
+ },
188
+ finish_reason: "stop"
189
+ }
190
+ ],
191
+
192
+ usage: {
193
+ prompt_tokens: 49,
194
+ completion_tokens: 8,
195
+ total_tokens: 57
196
+ },
197
+
198
+ billing: {
199
+ cost: 0.0024, // Credits deducted for this request
200
+ balanceAfter: 997.9976, // Your credit balance after this request
201
+ isFallback: false, // true if a fallback provider was used
202
+ latencyMs: 1243 // Total request latency in milliseconds
203
+ }
204
+ }
205
+ ```
206
+
207
+ #### `billing.isFallback`
208
+
209
+ When `isFallback: true` it means your primary provider (e.g. OpenAI) failed and MeridianBlue automatically retried with the next available provider (e.g. Groq). Your request succeeded — this is informational only.
210
+
211
+ ---
212
+
213
+ ## Error Handling
214
+
215
+ The SDK maps every HTTP error to a specific typed class so you can handle them precisely.
216
+
217
+ ### Error Classes
218
+
219
+ | Class | HTTP Status | When it's thrown |
220
+ |-------|-------------|-----------------|
221
+ | `AuthenticationError` | 401 | API key is missing, malformed, or invalid |
222
+ | `InsufficientBalanceError` | 402 | Credit balance is at or below the debt limit (-$10.00) |
223
+ | `PermissionError` | 403 | API key has been revoked |
224
+ | `NotFoundError` | 404 | The requested slug doesn't exist |
225
+ | `RateLimitError` | 429 | Too many requests — check `retryAfterSeconds` |
226
+ | `APIError` | 500 | Server error or all providers exhausted |
227
+ | `MeridianBlueError` | any | Base class — all errors extend this |
228
+
229
+ ### Error Properties
230
+
231
+ ```typescript
232
+ // All errors have:
233
+ error.message // Human-readable description
234
+ error.status // HTTP status code
235
+ error.code // Machine-readable code string
236
+
237
+ // InsufficientBalanceError also has:
238
+ error.currentBalance // number — your current credit balance
239
+ error.debtLimit // number — the limit (e.g. -1000)
240
+
241
+ // RateLimitError also has:
242
+ error.retryAfterSeconds // number — seconds until you can retry
243
+ ```
244
+
245
+ ### Full Error Handling Example
246
+
247
+ ```typescript
248
+ import {
249
+ MeridianBlue,
250
+ AuthenticationError,
251
+ InsufficientBalanceError,
252
+ PermissionError,
253
+ NotFoundError,
254
+ RateLimitError,
255
+ APIError,
256
+ } from '@company786/meridian-blue-sdk';
257
+
258
+ const meridianBlue = new MeridianBlue({ apiKey: 'kp_live_...' });
259
+
260
+ try {
261
+ const response = await meridianBlue.chat.completions({
262
+ slug: 'omni/gpt-4o',
263
+ messages: [{ role: 'user', content: 'Hello' }],
264
+ });
265
+
266
+ console.log(response.choices[0].message.content);
267
+
268
+ } catch (error) {
269
+ if (error instanceof AuthenticationError) {
270
+ // Invalid or missing API key
271
+ console.error('Check your API key:', error.message);
272
+
273
+ } else if (error instanceof InsufficientBalanceError) {
274
+ // Out of credits
275
+ console.error(`Out of credits.`);
276
+ console.error(`Current balance: ${error.currentBalance}`);
277
+ console.error(`Debt limit: ${error.debtLimit}`);
278
+ // → Redirect user to top-up page
279
+
280
+ } else if (error instanceof RateLimitError) {
281
+ // Too many requests
282
+ console.error(`Rate limited. Retry in ${error.retryAfterSeconds} seconds.`);
283
+ // → Implement exponential backoff
284
+
285
+ } else if (error instanceof NotFoundError) {
286
+ // Wrong slug
287
+ console.error('Model slug not found:', error.message);
288
+
289
+ } else if (error instanceof PermissionError) {
290
+ // Key revoked
291
+ console.error('API key has been revoked.');
292
+
293
+ } else if (error instanceof APIError) {
294
+ // Server-side failure
295
+ console.error('Server error:', error.message);
296
+
297
+ } else {
298
+ // Unknown error — rethrow
299
+ throw error;
300
+ }
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ## TypeScript Support
307
+
308
+ The SDK is written in TypeScript and ships with full type definitions. No `@types/` package needed.
309
+
310
+ ```typescript
311
+ import type {
312
+ MeridianBlueConfig,
313
+ ChatMessage,
314
+ ChatRole,
315
+ ChatCompletionRequest,
316
+ ChatCompletionResponse,
317
+ ChatChoice,
318
+ ChatUsage,
319
+ ChatBilling,
320
+ } from '@company786/meridian-blue-sdk';
321
+
322
+ // All types are available for use in your own code
323
+ const messages: ChatMessage[] = [
324
+ { role: 'user' as ChatRole, content: 'Hello' }
325
+ ];
326
+
327
+ const request: ChatCompletionRequest = {
328
+ slug: 'omni/gpt-4o',
329
+ messages,
330
+ temperature: 0.7,
331
+ };
332
+ ```
333
+
334
+ ---
335
+
336
+ ## How It Works
337
+
338
+ ```
339
+ Your Application
340
+
341
+ │ meridianBlue.chat.completions({ slug: 'omni/gpt-4o', ... })
342
+
343
+ @company786/meridian-blue-sdk
344
+ - Attaches your kp_live_ key as Bearer token
345
+ - POST /api/v1/chat/completions
346
+
347
+
348
+ MeridianBlue Server
349
+ - Validates your API key
350
+ - Checks your credit balance
351
+ - Routes request to the best available provider
352
+ - On failure → automatically retries with fallback provider
353
+ - Deducts credits and logs the transaction
354
+
355
+
356
+ AI Provider (OpenAI / Groq / Mistral / ...)
357
+
358
+
359
+ Response flows back through MeridianBlue → SDK → Your App
360
+ ```
361
+
362
+ Your API key never touches the AI providers directly. All routing, fallbacks, and billing happen on the MeridianBlue server.
363
+
364
+ ---
365
+
366
+ ## Contributing
367
+
368
+ 1. Fork the repository
369
+ 2. Create a feature branch: `git checkout -b feat/your-feature`
370
+ 3. Make your changes
371
+ 4. Build: `npm run build`
372
+ 5. Submit a pull request
373
+
374
+ ---
375
+
376
+ ## License
377
+
378
+ MIT © MeridianBlue
@@ -0,0 +1,9 @@
1
+ import { Chat } from "./resources/chat.js";
2
+ import type { MeridianBlueConfig } from "./types/requests.js";
3
+ export declare class MeridianBlue {
4
+ /** Chat completions resource */
5
+ readonly chat: Chat;
6
+ private readonly http;
7
+ constructor(config: MeridianBlueConfig);
8
+ }
9
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAe9D,qBAAa,YAAY;IACvB,gCAAgC;IAChC,SAAgB,IAAI,EAAE,IAAI,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;gBAEzB,MAAM,EAAE,kBAAkB;CA0DvC"}
package/dist/client.js ADDED
@@ -0,0 +1,52 @@
1
+ import axios, { isAxiosError } from "axios";
2
+ import { Chat } from "./resources/chat.js";
3
+ import { APIError, AuthenticationError, InsufficientBalanceError, NotFoundError, MeridianBlueError, PermissionError, RateLimitError, } from "./errors.js";
4
+ const DEFAULT_BASE_URL = "http://localhost:3000";
5
+ // const DEFAULT_BASE_URL = "https://api.meridian-blue.dev";
6
+ const DEFAULT_TIMEOUT = 30000;
7
+ export class MeridianBlue {
8
+ constructor(config) {
9
+ if (!config.apiKey) {
10
+ throw new AuthenticationError("apiKey is required. Pass it as: new MeridianBlue({ apiKey: 'kp_live_...' })");
11
+ }
12
+ this.http = axios.create({
13
+ baseURL: config.baseUrl ?? DEFAULT_BASE_URL,
14
+ timeout: config.timeout ?? DEFAULT_TIMEOUT,
15
+ headers: {
16
+ Authorization: `Bearer ${config.apiKey}`,
17
+ "Content-Type": "application/json",
18
+ "User-Agent": "@meridian-blue/sdk",
19
+ },
20
+ });
21
+ // ── Response interceptor: map HTTP errors to typed SDK errors ────────────
22
+ this.http.interceptors.response.use((res) => res, (error) => {
23
+ if (isAxiosError(error) && error.response) {
24
+ const { status, data, headers } = error.response;
25
+ const message = data?.error ?? error.message;
26
+ switch (status) {
27
+ case 401:
28
+ throw new AuthenticationError(message);
29
+ case 402:
30
+ throw new InsufficientBalanceError(message, data?.currentBalance, data?.debtLimit);
31
+ case 403:
32
+ throw new PermissionError(message);
33
+ case 404:
34
+ throw new NotFoundError(message);
35
+ case 429: {
36
+ const retryAfter = headers["retry-after"]
37
+ ? parseInt(headers["retry-after"], 10)
38
+ : undefined;
39
+ throw new RateLimitError(message, retryAfter);
40
+ }
41
+ default:
42
+ throw new APIError(message);
43
+ }
44
+ }
45
+ // Network error or no response
46
+ const msg = error instanceof Error ? error.message : "Unknown network error";
47
+ throw new MeridianBlueError(msg, 0, "NETWORK_ERROR");
48
+ });
49
+ this.chat = new Chat(this.http);
50
+ }
51
+ }
52
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAsB,YAAY,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAE3C,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,wBAAwB,EACxB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD,4DAA4D;AAC5D,MAAM,eAAe,GAAG,KAAM,CAAC;AAE/B,MAAM,OAAO,YAAY;IAMvB,YAAY,MAA0B;QACpC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,IAAI,mBAAmB,CAC3B,6EAA6E,CAC9E,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,gBAAgB;YAC3C,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe;YAC1C,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;gBACxC,cAAc,EAAE,kBAAkB;gBAClC,YAAY,EAAE,oBAAoB;aACnC;SACF,CAAC,CAAC;QAEH,4EAA4E;QAC5E,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CACjC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EACZ,CAAC,KAAc,EAAE,EAAE;YACjB,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC1C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,QAAQ,CAAC;gBACjD,MAAM,OAAO,GACV,IAA2B,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC;gBAEvD,QAAQ,MAAM,EAAE,CAAC;oBACf,KAAK,GAAG;wBACN,MAAM,IAAI,mBAAmB,CAAC,OAAO,CAAC,CAAC;oBACzC,KAAK,GAAG;wBACN,MAAM,IAAI,wBAAwB,CAChC,OAAO,EACN,IAAoC,EAAE,cAAc,EACpD,IAA+B,EAAE,SAAS,CAC5C,CAAC;oBACJ,KAAK,GAAG;wBACN,MAAM,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;oBACrC,KAAK,GAAG;wBACN,MAAM,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;oBACnC,KAAK,GAAG,CAAC,CAAC,CAAC;wBACT,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;4BACvC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAW,EAAE,EAAE,CAAC;4BAChD,CAAC,CAAC,SAAS,CAAC;wBACd,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;oBAChD,CAAC;oBACD;wBACE,MAAM,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC;YACD,+BAA+B;YAC/B,MAAM,GAAG,GACP,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;YACnE,MAAM,IAAI,iBAAiB,CAAC,GAAG,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC;QACvD,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Base error class for all MeridianBlue SDK errors.
3
+ * Always check `error.status` to handle specific HTTP error codes.
4
+ */
5
+ export declare class MeridianBlueError extends Error {
6
+ readonly status: number;
7
+ readonly code?: string;
8
+ constructor(message: string, status: number, code?: string);
9
+ }
10
+ /** 401 — API key missing or malformed */
11
+ export declare class AuthenticationError extends MeridianBlueError {
12
+ constructor(message?: string);
13
+ }
14
+ /** 402 — Credit balance below the debt limit */
15
+ export declare class InsufficientBalanceError extends MeridianBlueError {
16
+ readonly currentBalance?: number;
17
+ readonly debtLimit?: number;
18
+ constructor(message: string, currentBalance?: number, debtLimit?: number);
19
+ }
20
+ /** 403 — API key revoked */
21
+ export declare class PermissionError extends MeridianBlueError {
22
+ constructor(message?: string);
23
+ }
24
+ /** 404 — Resource not found (e.g. unknown slug) */
25
+ export declare class NotFoundError extends MeridianBlueError {
26
+ constructor(message: string);
27
+ }
28
+ /** 429 — Rate limit exceeded */
29
+ export declare class RateLimitError extends MeridianBlueError {
30
+ readonly retryAfterSeconds?: number;
31
+ constructor(message: string, retryAfterSeconds?: number);
32
+ }
33
+ /** 500 — Server or all-providers failure */
34
+ export declare class APIError extends MeridianBlueError {
35
+ constructor(message: string);
36
+ }
37
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAM3D;AAED,yCAAyC;AACzC,qBAAa,mBAAoB,SAAQ,iBAAiB;gBAC5C,OAAO,SAAgC;CAIpD;AAED,gDAAgD;AAChD,qBAAa,wBAAyB,SAAQ,iBAAiB;IAC7D,SAAgB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxC,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAC;gBAGjC,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM;CAOrB;AAED,4BAA4B;AAC5B,qBAAa,eAAgB,SAAQ,iBAAiB;gBACxC,OAAO,SAA8B;CAIlD;AAED,mDAAmD;AACnD,qBAAa,aAAc,SAAQ,iBAAiB;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED,gCAAgC;AAChC,qBAAa,cAAe,SAAQ,iBAAiB;IACnD,SAAgB,iBAAiB,CAAC,EAAE,MAAM,CAAC;gBAE/B,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM;CAKxD;AAED,4CAA4C;AAC5C,qBAAa,QAAS,SAAQ,iBAAiB;gBACjC,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Base error class for all MeridianBlue SDK errors.
3
+ * Always check `error.status` to handle specific HTTP error codes.
4
+ */
5
+ export class MeridianBlueError extends Error {
6
+ constructor(message, status, code) {
7
+ super(message);
8
+ this.name = "MeridianBlueError";
9
+ this.status = status;
10
+ this.code = code;
11
+ }
12
+ }
13
+ /** 401 — API key missing or malformed */
14
+ export class AuthenticationError extends MeridianBlueError {
15
+ constructor(message = "Invalid or missing API key.") {
16
+ super(message, 401, "AUTHENTICATION_ERROR");
17
+ this.name = "AuthenticationError";
18
+ }
19
+ }
20
+ /** 402 — Credit balance below the debt limit */
21
+ export class InsufficientBalanceError extends MeridianBlueError {
22
+ constructor(message, currentBalance, debtLimit) {
23
+ super(message, 402, "INSUFFICIENT_BALANCE");
24
+ this.name = "InsufficientBalanceError";
25
+ this.currentBalance = currentBalance;
26
+ this.debtLimit = debtLimit;
27
+ }
28
+ }
29
+ /** 403 — API key revoked */
30
+ export class PermissionError extends MeridianBlueError {
31
+ constructor(message = "API key has been revoked.") {
32
+ super(message, 403, "PERMISSION_ERROR");
33
+ this.name = "PermissionError";
34
+ }
35
+ }
36
+ /** 404 — Resource not found (e.g. unknown slug) */
37
+ export class NotFoundError extends MeridianBlueError {
38
+ constructor(message) {
39
+ super(message, 404, "NOT_FOUND");
40
+ this.name = "NotFoundError";
41
+ }
42
+ }
43
+ /** 429 — Rate limit exceeded */
44
+ export class RateLimitError extends MeridianBlueError {
45
+ constructor(message, retryAfterSeconds) {
46
+ super(message, 429, "RATE_LIMIT_EXCEEDED");
47
+ this.name = "RateLimitError";
48
+ this.retryAfterSeconds = retryAfterSeconds;
49
+ }
50
+ }
51
+ /** 500 — Server or all-providers failure */
52
+ export class APIError extends MeridianBlueError {
53
+ constructor(message) {
54
+ super(message, 500, "API_ERROR");
55
+ this.name = "APIError";
56
+ }
57
+ }
58
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAI1C,YAAY,OAAe,EAAE,MAAc,EAAE,IAAa;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,yCAAyC;AACzC,MAAM,OAAO,mBAAoB,SAAQ,iBAAiB;IACxD,YAAY,OAAO,GAAG,6BAA6B;QACjD,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,sBAAsB,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,gDAAgD;AAChD,MAAM,OAAO,wBAAyB,SAAQ,iBAAiB;IAI7D,YACE,OAAe,EACf,cAAuB,EACvB,SAAkB;QAElB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,sBAAsB,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,4BAA4B;AAC5B,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IACpD,YAAY,OAAO,GAAG,2BAA2B;QAC/C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,mDAAmD;AACnD,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,gCAAgC;AAChC,MAAM,OAAO,cAAe,SAAQ,iBAAiB;IAGnD,YAAY,OAAe,EAAE,iBAA0B;QACrD,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,qBAAqB,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;IAC7C,CAAC;CACF;AAED,4CAA4C;AAC5C,MAAM,OAAO,QAAS,SAAQ,iBAAiB;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,5 @@
1
+ export { MeridianBlue } from "./client.js";
2
+ export { MeridianBlueError, AuthenticationError, InsufficientBalanceError, PermissionError, NotFoundError, RateLimitError, APIError, } from "./errors.js";
3
+ export type { MeridianBlueConfig, ChatRole, ChatMessage, ChatCompletionRequest, } from "./types/requests.js";
4
+ export type { ChatChoice, ChatUsage, ChatBilling, ChatCompletionResponse, } from "./types/responses.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,kBAAkB,EAClB,QAAQ,EACR,WAAW,EACX,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,sBAAsB,GACvB,MAAM,sBAAsB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // Main client
2
+ export { MeridianBlue } from "./client.js";
3
+ // Error classes — export so users can do `catch (e) { if (e instanceof RateLimitError) }`
4
+ export { MeridianBlueError, AuthenticationError, InsufficientBalanceError, PermissionError, NotFoundError, RateLimitError, APIError, } from "./errors.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,0FAA0F;AAC1F,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { AxiosInstance } from "axios";
2
+ import type { ChatCompletionRequest } from "../types/requests.js";
3
+ import type { ChatCompletionResponse } from "../types/responses.js";
4
+ export declare class Chat {
5
+ private readonly http;
6
+ constructor(http: AxiosInstance);
7
+ /**
8
+ * Send a chat completion request through the MeridianBlue proxy.
9
+ *
10
+ * @example
11
+ * const response = await meridianBlue.chat.completions({
12
+ * slug: 'meridian-blue/gpt-4o',
13
+ * messages: [{ role: 'user', content: 'Hello!' }],
14
+ * });
15
+ * console.log(response.choices[0].message.content);
16
+ * console.log(`Cost: ${response.billing.cost} credits`);
17
+ */
18
+ completions(request: ChatCompletionRequest): Promise<ChatCompletionResponse>;
19
+ }
20
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/resources/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,aAAa;IAEhD;;;;;;;;;;OAUG;IACU,WAAW,CACtB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,sBAAsB,CAAC;CAOnC"}
@@ -0,0 +1,21 @@
1
+ export class Chat {
2
+ constructor(http) {
3
+ this.http = http;
4
+ }
5
+ /**
6
+ * Send a chat completion request through the MeridianBlue proxy.
7
+ *
8
+ * @example
9
+ * const response = await meridianBlue.chat.completions({
10
+ * slug: 'meridian-blue/gpt-4o',
11
+ * messages: [{ role: 'user', content: 'Hello!' }],
12
+ * });
13
+ * console.log(response.choices[0].message.content);
14
+ * console.log(`Cost: ${response.billing.cost} credits`);
15
+ */
16
+ async completions(request) {
17
+ const response = await this.http.post("/api/v1/chat/completions", request);
18
+ return response.data;
19
+ }
20
+ }
21
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/resources/chat.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,IAAI;IACf,YAA6B,IAAmB;QAAnB,SAAI,GAAJ,IAAI,CAAe;IAAG,CAAC;IAEpD;;;;;;;;;;OAUG;IACI,KAAK,CAAC,WAAW,CACtB,OAA8B;QAE9B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CACnC,0BAA0B,EAC1B,OAAO,CACR,CAAC;QACF,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ export interface MeridianBlueConfig {
2
+ /** Your kp_live_ API key */
3
+ apiKey: string;
4
+ /**
5
+ * Base URL of your MeridianBlue server.
6
+ * Defaults to https://api.meridian-blue.dev if not provided.
7
+ */
8
+ baseUrl?: string;
9
+ /** Request timeout in milliseconds. Defaults to 30000 (30s). */
10
+ timeout?: number;
11
+ }
12
+ export type ChatRole = "user" | "assistant" | "system";
13
+ export interface ChatMessage {
14
+ role: ChatRole;
15
+ content: string;
16
+ }
17
+ export interface ChatCompletionRequest {
18
+ /** The MeridianBlue model slug e.g. "omni/gpt-4o" */
19
+ slug: string;
20
+ messages: ChatMessage[];
21
+ temperature?: number;
22
+ max_tokens?: number;
23
+ [key: string]: unknown;
24
+ }
25
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEvD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
@@ -0,0 +1,3 @@
1
+ // ── SDK Configuration ──────────────────────────────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=requests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../src/types/requests.ts"],"names":[],"mappings":"AAAA,kFAAkF"}
@@ -0,0 +1,31 @@
1
+ import { ChatMessage } from "./requests.js";
2
+ export interface ChatChoice {
3
+ message: ChatMessage;
4
+ finish_reason?: string;
5
+ index: number;
6
+ }
7
+ export interface ChatUsage {
8
+ prompt_tokens: number;
9
+ completion_tokens: number;
10
+ total_tokens: number;
11
+ }
12
+ export interface ChatBilling {
13
+ /** Credits deducted for this request */
14
+ cost: number;
15
+ /** Your credit balance after this request */
16
+ balanceAfter: number;
17
+ /** True if a fallback provider was used instead of the primary */
18
+ isFallback: boolean;
19
+ /** Total request latency in milliseconds */
20
+ latencyMs: number;
21
+ }
22
+ export interface ChatCompletionResponse {
23
+ /** Conversation ID for debugging and usage logs */
24
+ id: string;
25
+ /** The slug that was routed e.g. "meridian-blue/gpt-4o" */
26
+ model: string;
27
+ choices: ChatChoice[];
28
+ usage: ChatUsage;
29
+ billing: ChatBilling;
30
+ }
31
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/types/responses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAI5C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,UAAU,EAAE,OAAO,CAAC;IACpB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,WAAW,CAAC;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/types/responses.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@company786/meridian-blue-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Official TypeScript/JavaScript SDK for the Meridian-Blue API",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "dev": "tsc --watch",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "meridian-blue",
24
+ "ai",
25
+ "llm",
26
+ "sdk",
27
+ "openai",
28
+ "groq",
29
+ "mistral"
30
+ ],
31
+ "author": "Meridian Blue",
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "axios": "^1.7.0"
35
+ },
36
+ "devDependencies": {
37
+ "typescript": "^5.4.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=18.0.0"
41
+ }
42
+ }