> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Development Kit (ADK)

> Build agents in Google's ADK that communicate with StackOne's A2A agents using RemoteA2aAgent.

## Overview

The [Agent Development Kit (ADK)](https://google.github.io/adk-docs/) is Google's open-source framework for building AI agents. ADK has built-in support for the A2A protocol, allowing your agents to communicate with remote A2A agents like StackOne's.

<Note>
  This guide covers using ADK to **call** StackOne's A2A agent. The StackOne A2A agent is itself **built on** ADK and the StackOne ADK plugin, see [How StackOne A2A works](/a2a/introduction#how-stackone-a2a-works) for how it works under the hood.
</Note>

Use ADK to build agents that:

* Consume StackOne's A2A agents as remote sub-agents
* Orchestrate multi-agent systems with local and remote agents
* Access StackOne platform actions without managing tool definitions

## Installation

Install ADK with A2A support using `uv`:

```bash theme={null}
uv add "google-adk[a2a]"
```

## Quick Start

This example creates an orchestrator agent that delegates HR tasks to a StackOne A2A agent.

```python theme={null}
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

# StackOne A2A configuration
STACKONE_API_KEY = "<stackone_api_key>"
STACKONE_ACCOUNT_ID = "<account_id>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# Create an HTTP client with StackOne authentication headers
http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": STACKONE_ACCOUNT_ID
    },
    timeout=httpx.Timeout(120.0),  # StackOne agents run an LLM per call; the 5s default is too short
)

# Create a remote A2A agent pointing to StackOne
stackone_agent = RemoteA2aAgent(
    name="stackone_hr_agent",
    description="Agent that handles HR operations via StackOne integrations.",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=http_client
)

# Create the orchestrator agent with StackOne as a sub-agent
root_agent = Agent(
    model="gemini-flash-latest",
    name="hr_assistant",
    instruction="""
        You are an HR assistant that helps with employee management tasks.
        Delegate HR operations to the stackone_hr_agent.

        When the user asks about employees, time off, or other HR data,
        use the stackone_hr_agent to fetch or update the information.
    """,
    sub_agents=[stackone_agent],
)
```

See [Authentication Guide](/a2a/auth-security) for details on obtaining your API key and account ID.

## Architecture

ADK's `RemoteA2aAgent` allows your local agent to delegate tasks to remote A2A agents:

```mermaid theme={null}
flowchart LR
    User[User] --> RootAgent[Root Agent<br/>Local ADK]
    RootAgent -->|A2A Protocol| StackOneA2A[StackOne A2A Agent]
    StackOneA2A --> Providers[(Connected SaaS<br/>HiBob, Workday, etc.)]
    RootAgent --> LocalTools[Local Tools<br/>Optional]

    style StackOneA2A fill:#10b981,stroke:#059669,color:#fff
```

## Complete Example

Here's a complete example with a local tool and a remote StackOne agent:

```python theme={null}
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
from google.genai import types

# Configuration
STACKONE_API_KEY = "<stackone_api_key>"
STACKONE_ACCOUNT_ID = "<account_id>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# Local tool example
def get_current_date() -> str:
    """Get the current date."""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d")

# Create an HTTP client with StackOne authentication headers
http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": STACKONE_ACCOUNT_ID
    },
    timeout=httpx.Timeout(120.0),  # StackOne agents run an LLM per call; the 5s default is too short
)

# Remote StackOne A2A agent
stackone_agent = RemoteA2aAgent(
    name="stackone_hr_agent",
    description="""
        Agent that handles HR operations via StackOne integrations.
        Can list employees, get employee details, manage time off requests,
        and perform other HR operations depending on the connected integration.
    """,
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=http_client
)

# Root orchestrator agent
root_agent = Agent(
    model="gemini-flash-latest",
    name="hr_assistant",
    instruction="""
        You are an HR assistant that helps with employee management tasks.

        You have access to:
        1. get_current_date - Get today's date
        2. stackone_hr_agent - Delegate HR operations (employees, time off, etc.)

        When users ask about HR data, delegate to stackone_hr_agent.
        Always confirm actions before making changes.
    """,
    global_instruction="You are HRBot, ready to help with HR tasks.",
    sub_agents=[stackone_agent],
    tools=[get_current_date],
    generate_content_config=types.GenerateContentConfig(
        temperature=0.7,
    ),
)
```

## Running the Agent

Use ADK's built-in web server to interact with your agent:

```bash theme={null}
adk web path/to/your/agent/folder
```

Then open `http://localhost:8000` in your browser to chat with your agent.

### Example Interactions

**Listing Employees:**

```text theme={null}
User: List all employees
Bot: I'll get that information for you from the HR system.
     [Delegates to stackone_hr_agent]
     Here are the employees:
     1. John Doe - Software Engineer
     2. Jane Smith - Product Manager
     ...
```

**Getting Employee Details:**

```text theme={null}
User: Get details for employee ID emp_123
Bot: [Delegates to stackone_hr_agent]
     Here are the details for emp_123:
     - Name: John Doe
     - Department: Engineering
     - Start Date: 2023-01-15
     ...
```

## Multiple StackOne Accounts

Connect to multiple StackOne accounts by creating separate HTTP clients and `RemoteA2aAgent` instances for each:

```python theme={null}
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

STACKONE_API_KEY = "<stackone_api_key>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# HTTP client for HiBob account
hibob_http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": "<hibob_account_id>"
    },
    timeout=httpx.Timeout(120.0),
)

# HTTP client for BambooHR account
bamboo_http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": "<bamboohr_account_id>"
    },
    timeout=httpx.Timeout(120.0),
)

# Agent for HiBob integration
hibob_agent = RemoteA2aAgent(
    name="hibob_agent",
    description="Agent for HiBob HR operations",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=hibob_http_client
)

# Agent for BambooHR integration
bamboo_agent = RemoteA2aAgent(
    name="bamboo_agent",
    description="Agent for BambooHR operations",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=bamboo_http_client
)

# Orchestrator with both agents
root_agent = Agent(
    model="gemini-flash-latest",
    name="multi_hr_assistant",
    instruction="""
        You have access to multiple HR systems:
        - hibob_agent: For HiBob HR operations
        - bamboo_agent: For BambooHR operations

        Route requests to the appropriate system based on user context.
    """,
    sub_agents=[hibob_agent, bamboo_agent],
)
```

## Best Practices

<AccordionGroup>
  <Accordion title="Clear Agent Descriptions" icon="file-lines">
    Provide detailed descriptions for your `RemoteA2aAgent` instances. The orchestrator uses these descriptions to decide when to delegate tasks.

    ```python theme={null}
    # Good: Specific description
    stackone_agent = RemoteA2aAgent(
        name="stackone_hr_agent",
        description="Handles employee management: listing employees, getting employee details, updating employee information, and managing time off requests.",
        ...
    )

    # Bad: Vague description
    stackone_agent = RemoteA2aAgent(
        name="stackone_agent",
        description="HR agent",
        ...
    )
    ```
  </Accordion>

  <Accordion title="Explicit Delegation Instructions" icon="diagram-project">
    Include clear delegation instructions in your orchestrator's system prompt:

    ```python theme={null}
    root_agent = Agent(
        instruction="""
            When the user asks about:
            - Employee data -> delegate to stackone_hr_agent
            - Time off requests -> delegate to stackone_hr_agent
            - Local operations -> use local tools

            Always confirm before making changes to HR systems.
        """,
        ...
    )
    ```
  </Accordion>

  <Accordion title="Error Handling" icon="triangle-exclamation">
    ADK handles A2A communication errors, but you should instruct your agent on how to respond:

    ```python theme={null}
    root_agent = Agent(
        instruction="""
            If the HR agent returns an error or is unavailable:
            1. Apologize to the user
            2. Explain the issue briefly
            3. Suggest trying again later or contacting support
        """,
        ...
    )
    ```
  </Accordion>

  <Accordion title="Resource Cleanup" icon="broom">
    When your application shuts down, clean up the HTTP client and agent resources:

    ```python theme={null}
    # Clean up when done
    await stackone_agent.cleanup()
    await http_client.aclose()
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="A2A SDK" icon="code" href="/a2a/a2a-sdk">
    Build custom A2A tools with the Python or JavaScript SDK
  </Card>

  <Card title="Authentication" icon="shield" href="/a2a/auth-security">
    Learn about authentication and security
  </Card>

  <Card title="Quickstart" icon="rocket" href="/a2a/quickstart">
    Learn A2A basics with cURL
  </Card>

  <Card title="Gemini Enterprise & Google Agent Platform" icon="google" href="/a2a/platform-guides/gemini-enterprise">
    Use StackOne agents from Google's platforms
  </Card>
</CardGroup>
