google-adk 1.7.0__tar.gz → 1.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {google_adk-1.7.0 → google_adk-1.8.0}/PKG-INFO +2 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/pyproject.toml +1 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/converters/request_converter.py +1 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/logs/log_utils.py +1 -2
- google_adk-1.8.0/src/google/adk/a2a/utils/agent_card_builder.py +544 -0
- google_adk-1.8.0/src/google/adk/a2a/utils/agent_to_a2a.py +118 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/base_agent.py +6 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/config_schemas/AgentConfig.json +22 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/live_request_queue.py +15 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/llm_agent.py +11 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/loop_agent.py +6 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/remote_a2a_agent.py +2 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/artifacts/gcs_artifact_service.py +86 -18
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/index.html +2 -2
- google_adk-1.7.0/src/google/adk/cli/browser/main-SRBSE46V.js → google_adk-1.8.0/src/google/adk/cli/browser/main-W7QZBYAR.js +139 -139
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/cli_eval.py +87 -12
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/cli_tools_click.py +143 -82
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/fast_api.py +136 -95
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_metrics.py +4 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_sets_manager.py +5 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/final_response_match_v2.py +2 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/gcs_eval_sets_manager.py +2 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/local_eval_service.py +2 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/local_eval_set_results_manager.py +2 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/local_eval_sets_manager.py +1 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/metric_evaluator_registry.py +16 -6
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/vertex_ai_eval_facade.py +7 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/events/event.py +7 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/base_llm_flow.py +25 -6
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/functions.py +13 -19
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/in_memory_memory_service.py +1 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/vertex_ai_memory_bank_service.py +12 -10
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/anthropic_llm.py +2 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/base_llm_connection.py +2 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/gemini_llm_connection.py +17 -6
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/google_llm.py +35 -5
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/lite_llm.py +31 -18
- google_adk-1.8.0/src/google/adk/py.typed +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/database_session_service.py +25 -24
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/vertex_ai_session_service.py +13 -5
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/__init__.py +2 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/_automatic_function_calling_util.py +20 -2
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/agent_tool.py +14 -3
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/base_toolset.py +22 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/metadata_tool.py +2 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/query_tool.py +15 -1
- google_adk-1.8.0/src/google/adk/tools/computer_use/base_computer.py +265 -0
- google_adk-1.8.0/src/google/adk/tools/computer_use/computer_use_tool.py +166 -0
- google_adk-1.8.0/src/google/adk/tools/computer_use/computer_use_toolset.py +220 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/exit_loop_tool.py +1 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/langchain_tool.py +14 -3
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_spec_parser.py +5 -0
- google_adk-1.8.0/src/google/adk/utils/__init__.py +13 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/version.py +1 -1
- {google_adk-1.7.0 → google_adk-1.8.0}/LICENSE +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/README.md +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/converters/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/converters/event_converter.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/converters/part_converter.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/converters/utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/executor/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/executor/a2a_agent_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/executor/task_result_aggregator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/a2a/logs/__init__.py +0 -0
- /google_adk-1.7.0/src/google/adk/py.typed → /google_adk-1.8.0/src/google/adk/a2a/utils/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/active_streaming_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/agent_config.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/callback_context.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/common_configs.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/config_agent_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/invocation_context.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/langgraph_agent.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/parallel_agent.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/readonly_context.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/run_config.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/sequential_agent.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/agents/transcription_entry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/artifacts/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/artifacts/base_artifact_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/artifacts/in_memory_artifact_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/auth_credential.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/auth_handler.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/auth_preprocessor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/auth_schemes.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/auth_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/credential_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/credential_service/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/credential_service/base_credential_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/credential_service/in_memory_credential_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/credential_service/session_state_credential_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/exchanger/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/exchanger/base_credential_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/exchanger/credential_exchanger_registry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/exchanger/oauth2_credential_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/oauth2_credential_util.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/refresher/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/refresher/base_credential_refresher.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/refresher/credential_refresher_registry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/auth/refresher/oauth2_credential_refresher.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/__main__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/agent_graph.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/adk_favicon.svg +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/assets/ADK-512-color.svg +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/assets/audio-processor.js +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/assets/config/runtime-config.json +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/chunk-EQDQRRRY.js +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/chunk-TXJFAAIW.js +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/polyfills-B6TNHZQ6.js +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/browser/styles-4VDSPQ37.css +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/cli.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/cli_create.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/cli_deploy.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/agent_loader.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/cleanup.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/common.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/envs.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/evals.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/cli/utils/logs.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/base_code_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/built_in_code_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/code_execution_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/code_executor_context.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/container_code_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/unsafe_local_code_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/code_executors/vertex_ai_code_executor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/errors/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/errors/not_found_error.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/_eval_set_results_manager_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/_eval_sets_manager_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/agent_evaluator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/base_eval_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/constants.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_case.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_result.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_set.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/eval_set_results_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/evaluation_constants.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/evaluation_generator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/evaluator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/final_response_match_v1.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/gcs_eval_set_results_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/in_memory_eval_sets_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/llm_as_judge.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/llm_as_judge_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/response_evaluator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/safety_evaluator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/evaluation/trajectory_evaluator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/events/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/events/event_actions.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/examples/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/examples/base_example_provider.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/examples/example.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/examples/example_util.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/examples/vertex_ai_example_store.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/_base_llm_processor.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/_code_execution.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/_nl_planning.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/agent_transfer.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/audio_transcriber.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/auto_flow.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/basic.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/contents.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/identity.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/instructions.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/flows/llm_flows/single_flow.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/base_memory_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/memory_entry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/memory/vertex_ai_rag_memory_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/base_llm.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/llm_request.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/llm_response.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/models/registry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/planners/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/planners/base_planner.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/planners/built_in_planner.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/planners/plan_re_act_planner.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/platform/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/platform/internal/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/platform/internal/thread.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/platform/thread.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/plugins/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/plugins/base_plugin.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/plugins/plugin_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/runners.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/_session_util.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/base_session_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/in_memory_session_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/session.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/sessions/state.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/telemetry.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/_forwarding_artifact_service.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/_function_parameter_parse_util.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/_gemini_schema_util.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/_memory_entry_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/apihub_tool/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/apihub_tool/apihub_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/apihub_tool/clients/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/apihub_tool/clients/apihub_client.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/apihub_tool/clients/secret_client.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/application_integration_tool/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/application_integration_tool/application_integration_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/application_integration_tool/clients/connections_client.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/application_integration_tool/clients/integration_client.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/application_integration_tool/integration_connector_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/authenticated_function_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/base_authenticated_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/base_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/bigquery_credentials.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/bigquery_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/bigquery_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/client.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/bigquery/config.py +0 -0
- {google_adk-1.7.0/src/google/adk/utils → google_adk-1.8.0/src/google/adk/tools/computer_use}/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/crewai_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/enterprise_search_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/example_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/function_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/get_user_choice_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_api_tool/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_api_tool/google_api_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_api_tool/google_api_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_api_tool/google_api_toolsets.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_api_tool/googleapi_to_openapi_converter.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/google_search_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/load_artifacts_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/load_memory_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/load_web_page.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/long_running_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/mcp_tool/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/mcp_tool/conversion_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/mcp_tool/mcp_session_manager.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/mcp_tool/mcp_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/mcp_tool/mcp_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/auth_helpers.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/credential_exchangers/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/credential_exchangers/auto_auth_credential_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/credential_exchangers/base_credential_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/credential_exchangers/oauth2_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/common/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/common/common.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/openapi_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/operation_parser.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/rest_api_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/openapi_tool/openapi_spec_parser/tool_auth_handler.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/preload_memory_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/retrieval/__init__.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/retrieval/base_retrieval_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/retrieval/files_retrieval.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/retrieval/llama_index_retrieval.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/retrieval/vertex_ai_rag_retrieval.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/tool_context.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/toolbox_toolset.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/transfer_to_agent_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/url_context_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/tools/vertex_ai_search_tool.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/utils/feature_decorator.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/utils/instructions_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/utils/model_name_utils.py +0 -0
- {google_adk-1.7.0 → google_adk-1.8.0}/src/google/adk/utils/variant_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: google-adk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.8.0
|
4
4
|
Summary: Agent Development Kit
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
6
6
|
Requires-Python: >=3.9
|
@@ -81,6 +81,7 @@ Requires-Dist: pytest-asyncio>=0.25.0 ; extra == "test"
|
|
81
81
|
Requires-Dist: pytest-mock>=3.14.0 ; extra == "test"
|
82
82
|
Requires-Dist: pytest-xdist>=3.6.1 ; extra == "test"
|
83
83
|
Requires-Dist: pytest>=8.3.4 ; extra == "test"
|
84
|
+
Requires-Dist: python-multipart>=0.0.9 ; extra == "test"
|
84
85
|
Project-URL: changelog, https://github.com/google/adk-python/blob/main/CHANGELOG.md
|
85
86
|
Project-URL: documentation, https://google.github.io/adk-docs/
|
86
87
|
Project-URL: homepage, https://google.github.io/adk-docs/
|
@@ -22,8 +22,7 @@ try:
|
|
22
22
|
except ImportError as e:
|
23
23
|
if sys.version_info < (3, 10):
|
24
24
|
raise ImportError(
|
25
|
-
'A2A
|
26
|
-
' version.'
|
25
|
+
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
|
27
26
|
) from e
|
28
27
|
else:
|
29
28
|
raise e
|
@@ -30,8 +30,7 @@ try:
|
|
30
30
|
except ImportError as e:
|
31
31
|
if sys.version_info < (3, 10):
|
32
32
|
raise ImportError(
|
33
|
-
"A2A
|
34
|
-
" version."
|
33
|
+
"A2A requires Python 3.10 or above. Please upgrade your Python version."
|
35
34
|
) from e
|
36
35
|
else:
|
37
36
|
raise e
|
@@ -0,0 +1,544 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import re
|
18
|
+
import sys
|
19
|
+
from typing import Dict
|
20
|
+
from typing import List
|
21
|
+
from typing import Optional
|
22
|
+
|
23
|
+
try:
|
24
|
+
from a2a.types import AgentCapabilities
|
25
|
+
from a2a.types import AgentCard
|
26
|
+
from a2a.types import AgentProvider
|
27
|
+
from a2a.types import AgentSkill
|
28
|
+
from a2a.types import SecurityScheme
|
29
|
+
except ImportError as e:
|
30
|
+
if sys.version_info < (3, 10):
|
31
|
+
raise ImportError(
|
32
|
+
'A2A requires Python 3.10 or above. Please upgrade your Python version.'
|
33
|
+
) from e
|
34
|
+
else:
|
35
|
+
raise e
|
36
|
+
|
37
|
+
|
38
|
+
from ...agents.base_agent import BaseAgent
|
39
|
+
from ...agents.llm_agent import LlmAgent
|
40
|
+
from ...agents.loop_agent import LoopAgent
|
41
|
+
from ...agents.parallel_agent import ParallelAgent
|
42
|
+
from ...agents.sequential_agent import SequentialAgent
|
43
|
+
from ...tools.example_tool import ExampleTool
|
44
|
+
from ...utils.feature_decorator import experimental
|
45
|
+
|
46
|
+
|
47
|
+
@experimental
|
48
|
+
class AgentCardBuilder:
|
49
|
+
"""Builder class for creating agent cards from ADK agents.
|
50
|
+
|
51
|
+
This class provides functionality to convert ADK agents into A2A agent cards,
|
52
|
+
including extracting skills, capabilities, and metadata from various agent
|
53
|
+
types.
|
54
|
+
"""
|
55
|
+
|
56
|
+
def __init__(
|
57
|
+
self,
|
58
|
+
*,
|
59
|
+
agent: BaseAgent,
|
60
|
+
rpc_url: Optional[str] = None,
|
61
|
+
capabilities: Optional[AgentCapabilities] = None,
|
62
|
+
doc_url: Optional[str] = None,
|
63
|
+
provider: Optional[AgentProvider] = None,
|
64
|
+
agent_version: Optional[str] = None,
|
65
|
+
security_schemes: Optional[Dict[str, SecurityScheme]] = None,
|
66
|
+
):
|
67
|
+
if not agent:
|
68
|
+
raise ValueError('Agent cannot be None or empty.')
|
69
|
+
|
70
|
+
self._agent = agent
|
71
|
+
self._rpc_url = rpc_url or 'http://localhost:80/a2a'
|
72
|
+
self._capabilities = capabilities or AgentCapabilities()
|
73
|
+
self._doc_url = doc_url
|
74
|
+
self._provider = provider
|
75
|
+
self._security_schemes = security_schemes
|
76
|
+
self._agent_version = agent_version or '0.0.1'
|
77
|
+
|
78
|
+
async def build(self) -> AgentCard:
|
79
|
+
"""Build and return the complete agent card."""
|
80
|
+
try:
|
81
|
+
primary_skills = await _build_primary_skills(self._agent)
|
82
|
+
sub_agent_skills = await _build_sub_agent_skills(self._agent)
|
83
|
+
all_skills = primary_skills + sub_agent_skills
|
84
|
+
|
85
|
+
return AgentCard(
|
86
|
+
name=self._agent.name,
|
87
|
+
description=self._agent.description or 'An ADK Agent',
|
88
|
+
doc_url=self._doc_url,
|
89
|
+
url=f"{self._rpc_url.rstrip('/')}",
|
90
|
+
version=self._agent_version,
|
91
|
+
capabilities=self._capabilities,
|
92
|
+
skills=all_skills,
|
93
|
+
defaultInputModes=['text/plain'],
|
94
|
+
defaultOutputModes=['text/plain'],
|
95
|
+
supportsAuthenticatedExtendedCard=False,
|
96
|
+
provider=self._provider,
|
97
|
+
securitySchemes=self._security_schemes,
|
98
|
+
)
|
99
|
+
except Exception as e:
|
100
|
+
raise RuntimeError(
|
101
|
+
f'Failed to build agent card for {self._agent.name}: {e}'
|
102
|
+
) from e
|
103
|
+
|
104
|
+
|
105
|
+
# Module-level helper functions
|
106
|
+
async def _build_primary_skills(agent: BaseAgent) -> List[AgentSkill]:
|
107
|
+
"""Build skills for any agent type."""
|
108
|
+
if isinstance(agent, LlmAgent):
|
109
|
+
return await _build_llm_agent_skills(agent)
|
110
|
+
else:
|
111
|
+
return await _build_non_llm_agent_skills(agent)
|
112
|
+
|
113
|
+
|
114
|
+
async def _build_llm_agent_skills(agent: LlmAgent) -> List[AgentSkill]:
|
115
|
+
"""Build skills for LLM agent."""
|
116
|
+
skills = []
|
117
|
+
|
118
|
+
# 1. Agent skill (main model skill)
|
119
|
+
agent_description = _build_llm_agent_description_with_instructions(agent)
|
120
|
+
agent_examples = await _extract_examples_from_agent(agent)
|
121
|
+
|
122
|
+
skills.append(
|
123
|
+
AgentSkill(
|
124
|
+
id=agent.name,
|
125
|
+
name='model',
|
126
|
+
description=agent_description,
|
127
|
+
examples=agent_examples,
|
128
|
+
inputModes=_get_input_modes(agent),
|
129
|
+
outputModes=_get_output_modes(agent),
|
130
|
+
tags=['llm'],
|
131
|
+
)
|
132
|
+
)
|
133
|
+
|
134
|
+
# 2. Tool skills
|
135
|
+
if agent.tools:
|
136
|
+
tool_skills = await _build_tool_skills(agent)
|
137
|
+
skills.extend(tool_skills)
|
138
|
+
|
139
|
+
# 3. Planner skill
|
140
|
+
if agent.planner:
|
141
|
+
skills.append(_build_planner_skill(agent))
|
142
|
+
|
143
|
+
# 4. Code executor skill
|
144
|
+
if agent.code_executor:
|
145
|
+
skills.append(_build_code_executor_skill(agent))
|
146
|
+
|
147
|
+
return skills
|
148
|
+
|
149
|
+
|
150
|
+
async def _build_sub_agent_skills(agent: BaseAgent) -> List[AgentSkill]:
|
151
|
+
"""Build skills for all sub-agents."""
|
152
|
+
sub_agent_skills = []
|
153
|
+
for sub_agent in agent.sub_agents:
|
154
|
+
try:
|
155
|
+
sub_skills = await _build_primary_skills(sub_agent)
|
156
|
+
for skill in sub_skills:
|
157
|
+
# Create a new skill instance to avoid modifying original if shared
|
158
|
+
aggregated_skill = AgentSkill(
|
159
|
+
id=f'{sub_agent.name}_{skill.id}',
|
160
|
+
name=f'{sub_agent.name}: {skill.name}',
|
161
|
+
description=skill.description,
|
162
|
+
examples=skill.examples,
|
163
|
+
inputModes=skill.inputModes,
|
164
|
+
outputModes=skill.outputModes,
|
165
|
+
tags=[f'sub_agent:{sub_agent.name}'] + (skill.tags or []),
|
166
|
+
)
|
167
|
+
sub_agent_skills.append(aggregated_skill)
|
168
|
+
except Exception as e:
|
169
|
+
# Log warning but continue with other sub-agents
|
170
|
+
print(
|
171
|
+
f'Warning: Failed to build skills for sub-agent {sub_agent.name}: {e}'
|
172
|
+
)
|
173
|
+
continue
|
174
|
+
|
175
|
+
return sub_agent_skills
|
176
|
+
|
177
|
+
|
178
|
+
async def _build_tool_skills(agent: LlmAgent) -> List[AgentSkill]:
|
179
|
+
"""Build skills for agent tools."""
|
180
|
+
tool_skills = []
|
181
|
+
canonical_tools = await agent.canonical_tools()
|
182
|
+
|
183
|
+
for tool in canonical_tools:
|
184
|
+
# Skip example tools as they're handled separately
|
185
|
+
if isinstance(tool, ExampleTool):
|
186
|
+
continue
|
187
|
+
|
188
|
+
tool_name = (
|
189
|
+
tool.name
|
190
|
+
if hasattr(tool, 'name') and tool.name
|
191
|
+
else tool.__class__.__name__
|
192
|
+
)
|
193
|
+
|
194
|
+
tool_skills.append(
|
195
|
+
AgentSkill(
|
196
|
+
id=f'{agent.name}-{tool_name}',
|
197
|
+
name=tool_name,
|
198
|
+
description=getattr(tool, 'description', f'Tool: {tool_name}'),
|
199
|
+
examples=None,
|
200
|
+
inputModes=None,
|
201
|
+
outputModes=None,
|
202
|
+
tags=['llm', 'tools'],
|
203
|
+
)
|
204
|
+
)
|
205
|
+
|
206
|
+
return tool_skills
|
207
|
+
|
208
|
+
|
209
|
+
def _build_planner_skill(agent: LlmAgent) -> AgentSkill:
|
210
|
+
"""Build planner skill for LLM agent."""
|
211
|
+
return AgentSkill(
|
212
|
+
id=f'{agent.name}-planner',
|
213
|
+
name='planning',
|
214
|
+
description='Can think about the tasks to do and make plans',
|
215
|
+
examples=None,
|
216
|
+
inputModes=None,
|
217
|
+
outputModes=None,
|
218
|
+
tags=['llm', 'planning'],
|
219
|
+
)
|
220
|
+
|
221
|
+
|
222
|
+
def _build_code_executor_skill(agent: LlmAgent) -> AgentSkill:
|
223
|
+
"""Build code executor skill for LLM agent."""
|
224
|
+
return AgentSkill(
|
225
|
+
id=f'{agent.name}-code-executor',
|
226
|
+
name='code-execution',
|
227
|
+
description='Can execute codes',
|
228
|
+
examples=None,
|
229
|
+
inputModes=None,
|
230
|
+
outputModes=None,
|
231
|
+
tags=['llm', 'code_execution'],
|
232
|
+
)
|
233
|
+
|
234
|
+
|
235
|
+
async def _build_non_llm_agent_skills(agent: BaseAgent) -> List[AgentSkill]:
|
236
|
+
"""Build skills for non-LLM agents."""
|
237
|
+
skills = []
|
238
|
+
|
239
|
+
# 1. Agent skill (main agent skill)
|
240
|
+
agent_description = _build_agent_description(agent)
|
241
|
+
agent_examples = await _extract_examples_from_agent(agent)
|
242
|
+
|
243
|
+
# Determine agent type and name
|
244
|
+
agent_type = _get_agent_type(agent)
|
245
|
+
agent_name = _get_agent_skill_name(agent)
|
246
|
+
|
247
|
+
skills.append(
|
248
|
+
AgentSkill(
|
249
|
+
id=agent.name,
|
250
|
+
name=agent_name,
|
251
|
+
description=agent_description,
|
252
|
+
examples=agent_examples,
|
253
|
+
inputModes=_get_input_modes(agent),
|
254
|
+
outputModes=_get_output_modes(agent),
|
255
|
+
tags=[agent_type],
|
256
|
+
)
|
257
|
+
)
|
258
|
+
|
259
|
+
# 2. Sub-agent orchestration skill (for agents with sub-agents)
|
260
|
+
if agent.sub_agents:
|
261
|
+
orchestration_skill = _build_orchestration_skill(agent, agent_type)
|
262
|
+
if orchestration_skill:
|
263
|
+
skills.append(orchestration_skill)
|
264
|
+
|
265
|
+
return skills
|
266
|
+
|
267
|
+
|
268
|
+
def _build_orchestration_skill(
|
269
|
+
agent: BaseAgent, agent_type: str
|
270
|
+
) -> Optional[AgentSkill]:
|
271
|
+
"""Build orchestration skill for agents with sub-agents."""
|
272
|
+
sub_agent_descriptions = []
|
273
|
+
for sub_agent in agent.sub_agents:
|
274
|
+
description = sub_agent.description or 'No description'
|
275
|
+
sub_agent_descriptions.append(f'{sub_agent.name}: {description}')
|
276
|
+
|
277
|
+
if not sub_agent_descriptions:
|
278
|
+
return None
|
279
|
+
|
280
|
+
return AgentSkill(
|
281
|
+
id=f'{agent.name}-sub-agents',
|
282
|
+
name='sub-agents',
|
283
|
+
description='Orchestrates: ' + '; '.join(sub_agent_descriptions),
|
284
|
+
examples=None,
|
285
|
+
inputModes=None,
|
286
|
+
outputModes=None,
|
287
|
+
tags=[agent_type, 'orchestration'],
|
288
|
+
)
|
289
|
+
|
290
|
+
|
291
|
+
def _get_agent_type(agent: BaseAgent) -> str:
|
292
|
+
"""Get the agent type for tagging."""
|
293
|
+
if isinstance(agent, LlmAgent):
|
294
|
+
return 'llm'
|
295
|
+
elif isinstance(agent, SequentialAgent):
|
296
|
+
return 'sequential_workflow'
|
297
|
+
elif isinstance(agent, ParallelAgent):
|
298
|
+
return 'parallel_workflow'
|
299
|
+
elif isinstance(agent, LoopAgent):
|
300
|
+
return 'loop_workflow'
|
301
|
+
else:
|
302
|
+
return 'custom_agent'
|
303
|
+
|
304
|
+
|
305
|
+
def _get_agent_skill_name(agent: BaseAgent) -> str:
|
306
|
+
"""Get the skill name based on agent type."""
|
307
|
+
if isinstance(agent, LlmAgent):
|
308
|
+
return 'model'
|
309
|
+
elif isinstance(agent, (SequentialAgent, ParallelAgent, LoopAgent)):
|
310
|
+
return 'workflow'
|
311
|
+
else:
|
312
|
+
return 'custom'
|
313
|
+
|
314
|
+
|
315
|
+
def _build_agent_description(agent: BaseAgent) -> str:
|
316
|
+
"""Build agent description from agent.description and workflow-specific descriptions."""
|
317
|
+
description_parts = []
|
318
|
+
|
319
|
+
# Add agent description
|
320
|
+
if agent.description:
|
321
|
+
description_parts.append(agent.description)
|
322
|
+
|
323
|
+
# Add workflow-specific descriptions for non-LLM agents
|
324
|
+
if not isinstance(agent, LlmAgent):
|
325
|
+
workflow_description = _get_workflow_description(agent)
|
326
|
+
if workflow_description:
|
327
|
+
description_parts.append(workflow_description)
|
328
|
+
|
329
|
+
return (
|
330
|
+
' '.join(description_parts)
|
331
|
+
if description_parts
|
332
|
+
else _get_default_description(agent)
|
333
|
+
)
|
334
|
+
|
335
|
+
|
336
|
+
def _build_llm_agent_description_with_instructions(agent: LlmAgent) -> str:
|
337
|
+
"""Build agent description including instructions for LlmAgents."""
|
338
|
+
description_parts = []
|
339
|
+
|
340
|
+
# Add agent description
|
341
|
+
if agent.description:
|
342
|
+
description_parts.append(agent.description)
|
343
|
+
|
344
|
+
# Add instruction (with pronoun replacement) - only for LlmAgent
|
345
|
+
if agent.instruction:
|
346
|
+
instruction = _replace_pronouns(agent.instruction)
|
347
|
+
description_parts.append(instruction)
|
348
|
+
|
349
|
+
# Add global instruction (with pronoun replacement) - only for LlmAgent
|
350
|
+
if agent.global_instruction:
|
351
|
+
global_instruction = _replace_pronouns(agent.global_instruction)
|
352
|
+
description_parts.append(global_instruction)
|
353
|
+
|
354
|
+
return (
|
355
|
+
' '.join(description_parts)
|
356
|
+
if description_parts
|
357
|
+
else _get_default_description(agent)
|
358
|
+
)
|
359
|
+
|
360
|
+
|
361
|
+
def _replace_pronouns(text: str) -> str:
|
362
|
+
"""Replace pronouns in text for agent description (you -> I, your -> my, etc.)."""
|
363
|
+
pronoun_map = {'you': 'I', 'your': 'my', 'yours': 'mine'}
|
364
|
+
|
365
|
+
return re.sub(
|
366
|
+
r'\b(you|your|yours)\b',
|
367
|
+
lambda match: pronoun_map[match.group(1).lower()],
|
368
|
+
text,
|
369
|
+
flags=re.IGNORECASE,
|
370
|
+
)
|
371
|
+
|
372
|
+
|
373
|
+
def _get_workflow_description(agent: BaseAgent) -> Optional[str]:
|
374
|
+
"""Get workflow-specific description for non-LLM agents."""
|
375
|
+
if not agent.sub_agents:
|
376
|
+
return None
|
377
|
+
|
378
|
+
if isinstance(agent, SequentialAgent):
|
379
|
+
return _build_sequential_description(agent)
|
380
|
+
elif isinstance(agent, ParallelAgent):
|
381
|
+
return _build_parallel_description(agent)
|
382
|
+
elif isinstance(agent, LoopAgent):
|
383
|
+
return _build_loop_description(agent)
|
384
|
+
|
385
|
+
return None
|
386
|
+
|
387
|
+
|
388
|
+
def _build_sequential_description(agent: SequentialAgent) -> str:
|
389
|
+
"""Build description for sequential workflow agent."""
|
390
|
+
descriptions = []
|
391
|
+
for i, sub_agent in enumerate(agent.sub_agents, 1):
|
392
|
+
sub_description = (
|
393
|
+
sub_agent.description or f'execute the {sub_agent.name} agent'
|
394
|
+
)
|
395
|
+
if i == 1:
|
396
|
+
descriptions.append(f'First, this agent will {sub_description}')
|
397
|
+
elif i == len(agent.sub_agents):
|
398
|
+
descriptions.append(f'Finally, this agent will {sub_description}')
|
399
|
+
else:
|
400
|
+
descriptions.append(f'Then, this agent will {sub_description}')
|
401
|
+
return ' '.join(descriptions) + '.'
|
402
|
+
|
403
|
+
|
404
|
+
def _build_parallel_description(agent: ParallelAgent) -> str:
|
405
|
+
"""Build description for parallel workflow agent."""
|
406
|
+
descriptions = []
|
407
|
+
for i, sub_agent in enumerate(agent.sub_agents):
|
408
|
+
sub_description = (
|
409
|
+
sub_agent.description or f'execute the {sub_agent.name} agent'
|
410
|
+
)
|
411
|
+
if i == 0:
|
412
|
+
descriptions.append(f'This agent will {sub_description}')
|
413
|
+
elif i == len(agent.sub_agents) - 1:
|
414
|
+
descriptions.append(f'and {sub_description}')
|
415
|
+
else:
|
416
|
+
descriptions.append(f', {sub_description}')
|
417
|
+
return ' '.join(descriptions) + ' simultaneously.'
|
418
|
+
|
419
|
+
|
420
|
+
def _build_loop_description(agent: LoopAgent) -> str:
|
421
|
+
"""Build description for loop workflow agent."""
|
422
|
+
max_iterations = agent.max_iterations or 'unlimited'
|
423
|
+
descriptions = []
|
424
|
+
for i, sub_agent in enumerate(agent.sub_agents):
|
425
|
+
sub_description = (
|
426
|
+
sub_agent.description or f'execute the {sub_agent.name} agent'
|
427
|
+
)
|
428
|
+
if i == 0:
|
429
|
+
descriptions.append(f'This agent will {sub_description}')
|
430
|
+
elif i == len(agent.sub_agents) - 1:
|
431
|
+
descriptions.append(f'and {sub_description}')
|
432
|
+
else:
|
433
|
+
descriptions.append(f', {sub_description}')
|
434
|
+
return (
|
435
|
+
f"{' '.join(descriptions)} in a loop (max {max_iterations} iterations)."
|
436
|
+
)
|
437
|
+
|
438
|
+
|
439
|
+
def _get_default_description(agent: BaseAgent) -> str:
|
440
|
+
"""Get default description based on agent type."""
|
441
|
+
agent_type_descriptions = {
|
442
|
+
LlmAgent: 'An LLM-based agent',
|
443
|
+
SequentialAgent: 'A sequential workflow agent',
|
444
|
+
ParallelAgent: 'A parallel workflow agent',
|
445
|
+
LoopAgent: 'A loop workflow agent',
|
446
|
+
}
|
447
|
+
|
448
|
+
for agent_type, description in agent_type_descriptions.items():
|
449
|
+
if isinstance(agent, agent_type):
|
450
|
+
return description
|
451
|
+
|
452
|
+
return 'A custom agent'
|
453
|
+
|
454
|
+
|
455
|
+
async def _extract_examples_from_agent(
|
456
|
+
agent: BaseAgent,
|
457
|
+
) -> Optional[List[Dict]]:
|
458
|
+
"""Extract examples from example_tool if configured, otherwise from agent instruction."""
|
459
|
+
if not isinstance(agent, LlmAgent):
|
460
|
+
return None
|
461
|
+
|
462
|
+
# First, try to find example_tool in tools
|
463
|
+
try:
|
464
|
+
canonical_tools = await agent.canonical_tools()
|
465
|
+
for tool in canonical_tools:
|
466
|
+
if isinstance(tool, ExampleTool):
|
467
|
+
return _convert_example_tool_examples(tool)
|
468
|
+
except Exception as e:
|
469
|
+
print(f'Warning: Failed to extract examples from tools: {e}')
|
470
|
+
|
471
|
+
# If no example_tool found, try to extract examples from instruction
|
472
|
+
if agent.instruction:
|
473
|
+
return _extract_examples_from_instruction(agent.instruction)
|
474
|
+
|
475
|
+
return None
|
476
|
+
|
477
|
+
|
478
|
+
def _convert_example_tool_examples(tool: ExampleTool) -> List[Dict]:
|
479
|
+
"""Convert ExampleTool examples to the expected format."""
|
480
|
+
examples = []
|
481
|
+
for example in tool.examples:
|
482
|
+
examples.append({
|
483
|
+
'input': (
|
484
|
+
example.input.model_dump()
|
485
|
+
if hasattr(example.input, 'model_dump')
|
486
|
+
else example.input
|
487
|
+
),
|
488
|
+
'output': [
|
489
|
+
output.model_dump() if hasattr(output, 'model_dump') else output
|
490
|
+
for output in example.output
|
491
|
+
],
|
492
|
+
})
|
493
|
+
return examples
|
494
|
+
|
495
|
+
|
496
|
+
def _extract_examples_from_instruction(
|
497
|
+
instruction: str,
|
498
|
+
) -> Optional[List[Dict]]:
|
499
|
+
"""Extract examples from agent instruction text using regex patterns."""
|
500
|
+
examples = []
|
501
|
+
|
502
|
+
# Look for common example patterns in instructions
|
503
|
+
example_patterns = [
|
504
|
+
r'Example Query:\s*["\']([^"\']+)["\']',
|
505
|
+
r'Example Response:\s*["\']([^"\']+)["\']',
|
506
|
+
r'Example:\s*["\']([^"\']+)["\']',
|
507
|
+
]
|
508
|
+
|
509
|
+
for pattern in example_patterns:
|
510
|
+
matches = re.findall(pattern, instruction, re.IGNORECASE)
|
511
|
+
if matches:
|
512
|
+
for i in range(0, len(matches), 2):
|
513
|
+
if i + 1 < len(matches):
|
514
|
+
examples.append({
|
515
|
+
'input': {'text': matches[i]},
|
516
|
+
'output': [{'text': matches[i + 1]}],
|
517
|
+
})
|
518
|
+
|
519
|
+
return examples if examples else None
|
520
|
+
|
521
|
+
|
522
|
+
def _get_input_modes(agent: BaseAgent) -> Optional[List[str]]:
|
523
|
+
"""Get input modes based on agent model."""
|
524
|
+
if not isinstance(agent, LlmAgent):
|
525
|
+
return None
|
526
|
+
|
527
|
+
# This could be enhanced to check model capabilities
|
528
|
+
# For now, return None to use defaultInputModes
|
529
|
+
return None
|
530
|
+
|
531
|
+
|
532
|
+
def _get_output_modes(agent: BaseAgent) -> Optional[List[str]]:
|
533
|
+
"""Get output modes from Agent.generate_content_config.response_modalities."""
|
534
|
+
if not isinstance(agent, LlmAgent):
|
535
|
+
return None
|
536
|
+
|
537
|
+
if (
|
538
|
+
hasattr(agent, 'generate_content_config')
|
539
|
+
and agent.generate_content_config
|
540
|
+
and hasattr(agent.generate_content_config, 'response_modalities')
|
541
|
+
):
|
542
|
+
return agent.generate_content_config.response_modalities
|
543
|
+
|
544
|
+
return None
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# Copyright 2025 Google LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
|
17
|
+
import logging
|
18
|
+
import sys
|
19
|
+
|
20
|
+
try:
|
21
|
+
from a2a.server.apps import A2AStarletteApplication
|
22
|
+
from a2a.server.request_handlers import DefaultRequestHandler
|
23
|
+
from a2a.server.tasks import InMemoryTaskStore
|
24
|
+
except ImportError as e:
|
25
|
+
if sys.version_info < (3, 10):
|
26
|
+
raise ImportError(
|
27
|
+
"A2A requires Python 3.10 or above. Please upgrade your Python version."
|
28
|
+
) from e
|
29
|
+
else:
|
30
|
+
raise e
|
31
|
+
|
32
|
+
from starlette.applications import Starlette
|
33
|
+
|
34
|
+
from ...agents.base_agent import BaseAgent
|
35
|
+
from ...artifacts.in_memory_artifact_service import InMemoryArtifactService
|
36
|
+
from ...auth.credential_service.in_memory_credential_service import InMemoryCredentialService
|
37
|
+
from ...cli.utils.logs import setup_adk_logger
|
38
|
+
from ...memory.in_memory_memory_service import InMemoryMemoryService
|
39
|
+
from ...runners import Runner
|
40
|
+
from ...sessions.in_memory_session_service import InMemorySessionService
|
41
|
+
from ..executor.a2a_agent_executor import A2aAgentExecutor
|
42
|
+
from .agent_card_builder import AgentCardBuilder
|
43
|
+
|
44
|
+
|
45
|
+
def to_a2a(
|
46
|
+
agent: BaseAgent, *, host: str = "localhost", port: int = 8000
|
47
|
+
) -> Starlette:
|
48
|
+
"""Convert an ADK agent to a A2A Starlette application.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
agent: The ADK agent to convert
|
52
|
+
host: The host for the A2A RPC URL (default: "localhost")
|
53
|
+
port: The port for the A2A RPC URL (default: 8000)
|
54
|
+
|
55
|
+
Returns:
|
56
|
+
A Starlette application that can be run with uvicorn
|
57
|
+
|
58
|
+
Example:
|
59
|
+
agent = MyAgent()
|
60
|
+
app = to_a2a(agent, host="localhost", port=8000)
|
61
|
+
# Then run with: uvicorn module:app --host localhost --port 8000
|
62
|
+
"""
|
63
|
+
# Set up ADK logging to ensure logs are visible when using uvicorn directly
|
64
|
+
setup_adk_logger(logging.INFO)
|
65
|
+
|
66
|
+
async def create_runner() -> Runner:
|
67
|
+
"""Create a runner for the agent."""
|
68
|
+
return Runner(
|
69
|
+
app_name=agent.name or "adk_agent",
|
70
|
+
agent=agent,
|
71
|
+
# Use minimal services - in a real implementation these could be configured
|
72
|
+
artifact_service=InMemoryArtifactService(),
|
73
|
+
session_service=InMemorySessionService(),
|
74
|
+
memory_service=InMemoryMemoryService(),
|
75
|
+
credential_service=InMemoryCredentialService(),
|
76
|
+
)
|
77
|
+
|
78
|
+
# Create A2A components
|
79
|
+
task_store = InMemoryTaskStore()
|
80
|
+
|
81
|
+
agent_executor = A2aAgentExecutor(
|
82
|
+
runner=create_runner,
|
83
|
+
)
|
84
|
+
|
85
|
+
request_handler = DefaultRequestHandler(
|
86
|
+
agent_executor=agent_executor, task_store=task_store
|
87
|
+
)
|
88
|
+
|
89
|
+
# Build agent card
|
90
|
+
rpc_url = f"http://{host}:{port}/"
|
91
|
+
card_builder = AgentCardBuilder(
|
92
|
+
agent=agent,
|
93
|
+
rpc_url=rpc_url,
|
94
|
+
)
|
95
|
+
|
96
|
+
# Create a Starlette app that will be configured during startup
|
97
|
+
app = Starlette()
|
98
|
+
|
99
|
+
# Add startup handler to build the agent card and configure A2A routes
|
100
|
+
async def setup_a2a():
|
101
|
+
# Build the agent card asynchronously
|
102
|
+
agent_card = await card_builder.build()
|
103
|
+
|
104
|
+
# Create the A2A Starlette application
|
105
|
+
a2a_app = A2AStarletteApplication(
|
106
|
+
agent_card=agent_card,
|
107
|
+
http_handler=request_handler,
|
108
|
+
)
|
109
|
+
|
110
|
+
# Add A2A routes to the main app
|
111
|
+
a2a_app.add_routes_to_app(
|
112
|
+
app,
|
113
|
+
)
|
114
|
+
|
115
|
+
# Store the setup function to be called during startup
|
116
|
+
app.add_event_handler("startup", setup_a2a)
|
117
|
+
|
118
|
+
return app
|