@webless/agent 0.6.7 → 0.6.9

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/embed.cjs CHANGED
@@ -407,6 +407,203 @@ function clearPersistedAgentSession(visitorSessionId, options) {
407
407
  sessionStorage.removeItem(runtimeLastMessageKey(visitorSessionId, prefix));
408
408
  }
409
409
 
410
+ // src/runtime/subagent-child-stream.ts
411
+ var INITIAL_RETRY_DELAY_MS = 100;
412
+ var MAX_RETRY_DELAY_MS = 2e3;
413
+ var MAX_CONSECUTIVE_RETRIES = 6;
414
+ function isRecord2(value) {
415
+ return typeof value === "object" && value !== null && !Array.isArray(value);
416
+ }
417
+ function parseError(value) {
418
+ if (!isRecord2(value)) return void 0;
419
+ const { code, message } = value;
420
+ if (typeof code !== "string" || typeof message !== "string") {
421
+ return void 0;
422
+ }
423
+ return { code, message };
424
+ }
425
+ function parseChildStreamEvent(value) {
426
+ if (!isRecord2(value) || typeof value.type !== "string") {
427
+ return { type: "other" };
428
+ }
429
+ if (value.type === "session.waiting" || value.type === "session.completed" || value.type === "session.failed") {
430
+ return { type: "session.boundary" };
431
+ }
432
+ if (value.type === "subagent.event" && isRecord2(value.data) && Object.hasOwn(value.data, "event")) {
433
+ return parseChildStreamEvent(value.data.event);
434
+ }
435
+ if (value.type === "subagent.called" && isRecord2(value.data)) {
436
+ const { childStreamPath } = value.data;
437
+ if (typeof childStreamPath === "string") {
438
+ return { childStreamPath, type: "subagent.called" };
439
+ }
440
+ }
441
+ if (value.type !== "action.result" || !isRecord2(value.data)) {
442
+ return { type: "other" };
443
+ }
444
+ const { data } = value;
445
+ if (data.status !== "completed" && data.status !== "failed" && data.status !== "rejected") {
446
+ return { type: "other" };
447
+ }
448
+ if (!isRecord2(data.result) || data.result.kind !== "tool-result") {
449
+ return { type: "other" };
450
+ }
451
+ const result = data.result;
452
+ if (typeof result.callId !== "string" || typeof result.toolName !== "string") {
453
+ return { type: "other" };
454
+ }
455
+ const error = parseError(data.error);
456
+ return {
457
+ type: "action.result",
458
+ hasOutput: Object.hasOwn(result, "output"),
459
+ result: {
460
+ callId: result.callId,
461
+ toolName: result.toolName,
462
+ status: data.status,
463
+ ...Object.hasOwn(result, "output") ? { output: result.output } : {},
464
+ ...error ? { error } : {}
465
+ }
466
+ };
467
+ }
468
+ async function* readNdjsonStream(body) {
469
+ const reader = body.getReader();
470
+ const decoder = new TextDecoder();
471
+ let buffer = "";
472
+ try {
473
+ while (true) {
474
+ const { done, value } = await reader.read();
475
+ buffer += decoder.decode(value, { stream: !done });
476
+ const lines = buffer.split("\n");
477
+ buffer = lines.pop() ?? "";
478
+ for (const line of lines) {
479
+ const trimmed2 = line.trim();
480
+ if (!trimmed2) continue;
481
+ try {
482
+ const parsed = JSON.parse(trimmed2);
483
+ yield parsed;
484
+ } catch {
485
+ }
486
+ }
487
+ if (done) break;
488
+ }
489
+ const trimmed = buffer.trim();
490
+ if (trimmed) {
491
+ try {
492
+ const parsed = JSON.parse(trimmed);
493
+ yield parsed;
494
+ } catch {
495
+ }
496
+ }
497
+ } finally {
498
+ reader.releaseLock();
499
+ }
500
+ }
501
+ function streamPathAt(path, streamIndex) {
502
+ if (streamIndex === 0) return path;
503
+ return `${path}${path.includes("?") ? "&" : "?"}startIndex=${streamIndex}`;
504
+ }
505
+ function abortableDelay(delayMs, signal) {
506
+ if (signal.aborted) return Promise.resolve();
507
+ return new Promise((resolve) => {
508
+ const finish = () => {
509
+ clearTimeout(timeout);
510
+ signal.removeEventListener("abort", finish);
511
+ resolve();
512
+ };
513
+ const timeout = setTimeout(finish, delayMs);
514
+ signal.addEventListener("abort", finish, { once: true });
515
+ });
516
+ }
517
+ var SubagentChildStreamCoordinator = class {
518
+ constructor(client, handlers, parentSignal) {
519
+ this.client = client;
520
+ this.handlers = handlers;
521
+ this.parentSignal = parentSignal;
522
+ }
523
+ client;
524
+ handlers;
525
+ parentSignal;
526
+ controllers = /* @__PURE__ */ new Map();
527
+ tasks = /* @__PURE__ */ new Map();
528
+ begin(event) {
529
+ this.beginPath(event.data.childStreamPath);
530
+ }
531
+ async waitForAll() {
532
+ let observedTaskCount = -1;
533
+ while (observedTaskCount !== this.tasks.size) {
534
+ observedTaskCount = this.tasks.size;
535
+ await Promise.all(this.tasks.values());
536
+ }
537
+ }
538
+ abortAll() {
539
+ for (const controller of this.controllers.values()) controller.abort();
540
+ this.controllers.clear();
541
+ }
542
+ beginPath(childStreamPath) {
543
+ if (this.tasks.has(childStreamPath)) return;
544
+ const controller = new AbortController();
545
+ const abort = () => controller.abort();
546
+ if (this.parentSignal.aborted) {
547
+ controller.abort();
548
+ } else {
549
+ this.parentSignal.addEventListener("abort", abort, { once: true });
550
+ }
551
+ this.controllers.set(childStreamPath, controller);
552
+ const task = this.consume(childStreamPath, controller.signal).finally(
553
+ () => {
554
+ this.parentSignal.removeEventListener("abort", abort);
555
+ if (this.controllers.get(childStreamPath) === controller) {
556
+ this.controllers.delete(childStreamPath);
557
+ }
558
+ }
559
+ );
560
+ this.tasks.set(childStreamPath, task);
561
+ }
562
+ async consume(path, signal) {
563
+ let streamIndex = 0;
564
+ let consecutiveRetries = 0;
565
+ let retryDelayMs = INITIAL_RETRY_DELAY_MS;
566
+ while (!signal.aborted && consecutiveRetries < MAX_CONSECUTIVE_RETRIES) {
567
+ let receivedEvent = false;
568
+ try {
569
+ const response = await this.client.fetch(
570
+ streamPathAt(path, streamIndex),
571
+ {
572
+ cache: "no-store",
573
+ signal
574
+ }
575
+ );
576
+ if (!response.ok || response.body === null) {
577
+ await response.body?.cancel().catch(() => {
578
+ });
579
+ throw new Error(`Child stream returned ${response.status}.`);
580
+ }
581
+ for await (const rawEvent of readNdjsonStream(response.body)) {
582
+ if (signal.aborted) return;
583
+ receivedEvent = true;
584
+ streamIndex += 1;
585
+ const event = parseChildStreamEvent(rawEvent);
586
+ if (event.type === "session.boundary") return;
587
+ if (event.type === "subagent.called") {
588
+ this.beginPath(event.childStreamPath);
589
+ continue;
590
+ }
591
+ if (event.type !== "action.result") continue;
592
+ this.handlers.onToolResult?.(event.result);
593
+ if (event.hasOutput) {
594
+ this.handlers.onActionResult?.(event.result.output);
595
+ }
596
+ }
597
+ } catch {
598
+ if (signal.aborted) return;
599
+ }
600
+ consecutiveRetries = receivedEvent ? 0 : consecutiveRetries + 1;
601
+ retryDelayMs = receivedEvent ? INITIAL_RETRY_DELAY_MS : Math.min(retryDelayMs * 2, MAX_RETRY_DELAY_MS);
602
+ await abortableDelay(retryDelayMs, signal);
603
+ }
604
+ }
605
+ };
606
+
410
607
  // src/runtime/tool-ui.ts
411
608
  var AGENT_TOOL_UI_SCHEMA_VERSION = "webless.tool-ui.v1";
412
609
  var AGENT_STRUCTURED_TOOL_INPUT_SCHEMA_VERSION = "webless.structured-tool-input.v1";
@@ -420,7 +617,7 @@ function formatAgentStructuredToolInput(surface, values) {
420
617
  };
421
618
  return `${AGENT_STRUCTURED_TOOL_INPUT_HEADER} ${JSON.stringify(payload)}`;
422
619
  }
423
- function isRecord2(value) {
620
+ function isRecord3(value) {
424
621
  return value !== null && typeof value === "object" && !Array.isArray(value);
425
622
  }
426
623
  function isJsonValue(value, seen = /* @__PURE__ */ new Set()) {
@@ -469,7 +666,7 @@ function isFieldKind(value) {
469
666
  ].includes(value);
470
667
  }
471
668
  function parseField(value) {
472
- if (!isRecord2(value)) return null;
669
+ if (!isRecord3(value)) return null;
473
670
  if (!hasOnlyKeys(value, [
474
671
  "description",
475
672
  "kind",
@@ -520,7 +717,7 @@ function parseField(value) {
520
717
  if (!Array.isArray(value.options) || value.options.length > 100)
521
718
  return null;
522
719
  for (const option of value.options) {
523
- if (!isRecord2(option) || !boundedString(option.label, 160) || !isJsonValue(option.value)) {
720
+ if (!isRecord3(option) || !boundedString(option.label, 160) || !isJsonValue(option.value)) {
524
721
  return null;
525
722
  }
526
723
  }
@@ -543,7 +740,7 @@ function parseField(value) {
543
740
  };
544
741
  }
545
742
  function parseStep(value) {
546
- if (!isRecord2(value)) return null;
743
+ if (!isRecord3(value)) return null;
547
744
  if (!hasOnlyKeys(value, ["description", "fieldPaths", "id", "label"])) {
548
745
  return null;
549
746
  }
@@ -563,7 +760,7 @@ function parseStep(value) {
563
760
  };
564
761
  }
565
762
  function parseAction(value) {
566
- if (!isRecord2(value)) return null;
763
+ if (!isRecord3(value)) return null;
567
764
  if (!hasOnlyKeys(value, ["id", "label"])) return null;
568
765
  const label = boundedString(value.label, 80);
569
766
  if (value.id !== "submit" && value.id !== "back" && value.id !== "next" && value.id !== "reset" || !label) {
@@ -575,7 +772,7 @@ function parseAction(value) {
575
772
  };
576
773
  }
577
774
  function parseAgentToolUiSurface(value) {
578
- if (!isRecord2(value) || value.schemaVersion !== AGENT_TOOL_UI_SCHEMA_VERSION)
775
+ if (!isRecord3(value) || value.schemaVersion !== AGENT_TOOL_UI_SCHEMA_VERSION)
579
776
  return null;
580
777
  if (!hasOnlyKeys(value, [
581
778
  "actions",
@@ -613,7 +810,7 @@ function parseAgentToolUiSurface(value) {
613
810
  if (value.operationId !== void 0 && !operationId) return null;
614
811
  if (value.requestId !== void 0 && !requestId) return null;
615
812
  if (value.submitLabel !== void 0 && !submitLabel) return null;
616
- const values = value.values !== void 0 && isRecord2(value.values) ? value.values : void 0;
813
+ const values = value.values !== void 0 && isRecord3(value.values) ? value.values : void 0;
617
814
  if (value.values !== void 0) {
618
815
  if (!values || !Object.values(values).every((item) => isJsonValue(item)))
619
816
  return null;
@@ -650,8 +847,7 @@ function applyMessageEvent(event, rendered, handlers, workItems) {
650
847
  if (event.type === "message.completed") {
651
848
  handlers.onComplete?.();
652
849
  }
653
- if (event.type === "action.result") emitActionResult(event, handlers);
654
- if (event.type === "input.requested") emitInputRequests(event, handlers);
850
+ emitVisitorInteractionEvent(event, handlers);
655
851
  if (event.type !== "message.appended") return rendered;
656
852
  const { messageDelta, messageSoFar } = event.data;
657
853
  let delta = messageDelta;
@@ -701,6 +897,13 @@ function emitInputRequests(event, handlers) {
701
897
  })
702
898
  );
703
899
  }
900
+ function emitVisitorInteractionEvent(event, handlers) {
901
+ if (event.type === "action.result") emitActionResult(event, handlers);
902
+ if (event.type === "input.requested") emitInputRequests(event, handlers);
903
+ if (event.type === "subagent.event") {
904
+ emitVisitorInteractionEvent(event.data.event, handlers);
905
+ }
906
+ }
704
907
  function isResumeTurnMessage(received, candidate) {
705
908
  if (received === candidate) return true;
706
909
  return Boolean(candidate) && received.endsWith(`
@@ -873,11 +1076,14 @@ var AgentSession = class {
873
1076
  clientHost;
874
1077
  session;
875
1078
  activeResponse;
1079
+ childStreams;
876
1080
  capability;
877
1081
  getActiveSessionId() {
878
1082
  return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
879
1083
  }
880
1084
  reset() {
1085
+ this.childStreams?.abortAll();
1086
+ this.childStreams = void 0;
881
1087
  if (this.activeResponse) {
882
1088
  void this.activeResponse.cancel().catch(() => {
883
1089
  });
@@ -973,6 +1179,12 @@ var AgentSession = class {
973
1179
  this.persistSessionCursor(session);
974
1180
  }
975
1181
  this.activeResponse = response;
1182
+ const childStreams = new SubagentChildStreamCoordinator(
1183
+ client,
1184
+ handlers,
1185
+ signal
1186
+ );
1187
+ this.childStreams = childStreams;
976
1188
  let streamIndex = session?.state.streamIndex ?? 0;
977
1189
  let rendered = "";
978
1190
  const workItems = /* @__PURE__ */ new Map();
@@ -980,6 +1192,7 @@ var AgentSession = class {
980
1192
  try {
981
1193
  for await (const event of response) {
982
1194
  if (signal.aborted) break;
1195
+ if (event.type === "subagent.called") childStreams.begin(event);
983
1196
  if (event.type === "input.requested") requestedInput = true;
984
1197
  rendered = applyMessageEvent(event, rendered, handlers, workItems);
985
1198
  streamIndex += 1;
@@ -992,8 +1205,11 @@ var AgentSession = class {
992
1205
  );
993
1206
  }
994
1207
  }
1208
+ await childStreams.waitForAll();
995
1209
  } finally {
1210
+ childStreams.abortAll();
996
1211
  this.activeResponse = void 0;
1212
+ if (this.childStreams === childStreams) this.childStreams = void 0;
997
1213
  if (session) {
998
1214
  this.persistSessionCursor(session);
999
1215
  }
@@ -1029,64 +1245,80 @@ var AgentSession = class {
1029
1245
  }
1030
1246
  let rendered = renderTurn(turnEvents);
1031
1247
  const workItems = /* @__PURE__ */ new Map();
1032
- for (const event of turnEvents) {
1033
- applyWorkEvent(event, handlers, workItems);
1034
- if (event.type === "input.requested") emitInputRequests(event, handlers);
1035
- if (event.type === "action.result") emitActionResult(event, handlers);
1036
- }
1037
- if (rendered.startsWith(initialText)) {
1038
- const missedText = rendered.slice(initialText.length);
1039
- if (missedText) handlers.onDelta(missedText);
1040
- } else if (initialText.startsWith(rendered)) {
1041
- rendered = initialText;
1042
- } else if (!initialText.startsWith(rendered)) {
1043
- rendered = initialText + rendered;
1044
- }
1045
- let session = client.sessions.attach(snapshot.session.sessionId, {
1046
- streamIndex: snapshot.session.streamIndex
1047
- });
1048
- this.session = session;
1049
- this.persistSessionCursor(session);
1050
- let snapshotBoundary;
1051
- for (let index = turnEvents.length - 1; index >= 0; index -= 1) {
1052
- const event = turnEvents[index];
1053
- if (event && isTurnBoundary(event)) {
1054
- snapshotBoundary = event;
1055
- break;
1248
+ const childStreams = new SubagentChildStreamCoordinator(
1249
+ client,
1250
+ handlers,
1251
+ signal
1252
+ );
1253
+ this.childStreams = childStreams;
1254
+ try {
1255
+ for (const event of turnEvents) {
1256
+ if (event.type === "subagent.called") childStreams.begin(event);
1257
+ applyWorkEvent(event, handlers, workItems);
1258
+ emitVisitorInteractionEvent(event, handlers);
1056
1259
  }
1057
- }
1058
- if (snapshotBoundary) {
1059
- if (snapshotBoundary.type === "session.failed") {
1060
- throw new Error(
1061
- snapshotBoundary.data.message || snapshotBoundary.data.code
1260
+ if (rendered.startsWith(initialText)) {
1261
+ const missedText = rendered.slice(initialText.length);
1262
+ if (missedText) handlers.onDelta(missedText);
1263
+ } else if (initialText.startsWith(rendered)) {
1264
+ rendered = initialText;
1265
+ } else if (!initialText.startsWith(rendered)) {
1266
+ rendered = initialText + rendered;
1267
+ }
1268
+ let session = client.sessions.attach(snapshot.session.sessionId, {
1269
+ streamIndex: snapshot.session.streamIndex
1270
+ });
1271
+ this.session = session;
1272
+ this.persistSessionCursor(session);
1273
+ let snapshotBoundary;
1274
+ for (let index = turnEvents.length - 1; index >= 0; index -= 1) {
1275
+ const event = turnEvents[index];
1276
+ if (event && isTurnBoundary(event)) {
1277
+ snapshotBoundary = event;
1278
+ break;
1279
+ }
1280
+ }
1281
+ if (snapshotBoundary) {
1282
+ if (snapshotBoundary.type === "session.failed") {
1283
+ throw new Error(
1284
+ snapshotBoundary.data.message || snapshotBoundary.data.code
1285
+ );
1286
+ }
1287
+ handlers.onComplete?.();
1288
+ await childStreams.waitForAll();
1289
+ if (!rendered.trim() && !hasInputRequest) {
1290
+ throw new Error("Empty response from runtime");
1291
+ }
1292
+ return rendered.trim();
1293
+ }
1294
+ let streamIndex = snapshot.session.streamIndex;
1295
+ for await (const event of session.stream({ signal })) {
1296
+ if (signal.aborted) break;
1297
+ if (event.type === "subagent.called") childStreams.begin(event);
1298
+ rendered = applyMessageEvent(event, rendered, handlers, workItems);
1299
+ streamIndex += 1;
1300
+ savePersistedAgentSession(
1301
+ this.visitorSessionId,
1302
+ session.state.sessionId,
1303
+ streamIndex,
1304
+ this.storeOptions
1062
1305
  );
1306
+ if (isTurnBoundary(event)) break;
1063
1307
  }
1064
- handlers.onComplete?.();
1065
- if (!rendered.trim() && !hasInputRequest) {
1308
+ await childStreams.waitForAll();
1309
+ session = client.sessions.attach(session.state.sessionId, {
1310
+ streamIndex
1311
+ });
1312
+ this.session = session;
1313
+ this.persistSessionCursor(session);
1314
+ if (!rendered.trim() && !signal.aborted && !hasInputRequest) {
1066
1315
  throw new Error("Empty response from runtime");
1067
1316
  }
1068
1317
  return rendered.trim();
1318
+ } finally {
1319
+ childStreams.abortAll();
1320
+ if (this.childStreams === childStreams) this.childStreams = void 0;
1069
1321
  }
1070
- let streamIndex = snapshot.session.streamIndex;
1071
- for await (const event of session.stream({ signal })) {
1072
- if (signal.aborted) break;
1073
- rendered = applyMessageEvent(event, rendered, handlers, workItems);
1074
- streamIndex += 1;
1075
- savePersistedAgentSession(
1076
- this.visitorSessionId,
1077
- session.state.sessionId,
1078
- streamIndex,
1079
- this.storeOptions
1080
- );
1081
- if (isTurnBoundary(event)) break;
1082
- }
1083
- session = client.sessions.attach(session.state.sessionId, { streamIndex });
1084
- this.session = session;
1085
- this.persistSessionCursor(session);
1086
- if (!rendered.trim() && !signal.aborted && !hasInputRequest) {
1087
- throw new Error("Empty response from runtime");
1088
- }
1089
- return rendered.trim();
1090
1322
  }
1091
1323
  async respondTurn(responses, signal, handlers) {
1092
1324
  const client = this.ensureClient();
@@ -1107,6 +1339,12 @@ var AgentSession = class {
1107
1339
  () => session.respond(inputResponses, { signal })
1108
1340
  );
1109
1341
  this.activeResponse = response;
1342
+ const childStreams = new SubagentChildStreamCoordinator(
1343
+ client,
1344
+ handlers,
1345
+ signal
1346
+ );
1347
+ this.childStreams = childStreams;
1110
1348
  let streamIndex = session.state.streamIndex;
1111
1349
  let rendered = "";
1112
1350
  let requestedInput = false;
@@ -1114,6 +1352,7 @@ var AgentSession = class {
1114
1352
  try {
1115
1353
  for await (const event of response) {
1116
1354
  if (signal.aborted) break;
1355
+ if (event.type === "subagent.called") childStreams.begin(event);
1117
1356
  if (event.type === "input.requested") requestedInput = true;
1118
1357
  rendered = applyMessageEvent(event, rendered, handlers, workItems);
1119
1358
  streamIndex += 1;
@@ -1124,8 +1363,11 @@ var AgentSession = class {
1124
1363
  this.storeOptions
1125
1364
  );
1126
1365
  }
1366
+ await childStreams.waitForAll();
1127
1367
  } finally {
1368
+ childStreams.abortAll();
1128
1369
  this.activeResponse = void 0;
1370
+ if (this.childStreams === childStreams) this.childStreams = void 0;
1129
1371
  this.session = client.sessions.attach(session.state.sessionId, {
1130
1372
  streamIndex
1131
1373
  });
@@ -1137,6 +1379,7 @@ var AgentSession = class {
1137
1379
  return rendered.trim();
1138
1380
  }
1139
1381
  cancelActive() {
1382
+ this.childStreams?.abortAll();
1140
1383
  if (this.activeResponse) {
1141
1384
  this.activeResponse.cancel().catch(() => {
1142
1385
  });
@@ -1975,7 +2218,7 @@ var ENVELOPE_KEYS = /* @__PURE__ */ new Set([
1975
2218
  "presentationKinds",
1976
2219
  "ui"
1977
2220
  ]);
1978
- function isRecord3(value) {
2221
+ function isRecord4(value) {
1979
2222
  return value !== null && typeof value === "object" && !Array.isArray(value);
1980
2223
  }
1981
2224
  function isJsonValue2(value, seen = /* @__PURE__ */ new Set()) {
@@ -2002,7 +2245,7 @@ function decodeEnvelope(value) {
2002
2245
  }
2003
2246
  function parseAgentToolResultEnvelope(value) {
2004
2247
  const decoded = decodeEnvelope(value);
2005
- if (!isRecord3(decoded)) return null;
2248
+ if (!isRecord4(decoded)) return null;
2006
2249
  const keys = Object.keys(decoded);
2007
2250
  if (keys.some((key) => !ENVELOPE_KEYS.has(key)) || decoded.schemaVersion !== "webless.tool-result.v1" || !isJsonValue2(decoded.output) || !Array.isArray(decoded.presentationKinds) || decoded.presentationKinds.length < 1 || decoded.presentationKinds.length > 16) {
2008
2251
  return null;
@@ -3986,7 +4229,7 @@ function ConfirmationCard({
3986
4229
  // src/react/components/ToolInputCard/ToolInputCard.tsx
3987
4230
  var import_react9 = require("react");
3988
4231
  var import_jsx_runtime7 = require("react/jsx-runtime");
3989
- function isRecord4(value) {
4232
+ function isRecord5(value) {
3990
4233
  return value !== null && typeof value === "object" && !Array.isArray(value);
3991
4234
  }
3992
4235
  function pathSegments(path) {
@@ -4000,7 +4243,7 @@ function valueAtPath(root, path) {
4000
4243
  current = Number.isInteger(index) ? current[index] : void 0;
4001
4244
  continue;
4002
4245
  }
4003
- current = isRecord4(current) ? current[segment] : void 0;
4246
+ current = isRecord5(current) ? current[segment] : void 0;
4004
4247
  }
4005
4248
  return current;
4006
4249
  }
@@ -4023,7 +4266,7 @@ function initialValues(surface) {
4023
4266
  }
4024
4267
  function cloneJsonValue(value) {
4025
4268
  if (Array.isArray(value)) return value.map(cloneJsonValue);
4026
- if (isRecord4(value)) {
4269
+ if (isRecord5(value)) {
4027
4270
  return Object.fromEntries(
4028
4271
  Object.entries(value).map(([key, item]) => [key, cloneJsonValue(item)])
4029
4272
  );
@@ -4039,7 +4282,7 @@ function assignPath(target, path, value) {
4039
4282
  return;
4040
4283
  }
4041
4284
  const existing = current[segment];
4042
- if (!isRecord4(existing)) current[segment] = {};
4285
+ if (!isRecord5(existing)) current[segment] = {};
4043
4286
  current = current[segment];
4044
4287
  });
4045
4288
  }
@@ -4335,7 +4578,7 @@ function ToolInputCard({
4335
4578
  (field) => validateField(field, values[field.path] ?? "")
4336
4579
  );
4337
4580
  if (nextErrors.some(Boolean)) return;
4338
- const result = isRecord4(surface.values) ? cloneJsonValue(surface.values) : {};
4581
+ const result = isRecord5(surface.values) ? cloneJsonValue(surface.values) : {};
4339
4582
  for (const field of surface.fields) {
4340
4583
  const parsed = parsedFieldValue(field, values[field.path] ?? "");
4341
4584
  if (parsed !== void 0) assignPath(result, field.path, parsed);