@modelrelay/sdk 0.2.0 → 0.4.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 +108 -26
- package/dist/index.cjs +644 -275
- package/dist/index.d.cts +354 -92
- package/dist/index.d.ts +354 -92
- package/dist/index.js +626 -272
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ModelRelay TypeScript SDK
|
|
2
2
|
|
|
3
|
-
Typed client for
|
|
3
|
+
Typed client for Node.js that wraps the ModelRelay API for **consuming** LLM/usage endpoints. Use secret API keys or bearer tokens issued by your backend; publishable-key frontend token flows have been removed.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -14,21 +14,12 @@ bun add @modelrelay/sdk
|
|
|
14
14
|
```ts
|
|
15
15
|
import { ModelRelay } from "@modelrelay/sdk";
|
|
16
16
|
|
|
17
|
-
// Use a
|
|
17
|
+
// Use a secret key or bearer token from your backend.
|
|
18
18
|
const mr = new ModelRelay({
|
|
19
|
-
key: "
|
|
20
|
-
endUser: { id: "user-123" } // required when using publishable keys
|
|
19
|
+
key: "mr_sk_..."
|
|
21
20
|
});
|
|
22
21
|
|
|
23
|
-
//
|
|
24
|
-
await mr.billing.checkout({
|
|
25
|
-
endUserId: "user-123",
|
|
26
|
-
planId: "pro-plan",
|
|
27
|
-
successUrl: window.location.origin + "/success",
|
|
28
|
-
cancelUrl: window.location.origin + "/cancel"
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// 2. Stream chat completions (publishable keys are exchanged for a frontend token automatically).
|
|
22
|
+
// Stream chat completions.
|
|
32
23
|
const stream = await mr.chat.completions.create({
|
|
33
24
|
model: "grok-4-1-fast-reasoning",
|
|
34
25
|
messages: [{ role: "user", content: "Hello" }]
|
|
@@ -41,18 +32,9 @@ for await (const event of stream) {
|
|
|
41
32
|
}
|
|
42
33
|
```
|
|
43
34
|
|
|
44
|
-
### Manual frontend token exchange
|
|
45
|
-
|
|
46
|
-
If you need to mint the token yourself (e.g., to store in your app state):
|
|
47
|
-
|
|
48
|
-
```ts
|
|
49
|
-
const token = await mr.auth.frontendToken({ userId: "user-123" });
|
|
50
|
-
const chat = new ModelRelay({ token: token.token });
|
|
51
|
-
```
|
|
52
|
-
|
|
53
35
|
### Server-side usage
|
|
54
36
|
|
|
55
|
-
Provide a secret API key or bearer token
|
|
37
|
+
Provide a secret API key or bearer token:
|
|
56
38
|
|
|
57
39
|
```ts
|
|
58
40
|
const mr = new ModelRelay({ key: "mr_sk_..." });
|
|
@@ -72,15 +54,115 @@ console.log(completion.content.join(""));
|
|
|
72
54
|
|
|
73
55
|
- **Environments**: `environment: "production" | "staging" | "sandbox"` or override `baseUrl`.
|
|
74
56
|
- **Auth**: pass a secret/publishable `key` or a bearer `token`. Publishable keys mint frontend tokens automatically.
|
|
75
|
-
- **Timeouts & retries**: `timeoutMs` (default 60s
|
|
57
|
+
- **Timeouts & retries**: `connectTimeoutMs` (default 5s per attempt) and `timeoutMs` (default 60s overall; set `0` to disable). Per-call overrides available on `chat.completions.create`. `retry` config (`{ maxAttempts, baseBackoffMs, maxBackoffMs, retryPost }` or `false`) controls exponential backoff with jitter.
|
|
76
58
|
- **Headers & metadata**: `defaultHeaders` are sent with every request; `defaultMetadata` merges into every chat request and can be overridden per-call via `metadata`.
|
|
77
59
|
- **Client header**: set `clientHeader` to override the telemetry header (defaults to `modelrelay-ts/<version>`).
|
|
78
60
|
|
|
61
|
+
### Timeouts & retry examples
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// Shorten connect + request timeouts globally
|
|
65
|
+
const mr = new ModelRelay({
|
|
66
|
+
key: "mr_sk_...",
|
|
67
|
+
connectTimeoutMs: 3_000,
|
|
68
|
+
timeoutMs: 20_000,
|
|
69
|
+
retry: { maxAttempts: 4, baseBackoffMs: 200, maxBackoffMs: 2_000 }
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Per-call overrides (blocking)
|
|
73
|
+
await mr.chat.completions.create(
|
|
74
|
+
{ model: "grok-4-1-fast-reasoning", messages: [{ role: "user", content: "Hi" }], stream: false },
|
|
75
|
+
{ timeoutMs: 5_000, retry: false }
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// Streaming: keep connect timeout but disable request timeout
|
|
79
|
+
const stream = await mr.chat.completions.create(
|
|
80
|
+
{ model: "grok-4-1-fast-reasoning", messages: [{ role: "user", content: "Hi" }] },
|
|
81
|
+
{ connectTimeoutMs: 2_000 } // request timeout is already disabled for streams by default
|
|
82
|
+
);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Typed models, providers, and stop reasons
|
|
86
|
+
|
|
87
|
+
- Models and providers use string literal unions with an `Other` escape hatch: pass `{ other: "my-provider" }` or `{ other: "custom/model-x" }` to preserve custom IDs while benefiting from autocomplete on known values (e.g., `Models.OpenAIGpt4o`, `Providers.Anthropic`).
|
|
88
|
+
- Stop reasons are parsed into the `StopReason` union (e.g., `StopReasons.EndTurn`); unknown values surface as `{ other: "<raw>" }`.
|
|
89
|
+
- Usage backfills `totalTokens` when providers omit it, ensuring consistent accounting.
|
|
90
|
+
|
|
91
|
+
### Telemetry & metrics hooks
|
|
92
|
+
|
|
93
|
+
Provide lightweight callbacks to observe latency and usage without extra deps:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const calls: string[] = [];
|
|
97
|
+
const mr = new ModelRelay({
|
|
98
|
+
key: "mr_sk_...",
|
|
99
|
+
metrics: {
|
|
100
|
+
httpRequest: (m) => calls.push(`http ${m.context.path} ${m.status} ${m.latencyMs}ms`),
|
|
101
|
+
streamFirstToken: (m) => calls.push(`first-token ${m.latencyMs}ms`),
|
|
102
|
+
usage: (m) => calls.push(`usage ${m.usage.totalTokens}`)
|
|
103
|
+
},
|
|
104
|
+
trace: {
|
|
105
|
+
streamEvent: ({ event }) => calls.push(`event ${event.type}`),
|
|
106
|
+
requestFinish: ({ status, latencyMs }) => calls.push(`finished ${status} in ${latencyMs}`)
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Per-call overrides
|
|
111
|
+
await mr.chat.completions.create(
|
|
112
|
+
{ model: "echo-1", messages: [{ role: "user", content: "hi" }] },
|
|
113
|
+
{ metrics: { usage: console.log }, trace: { streamEvent: console.debug } }
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Error categories
|
|
118
|
+
|
|
119
|
+
- **ConfigError**: missing key/token, invalid base URL, or request validation issues.
|
|
120
|
+
- **TransportError**: network/connect/request/timeout failures (`kind` is one of `connect | timeout | request | other`), includes retry metadata when retries were attempted.
|
|
121
|
+
- **APIError**: Non-2xx responses with `status`, `code`, `fields`, `requestId`, and optional `retries` metadata.
|
|
122
|
+
|
|
79
123
|
## API surface
|
|
80
124
|
|
|
81
|
-
- `auth.frontendToken()` — exchange publishable keys for short-lived frontend tokens (cached until expiry).
|
|
82
125
|
- `chat.completions.create(params, options?)`
|
|
83
126
|
- Supports streaming (default) or blocking JSON (`stream: false`).
|
|
84
127
|
- Accepts per-call `requestId`, `headers`, `metadata`, `timeoutMs`, and `retry` overrides.
|
|
85
|
-
- `billing.checkout()` — start an end-user Stripe Checkout session.
|
|
86
128
|
- `apiKeys.list() | create() | delete(id)` — manage API keys when using secret keys or bearer tokens.
|
|
129
|
+
- `customers` — manage customers with a secret key (see below).
|
|
130
|
+
|
|
131
|
+
## Backend Customer Management
|
|
132
|
+
|
|
133
|
+
Use a secret key (`mr_sk_*`) to manage customers from your backend:
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { ModelRelay } from "@modelrelay/sdk";
|
|
137
|
+
|
|
138
|
+
const mr = new ModelRelay({ key: "mr_sk_..." });
|
|
139
|
+
|
|
140
|
+
// Create or update a customer (upsert by external_id)
|
|
141
|
+
const customer = await mr.customers.upsert({
|
|
142
|
+
tier_id: "your-tier-uuid",
|
|
143
|
+
external_id: "github-user-12345", // your app's user ID
|
|
144
|
+
email: "user@example.com",
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// List all customers
|
|
148
|
+
const customers = await mr.customers.list();
|
|
149
|
+
|
|
150
|
+
// Get a specific customer
|
|
151
|
+
const customer = await mr.customers.get("customer-uuid");
|
|
152
|
+
|
|
153
|
+
// Create a checkout session for subscription billing
|
|
154
|
+
const session = await mr.customers.createCheckoutSession("customer-uuid", {
|
|
155
|
+
success_url: "https://myapp.com/billing/success",
|
|
156
|
+
cancel_url: "https://myapp.com/billing/cancel",
|
|
157
|
+
});
|
|
158
|
+
// Redirect user to session.url to complete payment
|
|
159
|
+
|
|
160
|
+
// Check subscription status
|
|
161
|
+
const status = await mr.customers.getSubscription("customer-uuid");
|
|
162
|
+
if (status.active) {
|
|
163
|
+
// Grant access
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Delete a customer
|
|
167
|
+
await mr.customers.delete("customer-uuid");
|
|
168
|
+
```
|