@meridianlabs/log-viewer 0.3.197 → 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 (42) 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/{utils → app/utils}/print.d.ts +2 -1
  10. package/lib/app/utils/print.d.ts.map +1 -0
  11. package/lib/client/api/client-api.d.ts.map +1 -1
  12. package/lib/client/api/static-http/api-static-http.d.ts.map +1 -1
  13. package/lib/client/api/types.d.ts +7 -2
  14. package/lib/client/api/types.d.ts.map +1 -1
  15. package/lib/client/api/view-server/api-view-server.d.ts.map +1 -1
  16. package/lib/client/api/vscode/api-vscode.d.ts.map +1 -1
  17. package/lib/client/api/vscode/jsonrpc.d.ts +1 -1
  18. package/lib/client/remote/remoteLogFile.d.ts +2 -2
  19. package/lib/client/remote/remoteLogFile.d.ts.map +1 -1
  20. package/lib/client/remote/remoteZipFile.d.ts +7 -6
  21. package/lib/client/remote/remoteZipFile.d.ts.map +1 -1
  22. package/lib/components/ActivityBar.d.ts +1 -0
  23. package/lib/components/ActivityBar.d.ts.map +1 -1
  24. package/lib/components/LiveVirtualList.d.ts.map +1 -1
  25. package/lib/components/MarkdownDiv.d.ts.map +1 -1
  26. package/lib/components/markdownRendering.d.ts +14 -0
  27. package/lib/components/markdownRendering.d.ts.map +1 -0
  28. package/lib/index.js +525 -336
  29. package/lib/index.js.map +1 -1
  30. package/lib/state/hooks.d.ts +1 -0
  31. package/lib/state/hooks.d.ts.map +1 -1
  32. package/lib/state/sampleSlice.d.ts +2 -1
  33. package/lib/state/sampleSlice.d.ts.map +1 -1
  34. package/lib/state/sampleUtils.d.ts.map +1 -1
  35. package/lib/state/useLoadSample.d.ts.map +1 -1
  36. package/lib/styles/index.css +63 -29
  37. package/lib/utils/expandEvents.d.ts +11 -0
  38. package/lib/utils/expandEvents.d.ts.map +1 -0
  39. package/lib/utils/json-worker.d.ts +10 -0
  40. package/lib/utils/json-worker.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/lib/utils/print.d.ts.map +0 -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";
@@ -99584,15 +99699,14 @@ const MessageContent = ({
99584
99699
  };
99585
99700
  const messageRenderers = {
99586
99701
  text: {
99587
- render: (key2, content2, isLast, context) => {
99702
+ render: (key2, content2, isLast, _context) => {
99588
99703
  const c2 = content2;
99589
99704
  const cites = c2.citations ?? [];
99590
99705
  if (!c2.text && !cites.length) {
99591
99706
  return void 0;
99592
99707
  }
99593
99708
  const purgeInternalContainers = (text2) => {
99594
- const isAssistantMessage = context.role === "assistant";
99595
- const internalTags = !isAssistantMessage ? ["internal", "content-internal"] : ["internal", "content-internal", "think"];
99709
+ const internalTags = ["internal", "content-internal"];
99596
99710
  internalTags.forEach((tag) => {
99597
99711
  const regex2 = new RegExp(`<${tag}[^>]*>[\\s\\S]*?<\\/${tag}>`, "gm");
99598
99712
  text2 = text2.replace(regex2, "");
@@ -99608,7 +99722,10 @@ const messageRenderers = {
99608
99722
  RenderedText,
99609
99723
  {
99610
99724
  markdown: purgeInternalContainers(c2.text) || "",
99611
- className: isLast ? "no-last-para-padding" : ""
99725
+ className: clsx(
99726
+ isLast ? "no-last-para-padding" : "",
99727
+ styles$1r.breakable
99728
+ )
99612
99729
  }
99613
99730
  ),
99614
99731
  c2.citations ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageCitations, { citations: c2.citations }) : void 0
@@ -99906,7 +100023,7 @@ const extractInput = (args2, inputDescriptor) => {
99906
100023
  };
99907
100024
  }
99908
100025
  };
99909
- const toolCallView = "_toolCallView_l6wae_1";
100026
+ const toolCallView = "_toolCallView_10z2l_1";
99910
100027
  const styles$1o = {
99911
100028
  toolCallView
99912
100029
  };
@@ -104164,6 +104281,7 @@ const useSampleData = () => {
104164
104281
  const runningEvents = useStore(
104165
104282
  (state) => state.sample.runningEvents
104166
104283
  );
104284
+ const downloadProgress = useStore((state) => state.sample.downloadProgress);
104167
104285
  return useMemo(() => {
104168
104286
  return {
104169
104287
  selectedSampleIdentifier,
@@ -104172,7 +104290,8 @@ const useSampleData = () => {
104172
104290
  error: sampleError,
104173
104291
  getSelectedSample,
104174
104292
  eventsCleared,
104175
- running: runningEvents
104293
+ running: runningEvents,
104294
+ downloadProgress
104176
104295
  };
104177
104296
  }, [
104178
104297
  sampleStatus2,
@@ -104181,7 +104300,8 @@ const useSampleData = () => {
104181
104300
  selectedSampleIdentifier,
104182
104301
  sampleNeedsReload,
104183
104302
  eventsCleared,
104184
- runningEvents
104303
+ runningEvents,
104304
+ downloadProgress
104185
104305
  ]);
104186
104306
  };
104187
104307
  const useSampleInvalidation = () => {
@@ -104613,25 +104733,33 @@ const useFlowServerData = (dir) => {
104613
104733
  }
104614
104734
  }, [dir, flowDir, api2, updateFlowData]);
104615
104735
  };
104616
- const wrapper$3 = "_wrapper_1tajk_1";
104617
- const container$j = "_container_1tajk_12";
104618
- 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";
104619
104740
  const styles$1f = {
104620
104741
  wrapper: wrapper$3,
104621
104742
  container: container$j,
104622
- animate
104743
+ animate,
104744
+ determinate
104623
104745
  };
104624
- const ActivityBar = ({ animating }) => {
104746
+ const ActivityBar = ({ animating, progress: progress2 }) => {
104625
104747
  return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1f.wrapper), children: /* @__PURE__ */ jsxRuntimeExports.jsx(
104626
104748
  "div",
104627
104749
  {
104628
104750
  className: clsx(styles$1f.container),
104629
104751
  role: "progressbar",
104630
104752
  "aria-label": "Progress bar",
104631
- "aria-valuenow": 25,
104753
+ "aria-valuenow": progress2 !== void 0 ? Math.round(progress2 * 100) : void 0,
104632
104754
  "aria-valuemin": 0,
104633
104755
  "aria-valuemax": 100,
104634
- 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 }))
104635
104763
  }
104636
104764
  ) });
104637
104765
  };
@@ -106611,7 +106739,7 @@ const ViewerOptionsPopover = ({
106611
106739
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.fullWidth, styles$1d.fullWidthPadded), children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: styles$1d.logDir, children: logDir2 }) }),
106612
106740
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.spacer) }),
106613
106741
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Version" }),
106614
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.197-0-g6e17b3bc6" }),
106742
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: "0.3.200-0-g01cd5b482" }),
106615
106743
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx("text-style-label", "text-style-secondary"), children: "Schema" }),
106616
106744
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(), children: DB_VERSION }),
106617
106745
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: clsx(styles$1d.spacer) }),
@@ -165172,7 +165300,20 @@ function useLoadSample() {
165172
165300
  if (completed !== false) {
165173
165301
  log$1.debug(`LOADING COMPLETED SAMPLE: ${id}-${epoch}`);
165174
165302
  getSamplePolling().stopPolling();
165175
- 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);
165176
165317
  log$1.debug(`LOADED COMPLETED SAMPLE: ${id}-${epoch}`);
165177
165318
  if (thisGeneration !== loadGeneration) {
165178
165319
  log$1.debug(`Discarding stale sample response: ${id}-${epoch}`);
@@ -165198,6 +165339,7 @@ function useLoadSample() {
165198
165339
  getSamplePolling().stopPolling();
165199
165340
  }
165200
165341
  } catch (e) {
165342
+ sampleActions.setDownloadProgress(void 0);
165201
165343
  sampleActions.setSampleError(e);
165202
165344
  sampleActions.setSampleStatus("error");
165203
165345
  }
@@ -165861,6 +166003,7 @@ async function findExtendedInDOM(searchTerm, back, lastFoundItem, extendedFindTe
165861
166003
  );
165862
166004
  if (foundInVirtual) {
165863
166005
  extendedSearchSucceeded = true;
166006
+ await waitForTextInDOM(searchTerm);
165864
166007
  continue;
165865
166008
  }
165866
166009
  }
@@ -165895,6 +166038,7 @@ async function findExtendedInDOM(searchTerm, back, lastFoundItem, extendedFindTe
165895
166038
  );
165896
166039
  if (foundInVirtual) {
165897
166040
  extendedSearchSucceeded = true;
166041
+ await waitForTextInDOM(searchTerm);
165898
166042
  continue;
165899
166043
  }
165900
166044
  positionSelectionForWrap(back);
@@ -165955,6 +166099,50 @@ function selectionParentElement(range2) {
165955
166099
  }
165956
166100
  return element;
165957
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
+ }
165958
166146
  const tabs$1 = "_tabs_1rv6h_1";
165959
166147
  const tabContents = "_tabContents_1rv6h_5";
165960
166148
  const scrollable = "_scrollable_1rv6h_11";
@@ -166199,51 +166387,6 @@ const NoContentsPanel = ({ text: text2 }) => {
166199
166387
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: text2 })
166200
166388
  ] }) });
166201
166389
  };
166202
- const printHtml = (html2, css2) => {
166203
- const printWindow = window.open("", "", "height=600,width=800");
166204
- if (printWindow !== null) {
166205
- printWindow.document.write("<html><head><title>Print</title>");
166206
- printWindow.document.write(`
166207
- <link rel="stylesheet" crossorigin="" href="./assets/index.css">
166208
- <style>
166209
- @media print {
166210
- ${css2}
166211
- }
166212
- </style>
166213
- `);
166214
- printWindow.document.write("</head><body>");
166215
- printWindow.document.write(html2);
166216
- printWindow.document.write("</body></html>");
166217
- printWindow.document.close();
166218
- printWindow.onload = function() {
166219
- printWindow.focus();
166220
- printWindow.print();
166221
- printWindow.close();
166222
- };
166223
- } else {
166224
- console.error("Print window failed to open.");
166225
- }
166226
- };
166227
- const printHeadingHtml = () => {
166228
- const taskEl = document.getElementById("task-title");
166229
- const modelEl = document.getElementById("task-model");
166230
- const timeEl = document.getElementById("task-created");
166231
- if (!taskEl || !modelEl || !timeEl) {
166232
- throw new Error(
166233
- "Failed to compute heading HTML. The task, model, or time element can't be found."
166234
- );
166235
- }
166236
- const task = taskEl.innerText;
166237
- const model2 = modelEl.innerText;
166238
- const time = timeEl.innerText;
166239
- const headingHtml = `
166240
- <div style="display: grid; grid-template-columns: repeat(3, 1fr); column-gap: 0.5em; margin-bottom: 2em; justify-content: space-between; border-bottom: solid 1px silver;">
166241
- <div style="font-weight: 600">${task}</div>
166242
- <div style="text-align: center;">${model2}</div>
166243
- <div style="text-align: right;">${time}</div>
166244
- </div>`;
166245
- return headingHtml;
166246
- };
166247
166390
  const messagesToStr = (messages2, options2) => {
166248
166391
  const opts = {};
166249
166392
  return messages2.map((msg) => messageToStr(msg, opts)).filter((str2) => str2 !== null).join("\n");
@@ -166636,6 +166779,7 @@ const LiveVirtualList = ({
166636
166779
  }, 100);
166637
166780
  }
166638
166781
  }, [live, followOutput, prevLive, scrollRef, setFollowOutput]);
166782
+ const isNearBottomRef = useRef(false);
166639
166783
  const handleScroll = useRafThrottle(() => {
166640
166784
  if (isAutoScrollingRef.current) return;
166641
166785
  if (!live) return;
@@ -166649,10 +166793,25 @@ const LiveVirtualList = ({
166649
166793
  }
166650
166794
  }
166651
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]);
166652
166802
  const heightChanged = useCallback(
166653
166803
  (height) => {
166654
166804
  requestAnimationFrame(() => {
166655
- 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) {
166656
166815
  isAutoScrollingRef.current = true;
166657
166816
  listHandle.current?.scrollTo({ top: height });
166658
166817
  requestAnimationFrame(() => {
@@ -166789,9 +166948,13 @@ const LiveVirtualList = ({
166789
166948
  const parent = scrollRef?.current;
166790
166949
  if (parent) {
166791
166950
  parent.addEventListener("scroll", handleScroll);
166792
- return () => parent.removeEventListener("scroll", handleScroll);
166951
+ parent.addEventListener("scroll", handleScrollSync);
166952
+ return () => {
166953
+ parent.removeEventListener("scroll", handleScroll);
166954
+ parent.removeEventListener("scroll", handleScrollSync);
166955
+ };
166793
166956
  }
166794
- }, [scrollRef, handleScroll]);
166957
+ }, [scrollRef, handleScroll, handleScrollSync]);
166795
166958
  const hasScrolled = useRef(false);
166796
166959
  useEffect(() => {
166797
166960
  if (initialTopMostItemIndex !== void 0 && listHandle.current) {
@@ -166953,7 +167116,7 @@ const ChatViewVirtualList = memo(
166953
167116
  } else if (event.key === "ArrowDown") {
166954
167117
  if (useVirtuoso) {
166955
167118
  listHandle.current?.scrollToIndex({
166956
- index: Math.min(messages2.length - 5, 0),
167119
+ index: Math.max(messages2.length - 5, 0),
166957
167120
  align: "center"
166958
167121
  });
166959
167122
  setTimeout(() => {
@@ -166972,16 +167135,10 @@ const ChatViewVirtualList = memo(
166972
167135
  }
166973
167136
  }
166974
167137
  };
166975
- const scrollElement = scrollRef?.current;
166976
- if (scrollElement) {
166977
- scrollElement.addEventListener("keydown", handleKeyDown);
166978
- if (!scrollElement.hasAttribute("tabIndex")) {
166979
- scrollElement.setAttribute("tabIndex", "0");
166980
- }
166981
- return () => {
166982
- scrollElement.removeEventListener("keydown", handleKeyDown);
166983
- };
166984
- }
167138
+ document.addEventListener("keydown", handleKeyDown);
167139
+ return () => {
167140
+ document.removeEventListener("keydown", handleKeyDown);
167141
+ };
166985
167142
  }, [scrollRef, messages2, useVirtuoso]);
166986
167143
  if (!useVirtuoso) {
166987
167144
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -168934,12 +169091,12 @@ const TranscriptOutline = ({
168934
169091
  }
168935
169092
  );
168936
169093
  };
168937
- const container$e = "_container_17sux_1";
168938
- const collapsed = "_collapsed_17sux_9";
168939
- const treeContainer = "_treeContainer_17sux_13";
168940
- const listContainer = "_listContainer_17sux_25";
168941
- const outline = "_outline_17sux_29";
168942
- 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";
168943
169100
  const styles$R = {
168944
169101
  container: container$e,
168945
169102
  collapsed,
@@ -180021,6 +180178,11 @@ const transformers = () => {
180021
180178
  matches: (node2) => node2.event.event === SPAN_BEGIN && node2.event["type"] === TYPE_SOLVER && node2.children.length === 2 && node2.children[0].event.event === SPAN_BEGIN && node2.children[0].event.type === TYPE_AGENT && node2.children[1].event.event === STATE,
180022
180179
  process: (node2) => skipFirstChildNode(node2)
180023
180180
  },
180181
+ {
180182
+ name: "unwrap_filtered-agent_solver",
180183
+ matches: (node2) => node2.event.event === SPAN_BEGIN && node2.event["type"] === TYPE_SOLVER && node2.children.length === 1 && node2.children[0].event.event === SPAN_BEGIN && node2.children[0].event.type === TYPE_AGENT,
180184
+ process: (node2) => skipFirstChildNode(node2)
180185
+ },
180024
180186
  {
180025
180187
  name: "unwrap_agent_solver w/store",
180026
180188
  matches: (node2) => node2.event.event === SPAN_BEGIN && node2.event["type"] === TYPE_SOLVER && node2.children.length === 3 && node2.children[0].event.event === SPAN_BEGIN && node2.children[0].event.type === TYPE_AGENT && node2.children[1].event.event === STATE && node2.children[2].event.event === STORE,
@@ -180454,17 +180616,11 @@ const TranscriptPanel = memo((props) => {
180454
180616
  }
180455
180617
  }
180456
180618
  };
180457
- const scrollElement = scrollRef.current;
180458
- if (scrollElement) {
180459
- scrollElement.addEventListener("keydown", handleKeyDown);
180460
- if (!scrollElement.hasAttribute("tabIndex")) {
180461
- scrollElement.setAttribute("tabIndex", "0");
180462
- }
180463
- return () => {
180464
- scrollElement.removeEventListener("keydown", handleKeyDown);
180465
- };
180466
- }
180467
- }, [scrollRef, flattenedNodes]);
180619
+ document.addEventListener("keydown", handleKeyDown);
180620
+ return () => {
180621
+ document.removeEventListener("keydown", handleKeyDown);
180622
+ };
180623
+ }, [flattenedNodes]);
180468
180624
  if (sampleStatus2 === "loading" && flattenedNodes.length === 0) {
180469
180625
  return void 0;
180470
180626
  }
@@ -180529,10 +180685,48 @@ const TranscriptPanel = memo((props) => {
180529
180685
  );
180530
180686
  }
180531
180687
  });
180688
+ const printHtml = (html2, css2) => {
180689
+ const printWindow = window.open("", "", "height=600,width=800");
180690
+ if (printWindow !== null) {
180691
+ printWindow.document.write("<html><head><title>Print</title>");
180692
+ printWindow.document.write(`
180693
+ <link rel="stylesheet" crossorigin="" href="./assets/index.css">
180694
+ <style>
180695
+ @media print {
180696
+ ${css2}
180697
+ }
180698
+ </style>
180699
+ `);
180700
+ printWindow.document.write("</head><body>");
180701
+ printWindow.document.write(html2);
180702
+ printWindow.document.write("</body></html>");
180703
+ printWindow.document.close();
180704
+ printWindow.onload = function() {
180705
+ printWindow.focus();
180706
+ printWindow.print();
180707
+ printWindow.close();
180708
+ };
180709
+ } else {
180710
+ console.error("Print window failed to open.");
180711
+ }
180712
+ };
180713
+ const printHeadingHtml = (evalSpec) => {
180714
+ const task = evalSpec?.task || "Unknown Task";
180715
+ const model2 = evalSpec?.model || "Unknown Model";
180716
+ const time = evalSpec?.created ? new Date(evalSpec.created).toLocaleString() : "Unknown Time";
180717
+ const headingHtml = `
180718
+ <div style="display: grid; grid-template-columns: repeat(3, 1fr); column-gap: 0.5em; margin-bottom: 2em; justify-content: space-between; border-bottom: solid 1px silver;">
180719
+ <div style="font-weight: 600">${task}</div>
180720
+ <div style="text-align: center;">${model2}</div>
180721
+ <div style="text-align: right;">${time}</div>
180722
+ </div>`;
180723
+ return headingHtml;
180724
+ };
180532
180725
  const SampleDisplay = ({
180533
180726
  id,
180534
180727
  scrollRef,
180535
180728
  showActivity,
180729
+ progress: progress2,
180536
180730
  focusOnLoad
180537
180731
  }) => {
180538
180732
  const baseId = `sample-display`;
@@ -180626,8 +180820,8 @@ const SampleDisplay = ({
180626
180820
  const filterRef = useRef(null);
180627
180821
  const optionsRef = useRef(null);
180628
180822
  const handlePrintClick = useCallback(() => {
180629
- printSample(id, targetId);
180630
- }, [id, targetId]);
180823
+ printSample(id, targetId, evalSpec);
180824
+ }, [id, targetId, evalSpec]);
180631
180825
  const toggleFilter = useCallback(() => {
180632
180826
  setShowing(!isShowing);
180633
180827
  }, [setShowing, isShowing]);
@@ -180764,7 +180958,7 @@ const SampleDisplay = ({
180764
180958
  const sampleDetailNavigation = useSampleDetailNavigation();
180765
180959
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(Fragment, { children: [
180766
180960
  selectedSampleSummary ? /* @__PURE__ */ jsxRuntimeExports.jsx(SampleSummaryView, { parent_id: id, sample: selectedSampleSummary }) : void 0,
180767
- /* @__PURE__ */ jsxRuntimeExports.jsx(ActivityBar, { animating: showActivity }),
180961
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ActivityBar, { animating: showActivity, progress: progress2 }),
180768
180962
  hasSampleData && /* @__PURE__ */ jsxRuntimeExports.jsxs(
180769
180963
  TabSet,
180770
180964
  {
@@ -181052,7 +181246,7 @@ const metadataViewsForSample = (id, scrollRef, sample2) => {
181052
181246
  }
181053
181247
  return sampleMetadatas;
181054
181248
  };
181055
- const printSample = (id, targetId) => {
181249
+ const printSample = (id, targetId, evalSpec) => {
181056
181250
  const targetTabEl = document.querySelector(
181057
181251
  `#${escapeSelector(targetId)} .sample-tab.tab-pane.show.active`
181058
181252
  );
@@ -181061,7 +181255,7 @@ const printSample = (id, targetId) => {
181061
181255
  if (targetEl) {
181062
181256
  const headingId = `sample-heading-${id}`;
181063
181257
  const headingEl = document.getElementById(headingId);
181064
- const headingHtml = printHeadingHtml();
181258
+ const headingHtml = printHeadingHtml(evalSpec);
181065
181259
  const css2 = `
181066
181260
  html { font-size: 9pt }
181067
181261
  /* Allow content to break anywhere without any forced page breaks */
@@ -181074,13 +181268,6 @@ const printSample = (id, targetId) => {
181074
181268
  page-break-after: auto;
181075
181269
  }
181076
181270
  /* Specifically disable all page breaks for divs */
181077
- div {
181078
- break-inside: auto;
181079
- page-break-inside: auto;
181080
- }
181081
- body > .transcript-step {
181082
- break-inside: avoid;
181083
- }
181084
181271
  body{
181085
181272
  -webkit-print-color-adjust:exact !important;
181086
181273
  print-color-adjust:exact !important;
@@ -181137,6 +181324,7 @@ const InlineSampleComponent = ({
181137
181324
  className: className2
181138
181325
  }) => {
181139
181326
  const sampleData = useSampleData();
181327
+ const sampleProgress = sampleData.status === "loading" && sampleData.downloadProgress && sampleData.downloadProgress.total > 0 ? sampleData.downloadProgress.complete / sampleData.downloadProgress.total : void 0;
181140
181328
  const scrollRef = useRef(null);
181141
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(
181142
181330
  ErrorPanel,
@@ -181149,6 +181337,7 @@ const InlineSampleComponent = ({
181149
181337
  {
181150
181338
  id: "inline-sample-display",
181151
181339
  showActivity: !!showActivity,
181340
+ progress: sampleProgress,
181152
181341
  scrollRef
181153
181342
  }
181154
181343
  ) }) }) }) });