@modelrelay/sdk 1.3.0 → 1.3.2

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 CHANGED
@@ -113,7 +113,7 @@ const req = customer.responses
113
113
  const stream = await customer.responses.streamJSON<z.infer<typeof schema>>(req);
114
114
  for await (const event of stream) {
115
115
  if (event.type === "completion") {
116
- console.log(event.value);
116
+ console.log(event.payload);
117
117
  }
118
118
  }
119
119
  ```
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.0",
821
+ version: "1.3.2",
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 (isRecord(parsed.payload) && typeof parsed.payload.content === "string") {
2046
- textDelta = parsed.payload.content;
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: parsed.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 accumulated = "";
2680
+ let sawDelta = false;
2642
2681
  try {
2643
2682
  for await (const evt of stream) {
2644
- if ((evt.type === "message_delta" || evt.type === "message_stop") && evt.textDelta) {
2645
- const next = evt.textDelta;
2646
- let delta = "";
2647
- if (next.startsWith(accumulated)) {
2648
- delta = next.slice(accumulated.length);
2649
- accumulated = next;
2650
- } else if (accumulated.startsWith(next)) {
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 accumulated = "";
2707
+ let sawDelta = false;
2677
2708
  try {
2678
2709
  for await (const evt of stream) {
2679
- if ((evt.type === "message_delta" || evt.type === "message_stop") && evt.textDelta) {
2680
- const next = evt.textDelta;
2681
- let delta = "";
2682
- if (next.startsWith(accumulated)) {
2683
- delta = next.slice(accumulated.length);
2684
- accumulated = next;
2685
- } else if (accumulated.startsWith(next)) {
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: "application/x-ndjson",
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: "application/x-ndjson",
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.0",
691
+ version: "1.3.2",
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 (isRecord(parsed.payload) && typeof parsed.payload.content === "string") {
1916
- textDelta = parsed.payload.content;
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: parsed.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 accumulated = "";
2550
+ let sawDelta = false;
2512
2551
  try {
2513
2552
  for await (const evt of stream) {
2514
- if ((evt.type === "message_delta" || evt.type === "message_stop") && evt.textDelta) {
2515
- const next = evt.textDelta;
2516
- let delta = "";
2517
- if (next.startsWith(accumulated)) {
2518
- delta = next.slice(accumulated.length);
2519
- accumulated = next;
2520
- } else if (accumulated.startsWith(next)) {
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 accumulated = "";
2577
+ let sawDelta = false;
2547
2578
  try {
2548
2579
  for await (const evt of stream) {
2549
- if ((evt.type === "message_delta" || evt.type === "message_stop") && evt.textDelta) {
2550
- const next = evt.textDelta;
2551
- let delta = "";
2552
- if (next.startsWith(accumulated)) {
2553
- delta = next.slice(accumulated.length);
2554
- accumulated = next;
2555
- } else if (accumulated.startsWith(next)) {
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: "application/x-ndjson",
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: "application/x-ndjson",
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.0",
3
+ "version": "1.3.2",
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",