You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Python: build the Agent Hooks middleware from a host declaration document #9329
Agent Framework supports Agent Hooks in Python through create_agent_hooks_middleware. Today a host configures it in code: interceptors, composition, identity provider, resolver, mode. Agent Hooks 0.1.0-beta.2 adds a host declaration document (spec section 7.7, contract agent-hooks-declaration/1.0): one JSON file that states the host's configuration, its declared surface, and its interceptor bindings by kind. An administrator can deploy that file through existing settings channels, and the loader refuses anything the host's code cannot honour before any emission.
Agent Framework should accept that document.
Proposal
Add a way to build the Agent Hooks middleware from a declaration, next to the existing code path:
create_agent_hooks_middleware_from_declaration(document_or_path_or_json, *, registry=None, ...) that loads through InterceptionEmitter.from_declaration_* from agent-hooks-sdk.
A host registry over Agent Framework's surface (all eight points, terminate posture, the capabilities the adapter declares today) where an app registers its own binding kinds, resolver and redactor.
A framework binding kind agent_framework.interceptor so a document can name an interceptor registered in code.
The existing code path keeps working. The document must state tool_seam_host_error: terminate, because the contract defaults to continue and the loader refuses a mismatch with the code's posture.
Scope
python/packages/core/agent_framework/_agent_hooks.py and the package exports.
Tests that run offline, covering the three construction paths, each refusal class, and the posture rule.
Bump the agent-hooks-sdk dev pin to 0.1.0b2 so the new tests run in CI.
The conformance toolkit in 0.1.0-beta.2 carries 22 declaration vectors (AH-CTK-120 to 141). The Agent Framework claim can grow to cover them once the harness builds its emitter through the loader.
I have experience with Python, AI agent workflows, middleware integration, debugging, and regression testing. I've also contributed to Docling Pipelines and submitted a fix for Microsoft Amplifier (PR #205).
I reviewed the proposed implementation scope and noticed that no pull request is currently linked.
Before starting, could you please confirm whether this issue is available for contribution and whether the proposed API design is ready for implementation?
I'd be happy to collaborate with the original author, follow the repository's contribution guidelines, implement the changes incrementally, and add the required offline tests.
The issue asks Agent Framework (Python) to support building the AGENT-HOOKS-0.1 enforcement middleware from a host declaration document — a JSON file (added in agent-hooks-sdk 0.1.0-beta.2, spec §7.7) that states host configuration, declared surface, and interceptor bindings, instead of only configuring everything in Python code as today.
I verified the relevant code and the upstream spec/SDK directly (not from any proposed PR):
Today, python/packages/core/agent_framework/_agent_hooks.py exposes exactly two public factories: create_agent_hooks_middleware(...) (code-only configuration) and create_agent_hooks_middleware_from_emitter(...) (host-owned InterceptionEmitter/AgentContextBuilder). Both return a MiddlewareBundle. There is no declaration-document path.
agent-hooks-sdk 0.1.0-beta.2 (released the same day as this issue) does add exactly what's described: HostDeclaration, HostRegistry, HostSurface, DeclarationError, and InterceptionEmitter.from_declaration / from_declaration_path / from_declaration_json / from_declaration_value, per the upstream CHANGELOG and declaration.py.
The current dev pin in python/pyproject.toml is agent-hooks-sdk>=0.1.0a4,<0.2, which does not yet guarantee 0.1.0-beta.2 is resolved/tested in CI, confirming the issue's point about bumping the pin.
A prior conformance report (conformance/claims/maf/REPORT.md in the agent-hooks repo) shows Agent Framework already has a full 47/47 conformance claim on the code-configured path, including the tool_seam_host_error: terminate posture this issue calls out as required — so that posture requirement is a real, already-understood constraint, not new.
No existing feature, workaround, or sample in this repository currently exposes a declaration-document loader, so this is a genuine capability gap rather than something already solved.
Recommendation
Code change is warranted. This is a natural, additive extension of an already-merged, first-class experimental feature (create_agent_hooks_middleware, merged via #7515), following the same one-factory/private-middleware pattern. It lets hosts move interception configuration out of Python code into a deployable JSON file managed through existing settings/config channels — a capability the upstream SDK now explicitly supports and that other language SDKs (Rust, TypeScript, .NET, Go) already implement. The risk is low: it's purely additive (new factory, no changes to existing factories' behavior), and the existing module already isolates the optional agent-hooks-sdk dependency behind lazy imports, so the pattern extends cleanly.
Proposed plan
Add create_agent_hooks_middleware_from_declaration(...) in _agent_hooks.py, mirroring the existing two factories:
Accept a HostDeclaration, a file path, or a JSON string/parsed value (three construction forms, matching the SDK's from_declaration / from_declaration_path / from_declaration_json / from_declaration_value), plus an optional registry: HostRegistry | None for app-registered resolver names, approval resolvers, and redactors.
Internally build the InterceptionEmitter through the SDK's loader and reuse the existing _build_bundle(...) plumbing so the returned MiddlewareBundle behaves identically to the other two factories.
Surface DeclarationError (and its refusal classes) unchanged so a bad document fails closed before any middleware runs, per the SDK's documented behavior.
Expose a default HostRegistry over Agent Framework's own surface (all eight interception points, the terminate posture the framework already enforces at the tool seam, and the capabilities the framework already declares in its conformance report), so a minimal document can be loaded without the app building a registry from scratch. Let apps extend it with their own binding kinds, resolver, and redactor.
Add the agent_framework.interceptor binding kind, a resolver that looks up an interceptor previously registered in code (by name), so a declaration document can reference code-defined interceptors without embedding arbitrary code in JSON.
Update exports: add the new factory to __init__.py's lazy export map and __init__.pyi, and to PACKAGE_STATUS.md's AGENT_HOOKS entry, consistent with the repo's lazy-export conventions.
Bump the dev dependencyagent-hooks-sdk floor in python/pyproject.toml from >=0.1.0a4 to >=0.1.0b2 so CI actually exercises the declaration loader.
Tests in test_agent_hooks.py (or a new test file) covering, offline:
All three construction paths (document object, path, JSON string) producing an equivalent bundle.
Each of the documented refusal classes (e.g., unsupported version, unknown field, unresolved reference/kind, surface the host can't honor) raising DeclarationError before any middleware executes.
The tool_seam_host_error: terminate posture rule: a document that doesn't declare terminate is refused, since the framework's code posture is fixed.
That existing create_agent_hooks_middleware / create_agent_hooks_middleware_from_emitter behavior and tests remain unaffected (regression safety for the two existing paths).
Documentation: extend the module docstring and any relevant sample/README text to describe the declaration path alongside the two existing factories.
You'd know this is resolved when: the new factory builds a working MiddlewareBundle from a real declaration document in a test, each refusal class is exercised and asserted, the agent-hooks-sdk floor is bumped and CI stays green, and the existing two factories' tests still pass unchanged.
This is a proposal only — no code has been changed. One open question worth confirming before implementation: whether the default HostRegistry's declared capability list should mirror exactly what's in the existing upstream conformance claim (model_calls, tool_calls, int64_json, bigint_json, host_declaration) or be narrower/broader for the initial version.
Generated by Issue Planning for #9329 · copilot · auto · 137.9 AIC · ⌖ 4.93 AIC · ⊞ 10.8K · ◷
Thank you for initiating the planning process and providing the detailed implementation proposal.
I've reviewed the generated plan, including the declaration-based factory, HostRegistry configuration, interceptor bindings, SDK dependency update, and offline regression coverage.
I'm interested in contributing to this implementation and would be happy to follow the proposed architecture.
Before starting, could you please confirm whether I may take ownership of this issue and whether the default HostRegistry capabilities should match the existing conformance claim or use a narrower initial scope?
Once confirmed, I can begin with a focused implementation, preserve backward compatibility, add the required tests, and submit a PR for review.
Activity
sunny-kavixo commentedon Oct 13, 2026
Hi MohammadHaroonAbuomar and Microsoft Agent Framework maintainers,
I'm interested in contributing to Issue #9329.
I have experience with Python, AI agent workflows, middleware integration, debugging, and regression testing. I've also contributed to Docling Pipelines and submitted a fix for Microsoft Amplifier (PR #205).
I reviewed the proposed implementation scope and noticed that no pull request is currently linked.
Before starting, could you please confirm whether this issue is available for contribution and whether the proposed API design is ready for implementation?
I'd be happy to collaborate with the original author, follow the repository's contribution guidelines, implement the changes incrementally, and add the required offline tests.
Thank you for your consideration!
eavanvalkenburg commentedon Oct 13, 2026
/plan
github-actions commentedon Oct 13, 2026
Summary
The issue asks Agent Framework (Python) to support building the AGENT-HOOKS-0.1 enforcement middleware from a host declaration document — a JSON file (added in
agent-hooks-sdk0.1.0-beta.2, spec §7.7) that states host configuration, declared surface, and interceptor bindings, instead of only configuring everything in Python code as today.I verified the relevant code and the upstream spec/SDK directly (not from any proposed PR):
python/packages/core/agent_framework/_agent_hooks.pyexposes exactly two public factories:create_agent_hooks_middleware(...)(code-only configuration) andcreate_agent_hooks_middleware_from_emitter(...)(host-ownedInterceptionEmitter/AgentContextBuilder). Both return aMiddlewareBundle. There is no declaration-document path.agent-hooks-sdk0.1.0-beta.2 (released the same day as this issue) does add exactly what's described:HostDeclaration,HostRegistry,HostSurface,DeclarationError, andInterceptionEmitter.from_declaration/from_declaration_path/from_declaration_json/from_declaration_value, per the upstream CHANGELOG anddeclaration.py.python/pyproject.tomlisagent-hooks-sdk>=0.1.0a4,<0.2, which does not yet guarantee 0.1.0-beta.2 is resolved/tested in CI, confirming the issue's point about bumping the pin.conformance/claims/maf/REPORT.mdin theagent-hooksrepo) shows Agent Framework already has a full 47/47 conformance claim on the code-configured path, including thetool_seam_host_error: terminateposture this issue calls out as required — so that posture requirement is a real, already-understood constraint, not new.No existing feature, workaround, or sample in this repository currently exposes a declaration-document loader, so this is a genuine capability gap rather than something already solved.
Recommendation
Code change is warranted. This is a natural, additive extension of an already-merged, first-class experimental feature (
create_agent_hooks_middleware, merged via #7515), following the same one-factory/private-middleware pattern. It lets hosts move interception configuration out of Python code into a deployable JSON file managed through existing settings/config channels — a capability the upstream SDK now explicitly supports and that other language SDKs (Rust, TypeScript, .NET, Go) already implement. The risk is low: it's purely additive (new factory, no changes to existing factories' behavior), and the existing module already isolates the optionalagent-hooks-sdkdependency behind lazy imports, so the pattern extends cleanly.Proposed plan
create_agent_hooks_middleware_from_declaration(...)in_agent_hooks.py, mirroring the existing two factories:HostDeclaration, a file path, or a JSON string/parsed value (three construction forms, matching the SDK'sfrom_declaration/from_declaration_path/from_declaration_json/from_declaration_value), plus an optionalregistry: HostRegistry | Nonefor app-registered resolver names, approval resolvers, and redactors.InterceptionEmitterthrough the SDK's loader and reuse the existing_build_bundle(...)plumbing so the returnedMiddlewareBundlebehaves identically to the other two factories.DeclarationError(and its refusal classes) unchanged so a bad document fails closed before any middleware runs, per the SDK's documented behavior.HostRegistryover Agent Framework's own surface (all eight interception points, theterminateposture the framework already enforces at the tool seam, and the capabilities the framework already declares in its conformance report), so a minimal document can be loaded without the app building a registry from scratch. Let apps extend it with their own bindingkinds, resolver, and redactor.agent_framework.interceptorbinding kind, a resolver that looks up an interceptor previously registered in code (by name), so a declaration document can reference code-defined interceptors without embedding arbitrary code in JSON.__init__.py's lazy export map and__init__.pyi, and toPACKAGE_STATUS.md'sAGENT_HOOKSentry, consistent with the repo's lazy-export conventions.agent-hooks-sdkfloor inpython/pyproject.tomlfrom>=0.1.0a4to>=0.1.0b2so CI actually exercises the declaration loader.test_agent_hooks.py(or a new test file) covering, offline:DeclarationErrorbefore any middleware executes.tool_seam_host_error: terminateposture rule: a document that doesn't declareterminateis refused, since the framework's code posture is fixed.create_agent_hooks_middleware/create_agent_hooks_middleware_from_emitterbehavior and tests remain unaffected (regression safety for the two existing paths).You'd know this is resolved when: the new factory builds a working
MiddlewareBundlefrom a real declaration document in a test, each refusal class is exercised and asserted, theagent-hooks-sdkfloor is bumped and CI stays green, and the existing two factories' tests still pass unchanged.This is a proposal only — no code has been changed. One open question worth confirming before implementation: whether the default
HostRegistry's declared capability list should mirror exactly what's in the existing upstream conformance claim (model_calls,tool_calls,int64_json,bigint_json,host_declaration) or be narrower/broader for the initial version.sunny-kavixo commentedon Oct 13, 2026
Hi Eduard van Valkenburg (@eavanvalkenburg) and MohammadHaroonAbuomar,
Thank you for initiating the planning process and providing the detailed implementation proposal.
I've reviewed the generated plan, including the declaration-based factory, HostRegistry configuration, interceptor bindings, SDK dependency update, and offline regression coverage.
I'm interested in contributing to this implementation and would be happy to follow the proposed architecture.
Before starting, could you please confirm whether I may take ownership of this issue and whether the default HostRegistry capabilities should match the existing conformance claim or use a narrower initial scope?
Once confirmed, I can begin with a focused implementation, preserve backward compatibility, add the required tests, and submit a PR for review.
Thank you for your guidance!
MohammadHaroonAbuomar commentedon Oct 15, 2026
Thank you Sandeep | AI Data & Automation (@sunny-kavixo) for offering to take this on. The implementation is up as #9405. Reviews are welcome.