Skip to content
Open
61 changes: 61 additions & 0 deletions sample_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from google.adk.agents.llm_agent import LlmAgent
from google.adk.agents.sequential_agent import SequentialAgent


def search_web(query: str) -> str:
"""Searches the web for given query."""
return f"Search results for: {query}"


def calculate(expression: str) -> str:
"""Calculates math expression."""
return f"Calculated: {expression}"


# 1. Researcher Agent with web search tool
researcher = LlmAgent(
name="ResearcherAgent",
instruction="Search the web and gather background information.",
tools=[search_web],
)

# 2. Analyst Agent with calculator tool
analyst = LlmAgent(
name="AnalystAgent",
instruction="Analyze research data and calculate statistics.",
tools=[calculate],
)

# 3. Writer Agent
writer = LlmAgent(
name="WriterAgent",
instruction="Synthesize findings and draft final executive report.",
)

# Root Sequential Pipeline
root_agent = SequentialAgent(
name="ResearchAndReportingPipeline",
description="Multi-agent workflow that researches, analyzes, and drafts reports.",
sub_agents=[researcher, analyst, writer],
)

# New Sequential Pipeline
ResearchAndReportingPipeline = SequentialAgent(
name="ResearchAndReportingPipeline",
description="Multi-agent workflow that researches, analyzes, and drafts reports.",
sub_agents=[],
)
53 changes: 53 additions & 0 deletions src/google/adk/cli/cli_graph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import logging
from pathlib import Path
from typing import Optional

import click

from .utils.agent_loader import AgentLoader
from .graph.inspector import AgentInspector
from .graph.graph_server import GraphServer

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


@click.command("graph")
@click.argument("agent_file", type=click.Path(exists=True), required=False)
@click.option("--host", default="0.0.0.0", help="Host address to bind the web server.")
@click.option("--port", default=8000, type=int, help="Port to serve the visual graph UI.")
def graph_cmd(agent_file: Optional[str], host: str, port: int) -> None:
"""Inspect and visualize agent topology interactively."""
if not agent_file:
click.echo("Starting ADK Graph Server in standalone builder mode...")
server = GraphServer(topology=None, host=host, port=port)
server.run()
return

click.echo(f"Inspecting agent at: {agent_file}")
path = Path(agent_file)
agent_or_app = AgentLoader.load_agent_or_app(path)

inspector = AgentInspector(agent_or_app)
topology = inspector.inspect()

click.echo(f"Successfully parsed agent graph! Total nodes: {len(topology.nodes)}, edges: {len(topology.edges)}")
click.echo(f"Serving Visual Agent Graph on http://{host}:{port}")

server = GraphServer(topology=topology, agent_file_path=path, host=host, port=port)
server.run()
40 changes: 40 additions & 0 deletions src/google/adk/cli/cli_tools_click.py
Original file line number Diff line number Diff line change
Expand Up @@ -1969,6 +1969,46 @@ def _check_windows_reload(reload: bool) -> bool:
return reload


@main.command("graph")
@click.argument("agent_file", type=click.Path(exists=True), required=False)
@click.option("--host", default="127.0.0.1", help="Host address to bind the web server.")
@click.option("--port", default=8000, type=int, help="Port to serve the visual graph UI.")
def cli_graph(agent_file: Optional[str], host: str, port: int) -> None:
"""Inspect and visualize agent topology interactively."""
from .graph.graph_server import GraphServer
from .graph.inspector import AgentInspector
from .utils.agent_loader import AgentLoader

if not agent_file:
click.echo("Starting ADK Graph Server in standalone builder mode...")
server = GraphServer(topology=None, host=host, port=port)
server.run()
return

click.echo(f"Inspecting agent at: {agent_file}")
path = Path(agent_file).resolve()
if path.is_file():
agents_dir = str(path.parent)
agent_name = path.stem
else:
agents_dir = str(path)
agent_name = path.name

loader = AgentLoader(agents_dir=agents_dir)
agent_or_app = loader.load_agent(agent_name)

inspector = AgentInspector(agent_or_app)
topology = inspector.inspect()

click.echo(f"Successfully parsed agent graph! Total nodes: {len(topology.nodes)}, edges: {len(topology.edges)}")
click.echo(f"Serving Visual Agent Graph on http://{host}:{port}")

server = GraphServer(
topology=topology, agent_file_path=path, host=host, port=port
)
server.run()


@main.command("web")
@feature_options()
@fast_api_common_options()
Expand Down
22 changes: 22 additions & 0 deletions src/google/adk/cli/graph/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2026 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Graph visualization and inspection package for ADK agents."""

from __future__ import annotations

from .inspector import AgentInspector, GraphTopology, GraphNode, GraphEdge
from .graph_server import GraphServer

__all__ = ["AgentInspector", "GraphTopology", "GraphNode", "GraphEdge", "GraphServer"]
Loading