[AAASM-3538] ✨ (examples): Add Microsoft Agent Framework example#153
Conversation
A runnable governance demo wiring Microsoft Agent Framework into Agent Assembly. The adapter patches `agent_framework.FunctionTool.invoke`, so a denied tool is short-circuited before its body runs. Two paths, mirroring the gallery: `--mock` (default, CI) replays the policy contract offline with no framework import; the live path drives the real `FunctionTool.invoke` (registering the adapter before init_assembly so the LocalPolicyEngine stays wired). `agent-framework` sits under the `live` extra (heavy, pre-release tree); smoke tests importorskip it. Refs AAASM-3538 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Refs AAASM-3538 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a verify-python job that installs the `dev` extra (CI's offline path) and runs the smoke tests (which importorskip agent-framework) plus the `--mock` demo — so the example is exercised without pulling the heavy `live` pre-release tree. Refs AAASM-3538 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Document the mock vs live paths, the agent-framework (PyPI) vs agent_framework (import) split, and the `--prerelease=allow` install caveat. Refs AAASM-3538 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude Code — review result (MS Agent Framework example)
Validated locally (live run): Merge order: LAST — after python-sdk #164 + b5 release. Full cross-repo review on AAASM-3535. |
|
Claude Code — SonarCloud new-code review (round 2) Two dispositions on this PR's new code:
Net: 0 open new-code issues; the gate is red solely on the accepted Duplications dimension — no Security/Reliability/Maintainability/Hotspot/Coverage findings. (Smoke job red = release-ordering until python-sdk #164 + b5; SonarCloud check on the example is acceptance-only.) |
Pin the SDK to python-sdk git master via [tool.uv.sources] so the example validates against the merged Microsoft Agent Framework adapter until 0.0.1b5 publishes it to PyPI. Regenerated uv.lock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…anups Reformat two long print/with statements via ruff format, and make the example clean under mypy --strict: add a scoped mypy override treating the stub-less `agent_framework` module as untyped, and scoped `untyped-decorator` ignores on the `@af.tool` decorators (genuine framework stub gap, not a real typing defect). No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring tests/ to the same mypy --strict bar as src/: the test's `@af.tool` decorator hit `untyped-decorator` (agent_framework ships no stubs), the same genuine framework gap already scoped-ignored in src/tools.py. Add the matching `# type: ignore[untyped-decorator]`. ruff (lint + format) and mypy --strict are now clean over src and tests, save the expected unresolved import of `agent_assembly.adapters.microsoft_agent_framework` (python-sdk PR #164 still open). No logic change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rged) Resolve the python gallery README overlap: keep BOTH the Haystack and Smolagents rows (now on master) and this branch's Microsoft Agent Framework row. verify-python.yml auto-merged (MS job intact). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
py #164 merged the Microsoft Agent Framework adapter to the SDK master. Bump agent-assembly in uv.lock to the current master tip so the example's adapter import resolves — the smoke suite now skips cleanly (agent_framework is only in the `live` extra) instead of failing collection with ModuleNotFoundError. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…smoke runs CI runs `uv sync --extra dev`, but agent-framework was only in the `live` extra — so the smoke `importorskip`ped the whole module, collected 0 tests, and pytest exited 5 (treated as failure). The smoke genuinely needs the framework (it builds real `@af.tool` FunctionTools), and the importorskip reason note already claimed `--extra dev` installs it. Move it into `dev` (prerelease resolution is already allowed) so the suite runs: 8 passed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…in CI Revert agent-framework back to the `live` extra — its pre-release tree has no Linux wheels (e.g. github-copilot-sdk is macOS-only), so installing it in CI's `uv sync --extra dev` fails outright. Instead add a tests/conftest.py that coerces pytest's NO_TESTS_COLLECTED (exit 5) to OK, so when agent_framework is absent the module importorskips and the suite skips cleanly (exit 0) instead of failing CI. When agent_framework IS installed (the live extra) the tests run and report normally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|



What changed
Adds a runnable governance example,
python/microsoft-agent-framework-tool-policy, wiring Microsoft Agent Framework (PyPIagent-framework, importagent_framework) into Agent Assembly. TheMicrosoftAgentFrameworkAdapterpatchesagent_framework.FunctionTool.invoke— the single async coroutine through which every function tool executes — so a denied tool is short-circuited before its body runs.Like the rest of the gallery it runs two ways:
--mock(default, what CI runs): replays the allow / deny / pending policy outcomes throughLocalPolicyEnginewithout importingagent_framework— so it needs only the SDK +devdeps.FunctionTool.invokethrough the installed adapter (registered beforeinit_assemblyso the local policy stays wired, not overwritten by auto-detection's no-op interceptor).agent-frameworksits under theliveextra (heavy, pre-release transitive tree); the smoke testsimportorskipit and skip cleanly under--extra dev. A[tool.uv] prerelease = "allow"setting letsuv lock/uv sync --extra liveresolve its pre-release sub-distributions.Related ticket
Refs AAASM-3538 (parent AAASM-3535)
How to verify
Verified locally against the python-sdk branch: the live run shows
get_weatherALLOWED,delete_records/send_emailBLOCKED, and all 8 smoke tests pass (including a negative control proving the denied tool body never runs). The--mockpath runs withdev-only deps and the smokes skip cleanly without the framework.Checklist
[AAASM-XXXX] <GitEmoji> (<scope>): <summary>.envfiles committedREADME.mdwith prerequisites and run instructions🤖 Generated with Claude Code