> ## 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.

# BeeAI Framework

> Build agents in BeeAI Framework that communicate with StackOne's A2A agents using A2AAgent.

## Overview

The [BeeAI Framework](https://framework.beeai.dev/) is an open-source framework for building AI agents, developed under the Linux Foundation. BeeAI has built-in support for the A2A protocol through `A2AAgent`, allowing your agents to communicate with remote A2A agents like StackOne's.

Use BeeAI Framework to build agents that:

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

<Note>
  **Python only**: BeeAI Framework's `A2AAgent` supports custom authentication headers required for StackOne in Python. For TypeScript, use the [A2A JavaScript SDK](/a2a/sdk-guides/javascript) directly.
</Note>

## Installation

Install BeeAI Framework with A2A support:

```bash theme={null}
pip install beeai-framework[a2a]
```

## Quick Start

This example creates an `A2AAgent` that connects to a StackOne A2A agent.

```python theme={null}
import asyncio
import base64
from beeai_framework.adapters.a2a.agents import A2AAgent, A2AAgentParameters, HttpxAsyncClientParameters
from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory

# 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()

async def main():
    # Create A2A agent with StackOne authentication
    agent = A2AAgent(
        url="https://a2a.stackone.com",
        memory=UnconstrainedMemory(),
        parameters=A2AAgentParameters(
            httpx_async_client=HttpxAsyncClientParameters(
                headers={
                    "Authorization": f"Basic {BASE64_API_KEY}",
                    "x-account-id": STACKONE_ACCOUNT_ID
                }
            )
        )
    )

    # Send a message and get the response
    response = await agent.run("List the first 5 employees")
    print(f"Agent response: {response.last_message.text}")

asyncio.run(main())
```

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

## Architecture

BeeAI's `A2AAgent` allows your application to communicate with remote A2A agents:

```mermaid theme={null}
flowchart LR
    App[Your Application] --> A2AAgent[A2AAgent<br/>BeeAI Framework]
    A2AAgent -->|A2A Protocol| StackOneA2A[StackOne A2A Agent]
    StackOneA2A --> Providers[(Connected SaaS<br/>HiBob, Workday, etc.)]

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

## Complete Example with Event Handling

Here's a complete example that handles events and debug information:

```python theme={null}
import asyncio
import base64
from beeai_framework.adapters.a2a.agents import A2AAgent, A2AAgentUpdateEvent, A2AAgentParameters, HttpxAsyncClientParameters
from beeai_framework.emitter import EventMeta
from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory
from beeai_framework.errors import FrameworkError

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

async def main():
    # Create A2A agent with StackOne authentication
    agent = A2AAgent(
        url="https://a2a.stackone.com",
        memory=UnconstrainedMemory(),
        parameters=A2AAgentParameters(
            httpx_async_client=HttpxAsyncClientParameters(
                headers={
                    "Authorization": f"Basic {BASE64_API_KEY}",
                    "x-account-id": STACKONE_ACCOUNT_ID
                }
            )
        )
    )

    # Define event handler for progress updates
    def handle_update(data: A2AAgentUpdateEvent, event: EventMeta) -> None:
        value = data.value
        debug_info = value[1] if isinstance(value, tuple) else value
        print(f"Agent progress: {debug_info}")

    # Run the agent with event handling
    try:
        response = await agent.run("List the first 5 employees").on("update", handle_update)
        print(f"\nAgent response: {response.last_message.text}")
    except FrameworkError as e:
        print(f"Error: {e.explain()}")

asyncio.run(main())
```

## Interactive Chat Loop

Create an interactive chat session with the StackOne agent:

```python theme={null}
import asyncio
import base64
from beeai_framework.adapters.a2a.agents import A2AAgent, A2AAgentParameters, HttpxAsyncClientParameters
from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory

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

async def main():
    agent = A2AAgent(
        url="https://a2a.stackone.com",
        memory=UnconstrainedMemory(),
        parameters=A2AAgentParameters(
            httpx_async_client=HttpxAsyncClientParameters(
                headers={
                    "Authorization": f"Basic {BASE64_API_KEY}",
                    "x-account-id": STACKONE_ACCOUNT_ID
                }
            )
        )
    )

    print("Connected to StackOne A2A Agent. Type 'quit' to exit.\n")

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() == "quit":
            break

        response = await agent.run(user_input)
        print(f"Agent: {response.last_message.text}\n")

asyncio.run(main())
```

## Multiple StackOne Accounts

Connect to multiple StackOne accounts by creating separate `A2AAgent` instances:

```python theme={null}
import base64
from beeai_framework.adapters.a2a.agents import A2AAgent, A2AAgentParameters, HttpxAsyncClientParameters
from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory

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

# Agent for HiBob integration
hibob_agent = A2AAgent(
    url="https://a2a.stackone.com",
    memory=UnconstrainedMemory(),
    parameters=A2AAgentParameters(
        httpx_async_client=HttpxAsyncClientParameters(
            headers={
                "Authorization": f"Basic {BASE64_API_KEY}",
                "x-account-id": "<hibob_account_id>"
            }
        )
    )
)

# Agent for BambooHR integration
bamboo_agent = A2AAgent(
    url="https://a2a.stackone.com",
    memory=UnconstrainedMemory(),
    parameters=A2AAgentParameters(
        httpx_async_client=HttpxAsyncClientParameters(
            headers={
                "Authorization": f"Basic {BASE64_API_KEY}",
                "x-account-id": "<bamboohr_account_id>"
            }
        )
    )
)

async def query_multiple_systems():
    # Query HiBob
    hibob_response = await hibob_agent.run("List all employees")
    print(f"HiBob: {hibob_response.last_message.text}")

    # Query BambooHR
    bamboo_response = await bamboo_agent.run("List all employees")
    print(f"BambooHR: {bamboo_response.last_message.text}")
```

## Memory Management

BeeAI Framework provides memory implementations for conversation history:

```python theme={null}
from beeai_framework.adapters.a2a.agents import A2AAgent, A2AAgentParameters, HttpxAsyncClientParameters
from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory

# UnconstrainedMemory: Keeps all messages (default choice)
agent = A2AAgent(
    url="https://a2a.stackone.com",
    memory=UnconstrainedMemory(),
    parameters=A2AAgentParameters(
        httpx_async_client=HttpxAsyncClientParameters(
            headers={
                "Authorization": f"Basic {BASE64_API_KEY}",
                "x-account-id": STACKONE_ACCOUNT_ID
            }
        )
    )
)

# Clear memory to start a new conversation
async def start_new_conversation():
    agent.memory = UnconstrainedMemory()  # Memory must be empty before setting
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use Appropriate Memory" icon="brain">
    Choose the right memory implementation for your use case:

    ```python theme={null}
    from beeai_framework.memory.unconstrained_memory import UnconstrainedMemory

    agent = A2AAgent(
        url="https://a2a.stackone.com",
        memory=UnconstrainedMemory(),
        # ...
    )
    ```

    Use `UnconstrainedMemory` for typical interactions. Memory must be empty when assigned to an agent.
  </Accordion>

  <Accordion title="Handle Events for Debugging" icon="bug">
    Subscribe to update events for debugging and progress tracking:

    ```python theme={null}
    def handle_update(data: A2AAgentUpdateEvent, event: EventMeta) -> None:
        print(f"Debug: {data.value}")

    response = await agent.run("Query").on("update", handle_update)
    ```

    This is especially useful for understanding agent behavior during development.
  </Accordion>

  <Accordion title="Error Handling" icon="triangle-exclamation">
    Wrap agent calls in try-except blocks to handle errors gracefully:

    ```python theme={null}
    from beeai_framework.errors import FrameworkError
    from beeai_framework.agents import AgentError

    try:
        response = await agent.run("List employees")
    except AgentError as e:
        print(f"Agent error: {e}")
        # Handle agent-specific errors
    except FrameworkError as e:
        print(f"Framework error: {e.explain()}")
        # Handle framework errors
    ```
  </Accordion>

  <Accordion title="Context Management" icon="arrows-rotate">
    Use context IDs and task IDs to manage multi-turn conversations:

    ```python theme={null}
    # Start a new conversation
    response = await agent.run(
        "List employees",
        clear_context=True  # Clears previous context
    )

    # Continue an existing conversation (uses stored context)
    follow_up = await agent.run("Tell me more about the first employee")
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

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

  <Card title="JavaScript SDK" icon="js" href="/a2a/sdk-guides/javascript">
    Use the A2A 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>
</CardGroup>
