@metrevals/inspect-log-viewer 0.3.160-beta.1767904540 → 0.3.160-beta.1767967208

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -16251,7 +16251,8 @@ const initialState$1 = {
16251
16251
  },
16252
16252
  samplesListState: {
16253
16253
  columnVisibility: {}
16254
- }
16254
+ },
16255
+ showRetriedLogs: false
16255
16256
  };
16256
16257
  const createLogsSlice = (set3, get2, _store) => {
16257
16258
  const slice = {
@@ -16572,6 +16573,11 @@ const createLogsSlice = (set3, get2, _store) => {
16572
16573
  log$7.debug("Sample query failed, returning empty results");
16573
16574
  return [];
16574
16575
  }
16576
+ },
16577
+ setShowRetriedLogs: (showRetriedLogs) => {
16578
+ set3((state) => {
16579
+ state.logs.showRetriedLogs = showRetriedLogs;
16580
+ });
16575
16581
  }
16576
16582
  }
16577
16583
  };
@@ -17956,6 +17962,11 @@ const ApplicationIcons = {
17956
17962
  use_tools: "bi bi-tools"
17957
17963
  },
17958
17964
  success: "bi bi-check-circle-fill",
17965
+ toggle: {
17966
+ // combination of toggle-on and toggle2-off looked best for our default button font size
17967
+ on: "bi bi-toggle-on",
17968
+ off: "bi bi-toggle2-off"
17969
+ },
17959
17970
  tree: {
17960
17971
  open: "bi bi-caret-down-fill",
17961
17972
  closed: "bi bi-caret-right-fill"
@@ -20230,6 +20241,7 @@ const ExpandablePanel = memo$1(
20230
20241
  {
20231
20242
  style: baseStyles,
20232
20243
  ref: contentRef,
20244
+ "data-expandable-panel": "true",
20233
20245
  className: clsx(
20234
20246
  styles$1J.expandablePanel,
20235
20247
  collapsed2 ? styles$1J.expandableCollapsed : void 0,
@@ -103235,11 +103247,7 @@ const useLogs = () => {
103235
103247
  const setLoading = useStore((state) => state.appActions.setLoading);
103236
103248
  const loadLogs = useCallback(
103237
103249
  async (logPath) => {
103238
- const exec2 = async () => {
103239
- await syncLogs();
103240
- await syncEvalSetInfo(logPath);
103241
- };
103242
- exec2().catch((e) => {
103250
+ await Promise.all([syncEvalSetInfo(logPath), syncLogs()]).catch((e) => {
103243
103251
  log$1.error("Error loading logs", e);
103244
103252
  setLoading(false, e);
103245
103253
  });
@@ -103313,6 +103321,54 @@ const useDocumentTitle = () => {
103313
103321
  };
103314
103322
  return { setDocumentTitle };
103315
103323
  };
103324
+ const simplifiedStatusForDeduplication = (status2) => status2 === "started" || status2 === "success" ? status2 : "_other_";
103325
+ const useLogsWithretried = () => {
103326
+ const logs = useStore((state) => state.logs.logs);
103327
+ const logPreviews = useStore((state) => state.logs.logPreviews);
103328
+ const logsWithEvalSetRetry = useMemo(() => {
103329
+ const logsByTaskId = logs.reduce(
103330
+ (acc, log2) => {
103331
+ const taskId = log2.task_id;
103332
+ if (taskId) {
103333
+ if (!(taskId in acc)) acc[taskId] = [];
103334
+ acc[taskId].push(log2);
103335
+ }
103336
+ return acc;
103337
+ },
103338
+ {}
103339
+ );
103340
+ const bestByName = {};
103341
+ for (const items of Object.values(logsByTaskId)) {
103342
+ items.sort((a, b) => {
103343
+ const as = simplifiedStatusForDeduplication(
103344
+ logPreviews[a.name]?.status
103345
+ );
103346
+ const bs = simplifiedStatusForDeduplication(
103347
+ logPreviews[b.name]?.status
103348
+ );
103349
+ const am = a.mtime ?? 0;
103350
+ const bm = b.mtime ?? 0;
103351
+ if (as === bs) return bm - am;
103352
+ if (as === "started") return -1;
103353
+ if (bs === "started") return 1;
103354
+ if (as === "success") return -1;
103355
+ if (bs === "success") return 1;
103356
+ console.warn(`Unexpected status combination: ${as}, ${bs}`, a, b);
103357
+ return 0;
103358
+ });
103359
+ const { name: name2 } = items[0];
103360
+ bestByName[name2] = { ...items[0], retried: false };
103361
+ }
103362
+ return logs.map(
103363
+ (log2) => bestByName[log2.name] ?? {
103364
+ ...log2,
103365
+ // task_id is optional for backward compatibility, only new logs files can be skippable
103366
+ retried: log2.task_id ? true : void 0
103367
+ }
103368
+ );
103369
+ }, [logs, logPreviews]);
103370
+ return logsWithEvalSetRetry;
103371
+ };
103316
103372
  const log = createLogger("Client-Events");
103317
103373
  function useClientEvents() {
103318
103374
  const syncLogs = useStore((state) => state.logsActions.syncLogs);
@@ -105411,7 +105467,7 @@ const ViewerOptionsPopover = ({
105411
105467
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1i.fullWidth, styles$1i.fullWidthPadded), children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1i.logDir, children: logDir2 }) }),
105412
105468
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1i.spacer) }),
105413
105469
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Version" }),
105414
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.159-25-g3ea6b9824" }),
105470
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.159-37-g4e8f25647" }),
105415
105471
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Schema" }),
105416
105472
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: DB_VERSION }),
105417
105473
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1i.spacer) }),
@@ -163290,7 +163346,7 @@ const LogListGrid = ({
163290
163346
  if (url) {
163291
163347
  setTimeout(() => {
163292
163348
  if (openInNewWindow) {
163293
- window.open(url, "_blank");
163349
+ window.open(`#${url}`, "_blank");
163294
163350
  } else {
163295
163351
  navigate(url);
163296
163352
  }
@@ -163307,7 +163363,7 @@ const LogListGrid = ({
163307
163363
  }
163308
163364
  const openInNewWindow = e.metaKey || e.ctrlKey || e.shiftKey;
163309
163365
  if (openInNewWindow) {
163310
- window.open(rowNode.data.url, "_blank");
163366
+ window.open(`#${rowNode.data.url}`, "_blank");
163311
163367
  } else {
163312
163368
  navigate(rowNode.data.url);
163313
163369
  }
@@ -163468,8 +163524,12 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163468
163524
  const gridRef = useRef(null);
163469
163525
  const [showColumnSelector, setShowColumnSelector] = useState(false);
163470
163526
  const columnButtonRef = useRef(null);
163527
+ const showRetriedLogs = useStore((state) => state.logs.showRetriedLogs);
163528
+ const setShowRetriedLogs = useStore(
163529
+ (state) => state.logsActions.setShowRetriedLogs
163530
+ );
163471
163531
  const logDir2 = useStore((state) => state.logs.logDir);
163472
- const logFiles = useStore((state) => state.logs.logs);
163532
+ const logFiles = useLogsWithretried();
163473
163533
  const evalSet = useStore((state) => state.logs.evalSet);
163474
163534
  const logPreviews = useStore((state) => state.logs.logPreviews);
163475
163535
  const { filteredCount } = useLogsListing();
@@ -163499,11 +163559,12 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163499
163559
  previousWatchedLogs.current = watchedLogs;
163500
163560
  }
163501
163561
  }, [watchedLogs, startPolling, stopPolling]);
163502
- const logItems = useMemo(() => {
163562
+ const [logItems, hasRetriedLogs] = useMemo(() => {
163503
163563
  const folderItems = [];
163504
163564
  const fileItems = [];
163505
163565
  const processedFolders = /* @__PURE__ */ new Set();
163506
163566
  const existingLogTaskIds = /* @__PURE__ */ new Set();
163567
+ let _hasRetriedLogs = false;
163507
163568
  for (const logFile of logFiles) {
163508
163569
  if (logFile.task_id) {
163509
163570
  existingLogTaskIds.add(logFile.task_id);
@@ -163519,14 +163580,19 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163519
163580
  decodeURIComponent(relativePath),
163520
163581
  decodeURIComponent(dirName)
163521
163582
  );
163522
- fileItems.push({
163523
- id: fileOrFolderName,
163524
- name: fileOrFolderName,
163525
- type: "file",
163526
- url: logsUrl(path, logDir2),
163527
- log: logFile,
163528
- logPreview: logPreviews[logFile.name]
163529
- });
163583
+ if (logFile.retried) {
163584
+ _hasRetriedLogs = true;
163585
+ }
163586
+ if (showRetriedLogs || !logFile.retried) {
163587
+ fileItems.push({
163588
+ id: fileOrFolderName,
163589
+ name: fileOrFolderName,
163590
+ type: "file",
163591
+ url: logsUrl(path, logDir2),
163592
+ log: logFile,
163593
+ logPreview: logPreviews[logFile.name]
163594
+ });
163595
+ }
163530
163596
  } else if (name2.startsWith(dirWithSlash)) {
163531
163597
  const relativePath = directoryRelativeUrl(name2, currentDir);
163532
163598
  const dirName = decodeURIComponent(rootName(relativePath));
@@ -163547,9 +163613,13 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163547
163613
  }
163548
163614
  }
163549
163615
  const orderedItems = [...folderItems, ...fileItems];
163550
- const collapsedLogItems = collapseLogItems(evalSet, orderedItems);
163551
- return appendPendingItems(evalSet, existingLogTaskIds, collapsedLogItems);
163552
- }, [evalSet, logFiles, currentDir, logDir2, logPreviews]);
163616
+ const _logFiles = appendPendingItems(
163617
+ evalSet,
163618
+ existingLogTaskIds,
163619
+ orderedItems
163620
+ );
163621
+ return [_logFiles, _hasRetriedLogs];
163622
+ }, [evalSet, logFiles, currentDir, logDir2, logPreviews, showRetriedLogs]);
163553
163623
  const { columns, setColumnVisibility } = useLogListColumns();
163554
163624
  const handleColumnVisibilityChange = useCallback(
163555
163625
  (newVisibility) => {
@@ -163589,10 +163659,7 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163589
163659
  };
163590
163660
  }, [logItems]);
163591
163661
  useEffect(() => {
163592
- const exec2 = async () => {
163593
- await loadLogs(logPath);
163594
- };
163595
- exec2();
163662
+ loadLogs(logPath);
163596
163663
  }, [loadLogs, logPath]);
163597
163664
  const handleResetFilters = () => {
163598
163665
  if (gridRef.current?.api) {
@@ -163627,6 +163694,16 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163627
163694
  },
163628
163695
  "reset-filters"
163629
163696
  ),
163697
+ hasRetriedLogs && /* @__PURE__ */ jsxRuntimeExports.jsx(
163698
+ NavbarButton,
163699
+ {
163700
+ label: "Show Retried Logs",
163701
+ icon: showRetriedLogs ? ApplicationIcons.toggle.on : ApplicationIcons.toggle.off,
163702
+ latched: showRetriedLogs,
163703
+ onClick: () => setShowRetriedLogs(!showRetriedLogs)
163704
+ },
163705
+ "show-retried"
163706
+ ),
163630
163707
  /* @__PURE__ */ jsxRuntimeExports.jsx(
163631
163708
  NavbarButton,
163632
163709
  {
@@ -163685,62 +163762,6 @@ const LogsPanel = ({ maybeShowSingleLog }) => {
163685
163762
  ] })
163686
163763
  ] });
163687
163764
  };
163688
- const collapseLogItems = (evalSet, logItems) => {
163689
- if (!evalSet) {
163690
- return logItems;
163691
- }
163692
- const running = logItems.some(
163693
- (l) => l.type === "file" && l.logPreview?.status === "started"
163694
- );
163695
- if (!running) {
163696
- return logItems;
163697
- }
163698
- const taskIdToItems = /* @__PURE__ */ new Map();
163699
- for (const item2 of logItems) {
163700
- if (item2.type === "file" && item2.log.task_id) {
163701
- const taskId = item2.log.task_id;
163702
- if (!taskIdToItems.has(taskId)) {
163703
- taskIdToItems.set(taskId, []);
163704
- }
163705
- taskIdToItems.get(taskId).push(item2);
163706
- } else if (item2.type === "folder" || item2.type === "file") ;
163707
- }
163708
- const selectedItems = /* @__PURE__ */ new Map();
163709
- for (const [taskId, items] of taskIdToItems) {
163710
- let bestItem = items[0];
163711
- for (const item2 of items) {
163712
- const currentStatus = item2.logPreview?.status;
163713
- const currentMtime = item2.log.mtime ?? 0;
163714
- const bestStatus = bestItem.logPreview?.status;
163715
- const bestMtime = bestItem.log.mtime ?? 0;
163716
- if (currentStatus === "started" && bestStatus !== "started") {
163717
- bestItem = item2;
163718
- } else if (currentStatus === "success" && bestStatus === "error") {
163719
- bestItem = item2;
163720
- } else if (currentStatus === bestStatus && currentMtime > bestMtime) {
163721
- bestItem = item2;
163722
- }
163723
- }
163724
- selectedItems.set(taskId, bestItem);
163725
- }
163726
- const collapsedLogItems = [];
163727
- const processedTaskIds = /* @__PURE__ */ new Set();
163728
- for (const item2 of logItems) {
163729
- if (item2.type === "file" && item2.log.task_id) {
163730
- const taskId = item2.log.task_id;
163731
- if (!processedTaskIds.has(taskId)) {
163732
- const selectedItem = selectedItems.get(taskId);
163733
- if (selectedItem) {
163734
- collapsedLogItems.push(selectedItem);
163735
- }
163736
- processedTaskIds.add(taskId);
163737
- }
163738
- } else {
163739
- collapsedLogItems.push(item2);
163740
- }
163741
- }
163742
- return collapsedLogItems;
163743
- };
163744
163765
  const appendPendingItems = (evalSet, tasksWithLogFiles, collapsedLogItems) => {
163745
163766
  const pendingTasks = new Array();
163746
163767
  for (const task of evalSet?.tasks || []) {
@@ -163843,11 +163864,14 @@ const FindBand = () => {
163843
163864
  const { extendedFindTerm } = useExtendedFind();
163844
163865
  const lastFoundItem = useRef(null);
163845
163866
  const currentSearchTerm = useRef("");
163867
+ const debounceTimerRef = useRef(null);
163868
+ const needsCursorRestoreRef = useRef(false);
163869
+ const lastNoResultTerm = useRef("");
163846
163870
  const getParentExpandablePanel = useCallback(
163847
163871
  (selection) => {
163848
163872
  let node2 = selection.anchorNode;
163849
163873
  while (node2) {
163850
- if (node2 instanceof HTMLElement && node2.classList.contains("expandable-panel")) {
163874
+ if (node2 instanceof HTMLElement && node2.hasAttribute("data-expandable-panel")) {
163851
163875
  return node2;
163852
163876
  }
163853
163877
  node2 = node2.parentElement;
@@ -163866,6 +163890,16 @@ const FindBand = () => {
163866
163890
  lastFoundItem.current = null;
163867
163891
  currentSearchTerm.current = searchTerm;
163868
163892
  }
163893
+ if (lastNoResultTerm.current && !searchTerm.startsWith(lastNoResultTerm.current)) {
163894
+ lastNoResultTerm.current = "";
163895
+ }
163896
+ const noResultEl = document.getElementById("inspect-find-no-results");
163897
+ if (lastNoResultTerm.current && searchTerm.startsWith(lastNoResultTerm.current)) {
163898
+ if (noResultEl) {
163899
+ noResultEl.style.opacity = "1";
163900
+ }
163901
+ return;
163902
+ }
163869
163903
  const focusedElement = document.activeElement;
163870
163904
  let result2 = await findExtendedInDOM(
163871
163905
  searchTerm,
@@ -163873,11 +163907,11 @@ const FindBand = () => {
163873
163907
  lastFoundItem.current,
163874
163908
  extendedFindTerm
163875
163909
  );
163876
- const noResultEl = document.getElementById("inspect-find-no-results");
163877
163910
  if (!noResultEl) {
163878
163911
  return;
163879
163912
  }
163880
163913
  noResultEl.style.opacity = result2 ? "0" : "1";
163914
+ lastNoResultTerm.current = result2 ? "" : searchTerm;
163881
163915
  if (result2) {
163882
163916
  const selection = window.getSelection();
163883
163917
  if (selection && selection.rangeCount > 0) {
@@ -163891,6 +163925,7 @@ const FindBand = () => {
163891
163925
  const parentPanel = getParentExpandablePanel(selection);
163892
163926
  if (parentPanel) {
163893
163927
  parentPanel.style.display = "block";
163928
+ parentPanel.style.maxHeight = "none";
163894
163929
  parentPanel.style.webkitLineClamp = "";
163895
163930
  parentPanel.style.webkitBoxOrient = "";
163896
163931
  }
@@ -163948,12 +163983,60 @@ const FindBand = () => {
163948
163983
  },
163949
163984
  [storeHideFind, handleSearch]
163950
163985
  );
163951
- const showSearch = useCallback(() => {
163986
+ const findPrevious = useCallback(() => {
163952
163987
  handleSearch(true);
163953
163988
  }, [handleSearch]);
163954
- const hideSearch = useCallback(() => {
163989
+ const findNext = useCallback(() => {
163955
163990
  handleSearch(false);
163956
163991
  }, [handleSearch]);
163992
+ const restoreCursor = useCallback(() => {
163993
+ if (!needsCursorRestoreRef.current) return;
163994
+ needsCursorRestoreRef.current = false;
163995
+ const input2 = searchBoxRef.current;
163996
+ if (input2) {
163997
+ const len = input2.value.length;
163998
+ input2.setSelectionRange(len, len);
163999
+ }
164000
+ }, []);
164001
+ const handleInputChange = useCallback(() => {
164002
+ if (debounceTimerRef.current !== null) {
164003
+ window.clearTimeout(debounceTimerRef.current);
164004
+ }
164005
+ debounceTimerRef.current = window.setTimeout(async () => {
164006
+ debounceTimerRef.current = null;
164007
+ if (!searchBoxRef.current) return;
164008
+ await handleSearch(false);
164009
+ needsCursorRestoreRef.current = true;
164010
+ }, 300);
164011
+ }, [handleSearch]);
164012
+ const handleBeforeInput = useCallback(() => {
164013
+ restoreCursor();
164014
+ }, [restoreCursor]);
164015
+ useEffect(() => {
164016
+ const handleGlobalKeyDown = (e) => {
164017
+ if (e.key === "F3") {
164018
+ e.preventDefault();
164019
+ handleSearch(e.shiftKey);
164020
+ return;
164021
+ }
164022
+ if (e.ctrlKey || e.metaKey || e.altKey) return;
164023
+ if (e.key.length !== 1 && e.key !== "Backspace" && e.key !== "Delete")
164024
+ return;
164025
+ const input2 = searchBoxRef.current;
164026
+ if (!input2) return;
164027
+ restoreCursor();
164028
+ if (document.activeElement !== input2) {
164029
+ input2.focus();
164030
+ }
164031
+ };
164032
+ document.addEventListener("keydown", handleGlobalKeyDown);
164033
+ return () => {
164034
+ document.removeEventListener("keydown", handleGlobalKeyDown);
164035
+ if (debounceTimerRef.current !== null) {
164036
+ window.clearTimeout(debounceTimerRef.current);
164037
+ }
164038
+ };
164039
+ }, [handleSearch, restoreCursor]);
163957
164040
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { "data-unsearchable": "true", className: clsx("findBand"), children: [
163958
164041
  /* @__PURE__ */ jsxRuntimeExports.jsx(
163959
164042
  "input",
@@ -163961,7 +164044,9 @@ const FindBand = () => {
163961
164044
  type: "text",
163962
164045
  ref: searchBoxRef,
163963
164046
  placeholder: "Find",
163964
- onKeyDown: handleKeyDown
164047
+ onKeyDown: handleKeyDown,
164048
+ onBeforeInput: handleBeforeInput,
164049
+ onChange: handleInputChange
163965
164050
  }
163966
164051
  ),
163967
164052
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { id: "inspect-find-no-results", children: "No results" }),
@@ -163971,7 +164056,7 @@ const FindBand = () => {
163971
164056
  type: "button",
163972
164057
  title: "Previous match",
163973
164058
  className: "btn next",
163974
- onClick: showSearch,
164059
+ onClick: findPrevious,
163975
164060
  children: /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: ApplicationIcons.arrows.up })
163976
164061
  }
163977
164062
  ),
@@ -163981,7 +164066,7 @@ const FindBand = () => {
163981
164066
  type: "button",
163982
164067
  title: "Next match",
163983
164068
  className: "btn prev",
163984
- onClick: hideSearch,
164069
+ onClick: findNext,
163985
164070
  children: /* @__PURE__ */ jsxRuntimeExports.jsx("i", { className: ApplicationIcons.arrows.down })
163986
164071
  }
163987
164072
  ),
@@ -165636,6 +165721,12 @@ const LiveVirtualList = ({
165636
165721
  behavior: "auto",
165637
165722
  align: "center"
165638
165723
  });
165724
+ setTimeout(() => {
165725
+ if (pendingSearchCallback.current === onContentReady) {
165726
+ pendingSearchCallback.current = null;
165727
+ onContentReady();
165728
+ }
165729
+ }, 200);
165639
165730
  return true;
165640
165731
  }
165641
165732
  }
@@ -206710,10 +206801,7 @@ const FlowPanel = () => {
206710
206801
  const flowDir = dirname(currentPath || "");
206711
206802
  const { loadLogs } = useLogs();
206712
206803
  useEffect(() => {
206713
- const exec2 = async () => {
206714
- await loadLogs(flowDir);
206715
- };
206716
- exec2();
206804
+ loadLogs(flowDir);
206717
206805
  }, [loadLogs, flowDir]);
206718
206806
  useFlowServerData(flowDir || "");
206719
206807
  const flow = useStore((state) => state.logs.flow);
@@ -206986,15 +207074,14 @@ const useSampleColumns = (logDetails) => {
206986
207074
  };
206987
207075
  };
206988
207076
  const SamplesGrid = ({
207077
+ items,
206989
207078
  samplesPath,
206990
207079
  gridRef: externalGridRef,
206991
207080
  columns
206992
207081
  }) => {
206993
- const logDetails = useStore((state) => state.logs.logDetails);
206994
207082
  const gridState = useStore((state) => state.logs.samplesListState.gridState);
206995
207083
  const setGridState = useStore((state) => state.logsActions.setGridState);
206996
207084
  const { navigateToSampleDetail } = useSamplesGridNavigation();
206997
- const logDir2 = useStore((state) => state.logs.logDir);
206998
207085
  const setFilteredSampleCount = useStore(
206999
207086
  (state) => state.logActions.setFilteredSampleCount
207000
207087
  );
@@ -207044,55 +207131,9 @@ const SamplesGrid = ({
207044
207131
  setPreviousSamplesPath(samplesPath);
207045
207132
  }
207046
207133
  }, [samplesPath, previousSamplesPath, setPreviousSamplesPath]);
207047
- const filteredLogDetails = useMemo(() => {
207048
- if (!samplesPath) {
207049
- return logDetails;
207050
- }
207051
- const samplesPathAbs = join(samplesPath, logDir2);
207052
- return Object.entries(logDetails).reduce(
207053
- (acc, [logFile, details]) => {
207054
- if (logFile.startsWith(samplesPathAbs)) {
207055
- acc[logFile] = details;
207056
- }
207057
- return acc;
207058
- },
207059
- {}
207060
- );
207061
- }, [logDetails, logDir2, samplesPath]);
207062
207134
  useEffect(() => {
207063
207135
  gridContainerRef.current?.focus();
207064
207136
  }, []);
207065
- const data = useMemo(() => {
207066
- const rows = [];
207067
- let displayIndex = 1;
207068
- Object.entries(filteredLogDetails).forEach(([logFile, details]) => {
207069
- details.sampleSummaries.forEach((sample2) => {
207070
- const row2 = {
207071
- logFile,
207072
- created: details.eval.created,
207073
- task: details.eval.task || "",
207074
- model: details.eval.model || "",
207075
- status: details.status,
207076
- sampleId: sample2.id,
207077
- epoch: sample2.epoch,
207078
- input: inputString(sample2.input).join("\n"),
207079
- target: Array.isArray(sample2.target) ? sample2.target.join(", ") : sample2.target,
207080
- error: sample2.error,
207081
- limit: sample2.limit,
207082
- retries: sample2.retries,
207083
- completed: sample2.completed || false,
207084
- displayIndex: displayIndex++
207085
- };
207086
- if (sample2.scores) {
207087
- Object.entries(sample2.scores).forEach(([scoreName, score2]) => {
207088
- row2[`score_${scoreName}`] = score2.value;
207089
- });
207090
- }
207091
- rows.push(row2);
207092
- });
207093
- });
207094
- return rows;
207095
- }, [filteredLogDetails]);
207096
207137
  const handleRowClick = useCallback(
207097
207138
  (e) => {
207098
207139
  if (e.data && e.node && gridRef.current?.api) {
@@ -207170,7 +207211,7 @@ const SamplesGrid = ({
207170
207211
  AgGridReact,
207171
207212
  {
207172
207213
  ref: gridRef,
207173
- rowData: data,
207214
+ rowData: items,
207174
207215
  animateRows: false,
207175
207216
  columnDefs: columns,
207176
207217
  defaultColDef: {
@@ -207222,7 +207263,7 @@ const SamplesGrid = ({
207222
207263
  selectCurrentSample();
207223
207264
  clearSelectedSample();
207224
207265
  },
207225
- loading: data.length === 0 && (loading > 0 || syncing)
207266
+ loading: items.length === 0 && (loading > 0 || syncing)
207226
207267
  }
207227
207268
  ) }) });
207228
207269
  };
@@ -207253,9 +207294,16 @@ const SamplesPanel = () => {
207253
207294
  const logDir2 = useStore((state) => state.logs.logDir);
207254
207295
  const loading = useStore((state) => state.app.status.loading);
207255
207296
  const syncing = useStore((state) => state.app.status.syncing);
207297
+ const showRetriedLogs = useStore((state) => state.logs.showRetriedLogs);
207298
+ const setShowRetriedLogs = useStore(
207299
+ (state) => state.logsActions.setShowRetriedLogs
207300
+ );
207256
207301
  const filteredSamplesCount = useStore(
207257
207302
  (state) => state.log.filteredSampleCount
207258
207303
  );
207304
+ const setFilteredSampleCount = useStore(
207305
+ (state) => state.logActions.setFilteredSampleCount
207306
+ );
207259
207307
  const gridRef = useRef(null);
207260
207308
  const [showColumnSelector, setShowColumnSelector] = useState(false);
207261
207309
  const columnButtonRef = useRef(null);
@@ -207291,17 +207339,19 @@ const SamplesPanel = () => {
207291
207339
  const flowData = useStore((state) => state.logs.flow);
207292
207340
  const currentDir = join(samplesPath || "", logDir2);
207293
207341
  const evalSet = useStore((state) => state.logs.evalSet);
207294
- const logFiles = useStore((state) => state.logs.logs);
207342
+ const logFiles = useLogsWithretried();
207295
207343
  const logPreviews = useStore((state) => state.logs.logPreviews);
207296
207344
  const currentDirLogFiles = useMemo(() => {
207297
207345
  const files = [];
207298
207346
  for (const logFile of logFiles) {
207299
- if (logFile.name.startsWith(currentDir)) {
207347
+ const inCurrentDir = logFile.name.startsWith(currentDir);
207348
+ const skipped = !showRetriedLogs && logFile.retried;
207349
+ if (inCurrentDir && !skipped) {
207300
207350
  files.push(logFile);
207301
207351
  }
207302
207352
  }
207303
207353
  return files;
207304
- }, [currentDir, logFiles]);
207354
+ }, [currentDir, logFiles, showRetriedLogs]);
207305
207355
  const totalTaskCount = useMemo(() => {
207306
207356
  const currentDirTaskIds = new Set(currentDirLogFiles.map((f) => f.task_id));
207307
207357
  let count = currentDirLogFiles.length;
@@ -207323,11 +207373,69 @@ const SamplesPanel = () => {
207323
207373
  return count;
207324
207374
  }, [logPreviews, currentDirLogFiles]);
207325
207375
  useEffect(() => {
207326
- const exec2 = async () => {
207327
- await loadLogs(samplesPath);
207328
- };
207329
- exec2();
207376
+ loadLogs(samplesPath);
207330
207377
  }, [loadLogs, samplesPath]);
207378
+ const logDetailsInPath = useMemo(() => {
207379
+ if (!samplesPath) {
207380
+ return logDetails;
207381
+ }
207382
+ const samplesPathAbs = join(samplesPath, logDir2);
207383
+ return Object.entries(logDetails).reduce(
207384
+ (acc, [logFile, details]) => {
207385
+ if (logFile.startsWith(samplesPathAbs)) {
207386
+ acc[logFile] = details;
207387
+ }
207388
+ return acc;
207389
+ },
207390
+ {}
207391
+ );
207392
+ }, [logDetails, logDir2, samplesPath]);
207393
+ const [sampleRows, hasRetriedLogs] = useMemo(() => {
207394
+ const allRows = [];
207395
+ let displayIndex = 1;
207396
+ let anyLogInCurrentDirCouldBeSkipped = false;
207397
+ const logInCurrentDirByName = currentDirLogFiles.reduce(
207398
+ (acc, log2) => {
207399
+ if (log2.retried) {
207400
+ anyLogInCurrentDirCouldBeSkipped = true;
207401
+ }
207402
+ acc[log2.name] = log2;
207403
+ return acc;
207404
+ },
207405
+ {}
207406
+ );
207407
+ Object.entries(logDetailsInPath).forEach(([logFile, logDetail]) => {
207408
+ logDetail.sampleSummaries.forEach((sampleSummary) => {
207409
+ const row2 = {
207410
+ logFile,
207411
+ created: logDetail.eval.created,
207412
+ task: logDetail.eval.task || "",
207413
+ model: logDetail.eval.model || "",
207414
+ status: logDetail.status,
207415
+ sampleId: sampleSummary.id,
207416
+ epoch: sampleSummary.epoch,
207417
+ input: inputString(sampleSummary.input).join("\n"),
207418
+ target: Array.isArray(sampleSummary.target) ? sampleSummary.target.join(", ") : sampleSummary.target,
207419
+ error: sampleSummary.error,
207420
+ limit: sampleSummary.limit,
207421
+ retries: sampleSummary.retries,
207422
+ completed: sampleSummary.completed || false,
207423
+ displayIndex: displayIndex++
207424
+ };
207425
+ if (sampleSummary.scores) {
207426
+ Object.entries(sampleSummary.scores).forEach(([scoreName, score2]) => {
207427
+ row2[`score_${scoreName}`] = score2.value;
207428
+ });
207429
+ }
207430
+ allRows.push(row2);
207431
+ });
207432
+ });
207433
+ const _sampleRows = allRows.filter(
207434
+ (row2) => row2.logFile in logInCurrentDirByName
207435
+ );
207436
+ const _hasRetriedLogs = _sampleRows.length < allRows.length || anyLogInCurrentDirCouldBeSkipped;
207437
+ return [_sampleRows, _hasRetriedLogs];
207438
+ }, [logDetailsInPath, currentDirLogFiles]);
207331
207439
  const filterModel = gridRef.current?.api?.getFilterModel() || {};
207332
207440
  const filteredFields = Object.keys(filterModel);
207333
207441
  const hasFilter = filteredFields.length > 0;
@@ -207342,6 +207450,25 @@ const SamplesPanel = () => {
207342
207450
  },
207343
207451
  "reset-filters"
207344
207452
  ),
207453
+ hasRetriedLogs && /* @__PURE__ */ jsxRuntimeExports.jsx(
207454
+ NavbarButton,
207455
+ {
207456
+ label: "Show Retried Logs",
207457
+ icon: showRetriedLogs ? ApplicationIcons.toggle.on : ApplicationIcons.toggle.off,
207458
+ latched: showRetriedLogs,
207459
+ onClick: () => {
207460
+ setShowRetriedLogs(!showRetriedLogs);
207461
+ setTimeout(() => {
207462
+ if (gridRef.current) {
207463
+ setFilteredSampleCount(
207464
+ gridRef.current.api.getDisplayedRowCount()
207465
+ );
207466
+ }
207467
+ }, 10);
207468
+ }
207469
+ },
207470
+ "show-retried"
207471
+ ),
207345
207472
  /* @__PURE__ */ jsxRuntimeExports.jsx(
207346
207473
  NavbarButton,
207347
207474
  {
@@ -207373,6 +207500,7 @@ const SamplesPanel = () => {
207373
207500
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1.list, "text-size-smaller"), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
207374
207501
  SamplesGrid,
207375
207502
  {
207503
+ items: sampleRows,
207376
207504
  samplesPath,
207377
207505
  gridRef,
207378
207506
  columns