pub struct Turn {
pub role: String,
pub content: String,
pub tool_calls: Vec<ToolCall>,
pub reasoning: Option<String>,
pub tool_call_id: Option<String>,
pub tool_name: Option<String>,
pub tool_responses: Vec<(String, Val)>,
pub task: Option<String>,
pub tools: Vec<Val>,
}Expand description
One chat turn for the tools-capable renderer (apply_chat_template_tools).
The reasoning/tool_call_id/tool_name/tool_responses fields are read ONLY by the
gemma4 arm; the qwen/step arms use role/content/tool_calls and leave the rest default.
Fields§
§role: String§content: String§tool_calls: Vec<ToolCall>§reasoning: Option<String>gemma4: assistant reasoning re-rendered as a <|channel>thought span (only for a
tool_calls-carrying assistant after the last user message — the template’s guard).
tool_call_id: Option<String>gemma4: on a role:“tool” turn, the OpenAI tool_call_id used to resolve the response
name against the preceding assistant’s tool_calls[].id.
tool_name: Option<String>gemma4: on a role:“tool” turn, the message’s own name field (fallback when the id
does not resolve).
tool_responses: Vec<(String, Val)>gemma4 native (Google) responses embedded on an assistant turn: (name, response value). OpenAI histories leave this empty and use role:“tool” turns instead.
task: Option<String>deepseek-v4 quick-instruction task token (action/query/authority/domain/
title/read_url, encoding_dsv4 DS_TASK_SP_TOKENS). Set only by the dsv4 fixture
harness (the internal-classification heads); the OpenAI serve surface has no task
field, so every serve request leaves this None and every other dialect ignores it.
tools: Vec<Val>deepseek-v4 per-turn tool function objects (encoding_dsv4 renders the tool
declaration on the message carrying them — system on the serve surface, or a developer
message in the search-pipeline fixtures). The serve path also passes request-level
tools via tools_struct, which the dsv4 arm folds onto the leading system turn.
Every other dialect ignores this.