@runtypelabs/sdk 4.20.0 → 4.21.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/dist/index.cjs CHANGED
@@ -89,6 +89,7 @@ __export(index_exports, {
89
89
  ToolEnsureConflictError: () => ToolEnsureConflictError,
90
90
  ToolsEndpoint: () => ToolsEndpoint,
91
91
  ToolsNamespace: () => ToolsNamespace,
92
+ UNIFIED_EVENTS_QUERY: () => UNIFIED_EVENTS_QUERY,
92
93
  UsersEndpoint: () => UsersEndpoint,
93
94
  applyGeneratedRuntimeToolProposalToDispatchRequest: () => applyGeneratedRuntimeToolProposalToDispatchRequest,
94
95
  attachRuntimeToolsToDispatchRequest: () => attachRuntimeToolsToDispatchRequest,
@@ -105,8 +106,10 @@ __export(index_exports, {
105
106
  computeSkillContentHash: () => computeSkillContentHash,
106
107
  computeSurfaceContentHash: () => computeSurfaceContentHash,
107
108
  computeToolContentHash: () => computeToolContentHash,
109
+ createAgentEventTranslator: () => createAgentEventTranslator,
108
110
  createClient: () => createClient,
109
111
  createExternalTool: () => createExternalTool,
112
+ createFlowEventTranslator: () => createFlowEventTranslator,
110
113
  defaultWorkflow: () => defaultWorkflow,
111
114
  defaultWorkflowConfig: () => defaultWorkflowConfig,
112
115
  defineAgent: () => defineAgent,
@@ -129,6 +132,7 @@ __export(index_exports, {
129
132
  isDiscoveryToolName: () => isDiscoveryToolName,
130
133
  isMarathonArtifactPath: () => isMarathonArtifactPath,
131
134
  isPreservationSensitiveTask: () => isPreservationSensitiveTask,
135
+ isUnifiedEventType: () => isUnifiedEventType,
132
136
  isWorkflowHookRef: () => isWorkflowHookRef,
133
137
  listWorkflowHooks: () => listWorkflowHooks,
134
138
  normalizeAgentDefinition: () => normalizeAgentDefinition,
@@ -151,10 +155,511 @@ __export(index_exports, {
151
155
  shouldInjectEmptySessionNudge: () => shouldInjectEmptySessionNudge,
152
156
  shouldRequestModelEscalation: () => shouldRequestModelEscalation,
153
157
  streamEvents: () => streamEvents,
154
- unregisterWorkflowHook: () => unregisterWorkflowHook
158
+ unregisterWorkflowHook: () => unregisterWorkflowHook,
159
+ withUnifiedEvents: () => withUnifiedEvents
155
160
  });
156
161
  module.exports = __toCommonJS(index_exports);
157
162
 
163
+ // src/unified-stream-adapter.ts
164
+ var UNIFIED_EVENTS_QUERY = "events=unified";
165
+ function withUnifiedEvents(path) {
166
+ return path.includes("?") ? `${path}&${UNIFIED_EVENTS_QUERY}` : `${path}?${UNIFIED_EVENTS_QUERY}`;
167
+ }
168
+ var UNIFIED_ONLY_EVENT_TYPES = /* @__PURE__ */ new Set([
169
+ "execution_start",
170
+ "execution_complete",
171
+ "execution_error",
172
+ "turn_start",
173
+ "turn_complete",
174
+ "text_start",
175
+ "text_delta",
176
+ "text_complete",
177
+ "reasoning_start",
178
+ "reasoning_delta",
179
+ "reasoning_complete",
180
+ "media_start",
181
+ "media_delta",
182
+ "media_complete",
183
+ "tool_output_delta",
184
+ "await"
185
+ ]);
186
+ function isUnifiedEventType(type) {
187
+ return typeof type === "string" && UNIFIED_ONLY_EVENT_TYPES.has(type);
188
+ }
189
+ function str(value) {
190
+ return typeof value === "string" ? value : void 0;
191
+ }
192
+ function num(value) {
193
+ return typeof value === "number" ? value : void 0;
194
+ }
195
+ function compact(event) {
196
+ const out = { type: event.type };
197
+ for (const [k, v] of Object.entries(event)) {
198
+ if (k !== "type" && v !== void 0) out[k] = v;
199
+ }
200
+ return out;
201
+ }
202
+ var LEGACY_FLOW_PASSTHROUGH = /* @__PURE__ */ new Set([
203
+ "flow_start",
204
+ "flow_complete",
205
+ "flow_error",
206
+ "flow_await",
207
+ "step_await",
208
+ "step_delta"
209
+ ]);
210
+ function createFlowEventTranslator() {
211
+ let currentStepId;
212
+ let currentStepName;
213
+ return (raw) => {
214
+ if (!raw || typeof raw !== "object") return [];
215
+ const data = raw;
216
+ const type = str(data.type);
217
+ if (!type) return [];
218
+ const executionId = str(data.executionId);
219
+ const seq = num(data.seq);
220
+ if (LEGACY_FLOW_PASSTHROUGH.has(type)) return [data];
221
+ switch (type) {
222
+ case "execution_start":
223
+ if (data.kind !== "flow") return [];
224
+ return [
225
+ compact({
226
+ type: "flow_start",
227
+ executionId,
228
+ seq,
229
+ flowId: data.flowId,
230
+ flowName: data.flowName,
231
+ totalSteps: data.totalSteps,
232
+ startedAt: data.startedAt,
233
+ source: data.source
234
+ })
235
+ ];
236
+ case "step_start": {
237
+ const id = str(data.id) ?? str(data.stepId);
238
+ const name = str(data.name) ?? str(data.stepName);
239
+ currentStepId = id;
240
+ currentStepName = name;
241
+ return [
242
+ compact({
243
+ type: "step_start",
244
+ executionId,
245
+ seq,
246
+ stepId: id,
247
+ name,
248
+ stepName: name,
249
+ stepType: data.stepType,
250
+ index: data.index,
251
+ totalSteps: data.totalSteps,
252
+ startedAt: data.startedAt,
253
+ outputVariable: data.outputVariable
254
+ })
255
+ ];
256
+ }
257
+ case "text_delta":
258
+ return [
259
+ compact({
260
+ type: "step_delta",
261
+ executionId,
262
+ seq,
263
+ delta: str(data.delta) ?? "",
264
+ text: str(data.delta) ?? "",
265
+ stepId: currentStepId,
266
+ name: currentStepName,
267
+ stepName: currentStepName
268
+ })
269
+ ];
270
+ case "step_complete": {
271
+ const id = str(data.id) ?? str(data.stepId);
272
+ const name = str(data.name) ?? str(data.stepName);
273
+ const out = compact({
274
+ type: "step_complete",
275
+ executionId,
276
+ seq,
277
+ stepId: id,
278
+ name,
279
+ stepName: name,
280
+ stepType: data.stepType,
281
+ result: data.result,
282
+ success: data.success,
283
+ executionTime: num(data.durationMs) ?? num(data.executionTime),
284
+ stopReason: data.stopReason,
285
+ completedAt: data.completedAt,
286
+ unresolvedVariables: data.unresolvedVariables,
287
+ error: data.error
288
+ });
289
+ currentStepId = void 0;
290
+ currentStepName = void 0;
291
+ return [out];
292
+ }
293
+ case "execution_complete":
294
+ if (data.kind !== "flow") return [];
295
+ return [
296
+ compact({
297
+ type: "flow_complete",
298
+ executionId,
299
+ seq,
300
+ success: data.success,
301
+ totalSteps: data.totalSteps,
302
+ successfulSteps: data.successfulSteps,
303
+ failedSteps: data.failedSteps,
304
+ executionTime: data.durationMs,
305
+ finalOutput: data.finalOutput,
306
+ completedAt: data.completedAt
307
+ })
308
+ ];
309
+ case "execution_error":
310
+ return [
311
+ compact({
312
+ type: "flow_error",
313
+ executionId,
314
+ seq,
315
+ error: data.error,
316
+ code: data.code,
317
+ upgradeUrl: data.upgradeUrl
318
+ })
319
+ ];
320
+ case "await":
321
+ return [
322
+ compact({
323
+ type: "flow_await",
324
+ executionId,
325
+ seq,
326
+ toolId: data.toolId ?? data.toolCallId,
327
+ toolName: data.toolName,
328
+ parameters: data.parameters,
329
+ awaitedAt: data.awaitedAt,
330
+ origin: data.origin,
331
+ pageOrigin: data.pageOrigin
332
+ })
333
+ ];
334
+ // Channels/markers/tool-family/approval/skip/source/custom/ping the flow
335
+ // consumer never read → no legacy event. (A non-terminal `error` is only
336
+ // produced on agent streams; dropping it here avoids a false flow_error.)
337
+ default:
338
+ return [];
339
+ }
340
+ };
341
+ }
342
+ function createAgentEventTranslator() {
343
+ let agentId;
344
+ let iteration;
345
+ let turnId;
346
+ let reasoningScope;
347
+ let media = null;
348
+ return (raw) => {
349
+ if (!raw || typeof raw !== "object") return [];
350
+ const data = raw;
351
+ const type = str(data.type);
352
+ if (!type) return [];
353
+ const executionId = str(data.executionId);
354
+ const seq = num(data.seq);
355
+ const iter = num(data.iteration) ?? iteration;
356
+ if (type.startsWith("agent_")) return [data];
357
+ switch (type) {
358
+ case "execution_start":
359
+ if (data.kind !== "agent") return [];
360
+ agentId = str(data.agentId);
361
+ return [
362
+ compact({
363
+ type: "agent_start",
364
+ executionId,
365
+ seq,
366
+ agentId: data.agentId,
367
+ agentName: data.agentName,
368
+ maxTurns: data.maxTurns,
369
+ startedAt: data.startedAt,
370
+ config: data.config
371
+ })
372
+ ];
373
+ case "turn_start":
374
+ turnId = str(data.id);
375
+ iteration = num(data.iteration) ?? iteration;
376
+ return [
377
+ compact({
378
+ type: "agent_turn_start",
379
+ executionId,
380
+ seq,
381
+ iteration: data.iteration ?? iteration,
382
+ turnId: data.id,
383
+ turnIndex: data.turnIndex,
384
+ role: data.role
385
+ })
386
+ ];
387
+ case "text_delta":
388
+ return [
389
+ compact({
390
+ type: "agent_turn_delta",
391
+ executionId,
392
+ seq,
393
+ iteration: iter,
394
+ turnId,
395
+ delta: str(data.delta) ?? "",
396
+ contentType: "text"
397
+ })
398
+ ];
399
+ case "reasoning_start":
400
+ reasoningScope = data.scope === "loop" ? "loop" : "turn";
401
+ return [];
402
+ case "reasoning_delta":
403
+ return [
404
+ compact({
405
+ type: "agent_turn_delta",
406
+ executionId,
407
+ seq,
408
+ iteration: iter,
409
+ turnId,
410
+ delta: str(data.delta) ?? "",
411
+ contentType: "thinking"
412
+ })
413
+ ];
414
+ case "reasoning_complete": {
415
+ const scope = data.scope === "loop" ? "loop" : reasoningScope;
416
+ reasoningScope = void 0;
417
+ if (scope === "loop") {
418
+ return [
419
+ compact({
420
+ type: "agent_reflection",
421
+ executionId,
422
+ seq,
423
+ iteration: iter,
424
+ reflection: data.text
425
+ })
426
+ ];
427
+ }
428
+ return [];
429
+ }
430
+ case "turn_complete":
431
+ return [
432
+ compact({
433
+ type: "agent_turn_complete",
434
+ executionId,
435
+ seq,
436
+ iteration: data.iteration ?? iter,
437
+ turnId: data.id,
438
+ role: data.role,
439
+ completedAt: data.completedAt,
440
+ content: data.content,
441
+ tokens: data.tokens,
442
+ cost: data.cost,
443
+ stopReason: data.stopReason
444
+ })
445
+ ];
446
+ case "tool_start":
447
+ return [
448
+ compact({
449
+ type: "agent_tool_start",
450
+ executionId,
451
+ seq,
452
+ iteration: iter,
453
+ toolCallId: data.toolCallId,
454
+ toolName: data.toolName,
455
+ toolType: data.toolType,
456
+ parameters: data.parameters,
457
+ origin: data.origin,
458
+ pageOrigin: data.pageOrigin
459
+ })
460
+ ];
461
+ case "tool_output_delta":
462
+ return [
463
+ compact({
464
+ type: "agent_tool_delta",
465
+ executionId,
466
+ seq,
467
+ iteration: iter,
468
+ toolCallId: data.toolCallId,
469
+ delta: str(data.delta) ?? ""
470
+ })
471
+ ];
472
+ case "tool_input_delta":
473
+ return [
474
+ compact({
475
+ type: "agent_tool_input_delta",
476
+ executionId,
477
+ seq,
478
+ iteration: iter,
479
+ toolCallId: data.toolCallId,
480
+ delta: str(data.delta) ?? ""
481
+ })
482
+ ];
483
+ case "tool_input_complete":
484
+ return [
485
+ compact({
486
+ type: "agent_tool_input_complete",
487
+ executionId,
488
+ seq,
489
+ iteration: iter,
490
+ toolCallId: data.toolCallId,
491
+ toolName: data.toolName,
492
+ parameters: data.parameters ?? {},
493
+ hiddenParameterNames: data.hiddenParameterNames
494
+ })
495
+ ];
496
+ case "tool_complete":
497
+ return [
498
+ compact({
499
+ type: "agent_tool_complete",
500
+ executionId,
501
+ seq,
502
+ iteration: num(data.iteration) ?? iter,
503
+ toolCallId: data.toolCallId,
504
+ toolName: data.toolName,
505
+ success: data.success,
506
+ result: data.result,
507
+ executionTime: data.executionTime
508
+ })
509
+ ];
510
+ case "media_start":
511
+ media = {
512
+ mediaType: str(data.mediaType),
513
+ role: str(data.role),
514
+ toolCallId: str(data.toolCallId),
515
+ chunks: []
516
+ };
517
+ return [];
518
+ case "media_delta": {
519
+ const delta = str(data.delta);
520
+ if (media && delta) media.chunks.push(delta);
521
+ return [];
522
+ }
523
+ case "media_complete": {
524
+ const acc = media;
525
+ media = null;
526
+ const mediaType = str(data.mediaType) ?? acc?.mediaType;
527
+ const toolCallId = str(data.toolCallId) ?? acc?.toolCallId;
528
+ const url = str(data.url);
529
+ const inlineData = str(data.data) ?? (acc && acc.chunks.length ? acc.chunks.join("") : void 0);
530
+ let item;
531
+ if (url) {
532
+ const kind = mediaType && mediaType.startsWith("image/") ? "image-url" : "file-url";
533
+ item = compact({ type: kind, url, mediaType });
534
+ } else {
535
+ item = compact({ type: "media", data: inlineData ?? "", mediaType });
536
+ }
537
+ return [
538
+ compact({
539
+ type: "agent_media",
540
+ executionId,
541
+ seq,
542
+ iteration: iter,
543
+ toolCallId,
544
+ media: [item]
545
+ })
546
+ ];
547
+ }
548
+ case "approval_start":
549
+ return [
550
+ compact({
551
+ type: "agent_approval_start",
552
+ executionId,
553
+ seq,
554
+ iteration: iter,
555
+ approvalId: data.approvalId,
556
+ toolCallId: data.toolCallId,
557
+ toolName: data.toolName,
558
+ toolType: data.toolType,
559
+ description: data.description,
560
+ reason: data.reason,
561
+ parameters: data.parameters,
562
+ timeout: data.timeout,
563
+ startedAt: data.startedAt
564
+ })
565
+ ];
566
+ case "approval_complete":
567
+ return [
568
+ compact({
569
+ type: "agent_approval_complete",
570
+ executionId,
571
+ seq,
572
+ approvalId: data.approvalId,
573
+ decision: data.decision,
574
+ completedAt: data.completedAt,
575
+ resolvedBy: data.resolvedBy
576
+ })
577
+ ];
578
+ case "await":
579
+ return [
580
+ compact({
581
+ type: "agent_await",
582
+ executionId,
583
+ seq,
584
+ toolId: data.toolId ?? data.toolCallId,
585
+ toolName: data.toolName,
586
+ parameters: data.parameters,
587
+ awaitedAt: data.awaitedAt,
588
+ origin: data.origin,
589
+ pageOrigin: data.pageOrigin
590
+ })
591
+ ];
592
+ case "execution_complete":
593
+ if (data.kind !== "agent") return [];
594
+ return [
595
+ compact({
596
+ type: "agent_complete",
597
+ executionId,
598
+ seq,
599
+ agentId: data.agentId ?? agentId,
600
+ success: data.success,
601
+ iterations: data.iterations,
602
+ stopReason: data.stopReason,
603
+ completedAt: data.completedAt,
604
+ totalCost: data.totalCost,
605
+ totalTokens: data.totalTokens,
606
+ finalOutput: data.finalOutput,
607
+ duration: data.durationMs
608
+ })
609
+ ];
610
+ case "execution_error":
611
+ return [
612
+ compact({
613
+ type: "agent_complete",
614
+ executionId,
615
+ seq,
616
+ agentId,
617
+ success: false,
618
+ stopReason: "error",
619
+ error: errorMessage(data.error),
620
+ completedAt: data.completedAt
621
+ })
622
+ ];
623
+ case "error":
624
+ return [
625
+ compact({
626
+ type: "agent_error",
627
+ executionId,
628
+ seq,
629
+ iteration: iter,
630
+ error: errorObject(data.error),
631
+ recoverable: true
632
+ })
633
+ ];
634
+ case "ping":
635
+ return [compact({ type: "agent_ping", executionId, seq, timestamp: data.timestamp })];
636
+ // turn/text/reasoning open+close markers, step_*, artifact_*, source,
637
+ // custom (fallback beat / routing), and the skill-fold result envelope
638
+ // the SDK never consumed → no legacy event.
639
+ default:
640
+ return [];
641
+ }
642
+ };
643
+ }
644
+ function errorMessage(error) {
645
+ if (typeof error === "string") return error;
646
+ if (error && typeof error === "object" && "message" in error) {
647
+ const message = error.message;
648
+ if (typeof message === "string") return message;
649
+ }
650
+ return error === void 0 ? "Agent execution failed" : JSON.stringify(error);
651
+ }
652
+ function errorObject(error) {
653
+ if (typeof error === "string") return { code: "error", message: error };
654
+ if (error && typeof error === "object") {
655
+ const e = error;
656
+ const obj = { code: e.code ?? "error", message: e.message ?? "" };
657
+ if (e.details !== void 0) obj.details = e.details;
658
+ return obj;
659
+ }
660
+ return { code: "error", message: String(error) };
661
+ }
662
+
158
663
  // src/stream-utils.ts
159
664
  function parseSSEChunk(chunk, buffer) {
160
665
  buffer += chunk;
@@ -192,7 +697,7 @@ function parseFinalBuffer(buffer) {
192
697
  }
193
698
  return null;
194
699
  }
195
- async function processStream(response, callbacks = {}) {
700
+ async function processStream(response, callbacks = {}, options = {}) {
196
701
  if (!response.ok) {
197
702
  const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
198
703
  callbacks.onError?.(error);
@@ -216,6 +721,20 @@ async function processStream(response, callbacks = {}) {
216
721
  executionTime: 0,
217
722
  success: true
218
723
  };
724
+ let translate = options.unified === true ? createFlowEventTranslator() : null;
725
+ const autoDetect = options.unified === void 0;
726
+ const dispatch = (parsed) => {
727
+ if (autoDetect && !translate && isUnifiedEventType(parsed?.type)) {
728
+ translate = createFlowEventTranslator();
729
+ }
730
+ if (translate) {
731
+ for (const ev of translate(parsed)) {
732
+ handleEvent(ev, callbacks, results, flowSummary);
733
+ }
734
+ } else {
735
+ handleEvent(parsed, callbacks, results, flowSummary);
736
+ }
737
+ };
219
738
  const contentType = response.headers.get("content-type");
220
739
  if (contentType?.includes("application/json")) {
221
740
  try {
@@ -272,8 +791,7 @@ async function processStream(response, callbacks = {}) {
272
791
  buffer = remainingBuffer;
273
792
  for (const eventStr of events) {
274
793
  try {
275
- const event = JSON.parse(eventStr);
276
- handleEvent(event, callbacks, results, flowSummary);
794
+ dispatch(JSON.parse(eventStr));
277
795
  } catch {
278
796
  console.warn("Failed to parse SSE event:", eventStr);
279
797
  }
@@ -282,8 +800,7 @@ async function processStream(response, callbacks = {}) {
282
800
  const finalEvent = parseFinalBuffer(buffer);
283
801
  if (finalEvent) {
284
802
  try {
285
- const event = JSON.parse(finalEvent);
286
- handleEvent(event, callbacks, results, flowSummary);
803
+ dispatch(JSON.parse(finalEvent));
287
804
  } catch {
288
805
  }
289
806
  }
@@ -353,10 +870,17 @@ function handleEvent(event, callbacks, results, summary) {
353
870
  break;
354
871
  }
355
872
  }
356
- async function* streamEvents(response) {
873
+ async function* streamEvents(response, options = {}) {
357
874
  if (!response.ok) {
358
875
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
359
876
  }
877
+ let translate = options.unified === true ? createFlowEventTranslator() : null;
878
+ const autoDetect = options.unified === void 0;
879
+ const maybeDetect = (parsed) => {
880
+ if (autoDetect && !translate && isUnifiedEventType(parsed?.type)) {
881
+ translate = createFlowEventTranslator();
882
+ }
883
+ };
360
884
  const contentType = response.headers.get("content-type");
361
885
  if (contentType?.includes("application/json")) {
362
886
  try {
@@ -386,19 +910,35 @@ async function* streamEvents(response) {
386
910
  const { events, remainingBuffer } = parseSSEChunk(chunk, buffer);
387
911
  buffer = remainingBuffer;
388
912
  for (const eventStr of events) {
913
+ let parsed;
389
914
  try {
390
- const event = JSON.parse(eventStr);
391
- yield event;
915
+ parsed = JSON.parse(eventStr);
392
916
  } catch {
917
+ continue;
918
+ }
919
+ maybeDetect(parsed);
920
+ if (translate) {
921
+ for (const ev of translate(parsed)) yield ev;
922
+ } else {
923
+ yield parsed;
393
924
  }
394
925
  }
395
926
  }
396
927
  const finalEvent = parseFinalBuffer(buffer);
397
928
  if (finalEvent) {
929
+ let parsed;
398
930
  try {
399
- const event = JSON.parse(finalEvent);
400
- yield event;
931
+ parsed = JSON.parse(finalEvent);
401
932
  } catch {
933
+ parsed = void 0;
934
+ }
935
+ if (parsed !== void 0) {
936
+ maybeDetect(parsed);
937
+ if (translate) {
938
+ for (const ev of translate(parsed)) yield ev;
939
+ } else {
940
+ yield parsed;
941
+ }
402
942
  }
403
943
  }
404
944
  } finally {
@@ -408,10 +948,16 @@ async function* streamEvents(response) {
408
948
 
409
949
  // src/flow-result.ts
410
950
  var FlowResult = class {
411
- constructor(response, summary) {
951
+ /**
952
+ * @param options.unified - The response is a unified-vocabulary SSE stream
953
+ * (`/dispatch` since the unified-SSE cutover). Set by dispatch call sites;
954
+ * left unset by still-legacy producers (`/prompts/{id}/run`, eval stream).
955
+ */
956
+ constructor(response, summary, options = {}) {
412
957
  this.consumed = false;
413
958
  this.cachedSummary = null;
414
959
  this.response = response;
960
+ this.streamOptions = options;
415
961
  if (summary) {
416
962
  this.cachedSummary = summary;
417
963
  this.consumed = true;
@@ -464,7 +1010,7 @@ var FlowResult = class {
464
1010
  }
465
1011
  this.ensureNotConsumed();
466
1012
  this.consumed = true;
467
- this.cachedSummary = await processStream(this.response, callbacks);
1013
+ this.cachedSummary = await processStream(this.response, callbacks, this.streamOptions);
468
1014
  return this.cachedSummary;
469
1015
  }
470
1016
  /**
@@ -1310,9 +1856,9 @@ var FlowBuilder = class {
1310
1856
  }
1311
1857
  const response = await client.dispatch(config);
1312
1858
  if (callbacks) {
1313
- return processStream(response, callbacks);
1859
+ return processStream(response, callbacks, { unified: true });
1314
1860
  }
1315
- return new FlowResult(response);
1861
+ return new FlowResult(response, void 0, { unified: true });
1316
1862
  }
1317
1863
  /**
1318
1864
  * Set a run condition (when predicate) on the last added step.
@@ -1444,9 +1990,9 @@ var ClientFlowBuilder = class extends FlowBuilder {
1444
1990
  }
1445
1991
  const response = await dispatchClient.dispatch(config);
1446
1992
  if (runCallbacks) {
1447
- return processStream(response, runCallbacks);
1993
+ return processStream(response, runCallbacks, { unified: true });
1448
1994
  }
1449
- return new FlowResult(response);
1995
+ return new FlowResult(response, void 0, { unified: true });
1450
1996
  }
1451
1997
  };
1452
1998
  function isStreamCallbacks(obj) {
@@ -2464,7 +3010,7 @@ var RuntypeFlowBuilder = class {
2464
3010
  config.options = { ...config.options, streamResponse: true };
2465
3011
  const client = this.getClient();
2466
3012
  const response = await this.dispatchWithPersistedFlow(client, config);
2467
- const result = new FlowResult(response);
3013
+ const result = new FlowResult(response, void 0, { unified: true });
2468
3014
  if (callbacks) {
2469
3015
  await result.stream(callbacks);
2470
3016
  }
@@ -2493,7 +3039,7 @@ var RuntypeFlowBuilder = class {
2493
3039
  config.options = { ...config.options, streamResponse: true };
2494
3040
  const client = this.getClient();
2495
3041
  const response = await this.dispatchWithPersistedFlow(client, config);
2496
- const result = new FlowResult(response);
3042
+ const result = new FlowResult(response, void 0, { unified: true });
2497
3043
  await result.getSummary();
2498
3044
  return result;
2499
3045
  }
@@ -2528,7 +3074,7 @@ var RuntypeFlowBuilder = class {
2528
3074
  onError: (error) => callbacks?.onError?.(error)
2529
3075
  };
2530
3076
  try {
2531
- for await (const event of streamEvents(response)) {
3077
+ for await (const event of streamEvents(response, { unified: true })) {
2532
3078
  collectLocalToolAwait(pausedTools, event);
2533
3079
  switch (event.type) {
2534
3080
  case "flow_start":
@@ -2636,7 +3182,7 @@ var RuntypeFlowBuilder = class {
2636
3182
  streamResponse: isStreaming
2637
3183
  };
2638
3184
  if (isStreaming) {
2639
- currentResponse = await client.requestStream("/dispatch/resume", {
3185
+ currentResponse = await client.requestStream(withUnifiedEvents("/dispatch/resume"), {
2640
3186
  method: "POST",
2641
3187
  body: JSON.stringify(resumeData)
2642
3188
  });
@@ -4880,7 +5426,7 @@ var RuntypeClient = class {
4880
5426
  * Dispatch flow execution (streaming)
4881
5427
  */
4882
5428
  async dispatch(config) {
4883
- return this.requestStream("/dispatch", {
5429
+ return this.requestStream(withUnifiedEvents("/dispatch"), {
4884
5430
  method: "POST",
4885
5431
  body: JSON.stringify(transformRequest(config))
4886
5432
  });
@@ -5251,7 +5797,7 @@ var Runtype = class {
5251
5797
 
5252
5798
  // src/version.ts
5253
5799
  var FALLBACK_VERSION = "0.0.0";
5254
- var SDK_VERSION = "4.20.0".length > 0 ? "4.20.0" : FALLBACK_VERSION;
5800
+ var SDK_VERSION = "4.21.0".length > 0 ? "4.21.0" : FALLBACK_VERSION;
5255
5801
  var RUNTYPE_CLIENT_KIND = "sdk";
5256
5802
  var SDK_USER_AGENT = `runtype-sdk/${SDK_VERSION} (typescript)`;
5257
5803
 
@@ -7745,7 +8291,7 @@ var DispatchEndpoint = class {
7745
8291
  * Dispatch with streaming response
7746
8292
  */
7747
8293
  async executeStream(data) {
7748
- return this.client.requestStream("/dispatch", {
8294
+ return this.client.requestStream(withUnifiedEvents("/dispatch"), {
7749
8295
  method: "POST",
7750
8296
  body: JSON.stringify(data)
7751
8297
  });
@@ -7761,7 +8307,7 @@ var DispatchEndpoint = class {
7761
8307
  */
7762
8308
  async resume(data) {
7763
8309
  if (data.streamResponse) {
7764
- return this.client.requestStream("/dispatch/resume", {
8310
+ return this.client.requestStream(withUnifiedEvents("/dispatch/resume"), {
7765
8311
  method: "POST",
7766
8312
  body: JSON.stringify(data)
7767
8313
  });
@@ -8276,6 +8822,19 @@ async function processAgentStream(body, callbacks) {
8276
8822
  const reader = body.getReader();
8277
8823
  const decoder = new TextDecoder();
8278
8824
  let buffer = "";
8825
+ let translate = null;
8826
+ const dispatch = (event) => {
8827
+ if (!translate && isUnifiedEventType(event.data?.type ?? event.eventType)) {
8828
+ translate = createAgentEventTranslator();
8829
+ }
8830
+ if (translate) {
8831
+ for (const legacy of translate(event.data)) {
8832
+ dispatchAgentEvent({ eventType: legacy.type, data: legacy }, callbacks);
8833
+ }
8834
+ } else {
8835
+ dispatchAgentEvent(event, callbacks);
8836
+ }
8837
+ };
8279
8838
  try {
8280
8839
  while (true) {
8281
8840
  const { done, value } = await reader.read();
@@ -8283,7 +8842,7 @@ async function processAgentStream(body, callbacks) {
8283
8842
  if (buffer.trim()) {
8284
8843
  const { events: events2 } = parseSSEChunkWithEventType(buffer + "\n\n", "");
8285
8844
  for (const event of events2) {
8286
- dispatchAgentEvent(event, callbacks);
8845
+ dispatch(event);
8287
8846
  }
8288
8847
  }
8289
8848
  break;
@@ -8292,7 +8851,7 @@ async function processAgentStream(body, callbacks) {
8292
8851
  const { events, remainingBuffer } = parseSSEChunkWithEventType(chunk, buffer);
8293
8852
  buffer = remainingBuffer;
8294
8853
  for (const event of events) {
8295
- dispatchAgentEvent(event, callbacks);
8854
+ dispatch(event);
8296
8855
  }
8297
8856
  }
8298
8857
  } finally {
@@ -8480,7 +9039,7 @@ var _AgentsEndpoint = class _AgentsEndpoint {
8480
9039
  * ```
8481
9040
  */
8482
9041
  async executeStream(id, data, init) {
8483
- return this.client.requestStream(`/agents/${id}/execute`, {
9042
+ return this.client.requestStream(withUnifiedEvents(`/agents/${id}/execute`), {
8484
9043
  method: "POST",
8485
9044
  body: JSON.stringify({
8486
9045
  ...data,
@@ -8832,16 +9391,19 @@ var _AgentsEndpoint = class _AgentsEndpoint {
8832
9391
  }
8833
9392
  let resumeResponse;
8834
9393
  try {
8835
- resumeResponse = await this.client.requestStream(`/agents/${id}/resume`, {
8836
- method: "POST",
8837
- body: JSON.stringify({
8838
- executionId,
8839
- toolOutputs: { [toolName]: toolResult },
8840
- streamResponse: true,
8841
- debugMode: data.debugMode
8842
- }),
8843
- ...abortSignal ? { signal: abortSignal } : {}
8844
- });
9394
+ resumeResponse = await this.client.requestStream(
9395
+ withUnifiedEvents(`/agents/${id}/resume`),
9396
+ {
9397
+ method: "POST",
9398
+ body: JSON.stringify({
9399
+ executionId,
9400
+ toolOutputs: { [toolName]: toolResult },
9401
+ streamResponse: true,
9402
+ debugMode: data.debugMode
9403
+ }),
9404
+ ...abortSignal ? { signal: abortSignal } : {}
9405
+ }
9406
+ );
8845
9407
  } catch (error) {
8846
9408
  if (abortSignal?.aborted) return finishAborted(executionId);
8847
9409
  throw error;
@@ -10306,9 +10868,9 @@ var _AgentsEndpoint = class _AgentsEndpoint {
10306
10868
  }
10307
10869
  /** Returns true if a server-side session error message indicates a transient
10308
10870
  * network failure that is safe to retry. */
10309
- static isRetryableSessionError(errorMessage) {
10310
- if (!errorMessage) return false;
10311
- const lower = errorMessage.toLowerCase();
10871
+ static isRetryableSessionError(errorMessage2) {
10872
+ if (!errorMessage2) return false;
10873
+ const lower = errorMessage2.toLowerCase();
10312
10874
  return _AgentsEndpoint.RETRYABLE_SESSION_ERROR_PATTERNS.some(
10313
10875
  (pattern) => lower.includes(pattern)
10314
10876
  );
@@ -11760,7 +12322,7 @@ var RuntypeClient2 = class {
11760
12322
  success: true
11761
12323
  };
11762
12324
  try {
11763
- for await (const event of streamEvents(response)) {
12325
+ for await (const event of streamEvents(response, { unified: true })) {
11764
12326
  collectLocalToolAwait(pausedTools, event);
11765
12327
  switch (event.type) {
11766
12328
  case "flow_start":
@@ -12944,6 +13506,7 @@ var STEP_TYPE_TO_METHOD = {
12944
13506
  ToolEnsureConflictError,
12945
13507
  ToolsEndpoint,
12946
13508
  ToolsNamespace,
13509
+ UNIFIED_EVENTS_QUERY,
12947
13510
  UsersEndpoint,
12948
13511
  applyGeneratedRuntimeToolProposalToDispatchRequest,
12949
13512
  attachRuntimeToolsToDispatchRequest,
@@ -12960,8 +13523,10 @@ var STEP_TYPE_TO_METHOD = {
12960
13523
  computeSkillContentHash,
12961
13524
  computeSurfaceContentHash,
12962
13525
  computeToolContentHash,
13526
+ createAgentEventTranslator,
12963
13527
  createClient,
12964
13528
  createExternalTool,
13529
+ createFlowEventTranslator,
12965
13530
  defaultWorkflow,
12966
13531
  defaultWorkflowConfig,
12967
13532
  defineAgent,
@@ -12984,6 +13549,7 @@ var STEP_TYPE_TO_METHOD = {
12984
13549
  isDiscoveryToolName,
12985
13550
  isMarathonArtifactPath,
12986
13551
  isPreservationSensitiveTask,
13552
+ isUnifiedEventType,
12987
13553
  isWorkflowHookRef,
12988
13554
  listWorkflowHooks,
12989
13555
  normalizeAgentDefinition,
@@ -13006,5 +13572,6 @@ var STEP_TYPE_TO_METHOD = {
13006
13572
  shouldInjectEmptySessionNudge,
13007
13573
  shouldRequestModelEscalation,
13008
13574
  streamEvents,
13009
- unregisterWorkflowHook
13575
+ unregisterWorkflowHook,
13576
+ withUnifiedEvents
13010
13577
  });