Skip to content

fix(agno): route tools to metadata, materialize media attachments, propagate exception objects#582

Merged
Abhijeet Prasad (AbhiPrasad) merged 4 commits into
mainfrom
fix/agno-skill-compliance
Jul 16, 2026
Merged

fix(agno): route tools to metadata, materialize media attachments, propagate exception objects#582
Abhijeet Prasad (AbhiPrasad) merged 4 commits into
mainfrom
fix/agno-skill-compliance

Conversation

@starfolkai

@starfolkai starfolkai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Align the Agno integration with .agents/skills/sdk-integrations/SKILL.md. Audit turned up six issues; this PR fixes five (a metric-key concern was retracted as widely-used).

  • Errorsspan.log(error=e) instead of span.log(error=str(e)) across all 15 wrappers, matching the anthropic pattern.
  • Tool placementtools, tool_choice, functions, tool_call_limit route into metadata via a new _split_model_call() helper (fixes the pre-existing tool_chocie typo by construction).
  • Instrumentation isolationFunctionCall._build_entrypoint_args() and instance.function.* reads are now guarded so extraction failures don't escape into the user's tool exec.
  • Multimodal — inline Image / Audio / Video / File bytes get materialized to Braintrust Attachments (via _materialize_attachment in integrations/utils.py), applied to input messages, non-streaming model output, and both streaming aggregators. Images use image_url.url; other media use file.file_data; remote urls pass through verbatim.
  • Deleted dead get_args_kwargs (superseded by _split_model_call).

Test plan

  • cd py && CI=1 BRAINTRUST_TEST_PACKAGE_VERSION=latest OPENAI_API_KEY=sk-test python -m pytest src/braintrust/integrations/agno/ — 34 passed, 3 skipped (2 new cassettes pending, 1 pre-existing importorskip).
  • Extended test_agno_simple_agent_execution (existing cassette) with a negative assertion that tool fields never appear in input.
  • Cassettes pending — record with real OpenAI credentials for the two new positive tests. _skip_if_cassette_missing() keeps CI green in the meantime:
    nox -s "test_agno(latest)" -- --vcr-record=all \ -k "test_agno_agent_tools_metadata_placement or test_agno_agent_image_input_materializes_attachment"
  • cd py && make lint

Notes

  • The tool schema Agno passes to Model.response(tools=...) is {name, description, parameters, ...} — not yet wrapped in the OpenAI {"type": "function", "function": {...}} envelope. Placement is now correct (metadata, not input); full OpenAI-shape normalization is a follow-up.
  • Attachment materialization is scoped to the model wrappers. Agent/Team outputs (RunOutput) can also carry media — worth revisiting once the model-side fix has some soak time.

🤖 Generated with Claude Code

Created by abhijeet

Slack thread

starfolkbot and others added 4 commits July 16, 2026 19:51
Align the Agno integration with `.agents/skills/sdk-integrations/SKILL.md`.

- Pass `Exception` instances to `span.log(error=...)` instead of `str(e)`,
  matching the anthropic pattern and giving Braintrust a chance to extract
  structured error info.
- Route `tools`, `tool_choice`, `functions`, and `tool_call_limit` into
  `metadata` rather than `input` via a new `_split_model_call()` helper.
  Fixes the pre-existing `tool_chocie` typo by construction.
- Guard `FunctionCall._build_entrypoint_args()` and attribute reads on
  `instance.function.*` so extraction failures no longer escape into the
  user's tool exec path.
- Materialize inline `Image` / `Audio` / `Video` / `File` bytes as Braintrust
  `Attachment`s using `_materialize_attachment` from `integrations/utils.py`.
  Applied to model input `messages`, non-streaming model output, and both
  streaming aggregators. Images land under `image_url.url`, other media
  under `file.file_data` with `filename` preserved, remote `url`s pass
  through verbatim.
- Fix an off-by-check bug in the existing `get_args_kwargs` helper (would
  IndexError when kwargs-only, then removed since it's now unused).
- Extend `test_agno_simple_agent_execution` with a negative assertion that
  tool-related keys never leak into `input`.
- Add `test_agno_agent_tools_metadata_placement` (tools) and
  `test_agno_agent_image_input_materializes_attachment` (vision) as
  cassette-backed positive tests. Both call `_skip_if_cassette_missing()`
  so CI stays green until the cassettes are recorded.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
`_prepare_model_input` and `_prepare_model_output` used to call
`_try_to_dict()` on every model turn — a wasted `.model_dump()` on
non-media calls, since Braintrust's log-time serializer already handles
dataclasses and Pydantic models. Now they check for inline `content`
bytes or `filepath` first and pass the raw SDK object through when no
materialization is needed. Only calls that actually carry binary media
pay for the conversion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@starfolkai starfolkai Bot changed the title fix(agno): SKILL-compliance for spans, tools, errors, and multimodal fix(agno): route tools to metadata, materialize media attachments, propagate exception objects Jul 16, 2026
@AbhiPrasad Abhijeet Prasad (AbhiPrasad) marked this pull request as ready for review July 16, 2026 21:15
@AbhiPrasad Abhijeet Prasad (AbhiPrasad) merged commit cb8323f into main Jul 16, 2026
82 checks passed
@AbhiPrasad Abhijeet Prasad (AbhiPrasad) deleted the fix/agno-skill-compliance branch July 16, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants