@lvce-editor/chat-debug-view 7.2.0 → 7.4.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.
@@ -1139,6 +1139,10 @@ const ClientY = 'event.clientY';
1139
1139
  const TargetName = 'event.target.name';
1140
1140
  const TargetValue = 'event.target.value';
1141
1141
 
1142
+ const None = 0;
1143
+ const Checked = 2;
1144
+ const Unchecked = 3;
1145
+
1142
1146
  const ChatStorageWorker = 6003;
1143
1147
  const RendererWorker = 1;
1144
1148
 
@@ -1305,6 +1309,186 @@ const appendStoredEventForTest = async (state, event) => {
1305
1309
  return state;
1306
1310
  };
1307
1311
 
1312
+ const emptyObject = {};
1313
+ const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1314
+ const i18nString = (key, placeholders = emptyObject) => {
1315
+ if (placeholders === emptyObject) {
1316
+ return key;
1317
+ }
1318
+ const replacer = (match, rest) => {
1319
+ return placeholders[rest];
1320
+ };
1321
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
1322
+ };
1323
+
1324
+ const All$1 = 'All';
1325
+ const CloseDetails$1 = 'Close details';
1326
+ const Copy = 'Copy';
1327
+ const DetailSections = 'Detail sections';
1328
+ const Duration$1 = 'Duration';
1329
+ const Ended = 'Ended';
1330
+ const FailedToLoadChatDebugSession = 'Failed to load chat debug session "{PH1}". Please try again.';
1331
+ const FailedToLoadChatDebugSessionWithError = 'Failed to load chat debug session "{PH1}": {PH2}';
1332
+ const FilterEvents = 'Filter events';
1333
+ const FromSeconds = 'from {PH1}s';
1334
+ const InvalidSessionId = 'Invalid session id';
1335
+ const InvalidUriEncoding = 'Invalid URI encoding';
1336
+ const InvalidUriFormat = 'Invalid URI format';
1337
+ const MissingUri = 'Missing URI';
1338
+ const Network$1 = 'Network';
1339
+ const NoChatSessionFound = 'No chat session found for sessionId "{PH1}".';
1340
+ const NoEventsFound = 'No events have been found';
1341
+ const NoEventsFoundMatching = 'No events found matching {PH1}';
1342
+ const NoToolCallEvents = 'No tool call events.';
1343
+ const Preview$1 = 'Preview';
1344
+ const Refresh$1 = 'Refresh';
1345
+ const RefreshEvents = 'Refresh events';
1346
+ const ResetColumns = 'Reset columns';
1347
+ const Response$1 = 'Response';
1348
+ const SecondsRange = '{PH1}s-{PH2}s';
1349
+ const Started = 'Started';
1350
+ const Status$1 = 'Status';
1351
+ const Stream$1 = 'Stream';
1352
+ const Timing$1 = 'Timing';
1353
+ const ToSeconds = 'to {PH1}s';
1354
+ const Tools$1 = 'Tools';
1355
+ const Type$1 = 'Type';
1356
+ const Ui$1 = 'UI';
1357
+ const UnableToLoadDebugSessionInvalidUri = 'Unable to load debug session: invalid URI "{PH1}". Expected format: chat-debug://<sessionId>.';
1358
+ const UnableToLoadDebugSessionMissingUri = 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
1359
+ const WindowSummary = 'Window {PH1}-{PH2} of {PH3}';
1360
+
1361
+ const copy = () => {
1362
+ return i18nString(Copy);
1363
+ };
1364
+ const status = () => {
1365
+ return i18nString(Status$1);
1366
+ };
1367
+ const all = () => {
1368
+ return i18nString(All$1);
1369
+ };
1370
+ const closeDetails = () => {
1371
+ return i18nString(CloseDetails$1);
1372
+ };
1373
+ const detailSections = () => {
1374
+ return i18nString(DetailSections);
1375
+ };
1376
+ const duration = () => {
1377
+ return i18nString(Duration$1);
1378
+ };
1379
+ const ended = () => {
1380
+ return i18nString(Ended);
1381
+ };
1382
+ const failedToLoadChatDebugSession = sessionId => {
1383
+ return i18nString(FailedToLoadChatDebugSession, {
1384
+ PH1: sessionId
1385
+ });
1386
+ };
1387
+ const failedToLoadChatDebugSessionWithError = (sessionId, errorMessage) => {
1388
+ return i18nString(FailedToLoadChatDebugSessionWithError, {
1389
+ PH1: sessionId,
1390
+ PH2: errorMessage
1391
+ });
1392
+ };
1393
+ const filterEvents = () => {
1394
+ return i18nString(FilterEvents);
1395
+ };
1396
+ const fromSeconds = seconds => {
1397
+ return i18nString(FromSeconds, {
1398
+ PH1: seconds
1399
+ });
1400
+ };
1401
+ const invalidSessionId = () => {
1402
+ return i18nString(InvalidSessionId);
1403
+ };
1404
+ const invalidUriEncoding = () => {
1405
+ return i18nString(InvalidUriEncoding);
1406
+ };
1407
+ const invalidUriFormat = () => {
1408
+ return i18nString(InvalidUriFormat);
1409
+ };
1410
+ const missingUri = () => {
1411
+ return i18nString(MissingUri);
1412
+ };
1413
+ const network = () => {
1414
+ return i18nString(Network$1);
1415
+ };
1416
+ const noChatSessionFound = sessionId => {
1417
+ return i18nString(NoChatSessionFound, {
1418
+ PH1: sessionId
1419
+ });
1420
+ };
1421
+ const noEventsFound = () => {
1422
+ return i18nString(NoEventsFound);
1423
+ };
1424
+ const noEventsFoundMatching = filterDescription => {
1425
+ return i18nString(NoEventsFoundMatching, {
1426
+ PH1: filterDescription
1427
+ });
1428
+ };
1429
+ const noToolCallEvents = () => {
1430
+ return i18nString(NoToolCallEvents);
1431
+ };
1432
+ const preview = () => {
1433
+ return i18nString(Preview$1);
1434
+ };
1435
+ const refresh$1 = () => {
1436
+ return i18nString(Refresh$1);
1437
+ };
1438
+ const refreshEvents$1 = () => {
1439
+ return i18nString(RefreshEvents);
1440
+ };
1441
+ const resetColumns = () => {
1442
+ return i18nString(ResetColumns);
1443
+ };
1444
+ const response = () => {
1445
+ return i18nString(Response$1);
1446
+ };
1447
+ const secondsRange = (start, end) => {
1448
+ return i18nString(SecondsRange, {
1449
+ PH1: start,
1450
+ PH2: end
1451
+ });
1452
+ };
1453
+ const started = () => {
1454
+ return i18nString(Started);
1455
+ };
1456
+ const stream = () => {
1457
+ return i18nString(Stream$1);
1458
+ };
1459
+ const timing = () => {
1460
+ return i18nString(Timing$1);
1461
+ };
1462
+ const toSeconds = seconds => {
1463
+ return i18nString(ToSeconds, {
1464
+ PH1: seconds
1465
+ });
1466
+ };
1467
+ const tools = () => {
1468
+ return i18nString(Tools$1);
1469
+ };
1470
+ const type = () => {
1471
+ return i18nString(Type$1);
1472
+ };
1473
+ const ui = () => {
1474
+ return i18nString(Ui$1);
1475
+ };
1476
+ const unableToLoadDebugSessionInvalidUri = uri => {
1477
+ return i18nString(UnableToLoadDebugSessionInvalidUri, {
1478
+ PH1: uri
1479
+ });
1480
+ };
1481
+ const unableToLoadDebugSessionMissingUri = () => {
1482
+ return i18nString(UnableToLoadDebugSessionMissingUri);
1483
+ };
1484
+ const windowSummary = (start, end, duration) => {
1485
+ return i18nString(WindowSummary, {
1486
+ PH1: start,
1487
+ PH2: end,
1488
+ PH3: duration
1489
+ });
1490
+ };
1491
+
1308
1492
  const Response = 'response';
1309
1493
  const Preview = 'preview';
1310
1494
  const Timing = 'timing';
@@ -1314,29 +1498,29 @@ const isDetailTab = value => {
1314
1498
  };
1315
1499
  const getDetailTabLabel = value => {
1316
1500
  if (value === Preview) {
1317
- return 'Preview';
1501
+ return preview();
1318
1502
  }
1319
1503
  if (value === Timing) {
1320
- return 'Timing';
1504
+ return timing();
1321
1505
  }
1322
- return 'Response';
1506
+ return response();
1323
1507
  };
1324
1508
 
1325
1509
  const createEventCategoryFilterOptions = () => {
1326
1510
  return [{
1327
- label: 'All',
1511
+ label: all(),
1328
1512
  value: All
1329
1513
  }, {
1330
- label: 'Tools',
1514
+ label: tools(),
1331
1515
  value: Tools
1332
1516
  }, {
1333
- label: 'Network',
1517
+ label: network(),
1334
1518
  value: Network
1335
1519
  }, {
1336
- label: 'UI',
1520
+ label: ui(),
1337
1521
  value: Ui
1338
1522
  }, {
1339
- label: 'Stream',
1523
+ label: stream(),
1340
1524
  value: Stream
1341
1525
  }];
1342
1526
  };
@@ -1344,15 +1528,15 @@ const createEventCategoryFilterOptions = () => {
1344
1528
  const getEventCategoryFilterLabel = eventCategoryFilter => {
1345
1529
  switch (eventCategoryFilter) {
1346
1530
  case Network:
1347
- return 'Network';
1531
+ return network();
1348
1532
  case Stream:
1349
- return 'Stream';
1533
+ return stream();
1350
1534
  case Tools:
1351
- return 'Tools';
1535
+ return tools();
1352
1536
  case Ui:
1353
- return 'UI';
1537
+ return ui();
1354
1538
  default:
1355
- return 'All';
1539
+ return all();
1356
1540
  }
1357
1541
  };
1358
1542
 
@@ -1381,6 +1565,22 @@ const parseFilterValue = filterValue => {
1381
1565
  };
1382
1566
  };
1383
1567
 
1568
+ const Type = 'type';
1569
+ const Duration = 'duration';
1570
+ const Status = 'status';
1571
+ const tableColumns = [Type, Duration, Status];
1572
+ const defaultVisibleTableColumns = tableColumns;
1573
+ const isTableColumn = value => {
1574
+ return tableColumns.includes(value);
1575
+ };
1576
+ const getOrderedVisibleTableColumns = values => {
1577
+ const visibleColumns = new Set(values.filter(isTableColumn));
1578
+ return tableColumns.filter(column => visibleColumns.has(column));
1579
+ };
1580
+ const isVisibleTableColumn = (visibleTableColumns, column) => {
1581
+ return visibleTableColumns.includes(column);
1582
+ };
1583
+
1384
1584
  const validEventCategoryFilters = new Set([All, Network, Stream, Tools, Ui]);
1385
1585
  const isSavedState = value => {
1386
1586
  return typeof value === 'object' && value !== null;
@@ -1398,6 +1598,7 @@ const restoreSavedState = (state, savedState) => {
1398
1598
  if (!isSavedState(savedState)) {
1399
1599
  return state;
1400
1600
  }
1601
+ const restoredVisibleTableColumns = Array.isArray(savedState.visibleTableColumns) ? getOrderedVisibleTableColumns(savedState.visibleTableColumns.filter(value => typeof value === 'string')) : state.visibleTableColumns;
1401
1602
  return {
1402
1603
  ...state,
1403
1604
  eventCategoryFilter: getRestoredEventCategoryFilter(savedState, state.eventCategoryFilter),
@@ -1405,7 +1606,8 @@ const restoreSavedState = (state, savedState) => {
1405
1606
  selectedDetailTab: typeof savedState.selectedDetailTab === 'string' && isDetailTab(savedState.selectedDetailTab) ? savedState.selectedDetailTab : state.selectedDetailTab,
1406
1607
  selectedEventId: typeof savedState.selectedEventId === 'number' || savedState.selectedEventId === null ? savedState.selectedEventId : state.selectedEventId,
1407
1608
  timelineEndSeconds: typeof savedState.timelineEndSeconds === 'string' ? savedState.timelineEndSeconds : state.timelineEndSeconds,
1408
- timelineStartSeconds: typeof savedState.timelineStartSeconds === 'string' ? savedState.timelineStartSeconds : state.timelineStartSeconds
1609
+ timelineStartSeconds: typeof savedState.timelineStartSeconds === 'string' ? savedState.timelineStartSeconds : state.timelineStartSeconds,
1610
+ visibleTableColumns: restoredVisibleTableColumns
1409
1611
  };
1410
1612
  };
1411
1613
 
@@ -1477,6 +1679,7 @@ const createDefaultState = () => {
1477
1679
  uid: 0,
1478
1680
  uri: '',
1479
1681
  useDevtoolsLayout: true,
1682
+ visibleTableColumns: defaultVisibleTableColumns,
1480
1683
  width: 0,
1481
1684
  x: 0,
1482
1685
  y: 0
@@ -1510,7 +1713,7 @@ const RenderCss = 2;
1510
1713
  const RenderIncremental = 3;
1511
1714
 
1512
1715
  const diff = (oldState, newState) => {
1513
- if (oldState.errorMessage !== newState.errorMessage || oldState.eventCategoryFilter !== newState.eventCategoryFilter || oldState.events !== newState.events || oldState.filterValue !== newState.filterValue || oldState.sessionId !== newState.sessionId || oldState.showEventStreamFinishedEvents !== newState.showEventStreamFinishedEvents || oldState.showInputEvents !== newState.showInputEvents || oldState.showResponsePartEvents !== newState.showResponsePartEvents || oldState.tableWidth !== newState.tableWidth || oldState.timelineEndSeconds !== newState.timelineEndSeconds || oldState.timelineSelectionActive !== newState.timelineSelectionActive || oldState.timelineSelectionAnchorSeconds !== newState.timelineSelectionAnchorSeconds || oldState.timelineSelectionFocusSeconds !== newState.timelineSelectionFocusSeconds || oldState.timelineStartSeconds !== newState.timelineStartSeconds || oldState.useDevtoolsLayout !== newState.useDevtoolsLayout || oldState.selectedDetailTab !== newState.selectedDetailTab || oldState.selectedEvent !== newState.selectedEvent || oldState.selectedEventIndex !== newState.selectedEventIndex || oldState.width !== newState.width || oldState.uid !== newState.uid) {
1716
+ if (oldState.errorMessage !== newState.errorMessage || oldState.eventCategoryFilter !== newState.eventCategoryFilter || oldState.events !== newState.events || oldState.filterValue !== newState.filterValue || oldState.sessionId !== newState.sessionId || oldState.showEventStreamFinishedEvents !== newState.showEventStreamFinishedEvents || oldState.showInputEvents !== newState.showInputEvents || oldState.showResponsePartEvents !== newState.showResponsePartEvents || oldState.tableWidth !== newState.tableWidth || oldState.timelineEndSeconds !== newState.timelineEndSeconds || oldState.timelineSelectionActive !== newState.timelineSelectionActive || oldState.timelineSelectionAnchorSeconds !== newState.timelineSelectionAnchorSeconds || oldState.timelineSelectionFocusSeconds !== newState.timelineSelectionFocusSeconds || oldState.timelineStartSeconds !== newState.timelineStartSeconds || oldState.useDevtoolsLayout !== newState.useDevtoolsLayout || oldState.visibleTableColumns !== newState.visibleTableColumns || oldState.selectedDetailTab !== newState.selectedDetailTab || oldState.selectedEvent !== newState.selectedEvent || oldState.selectedEventIndex !== newState.selectedEventIndex || oldState.width !== newState.width || oldState.uid !== newState.uid) {
1514
1717
  return [RenderIncremental, RenderCss];
1515
1718
  }
1516
1719
  return [];
@@ -1524,28 +1727,12 @@ const diff2 = uid => {
1524
1727
  return diff(oldState, newState);
1525
1728
  };
1526
1729
 
1527
- const getMenuIds = () => {
1528
- return [555, 556, 557];
1529
- };
1530
-
1531
- const getErrorMessage = error => {
1532
- if (error instanceof Error) {
1533
- return error.message;
1534
- }
1535
- if (typeof error === 'string') {
1536
- return error;
1537
- }
1538
- if (error && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
1539
- return error.message;
1540
- }
1541
- return undefined;
1542
- };
1543
- const getFailedToLoadMessage = (sessionId, error) => {
1544
- const errorMessage = getErrorMessage(error);
1545
- if (errorMessage) {
1546
- return `Failed to load chat debug session "${sessionId}": ${errorMessage}`;
1547
- }
1548
- return `Failed to load chat debug session "${sessionId}". Please try again.`;
1730
+ const MenuChatDebugTableHeader = 2189;
1731
+ const handleHeaderContextMenu = async (state, eventX, eventY) => {
1732
+ await showContextMenu2(state.uid, MenuChatDebugTableHeader, eventX, eventY, {
1733
+ menuId: MenuChatDebugTableHeader
1734
+ });
1735
+ return state;
1549
1736
  };
1550
1737
 
1551
1738
  const hasMatchingToolName = (startedEvent, finishedEvent) => {
@@ -1690,24 +1877,6 @@ const getFilteredEvents = (events, filterValue, eventCategoryFilter, showInputEv
1690
1877
  return filteredByCategory.filter(event => JSON.stringify(event).toLowerCase().includes(filterText));
1691
1878
  };
1692
1879
 
1693
- const ParseChatDebugUriErrorCode = {
1694
- InvalidSessionId: 'invalid-session-id',
1695
- InvalidUriEncoding: 'invalid-uri-encoding',
1696
- InvalidUriFormat: 'invalid-uri-format',
1697
- MissingUri: 'missing-uri'
1698
- };
1699
-
1700
- const getInvalidUriMessage = (uri, code) => {
1701
- if (code === ParseChatDebugUriErrorCode.MissingUri) {
1702
- return 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
1703
- }
1704
- return `Unable to load debug session: invalid URI "${uri}". Expected format: chat-debug://<sessionId>.`;
1705
- };
1706
-
1707
- const getSessionNotFoundMessage = sessionId => {
1708
- return `No chat session found for sessionId "${sessionId}".`;
1709
- };
1710
-
1711
1880
  const toTimeNumber = value => {
1712
1881
  if (typeof value === 'number' && Number.isFinite(value)) {
1713
1882
  return value;
@@ -1859,6 +2028,165 @@ const getTimelineInfo = (events, startValue, endValue) => {
1859
2028
  };
1860
2029
  };
1861
2030
 
2031
+ const getCurrentEvents$3 = state => {
2032
+ const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
2033
+ return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
2034
+ };
2035
+ const selectEventAtIndex = async (state, selectedEventIndex, dependencies) => {
2036
+ const currentEvents = getCurrentEvents$3(state);
2037
+ const selectedEvent = currentEvents[selectedEventIndex];
2038
+ if (!selectedEvent) {
2039
+ return {
2040
+ ...state,
2041
+ selectedEvent: null,
2042
+ selectedEventId: null,
2043
+ selectedEventIndex
2044
+ };
2045
+ }
2046
+ if (typeof selectedEvent.eventId !== 'number') {
2047
+ return {
2048
+ ...state,
2049
+ selectedEvent,
2050
+ selectedEventId: null,
2051
+ selectedEventIndex
2052
+ };
2053
+ }
2054
+ const selectedEventDetails = await dependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
2055
+ return {
2056
+ ...state,
2057
+ selectedEvent: selectedEventDetails ?? selectedEvent,
2058
+ selectedEventId: selectedEvent.eventId,
2059
+ selectedEventIndex
2060
+ };
2061
+ };
2062
+
2063
+ const devtoolsRootGap = 4;
2064
+ const devtoolsTopHeight = 28;
2065
+ const devtoolsTimelineHeight = 88;
2066
+ const devtoolsTableHeaderHeight = 24;
2067
+ const devtoolsTableRowHeight = 24;
2068
+ const getTableBodyY = (state, hasTimeline) => {
2069
+ return state.y + viewPadding + devtoolsTopHeight + devtoolsRootGap + (hasTimeline ? devtoolsTimelineHeight : 0) + devtoolsTableHeaderHeight;
2070
+ };
2071
+ const getTableBodyEventIndex = (state, eventX, eventY) => {
2072
+ if (!state.useDevtoolsLayout) {
2073
+ return -1;
2074
+ }
2075
+ const currentEvents = getCurrentEvents$3(state);
2076
+ if (currentEvents.length === 0) {
2077
+ return -1;
2078
+ }
2079
+ const tableX = state.x + leftPadding;
2080
+ const tableWidth = clampTableWidth(state.width, state.tableWidth);
2081
+ const hasTimeline = currentEvents.length > 0;
2082
+ const tableBodyY = getTableBodyY(state, hasTimeline);
2083
+ const relativeX = eventX - tableX;
2084
+ const relativeY = eventY - tableBodyY;
2085
+ if (relativeX < 0 || relativeX >= tableWidth || relativeY < 0) {
2086
+ return -1;
2087
+ }
2088
+ const eventIndex = Math.floor(relativeY / devtoolsTableRowHeight);
2089
+ if (eventIndex < 0 || eventIndex >= currentEvents.length) {
2090
+ return -1;
2091
+ }
2092
+ return eventIndex;
2093
+ };
2094
+
2095
+ const MenuChatDebugTableBody = 2190;
2096
+ const handleTableBodyContextMenu = async (state, eventX, eventY) => {
2097
+ const eventIndex = getTableBodyEventIndex(state, eventX, eventY);
2098
+ await showContextMenu2(state.uid, MenuChatDebugTableBody, eventX, eventY, {
2099
+ eventIndex,
2100
+ menuId: MenuChatDebugTableBody
2101
+ });
2102
+ return state;
2103
+ };
2104
+
2105
+ const getColumnVisibilityFlags = (state, column) => {
2106
+ return isVisibleTableColumn(state.visibleTableColumns, column) ? Checked : Unchecked;
2107
+ };
2108
+ const getMenuEntries2 = (state, props) => {
2109
+ if (props.menuId === MenuChatDebugTableHeader) {
2110
+ return [{
2111
+ args: [Type],
2112
+ command: 'ChatDebug.toggleTableColumnVisibility',
2113
+ flags: getColumnVisibilityFlags(state, Type),
2114
+ id: 'type',
2115
+ label: type()
2116
+ }, {
2117
+ args: [Duration],
2118
+ command: 'ChatDebug.toggleTableColumnVisibility',
2119
+ flags: getColumnVisibilityFlags(state, Duration),
2120
+ id: 'duration',
2121
+ label: duration()
2122
+ }, {
2123
+ args: [Status],
2124
+ command: 'ChatDebug.toggleTableColumnVisibility',
2125
+ flags: getColumnVisibilityFlags(state, Status),
2126
+ id: 'status',
2127
+ label: status()
2128
+ }, {
2129
+ args: [],
2130
+ command: 'ChatDebug.resetTableColumns',
2131
+ flags: None,
2132
+ id: 'reset-columns',
2133
+ label: resetColumns()
2134
+ }];
2135
+ }
2136
+ if (props.menuId === MenuChatDebugTableBody) {
2137
+ return [{
2138
+ args: [],
2139
+ command: 'ChatDebug.copy',
2140
+ flags: None,
2141
+ id: 'copy',
2142
+ label: copy()
2143
+ }];
2144
+ }
2145
+ return [];
2146
+ };
2147
+
2148
+ const getMenuIds = () => {
2149
+ return [MenuChatDebugTableHeader, MenuChatDebugTableBody, 556, 557];
2150
+ };
2151
+
2152
+ const getErrorMessage = error => {
2153
+ if (error instanceof Error) {
2154
+ return error.message;
2155
+ }
2156
+ if (typeof error === 'string') {
2157
+ return error;
2158
+ }
2159
+ if (error && typeof error === 'object' && 'message' in error && typeof error.message === 'string') {
2160
+ return error.message;
2161
+ }
2162
+ return undefined;
2163
+ };
2164
+ const getFailedToLoadMessage = (sessionId, error) => {
2165
+ const errorMessage = getErrorMessage(error);
2166
+ if (errorMessage) {
2167
+ return failedToLoadChatDebugSessionWithError(sessionId, errorMessage);
2168
+ }
2169
+ return failedToLoadChatDebugSession(sessionId);
2170
+ };
2171
+
2172
+ const ParseChatDebugUriErrorCode = {
2173
+ InvalidSessionId: 'invalid-session-id',
2174
+ InvalidUriEncoding: 'invalid-uri-encoding',
2175
+ InvalidUriFormat: 'invalid-uri-format',
2176
+ MissingUri: 'missing-uri'
2177
+ };
2178
+
2179
+ const getInvalidUriMessage = (uri, code) => {
2180
+ if (code === ParseChatDebugUriErrorCode.MissingUri) {
2181
+ return unableToLoadDebugSessionMissingUri();
2182
+ }
2183
+ return unableToLoadDebugSessionInvalidUri(uri);
2184
+ };
2185
+
2186
+ const getSessionNotFoundMessage = sessionId => {
2187
+ return noChatSessionFound(sessionId);
2188
+ };
2189
+
1862
2190
  const listChatViewEventsDependencies = {
1863
2191
  listChatViewEventsFromWorker: listChatViewEvents$1
1864
2192
  };
@@ -1886,7 +2214,7 @@ const parseChatDebugUri = uri => {
1886
2214
  if (!uri) {
1887
2215
  return {
1888
2216
  code: ParseChatDebugUriErrorCode.MissingUri,
1889
- message: 'Missing URI',
2217
+ message: missingUri(),
1890
2218
  type: 'error'
1891
2219
  };
1892
2220
  }
@@ -1894,7 +2222,7 @@ const parseChatDebugUri = uri => {
1894
2222
  if (!match) {
1895
2223
  return {
1896
2224
  code: ParseChatDebugUriErrorCode.InvalidUriFormat,
1897
- message: 'Invalid URI format',
2225
+ message: invalidUriFormat(),
1898
2226
  type: 'error'
1899
2227
  };
1900
2228
  }
@@ -1905,14 +2233,14 @@ const parseChatDebugUri = uri => {
1905
2233
  } catch {
1906
2234
  return {
1907
2235
  code: ParseChatDebugUriErrorCode.InvalidUriEncoding,
1908
- message: 'Invalid URI encoding',
2236
+ message: invalidUriEncoding(),
1909
2237
  type: 'error'
1910
2238
  };
1911
2239
  }
1912
2240
  if (!sessionId || invalidSessionIdPattern.test(sessionId)) {
1913
2241
  return {
1914
2242
  code: ParseChatDebugUriErrorCode.InvalidSessionId,
1915
- message: 'Invalid session id',
2243
+ message: invalidSessionId(),
1916
2244
  type: 'error'
1917
2245
  };
1918
2246
  }
@@ -1926,7 +2254,7 @@ const loadEventsDependencies = {
1926
2254
  listChatViewEvents: listChatViewEvents,
1927
2255
  loadSelectedEvent: loadSelectedEvent
1928
2256
  };
1929
- const getCurrentEvents$3 = state => {
2257
+ const getCurrentEvents$2 = state => {
1930
2258
  const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
1931
2259
  return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
1932
2260
  };
@@ -1938,7 +2266,7 @@ const restoreSelectedEvent = async state => {
1938
2266
  selectedEventIndex: null
1939
2267
  };
1940
2268
  }
1941
- const currentEvents = getCurrentEvents$3(state);
2269
+ const currentEvents = getCurrentEvents$2(state);
1942
2270
  const selectedEventIndex = currentEvents.findIndex(event => event.eventId === state.selectedEventId);
1943
2271
  if (selectedEventIndex === -1) {
1944
2272
  return {
@@ -2071,6 +2399,10 @@ const handleDetailsContextMenu = state => {
2071
2399
  return state;
2072
2400
  };
2073
2401
 
2402
+ const handleDetailsTopContextMenu = state => {
2403
+ return state;
2404
+ };
2405
+
2074
2406
  const handleDetailTab = (state, value) => {
2075
2407
  if (!isDetailTab(value)) {
2076
2408
  return state;
@@ -2081,7 +2413,7 @@ const handleDetailTab = (state, value) => {
2081
2413
  };
2082
2414
  };
2083
2415
 
2084
- const getCurrentEvents$2 = state => {
2416
+ const getCurrentEvents$1 = state => {
2085
2417
  const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
2086
2418
  return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
2087
2419
  };
@@ -2095,7 +2427,7 @@ const getSelectedEventIndex$1 = state => {
2095
2427
  if (selectedEventIndex === null) {
2096
2428
  return null;
2097
2429
  }
2098
- const filteredEvents = getCurrentEvents$2(state);
2430
+ const filteredEvents = getCurrentEvents$1(state);
2099
2431
  const selectedEvent = filteredEvents[selectedEventIndex];
2100
2432
  if (!selectedEvent) {
2101
2433
  return null;
@@ -2113,12 +2445,12 @@ const getPreservedSelectedEventIndex$1 = (oldState, newState) => {
2113
2445
  if (selectedEventIndex === null) {
2114
2446
  return null;
2115
2447
  }
2116
- const oldFilteredEvents = getCurrentEvents$2(oldState);
2448
+ const oldFilteredEvents = getCurrentEvents$1(oldState);
2117
2449
  const selectedEvent = oldFilteredEvents[selectedEventIndex];
2118
2450
  if (!selectedEvent) {
2119
2451
  return null;
2120
2452
  }
2121
- const newFilteredEvents = getCurrentEvents$2(newState);
2453
+ const newFilteredEvents = getCurrentEvents$1(newState);
2122
2454
  const newIndex = getEventIndexByStableId$1(newFilteredEvents, selectedEvent);
2123
2455
  if (newIndex === -1) {
2124
2456
  return null;
@@ -2143,38 +2475,6 @@ const handleEventCategoryFilter = (state, value) => {
2143
2475
  return withPreservedSelection$1(state, nextState);
2144
2476
  };
2145
2477
 
2146
- const getCurrentEvents$1 = state => {
2147
- const filteredEvents = getFilteredEvents(state.events, state.filterValue, state.eventCategoryFilter, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
2148
- return filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
2149
- };
2150
- const selectEventAtIndex = async (state, selectedEventIndex, dependencies) => {
2151
- const currentEvents = getCurrentEvents$1(state);
2152
- const selectedEvent = currentEvents[selectedEventIndex];
2153
- if (!selectedEvent) {
2154
- return {
2155
- ...state,
2156
- selectedEvent: null,
2157
- selectedEventId: null,
2158
- selectedEventIndex
2159
- };
2160
- }
2161
- if (typeof selectedEvent.eventId !== 'number') {
2162
- return {
2163
- ...state,
2164
- selectedEvent,
2165
- selectedEventId: null,
2166
- selectedEventIndex
2167
- };
2168
- }
2169
- const selectedEventDetails = await dependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
2170
- return {
2171
- ...state,
2172
- selectedEvent: selectedEventDetails ?? selectedEvent,
2173
- selectedEventId: selectedEvent.eventId,
2174
- selectedEventIndex
2175
- };
2176
- };
2177
-
2178
2478
  const handleEventRowClickDependencies = {
2179
2479
  loadSelectedEvent: loadSelectedEvent
2180
2480
  };
@@ -2199,10 +2499,6 @@ const handleEventRowClick = async (state, value, button = 0) => {
2199
2499
  return selectEventAtIndex(state, selectedEventIndex, handleEventRowClickDependencies);
2200
2500
  };
2201
2501
 
2202
- const handleHeaderContextMenu = state => {
2203
- return state;
2204
- };
2205
-
2206
2502
  const getBoolean = value => {
2207
2503
  return value === true || value === 'true' || value === 'on' || value === '1';
2208
2504
  };
@@ -2406,44 +2702,7 @@ const handleSashPointerUp = (state, eventX, eventY) => {
2406
2702
  return state;
2407
2703
  };
2408
2704
 
2409
- const devtoolsRootGap = 4;
2410
- const devtoolsTopHeight = 28;
2411
- const devtoolsTimelineHeight = 88;
2412
- const devtoolsTableHeaderHeight = 24;
2413
- const devtoolsTableRowHeight = 24;
2414
- const MenuChatDebugTableBody = 2190;
2415
- const getTableBodyY = (state, hasTimeline) => {
2416
- return state.y + viewPadding + devtoolsTopHeight + devtoolsRootGap + (hasTimeline ? devtoolsTimelineHeight : 0) + devtoolsTableHeaderHeight;
2417
- };
2418
- const getTableBodyEventIndex = (state, eventX, eventY) => {
2419
- if (!state.useDevtoolsLayout) {
2420
- return -1;
2421
- }
2422
- const currentEvents = getCurrentEvents$1(state);
2423
- if (currentEvents.length === 0) {
2424
- return -1;
2425
- }
2426
- const tableX = state.x + leftPadding;
2427
- const tableWidth = clampTableWidth(state.width, state.tableWidth);
2428
- const hasTimeline = currentEvents.length > 0;
2429
- const tableBodyY = getTableBodyY(state, hasTimeline);
2430
- const relativeX = eventX - tableX;
2431
- const relativeY = eventY - tableBodyY;
2432
- if (relativeX < 0 || relativeX >= tableWidth || relativeY < 0) {
2433
- return -1;
2434
- }
2435
- const eventIndex = Math.floor(relativeY / devtoolsTableRowHeight);
2436
- if (eventIndex < 0 || eventIndex >= currentEvents.length) {
2437
- return -1;
2438
- }
2439
- return eventIndex;
2440
- };
2441
- const handleTableBodyContextMenu = async (state, eventX, eventY) => {
2442
- const eventIndex = getTableBodyEventIndex(state, eventX, eventY);
2443
- await showContextMenu2(state.uid, MenuChatDebugTableBody, eventX, eventY, {
2444
- eventIndex,
2445
- menuId: MenuChatDebugTableBody
2446
- });
2705
+ const handleTimelineContextMenu = state => {
2447
2706
  return state;
2448
2707
  };
2449
2708
 
@@ -3104,17 +3363,19 @@ const HandleTableKeyDown = 18;
3104
3363
  const HandleTimelineRangePreset = 19;
3105
3364
  const HandleCloseDetails = 20;
3106
3365
  const HandleClickRefresh = 21;
3366
+ const HandleDetailsTopContextMenu = 22;
3367
+ const HandleTimelineContextMenu = 23;
3107
3368
 
3108
3369
  const getRefreshButtonDom = () => {
3109
3370
  return [{
3110
- 'aria-label': 'Refresh events',
3371
+ 'aria-label': refreshEvents$1(),
3111
3372
  childCount: 1,
3112
3373
  className: ChatDebugViewRefreshButton,
3113
3374
  name: Refresh,
3114
3375
  onClick: HandleClickRefresh,
3115
3376
  type: Button$1,
3116
3377
  value: Refresh
3117
- }, text('Refresh')];
3378
+ }, text(refresh$1())];
3118
3379
  };
3119
3380
  const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) => {
3120
3381
  const refreshButtonDom = getRefreshButtonDom();
@@ -3131,7 +3392,7 @@ const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) =>
3131
3392
  inputType: 'search',
3132
3393
  name: Filter,
3133
3394
  onInput: HandleFilterInput,
3134
- placeholder: 'Filter events',
3395
+ placeholder: filterEvents(),
3135
3396
  type: Input,
3136
3397
  value: filterValue
3137
3398
  }, ...quickFilterNodes, ...refreshButtonDom];
@@ -3148,7 +3409,7 @@ const getDebugViewTopDom = (filterValue, useDevtoolsLayout, quickFilterNodes) =>
3148
3409
  inputType: 'search',
3149
3410
  name: Filter,
3150
3411
  onInput: HandleFilterInput,
3151
- placeholder: 'Filter events',
3412
+ placeholder: filterEvents(),
3152
3413
  type: Input,
3153
3414
  value: filterValue
3154
3415
  }, ...refreshButtonDom];
@@ -3224,7 +3485,7 @@ const getTimingDetailsDom = event => {
3224
3485
  childCount: 3,
3225
3486
  className: ChatDebugViewTiming,
3226
3487
  type: Div
3227
- }, ...getTimingRowDom('Started', getStartText(event)), ...getTimingRowDom('Ended', getEndText(event)), ...getTimingRowDom('Duration', getDurationText(event))];
3488
+ }, ...getTimingRowDom(started(), getStartText(event)), ...getTimingRowDom(ended(), getEndText(event)), ...getTimingRowDom(duration(), getDurationText(event))];
3228
3489
  };
3229
3490
 
3230
3491
  const getTabId = detailTab => {
@@ -3264,9 +3525,10 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
3264
3525
  }, {
3265
3526
  childCount: 2,
3266
3527
  className: ChatDebugViewDetailsTop,
3528
+ onContextMenu: HandleDetailsTopContextMenu,
3267
3529
  type: Div
3268
3530
  }, {
3269
- 'aria-label': 'Close details',
3531
+ 'aria-label': closeDetails(),
3270
3532
  childCount: 0,
3271
3533
  className: ChatDebugViewDetailsClose,
3272
3534
  name: CloseDetails,
@@ -3275,7 +3537,7 @@ const getDetailsDom = (previewEventNodes, responseEventNodes = previewEventNodes
3275
3537
  type: Button$1,
3276
3538
  value: 'close'
3277
3539
  }, {
3278
- 'aria-label': 'Detail sections',
3540
+ 'aria-label': detailSections(),
3279
3541
  childCount: detailTabs.length,
3280
3542
  className: ChatDebugViewDetailsTabs,
3281
3543
  role: 'tablist',
@@ -3371,30 +3633,45 @@ const getStatusText = event => {
3371
3633
  return hasErrorStatus(event) ? '400' : '200';
3372
3634
  };
3373
3635
 
3374
- const getDevtoolsRows = (events, selectedEventIndex) => {
3636
+ const getRowCellNodes = (event, isErrorStatus, visibleTableColumns) => {
3637
+ return visibleTableColumns.flatMap(column => {
3638
+ switch (column) {
3639
+ case Duration:
3640
+ return [{
3641
+ childCount: 1,
3642
+ className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellDuration),
3643
+ type: Td
3644
+ }, text(getDurationText(event))];
3645
+ case Status:
3646
+ return [{
3647
+ childCount: 1,
3648
+ className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellStatus, isErrorStatus && ChatDebugViewCellStatusError),
3649
+ type: Td
3650
+ }, text(getStatusText(event))];
3651
+ case Type:
3652
+ return [{
3653
+ childCount: 1,
3654
+ className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellType),
3655
+ type: Td
3656
+ }, text(getEventTypeLabel(event))];
3657
+ default:
3658
+ return [];
3659
+ }
3660
+ });
3661
+ };
3662
+ const getDevtoolsRows = (events, selectedEventIndex, visibleTableColumns = defaultVisibleTableColumns) => {
3375
3663
  return events.flatMap((event, i) => {
3376
3664
  const isEvenRow = i % 2 === 1;
3377
3665
  const isSelected = selectedEventIndex === i;
3378
3666
  const isErrorStatus = hasErrorStatus(event);
3379
3667
  const rowIndex = String(i);
3668
+ const rowCellNodes = getRowCellNodes(event, isErrorStatus, visibleTableColumns);
3380
3669
  return [{
3381
- childCount: 3,
3670
+ childCount: visibleTableColumns.length,
3382
3671
  className: joinClassNames(ChatDebugViewEventRow, isEvenRow && TableRowEven, isSelected && ChatDebugViewEventRowSelected),
3383
3672
  'data-index': rowIndex,
3384
3673
  type: Tr
3385
- }, {
3386
- childCount: 1,
3387
- className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellType),
3388
- type: Td
3389
- }, text(getEventTypeLabel(event)), {
3390
- childCount: 1,
3391
- className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellDuration),
3392
- type: Td
3393
- }, text(getDurationText(event)), {
3394
- childCount: 1,
3395
- className: joinClassNames(ChatDebugViewCell, ChatDebugViewCellStatus, isErrorStatus && ChatDebugViewCellStatusError),
3396
- type: Td
3397
- }, text(getStatusText(event))];
3674
+ }, ...rowCellNodes];
3398
3675
  });
3399
3676
  };
3400
3677
 
@@ -3693,39 +3970,55 @@ const getTableBodyDom = (rowNodes, eventCount) => {
3693
3970
  }, ...rowNodes];
3694
3971
  };
3695
3972
 
3696
- const getTableHeaderDom = () => {
3973
+ const getHeaderCellNodes = visibleTableColumns => {
3974
+ return visibleTableColumns.flatMap(column => {
3975
+ switch (column) {
3976
+ case Duration:
3977
+ return [{
3978
+ childCount: 1,
3979
+ className: ChatDebugViewHeaderCell,
3980
+ scope: 'col',
3981
+ type: Th
3982
+ }, text(duration())];
3983
+ case Status:
3984
+ return [{
3985
+ childCount: 1,
3986
+ className: ChatDebugViewHeaderCell,
3987
+ scope: 'col',
3988
+ type: Th
3989
+ }, text(status())];
3990
+ case Type:
3991
+ return [{
3992
+ childCount: 1,
3993
+ className: ChatDebugViewHeaderCell,
3994
+ scope: 'col',
3995
+ type: Th
3996
+ }, text(type())];
3997
+ default:
3998
+ return [];
3999
+ }
4000
+ });
4001
+ };
4002
+ const getTableHeaderDom = (visibleTableColumns = defaultVisibleTableColumns) => {
4003
+ const headerCellNodes = getHeaderCellNodes(visibleTableColumns);
3697
4004
  return [{
3698
4005
  childCount: 1,
3699
4006
  className: ChatDebugViewTableHeader,
4007
+ onContextMenu: HandleHeaderContextMenu,
3700
4008
  type: THead
3701
4009
  }, {
3702
- childCount: 3,
4010
+ childCount: visibleTableColumns.length,
3703
4011
  className: ChatDebugViewTableHeaderRow,
3704
4012
  type: Tr
3705
- }, {
3706
- childCount: 1,
3707
- className: ChatDebugViewHeaderCell,
3708
- scope: 'col',
3709
- type: Th
3710
- }, text('Type'), {
3711
- childCount: 1,
3712
- className: ChatDebugViewHeaderCell,
3713
- scope: 'col',
3714
- type: Th
3715
- }, text('Duration'), {
3716
- childCount: 1,
3717
- className: ChatDebugViewHeaderCell,
3718
- scope: 'col',
3719
- type: Th
3720
- }, text('Status')];
4013
+ }, ...headerCellNodes];
3721
4014
  };
3722
4015
 
3723
- const getTableDom = (rowNodes, eventCount) => {
4016
+ const getTableDom = (rowNodes, eventCount, visibleTableColumns = defaultVisibleTableColumns) => {
3724
4017
  return [{
3725
4018
  childCount: 2,
3726
4019
  className: ChatDebugViewTable,
3727
4020
  type: Table
3728
- }, ...getTableHeaderDom(), ...getTableBodyDom(rowNodes, eventCount)];
4021
+ }, ...getTableHeaderDom(visibleTableColumns), ...getTableBodyDom(rowNodes, eventCount)];
3729
4022
  };
3730
4023
 
3731
4024
  const formatPercent = value => {
@@ -3794,9 +4087,9 @@ const formatTimelineSeconds = value => {
3794
4087
  const getTimelineSummary = (timelineEvents, timelineStartSeconds, timelineEndSeconds) => {
3795
4088
  const timelineInfo = getTimelineInfo(timelineEvents, timelineStartSeconds, timelineEndSeconds);
3796
4089
  if (timelineInfo.hasSelection && timelineInfo.startSeconds !== null && timelineInfo.endSeconds !== null) {
3797
- return `Window ${formatTimelineSeconds(timelineInfo.startSeconds)}-${formatTimelineSeconds(timelineInfo.endSeconds)} of ${formatTimelineSeconds(timelineInfo.durationSeconds)}`;
4090
+ return windowSummary(formatTimelineSeconds(timelineInfo.startSeconds), formatTimelineSeconds(timelineInfo.endSeconds), formatTimelineSeconds(timelineInfo.durationSeconds));
3798
4091
  }
3799
- return `Window 0s-${formatTimelineSeconds(timelineInfo.durationSeconds)} of ${formatTimelineSeconds(timelineInfo.durationSeconds)}`;
4092
+ return windowSummary('0s', formatTimelineSeconds(timelineInfo.durationSeconds), formatTimelineSeconds(timelineInfo.durationSeconds));
3800
4093
  };
3801
4094
 
3802
4095
  const getTimelineNodes = (timelineEvents, timelineStartSeconds, timelineEndSeconds, timelineSelectionActive = false, timelineSelectionAnchorSeconds = '', timelineSelectionFocusSeconds = '') => {
@@ -3824,6 +4117,7 @@ const getTimelineNodes = (timelineEvents, timelineStartSeconds, timelineEndSecon
3824
4117
  return [{
3825
4118
  childCount: 2,
3826
4119
  className: ChatDebugViewTimeline,
4120
+ onContextMenu: HandleTimelineContextMenu,
3827
4121
  type: Section
3828
4122
  }, {
3829
4123
  childCount: 1,
@@ -3850,13 +4144,13 @@ const getTimelineNodes = (timelineEvents, timelineStartSeconds, timelineEndSecon
3850
4144
  }, ...selectionNodes];
3851
4145
  };
3852
4146
 
3853
- const getDevtoolsDom = (events, selectedEvent, selectedEventIndex, timelineEvents, timelineStartSeconds, timelineEndSeconds, emptyMessage = 'No events have been found', timelineSelectionActive = false, timelineSelectionAnchorSeconds = '', timelineSelectionFocusSeconds = '', selectedDetailTab = Response) => {
3854
- const rowNodes = getDevtoolsRows(events, selectedEventIndex);
4147
+ const getDevtoolsDom = (events, selectedEvent, selectedEventIndex, timelineEvents, timelineStartSeconds, timelineEndSeconds, emptyMessage = noEventsFound(), timelineSelectionActive = false, timelineSelectionAnchorSeconds = '', timelineSelectionFocusSeconds = '', selectedDetailTab = Response, visibleTableColumns = defaultVisibleTableColumns) => {
4148
+ const rowNodes = getDevtoolsRows(events, selectedEventIndex, visibleTableColumns);
3855
4149
  const timelineNodes = getTimelineNodes(timelineEvents, timelineStartSeconds, timelineEndSeconds, timelineSelectionActive, timelineSelectionAnchorSeconds, timelineSelectionFocusSeconds);
3856
4150
  const previewEventNodes = selectedEvent ? getEventNode(getPreviewEvent(selectedEvent)) : [];
3857
4151
  const responseEventNodes = selectedEvent ? getEventNode(selectedEvent) : [];
3858
4152
  const hasSelectedEvent = responseEventNodes.length > 0;
3859
- const tableNodes = events.length === 0 ? getEmptyStateDom(emptyMessage) : getTableDom(rowNodes, events.length);
4153
+ const tableNodes = events.length === 0 ? getEmptyStateDom(emptyMessage) : getTableDom(rowNodes, events.length, visibleTableColumns);
3860
4154
  const eventsClassName = getEventsClassName(hasSelectedEvent);
3861
4155
  const detailsNodes = getDetailsDom(previewEventNodes, responseEventNodes, selectedEvent, isDetailTab(selectedDetailTab) ? selectedDetailTab : Response);
3862
4156
  const sashNodes = getSashNodesDom(hasSelectedEvent);
@@ -3924,18 +4218,18 @@ const getTimelineFilterDescription = (timelineStartSeconds, timelineEndSeconds)
3924
4218
  const trimmedStart = timelineStartSeconds.trim();
3925
4219
  const trimmedEnd = timelineEndSeconds.trim();
3926
4220
  if (trimmedStart && trimmedEnd) {
3927
- return `${trimmedStart}s-${trimmedEnd}s`;
4221
+ return secondsRange(trimmedStart, trimmedEnd);
3928
4222
  }
3929
4223
  if (trimmedStart) {
3930
- return `from ${trimmedStart}s`;
4224
+ return fromSeconds(trimmedStart);
3931
4225
  }
3932
4226
  if (trimmedEnd) {
3933
- return `to ${trimmedEnd}s`;
4227
+ return toSeconds(trimmedEnd);
3934
4228
  }
3935
4229
  return '';
3936
4230
  };
3937
4231
 
3938
- const getChatDebugViewDom = (errorMessage, filterValue, eventCategoryFilter, eventCategoryFilterOptions, _showEventStreamFinishedEvents, _showInputEvents, _showResponsePartEvents, useDevtoolsLayout, selectedEvent, selectedEventIndex, timelineStartSeconds, timelineEndSeconds, timelineEvents, events, timelineSelectionActive = false, timelineSelectionAnchorSeconds = '', timelineSelectionFocusSeconds = '', selectedDetailTab = Response) => {
4232
+ const getChatDebugViewDom = (errorMessage, filterValue, eventCategoryFilter, eventCategoryFilterOptions, _showEventStreamFinishedEvents, _showInputEvents, _showResponsePartEvents, useDevtoolsLayout, selectedEvent, selectedEventIndex, timelineStartSeconds, timelineEndSeconds, timelineEvents, events, timelineSelectionActive = false, timelineSelectionAnchorSeconds = '', timelineSelectionFocusSeconds = '', selectedDetailTab = Response, visibleTableColumns = defaultVisibleTableColumns) => {
3939
4233
  if (errorMessage) {
3940
4234
  return getDebugErrorDom(errorMessage);
3941
4235
  }
@@ -3954,11 +4248,11 @@ const getChatDebugViewDom = (errorMessage, filterValue, eventCategoryFilter, eve
3954
4248
  const hasTimelineFilter = Boolean(timelineFilterDescription);
3955
4249
  const hasFilterValue = filterDescriptionParts.length > 0;
3956
4250
  const filterDescription = filterDescriptionParts.join(' ');
3957
- const noFilteredEventsMessage = `no events found matching ${filterDescription}`;
4251
+ const noFilteredEventsMessage = noEventsFoundMatching(filterDescription);
3958
4252
  const useNoToolCallEventsMessage = eventCategoryFilter === Tools && !trimmedFilterValue && !hasTimelineFilter;
3959
- const emptyMessage = events.length === 0 && hasFilterValue ? useNoToolCallEventsMessage ? 'No tool call events.' : noFilteredEventsMessage : 'No events have been found';
4253
+ const emptyMessage = events.length === 0 && hasFilterValue ? useNoToolCallEventsMessage ? noToolCallEvents() : noFilteredEventsMessage : noEventsFound();
3960
4254
  const safeSelectedEventIndex = selectedEventIndex === null || selectedEventIndex < 0 || selectedEventIndex >= events.length ? null : selectedEventIndex;
3961
- const contentNodes = useDevtoolsLayout ? getDevtoolsDom(events, selectedEvent, safeSelectedEventIndex, timelineEvents, timelineStartSeconds, timelineEndSeconds, emptyMessage, timelineSelectionActive, timelineSelectionAnchorSeconds, timelineSelectionFocusSeconds, isDetailTab(selectedDetailTab) ? selectedDetailTab : Response) : getLegacyEventsDom(errorMessage, emptyMessage, events.flatMap(getEventNode));
4255
+ const contentNodes = useDevtoolsLayout ? getDevtoolsDom(events, selectedEvent, safeSelectedEventIndex, timelineEvents, timelineStartSeconds, timelineEndSeconds, emptyMessage, timelineSelectionActive, timelineSelectionAnchorSeconds, timelineSelectionFocusSeconds, isDetailTab(selectedDetailTab) ? selectedDetailTab : Response, visibleTableColumns) : getLegacyEventsDom(errorMessage, emptyMessage, events.flatMap(getEventNode));
3962
4256
  const quickFilterNodes = useDevtoolsLayout ? getQuickFilterNodes(eventCategoryFilter, eventCategoryFilterOptions) : [];
3963
4257
  const debugViewTopDom = getDebugViewTopDom(filterValue, useDevtoolsLayout, quickFilterNodes);
3964
4258
  const rootChildCount = 2;
@@ -3983,7 +4277,7 @@ const renderItems = (oldState, newState) => {
3983
4277
  }
3984
4278
  const timelineEvents = getTimelineEvents(newState);
3985
4279
  const filteredEvents = filterEventsByTimelineRange(timelineEvents, newState.timelineStartSeconds, newState.timelineEndSeconds);
3986
- const dom = getChatDebugViewDom(newState.errorMessage, newState.filterValue, newState.eventCategoryFilter, newState.eventCategoryFilterOptions, newState.showEventStreamFinishedEvents, newState.showInputEvents, newState.showResponsePartEvents, newState.useDevtoolsLayout, newState.selectedEvent, newState.selectedEventIndex, newState.timelineStartSeconds, newState.timelineEndSeconds, withSessionEventIds(timelineEvents), withSessionEventIds(filteredEvents), newState.timelineSelectionActive, newState.timelineSelectionAnchorSeconds, newState.timelineSelectionFocusSeconds, newState.selectedDetailTab);
4280
+ const dom = getChatDebugViewDom(newState.errorMessage, newState.filterValue, newState.eventCategoryFilter, newState.eventCategoryFilterOptions, newState.showEventStreamFinishedEvents, newState.showInputEvents, newState.showResponsePartEvents, newState.useDevtoolsLayout, newState.selectedEvent, newState.selectedEventIndex, newState.timelineStartSeconds, newState.timelineEndSeconds, withSessionEventIds(timelineEvents), withSessionEventIds(filteredEvents), newState.timelineSelectionActive, newState.timelineSelectionAnchorSeconds, newState.timelineSelectionFocusSeconds, newState.selectedDetailTab, newState.visibleTableColumns);
3987
4281
  return [SetDom2, newState.uid, dom];
3988
4282
  };
3989
4283
 
@@ -4031,7 +4325,7 @@ const render2 = (uid, diffResult) => {
4031
4325
  const renderEventListeners = () => {
4032
4326
  return [{
4033
4327
  name: HandleHeaderContextMenu,
4034
- params: ['handleHeaderContextMenu'],
4328
+ params: ['handleHeaderContextMenu', ClientX, ClientY],
4035
4329
  preventDefault: true
4036
4330
  }, {
4037
4331
  name: HandleEventRowClick,
@@ -4044,6 +4338,14 @@ const renderEventListeners = () => {
4044
4338
  name: HandleDetailsContextMenu,
4045
4339
  params: ['handleDetailsContextMenu'],
4046
4340
  preventDefault: true
4341
+ }, {
4342
+ name: HandleDetailsTopContextMenu,
4343
+ params: ['handleDetailsTopContextMenu'],
4344
+ preventDefault: true
4345
+ }, {
4346
+ name: HandleTimelineContextMenu,
4347
+ params: ['handleTimelineContextMenu'],
4348
+ preventDefault: true
4047
4349
  }, {
4048
4350
  name: HandleFilterInput,
4049
4351
  params: ['handleInput', TargetName, TargetValue]
@@ -4095,6 +4397,19 @@ const rerender = state => {
4095
4397
  return structuredClone(state);
4096
4398
  };
4097
4399
 
4400
+ const isSameVisibleTableColumns = (a, b) => {
4401
+ return a.length === b.length && a.every((value, index) => value === b[index]);
4402
+ };
4403
+ const resetTableColumns = state => {
4404
+ if (isSameVisibleTableColumns(state.visibleTableColumns, defaultVisibleTableColumns)) {
4405
+ return state;
4406
+ }
4407
+ return {
4408
+ ...state,
4409
+ visibleTableColumns: defaultVisibleTableColumns
4410
+ };
4411
+ };
4412
+
4098
4413
  const handleResize = (state, dimensions) => {
4099
4414
  const nextState = {
4100
4415
  ...state,
@@ -4124,7 +4439,8 @@ const saveState = state => {
4124
4439
  selectedEventId,
4125
4440
  sessionId,
4126
4441
  timelineEndSeconds,
4127
- timelineStartSeconds
4442
+ timelineStartSeconds,
4443
+ visibleTableColumns
4128
4444
  } = state;
4129
4445
  return {
4130
4446
  eventCategoryFilter,
@@ -4133,7 +4449,8 @@ const saveState = state => {
4133
4449
  selectedEventId,
4134
4450
  sessionId,
4135
4451
  timelineEndSeconds,
4136
- timelineStartSeconds
4452
+ timelineStartSeconds,
4453
+ visibleTableColumns
4137
4454
  };
4138
4455
  };
4139
4456
 
@@ -4181,15 +4498,33 @@ const setSessionId = async (state, sessionId) => {
4181
4498
  };
4182
4499
  };
4183
4500
 
4501
+ const toggleTableColumnVisibility = (state, column) => {
4502
+ if (!isTableColumn(column)) {
4503
+ return state;
4504
+ }
4505
+ const nextVisibleColumns = new Set(state.visibleTableColumns);
4506
+ if (nextVisibleColumns.has(column)) {
4507
+ nextVisibleColumns.delete(column);
4508
+ } else {
4509
+ nextVisibleColumns.add(column);
4510
+ }
4511
+ return {
4512
+ ...state,
4513
+ visibleTableColumns: getOrderedVisibleTableColumns([...nextVisibleColumns])
4514
+ };
4515
+ };
4516
+
4184
4517
  const commandMap = {
4185
4518
  'ChatDebug.appendStoredEventForTest': wrapCommand(appendStoredEventForTest),
4186
4519
  'ChatDebug.create': create,
4187
4520
  'ChatDebug.diff2': diff2,
4188
4521
  'ChatDebug.getCommandIds': getCommandIds,
4522
+ 'ChatDebug.getMenuEntries': wrapGetter(getMenuEntries2),
4189
4523
  'ChatDebug.getMenuIds': getMenuIds,
4190
4524
  'ChatDebug.handleClickRefresh': wrapCommand(handleClickRefresh),
4191
4525
  'ChatDebug.handleCloseDetails': wrapCommand(handleCloseDetails),
4192
4526
  'ChatDebug.handleDetailsContextMenu': wrapCommand(handleDetailsContextMenu),
4527
+ 'ChatDebug.handleDetailsTopContextMenu': wrapCommand(handleDetailsTopContextMenu),
4193
4528
  'ChatDebug.handleDetailTab': wrapCommand(handleDetailTab),
4194
4529
  'ChatDebug.handleEventCategoryFilter': wrapCommand(handleEventCategoryFilter),
4195
4530
  'ChatDebug.handleEventRowClick': wrapCommand(handleEventRowClick),
@@ -4202,6 +4537,7 @@ const commandMap = {
4202
4537
  'ChatDebug.handleShowInputEvents': wrapCommand(handleShowInputEvents),
4203
4538
  'ChatDebug.handleShowResponsePartEvents': wrapCommand(handleShowResponsePartEvents),
4204
4539
  'ChatDebug.handleTableBodyContextMenu': wrapCommand(handleTableBodyContextMenu),
4540
+ 'ChatDebug.handleTimelineContextMenu': wrapCommand(handleTimelineContextMenu),
4205
4541
  'ChatDebug.handleTimelineDoubleClick': wrapCommand(handleTimelineDoubleClick),
4206
4542
  'ChatDebug.handleTimelineEndSeconds': wrapCommand(handleTimelineEndSeconds),
4207
4543
  'ChatDebug.handleTimelinePointerDown': wrapCommand(handleTimelinePointerDown),
@@ -4216,11 +4552,13 @@ const commandMap = {
4216
4552
  'ChatDebug.render2': render2,
4217
4553
  'ChatDebug.renderEventListeners': renderEventListeners,
4218
4554
  'ChatDebug.rerender': wrapCommand(rerender),
4555
+ 'ChatDebug.resetTableColumns': wrapCommand(resetTableColumns),
4219
4556
  'ChatDebug.resize': wrapCommand(resize),
4220
4557
  'ChatDebug.saveState': wrapGetter(saveState),
4221
4558
  'ChatDebug.setEvents': wrapCommand(setEvents),
4222
4559
  'ChatDebug.setSessionId': wrapCommand(setSessionId),
4223
- 'ChatDebug.terminate': terminate
4560
+ 'ChatDebug.terminate': terminate,
4561
+ 'ChatDebug.toggleTableColumnVisibility': wrapCommand(toggleTableColumnVisibility)
4224
4562
  };
4225
4563
 
4226
4564
  const sendMessagePortToChatStorageWorker = async port => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-debug-view",
3
- "version": "7.2.0",
3
+ "version": "7.4.0",
4
4
  "description": "Chat Debug View Worker",
5
5
  "repository": {
6
6
  "type": "git",