@lvce-editor/chat-debug-view 10.10.0 → 10.13.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.
@@ -1185,6 +1185,9 @@ const writeClipBoardText = async text => {
1185
1185
  const getPreference = async key => {
1186
1186
  return await invoke('Preferences.get', key);
1187
1187
  };
1188
+ const openUri = async (uri, focus, options) => {
1189
+ await invoke('Main.openUri', uri, focus, options);
1190
+ };
1188
1191
 
1189
1192
  const toCommandId = key => {
1190
1193
  const dotIndex = key.indexOf('.');
@@ -1420,6 +1423,31 @@ const appendStoredRemovedImageAttachmentForTest = async (state, sessionId, event
1420
1423
  return state;
1421
1424
  };
1422
1425
 
1426
+ const Filter = 'filter';
1427
+ const EventCategoryFilter = 'eventCategoryFilter';
1428
+ const ShowEventStreamFinishedEvents = 'showEventStreamFinishedEvents';
1429
+ const ShowInputEvents = 'showInputEvents';
1430
+ const ShowResponsePartEvents = 'showResponsePartEvents';
1431
+ const UseDevtoolsLayout = 'useDevtoolsLayout';
1432
+ const SelectedEventIndex = 'selectedEventIndex';
1433
+ const CloseDetails$1 = 'closeDetails';
1434
+ const DetailTab = 'detailTab';
1435
+ const TimelineStartSeconds = 'timelineStartSeconds';
1436
+ const TimelineEndSeconds = 'timelineEndSeconds';
1437
+ const TimelineRangePreset = 'timelineRangePreset';
1438
+ const Refresh$1 = 'refresh';
1439
+ const All$1 = 'all';
1440
+ const Tools$1 = 'tools';
1441
+ const Network$1 = 'network';
1442
+ const Ui$1 = 'ui';
1443
+ const Stream$1 = 'stream';
1444
+ const Response$1 = 'response';
1445
+ const Preview$1 = 'preview';
1446
+ const Payload$1 = 'payload';
1447
+ const Headers$1 = 'headers';
1448
+ const Tokens$1 = 'tokens';
1449
+ const Timing$1 = 'timing';
1450
+
1423
1451
  const emptyObject = {};
1424
1452
  const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1425
1453
  const i18nString = (key, placeholders = emptyObject) => {
@@ -1432,9 +1460,10 @@ const i18nString = (key, placeholders = emptyObject) => {
1432
1460
  return key.replaceAll(RE_PLACEHOLDER, replacer);
1433
1461
  };
1434
1462
 
1435
- const All$1 = 'All';
1436
- const CloseDetails$1 = 'Close details';
1463
+ const All = 'All';
1464
+ const CloseDetails = 'Close details';
1437
1465
  const Copy = 'Copy';
1466
+ const CachedTokens = 'Cached Tokens';
1438
1467
  const DetailSections = 'Detail sections';
1439
1468
  const Duration$1 = 'Time';
1440
1469
  const Ended = 'Ended';
@@ -1442,49 +1471,62 @@ const FailedToLoadChatDebugSession = 'Failed to load chat debug session "{PH1}".
1442
1471
  const FailedToLoadChatDebugSessionWithError = 'Failed to load chat debug session "{PH1}": {PH2}';
1443
1472
  const FilterEvents = 'Filter events';
1444
1473
  const FromSeconds = 'from {PH1}s';
1474
+ const Headers = 'Headers';
1445
1475
  const ImageCouldNotBeLoaded = 'image could not be loaded';
1476
+ const InputTokens = 'Input Tokens';
1446
1477
  const InvalidSessionId = 'Invalid session id';
1447
1478
  const InvalidUriEncoding = 'Invalid URI encoding';
1448
1479
  const InvalidUriFormat = 'Invalid URI format';
1449
1480
  const Method$1 = 'Method';
1450
1481
  const MissingUri = 'Missing URI';
1451
- const Network$1 = 'Network';
1482
+ const Name = 'Name';
1483
+ const Network = 'Network';
1452
1484
  const NoChatSessionFound = 'No chat session found for sessionId "{PH1}".';
1453
1485
  const NoEventsFound = 'No events have been found';
1454
1486
  const NoEventsFoundMatching = 'No events found matching {PH1}';
1455
1487
  const NoToolCallEvents = 'No tool call events.';
1456
- const Payload$1 = 'Payload';
1457
- const Preview$1 = 'Preview';
1458
- const Refresh$1 = 'Refresh';
1488
+ const OpenInNewTab = 'Open in New Tab';
1489
+ const OutputTokens = 'Output Tokens';
1490
+ const Payload = 'Payload';
1491
+ const Preview = 'Preview';
1492
+ const Refresh = 'Refresh';
1459
1493
  const RefreshEvents = 'Refresh events';
1460
1494
  const ResetColumns = 'Reset columns';
1461
- const Response$1 = 'Response';
1495
+ const Response = 'Response';
1462
1496
  const SecondsRange = '{PH1}s-{PH2}s';
1463
1497
  const Started = 'Started';
1464
1498
  const Status$2 = 'Status';
1465
- const Stream$1 = 'Stream';
1499
+ const Stream = 'Stream';
1466
1500
  const TableSummaryPlural = '{PH1} events, {PH2} from start to finish';
1467
1501
  const TableSummarySingular = '{PH1} event, {PH2} from start to finish';
1468
- const Timing$1 = 'Timing';
1502
+ const Timing = 'Timing';
1503
+ const Tokens = 'Tokens';
1469
1504
  const ToSeconds = 'to {PH1}s';
1470
- const Tools$1 = 'Tools';
1505
+ const Tools = 'Tools';
1471
1506
  const Type$1 = 'Type';
1472
- const Ui$1 = 'UI';
1507
+ const Ui = 'UI';
1473
1508
  const UnableToLoadDebugSessionInvalidUri = 'Unable to load debug session: invalid URI "{PH1}". Expected format: chat-debug://<sessionId>.';
1474
1509
  const UnableToLoadDebugSessionMissingUri = 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
1510
+ const Value = 'Value';
1475
1511
  const WindowSummary = 'Window {PH1}-{PH2} of {PH3}';
1476
1512
 
1477
1513
  const copy = () => {
1478
1514
  return i18nString(Copy);
1479
1515
  };
1516
+ const openInNewTab = () => {
1517
+ return i18nString(OpenInNewTab);
1518
+ };
1519
+ const cachedTokens = () => {
1520
+ return i18nString(CachedTokens);
1521
+ };
1480
1522
  const status = () => {
1481
1523
  return i18nString(Status$2);
1482
1524
  };
1483
1525
  const all = () => {
1484
- return i18nString(All$1);
1526
+ return i18nString(All);
1485
1527
  };
1486
1528
  const closeDetails = () => {
1487
- return i18nString(CloseDetails$1);
1529
+ return i18nString(CloseDetails);
1488
1530
  };
1489
1531
  const detailSections = () => {
1490
1532
  return i18nString(DetailSections);
@@ -1514,12 +1556,18 @@ const fromSeconds = seconds => {
1514
1556
  PH1: seconds
1515
1557
  });
1516
1558
  };
1559
+ const headers = () => {
1560
+ return i18nString(Headers);
1561
+ };
1517
1562
  const invalidSessionId = () => {
1518
1563
  return i18nString(InvalidSessionId);
1519
1564
  };
1520
1565
  const imageCouldNotBeLoaded = () => {
1521
1566
  return i18nString(ImageCouldNotBeLoaded);
1522
1567
  };
1568
+ const inputTokens = () => {
1569
+ return i18nString(InputTokens);
1570
+ };
1523
1571
  const invalidUriEncoding = () => {
1524
1572
  return i18nString(InvalidUriEncoding);
1525
1573
  };
@@ -1532,8 +1580,11 @@ const missingUri = () => {
1532
1580
  const method = () => {
1533
1581
  return i18nString(Method$1);
1534
1582
  };
1583
+ const name = () => {
1584
+ return i18nString(Name);
1585
+ };
1535
1586
  const network = () => {
1536
- return i18nString(Network$1);
1587
+ return i18nString(Network);
1537
1588
  };
1538
1589
  const noChatSessionFound = sessionId => {
1539
1590
  return i18nString(NoChatSessionFound, {
@@ -1552,13 +1603,16 @@ const noToolCallEvents = () => {
1552
1603
  return i18nString(NoToolCallEvents);
1553
1604
  };
1554
1605
  const preview = () => {
1555
- return i18nString(Preview$1);
1606
+ return i18nString(Preview);
1556
1607
  };
1557
1608
  const payload = () => {
1558
- return i18nString(Payload$1);
1609
+ return i18nString(Payload);
1610
+ };
1611
+ const outputTokens = () => {
1612
+ return i18nString(OutputTokens);
1559
1613
  };
1560
1614
  const refresh$1 = () => {
1561
- return i18nString(Refresh$1);
1615
+ return i18nString(Refresh);
1562
1616
  };
1563
1617
  const refreshEvents$1 = () => {
1564
1618
  return i18nString(RefreshEvents);
@@ -1567,7 +1621,7 @@ const resetColumns = () => {
1567
1621
  return i18nString(ResetColumns);
1568
1622
  };
1569
1623
  const response = () => {
1570
- return i18nString(Response$1);
1624
+ return i18nString(Response);
1571
1625
  };
1572
1626
  const secondsRange = (start, end) => {
1573
1627
  return i18nString(SecondsRange, {
@@ -1579,10 +1633,13 @@ const started = () => {
1579
1633
  return i18nString(Started);
1580
1634
  };
1581
1635
  const stream = () => {
1582
- return i18nString(Stream$1);
1636
+ return i18nString(Stream);
1583
1637
  };
1584
1638
  const timing = () => {
1585
- return i18nString(Timing$1);
1639
+ return i18nString(Timing);
1640
+ };
1641
+ const tokens = () => {
1642
+ return i18nString(Tokens);
1586
1643
  };
1587
1644
  const tableSummary = (eventCount, duration) => {
1588
1645
  return i18nString(eventCount === 1 ? TableSummarySingular : TableSummaryPlural, {
@@ -1596,13 +1653,16 @@ const toSeconds = seconds => {
1596
1653
  });
1597
1654
  };
1598
1655
  const tools = () => {
1599
- return i18nString(Tools$1);
1656
+ return i18nString(Tools);
1600
1657
  };
1601
1658
  const type = () => {
1602
1659
  return i18nString(Type$1);
1603
1660
  };
1661
+ const value = () => {
1662
+ return i18nString(Value);
1663
+ };
1604
1664
  const ui = () => {
1605
- return i18nString(Ui$1);
1665
+ return i18nString(Ui);
1606
1666
  };
1607
1667
  const unableToLoadDebugSessionInvalidUri = uri => {
1608
1668
  return i18nString(UnableToLoadDebugSessionInvalidUri, {
@@ -1620,159 +1680,66 @@ const windowSummary = (start, end, duration) => {
1620
1680
  });
1621
1681
  };
1622
1682
 
1623
- const Filter = 'filter';
1624
- const EventCategoryFilter = 'eventCategoryFilter';
1625
- const ShowEventStreamFinishedEvents = 'showEventStreamFinishedEvents';
1626
- const ShowInputEvents = 'showInputEvents';
1627
- const ShowResponsePartEvents = 'showResponsePartEvents';
1628
- const UseDevtoolsLayout = 'useDevtoolsLayout';
1629
- const SelectedEventIndex = 'selectedEventIndex';
1630
- const CloseDetails = 'closeDetails';
1631
- const DetailTab = 'detailTab';
1632
- const TimelineStartSeconds = 'timelineStartSeconds';
1633
- const TimelineEndSeconds = 'timelineEndSeconds';
1634
- const TimelineRangePreset = 'timelineRangePreset';
1635
- const Refresh = 'refresh';
1636
- const All = 'all';
1637
- const Tools = 'tools';
1638
- const Network = 'network';
1639
- const Ui = 'ui';
1640
- const Stream = 'stream';
1641
- const Response = 'response';
1642
- const Preview = 'preview';
1643
- const Payload = 'payload';
1644
- const Timing = 'timing';
1645
-
1646
- const isDetailTab = value => {
1647
- return value === Response || value === Preview || value === Payload || value === Timing;
1648
- };
1649
-
1650
- const getSafeSelectedDetailTab = selectedDetailTab => {
1651
- return isDetailTab(selectedDetailTab) ? selectedDetailTab : Response;
1652
- };
1653
-
1654
- const hasTimingDetails = event => {
1655
- const hasDuration = typeof event.duration === 'number' || typeof event.durationMs === 'number';
1656
- const hasStart = event.started !== undefined || event.startTime !== undefined || event.startTimestamp !== undefined;
1657
- const hasEnd = event.ended !== undefined || event.endTime !== undefined || event.endTimestamp !== undefined;
1658
- return hasDuration || hasStart && hasEnd;
1659
- };
1660
-
1661
- const createDetailTabs = (selectedDetailTab = Response, event) => {
1662
- const hasTimingTab = event ? hasTimingDetails(event) : true;
1663
- const safeSelectedDetailTab = getSafeSelectedDetailTab(selectedDetailTab);
1664
- const normalizedSelectedDetailTab = hasTimingTab || safeSelectedDetailTab !== Timing ? safeSelectedDetailTab : Response;
1665
- const detailTabs = [{
1666
- isSelected: normalizedSelectedDetailTab === Preview,
1667
- label: preview(),
1668
- name: Preview
1669
- }, {
1670
- isSelected: normalizedSelectedDetailTab === Payload,
1671
- label: payload(),
1672
- name: Payload
1673
- }, {
1674
- isSelected: normalizedSelectedDetailTab === Response,
1675
- label: response(),
1676
- name: Response
1677
- }];
1678
- if (hasTimingTab) {
1679
- detailTabs.push({
1680
- isSelected: normalizedSelectedDetailTab === Timing,
1681
- label: timing(),
1682
- name: Timing
1683
- });
1684
- }
1685
- return detailTabs;
1686
- };
1687
-
1688
- const getSelectedDetailTab = detailTabs => {
1689
- const selectedDetailTab = detailTabs.find(detailTab => detailTab.isSelected);
1690
- if (selectedDetailTab) {
1691
- return selectedDetailTab.name;
1692
- }
1693
- const responseTab = detailTabs.find(detailTab => detailTab.name === Response);
1694
- if (responseTab) {
1695
- return responseTab.name;
1696
- }
1697
- return detailTabs[0]?.name ?? Response;
1698
- };
1699
-
1700
- const hasDetailTab = (detailTabs, value) => {
1701
- return detailTabs.some(detailTab => detailTab.name === value);
1702
- };
1703
-
1704
- const selectDetailTab$1 = (detailTabs, selectedDetailTab) => {
1705
- if (!hasDetailTab(detailTabs, selectedDetailTab)) {
1706
- return detailTabs;
1707
- }
1708
- return detailTabs.map(detailTab => {
1709
- return {
1710
- ...detailTab,
1711
- isSelected: detailTab.name === selectedDetailTab
1712
- };
1713
- });
1714
- };
1715
-
1716
1683
  const getEventCategoryFilterLabel = eventCategoryFilter => {
1717
1684
  switch (eventCategoryFilter) {
1718
- case Network:
1685
+ case Network$1:
1719
1686
  return network();
1720
- case Stream:
1687
+ case Stream$1:
1721
1688
  return stream();
1722
- case Tools:
1689
+ case Tools$1:
1723
1690
  return tools();
1724
- case Ui:
1691
+ case Ui$1:
1725
1692
  return ui();
1726
1693
  default:
1727
1694
  return all();
1728
1695
  }
1729
1696
  };
1730
1697
 
1731
- const eventCategoryFilters = [All, Tools, Network, Ui, Stream];
1732
- const normalizeSelectedEventCategoryFilters = (selectedEventCategoryFilter = All) => {
1698
+ const eventCategoryFilters = [All$1, Tools$1, Network$1, Ui$1, Stream$1];
1699
+ const normalizeSelectedEventCategoryFilters = (selectedEventCategoryFilter = All$1) => {
1733
1700
  const selectedEventCategoryFilters = Array.isArray(selectedEventCategoryFilter) ? selectedEventCategoryFilter : [selectedEventCategoryFilter];
1734
1701
  const uniqueSelectedEventCategoryFilters = [...new Set(selectedEventCategoryFilters)];
1735
1702
  const validSelectedEventCategoryFilters = uniqueSelectedEventCategoryFilters.filter(value => {
1736
1703
  return eventCategoryFilters.includes(value);
1737
1704
  });
1738
1705
  if (validSelectedEventCategoryFilters.length === 0) {
1739
- return [All];
1706
+ return [All$1];
1740
1707
  }
1741
- if (validSelectedEventCategoryFilters.includes(All)) {
1742
- return [All];
1708
+ if (validSelectedEventCategoryFilters.includes(All$1)) {
1709
+ return [All$1];
1743
1710
  }
1744
1711
  return validSelectedEventCategoryFilters;
1745
1712
  };
1746
- const createCategoryFilters$1 = (selectedEventCategoryFilter = All) => {
1713
+ const createCategoryFilters$1 = (selectedEventCategoryFilter = All$1) => {
1747
1714
  const selectedEventCategoryFilters = normalizeSelectedEventCategoryFilters(selectedEventCategoryFilter);
1748
1715
  return [{
1749
- isSelected: selectedEventCategoryFilters.includes(All),
1716
+ isSelected: selectedEventCategoryFilters.includes(All$1),
1750
1717
  label: all(),
1751
- name: All
1718
+ name: All$1
1752
1719
  }, {
1753
- isSelected: selectedEventCategoryFilters.includes(Tools),
1720
+ isSelected: selectedEventCategoryFilters.includes(Tools$1),
1754
1721
  label: tools(),
1755
- name: Tools
1722
+ name: Tools$1
1756
1723
  }, {
1757
- isSelected: selectedEventCategoryFilters.includes(Network),
1724
+ isSelected: selectedEventCategoryFilters.includes(Network$1),
1758
1725
  label: network(),
1759
- name: Network
1726
+ name: Network$1
1760
1727
  }, {
1761
- isSelected: selectedEventCategoryFilters.includes(Ui),
1728
+ isSelected: selectedEventCategoryFilters.includes(Ui$1),
1762
1729
  label: ui(),
1763
- name: Ui
1730
+ name: Ui$1
1764
1731
  }, {
1765
- isSelected: selectedEventCategoryFilters.includes(Stream),
1732
+ isSelected: selectedEventCategoryFilters.includes(Stream$1),
1766
1733
  label: stream(),
1767
- name: Stream
1734
+ name: Stream$1
1768
1735
  }];
1769
1736
  };
1770
1737
 
1771
- const createCategoryFilters = (selectedEventCategoryFilter = All) => {
1738
+ const createCategoryFilters = (selectedEventCategoryFilter = All$1) => {
1772
1739
  return createCategoryFilters$1(selectedEventCategoryFilter);
1773
1740
  };
1774
1741
  const isEventCategoryFilter = value => {
1775
- return value === All || value === Tools || value === Network || value === Ui || value === Stream;
1742
+ return value === All$1 || value === Tools$1 || value === Network$1 || value === Ui$1 || value === Stream$1;
1776
1743
  };
1777
1744
  const getSelectedEventCategoryFilters = categoryFilters => {
1778
1745
  const selectedCategoryFilters = categoryFilters.filter(categoryFilter => categoryFilter.isSelected);
@@ -1784,7 +1751,7 @@ const getSelectedEventCategoryFilter = categoryFilters => {
1784
1751
  if (selectedEventCategoryFilters.length === 1) {
1785
1752
  return selectedEventCategoryFilters[0];
1786
1753
  }
1787
- return All;
1754
+ return All$1;
1788
1755
  };
1789
1756
  const selectCategoryFilters = (categoryFilters, selectedEventCategoryFilters) => {
1790
1757
  const normalizedSelectedEventCategoryFilters = normalizeSelectedEventCategoryFilters(selectedEventCategoryFilters.filter(value => isEventCategoryFilter(value)));
@@ -1803,29 +1770,33 @@ const selectCategoryFilter = (categoryFilters, selectedEventCategoryFilter, addi
1803
1770
  if (!isEventCategoryFilter(selectedEventCategoryFilter)) {
1804
1771
  return categoryFilters;
1805
1772
  }
1806
- if (!additive || selectedEventCategoryFilter === All) {
1773
+ if (!additive || selectedEventCategoryFilter === All$1) {
1807
1774
  return selectCategoryFilters(categoryFilters, [selectedEventCategoryFilter]);
1808
1775
  }
1809
- const selectedEventCategoryFilters = getSelectedEventCategoryFilters(categoryFilters).filter(value => value !== All);
1776
+ const selectedEventCategoryFilters = getSelectedEventCategoryFilters(categoryFilters).filter(value => value !== All$1);
1810
1777
  const nextSelectedEventCategoryFilters = selectedEventCategoryFilters.includes(selectedEventCategoryFilter) ? selectedEventCategoryFilters.filter(value => value !== selectedEventCategoryFilter) : [...selectedEventCategoryFilters, selectedEventCategoryFilter];
1811
1778
  if (nextSelectedEventCategoryFilters.length === 0) {
1812
- return selectCategoryFilters(categoryFilters, [All]);
1779
+ return selectCategoryFilters(categoryFilters, [All$1]);
1813
1780
  }
1814
1781
  return selectCategoryFilters(categoryFilters, nextSelectedEventCategoryFilters);
1815
1782
  };
1816
1783
 
1784
+ const isDetailTab = value => {
1785
+ return value === Response$1 || value === Preview$1 || value === Payload$1 || value === Headers$1 || value === Tokens$1 || value === Headers$1 || value === Timing$1;
1786
+ };
1787
+
1817
1788
  const RE_SPACE = /\s+/;
1818
- const tokenToEventCategoryFilter = new Map([['@tools', Tools], ['@network', Network], ['@ui', Ui], ['@stream', Stream]]);
1789
+ const tokenToEventCategoryFilter = new Map([['@tools', Tools$1], ['@network', Network$1], ['@ui', Ui$1], ['@stream', Stream$1]]);
1819
1790
  const parseFilterValue = filterValue => {
1820
1791
  const normalizedFilter = filterValue.trim().toLowerCase();
1821
1792
  if (!normalizedFilter) {
1822
1793
  return {
1823
- eventCategoryFilter: All,
1794
+ eventCategoryFilter: All$1,
1824
1795
  filterText: ''
1825
1796
  };
1826
1797
  }
1827
1798
  const parts = normalizedFilter.split(RE_SPACE);
1828
- const eventCategoryFilter = parts.map(part => tokenToEventCategoryFilter.get(part)).find(Boolean) || All;
1799
+ const eventCategoryFilter = parts.map(part => tokenToEventCategoryFilter.get(part)).find(Boolean) || All$1;
1829
1800
  const filterText = parts.filter(part => !tokenToEventCategoryFilter.has(part)).join(' ');
1830
1801
  return {
1831
1802
  eventCategoryFilter,
@@ -1833,6 +1804,22 @@ const parseFilterValue = filterValue => {
1833
1804
  };
1834
1805
  };
1835
1806
 
1807
+ const hasDetailTab = (detailTabs, value) => {
1808
+ return detailTabs.some(detailTab => detailTab.name === value);
1809
+ };
1810
+
1811
+ const selectDetailTab$1 = (detailTabs, selectedDetailTab) => {
1812
+ if (!hasDetailTab(detailTabs, selectedDetailTab)) {
1813
+ return detailTabs;
1814
+ }
1815
+ return detailTabs.map(detailTab => {
1816
+ return {
1817
+ ...detailTab,
1818
+ isSelected: detailTab.name === selectedDetailTab
1819
+ };
1820
+ });
1821
+ };
1822
+
1836
1823
  const Type = 'type';
1837
1824
  const Method = 'method';
1838
1825
  const Duration = 'duration';
@@ -1904,31 +1891,23 @@ const defaultTableColumnWidths = {
1904
1891
  type: 260
1905
1892
  };
1906
1893
 
1907
- const defaultTableWidth = 480;
1908
- const minTableWidth = 240;
1909
- const minDetailsWidth = 280;
1910
- const sashWidth = 8;
1911
- const viewPadding = 8;
1912
- const timelineHorizontalPadding = 10;
1913
- const horizontalPadding = viewPadding * 2;
1914
- const leftPadding = viewPadding;
1915
- const getMainWidth = width => {
1916
- return Math.max(0, width - horizontalPadding);
1917
- };
1918
- const clampTableWidth = (width, tableWidth) => {
1919
- const mainWidth = getMainWidth(width);
1920
- const maxTableWidth = Math.max(0, mainWidth - minDetailsWidth - sashWidth);
1921
- const minClampedTableWidth = Math.min(minTableWidth, maxTableWidth);
1894
+ const getMainWidth = state => {
1895
+ return Math.max(0, state.width - state.horizontalPadding);
1896
+ };
1897
+ const clampTableWidth = (state, tableWidth) => {
1898
+ const mainWidth = getMainWidth(state);
1899
+ const maxTableWidth = Math.max(0, mainWidth - state.minDetailsWidth - state.sashWidth);
1900
+ const minClampedTableWidth = Math.min(state.minTableWidth, maxTableWidth);
1922
1901
  return Math.max(minClampedTableWidth, Math.min(tableWidth, maxTableWidth));
1923
1902
  };
1924
- const getDetailsWidth = (width, tableWidth) => {
1925
- const mainWidth = getMainWidth(width);
1926
- const clampedTableWidth = clampTableWidth(width, tableWidth);
1927
- return Math.max(0, mainWidth - clampedTableWidth - sashWidth);
1903
+ const getDetailsWidth = (state, tableWidth) => {
1904
+ const mainWidth = getMainWidth(state);
1905
+ const clampedTableWidth = clampTableWidth(state, tableWidth);
1906
+ return Math.max(0, mainWidth - clampedTableWidth - state.sashWidth);
1928
1907
  };
1929
- const getTableWidthFromClientX = (viewX, width, clientX) => {
1930
- const nextTableWidth = clientX - viewX - leftPadding;
1931
- return clampTableWidth(width, nextTableWidth);
1908
+ const getTableWidthFromClientX = (state, clientX) => {
1909
+ const nextTableWidth = clientX - state.x - state.leftPadding;
1910
+ return clampTableWidth(state, nextTableWidth);
1932
1911
  };
1933
1912
 
1934
1913
  const minimumTableColumnWidths = {
@@ -1981,8 +1960,8 @@ const getTableColumnLayout = (tableWidth, visibleTableColumns, tableColumnWidths
1981
1960
  };
1982
1961
  };
1983
1962
 
1984
- const getResizedTableColumnWidths = (width, tableWidth, visibleTableColumns, tableColumnWidths, viewX, clientX, resizerDownId) => {
1985
- const clampedTableWidth = clampTableWidth(width, tableWidth);
1963
+ const getResizedTableColumnWidths = (state, visibleTableColumns, tableColumnWidths, clientX, resizerDownId) => {
1964
+ const clampedTableWidth = clampTableWidth(state, state.tableWidth);
1986
1965
  const layout = getTableColumnLayout(clampedTableWidth, visibleTableColumns, tableColumnWidths);
1987
1966
  if (resizerDownId < 1 || resizerDownId >= layout.visibleColumns.length) {
1988
1967
  return tableColumnWidths;
@@ -1993,7 +1972,7 @@ const getResizedTableColumnWidths = (width, tableWidth, visibleTableColumns, tab
1993
1972
  const minimumWidth = getMinimumTableColumnWidth(resizedColumn);
1994
1973
  const minimumRemainingWidth = layout.visibleColumns.slice(boundaryIndex + 1).reduce((total, column) => total + getMinimumTableColumnWidth(column), 0);
1995
1974
  const maxWidth = Math.max(minimumWidth, clampedTableWidth - precedingWidth - minimumRemainingWidth);
1996
- const nextWidth = clientX - viewX - leftPadding - precedingWidth;
1975
+ const nextWidth = clientX - state.x - state.leftPadding - precedingWidth;
1997
1976
  const clampedWidth = Math.max(minimumWidth, Math.min(nextWidth, maxWidth));
1998
1977
  return {
1999
1978
  ...tableColumnWidths,
@@ -2017,7 +1996,7 @@ const isTableColumnWidths = value => {
2017
1996
  return isFiniteNumber(record.type) && isFiniteNumber(record.method) && isFiniteNumber(record.duration) && isFiniteNumber(record.status);
2018
1997
  };
2019
1998
 
2020
- const validEventCategoryFilters = new Set([All, Network, Stream, Tools, Ui]);
1999
+ const validEventCategoryFilters = new Set([All$1, Network$1, Stream$1, Tools$1, Ui$1]);
2021
2000
  const isSavedState = value => {
2022
2001
  return typeof value === 'object' && value !== null;
2023
2002
  };
@@ -2084,6 +2063,145 @@ const {
2084
2063
  wrapGetter
2085
2064
  } = create$1();
2086
2065
 
2066
+ const getSafeSelectedDetailTab = selectedDetailTab => {
2067
+ return isDetailTab(selectedDetailTab) ? selectedDetailTab : Response$1;
2068
+ };
2069
+
2070
+ const isHeadersRecord$1 = value => {
2071
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
2072
+ };
2073
+ const hasHeadersDetails = event => {
2074
+ return event.type === 'ai-request' && isHeadersRecord$1(event.headers);
2075
+ };
2076
+
2077
+ const hasTimingDetails = event => {
2078
+ const hasDuration = typeof event.duration === 'number' || typeof event.durationMs === 'number';
2079
+ const hasStart = event.started !== undefined || event.startTime !== undefined || event.startTimestamp !== undefined;
2080
+ const hasEnd = event.ended !== undefined || event.endTime !== undefined || event.endTimestamp !== undefined;
2081
+ return hasDuration || hasStart && hasEnd;
2082
+ };
2083
+
2084
+ const getResponseEvent = event => {
2085
+ const {
2086
+ responseEvent
2087
+ } = event;
2088
+ if (responseEvent && typeof responseEvent === 'object' && typeof responseEvent.type === 'string') {
2089
+ const mergedResponseEvent = responseEvent;
2090
+ if (mergedResponseEvent.value !== undefined) {
2091
+ return mergedResponseEvent.value;
2092
+ }
2093
+ return responseEvent;
2094
+ }
2095
+ return event;
2096
+ };
2097
+
2098
+ const isObject = value => {
2099
+ return typeof value === 'object' && value !== null;
2100
+ };
2101
+ const getNumber = (value, ...keys) => {
2102
+ for (const key of keys) {
2103
+ if (typeof value[key] === 'number') {
2104
+ return value[key];
2105
+ }
2106
+ }
2107
+ return undefined;
2108
+ };
2109
+ const getUsage = event => {
2110
+ const responseEvent = getResponseEvent(event);
2111
+ if (isObject(responseEvent) && isObject(responseEvent.usage)) {
2112
+ return responseEvent.usage;
2113
+ }
2114
+ if (isObject(responseEvent) && isObject(responseEvent.value) && isObject(responseEvent.value.usage)) {
2115
+ return responseEvent.value.usage;
2116
+ }
2117
+ return undefined;
2118
+ };
2119
+ const getTokenUsageDetails = event => {
2120
+ const usage = getUsage(event);
2121
+ if (!usage) {
2122
+ return undefined;
2123
+ }
2124
+ const inputTokens = getNumber(usage, 'input_tokens', 'inputTokens');
2125
+ const outputTokens = getNumber(usage, 'output_tokens', 'outputTokens');
2126
+ let inputTokenDetails;
2127
+ if (isObject(usage.input_tokens_details)) {
2128
+ inputTokenDetails = usage.input_tokens_details;
2129
+ } else if (isObject(usage.inputTokensDetails)) {
2130
+ inputTokenDetails = usage.inputTokensDetails;
2131
+ }
2132
+ const cachedTokens = inputTokenDetails ? getNumber(inputTokenDetails, 'cached_tokens', 'cachedTokens') : getNumber(usage, 'cached_tokens', 'cachedTokens');
2133
+ if (inputTokens === undefined && outputTokens === undefined && cachedTokens === undefined) {
2134
+ return undefined;
2135
+ }
2136
+ return {
2137
+ ...(cachedTokens === undefined ? undefined : {
2138
+ cachedTokens
2139
+ }),
2140
+ ...(inputTokens === undefined ? undefined : {
2141
+ inputTokens
2142
+ }),
2143
+ ...(outputTokens === undefined ? undefined : {
2144
+ outputTokens
2145
+ })
2146
+ };
2147
+ };
2148
+
2149
+ const hasTokenUsageDetails = event => {
2150
+ return getTokenUsageDetails(event) !== undefined;
2151
+ };
2152
+
2153
+ const createDetailTabs = (selectedDetailTab = Response$1, event) => {
2154
+ const hasHeadersTab = event ? hasHeadersDetails(event) : false;
2155
+ const hasTokensTab = event ? hasTokenUsageDetails(event) : false;
2156
+ const hasTimingTab = event ? hasTimingDetails(event) : true;
2157
+ const safeSelectedDetailTab = getSafeSelectedDetailTab(selectedDetailTab);
2158
+ let normalizedSelectedDetailTab = safeSelectedDetailTab;
2159
+ if (!hasHeadersTab && normalizedSelectedDetailTab === Headers$1) {
2160
+ normalizedSelectedDetailTab = Response$1;
2161
+ }
2162
+ if (!hasTokensTab && normalizedSelectedDetailTab === Tokens$1) {
2163
+ normalizedSelectedDetailTab = Response$1;
2164
+ }
2165
+ if (!hasTimingTab && normalizedSelectedDetailTab === Timing$1) {
2166
+ normalizedSelectedDetailTab = Response$1;
2167
+ }
2168
+ const detailTabs = [{
2169
+ isSelected: normalizedSelectedDetailTab === Preview$1,
2170
+ label: preview(),
2171
+ name: Preview$1
2172
+ }, {
2173
+ isSelected: normalizedSelectedDetailTab === Payload$1,
2174
+ label: payload(),
2175
+ name: Payload$1
2176
+ }, {
2177
+ isSelected: normalizedSelectedDetailTab === Response$1,
2178
+ label: response(),
2179
+ name: Response$1
2180
+ }];
2181
+ if (hasHeadersTab) {
2182
+ detailTabs.push({
2183
+ isSelected: normalizedSelectedDetailTab === Headers$1,
2184
+ label: headers(),
2185
+ name: Headers$1
2186
+ });
2187
+ }
2188
+ if (hasTokensTab) {
2189
+ detailTabs.push({
2190
+ isSelected: normalizedSelectedDetailTab === Tokens$1,
2191
+ label: tokens(),
2192
+ name: Tokens$1
2193
+ });
2194
+ }
2195
+ if (hasTimingTab) {
2196
+ detailTabs.push({
2197
+ isSelected: normalizedSelectedDetailTab === Timing$1,
2198
+ label: timing(),
2199
+ name: Timing$1
2200
+ });
2201
+ }
2202
+ return detailTabs;
2203
+ };
2204
+
2087
2205
  const toTimeNumber = value => {
2088
2206
  if (typeof value === 'number' && Number.isFinite(value)) {
2089
2207
  return value;
@@ -2217,11 +2335,20 @@ const getTimelineInfo = (events, startValue, endValue) => {
2217
2335
  };
2218
2336
 
2219
2337
  const createDefaultState = () => {
2338
+ const defaultTableWidth = 480;
2339
+ const minTableWidth = 240;
2340
+ const minDetailsWidth = 280;
2341
+ const sashWidth = 4;
2342
+ const viewPadding = 8;
2343
+ const timelineHorizontalPadding = 10;
2344
+ const horizontalPadding = viewPadding * 2;
2345
+ const leftPadding = viewPadding;
2220
2346
  return {
2221
2347
  assetDir: '',
2222
2348
  categoryFilters: createCategoryFilters(),
2223
2349
  databaseName: 'lvce-chat-view-sessions',
2224
2350
  dataBaseVersion: 2,
2351
+ defaultTableWidth,
2225
2352
  detailTabs: createDetailTabs(),
2226
2353
  devtoolsRootGap: 4,
2227
2354
  devtoolsTimelineHeight: 88,
@@ -2232,9 +2359,13 @@ const createDefaultState = () => {
2232
2359
  filterValue: '',
2233
2360
  focus: 0,
2234
2361
  height: 0,
2362
+ horizontalPadding,
2235
2363
  initial: false,
2236
2364
  largeBreakpoint: 900,
2365
+ leftPadding,
2237
2366
  mediumBreakpoint: 600,
2367
+ minDetailsWidth,
2368
+ minTableWidth,
2238
2369
  platform: 0,
2239
2370
  previewTextCursorColumnIndex: null,
2240
2371
  previewTextCursorRowIndex: null,
@@ -2242,6 +2373,7 @@ const createDefaultState = () => {
2242
2373
  previewTextScrollBarHandleOffset: 0,
2243
2374
  previewTextScrollBarPointerActive: false,
2244
2375
  sashPointerActive: false,
2376
+ sashWidth,
2245
2377
  selectedEvent: null,
2246
2378
  selectedEventId: null,
2247
2379
  selectedEventIndex: null,
@@ -2265,6 +2397,7 @@ const createDefaultState = () => {
2265
2397
  timelineEvents: [],
2266
2398
  timelineFilterDescription: '',
2267
2399
  timelineHeight: 81,
2400
+ timelineHorizontalPadding,
2268
2401
  timelineHoverPercent: null,
2269
2402
  timelineHoverSeconds: '',
2270
2403
  timelineInfo: emptyTimelineInfo,
@@ -2275,6 +2408,7 @@ const createDefaultState = () => {
2275
2408
  uid: 0,
2276
2409
  uri: '',
2277
2410
  useDevtoolsLayout: true,
2411
+ viewPadding,
2278
2412
  width: 0,
2279
2413
  x: 0,
2280
2414
  y: 0
@@ -2326,6 +2460,18 @@ const diff2 = uid => {
2326
2460
  return diff(oldState, newState);
2327
2461
  };
2328
2462
 
2463
+ const getSelectedDetailTab = detailTabs => {
2464
+ const selectedDetailTab = detailTabs.find(detailTab => detailTab.isSelected);
2465
+ if (selectedDetailTab) {
2466
+ return selectedDetailTab.name;
2467
+ }
2468
+ const responseTab = detailTabs.find(detailTab => detailTab.name === Response$1);
2469
+ if (responseTab) {
2470
+ return responseTab.name;
2471
+ }
2472
+ return detailTabs[0]?.name ?? Response$1;
2473
+ };
2474
+
2329
2475
  const filterEventsByTimelineRange = (events, startValue, endValue) => {
2330
2476
  const eventsWithTime = getEventsWithTime(events);
2331
2477
  if (eventsWithTime.length === 0) {
@@ -2538,20 +2684,20 @@ const isUiEvent = event => {
2538
2684
 
2539
2685
  const matchesSingleEventCategoryFilter = (event, eventCategoryFilter) => {
2540
2686
  switch (eventCategoryFilter) {
2541
- case Network:
2687
+ case Network$1:
2542
2688
  return isNetworkEvent(event);
2543
- case Stream:
2689
+ case Stream$1:
2544
2690
  return isStreamEvent(event);
2545
- case Tools:
2691
+ case Tools$1:
2546
2692
  return isToolEvent(event);
2547
- case Ui:
2693
+ case Ui$1:
2548
2694
  return isUiEvent(event);
2549
2695
  default:
2550
2696
  return true;
2551
2697
  }
2552
2698
  };
2553
2699
  const matchesEventCategoryFilter = (event, eventCategoryFilters) => {
2554
- if (eventCategoryFilters.length === 0 || eventCategoryFilters.includes(All)) {
2700
+ if (eventCategoryFilters.length === 0 || eventCategoryFilters.includes(All$1)) {
2555
2701
  return true;
2556
2702
  }
2557
2703
  return eventCategoryFilters.some(eventCategoryFilter => matchesSingleEventCategoryFilter(event, eventCategoryFilter));
@@ -2561,7 +2707,7 @@ const getFilteredEvents = (events, filterValue, eventCategoryFilters, showInputE
2561
2707
  const visibleEvents = getVisibleEvents(events, showInputEvents, showResponsePartEvents, showEventStreamFinishedEvents);
2562
2708
  const collapsedEvents = collapseToolExecutionEvents(visibleEvents);
2563
2709
  const parsedFilter = parseFilterValue(filterValue);
2564
- const activeEventCategoryFilters = parsedFilter.eventCategoryFilter === All ? eventCategoryFilters : [parsedFilter.eventCategoryFilter];
2710
+ const activeEventCategoryFilters = parsedFilter.eventCategoryFilter === All$1 ? eventCategoryFilters : [parsedFilter.eventCategoryFilter];
2565
2711
  const filteredByCategory = collapsedEvents.filter(event => matchesEventCategoryFilter(event, activeEventCategoryFilters));
2566
2712
  const {
2567
2713
  filterText
@@ -2747,7 +2893,10 @@ const mergeSelectedEventDetails = (selectedEvent, selectedEventDetails) => {
2747
2893
  responseEvent
2748
2894
  } = selectedEvent;
2749
2895
  if (!requestEvent || !responseEvent || typeof requestEvent !== 'object' || typeof responseEvent !== 'object') {
2750
- return selectedEventDetails;
2896
+ return {
2897
+ ...selectedEvent,
2898
+ ...selectedEventDetails
2899
+ };
2751
2900
  }
2752
2901
  const selectedEventDetailsType = selectedEventDetails.type;
2753
2902
  const resolvedResponseEvent = selectedEventDetailsType === 'response' || selectedEventDetailsType === 'ai-response-success' ? selectedEventDetails : responseEvent;
@@ -2773,6 +2922,7 @@ const getTableBodyY = (state, hasTimeline) => {
2773
2922
  devtoolsRootGap,
2774
2923
  devtoolsTimelineHeight,
2775
2924
  devtoolsTopHeight,
2925
+ viewPadding,
2776
2926
  y
2777
2927
  } = state;
2778
2928
  return y + viewPadding + devtoolsTopHeight + devtoolsRootGap + (hasTimeline ? devtoolsTimelineHeight : 0) + devtoolsTableHeaderHeight;
@@ -2783,7 +2933,7 @@ const getTableBodyHeight = (state, eventCount) => {
2783
2933
  return 0;
2784
2934
  }
2785
2935
  const tableBodyY = getTableBodyY(state, true);
2786
- return Math.max(0, state.height - (tableBodyY - state.y) - viewPadding - devtoolsTableSummaryHeight);
2936
+ return Math.max(0, state.height - (tableBodyY - state.y) - state.viewPadding - devtoolsTableSummaryHeight);
2787
2937
  };
2788
2938
  const getVisibleRowCount = tableBodyHeight => {
2789
2939
  if (tableBodyHeight <= 0) {
@@ -2984,7 +3134,15 @@ const selectEventAtIndexDependencies = {
2984
3134
  };
2985
3135
  const getCurrentEvents$1 = state => getCurrentEvents$2(state);
2986
3136
  const selectEventAtIndex = async (state, selectedEventIndex, dependencies = selectEventAtIndexDependencies) => {
2987
- const selectedDetailTab = getSelectedDetailTab(state.detailTabs);
3137
+ const {
3138
+ databaseName,
3139
+ dataBaseVersion,
3140
+ detailTabs,
3141
+ eventStoreName,
3142
+ sessionId,
3143
+ sessionIdIndexName
3144
+ } = state;
3145
+ const selectedDetailTab = getSelectedDetailTab(detailTabs);
2988
3146
  const currentEvents = getCurrentEvents$1(state);
2989
3147
  const selectedEvent = currentEvents[selectedEventIndex];
2990
3148
  if (!selectedEvent) {
@@ -3003,7 +3161,7 @@ const selectEventAtIndex = async (state, selectedEventIndex, dependencies = sele
3003
3161
  selectedEventIndex
3004
3162
  };
3005
3163
  }
3006
- const selectedEventDetails = await dependencies.loadSelectedEvent(state.databaseName, state.dataBaseVersion, state.eventStoreName, state.sessionId, state.sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
3164
+ const selectedEventDetails = await dependencies.loadSelectedEvent(databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
3007
3165
  const resolvedSelectedEvent = await withPreparedSelectedEventPreview(mergeSelectedEventDetails(selectedEvent, selectedEventDetails));
3008
3166
  return withSelectedEventVisible({
3009
3167
  ...state,
@@ -3067,6 +3225,12 @@ const getMenuEntriesTableBody = props => {
3067
3225
  flags: None$1,
3068
3226
  id: 'copy',
3069
3227
  label: copy()
3228
+ }, {
3229
+ args: [props.eventIndex],
3230
+ command: 'ChatDebug.handleTableRowOpenInNewTab',
3231
+ flags: None$1,
3232
+ id: 'open-in-new-tab',
3233
+ label: openInNewTab()
3070
3234
  }];
3071
3235
  };
3072
3236
 
@@ -3120,7 +3284,6 @@ const getTableBodyEventIndex = (state, eventX, eventY) => {
3120
3284
  tableMinLineY,
3121
3285
  tableWidth,
3122
3286
  useDevtoolsLayout,
3123
- width,
3124
3287
  x
3125
3288
  } = state;
3126
3289
  if (!useDevtoolsLayout) {
@@ -3130,8 +3293,8 @@ const getTableBodyEventIndex = (state, eventX, eventY) => {
3130
3293
  if (currentEvents.length === 0) {
3131
3294
  return -1;
3132
3295
  }
3133
- const tableX = x + leftPadding;
3134
- const tableWidthNew = clampTableWidth(width, tableWidth);
3296
+ const tableX = x + state.leftPadding;
3297
+ const tableWidthNew = clampTableWidth(state, tableWidth);
3135
3298
  const hasTimeline = currentEvents.length > 0;
3136
3299
  const tableBodyY = getTableBodyY(state, hasTimeline);
3137
3300
  const relativeX = eventX - tableX;
@@ -3170,9 +3333,51 @@ const getMenuIds = () => {
3170
3333
  return [MenuChatDebugTableHeader, MenuChatDebugTableBody, 556, 557];
3171
3334
  };
3172
3335
 
3336
+ const getResponseMap = events => {
3337
+ const seen = Object.create(null);
3338
+ for (const event of events) {
3339
+ if (event.type === 'ai-response' && 'requestId' in event && typeof event.requestId === 'string') {
3340
+ seen[event.requestId] = event;
3341
+ }
3342
+ }
3343
+ return seen;
3344
+ };
3345
+
3346
+ const toPrettyEvents = rawEvents => {
3347
+ if (rawEvents.type === 'error') {
3348
+ return [];
3349
+ }
3350
+ const pretty = [];
3351
+ const map = getResponseMap(rawEvents.events);
3352
+ for (const item of rawEvents.events) {
3353
+ if (item.type === 'ai-request' && 'requestId' in item && typeof item.requestId === 'string') {
3354
+ const response = map[item.requestId];
3355
+ if (response) {
3356
+ pretty.push({
3357
+ eventId: item.eventId,
3358
+ type: 'ai-request-response'
3359
+ });
3360
+ } else {
3361
+ pretty.push(item);
3362
+ }
3363
+ } else if (item.type === 'ai-response' && 'requestId' in item && typeof item.requestId === 'string') ; else {
3364
+ pretty.push(item);
3365
+ }
3366
+ }
3367
+ return pretty;
3368
+ };
3369
+
3173
3370
  const listChatViewEvents = async (sessionId, _databaseName, _dataBaseVersion, _eventStoreName, _sessionIdIndexName) => {
3174
3371
  try {
3175
- return await listChatViewEvents$1(sessionId);
3372
+ const rawEvents = await listChatViewEvents$1(sessionId);
3373
+ if (rawEvents.type === 'error') {
3374
+ return rawEvents;
3375
+ }
3376
+ const prettyEvents = toPrettyEvents(rawEvents);
3377
+ return {
3378
+ events: prettyEvents,
3379
+ type: 'success'
3380
+ };
3176
3381
  } catch (error) {
3177
3382
  return {
3178
3383
  error,
@@ -3582,7 +3787,7 @@ const handleEventCategoryFilter$1 = (state, value, ctrlKey = false, metaKey = fa
3582
3787
  const {
3583
3788
  categoryFilters
3584
3789
  } = state;
3585
- const newCategoryFilters = selectCategoryFilter(categoryFilters, value || All, ctrlKey || metaKey);
3790
+ const newCategoryFilters = selectCategoryFilter(categoryFilters, value || All$1, ctrlKey || metaKey);
3586
3791
  if (newCategoryFilters === categoryFilters) {
3587
3792
  return state;
3588
3793
  }
@@ -3703,7 +3908,7 @@ const handleFilter = (state, value) => {
3703
3908
  });
3704
3909
  };
3705
3910
  const handleEventCategoryFilter = (state, value) => {
3706
- const categoryFilters = selectCategoryFilter(state.categoryFilters, value || All);
3911
+ const categoryFilters = selectCategoryFilter(state.categoryFilters, value || All$1);
3707
3912
  if (categoryFilters === state.categoryFilters) {
3708
3913
  return state;
3709
3914
  }
@@ -3789,7 +3994,7 @@ const handleDetailTab = (state, value) => {
3789
3994
  };
3790
3995
  };
3791
3996
  const inputHandlers = {
3792
- [CloseDetails]: handleCloseDetails,
3997
+ [CloseDetails$1]: handleCloseDetails,
3793
3998
  [DetailTab]: handleDetailTab,
3794
3999
  [EventCategoryFilter]: handleEventCategoryFilter,
3795
4000
  [Filter]: handleFilter,
@@ -4320,7 +4525,7 @@ const handleSashPointerMove = (state, eventX, eventY) => {
4320
4525
  }
4321
4526
  return {
4322
4527
  ...state,
4323
- tableWidth: getTableWidthFromClientX(state.x, state.width, eventX)
4528
+ tableWidth: getTableWidthFromClientX(state, eventX)
4324
4529
  };
4325
4530
  };
4326
4531
 
@@ -4385,7 +4590,7 @@ const handleTableResizerPointerMove = (state, clientX) => {
4385
4590
  }
4386
4591
  return {
4387
4592
  ...state,
4388
- tableColumnWidths: getResizedTableColumnWidths(state.width, state.tableWidth, getVisibleTableColumns(state.tableColumns), state.tableColumnWidths, state.x, clientX, state.tableResizerDownId)
4593
+ tableColumnWidths: getResizedTableColumnWidths(state, getVisibleTableColumns(state.tableColumns), state.tableColumnWidths, clientX, state.tableResizerDownId)
4389
4594
  };
4390
4595
  };
4391
4596
 
@@ -4410,6 +4615,20 @@ const handleTableRowCopy = async (state, eventIndex) => {
4410
4615
  return state;
4411
4616
  };
4412
4617
 
4618
+ const toDataUri = text => {
4619
+ return `data:application/json,${encodeURIComponent(text)}`;
4620
+ };
4621
+ const handleTableRowOpenInNewTab = async (state, eventIndex) => {
4622
+ const currentEvents = getCurrentEvents$1(state);
4623
+ const event = currentEvents[eventIndex];
4624
+ if (!event) {
4625
+ return state;
4626
+ }
4627
+ const text = JSON.stringify(event, null, 2);
4628
+ await openUri(toDataUri(text));
4629
+ return state;
4630
+ };
4631
+
4413
4632
  const getHandleOffsetAndPercent = (tableBodyHeight, scrollBarHeight, relativeY) => {
4414
4633
  const halfScrollBarHeight = scrollBarHeight / 2;
4415
4634
  if (relativeY <= halfScrollBarHeight) {
@@ -4550,10 +4769,10 @@ const getTimelineEventX = eventX => {
4550
4769
  };
4551
4770
 
4552
4771
  const getTimelineLeft = state => {
4553
- return state.x + viewPadding + timelineHorizontalPadding;
4772
+ return state.x + state.viewPadding + state.timelineHorizontalPadding;
4554
4773
  };
4555
4774
  const getTimelineWidth = state => {
4556
- return Math.max(0, getMainWidth(state.width) - timelineHorizontalPadding * 2);
4775
+ return Math.max(0, getMainWidth(state) - state.timelineHorizontalPadding * 2);
4557
4776
  };
4558
4777
 
4559
4778
  const getTimelineDurationSeconds = events => {
@@ -4751,20 +4970,8 @@ const isAttachmentImagePreview = value => {
4751
4970
  return typeof value === 'object' && value !== null && value.previewType === 'image';
4752
4971
  };
4753
4972
 
4754
- const getResponseEvent = event => {
4755
- const {
4756
- responseEvent
4757
- } = event;
4758
- if (responseEvent && typeof responseEvent === 'object' && typeof responseEvent.type === 'string') {
4759
- const mergedResponseEvent = responseEvent;
4760
- if (mergedResponseEvent.value !== undefined) {
4761
- return mergedResponseEvent.value;
4762
- }
4763
- return responseEvent;
4764
- }
4765
- return event;
4766
- };
4767
-
4973
+ const detailsLineNumberDigitWidth = 8;
4974
+ const detailsLineNumberHorizontalPadding = 8;
4768
4975
  const getStringLineCount = value => {
4769
4976
  return value.split('\n').length;
4770
4977
  };
@@ -4809,13 +5016,13 @@ const getLineCount = state => {
4809
5016
  return 0;
4810
5017
  }
4811
5018
  const selectedDetailTab = getSelectedDetailTab(state.detailTabs);
4812
- if (selectedDetailTab === Timing) {
5019
+ if (selectedDetailTab === Timing$1 || selectedDetailTab === Tokens$1) {
4813
5020
  return 0;
4814
5021
  }
4815
- if (selectedDetailTab === Preview) {
5022
+ if (selectedDetailTab === Preview$1) {
4816
5023
  return getPreviewLineCount(selectedEvent);
4817
5024
  }
4818
- if (selectedDetailTab === Payload) {
5025
+ if (selectedDetailTab === Payload$1) {
4819
5026
  return getJsonLineCount(getPayloadEvent(selectedEvent));
4820
5027
  }
4821
5028
  return getJsonLineCount(getResponseEvent(selectedEvent));
@@ -4825,14 +5032,15 @@ const getDetailsLineNumberWidth = state => {
4825
5032
  if (lineCount === 0) {
4826
5033
  return 0;
4827
5034
  }
4828
- return String(lineCount).length * defaultPreviewTextColumnWidth;
5035
+ const digitCount = String(lineCount).length;
5036
+ return digitCount * detailsLineNumberDigitWidth + detailsLineNumberHorizontalPadding;
4829
5037
  };
4830
5038
 
4831
5039
  // cspell:ignore liga calt
4832
5040
 
4833
5041
  const getCss = state => {
4834
5042
  const hasSelectedEvent = !!state.selectedEvent;
4835
- const tableWidth = hasSelectedEvent ? clampTableWidth(state.width, state.tableWidth) : getMainWidth(state.width);
5043
+ const tableWidth = hasSelectedEvent ? clampTableWidth(state, state.tableWidth) : getMainWidth(state);
4836
5044
  const currentEvents = getCurrentEvents$2(state);
4837
5045
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
4838
5046
  const scrollBarHeight = getScrollBarHeight(currentEvents.length, tableBodyHeight);
@@ -4840,7 +5048,7 @@ const getCss = state => {
4840
5048
  const showScrollBar = scrollBarHeight > 0;
4841
5049
  const scrollBarOffset = getScrollBarOffset(state.tableDeltaY, maxDeltaY, tableBodyHeight, scrollBarHeight);
4842
5050
  const tableContentWidth = Math.max(0, tableWidth - (showScrollBar ? devtoolsTableScrollBarWidth : 0));
4843
- const detailsWidth = hasSelectedEvent ? getDetailsWidth(state.width, state.tableWidth) : 0;
5051
+ const detailsWidth = hasSelectedEvent ? getDetailsWidth(state, state.tableWidth) : 0;
4844
5052
  const detailsLineNumberWidth = getDetailsLineNumberWidth(state);
4845
5053
  const previewTextViewportHeight = getPreviewTextViewportHeight(state);
4846
5054
  const previewVirtualization = getPreviewVirtualizationState(state.selectedEvent, previewTextViewportHeight, state.previewTextDeltaY);
@@ -4879,7 +5087,7 @@ const getCss = state => {
4879
5087
  --ResizerOneLeft: ${resizerOneLeft}px;
4880
5088
  --ResizerTwoLeft: ${resizerTwoLeft}px;
4881
5089
  --ResizerThreeLeft: ${resizerThreeLeft}px;
4882
- --ChatDebugViewSashWidth: ${sashWidth}px;
5090
+ --ChatDebugViewSashWidth: ${state.sashWidth}px;
4883
5091
  --ChatDebugViewTableWidth: ${tableWidth}px;
4884
5092
  --ChatDebugViewTimelineHeight: ${state.timelineHeight}px;
4885
5093
  --ChatDebugViewTimelineCursorGuideLeft: ${state.timelineHoverPercent ?? 0}%;
@@ -4887,7 +5095,7 @@ const getCss = state => {
4887
5095
  --ChatDebugViewTimelineSelectionStartLeft: ${selectionStartPercent ?? 0}%;
4888
5096
  --ChatDebugViewTopSize: ${topSize}px;
4889
5097
  --ChatDebugViewTypeColumnWidth: ${state.tableColumnWidths.type}px;
4890
- padding: ${viewPadding}px;
5098
+ padding: ${state.viewPadding}px;
4891
5099
  padding-right: 0;
4892
5100
  }
4893
5101
 
@@ -4901,6 +5109,51 @@ const getCss = state => {
4901
5109
  width: calc(100% - var(--ChatDebugViewTableScrollBarWidth));
4902
5110
  }
4903
5111
 
5112
+ .Resizers {
5113
+ bottom: 0;
5114
+ left: 0;
5115
+ pointer-events: none;
5116
+ position: absolute;
5117
+ right: var(--ChatDebugViewTableScrollBarWidth);
5118
+ top: 0;
5119
+ }
5120
+
5121
+ .Resizer {
5122
+ background: transparent;
5123
+ border: 0;
5124
+ bottom: 0;
5125
+ cursor: col-resize;
5126
+ margin: 0;
5127
+ padding: 0;
5128
+ pointer-events: auto;
5129
+ position: absolute;
5130
+ top: 0;
5131
+ transform: translateX(calc(-0.5 * var(--ChatDebugViewSashWidth)));
5132
+ width: var(--ChatDebugViewSashWidth);
5133
+ }
5134
+
5135
+ .ResizerOne {
5136
+ left: var(--ResizerOneLeft);
5137
+ }
5138
+
5139
+ .ResizerTwo {
5140
+ left: var(--ResizerTwoLeft);
5141
+ }
5142
+
5143
+ .ResizerThree {
5144
+ left: var(--ResizerThreeLeft);
5145
+ }
5146
+
5147
+ .ResizerInner {
5148
+ background: var(--vscode-panel-border, rgba(255, 255, 255, 0.12));
5149
+ bottom: 0;
5150
+ pointer-events: none;
5151
+ position: absolute;
5152
+ top: 0;
5153
+ transform: translateX(-0.5px);
5154
+ width: 1px;
5155
+ }
5156
+
4904
5157
  .ChatDebugViewTimeline {
4905
5158
  contain: strict;
4906
5159
  display: flex;
@@ -4920,12 +5173,40 @@ const getCss = state => {
4920
5173
  width: var(--ChatDebugViewDetailsLineNumberWidth);
4921
5174
  }
4922
5175
 
4923
- .ChatDebugViewDetailsBottom .ChatDebugViewEventLineNumber {
4924
- display: inline-block;
4925
- min-width: var(--ChatDebugViewDetailsLineNumberWidth);
4926
- width: var(--ChatDebugViewDetailsLineNumberWidth);
5176
+ .ChatDebugViewHeadersTable {
5177
+ border-collapse: collapse;
5178
+ table-layout: fixed;
5179
+ width: 100%;
5180
+ }
5181
+
5182
+ .ChatDebugViewHeadersCell {
5183
+ border-bottom: 1px solid var(--vscode-panel-border, rgba(255, 255, 255, 0.12));
5184
+ color: var(--vscode-editor-foreground);
5185
+ padding: 6px 10px;
5186
+ text-align: left;
5187
+ vertical-align: top;
5188
+ word-break: break-word;
5189
+ }
5190
+
5191
+ .ChatDebugViewHeadersHead .ChatDebugViewHeadersCell {
5192
+ color: var(--vscode-descriptionForeground, rgba(255, 255, 255, 0.7));
5193
+ font-size: 11px;
5194
+ font-weight: 600;
5195
+ text-transform: uppercase;
5196
+ }
5197
+
5198
+ .ChatDebugViewHeadersRowOdd {
5199
+ background: rgba(255, 255, 255, 0.02);
5200
+ }
5201
+
5202
+ .ChatDebugViewHeadersRowEven {
5203
+ background: rgba(255, 255, 255, 0.04);
4927
5204
  }
4928
5205
 
5206
+ .ChatDebugViewHeadersCellName {
5207
+ font-weight: 500;
5208
+ width: 38%;
5209
+ }
4929
5210
  .PreviewVirtualizedEditor {
4930
5211
  height: var(--ChatDebugViewPreviewViewportHeight);
4931
5212
  overflow: hidden;
@@ -5325,6 +5606,15 @@ const PanelTab = 'PanelTab';
5325
5606
  const PanelTabSelected = 'PanelTabSelected';
5326
5607
  const ChatDebugViewDetailsTabs = 'ChatDebugViewDetailsTabs';
5327
5608
  const ChatDebugViewDetailsTop = 'ChatDebugViewDetailsTop';
5609
+ const ChatDebugViewHeadersBody = 'ChatDebugViewHeadersBody';
5610
+ const ChatDebugViewHeadersCell = 'ChatDebugViewHeadersCell';
5611
+ const ChatDebugViewHeadersCellName = 'ChatDebugViewHeadersCellName';
5612
+ const ChatDebugViewHeadersCellValue = 'ChatDebugViewHeadersCellValue';
5613
+ const ChatDebugViewHeadersHead = 'ChatDebugViewHeadersHead';
5614
+ const ChatDebugViewHeadersRow = 'ChatDebugViewHeadersRow';
5615
+ const ChatDebugViewHeadersRowEven = 'ChatDebugViewHeadersRowEven';
5616
+ const ChatDebugViewHeadersRowOdd = 'ChatDebugViewHeadersRowOdd';
5617
+ const ChatDebugViewHeadersTable = 'ChatDebugViewHeadersTable';
5328
5618
  const ChatDebugViewDevtoolsSplit = 'ChatDebugViewDevtoolsSplit';
5329
5619
  const ChatDebugViewEmpty = 'ChatDebugViewEmpty';
5330
5620
  const ChatDebugViewError = 'ChatDebugViewError';
@@ -5525,10 +5815,10 @@ const refreshButtonDom = [{
5525
5815
  'aria-label': refreshEvents$1(),
5526
5816
  childCount: 1,
5527
5817
  className: ChatDebugViewRefreshButton,
5528
- name: Refresh,
5818
+ name: Refresh$1,
5529
5819
  onClick: HandleClickRefresh,
5530
5820
  type: Button$1,
5531
- value: Refresh
5821
+ value: Refresh$1
5532
5822
  }, text(refresh$1())];
5533
5823
  const getRefreshButtonDom = () => {
5534
5824
  return refreshButtonDom;
@@ -5590,7 +5880,7 @@ const detailsCloseButtonDom = [{
5590
5880
  'aria-label': closeDetails(),
5591
5881
  childCount: 1,
5592
5882
  className: ChatDebugViewDetailsClose,
5593
- name: CloseDetails,
5883
+ name: CloseDetails$1,
5594
5884
  onChange: HandleCloseDetails,
5595
5885
  onClick: HandleCloseDetails,
5596
5886
  type: Button$1,
@@ -5604,6 +5894,44 @@ const getDetailsCloseButtonDom = () => {
5604
5894
  return detailsCloseButtonDom;
5605
5895
  };
5606
5896
 
5897
+ const getDetailTabDom = detailTab => {
5898
+ const {
5899
+ isSelected
5900
+ } = detailTab;
5901
+ return [{
5902
+ 'aria-controls': getPanelId(detailTab.name),
5903
+ ariaSelected: isSelected,
5904
+ childCount: 1,
5905
+ className: mergeClassNames(PanelTab, isSelected ? PanelTabSelected : ''),
5906
+ name: detailTab.name,
5907
+ onChange: SelectDetailTab,
5908
+ onClick: SelectDetailTab,
5909
+ onFocus: HandleDetailTabsFocus,
5910
+ role: Tab,
5911
+ tabIndex: isSelected ? 0 : -1,
5912
+ type: Button$1
5913
+ }, text(detailTab.label)];
5914
+ };
5915
+
5916
+ const getTabNodes = detailTabs => {
5917
+ return [{
5918
+ 'aria-label': detailSections(),
5919
+ childCount: detailTabs.length,
5920
+ className: ChatDebugViewDetailsTabs,
5921
+ role: 'tablist',
5922
+ type: Div
5923
+ }, ...detailTabs.flatMap(getDetailTabDom)];
5924
+ };
5925
+
5926
+ const getDetailsTopVirtualDom = detailTabs => {
5927
+ return [{
5928
+ childCount: 2,
5929
+ className: ChatDebugViewDetailsTop,
5930
+ onContextMenu: HandleDetailsTopContextMenu,
5931
+ type: Div
5932
+ }, ...getDetailsCloseButtonDom(), ...getTabNodes(detailTabs)];
5933
+ };
5934
+
5607
5935
  const getNormalizedDetailTabs = (selectedEvent, detailTabs) => {
5608
5936
  if (selectedEvent === null) {
5609
5937
  return detailTabs;
@@ -5611,6 +5939,99 @@ const getNormalizedDetailTabs = (selectedEvent, detailTabs) => {
5611
5939
  return createDetailTabs(getSelectedDetailTab(detailTabs), selectedEvent);
5612
5940
  };
5613
5941
 
5942
+ const isHeadersRecord = value => {
5943
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
5944
+ };
5945
+ const stringifyHeaderValue = value => {
5946
+ try {
5947
+ return JSON.stringify(value, (_key, nestedValue) => {
5948
+ if (typeof nestedValue === 'bigint') {
5949
+ return nestedValue.toString();
5950
+ }
5951
+ return nestedValue;
5952
+ });
5953
+ } catch {
5954
+ return '[unserializable]';
5955
+ }
5956
+ };
5957
+ const getHeaderValueText = value => {
5958
+ if (typeof value === 'string') {
5959
+ return value;
5960
+ }
5961
+ if (value === undefined) {
5962
+ return '';
5963
+ }
5964
+ if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
5965
+ return String(value);
5966
+ }
5967
+ if (value === null) {
5968
+ return 'null';
5969
+ }
5970
+ if (typeof value === 'symbol') {
5971
+ return value.description ? `Symbol(${value.description})` : 'Symbol()';
5972
+ }
5973
+ if (typeof value === 'function') {
5974
+ return '[function]';
5975
+ }
5976
+ return stringifyHeaderValue(value);
5977
+ };
5978
+ const getHeaders = selectedEvent => {
5979
+ if (selectedEvent === null || !isHeadersRecord(selectedEvent.headers)) {
5980
+ return [];
5981
+ }
5982
+ return Object.entries(selectedEvent.headers);
5983
+ };
5984
+ const getHeaderRowNodes = (headerName, headerValue, index) => {
5985
+ return [{
5986
+ childCount: 2,
5987
+ className: mergeClassNames(ChatDebugViewHeadersRow, index % 2 === 0 ? ChatDebugViewHeadersRowOdd : ChatDebugViewHeadersRowEven),
5988
+ type: Tr
5989
+ }, {
5990
+ childCount: 1,
5991
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellName),
5992
+ type: Td
5993
+ }, text(headerName), {
5994
+ childCount: 1,
5995
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellValue),
5996
+ type: Td
5997
+ }, text(getHeaderValueText(headerValue))];
5998
+ };
5999
+ const getHeadersContentNodes = (responseEventNodes, selectedEvent) => {
6000
+ const headers = getHeaders(selectedEvent);
6001
+ if (headers.length === 0) {
6002
+ return responseEventNodes;
6003
+ }
6004
+ const headerRows = [];
6005
+ for (const [index, [headerName, headerValue]] of headers.entries()) {
6006
+ headerRows.push(...getHeaderRowNodes(headerName, headerValue, index));
6007
+ }
6008
+ return [{
6009
+ childCount: 2,
6010
+ className: ChatDebugViewHeadersTable,
6011
+ type: Table$1
6012
+ }, {
6013
+ childCount: 1,
6014
+ className: ChatDebugViewHeadersHead,
6015
+ type: THead
6016
+ }, {
6017
+ childCount: 2,
6018
+ className: ChatDebugViewHeadersRow,
6019
+ type: Tr
6020
+ }, {
6021
+ childCount: 1,
6022
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellName),
6023
+ type: Th
6024
+ }, text(name()), {
6025
+ childCount: 1,
6026
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellValue),
6027
+ type: Th
6028
+ }, text(value()), {
6029
+ childCount: headers.length,
6030
+ className: ChatDebugViewHeadersBody,
6031
+ type: TBody
6032
+ }, ...headerRows];
6033
+ };
6034
+
5614
6035
  const getEditorRowDom = line => {
5615
6036
  return [{
5616
6037
  childCount: line.childCount,
@@ -6653,48 +7074,58 @@ const getTimingContentNodes = (responseEventNodes, selectedEvent) => {
6653
7074
  return getTimingDetailsDom(selectedEvent);
6654
7075
  };
6655
7076
 
7077
+ const getTokenUsageDetailsDom = event => {
7078
+ const usageDetails = getTokenUsageDetails(event);
7079
+ if (!usageDetails) {
7080
+ return [];
7081
+ }
7082
+ const rows = [];
7083
+ let rowCount = 0;
7084
+ if (usageDetails.inputTokens !== undefined) {
7085
+ rows.push(...getTimingRowDom(inputTokens(), String(usageDetails.inputTokens)));
7086
+ rowCount++;
7087
+ }
7088
+ if (usageDetails.outputTokens !== undefined) {
7089
+ rows.push(...getTimingRowDom(outputTokens(), String(usageDetails.outputTokens)));
7090
+ rowCount++;
7091
+ }
7092
+ if (usageDetails.cachedTokens !== undefined) {
7093
+ rows.push(...getTimingRowDom(cachedTokens(), String(usageDetails.cachedTokens)));
7094
+ rowCount++;
7095
+ }
7096
+ return [{
7097
+ childCount: rowCount,
7098
+ className: ChatDebugViewTiming,
7099
+ type: Div
7100
+ }, ...rows];
7101
+ };
7102
+
7103
+ const getTokenUsageContentNodes = (responseEventNodes, selectedEvent) => {
7104
+ if (selectedEvent === null) {
7105
+ return responseEventNodes;
7106
+ }
7107
+ return getTokenUsageDetailsDom(selectedEvent);
7108
+ };
7109
+
6656
7110
  const getSelectedContentNodes = (safeSelectedDetailTab, previewEventNodes, payloadEventNodes, responseEventNodes, selectedEvent, previewTextCursorRowIndex, previewTextCursorColumnIndex, previewVirtualization) => {
6657
- if (safeSelectedDetailTab === Timing) {
7111
+ if (safeSelectedDetailTab === Tokens$1) {
7112
+ return getTokenUsageContentNodes(responseEventNodes, selectedEvent);
7113
+ }
7114
+ if (safeSelectedDetailTab === Timing$1) {
6658
7115
  return getTimingContentNodes(responseEventNodes, selectedEvent);
6659
7116
  }
6660
- if (safeSelectedDetailTab === Preview) {
7117
+ if (safeSelectedDetailTab === Preview$1) {
6661
7118
  return getPreviewContentNodes(previewEventNodes, selectedEvent, previewTextCursorRowIndex, previewTextCursorColumnIndex, previewVirtualization);
6662
7119
  }
6663
- if (safeSelectedDetailTab === Payload) {
7120
+ if (safeSelectedDetailTab === Payload$1) {
6664
7121
  return getPayloadContentNodes(payloadEventNodes, selectedEvent);
6665
7122
  }
7123
+ if (safeSelectedDetailTab === Headers$1) {
7124
+ return getHeadersContentNodes(responseEventNodes, selectedEvent);
7125
+ }
6666
7126
  return getResponseContentNodes(responseEventNodes, selectedEvent);
6667
7127
  };
6668
7128
 
6669
- const getDetailTabDom = detailTab => {
6670
- const {
6671
- isSelected
6672
- } = detailTab;
6673
- return [{
6674
- 'aria-controls': getPanelId(detailTab.name),
6675
- ariaSelected: isSelected,
6676
- childCount: 1,
6677
- className: mergeClassNames(PanelTab, isSelected ? PanelTabSelected : ''),
6678
- name: detailTab.name,
6679
- onChange: SelectDetailTab,
6680
- onClick: SelectDetailTab,
6681
- onFocus: HandleDetailTabsFocus,
6682
- role: Tab,
6683
- tabIndex: isSelected ? 0 : -1,
6684
- type: Button$1
6685
- }, text(detailTab.label)];
6686
- };
6687
-
6688
- const getTabNodes = detailTabs => {
6689
- return [{
6690
- 'aria-label': detailSections(),
6691
- childCount: detailTabs.length,
6692
- className: ChatDebugViewDetailsTabs,
6693
- role: 'tablist',
6694
- type: Div
6695
- }, ...detailTabs.flatMap(getDetailTabDom)];
6696
- };
6697
-
6698
7129
  const getDetailsDom = (previewEventNodes, payloadEventNodes = previewEventNodes, responseEventNodes = payloadEventNodes, selectedEvent = null, detailTabs = createDetailTabs(), previewTextCursorRowIndex = null, previewTextCursorColumnIndex = null, previewVirtualization) => {
6699
7130
  if (previewEventNodes.length === 0 && payloadEventNodes.length === 0 && responseEventNodes.length === 0) {
6700
7131
  return [];
@@ -6707,12 +7138,7 @@ const getDetailsDom = (previewEventNodes, payloadEventNodes = previewEventNodes,
6707
7138
  childCount: 2,
6708
7139
  className: ChatDebugViewDetails,
6709
7140
  type: Section
6710
- }, {
6711
- childCount: 2,
6712
- className: ChatDebugViewDetailsTop,
6713
- onContextMenu: HandleDetailsTopContextMenu,
6714
- type: Div
6715
- }, ...getDetailsCloseButtonDom(), ...getTabNodes(normalizedDetailTabs), ...getDetailContentDom(selectedDetailTab, safeSelectedDetailTab, contentNodes)];
7141
+ }, ...getDetailsTopVirtualDom(normalizedDetailTabs), ...getDetailContentDom(selectedDetailTab, safeSelectedDetailTab, contentNodes)];
6716
7142
  };
6717
7143
 
6718
7144
  const getMethods = new Set(['list_dir', 'list_files', 'read_file']);
@@ -7284,7 +7710,7 @@ const getTopLevelChildCount = nodes => {
7284
7710
  return count;
7285
7711
  };
7286
7712
  const getEventCategoryFilterDescription = eventCategoryFilters => {
7287
- if (eventCategoryFilters.length === 0 || eventCategoryFilters.includes(All)) {
7713
+ if (eventCategoryFilters.length === 0 || eventCategoryFilters.includes(All$1)) {
7288
7714
  return '';
7289
7715
  }
7290
7716
  return eventCategoryFilters.map(eventCategoryFilter => getEventCategoryFilterLabel(eventCategoryFilter).toLowerCase()).join(', ');
@@ -7309,7 +7735,7 @@ const getChatDebugViewDom = (errorMessage, filterValue, eventCategoryFilters, ca
7309
7735
  const hasFilterValue = filterDescriptionParts.length > 0;
7310
7736
  const filterDescription = filterDescriptionParts.join(' ');
7311
7737
  const noFilteredEventsMessage = noEventsFoundMatching(filterDescription);
7312
- const useNoToolCallEventsMessage = eventCategoryFilters.length === 1 && eventCategoryFilters[0] === Tools && !trimmedFilterValue && !hasTimelineFilter;
7738
+ const useNoToolCallEventsMessage = eventCategoryFilters.length === 1 && eventCategoryFilters[0] === Tools$1 && !trimmedFilterValue && !hasTimelineFilter;
7313
7739
  const emptyMessage = getEmptyMessage(events.length, hasFilterValue, useNoToolCallEventsMessage, noFilteredEventsMessage);
7314
7740
  const safeSelectedEventIndex = selectedEventIndex === null || selectedEventIndex < 0 || selectedEventIndex >= events.length ? null : selectedEventIndex;
7315
7741
  if (useDevtoolsLayout) {
@@ -7510,12 +7936,10 @@ const renderEventListeners = () => {
7510
7936
  }, {
7511
7937
  name: HandleTableWheel,
7512
7938
  params: ['handleTableWheel', 'event.deltaY'],
7513
- passive: true,
7514
7939
  preventDefault: true
7515
7940
  }, {
7516
7941
  name: HandlePreviewTextWheel,
7517
7942
  params: ['handlePreviewTextWheel', 'event.deltaY'],
7518
- passive: true,
7519
7943
  preventDefault: true
7520
7944
  }, {
7521
7945
  name: HandlePreviewTextScrollBarPointerDown,
@@ -7573,7 +7997,7 @@ const handleResize = (state, dimensions) => {
7573
7997
  };
7574
7998
  return applyVirtualTableState({
7575
7999
  ...nextState,
7576
- tableWidth: clampTableWidth(nextState.width, state.tableWidth)
8000
+ tableWidth: clampTableWidth(nextState, state.tableWidth)
7577
8001
  });
7578
8002
  };
7579
8003
 
@@ -7750,6 +8174,7 @@ const commandMap = {
7750
8174
  'ChatDebug.handleTableResizerPointerMove': wrapCommand(handleTableResizerPointerMove),
7751
8175
  'ChatDebug.handleTableResizerPointerUp': wrapCommand(handleTableResizerPointerUp),
7752
8176
  'ChatDebug.handleTableRowCopy': wrapCommand(handleTableRowCopy),
8177
+ 'ChatDebug.handleTableRowOpenInNewTab': wrapCommand(handleTableRowOpenInNewTab),
7753
8178
  'ChatDebug.handleTableScrollBarPointerDown': wrapCommand(handleTableScrollBarPointerDown),
7754
8179
  'ChatDebug.handleTableScrollBarPointerMove': wrapCommand(handleTableScrollBarPointerMove),
7755
8180
  'ChatDebug.handleTableScrollBarPointerUp': wrapCommand(handleTableScrollBarPointerUp),