Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions .github/workflows/python-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13"]

steps:
- name: Checkout code
Expand All @@ -48,14 +48,6 @@ jobs:
- name: Run unit tests with pytest
run: |
source .venv/bin/activate
if [[ "${{ matrix.python-version }}" == "3.9" ]]; then
pytest tests/unittests \
--ignore=tests/unittests/a2a \
--ignore=tests/unittests/tools/mcp_tool \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
else
pytest tests/unittests \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
fi
pytest tests/unittests \
--ignore=tests/unittests/artifacts/test_artifact_service.py \
--ignore=tests/unittests/tools/google_api_tool/test_googleapi_to_openapi_converter.py
25 changes: 15 additions & 10 deletions contributing/samples/adk_triaging_agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,21 @@
import requests

LABEL_TO_OWNER = {
"a2a": "seanzhou1023",
"agent engine": "yeesian",
"documentation": "polong-lin",
"services": "DeanChensj",
"question": "",
"mcp": "seanzhou1023",
"tools": "seanzhou1023",
"auth": "seanzhou1023",
"bq": "shobsi",
"core": "Jacksunwei",
"documentation": "joefernandez",
"eval": "ankursharmas",
"live": "hangfei",
"models": "genquan9",
"live": "seanzhou1023",
"mcp": "seanzhou1023",
"models": "xuanyang15",
"services": "DeanChensj",
"tools": "xuanyang15",
"tracing": "jawoszek",
"core": "Jacksunwei",
"web": "wyf7107",
"a2a": "seanzhou1023",
"bq": "shobsi",
"workflow": "DeanChensj",
}

LABEL_GUIDELINES = """
Expand All @@ -65,6 +66,8 @@
Agent Engine concepts, do not use this label—choose "core" instead.
- "a2a": Agent-to-agent workflows, coordination logic, or A2A protocol.
- "bq": BigQuery integration or general issues related to BigQuery.
- "workflow": Workflow agents and workflow execution.
- "auth": Authentication or authorization issues.

When unsure between labels, prefer the most specific match. If a label
cannot be assigned confidently, do not call the labeling tool.
Expand Down Expand Up @@ -265,6 +268,8 @@ def change_issue_type(issue_number: int, issue_type: str) -> dict[str, Any]:
- If it's about Model Context Protocol (e.g. MCP tool, MCP toolset, MCP session management etc.), label it with both "mcp" and "tools".
- If it's about A2A integrations or workflows, label it with "a2a".
- If it's about BigQuery integrations, label it with "bq".
- If it's about workflow agents or workflow execution, label it with "workflow".
- If it's about authentication, label it with "auth".
- If you can't find an appropriate labels for the issue, follow the previous instruction that starts with "IMPORTANT:".

## Triaging Workflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ prepend_sys_path = .

# timezone to use when rendering the date within the migration file
# as well as the filename.
# If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library.
# If specified, requires the python>=3.10 and tzdata library.
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
# string value is passed to ZoneInfo()
# leave blank for localtime
Expand Down
37 changes: 16 additions & 21 deletions contributing/samples/telemetry/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import asyncio
from contextlib import aclosing
import os
import time

Expand Down Expand Up @@ -46,19 +47,16 @@ async def run_prompt(session: Session, new_message: str):
role='user', parts=[types.Part.from_text(text=new_message)]
)
print('** User says:', content.model_dump(exclude_none=True))
# TODO - migrate try...finally to contextlib.aclosing after Python 3.9 is
# no longer supported.
agen = runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
)
try:
async with aclosing(
runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
)
) as agen:
async for event in agen:
if event.content.parts and event.content.parts[0].text:
print(f'** {event.author}: {event.content.parts[0].text}')
finally:
await agen.aclose()

async def run_prompt_bytes(session: Session, new_message: str):
content = types.Content(
Expand All @@ -70,20 +68,17 @@ async def run_prompt_bytes(session: Session, new_message: str):
],
)
print('** User says:', content.model_dump(exclude_none=True))
# TODO - migrate try...finally to contextlib.aclosing after Python 3.9 is
# no longer supported.
agen = runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
run_config=RunConfig(save_input_blobs_as_artifacts=True),
)
try:
async with aclosing(
runner.run_async(
user_id=user_id_1,
session_id=session.id,
new_message=content,
run_config=RunConfig(save_input_blobs_as_artifacts=True),
)
) as agen:
async for event in agen:
if event.content.parts and event.content.parts[0].text:
print(f'** {event.author}: {event.content.parts[0].text}')
finally:
await agen.aclose()

start_time = time.time()
print('Start time:', start_time)
Expand Down
6 changes: 3 additions & 3 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5620,7 +5620,7 @@ pip install google-cloud-aiplatform[adk,agent_engines]
```

!!!info
Agent Engine only supported Python version >=3.9 and <=3.12.
Agent Engine only supported Python version >=3.10 and <=3.12.

### Initialization

Expand Down Expand Up @@ -8073,7 +8073,7 @@ setting up a basic agent with multiple tools, and running it locally either in t
<!-- <img src="../../assets/quickstart.png" alt="Quickstart setup"> -->

This quickstart assumes a local IDE (VS Code, PyCharm, IntelliJ IDEA, etc.)
with Python 3.9+ or Java 17+ and terminal access. This method runs the
with Python 3.10+ or Java 17+ and terminal access. This method runs the
application entirely on your machine and is recommended for internal development.

## 1. Set up Environment & Install ADK {#venv-install}
Expand Down Expand Up @@ -16475,7 +16475,7 @@ This guide covers two primary integration patterns:
Before you begin, ensure you have the following set up:

* **Set up ADK:** Follow the standard ADK [setup instructions](../get-started/quickstart.md/#venv-install) in the quickstart.
* **Install/update Python/Java:** MCP requires Python version of 3.9 or higher for Python or Java 17+.
* **Install/update Python/Java:** MCP requires Python version of 3.10 or higher for Python or Java 17+.
* **Setup Node.js and npx:** **(Python only)** Many community MCP servers are distributed as Node.js packages and run using `npx`. Install Node.js (which includes npx) if you haven't already. For details, see [https://nodejs.org/en](https://nodejs.org/en).
* **Verify Installations:** **(Python only)** Confirm `adk` and `npx` are in your PATH within the activated virtual environment:

Expand Down
16 changes: 2 additions & 14 deletions src/google/adk/a2a/converters/part_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,11 @@
from typing import Optional
from typing import Union

from .utils import _get_adk_metadata_key

try:
from a2a import types as a2a_types
except ImportError as e:
import sys

if sys.version_info < (3, 10):
raise ImportError(
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
) from e
else:
raise e

from a2a import types as a2a_types
from google.genai import types as genai_types

from ..experimental import a2a_experimental
from .utils import _get_adk_metadata_key

logger = logging.getLogger('google_adk.' + __name__)

Expand Down
15 changes: 2 additions & 13 deletions src/google/adk/a2a/converters/request_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,12 @@
from __future__ import annotations

from collections.abc import Callable
import sys
from typing import Any
from typing import Optional

from pydantic import BaseModel

try:
from a2a.server.agent_execution import RequestContext
except ImportError as e:
if sys.version_info < (3, 10):
raise ImportError(
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
) from e
else:
raise e

from a2a.server.agent_execution import RequestContext
from google.genai import types as genai_types
from pydantic import BaseModel

from ...runners import RunConfig
from ..experimental import a2a_experimental
Expand Down
36 changes: 12 additions & 24 deletions src/google/adk/a2a/executor/a2a_agent_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,22 @@
from typing import Optional
import uuid

from ...utils.context_utils import Aclosing

try:
from a2a.server.agent_execution import AgentExecutor
from a2a.server.agent_execution.context import RequestContext
from a2a.server.events.event_queue import EventQueue
from a2a.types import Artifact
from a2a.types import Message
from a2a.types import Role
from a2a.types import TaskArtifactUpdateEvent
from a2a.types import TaskState
from a2a.types import TaskStatus
from a2a.types import TaskStatusUpdateEvent
from a2a.types import TextPart

except ImportError as e:
import sys

if sys.version_info < (3, 10):
raise ImportError(
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
) from e
else:
raise e
from a2a.server.agent_execution import AgentExecutor
from a2a.server.agent_execution.context import RequestContext
from a2a.server.events.event_queue import EventQueue
from a2a.types import Artifact
from a2a.types import Message
from a2a.types import Role
from a2a.types import TaskArtifactUpdateEvent
from a2a.types import TaskState
from a2a.types import TaskStatus
from a2a.types import TaskStatusUpdateEvent
from a2a.types import TextPart
from google.adk.runners import Runner
from pydantic import BaseModel
from typing_extensions import override

from ...utils.context_utils import Aclosing
from ..converters.event_converter import AdkEventToA2AEventsConverter
from ..converters.event_converter import convert_event_to_a2a_events
from ..converters.part_converter import A2APartToGenAIPartConverter
Expand Down
20 changes: 5 additions & 15 deletions src/google/adk/a2a/utils/agent_card_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,15 @@
from __future__ import annotations

import re
import sys
from typing import Dict
from typing import List
from typing import Optional

try:
from a2a.types import AgentCapabilities
from a2a.types import AgentCard
from a2a.types import AgentProvider
from a2a.types import AgentSkill
from a2a.types import SecurityScheme
except ImportError as e:
if sys.version_info < (3, 10):
raise ImportError(
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
) from e
else:
raise e

from a2a.types import AgentCapabilities
from a2a.types import AgentCard
from a2a.types import AgentProvider
from a2a.types import AgentSkill
from a2a.types import SecurityScheme

from ...agents.base_agent import BaseAgent
from ...agents.llm_agent import LlmAgent
Expand Down
23 changes: 6 additions & 17 deletions src/google/adk/a2a/utils/agent_to_a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,18 @@
from __future__ import annotations

import logging
import sys

try:
from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryTaskStore
from a2a.types import AgentCard
except ImportError as e:
if sys.version_info < (3, 10):
raise ImportError(
"A2A requires Python 3.10 or above. Please upgrade your Python version."
) from e
else:
raise e

from typing import Optional
from typing import Union

from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.tasks import InMemoryTaskStore
from a2a.types import AgentCard
from starlette.applications import Starlette

from ...agents.base_agent import BaseAgent
from ...artifacts.in_memory_artifact_service import InMemoryArtifactService
from ...auth.credential_service.in_memory_credential_service import InMemoryCredentialService
from ...cli.utils.logs import setup_adk_logger
from ...memory.in_memory_memory_service import InMemoryMemoryService
from ...runners import Runner
from ...sessions.in_memory_session_service import InMemorySessionService
Expand Down Expand Up @@ -117,7 +105,8 @@ def to_a2a(
app = to_a2a(agent, agent_card=my_custom_agent_card)
"""
# Set up ADK logging to ensure logs are visible when using uvicorn directly
setup_adk_logger(logging.INFO)
adk_logger = logging.getLogger("google_adk")
adk_logger.setLevel(logging.INFO)

async def create_runner() -> Runner:
"""Create a runner for the agent."""
Expand Down
18 changes: 2 additions & 16 deletions src/google/adk/agents/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import logging
import sys

from .base_agent import BaseAgent
from .invocation_context import InvocationContext
from .live_request_queue import LiveRequest
from .live_request_queue import LiveRequestQueue
from .llm_agent import Agent
from .llm_agent import LlmAgent
from .loop_agent import LoopAgent
from .mcp_instruction_provider import McpInstructionProvider
from .parallel_agent import ParallelAgent
from .run_config import RunConfig
from .sequential_agent import SequentialAgent
Expand All @@ -31,23 +29,11 @@
'BaseAgent',
'LlmAgent',
'LoopAgent',
'McpInstructionProvider',
'ParallelAgent',
'SequentialAgent',
'InvocationContext',
'LiveRequest',
'LiveRequestQueue',
'RunConfig',
]

if sys.version_info < (3, 10):
logger = logging.getLogger('google_adk.' + __name__)
logger.warning(
'MCP requires Python 3.10 or above. Please upgrade your Python'
' version in order to use it.'
)
else:
from .mcp_instruction_provider import McpInstructionProvider

__all__.extend([
'McpInstructionProvider',
])
Loading
Loading