|
| 1 | +# Session Traces Format |
| 2 | + |
| 3 | +Agent traces from Claude Code, Codex, and Pi are supported out of the box (see [Agent Traces](./agent-traces)). If you build your own harness, you can make its sessions render in the same viewer by writing them in the **Session Trace Simple Format (STS-Format)** described below. |
| 4 | + |
| 5 | +The **Session Trace Simple Format (STS-Format)** is a [JSONL](https://jsonlines.org) file (one JSON object per line) that the Hugging Face Hub detects and renders in its trace viewer. It captures a single agent/chat session as a header line followed by message lines. |
| 6 | + |
| 7 | +## 1. Session header (first line) |
| 8 | + |
| 9 | +```json |
| 10 | +{ "type": "session", "harness": "my-agent", "id": "b1a2c3" } |
| 11 | +``` |
| 12 | + |
| 13 | +| field | required | notes | |
| 14 | +| --------- | -------- | ------------------------------------------------- | |
| 15 | +| `type` | yes | must be `"session"` | |
| 16 | +| `harness` | yes | **the id of the harness** that produced the trace | |
| 17 | +| `id` | yes | unique session id | |
| 18 | +| `name` | no | human-readable title | |
| 19 | +| … | no | any extra metadata is allowed and ignored | |
| 20 | + |
| 21 | +`harness` is the key field: it is **the id of the harness**, and it tells the Hub which renderer, icon, and label to use for the session. Currently recognized ids: `llama.app`. It is very easy to add a new harness identifier here. |
| 22 | + |
| 23 | +> Building a harness of your own? Ping us and we'll add an icon and label for it so your sessions render with your branding. |
| 24 | +
|
| 25 | +## 2. Messages (every following line) |
| 26 | + |
| 27 | +Each line is one message in an envelope: |
| 28 | + |
| 29 | +```json |
| 30 | +{ "type": "message", "message": { "role": "assistant", "content": "…" } } |
| 31 | +``` |
| 32 | + |
| 33 | +The `message` object: |
| 34 | + |
| 35 | +| field | required | notes | |
| 36 | +| ------------------ | -------- | ------------------------------------------------------------------------------------------------------ | |
| 37 | +| `role` | yes | `"user"` · `"assistant"` · `"system"` · `"tool"` | |
| 38 | +| `content` | yes | text (may be empty) | |
| 39 | +| `reasoningContent` | no | model reasoning, shown as a separate thinking block | |
| 40 | +| `toolCalls` | no | assistant tool calls: `[{ "id", "function": { "name", "arguments" } }]` (`arguments` is a JSON string) | |
| 41 | +| `toolCallId` | no | on a `role: "tool"` message, links the result to the `toolCalls[].id` it answers | |
| 42 | +| `timestamp` | no | epoch milliseconds | |
| 43 | +| `model` | no | model name | |
| 44 | + |
| 45 | +Tool results are messages with `role: "tool"` carrying a `toolCallId`; the viewer stitches each result next to the call that produced it. |
| 46 | + |
| 47 | +### Example |
| 48 | + |
| 49 | +```jsonl |
| 50 | +{"type":"session","harness":"my-agent","id":"abc123","name":"what time is it"} |
| 51 | +{"type":"message","message":{"role":"user","content":"what time is it?"}} |
| 52 | +{"type":"message","message":{"role":"assistant","content":"","toolCalls":[{"id":"t1","function":{"name":"get_time","arguments":"{}"}}]}} |
| 53 | +{"type":"message","message":{"role":"tool","toolCallId":"t1","content":"2026-07-01T15:00:00Z"}} |
| 54 | +{"type":"message","message":{"role":"assistant","content":"it is 15:00 UTC"}} |
| 55 | +``` |
| 56 | + |
| 57 | +Upload the resulting `.jsonl` to a [Dataset](https://huggingface.co/datasets) or a [Storage Bucket](./storage-buckets) to open it in the trace viewer. |
| 58 | + |
| 59 | +## Alternative: Pi's session format |
| 60 | + |
| 61 | +If you'd rather not adopt the shape above, you can emit **Pi's session format** ([session-format.md](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/session-format.md)), which the Hub already supports. In that case, add a `harness: "..."` field to Pi's session-header line as well, so the Hub can attribute the trace to your harness. |
0 commit comments