diff --git a/src/google/adk/cli/api_server.py b/src/google/adk/cli/api_server.py index 6ad354a344..4b41b4bfeb 100644 --- a/src/google/adk/cli/api_server.py +++ b/src/google/adk/cli/api_server.py @@ -680,6 +680,24 @@ def _maybe_add_bq_plugin(plugins: list[BasePlugin]) -> list[BasePlugin]: ) return plugins + def _wrap_loaded_agent( + app_name: str, + agent_or_app: Any, + plugins: list[BasePlugin], + ) -> App: + if app_name.startswith("__"): + # AgentLoader validates special agents before they reach this point. + return App.model_construct( + name=app_name, + root_agent=agent_or_app, + plugins=plugins, + ) + return App( + name=app_name, + root_agent=agent_or_app, + plugins=plugins, + ) + if isinstance(agent_or_app, App): # Combine existing plugins with extra plugins plugins = _maybe_add_bq_plugin( @@ -689,17 +707,11 @@ def _maybe_add_bq_plugin(plugins: list[BasePlugin]) -> list[BasePlugin]: agentic_app = agent_or_app elif isinstance(agent_or_app, BaseAgent): plugins = _maybe_add_bq_plugin(extra_plugins_instances) - agentic_app = App( - name=app_name, - root_agent=agent_or_app, - plugins=plugins, - ) + agentic_app = _wrap_loaded_agent(app_name, agent_or_app, plugins) else: # BaseNode (non-agent) - agentic_app = App( - name=app_name, - root_agent=agent_or_app, - plugins=extra_plugins_instances, + agentic_app = _wrap_loaded_agent( + app_name, agent_or_app, extra_plugins_instances ) # If the root agent was loaded from YAML, we treat it as being from Visual Builder diff --git a/tests/unittests/cli/test_fast_api.py b/tests/unittests/cli/test_fast_api.py index b00dd118d2..66bf2af5fa 100755 --- a/tests/unittests/cli/test_fast_api.py +++ b/tests/unittests/cli/test_fast_api.py @@ -644,6 +644,39 @@ def test_agent_with_bigquery_analytics_plugin( assert getattr(runner.app, "_is_visual_builder_app", False) is True +def test_get_runner_async_accepts_internal_special_agent_name( + tmp_path, + mock_session_service, + mock_artifact_service, + mock_memory_service, + mock_agent_loader, + mock_eval_sets_manager, + mock_eval_set_results_manager, +): + from google.adk.cli.adk_web_server import AdkWebServer + + special_app_name = "__adk_agent_builder_assistant" + special_agent = DummyAgent(name="agent_builder_assistant") + mock_agent_loader.load_agent = MagicMock(return_value=special_agent) + + adk_web_server = AdkWebServer( + agent_loader=mock_agent_loader, + session_service=mock_session_service, + memory_service=mock_memory_service, + artifact_service=mock_artifact_service, + credential_service=MagicMock(), + eval_sets_manager=mock_eval_sets_manager, + eval_set_results_manager=mock_eval_set_results_manager, + agents_dir=str(tmp_path), + ) + + runner = asyncio.run(adk_web_server.get_runner_async(special_app_name)) + + assert runner.app.name == special_app_name + assert runner.app.root_agent is special_agent + mock_agent_loader.load_agent.assert_called_once_with(special_app_name) + + @pytest.fixture def test_app( mock_session_service,