> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cartesia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CHANGELOG 0.2.3

## Detailed Changelog: v0.2.2 → v0.2.3

### Feature: History Management API

`LlmAgent` now exposes a `self.history` attribute of type `History`, providing structured control over the conversation history that the LLM sees.

**`history.add_entry(content, role, *, before, after)`**

Inserts a `CustomHistoryEntry` into the conversation history. The entry appears as a message with the given `role` (`"system"` or `"user"`) in the LLM conversation. Positioning is controlled via anchors:

* No anchor: appends to the current end of history.
* `before=event`: inserts immediately before the specified event.
* `after=event`: inserts immediately after the specified event.

Raises `ValueError` if both `before` and `after` are specified, or if the anchor event is not found in the current history.

```python theme={null}
# Append a user note at the end (role="user" is the default)
agent.history.add_entry("The user prefers formal language.")

# Insert before a specific event
agent.history.add_entry("Context about the caller.", before=some_event)
```

**`history.update(events, *, start, end)`**

Replaces a segment of history with new events. Behavior depends on which anchors are provided:

* Neither `start` nor `end`: replaces the entire history as it currently exists.
* `start` only: replaces everything from `start` through the current end of history.
* `end` only: replaces everything from the beginning through `end` with `events`.
* Both `start` and `end`: replaces the segment `[start..end]` inclusive with `events`.

Raises `ValueError` if anchors are not found or `end` appears before `start`.

***

### Feature: Per-Turn Overrides on `process()`

`LlmAgent.process()` now accepts four arguments that apply to just that turn:

**`config: Optional[LlmConfig]`**

Merged onto the agent's stored config for this turn only. Uses a layered merge where the last explicitly-set value wins (agent default \< stored config \< per-turn override).

```python theme={null}
# Use a higher temperature for just this turn
await agent.process(env, event, config=LlmConfig(temperature=0.9))
```

Only the fields you explicitly set in the override `LlmConfig` take effect. Unset fields fall through to the agent's stored config.

**`tools: Optional[List[ToolSpec]]`**

Tools with matching names replace those in the agent's tool list; unmatched base tools are preserved. This lets you swap out a specific tool's implementation for one turn without losing the rest.

```python theme={null}
# Replace just the "lookup" tool for this turn
await agent.process(env, event, tools=[custom_lookup_tool])
```

**`context: Union[str, List[HistoryEvent], None]`**

Extra context appended to the end of history for message building. If a string, it is automatically wrapped as a user message. If a list of events, they are appended as-is. Not persisted — only affects this single turn.

```python theme={null}
# Inject ephemeral context
await agent.process(env, event, context="The user is a VIP customer.")
```

**`history: Optional[List[HistoryEvent]]`**

Completely overrides the managed history for this turn. The managed history still receives normal updates (so subsequent turns without the override see the full history).

***

### Feature: Configurable `EndCallTool`

`end_call` now accepts an `description` argument.

```python theme={null}
from line.llm_agent.tools.system import end_call

# Custom — control when the LLM ends the call
LlmAgent(tools=[end_call(description="End when the customer confirms their order.")])
```

***

### Feature: Multilingual STT/TTS Language Support

`AgentUpdateCall` now has a `language` field:

```python theme={null}
yield AgentUpdateCall(voice_id="some-voice", language="es")
```

to specify TTS/STT language. Use `language="multilingual"` to enable automatic language detection.

***

### Feature: Custom Events

Two new event types enable arbitrary metadata exchange between agent code and the harness.

**Agent → Harness: `AgentSendCustom`**

```python theme={null}
yield AgentSendCustom(metadata={"action": "show_form", "form_id": "checkout"})
```

**Harness → Agent: `UserCustomSent`**

Received when the call side sends a custom event to the agent.

***

### Feature: Agent-as-Handoff Update Parameters

`agent_as_handoff()` now accepts an `update_call` parameter to change voice/STT/TTS settings during a handoff:

```python theme={null}
from line.llm_agent.tools.system import agent_as_handoff, UpdateCallConfig

spanish_agent = LlmAgent(
    model="gemini/gemini-2.5-flash-preview-09-2025",
    config=LlmConfig(system_prompt="You speak only in Spanish."),
)

main_agent = LlmAgent(
    model="gemini/gemini-2.5-flash-preview-09-2025",
    tools=[
        agent_as_handoff(
            spanish_agent,
            handoff_message="Transferring you to our Spanish-speaking agent...",
            update_call=UpdateCallConfig(
                voice_id="spanish-voice-id",
                language="es",
            ),
            name="transfer_to_spanish",
            description="Transfer to a Spanish-speaking agent when requested.",
        ),
    ],
)
```

`UpdateCallConfig` supports `voice_id`, `pronunciation_dict_id`, and `language`.

***

### Feature: LLM Agent Timing Metrics

Three `LogMetric` events are now automatically emitted on every turn.

| Metric               | Description                                                                            |
| -------------------- | -------------------------------------------------------------------------------------- |
| `llm_first_chunk_ms` | Time from start of response generation to first chunk (text or tool call) from the LLM |
| `llm_first_text_ms`  | Time from start of response generation to first *text* chunk.                          |
| `agent_turn_ms`      | Total agent processing time for the turn, from start to completion.                    |
