Skip to content

AG UI: Validation errors when using reasoning models with Ollama (gpt-oss and qwen3)Β #2766

@celeritatem

Description

@celeritatem

Initial Checks

Description

I am encountering some validation errors when running ag-ui with Ollama running two different reasoning models: gpt-oss:20b and qwen3:4b.

I am trying to implement the simplest examples from pydantic-ai's ag-ui docs (https://ai.pydantic.dev/ag-ui/#installation) and the simplest chat with your agent example from the ConvexKit quickstart (https://docs.copilotkit.ai/pydantic-ai/quickstart/pydantic-ai?path=exiting-agent).

I am completely new to pydantic-ai and ag-ui so its possible I might just be making an obvious mistake. If that's the case, please point me in the correct direction. Thanks.

gpt-oss:20b

I get the following error:

File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 366, in run_ag_ui
    raise e
  File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 356, in run_ag_ui
    async for event in _agent_stream(run):
  File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 390, in _agent_stream
    async for msg in _handle_model_request_event(stream_ctx, agent_event):
  File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 471, in _handle_model_request_event
    yield TextMessageContentEvent(
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File .../.venv/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
    validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pydantic_core._pydantic_core.ValidationError: 1 validation error for TextMessageContentEvent
delta
  String should have at least 1 character [type=string_too_short, input_value='', input_type=str]

The example worked as expected after I modified the TextMessageContentEvent instantiation around line 470 in the _handle_model_request_event function in ag_ui.py as follows,

            # Orig:
            # yield TextMessageContentEvent(
            #     message_id=stream_ctx.message_id,
            #     delta=delta.content_delta,
            # )
            if len(delta.content_delta) > 0:
                yield TextMessageContentEvent(
                    message_id=stream_ctx.message_id,
                    delta=delta.content_delta,
                )

qwen3:4b

I tried the same example with a different reasoning model to confirm the bug and I got a different error:

 File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 366, in run_ag_ui
    |     raise e
    |   File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 356, in run_ag_ui
    |     async for event in _agent_stream(run):
    |   File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 390, in _agent_stream
    |     async for msg in _handle_model_request_event(stream_ctx, agent_event):
    |   File ".../.venv/lib/python3.12/site-packages/pydantic_ai/ag_ui.py", line 459, in _handle_model_request_event
    |     yield ThinkingTextMessageContentEvent(
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File ".../.venv/lib/python3.12/site-packages/pydantic/main.py", line 253, in __init__
    |     validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self)
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | pydantic_core._pydantic_core.ValidationError: 1 validation error for ThinkingTextMessageContentEvent
    |   Value error, Delta must not be an empty string [type=value_error, input_value={'type': <EventType.THINK..._CONTENT'>, 'delta': ''}, input_type=dict]

There is a comment above line 459 about always sending empty content which confuses me because it seems to contradict the validation check in the ThinkingTextMessageContentEvent:

           # Always send the content even if it's empty, as it may be
            # used to indicate the start of thinking.
            yield ThinkingTextMessageContentEvent(
                type=EventType.THINKING_TEXT_MESSAGE_CONTENT,
                delta=part.content,
            )
class ThinkingTextMessageContentEvent(BaseEvent):
  ...
    def model_post_init(self, __context):
        if len(self.delta) == 0:
            raise ValueError("Delta must not be an empty string")

If I ignore the comment and add a delta length check as follows, I then get the same validation error I got with gpt-oss:20b. But, if I add another length check before instantiating the event the agent simply doesn't respond causing an error in the frontend Cannot send 'THINKING_TEXT_MESSAGE_START' event: A thinking step is not in progress. Create one with 'THINKING_START' first..

           # modification to line 459 _handle_model_request_event function in ag_ui.py
           if len(part.content) > 0:
                yield ThinkingTextMessageContentEvent(
                    type=EventType.THINKING_TEXT_MESSAGE_CONTENT,
                    delta=part.content,
                )

Example Code

from fastapi import FastAPI
from pydantic_ai import Agent
from pydantic_ai.ag_ui import handle_ag_ui_request
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.ollama import OllamaProvider
from starlette.requests import Request
from starlette.responses import Response

# Model:
model_name = "qwen3:4b" # OR, "gpt-oss:20b"

model = OpenAIChatModel(
    model_name=model_name,
    provider=OllamaProvider(base_url="http://127.0.0.1:11434/v1"),
)

agent = Agent(model)

# app = agent.to_ag_ui()

app = FastAPI()

@app.post("/")
async def run_agent(req: Request) -> Response:
    return await handle_ag_ui_request(agent, req)

Python, Pydantic AI & LLM client version

Python 3.12.3
pydantic v2.11.7
pydantic-ai-slim[ag-ui, openai] v0.8.1
ag-ui-protocol v0.1.8

Ollama + LLMs:
---------------
ollama 0.11.6
qwen3:4b             e55aed6fe643
gpt-oss:20b          aa4295ac10c3

JS Client:
-----------
"@copilotkit/react-core": "^1.10.3",
"@copilotkit/react-ui": "^1.10.3",
"@copilotkit/runtime": "^1.10.3",

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions