HTML Viewer
The viewer turns an InifDocument into a single HTML file with no server, no build step, and no external dependencies. It’s the same renderer used by the inif view CLI command.
What you get
- Collapsible sidebar listing every sample, with pass/fail indicators when the sample carries scores.
- Token-level display: each token is one element with hover tooltips showing its id, string, and every extra field present.
- Annotation highlighting with a color legend per sample. Roles (
system/user/assistant/tool/template) get stable colors; reasoning and tool-call sub-text annotations have their own contrasting palette; user-defined annotations are auto-assigned from a 12-color pastel palette. - Per-message panels driven by
Sample.texts— each message renders its ownvalue(with markdown for assistant content), nested children for reasoning / content / tool-call sub-sections, and a labeledtokens/texttoggle that swaps the panel between the rendered text view and the corresponding token strip for that message’s range. - Span borders and underline indicators for tokens carrying extras (e.g.
logprob,logit_lens,probe_score). - Newline-aware token wrapping — visual line breaks are inserted after newline tokens so multi-line outputs are readable.
Three entry points
All three are methods on InifDocument:
| Method | Returns | Use when |
|---|---|---|
doc.render_html() |
str of HTML |
You want to embed the markup or post-process it. |
doc.save_html(path) |
None (writes file) |
You want a file on disk. |
doc.show() |
Jupyter HTML object |
You’re in a notebook. |
All three accept the same shaping arguments:
| Arg | Default | Effect |
|---|---|---|
compact |
False |
When True, hides empty panels (no annotations / no extras / no scores). |
title |
None |
Custom page title. Falls back to source filename then to model name. |
tokenizer |
None |
When given, the tokenizer’s byte-level newline (e.g. Ċ for GPT-2) is auto-detected so visual line breaks fire after BPE newline tokens too. |
save_html also takes source: str | Path | None so it can default the title to the source filename. The CLI uses this to make the page title read like traces.inif.json instead of inif: gpt2.
From Jupyter
from inif import InifDocument
doc = InifDocument.load("traces.inif.json")
doc.show()The page is rendered inline. Use doc.show(compact=True) when sharing in a notebook export to drop the empty panels.
To disk
doc.save_html("traces.html")
doc.save_html("traces.html", compact=True, title="Eval results — gpt2")The output is fully self-contained — no external CSS or JS. You can open the file directly, share it, or commit it to a repo.
From the CLI
inif view traces.inif.json # opens in browser
inif view traces.inif.json -o traces.html # saves to disk
inif view traces.inif.json --compact --title "Run 42"When -o is omitted, the CLI writes to a temp file and opens it in your default browser via webbrowser.open. See the CLI reference for all flags.
Newline handling
Tokenizers that split tokens by byte (GPT-2 family, most BPE variants) encode "\n" as a non-"\n" glyph (e.g. "Ċ"). Without the tokenizer, the viewer only knows about "\n" and won’t break lines for those tokens.
Pass tokenizer to opt in to auto-detection:
from transformers import AutoTokenizer
from inif import InifDocument
tokenizer = AutoTokenizer.from_pretrained("gpt2")
doc = InifDocument.load("traces.inif.json")
doc.save_html("traces.html", tokenizer=tokenizer)The CLI’s view subcommand does not take a tokenizer — line breaks for byte-level newline glyphs require the Python API.
What’s not in the viewer
- Editing. The page is read-only; annotations and extras are baked in at render time.
- Live filtering across samples. The sidebar lists samples and you click one at a time. For corpus-level analysis, query the document in Python via the selectors.
- Custom theming. Colors are hard-coded for stability; if you need a different palette, post-process the HTML or contribute a config.