@lvce-editor/chat-debug-view 10.10.0 → 10.11.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.
@@ -1435,6 +1435,7 @@ const i18nString = (key, placeholders = emptyObject) => {
1435
1435
  const All$1 = 'All';
1436
1436
  const CloseDetails$1 = 'Close details';
1437
1437
  const Copy = 'Copy';
1438
+ const CachedTokens = 'Cached Tokens';
1438
1439
  const DetailSections = 'Detail sections';
1439
1440
  const Duration$1 = 'Time';
1440
1441
  const Ended = 'Ended';
@@ -1442,17 +1443,21 @@ const FailedToLoadChatDebugSession = 'Failed to load chat debug session "{PH1}".
1442
1443
  const FailedToLoadChatDebugSessionWithError = 'Failed to load chat debug session "{PH1}": {PH2}';
1443
1444
  const FilterEvents = 'Filter events';
1444
1445
  const FromSeconds = 'from {PH1}s';
1446
+ const Headers$1 = 'Headers';
1445
1447
  const ImageCouldNotBeLoaded = 'image could not be loaded';
1448
+ const InputTokens = 'Input Tokens';
1446
1449
  const InvalidSessionId = 'Invalid session id';
1447
1450
  const InvalidUriEncoding = 'Invalid URI encoding';
1448
1451
  const InvalidUriFormat = 'Invalid URI format';
1449
1452
  const Method$1 = 'Method';
1450
1453
  const MissingUri = 'Missing URI';
1454
+ const Name = 'Name';
1451
1455
  const Network$1 = 'Network';
1452
1456
  const NoChatSessionFound = 'No chat session found for sessionId "{PH1}".';
1453
1457
  const NoEventsFound = 'No events have been found';
1454
1458
  const NoEventsFoundMatching = 'No events found matching {PH1}';
1455
1459
  const NoToolCallEvents = 'No tool call events.';
1460
+ const OutputTokens = 'Output Tokens';
1456
1461
  const Payload$1 = 'Payload';
1457
1462
  const Preview$1 = 'Preview';
1458
1463
  const Refresh$1 = 'Refresh';
@@ -1466,17 +1471,22 @@ const Stream$1 = 'Stream';
1466
1471
  const TableSummaryPlural = '{PH1} events, {PH2} from start to finish';
1467
1472
  const TableSummarySingular = '{PH1} event, {PH2} from start to finish';
1468
1473
  const Timing$1 = 'Timing';
1474
+ const Tokens$1 = 'Tokens';
1469
1475
  const ToSeconds = 'to {PH1}s';
1470
1476
  const Tools$1 = 'Tools';
1471
1477
  const Type$1 = 'Type';
1472
1478
  const Ui$1 = 'UI';
1473
1479
  const UnableToLoadDebugSessionInvalidUri = 'Unable to load debug session: invalid URI "{PH1}". Expected format: chat-debug://<sessionId>.';
1474
1480
  const UnableToLoadDebugSessionMissingUri = 'Unable to load debug session: missing URI. Expected format: chat-debug://<sessionId>.';
1481
+ const Value = 'Value';
1475
1482
  const WindowSummary = 'Window {PH1}-{PH2} of {PH3}';
1476
1483
 
1477
1484
  const copy = () => {
1478
1485
  return i18nString(Copy);
1479
1486
  };
1487
+ const cachedTokens = () => {
1488
+ return i18nString(CachedTokens);
1489
+ };
1480
1490
  const status = () => {
1481
1491
  return i18nString(Status$2);
1482
1492
  };
@@ -1514,12 +1524,18 @@ const fromSeconds = seconds => {
1514
1524
  PH1: seconds
1515
1525
  });
1516
1526
  };
1527
+ const headers = () => {
1528
+ return i18nString(Headers$1);
1529
+ };
1517
1530
  const invalidSessionId = () => {
1518
1531
  return i18nString(InvalidSessionId);
1519
1532
  };
1520
1533
  const imageCouldNotBeLoaded = () => {
1521
1534
  return i18nString(ImageCouldNotBeLoaded);
1522
1535
  };
1536
+ const inputTokens = () => {
1537
+ return i18nString(InputTokens);
1538
+ };
1523
1539
  const invalidUriEncoding = () => {
1524
1540
  return i18nString(InvalidUriEncoding);
1525
1541
  };
@@ -1532,6 +1548,9 @@ const missingUri = () => {
1532
1548
  const method = () => {
1533
1549
  return i18nString(Method$1);
1534
1550
  };
1551
+ const name = () => {
1552
+ return i18nString(Name);
1553
+ };
1535
1554
  const network = () => {
1536
1555
  return i18nString(Network$1);
1537
1556
  };
@@ -1557,6 +1576,9 @@ const preview = () => {
1557
1576
  const payload = () => {
1558
1577
  return i18nString(Payload$1);
1559
1578
  };
1579
+ const outputTokens = () => {
1580
+ return i18nString(OutputTokens);
1581
+ };
1560
1582
  const refresh$1 = () => {
1561
1583
  return i18nString(Refresh$1);
1562
1584
  };
@@ -1584,6 +1606,9 @@ const stream = () => {
1584
1606
  const timing = () => {
1585
1607
  return i18nString(Timing$1);
1586
1608
  };
1609
+ const tokens = () => {
1610
+ return i18nString(Tokens$1);
1611
+ };
1587
1612
  const tableSummary = (eventCount, duration) => {
1588
1613
  return i18nString(eventCount === 1 ? TableSummarySingular : TableSummaryPlural, {
1589
1614
  PH1: String(eventCount),
@@ -1601,6 +1626,9 @@ const tools = () => {
1601
1626
  const type = () => {
1602
1627
  return i18nString(Type$1);
1603
1628
  };
1629
+ const value = () => {
1630
+ return i18nString(Value);
1631
+ };
1604
1632
  const ui = () => {
1605
1633
  return i18nString(Ui$1);
1606
1634
  };
@@ -1641,16 +1669,25 @@ const Stream = 'stream';
1641
1669
  const Response = 'response';
1642
1670
  const Preview = 'preview';
1643
1671
  const Payload = 'payload';
1672
+ const Headers = 'headers';
1673
+ const Tokens = 'tokens';
1644
1674
  const Timing = 'timing';
1645
1675
 
1646
1676
  const isDetailTab = value => {
1647
- return value === Response || value === Preview || value === Payload || value === Timing;
1677
+ return value === Response || value === Preview || value === Payload || value === Headers || value === Tokens || value === Headers || value === Timing;
1648
1678
  };
1649
1679
 
1650
1680
  const getSafeSelectedDetailTab = selectedDetailTab => {
1651
1681
  return isDetailTab(selectedDetailTab) ? selectedDetailTab : Response;
1652
1682
  };
1653
1683
 
1684
+ const isHeadersRecord$1 = value => {
1685
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
1686
+ };
1687
+ const hasHeadersDetails = event => {
1688
+ return event.type === 'ai-request' && isHeadersRecord$1(event.headers);
1689
+ };
1690
+
1654
1691
  const hasTimingDetails = event => {
1655
1692
  const hasDuration = typeof event.duration === 'number' || typeof event.durationMs === 'number';
1656
1693
  const hasStart = event.started !== undefined || event.startTime !== undefined || event.startTimestamp !== undefined;
@@ -1658,10 +1695,90 @@ const hasTimingDetails = event => {
1658
1695
  return hasDuration || hasStart && hasEnd;
1659
1696
  };
1660
1697
 
1698
+ const getResponseEvent = event => {
1699
+ const {
1700
+ responseEvent
1701
+ } = event;
1702
+ if (responseEvent && typeof responseEvent === 'object' && typeof responseEvent.type === 'string') {
1703
+ const mergedResponseEvent = responseEvent;
1704
+ if (mergedResponseEvent.value !== undefined) {
1705
+ return mergedResponseEvent.value;
1706
+ }
1707
+ return responseEvent;
1708
+ }
1709
+ return event;
1710
+ };
1711
+
1712
+ const isObject = value => {
1713
+ return typeof value === 'object' && value !== null;
1714
+ };
1715
+ const getNumber = (value, ...keys) => {
1716
+ for (const key of keys) {
1717
+ if (typeof value[key] === 'number') {
1718
+ return value[key];
1719
+ }
1720
+ }
1721
+ return undefined;
1722
+ };
1723
+ const getUsage = event => {
1724
+ const responseEvent = getResponseEvent(event);
1725
+ if (isObject(responseEvent) && isObject(responseEvent.usage)) {
1726
+ return responseEvent.usage;
1727
+ }
1728
+ if (isObject(responseEvent) && isObject(responseEvent.value) && isObject(responseEvent.value.usage)) {
1729
+ return responseEvent.value.usage;
1730
+ }
1731
+ return undefined;
1732
+ };
1733
+ const getTokenUsageDetails = event => {
1734
+ const usage = getUsage(event);
1735
+ if (!usage) {
1736
+ return undefined;
1737
+ }
1738
+ const inputTokens = getNumber(usage, 'input_tokens', 'inputTokens');
1739
+ const outputTokens = getNumber(usage, 'output_tokens', 'outputTokens');
1740
+ let inputTokenDetails;
1741
+ if (isObject(usage.input_tokens_details)) {
1742
+ inputTokenDetails = usage.input_tokens_details;
1743
+ } else if (isObject(usage.inputTokensDetails)) {
1744
+ inputTokenDetails = usage.inputTokensDetails;
1745
+ }
1746
+ const cachedTokens = inputTokenDetails ? getNumber(inputTokenDetails, 'cached_tokens', 'cachedTokens') : getNumber(usage, 'cached_tokens', 'cachedTokens');
1747
+ if (inputTokens === undefined && outputTokens === undefined && cachedTokens === undefined) {
1748
+ return undefined;
1749
+ }
1750
+ return {
1751
+ ...(cachedTokens === undefined ? undefined : {
1752
+ cachedTokens
1753
+ }),
1754
+ ...(inputTokens === undefined ? undefined : {
1755
+ inputTokens
1756
+ }),
1757
+ ...(outputTokens === undefined ? undefined : {
1758
+ outputTokens
1759
+ })
1760
+ };
1761
+ };
1762
+
1763
+ const hasTokenUsageDetails = event => {
1764
+ return getTokenUsageDetails(event) !== undefined;
1765
+ };
1766
+
1661
1767
  const createDetailTabs = (selectedDetailTab = Response, event) => {
1768
+ const hasHeadersTab = event ? hasHeadersDetails(event) : false;
1769
+ const hasTokensTab = event ? hasTokenUsageDetails(event) : false;
1662
1770
  const hasTimingTab = event ? hasTimingDetails(event) : true;
1663
1771
  const safeSelectedDetailTab = getSafeSelectedDetailTab(selectedDetailTab);
1664
- const normalizedSelectedDetailTab = hasTimingTab || safeSelectedDetailTab !== Timing ? safeSelectedDetailTab : Response;
1772
+ let normalizedSelectedDetailTab = safeSelectedDetailTab;
1773
+ if (!hasHeadersTab && normalizedSelectedDetailTab === Headers) {
1774
+ normalizedSelectedDetailTab = Response;
1775
+ }
1776
+ if (!hasTokensTab && normalizedSelectedDetailTab === Tokens) {
1777
+ normalizedSelectedDetailTab = Response;
1778
+ }
1779
+ if (!hasTimingTab && normalizedSelectedDetailTab === Timing) {
1780
+ normalizedSelectedDetailTab = Response;
1781
+ }
1665
1782
  const detailTabs = [{
1666
1783
  isSelected: normalizedSelectedDetailTab === Preview,
1667
1784
  label: preview(),
@@ -1675,6 +1792,20 @@ const createDetailTabs = (selectedDetailTab = Response, event) => {
1675
1792
  label: response(),
1676
1793
  name: Response
1677
1794
  }];
1795
+ if (hasHeadersTab) {
1796
+ detailTabs.push({
1797
+ isSelected: normalizedSelectedDetailTab === Headers,
1798
+ label: headers(),
1799
+ name: Headers
1800
+ });
1801
+ }
1802
+ if (hasTokensTab) {
1803
+ detailTabs.push({
1804
+ isSelected: normalizedSelectedDetailTab === Tokens,
1805
+ label: tokens(),
1806
+ name: Tokens
1807
+ });
1808
+ }
1678
1809
  if (hasTimingTab) {
1679
1810
  detailTabs.push({
1680
1811
  isSelected: normalizedSelectedDetailTab === Timing,
@@ -1904,31 +2035,23 @@ const defaultTableColumnWidths = {
1904
2035
  type: 260
1905
2036
  };
1906
2037
 
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);
2038
+ const getMainWidth = state => {
2039
+ return Math.max(0, state.width - state.horizontalPadding);
2040
+ };
2041
+ const clampTableWidth = (state, tableWidth) => {
2042
+ const mainWidth = getMainWidth(state);
2043
+ const maxTableWidth = Math.max(0, mainWidth - state.minDetailsWidth - state.sashWidth);
2044
+ const minClampedTableWidth = Math.min(state.minTableWidth, maxTableWidth);
1922
2045
  return Math.max(minClampedTableWidth, Math.min(tableWidth, maxTableWidth));
1923
2046
  };
1924
- const getDetailsWidth = (width, tableWidth) => {
1925
- const mainWidth = getMainWidth(width);
1926
- const clampedTableWidth = clampTableWidth(width, tableWidth);
1927
- return Math.max(0, mainWidth - clampedTableWidth - sashWidth);
2047
+ const getDetailsWidth = (state, tableWidth) => {
2048
+ const mainWidth = getMainWidth(state);
2049
+ const clampedTableWidth = clampTableWidth(state, tableWidth);
2050
+ return Math.max(0, mainWidth - clampedTableWidth - state.sashWidth);
1928
2051
  };
1929
- const getTableWidthFromClientX = (viewX, width, clientX) => {
1930
- const nextTableWidth = clientX - viewX - leftPadding;
1931
- return clampTableWidth(width, nextTableWidth);
2052
+ const getTableWidthFromClientX = (state, clientX) => {
2053
+ const nextTableWidth = clientX - state.x - state.leftPadding;
2054
+ return clampTableWidth(state, nextTableWidth);
1932
2055
  };
1933
2056
 
1934
2057
  const minimumTableColumnWidths = {
@@ -1981,8 +2104,8 @@ const getTableColumnLayout = (tableWidth, visibleTableColumns, tableColumnWidths
1981
2104
  };
1982
2105
  };
1983
2106
 
1984
- const getResizedTableColumnWidths = (width, tableWidth, visibleTableColumns, tableColumnWidths, viewX, clientX, resizerDownId) => {
1985
- const clampedTableWidth = clampTableWidth(width, tableWidth);
2107
+ const getResizedTableColumnWidths = (state, visibleTableColumns, tableColumnWidths, clientX, resizerDownId) => {
2108
+ const clampedTableWidth = clampTableWidth(state, state.tableWidth);
1986
2109
  const layout = getTableColumnLayout(clampedTableWidth, visibleTableColumns, tableColumnWidths);
1987
2110
  if (resizerDownId < 1 || resizerDownId >= layout.visibleColumns.length) {
1988
2111
  return tableColumnWidths;
@@ -1993,7 +2116,7 @@ const getResizedTableColumnWidths = (width, tableWidth, visibleTableColumns, tab
1993
2116
  const minimumWidth = getMinimumTableColumnWidth(resizedColumn);
1994
2117
  const minimumRemainingWidth = layout.visibleColumns.slice(boundaryIndex + 1).reduce((total, column) => total + getMinimumTableColumnWidth(column), 0);
1995
2118
  const maxWidth = Math.max(minimumWidth, clampedTableWidth - precedingWidth - minimumRemainingWidth);
1996
- const nextWidth = clientX - viewX - leftPadding - precedingWidth;
2119
+ const nextWidth = clientX - state.x - state.leftPadding - precedingWidth;
1997
2120
  const clampedWidth = Math.max(minimumWidth, Math.min(nextWidth, maxWidth));
1998
2121
  return {
1999
2122
  ...tableColumnWidths,
@@ -2217,11 +2340,20 @@ const getTimelineInfo = (events, startValue, endValue) => {
2217
2340
  };
2218
2341
 
2219
2342
  const createDefaultState = () => {
2343
+ const defaultTableWidth = 480;
2344
+ const minTableWidth = 240;
2345
+ const minDetailsWidth = 280;
2346
+ const sashWidth = 4;
2347
+ const viewPadding = 8;
2348
+ const timelineHorizontalPadding = 10;
2349
+ const horizontalPadding = viewPadding * 2;
2350
+ const leftPadding = viewPadding;
2220
2351
  return {
2221
2352
  assetDir: '',
2222
2353
  categoryFilters: createCategoryFilters(),
2223
2354
  databaseName: 'lvce-chat-view-sessions',
2224
2355
  dataBaseVersion: 2,
2356
+ defaultTableWidth,
2225
2357
  detailTabs: createDetailTabs(),
2226
2358
  devtoolsRootGap: 4,
2227
2359
  devtoolsTimelineHeight: 88,
@@ -2232,9 +2364,13 @@ const createDefaultState = () => {
2232
2364
  filterValue: '',
2233
2365
  focus: 0,
2234
2366
  height: 0,
2367
+ horizontalPadding,
2235
2368
  initial: false,
2236
2369
  largeBreakpoint: 900,
2370
+ leftPadding,
2237
2371
  mediumBreakpoint: 600,
2372
+ minDetailsWidth,
2373
+ minTableWidth,
2238
2374
  platform: 0,
2239
2375
  previewTextCursorColumnIndex: null,
2240
2376
  previewTextCursorRowIndex: null,
@@ -2242,6 +2378,7 @@ const createDefaultState = () => {
2242
2378
  previewTextScrollBarHandleOffset: 0,
2243
2379
  previewTextScrollBarPointerActive: false,
2244
2380
  sashPointerActive: false,
2381
+ sashWidth,
2245
2382
  selectedEvent: null,
2246
2383
  selectedEventId: null,
2247
2384
  selectedEventIndex: null,
@@ -2265,6 +2402,7 @@ const createDefaultState = () => {
2265
2402
  timelineEvents: [],
2266
2403
  timelineFilterDescription: '',
2267
2404
  timelineHeight: 81,
2405
+ timelineHorizontalPadding,
2268
2406
  timelineHoverPercent: null,
2269
2407
  timelineHoverSeconds: '',
2270
2408
  timelineInfo: emptyTimelineInfo,
@@ -2275,6 +2413,7 @@ const createDefaultState = () => {
2275
2413
  uid: 0,
2276
2414
  uri: '',
2277
2415
  useDevtoolsLayout: true,
2416
+ viewPadding,
2278
2417
  width: 0,
2279
2418
  x: 0,
2280
2419
  y: 0
@@ -2747,7 +2886,10 @@ const mergeSelectedEventDetails = (selectedEvent, selectedEventDetails) => {
2747
2886
  responseEvent
2748
2887
  } = selectedEvent;
2749
2888
  if (!requestEvent || !responseEvent || typeof requestEvent !== 'object' || typeof responseEvent !== 'object') {
2750
- return selectedEventDetails;
2889
+ return {
2890
+ ...selectedEvent,
2891
+ ...selectedEventDetails
2892
+ };
2751
2893
  }
2752
2894
  const selectedEventDetailsType = selectedEventDetails.type;
2753
2895
  const resolvedResponseEvent = selectedEventDetailsType === 'response' || selectedEventDetailsType === 'ai-response-success' ? selectedEventDetails : responseEvent;
@@ -2773,6 +2915,7 @@ const getTableBodyY = (state, hasTimeline) => {
2773
2915
  devtoolsRootGap,
2774
2916
  devtoolsTimelineHeight,
2775
2917
  devtoolsTopHeight,
2918
+ viewPadding,
2776
2919
  y
2777
2920
  } = state;
2778
2921
  return y + viewPadding + devtoolsTopHeight + devtoolsRootGap + (hasTimeline ? devtoolsTimelineHeight : 0) + devtoolsTableHeaderHeight;
@@ -2783,7 +2926,7 @@ const getTableBodyHeight = (state, eventCount) => {
2783
2926
  return 0;
2784
2927
  }
2785
2928
  const tableBodyY = getTableBodyY(state, true);
2786
- return Math.max(0, state.height - (tableBodyY - state.y) - viewPadding - devtoolsTableSummaryHeight);
2929
+ return Math.max(0, state.height - (tableBodyY - state.y) - state.viewPadding - devtoolsTableSummaryHeight);
2787
2930
  };
2788
2931
  const getVisibleRowCount = tableBodyHeight => {
2789
2932
  if (tableBodyHeight <= 0) {
@@ -3120,7 +3263,6 @@ const getTableBodyEventIndex = (state, eventX, eventY) => {
3120
3263
  tableMinLineY,
3121
3264
  tableWidth,
3122
3265
  useDevtoolsLayout,
3123
- width,
3124
3266
  x
3125
3267
  } = state;
3126
3268
  if (!useDevtoolsLayout) {
@@ -3130,8 +3272,8 @@ const getTableBodyEventIndex = (state, eventX, eventY) => {
3130
3272
  if (currentEvents.length === 0) {
3131
3273
  return -1;
3132
3274
  }
3133
- const tableX = x + leftPadding;
3134
- const tableWidthNew = clampTableWidth(width, tableWidth);
3275
+ const tableX = x + state.leftPadding;
3276
+ const tableWidthNew = clampTableWidth(state, tableWidth);
3135
3277
  const hasTimeline = currentEvents.length > 0;
3136
3278
  const tableBodyY = getTableBodyY(state, hasTimeline);
3137
3279
  const relativeX = eventX - tableX;
@@ -4320,7 +4462,7 @@ const handleSashPointerMove = (state, eventX, eventY) => {
4320
4462
  }
4321
4463
  return {
4322
4464
  ...state,
4323
- tableWidth: getTableWidthFromClientX(state.x, state.width, eventX)
4465
+ tableWidth: getTableWidthFromClientX(state, eventX)
4324
4466
  };
4325
4467
  };
4326
4468
 
@@ -4385,7 +4527,7 @@ const handleTableResizerPointerMove = (state, clientX) => {
4385
4527
  }
4386
4528
  return {
4387
4529
  ...state,
4388
- tableColumnWidths: getResizedTableColumnWidths(state.width, state.tableWidth, getVisibleTableColumns(state.tableColumns), state.tableColumnWidths, state.x, clientX, state.tableResizerDownId)
4530
+ tableColumnWidths: getResizedTableColumnWidths(state, getVisibleTableColumns(state.tableColumns), state.tableColumnWidths, clientX, state.tableResizerDownId)
4389
4531
  };
4390
4532
  };
4391
4533
 
@@ -4550,10 +4692,10 @@ const getTimelineEventX = eventX => {
4550
4692
  };
4551
4693
 
4552
4694
  const getTimelineLeft = state => {
4553
- return state.x + viewPadding + timelineHorizontalPadding;
4695
+ return state.x + state.viewPadding + state.timelineHorizontalPadding;
4554
4696
  };
4555
4697
  const getTimelineWidth = state => {
4556
- return Math.max(0, getMainWidth(state.width) - timelineHorizontalPadding * 2);
4698
+ return Math.max(0, getMainWidth(state) - state.timelineHorizontalPadding * 2);
4557
4699
  };
4558
4700
 
4559
4701
  const getTimelineDurationSeconds = events => {
@@ -4751,20 +4893,8 @@ const isAttachmentImagePreview = value => {
4751
4893
  return typeof value === 'object' && value !== null && value.previewType === 'image';
4752
4894
  };
4753
4895
 
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
-
4896
+ const detailsLineNumberDigitWidth = 8;
4897
+ const detailsLineNumberHorizontalPadding = 8;
4768
4898
  const getStringLineCount = value => {
4769
4899
  return value.split('\n').length;
4770
4900
  };
@@ -4809,7 +4939,7 @@ const getLineCount = state => {
4809
4939
  return 0;
4810
4940
  }
4811
4941
  const selectedDetailTab = getSelectedDetailTab(state.detailTabs);
4812
- if (selectedDetailTab === Timing) {
4942
+ if (selectedDetailTab === Timing || selectedDetailTab === Tokens) {
4813
4943
  return 0;
4814
4944
  }
4815
4945
  if (selectedDetailTab === Preview) {
@@ -4825,14 +4955,15 @@ const getDetailsLineNumberWidth = state => {
4825
4955
  if (lineCount === 0) {
4826
4956
  return 0;
4827
4957
  }
4828
- return String(lineCount).length * defaultPreviewTextColumnWidth;
4958
+ const digitCount = String(lineCount).length;
4959
+ return digitCount * detailsLineNumberDigitWidth + detailsLineNumberHorizontalPadding;
4829
4960
  };
4830
4961
 
4831
4962
  // cspell:ignore liga calt
4832
4963
 
4833
4964
  const getCss = state => {
4834
4965
  const hasSelectedEvent = !!state.selectedEvent;
4835
- const tableWidth = hasSelectedEvent ? clampTableWidth(state.width, state.tableWidth) : getMainWidth(state.width);
4966
+ const tableWidth = hasSelectedEvent ? clampTableWidth(state, state.tableWidth) : getMainWidth(state);
4836
4967
  const currentEvents = getCurrentEvents$2(state);
4837
4968
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
4838
4969
  const scrollBarHeight = getScrollBarHeight(currentEvents.length, tableBodyHeight);
@@ -4840,7 +4971,7 @@ const getCss = state => {
4840
4971
  const showScrollBar = scrollBarHeight > 0;
4841
4972
  const scrollBarOffset = getScrollBarOffset(state.tableDeltaY, maxDeltaY, tableBodyHeight, scrollBarHeight);
4842
4973
  const tableContentWidth = Math.max(0, tableWidth - (showScrollBar ? devtoolsTableScrollBarWidth : 0));
4843
- const detailsWidth = hasSelectedEvent ? getDetailsWidth(state.width, state.tableWidth) : 0;
4974
+ const detailsWidth = hasSelectedEvent ? getDetailsWidth(state, state.tableWidth) : 0;
4844
4975
  const detailsLineNumberWidth = getDetailsLineNumberWidth(state);
4845
4976
  const previewTextViewportHeight = getPreviewTextViewportHeight(state);
4846
4977
  const previewVirtualization = getPreviewVirtualizationState(state.selectedEvent, previewTextViewportHeight, state.previewTextDeltaY);
@@ -4879,7 +5010,7 @@ const getCss = state => {
4879
5010
  --ResizerOneLeft: ${resizerOneLeft}px;
4880
5011
  --ResizerTwoLeft: ${resizerTwoLeft}px;
4881
5012
  --ResizerThreeLeft: ${resizerThreeLeft}px;
4882
- --ChatDebugViewSashWidth: ${sashWidth}px;
5013
+ --ChatDebugViewSashWidth: ${state.sashWidth}px;
4883
5014
  --ChatDebugViewTableWidth: ${tableWidth}px;
4884
5015
  --ChatDebugViewTimelineHeight: ${state.timelineHeight}px;
4885
5016
  --ChatDebugViewTimelineCursorGuideLeft: ${state.timelineHoverPercent ?? 0}%;
@@ -4887,7 +5018,7 @@ const getCss = state => {
4887
5018
  --ChatDebugViewTimelineSelectionStartLeft: ${selectionStartPercent ?? 0}%;
4888
5019
  --ChatDebugViewTopSize: ${topSize}px;
4889
5020
  --ChatDebugViewTypeColumnWidth: ${state.tableColumnWidths.type}px;
4890
- padding: ${viewPadding}px;
5021
+ padding: ${state.viewPadding}px;
4891
5022
  padding-right: 0;
4892
5023
  }
4893
5024
 
@@ -4901,6 +5032,51 @@ const getCss = state => {
4901
5032
  width: calc(100% - var(--ChatDebugViewTableScrollBarWidth));
4902
5033
  }
4903
5034
 
5035
+ .Resizers {
5036
+ bottom: 0;
5037
+ left: 0;
5038
+ pointer-events: none;
5039
+ position: absolute;
5040
+ right: var(--ChatDebugViewTableScrollBarWidth);
5041
+ top: 0;
5042
+ }
5043
+
5044
+ .Resizer {
5045
+ background: transparent;
5046
+ border: 0;
5047
+ bottom: 0;
5048
+ cursor: col-resize;
5049
+ margin: 0;
5050
+ padding: 0;
5051
+ pointer-events: auto;
5052
+ position: absolute;
5053
+ top: 0;
5054
+ transform: translateX(calc(-0.5 * var(--ChatDebugViewSashWidth)));
5055
+ width: var(--ChatDebugViewSashWidth);
5056
+ }
5057
+
5058
+ .ResizerOne {
5059
+ left: var(--ResizerOneLeft);
5060
+ }
5061
+
5062
+ .ResizerTwo {
5063
+ left: var(--ResizerTwoLeft);
5064
+ }
5065
+
5066
+ .ResizerThree {
5067
+ left: var(--ResizerThreeLeft);
5068
+ }
5069
+
5070
+ .ResizerInner {
5071
+ background: var(--vscode-panel-border, rgba(255, 255, 255, 0.12));
5072
+ bottom: 0;
5073
+ pointer-events: none;
5074
+ position: absolute;
5075
+ top: 0;
5076
+ transform: translateX(-0.5px);
5077
+ width: 1px;
5078
+ }
5079
+
4904
5080
  .ChatDebugViewTimeline {
4905
5081
  contain: strict;
4906
5082
  display: flex;
@@ -4920,12 +5096,40 @@ const getCss = state => {
4920
5096
  width: var(--ChatDebugViewDetailsLineNumberWidth);
4921
5097
  }
4922
5098
 
4923
- .ChatDebugViewDetailsBottom .ChatDebugViewEventLineNumber {
4924
- display: inline-block;
4925
- min-width: var(--ChatDebugViewDetailsLineNumberWidth);
4926
- width: var(--ChatDebugViewDetailsLineNumberWidth);
5099
+ .ChatDebugViewHeadersTable {
5100
+ border-collapse: collapse;
5101
+ table-layout: fixed;
5102
+ width: 100%;
5103
+ }
5104
+
5105
+ .ChatDebugViewHeadersCell {
5106
+ border-bottom: 1px solid var(--vscode-panel-border, rgba(255, 255, 255, 0.12));
5107
+ color: var(--vscode-editor-foreground);
5108
+ padding: 6px 10px;
5109
+ text-align: left;
5110
+ vertical-align: top;
5111
+ word-break: break-word;
5112
+ }
5113
+
5114
+ .ChatDebugViewHeadersHead .ChatDebugViewHeadersCell {
5115
+ color: var(--vscode-descriptionForeground, rgba(255, 255, 255, 0.7));
5116
+ font-size: 11px;
5117
+ font-weight: 600;
5118
+ text-transform: uppercase;
5119
+ }
5120
+
5121
+ .ChatDebugViewHeadersRowOdd {
5122
+ background: rgba(255, 255, 255, 0.02);
4927
5123
  }
4928
5124
 
5125
+ .ChatDebugViewHeadersRowEven {
5126
+ background: rgba(255, 255, 255, 0.04);
5127
+ }
5128
+
5129
+ .ChatDebugViewHeadersCellName {
5130
+ font-weight: 500;
5131
+ width: 38%;
5132
+ }
4929
5133
  .PreviewVirtualizedEditor {
4930
5134
  height: var(--ChatDebugViewPreviewViewportHeight);
4931
5135
  overflow: hidden;
@@ -5325,6 +5529,15 @@ const PanelTab = 'PanelTab';
5325
5529
  const PanelTabSelected = 'PanelTabSelected';
5326
5530
  const ChatDebugViewDetailsTabs = 'ChatDebugViewDetailsTabs';
5327
5531
  const ChatDebugViewDetailsTop = 'ChatDebugViewDetailsTop';
5532
+ const ChatDebugViewHeadersBody = 'ChatDebugViewHeadersBody';
5533
+ const ChatDebugViewHeadersCell = 'ChatDebugViewHeadersCell';
5534
+ const ChatDebugViewHeadersCellName = 'ChatDebugViewHeadersCellName';
5535
+ const ChatDebugViewHeadersCellValue = 'ChatDebugViewHeadersCellValue';
5536
+ const ChatDebugViewHeadersHead = 'ChatDebugViewHeadersHead';
5537
+ const ChatDebugViewHeadersRow = 'ChatDebugViewHeadersRow';
5538
+ const ChatDebugViewHeadersRowEven = 'ChatDebugViewHeadersRowEven';
5539
+ const ChatDebugViewHeadersRowOdd = 'ChatDebugViewHeadersRowOdd';
5540
+ const ChatDebugViewHeadersTable = 'ChatDebugViewHeadersTable';
5328
5541
  const ChatDebugViewDevtoolsSplit = 'ChatDebugViewDevtoolsSplit';
5329
5542
  const ChatDebugViewEmpty = 'ChatDebugViewEmpty';
5330
5543
  const ChatDebugViewError = 'ChatDebugViewError';
@@ -5611,6 +5824,99 @@ const getNormalizedDetailTabs = (selectedEvent, detailTabs) => {
5611
5824
  return createDetailTabs(getSelectedDetailTab(detailTabs), selectedEvent);
5612
5825
  };
5613
5826
 
5827
+ const isHeadersRecord = value => {
5828
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
5829
+ };
5830
+ const stringifyHeaderValue = value => {
5831
+ try {
5832
+ return JSON.stringify(value, (_key, nestedValue) => {
5833
+ if (typeof nestedValue === 'bigint') {
5834
+ return nestedValue.toString();
5835
+ }
5836
+ return nestedValue;
5837
+ });
5838
+ } catch {
5839
+ return '[unserializable]';
5840
+ }
5841
+ };
5842
+ const getHeaderValueText = value => {
5843
+ if (typeof value === 'string') {
5844
+ return value;
5845
+ }
5846
+ if (value === undefined) {
5847
+ return '';
5848
+ }
5849
+ if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {
5850
+ return String(value);
5851
+ }
5852
+ if (value === null) {
5853
+ return 'null';
5854
+ }
5855
+ if (typeof value === 'symbol') {
5856
+ return value.description ? `Symbol(${value.description})` : 'Symbol()';
5857
+ }
5858
+ if (typeof value === 'function') {
5859
+ return '[function]';
5860
+ }
5861
+ return stringifyHeaderValue(value);
5862
+ };
5863
+ const getHeaders = selectedEvent => {
5864
+ if (selectedEvent === null || !isHeadersRecord(selectedEvent.headers)) {
5865
+ return [];
5866
+ }
5867
+ return Object.entries(selectedEvent.headers);
5868
+ };
5869
+ const getHeaderRowNodes = (headerName, headerValue, index) => {
5870
+ return [{
5871
+ childCount: 2,
5872
+ className: mergeClassNames(ChatDebugViewHeadersRow, index % 2 === 0 ? ChatDebugViewHeadersRowOdd : ChatDebugViewHeadersRowEven),
5873
+ type: Tr
5874
+ }, {
5875
+ childCount: 1,
5876
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellName),
5877
+ type: Td
5878
+ }, text(headerName), {
5879
+ childCount: 1,
5880
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellValue),
5881
+ type: Td
5882
+ }, text(getHeaderValueText(headerValue))];
5883
+ };
5884
+ const getHeadersContentNodes = (responseEventNodes, selectedEvent) => {
5885
+ const headers = getHeaders(selectedEvent);
5886
+ if (headers.length === 0) {
5887
+ return responseEventNodes;
5888
+ }
5889
+ const headerRows = [];
5890
+ for (const [index, [headerName, headerValue]] of headers.entries()) {
5891
+ headerRows.push(...getHeaderRowNodes(headerName, headerValue, index));
5892
+ }
5893
+ return [{
5894
+ childCount: 2,
5895
+ className: ChatDebugViewHeadersTable,
5896
+ type: Table$1
5897
+ }, {
5898
+ childCount: 1,
5899
+ className: ChatDebugViewHeadersHead,
5900
+ type: THead
5901
+ }, {
5902
+ childCount: 2,
5903
+ className: ChatDebugViewHeadersRow,
5904
+ type: Tr
5905
+ }, {
5906
+ childCount: 1,
5907
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellName),
5908
+ type: Th
5909
+ }, text(name()), {
5910
+ childCount: 1,
5911
+ className: mergeClassNames(ChatDebugViewHeadersCell, ChatDebugViewHeadersCellValue),
5912
+ type: Th
5913
+ }, text(value()), {
5914
+ childCount: headers.length,
5915
+ className: ChatDebugViewHeadersBody,
5916
+ type: TBody
5917
+ }, ...headerRows];
5918
+ };
5919
+
5614
5920
  const getEditorRowDom = line => {
5615
5921
  return [{
5616
5922
  childCount: line.childCount,
@@ -6653,7 +6959,43 @@ const getTimingContentNodes = (responseEventNodes, selectedEvent) => {
6653
6959
  return getTimingDetailsDom(selectedEvent);
6654
6960
  };
6655
6961
 
6962
+ const getTokenUsageDetailsDom = event => {
6963
+ const usageDetails = getTokenUsageDetails(event);
6964
+ if (!usageDetails) {
6965
+ return [];
6966
+ }
6967
+ const rows = [];
6968
+ let rowCount = 0;
6969
+ if (usageDetails.inputTokens !== undefined) {
6970
+ rows.push(...getTimingRowDom(inputTokens(), String(usageDetails.inputTokens)));
6971
+ rowCount++;
6972
+ }
6973
+ if (usageDetails.outputTokens !== undefined) {
6974
+ rows.push(...getTimingRowDom(outputTokens(), String(usageDetails.outputTokens)));
6975
+ rowCount++;
6976
+ }
6977
+ if (usageDetails.cachedTokens !== undefined) {
6978
+ rows.push(...getTimingRowDom(cachedTokens(), String(usageDetails.cachedTokens)));
6979
+ rowCount++;
6980
+ }
6981
+ return [{
6982
+ childCount: rowCount,
6983
+ className: ChatDebugViewTiming,
6984
+ type: Div
6985
+ }, ...rows];
6986
+ };
6987
+
6988
+ const getTokenUsageContentNodes = (responseEventNodes, selectedEvent) => {
6989
+ if (selectedEvent === null) {
6990
+ return responseEventNodes;
6991
+ }
6992
+ return getTokenUsageDetailsDom(selectedEvent);
6993
+ };
6994
+
6656
6995
  const getSelectedContentNodes = (safeSelectedDetailTab, previewEventNodes, payloadEventNodes, responseEventNodes, selectedEvent, previewTextCursorRowIndex, previewTextCursorColumnIndex, previewVirtualization) => {
6996
+ if (safeSelectedDetailTab === Tokens) {
6997
+ return getTokenUsageContentNodes(responseEventNodes, selectedEvent);
6998
+ }
6657
6999
  if (safeSelectedDetailTab === Timing) {
6658
7000
  return getTimingContentNodes(responseEventNodes, selectedEvent);
6659
7001
  }
@@ -6663,6 +7005,9 @@ const getSelectedContentNodes = (safeSelectedDetailTab, previewEventNodes, paylo
6663
7005
  if (safeSelectedDetailTab === Payload) {
6664
7006
  return getPayloadContentNodes(payloadEventNodes, selectedEvent);
6665
7007
  }
7008
+ if (safeSelectedDetailTab === Headers) {
7009
+ return getHeadersContentNodes(responseEventNodes, selectedEvent);
7010
+ }
6666
7011
  return getResponseContentNodes(responseEventNodes, selectedEvent);
6667
7012
  };
6668
7013
 
@@ -7510,12 +7855,10 @@ const renderEventListeners = () => {
7510
7855
  }, {
7511
7856
  name: HandleTableWheel,
7512
7857
  params: ['handleTableWheel', 'event.deltaY'],
7513
- passive: true,
7514
7858
  preventDefault: true
7515
7859
  }, {
7516
7860
  name: HandlePreviewTextWheel,
7517
7861
  params: ['handlePreviewTextWheel', 'event.deltaY'],
7518
- passive: true,
7519
7862
  preventDefault: true
7520
7863
  }, {
7521
7864
  name: HandlePreviewTextScrollBarPointerDown,
@@ -7573,7 +7916,7 @@ const handleResize = (state, dimensions) => {
7573
7916
  };
7574
7917
  return applyVirtualTableState({
7575
7918
  ...nextState,
7576
- tableWidth: clampTableWidth(nextState.width, state.tableWidth)
7919
+ tableWidth: clampTableWidth(nextState, state.tableWidth)
7577
7920
  });
7578
7921
  };
7579
7922
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-debug-view",
3
- "version": "10.10.0",
3
+ "version": "10.11.0",
4
4
  "description": "Chat Debug View Worker",
5
5
  "repository": {
6
6
  "type": "git",