-
Notifications
You must be signed in to change notification settings - Fork 353
Allow configuration of max payload size limit #1180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: kevin-shelaga <[email protected]>
Signed-off-by: kevin-shelaga <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds support for configuring the maximum payload size limit for A2A (Agent-to-Agent) requests across the kagent platform. The change addresses the hardcoded payload size limit in the a2a-python library (~7-8MB) by allowing users to specify custom limits through configuration.
Key Changes
- Added
max_payload_sizeconfiguration parameter to AgentConfig types in Python (ADK, LangGraph, CrewAI) and Go (v1alpha1, v1alpha2 APIs) - Implemented runtime patching mechanism (
_patch_a2a_payload_limit) to override a2a-python's hardcoded payload size limits - Extended CLI and KAgentApp classes to accept and propagate max_payload_size configuration
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
python/packages/kagent-adk/src/kagent/adk/types.py |
Added max_payload_size field to AgentConfig with inline documentation |
python/packages/kagent-adk/src/kagent/adk/_a2a.py |
Implemented _patch_a2a_payload_limit function and integrated it into KAgentApp.build() |
python/packages/kagent-adk/src/kagent/adk/cli.py |
Updated CLI to pass max_payload_size from config to KAgentApp |
python/packages/kagent-langgraph/src/kagent/langgraph/_a2a.py |
Added payload patching support for LangGraph integration |
python/packages/kagent-langgraph/src/kagent/langgraph/_executor.py |
Reordered imports (langgraph imports moved after kagent.core imports) |
python/packages/kagent-crewai/src/kagent/crewai/_a2a.py |
Added payload patching support for CrewAI integration |
python/packages/kagent-crewai/src/kagent/crewai/_executor.py |
Minor whitespace cleanup (removed blank line) |
python/packages/kagent-core/src/kagent/core/tracing/_span_processor.py |
Reordered imports for consistency |
python/packages/kagent-adk/tests/unittests/test_agent_config.py |
Added comprehensive unit tests for AgentConfig with max_payload_size field |
python/packages/kagent-adk/tests/unittests/test_a2a_payload_size.py |
Added unit tests for the patching mechanism with various edge cases |
go/api/v1alpha2/agent_types.go |
Added MaxPayloadSize field to A2AConfig with Kubernetes quantity support |
go/api/v1alpha1/agent_types.go |
Added MaxPayloadSize field to A2AConfig for v1alpha1 API compatibility |
go/internal/adk/types.go |
Added MaxPayloadSize to AgentConfig struct and unmarshal logic |
go/internal/controller/translator/agent/adk_api_translator.go |
Implemented extraction and translation of maxPayloadSize from Agent CRD to AgentConfig |
go/internal/controller/translator/agent/testdata/inputs/agent_with_max_payload_size.yaml |
Added test case with maxPayloadSize configuration (50Mi) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Patch a2a-python's payload size limit if specified | ||
| if self.max_payload_size is not None: | ||
| _patch_a2a_payload_limit(self.max_payload_size) |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patching approach modifies a global module-level constant at runtime. In deployment scenarios where multiple KAgentApp instances might be created with different max_payload_size values (e.g., in tests or multi-tenant environments), the last value set will override previous ones, potentially causing unexpected behavior. Consider documenting this limitation or implementing the patch only once during module initialization if multiple instances are expected.
| def _patch_a2a_payload_limit(max_body_size: int): | ||
| """Attempt to patch a2a-python library's hardcoded payload size limit.""" | ||
| try: | ||
| # Try different import paths for jsonrpc_app module | ||
| jsonrpc_app = None | ||
| import_paths = [ | ||
| "a2a.server.apps.jsonrpc.jsonrpc_app", | ||
| "a2a.server.apps.jsonrpc_app", | ||
| ] | ||
| for path in import_paths: | ||
| try: | ||
| jsonrpc_app = __import__(path, fromlist=[""]) | ||
| break | ||
| except ImportError: | ||
| continue | ||
|
|
||
| if jsonrpc_app is None: | ||
| logger.debug("Could not find a2a-python jsonrpc_app module to patch") | ||
| return | ||
|
|
||
| # Check if MAX_PAYLOAD_SIZE or similar constant exists | ||
| if hasattr(jsonrpc_app, "MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app.MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| # Also check for _MAX_PAYLOAD_SIZE or other variants | ||
| elif hasattr(jsonrpc_app, "_MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app._MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python _MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| else: | ||
| logger.debug("Could not find MAX_PAYLOAD_SIZE constant in a2a-python jsonrpc_app") | ||
| except (ImportError, AttributeError) as e: | ||
| # If patching fails, log a debug message but continue | ||
| logger.debug(f"Could not patch a2a-python payload limit: {e}") |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _patch_a2a_payload_limit function is duplicated identically across three files: kagent-adk/_a2a.py, kagent-langgraph/_a2a.py, and kagent-crewai/_a2a.py. This code duplication makes maintenance more difficult, as any bug fixes or improvements would need to be applied in multiple places. Consider extracting this function to a shared module in kagent-core (e.g., kagent.core.a2a) and importing it from there instead.
| def _patch_a2a_payload_limit(max_body_size: int): | ||
| """Attempt to patch a2a-python library's hardcoded payload size limit.""" | ||
| try: | ||
| # Try different import paths for jsonrpc_app module | ||
| jsonrpc_app = None | ||
| import_paths = [ | ||
| "a2a.server.apps.jsonrpc.jsonrpc_app", | ||
| "a2a.server.apps.jsonrpc_app", | ||
| ] | ||
| for path in import_paths: | ||
| try: | ||
| jsonrpc_app = __import__(path, fromlist=[""]) | ||
| break | ||
| except ImportError: | ||
| continue | ||
|
|
||
| if jsonrpc_app is None: | ||
| logger.debug("Could not find a2a-python jsonrpc_app module to patch") | ||
| return | ||
|
|
||
| # Check if MAX_PAYLOAD_SIZE or similar constant exists | ||
| if hasattr(jsonrpc_app, "MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app.MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| # Also check for _MAX_PAYLOAD_SIZE or other variants | ||
| elif hasattr(jsonrpc_app, "_MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app._MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python _MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| else: | ||
| logger.debug("Could not find MAX_PAYLOAD_SIZE constant in a2a-python jsonrpc_app") | ||
| except (ImportError, AttributeError) as e: | ||
| # If patching fails, log a debug message but continue | ||
| logger.debug(f"Could not patch a2a-python payload limit: {e}") |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _patch_a2a_payload_limit function is duplicated identically across three files: kagent-adk/_a2a.py, kagent-langgraph/_a2a.py, and kagent-crewai/_a2a.py. This code duplication makes maintenance more difficult, as any bug fixes or improvements would need to be applied in multiple places. Consider extracting this function to a shared module in kagent-core (e.g., kagent.core.a2a) and importing it from there instead.
| def _patch_a2a_payload_limit(max_body_size: int): | ||
| """Attempt to patch a2a-python library's hardcoded payload size limit.""" | ||
| try: | ||
| # Try different import paths for jsonrpc_app module | ||
| jsonrpc_app = None | ||
| import_paths = [ | ||
| "a2a.server.apps.jsonrpc.jsonrpc_app", | ||
| "a2a.server.apps.jsonrpc_app", | ||
| ] | ||
| for path in import_paths: | ||
| try: | ||
| jsonrpc_app = __import__(path, fromlist=[""]) | ||
| break | ||
| except ImportError: | ||
| continue | ||
|
|
||
| if jsonrpc_app is None: | ||
| logger.debug("Could not find a2a-python jsonrpc_app module to patch") | ||
| return | ||
|
|
||
| # Check if MAX_PAYLOAD_SIZE or similar constant exists | ||
| if hasattr(jsonrpc_app, "MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app.MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| # Also check for _MAX_PAYLOAD_SIZE or other variants | ||
| elif hasattr(jsonrpc_app, "_MAX_PAYLOAD_SIZE"): | ||
| jsonrpc_app._MAX_PAYLOAD_SIZE = max_body_size | ||
| logger.info(f"Patched a2a-python _MAX_PAYLOAD_SIZE to {max_body_size} bytes") | ||
| else: | ||
| logger.debug("Could not find MAX_PAYLOAD_SIZE constant in a2a-python jsonrpc_app") | ||
| except (ImportError, AttributeError) as e: | ||
| # If patching fails, log a debug message but continue | ||
| logger.debug(f"Could not patch a2a-python payload limit: {e}") |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _patch_a2a_payload_limit function is duplicated identically across three files: kagent-adk/_a2a.py, kagent-langgraph/_a2a.py, and kagent-crewai/_a2a.py. This code duplication makes maintenance more difficult, as any bug fixes or improvements would need to be applied in multiple places. Consider extracting this function to a shared module in kagent-core (e.g., kagent.core.a2a) and importing it from there instead.
| sse_tools: list[SseMcpServerConfig] | None = None # SSE MCP tools | ||
| remote_agents: list[RemoteAgentConfig] | None = None # remote agents | ||
| execute_code: bool | None = None | ||
| max_payload_size: int | None = None # Maximum payload size in bytes for A2A requests |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The max_payload_size parameter lacks input validation. Negative or zero values could be passed and would be used to patch the a2a-python library, potentially causing unexpected behavior. Consider adding validation to ensure the value is positive (e.g., max_payload_size > 0) or documenting the acceptable range.
|
|
||
| // Extract maxPayloadSize from A2AConfig if present | ||
| if agent.Spec.Declarative.A2AConfig != nil && agent.Spec.Declarative.A2AConfig.MaxPayloadSize != nil { | ||
| maxPayloadSizeBytes := agent.Spec.Declarative.A2AConfig.MaxPayloadSize.Value() |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The extracted maxPayloadSizeBytes value is not validated before being assigned to the config. While Kubernetes resource.Quantity parsing handles invalid formats, it can accept negative values (e.g., "-10Mi"). Consider adding validation to ensure the value is positive before assigning it to cfg.MaxPayloadSize.
| maxPayloadSizeBytes := agent.Spec.Declarative.A2AConfig.MaxPayloadSize.Value() | |
| maxPayloadSizeBytes := agent.Spec.Declarative.A2AConfig.MaxPayloadSize.Value() | |
| if maxPayloadSizeBytes <= 0 { | |
| return nil, nil, nil, fmt.Errorf("invalid maxPayloadSize: must be positive, got %d", maxPayloadSizeBytes) | |
| } |
| # Patch a2a-python's payload size limit if specified | ||
| if self.max_payload_size is not None: | ||
| _patch_a2a_payload_limit(self.max_payload_size) |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patching approach modifies a global module-level constant at runtime. In deployment scenarios where multiple KAgentApp instances might be created with different max_payload_size values (e.g., in tests or multi-tenant environments), the last value set will override previous ones, potentially causing unexpected behavior. Consider documenting this limitation or implementing the patch only once during module initialization if multiple instances are expected.
| # Patch a2a-python's payload size limit if specified | ||
| if self.max_payload_size is not None: | ||
| _patch_a2a_payload_limit(self.max_payload_size) |
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patching approach modifies a global module-level constant at runtime. In deployment scenarios where multiple KAgentApp instances might be created with different max_payload_size values (e.g., in tests or multi-tenant environments), the last value set will override previous ones, potentially causing unexpected behavior. Consider documenting this limitation or implementing the patch only once during module initialization if multiple instances are expected.
| import pytest | ||
|
|
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'pytest' is not used.
| import pytest |
| import pytest | ||
|
|
Copilot
AI
Dec 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'pytest' is not used.
| import pytest |
Signed-off-by: kevin-shelaga <[email protected]>
… into payload-limit Signed-off-by: kevin-shelaga <[email protected]>
a032212 to
7c55825
Compare
No description provided.