[User] What's this?

[Assistant] Hi! This is Euphony, a web-based interactive tool for visualizing Harmony chat data. It lets you browse, explore, and share conversation data.

[User] So it's basically like a chat viewer?

[Assistant] Yes, but it does more than that. You can inspect metadata, filter conversations, render markdown, translate text, view Codex sessions, and inspect Harmony token rendering.

[User] Nice. How do I actually load data into it?

[Assistant] You can load data in three ways: paste JSON or JSONL from the clipboard, choose a local file, or provide a public HTTP(S) URL that serves JSON or JSONL.

[User] And once I load it, I can share these conversations?

[Assistant] Exactly. After loading, you can share a link to a conversation, and you can also share links to individual messages.

[User] What if something does not load the way I expect?

[Assistant] The easiest next steps are to inspect the metadata, check whether the file is valid JSON or JSONL, and compare against the example files bundled with the app.

title: Introduction


[User] Cool, I loaded some data. How do I see metadata and render markdown?

[Assistant] Use the conversation metadata button for conversation-level metadata, and hover over a message role icon for message-level metadata. You can also enable markdown rendering to display rich formatting and formulas inline.

[Tool]
# Euphony 示例对话笔记

Euphony 支持复杂标注与 Markdown 渲染。你不仅能看到文字，还能查看结构化元数据，而且所有公式、Markdown 渲染都能直接在对话气泡中展示。

---

## 示例公式：损失融合

\[
\sum_{m \in \{\text{文本}\}}
\underbrace{ \alpha_m \cdot \mathrm{Score}^T(m) }_{\text{语义层的相关性}}
\;+\;
\underbrace{ \beta_m \cdot \mathrm{Score}^S(m) }_{\substack{\text{信号层的结构}\\\text{完整性度量}}}
\]

- **文本模态**：\(\mathrm{Score}^T\) 表示 BLEU/ROUGE，\(\mathrm{Score}^S\) 表示句法完整性。

---

## 功能展示
- **数学公式支持**：如上例，复杂的下标、上标和分块说明都能正常渲染。
- **翻译**：支持将非英文消息直接翻译并内联显示。

[Assistant] Markdown rendering also works well with metadata inspection and inline formulas.

title: Metadata, Markdown, and Translation


[User] My conversations have more than just plain user and assistant text. What else can Euphony load?

[Assistant] In this viewer, Euphony supports text, code, system content, and developer content. System and developer messages are rendered as first-class parts of the conversation, which is useful when you want to inspect the full prompt stack.

[System] You are ChatGPT, a large language model trained by OpenAI.

[developer] Keep answers concise, prefer exact file names, and give concrete next steps.

[Assistant]
{
  "role": "assistant",
  "channel": "final",
  "content": [
    {"type": "text", "text": "Rendered code blocks are supported too."}
  ]
}

[Assistant]
diff --git a/src/components/conversation/conversation.ts b/src/components/conversation/conversation.ts
index 1a2b3c4..5d6e7f8 100644
--- a/src/components/conversation/conversation.ts
+++ b/src/components/conversation/conversation.ts
@@ -210,7 +210,7 @@ const renderHeader = () => {
-  const label = 'Conversation';
+  const label = 'Euphony';
   return html`<h2>${label}</h2>`;
 }

title: Supported Harmony Content


[User] Does Euphony handle anything else?

[Assistant] It also supports rendering HTML elements in markdown text when markdown rendering is enabled. Here is the same HTML demo used in the main tutorial flow.

[Tool]
```html
<div class="flip-wrap" style="font-family:system-ui">
  <div class="flip-card" aria-label="Euphony flip card">
    <div class="flip-inner">
      <div class="face front"><div class="title">Euphony</div><div class="sub">hover to flip</div></div>
      <div class="face back"><div class="title">Euphony</div><div class="sub">HTML Rendering</div></div>
    </div>
  </div>

  <style>
    .flip-wrap{width:calc(100vw - 50px);height:calc(100vh - 50px);display:flex;justify-content:center;align-items:center}
    .flip-card{width:250px;height:110px;border-radius:18px;perspective:900px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}
    .flip-inner{width:100%;height:100%;position:relative;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .7s cubic-bezier(.2,.9,.2,1);will-change:transform}
    .flip-card:hover .flip-inner{transform:rotateY(180deg)}
    .face{position:absolute;inset:0;border-radius:18px;display:grid;place-items:center;backface-visibility:hidden;-webkit-backface-visibility:hidden;transform:translateZ(.1px);border:1px solid rgba(255,255,255,.10);box-shadow:0 16px 45px rgba(0,0,0,.35);overflow:hidden}
    .front{background:radial-gradient(120% 120% at 0% 0%,rgba(255,92,244,.28),transparent 55%),radial-gradient(120% 120% at 100% 100%,rgba(92,255,241,.22),transparent 55%),linear-gradient(135deg,#0b1220,#111827);color:#e5e7eb}
    .back{transform:rotateY(180deg) translateZ(.1px);-webkit-transform:rotateY(180deg) translateZ(.1px);background:radial-gradient(120% 120% at 100% 0%,rgba(92,255,241,.26),transparent 55%),radial-gradient(120% 120% at 0% 100%,rgba(255,92,244,.22),transparent 55%),linear-gradient(135deg,#111827,#0b1220);color:#e5e7eb}
    .title{font-weight:950;font-size:34px;letter-spacing:.06em;text-shadow:0 10px 30px rgba(0,0,0,.45);position:relative}
    .sub{margin-top:6px;font-size:12px;color:#94a3b8;letter-spacing:.14em;text-transform:uppercase}
    .front::before,.back::before{content:"";position:absolute;inset:-60px;background:conic-gradient(from 0deg,rgba(255,92,244,0),rgba(255,92,244,.55),rgba(92,255,241,.55),rgba(255,92,244,0));filter:blur(16px);opacity:.45;animation:spin 3.2s linear infinite;backface-visibility:hidden;-webkit-backface-visibility:hidden}
    .front>*,.back>*{position:relative;z-index:1;text-align:center}
    @keyframes spin{to{transform:rotate(360deg)}}
  </style>
</div>
```

[Assistant] That gives you a richer embedded demo without needing a separate content type.

title: HTML Rendering


[User] I've loaded a big dataset, but I only want to view a subset of it and skim a lot of conversations at once. How do I do that?

[Assistant] Use Filter data to apply a JMESPath query across the loaded conversations. Any metadata key in your JSONL can be used, for example `metadata.language == 'en'`. If you want to scan many samples quickly after filtering, switch the layout to Grid in Preferences.

[User] Some of my rollouts have a lot of tool call messages, but I want to focus on the user messages.

[Assistant] Use focus mode to filter messages by role, recipient, or content type. That lets you hide noisy messages while keeping the surrounding conversations visible.

title: Filtering, Focus Mode, and Grid


[User] Can I edit the loaded JSONL directly in the app?

[Assistant] Yes. Switch to editor mode. It lets you view and edit the underlying JSONL content directly, which is useful for fixing message text, adjusting metadata, and iterating on examples without leaving the viewer.

[Assistant] {"messages":[{"role":"user","content":[{"type":"text","text":"Original prompt"}]},{"role":"assistant","content":[{"type":"text","text":"Edited answer"}]}]}

title: Editing Mode


[User] Is there a way to highlight some metadata or messages in Euphony?

[Assistant] Yes. Euphony supports conversation and message labels through magic metadata fields such as `euphony_custom_labels` and `euphony_custom_message_labels`.

[Assistant]
{
  "metadata": {
    "euphony_custom_labels": [
      ["score", "8", "Likert score of this conversation", "orangered"],
      ["is_correct", "true", "Whether the final answer is correct", "#2e7d32"]
    ],
    "euphony_custom_message_labels": [
      [0, "Important first user turn", "#006bb2", "important"]
    ]
  }
}

[Assistant] That is useful for evaluation annotations, correctness tags, or any workflow-specific markers you want visible during review.

title: Custom Labels

euphony_custom_labels:
score
8
Likert score of this conversation
orangered

euphony_custom_message_labels:
Important first user turn
#006bb2
important


[User] While skimming, is there a way to understand how the model tokenizes a conversation?

[Assistant] Yes. Euphony supports token visualization with Harmony renderers. Open the token render window for a conversation, choose a renderer, and inspect the rendered text, token IDs, and decoded tokens.

[Assistant] <|start|>user<|message|>Explain quicksort.<|end|><|start|>assistant<|channel|>final<|message|>Quicksort is a divide-and-conquer sorting algorithm...<|end|>

[Assistant] Euphony can also transform Codex sessions into conversations and visualize them just like other conversation data.

title: Harmony Rendering and Codex Sessions