@webless/agent 0.6.8 → 0.6.10
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/{chunk-CXIKIQJL.js → chunk-NEI5GKGH.js} +322 -71
- package/dist/chunk-NEI5GKGH.js.map +1 -0
- package/dist/embed.cjs +312 -67
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.js +1 -1
- package/dist/index.cjs +297 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +297 -59
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +312 -67
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CXIKIQJL.js.map +0 -1
|
@@ -1291,6 +1291,203 @@ function clearPersistedAgentSession(visitorSessionId, options) {
|
|
|
1291
1291
|
sessionStorage.removeItem(runtimeLastMessageKey(visitorSessionId, prefix));
|
|
1292
1292
|
}
|
|
1293
1293
|
|
|
1294
|
+
// src/runtime/subagent-child-stream.ts
|
|
1295
|
+
var INITIAL_RETRY_DELAY_MS = 100;
|
|
1296
|
+
var MAX_RETRY_DELAY_MS = 2e3;
|
|
1297
|
+
var MAX_CONSECUTIVE_RETRIES = 6;
|
|
1298
|
+
function isRecord4(value) {
|
|
1299
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1300
|
+
}
|
|
1301
|
+
function parseError(value) {
|
|
1302
|
+
if (!isRecord4(value)) return void 0;
|
|
1303
|
+
const { code, message } = value;
|
|
1304
|
+
if (typeof code !== "string" || typeof message !== "string") {
|
|
1305
|
+
return void 0;
|
|
1306
|
+
}
|
|
1307
|
+
return { code, message };
|
|
1308
|
+
}
|
|
1309
|
+
function parseChildStreamEvent(value) {
|
|
1310
|
+
if (!isRecord4(value) || typeof value.type !== "string") {
|
|
1311
|
+
return { type: "other" };
|
|
1312
|
+
}
|
|
1313
|
+
if (value.type === "session.waiting" || value.type === "session.completed" || value.type === "session.failed") {
|
|
1314
|
+
return { type: "session.boundary" };
|
|
1315
|
+
}
|
|
1316
|
+
if (value.type === "subagent.event" && isRecord4(value.data) && Object.hasOwn(value.data, "event")) {
|
|
1317
|
+
return parseChildStreamEvent(value.data.event);
|
|
1318
|
+
}
|
|
1319
|
+
if (value.type === "subagent.called" && isRecord4(value.data)) {
|
|
1320
|
+
const { childStreamPath } = value.data;
|
|
1321
|
+
if (typeof childStreamPath === "string") {
|
|
1322
|
+
return { childStreamPath, type: "subagent.called" };
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
if (value.type !== "action.result" || !isRecord4(value.data)) {
|
|
1326
|
+
return { type: "other" };
|
|
1327
|
+
}
|
|
1328
|
+
const { data } = value;
|
|
1329
|
+
if (data.status !== "completed" && data.status !== "failed" && data.status !== "rejected") {
|
|
1330
|
+
return { type: "other" };
|
|
1331
|
+
}
|
|
1332
|
+
if (!isRecord4(data.result) || data.result.kind !== "tool-result") {
|
|
1333
|
+
return { type: "other" };
|
|
1334
|
+
}
|
|
1335
|
+
const result = data.result;
|
|
1336
|
+
if (typeof result.callId !== "string" || typeof result.toolName !== "string") {
|
|
1337
|
+
return { type: "other" };
|
|
1338
|
+
}
|
|
1339
|
+
const error = parseError(data.error);
|
|
1340
|
+
return {
|
|
1341
|
+
type: "action.result",
|
|
1342
|
+
hasOutput: Object.hasOwn(result, "output"),
|
|
1343
|
+
result: {
|
|
1344
|
+
callId: result.callId,
|
|
1345
|
+
toolName: result.toolName,
|
|
1346
|
+
status: data.status,
|
|
1347
|
+
...Object.hasOwn(result, "output") ? { output: result.output } : {},
|
|
1348
|
+
...error ? { error } : {}
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
async function* readNdjsonStream(body) {
|
|
1353
|
+
const reader = body.getReader();
|
|
1354
|
+
const decoder = new TextDecoder();
|
|
1355
|
+
let buffer = "";
|
|
1356
|
+
try {
|
|
1357
|
+
while (true) {
|
|
1358
|
+
const { done, value } = await reader.read();
|
|
1359
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
1360
|
+
const lines = buffer.split("\n");
|
|
1361
|
+
buffer = lines.pop() ?? "";
|
|
1362
|
+
for (const line of lines) {
|
|
1363
|
+
const trimmed2 = line.trim();
|
|
1364
|
+
if (!trimmed2) continue;
|
|
1365
|
+
try {
|
|
1366
|
+
const parsed = JSON.parse(trimmed2);
|
|
1367
|
+
yield parsed;
|
|
1368
|
+
} catch {
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
if (done) break;
|
|
1372
|
+
}
|
|
1373
|
+
const trimmed = buffer.trim();
|
|
1374
|
+
if (trimmed) {
|
|
1375
|
+
try {
|
|
1376
|
+
const parsed = JSON.parse(trimmed);
|
|
1377
|
+
yield parsed;
|
|
1378
|
+
} catch {
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
} finally {
|
|
1382
|
+
reader.releaseLock();
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
function streamPathAt(path, streamIndex) {
|
|
1386
|
+
if (streamIndex === 0) return path;
|
|
1387
|
+
return `${path}${path.includes("?") ? "&" : "?"}startIndex=${streamIndex}`;
|
|
1388
|
+
}
|
|
1389
|
+
function abortableDelay(delayMs, signal) {
|
|
1390
|
+
if (signal.aborted) return Promise.resolve();
|
|
1391
|
+
return new Promise((resolve) => {
|
|
1392
|
+
const finish = () => {
|
|
1393
|
+
clearTimeout(timeout);
|
|
1394
|
+
signal.removeEventListener("abort", finish);
|
|
1395
|
+
resolve();
|
|
1396
|
+
};
|
|
1397
|
+
const timeout = setTimeout(finish, delayMs);
|
|
1398
|
+
signal.addEventListener("abort", finish, { once: true });
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
var SubagentChildStreamCoordinator = class {
|
|
1402
|
+
constructor(client, handlers, parentSignal) {
|
|
1403
|
+
this.client = client;
|
|
1404
|
+
this.handlers = handlers;
|
|
1405
|
+
this.parentSignal = parentSignal;
|
|
1406
|
+
}
|
|
1407
|
+
client;
|
|
1408
|
+
handlers;
|
|
1409
|
+
parentSignal;
|
|
1410
|
+
controllers = /* @__PURE__ */ new Map();
|
|
1411
|
+
tasks = /* @__PURE__ */ new Map();
|
|
1412
|
+
begin(event) {
|
|
1413
|
+
this.beginPath(event.data.childStreamPath);
|
|
1414
|
+
}
|
|
1415
|
+
async waitForAll() {
|
|
1416
|
+
let observedTaskCount = -1;
|
|
1417
|
+
while (observedTaskCount !== this.tasks.size) {
|
|
1418
|
+
observedTaskCount = this.tasks.size;
|
|
1419
|
+
await Promise.all(this.tasks.values());
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
abortAll() {
|
|
1423
|
+
for (const controller of this.controllers.values()) controller.abort();
|
|
1424
|
+
this.controllers.clear();
|
|
1425
|
+
}
|
|
1426
|
+
beginPath(childStreamPath) {
|
|
1427
|
+
if (this.tasks.has(childStreamPath)) return;
|
|
1428
|
+
const controller = new AbortController();
|
|
1429
|
+
const abort = () => controller.abort();
|
|
1430
|
+
if (this.parentSignal.aborted) {
|
|
1431
|
+
controller.abort();
|
|
1432
|
+
} else {
|
|
1433
|
+
this.parentSignal.addEventListener("abort", abort, { once: true });
|
|
1434
|
+
}
|
|
1435
|
+
this.controllers.set(childStreamPath, controller);
|
|
1436
|
+
const task = this.consume(childStreamPath, controller.signal).finally(
|
|
1437
|
+
() => {
|
|
1438
|
+
this.parentSignal.removeEventListener("abort", abort);
|
|
1439
|
+
if (this.controllers.get(childStreamPath) === controller) {
|
|
1440
|
+
this.controllers.delete(childStreamPath);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
);
|
|
1444
|
+
this.tasks.set(childStreamPath, task);
|
|
1445
|
+
}
|
|
1446
|
+
async consume(path, signal) {
|
|
1447
|
+
let streamIndex = 0;
|
|
1448
|
+
let consecutiveRetries = 0;
|
|
1449
|
+
let retryDelayMs = INITIAL_RETRY_DELAY_MS;
|
|
1450
|
+
while (!signal.aborted && consecutiveRetries < MAX_CONSECUTIVE_RETRIES) {
|
|
1451
|
+
let receivedEvent = false;
|
|
1452
|
+
try {
|
|
1453
|
+
const response = await this.client.fetch(
|
|
1454
|
+
streamPathAt(path, streamIndex),
|
|
1455
|
+
{
|
|
1456
|
+
cache: "no-store",
|
|
1457
|
+
signal
|
|
1458
|
+
}
|
|
1459
|
+
);
|
|
1460
|
+
if (!response.ok || response.body === null) {
|
|
1461
|
+
await response.body?.cancel().catch(() => {
|
|
1462
|
+
});
|
|
1463
|
+
throw new Error(`Child stream returned ${response.status}.`);
|
|
1464
|
+
}
|
|
1465
|
+
for await (const rawEvent of readNdjsonStream(response.body)) {
|
|
1466
|
+
if (signal.aborted) return;
|
|
1467
|
+
receivedEvent = true;
|
|
1468
|
+
streamIndex += 1;
|
|
1469
|
+
const event = parseChildStreamEvent(rawEvent);
|
|
1470
|
+
if (event.type === "session.boundary") return;
|
|
1471
|
+
if (event.type === "subagent.called") {
|
|
1472
|
+
this.beginPath(event.childStreamPath);
|
|
1473
|
+
continue;
|
|
1474
|
+
}
|
|
1475
|
+
if (event.type !== "action.result") continue;
|
|
1476
|
+
this.handlers.onToolResult?.(event.result);
|
|
1477
|
+
if (event.hasOutput) {
|
|
1478
|
+
this.handlers.onActionResult?.(event.result.output);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
} catch {
|
|
1482
|
+
if (signal.aborted) return;
|
|
1483
|
+
}
|
|
1484
|
+
consecutiveRetries = receivedEvent ? 0 : consecutiveRetries + 1;
|
|
1485
|
+
retryDelayMs = receivedEvent ? INITIAL_RETRY_DELAY_MS : Math.min(retryDelayMs * 2, MAX_RETRY_DELAY_MS);
|
|
1486
|
+
await abortableDelay(retryDelayMs, signal);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
};
|
|
1490
|
+
|
|
1294
1491
|
// src/runtime/client.ts
|
|
1295
1492
|
function isTurnBoundary(event) {
|
|
1296
1493
|
return event.type === "session.waiting" || event.type === "session.completed" || event.type === "session.failed";
|
|
@@ -1532,11 +1729,14 @@ var AgentSession = class {
|
|
|
1532
1729
|
clientHost;
|
|
1533
1730
|
session;
|
|
1534
1731
|
activeResponse;
|
|
1732
|
+
childStreams;
|
|
1535
1733
|
capability;
|
|
1536
1734
|
getActiveSessionId() {
|
|
1537
1735
|
return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
|
|
1538
1736
|
}
|
|
1539
1737
|
reset() {
|
|
1738
|
+
this.childStreams?.abortAll();
|
|
1739
|
+
this.childStreams = void 0;
|
|
1540
1740
|
if (this.activeResponse) {
|
|
1541
1741
|
void this.activeResponse.cancel().catch(() => {
|
|
1542
1742
|
});
|
|
@@ -1632,6 +1832,12 @@ var AgentSession = class {
|
|
|
1632
1832
|
this.persistSessionCursor(session);
|
|
1633
1833
|
}
|
|
1634
1834
|
this.activeResponse = response;
|
|
1835
|
+
const childStreams = new SubagentChildStreamCoordinator(
|
|
1836
|
+
client,
|
|
1837
|
+
handlers,
|
|
1838
|
+
signal
|
|
1839
|
+
);
|
|
1840
|
+
this.childStreams = childStreams;
|
|
1635
1841
|
let streamIndex = session?.state.streamIndex ?? 0;
|
|
1636
1842
|
let rendered = "";
|
|
1637
1843
|
const workItems = /* @__PURE__ */ new Map();
|
|
@@ -1639,6 +1845,7 @@ var AgentSession = class {
|
|
|
1639
1845
|
try {
|
|
1640
1846
|
for await (const event of response) {
|
|
1641
1847
|
if (signal.aborted) break;
|
|
1848
|
+
if (event.type === "subagent.called") childStreams.begin(event);
|
|
1642
1849
|
if (event.type === "input.requested") requestedInput = true;
|
|
1643
1850
|
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
1644
1851
|
streamIndex += 1;
|
|
@@ -1651,8 +1858,11 @@ var AgentSession = class {
|
|
|
1651
1858
|
);
|
|
1652
1859
|
}
|
|
1653
1860
|
}
|
|
1861
|
+
await childStreams.waitForAll();
|
|
1654
1862
|
} finally {
|
|
1863
|
+
childStreams.abortAll();
|
|
1655
1864
|
this.activeResponse = void 0;
|
|
1865
|
+
if (this.childStreams === childStreams) this.childStreams = void 0;
|
|
1656
1866
|
if (session) {
|
|
1657
1867
|
this.persistSessionCursor(session);
|
|
1658
1868
|
}
|
|
@@ -1688,63 +1898,80 @@ var AgentSession = class {
|
|
|
1688
1898
|
}
|
|
1689
1899
|
let rendered = renderTurn(turnEvents);
|
|
1690
1900
|
const workItems = /* @__PURE__ */ new Map();
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
}
|
|
1703
|
-
let session = client.sessions.attach(snapshot.session.sessionId, {
|
|
1704
|
-
streamIndex: snapshot.session.streamIndex
|
|
1705
|
-
});
|
|
1706
|
-
this.session = session;
|
|
1707
|
-
this.persistSessionCursor(session);
|
|
1708
|
-
let snapshotBoundary;
|
|
1709
|
-
for (let index = turnEvents.length - 1; index >= 0; index -= 1) {
|
|
1710
|
-
const event = turnEvents[index];
|
|
1711
|
-
if (event && isTurnBoundary(event)) {
|
|
1712
|
-
snapshotBoundary = event;
|
|
1713
|
-
break;
|
|
1901
|
+
const childStreams = new SubagentChildStreamCoordinator(
|
|
1902
|
+
client,
|
|
1903
|
+
handlers,
|
|
1904
|
+
signal
|
|
1905
|
+
);
|
|
1906
|
+
this.childStreams = childStreams;
|
|
1907
|
+
try {
|
|
1908
|
+
for (const event of turnEvents) {
|
|
1909
|
+
if (event.type === "subagent.called") childStreams.begin(event);
|
|
1910
|
+
applyWorkEvent(event, handlers, workItems);
|
|
1911
|
+
emitVisitorInteractionEvent(event, handlers);
|
|
1714
1912
|
}
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1913
|
+
if (rendered.startsWith(initialText)) {
|
|
1914
|
+
const missedText = rendered.slice(initialText.length);
|
|
1915
|
+
if (missedText) handlers.onDelta(missedText);
|
|
1916
|
+
} else if (initialText.startsWith(rendered)) {
|
|
1917
|
+
rendered = initialText;
|
|
1918
|
+
} else if (!initialText.startsWith(rendered)) {
|
|
1919
|
+
rendered = initialText + rendered;
|
|
1920
|
+
}
|
|
1921
|
+
let session = client.sessions.attach(snapshot.session.sessionId, {
|
|
1922
|
+
streamIndex: snapshot.session.streamIndex
|
|
1923
|
+
});
|
|
1924
|
+
this.session = session;
|
|
1925
|
+
this.persistSessionCursor(session);
|
|
1926
|
+
let snapshotBoundary;
|
|
1927
|
+
for (let index = turnEvents.length - 1; index >= 0; index -= 1) {
|
|
1928
|
+
const event = turnEvents[index];
|
|
1929
|
+
if (event && isTurnBoundary(event)) {
|
|
1930
|
+
snapshotBoundary = event;
|
|
1931
|
+
break;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
if (snapshotBoundary) {
|
|
1935
|
+
if (snapshotBoundary.type === "session.failed") {
|
|
1936
|
+
throw new Error(
|
|
1937
|
+
snapshotBoundary.data.message || snapshotBoundary.data.code
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
handlers.onComplete?.();
|
|
1941
|
+
await childStreams.waitForAll();
|
|
1942
|
+
if (!rendered.trim() && !hasInputRequest) {
|
|
1943
|
+
throw new Error("Empty response from runtime");
|
|
1944
|
+
}
|
|
1945
|
+
return rendered.trim();
|
|
1946
|
+
}
|
|
1947
|
+
let streamIndex = snapshot.session.streamIndex;
|
|
1948
|
+
for await (const event of session.stream({ signal })) {
|
|
1949
|
+
if (signal.aborted) break;
|
|
1950
|
+
if (event.type === "subagent.called") childStreams.begin(event);
|
|
1951
|
+
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
1952
|
+
streamIndex += 1;
|
|
1953
|
+
savePersistedAgentSession(
|
|
1954
|
+
this.visitorSessionId,
|
|
1955
|
+
session.state.sessionId,
|
|
1956
|
+
streamIndex,
|
|
1957
|
+
this.storeOptions
|
|
1720
1958
|
);
|
|
1959
|
+
if (isTurnBoundary(event)) break;
|
|
1721
1960
|
}
|
|
1722
|
-
|
|
1723
|
-
|
|
1961
|
+
await childStreams.waitForAll();
|
|
1962
|
+
session = client.sessions.attach(session.state.sessionId, {
|
|
1963
|
+
streamIndex
|
|
1964
|
+
});
|
|
1965
|
+
this.session = session;
|
|
1966
|
+
this.persistSessionCursor(session);
|
|
1967
|
+
if (!rendered.trim() && !signal.aborted && !hasInputRequest) {
|
|
1724
1968
|
throw new Error("Empty response from runtime");
|
|
1725
1969
|
}
|
|
1726
1970
|
return rendered.trim();
|
|
1971
|
+
} finally {
|
|
1972
|
+
childStreams.abortAll();
|
|
1973
|
+
if (this.childStreams === childStreams) this.childStreams = void 0;
|
|
1727
1974
|
}
|
|
1728
|
-
let streamIndex = snapshot.session.streamIndex;
|
|
1729
|
-
for await (const event of session.stream({ signal })) {
|
|
1730
|
-
if (signal.aborted) break;
|
|
1731
|
-
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
1732
|
-
streamIndex += 1;
|
|
1733
|
-
savePersistedAgentSession(
|
|
1734
|
-
this.visitorSessionId,
|
|
1735
|
-
session.state.sessionId,
|
|
1736
|
-
streamIndex,
|
|
1737
|
-
this.storeOptions
|
|
1738
|
-
);
|
|
1739
|
-
if (isTurnBoundary(event)) break;
|
|
1740
|
-
}
|
|
1741
|
-
session = client.sessions.attach(session.state.sessionId, { streamIndex });
|
|
1742
|
-
this.session = session;
|
|
1743
|
-
this.persistSessionCursor(session);
|
|
1744
|
-
if (!rendered.trim() && !signal.aborted && !hasInputRequest) {
|
|
1745
|
-
throw new Error("Empty response from runtime");
|
|
1746
|
-
}
|
|
1747
|
-
return rendered.trim();
|
|
1748
1975
|
}
|
|
1749
1976
|
async respondTurn(responses, signal, handlers) {
|
|
1750
1977
|
const client = this.ensureClient();
|
|
@@ -1765,6 +1992,12 @@ var AgentSession = class {
|
|
|
1765
1992
|
() => session.respond(inputResponses, { signal })
|
|
1766
1993
|
);
|
|
1767
1994
|
this.activeResponse = response;
|
|
1995
|
+
const childStreams = new SubagentChildStreamCoordinator(
|
|
1996
|
+
client,
|
|
1997
|
+
handlers,
|
|
1998
|
+
signal
|
|
1999
|
+
);
|
|
2000
|
+
this.childStreams = childStreams;
|
|
1768
2001
|
let streamIndex = session.state.streamIndex;
|
|
1769
2002
|
let rendered = "";
|
|
1770
2003
|
let requestedInput = false;
|
|
@@ -1772,6 +2005,7 @@ var AgentSession = class {
|
|
|
1772
2005
|
try {
|
|
1773
2006
|
for await (const event of response) {
|
|
1774
2007
|
if (signal.aborted) break;
|
|
2008
|
+
if (event.type === "subagent.called") childStreams.begin(event);
|
|
1775
2009
|
if (event.type === "input.requested") requestedInput = true;
|
|
1776
2010
|
rendered = applyMessageEvent(event, rendered, handlers, workItems);
|
|
1777
2011
|
streamIndex += 1;
|
|
@@ -1782,8 +2016,11 @@ var AgentSession = class {
|
|
|
1782
2016
|
this.storeOptions
|
|
1783
2017
|
);
|
|
1784
2018
|
}
|
|
2019
|
+
await childStreams.waitForAll();
|
|
1785
2020
|
} finally {
|
|
2021
|
+
childStreams.abortAll();
|
|
1786
2022
|
this.activeResponse = void 0;
|
|
2023
|
+
if (this.childStreams === childStreams) this.childStreams = void 0;
|
|
1787
2024
|
this.session = client.sessions.attach(session.state.sessionId, {
|
|
1788
2025
|
streamIndex
|
|
1789
2026
|
});
|
|
@@ -1795,6 +2032,7 @@ var AgentSession = class {
|
|
|
1795
2032
|
return rendered.trim();
|
|
1796
2033
|
}
|
|
1797
2034
|
cancelActive() {
|
|
2035
|
+
this.childStreams?.abortAll();
|
|
1798
2036
|
if (this.activeResponse) {
|
|
1799
2037
|
this.activeResponse.cancel().catch(() => {
|
|
1800
2038
|
});
|
|
@@ -2959,7 +3197,7 @@ var defaultDarkAgentRailTheme = {
|
|
|
2959
3197
|
};
|
|
2960
3198
|
|
|
2961
3199
|
// src/react/components/AgentRail/AgentRail.tsx
|
|
2962
|
-
import { useEffect as
|
|
3200
|
+
import { useEffect as useEffect4, useRef as useRef4, useState as useState8 } from "react";
|
|
2963
3201
|
|
|
2964
3202
|
// src/react/hooks/useAgentColorScheme.ts
|
|
2965
3203
|
import { useSyncExternalStore } from "react";
|
|
@@ -3372,7 +3610,13 @@ function FollowUpChips({
|
|
|
3372
3610
|
import { useState as useState5 } from "react";
|
|
3373
3611
|
|
|
3374
3612
|
// src/react/components/BookingCard/BookingCard.tsx
|
|
3375
|
-
import {
|
|
3613
|
+
import {
|
|
3614
|
+
useEffect as useEffect3,
|
|
3615
|
+
useId as useId2,
|
|
3616
|
+
useMemo as useMemo2,
|
|
3617
|
+
useRef as useRef3,
|
|
3618
|
+
useState as useState4
|
|
3619
|
+
} from "react";
|
|
3376
3620
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
3377
3621
|
var BOOKING_STEPS = [
|
|
3378
3622
|
{ id: "date", label: "Date" },
|
|
@@ -3418,7 +3662,14 @@ function BookingCard({
|
|
|
3418
3662
|
const [startTime, setStartTime] = useState4("");
|
|
3419
3663
|
const [name, setName] = useState4("");
|
|
3420
3664
|
const [email, setEmail] = useState4("");
|
|
3665
|
+
const activeStepRef = useRef3(null);
|
|
3666
|
+
const previousStepRef = useRef3(step);
|
|
3421
3667
|
const stepIndex = BOOKING_STEPS.findIndex((item) => item.id === step);
|
|
3668
|
+
useEffect3(() => {
|
|
3669
|
+
if (previousStepRef.current === step) return;
|
|
3670
|
+
previousStepRef.current = step;
|
|
3671
|
+
activeStepRef.current?.scrollIntoView({ block: "nearest" });
|
|
3672
|
+
}, [step]);
|
|
3422
3673
|
const slots = useMemo2(
|
|
3423
3674
|
() => bookingSlotsForEventType(offer.slots, eventTypeUri),
|
|
3424
3675
|
[eventTypeUri, offer.slots]
|
|
@@ -3512,7 +3763,7 @@ function BookingCard({
|
|
|
3512
3763
|
},
|
|
3513
3764
|
item.id
|
|
3514
3765
|
)) }),
|
|
3515
|
-
step === "date" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", children: [
|
|
3766
|
+
step === "date" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
3516
3767
|
/* @__PURE__ */ jsx4("p", { className: "booking-card__title", children: selectedType?.name || "Pick a date" }),
|
|
3517
3768
|
timeZone ? /* @__PURE__ */ jsxs4("p", { className: "booking-card__tz", children: [
|
|
3518
3769
|
"Times in ",
|
|
@@ -3602,7 +3853,7 @@ function BookingCard({
|
|
|
3602
3853
|
}
|
|
3603
3854
|
)
|
|
3604
3855
|
] }, "date") : null,
|
|
3605
|
-
step === "time" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", children: [
|
|
3856
|
+
step === "time" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
3606
3857
|
/* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
|
|
3607
3858
|
/* @__PURE__ */ jsx4(
|
|
3608
3859
|
"button",
|
|
@@ -3633,7 +3884,7 @@ function BookingCard({
|
|
|
3633
3884
|
slot.startTime
|
|
3634
3885
|
)) })
|
|
3635
3886
|
] }, "time") : null,
|
|
3636
|
-
step === "details" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", children: [
|
|
3887
|
+
step === "details" ? /* @__PURE__ */ jsxs4("div", { className: "booking-card__step", ref: activeStepRef, children: [
|
|
3637
3888
|
/* @__PURE__ */ jsxs4("div", { className: "booking-card__step-bar", children: [
|
|
3638
3889
|
/* @__PURE__ */ jsx4(
|
|
3639
3890
|
"button",
|
|
@@ -3869,7 +4120,7 @@ function ConfirmationCard({
|
|
|
3869
4120
|
// src/react/components/ToolInputCard/ToolInputCard.tsx
|
|
3870
4121
|
import { useState as useState6 } from "react";
|
|
3871
4122
|
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3872
|
-
function
|
|
4123
|
+
function isRecord5(value) {
|
|
3873
4124
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
3874
4125
|
}
|
|
3875
4126
|
function pathSegments(path) {
|
|
@@ -3883,7 +4134,7 @@ function valueAtPath(root, path) {
|
|
|
3883
4134
|
current = Number.isInteger(index) ? current[index] : void 0;
|
|
3884
4135
|
continue;
|
|
3885
4136
|
}
|
|
3886
|
-
current =
|
|
4137
|
+
current = isRecord5(current) ? current[segment] : void 0;
|
|
3887
4138
|
}
|
|
3888
4139
|
return current;
|
|
3889
4140
|
}
|
|
@@ -3906,7 +4157,7 @@ function initialValues(surface) {
|
|
|
3906
4157
|
}
|
|
3907
4158
|
function cloneJsonValue(value) {
|
|
3908
4159
|
if (Array.isArray(value)) return value.map(cloneJsonValue);
|
|
3909
|
-
if (
|
|
4160
|
+
if (isRecord5(value)) {
|
|
3910
4161
|
return Object.fromEntries(
|
|
3911
4162
|
Object.entries(value).map(([key, item]) => [key, cloneJsonValue(item)])
|
|
3912
4163
|
);
|
|
@@ -3922,7 +4173,7 @@ function assignPath(target, path, value) {
|
|
|
3922
4173
|
return;
|
|
3923
4174
|
}
|
|
3924
4175
|
const existing = current[segment];
|
|
3925
|
-
if (!
|
|
4176
|
+
if (!isRecord5(existing)) current[segment] = {};
|
|
3926
4177
|
current = current[segment];
|
|
3927
4178
|
});
|
|
3928
4179
|
}
|
|
@@ -4218,7 +4469,7 @@ function ToolInputCard({
|
|
|
4218
4469
|
(field) => validateField(field, values[field.path] ?? "")
|
|
4219
4470
|
);
|
|
4220
4471
|
if (nextErrors.some(Boolean)) return;
|
|
4221
|
-
const result =
|
|
4472
|
+
const result = isRecord5(surface.values) ? cloneJsonValue(surface.values) : {};
|
|
4222
4473
|
for (const field of surface.fields) {
|
|
4223
4474
|
const parsed = parsedFieldValue(field, values[field.path] ?? "");
|
|
4224
4475
|
if (parsed !== void 0) assignPath(result, field.path, parsed);
|
|
@@ -4601,7 +4852,7 @@ function AgentRail({
|
|
|
4601
4852
|
onInputResponse,
|
|
4602
4853
|
onToolInput
|
|
4603
4854
|
}) {
|
|
4604
|
-
const transcriptRef =
|
|
4855
|
+
const transcriptRef = useRef4(null);
|
|
4605
4856
|
const resolvedBrandLabel = brandLabel.trim();
|
|
4606
4857
|
const resolvedBrandLogoUrl = brandLogoUrl?.trim();
|
|
4607
4858
|
const [failedLogoUrl, setFailedLogoUrl] = useState8(null);
|
|
@@ -4706,7 +4957,7 @@ function AgentRail({
|
|
|
4706
4957
|
hasPendingConfirmation,
|
|
4707
4958
|
enabled: lastIsAgent && !isBusy
|
|
4708
4959
|
});
|
|
4709
|
-
|
|
4960
|
+
useEffect4(() => {
|
|
4710
4961
|
const node = transcriptRef.current;
|
|
4711
4962
|
if (!node) return;
|
|
4712
4963
|
node.scrollTop = node.scrollHeight;
|
|
@@ -5117,10 +5368,10 @@ function AssistEdgeTab({
|
|
|
5117
5368
|
}
|
|
5118
5369
|
|
|
5119
5370
|
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
5120
|
-
import { useEffect as
|
|
5371
|
+
import { useEffect as useEffect7, useRef as useRef5, useState as useState10 } from "react";
|
|
5121
5372
|
|
|
5122
5373
|
// src/react/page-shift.ts
|
|
5123
|
-
import { useEffect as
|
|
5374
|
+
import { useEffect as useEffect5 } from "react";
|
|
5124
5375
|
var PAGE_SHIFT_CLASS = "webless-agent-page-shift";
|
|
5125
5376
|
var DEFAULT_RAIL_WIDTH_PX = 450;
|
|
5126
5377
|
function shouldApplyPageShift(input) {
|
|
@@ -5172,7 +5423,7 @@ function clearPageMargin() {
|
|
|
5172
5423
|
}
|
|
5173
5424
|
function usePageShift(input) {
|
|
5174
5425
|
const { active, railSlotRef } = input;
|
|
5175
|
-
|
|
5426
|
+
useEffect5(() => {
|
|
5176
5427
|
if (typeof document === "undefined") {
|
|
5177
5428
|
return;
|
|
5178
5429
|
}
|
|
@@ -5200,12 +5451,12 @@ function usePageShift(input) {
|
|
|
5200
5451
|
}
|
|
5201
5452
|
|
|
5202
5453
|
// src/react/hooks/useIsMobile.ts
|
|
5203
|
-
import { useEffect as
|
|
5454
|
+
import { useEffect as useEffect6, useState as useState9 } from "react";
|
|
5204
5455
|
function useIsMobile(breakpoint = 767) {
|
|
5205
5456
|
const [isMobile, setIsMobile] = useState9(
|
|
5206
5457
|
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
5207
5458
|
);
|
|
5208
|
-
|
|
5459
|
+
useEffect6(() => {
|
|
5209
5460
|
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
5210
5461
|
const onChange = () => setIsMobile(media.matches);
|
|
5211
5462
|
onChange();
|
|
@@ -5234,7 +5485,7 @@ function AgentWidget({
|
|
|
5234
5485
|
}) {
|
|
5235
5486
|
const isMobile = useIsMobile();
|
|
5236
5487
|
const placement = normalizeAgentPlacement(placementInput);
|
|
5237
|
-
const railSlotRef =
|
|
5488
|
+
const railSlotRef = useRef5(null);
|
|
5238
5489
|
const [railCollapsed, setRailCollapsed] = useState10(defaultCollapsed);
|
|
5239
5490
|
const [railExpanded, setRailExpanded] = useState10(false);
|
|
5240
5491
|
const pageShiftActive = shouldApplyPageShift({
|
|
@@ -5279,7 +5530,7 @@ function AgentWidget({
|
|
|
5279
5530
|
} : {},
|
|
5280
5531
|
...branding?.colors?.border ? { border: branding.colors.border } : {}
|
|
5281
5532
|
};
|
|
5282
|
-
|
|
5533
|
+
useEffect7(() => {
|
|
5283
5534
|
if (!registerPanelController) return;
|
|
5284
5535
|
registerAgentPanelController(customerId, {
|
|
5285
5536
|
open: () => setRailCollapsed(false),
|
|
@@ -5296,7 +5547,7 @@ function AgentWidget({
|
|
|
5296
5547
|
if (isMobile) setRailCollapsed(false);
|
|
5297
5548
|
await submit(message);
|
|
5298
5549
|
}
|
|
5299
|
-
|
|
5550
|
+
useEffect7(() => {
|
|
5300
5551
|
if (railCollapsed) return;
|
|
5301
5552
|
const handleKeyDown = (event) => {
|
|
5302
5553
|
if (event.key === "Tab" && (isMobile || railExpanded)) {
|
|
@@ -5419,4 +5670,4 @@ export {
|
|
|
5419
5670
|
AssistEdgeTab,
|
|
5420
5671
|
AgentWidget
|
|
5421
5672
|
};
|
|
5422
|
-
//# sourceMappingURL=chunk-
|
|
5673
|
+
//# sourceMappingURL=chunk-NEI5GKGH.js.map
|