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

# History

> Access conversation turn history as UserInput and AgentResponse objects from conv.history.

<Info>
  **This page requires Python familiarity.** It covers accessing conversation history from Python functions.
</Info>

The `conv.history` attribute contains a chronological list of `UserInput` and `AgentResponse` objects representing the conversation so far.

<Note>
  As the platform evolves, `conv.history` may include new event types beyond `UserInput` and `AgentResponse`. Use `isinstance()` checks rather than `event.role` comparisons to safely filter events – this ensures your code won't break if new event types are introduced that don't have a `role` attribute.
</Note>

## `UserInput`

Represents a user turn in the conversation.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
for event in conv.history:
    if isinstance(event, UserInput):
        print(f"User said: {event.text}")
```

### Properties

| Property | Type | Description                                                                                     |
| -------- | ---- | ----------------------------------------------------------------------------------------------- |
| `text`   | str  | The user's input text. Can be an empty string when the user is silent or no speech is detected. |
| `role`   | str  | Always `"user"`                                                                                 |

### Methods

| Method        | Returns | Description                               |
| ------------- | ------- | ----------------------------------------- |
| `to_dict()`   | dict    | Returns `{"type": "user", "text": "..."}` |
| `to_string()` | str     | Returns `"User: <text>"`                  |

## `AgentResponse`

Represents an agent turn in the conversation.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
for event in conv.history:
    if isinstance(event, AgentResponse):
        print(f"Agent said: {event.text}")
```

### Properties

| Property | Type | Description               |
| -------- | ---- | ------------------------- |
| `text`   | str  | The agent's response text |
| `role`   | str  | Always `"agent"`          |

### Methods

| Method        | Returns | Description                                |
| ------------- | ------- | ------------------------------------------ |
| `to_dict()`   | dict    | Returns `{"type": "agent", "text": "..."}` |
| `to_string()` | str     | Returns `"Agent: <text>"`                  |

## Example: format history for logging

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def log_conversation(conv: Conversation):
    for event in conv.history:
        conv.log.info(event.to_string())
```

## Example: get last user message

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def get_last_user_input(conv: Conversation) -> str:
    for event in reversed(conv.history):
        if isinstance(event, UserInput):
            return event.text
    return ""
```

## Notes

* **Empty `text` values**: `UserInput.text` can be an empty string (e.g., when a user is silent or no speech is detected). Guard against this in your functions if downstream logic depends on non-empty input:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
last_input = get_last_user_input(conv)
if last_input.strip():
    # Process the input
    pass
```

* **Metric events**: Metric data is not part of `conv.history`. Custom metrics are written separately via [`conv.write_metric`](./conv-object#write-metric).

## See also

* [`conv` object](./conv-object) – full list of conversation methods and attributes.
