@lvce-editor/chat-debug-view 5.3.0 → 5.5.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/chatDebugViewWorkerMain.js +594 -396
- package/package.json +1 -1
|
@@ -1171,14 +1171,435 @@ const diff2 = uid => {
|
|
|
1171
1171
|
return diff(oldState, newState);
|
|
1172
1172
|
};
|
|
1173
1173
|
|
|
1174
|
+
const handleCloseDetails = state => {
|
|
1175
|
+
return {
|
|
1176
|
+
...state,
|
|
1177
|
+
selectedEvent: null,
|
|
1178
|
+
selectedEventId: null,
|
|
1179
|
+
selectedEventIndex: null
|
|
1180
|
+
};
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1174
1183
|
const handleDetailsContextMenu = state => {
|
|
1175
1184
|
return state;
|
|
1176
1185
|
};
|
|
1177
1186
|
|
|
1187
|
+
const handleDetailTab = (state, value) => {
|
|
1188
|
+
if (!isDetailTab(value)) {
|
|
1189
|
+
return state;
|
|
1190
|
+
}
|
|
1191
|
+
return {
|
|
1192
|
+
...state,
|
|
1193
|
+
selectedDetailTab: value
|
|
1194
|
+
};
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
const hasMatchingToolName$1 = (startedEvent, finishedEvent) => {
|
|
1198
|
+
if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
|
|
1199
|
+
return startedEvent.toolName === finishedEvent.toolName;
|
|
1200
|
+
}
|
|
1201
|
+
return true;
|
|
1202
|
+
};
|
|
1203
|
+
|
|
1204
|
+
const isMatchingToolExecutionPair = (startedEvent, finishedEvent) => {
|
|
1205
|
+
return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName$1(startedEvent, finishedEvent);
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
const startedEventType$1 = 'tool-execution-started';
|
|
1209
|
+
const finishedEventType$1 = 'tool-execution-finished';
|
|
1210
|
+
const mergedEventType = 'tool-execution';
|
|
1211
|
+
|
|
1212
|
+
const isToolExecutionFinishedEvent = event => {
|
|
1213
|
+
return event.type === finishedEventType$1;
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
const isToolExecutionStartedEvent = event => {
|
|
1217
|
+
return event.type === startedEventType$1;
|
|
1218
|
+
};
|
|
1219
|
+
|
|
1220
|
+
const getTimestamp$1 = value => {
|
|
1221
|
+
return typeof value === 'string' || typeof value === 'number' ? value : undefined;
|
|
1222
|
+
};
|
|
1223
|
+
|
|
1224
|
+
const getEndedTimestamp = event => {
|
|
1225
|
+
return getTimestamp$1(event.ended) ?? getTimestamp$1(event.endTime) ?? getTimestamp$1(event.endTimestamp) ?? getTimestamp$1(event.timestamp);
|
|
1226
|
+
};
|
|
1227
|
+
|
|
1228
|
+
const eventStableIds = new WeakMap();
|
|
1229
|
+
const eventStableIdState = {
|
|
1230
|
+
nextStableEventId: 1
|
|
1231
|
+
};
|
|
1232
|
+
|
|
1233
|
+
const getOrCreateStableEventId = event => {
|
|
1234
|
+
const existingStableEventId = eventStableIds.get(event);
|
|
1235
|
+
if (existingStableEventId) {
|
|
1236
|
+
return existingStableEventId;
|
|
1237
|
+
}
|
|
1238
|
+
const stableEventId = `event-${eventStableIdState.nextStableEventId++}`;
|
|
1239
|
+
eventStableIds.set(event, stableEventId);
|
|
1240
|
+
return stableEventId;
|
|
1241
|
+
};
|
|
1242
|
+
|
|
1243
|
+
const getStartedTimestamp = event => {
|
|
1244
|
+
return getTimestamp$1(event.started) ?? getTimestamp$1(event.startTime) ?? getTimestamp$1(event.startTimestamp) ?? getTimestamp$1(event.timestamp);
|
|
1245
|
+
};
|
|
1246
|
+
|
|
1247
|
+
const setStableEventId = (event, stableEventId) => {
|
|
1248
|
+
eventStableIds.set(event, stableEventId);
|
|
1249
|
+
};
|
|
1250
|
+
|
|
1251
|
+
const mergeToolExecutionEvents$1 = (startedEvent, finishedEvent) => {
|
|
1252
|
+
const ended = getEndedTimestamp(finishedEvent);
|
|
1253
|
+
const {
|
|
1254
|
+
eventId
|
|
1255
|
+
} = startedEvent;
|
|
1256
|
+
const started = getStartedTimestamp(startedEvent);
|
|
1257
|
+
const mergedEvent = {
|
|
1258
|
+
...startedEvent,
|
|
1259
|
+
...finishedEvent,
|
|
1260
|
+
...(ended === undefined ? {} : {
|
|
1261
|
+
ended
|
|
1262
|
+
}),
|
|
1263
|
+
...(eventId === undefined ? {} : {
|
|
1264
|
+
eventId
|
|
1265
|
+
}),
|
|
1266
|
+
...(started === undefined ? {} : {
|
|
1267
|
+
started
|
|
1268
|
+
}),
|
|
1269
|
+
type: mergedEventType
|
|
1270
|
+
};
|
|
1271
|
+
const stableEventId = `${getOrCreateStableEventId(startedEvent)}:${getOrCreateStableEventId(finishedEvent)}`;
|
|
1272
|
+
setStableEventId(mergedEvent, stableEventId);
|
|
1273
|
+
return mergedEvent;
|
|
1274
|
+
};
|
|
1275
|
+
|
|
1276
|
+
const getStableEventId = event => {
|
|
1277
|
+
return getOrCreateStableEventId(event);
|
|
1278
|
+
};
|
|
1279
|
+
|
|
1280
|
+
const collapseToolExecutionEvents = events => {
|
|
1281
|
+
const collapsedEvents = [];
|
|
1282
|
+
for (let i = 0; i < events.length; i++) {
|
|
1283
|
+
const event = events[i];
|
|
1284
|
+
if (isToolExecutionStartedEvent(event)) {
|
|
1285
|
+
const nextEvent = events[i + 1];
|
|
1286
|
+
if (nextEvent && isToolExecutionFinishedEvent(nextEvent) && isMatchingToolExecutionPair(event, nextEvent)) {
|
|
1287
|
+
collapsedEvents.push(mergeToolExecutionEvents$1(event, nextEvent));
|
|
1288
|
+
i++;
|
|
1289
|
+
continue;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
collapsedEvents.push(event);
|
|
1293
|
+
}
|
|
1294
|
+
return collapsedEvents;
|
|
1295
|
+
};
|
|
1296
|
+
|
|
1297
|
+
const getVisibleEvents = (events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
|
|
1298
|
+
return events.filter(event => {
|
|
1299
|
+
if (!showInputEvents && event.type === 'handle-input') {
|
|
1300
|
+
return false;
|
|
1301
|
+
}
|
|
1302
|
+
if (!showResponsePartEvents && event.type === 'sse-response-part') {
|
|
1303
|
+
return false;
|
|
1304
|
+
}
|
|
1305
|
+
if (!showEventStreamFinishedEvents && event.type === 'event-stream-finished') {
|
|
1306
|
+
return false;
|
|
1307
|
+
}
|
|
1308
|
+
// hide session creation events by default — not useful in the debug view
|
|
1309
|
+
if (event.type === 'chat-session-created') {
|
|
1310
|
+
return false;
|
|
1311
|
+
}
|
|
1312
|
+
return true;
|
|
1313
|
+
});
|
|
1314
|
+
};
|
|
1315
|
+
|
|
1316
|
+
const isNetworkEvent = event => {
|
|
1317
|
+
const normalizedType = event.type.toLowerCase();
|
|
1318
|
+
return normalizedType === 'request' || normalizedType === 'response' || normalizedType === 'handle-response' || normalizedType.includes('fetch') || normalizedType.includes('xhr');
|
|
1319
|
+
};
|
|
1320
|
+
|
|
1321
|
+
const isStreamEvent = event => {
|
|
1322
|
+
return event.type === 'sse-response-part' || event.type === 'event-stream-finished';
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
const toolEventTypePrefix = 'tool-execution';
|
|
1326
|
+
const isToolEvent = event => {
|
|
1327
|
+
return event.type.startsWith(toolEventTypePrefix);
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
const isUiEvent = event => {
|
|
1331
|
+
return event.type.startsWith('handle-') && event.type !== 'handle-response';
|
|
1332
|
+
};
|
|
1333
|
+
|
|
1334
|
+
const matchesEventCategoryFilter = (event, eventCategoryFilter) => {
|
|
1335
|
+
switch (eventCategoryFilter) {
|
|
1336
|
+
case Network:
|
|
1337
|
+
return isNetworkEvent(event);
|
|
1338
|
+
case Stream:
|
|
1339
|
+
return isStreamEvent(event);
|
|
1340
|
+
case Tools:
|
|
1341
|
+
return isToolEvent(event);
|
|
1342
|
+
case Ui:
|
|
1343
|
+
return isUiEvent(event);
|
|
1344
|
+
default:
|
|
1345
|
+
return true;
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
|
|
1350
|
+
const visibleEvents = getVisibleEvents(events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
|
|
1351
|
+
const collapsedEvents = collapseToolExecutionEvents(visibleEvents);
|
|
1352
|
+
const parsedFilter = parseFilterValue(filterValue);
|
|
1353
|
+
const activeEventCategoryFilter = parsedFilter.eventCategoryFilter === All ? eventCategoryFilter : parsedFilter.eventCategoryFilter;
|
|
1354
|
+
const filteredByCategory = collapsedEvents.filter(event => matchesEventCategoryFilter(event, activeEventCategoryFilter));
|
|
1355
|
+
const {
|
|
1356
|
+
filterText
|
|
1357
|
+
} = parsedFilter;
|
|
1358
|
+
if (!filterText) {
|
|
1359
|
+
return filteredByCategory;
|
|
1360
|
+
}
|
|
1361
|
+
return filteredByCategory.filter(event => JSON.stringify(event).toLowerCase().includes(filterText));
|
|
1362
|
+
};
|
|
1363
|
+
|
|
1364
|
+
const toTimeNumber = value => {
|
|
1365
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
1366
|
+
return value;
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof value === 'string') {
|
|
1369
|
+
const timestamp = Date.parse(value);
|
|
1370
|
+
if (!Number.isNaN(timestamp)) {
|
|
1371
|
+
return timestamp;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
return undefined;
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
const getEventTime = event => {
|
|
1378
|
+
return toTimeNumber(event.started ?? event.startTime ?? event.startTimestamp ?? event.timestamp);
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
const maxBarUnits = 8;
|
|
1382
|
+
const parseTimelineSeconds = value => {
|
|
1383
|
+
const trimmed = value.trim();
|
|
1384
|
+
if (!trimmed) {
|
|
1385
|
+
return undefined;
|
|
1386
|
+
}
|
|
1387
|
+
const parsed = Number.parseFloat(trimmed);
|
|
1388
|
+
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
1389
|
+
return undefined;
|
|
1390
|
+
}
|
|
1391
|
+
return parsed;
|
|
1392
|
+
};
|
|
1393
|
+
const roundSeconds = value => {
|
|
1394
|
+
return Number(value.toFixed(3));
|
|
1395
|
+
};
|
|
1396
|
+
const getEventsWithTime = events => {
|
|
1397
|
+
return events.flatMap(event => {
|
|
1398
|
+
const time = getEventTime(event);
|
|
1399
|
+
if (time === undefined) {
|
|
1400
|
+
return [];
|
|
1401
|
+
}
|
|
1402
|
+
return [{
|
|
1403
|
+
event,
|
|
1404
|
+
time
|
|
1405
|
+
}];
|
|
1406
|
+
});
|
|
1407
|
+
};
|
|
1408
|
+
const getTimelineDurationSeconds = events => {
|
|
1409
|
+
const eventsWithTime = getEventsWithTime(events);
|
|
1410
|
+
if (eventsWithTime.length === 0) {
|
|
1411
|
+
return 0;
|
|
1412
|
+
}
|
|
1413
|
+
const baseTime = eventsWithTime[0].time;
|
|
1414
|
+
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1415
|
+
return roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
|
|
1416
|
+
};
|
|
1417
|
+
const getSelectionPercent = (value, durationSeconds) => {
|
|
1418
|
+
if (durationSeconds <= 0) {
|
|
1419
|
+
return 0;
|
|
1420
|
+
}
|
|
1421
|
+
return Number((value / durationSeconds * 100).toFixed(3));
|
|
1422
|
+
};
|
|
1423
|
+
const getNormalizedRange = (durationSeconds, startValue, endValue) => {
|
|
1424
|
+
const parsedStart = parseTimelineSeconds(startValue);
|
|
1425
|
+
const parsedEnd = parseTimelineSeconds(endValue);
|
|
1426
|
+
if (parsedStart === undefined && parsedEnd === undefined) {
|
|
1427
|
+
return {
|
|
1428
|
+
endSeconds: null,
|
|
1429
|
+
hasSelection: false,
|
|
1430
|
+
startSeconds: null
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
const rawStart = parsedStart ?? 0;
|
|
1434
|
+
const rawEnd = parsedEnd ?? durationSeconds;
|
|
1435
|
+
const normalizedStart = Math.max(0, Math.min(durationSeconds, Math.min(rawStart, rawEnd)));
|
|
1436
|
+
const normalizedEnd = Math.max(0, Math.min(durationSeconds, Math.max(rawStart, rawEnd)));
|
|
1437
|
+
return {
|
|
1438
|
+
endSeconds: roundSeconds(normalizedEnd),
|
|
1439
|
+
hasSelection: true,
|
|
1440
|
+
startSeconds: roundSeconds(normalizedStart)
|
|
1441
|
+
};
|
|
1442
|
+
};
|
|
1443
|
+
const filterEventsByTimelineRange = (events, startValue, endValue) => {
|
|
1444
|
+
const eventsWithTime = getEventsWithTime(events);
|
|
1445
|
+
if (eventsWithTime.length === 0) {
|
|
1446
|
+
return events;
|
|
1447
|
+
}
|
|
1448
|
+
const baseTime = eventsWithTime[0].time;
|
|
1449
|
+
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1450
|
+
const durationSeconds = roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
|
|
1451
|
+
const range = getNormalizedRange(durationSeconds, startValue, endValue);
|
|
1452
|
+
if (!range.hasSelection || range.startSeconds === null || range.endSeconds === null) {
|
|
1453
|
+
return events;
|
|
1454
|
+
}
|
|
1455
|
+
const startTime = baseTime + range.startSeconds * 1000;
|
|
1456
|
+
const endTime = baseTime + range.endSeconds * 1000;
|
|
1457
|
+
return eventsWithTime.filter(item => item.time >= startTime && item.time <= endTime).map(item => item.event);
|
|
1458
|
+
};
|
|
1459
|
+
const getTimelineInfo = (events, startValue, endValue) => {
|
|
1460
|
+
const eventsWithTime = getEventsWithTime(events);
|
|
1461
|
+
if (eventsWithTime.length === 0) {
|
|
1462
|
+
return {
|
|
1463
|
+
buckets: [],
|
|
1464
|
+
durationSeconds: 0,
|
|
1465
|
+
endSeconds: null,
|
|
1466
|
+
hasSelection: false,
|
|
1467
|
+
selectionEndPercent: null,
|
|
1468
|
+
selectionStartPercent: null,
|
|
1469
|
+
startSeconds: null
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
const baseTime = eventsWithTime[0].time;
|
|
1473
|
+
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1474
|
+
const durationMs = Math.max(0, lastTime - baseTime);
|
|
1475
|
+
const durationSeconds = roundSeconds(durationMs / 1000);
|
|
1476
|
+
const range = getNormalizedRange(durationSeconds, startValue, endValue);
|
|
1477
|
+
const bucketCount = durationSeconds === 0 ? 1 : Math.max(12, Math.min(48, Math.ceil(durationSeconds)));
|
|
1478
|
+
const bucketDurationMs = durationMs === 0 ? 1000 : durationMs / bucketCount;
|
|
1479
|
+
const counts = Array.from({
|
|
1480
|
+
length: bucketCount
|
|
1481
|
+
}).fill(0);
|
|
1482
|
+
for (const item of eventsWithTime) {
|
|
1483
|
+
const offsetMs = item.time - baseTime;
|
|
1484
|
+
const index = durationMs === 0 ? 0 : Math.min(bucketCount - 1, Math.floor(offsetMs / durationMs * bucketCount));
|
|
1485
|
+
counts[index] += 1;
|
|
1486
|
+
}
|
|
1487
|
+
const maxCount = Math.max(...counts);
|
|
1488
|
+
const selectionStartPercent = range.hasSelection && range.startSeconds !== null ? getSelectionPercent(range.startSeconds, durationSeconds) : null;
|
|
1489
|
+
const selectionEndPercent = range.hasSelection && range.endSeconds !== null ? getSelectionPercent(range.endSeconds, durationSeconds) : null;
|
|
1490
|
+
const buckets = counts.map((count, index) => {
|
|
1491
|
+
const bucketStartMs = index * bucketDurationMs;
|
|
1492
|
+
const bucketEndMs = index === bucketCount - 1 ? durationMs : (index + 1) * bucketDurationMs;
|
|
1493
|
+
const hasSelection = range.hasSelection && range.startSeconds !== null && range.endSeconds !== null;
|
|
1494
|
+
const selectionStartMs = hasSelection ? range.startSeconds * 1000 : 0;
|
|
1495
|
+
const selectionEndMs = hasSelection ? range.endSeconds * 1000 : 0;
|
|
1496
|
+
return {
|
|
1497
|
+
count,
|
|
1498
|
+
endSeconds: roundSeconds(bucketEndMs / 1000),
|
|
1499
|
+
isSelected: hasSelection && bucketEndMs >= selectionStartMs && bucketStartMs <= selectionEndMs,
|
|
1500
|
+
startSeconds: roundSeconds(bucketStartMs / 1000),
|
|
1501
|
+
unitCount: count === 0 ? 0 : Math.max(1, Math.round(count / maxCount * maxBarUnits))
|
|
1502
|
+
};
|
|
1503
|
+
});
|
|
1504
|
+
return {
|
|
1505
|
+
buckets,
|
|
1506
|
+
durationSeconds,
|
|
1507
|
+
endSeconds: range.endSeconds,
|
|
1508
|
+
hasSelection: range.hasSelection,
|
|
1509
|
+
selectionEndPercent,
|
|
1510
|
+
selectionStartPercent,
|
|
1511
|
+
startSeconds: range.startSeconds
|
|
1512
|
+
};
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
const getCurrentEvents$3 = state => {
|
|
1516
|
+
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
1517
|
+
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
1518
|
+
};
|
|
1519
|
+
const getEventIndexByStableId$1 = (events, event) => {
|
|
1520
|
+
const stableEventId = getStableEventId(event);
|
|
1521
|
+
return events.findIndex(candidate => getStableEventId(candidate) === stableEventId);
|
|
1522
|
+
};
|
|
1523
|
+
const getSelectedEventIndex$1 = state => {
|
|
1524
|
+
const {
|
|
1525
|
+
selectedEventIndex
|
|
1526
|
+
} = state;
|
|
1527
|
+
if (selectedEventIndex === null) {
|
|
1528
|
+
return null;
|
|
1529
|
+
}
|
|
1530
|
+
const filteredEvents = getCurrentEvents$3(state);
|
|
1531
|
+
const selectedEvent = filteredEvents[selectedEventIndex];
|
|
1532
|
+
if (!selectedEvent) {
|
|
1533
|
+
return null;
|
|
1534
|
+
}
|
|
1535
|
+
const newIndex = getEventIndexByStableId$1(filteredEvents, selectedEvent);
|
|
1536
|
+
if (newIndex === -1) {
|
|
1537
|
+
return null;
|
|
1538
|
+
}
|
|
1539
|
+
return newIndex;
|
|
1540
|
+
};
|
|
1541
|
+
const getPreservedSelectedEventIndex$1 = (oldState, newState) => {
|
|
1542
|
+
const {
|
|
1543
|
+
selectedEventIndex
|
|
1544
|
+
} = oldState;
|
|
1545
|
+
if (selectedEventIndex === null) {
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
const oldFilteredEvents = getCurrentEvents$3(oldState);
|
|
1549
|
+
const selectedEvent = oldFilteredEvents[selectedEventIndex];
|
|
1550
|
+
if (!selectedEvent) {
|
|
1551
|
+
return null;
|
|
1552
|
+
}
|
|
1553
|
+
const newFilteredEvents = getCurrentEvents$3(newState);
|
|
1554
|
+
const newIndex = getEventIndexByStableId$1(newFilteredEvents, selectedEvent);
|
|
1555
|
+
if (newIndex === -1) {
|
|
1556
|
+
return null;
|
|
1557
|
+
}
|
|
1558
|
+
return newIndex;
|
|
1559
|
+
};
|
|
1560
|
+
const withPreservedSelection$1 = (state, nextState) => {
|
|
1561
|
+
const selectedEventIndex = getPreservedSelectedEventIndex$1(state, nextState);
|
|
1562
|
+
return {
|
|
1563
|
+
...nextState,
|
|
1564
|
+
selectedEvent: selectedEventIndex === null ? null : state.selectedEvent,
|
|
1565
|
+
selectedEventId: selectedEventIndex === null ? null : state.selectedEventId,
|
|
1566
|
+
selectedEventIndex
|
|
1567
|
+
};
|
|
1568
|
+
};
|
|
1569
|
+
|
|
1570
|
+
const handleEventCategoryFilter = (state, value) => {
|
|
1571
|
+
const nextState = {
|
|
1572
|
+
...state,
|
|
1573
|
+
eventCategoryFilter: value || All
|
|
1574
|
+
};
|
|
1575
|
+
return withPreservedSelection$1(state, nextState);
|
|
1576
|
+
};
|
|
1577
|
+
|
|
1578
|
+
let workerRpc;
|
|
1579
|
+
const setWorkerRpc = value => {
|
|
1580
|
+
workerRpc = value;
|
|
1581
|
+
};
|
|
1582
|
+
const invoke = async (method, ...params) => {
|
|
1583
|
+
if (!workerRpc) {
|
|
1584
|
+
throw new Error('worker rpc is not initialized');
|
|
1585
|
+
}
|
|
1586
|
+
return workerRpc.invoke(method, ...params);
|
|
1587
|
+
};
|
|
1588
|
+
|
|
1589
|
+
const chatStorageWorkerClientDependencies = {
|
|
1590
|
+
invoke: invoke
|
|
1591
|
+
};
|
|
1592
|
+
const listChatViewEvents$1 = async sessionId => {
|
|
1593
|
+
return chatStorageWorkerClientDependencies.invoke('ChatStorage.listChatViewEvents', sessionId);
|
|
1594
|
+
};
|
|
1595
|
+
const loadSelectedEvent$1 = async (sessionId, eventId, type) => {
|
|
1596
|
+
return chatStorageWorkerClientDependencies.invoke('ChatStorage.loadSelectedEvent', sessionId, eventId, type);
|
|
1597
|
+
};
|
|
1598
|
+
|
|
1178
1599
|
// cspell:ignore IDBP
|
|
1179
1600
|
|
|
1180
|
-
const startedEventType
|
|
1181
|
-
const finishedEventType
|
|
1601
|
+
const startedEventType = 'tool-execution-started';
|
|
1602
|
+
const finishedEventType = 'tool-execution-finished';
|
|
1182
1603
|
const getRawEventBySessionIdAndEventId = async (store, sessionId, sessionIdIndexName, eventId) => {
|
|
1183
1604
|
if (eventId < 1) {
|
|
1184
1605
|
return undefined;
|
|
@@ -1200,18 +1621,18 @@ const getRawEventBySessionIdAndEventId = async (store, sessionId, sessionIdIndex
|
|
|
1200
1621
|
const events = all.filter(event => event.sessionId === sessionId);
|
|
1201
1622
|
return events[eventId - 1];
|
|
1202
1623
|
};
|
|
1203
|
-
const getTimestamp
|
|
1624
|
+
const getTimestamp = value => {
|
|
1204
1625
|
return typeof value === 'string' || typeof value === 'number' ? value : undefined;
|
|
1205
1626
|
};
|
|
1206
|
-
const hasMatchingToolName
|
|
1627
|
+
const hasMatchingToolName = (startedEvent, finishedEvent) => {
|
|
1207
1628
|
if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
|
|
1208
1629
|
return startedEvent.toolName === finishedEvent.toolName;
|
|
1209
1630
|
}
|
|
1210
1631
|
return true;
|
|
1211
1632
|
};
|
|
1212
|
-
const mergeToolExecutionEvents
|
|
1213
|
-
const ended = getTimestamp
|
|
1214
|
-
const started = getTimestamp
|
|
1633
|
+
const mergeToolExecutionEvents = (startedEvent, finishedEvent, eventId) => {
|
|
1634
|
+
const ended = getTimestamp(finishedEvent.ended) ?? getTimestamp(finishedEvent.endTime) ?? getTimestamp(finishedEvent.timestamp);
|
|
1635
|
+
const started = getTimestamp(startedEvent.started) ?? getTimestamp(startedEvent.startTime) ?? getTimestamp(startedEvent.timestamp);
|
|
1215
1636
|
return {
|
|
1216
1637
|
...startedEvent,
|
|
1217
1638
|
...finishedEvent,
|
|
@@ -1236,20 +1657,20 @@ const getEventDetailsBySessionIdAndEventId = async (store, sessionId, sessionIdI
|
|
|
1236
1657
|
eventId
|
|
1237
1658
|
};
|
|
1238
1659
|
}
|
|
1239
|
-
if (event.type !== startedEventType
|
|
1660
|
+
if (event.type !== startedEventType) {
|
|
1240
1661
|
return {
|
|
1241
1662
|
...event,
|
|
1242
1663
|
eventId
|
|
1243
1664
|
};
|
|
1244
1665
|
}
|
|
1245
1666
|
const nextEvent = await getRawEventBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId + 1);
|
|
1246
|
-
if (!nextEvent || nextEvent.type !== finishedEventType
|
|
1667
|
+
if (!nextEvent || nextEvent.type !== finishedEventType || nextEvent.sessionId !== sessionId || !hasMatchingToolName(event, nextEvent)) {
|
|
1247
1668
|
return {
|
|
1248
1669
|
...event,
|
|
1249
1670
|
eventId
|
|
1250
1671
|
};
|
|
1251
1672
|
}
|
|
1252
|
-
return mergeToolExecutionEvents
|
|
1673
|
+
return mergeToolExecutionEvents(event, nextEvent, eventId);
|
|
1253
1674
|
};
|
|
1254
1675
|
|
|
1255
1676
|
const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
|
|
@@ -1473,381 +1894,64 @@ const cursorIteratorTraps = {
|
|
|
1473
1894
|
return cachedFunc;
|
|
1474
1895
|
}
|
|
1475
1896
|
};
|
|
1476
|
-
async function* iterate(...args) {
|
|
1477
|
-
// tslint:disable-next-line:no-this-assignment
|
|
1478
|
-
let cursor = this;
|
|
1479
|
-
if (!(cursor instanceof IDBCursor)) {
|
|
1480
|
-
cursor = await cursor.openCursor(...args);
|
|
1481
|
-
}
|
|
1482
|
-
if (!cursor) return;
|
|
1483
|
-
cursor = cursor;
|
|
1484
|
-
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
|
|
1485
|
-
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
|
|
1486
|
-
// Map this double-proxy back to the original, so other cursor methods work.
|
|
1487
|
-
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
|
|
1488
|
-
while (cursor) {
|
|
1489
|
-
yield proxiedCursor;
|
|
1490
|
-
// If one of the advancing methods was not called, call continue().
|
|
1491
|
-
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
|
|
1492
|
-
advanceResults.delete(proxiedCursor);
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
function isIteratorProp(target, prop) {
|
|
1496
|
-
return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
|
|
1497
|
-
}
|
|
1498
|
-
replaceTraps(oldTraps => ({
|
|
1499
|
-
...oldTraps,
|
|
1500
|
-
get(target, prop, receiver) {
|
|
1501
|
-
if (isIteratorProp(target, prop)) return iterate;
|
|
1502
|
-
return oldTraps.get(target, prop, receiver);
|
|
1503
|
-
},
|
|
1504
|
-
has(target, prop) {
|
|
1505
|
-
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
|
|
1506
|
-
}
|
|
1507
|
-
}));
|
|
1508
|
-
|
|
1509
|
-
const openDatabaseDependencies = {
|
|
1510
|
-
openDB: openDB
|
|
1511
|
-
};
|
|
1512
|
-
const openDatabase = async (databaseName, dataBaseVersion) => {
|
|
1513
|
-
return openDatabaseDependencies.openDB(databaseName, dataBaseVersion);
|
|
1514
|
-
};
|
|
1515
|
-
|
|
1516
|
-
const loadSelectedEventDependencies = {
|
|
1517
|
-
getEventDetailsBySessionIdAndEventId: getEventDetailsBySessionIdAndEventId,
|
|
1518
|
-
openDatabase: openDatabase
|
|
1519
|
-
};
|
|
1520
|
-
const loadSelectedEvent = async (databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, eventId, type) => {
|
|
1521
|
-
const database = await loadSelectedEventDependencies.openDatabase(databaseName, dataBaseVersion);
|
|
1522
|
-
try {
|
|
1523
|
-
if (!database.objectStoreNames.contains(eventStoreName)) {
|
|
1524
|
-
return null;
|
|
1525
|
-
}
|
|
1526
|
-
const transaction = database.transaction(eventStoreName, 'readonly');
|
|
1527
|
-
const store = transaction.objectStore(eventStoreName);
|
|
1528
|
-
const event = await loadSelectedEventDependencies.getEventDetailsBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId, type);
|
|
1529
|
-
return event ?? null;
|
|
1530
|
-
} finally {
|
|
1531
|
-
database.close();
|
|
1532
|
-
}
|
|
1533
|
-
};
|
|
1534
|
-
|
|
1535
|
-
const hasMatchingToolName = (startedEvent, finishedEvent) => {
|
|
1536
|
-
if (typeof startedEvent.toolName === 'string' && typeof finishedEvent.toolName === 'string') {
|
|
1537
|
-
return startedEvent.toolName === finishedEvent.toolName;
|
|
1538
|
-
}
|
|
1539
|
-
return true;
|
|
1540
|
-
};
|
|
1541
|
-
|
|
1542
|
-
const isMatchingToolExecutionPair = (startedEvent, finishedEvent) => {
|
|
1543
|
-
return startedEvent.sessionId === finishedEvent.sessionId && hasMatchingToolName(startedEvent, finishedEvent);
|
|
1544
|
-
};
|
|
1545
|
-
|
|
1546
|
-
const startedEventType = 'tool-execution-started';
|
|
1547
|
-
const finishedEventType = 'tool-execution-finished';
|
|
1548
|
-
const mergedEventType = 'tool-execution';
|
|
1549
|
-
|
|
1550
|
-
const isToolExecutionFinishedEvent = event => {
|
|
1551
|
-
return event.type === finishedEventType;
|
|
1552
|
-
};
|
|
1553
|
-
|
|
1554
|
-
const isToolExecutionStartedEvent = event => {
|
|
1555
|
-
return event.type === startedEventType;
|
|
1556
|
-
};
|
|
1557
|
-
|
|
1558
|
-
const getTimestamp = value => {
|
|
1559
|
-
return typeof value === 'string' || typeof value === 'number' ? value : undefined;
|
|
1560
|
-
};
|
|
1561
|
-
|
|
1562
|
-
const getEndedTimestamp = event => {
|
|
1563
|
-
return getTimestamp(event.ended) ?? getTimestamp(event.endTime) ?? getTimestamp(event.endTimestamp) ?? getTimestamp(event.timestamp);
|
|
1564
|
-
};
|
|
1565
|
-
|
|
1566
|
-
const eventStableIds = new WeakMap();
|
|
1567
|
-
const eventStableIdState = {
|
|
1568
|
-
nextStableEventId: 1
|
|
1569
|
-
};
|
|
1570
|
-
|
|
1571
|
-
const getOrCreateStableEventId = event => {
|
|
1572
|
-
const existingStableEventId = eventStableIds.get(event);
|
|
1573
|
-
if (existingStableEventId) {
|
|
1574
|
-
return existingStableEventId;
|
|
1575
|
-
}
|
|
1576
|
-
const stableEventId = `event-${eventStableIdState.nextStableEventId++}`;
|
|
1577
|
-
eventStableIds.set(event, stableEventId);
|
|
1578
|
-
return stableEventId;
|
|
1579
|
-
};
|
|
1580
|
-
|
|
1581
|
-
const getStartedTimestamp = event => {
|
|
1582
|
-
return getTimestamp(event.started) ?? getTimestamp(event.startTime) ?? getTimestamp(event.startTimestamp) ?? getTimestamp(event.timestamp);
|
|
1583
|
-
};
|
|
1584
|
-
|
|
1585
|
-
const setStableEventId = (event, stableEventId) => {
|
|
1586
|
-
eventStableIds.set(event, stableEventId);
|
|
1587
|
-
};
|
|
1588
|
-
|
|
1589
|
-
const mergeToolExecutionEvents = (startedEvent, finishedEvent) => {
|
|
1590
|
-
const ended = getEndedTimestamp(finishedEvent);
|
|
1591
|
-
const {
|
|
1592
|
-
eventId
|
|
1593
|
-
} = startedEvent;
|
|
1594
|
-
const started = getStartedTimestamp(startedEvent);
|
|
1595
|
-
const mergedEvent = {
|
|
1596
|
-
...startedEvent,
|
|
1597
|
-
...finishedEvent,
|
|
1598
|
-
...(ended === undefined ? {} : {
|
|
1599
|
-
ended
|
|
1600
|
-
}),
|
|
1601
|
-
...(eventId === undefined ? {} : {
|
|
1602
|
-
eventId
|
|
1603
|
-
}),
|
|
1604
|
-
...(started === undefined ? {} : {
|
|
1605
|
-
started
|
|
1606
|
-
}),
|
|
1607
|
-
type: mergedEventType
|
|
1608
|
-
};
|
|
1609
|
-
const stableEventId = `${getOrCreateStableEventId(startedEvent)}:${getOrCreateStableEventId(finishedEvent)}`;
|
|
1610
|
-
setStableEventId(mergedEvent, stableEventId);
|
|
1611
|
-
return mergedEvent;
|
|
1612
|
-
};
|
|
1613
|
-
|
|
1614
|
-
const getStableEventId = event => {
|
|
1615
|
-
return getOrCreateStableEventId(event);
|
|
1616
|
-
};
|
|
1617
|
-
|
|
1618
|
-
const collapseToolExecutionEvents = events => {
|
|
1619
|
-
const collapsedEvents = [];
|
|
1620
|
-
for (let i = 0; i < events.length; i++) {
|
|
1621
|
-
const event = events[i];
|
|
1622
|
-
if (isToolExecutionStartedEvent(event)) {
|
|
1623
|
-
const nextEvent = events[i + 1];
|
|
1624
|
-
if (nextEvent && isToolExecutionFinishedEvent(nextEvent) && isMatchingToolExecutionPair(event, nextEvent)) {
|
|
1625
|
-
collapsedEvents.push(mergeToolExecutionEvents(event, nextEvent));
|
|
1626
|
-
i++;
|
|
1627
|
-
continue;
|
|
1628
|
-
}
|
|
1629
|
-
}
|
|
1630
|
-
collapsedEvents.push(event);
|
|
1631
|
-
}
|
|
1632
|
-
return collapsedEvents;
|
|
1633
|
-
};
|
|
1634
|
-
|
|
1635
|
-
const getVisibleEvents = (events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
|
|
1636
|
-
return events.filter(event => {
|
|
1637
|
-
if (!showInputEvents && event.type === 'handle-input') {
|
|
1638
|
-
return false;
|
|
1639
|
-
}
|
|
1640
|
-
if (!showResponsePartEvents && event.type === 'sse-response-part') {
|
|
1641
|
-
return false;
|
|
1642
|
-
}
|
|
1643
|
-
if (!showEventStreamFinishedEvents && event.type === 'event-stream-finished') {
|
|
1644
|
-
return false;
|
|
1645
|
-
}
|
|
1646
|
-
// hide session creation events by default — not useful in the debug view
|
|
1647
|
-
if (event.type === 'chat-session-created') {
|
|
1648
|
-
return false;
|
|
1649
|
-
}
|
|
1650
|
-
return true;
|
|
1651
|
-
});
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
const isNetworkEvent = event => {
|
|
1655
|
-
const normalizedType = event.type.toLowerCase();
|
|
1656
|
-
return normalizedType === 'request' || normalizedType === 'response' || normalizedType === 'handle-response' || normalizedType.includes('fetch') || normalizedType.includes('xhr');
|
|
1657
|
-
};
|
|
1658
|
-
|
|
1659
|
-
const isStreamEvent = event => {
|
|
1660
|
-
return event.type === 'sse-response-part' || event.type === 'event-stream-finished';
|
|
1661
|
-
};
|
|
1662
|
-
|
|
1663
|
-
const toolEventTypePrefix = 'tool-execution';
|
|
1664
|
-
const isToolEvent = event => {
|
|
1665
|
-
return event.type.startsWith(toolEventTypePrefix);
|
|
1666
|
-
};
|
|
1667
|
-
|
|
1668
|
-
const isUiEvent = event => {
|
|
1669
|
-
return event.type.startsWith('handle-') && event.type !== 'handle-response';
|
|
1670
|
-
};
|
|
1671
|
-
|
|
1672
|
-
const matchesEventCategoryFilter = (event, eventCategoryFilter) => {
|
|
1673
|
-
switch (eventCategoryFilter) {
|
|
1674
|
-
case Network:
|
|
1675
|
-
return isNetworkEvent(event);
|
|
1676
|
-
case Stream:
|
|
1677
|
-
return isStreamEvent(event);
|
|
1678
|
-
case Tools:
|
|
1679
|
-
return isToolEvent(event);
|
|
1680
|
-
case Ui:
|
|
1681
|
-
return isUiEvent(event);
|
|
1682
|
-
default:
|
|
1683
|
-
return true;
|
|
1684
|
-
}
|
|
1685
|
-
};
|
|
1686
|
-
|
|
1687
|
-
const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents) => {
|
|
1688
|
-
const visibleEvents = getVisibleEvents(events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
|
|
1689
|
-
const collapsedEvents = collapseToolExecutionEvents(visibleEvents);
|
|
1690
|
-
const parsedFilter = parseFilterValue(filterValue);
|
|
1691
|
-
const activeEventCategoryFilter = parsedFilter.eventCategoryFilter === All ? eventCategoryFilter : parsedFilter.eventCategoryFilter;
|
|
1692
|
-
const filteredByCategory = collapsedEvents.filter(event => matchesEventCategoryFilter(event, activeEventCategoryFilter));
|
|
1693
|
-
const {
|
|
1694
|
-
filterText
|
|
1695
|
-
} = parsedFilter;
|
|
1696
|
-
if (!filterText) {
|
|
1697
|
-
return filteredByCategory;
|
|
1897
|
+
async function* iterate(...args) {
|
|
1898
|
+
// tslint:disable-next-line:no-this-assignment
|
|
1899
|
+
let cursor = this;
|
|
1900
|
+
if (!(cursor instanceof IDBCursor)) {
|
|
1901
|
+
cursor = await cursor.openCursor(...args);
|
|
1698
1902
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1903
|
+
if (!cursor) return;
|
|
1904
|
+
cursor = cursor;
|
|
1905
|
+
const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);
|
|
1906
|
+
ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);
|
|
1907
|
+
// Map this double-proxy back to the original, so other cursor methods work.
|
|
1908
|
+
reverseTransformCache.set(proxiedCursor, unwrap(cursor));
|
|
1909
|
+
while (cursor) {
|
|
1910
|
+
yield proxiedCursor;
|
|
1911
|
+
// If one of the advancing methods was not called, call continue().
|
|
1912
|
+
cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());
|
|
1913
|
+
advanceResults.delete(proxiedCursor);
|
|
1705
1914
|
}
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1915
|
+
}
|
|
1916
|
+
function isIteratorProp(target, prop) {
|
|
1917
|
+
return prop === Symbol.asyncIterator && instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor]) || prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore]);
|
|
1918
|
+
}
|
|
1919
|
+
replaceTraps(oldTraps => ({
|
|
1920
|
+
...oldTraps,
|
|
1921
|
+
get(target, prop, receiver) {
|
|
1922
|
+
if (isIteratorProp(target, prop)) return iterate;
|
|
1923
|
+
return oldTraps.get(target, prop, receiver);
|
|
1924
|
+
},
|
|
1925
|
+
has(target, prop) {
|
|
1926
|
+
return isIteratorProp(target, prop) || oldTraps.has(target, prop);
|
|
1711
1927
|
}
|
|
1712
|
-
|
|
1713
|
-
};
|
|
1928
|
+
}));
|
|
1714
1929
|
|
|
1715
|
-
const
|
|
1716
|
-
|
|
1930
|
+
const openDatabaseDependencies = {
|
|
1931
|
+
openDB: openDB
|
|
1717
1932
|
};
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
const parseTimelineSeconds = value => {
|
|
1721
|
-
const trimmed = value.trim();
|
|
1722
|
-
if (!trimmed) {
|
|
1723
|
-
return undefined;
|
|
1724
|
-
}
|
|
1725
|
-
const parsed = Number.parseFloat(trimmed);
|
|
1726
|
-
if (!Number.isFinite(parsed) || parsed < 0) {
|
|
1727
|
-
return undefined;
|
|
1728
|
-
}
|
|
1729
|
-
return parsed;
|
|
1933
|
+
const openDatabase = async (databaseName, dataBaseVersion) => {
|
|
1934
|
+
return openDatabaseDependencies.openDB(databaseName, dataBaseVersion);
|
|
1730
1935
|
};
|
|
1731
|
-
|
|
1732
|
-
|
|
1936
|
+
|
|
1937
|
+
const loadSelectedEventDependencies = {
|
|
1938
|
+
getEventDetailsBySessionIdAndEventId: getEventDetailsBySessionIdAndEventId,
|
|
1939
|
+
loadSelectedEventFromWorker: loadSelectedEvent$1,
|
|
1940
|
+
openDatabase: openDatabase
|
|
1733
1941
|
};
|
|
1734
|
-
const
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
if (
|
|
1738
|
-
return
|
|
1942
|
+
const loadSelectedEvent = async (databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, eventId, type) => {
|
|
1943
|
+
const database = await loadSelectedEventDependencies.openDatabase(databaseName, dataBaseVersion);
|
|
1944
|
+
try {
|
|
1945
|
+
if (!database.objectStoreNames.contains(eventStoreName)) {
|
|
1946
|
+
return null;
|
|
1739
1947
|
}
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
const getTimelineDurationSeconds = events => {
|
|
1747
|
-
const eventsWithTime = getEventsWithTime(events);
|
|
1748
|
-
if (eventsWithTime.length === 0) {
|
|
1749
|
-
return 0;
|
|
1750
|
-
}
|
|
1751
|
-
const baseTime = eventsWithTime[0].time;
|
|
1752
|
-
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1753
|
-
return roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
|
|
1754
|
-
};
|
|
1755
|
-
const getSelectionPercent = (value, durationSeconds) => {
|
|
1756
|
-
if (durationSeconds <= 0) {
|
|
1757
|
-
return 0;
|
|
1758
|
-
}
|
|
1759
|
-
return Number((value / durationSeconds * 100).toFixed(3));
|
|
1760
|
-
};
|
|
1761
|
-
const getNormalizedRange = (durationSeconds, startValue, endValue) => {
|
|
1762
|
-
const parsedStart = parseTimelineSeconds(startValue);
|
|
1763
|
-
const parsedEnd = parseTimelineSeconds(endValue);
|
|
1764
|
-
if (parsedStart === undefined && parsedEnd === undefined) {
|
|
1765
|
-
return {
|
|
1766
|
-
endSeconds: null,
|
|
1767
|
-
hasSelection: false,
|
|
1768
|
-
startSeconds: null
|
|
1769
|
-
};
|
|
1770
|
-
}
|
|
1771
|
-
const rawStart = parsedStart ?? 0;
|
|
1772
|
-
const rawEnd = parsedEnd ?? durationSeconds;
|
|
1773
|
-
const normalizedStart = Math.max(0, Math.min(durationSeconds, Math.min(rawStart, rawEnd)));
|
|
1774
|
-
const normalizedEnd = Math.max(0, Math.min(durationSeconds, Math.max(rawStart, rawEnd)));
|
|
1775
|
-
return {
|
|
1776
|
-
endSeconds: roundSeconds(normalizedEnd),
|
|
1777
|
-
hasSelection: true,
|
|
1778
|
-
startSeconds: roundSeconds(normalizedStart)
|
|
1779
|
-
};
|
|
1780
|
-
};
|
|
1781
|
-
const filterEventsByTimelineRange = (events, startValue, endValue) => {
|
|
1782
|
-
const eventsWithTime = getEventsWithTime(events);
|
|
1783
|
-
if (eventsWithTime.length === 0) {
|
|
1784
|
-
return events;
|
|
1785
|
-
}
|
|
1786
|
-
const baseTime = eventsWithTime[0].time;
|
|
1787
|
-
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1788
|
-
const durationSeconds = roundSeconds(Math.max(0, lastTime - baseTime) / 1000);
|
|
1789
|
-
const range = getNormalizedRange(durationSeconds, startValue, endValue);
|
|
1790
|
-
if (!range.hasSelection || range.startSeconds === null || range.endSeconds === null) {
|
|
1791
|
-
return events;
|
|
1792
|
-
}
|
|
1793
|
-
const startTime = baseTime + range.startSeconds * 1000;
|
|
1794
|
-
const endTime = baseTime + range.endSeconds * 1000;
|
|
1795
|
-
return eventsWithTime.filter(item => item.time >= startTime && item.time <= endTime).map(item => item.event);
|
|
1796
|
-
};
|
|
1797
|
-
const getTimelineInfo = (events, startValue, endValue) => {
|
|
1798
|
-
const eventsWithTime = getEventsWithTime(events);
|
|
1799
|
-
if (eventsWithTime.length === 0) {
|
|
1800
|
-
return {
|
|
1801
|
-
buckets: [],
|
|
1802
|
-
durationSeconds: 0,
|
|
1803
|
-
endSeconds: null,
|
|
1804
|
-
hasSelection: false,
|
|
1805
|
-
selectionEndPercent: null,
|
|
1806
|
-
selectionStartPercent: null,
|
|
1807
|
-
startSeconds: null
|
|
1808
|
-
};
|
|
1809
|
-
}
|
|
1810
|
-
const baseTime = eventsWithTime[0].time;
|
|
1811
|
-
const lastTime = eventsWithTime.at(-1)?.time ?? baseTime;
|
|
1812
|
-
const durationMs = Math.max(0, lastTime - baseTime);
|
|
1813
|
-
const durationSeconds = roundSeconds(durationMs / 1000);
|
|
1814
|
-
const range = getNormalizedRange(durationSeconds, startValue, endValue);
|
|
1815
|
-
const bucketCount = durationSeconds === 0 ? 1 : Math.max(12, Math.min(48, Math.ceil(durationSeconds)));
|
|
1816
|
-
const bucketDurationMs = durationMs === 0 ? 1000 : durationMs / bucketCount;
|
|
1817
|
-
const counts = Array.from({
|
|
1818
|
-
length: bucketCount
|
|
1819
|
-
}).fill(0);
|
|
1820
|
-
for (const item of eventsWithTime) {
|
|
1821
|
-
const offsetMs = item.time - baseTime;
|
|
1822
|
-
const index = durationMs === 0 ? 0 : Math.min(bucketCount - 1, Math.floor(offsetMs / durationMs * bucketCount));
|
|
1823
|
-
counts[index] += 1;
|
|
1948
|
+
const transaction = database.transaction(eventStoreName, 'readonly');
|
|
1949
|
+
const store = transaction.objectStore(eventStoreName);
|
|
1950
|
+
const event = await loadSelectedEventDependencies.getEventDetailsBySessionIdAndEventId(store, sessionId, sessionIdIndexName, eventId, type);
|
|
1951
|
+
return event ?? null;
|
|
1952
|
+
} finally {
|
|
1953
|
+
database.close();
|
|
1824
1954
|
}
|
|
1825
|
-
const maxCount = Math.max(...counts);
|
|
1826
|
-
const selectionStartPercent = range.hasSelection && range.startSeconds !== null ? getSelectionPercent(range.startSeconds, durationSeconds) : null;
|
|
1827
|
-
const selectionEndPercent = range.hasSelection && range.endSeconds !== null ? getSelectionPercent(range.endSeconds, durationSeconds) : null;
|
|
1828
|
-
const buckets = counts.map((count, index) => {
|
|
1829
|
-
const bucketStartMs = index * bucketDurationMs;
|
|
1830
|
-
const bucketEndMs = index === bucketCount - 1 ? durationMs : (index + 1) * bucketDurationMs;
|
|
1831
|
-
const hasSelection = range.hasSelection && range.startSeconds !== null && range.endSeconds !== null;
|
|
1832
|
-
const selectionStartMs = hasSelection ? range.startSeconds * 1000 : 0;
|
|
1833
|
-
const selectionEndMs = hasSelection ? range.endSeconds * 1000 : 0;
|
|
1834
|
-
return {
|
|
1835
|
-
count,
|
|
1836
|
-
endSeconds: roundSeconds(bucketEndMs / 1000),
|
|
1837
|
-
isSelected: hasSelection && bucketEndMs >= selectionStartMs && bucketStartMs <= selectionEndMs,
|
|
1838
|
-
startSeconds: roundSeconds(bucketStartMs / 1000),
|
|
1839
|
-
unitCount: count === 0 ? 0 : Math.max(1, Math.round(count / maxCount * maxBarUnits))
|
|
1840
|
-
};
|
|
1841
|
-
});
|
|
1842
|
-
return {
|
|
1843
|
-
buckets,
|
|
1844
|
-
durationSeconds,
|
|
1845
|
-
endSeconds: range.endSeconds,
|
|
1846
|
-
hasSelection: range.hasSelection,
|
|
1847
|
-
selectionEndPercent,
|
|
1848
|
-
selectionStartPercent,
|
|
1849
|
-
startSeconds: range.startSeconds
|
|
1850
|
-
};
|
|
1851
1955
|
};
|
|
1852
1956
|
|
|
1853
1957
|
const getCurrentEvents$2 = state => {
|
|
@@ -1895,7 +1999,7 @@ const parseSelectedEventIndex$1 = value => {
|
|
|
1895
1999
|
}
|
|
1896
2000
|
return parsed;
|
|
1897
2001
|
};
|
|
1898
|
-
const handleEventRowClick = async (state, value, button) => {
|
|
2002
|
+
const handleEventRowClick = async (state, value, button = 0) => {
|
|
1899
2003
|
if (!isPrimaryButton(button)) {
|
|
1900
2004
|
return state;
|
|
1901
2005
|
}
|
|
@@ -1931,7 +2035,7 @@ const getCurrentEvents$1 = state => {
|
|
|
1931
2035
|
const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
|
|
1932
2036
|
return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
|
|
1933
2037
|
};
|
|
1934
|
-
const parseTimelineRangePreset = value => {
|
|
2038
|
+
const parseTimelineRangePreset$1 = value => {
|
|
1935
2039
|
if (!value) {
|
|
1936
2040
|
return {
|
|
1937
2041
|
timelineEndSeconds: '',
|
|
@@ -2074,7 +2178,7 @@ const handleInput = (state, name, value, checked) => {
|
|
|
2074
2178
|
if (name === TimelineRangePreset) {
|
|
2075
2179
|
const nextState = {
|
|
2076
2180
|
...state,
|
|
2077
|
-
...parseTimelineRangePreset(value)
|
|
2181
|
+
...parseTimelineRangePreset$1(value)
|
|
2078
2182
|
};
|
|
2079
2183
|
return withPreservedSelection(state, nextState);
|
|
2080
2184
|
}
|
|
@@ -2126,8 +2230,43 @@ const clearTimelineSelectionState = state => {
|
|
|
2126
2230
|
};
|
|
2127
2231
|
};
|
|
2128
2232
|
|
|
2233
|
+
const parseTimelineRangePreset = value => {
|
|
2234
|
+
if (!value) {
|
|
2235
|
+
return {
|
|
2236
|
+
timelineEndSeconds: '',
|
|
2237
|
+
timelineStartSeconds: ''
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
const [timelineStartSeconds = '', timelineEndSeconds = ''] = value.split(':', 2);
|
|
2241
|
+
return {
|
|
2242
|
+
timelineEndSeconds,
|
|
2243
|
+
timelineStartSeconds
|
|
2244
|
+
};
|
|
2245
|
+
};
|
|
2246
|
+
const handleTimelineStartSeconds = (state, value) => {
|
|
2247
|
+
const nextState = {
|
|
2248
|
+
...state,
|
|
2249
|
+
timelineStartSeconds: value
|
|
2250
|
+
};
|
|
2251
|
+
return withPreservedSelection$1(state, nextState);
|
|
2252
|
+
};
|
|
2253
|
+
const handleTimelineEndSeconds = (state, value) => {
|
|
2254
|
+
const nextState = {
|
|
2255
|
+
...state,
|
|
2256
|
+
timelineEndSeconds: value
|
|
2257
|
+
};
|
|
2258
|
+
return withPreservedSelection$1(state, nextState);
|
|
2259
|
+
};
|
|
2260
|
+
const handleTimelineRangePreset = (state, value) => {
|
|
2261
|
+
const nextState = {
|
|
2262
|
+
...state,
|
|
2263
|
+
...parseTimelineRangePreset(value)
|
|
2264
|
+
};
|
|
2265
|
+
return withPreservedSelection$1(state, nextState);
|
|
2266
|
+
};
|
|
2267
|
+
|
|
2129
2268
|
const handleTimelineDoubleClick = state => {
|
|
2130
|
-
const nextState =
|
|
2269
|
+
const nextState = handleTimelineRangePreset(state, '');
|
|
2131
2270
|
return clearTimelineSelectionState(nextState);
|
|
2132
2271
|
};
|
|
2133
2272
|
|
|
@@ -2217,10 +2356,44 @@ const handleTimelinePointerUp = (state, eventX) => {
|
|
|
2217
2356
|
const focus = Number.parseFloat(focusSeconds);
|
|
2218
2357
|
const startSeconds = formatTimelinePresetValue(Math.min(anchor, focus));
|
|
2219
2358
|
const endSeconds = formatTimelinePresetValue(Math.max(anchor, focus));
|
|
2220
|
-
const nextState =
|
|
2359
|
+
const nextState = handleTimelineRangePreset(state, `${startSeconds}:${endSeconds}`);
|
|
2221
2360
|
return clearTimelineSelectionState(nextState);
|
|
2222
2361
|
};
|
|
2223
2362
|
|
|
2363
|
+
const handleUseDevtoolsLayout = (state, checked) => {
|
|
2364
|
+
const useDevtoolsLayout = getBoolean(checked);
|
|
2365
|
+
const selectedEventIndex = useDevtoolsLayout ? getSelectedEventIndex$1(state) : null;
|
|
2366
|
+
return {
|
|
2367
|
+
...state,
|
|
2368
|
+
selectedEvent: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEvent : null,
|
|
2369
|
+
selectedEventId: useDevtoolsLayout && selectedEventIndex !== null ? state.selectedEventId : null,
|
|
2370
|
+
selectedEventIndex,
|
|
2371
|
+
useDevtoolsLayout
|
|
2372
|
+
};
|
|
2373
|
+
};
|
|
2374
|
+
|
|
2375
|
+
const handleShowEventStreamFinishedEvents = (state, checked) => {
|
|
2376
|
+
const nextState = {
|
|
2377
|
+
...state,
|
|
2378
|
+
showEventStreamFinishedEvents: getBoolean(checked)
|
|
2379
|
+
};
|
|
2380
|
+
return withPreservedSelection$1(state, nextState);
|
|
2381
|
+
};
|
|
2382
|
+
const handleShowInputEvents = (state, checked) => {
|
|
2383
|
+
const nextState = {
|
|
2384
|
+
...state,
|
|
2385
|
+
showInputEvents: getBoolean(checked)
|
|
2386
|
+
};
|
|
2387
|
+
return withPreservedSelection$1(state, nextState);
|
|
2388
|
+
};
|
|
2389
|
+
const handleShowResponsePartEvents = (state, checked) => {
|
|
2390
|
+
const nextState = {
|
|
2391
|
+
...state,
|
|
2392
|
+
showResponsePartEvents: getBoolean(checked)
|
|
2393
|
+
};
|
|
2394
|
+
return withPreservedSelection$1(state, nextState);
|
|
2395
|
+
};
|
|
2396
|
+
|
|
2224
2397
|
const getFailedToLoadMessage = sessionId => {
|
|
2225
2398
|
return `Failed to load chat debug session "${sessionId}". Please try again.`;
|
|
2226
2399
|
};
|
|
@@ -2342,6 +2515,7 @@ const isIndexedDbSupported = indexedDbSupportOverride => {
|
|
|
2342
2515
|
|
|
2343
2516
|
const listChatViewEventsDependencies = {
|
|
2344
2517
|
getEventsBySessionId: getEventsBySessionId,
|
|
2518
|
+
listChatViewEventsFromWorker: listChatViewEvents$1,
|
|
2345
2519
|
openDatabase: openDatabase
|
|
2346
2520
|
};
|
|
2347
2521
|
const listChatViewEvents = async (sessionId, databaseName, dataBaseVersion, eventStoreName, sessionIdIndexName, indexedDbSupportOverride) => {
|
|
@@ -2588,7 +2762,6 @@ const Reference = 100;
|
|
|
2588
2762
|
|
|
2589
2763
|
const ClientX = 'event.clientX';
|
|
2590
2764
|
const ClientY = 'event.clientY';
|
|
2591
|
-
const TargetChecked = 'event.target.checked';
|
|
2592
2765
|
const TargetName = 'event.target.name';
|
|
2593
2766
|
const TargetValue = 'event.target.value';
|
|
2594
2767
|
|
|
@@ -3715,9 +3888,9 @@ const getDebugErrorDom = errorMessage => {
|
|
|
3715
3888
|
}, text(errorMessage)];
|
|
3716
3889
|
};
|
|
3717
3890
|
|
|
3718
|
-
const
|
|
3891
|
+
const HandleEventCategoryFilter = 4;
|
|
3719
3892
|
const HandleFilterInput = 5;
|
|
3720
|
-
const
|
|
3893
|
+
const HandleDetailTab = 6;
|
|
3721
3894
|
const HandleEventRowClick = 7;
|
|
3722
3895
|
const HandleHeaderContextMenu = 8;
|
|
3723
3896
|
const HandleSashPointerDown = 9;
|
|
@@ -3730,6 +3903,8 @@ const HandleTimelinePointerMove = 15;
|
|
|
3730
3903
|
const HandleTimelinePointerUp = 16;
|
|
3731
3904
|
const HandleTimelineDoubleClick = 17;
|
|
3732
3905
|
const HandleTableKeyDown = 18;
|
|
3906
|
+
const HandleTimelineRangePreset = 19;
|
|
3907
|
+
const HandleCloseDetails = 20;
|
|
3733
3908
|
|
|
3734
3909
|
const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) => {
|
|
3735
3910
|
if (useDevtoolsLayout) {
|
|
@@ -3857,8 +4032,8 @@ const getTabNodes = selectedDetailTab => {
|
|
|
3857
4032
|
className: joinClassNames(ChatDebugViewDetailsTab, isSelected && ChatDebugViewDetailsTabSelected),
|
|
3858
4033
|
id: getTabId(detailTab),
|
|
3859
4034
|
name: DetailTab,
|
|
3860
|
-
onChange:
|
|
3861
|
-
onClick:
|
|
4035
|
+
onChange: HandleDetailTab,
|
|
4036
|
+
onClick: HandleDetailTab,
|
|
3862
4037
|
role: 'tab',
|
|
3863
4038
|
tabIndex: isSelected ? 0 : -1,
|
|
3864
4039
|
type: Button,
|
|
@@ -3884,8 +4059,8 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
|
|
|
3884
4059
|
childCount: 0,
|
|
3885
4060
|
className: ChatDebugViewDetailsClose,
|
|
3886
4061
|
name: CloseDetails,
|
|
3887
|
-
onChange:
|
|
3888
|
-
onClick:
|
|
4062
|
+
onChange: HandleCloseDetails,
|
|
4063
|
+
onClick: HandleCloseDetails,
|
|
3889
4064
|
type: Button,
|
|
3890
4065
|
value: 'close'
|
|
3891
4066
|
}, {
|
|
@@ -4316,7 +4491,7 @@ const getBucketDom = bucket => {
|
|
|
4316
4491
|
className: ChatDebugViewTimelinePresetInput,
|
|
4317
4492
|
inputType: 'radio',
|
|
4318
4493
|
name: TimelineRangePreset,
|
|
4319
|
-
onChange:
|
|
4494
|
+
onChange: HandleTimelineRangePreset,
|
|
4320
4495
|
type: Input,
|
|
4321
4496
|
value: presetValue
|
|
4322
4497
|
}, {
|
|
@@ -4466,7 +4641,7 @@ const getQuickFilterNodes = (eventCategoryFilter, eventCategoryFilterOptions) =>
|
|
|
4466
4641
|
className: ChatDebugViewQuickFilterInput,
|
|
4467
4642
|
inputType: 'radio',
|
|
4468
4643
|
name: EventCategoryFilter,
|
|
4469
|
-
onChange:
|
|
4644
|
+
onChange: HandleEventCategoryFilter,
|
|
4470
4645
|
type: Input,
|
|
4471
4646
|
value: option.value
|
|
4472
4647
|
}, text(option.label)];
|
|
@@ -4593,11 +4768,17 @@ const renderEventListeners = () => {
|
|
|
4593
4768
|
name: HandleFilterInput,
|
|
4594
4769
|
params: ['handleInput', TargetName, TargetValue]
|
|
4595
4770
|
}, {
|
|
4596
|
-
name:
|
|
4597
|
-
params: ['
|
|
4771
|
+
name: HandleEventCategoryFilter,
|
|
4772
|
+
params: ['handleEventCategoryFilter', TargetValue]
|
|
4598
4773
|
}, {
|
|
4599
|
-
name:
|
|
4600
|
-
params: ['
|
|
4774
|
+
name: HandleDetailTab,
|
|
4775
|
+
params: ['handleDetailTab', TargetValue]
|
|
4776
|
+
}, {
|
|
4777
|
+
name: HandleTimelineRangePreset,
|
|
4778
|
+
params: ['handleTimelineRangePreset', TargetValue]
|
|
4779
|
+
}, {
|
|
4780
|
+
name: HandleCloseDetails,
|
|
4781
|
+
params: ['handleCloseDetails']
|
|
4601
4782
|
}, {
|
|
4602
4783
|
name: HandleSashPointerDown,
|
|
4603
4784
|
params: ['handleSashPointerDown', ClientX, ClientY],
|
|
@@ -4694,8 +4875,11 @@ const setIndexedDbSupportForTest = supported => {
|
|
|
4694
4875
|
return setIndexedDbSupportOverride(supported);
|
|
4695
4876
|
};
|
|
4696
4877
|
|
|
4878
|
+
const setSessionIdDependencies = {
|
|
4879
|
+
listChatViewEvents: listChatViewEvents
|
|
4880
|
+
};
|
|
4697
4881
|
const setSessionId = async (state, sessionId) => {
|
|
4698
|
-
const result = await listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName);
|
|
4882
|
+
const result = await setSessionIdDependencies.listChatViewEvents(sessionId, state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionIdIndexName, state.indexedDbSupportOverride);
|
|
4699
4883
|
if (result.type === 'not-supported') {
|
|
4700
4884
|
return {
|
|
4701
4885
|
...state,
|
|
@@ -4704,6 +4888,7 @@ const setSessionId = async (state, sessionId) => {
|
|
|
4704
4888
|
initial: false,
|
|
4705
4889
|
selectedEvent: null,
|
|
4706
4890
|
selectedEventId: null,
|
|
4891
|
+
selectedEventIndex: null,
|
|
4707
4892
|
sessionId
|
|
4708
4893
|
};
|
|
4709
4894
|
}
|
|
@@ -4715,6 +4900,7 @@ const setSessionId = async (state, sessionId) => {
|
|
|
4715
4900
|
initial: false,
|
|
4716
4901
|
selectedEvent: null,
|
|
4717
4902
|
selectedEventId: null,
|
|
4903
|
+
selectedEventIndex: null,
|
|
4718
4904
|
sessionId
|
|
4719
4905
|
};
|
|
4720
4906
|
}
|
|
@@ -4728,6 +4914,7 @@ const setSessionId = async (state, sessionId) => {
|
|
|
4728
4914
|
initial: false,
|
|
4729
4915
|
selectedEvent: null,
|
|
4730
4916
|
selectedEventId: null,
|
|
4917
|
+
selectedEventIndex: null,
|
|
4731
4918
|
sessionId
|
|
4732
4919
|
};
|
|
4733
4920
|
};
|
|
@@ -4736,18 +4923,28 @@ const commandMap = {
|
|
|
4736
4923
|
'ChatDebug.create': create,
|
|
4737
4924
|
'ChatDebug.diff2': diff2,
|
|
4738
4925
|
'ChatDebug.getCommandIds': getCommandIds,
|
|
4926
|
+
'ChatDebug.handleCloseDetails': wrapCommand(handleCloseDetails),
|
|
4739
4927
|
'ChatDebug.handleDetailsContextMenu': wrapCommand(handleDetailsContextMenu),
|
|
4928
|
+
'ChatDebug.handleDetailTab': wrapCommand(handleDetailTab),
|
|
4929
|
+
'ChatDebug.handleEventCategoryFilter': wrapCommand(handleEventCategoryFilter),
|
|
4740
4930
|
'ChatDebug.handleEventRowClick': wrapCommand(handleEventRowClick),
|
|
4741
4931
|
'ChatDebug.handleHeaderContextMenu': wrapCommand(handleHeaderContextMenu),
|
|
4742
4932
|
'ChatDebug.handleInput': wrapCommand(handleInput),
|
|
4743
4933
|
'ChatDebug.handleSashPointerDown': wrapCommand(handleSashPointerDown),
|
|
4744
4934
|
'ChatDebug.handleSashPointerMove': wrapCommand(handleSashPointerMove),
|
|
4745
4935
|
'ChatDebug.handleSashPointerUp': wrapCommand(handleSashPointerUp),
|
|
4936
|
+
'ChatDebug.handleShowEventStreamFinishedEvents': wrapCommand(handleShowEventStreamFinishedEvents),
|
|
4937
|
+
'ChatDebug.handleShowInputEvents': wrapCommand(handleShowInputEvents),
|
|
4938
|
+
'ChatDebug.handleShowResponsePartEvents': wrapCommand(handleShowResponsePartEvents),
|
|
4746
4939
|
'ChatDebug.handleTableBodyContextMenu': wrapCommand(handleTableBodyContextMenu),
|
|
4747
4940
|
'ChatDebug.handleTimelineDoubleClick': wrapCommand(handleTimelineDoubleClick),
|
|
4941
|
+
'ChatDebug.handleTimelineEndSeconds': wrapCommand(handleTimelineEndSeconds),
|
|
4748
4942
|
'ChatDebug.handleTimelinePointerDown': wrapCommand(handleTimelinePointerDown),
|
|
4749
4943
|
'ChatDebug.handleTimelinePointerMove': wrapCommand(handleTimelinePointerMove),
|
|
4750
4944
|
'ChatDebug.handleTimelinePointerUp': wrapCommand(handleTimelinePointerUp),
|
|
4945
|
+
'ChatDebug.handleTimelineRangePreset': wrapCommand(handleTimelineRangePreset),
|
|
4946
|
+
'ChatDebug.handleTimelineStartSeconds': wrapCommand(handleTimelineStartSeconds),
|
|
4947
|
+
'ChatDebug.handleUseDevtoolsLayout': wrapCommand(handleUseDevtoolsLayout),
|
|
4751
4948
|
'ChatDebug.loadContent': wrapCommand(loadContent),
|
|
4752
4949
|
'ChatDebug.loadContent2': wrapCommand(loadContent),
|
|
4753
4950
|
'ChatDebug.refresh': wrapCommand(refresh),
|
|
@@ -4764,9 +4961,10 @@ const commandMap = {
|
|
|
4764
4961
|
|
|
4765
4962
|
const listen = async () => {
|
|
4766
4963
|
registerCommands(commandMap);
|
|
4767
|
-
await create$2({
|
|
4964
|
+
const rpc = await create$2({
|
|
4768
4965
|
commandMap: commandMap
|
|
4769
4966
|
});
|
|
4967
|
+
setWorkerRpc(rpc);
|
|
4770
4968
|
};
|
|
4771
4969
|
|
|
4772
4970
|
const main = async () => {
|