# Code study — chat & tools protocol

Primary: [`reference/hub/chat_template.jinja`](../reference/hub/chat_template.jinja)  
Token table: [`derived/special_tokens.md`](../derived/special_tokens.md)

---

## Roles

| Role | Token | ID |
|---|---|---|
| user | `<\|message_user\|>` | 200000 |
| model | `<\|message_model\|>` | 200001 |
| system | `<\|message_system\|>` | 200002 |
| tool | `<\|message_tool\|>` | 200003 |

Messages end with `
` (200010).

---

## Content kinds

| Kind | Token | ID |
|---|---|---|
| text | `<\|content_text\|>` | 200004 |
| thinking | `<\|content_thinking\|>` | 200008 |
| image BOS | `<\|content_image\|>` | 200005 |
| audio BOS | `<\|content_audio_input\|>` | 200020 |
| image soft slot | `<\|unused_200054\|>` | 200054 |
| audio soft slot | `<\|unused_200053\|>` | 200053 |
| audio end | `<\|audio_end\|>` | 200043 |
| tool invoke JSON | `<\|content_invoke_tool_json\|>` | 200049 |
| tool invoke text | `<\|content_invoke_tool_text\|>` | 200057 |
| tool error | `<\|content_tool_error\|>` | 200022 |
| xml / tool declare body | `<\|content_xml\|>` | 200024 |
| end sampling | `<\|content_model_end_sampling\|>` | 200006 |

Soft slots are **expanded** by the processor to match patch/frame counts; BOS markers stay as ordinary embedded tokens.

---

## Thinking effort injection

Template maps aliases → floats and emits a **system** message:

```


Thinking effort level: 0.9

```

Rules:

- default **0.9** if unspecified  
- allowed numeric range **[0.0, 0.99]**  
- emitted once before the first non-system message (or at end if only systems)  

Aliases: `none=0`, `minimal=0.1`, `low=0.2`, `medium=0.7`, `high=0.9`, `max=0.99`.

---

## Tools

If `tools` provided:

1. Build list of `{name, description, parameters, type}`  
2. Emit system message: `tool_declare` + `
` + compact JSON  

Model tool call shape:

```

{fn_name}
{"name":...,"args":...}

```

Tool result:

```

{fn_name}
{result}

```

Assistant turns may include `
…` then answer content, then tool calls, then `
`.

---

## Generation prompt

With `add_generation_prompt=true`, template ends with:

```


```

---

## Practical rules

1. Never hand-roll special token strings for production — use `apply_chat_template` / `tml-renderers`.  
2. Tool `arguments` must be objects, not pre-stringified JSON (template raises).  
3. Effort is part of the *prompt distribution* the model was RL’d on — omitting it changes behavior.  

Next: [03-multimodal-io.md](03-multimodal-io.md)