@meridianlabs/log-viewer 0.3.199 → 0.3.200

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.
Files changed (39) hide show
  1. package/lib/app/samples/InlineSampleDisplay.d.ts.map +1 -1
  2. package/lib/app/samples/SampleDisplay.d.ts +1 -0
  3. package/lib/app/samples/SampleDisplay.d.ts.map +1 -1
  4. package/lib/app/samples/chat/ChatViewVirtualList.d.ts.map +1 -1
  5. package/lib/app/samples/chat/MessageContent.d.ts.map +1 -1
  6. package/lib/app/samples/transcript/TranscriptPanel.d.ts.map +1 -1
  7. package/lib/app/types.d.ts +5 -0
  8. package/lib/app/types.d.ts.map +1 -1
  9. package/lib/client/api/client-api.d.ts.map +1 -1
  10. package/lib/client/api/static-http/api-static-http.d.ts.map +1 -1
  11. package/lib/client/api/types.d.ts +7 -2
  12. package/lib/client/api/types.d.ts.map +1 -1
  13. package/lib/client/api/view-server/api-view-server.d.ts.map +1 -1
  14. package/lib/client/api/vscode/api-vscode.d.ts.map +1 -1
  15. package/lib/client/api/vscode/jsonrpc.d.ts +1 -1
  16. package/lib/client/remote/remoteLogFile.d.ts +2 -2
  17. package/lib/client/remote/remoteLogFile.d.ts.map +1 -1
  18. package/lib/client/remote/remoteZipFile.d.ts +7 -6
  19. package/lib/client/remote/remoteZipFile.d.ts.map +1 -1
  20. package/lib/components/ActivityBar.d.ts +1 -0
  21. package/lib/components/ActivityBar.d.ts.map +1 -1
  22. package/lib/components/LiveVirtualList.d.ts.map +1 -1
  23. package/lib/components/MarkdownDiv.d.ts.map +1 -1
  24. package/lib/components/markdownRendering.d.ts +14 -0
  25. package/lib/components/markdownRendering.d.ts.map +1 -0
  26. package/lib/index.js +477 -277
  27. package/lib/index.js.map +1 -1
  28. package/lib/state/hooks.d.ts +1 -0
  29. package/lib/state/hooks.d.ts.map +1 -1
  30. package/lib/state/sampleSlice.d.ts +2 -1
  31. package/lib/state/sampleSlice.d.ts.map +1 -1
  32. package/lib/state/sampleUtils.d.ts.map +1 -1
  33. package/lib/state/useLoadSample.d.ts.map +1 -1
  34. package/lib/styles/index.css +53 -29
  35. package/lib/utils/expandEvents.d.ts +11 -0
  36. package/lib/utils/expandEvents.d.ts.map +1 -0
  37. package/lib/utils/json-worker.d.ts +10 -0
  38. package/lib/utils/json-worker.d.ts.map +1 -1
  39. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -16820,54 +16820,48 @@ const resolveAttachments = (value2, attachments, onFailedResolve) => {
16820
16820
  }
16821
16821
  return value2;
16822
16822
  };
16823
- const expandRefs = (refs, pool) => refs.flatMap(([start2, end_exclusive]) => pool.slice(start2, end_exclusive));
16824
- const resolveEventRefs = (events, msgPool, callPool) => {
16823
+ const expandRefs = (refs, pool) => refs.flatMap(([start2, end2]) => pool.slice(start2, end2));
16824
+ const isModelEvent = (event) => event.event === "model";
16825
+ function expandEvents(events, eventsData) {
16826
+ if (!eventsData) return events;
16827
+ const { messages: messages2, calls } = eventsData;
16828
+ const hasMessages = messages2.length > 0;
16829
+ const hasCalls = calls.length > 0;
16830
+ if (!hasMessages && !hasCalls) return events;
16825
16831
  return events.map((event) => {
16826
- if (event.event !== "model") return event;
16827
- const resolved = Array.isArray(event.input_refs) ? {
16828
- ...event,
16829
- input: expandRefs(
16830
- event.input_refs,
16831
- msgPool
16832
- ),
16833
- input_refs: null
16834
- } : event;
16835
- if (!resolved.call || !Array.isArray(resolved.call.call_refs))
16836
- return resolved;
16837
- return {
16838
- ...resolved,
16839
- call: {
16840
- ...resolved.call,
16841
- request: {
16842
- ...resolved.call.request,
16843
- [resolved.call.call_key || "messages"]: expandRefs(
16844
- resolved.call.call_refs,
16845
- callPool
16846
- )
16847
- },
16832
+ if (!isModelEvent(event)) return event;
16833
+ let changed = false;
16834
+ let input2 = event.input;
16835
+ let call = event.call;
16836
+ if (event.input_refs != null && hasMessages) {
16837
+ input2 = expandRefs(event.input_refs, messages2);
16838
+ changed = true;
16839
+ }
16840
+ if (call?.call_refs != null && hasCalls) {
16841
+ const key2 = call.call_key ?? "messages";
16842
+ const expandedMsgs = expandRefs(
16843
+ call.call_refs,
16844
+ calls
16845
+ );
16846
+ call = {
16847
+ ...call,
16848
+ request: { ...call.request, [key2]: expandedMsgs },
16848
16849
  call_refs: null,
16849
16850
  call_key: null
16850
- }
16851
- };
16851
+ };
16852
+ changed = true;
16853
+ }
16854
+ return changed ? { ...event, input: input2, input_refs: null, call } : event;
16852
16855
  });
16853
- };
16854
- const resolvePools = (sample2) => {
16855
- const { message_pool, call_pool } = sample2;
16856
- if (!message_pool?.length && !call_pool?.length) return sample2;
16857
- return {
16858
- ...sample2,
16859
- events: resolveEventRefs(sample2.events, message_pool, call_pool),
16860
- message_pool: [],
16861
- call_pool: []
16862
- };
16863
- };
16856
+ }
16864
16857
  const resolveSample$1 = (sample2) => {
16865
16858
  sample2 = { ...sample2 };
16866
16859
  if (sample2.transcript) {
16867
16860
  sample2.events = sample2.transcript.events;
16868
16861
  sample2.attachments = sample2.transcript.content;
16869
16862
  }
16870
- sample2 = resolvePools(sample2);
16863
+ sample2.events = expandEvents(sample2.events, sample2.events_data ?? null);
16864
+ sample2.events_data = null;
16871
16865
  sample2.attachments = sample2.attachments || {};
16872
16866
  sample2.input = resolveAttachments(sample2.input, sample2.attachments);
16873
16867
  sample2.messages = resolveAttachments(sample2.messages, sample2.attachments);
@@ -17252,6 +17246,7 @@ const initialState = {
17252
17246
  sampleStatus: "ok",
17253
17247
  sampleError: void 0,
17254
17248
  eventsCleared: false,
17249
+ downloadProgress: void 0,
17255
17250
  visiblePopover: void 0,
17256
17251
  // signals that the sample needs to be reloaded
17257
17252
  sampleNeedsReload: 0,
@@ -17306,6 +17301,7 @@ const createSampleSlice = (set3, get2, _store) => {
17306
17301
  state.sample.sampleInState = false;
17307
17302
  state.sample.runningEvents = [];
17308
17303
  state.sample.sampleStatus = "ok";
17304
+ state.sample.downloadProgress = void 0;
17309
17305
  state.log.selectedSampleHandle = void 0;
17310
17306
  });
17311
17307
  },
@@ -17327,6 +17323,9 @@ const createSampleSlice = (set3, get2, _store) => {
17327
17323
  setSampleError: (error2) => set3((state) => {
17328
17324
  state.sample.sampleError = error2;
17329
17325
  }),
17326
+ setDownloadProgress: (progress2) => set3((state) => {
17327
+ state.sample.downloadProgress = progress2;
17328
+ }),
17330
17329
  setCollapsedEvents: (scope, collapsed2) => {
17331
17330
  set3((state) => {
17332
17331
  if (state.sample.collapsedEvents === null) {
@@ -24836,16 +24835,16 @@ const supportsLinking = () => {
24836
24835
  const toFullUrl = (path) => {
24837
24836
  return `${window.location.origin}${window.location.pathname}${window.location.search}#${path}`;
24838
24837
  };
24839
- const message$3 = "_message_1k527_1";
24840
- const systemRole = "_systemRole_1k527_8";
24841
- const timestamp = "_timestamp_1k527_12";
24842
- const messageGrid = "_messageGrid_1k527_18";
24843
- const toolMessageGrid = "_toolMessageGrid_1k527_28";
24844
- const messageContents = "_messageContents_1k527_32";
24845
- const indented = "_indented_1k527_37";
24846
- const copyLink$1 = "_copyLink_1k527_41";
24847
- const metadataLabel = "_metadataLabel_1k527_52";
24848
- const hover$1 = "_hover_1k527_56";
24838
+ const message$3 = "_message_1kuwu_1";
24839
+ const systemRole = "_systemRole_1kuwu_9";
24840
+ const timestamp = "_timestamp_1kuwu_13";
24841
+ const messageGrid = "_messageGrid_1kuwu_19";
24842
+ const toolMessageGrid = "_toolMessageGrid_1kuwu_29";
24843
+ const messageContents = "_messageContents_1kuwu_33";
24844
+ const indented = "_indented_1kuwu_38";
24845
+ const copyLink$1 = "_copyLink_1kuwu_42";
24846
+ const metadataLabel = "_metadataLabel_1kuwu_53";
24847
+ const hover$1 = "_hover_1kuwu_57";
24849
24848
  const styles$1C = {
24850
24849
  message: message$3,
24851
24850
  systemRole,
@@ -24935,6 +24934,23 @@ class JsonWorkerPool {
24935
24934
  );
24936
24935
  });
24937
24936
  }
24937
+ async parseBytes(data) {
24938
+ this.ensureWorkers();
24939
+ const requestId = this.nextRequestId++;
24940
+ const ownedData = data.byteOffset === 0 && data.byteLength === data.buffer.byteLength ? data : data.slice();
24941
+ return new Promise((resolve, reject) => {
24942
+ this.pendingRequests.set(requestId, { resolve, reject });
24943
+ const worker = this.workers[requestId % this.workers.length];
24944
+ worker?.postMessage(
24945
+ {
24946
+ type: "parse",
24947
+ requestId,
24948
+ encodedText: ownedData
24949
+ },
24950
+ [ownedData.buffer]
24951
+ );
24952
+ });
24953
+ }
24938
24954
  terminate() {
24939
24955
  this.workers.forEach((w) => w.terminate());
24940
24956
  this.workers = [];
@@ -24959,6 +24975,14 @@ const asyncJsonParse = async (text2) => {
24959
24975
  return workerPool.parse(text2);
24960
24976
  }
24961
24977
  };
24978
+ const asyncJsonParseBytes = async (data) => {
24979
+ if (data.length < 5e4) {
24980
+ const text2 = new TextDecoder("utf-8").decode(data);
24981
+ return jsonParse(text2);
24982
+ } else {
24983
+ return workerPool.parseBytes(data);
24984
+ }
24985
+ };
24962
24986
  const jsonParse = (text2) => {
24963
24987
  try {
24964
24988
  return JSON.parse(text2);
@@ -95421,16 +95445,163 @@ function requireMarkdownItMathjax3() {
95421
95445
  }
95422
95446
  var markdownItMathjax3Exports = requireMarkdownItMathjax3();
95423
95447
  const markdownitMathjax3 = /* @__PURE__ */ getDefaultExportFromCjs(markdownItMathjax3Exports);
95448
+ const mdInstanceCache = {};
95449
+ const getOptionsKey = (omitMedia, omitMath) => `${omitMedia ? "1" : "0"}:${omitMath ? "1" : "0"}`;
95450
+ const unescapeHtmlForMath = (content2) => {
95451
+ return content2.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&apos;/g, "'").replace(/&quot;/g, '"');
95452
+ };
95453
+ const getMarkdownInstance = (omitMedia, omitMath) => {
95454
+ const key2 = getOptionsKey(omitMedia, omitMath);
95455
+ if (!mdInstanceCache[key2]) {
95456
+ const md = new MarkdownIt({ breaks: true, html: true });
95457
+ if (!omitMath) {
95458
+ md.use(markdownitMathjax3);
95459
+ const origInline = md.renderer.rules.math_inline;
95460
+ const origBlock = md.renderer.rules.math_block;
95461
+ if (origInline) {
95462
+ md.renderer.rules.math_inline = (tokens, idx, options2, env, self2) => {
95463
+ tokens[idx].content = unescapeHtmlForMath(tokens[idx].content);
95464
+ return origInline(tokens, idx, options2, env, self2);
95465
+ };
95466
+ }
95467
+ if (origBlock) {
95468
+ md.renderer.rules.math_block = (tokens, idx, options2, env, self2) => {
95469
+ tokens[idx].content = unescapeHtmlForMath(tokens[idx].content);
95470
+ return origBlock(tokens, idx, options2, env, self2);
95471
+ };
95472
+ }
95473
+ }
95474
+ if (omitMedia) {
95475
+ md.disable(["image"]);
95476
+ }
95477
+ mdInstanceCache[key2] = md;
95478
+ }
95479
+ return mdInstanceCache[key2];
95480
+ };
95481
+ const escapeHtmlCharacters = (content2) => {
95482
+ if (!content2) return content2;
95483
+ return content2.replace(/[<>&'"]/g, (c2) => {
95484
+ switch (c2) {
95485
+ case "<":
95486
+ return "&lt;";
95487
+ case ">":
95488
+ return "&gt;";
95489
+ case "&":
95490
+ return "&amp;";
95491
+ case "'":
95492
+ return "&apos;";
95493
+ case '"':
95494
+ return "&quot;";
95495
+ default:
95496
+ throw new Error("Matched a value that isn't replaceable");
95497
+ }
95498
+ });
95499
+ };
95500
+ const protectBackslashesInLatex = (content2) => {
95501
+ if (!content2) return content2;
95502
+ try {
95503
+ const inlineRegex = /\$(.*?)\$/g;
95504
+ const blockRegex = /\$\$([\s\S]*?)\$\$/g;
95505
+ let result2 = content2.replace(inlineRegex, (_match, latex) => {
95506
+ const protectedTex = latex.replace(/\\/g, "___LATEX_BACKSLASH___");
95507
+ return `$${protectedTex}$`;
95508
+ });
95509
+ result2 = result2.replace(blockRegex, (_match, latex) => {
95510
+ const protectedTex = latex.replace(/\\/g, "___LATEX_BACKSLASH___");
95511
+ return `$$${protectedTex}$$`;
95512
+ });
95513
+ return result2;
95514
+ } catch (error2) {
95515
+ console.error("Error protecting LaTeX content:", error2);
95516
+ return content2;
95517
+ }
95518
+ };
95519
+ const restoreBackslashesForLatex = (content2) => {
95520
+ if (!content2) {
95521
+ return content2;
95522
+ }
95523
+ try {
95524
+ let result2 = content2.replace(/___LATEX_BACKSLASH___/g, "\\");
95525
+ result2 = fixDotsNotation(result2);
95526
+ return result2;
95527
+ } catch (error2) {
95528
+ console.error("Error restoring LaTeX content:", error2);
95529
+ return content2;
95530
+ }
95531
+ };
95532
+ const fixDotsNotation = (content2) => {
95533
+ if (!content2) return content2;
95534
+ try {
95535
+ let result2 = content2.replace(/(\$[^$]*?)\\dots([^$]*?\$)/g, "$1\\ldots$2");
95536
+ result2 = result2.replace(/(\$\$[^$]*?)\\dots([^$]*?\$\$)/g, "$1\\ldots$2");
95537
+ return result2;
95538
+ } catch (error2) {
95539
+ console.error("Error fixing dots notation:", error2);
95540
+ return content2;
95541
+ }
95542
+ };
95543
+ const kLetterListPattern = /^([a-zA-Z][).]\s.*?)$/gm;
95544
+ const kCommonmarkReferenceLinkPattern = /\[([^\]]*)\]: (?!http)(.*)/g;
95545
+ const preRenderText = (txt) => {
95546
+ if (!txt) return txt;
95547
+ txt = txt.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, "");
95548
+ return txt.replaceAll(
95549
+ kLetterListPattern,
95550
+ "<p class='markdown-ordered-list-item'>$1</p>"
95551
+ );
95552
+ };
95553
+ const protectMarkdown = (txt) => {
95554
+ if (!txt) return txt;
95555
+ return txt.replaceAll(
95556
+ kCommonmarkReferenceLinkPattern,
95557
+ "(open:767A125E)$1(close:767A125E) $2 "
95558
+ );
95559
+ };
95560
+ const unprotectMarkdown = (txt) => {
95561
+ if (!txt) return txt;
95562
+ txt = txt.replaceAll("(open:767A125E)", "[");
95563
+ txt = txt.replaceAll("(close:767A125E)", "]");
95564
+ return txt;
95565
+ };
95566
+ function unescapeSupHtmlEntities(str2) {
95567
+ if (!str2) {
95568
+ return str2;
95569
+ }
95570
+ return str2.replace(/&lt;sup&gt;/g, "<sup>").replace(/&lt;\/sup&gt;/g, "</sup>");
95571
+ }
95572
+ function unescapeCodeHtmlEntities(str2) {
95573
+ if (!str2) return str2;
95574
+ const htmlEntities = {
95575
+ "&lt;": "<",
95576
+ "&gt;": ">",
95577
+ "&amp;": "&",
95578
+ "&#x5C;": "\\",
95579
+ "&quot;": '"'
95580
+ };
95581
+ return str2.replace(
95582
+ /(<code[^>]*>)([\s\S]*?)(<\/code>)/gi,
95583
+ (_match, starttag, content2, endtag) => {
95584
+ return starttag + content2.replace(
95585
+ /&(?:amp|lt|gt|quot|#39|#x2F|#x5C|#96);/g,
95586
+ (entity2) => htmlEntities[entity2] || entity2
95587
+ ) + endtag;
95588
+ }
95589
+ );
95590
+ }
95424
95591
  const MarkdownDivComponent = forwardRef(
95425
95592
  ({ markdown, omitMedia, omitMath, style: style2, className: className2 }, ref) => {
95426
- const optionsKey = getOptionsKey(omitMedia, omitMath);
95593
+ const optionsKey = `${omitMedia ? "1" : "0"}:${omitMath ? "1" : "0"}`;
95427
95594
  const cacheKey = `${markdown}:${optionsKey}`;
95428
95595
  const cachedHtml = renderCache.get(cacheKey);
95596
+ const sanitizeMarkdown = (md) => {
95597
+ const escapedBr = md.replace(/\n/g, "<br/>");
95598
+ return escapeHtmlCharacters(escapedBr);
95599
+ };
95429
95600
  const [renderedHtml, setRenderedHtml] = useState(() => {
95430
95601
  if (cachedHtml) {
95431
95602
  return cachedHtml;
95432
95603
  }
95433
- return markdown.replace(/\n/g, "<br/>");
95604
+ return sanitizeMarkdown(markdown);
95434
95605
  });
95435
95606
  useEffect(() => {
95436
95607
  if (cachedHtml) {
@@ -95441,7 +95612,7 @@ const MarkdownDivComponent = forwardRef(
95441
95612
  }
95442
95613
  return;
95443
95614
  }
95444
- setRenderedHtml(markdown.replace(/\n/g, "<br/>"));
95615
+ setRenderedHtml(sanitizeMarkdown(markdown));
95445
95616
  const { promise, cancel } = renderQueue.enqueue(async () => {
95446
95617
  const protectedContent = protectBackslashesInLatex(markdown);
95447
95618
  const escaped = escapeHtmlCharacters(protectedContent);
@@ -95493,22 +95664,6 @@ const MarkdownDivComponent = forwardRef(
95493
95664
  const MarkdownDiv = memo(MarkdownDivComponent);
95494
95665
  const renderCache = /* @__PURE__ */ new Map();
95495
95666
  const MAX_CACHE_SIZE = 500;
95496
- const mdInstanceCache = {};
95497
- const getOptionsKey = (omitMedia, omitMath) => `${omitMedia ? "1" : "0"}:${omitMath ? "1" : "0"}`;
95498
- const getMarkdownInstance = (omitMedia, omitMath) => {
95499
- const key2 = getOptionsKey(omitMedia, omitMath);
95500
- if (!mdInstanceCache[key2]) {
95501
- const md = new MarkdownIt({ breaks: true, html: true });
95502
- if (!omitMath) {
95503
- md.use(markdownitMathjax3);
95504
- }
95505
- if (omitMedia) {
95506
- md.disable(["image"]);
95507
- }
95508
- mdInstanceCache[key2] = md;
95509
- }
95510
- return mdInstanceCache[key2];
95511
- };
95512
95667
  class MarkdownRenderQueue {
95513
95668
  queue = [];
95514
95669
  activeCount = 0;
@@ -95575,116 +95730,6 @@ class MarkdownRenderQueue {
95575
95730
  }
95576
95731
  }
95577
95732
  const renderQueue = new MarkdownRenderQueue(10);
95578
- const kLetterListPattern = /^([a-zA-Z][).]\s.*?)$/gm;
95579
- const kCommonmarkReferenceLinkPattern = /\[([^\]]*)\]: (?!http)(.*)/g;
95580
- const protectBackslashesInLatex = (content2) => {
95581
- if (!content2) return content2;
95582
- try {
95583
- const inlineRegex = /\$(.*?)\$/g;
95584
- const blockRegex = /\$\$([\s\S]*?)\$\$/g;
95585
- let result2 = content2.replace(inlineRegex, (_match, latex) => {
95586
- const protectedTex = latex.replace(/\\/g, "___LATEX_BACKSLASH___").replace(/</g, "___LATEX_LT___").replace(/>/g, "___LATEX_GT___").replace(/&/g, "___LATEX_AMP___").replace(/'/g, "___LATEX_APOS___").replace(/"/g, "___LATEX_QUOT___");
95587
- return `$${protectedTex}$`;
95588
- });
95589
- result2 = result2.replace(blockRegex, (_match, latex) => {
95590
- const protectedTex = latex.replace(/\\/g, "___LATEX_BACKSLASH___").replace(/</g, "___LATEX_LT___").replace(/>/g, "___LATEX_GT___").replace(/&/g, "___LATEX_AMP___").replace(/'/g, "___LATEX_APOS___").replace(/"/g, "___LATEX_QUOT___");
95591
- return `$$${protectedTex}$$`;
95592
- });
95593
- return result2;
95594
- } catch (error2) {
95595
- console.error("Error protecting LaTeX content:", error2);
95596
- return content2;
95597
- }
95598
- };
95599
- const restoreBackslashesForLatex = (content2) => {
95600
- if (!content2) {
95601
- return content2;
95602
- }
95603
- try {
95604
- let result2 = content2.replace(/___LATEX_BACKSLASH___/g, "\\").replace(/___LATEX_LT___/g, "<").replace(/___LATEX_GT___/g, ">").replace(/___LATEX_AMP___/g, "&").replace(/___LATEX_APOS___/g, "'").replace(/___LATEX_QUOT___/g, '"');
95605
- result2 = fixDotsNotation(result2);
95606
- return result2;
95607
- } catch (error2) {
95608
- console.error("Error restoring LaTeX content:", error2);
95609
- return content2;
95610
- }
95611
- };
95612
- const fixDotsNotation = (content2) => {
95613
- if (!content2) return content2;
95614
- try {
95615
- let result2 = content2.replace(/(\$[^$]*?)\\dots([^$]*?\$)/g, "$1\\ldots$2");
95616
- result2 = result2.replace(/(\$\$[^$]*?)\\dots([^$]*?\$\$)/g, "$1\\ldots$2");
95617
- return result2;
95618
- } catch (error2) {
95619
- console.error("Error fixing dots notation:", error2);
95620
- return content2;
95621
- }
95622
- };
95623
- const escapeHtmlCharacters = (content2) => {
95624
- if (!content2) return content2;
95625
- return content2.replace(/[<>&'"]/g, (c2) => {
95626
- switch (c2) {
95627
- case "<":
95628
- return "&lt;";
95629
- case ">":
95630
- return "&gt;";
95631
- case "&":
95632
- return "&amp;";
95633
- case "'":
95634
- return "&apos;";
95635
- case '"':
95636
- return "&quot;";
95637
- default:
95638
- throw new Error("Matched a value that isn't replaceable");
95639
- }
95640
- });
95641
- };
95642
- const preRenderText = (txt) => {
95643
- if (!txt) return txt;
95644
- txt = txt.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, "");
95645
- return txt.replaceAll(
95646
- kLetterListPattern,
95647
- "<p class='markdown-ordered-list-item'>$1</p>"
95648
- );
95649
- };
95650
- const protectMarkdown = (txt) => {
95651
- if (!txt) return txt;
95652
- return txt.replaceAll(
95653
- kCommonmarkReferenceLinkPattern,
95654
- "(open:767A125E)$1(close:767A125E) $2 "
95655
- );
95656
- };
95657
- const unprotectMarkdown = (txt) => {
95658
- if (!txt) return txt;
95659
- txt = txt.replaceAll("(open:767A125E)", "[");
95660
- txt = txt.replaceAll("(close:767A125E)", "]");
95661
- return txt;
95662
- };
95663
- function unescapeSupHtmlEntities(str2) {
95664
- if (!str2) {
95665
- return str2;
95666
- }
95667
- return str2.replace(/&lt;sup&gt;/g, "<sup>").replace(/&lt;\/sup&gt;/g, "</sup>");
95668
- }
95669
- function unescapeCodeHtmlEntities(str2) {
95670
- if (!str2) return str2;
95671
- const htmlEntities = {
95672
- "&lt;": "<",
95673
- "&gt;": ">",
95674
- "&amp;": "&",
95675
- "&#x5C;": "\\",
95676
- "&quot;": '"'
95677
- };
95678
- return str2.replace(
95679
- /(<code[^>]*>)([\s\S]*?)(<\/code>)/gi,
95680
- (_match, starttag, content2, endtag) => {
95681
- return starttag + content2.replace(
95682
- /&(?:amp|lt|gt|quot|#39|#x2F|#x5C|#96);/g,
95683
- (entity2) => htmlEntities[entity2] || entity2
95684
- ) + endtag;
95685
- }
95686
- );
95687
- }
95688
95733
  const content$3 = "_content_13ihw_1";
95689
95734
  const styles$1A = {
95690
95735
  content: content$3
@@ -96086,6 +96131,13 @@ function clearLargeEventsArray(data) {
96086
96131
  result2.set(after, offset2);
96087
96132
  return result2;
96088
96133
  }
96134
+ const fetchRange = async (url, start2, end2) => {
96135
+ const response = await fetch(url, {
96136
+ headers: { Range: `bytes=${start2}-${end2}` }
96137
+ });
96138
+ const arrayBuffer = await response.arrayBuffer();
96139
+ return new Uint8Array(arrayBuffer);
96140
+ };
96089
96141
  class AsyncQueue {
96090
96142
  constructor(concurrentLimit = 6) {
96091
96143
  this.concurrentLimit = concurrentLimit;
@@ -97490,8 +97542,50 @@ class FileSizeLimitError extends Error {
97490
97542
  Object.setPrototypeOf(this, FileSizeLimitError.prototype);
97491
97543
  }
97492
97544
  }
97493
- const openRemoteZipFile = async (url, fetchContentLength = fetchSize, fetchBytes = fetchRange) => {
97494
- const contentLength = await fetchContentLength(url);
97545
+ const PARALLEL_CHUNK_THRESHOLD = 8 * 1024 * 1024;
97546
+ const PARALLEL_CHUNK_SIZE = 8 * 1024 * 1024;
97547
+ const MAX_PARALLEL_CHUNKS = 10;
97548
+ const fetchBytesParallel = async (fetchFn, url, start2, end2, onProgress) => {
97549
+ const totalSize = end2 - start2 + 1;
97550
+ if (totalSize <= PARALLEL_CHUNK_THRESHOLD) {
97551
+ return fetchFn(url, start2, end2);
97552
+ }
97553
+ const chunks = [];
97554
+ let offset2 = start2;
97555
+ while (offset2 <= end2) {
97556
+ const chunkEnd = Math.min(offset2 + PARALLEL_CHUNK_SIZE - 1, end2);
97557
+ chunks.push({ start: offset2, end: chunkEnd, index: chunks.length });
97558
+ offset2 = chunkEnd + 1;
97559
+ }
97560
+ const concurrency = Math.min(chunks.length, MAX_PARALLEL_CHUNKS);
97561
+ const results = new Array(chunks.length);
97562
+ let nextChunk = 0;
97563
+ let bytesLoaded = 0;
97564
+ if (onProgress) {
97565
+ onProgress(0, totalSize);
97566
+ }
97567
+ const worker = async () => {
97568
+ while (nextChunk < chunks.length) {
97569
+ const idx = nextChunk++;
97570
+ const chunk = chunks[idx];
97571
+ results[idx] = await fetchFn(url, chunk.start, chunk.end);
97572
+ if (onProgress) {
97573
+ bytesLoaded += results[idx].length;
97574
+ onProgress(bytesLoaded, totalSize);
97575
+ }
97576
+ }
97577
+ };
97578
+ await Promise.all(Array.from({ length: concurrency }, () => worker()));
97579
+ const combined = new Uint8Array(totalSize);
97580
+ let pos2 = 0;
97581
+ for (const chunk of results) {
97582
+ combined.set(chunk, pos2);
97583
+ pos2 += chunk.length;
97584
+ }
97585
+ return combined;
97586
+ };
97587
+ const openRemoteZipFile = async (url, contentLength, fetchBytes = fetchRange) => {
97588
+ contentLength = contentLength ?? await fetchSize(url);
97495
97589
  const eocdrBuffer = await fetchBytes(
97496
97590
  url,
97497
97591
  contentLength - 22,
@@ -97533,7 +97627,8 @@ const openRemoteZipFile = async (url, fetchContentLength = fetchSize, fetchBytes
97533
97627
  centralDirSize = Number(zip64EOCDView.getBigUint64(40, true));
97534
97628
  centralDirOffset = Number(zip64EOCDView.getBigUint64(48, true));
97535
97629
  }
97536
- const centralDirBuffer = await fetchBytes(
97630
+ const centralDirBuffer = await fetchBytesParallel(
97631
+ fetchBytes,
97537
97632
  url,
97538
97633
  centralDirOffset,
97539
97634
  centralDirOffset + centralDirSize - 1
@@ -97541,28 +97636,40 @@ const openRemoteZipFile = async (url, fetchContentLength = fetchSize, fetchBytes
97541
97636
  const centralDirectory = parseCentralDirectory(centralDirBuffer);
97542
97637
  return {
97543
97638
  centralDirectory,
97544
- readFile: async (file, maxBytes) => {
97639
+ readFile: async (file, maxBytes, onProgress) => {
97545
97640
  const entry = centralDirectory.get(file);
97546
97641
  if (!entry) {
97547
97642
  throw new Error(`File not found: ${file}`);
97548
97643
  }
97549
97644
  const headerSize = 30;
97550
- const headerData = await fetchBytes(
97551
- url,
97552
- entry.fileOffset,
97553
- entry.fileOffset + headerSize - 1
97554
- );
97555
- const filenameLength = headerData[26] + (headerData[27] << 8);
97556
- const extraFieldLength = headerData[28] + (headerData[29] << 8);
97557
- const totalSizeToFetch = headerSize + filenameLength + extraFieldLength + entry.compressedSize;
97558
- if (maxBytes && totalSizeToFetch > maxBytes) {
97645
+ const extraFieldPadding = 256;
97646
+ const estimatedSize = headerSize + entry.filenameLength + extraFieldPadding + entry.compressedSize;
97647
+ if (maxBytes && headerSize + entry.filenameLength + entry.compressedSize > maxBytes) {
97559
97648
  throw new FileSizeLimitError(file, maxBytes);
97560
97649
  }
97561
- const fileData = await fetchBytes(
97650
+ let fileData = await fetchBytesParallel(
97651
+ fetchBytes,
97562
97652
  url,
97563
97653
  entry.fileOffset,
97564
- entry.fileOffset + totalSizeToFetch - 1
97654
+ entry.fileOffset + estimatedSize - 1,
97655
+ onProgress
97565
97656
  );
97657
+ if (fileData.length < headerSize) {
97658
+ throw new Error(`File entry header is truncated for ${file}`);
97659
+ }
97660
+ const actualExtraFieldLength = fileData[28] + (fileData[29] << 8);
97661
+ const actualTotal = headerSize + entry.filenameLength + actualExtraFieldLength + entry.compressedSize;
97662
+ if (maxBytes && actualTotal > maxBytes) {
97663
+ throw new FileSizeLimitError(file, maxBytes);
97664
+ }
97665
+ if (actualTotal > estimatedSize) {
97666
+ fileData = await fetchBytesParallel(
97667
+ fetchBytes,
97668
+ url,
97669
+ entry.fileOffset,
97670
+ entry.fileOffset + actualTotal - 1
97671
+ );
97672
+ }
97566
97673
  const zipFileEntry = await parseZipFileEntry(file, fileData);
97567
97674
  return decompressData(
97568
97675
  zipFileEntry.data,
@@ -97597,13 +97704,6 @@ const fetchSize = async (url) => {
97597
97704
  }
97598
97705
  throw new Error(`Could not determine content length for ${url}`);
97599
97706
  };
97600
- const fetchRange = async (url, start2, end2) => {
97601
- const response = await fetch(`${url}`, {
97602
- headers: { Range: `bytes=${start2}-${end2}` }
97603
- });
97604
- const arrayBuffer = await response.arrayBuffer();
97605
- return new Uint8Array(arrayBuffer);
97606
- };
97607
97707
  const parseZipFileEntry = async (file, rawData) => {
97608
97708
  const view = new DataView(rawData.buffer);
97609
97709
  let offset2 = 0;
@@ -97715,7 +97815,8 @@ const parseCentralDirectory = (buffer2) => {
97715
97815
  compressionMethod: view.getUint16(offset2 + 10, true),
97716
97816
  compressedSize,
97717
97817
  uncompressedSize,
97718
- fileOffset
97818
+ fileOffset,
97819
+ filenameLength
97719
97820
  };
97720
97821
  entries.set(filename2, entry);
97721
97822
  offset2 += kFileHeaderSize + filenameLength + extraFieldLength + fileCommentLength;
@@ -97733,15 +97834,23 @@ class SampleNotFoundError extends Error {
97733
97834
  }
97734
97835
  const openRemoteLogFile = async (api2, url, concurrency) => {
97735
97836
  const queue = new AsyncQueue(concurrency);
97837
+ const logInfo = await api2.get_log_info(url);
97838
+ const directUrl = logInfo.direct_url;
97839
+ const fetchBytes = async (_url, start2, end2) => {
97840
+ if (directUrl) {
97841
+ try {
97842
+ return await fetchRange(directUrl, start2, end2);
97843
+ } catch (e) {
97844
+ console.warn("Direct URL fetch failed, falling back to proxy", e);
97845
+ }
97846
+ }
97847
+ return api2.get_log_bytes(url, start2, end2);
97848
+ };
97736
97849
  let remoteZipFile = void 0;
97737
97850
  let retryCount = 0;
97738
97851
  while (!remoteZipFile && retryCount < OPEN_RETRY_LIMIT) {
97739
97852
  try {
97740
- remoteZipFile = await openRemoteZipFile(
97741
- url,
97742
- api2.get_log_size,
97743
- api2.get_log_bytes
97744
- );
97853
+ remoteZipFile = await openRemoteZipFile(url, logInfo.size, fetchBytes);
97745
97854
  } catch {
97746
97855
  retryCount++;
97747
97856
  console.warn(
@@ -97757,20 +97866,13 @@ const openRemoteLogFile = async (api2, url, concurrency) => {
97757
97866
  `Failed to open remote log file at ${url} after ${OPEN_RETRY_LIMIT} attempts.`
97758
97867
  );
97759
97868
  }
97760
- const readJSONFile = async (file, maxBytes, preprocessor2) => {
97869
+ const readJSONFile = async (file, maxBytes, preprocessor2, onProgress) => {
97761
97870
  try {
97762
- let data = await remoteZipFile.readFile(file, maxBytes);
97871
+ let data = await remoteZipFile.readFile(file, maxBytes, onProgress);
97763
97872
  if (preprocessor2) {
97764
97873
  data = preprocessor2.preprocess(data);
97765
97874
  }
97766
- const textDecoder = new TextDecoder("utf-8");
97767
- const jsonString = textDecoder.decode(data);
97768
- if (data.length > 0 && jsonString.length === 0) {
97769
- throw new Error(
97770
- `Failed to decode ${file} (${(data.length / 1024 / 1024).toFixed(0)}MB). The file may be corrupted or contain invalid UTF-8 sequences.`
97771
- );
97772
- }
97773
- return asyncJsonParse(jsonString);
97875
+ return asyncJsonParseBytes(data);
97774
97876
  } catch (error2) {
97775
97877
  if (error2 instanceof FileSizeLimitError) {
97776
97878
  throw error2;
@@ -97796,7 +97898,7 @@ const openRemoteLogFile = async (api2, url, concurrency) => {
97796
97898
  };
97797
97899
  });
97798
97900
  };
97799
- const readSample = async (sampleId, epoch) => {
97901
+ const readSample = async (sampleId, epoch, onProgress) => {
97800
97902
  const sampleFile = `samples/${sampleId}_epoch_${epoch}.json`;
97801
97903
  if (!remoteZipFile.centralDirectory.has(sampleFile)) {
97802
97904
  throw new SampleNotFoundError(
@@ -97813,7 +97915,8 @@ const openRemoteLogFile = async (api2, url, concurrency) => {
97813
97915
  return await readJSONFile(
97814
97916
  sampleFile,
97815
97917
  void 0,
97816
- eventsPreprocessor
97918
+ eventsPreprocessor,
97919
+ onProgress
97817
97920
  );
97818
97921
  };
97819
97922
  const readHeader = async () => {
@@ -97982,7 +98085,7 @@ const clientApi = (api2, log_file, debug2 = false) => {
97982
98085
  let pending_log_promise = null;
97983
98086
  const get_log_details = async (log_file2) => {
97984
98087
  if (isEvalFile(log_file2)) {
97985
- const remoteLogFile = await remoteEvalFile(log_file2);
98088
+ const remoteLogFile = await remoteEvalFile(log_file2, true);
97986
98089
  if (remoteLogFile) {
97987
98090
  return await remoteLogFile.readLogSummary();
97988
98091
  } else {
@@ -98017,7 +98120,7 @@ const clientApi = (api2, log_file, debug2 = false) => {
98017
98120
  };
98018
98121
  }
98019
98122
  };
98020
- const get_log_sample = async (log_file2, id, epoch) => {
98123
+ const get_log_sample = async (log_file2, id, epoch, onProgress) => {
98021
98124
  if (isEvalFile(log_file2)) {
98022
98125
  let handleError2 = function(error2) {
98023
98126
  if (error2 instanceof FileSizeLimitError) {
@@ -98030,7 +98133,7 @@ const clientApi = (api2, log_file, debug2 = false) => {
98030
98133
  if (!remoteLogFile) {
98031
98134
  throw new Error(`Unable to read remote eval file ${log_file2}`);
98032
98135
  }
98033
- return await remoteLogFile.readSample(String(id), epoch);
98136
+ return await remoteLogFile.readSample(String(id), epoch, onProgress);
98034
98137
  }
98035
98138
  try {
98036
98139
  return await fetchSample(true);
@@ -98435,8 +98538,9 @@ function staticHttpApiForLog(logInfo) {
98435
98538
  throw new Error(`"Unable to load eval log ${log_file}`);
98436
98539
  }
98437
98540
  },
98438
- get_log_size: async (log_file) => {
98439
- return await fetchSize(log_file);
98541
+ get_log_info: async (log_file) => {
98542
+ const size = await fetchSize(log_file);
98543
+ return { size };
98440
98544
  },
98441
98545
  get_log_bytes: async (log_file, start2, end2) => {
98442
98546
  return await fetchRange(log_file, start2, end2);
@@ -98708,10 +98812,10 @@ function viewServerApi(options2 = {}) {
98708
98812
  );
98709
98813
  return result2;
98710
98814
  };
98711
- const get_log_size2 = async (file) => {
98815
+ const get_log_info2 = async (file) => {
98712
98816
  const result2 = await requestApi.fetchString(
98713
98817
  "GET",
98714
- `/log-size/${encodeURIComponent(file)}`
98818
+ `/log-info/${encodeURIComponent(file)}`
98715
98819
  );
98716
98820
  return result2.parsed;
98717
98821
  };
@@ -98866,7 +98970,7 @@ function viewServerApi(options2 = {}) {
98866
98970
  get_eval_set: get_eval_set2,
98867
98971
  get_flow: get_flow2,
98868
98972
  get_log_contents: get_log_contents2,
98869
- get_log_size: get_log_size2,
98973
+ get_log_info: get_log_info2,
98870
98974
  get_log_bytes: get_log_bytes2,
98871
98975
  get_log_summaries: get_log_summaries2,
98872
98976
  log_message: log_message2,
@@ -98882,12 +98986,13 @@ const kMethodEvalLogDir = "eval_log_dir";
98882
98986
  const kMethodEvalLogs = "eval_logs";
98883
98987
  const kMethodEvalLogFiles = "eval_log_files";
98884
98988
  const kMethodEvalLog = "eval_log";
98885
- const kMethodEvalLogSize = "eval_log_size";
98989
+ const kMethodEvalLogInfo = "eval_log_info";
98886
98990
  const kMethodEvalLogBytes = "eval_log_bytes";
98887
98991
  const kMethodEvalLogHeaders = "eval_log_headers";
98888
98992
  const kMethodPendingSamples = "eval_log_pending_samples";
98889
98993
  const kMethodSampleData = "eval_log_sample_data";
98890
98994
  const kMethodLogMessage = "log_message";
98995
+ const kJsonRpcMethodNotFound = -32601;
98891
98996
  const kJsonRpcVersion = "2.0";
98892
98997
  function webViewJsonRpcClient(vscode) {
98893
98998
  const target2 = {
@@ -99020,8 +99125,16 @@ async function get_log_contents(log_file, headerOnly, capabilities) {
99020
99125
  throw new Error(`Unable to load eval log ${log_file}.`);
99021
99126
  }
99022
99127
  }
99023
- async function get_log_size(log_file) {
99024
- return await vscodeClient(kMethodEvalLogSize, [log_file]);
99128
+ async function get_log_info(log_file) {
99129
+ try {
99130
+ return await vscodeClient(kMethodEvalLogInfo, [log_file]);
99131
+ } catch (e) {
99132
+ if (e?.code === kJsonRpcMethodNotFound) {
99133
+ const size = await vscodeClient("eval_log_size", [log_file]);
99134
+ return { size };
99135
+ }
99136
+ throw e;
99137
+ }
99025
99138
  }
99026
99139
  async function get_log_bytes(log_file, start2, end2) {
99027
99140
  return await vscodeClient(kMethodEvalLogBytes, [log_file, start2, end2]);
@@ -99104,7 +99217,7 @@ const api$1 = {
99104
99217
  get_eval_set,
99105
99218
  get_flow,
99106
99219
  get_log_contents,
99107
- get_log_size,
99220
+ get_log_info,
99108
99221
  get_log_bytes,
99109
99222
  get_log_summaries,
99110
99223
  log_message,
@@ -99287,11 +99400,13 @@ ${citation.url}` : citation.url,
99287
99400
  }
99288
99401
  );
99289
99402
  const OtherCitation = ({ children: children2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: children2 });
99290
- const contentImage = "_contentImage_srbm0_1";
99291
- const reasoning = "_reasoning_srbm0_6";
99403
+ const contentImage = "_contentImage_16eyd_1";
99404
+ const reasoning = "_reasoning_16eyd_6";
99405
+ const breakable = "_breakable_16eyd_21";
99292
99406
  const styles$1r = {
99293
99407
  contentImage,
99294
- reasoning
99408
+ reasoning,
99409
+ breakable
99295
99410
  };
99296
99411
  const mcpToolUse = "_mcpToolUse_1792k_1";
99297
99412
  const title$2 = "_title_1792k_9";
@@ -99607,7 +99722,10 @@ const messageRenderers = {
99607
99722
  RenderedText,
99608
99723
  {
99609
99724
  markdown: purgeInternalContainers(c2.text) || "",
99610
- className: isLast ? "no-last-para-padding" : ""
99725
+ className: clsx(
99726
+ isLast ? "no-last-para-padding" : "",
99727
+ styles$1r.breakable
99728
+ )
99611
99729
  }
99612
99730
  ),
99613
99731
  c2.citations ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageCitations, { citations: c2.citations }) : void 0
@@ -99905,7 +100023,7 @@ const extractInput = (args2, inputDescriptor) => {
99905
100023
  };
99906
100024
  }
99907
100025
  };
99908
- const toolCallView = "_toolCallView_l6wae_1";
100026
+ const toolCallView = "_toolCallView_10z2l_1";
99909
100027
  const styles$1o = {
99910
100028
  toolCallView
99911
100029
  };
@@ -104163,6 +104281,7 @@ const useSampleData = () => {
104163
104281
  const runningEvents = useStore(
104164
104282
  (state) => state.sample.runningEvents
104165
104283
  );
104284
+ const downloadProgress = useStore((state) => state.sample.downloadProgress);
104166
104285
  return useMemo(() => {
104167
104286
  return {
104168
104287
  selectedSampleIdentifier,
@@ -104171,7 +104290,8 @@ const useSampleData = () => {
104171
104290
  error: sampleError,
104172
104291
  getSelectedSample,
104173
104292
  eventsCleared,
104174
- running: runningEvents
104293
+ running: runningEvents,
104294
+ downloadProgress
104175
104295
  };
104176
104296
  }, [
104177
104297
  sampleStatus2,
@@ -104180,7 +104300,8 @@ const useSampleData = () => {
104180
104300
  selectedSampleIdentifier,
104181
104301
  sampleNeedsReload,
104182
104302
  eventsCleared,
104183
- runningEvents
104303
+ runningEvents,
104304
+ downloadProgress
104184
104305
  ]);
104185
104306
  };
104186
104307
  const useSampleInvalidation = () => {
@@ -104612,25 +104733,33 @@ const useFlowServerData = (dir) => {
104612
104733
  }
104613
104734
  }, [dir, flowDir, api2, updateFlowData]);
104614
104735
  };
104615
- const wrapper$3 = "_wrapper_1tajk_1";
104616
- const container$j = "_container_1tajk_12";
104617
- const animate = "_animate_1tajk_21";
104736
+ const wrapper$3 = "_wrapper_44dmw_1";
104737
+ const container$j = "_container_44dmw_12";
104738
+ const animate = "_animate_44dmw_21";
104739
+ const determinate = "_determinate_44dmw_31";
104618
104740
  const styles$1f = {
104619
104741
  wrapper: wrapper$3,
104620
104742
  container: container$j,
104621
- animate
104743
+ animate,
104744
+ determinate
104622
104745
  };
104623
- const ActivityBar = ({ animating }) => {
104746
+ const ActivityBar = ({ animating, progress: progress2 }) => {
104624
104747
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1f.wrapper), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
104625
104748
  "div",
104626
104749
  {
104627
104750
  className: clsx(styles$1f.container),
104628
104751
  role: "progressbar",
104629
104752
  "aria-label": "Progress bar",
104630
- "aria-valuenow": 25,
104753
+ "aria-valuenow": progress2 !== void 0 ? Math.round(progress2 * 100) : void 0,
104631
104754
  "aria-valuemin": 0,
104632
104755
  "aria-valuemax": 100,
104633
- children: animating && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$1f.animate })
104756
+ children: animating && (progress2 !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
104757
+ "div",
104758
+ {
104759
+ className: styles$1f.determinate,
104760
+ style: { width: `${progress2 * 100}%` }
104761
+ }
104762
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$1f.animate }))
104634
104763
  }
104635
104764
  ) });
104636
104765
  };
@@ -106610,7 +106739,7 @@ const ViewerOptionsPopover = ({
106610
106739
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.fullWidth, styles$1d.fullWidthPadded), children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1d.logDir, children: logDir2 }) }),
106611
106740
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.spacer) }),
106612
106741
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Version" }),
106613
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.199-0-gffdb82c59" }),
106742
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.200-0-g01cd5b482" }),
106614
106743
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Schema" }),
106615
106744
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: DB_VERSION }),
106616
106745
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.spacer) }),
@@ -165171,7 +165300,20 @@ function useLoadSample() {
165171
165300
  if (completed !== false) {
165172
165301
  log$1.debug(`LOADING COMPLETED SAMPLE: ${id}-${epoch}`);
165173
165302
  getSamplePolling().stopPolling();
165174
- const sample2 = await api2?.get_log_sample(logFile, id, epoch);
165303
+ sampleActions.setDownloadProgress(void 0);
165304
+ const onProgress = (bytesLoaded, bytesTotal) => {
165305
+ sampleActions.setDownloadProgress({
165306
+ complete: bytesLoaded,
165307
+ total: bytesTotal
165308
+ });
165309
+ };
165310
+ const sample2 = await api2?.get_log_sample(
165311
+ logFile,
165312
+ id,
165313
+ epoch,
165314
+ onProgress
165315
+ );
165316
+ sampleActions.setDownloadProgress(void 0);
165175
165317
  log$1.debug(`LOADED COMPLETED SAMPLE: ${id}-${epoch}`);
165176
165318
  if (thisGeneration !== loadGeneration) {
165177
165319
  log$1.debug(`Discarding stale sample response: ${id}-${epoch}`);
@@ -165197,6 +165339,7 @@ function useLoadSample() {
165197
165339
  getSamplePolling().stopPolling();
165198
165340
  }
165199
165341
  } catch (e) {
165342
+ sampleActions.setDownloadProgress(void 0);
165200
165343
  sampleActions.setSampleError(e);
165201
165344
  sampleActions.setSampleStatus("error");
165202
165345
  }
@@ -165860,6 +166003,7 @@ async function findExtendedInDOM(searchTerm, back, lastFoundItem, extendedFindTe
165860
166003
  );
165861
166004
  if (foundInVirtual) {
165862
166005
  extendedSearchSucceeded = true;
166006
+ await waitForTextInDOM(searchTerm);
165863
166007
  continue;
165864
166008
  }
165865
166009
  }
@@ -165894,6 +166038,7 @@ async function findExtendedInDOM(searchTerm, back, lastFoundItem, extendedFindTe
165894
166038
  );
165895
166039
  if (foundInVirtual) {
165896
166040
  extendedSearchSucceeded = true;
166041
+ await waitForTextInDOM(searchTerm);
165897
166042
  continue;
165898
166043
  }
165899
166044
  positionSelectionForWrap(back);
@@ -165954,6 +166099,50 @@ function selectionParentElement(range2) {
165954
166099
  }
165955
166100
  return element;
165956
166101
  }
166102
+ function waitForTextInDOM(searchTerm, timeoutMs = 2e3) {
166103
+ const lowerTerm = searchTerm.toLowerCase();
166104
+ const isTextInSearchableDOM = () => {
166105
+ const walker = document.createTreeWalker(
166106
+ document.body,
166107
+ NodeFilter.SHOW_TEXT,
166108
+ {
166109
+ acceptNode: (node2) => {
166110
+ let el2 = node2.parentElement;
166111
+ while (el2) {
166112
+ if (el2.hasAttribute("data-unsearchable")) {
166113
+ return NodeFilter.FILTER_REJECT;
166114
+ }
166115
+ el2 = el2.parentElement;
166116
+ }
166117
+ return NodeFilter.FILTER_ACCEPT;
166118
+ }
166119
+ }
166120
+ );
166121
+ while (walker.nextNode()) {
166122
+ if (walker.currentNode.textContent?.toLowerCase().includes(lowerTerm)) {
166123
+ return true;
166124
+ }
166125
+ }
166126
+ return false;
166127
+ };
166128
+ return new Promise((resolve) => {
166129
+ const interval = 50;
166130
+ let elapsed = 0;
166131
+ const check2 = () => {
166132
+ if (isTextInSearchableDOM()) {
166133
+ resolve(true);
166134
+ return;
166135
+ }
166136
+ elapsed += interval;
166137
+ if (elapsed >= timeoutMs) {
166138
+ resolve(false);
166139
+ return;
166140
+ }
166141
+ setTimeout(check2, interval);
166142
+ };
166143
+ check2();
166144
+ });
166145
+ }
165957
166146
  const tabs$1 = "_tabs_1rv6h_1";
165958
166147
  const tabContents = "_tabContents_1rv6h_5";
165959
166148
  const scrollable = "_scrollable_1rv6h_11";
@@ -166590,6 +166779,7 @@ const LiveVirtualList = ({
166590
166779
  }, 100);
166591
166780
  }
166592
166781
  }, [live, followOutput, prevLive, scrollRef, setFollowOutput]);
166782
+ const isNearBottomRef = useRef(false);
166593
166783
  const handleScroll = useRafThrottle(() => {
166594
166784
  if (isAutoScrollingRef.current) return;
166595
166785
  if (!live) return;
@@ -166603,10 +166793,25 @@ const LiveVirtualList = ({
166603
166793
  }
166604
166794
  }
166605
166795
  }, [setFollowOutput, followOutput, live]);
166796
+ const handleScrollSync = useCallback(() => {
166797
+ if (isAutoScrollingRef.current) return;
166798
+ if (!scrollRef?.current) return;
166799
+ const parent = scrollRef.current;
166800
+ isNearBottomRef.current = parent.scrollHeight - parent.scrollTop <= parent.clientHeight + 50;
166801
+ }, [scrollRef]);
166606
166802
  const heightChanged = useCallback(
166607
166803
  (height) => {
166608
166804
  requestAnimationFrame(() => {
166609
- if (followOutput && live && scrollRef?.current) {
166805
+ if (!scrollRef?.current) return;
166806
+ if (followOutput && live) {
166807
+ isAutoScrollingRef.current = true;
166808
+ listHandle.current?.scrollTo({ top: height });
166809
+ requestAnimationFrame(() => {
166810
+ isAutoScrollingRef.current = false;
166811
+ });
166812
+ return;
166813
+ }
166814
+ if (isNearBottomRef.current) {
166610
166815
  isAutoScrollingRef.current = true;
166611
166816
  listHandle.current?.scrollTo({ top: height });
166612
166817
  requestAnimationFrame(() => {
@@ -166743,9 +166948,13 @@ const LiveVirtualList = ({
166743
166948
  const parent = scrollRef?.current;
166744
166949
  if (parent) {
166745
166950
  parent.addEventListener("scroll", handleScroll);
166746
- return () => parent.removeEventListener("scroll", handleScroll);
166951
+ parent.addEventListener("scroll", handleScrollSync);
166952
+ return () => {
166953
+ parent.removeEventListener("scroll", handleScroll);
166954
+ parent.removeEventListener("scroll", handleScrollSync);
166955
+ };
166747
166956
  }
166748
- }, [scrollRef, handleScroll]);
166957
+ }, [scrollRef, handleScroll, handleScrollSync]);
166749
166958
  const hasScrolled = useRef(false);
166750
166959
  useEffect(() => {
166751
166960
  if (initialTopMostItemIndex !== void 0 && listHandle.current) {
@@ -166907,7 +167116,7 @@ const ChatViewVirtualList = memo(
166907
167116
  } else if (event.key === "ArrowDown") {
166908
167117
  if (useVirtuoso) {
166909
167118
  listHandle.current?.scrollToIndex({
166910
- index: Math.min(messages2.length - 5, 0),
167119
+ index: Math.max(messages2.length - 5, 0),
166911
167120
  align: "center"
166912
167121
  });
166913
167122
  setTimeout(() => {
@@ -166926,16 +167135,10 @@ const ChatViewVirtualList = memo(
166926
167135
  }
166927
167136
  }
166928
167137
  };
166929
- const scrollElement = scrollRef?.current;
166930
- if (scrollElement) {
166931
- scrollElement.addEventListener("keydown", handleKeyDown);
166932
- if (!scrollElement.hasAttribute("tabIndex")) {
166933
- scrollElement.setAttribute("tabIndex", "0");
166934
- }
166935
- return () => {
166936
- scrollElement.removeEventListener("keydown", handleKeyDown);
166937
- };
166938
- }
167138
+ document.addEventListener("keydown", handleKeyDown);
167139
+ return () => {
167140
+ document.removeEventListener("keydown", handleKeyDown);
167141
+ };
166939
167142
  }, [scrollRef, messages2, useVirtuoso]);
166940
167143
  if (!useVirtuoso) {
166941
167144
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -168888,12 +169091,12 @@ const TranscriptOutline = ({
168888
169091
  }
168889
169092
  );
168890
169093
  };
168891
- const container$e = "_container_17sux_1";
168892
- const collapsed = "_collapsed_17sux_9";
168893
- const treeContainer = "_treeContainer_17sux_13";
168894
- const listContainer = "_listContainer_17sux_25";
168895
- const outline = "_outline_17sux_29";
168896
- const outlineToggle = "_outlineToggle_17sux_33";
169094
+ const container$e = "_container_n37ko_1";
169095
+ const collapsed = "_collapsed_n37ko_13";
169096
+ const treeContainer = "_treeContainer_n37ko_17";
169097
+ const listContainer = "_listContainer_n37ko_29";
169098
+ const outline = "_outline_n37ko_33";
169099
+ const outlineToggle = "_outlineToggle_n37ko_37";
168897
169100
  const styles$R = {
168898
169101
  container: container$e,
168899
169102
  collapsed,
@@ -180413,17 +180616,11 @@ const TranscriptPanel = memo((props) => {
180413
180616
  }
180414
180617
  }
180415
180618
  };
180416
- const scrollElement = scrollRef.current;
180417
- if (scrollElement) {
180418
- scrollElement.addEventListener("keydown", handleKeyDown);
180419
- if (!scrollElement.hasAttribute("tabIndex")) {
180420
- scrollElement.setAttribute("tabIndex", "0");
180421
- }
180422
- return () => {
180423
- scrollElement.removeEventListener("keydown", handleKeyDown);
180424
- };
180425
- }
180426
- }, [scrollRef, flattenedNodes]);
180619
+ document.addEventListener("keydown", handleKeyDown);
180620
+ return () => {
180621
+ document.removeEventListener("keydown", handleKeyDown);
180622
+ };
180623
+ }, [flattenedNodes]);
180427
180624
  if (sampleStatus2 === "loading" && flattenedNodes.length === 0) {
180428
180625
  return void 0;
180429
180626
  }
@@ -180529,6 +180726,7 @@ const SampleDisplay = ({
180529
180726
  id,
180530
180727
  scrollRef,
180531
180728
  showActivity,
180729
+ progress: progress2,
180532
180730
  focusOnLoad
180533
180731
  }) => {
180534
180732
  const baseId = `sample-display`;
@@ -180760,7 +180958,7 @@ const SampleDisplay = ({
180760
180958
  const sampleDetailNavigation = useSampleDetailNavigation();
180761
180959
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Fragment, { children: [
180762
180960
  selectedSampleSummary ? /* @__PURE__ */ jsxRuntimeExports.jsx(SampleSummaryView, { parent_id: id, sample: selectedSampleSummary }) : void 0,
180763
- /* @__PURE__ */ jsxRuntimeExports.jsx(ActivityBar, { animating: showActivity }),
180961
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ActivityBar, { animating: showActivity, progress: progress2 }),
180764
180962
  hasSampleData && /* @__PURE__ */ jsxRuntimeExports.jsxs(
180765
180963
  TabSet,
180766
180964
  {
@@ -181126,6 +181324,7 @@ const InlineSampleComponent = ({
181126
181324
  className: className2
181127
181325
  }) => {
181128
181326
  const sampleData = useSampleData();
181327
+ const sampleProgress = sampleData.status === "loading" && sampleData.downloadProgress && sampleData.downloadProgress.total > 0 ? sampleData.downloadProgress.complete / sampleData.downloadProgress.total : void 0;
181129
181328
  const scrollRef = useRef(null);
181130
181329
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(className2, styles$w.container), children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$w.scroller), ref: scrollRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx(StickyScrollProvider, { value: scrollRef, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: styles$w.body, children: sampleData.error ? /* @__PURE__ */ jsxRuntimeExports.jsx(
181131
181330
  ErrorPanel,
@@ -181138,6 +181337,7 @@ const InlineSampleComponent = ({
181138
181337
  {
181139
181338
  id: "inline-sample-display",
181140
181339
  showActivity: !!showActivity,
181340
+ progress: sampleProgress,
181141
181341
  scrollRef
181142
181342
  }
181143
181343
  ) }) }) }) });