> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/automodel/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/automodel/_mcp/server.

# nemo_automodel.components.models.kimi_k3.encoding

Kimi K3 XTML encoding helpers.

This module keeps chat rendering in Python.
Callers that need token IDs should consume `EncodeSegment` objects directly:
structural markers may be encoded as tiktoken special tokens, while user/tool
text and attribute values are encoded as ordinary text.

## Module Contents

### Classes

| Name                                                                                        | Description |
| ------------------------------------------------------------------------------------------- | ----------- |
| [`EncodeSegment`](#nemo_automodel-components-models-kimi_k3-encoding-EncodeSegment)         | -           |
| [`_ImagePromptState`](#nemo_automodel-components-models-kimi_k3-encoding-_ImagePromptState) | -           |

### Functions

| Name                                                                                                                            | Description                                                             |
| ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| [`_append_text`](#nemo_automodel-components-models-kimi_k3-encoding-_append_text)                                               | -                                                                       |
| [`_attr`](#nemo_automodel-components-models-kimi_k3-encoding-_attr)                                                             | -                                                                       |
| [`_close_tag`](#nemo_automodel-components-models-kimi_k3-encoding-_close_tag)                                                   | -                                                                       |
| [`_control`](#nemo_automodel-components-models-kimi_k3-encoding-_control)                                                       | -                                                                       |
| [`_end_of_msg`](#nemo_automodel-components-models-kimi_k3-encoding-_end_of_msg)                                                 | -                                                                       |
| [`_escape_attr_value`](#nemo_automodel-components-models-kimi_k3-encoding-_escape_attr_value)                                   | -                                                                       |
| [`_get_value`](#nemo_automodel-components-models-kimi_k3-encoding-_get_value)                                                   | -                                                                       |
| [`_internal_system_message`](#nemo_automodel-components-models-kimi_k3-encoding-_internal_system_message)                       | -                                                                       |
| [`_is_mapping`](#nemo_automodel-components-models-kimi_k3-encoding-_is_mapping)                                                 | -                                                                       |
| [`_json_compact`](#nemo_automodel-components-models-kimi_k3-encoding-_json_compact)                                             | -                                                                       |
| [`_mark_assistant`](#nemo_automodel-components-models-kimi_k3-encoding-_mark_assistant)                                         | -                                                                       |
| [`_open_tag`](#nemo_automodel-components-models-kimi_k3-encoding-_open_tag)                                                     | -                                                                       |
| [`_render_assistant_segments`](#nemo_automodel-components-models-kimi_k3-encoding-_render_assistant_segments)                   | -                                                                       |
| [`_render_content_segments`](#nemo_automodel-components-models-kimi_k3-encoding-_render_content_segments)                       | -                                                                       |
| [`_render_tool_declare`](#nemo_automodel-components-models-kimi_k3-encoding-_render_tool_declare)                               | -                                                                       |
| [`_segment`](#nemo_automodel-components-models-kimi_k3-encoding-_segment)                                                       | -                                                                       |
| [`_text`](#nemo_automodel-components-models-kimi_k3-encoding-_text)                                                             | -                                                                       |
| [`_tool_call_id_index`](#nemo_automodel-components-models-kimi_k3-encoding-_tool_call_id_index)                                 | Map assistant `tool_calls[].id` to `(1-based position, function name)`. |
| [`_xtml_type`](#nemo_automodel-components-models-kimi_k3-encoding-_xtml_type)                                                   | -                                                                       |
| [`_xtml_value`](#nemo_automodel-components-models-kimi_k3-encoding-_xtml_value)                                                 | -                                                                       |
| [`build_chat_segments`](#nemo_automodel-components-models-kimi_k3-encoding-build_chat_segments)                                 | -                                                                       |
| [`deep_sort_dict`](#nemo_automodel-components-models-kimi_k3-encoding-deep_sort_dict)                                           | -                                                                       |
| [`extract_response_schema`](#nemo_automodel-components-models-kimi_k3-encoding-extract_response_schema)                         | -                                                                       |
| [`is_batched_conversation`](#nemo_automodel-components-models-kimi_k3-encoding-is_batched_conversation)                         | -                                                                       |
| [`normalize_conversation`](#nemo_automodel-components-models-kimi_k3-encoding-normalize_conversation)                           | -                                                                       |
| [`normalize_message`](#nemo_automodel-components-models-kimi_k3-encoding-normalize_message)                                     | -                                                                       |
| [`normalize_tool_arguments`](#nemo_automodel-components-models-kimi_k3-encoding-normalize_tool_arguments)                       | -                                                                       |
| [`normalize_xtml_tool_result_messages`](#nemo_automodel-components-models-kimi_k3-encoding-normalize_xtml_tool_result_messages) | Re-sort K3 XTML tool results into assistant `tool_calls` order.         |

### Data

[`CLOSE_TOKEN`](#nemo_automodel-components-models-kimi_k3-encoding-CLOSE_TOKEN)

[`END_OF_MSG_TOKEN`](#nemo_automodel-components-models-kimi_k3-encoding-END_OF_MSG_TOKEN)

[`IMAGE_PLACEHOLDER`](#nemo_automodel-components-models-kimi_k3-encoding-IMAGE_PLACEHOLDER)

[`OPEN_TOKEN`](#nemo_automodel-components-models-kimi_k3-encoding-OPEN_TOKEN)

[`SEP_TOKEN`](#nemo_automodel-components-models-kimi_k3-encoding-SEP_TOKEN)

[`_VALID_THINKING_EFFORTS`](#nemo_automodel-components-models-kimi_k3-encoding-_VALID_THINKING_EFFORTS)

### API

```python
class nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment(
    text: str,
    allow_special: bool = False,
    is_assistant: bool = False
)
```

Dataclass

**`allow_special`** `bool = False`

---

**`is_assistant`** `bool = False`

---

**`text`** `str`

---

```python
class nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState(
    image_prompts: typing.Optional[list[str]] = None
)
```

**`index`** `= 0`

---

```python
nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState.assert_consumed() -> None
```

```python
nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState.next_prompt() -> str
```

```python
nemo_automodel.components.models.kimi_k3.encoding._append_text(
    segments: list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment],
    text: typing.Any,
    image_state: nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState
) -> None
```

```python
nemo_automodel.components.models.kimi_k3.encoding._attr(
    key: str,
    value: typing.Any
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._close_tag(
    tag: str
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._control(
    text: str
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._end_of_msg() -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._escape_attr_value(
    value: typing.Any
) -> str
```

```python
nemo_automodel.components.models.kimi_k3.encoding._get_value(
    obj: typing.Any,
    key: str,
    default: typing.Any = None
) -> typing.Any
```

```python
nemo_automodel.components.models.kimi_k3.encoding._internal_system_message(
    message_type: str,
    body: str
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._is_mapping(
    value: typing.Any
) -> bool
```

```python
nemo_automodel.components.models.kimi_k3.encoding._json_compact(
    value: typing.Any
) -> str
```

```python
nemo_automodel.components.models.kimi_k3.encoding._mark_assistant(
    segments: list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._open_tag(
    tag: str,
    attrs: typing.Iterable[tuple[str, typing.Any]] = ()
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._render_assistant_segments(
    message: dict[str, typing.Any],
    image_state: nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState,
    thinking: bool = True
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._render_content_segments(
    content: typing.Any,
    image_state: nemo_automodel.components.models.kimi_k3.encoding._ImagePromptState
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._render_tool_declare(
    tools: typing.Any,
    dynamic: bool = False
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._segment(
    text: typing.Any,
    allow_special: bool = False
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._text(
    text: typing.Any
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding._tool_call_id_index(
    tool_calls: typing.Any
) -> dict
```

Map assistant `tool_calls[].id` to `(1-based position, function name)`.

The position mirrors the chat template's enumeration over `tool_calls`
(every entry advances the position, even an id-less one). Duplicate ids keep
their first occurrence.

```python
nemo_automodel.components.models.kimi_k3.encoding._xtml_type(
    value: typing.Any
) -> str
```

```python
nemo_automodel.components.models.kimi_k3.encoding._xtml_value(
    value: typing.Any
) -> str
```

```python
nemo_automodel.components.models.kimi_k3.encoding.build_chat_segments(
    messages: list[typing.Any],
    tools: typing.Optional[list[dict]] = None,
    add_generation_prompt: bool = True,
    thinking: bool = True,
    image_prompts: typing.Optional[list[str]] = None,
    kwargs: typing.Any = {}
) -> list[nemo_automodel.components.models.kimi_k3.encoding.EncodeSegment]
```

```python
nemo_automodel.components.models.kimi_k3.encoding.deep_sort_dict(
    obj: typing.Any
) -> typing.Any
```

```python
nemo_automodel.components.models.kimi_k3.encoding.extract_response_schema(
    response_format: typing.Any
) -> typing.Any
```

```python
nemo_automodel.components.models.kimi_k3.encoding.is_batched_conversation(
    conversation: typing.Any
) -> bool
```

```python
nemo_automodel.components.models.kimi_k3.encoding.normalize_conversation(
    conversation: typing.Any
) -> typing.Any
```

```python
nemo_automodel.components.models.kimi_k3.encoding.normalize_message(
    message: typing.Any
) -> typing.Any
```

```python
nemo_automodel.components.models.kimi_k3.encoding.normalize_tool_arguments(
    arguments: typing.Any
) -> tuple[dict[str, typing.Any], typing.Optional[str]]
```

```python
nemo_automodel.components.models.kimi_k3.encoding.normalize_xtml_tool_result_messages(
    messages: list[typing.Any]
) -> list[typing.Any]
```

Re-sort K3 XTML tool results into assistant `tool_calls` order.

Serving frameworks generally deliver tool results already in call order. A
direct Transformers caller, however, may pass OpenAI-style tool messages in any
order, so each run of consecutive tool messages is matched against the most
recent preceding assistant `tool_calls` by opaque `tool_call_id` ==
`tool_calls[].id` (K3 drops the `func:index` format requirement) and
sorted by the matched 1-based position. The matched call is authoritative,
so each matched message's `tool` is set to that call's function name --
this keeps an explicit (and possibly stale) `tool`/`name` from drifting
out of sync with the reordered position. `index` is still derived from the
rendered position by the chat template. A run that cannot be fully matched is
left untouched. Re-running is idempotent.

This function is side-effect free: matched tool messages are shallow-copied
before their `tool`/`name` is rewritten, and every other message is
appended to the output as-is. The input list and its message objects are
never mutated.

```python
nemo_automodel.components.models.kimi_k3.encoding.CLOSE_TOKEN = '<|close|>'
```

```python
nemo_automodel.components.models.kimi_k3.encoding.END_OF_MSG_TOKEN = '<|end_of_msg|>'
```

```python
nemo_automodel.components.models.kimi_k3.encoding.IMAGE_PLACEHOLDER = '<|kimi_image_placeholder|>'
```

```python
nemo_automodel.components.models.kimi_k3.encoding.OPEN_TOKEN = '<|open|>'
```

```python
nemo_automodel.components.models.kimi_k3.encoding.SEP_TOKEN = '<|sep|>'
```

```python
nemo_automodel.components.models.kimi_k3.encoding._VALID_THINKING_EFFORTS = {'low', 'medium', 'high', 'max'}
```