mishig HF Staff commited on
Commit
f7fb1b0
Β·
verified Β·
1 Parent(s): 62974fd

Dark-mode terminal palette

Browse files
Files changed (2) hide show
  1. src/app.css +25 -25
  2. src/lib/TraceViewer.svelte +67 -67
src/app.css CHANGED
@@ -84,14 +84,14 @@
84
  code {
85
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
86
  font-size: 0.92em;
87
- background: #f5f5f2;
88
- border: 1px solid #eeeae0;
89
  border-radius: 3px;
90
  padding: 0 0.3em;
91
  }
92
  pre {
93
- background: #f5f5f2;
94
- border: 1px solid #eeeae0;
95
  border-radius: 4px;
96
  padding: 0.6em 0.8em;
97
  overflow-x: auto;
@@ -105,13 +105,13 @@
105
  font-size: 0.92em;
106
  }
107
  blockquote {
108
- border-left: 3px solid #e5e5e0;
109
  padding-left: 0.8em;
110
- color: #5f5f5c;
111
  margin: 0.5em 0;
112
  }
113
  a {
114
- color: #8b5cf6;
115
  text-decoration: underline;
116
  }
117
  a:hover {
@@ -119,7 +119,7 @@
119
  }
120
  hr {
121
  border: 0;
122
- border-top: 1px solid #eeeae0;
123
  margin: 0.8em 0;
124
  }
125
  table {
@@ -128,12 +128,12 @@
128
  font-size: 0.95em;
129
  }
130
  th, td {
131
- border: 1px solid #eeeae0;
132
  padding: 0.3em 0.6em;
133
  text-align: left;
134
  }
135
  th {
136
- background: #faf9f5;
137
  font-weight: 600;
138
  }
139
  img {
@@ -155,10 +155,10 @@
155
  padding: 2px 8px;
156
  font-size: 11px;
157
  line-height: 1.4;
158
- background: #fff;
159
- border: 1px solid #e5e5e0;
160
  border-radius: 4px;
161
- color: #6a6a66;
162
  cursor: pointer;
163
  opacity: 0;
164
  transition:
@@ -174,24 +174,24 @@
174
  opacity: 1;
175
  }
176
  .copy-btn:hover {
177
- background: #faf9f5;
178
- color: #222220;
179
  }
180
  .copy-btn.copied {
181
- color: #0f5a2a;
182
- border-color: #bbf7d0;
183
- background: #f0fdf4;
184
  }
185
  }
186
 
187
  @utility prose-thinking {
188
  code, pre {
189
- background: #faf5ff;
190
- border-color: #e9d5ff;
191
  }
192
  blockquote {
193
- border-left-color: #e9d5ff;
194
- color: #7e22ce;
195
  }
196
  }
197
 
@@ -204,7 +204,7 @@
204
 
205
  @utility thin-scrollbar {
206
  scrollbar-width: thin;
207
- scrollbar-color: #d0d0ca transparent;
208
 
209
  &::-webkit-scrollbar {
210
  width: 6px;
@@ -214,10 +214,10 @@
214
  background: transparent;
215
  }
216
  &::-webkit-scrollbar-thumb {
217
- background-color: #d0d0ca;
218
  border-radius: 3px;
219
  }
220
  &::-webkit-scrollbar-thumb:hover {
221
- background-color: #a8a8a0;
222
  }
223
  }
 
84
  code {
85
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
86
  font-size: 0.92em;
87
+ background: #1a1a1a;
88
+ border: 1px solid #2a2a2a;
89
  border-radius: 3px;
90
  padding: 0 0.3em;
91
  }
92
  pre {
93
+ background: #1a1a1a;
94
+ border: 1px solid #2a2a2a;
95
  border-radius: 4px;
96
  padding: 0.6em 0.8em;
97
  overflow-x: auto;
 
105
  font-size: 0.92em;
106
  }
107
  blockquote {
108
+ border-left: 3px solid #2a2a2a;
109
  padding-left: 0.8em;
110
+ color: #999999;
111
  margin: 0.5em 0;
112
  }
113
  a {
114
+ color: #a78bfa;
115
  text-decoration: underline;
116
  }
117
  a:hover {
 
119
  }
120
  hr {
121
  border: 0;
122
+ border-top: 1px solid #2a2a2a;
123
  margin: 0.8em 0;
124
  }
125
  table {
 
128
  font-size: 0.95em;
129
  }
130
  th, td {
131
+ border: 1px solid #2a2a2a;
132
  padding: 0.3em 0.6em;
133
  text-align: left;
134
  }
135
  th {
136
+ background: #1e1e1e;
137
  font-weight: 600;
138
  }
139
  img {
 
155
  padding: 2px 8px;
156
  font-size: 11px;
157
  line-height: 1.4;
158
+ background: #1a1a1a;
159
+ border: 1px solid #2a2a2a;
160
  border-radius: 4px;
161
+ color: #999999;
162
  cursor: pointer;
163
  opacity: 0;
164
  transition:
 
174
  opacity: 1;
175
  }
176
  .copy-btn:hover {
177
+ background: #1e1e1e;
178
+ color: #e8e8e5;
179
  }
180
  .copy-btn.copied {
181
+ color: #4ade80;
182
+ border-color: #166534;
183
+ background: #0f2a1a;
184
  }
185
  }
186
 
187
  @utility prose-thinking {
188
  code, pre {
189
+ background: #1a0d24;
190
+ border-color: #4c1d95;
191
  }
192
  blockquote {
193
+ border-left-color: #4c1d95;
194
+ color: #c084fc;
195
  }
196
  }
197
 
 
204
 
205
  @utility thin-scrollbar {
206
  scrollbar-width: thin;
207
+ scrollbar-color: #3a3a3a transparent;
208
 
209
  &::-webkit-scrollbar {
210
  width: 6px;
 
214
  background: transparent;
215
  }
216
  &::-webkit-scrollbar-thumb {
217
+ background-color: #3a3a3a;
218
  border-radius: 3px;
219
  }
220
  &::-webkit-scrollbar-thumb:hover {
221
+ background-color: #555555;
222
  }
223
  }
src/lib/TraceViewer.svelte CHANGED
@@ -298,12 +298,12 @@
298
  });
299
 
300
  const roleColor = {
301
- user: 'text-[#1e40af]',
302
- assistant: 'text-[#0f5a2a]',
303
- tool: 'text-[#6b21a8]',
304
- system: 'text-[#92400e]',
305
- meta: 'text-[#6a6a66]',
306
- unknown: 'text-[#6a6a66]',
307
  };
308
  </script>
309
 
@@ -313,18 +313,18 @@
313
  class="frame-bg frame-shadow w-[960px] max-w-[calc(100vw-48px)] rounded-[20px] p-[3px]"
314
  >
315
  <div
316
- class="w-full h-[85vh] bg-[#fbfbf9] rounded-[17px] overflow-hidden flex flex-col font-mono text-[14px] leading-[1.7] text-[#232323]"
317
  >
318
  <!-- chrome -->
319
  <div class="flex items-center gap-2 pt-4 px-[18px] pb-2 shrink-0">
320
- <span class="w-3 h-3 rounded-full bg-[#d7d7d3]"></span>
321
- <span class="w-3 h-3 rounded-full bg-[#d7d7d3]"></span>
322
- <span class="w-3 h-3 rounded-full bg-[#d7d7d3]"></span>
323
  <a
324
  href="https://huggingface.co/datasets?format=format%3Aagent-traces"
325
  target="_blank"
326
  rel="noopener noreferrer"
327
- class="ml-auto text-[12px] text-[#6a6a66] hover:text-[#222220] hover:underline select-none transition-colors"
328
  title="Browse agent-trace datasets on Hugging Face"
329
  >
330
  πŸ€— traces
@@ -333,9 +333,9 @@
333
 
334
  <!-- url prompt -->
335
  <div
336
- class="flex items-center gap-2 px-5 py-3 border-b border-[#eeeae0] shrink-0"
337
  >
338
- <span class="text-[#6a6a66] select-none">β€Ί</span>
339
  <input
340
  type="url"
341
  bind:value={url}
@@ -343,7 +343,7 @@
343
  if (e.key === 'Enter') load();
344
  }}
345
  placeholder="paste .jsonl dataset URL and press Enter"
346
- class="flex-1 bg-transparent border-none outline-none text-[13px] text-[#222220] placeholder:text-[#b0b0aa]"
347
  />
348
  <button
349
  type="button"
@@ -358,11 +358,11 @@
358
  onclick={shareTrace}
359
  disabled={messages.length === 0 || loading}
360
  title="Copy a shareable link to this replay"
361
- class="inline-flex items-center gap-1.5 px-3 py-1 bg-white border border-[#ffd21e] rounded text-[12px] font-semibold text-[#8a6b00] hover:bg-[#fffbe6] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer transition-colors shrink-0"
362
  >
363
  {#if copied}
364
- <span class="text-[#0f7a3a]">βœ“</span>
365
- <span class="text-[#0f5a2a]">copied</span>
366
  {:else}
367
  <svg
368
  xmlns="http://www.w3.org/2000/svg"
@@ -385,7 +385,7 @@
385
 
386
  <!-- examples -->
387
  <div
388
- class="flex flex-wrap items-center gap-2 px-5 py-2 border-b border-[#eeeae0] shrink-0"
389
  >
390
  <span class="text-[11px] text-[#888] select-none">examples:</span>
391
  {#each examples as ex}
@@ -393,7 +393,7 @@
393
  type="button"
394
  onclick={() => pickExample(ex)}
395
  disabled={loading || playing}
396
- class="text-[11px] px-2 py-1 bg-[#fffbe6] border border-[#ffedb0] rounded hover:bg-[#ffd21e] hover:border-[#ffbb1a] disabled:opacity-50 disabled:hover:bg-[#fffbe6] disabled:hover:border-[#ffedb0] transition-colors cursor-pointer"
397
  >
398
  {ex.label}
399
  </button>
@@ -411,29 +411,29 @@
411
  >
412
  {#if loading}
413
  <div class="flex items-baseline gap-2">
414
- <span class="w-[1ch] text-center text-[#5f5f5c]"
415
  >{spinnerFrames[spinnerFrame]}</span
416
  >
417
- <span class="text-[#333331]">Fetching traces...</span>
418
  </div>
419
  {:else if error}
420
  <div class="flex items-baseline gap-2">
421
- <span class="w-[1ch] text-center text-[#991b1b]">βœ—</span>
422
- <span class="text-[#991b1b]">{error}</span>
423
  </div>
424
  {:else if messages.length > 0}
425
  <div class="flex items-baseline gap-2 mb-3 animate-fade-in">
426
  <span
427
  class="w-[1ch] text-center {playing
428
- ? 'text-[#5f5f5c]'
429
- : 'text-[#0f7a3a] animate-ready-pulse'}"
430
  >
431
  {playing ? spinnerFrames[spinnerFrame] : '●'}
432
  </span>
433
  <span
434
  class="{playing
435
- ? 'text-[#333331]'
436
- : 'text-[#0f5a2a]'} font-semibold"
437
  >
438
  {playing
439
  ? `Streaming ${focusedIdx + 1} / ${loadedCount}...`
@@ -443,33 +443,33 @@
443
  {:else}
444
  <div class="text-[#888] text-[13px] leading-relaxed">
445
  <div class="flex items-baseline gap-2 mb-1">
446
- <span class="w-[1ch] text-center text-[#6b6b68]">β—‹</span>
447
  <span>waiting for input</span>
448
  </div>
449
  <div class="pl-[2.2ch] text-[#888]">
450
- paste a <code class="text-[#8b5cf6]">.jsonl</code> dataset URL above,
451
  press
452
  <kbd
453
- class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px]"
454
  >Enter</kbd
455
  > to load.
456
  </div>
457
  <div class="pl-[2.2ch] text-[#888] mt-1">
458
  then <kbd
459
- class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px]"
460
  >↑</kbd
461
  >
462
  <kbd
463
- class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px]"
464
  >↓</kbd
465
  >
466
  to navigate sections,
467
  <kbd
468
- class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px]"
469
  >Home</kbd
470
  >/
471
  <kbd
472
- class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px]"
473
  >End</kbd
474
  > for start/end.
475
  </div>
@@ -478,7 +478,7 @@
478
  href="https://huggingface.co/changelog/agent-trace-viewer"
479
  target="_blank"
480
  rel="noopener noreferrer"
481
- class="text-[#8b5cf6] hover:underline"
482
  >β†’ learn more about the agent trace viewer on Hugging Face</a
483
  >
484
  </div>
@@ -494,15 +494,15 @@
494
  data-idx={i}
495
  onclick={() => (focusedIdx = i)}
496
  class="py-1 cursor-default rounded transition-colors animate-fade-in {focused
497
- ? 'bg-[#fffbe6]'
498
- : 'hover:bg-[#faf9f5]'}"
499
  >
500
  <!-- header -->
501
  <div class="flex items-baseline gap-2 px-2">
502
  <span
503
  class="w-[1ch] text-center {focused
504
- ? 'text-[#0f7a3a] animate-ready-pulse'
505
- : 'text-[#6b6b68]'}"
506
  >
507
  {focused ? '●' : 'β—‹'}
508
  </span>
@@ -514,7 +514,7 @@
514
  {msg.role}
515
  </span>
516
  {#if msg.title}
517
- <span class="text-[12px] text-[#6a6a66] truncate"
518
  >{msg.title}</span
519
  >
520
  {/if}
@@ -522,7 +522,7 @@
522
  {#if msg.model}
523
  <span class="text-[11px] text-[#888]">{msg.model}</span>
524
  {/if}
525
- <span class="text-[11px] text-[#aaa]">#{i}</span>
526
  </span>
527
  </div>
528
 
@@ -531,20 +531,20 @@
531
  {#if bi < msg._visibleBlocks}
532
  {@const isLast = bi === msg.blocks.length - 1}
533
  <div class="flex items-start gap-2 px-2 animate-fade-in">
534
- <span class="w-[1ch] text-[#b3b3ad] shrink-0 mt-[2px]"
535
  >{isLast ? 'β””' : 'β”œ'}</span
536
  >
537
  <div class="flex-1 min-w-0">
538
  {#if block.kind === 'text'}
539
  {#if block._typing || block._typedText !== block.text}
540
  <pre
541
- class="whitespace-pre-wrap break-words text-[13px] text-[#232323] leading-[1.65] font-mono">{block._typedText}{#if block._typing}<span
542
- class="animate-blink text-[#8b5cf6]"
543
  aria-hidden="true">β–Ž</span
544
  >{/if}</pre>
545
  {:else}
546
  <div
547
- class="prose-trace text-[13px] text-[#232323] leading-[1.65]"
548
  >
549
  {@html renderMarkdown(block.text)}
550
  </div>
@@ -552,18 +552,18 @@
552
  {:else if block.kind === 'thinking'}
553
  <details class="py-0.5" open>
554
  <summary
555
- class="cursor-pointer text-[11px] text-[#8b5cf6] font-semibold select-none hover:underline"
556
  >thinking</summary
557
  >
558
  {#if block._typing || block._typedText !== block.text}
559
  <pre
560
- class="whitespace-pre-wrap break-words text-[12px] text-[#6b21a8] mt-1 leading-[1.65] pl-[1ch] border-l border-[#e9d5ff]">{block._typedText}{#if block._typing}<span
561
- class="animate-blink text-[#8b5cf6]"
562
  aria-hidden="true">β–Ž</span
563
  >{/if}</pre>
564
  {:else}
565
  <div
566
- class="prose-trace prose-thinking text-[12px] text-[#6b21a8] mt-1 leading-[1.65] pl-[1ch] border-l border-[#e9d5ff]"
567
  >
568
  {@html renderMarkdown(block.text)}
569
  </div>
@@ -571,12 +571,12 @@
571
  </details>
572
  {:else if block.kind === 'tool_call'}
573
  <div class="py-0.5">
574
- <div class="text-[12px] text-[#6b21a8]">
575
- <span class="text-[#aaa]">tool</span>
576
  <span class="font-semibold">{block.name}</span>
577
  </div>
578
  <pre
579
- class="text-[12px] text-[#3a3a38] whitespace-pre-wrap break-words mt-0.5 pl-[1ch] border-l border-[#e9d5ff]">{formatJson(
580
  block.input
581
  )}</pre>
582
  </div>
@@ -584,21 +584,21 @@
584
  <div class="py-0.5">
585
  <div
586
  class="text-[12px] {block.isError
587
- ? 'text-[#991b1b]'
588
- : 'text-[#6a6a66]'}"
589
  >
590
- <span class="text-[#aaa]">result</span>
591
  {#if block.isError}<span class="font-semibold"
592
  >Β· error</span
593
  >{/if}
594
  </div>
595
  <pre
596
- class="text-[12px] text-[#3a3a38] whitespace-pre-wrap break-words mt-0.5 pl-[1ch] border-l {block.isError
597
- ? 'border-[#fecaca]'
598
- : 'border-[#e5e5e0]'}">{block.text}</pre>
599
  </div>
600
  {:else if block.kind === 'image'}
601
- <div class="text-[12px] text-[#6a6a66] italic">
602
  [image attachment]
603
  </div>
604
  {:else if block.kind === 'raw'}
@@ -608,7 +608,7 @@
608
  >raw</summary
609
  >
610
  <pre
611
- class="text-[11px] text-[#555] whitespace-pre-wrap break-words mt-1 pl-[1ch] border-l border-[#e5e5e0]">{formatJson(
612
  block.json
613
  )}</pre>
614
  </details>
@@ -624,7 +624,7 @@
624
 
625
  <!-- footer -->
626
  <div
627
- class="flex items-center gap-4 px-5 py-2 border-t border-[#eeeae0] text-[11px] text-[#888] shrink-0"
628
  >
629
  {#if messages.length > 0}
630
  <span>{focusedIdx + 1} / {messages.length}</span>
@@ -634,23 +634,23 @@
634
  {#if playing}
635
  <button
636
  onclick={skip}
637
- class="px-2 py-0.5 bg-[#f5f5f2] rounded border border-[#e5e5e0] text-[11px] hover:bg-[#eeeae0] cursor-pointer"
638
  >skip</button
639
  >
640
  {:else}
641
  <span class="flex items-center gap-1">
642
- <kbd class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0]"
643
  >↑</kbd
644
  >
645
- <kbd class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0]"
646
  >↓</kbd
647
  > navigate
648
  </span>
649
  <span class="flex items-center gap-1">
650
- <kbd class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0]"
651
  >Home</kbd
652
  >
653
- <kbd class="px-1 py-px bg-[#f5f5f2] rounded border border-[#e5e5e0]"
654
  >End</kbd
655
  > jump
656
  </span>
@@ -659,7 +659,7 @@
659
  href="https://huggingface.co/changelog/agent-trace-viewer"
660
  target="_blank"
661
  rel="noopener noreferrer"
662
- class="ml-auto text-[#8b5cf6] hover:underline"
663
  title="HF changelog Β· agent trace viewer"
664
  >changelog β†’</a
665
  >
 
298
  });
299
 
300
  const roleColor = {
301
+ user: 'text-[#60a5fa]',
302
+ assistant: 'text-[#4ade80]',
303
+ tool: 'text-[#c084fc]',
304
+ system: 'text-[#fbbf24]',
305
+ meta: 'text-[#999999]',
306
+ unknown: 'text-[#999999]',
307
  };
308
  </script>
309
 
 
313
  class="frame-bg frame-shadow w-[960px] max-w-[calc(100vw-48px)] rounded-[20px] p-[3px]"
314
  >
315
  <div
316
+ class="w-full h-[85vh] bg-[#0d0d0d] rounded-[17px] overflow-hidden flex flex-col font-mono text-[14px] leading-[1.7] text-[#e8e8e5]"
317
  >
318
  <!-- chrome -->
319
  <div class="flex items-center gap-2 pt-4 px-[18px] pb-2 shrink-0">
320
+ <span class="w-3 h-3 rounded-full bg-[#3a3a3a]"></span>
321
+ <span class="w-3 h-3 rounded-full bg-[#3a3a3a]"></span>
322
+ <span class="w-3 h-3 rounded-full bg-[#3a3a3a]"></span>
323
  <a
324
  href="https://huggingface.co/datasets?format=format%3Aagent-traces"
325
  target="_blank"
326
  rel="noopener noreferrer"
327
+ class="ml-auto text-[12px] text-[#999999] hover:text-[#e8e8e5] hover:underline select-none transition-colors"
328
  title="Browse agent-trace datasets on Hugging Face"
329
  >
330
  πŸ€— traces
 
333
 
334
  <!-- url prompt -->
335
  <div
336
+ class="flex items-center gap-2 px-5 py-3 border-b border-[#2a2a2a] shrink-0"
337
  >
338
+ <span class="text-[#999999] select-none">β€Ί</span>
339
  <input
340
  type="url"
341
  bind:value={url}
 
343
  if (e.key === 'Enter') load();
344
  }}
345
  placeholder="paste .jsonl dataset URL and press Enter"
346
+ class="flex-1 bg-transparent border-none outline-none text-[13px] text-[#e8e8e5] placeholder:text-[#555555]"
347
  />
348
  <button
349
  type="button"
 
358
  onclick={shareTrace}
359
  disabled={messages.length === 0 || loading}
360
  title="Copy a shareable link to this replay"
361
+ class="inline-flex items-center gap-1.5 px-3 py-1 bg-[#1a1a1a] border border-[#ffd21e] rounded text-[12px] font-semibold text-[#ffd21e] hover:bg-[#3a2e08] disabled:opacity-40 disabled:cursor-not-allowed cursor-pointer transition-colors shrink-0"
362
  >
363
  {#if copied}
364
+ <span class="text-[#4ade80]">βœ“</span>
365
+ <span class="text-[#4ade80]">copied</span>
366
  {:else}
367
  <svg
368
  xmlns="http://www.w3.org/2000/svg"
 
385
 
386
  <!-- examples -->
387
  <div
388
+ class="flex flex-wrap items-center gap-2 px-5 py-2 border-b border-[#2a2a2a] shrink-0"
389
  >
390
  <span class="text-[11px] text-[#888] select-none">examples:</span>
391
  {#each examples as ex}
 
393
  type="button"
394
  onclick={() => pickExample(ex)}
395
  disabled={loading || playing}
396
+ class="text-[11px] px-2 py-1 bg-[#3a2e08] border border-[#665a00] rounded hover:bg-[#ffd21e] hover:border-[#ffbb1a] disabled:opacity-50 disabled:hover:bg-[#3a2e08] disabled:hover:border-[#665a00] transition-colors cursor-pointer"
397
  >
398
  {ex.label}
399
  </button>
 
411
  >
412
  {#if loading}
413
  <div class="flex items-baseline gap-2">
414
+ <span class="w-[1ch] text-center text-[#999999]"
415
  >{spinnerFrames[spinnerFrame]}</span
416
  >
417
+ <span class="text-[#d4d4d4]">Fetching traces...</span>
418
  </div>
419
  {:else if error}
420
  <div class="flex items-baseline gap-2">
421
+ <span class="w-[1ch] text-center text-[#f87171]">βœ—</span>
422
+ <span class="text-[#f87171]">{error}</span>
423
  </div>
424
  {:else if messages.length > 0}
425
  <div class="flex items-baseline gap-2 mb-3 animate-fade-in">
426
  <span
427
  class="w-[1ch] text-center {playing
428
+ ? 'text-[#999999]'
429
+ : 'text-[#4ade80] animate-ready-pulse'}"
430
  >
431
  {playing ? spinnerFrames[spinnerFrame] : '●'}
432
  </span>
433
  <span
434
  class="{playing
435
+ ? 'text-[#d4d4d4]'
436
+ : 'text-[#4ade80]'} font-semibold"
437
  >
438
  {playing
439
  ? `Streaming ${focusedIdx + 1} / ${loadedCount}...`
 
443
  {:else}
444
  <div class="text-[#888] text-[13px] leading-relaxed">
445
  <div class="flex items-baseline gap-2 mb-1">
446
+ <span class="w-[1ch] text-center text-[#999999]">β—‹</span>
447
  <span>waiting for input</span>
448
  </div>
449
  <div class="pl-[2.2ch] text-[#888]">
450
+ paste a <code class="text-[#a78bfa]">.jsonl</code> dataset URL above,
451
  press
452
  <kbd
453
+ class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px]"
454
  >Enter</kbd
455
  > to load.
456
  </div>
457
  <div class="pl-[2.2ch] text-[#888] mt-1">
458
  then <kbd
459
+ class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px]"
460
  >↑</kbd
461
  >
462
  <kbd
463
+ class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px]"
464
  >↓</kbd
465
  >
466
  to navigate sections,
467
  <kbd
468
+ class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px]"
469
  >Home</kbd
470
  >/
471
  <kbd
472
+ class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px]"
473
  >End</kbd
474
  > for start/end.
475
  </div>
 
478
  href="https://huggingface.co/changelog/agent-trace-viewer"
479
  target="_blank"
480
  rel="noopener noreferrer"
481
+ class="text-[#a78bfa] hover:underline"
482
  >β†’ learn more about the agent trace viewer on Hugging Face</a
483
  >
484
  </div>
 
494
  data-idx={i}
495
  onclick={() => (focusedIdx = i)}
496
  class="py-1 cursor-default rounded transition-colors animate-fade-in {focused
497
+ ? 'bg-[#3a2e08]'
498
+ : 'hover:bg-[#1e1e1e]'}"
499
  >
500
  <!-- header -->
501
  <div class="flex items-baseline gap-2 px-2">
502
  <span
503
  class="w-[1ch] text-center {focused
504
+ ? 'text-[#4ade80] animate-ready-pulse'
505
+ : 'text-[#999999]'}"
506
  >
507
  {focused ? '●' : 'β—‹'}
508
  </span>
 
514
  {msg.role}
515
  </span>
516
  {#if msg.title}
517
+ <span class="text-[12px] text-[#999999] truncate"
518
  >{msg.title}</span
519
  >
520
  {/if}
 
522
  {#if msg.model}
523
  <span class="text-[11px] text-[#888]">{msg.model}</span>
524
  {/if}
525
+ <span class="text-[11px] text-[#6a6a6a]">#{i}</span>
526
  </span>
527
  </div>
528
 
 
531
  {#if bi < msg._visibleBlocks}
532
  {@const isLast = bi === msg.blocks.length - 1}
533
  <div class="flex items-start gap-2 px-2 animate-fade-in">
534
+ <span class="w-[1ch] text-[#555555] shrink-0 mt-[2px]"
535
  >{isLast ? 'β””' : 'β”œ'}</span
536
  >
537
  <div class="flex-1 min-w-0">
538
  {#if block.kind === 'text'}
539
  {#if block._typing || block._typedText !== block.text}
540
  <pre
541
+ class="whitespace-pre-wrap break-words text-[13px] text-[#e8e8e5] leading-[1.65] font-mono">{block._typedText}{#if block._typing}<span
542
+ class="animate-blink text-[#a78bfa]"
543
  aria-hidden="true">β–Ž</span
544
  >{/if}</pre>
545
  {:else}
546
  <div
547
+ class="prose-trace text-[13px] text-[#e8e8e5] leading-[1.65]"
548
  >
549
  {@html renderMarkdown(block.text)}
550
  </div>
 
552
  {:else if block.kind === 'thinking'}
553
  <details class="py-0.5" open>
554
  <summary
555
+ class="cursor-pointer text-[11px] text-[#a78bfa] font-semibold select-none hover:underline"
556
  >thinking</summary
557
  >
558
  {#if block._typing || block._typedText !== block.text}
559
  <pre
560
+ class="whitespace-pre-wrap break-words text-[12px] text-[#c084fc] mt-1 leading-[1.65] pl-[1ch] border-l border-[#4c1d95]">{block._typedText}{#if block._typing}<span
561
+ class="animate-blink text-[#a78bfa]"
562
  aria-hidden="true">β–Ž</span
563
  >{/if}</pre>
564
  {:else}
565
  <div
566
+ class="prose-trace prose-thinking text-[12px] text-[#c084fc] mt-1 leading-[1.65] pl-[1ch] border-l border-[#4c1d95]"
567
  >
568
  {@html renderMarkdown(block.text)}
569
  </div>
 
571
  </details>
572
  {:else if block.kind === 'tool_call'}
573
  <div class="py-0.5">
574
+ <div class="text-[12px] text-[#c084fc]">
575
+ <span class="text-[#6a6a6a]">tool</span>
576
  <span class="font-semibold">{block.name}</span>
577
  </div>
578
  <pre
579
+ class="text-[12px] text-[#d4d4d4] whitespace-pre-wrap break-words mt-0.5 pl-[1ch] border-l border-[#4c1d95]">{formatJson(
580
  block.input
581
  )}</pre>
582
  </div>
 
584
  <div class="py-0.5">
585
  <div
586
  class="text-[12px] {block.isError
587
+ ? 'text-[#f87171]'
588
+ : 'text-[#999999]'}"
589
  >
590
+ <span class="text-[#6a6a6a]">result</span>
591
  {#if block.isError}<span class="font-semibold"
592
  >Β· error</span
593
  >{/if}
594
  </div>
595
  <pre
596
+ class="text-[12px] text-[#d4d4d4] whitespace-pre-wrap break-words mt-0.5 pl-[1ch] border-l {block.isError
597
+ ? 'border-[#991b1b]'
598
+ : 'border-[#2a2a2a]'}">{block.text}</pre>
599
  </div>
600
  {:else if block.kind === 'image'}
601
+ <div class="text-[12px] text-[#999999] italic">
602
  [image attachment]
603
  </div>
604
  {:else if block.kind === 'raw'}
 
608
  >raw</summary
609
  >
610
  <pre
611
+ class="text-[11px] text-[#a0a0a0] whitespace-pre-wrap break-words mt-1 pl-[1ch] border-l border-[#2a2a2a]">{formatJson(
612
  block.json
613
  )}</pre>
614
  </details>
 
624
 
625
  <!-- footer -->
626
  <div
627
+ class="flex items-center gap-4 px-5 py-2 border-t border-[#2a2a2a] text-[11px] text-[#888] shrink-0"
628
  >
629
  {#if messages.length > 0}
630
  <span>{focusedIdx + 1} / {messages.length}</span>
 
634
  {#if playing}
635
  <button
636
  onclick={skip}
637
+ class="px-2 py-0.5 bg-[#1a1a1a] rounded border border-[#2a2a2a] text-[11px] hover:bg-[#2a2a2a] cursor-pointer"
638
  >skip</button
639
  >
640
  {:else}
641
  <span class="flex items-center gap-1">
642
+ <kbd class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a]"
643
  >↑</kbd
644
  >
645
+ <kbd class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a]"
646
  >↓</kbd
647
  > navigate
648
  </span>
649
  <span class="flex items-center gap-1">
650
+ <kbd class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a]"
651
  >Home</kbd
652
  >
653
+ <kbd class="px-1 py-px bg-[#1a1a1a] rounded border border-[#2a2a2a]"
654
  >End</kbd
655
  > jump
656
  </span>
 
659
  href="https://huggingface.co/changelog/agent-trace-viewer"
660
  target="_blank"
661
  rel="noopener noreferrer"
662
+ class="ml-auto text-[#a78bfa] hover:underline"
663
  title="HF changelog Β· agent trace viewer"
664
  >changelog β†’</a
665
  >