feat: integrate A2A agents into plugin framework for header handling and RBAC (ICACF-43)#4775
Open
MohanLaksh wants to merge 12 commits into
Open
feat: integrate A2A agents into plugin framework for header handling and RBAC (ICACF-43)#4775MohanLaksh wants to merge 12 commits into
MohanLaksh wants to merge 12 commits into
Conversation
- Add A2AAgentPluginBinding model to mcpgateway/db.py with team_id, agent_name, plugin_id, mode, priority, config, binding_reference_id, and on_error fields - Create unique constraint on (team_id, agent_name, plugin_id) to enforce one-binding-per-plugin-per-agent rule - Add Alembic migration b29af8761e97 to create a2a_agent_plugin_bindings table with proper indexes and constraints - Add Pydantic schemas for A2A agent plugin binding request/response (A2AAgentPluginBindingRequest, A2AAgentPluginBindingResponse, A2AAgentPluginBindingListResponse) - Add PydanticA2AAgent helper schema for plugin context metadata This mirrors ToolPluginBinding but for A2A agents, enabling per-agent plugin policies. Closes ICACF-43 Signed-off-by: Mohan Lakshmaiah <[email protected]>
- Add A2AAgentPluginBindingService with CRUD operations (upsert, list, delete) - Add A2A agent plugin bindings router (POST/GET/DELETE endpoints) - Register router in main.py - Add plugin hooks (PRE_INVOKE, POST_INVOKE) to a2a_service.invoke_agent() - Extract A2A agent metadata (team_id, visibility, tags, oauth, passthrough) before DB release - Create GlobalContext with A2A_AGENT_METADATA for plugin context - Handle pre-invoke modifications to parameters and headers - Handle post-invoke with non-blocking error mode Signed-off-by: Mohan Lakshmaiah <[email protected]>
The auto-generated migration tried to recreate 19 pre-existing tables (global_config, gateways, servers, tools, etc.) alongside the new a2a_agent_plugin_bindings table. This would fail on any real database. - Rewrite migration to only create a2a_agent_plugin_bindings table - Add inspector-based idempotency guards (per AGENTS.md pattern) - Add 4 test files (1971 lines): binding service, invoke hooks, API router, and admin endpoints Signed-off-by: Mohan Lakshmaiah <[email protected]>
…ugin bindings (ICACF-43) - Add admin.py endpoints: HTMX partial, create, delete for A2A plugin bindings - Add sidebar tab + panel in admin.html for A2A Plugin Bindings - Add content_type/request_headers extraction in main.py handlers (invoke_a2a_agent, invoke_a2a_agent_by_id) - Add content_type field to PydanticA2AAgent schema - Add content_type/request_headers params to a2a_service.invoke_agent() - Fix: safe agent.oauth_config access via getattr - Fix: correlation_id None handling in GlobalContext - Fix: tenant_id type guard for non-string team_ids - Fix: use request_headers (not prepared.headers) in pre-invoke hook payload Signed-off-by: Mohan Lakshmaiah <[email protected]>
…ributeError in existing tests (ICACF-43) Signed-off-by: Mohan Lakshmaiah <[email protected]>
…refix with _ to suppress pylint W0613 Signed-off-by: Mohan Lakshmaiah <[email protected]>
…hip transfer (ICACF-43) Add 8 new tests to push diff coverage from 92% to 97% (above 93% CI threshold): - admin: partial render error, create service error, delete forbidden and generic error - a2a_service: metadata build exception swallowed - router: ValueError converted to HTTP 400 - binding service: binding_reference_id ownership transfer warning Signed-off-by: Mohan Lakshmaiah <[email protected]>
…(ICACF-43) Signed-off-by: Mohan Lakshmaiah <[email protected]>
…value-double-quotes error Signed-off-by: Mohan Lakshmaiah <[email protected]>
…ependency CI has cpex v0.1.0 which predates the A2A_AGENT_METADATA constant. Defined the constant in mcpgateway.schemas and redirected imports from the production code and tests to use it, removing the cpex dependency. Signed-off-by: Mohan Lakshmaiah <[email protected]>
…le module docstrings warning Signed-off-by: Mohan Lakshmaiah <[email protected]>
…e triple-quoted string with comment Signed-off-by: Mohan Lakshmaiah <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A2A (Agent-to-Agent) agents previously bypassed the plugin pipeline entirely, preventing plugins like VaultPlugin from functioning with A2A tools. This PR integrates A2A agents into the plugin framework for full feature parity with MCP tools.
Before: MCP tools → fire pre/post-invoke hooks → VaultPlugin works; A2A agents → no hooks → VaultPlugin unusable
After: A2A agents fire
AGENT_PRE_INVOKEandAGENT_POST_INVOKEhooks, enabling header injection, RBAC validation, and response transformation via plugins.What Changed
Core Plugin Integration
AGENT_PRE_INVOKEandAGENT_POST_INVOKEhooks toA2AAgentService.invoke_agent()(a2a_service.py)PydanticA2AAgentschema exposing agent metadata (tags,oauth_config,passthrough_headers,auth_type,auth_value,content_type) to plugins viaGlobalContext.metadata[A2A_AGENT_METADATA]content_typeandrequest_headersparameters toinvoke_agent()for plugin contextinvoke_a2a_agent,invoke_a2a_agent_by_id) inmain.pynow extract and forward inbound headersDatabase & Schema
A2AAgentPluginBindingORM model mirroringToolPluginBindingstructure (db.py)b29af8761e97with inspector-based guardsA2AAgentPluginBindingRequest,A2AAgentPluginBindingResponse,A2AAgentPluginBindingListResponseAdmin API & UI
routers/a2a_agent_plugin_bindings.py): POST upsert, GET list, GET by team, DELETE by ID, DELETE by referenceservices/a2a_agent_plugin_binding_service.py): full CRUD with specificity-wins wildcard semanticsTesting
All 5 Gaps from ICACF-43 Addressed
Related
Breaking Changes
None — all changes are additive and backward compatible.