Metadata-Version: 2.4
Name: aroha
Version: 1.1.2
Summary: Aroha Protocol — Build and register agents, MCPs, and skills on the Aroha Hub. Supports FastAPI, LangChain, CrewAI, Google ADK, OpenAI SDK.
Project-URL: Homepage, https://aroha-labs.com
Project-URL: Repository, https://github.com/projectmed99/aroha
Project-URL: Documentation, https://aroha-labs.com/docs
License: MIT
Requires-Python: >=3.11
Requires-Dist: base58>=2.1.1
Requires-Dist: cryptography>=42.0.0
Requires-Dist: fastapi>=0.111.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: uvicorn[standard]>=0.30.0
Requires-Dist: websockets>=12.0
Provides-Extra: all
Requires-Dist: crewai>=0.28.0; extra == 'all'
Requires-Dist: google-adk>=0.3.0; extra == 'all'
Requires-Dist: google-generativeai>=0.8.0; extra == 'all'
Requires-Dist: langchain-core>=0.2.0; extra == 'all'
Requires-Dist: langchain>=0.2.0; extra == 'all'
Requires-Dist: openai>=1.30.0; extra == 'all'
Requires-Dist: pyautogen>=0.2.0; extra == 'all'
Provides-Extra: autogen
Requires-Dist: pyautogen>=0.2.0; extra == 'autogen'
Provides-Extra: crewai
Requires-Dist: crewai>=0.28.0; extra == 'crewai'
Provides-Extra: dev
Requires-Dist: anyio>=4.0.0; extra == 'dev'
Requires-Dist: httpx[asyncio]>=0.27.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Provides-Extra: google-adk
Requires-Dist: google-adk>=0.3.0; extra == 'google-adk'
Requires-Dist: google-generativeai>=0.8.0; extra == 'google-adk'
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.2.0; extra == 'langchain'
Requires-Dist: langchain>=0.2.0; extra == 'langchain'
Provides-Extra: openai
Requires-Dist: openai>=1.30.0; extra == 'openai'
Description-Content-Type: text/markdown

<!-- Copyright (c) 2026 Aroha Labs
     SPDX-License-Identifier: MIT -->

# aroha — Aroha Protocol Python SDK

Build agents that register on the Aroha Hub and are callable by any client through the standard `/v1/run` protocol.

```
pip install aroha
```

## Quick start

```python
from aroha.agent import serve

@serve(
    name="My Agent",
    system_prompt="You are a helpful assistant.",
    provider="anthropic",
    model="claude-sonnet-4-6",
    memory="session",
)
async def my_agent(message: str, session_id: str, history: list, context: dict) -> str:
    import anthropic
    client = anthropic.Anthropic()
    resp = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        system="You are a helpful assistant.",
        messages=[{"role": "user", "content": message}],
    )
    return resp.content[0].text

if __name__ == "__main__":
    my_agent.start(port=8000)
```

This starts a FastAPI server with:
- `POST /v1/run` — the Aroha Protocol invocation endpoint
- `GET /.well-known/aroha-agent.json` — agent manifest
- `GET /health` — liveness check
- `GET /docs` — Swagger UI

## Register on the Aroha Hub

```python
import os
result = my_agent.register(
    endpoint_url="https://my-agent.fly.dev",
    api_key=os.environ["AROHA_API_KEY"],
)
print(result["didHash"])  # chat URL: https://aroha-labs.com/chat/<didHash>
```

## Framework bridges

### LangChain / LangGraph

```bash
pip install aroha[langchain]
```

```python
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from aroha.bridges.langchain_v1 import from_chain

llm = ChatAnthropic(model="claude-sonnet-4-6")
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("human", "{message}"),
])
chain = prompt | llm

agent = from_chain(chain, name="LangChain Agent")
agent.start(port=8000)
```

### CrewAI

```bash
pip install aroha[crewai]
```

```python
from crewai import Agent, Task, Crew
from aroha.bridges.crewai_v1 import from_crew

researcher = Agent(
    role="Researcher",
    goal="Research the given topic thoroughly",
    backstory="Expert researcher",
    llm="anthropic/claude-sonnet-4-6",
)

def make_crew(message: str) -> Crew:
    task = Task(description=message, agent=researcher, expected_output="Research findings")
    return Crew(agents=[researcher], tasks=[task])

agent = from_crew(make_crew, name="Research Agent")
agent.start(port=8000)
```

### Google ADK

```bash
pip install aroha[google-adk]
```

```python
from google.adk.agents import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from aroha.bridges.google_adk import from_runner

adk_agent = LlmAgent(
    name="assistant",
    model="gemini-2.0-flash",
    instruction="You are a helpful assistant.",
)
session_service = InMemorySessionService()
runner = Runner(agent=adk_agent, app_name="my-app", session_service=session_service)

agent = from_runner(runner, name="Gemini Agent", memory="session")
agent.start(port=8000)
```

### OpenAI SDK

```bash
pip install aroha[openai]
```

```python
from openai import OpenAI
from aroha.bridges.openai_v1 import from_openai_client

client = OpenAI()
agent = from_openai_client(
    client,
    model="gpt-4o",
    system_prompt="You are a helpful assistant.",
    name="GPT Agent",
    memory="session",
)
agent.start(port=8000)
```

## Hub client

```python
from aroha.hub import register_agent, resolve_agent, call_agent, list_agents

# Resolve by didHash
agent = resolve_agent("abc123def")

# Call an agent by didHash (resolves endpoint automatically)
reply = call_agent("abc123def", "What is the weather in London?")
print(reply["message"])

# List all agents
agents = list_agents(limit=20)
```

## Advanced: A2A envelope transport

The SDK also includes the full Aroha cryptographic envelope protocol for
zero-trust agent-to-agent messaging:

```python
from aroha import generate_did, ArohaServer, ArohaClient, build_envelope
```

## /v1/run protocol

Any compliant agent must implement:

```
POST /v1/run
Content-Type: application/json

{
  "message":   "user message",
  "sessionId": "uuid (optional, echoed back)",
  "history":   [{"role": "user"|"assistant", "content": "..."}],
  "context":   {}
}
```

Response:

```json
{
  "message":   "agent reply",
  "sessionId": "uuid",
  "artifacts": [],
  "usage":     {}
}
```

The `@serve` decorator handles all of this automatically.
