@lvce-editor/chat-debug-view 10.15.0 → 10.16.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.
@@ -2466,18 +2466,6 @@ const diff2 = uid => {
2466
2466
  return diff(oldState, newState);
2467
2467
  };
2468
2468
 
2469
- const getSelectedDetailTab = detailTabs => {
2470
- const selectedDetailTab = detailTabs.find(detailTab => detailTab.isSelected);
2471
- if (selectedDetailTab) {
2472
- return selectedDetailTab.name;
2473
- }
2474
- const responseTab = detailTabs.find(detailTab => detailTab.name === Response$1);
2475
- if (responseTab) {
2476
- return responseTab.name;
2477
- }
2478
- return detailTabs[0]?.name ?? Response$1;
2479
- };
2480
-
2481
2469
  const filterEventsByTimelineRange = (events, startValue, endValue) => {
2482
2470
  const eventsWithTime = getEventsWithTime(events);
2483
2471
  if (eventsWithTime.length === 0) {
@@ -2879,15 +2867,38 @@ const sortEventsByTableColumn = (events, sortColumn, sortDescending) => {
2879
2867
  return sortableEvents.toSorted(compareEntries).map(item => item.event);
2880
2868
  };
2881
2869
 
2882
- const getCurrentEvents$2 = state => {
2870
+ const getCurrentEvents$1 = state => {
2883
2871
  const eventCategoryFilters = getSelectedEventCategoryFilters(state.categoryFilters);
2884
2872
  const filteredEvents = getFilteredEvents(state.events, state.filterValue, eventCategoryFilters, state.showInputEvents, state.showResponsePartEvents, state.showEventStreamFinishedEvents);
2885
2873
  const timelineEvents = filterEventsByTimelineRange(filteredEvents, state.timelineStartSeconds, state.timelineEndSeconds);
2886
2874
  return sortEventsByTableColumn(timelineEvents, state.sortColumn, state.sortDescending);
2887
2875
  };
2888
2876
 
2889
- const loadSelectedEvent = async (_databaseName, _dataBaseVersion, _eventStoreName, sessionId, _sessionIdIndexName, eventId, type) => {
2890
- return loadSelectedEvent$1(sessionId, eventId, type);
2877
+ const getCurrentEvents = state => getCurrentEvents$1(state);
2878
+
2879
+ const getSelectedDetailTab = detailTabs => {
2880
+ const selectedDetailTab = detailTabs.find(detailTab => detailTab.isSelected);
2881
+ if (selectedDetailTab) {
2882
+ return selectedDetailTab.name;
2883
+ }
2884
+ const responseTab = detailTabs.find(detailTab => detailTab.name === Response$1);
2885
+ if (responseTab) {
2886
+ return responseTab.name;
2887
+ }
2888
+ return detailTabs[0]?.name ?? Response$1;
2889
+ };
2890
+
2891
+ const loadSelectedEvent = async (_databaseName, _dataBaseVersion, _eventStoreName, sessionId, _sessionIdIndexName, eventId, type, endEventId) => {
2892
+ const raw = await loadSelectedEvent$1(sessionId, eventId, type);
2893
+ if (endEventId && endEventId !== -1) {
2894
+ const end = await loadSelectedEvent$1(sessionId, endEventId, type);
2895
+ // @ts-ignore
2896
+ return {
2897
+ ...raw,
2898
+ endValue: end
2899
+ };
2900
+ }
2901
+ return raw;
2891
2902
  };
2892
2903
 
2893
2904
  const mergeSelectedEventDetails = (selectedEvent, selectedEventDetails) => {
@@ -2977,7 +2988,7 @@ const getScrollBarOffset = (deltaY, maxDeltaY, tableBodyHeight, scrollBarHeight)
2977
2988
  return Math.round(deltaY / maxDeltaY * (tableBodyHeight - scrollBarHeight));
2978
2989
  };
2979
2990
  const applyVirtualTableState = state => {
2980
- const currentEvents = getCurrentEvents$2(state);
2991
+ const currentEvents = getCurrentEvents$1(state);
2981
2992
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
2982
2993
  const deltaY = clampTableDeltaY(state.tableDeltaY, currentEvents.length, tableBodyHeight);
2983
2994
  const minLineY = Math.floor(deltaY / devtoolsTableRowHeight);
@@ -3000,7 +3011,7 @@ const withSelectedEventVisible = state => {
3000
3011
  if (state.selectedEventIndex === null || state.selectedEventIndex < 0) {
3001
3012
  return applyVirtualTableState(state);
3002
3013
  }
3003
- const currentEvents = getCurrentEvents$2(state);
3014
+ const currentEvents = getCurrentEvents$1(state);
3004
3015
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
3005
3016
  const visibleRowCount = getVisibleRowCount(tableBodyHeight);
3006
3017
  if (visibleRowCount === 0) {
@@ -3017,10 +3028,11 @@ const withSelectedEventVisible = state => {
3017
3028
  return applyVirtualTableState(state);
3018
3029
  };
3019
3030
 
3020
- const svgWidthRegex = /\bwidth=["']([\d.]+)(?:px)?["']/i;
3021
- const svgHeightRegex = /\bheight=["']([\d.]+)(?:px)?["']/i;
3022
- const svgViewBoxRegex = /\bviewBox=["'][^"']*?([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)["']/i;
3023
- const getBlob = event => {
3031
+ const getAttachmentImagePreviewAltText = event => {
3032
+ return typeof event.name === 'string' && event.name ? event.name : 'image preview';
3033
+ };
3034
+
3035
+ const getAttachmentImagePreviewBlob = event => {
3024
3036
  const {
3025
3037
  blob
3026
3038
  } = event;
@@ -3029,24 +3041,37 @@ const getBlob = event => {
3029
3041
  }
3030
3042
  return undefined;
3031
3043
  };
3032
- const getMimeType = event => {
3044
+
3045
+ const getAttachmentImagePreviewMimeType = event => {
3033
3046
  return typeof event.mimeType === 'string' ? event.mimeType : undefined;
3034
3047
  };
3035
- const getAltText = event => {
3036
- return typeof event.name === 'string' && event.name ? event.name : 'image preview';
3037
- };
3038
- const isImageMimeType = mimeType => {
3039
- return typeof mimeType === 'string' && mimeType.startsWith('image/');
3040
- };
3048
+
3041
3049
  const formatImageSize = size => {
3042
3050
  if (size < 1024) {
3043
3051
  return `${size} B`;
3044
3052
  }
3045
3053
  return `${(size / 1024).toFixed(1)} kB`;
3046
3054
  };
3055
+
3047
3056
  const formatImageStats = (width, height, size) => {
3048
3057
  return `${width} × ${height} px · ${formatImageSize(size)}`;
3049
3058
  };
3059
+
3060
+ const getRasterImageStats = async blob => {
3061
+ if (typeof createImageBitmap !== 'function') {
3062
+ throw new TypeError('image bitmap decoder is not available');
3063
+ }
3064
+ const bitmap = await createImageBitmap(blob);
3065
+ try {
3066
+ return formatImageStats(bitmap.width, bitmap.height, blob.size);
3067
+ } finally {
3068
+ bitmap.close?.();
3069
+ }
3070
+ };
3071
+
3072
+ const svgWidthRegex = /\bwidth=["']([\d.]+)(?:px)?["']/i;
3073
+ const svgHeightRegex = /\bheight=["']([\d.]+)(?:px)?["']/i;
3074
+ const svgViewBoxRegex = /\bviewBox=["'][^"']*?([\d.]+)\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)["']/i;
3050
3075
  const getSvgImageStats = async blob => {
3051
3076
  const text = await blob.text();
3052
3077
  const widthMatch = text.match(svgWidthRegex);
@@ -3060,27 +3085,7 @@ const getSvgImageStats = async blob => {
3060
3085
  }
3061
3086
  return undefined;
3062
3087
  };
3063
- const readBlobAsPreviewUrl = blob => {
3064
- if (typeof FileReaderSync === 'function') {
3065
- const reader = new FileReaderSync();
3066
- return reader.readAsDataURL(blob);
3067
- }
3068
- if (typeof URL.createObjectURL === 'function') {
3069
- return URL.createObjectURL(blob);
3070
- }
3071
- throw new Error('image preview reader is not available');
3072
- };
3073
- const getRasterImageStats = async blob => {
3074
- if (typeof createImageBitmap !== 'function') {
3075
- throw new TypeError('image bitmap decoder is not available');
3076
- }
3077
- const bitmap = await createImageBitmap(blob);
3078
- try {
3079
- return formatImageStats(bitmap.width, bitmap.height, blob.size);
3080
- } finally {
3081
- bitmap.close?.();
3082
- }
3083
- };
3088
+
3084
3089
  const getImageStats = async (blob, mimeType) => {
3085
3090
  if (mimeType === 'image/svg+xml') {
3086
3091
  const svgStats = await getSvgImageStats(blob);
@@ -3091,19 +3096,35 @@ const getImageStats = async (blob, mimeType) => {
3091
3096
  }
3092
3097
  return getRasterImageStats(blob);
3093
3098
  };
3099
+
3100
+ const isImageMimeType = mimeType => {
3101
+ return typeof mimeType === 'string' && mimeType.startsWith('image/');
3102
+ };
3103
+
3104
+ const readBlobAsPreviewUrl = blob => {
3105
+ if (typeof FileReaderSync === 'function') {
3106
+ const reader = new FileReaderSync();
3107
+ return reader.readAsDataURL(blob);
3108
+ }
3109
+ if (typeof URL.createObjectURL === 'function') {
3110
+ return URL.createObjectURL(blob);
3111
+ }
3112
+ throw new Error('image preview reader is not available');
3113
+ };
3114
+
3094
3115
  const getAttachmentImagePreview = async event => {
3095
3116
  if (event.type !== 'chat-attachment-added' && event.type !== 'chat-attachment-removed') {
3096
3117
  return undefined;
3097
3118
  }
3098
- const blob = getBlob(event);
3099
- const mimeType = getMimeType(event);
3119
+ const blob = getAttachmentImagePreviewBlob(event);
3120
+ const mimeType = getAttachmentImagePreviewMimeType(event);
3100
3121
  if (!blob || !isImageMimeType(mimeType)) {
3101
3122
  return undefined;
3102
3123
  }
3103
3124
  try {
3104
3125
  const stats = await getImageStats(blob, mimeType);
3105
3126
  return {
3106
- alt: getAltText(event),
3127
+ alt: getAttachmentImagePreviewAltText(event),
3107
3128
  previewType: 'image',
3108
3129
  src: readBlobAsPreviewUrl(blob),
3109
3130
  stats
@@ -3135,8 +3156,7 @@ const withPreparedSelectedEventPreview = async event => {
3135
3156
  return setSelectedEventPreview(event, preview);
3136
3157
  };
3137
3158
 
3138
- const getCurrentEvents$1 = state => getCurrentEvents$2(state);
3139
- const selectEventAtIndex = async (state, selectedEventIndex, loadSelectedEvent$1 = loadSelectedEvent) => {
3159
+ const selectEventAtIndex = async (state, selectedEventIndex) => {
3140
3160
  const {
3141
3161
  databaseName,
3142
3162
  dataBaseVersion,
@@ -3164,7 +3184,9 @@ const selectEventAtIndex = async (state, selectedEventIndex, loadSelectedEvent$1
3164
3184
  selectedEventIndex
3165
3185
  };
3166
3186
  }
3167
- const selectedEventDetails = await loadSelectedEvent$1(databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, selectedEvent.eventId, selectedEvent.type);
3187
+ const selectedEventDetails = await loadSelectedEvent(databaseName, dataBaseVersion, eventStoreName, sessionId, sessionIdIndexName, selectedEvent.eventId, selectedEvent.type,
3188
+ // @ts-ignore
3189
+ selectedEvent['eventEndId'] || 0);
3168
3190
  const resolvedSelectedEvent = await withPreparedSelectedEventPreview(mergeSelectedEventDetails(selectedEvent, selectedEventDetails));
3169
3191
  return withSelectedEventVisible({
3170
3192
  ...state,
@@ -3181,7 +3203,7 @@ const selectEventAtIndex = async (state, selectedEventIndex, loadSelectedEvent$1
3181
3203
  };
3182
3204
 
3183
3205
  const focusIndex = async (state, index) => {
3184
- const currentEvents = getCurrentEvents$1(state);
3206
+ const currentEvents = getCurrentEvents(state);
3185
3207
  if (currentEvents.length === 0 || state.selectedEventIndex === index) {
3186
3208
  return state;
3187
3209
  }
@@ -3360,6 +3382,7 @@ const toPrettyEvents = rawEvents => {
3360
3382
  const response = map[item.requestId];
3361
3383
  if (response) {
3362
3384
  pretty.push({
3385
+ eventEndId: response.eventId,
3363
3386
  eventId: item.eventId,
3364
3387
  type: 'ai-request-response'
3365
3388
  });
@@ -3573,7 +3596,7 @@ const restoreSelectedEvent = async state => {
3573
3596
  selectedEventIndex: null
3574
3597
  };
3575
3598
  }
3576
- const currentEvents = getCurrentEvents$2(state);
3599
+ const currentEvents = getCurrentEvents$1(state);
3577
3600
  const selectedEventIndex = currentEvents.findIndex(event => event.eventId === state.selectedEventId);
3578
3601
  if (selectedEventIndex === -1) {
3579
3602
  return {
@@ -3733,8 +3756,6 @@ const handleEscape = state => {
3733
3756
  return state;
3734
3757
  };
3735
3758
 
3736
- const getCurrentEvents = state => getCurrentEvents$2(state);
3737
-
3738
3759
  const getEventIndexByStableId$1 = (events, event) => {
3739
3760
  return events.findIndex(candidate => candidate.eventId === event.eventId);
3740
3761
  };
@@ -3807,7 +3828,7 @@ const handleEventCategoryFilter$1 = (state, value, ctrlKey = false, metaKey = fa
3807
3828
  const isPrimaryButton = button => {
3808
3829
  return button === 0;
3809
3830
  };
3810
- const handleEventRowClick = async (state, index, button = 0, loadSelectedEvent) => {
3831
+ const handleEventRowClick = async (state, index, button = 0) => {
3811
3832
  const actual = typeof index === 'string' ? Number.parseInt(index, 10) : index;
3812
3833
  if (!isPrimaryButton(button)) {
3813
3834
  return state;
@@ -3815,12 +3836,12 @@ const handleEventRowClick = async (state, index, button = 0, loadSelectedEvent)
3815
3836
  if (actual === -1) {
3816
3837
  return state;
3817
3838
  }
3818
- return selectEventAtIndex(state, actual, loadSelectedEvent);
3839
+ return selectEventAtIndex(state, actual);
3819
3840
  };
3820
3841
 
3821
- const handleEventRowClickAt = async (state, eventX, eventY, button = 0, loadSelectedEvent) => {
3842
+ const handleEventRowClickAt = async (state, eventX, eventY, button = 0) => {
3822
3843
  const selectedEventIndex = getTableBodyEventIndex(state, eventX, eventY);
3823
- return handleEventRowClick(state, selectedEventIndex, button, loadSelectedEvent);
3844
+ return handleEventRowClick(state, selectedEventIndex, button);
3824
3845
  };
3825
3846
 
3826
3847
  const getBoolean = value => {
@@ -3850,7 +3871,7 @@ const getSelectedEventIndex = state => {
3850
3871
  if (selectedEventIndex === null) {
3851
3872
  return null;
3852
3873
  }
3853
- const filteredEvents = getCurrentEvents$2(state);
3874
+ const filteredEvents = getCurrentEvents$1(state);
3854
3875
  const selectedEvent = filteredEvents[selectedEventIndex];
3855
3876
  if (!selectedEvent) {
3856
3877
  return null;
@@ -3868,12 +3889,12 @@ const getPreservedSelectedEventIndex = (oldState, newState) => {
3868
3889
  if (selectedEventIndex === null) {
3869
3890
  return null;
3870
3891
  }
3871
- const oldFilteredEvents = getCurrentEvents$2(oldState);
3892
+ const oldFilteredEvents = getCurrentEvents$1(oldState);
3872
3893
  const selectedEvent = oldFilteredEvents[selectedEventIndex];
3873
3894
  if (!selectedEvent) {
3874
3895
  return null;
3875
3896
  }
3876
- const newFilteredEvents = getCurrentEvents$2(newState);
3897
+ const newFilteredEvents = getCurrentEvents$1(newState);
3877
3898
  const newIndex = getEventIndexByStableId(newFilteredEvents, selectedEvent);
3878
3899
  if (newIndex === -1) {
3879
3900
  return null;
@@ -4661,7 +4682,7 @@ const getHandleOffsetAndPercent = (tableBodyHeight, scrollBarHeight, relativeY)
4661
4682
  };
4662
4683
  };
4663
4684
  const handleTableScrollBarPointerDown = (state, eventY) => {
4664
- const currentEvents = getCurrentEvents$2(state);
4685
+ const currentEvents = getCurrentEvents$1(state);
4665
4686
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
4666
4687
  const scrollBarHeight = getScrollBarHeight(currentEvents.length, tableBodyHeight);
4667
4688
  if (tableBodyHeight === 0 || scrollBarHeight === 0) {
@@ -4685,7 +4706,7 @@ const handleTableScrollBarPointerMove = (state, eventY) => {
4685
4706
  if (!state.tableScrollBarPointerActive) {
4686
4707
  return state;
4687
4708
  }
4688
- const currentEvents = getCurrentEvents$2(state);
4709
+ const currentEvents = getCurrentEvents$1(state);
4689
4710
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
4690
4711
  const scrollBarHeight = getScrollBarHeight(currentEvents.length, tableBodyHeight);
4691
4712
  if (tableBodyHeight === 0 || scrollBarHeight === 0) {
@@ -5053,7 +5074,7 @@ const getDetailsLineNumberWidth = state => {
5053
5074
  const getCss = state => {
5054
5075
  const hasSelectedEvent = !!state.selectedEvent;
5055
5076
  const tableWidth = hasSelectedEvent ? clampTableWidth(state, state.tableWidth) : getMainWidth(state);
5056
- const currentEvents = getCurrentEvents$2(state);
5077
+ const currentEvents = getCurrentEvents$1(state);
5057
5078
  const tableBodyHeight = getTableBodyHeight(state, currentEvents.length);
5058
5079
  const scrollBarHeight = getScrollBarHeight(currentEvents.length, tableBodyHeight);
5059
5080
  const maxDeltaY = getMaxDeltaY(currentEvents.length, tableBodyHeight);
@@ -7020,13 +7041,6 @@ const getStartText = event => {
7020
7041
  return getTimestampText(event.started ?? event.startTime ?? event.startTimestamp ?? event.timestamp);
7021
7042
  };
7022
7043
 
7023
- const getTimingPreviewSegments = event => {
7024
- return [{
7025
- endPercent: 100,
7026
- label: getDurationText(event),
7027
- startPercent: 0
7028
- }];
7029
- };
7030
7044
  const getTimingPreviewSegmentNodes = segments => {
7031
7045
  return [{
7032
7046
  childCount: segments.length,
@@ -7042,6 +7056,15 @@ const getTimingPreviewSegmentNodes = segments => {
7042
7056
  }, text(segment.label)];
7043
7057
  })];
7044
7058
  };
7059
+
7060
+ const getTimingPreviewSegments = event => {
7061
+ return [{
7062
+ endPercent: 100,
7063
+ label: getDurationText(event),
7064
+ startPercent: 0
7065
+ }];
7066
+ };
7067
+
7045
7068
  const getTimingPreviewDom = event => {
7046
7069
  const segments = getTimingPreviewSegments(event);
7047
7070
  return [{
@@ -7103,27 +7126,30 @@ const getTimingContentNodes = (responseEventNodes, selectedEvent) => {
7103
7126
  return getTimingDetailsDom(selectedEvent);
7104
7127
  };
7105
7128
 
7106
- const getTokenUsageDetailsDom = event => {
7129
+ const getRowViewModels = event => {
7107
7130
  const usageDetails = getTokenUsageDetails(event);
7108
7131
  if (!usageDetails) {
7109
7132
  return [];
7110
7133
  }
7111
- const rows = [];
7112
- let rowCount = 0;
7113
- if (usageDetails.inputTokens !== undefined) {
7114
- rows.push(...getTimingRowDom(inputTokens(), String(usageDetails.inputTokens)));
7115
- rowCount++;
7116
- }
7117
- if (usageDetails.outputTokens !== undefined) {
7118
- rows.push(...getTimingRowDom(outputTokens(), String(usageDetails.outputTokens)));
7119
- rowCount++;
7120
- }
7121
- if (usageDetails.cachedTokens !== undefined) {
7122
- rows.push(...getTimingRowDom(cachedTokens(), String(usageDetails.cachedTokens)));
7123
- rowCount++;
7134
+ return [{
7135
+ key: inputTokens(),
7136
+ value: usageDetails.inputTokens
7137
+ }, {
7138
+ key: outputTokens(),
7139
+ value: usageDetails.outputTokens
7140
+ }, {
7141
+ key: cachedTokens(),
7142
+ value: usageDetails.cachedTokens
7143
+ }].filter(row => row.value !== undefined);
7144
+ };
7145
+ const getTokenUsageDetailsDom = event => {
7146
+ const rowViewModels = getRowViewModels(event);
7147
+ if (rowViewModels.length === 0) {
7148
+ return [];
7124
7149
  }
7150
+ const rows = rowViewModels.flatMap(row => getTimingRowDom(row.key, String(row.value)));
7125
7151
  return [{
7126
- childCount: rowCount,
7152
+ childCount: rowViewModels.length,
7127
7153
  className: ChatDebugViewTiming,
7128
7154
  type: Div
7129
7155
  }, ...rows];
@@ -7804,7 +7830,7 @@ const renderItems = (oldState, newState) => {
7804
7830
  if (newState.initial) {
7805
7831
  return [SetDom2, newState.uid, []];
7806
7832
  }
7807
- const filteredEvents = getCurrentEvents$2(newState);
7833
+ const filteredEvents = getCurrentEvents$1(newState);
7808
7834
  const previewTextViewportHeight = getPreviewTextViewportHeight(newState);
7809
7835
  const dom = getChatDebugViewDom(newState.errorMessage, newState.filterValue, getSelectedEventCategoryFilters(newState.categoryFilters), newState.categoryFilters, newState.showEventStreamFinishedEvents, newState.showInputEvents, newState.showResponsePartEvents, newState.useDevtoolsLayout, newState.selectedEvent, newState.selectedEventIndex, newState.timelineStartSeconds, newState.timelineEndSeconds, newState.timelineFilterDescription, withSessionEventIds(newState.timelineEvents), withSessionEventIds(filteredEvents), newState.timelineSelectionActive, newState.timelineSelectionAnchorSeconds, newState.timelineSelectionFocusSeconds, getVisibleTableColumns(newState.tableColumns), newState.detailTabs, newState.tableColumns, newState.timelineInfo, newState.timelineHoverPercent, newState.focus, newState.previewTextCursorRowIndex, newState.previewTextCursorColumnIndex, newState.tableMinLineY, newState.tableMaxLineY, newState.previewTextDeltaY, previewTextViewportHeight);
7810
7836
  return [SetDom2, newState.uid, dom];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-debug-view",
3
- "version": "10.15.0",
3
+ "version": "10.16.0",
4
4
  "description": "Chat Debug View Worker",
5
5
  "repository": {
6
6
  "type": "git",