@modelrelay/sdk 1.3.1 → 1.3.3
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 +145 -218
- package/dist/index.cjs +61 -38
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +61 -38
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,220 +1,40 @@
|
|
|
1
1
|
# ModelRelay TypeScript SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
bun add @modelrelay/sdk
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
## Token Providers (Automatic Bearer Auth)
|
|
8
|
-
|
|
9
|
-
Use token providers when you want the SDK to automatically obtain/refresh **bearer tokens** for data-plane calls like `/responses` and `/runs`.
|
|
10
|
-
|
|
11
|
-
### OIDC id_token → customer bearer token (exchange)
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { ModelRelay, OIDCExchangeTokenProvider, parseSecretKey } from "@modelrelay/sdk";
|
|
15
|
-
|
|
16
|
-
const tokenProvider = new OIDCExchangeTokenProvider({
|
|
17
|
-
apiKey: parseSecretKey(process.env.MODELRELAY_API_KEY!),
|
|
18
|
-
idTokenProvider: async () => {
|
|
19
|
-
// Return an OIDC id_token from your auth system (web login, device flow, etc).
|
|
20
|
-
return process.env.OIDC_ID_TOKEN!;
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const mr = new ModelRelay({ tokenProvider });
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
If you need an `id_token` in a CLI-like context, you can use the OAuth device flow helper:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
import { runOAuthDeviceFlowForIDToken } from "@modelrelay/sdk";
|
|
31
|
-
|
|
32
|
-
const idToken = await runOAuthDeviceFlowForIDToken({
|
|
33
|
-
deviceAuthorizationEndpoint: "https://issuer.example.com/oauth/device/code",
|
|
34
|
-
tokenEndpoint: "https://issuer.example.com/oauth/token",
|
|
35
|
-
clientId: "your-client-id",
|
|
36
|
-
scope: "openid email profile",
|
|
37
|
-
onUserCode: ({ verificationUri, userCode }) => {
|
|
38
|
-
console.log(`Open ${verificationUri} and enter code: ${userCode}`);
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Secret key → customer bearer token (mint)
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
import { CustomerTokenProvider, ModelRelay } from "@modelrelay/sdk";
|
|
47
|
-
|
|
48
|
-
const tokenProvider = new CustomerTokenProvider({
|
|
49
|
-
secretKey: process.env.MODELRELAY_API_KEY!,
|
|
50
|
-
request: { projectId: "proj_...", customerId: "cust_..." },
|
|
51
|
-
});
|
|
3
|
+
The ModelRelay TypeScript SDK is a **responses-first**, **streaming-first** client for building cross-provider LLM features without committing to any single vendor API.
|
|
52
4
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```ts
|
|
59
|
-
import { ModelRelay } from "@modelrelay/sdk";
|
|
60
|
-
|
|
61
|
-
const mr = ModelRelay.fromSecretKey("mr_sk_...");
|
|
62
|
-
|
|
63
|
-
const req = mr.responses
|
|
64
|
-
.new()
|
|
65
|
-
.model("claude-sonnet-4-20250514")
|
|
66
|
-
.user("Hello")
|
|
67
|
-
.build();
|
|
68
|
-
|
|
69
|
-
const stream = await mr.responses.stream(req);
|
|
5
|
+
It's designed to feel great in TypeScript:
|
|
6
|
+
- One fluent builder for **streaming/non-streaming**, **text/structured**, and **customer-attributed** requests
|
|
7
|
+
- Structured outputs powered by Zod schemas with validation and retry
|
|
8
|
+
- A practical tool-use toolkit for "LLM + tools" apps
|
|
70
9
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
10
|
+
```bash
|
|
11
|
+
npm install @modelrelay/sdk
|
|
12
|
+
# or
|
|
13
|
+
bun add @modelrelay/sdk
|
|
76
14
|
```
|
|
77
15
|
|
|
78
|
-
##
|
|
16
|
+
## Quick Start
|
|
79
17
|
|
|
80
18
|
```ts
|
|
81
19
|
import { ModelRelay } from "@modelrelay/sdk";
|
|
82
20
|
|
|
83
|
-
const mr = ModelRelay.fromSecretKey(
|
|
84
|
-
const customer = mr.forCustomer("cust_abc123");
|
|
21
|
+
const mr = ModelRelay.fromSecretKey(process.env.MODELRELAY_API_KEY!);
|
|
85
22
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
23
|
+
const response = await mr.responses.create(
|
|
24
|
+
mr.responses
|
|
25
|
+
.new()
|
|
26
|
+
.model("claude-sonnet-4-20250514")
|
|
27
|
+
.system("Answer concisely.")
|
|
28
|
+
.user("Write one line about TypeScript.")
|
|
29
|
+
.build()
|
|
89
30
|
);
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
You can also stream structured JSON for a specific customer:
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
import { z } from "zod";
|
|
96
|
-
import { ModelRelay, outputFormatFromZod } from "@modelrelay/sdk";
|
|
97
31
|
|
|
98
|
-
|
|
99
|
-
const customer = mr.forCustomer("cust_abc123");
|
|
100
|
-
|
|
101
|
-
const schema = z.object({
|
|
102
|
-
summary: z.string(),
|
|
103
|
-
highlights: z.array(z.string()),
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
const req = customer.responses
|
|
107
|
-
.new()
|
|
108
|
-
.outputFormat(outputFormatFromZod(schema))
|
|
109
|
-
.system("You are a helpful assistant.")
|
|
110
|
-
.user("Summarize Q4 results")
|
|
111
|
-
.build();
|
|
112
|
-
|
|
113
|
-
const stream = await customer.responses.streamJSON<z.infer<typeof schema>>(req);
|
|
114
|
-
for await (const event of stream) {
|
|
115
|
-
if (event.type === "completion") {
|
|
116
|
-
console.log(event.value);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
You can also pass a single object to `textForCustomer`:
|
|
122
|
-
|
|
123
|
-
```ts
|
|
124
|
-
const text = await mr.responses.textForCustomer({
|
|
125
|
-
customerId: "cust_abc123",
|
|
126
|
-
system: "You are a helpful assistant.",
|
|
127
|
-
user: "Summarize Q4 results",
|
|
128
|
-
});
|
|
32
|
+
console.log(response.text());
|
|
129
33
|
```
|
|
130
34
|
|
|
131
|
-
## Workflow Runs (workflow.v0)
|
|
132
|
-
|
|
133
|
-
```ts
|
|
134
|
-
import {
|
|
135
|
-
ModelRelay,
|
|
136
|
-
type LLMResponsesBindingV0,
|
|
137
|
-
parseNodeId,
|
|
138
|
-
parseOutputName,
|
|
139
|
-
parseSecretKey,
|
|
140
|
-
workflowV0,
|
|
141
|
-
} from "@modelrelay/sdk";
|
|
142
|
-
|
|
143
|
-
const mr = new ModelRelay({ key: parseSecretKey("mr_sk_...") });
|
|
144
|
-
|
|
145
|
-
const spec = workflowV0()
|
|
146
|
-
.name("multi_agent_v0_example")
|
|
147
|
-
.execution({ max_parallelism: 3, node_timeout_ms: 20_000, run_timeout_ms: 30_000 })
|
|
148
|
-
.llmResponses(parseNodeId("agent_a"), {
|
|
149
|
-
model: "claude-sonnet-4-20250514",
|
|
150
|
-
input: [
|
|
151
|
-
{ type: "message", role: "system", content: [{ type: "text", text: "You are Agent A." }] },
|
|
152
|
-
{ type: "message", role: "user", content: [{ type: "text", text: "Write 3 ideas for a landing page." }] },
|
|
153
|
-
],
|
|
154
|
-
})
|
|
155
|
-
.llmResponses(parseNodeId("agent_b"), {
|
|
156
|
-
model: "claude-sonnet-4-20250514",
|
|
157
|
-
input: [
|
|
158
|
-
{ type: "message", role: "system", content: [{ type: "text", text: "You are Agent B." }] },
|
|
159
|
-
{ type: "message", role: "user", content: [{ type: "text", text: "Write 3 objections a user might have." }] },
|
|
160
|
-
],
|
|
161
|
-
})
|
|
162
|
-
.llmResponses(parseNodeId("agent_c"), {
|
|
163
|
-
model: "claude-sonnet-4-20250514",
|
|
164
|
-
input: [
|
|
165
|
-
{ type: "message", role: "system", content: [{ type: "text", text: "You are Agent C." }] },
|
|
166
|
-
{ type: "message", role: "user", content: [{ type: "text", text: "Write 3 alternative headlines." }] },
|
|
167
|
-
],
|
|
168
|
-
})
|
|
169
|
-
.joinAll(parseNodeId("join"))
|
|
170
|
-
.llmResponses(
|
|
171
|
-
parseNodeId("aggregate"),
|
|
172
|
-
{
|
|
173
|
-
model: "claude-sonnet-4-20250514",
|
|
174
|
-
input: [
|
|
175
|
-
{
|
|
176
|
-
type: "message",
|
|
177
|
-
role: "system",
|
|
178
|
-
content: [{ type: "text", text: "Synthesize the best answer from the following agent outputs (JSON)." }],
|
|
179
|
-
},
|
|
180
|
-
{ type: "message", role: "user", content: [{ type: "text", text: "" }] }, // overwritten by bindings
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
// Bind the join output into the aggregator prompt (fan-in).
|
|
185
|
-
bindings: [
|
|
186
|
-
{
|
|
187
|
-
from: parseNodeId("join"),
|
|
188
|
-
to: "/input/1/content/0/text",
|
|
189
|
-
encoding: "json_string",
|
|
190
|
-
} satisfies LLMResponsesBindingV0,
|
|
191
|
-
],
|
|
192
|
-
},
|
|
193
|
-
)
|
|
194
|
-
.edge(parseNodeId("agent_a"), parseNodeId("join"))
|
|
195
|
-
.edge(parseNodeId("agent_b"), parseNodeId("join"))
|
|
196
|
-
.edge(parseNodeId("agent_c"), parseNodeId("join"))
|
|
197
|
-
.edge(parseNodeId("join"), parseNodeId("aggregate"))
|
|
198
|
-
.output(parseOutputName("result"), parseNodeId("aggregate"))
|
|
199
|
-
.build();
|
|
200
|
-
|
|
201
|
-
const { run_id } = await mr.runs.create(spec);
|
|
202
|
-
|
|
203
|
-
const events = await mr.runs.events(run_id);
|
|
204
|
-
for await (const ev of events) {
|
|
205
|
-
if (ev.type === "run_completed") {
|
|
206
|
-
const status = await mr.runs.get(run_id);
|
|
207
|
-
console.log("outputs:", status.outputs);
|
|
208
|
-
console.log("cost_summary:", status.cost_summary);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
See the full example in `sdk/ts/examples/workflows_multi_agent.ts`.
|
|
214
|
-
|
|
215
35
|
## Chat-Like Text Helpers
|
|
216
36
|
|
|
217
|
-
For the most common path (**system + user → assistant text**):
|
|
37
|
+
For the most common path (**system + user → assistant text**), use the built-in convenience:
|
|
218
38
|
|
|
219
39
|
```ts
|
|
220
40
|
const text = await mr.responses.text(
|
|
@@ -228,14 +48,16 @@ console.log(text);
|
|
|
228
48
|
For customer-attributed requests where the backend selects the model:
|
|
229
49
|
|
|
230
50
|
```ts
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
"
|
|
234
|
-
"
|
|
51
|
+
const customer = mr.forCustomer("customer-123");
|
|
52
|
+
const text = await customer.responses.text(
|
|
53
|
+
"You are a helpful assistant.",
|
|
54
|
+
"Summarize Q4 results",
|
|
235
55
|
);
|
|
236
56
|
```
|
|
237
57
|
|
|
238
|
-
|
|
58
|
+
## Streaming
|
|
59
|
+
|
|
60
|
+
Stream text deltas for real-time output:
|
|
239
61
|
|
|
240
62
|
```ts
|
|
241
63
|
const deltas = await mr.responses.streamTextDeltas(
|
|
@@ -248,14 +70,31 @@ for await (const delta of deltas) {
|
|
|
248
70
|
}
|
|
249
71
|
```
|
|
250
72
|
|
|
73
|
+
For full control, stream typed events:
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
const req = mr.responses
|
|
77
|
+
.new()
|
|
78
|
+
.model("claude-sonnet-4-20250514")
|
|
79
|
+
.user("Hello")
|
|
80
|
+
.build();
|
|
81
|
+
|
|
82
|
+
const stream = await mr.responses.stream(req);
|
|
83
|
+
|
|
84
|
+
for await (const event of stream) {
|
|
85
|
+
if (event.type === "message_delta" && event.textDelta) {
|
|
86
|
+
process.stdout.write(event.textDelta);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
251
91
|
## Structured Outputs with Zod
|
|
252
92
|
|
|
93
|
+
Get typed, validated responses from the model:
|
|
94
|
+
|
|
253
95
|
```ts
|
|
254
|
-
import { ModelRelay, parseSecretKey } from "@modelrelay/sdk";
|
|
255
96
|
import { z } from "zod";
|
|
256
97
|
|
|
257
|
-
const mr = new ModelRelay({ key: parseSecretKey("mr_sk_...") });
|
|
258
|
-
|
|
259
98
|
const Person = z.object({
|
|
260
99
|
name: z.string(),
|
|
261
100
|
age: z.number(),
|
|
@@ -270,16 +109,11 @@ const result = await mr.responses.structured(
|
|
|
270
109
|
console.log(result.value); // { name: "John Doe", age: 30 }
|
|
271
110
|
```
|
|
272
111
|
|
|
273
|
-
|
|
112
|
+
### Streaming Structured Outputs
|
|
274
113
|
|
|
275
114
|
Build progressive UIs that render fields as they complete:
|
|
276
115
|
|
|
277
116
|
```ts
|
|
278
|
-
import { ModelRelay, parseSecretKey } from "@modelrelay/sdk";
|
|
279
|
-
import { z } from "zod";
|
|
280
|
-
|
|
281
|
-
const mr = new ModelRelay({ key: parseSecretKey("mr_sk_...") });
|
|
282
|
-
|
|
283
117
|
const Article = z.object({
|
|
284
118
|
title: z.string(),
|
|
285
119
|
summary: z.string(),
|
|
@@ -292,15 +126,12 @@ const stream = await mr.responses.streamStructured(
|
|
|
292
126
|
);
|
|
293
127
|
|
|
294
128
|
for await (const event of stream) {
|
|
295
|
-
// Render fields as soon as they're complete
|
|
296
129
|
if (event.completeFields.has("title")) {
|
|
297
130
|
renderTitle(event.payload.title); // Safe to display
|
|
298
131
|
}
|
|
299
132
|
if (event.completeFields.has("summary")) {
|
|
300
133
|
renderSummary(event.payload.summary);
|
|
301
134
|
}
|
|
302
|
-
|
|
303
|
-
// Show streaming preview of incomplete fields
|
|
304
135
|
if (!event.completeFields.has("body")) {
|
|
305
136
|
renderBodyPreview(event.payload.body + "▋");
|
|
306
137
|
}
|
|
@@ -309,7 +140,7 @@ for await (const event of stream) {
|
|
|
309
140
|
|
|
310
141
|
## Customer-Attributed Requests
|
|
311
142
|
|
|
312
|
-
For metered billing, use `customerId()
|
|
143
|
+
For metered billing, use `customerId()`. The customer's tier determines the model, so `model()` can be omitted:
|
|
313
144
|
|
|
314
145
|
```ts
|
|
315
146
|
const req = mr.responses
|
|
@@ -321,6 +152,16 @@ const req = mr.responses
|
|
|
321
152
|
const stream = await mr.responses.stream(req);
|
|
322
153
|
```
|
|
323
154
|
|
|
155
|
+
Or use the convenience method:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const text = await mr.responses.textForCustomer(
|
|
159
|
+
"customer-123",
|
|
160
|
+
"Answer concisely.",
|
|
161
|
+
"Say hi.",
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
324
165
|
## Customer Management (Backend)
|
|
325
166
|
|
|
326
167
|
```ts
|
|
@@ -341,6 +182,92 @@ const session = await mr.customers.createCheckoutSession(customer.id, {
|
|
|
341
182
|
const status = await mr.customers.getSubscription(customer.id);
|
|
342
183
|
```
|
|
343
184
|
|
|
185
|
+
## Workflow Runs
|
|
186
|
+
|
|
187
|
+
Build multi-agent workflows with parallel execution:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import { workflowV0, parseNodeId, parseOutputName, type LLMResponsesBindingV0 } from "@modelrelay/sdk";
|
|
191
|
+
|
|
192
|
+
const spec = workflowV0()
|
|
193
|
+
.name("multi_agent_example")
|
|
194
|
+
.execution({ max_parallelism: 3, node_timeout_ms: 20_000, run_timeout_ms: 30_000 })
|
|
195
|
+
.llmResponses(parseNodeId("agent_a"), {
|
|
196
|
+
model: "claude-sonnet-4-20250514",
|
|
197
|
+
input: [
|
|
198
|
+
{ type: "message", role: "system", content: [{ type: "text", text: "You are Agent A." }] },
|
|
199
|
+
{ type: "message", role: "user", content: [{ type: "text", text: "Analyze the question." }] },
|
|
200
|
+
],
|
|
201
|
+
})
|
|
202
|
+
.llmResponses(parseNodeId("agent_b"), {
|
|
203
|
+
model: "claude-sonnet-4-20250514",
|
|
204
|
+
input: [
|
|
205
|
+
{ type: "message", role: "system", content: [{ type: "text", text: "You are Agent B." }] },
|
|
206
|
+
{ type: "message", role: "user", content: [{ type: "text", text: "Find edge cases." }] },
|
|
207
|
+
],
|
|
208
|
+
})
|
|
209
|
+
.joinAll(parseNodeId("join"))
|
|
210
|
+
.llmResponses(
|
|
211
|
+
parseNodeId("aggregate"),
|
|
212
|
+
{
|
|
213
|
+
model: "claude-sonnet-4-20250514",
|
|
214
|
+
input: [
|
|
215
|
+
{ type: "message", role: "system", content: [{ type: "text", text: "Synthesize the best answer." }] },
|
|
216
|
+
{ type: "message", role: "user", content: [{ type: "text", text: "" }] },
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
bindings: [
|
|
221
|
+
{ from: parseNodeId("join"), to: "/input/1/content/0/text", encoding: "json_string" } satisfies LLMResponsesBindingV0,
|
|
222
|
+
],
|
|
223
|
+
},
|
|
224
|
+
)
|
|
225
|
+
.edge(parseNodeId("agent_a"), parseNodeId("join"))
|
|
226
|
+
.edge(parseNodeId("agent_b"), parseNodeId("join"))
|
|
227
|
+
.edge(parseNodeId("join"), parseNodeId("aggregate"))
|
|
228
|
+
.output(parseOutputName("result"), parseNodeId("aggregate"))
|
|
229
|
+
.build();
|
|
230
|
+
|
|
231
|
+
const { run_id } = await mr.runs.create(spec);
|
|
232
|
+
|
|
233
|
+
for await (const ev of await mr.runs.events(run_id)) {
|
|
234
|
+
if (ev.type === "run_completed") {
|
|
235
|
+
const status = await mr.runs.get(run_id);
|
|
236
|
+
console.log("outputs:", status.outputs);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Token Providers (Advanced)
|
|
242
|
+
|
|
243
|
+
For automatic bearer token management in data-plane calls:
|
|
244
|
+
|
|
245
|
+
### Secret key → customer bearer token
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
import { CustomerTokenProvider, ModelRelay } from "@modelrelay/sdk";
|
|
249
|
+
|
|
250
|
+
const tokenProvider = new CustomerTokenProvider({
|
|
251
|
+
secretKey: process.env.MODELRELAY_API_KEY!,
|
|
252
|
+
request: { projectId: "proj_...", customerId: "cust_..." },
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
const mr = new ModelRelay({ tokenProvider });
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### OIDC exchange
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
import { ModelRelay, OIDCExchangeTokenProvider, parseSecretKey } from "@modelrelay/sdk";
|
|
262
|
+
|
|
263
|
+
const tokenProvider = new OIDCExchangeTokenProvider({
|
|
264
|
+
apiKey: parseSecretKey(process.env.MODELRELAY_API_KEY!),
|
|
265
|
+
idTokenProvider: async () => process.env.OIDC_ID_TOKEN!,
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const mr = new ModelRelay({ tokenProvider });
|
|
269
|
+
```
|
|
270
|
+
|
|
344
271
|
## Configuration
|
|
345
272
|
|
|
346
273
|
```ts
|
package/dist/index.cjs
CHANGED
|
@@ -818,7 +818,7 @@ function isTokenReusable(token) {
|
|
|
818
818
|
// package.json
|
|
819
819
|
var package_default = {
|
|
820
820
|
name: "@modelrelay/sdk",
|
|
821
|
-
version: "1.3.
|
|
821
|
+
version: "1.3.3",
|
|
822
822
|
description: "TypeScript SDK for the ModelRelay API",
|
|
823
823
|
type: "module",
|
|
824
824
|
main: "dist/index.cjs",
|
|
@@ -850,6 +850,9 @@ var package_default = {
|
|
|
850
850
|
],
|
|
851
851
|
author: "Shane Vitarana",
|
|
852
852
|
license: "Apache-2.0",
|
|
853
|
+
dependencies: {
|
|
854
|
+
"fast-json-patch": "^3.1.1"
|
|
855
|
+
},
|
|
853
856
|
devDependencies: {
|
|
854
857
|
"openapi-typescript": "^7.4.4",
|
|
855
858
|
tsup: "^8.2.4",
|
|
@@ -2042,8 +2045,11 @@ function mapNDJSONResponseEvent(line, requestId) {
|
|
|
2042
2045
|
const model = normalizeModelId(parsed.model);
|
|
2043
2046
|
const stopReason = normalizeStopReason(parsed.stop_reason);
|
|
2044
2047
|
let textDelta;
|
|
2045
|
-
if (
|
|
2046
|
-
textDelta = parsed.
|
|
2048
|
+
if (recordType2 === "update" && typeof parsed.delta === "string") {
|
|
2049
|
+
textDelta = parsed.delta;
|
|
2050
|
+
}
|
|
2051
|
+
if (recordType2 === "completion" && typeof parsed.content === "string") {
|
|
2052
|
+
textDelta = parsed.content;
|
|
2047
2053
|
}
|
|
2048
2054
|
const toolCallDelta = extractToolCallDelta(parsed, type);
|
|
2049
2055
|
const toolCalls = extractToolCalls(parsed, type);
|
|
@@ -2143,6 +2149,7 @@ function normalizeToolCalls(toolCalls) {
|
|
|
2143
2149
|
}
|
|
2144
2150
|
|
|
2145
2151
|
// src/responses_stream.ts
|
|
2152
|
+
var import_fast_json_patch = require("fast-json-patch");
|
|
2146
2153
|
var ResponsesStream = class {
|
|
2147
2154
|
constructor(response, requestId, context, metrics, trace, timeouts = {}, startedAtMs = Date.now()) {
|
|
2148
2155
|
this.firstTokenEmitted = false;
|
|
@@ -2269,6 +2276,9 @@ var ResponsesStream = class {
|
|
|
2269
2276
|
if (evt.type === "message_stop") {
|
|
2270
2277
|
stopReason = evt.stopReason;
|
|
2271
2278
|
usage = evt.usage;
|
|
2279
|
+
if (evt.textDelta) {
|
|
2280
|
+
text = evt.textDelta;
|
|
2281
|
+
}
|
|
2272
2282
|
const raw2 = isRecord(evt.data) ? evt.data : {};
|
|
2273
2283
|
citations = normalizeCitations(raw2.citations) ?? citations;
|
|
2274
2284
|
}
|
|
@@ -2344,6 +2354,7 @@ var StructuredJSONStream = class {
|
|
|
2344
2354
|
this.closed = false;
|
|
2345
2355
|
this.sawTerminal = false;
|
|
2346
2356
|
this.firstContentSeen = false;
|
|
2357
|
+
this.currentPayload = {};
|
|
2347
2358
|
if (!response.body) {
|
|
2348
2359
|
throw new ConfigError("streaming response is missing a body");
|
|
2349
2360
|
}
|
|
@@ -2487,9 +2498,36 @@ var StructuredJSONStream = class {
|
|
|
2487
2498
|
}
|
|
2488
2499
|
this.firstContentSeen = true;
|
|
2489
2500
|
const completeFieldsArray = Array.isArray(parsed.complete_fields) ? parsed.complete_fields.filter((f) => typeof f === "string") : [];
|
|
2501
|
+
let payload;
|
|
2502
|
+
if (rawType === "update") {
|
|
2503
|
+
const patch = Array.isArray(parsed.patch) ? parsed.patch : null;
|
|
2504
|
+
if (!patch) {
|
|
2505
|
+
throw new TransportError("structured stream update missing patch", {
|
|
2506
|
+
kind: "request"
|
|
2507
|
+
});
|
|
2508
|
+
}
|
|
2509
|
+
try {
|
|
2510
|
+
const applied = (0, import_fast_json_patch.applyPatch)(this.currentPayload, patch, false, true);
|
|
2511
|
+
this.currentPayload = applied.newDocument;
|
|
2512
|
+
payload = this.currentPayload;
|
|
2513
|
+
} catch (err) {
|
|
2514
|
+
throw new TransportError("failed to apply structured patch", {
|
|
2515
|
+
kind: "request",
|
|
2516
|
+
cause: err
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
} else {
|
|
2520
|
+
if (parsed.payload === void 0) {
|
|
2521
|
+
throw new TransportError("structured stream completion missing payload", {
|
|
2522
|
+
kind: "request"
|
|
2523
|
+
});
|
|
2524
|
+
}
|
|
2525
|
+
this.currentPayload = parsed.payload;
|
|
2526
|
+
payload = this.currentPayload;
|
|
2527
|
+
}
|
|
2490
2528
|
return {
|
|
2491
2529
|
type: rawType,
|
|
2492
|
-
payload
|
|
2530
|
+
payload,
|
|
2493
2531
|
requestId: this.requestId,
|
|
2494
2532
|
completeFields: new Set(completeFieldsArray)
|
|
2495
2533
|
};
|
|
@@ -2599,6 +2637,7 @@ async function readWithTimeout(readPromise, next, onTimeout) {
|
|
|
2599
2637
|
}
|
|
2600
2638
|
|
|
2601
2639
|
// src/responses_client.ts
|
|
2640
|
+
var RESPONSES_STREAM_ACCEPT = 'application/x-ndjson; profile="responses-stream/v2"';
|
|
2602
2641
|
var ResponsesClient = class {
|
|
2603
2642
|
constructor(http, auth, cfg = {}) {
|
|
2604
2643
|
this.http = http;
|
|
@@ -2638,24 +2677,16 @@ var ResponsesClient = class {
|
|
|
2638
2677
|
const stream = await this.stream(req, options);
|
|
2639
2678
|
return {
|
|
2640
2679
|
async *[Symbol.asyncIterator]() {
|
|
2641
|
-
let
|
|
2680
|
+
let sawDelta = false;
|
|
2642
2681
|
try {
|
|
2643
2682
|
for await (const evt of stream) {
|
|
2644
|
-
if (
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
accumulated = next;
|
|
2652
|
-
} else {
|
|
2653
|
-
delta = next;
|
|
2654
|
-
accumulated += next;
|
|
2655
|
-
}
|
|
2656
|
-
if (delta) {
|
|
2657
|
-
yield delta;
|
|
2658
|
-
}
|
|
2683
|
+
if (evt.type === "message_delta" && evt.textDelta) {
|
|
2684
|
+
sawDelta = true;
|
|
2685
|
+
yield evt.textDelta;
|
|
2686
|
+
}
|
|
2687
|
+
if (evt.type === "message_stop" && evt.textDelta && !sawDelta) {
|
|
2688
|
+
sawDelta = true;
|
|
2689
|
+
yield evt.textDelta;
|
|
2659
2690
|
}
|
|
2660
2691
|
}
|
|
2661
2692
|
} finally {
|
|
@@ -2673,24 +2704,16 @@ var ResponsesClient = class {
|
|
|
2673
2704
|
const stream = await this.stream(req, args.options ?? options);
|
|
2674
2705
|
return {
|
|
2675
2706
|
async *[Symbol.asyncIterator]() {
|
|
2676
|
-
let
|
|
2707
|
+
let sawDelta = false;
|
|
2677
2708
|
try {
|
|
2678
2709
|
for await (const evt of stream) {
|
|
2679
|
-
if (
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
accumulated = next;
|
|
2687
|
-
} else {
|
|
2688
|
-
delta = next;
|
|
2689
|
-
accumulated += next;
|
|
2690
|
-
}
|
|
2691
|
-
if (delta) {
|
|
2692
|
-
yield delta;
|
|
2693
|
-
}
|
|
2710
|
+
if (evt.type === "message_delta" && evt.textDelta) {
|
|
2711
|
+
sawDelta = true;
|
|
2712
|
+
yield evt.textDelta;
|
|
2713
|
+
}
|
|
2714
|
+
if (evt.type === "message_stop" && evt.textDelta && !sawDelta) {
|
|
2715
|
+
sawDelta = true;
|
|
2716
|
+
yield evt.textDelta;
|
|
2694
2717
|
}
|
|
2695
2718
|
}
|
|
2696
2719
|
} finally {
|
|
@@ -2789,7 +2812,7 @@ var ResponsesClient = class {
|
|
|
2789
2812
|
headers,
|
|
2790
2813
|
apiKey: authHeaders.apiKey,
|
|
2791
2814
|
accessToken: authHeaders.accessToken,
|
|
2792
|
-
accept:
|
|
2815
|
+
accept: RESPONSES_STREAM_ACCEPT,
|
|
2793
2816
|
raw: true,
|
|
2794
2817
|
signal: merged.signal,
|
|
2795
2818
|
timeoutMs: merged.timeoutMs ?? 0,
|
|
@@ -2869,7 +2892,7 @@ var ResponsesClient = class {
|
|
|
2869
2892
|
headers,
|
|
2870
2893
|
apiKey: authHeaders.apiKey,
|
|
2871
2894
|
accessToken: authHeaders.accessToken,
|
|
2872
|
-
accept:
|
|
2895
|
+
accept: RESPONSES_STREAM_ACCEPT,
|
|
2873
2896
|
raw: true,
|
|
2874
2897
|
signal: merged.signal,
|
|
2875
2898
|
timeoutMs: merged.timeoutMs ?? 0,
|
package/dist/index.d.cts
CHANGED
|
@@ -1668,6 +1668,7 @@ declare class StructuredJSONStream<T> implements AsyncIterable<StructuredJSONEve
|
|
|
1668
1668
|
private closed;
|
|
1669
1669
|
private sawTerminal;
|
|
1670
1670
|
private firstContentSeen;
|
|
1671
|
+
private currentPayload;
|
|
1671
1672
|
constructor(response: globalThis.Response, requestId: string | undefined, context: RequestContext, _metrics?: MetricsCallbacks, trace?: TraceCallbacks, timeouts?: StreamTimeoutsMs, startedAtMs?: number);
|
|
1672
1673
|
cancel(reason?: unknown): Promise<void>;
|
|
1673
1674
|
[Symbol.asyncIterator](): AsyncIterator<StructuredJSONEvent<T>>;
|
|
@@ -3405,9 +3406,25 @@ interface components {
|
|
|
3405
3406
|
/** @description Sources from web search results */
|
|
3406
3407
|
citations?: components["schemas"]["Citation"][];
|
|
3407
3408
|
};
|
|
3409
|
+
JSONPatchOperation: {
|
|
3410
|
+
/** @enum {string} */
|
|
3411
|
+
op: "add" | "remove" | "replace" | "move" | "copy" | "test";
|
|
3412
|
+
path: string;
|
|
3413
|
+
from?: string;
|
|
3414
|
+
value?: {
|
|
3415
|
+
[key: string]: unknown;
|
|
3416
|
+
};
|
|
3417
|
+
};
|
|
3408
3418
|
ResponsesStreamEnvelope: {
|
|
3409
3419
|
/** @enum {string} */
|
|
3410
3420
|
type: "start" | "update" | "completion" | "error" | "keepalive" | "tool_use_start" | "tool_use_delta" | "tool_use_stop";
|
|
3421
|
+
/** @enum {string} */
|
|
3422
|
+
stream_mode?: "text-delta" | "structured-patch";
|
|
3423
|
+
/** @enum {string} */
|
|
3424
|
+
stream_version?: "v2";
|
|
3425
|
+
delta?: string;
|
|
3426
|
+
content?: string;
|
|
3427
|
+
patch?: components["schemas"]["JSONPatchOperation"][];
|
|
3411
3428
|
payload?: {
|
|
3412
3429
|
[key: string]: unknown;
|
|
3413
3430
|
};
|
|
@@ -3702,7 +3719,7 @@ interface components {
|
|
|
3702
3719
|
* @description Workflow-critical model capability identifier.
|
|
3703
3720
|
* @enum {string}
|
|
3704
3721
|
*/
|
|
3705
|
-
ModelCapability: "tools" | "vision" | "web_search" | "computer_use" | "code_execution";
|
|
3722
|
+
ModelCapability: "tools" | "vision" | "web_search" | "web_fetch" | "computer_use" | "code_execution";
|
|
3706
3723
|
Model: {
|
|
3707
3724
|
model_id: components["schemas"]["ModelId"];
|
|
3708
3725
|
provider: components["schemas"]["ProviderId"];
|
package/dist/index.d.ts
CHANGED
|
@@ -1668,6 +1668,7 @@ declare class StructuredJSONStream<T> implements AsyncIterable<StructuredJSONEve
|
|
|
1668
1668
|
private closed;
|
|
1669
1669
|
private sawTerminal;
|
|
1670
1670
|
private firstContentSeen;
|
|
1671
|
+
private currentPayload;
|
|
1671
1672
|
constructor(response: globalThis.Response, requestId: string | undefined, context: RequestContext, _metrics?: MetricsCallbacks, trace?: TraceCallbacks, timeouts?: StreamTimeoutsMs, startedAtMs?: number);
|
|
1672
1673
|
cancel(reason?: unknown): Promise<void>;
|
|
1673
1674
|
[Symbol.asyncIterator](): AsyncIterator<StructuredJSONEvent<T>>;
|
|
@@ -3405,9 +3406,25 @@ interface components {
|
|
|
3405
3406
|
/** @description Sources from web search results */
|
|
3406
3407
|
citations?: components["schemas"]["Citation"][];
|
|
3407
3408
|
};
|
|
3409
|
+
JSONPatchOperation: {
|
|
3410
|
+
/** @enum {string} */
|
|
3411
|
+
op: "add" | "remove" | "replace" | "move" | "copy" | "test";
|
|
3412
|
+
path: string;
|
|
3413
|
+
from?: string;
|
|
3414
|
+
value?: {
|
|
3415
|
+
[key: string]: unknown;
|
|
3416
|
+
};
|
|
3417
|
+
};
|
|
3408
3418
|
ResponsesStreamEnvelope: {
|
|
3409
3419
|
/** @enum {string} */
|
|
3410
3420
|
type: "start" | "update" | "completion" | "error" | "keepalive" | "tool_use_start" | "tool_use_delta" | "tool_use_stop";
|
|
3421
|
+
/** @enum {string} */
|
|
3422
|
+
stream_mode?: "text-delta" | "structured-patch";
|
|
3423
|
+
/** @enum {string} */
|
|
3424
|
+
stream_version?: "v2";
|
|
3425
|
+
delta?: string;
|
|
3426
|
+
content?: string;
|
|
3427
|
+
patch?: components["schemas"]["JSONPatchOperation"][];
|
|
3411
3428
|
payload?: {
|
|
3412
3429
|
[key: string]: unknown;
|
|
3413
3430
|
};
|
|
@@ -3702,7 +3719,7 @@ interface components {
|
|
|
3702
3719
|
* @description Workflow-critical model capability identifier.
|
|
3703
3720
|
* @enum {string}
|
|
3704
3721
|
*/
|
|
3705
|
-
ModelCapability: "tools" | "vision" | "web_search" | "computer_use" | "code_execution";
|
|
3722
|
+
ModelCapability: "tools" | "vision" | "web_search" | "web_fetch" | "computer_use" | "code_execution";
|
|
3706
3723
|
Model: {
|
|
3707
3724
|
model_id: components["schemas"]["ModelId"];
|
|
3708
3725
|
provider: components["schemas"]["ProviderId"];
|
package/dist/index.js
CHANGED
|
@@ -688,7 +688,7 @@ function isTokenReusable(token) {
|
|
|
688
688
|
// package.json
|
|
689
689
|
var package_default = {
|
|
690
690
|
name: "@modelrelay/sdk",
|
|
691
|
-
version: "1.3.
|
|
691
|
+
version: "1.3.3",
|
|
692
692
|
description: "TypeScript SDK for the ModelRelay API",
|
|
693
693
|
type: "module",
|
|
694
694
|
main: "dist/index.cjs",
|
|
@@ -720,6 +720,9 @@ var package_default = {
|
|
|
720
720
|
],
|
|
721
721
|
author: "Shane Vitarana",
|
|
722
722
|
license: "Apache-2.0",
|
|
723
|
+
dependencies: {
|
|
724
|
+
"fast-json-patch": "^3.1.1"
|
|
725
|
+
},
|
|
723
726
|
devDependencies: {
|
|
724
727
|
"openapi-typescript": "^7.4.4",
|
|
725
728
|
tsup: "^8.2.4",
|
|
@@ -1912,8 +1915,11 @@ function mapNDJSONResponseEvent(line, requestId) {
|
|
|
1912
1915
|
const model = normalizeModelId(parsed.model);
|
|
1913
1916
|
const stopReason = normalizeStopReason(parsed.stop_reason);
|
|
1914
1917
|
let textDelta;
|
|
1915
|
-
if (
|
|
1916
|
-
textDelta = parsed.
|
|
1918
|
+
if (recordType2 === "update" && typeof parsed.delta === "string") {
|
|
1919
|
+
textDelta = parsed.delta;
|
|
1920
|
+
}
|
|
1921
|
+
if (recordType2 === "completion" && typeof parsed.content === "string") {
|
|
1922
|
+
textDelta = parsed.content;
|
|
1917
1923
|
}
|
|
1918
1924
|
const toolCallDelta = extractToolCallDelta(parsed, type);
|
|
1919
1925
|
const toolCalls = extractToolCalls(parsed, type);
|
|
@@ -2013,6 +2019,7 @@ function normalizeToolCalls(toolCalls) {
|
|
|
2013
2019
|
}
|
|
2014
2020
|
|
|
2015
2021
|
// src/responses_stream.ts
|
|
2022
|
+
import { applyPatch } from "fast-json-patch";
|
|
2016
2023
|
var ResponsesStream = class {
|
|
2017
2024
|
constructor(response, requestId, context, metrics, trace, timeouts = {}, startedAtMs = Date.now()) {
|
|
2018
2025
|
this.firstTokenEmitted = false;
|
|
@@ -2139,6 +2146,9 @@ var ResponsesStream = class {
|
|
|
2139
2146
|
if (evt.type === "message_stop") {
|
|
2140
2147
|
stopReason = evt.stopReason;
|
|
2141
2148
|
usage = evt.usage;
|
|
2149
|
+
if (evt.textDelta) {
|
|
2150
|
+
text = evt.textDelta;
|
|
2151
|
+
}
|
|
2142
2152
|
const raw2 = isRecord(evt.data) ? evt.data : {};
|
|
2143
2153
|
citations = normalizeCitations(raw2.citations) ?? citations;
|
|
2144
2154
|
}
|
|
@@ -2214,6 +2224,7 @@ var StructuredJSONStream = class {
|
|
|
2214
2224
|
this.closed = false;
|
|
2215
2225
|
this.sawTerminal = false;
|
|
2216
2226
|
this.firstContentSeen = false;
|
|
2227
|
+
this.currentPayload = {};
|
|
2217
2228
|
if (!response.body) {
|
|
2218
2229
|
throw new ConfigError("streaming response is missing a body");
|
|
2219
2230
|
}
|
|
@@ -2357,9 +2368,36 @@ var StructuredJSONStream = class {
|
|
|
2357
2368
|
}
|
|
2358
2369
|
this.firstContentSeen = true;
|
|
2359
2370
|
const completeFieldsArray = Array.isArray(parsed.complete_fields) ? parsed.complete_fields.filter((f) => typeof f === "string") : [];
|
|
2371
|
+
let payload;
|
|
2372
|
+
if (rawType === "update") {
|
|
2373
|
+
const patch = Array.isArray(parsed.patch) ? parsed.patch : null;
|
|
2374
|
+
if (!patch) {
|
|
2375
|
+
throw new TransportError("structured stream update missing patch", {
|
|
2376
|
+
kind: "request"
|
|
2377
|
+
});
|
|
2378
|
+
}
|
|
2379
|
+
try {
|
|
2380
|
+
const applied = applyPatch(this.currentPayload, patch, false, true);
|
|
2381
|
+
this.currentPayload = applied.newDocument;
|
|
2382
|
+
payload = this.currentPayload;
|
|
2383
|
+
} catch (err) {
|
|
2384
|
+
throw new TransportError("failed to apply structured patch", {
|
|
2385
|
+
kind: "request",
|
|
2386
|
+
cause: err
|
|
2387
|
+
});
|
|
2388
|
+
}
|
|
2389
|
+
} else {
|
|
2390
|
+
if (parsed.payload === void 0) {
|
|
2391
|
+
throw new TransportError("structured stream completion missing payload", {
|
|
2392
|
+
kind: "request"
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2395
|
+
this.currentPayload = parsed.payload;
|
|
2396
|
+
payload = this.currentPayload;
|
|
2397
|
+
}
|
|
2360
2398
|
return {
|
|
2361
2399
|
type: rawType,
|
|
2362
|
-
payload
|
|
2400
|
+
payload,
|
|
2363
2401
|
requestId: this.requestId,
|
|
2364
2402
|
completeFields: new Set(completeFieldsArray)
|
|
2365
2403
|
};
|
|
@@ -2469,6 +2507,7 @@ async function readWithTimeout(readPromise, next, onTimeout) {
|
|
|
2469
2507
|
}
|
|
2470
2508
|
|
|
2471
2509
|
// src/responses_client.ts
|
|
2510
|
+
var RESPONSES_STREAM_ACCEPT = 'application/x-ndjson; profile="responses-stream/v2"';
|
|
2472
2511
|
var ResponsesClient = class {
|
|
2473
2512
|
constructor(http, auth, cfg = {}) {
|
|
2474
2513
|
this.http = http;
|
|
@@ -2508,24 +2547,16 @@ var ResponsesClient = class {
|
|
|
2508
2547
|
const stream = await this.stream(req, options);
|
|
2509
2548
|
return {
|
|
2510
2549
|
async *[Symbol.asyncIterator]() {
|
|
2511
|
-
let
|
|
2550
|
+
let sawDelta = false;
|
|
2512
2551
|
try {
|
|
2513
2552
|
for await (const evt of stream) {
|
|
2514
|
-
if (
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
accumulated = next;
|
|
2522
|
-
} else {
|
|
2523
|
-
delta = next;
|
|
2524
|
-
accumulated += next;
|
|
2525
|
-
}
|
|
2526
|
-
if (delta) {
|
|
2527
|
-
yield delta;
|
|
2528
|
-
}
|
|
2553
|
+
if (evt.type === "message_delta" && evt.textDelta) {
|
|
2554
|
+
sawDelta = true;
|
|
2555
|
+
yield evt.textDelta;
|
|
2556
|
+
}
|
|
2557
|
+
if (evt.type === "message_stop" && evt.textDelta && !sawDelta) {
|
|
2558
|
+
sawDelta = true;
|
|
2559
|
+
yield evt.textDelta;
|
|
2529
2560
|
}
|
|
2530
2561
|
}
|
|
2531
2562
|
} finally {
|
|
@@ -2543,24 +2574,16 @@ var ResponsesClient = class {
|
|
|
2543
2574
|
const stream = await this.stream(req, args.options ?? options);
|
|
2544
2575
|
return {
|
|
2545
2576
|
async *[Symbol.asyncIterator]() {
|
|
2546
|
-
let
|
|
2577
|
+
let sawDelta = false;
|
|
2547
2578
|
try {
|
|
2548
2579
|
for await (const evt of stream) {
|
|
2549
|
-
if (
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
accumulated = next;
|
|
2557
|
-
} else {
|
|
2558
|
-
delta = next;
|
|
2559
|
-
accumulated += next;
|
|
2560
|
-
}
|
|
2561
|
-
if (delta) {
|
|
2562
|
-
yield delta;
|
|
2563
|
-
}
|
|
2580
|
+
if (evt.type === "message_delta" && evt.textDelta) {
|
|
2581
|
+
sawDelta = true;
|
|
2582
|
+
yield evt.textDelta;
|
|
2583
|
+
}
|
|
2584
|
+
if (evt.type === "message_stop" && evt.textDelta && !sawDelta) {
|
|
2585
|
+
sawDelta = true;
|
|
2586
|
+
yield evt.textDelta;
|
|
2564
2587
|
}
|
|
2565
2588
|
}
|
|
2566
2589
|
} finally {
|
|
@@ -2659,7 +2682,7 @@ var ResponsesClient = class {
|
|
|
2659
2682
|
headers,
|
|
2660
2683
|
apiKey: authHeaders.apiKey,
|
|
2661
2684
|
accessToken: authHeaders.accessToken,
|
|
2662
|
-
accept:
|
|
2685
|
+
accept: RESPONSES_STREAM_ACCEPT,
|
|
2663
2686
|
raw: true,
|
|
2664
2687
|
signal: merged.signal,
|
|
2665
2688
|
timeoutMs: merged.timeoutMs ?? 0,
|
|
@@ -2739,7 +2762,7 @@ var ResponsesClient = class {
|
|
|
2739
2762
|
headers,
|
|
2740
2763
|
apiKey: authHeaders.apiKey,
|
|
2741
2764
|
accessToken: authHeaders.accessToken,
|
|
2742
|
-
accept:
|
|
2765
|
+
accept: RESPONSES_STREAM_ACCEPT,
|
|
2743
2766
|
raw: true,
|
|
2744
2767
|
signal: merged.signal,
|
|
2745
2768
|
timeoutMs: merged.timeoutMs ?? 0,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modelrelay/sdk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "TypeScript SDK for the ModelRelay API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
],
|
|
33
33
|
"author": "Shane Vitarana",
|
|
34
34
|
"license": "Apache-2.0",
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"fast-json-patch": "^3.1.1"
|
|
37
|
+
},
|
|
35
38
|
"devDependencies": {
|
|
36
39
|
"openapi-typescript": "^7.4.4",
|
|
37
40
|
"tsup": "^8.2.4",
|