[AAASM-3540] ✨ (adapters): Add Haystack framework adapter#160
Conversation
Govern deepset Haystack 2.x agents by patching haystack.tools.Tool.invoke, the single execution chokepoint through which both direct Tool.invoke() calls and the Agent/ToolInvoker tool-call loop flow. Pre-execution allow/deny/pending gate plus post-execution result recording; unknown verdicts fail closed under enforce (AAASM-3107). Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add HaystackAdapter to the builtin adapter list and priority map so init_assembly() auto-detects and hooks Haystack when it is importable. Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prove real governance, not a no-op: deny blocks the underlying tool function and returns a policy string; allow runs and records; pending waits for approval; unknown verdicts fail closed under enforce. The negative-control tests drive a real haystack.tools.Tool and assert the wrapped function never executes on deny. Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add Haystack to the framework-compatibility tables in the README and the authoritative docs/compatibility/frameworks.md (supported range >=2.0.0,<3.0, tested 2.30.x, Tool.invoke hook point). Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
|
Claude Code — review result ✅ Real CI green. Only SonarCloud fails — acceptance gate, ignored per standing rule.
Ready to merge. Merge before the examples PR #149 + a python-sdk release (the example import resolves only after b5 is on PyPI). Full cross-repo review on AAASM-3535. |
|
Claude Code — SonarCloud new-code review (round 2) New-code pass: 0 issues — no new Security / Reliability / Maintainability / Hotspot / Coverage findings. The quality gate is red solely on ✅ Ready to merge (modulo the trivial keep-all rebase as siblings land). |
Resolve the registry + README overlaps after py #160 (Haystack) merged: keep both the Haystack (now on master) and Smolagents registry entries, adapter imports, builtin-list entries, and the combined README adapter list. frameworks.md auto-merged (both rows present). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve registry + README overlaps after py #160 (Haystack) merged: keep both the Haystack (master) and Agno entries/imports/builtins and the combined README adapter list. frameworks.md + compat table auto-merged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve registry + README + frameworks.md overlaps after py #160 (Haystack) merged: keep both frameworks' entries/imports/builtins/rows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve registry + README overlaps after py #160 (Haystack) merged: keep both frameworks' entries/imports/builtins. frameworks.md + compat table auto-merged (both rows present). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>


Description
Adds full Python SDK governance support for deepset Haystack (
pip install haystack-ai, imported ashaystack).The adapter intercepts tool execution at
haystack.tools.Tool.invoke(**kwargs)— the single execution chokepoint in Haystack 2.x. Both the bareTool.invoke()path and the agenticAgent→ToolInvokertool-call loop ultimately calltool.invoke(**final_args)(viaToolInvoker._make_context_bound_invoke), so patchingTool.invokegoverns every tool execution from one place.Governance behavior mirrors the CrewAI / Pydantic AI tool-call adapters: a
check_tool_startpre-execution allow/deny/pending gate, an optionalwait_for_tool_approvalpending flow, and post-executionrecord_result/on_tool_endauditing. Unknown / malformed verdicts fail closed under theenforceposture (AAASM-3107).HaystackAdapteris registered in the builtin registry and priority map, soinit_assembly()auto-detects and hooks Haystack whenever it is importable.Type of Change
Breaking Changes
Related Issues
Testing
test/unit/adapters/haystack/test_patch.py(24 tests). Proves real governance, not a no-op (AAASM-3528 lesson):test_real_haystack_tool_is_genuinely_governed— drives a realhaystack.tools.Tool; ondenythe wrapped function never runs (side_effects == []) and a[BLOCKED by governance policy]string is returned; afterrevert()the same tool runs normally. This is the negative control — it fails if the patch is a pass-through.test_real_haystack_tool_allow_runs_and_records— real Tool runs onallowand the result is recorded.Validated locally: full suite
pytest test/→ 603 passed, 13 skipped;ruff checkclean on new files;mypy agent_assemblyclean for the new module (only pre-existing_core/grpc-stub errors remain); pre-commit (black/isort/autoflake/mypy) green.Checklist
docs/compatibility/frameworks.md)🤖 Generated with Claude Code