Metadata-Version: 2.4
Name: bridge-adk
Version: 0.1.0
Summary: Wrap an existing Google ADK / OpenAI Agents SDK / Claude Agent SDK agent and make it talk A2A in one or two lines of code.
Author: Bridge ADK contributors
License: MIT
Project-URL: Homepage, https://github.com/bridge-adk/bridge-adk
Keywords: a2a,agent2agent,agents,adk,openai-agents,claude-agent-sdk,interoperability
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: a2a-sdk[http-server]>=1.1.0
Requires-Dist: uvicorn>=0.30
Requires-Dist: httpx>=0.27
Requires-Dist: starlette>=0.37
Provides-Extra: openai
Requires-Dist: openai-agents>=0.1; extra == "openai"
Provides-Extra: adk
Requires-Dist: google-adk>=1.0; extra == "adk"
Provides-Extra: claude
Requires-Dist: claude-agent-sdk>=0.1; extra == "claude"
Provides-Extra: all
Requires-Dist: openai-agents>=0.1; extra == "all"
Requires-Dist: google-adk>=1.0; extra == "all"
Requires-Dist: claude-agent-sdk>=0.1; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.24; extra == "dev"
Dynamic: license-file

# Bridge ADK

**Wrap an existing Google ADK / OpenAI Agents SDK / Claude Agent SDK agent and
make it talk [A2A](https://a2a-protocol.org/) — in one or two lines of code.**

```python
import bridge_adk

bridge_adk.serve(my_agent, port=9000)          # any supported framework — that's it
```

```python
remote = bridge_adk.connect("http://localhost:9000")
answer = await remote.ask("Summarize the latest sales report")
```

A2A (Agent2Agent, now a Linux Foundation project) is the open standard for
agent-to-agent interoperability. Every major vendor ships its own agent SDK,
but getting agents from *different* SDKs to call each other still means
hand-writing protocol plumbing. Bridge ADK is that plumbing, done once.

## Documentation

Full guides live in [docs/](docs/README.md): [installation](docs/01-installation.md),
[5-minute quickstart](docs/02-quickstart.md), [serving each SDK](docs/03-serving-agents.md),
[client usage](docs/04-talking-to-agents.md), [orchestration walkthrough](docs/05-orchestration.md),
[custom adapters](docs/06-extending-adapters.md), [deployment](docs/07-deployment.md),
[API reference](docs/08-api-reference.md), and [troubleshooting](docs/09-troubleshooting.md).

## Why this exists (the gap)

| Existing option | What it covers | What's missing |
|---|---|---|
| Google ADK `to_a2a()` | ADK agents only | Nothing for OpenAI / Claude agents |
| Pydantic `FastA2A` | Pydantic AI agents only | Other frameworks |
| `a2a-adapter` | n8n, LangGraph, CrewAI, Claude Code CLI, Codex, Ollama | The three big vendor agent SDKs |
| `python-a2a` | Its own agent framework | Wrapping *existing* SDK agents |
| Official `a2a-sdk` | Full protocol implementation | ~50 lines of executor/card/handler boilerplate per agent |

Bridge ADK fills the hole in the middle: **one library, one call, the three
major vendor agent SDKs** — plus plain Python callables and a registry for
anything else.

## Install

```bash
pip install bridge-adk                 # core (a2a-sdk, uvicorn, httpx)
pip install bridge-adk[openai]         # + OpenAI Agents SDK support
pip install bridge-adk[adk]            # + Google ADK support
pip install bridge-adk[claude]         # + Claude Agent SDK support
pip install bridge-adk[all]
```

## Serve an agent (server side)

The framework is auto-detected — no flags, no subclassing.

**OpenAI Agents SDK**

```python
from agents import Agent
import bridge_adk

triage = Agent(name="triage", instructions="Route customer questions.")
bridge_adk.serve(triage, port=9001)
```

**Google ADK**

```python
from google.adk.agents import Agent
import bridge_adk

researcher = Agent(name="researcher", model="gemini-2.0-flash",
                   description="Finds and summarizes information.")
bridge_adk.serve(researcher, port=9002)
```

**Claude Agent SDK** (an agent here is a `ClaudeAgentOptions`)

```python
from claude_agent_sdk import ClaudeAgentOptions
import bridge_adk

coder = ClaudeAgentOptions(system_prompt="You are a careful Python reviewer.")
bridge_adk.serve(coder, name="reviewer", port=9003)
```

**Plain function** (escape hatch / testing)

```python
async def echo(prompt: str) -> str:
    "Echoes the prompt."
    return f"echo: {prompt}"

bridge_adk.serve(echo, port=9000)
```

Each server exposes a spec-compliant agent card at
`/.well-known/agent-card.json`, JSON-RPC at `/`, and the A2A REST binding —
all generated from the agent's own name/description/instructions.

Need the ASGI app instead of a blocking server (e.g. for gunicorn/deployment)?

```python
app = bridge_adk.to_a2a(my_agent, url="https://agents.example.com/reviewer/")
```

## Talk to an agent (client side)

```python
remote = bridge_adk.connect("http://localhost:9002")

answer = await remote.ask("What changed in the A2A 1.0 spec?")
answer = remote.ask_sync("...")                       # blocking variant
answer = await remote.ask("follow-up", context_id="conv-1")  # multi-turn
```

### Cross-framework: drop a remote agent into another SDK as a tool

This is the part that makes agents *talk to each other*:

```python
remote = bridge_adk.connect("http://localhost:9002")   # a Google ADK agent

# ...inside an OpenAI Agents SDK agent:
from agents import Agent
boss = Agent(name="boss", instructions="Delegate research.",
             tools=[remote.as_openai_tool()])

# ...inside a Google ADK agent:
from google.adk.agents import Agent
boss = Agent(name="boss", model="gemini-2.0-flash",
             tools=[remote.as_adk_tool()])

# ...inside a Claude Agent SDK agent:
from claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions(
    mcp_servers={"research": remote.as_claude_mcp_server()},
    allowed_tools=["mcp__research"],
)
```

The tool name and description come from the remote agent card, so the calling
LLM knows what the remote agent is good at. Any A2A server works — not just
ones served by Bridge ADK.

## Extending to other frameworks

```python
from bridge_adk import BridgeAdapter, AgentMeta, register_adapter

class MyFrameworkAdapter(BridgeAdapter):
    name = "my-framework"
    def matches(self, agent): ...
    def metadata(self, agent): return AgentMeta(name=..., description=...)
    async def stream(self, agent, prompt, context_id):
        yield await agent.do_the_thing(prompt)

register_adapter(MyFrameworkAdapter())
```

## How it works

```
your agent ──► adapter (auto-detected) ──► BridgeExecutor ──► a2a-sdk v1 runtime
                                                              ├─ agent card route
                                                              ├─ JSON-RPC binding
                                                              └─ REST binding
remote A2A agent ──► connect() ──► RemoteAgent.ask() / .as_<framework>_tool()
```

Built on the official [`a2a-sdk`](https://github.com/a2aproject/a2a-python)
(v1.1+, A2A spec 1.0). Framework SDKs are imported lazily — Bridge ADK itself
only depends on the A2A SDK, uvicorn, and httpx.

Session mapping: each A2A `context_id` maps to a session in the wrapped
framework where the framework supports it (Google ADK sessions today; OpenAI
Agents SDK sessions are on the roadmap — calls are currently stateless there).

## Limitations (v0.1)

- Text in / text out. File and structured-data parts are not yet mapped.
- Token-level streaming is aggregated into a single artifact (the A2A task
  lifecycle events still stream).
- No auth on the served endpoints — put it behind your gateway, or use
  a2a-sdk interceptors via a custom build for now.

## Running the tests

```bash
pip install -e .[dev]
pytest
```
