[AAASM-3540] ✨ (examples): Add Haystack tool-policy example#149
Conversation
A real Haystack agent governed via the SDK's native adapter: HaystackPatch hooks haystack.tools.Tool.invoke and three real haystack.tools.Tool instances are driven through a genuine ToolInvoker (the agent's tool-dispatch component). An allowed tool runs; the denied execute_sql tool is short-circuited before its body executes — real governance, proven by the no-op-guard smoke test. Offline; no LLM/key. Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add haystack-tool-policy to the python/ and root example galleries. Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirror the per-example verify-python job (uv sync --extra dev + pytest) for the new Haystack example. Refs AAASM-3540 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude Code — review result (Haystack example)
The adapter ships only in python-sdk #160 (unmerged) — so the example's import resolves once #160 merges and a python-sdk release publishes to PyPI. The agent validated the example locally against the #160 branch (real Haystack agent governed via a Merge order: LAST — after python-sdk #160 merges + b5 release. I'll re-confirm this job goes green once b5 is on PyPI. Full cross-repo review on AAASM-3535. |
Sonar S7632 flags the trailing em-dash prose after the noqa codes as a malformed suppression comment. Drop the inline prose; the function's docstring already documents what it returns. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude Code — SonarCloud new-code review (round 2) Found + fixed 1 finding: S7632 MAJOR ✅ Sonar gate OK; 0 new-code issues. (Reminder: the |
The example imports `agent_assembly.adapters.haystack`, which ships only on the SDK's master branch until 0.0.1b5 publishes it to PyPI. Pin the SDK to git master via [tool.uv.sources] so `uv sync` validates the example against the merged adapter (smoke 6/6 green) instead of failing on the PyPI release that predates the adapter. Revert to the PyPI pin once 0.0.1b5 is out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reformat src/ and tests/ to ruff's default 88-col style and type the ToolInvoker helper's tools param as list[Tool] (with the Tool import), dropping the redundant ANN001 suppression. No runtime behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Annotate the governed fixture (Iterator[list[Tool]]), the _by_name helper (list[Tool], str -> Tool), and every test function (-> None / governed param), then drop the now-redundant # noqa: ANN201/ANN202/ANN001 suppressions. Test logic is unchanged. ruff and mypy --strict are now clean over src and tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Resolve shared-file overlaps after the Haystack example (#149) merged: keep BOTH the smolagents-tool-policy and haystack-tool-policy CI jobs (each with its own steps) and both gallery README rows. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>



Description
Adds
python/haystack-tool-policy/— a runnable governance demo for a real Haystack agent using the SDK's native Haystack adapter (AAASM-3540, companion to python-sdk#160 and integration-tests#106).The example installs the native
HaystackPatch(which hookshaystack.tools.Tool.invoke) against a local policy, then drives three realhaystack.tools.Toolinstances through a genuinehaystack.components.tools.ToolInvoker— the exact component a HaystackAgentuses to execute a model-chosen tool call. An allowed tool (query_index) runs; the deniedexecute_sqltool is short-circuited before its body executes. This is genuine governance, not a no-op — theEXECUTEDledger and thetest_denied_tool_body_never_runssmoke test prove the denied tool function never ran.Offline by default: tools are driven via a hand-built
ToolCall, so no LLM or API key is needed (matching the other native-adapter examples likepydantic-ai/google-adk).Also adds the example to both gallery indexes and a
haystack-tool-policyjob toverify-python.yml.Type of Change
Related Issues
Testing
Validated locally against the python-sdk Haystack branch (the adapter is not yet in a published SDK):
The
--mock/offline smoke is the CI path (uv sync --extra dev).Known release-ordering note
uv syncresolvesagent-assemblyfrom PyPI, where the Haystack adapter has not shipped yet (it lands with python-sdk#160). Until a newagent-assemblyrelease includesagent_assembly.adapters.haystack, the CIverify-pythonjob for this example will fail import — exactly as any new native-adapter example does before its SDK release. This PR should merge after the SDK adapter is released (or the smokeimportorskips on the adapter if reviewers prefer; happy to adjust).Checklist
.env.exampleonlyhaystack-aipinned>=2.0.0,<3.0(not a bare>=)🤖 Generated with Claude Code