mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
chore: Drop Python 3.9 support, set minimum to Python 3.10
Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 839799108
This commit is contained in:
committed by
Copybara-Service
parent
e02b9fb608
commit
8c9105bf14
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import asyncio
|
||||
from contextlib import aclosing
|
||||
import os
|
||||
import time
|
||||
|
||||
@@ -46,19 +47,16 @@ async def main():
|
||||
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(
|
||||
@@ -70,20 +68,17 @@ async def main():
|
||||
],
|
||||
)
|
||||
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)
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
@@ -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}
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -26,23 +26,11 @@ from typing import List
|
||||
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__)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,34 +23,22 @@ from typing import Callable
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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."""
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
# 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
|
||||
@@ -22,6 +19,7 @@ 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
|
||||
@@ -31,6 +29,7 @@ __all__ = [
|
||||
'BaseAgent',
|
||||
'LlmAgent',
|
||||
'LoopAgent',
|
||||
'McpInstructionProvider',
|
||||
'ParallelAgent',
|
||||
'SequentialAgent',
|
||||
'InvocationContext',
|
||||
@@ -38,16 +37,3 @@ __all__ = [
|
||||
'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',
|
||||
])
|
||||
|
||||
@@ -22,24 +22,12 @@ from typing import Any
|
||||
from typing import Dict
|
||||
from typing import TextIO
|
||||
|
||||
from mcp import types
|
||||
|
||||
from ..tools.mcp_tool.mcp_session_manager import MCPSessionManager
|
||||
from .llm_agent import InstructionProvider
|
||||
from .readonly_context import ReadonlyContext
|
||||
|
||||
# Attempt to import MCP Session Manager from the MCP library, and hints user to
|
||||
# upgrade their Python version to 3.10 if it fails.
|
||||
try:
|
||||
from mcp import types
|
||||
|
||||
from ..tools.mcp_tool.mcp_session_manager import MCPSessionManager
|
||||
except ImportError as e:
|
||||
if sys.version_info < (3, 10):
|
||||
raise ImportError(
|
||||
"MCP Session Manager requires Python 3.10 or above. Please upgrade"
|
||||
" your Python version."
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
class McpInstructionProvider(InstructionProvider):
|
||||
"""Fetches agent instructions from an MCP server."""
|
||||
|
||||
@@ -48,19 +48,54 @@ def _create_branch_ctx_for_sub_agent(
|
||||
return invocation_context
|
||||
|
||||
|
||||
async def _merge_agent_run(
|
||||
agent_runs: list[AsyncGenerator[Event, None]],
|
||||
) -> AsyncGenerator[Event, None]:
|
||||
"""Merges agent runs using asyncio.TaskGroup on Python 3.11+."""
|
||||
sentinel = object()
|
||||
queue = asyncio.Queue()
|
||||
|
||||
# Agents are processed in parallel.
|
||||
# Events for each agent are put on queue sequentially.
|
||||
async def process_an_agent(events_for_one_agent):
|
||||
try:
|
||||
async for event in events_for_one_agent:
|
||||
resume_signal = asyncio.Event()
|
||||
await queue.put((event, resume_signal))
|
||||
# Wait for upstream to consume event before generating new events.
|
||||
await resume_signal.wait()
|
||||
finally:
|
||||
# Mark agent as finished.
|
||||
await queue.put((sentinel, None))
|
||||
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
for events_for_one_agent in agent_runs:
|
||||
tg.create_task(process_an_agent(events_for_one_agent))
|
||||
|
||||
sentinel_count = 0
|
||||
# Run until all agents finished processing.
|
||||
while sentinel_count < len(agent_runs):
|
||||
event, resume_signal = await queue.get()
|
||||
# Agent finished processing.
|
||||
if event is sentinel:
|
||||
sentinel_count += 1
|
||||
else:
|
||||
yield event
|
||||
# Signal to agent that it should generate next event.
|
||||
resume_signal.set()
|
||||
|
||||
|
||||
# TODO - remove once Python <3.11 is no longer supported.
|
||||
async def _merge_agent_run_pre_3_11(
|
||||
agent_runs: list[AsyncGenerator[Event, None]],
|
||||
) -> AsyncGenerator[Event, None]:
|
||||
"""Merges the agent run event generator.
|
||||
This version works in Python 3.9 and 3.10 and uses custom replacement for
|
||||
asyncio.TaskGroup for tasks cancellation and exception handling.
|
||||
"""Merges agent runs for Python 3.10 without asyncio.TaskGroup.
|
||||
|
||||
This implementation guarantees for each agent, it won't move on until the
|
||||
generated event is processed by upstream runner.
|
||||
Uses custom cancellation and exception handling to mirror TaskGroup
|
||||
semantics. Each agent waits until the runner processes emitted events.
|
||||
|
||||
Args:
|
||||
agent_runs: A list of async generators that yield events from each agent.
|
||||
agent_runs: Async generators that yield events from each agent.
|
||||
|
||||
Yields:
|
||||
Event: The next event from the merged generator.
|
||||
@@ -112,53 +147,6 @@ async def _merge_agent_run_pre_3_11(
|
||||
task.cancel()
|
||||
|
||||
|
||||
async def _merge_agent_run(
|
||||
agent_runs: list[AsyncGenerator[Event, None]],
|
||||
) -> AsyncGenerator[Event, None]:
|
||||
"""Merges the agent run event generator.
|
||||
|
||||
This implementation guarantees for each agent, it won't move on until the
|
||||
generated event is processed by upstream runner.
|
||||
|
||||
Args:
|
||||
agent_runs: A list of async generators that yield events from each agent.
|
||||
|
||||
Yields:
|
||||
Event: The next event from the merged generator.
|
||||
"""
|
||||
sentinel = object()
|
||||
queue = asyncio.Queue()
|
||||
|
||||
# Agents are processed in parallel.
|
||||
# Events for each agent are put on queue sequentially.
|
||||
async def process_an_agent(events_for_one_agent):
|
||||
try:
|
||||
async for event in events_for_one_agent:
|
||||
resume_signal = asyncio.Event()
|
||||
await queue.put((event, resume_signal))
|
||||
# Wait for upstream to consume event before generating new events.
|
||||
await resume_signal.wait()
|
||||
finally:
|
||||
# Mark agent as finished.
|
||||
await queue.put((sentinel, None))
|
||||
|
||||
async with asyncio.TaskGroup() as tg:
|
||||
for events_for_one_agent in agent_runs:
|
||||
tg.create_task(process_an_agent(events_for_one_agent))
|
||||
|
||||
sentinel_count = 0
|
||||
# Run until all agents finished processing.
|
||||
while sentinel_count < len(agent_runs):
|
||||
event, resume_signal = await queue.get()
|
||||
# Agent finished processing.
|
||||
if event is sentinel:
|
||||
sentinel_count += 1
|
||||
else:
|
||||
yield event
|
||||
# Signal to agent that it should generate next event.
|
||||
resume_signal.set()
|
||||
|
||||
|
||||
class ParallelAgent(BaseAgent):
|
||||
"""A shell agent that runs its sub-agents in parallel in an isolated manner.
|
||||
|
||||
@@ -195,13 +183,11 @@ class ParallelAgent(BaseAgent):
|
||||
|
||||
pause_invocation = False
|
||||
try:
|
||||
# TODO remove if once Python <3.11 is no longer supported.
|
||||
merge_func = (
|
||||
_merge_agent_run
|
||||
if sys.version_info >= (3, 11)
|
||||
else _merge_agent_run_pre_3_11
|
||||
)
|
||||
|
||||
async with Aclosing(merge_func(agent_runs)) as agen:
|
||||
async for event in agen:
|
||||
yield event
|
||||
|
||||
@@ -26,30 +26,22 @@ from typing import Union
|
||||
from urllib.parse import urlparse
|
||||
import uuid
|
||||
|
||||
try:
|
||||
from a2a.client import Client as A2AClient
|
||||
from a2a.client import ClientEvent as A2AClientEvent
|
||||
from a2a.client.card_resolver import A2ACardResolver
|
||||
from a2a.client.client import ClientConfig as A2AClientConfig
|
||||
from a2a.client.client_factory import ClientFactory as A2AClientFactory
|
||||
from a2a.client.errors import A2AClientError
|
||||
from a2a.types import AgentCard
|
||||
from a2a.types import Message as A2AMessage
|
||||
from a2a.types import Part as A2APart
|
||||
from a2a.types import Role
|
||||
from a2a.types import TaskArtifactUpdateEvent as A2ATaskArtifactUpdateEvent
|
||||
from a2a.types import TaskState
|
||||
from a2a.types import TaskStatusUpdateEvent as A2ATaskStatusUpdateEvent
|
||||
from a2a.types import TransportProtocol as A2ATransport
|
||||
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.client import Client as A2AClient
|
||||
from a2a.client import ClientEvent as A2AClientEvent
|
||||
from a2a.client.card_resolver import A2ACardResolver
|
||||
from a2a.client.client import ClientConfig as A2AClientConfig
|
||||
from a2a.client.client_factory import ClientFactory as A2AClientFactory
|
||||
from a2a.client.errors import A2AClientError
|
||||
from a2a.types import AgentCard
|
||||
from a2a.types import Message as A2AMessage
|
||||
from a2a.types import Part as A2APart
|
||||
from a2a.types import Role
|
||||
from a2a.types import TaskArtifactUpdateEvent as A2ATaskArtifactUpdateEvent
|
||||
from a2a.types import TaskState
|
||||
from a2a.types import TaskStatusUpdateEvent as A2ATaskStatusUpdateEvent
|
||||
from a2a.types import TransportProtocol as A2ATransport
|
||||
from google.genai import types as genai_types
|
||||
import httpx
|
||||
|
||||
try:
|
||||
from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
|
||||
@@ -57,9 +49,6 @@ except ImportError:
|
||||
# Fallback for older versions of a2a-sdk.
|
||||
AGENT_CARD_WELL_KNOWN_PATH = "/.well-known/agent.json"
|
||||
|
||||
from google.genai import types as genai_types
|
||||
import httpx
|
||||
|
||||
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
|
||||
|
||||
@@ -342,25 +342,14 @@ def get_fast_api_app(
|
||||
)
|
||||
|
||||
if a2a:
|
||||
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
|
||||
from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
|
||||
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 a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
|
||||
|
||||
from ..a2a.executor.a2a_agent_executor import A2aAgentExecutor
|
||||
from ..a2a.executor.a2a_agent_executor import A2aAgentExecutor
|
||||
|
||||
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
|
||||
# locate all a2a agent apps in the agents directory
|
||||
base_path = Path.cwd() / agents_dir
|
||||
# the root agents directory should be an existing folder
|
||||
|
||||
@@ -30,16 +30,9 @@ from .tool_context import ToolContext
|
||||
try:
|
||||
from crewai.tools import BaseTool as CrewaiBaseTool
|
||||
except ImportError as e:
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
raise ImportError(
|
||||
'Crewai Tools require Python 3.10+. Please upgrade your Python version.'
|
||||
) from e
|
||||
else:
|
||||
raise ImportError(
|
||||
"Crewai Tools require pip install 'google-adk[extensions]'."
|
||||
) from e
|
||||
raise ImportError(
|
||||
"Crewai Tools require pip install 'google-adk[extensions]'."
|
||||
) from e
|
||||
|
||||
|
||||
class CrewaiTool(FunctionTool):
|
||||
|
||||
@@ -39,15 +39,7 @@ try:
|
||||
|
||||
except ImportError as e:
|
||||
import logging
|
||||
import sys
|
||||
|
||||
logger = logging.getLogger('google_adk.' + __name__)
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
logger.warning(
|
||||
'MCP Tool requires Python 3.10 or above. Please upgrade your Python'
|
||||
' version.'
|
||||
)
|
||||
else:
|
||||
logger.debug('MCP Tool is not installed')
|
||||
logger.debug(e)
|
||||
logger.debug('MCP Tool is not installed')
|
||||
logger.debug(e)
|
||||
|
||||
@@ -29,24 +29,13 @@ from typing import TextIO
|
||||
from typing import Union
|
||||
|
||||
import anyio
|
||||
from mcp import ClientSession
|
||||
from mcp import StdioServerParameters
|
||||
from mcp.client.sse import sse_client
|
||||
from mcp.client.stdio import stdio_client
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
from pydantic import BaseModel
|
||||
|
||||
try:
|
||||
from mcp import ClientSession
|
||||
from mcp import StdioServerParameters
|
||||
from mcp.client.sse import sse_client
|
||||
from mcp.client.stdio import stdio_client
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
except ImportError as e:
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
raise ImportError(
|
||||
'MCP Tool requires Python 3.10 or above. Please upgrade your Python'
|
||||
' version.'
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
|
||||
logger = logging.getLogger('google_adk.' + __name__)
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ from __future__ import annotations
|
||||
import base64
|
||||
import inspect
|
||||
import logging
|
||||
import sys
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
@@ -27,35 +26,21 @@ import warnings
|
||||
|
||||
from fastapi.openapi.models import APIKeyIn
|
||||
from google.genai.types import FunctionDeclaration
|
||||
from mcp.types import Tool as McpBaseTool
|
||||
from typing_extensions import override
|
||||
|
||||
from ...agents.readonly_context import ReadonlyContext
|
||||
from ...features import FeatureName
|
||||
from ...features import is_feature_enabled
|
||||
from .._gemini_schema_util import _to_gemini_schema
|
||||
from .mcp_session_manager import MCPSessionManager
|
||||
from .mcp_session_manager import retry_on_errors
|
||||
|
||||
# Attempt to import MCP Tool from the MCP library, and hints user to upgrade
|
||||
# their Python version to 3.10 if it fails.
|
||||
try:
|
||||
from mcp.types import Tool as McpBaseTool
|
||||
except ImportError as e:
|
||||
if sys.version_info < (3, 10):
|
||||
raise ImportError(
|
||||
"MCP Tool requires Python 3.10 or above. Please upgrade your Python"
|
||||
" version."
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
|
||||
|
||||
from ...auth.auth_credential import AuthCredential
|
||||
from ...auth.auth_schemes import AuthScheme
|
||||
from ...auth.auth_tool import AuthConfig
|
||||
from ...features import FeatureName
|
||||
from ...features import is_feature_enabled
|
||||
from .._gemini_schema_util import _to_gemini_schema
|
||||
from ..base_authenticated_tool import BaseAuthenticatedTool
|
||||
# import
|
||||
from ..tool_context import ToolContext
|
||||
from .mcp_session_manager import MCPSessionManager
|
||||
from .mcp_session_manager import retry_on_errors
|
||||
|
||||
logger = logging.getLogger("google_adk." + __name__)
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ from typing import TextIO
|
||||
from typing import Union
|
||||
import warnings
|
||||
|
||||
from mcp import StdioServerParameters
|
||||
from mcp.types import ListToolsResult
|
||||
from pydantic import model_validator
|
||||
from typing_extensions import override
|
||||
|
||||
@@ -41,23 +43,6 @@ from .mcp_session_manager import retry_on_errors
|
||||
from .mcp_session_manager import SseConnectionParams
|
||||
from .mcp_session_manager import StdioConnectionParams
|
||||
from .mcp_session_manager import StreamableHTTPConnectionParams
|
||||
|
||||
# Attempt to import MCP Tool from the MCP library, and hints user to upgrade
|
||||
# their Python version to 3.10 if it fails.
|
||||
try:
|
||||
from mcp import StdioServerParameters
|
||||
from mcp.types import ListToolsResult
|
||||
except ImportError as e:
|
||||
import sys
|
||||
|
||||
if sys.version_info < (3, 10):
|
||||
raise ImportError(
|
||||
"MCP Tool requires Python 3.10 or above. Please upgrade your Python"
|
||||
" version."
|
||||
) from e
|
||||
else:
|
||||
raise e
|
||||
|
||||
from .mcp_tool import MCPTool
|
||||
|
||||
logger = logging.getLogger("google_adk." + __name__)
|
||||
|
||||
@@ -20,30 +20,7 @@ Please do not rely on the implementation details.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import AbstractAsyncContextManager
|
||||
from typing import Any
|
||||
from typing import AsyncGenerator
|
||||
from contextlib import aclosing
|
||||
|
||||
|
||||
class Aclosing(AbstractAsyncContextManager):
|
||||
"""Async context manager for safely finalizing an asynchronously cleaned-up
|
||||
resource such as an async generator, calling its ``aclose()`` method.
|
||||
Needed to correctly close contexts for OTel spans.
|
||||
See https://github.com/google/adk-python/issues/1670#issuecomment-3115891100.
|
||||
|
||||
Based on
|
||||
https://docs.python.org/3/library/contextlib.html#contextlib.aclosing
|
||||
which is available in Python 3.10+.
|
||||
|
||||
TODO: replace all occurrences with contextlib.aclosing once Python 3.9 is no
|
||||
longer supported.
|
||||
"""
|
||||
|
||||
def __init__(self, async_generator: AsyncGenerator[Any, None]):
|
||||
self.async_generator = async_generator
|
||||
|
||||
async def __aenter__(self):
|
||||
return self.async_generator
|
||||
|
||||
async def __aexit__(self, *exc_info):
|
||||
await self.async_generator.aclose()
|
||||
# Re-export aclosing for backward compatibility
|
||||
Aclosing = aclosing
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user