[AAASM-3537] ✨ (examples): Add Agno tool-policy example#151
Conversation
…pter A runnable offline demo that governs real Agno @tool functions through the SDK's native Agno adapter (AgnoPatch over FunctionCall.execute): get_weather and summarize_docs are allowed, execute_sql is blocked before its body runs. Refs AAASM-3537 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drive real Agno tools through AgnoPatch and assert a denied tool's body never runs (negative control) and an allowed tool returns its real output. Refs AAASM-3537 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the example README and list it in the Python examples index. Refs AAASM-3537 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an agno-tool-policy job mirroring the other per-example smoke jobs. Refs AAASM-3537 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude Code — review result (Agno example)
Two non-defect reds to note:
Validated locally: 6 smoke tests pass; |
SonarCloud flagged the agno-tool-policy job's actions as a security hotspot (tag-pinned, not SHA-pinned). Pin actions/checkout and astral-sh/setup-uv to full commit SHAs (annotated with the tracked major version) to remove the supply-chain hotspot on this job's new code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude Code — SonarCloud new-code review (round 2) Found + fixed 1 security finding: hotspot ✅ SonarCloud quality gate flipped to OK; 0 new-code issues, hotspot resolved. (The |
The PyPI agent-assembly pin does not yet ship the native agno adapter. Track the python-sdk git master so the example validates against the merged adapter; it greens automatically once the agno adapter lands on master (revert to the PyPI pin when 0.0.1b5 publishes it). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wrap long lines per ruff format and replace the loose object/dict annotations on _run_governed_call with precise Function and dict[str, str] types so mypy --strict passes. Re-resolve the agent-assembly git pin to current python-sdk master so the native agno adapter import resolves. No runtime behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace loose object/dict typing in the _run helper with precise Agno types (Function, dict[str, Any], FunctionExecutionResult) so mypy --strict passes over both src and tests. Coerce Optional[Any] tool results via str() at the assertion sites. No logic or behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|



Description
Adds
python/agno-tool-policy, a runnable offline example that governs a realAgno (formerly Phidata) agent's tools through the SDK's native Agno
adapter — not a no-op.
Agno runs every function-tool call through
agno.tools.function.FunctionCall.execute;the SDK's Agno adapter patches that chokepoint so governance runs before the tool
body. The example drives real Agno
@toolfunctions exactly as an AgnoAgentdoes (
FunctionCall(...).execute()), wired to a local offline policy:get_weather,summarize_docs→ allowed, run and return their real output;execute_sql→ denied, body short-circuited before it runs.Mirrors the existing
*-tool-policyexamples (src/main.py, src/tools.py,src/policy.py, tests/test_smoke.py, README, .env.example) and adds a CI job to
verify-python.yml.The smoke tests are a genuine governance proof: the deny test asserts the denied
tool's body never executed (a no-op patch would let it run), and the allow
test asserts the real body ran.
Cross-repo dependency
The example imports
agent_assembly.adapters.agno, which ships in the python-sdkAAASM-3537 branch (PR ai-agent-assembly/python-sdk#162). Until that lands and
a release is published to PyPI,
uv syncshould install the SDK from that branch.This is noted in the example's
pyproject.tomland README.Verification
Validated locally against the python-sdk AAASM-3537 branch:
Refs AAASM-3537
🤖 Generated with Claude Code