chore: add experimental messages for a2a related API

PiperOrigin-RevId: 793812544
This commit is contained in:
Xiang (Sean) Zhou
2025-08-11 15:08:29 -07:00
committed by Copybara-Service
parent d674178a05
commit d0b3b5d857
8 changed files with 74 additions and 20 deletions
@@ -38,7 +38,7 @@ from google.genai import types as genai_types
from ...agents.invocation_context import InvocationContext
from ...events.event import Event
from ...flows.llm_flows.functions import REQUEST_EUC_FUNCTION_CALL_NAME
from ...utils.feature_decorator import experimental
from ..experimental import a2a_experimental
from .part_converter import A2A_DATA_PART_METADATA_IS_LONG_RUNNING_KEY
from .part_converter import A2A_DATA_PART_METADATA_TYPE_FUNCTION_CALL
from .part_converter import A2A_DATA_PART_METADATA_TYPE_KEY
@@ -224,7 +224,7 @@ def convert_a2a_task_to_event(
raise
@experimental
@a2a_experimental
def convert_a2a_message_to_event(
a2a_message: Message,
author: Optional[str] = None,
@@ -320,7 +320,7 @@ def convert_a2a_message_to_event(
raise RuntimeError(f"Failed to convert message: {e}") from e
@experimental
@a2a_experimental
def convert_event_to_a2a_message(
event: Event, invocation_context: InvocationContext, role: Role = Role.agent
) -> Optional[Message]:
@@ -471,7 +471,7 @@ def _create_status_update_event(
)
@experimental
@a2a_experimental
def convert_event_to_a2a_events(
event: Event,
invocation_context: InvocationContext,
@@ -39,7 +39,7 @@ except ImportError as e:
from google.genai import types as genai_types
from ...utils.feature_decorator import experimental
from ..experimental import a2a_experimental
logger = logging.getLogger('google_adk.' + __name__)
@@ -51,7 +51,7 @@ A2A_DATA_PART_METADATA_TYPE_CODE_EXECUTION_RESULT = 'code_execution_result'
A2A_DATA_PART_METADATA_TYPE_EXECUTABLE_CODE = 'executable_code'
@experimental
@a2a_experimental
def convert_a2a_part_to_genai_part(
a2a_part: a2a_types.Part,
) -> Optional[genai_types.Part]:
@@ -140,7 +140,7 @@ def convert_a2a_part_to_genai_part(
return None
@experimental
@a2a_experimental
def convert_genai_part_to_a2a_part(
part: genai_types.Part,
) -> Optional[a2a_types.Part]:
@@ -30,7 +30,7 @@ except ImportError as e:
from google.genai import types as genai_types
from ...runners import RunConfig
from ...utils.feature_decorator import experimental
from ..experimental import a2a_experimental
from .part_converter import convert_a2a_part_to_genai_part
@@ -47,7 +47,7 @@ def _get_user_id(request: RequestContext) -> str:
return f'A2A_USER_{request.context_id}'
@experimental
@a2a_experimental
def convert_a2a_request_to_adk_run_args(
request: RequestContext,
) -> dict[str, Any]:
@@ -50,23 +50,23 @@ from google.adk.runners import Runner
from pydantic import BaseModel
from typing_extensions import override
from ...utils.feature_decorator import experimental
from ..converters.event_converter import convert_event_to_a2a_events
from ..converters.request_converter import convert_a2a_request_to_adk_run_args
from ..converters.utils import _get_adk_metadata_key
from ..experimental import a2a_experimental
from .task_result_aggregator import TaskResultAggregator
logger = logging.getLogger('google_adk.' + __name__)
@experimental
@a2a_experimental
class A2aAgentExecutorConfig(BaseModel):
"""Configuration for the A2aAgentExecutor."""
pass
@experimental
@a2a_experimental
class A2aAgentExecutor(AgentExecutor):
"""An AgentExecutor that runs an ADK Agent against an A2A request and
publishes updates to an event queue.
@@ -19,10 +19,10 @@ from a2a.types import Message
from a2a.types import TaskState
from a2a.types import TaskStatusUpdateEvent
from ...utils.feature_decorator import experimental
from ..experimental import a2a_experimental
@experimental
@a2a_experimental
class TaskResultAggregator:
"""Aggregates the task status updates and provides the final task state."""
+54
View File
@@ -0,0 +1,54 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A2A specific experimental decorator with custom warning message."""
from __future__ import annotations
from google.adk.utils.feature_decorator import _make_feature_decorator
a2a_experimental = _make_feature_decorator(
label="EXPERIMENTAL",
default_message=(
"ADK Implementation for A2A support (A2aAgentExecutor, RemoteA2aAgent "
"and corresponding supporting components etc.) is in experimental mode "
"and is subjected to breaking changes. A2A protocol and SDK are"
"themselves not experimental. Once it's stable enough the experimental "
"mode will be removed. Your feedback is welcome."
),
)
"""Mark a class or function as experimental A2A feature.
This decorator shows a specific warning message for A2A functionality,
indicating that the API is experimental and subject to breaking changes.
Sample usage:
```
# Use with default A2A experimental message
@a2a_experimental
class A2AExperimentalClass:
pass
# Use with custom message (overrides default A2A message)
@a2a_experimental("Custom A2A experimental message.")
def a2a_experimental_function():
pass
# Use with empty parentheses (same as default A2A message)
@a2a_experimental()
class AnotherA2AClass:
pass
```
"""
@@ -41,10 +41,10 @@ from ...agents.loop_agent import LoopAgent
from ...agents.parallel_agent import ParallelAgent
from ...agents.sequential_agent import SequentialAgent
from ...tools.example_tool import ExampleTool
from ...utils.feature_decorator import experimental
from ..experimental import a2a_experimental
@experimental
@a2a_experimental
class AgentCardBuilder:
"""Builder class for creating agent cards from ADK agents.
+4 -4
View File
@@ -58,6 +58,7 @@ from ..a2a.converters.event_converter import convert_a2a_message_to_event
from ..a2a.converters.event_converter import convert_a2a_task_to_event
from ..a2a.converters.event_converter import convert_event_to_a2a_message
from ..a2a.converters.part_converter import convert_genai_part_to_a2a_part
from ..a2a.experimental import a2a_experimental
from ..a2a.logs.log_utils import build_a2a_request_log
from ..a2a.logs.log_utils import build_a2a_response_log
from ..agents.invocation_context import InvocationContext
@@ -65,7 +66,6 @@ from ..events.event import Event
from ..flows.llm_flows.contents import _convert_foreign_event
from ..flows.llm_flows.contents import _is_other_agent_reply
from ..flows.llm_flows.functions import find_matching_function_call
from ..utils.feature_decorator import experimental
from .base_agent import BaseAgent
__all__ = [
@@ -83,21 +83,21 @@ DEFAULT_TIMEOUT = 600.0
logger = logging.getLogger("google_adk." + __name__)
@experimental
@a2a_experimental
class AgentCardResolutionError(Exception):
"""Raised when agent card resolution fails."""
pass
@experimental
@a2a_experimental
class A2AClientError(Exception):
"""Raised when A2A client operations fail."""
pass
@experimental
@a2a_experimental
class RemoteA2aAgent(BaseAgent):
"""Agent that communicates with a remote A2A agent via A2A client.