Metadata-Version: 2.4
Name: uni-agent
Version: 0.1.1
Summary: Unified Agent SDK
Author: Kevin
License: MIT
Keywords: ai,agent,llm,claude,openai,gemini,langchain,unified-api
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic<3,>=1.10
Requires-Dist: typing-extensions>=4.6
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.20; extra == "otel"
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.30; extra == "anthropic"
Provides-Extra: gemini
Requires-Dist: google-genai>=0.1; extra == "gemini"
Provides-Extra: deep-agent
Requires-Dist: langgraph>=0.2; extra == "deep-agent"
Provides-Extra: openai
Requires-Dist: openai>=1.0; extra == "openai"
Provides-Extra: all
Requires-Dist: anthropic>=0.30; extra == "all"
Requires-Dist: google-genai>=0.1; extra == "all"
Requires-Dist: langgraph>=0.2; extra == "all"
Requires-Dist: openai>=1.0; extra == "all"
Requires-Dist: opentelemetry-api>=1.20; extra == "all"
Dynamic: license-file

# UniAgent

UniAgent provides a unified agent SDK that normalizes LLM inputs/outputs to a
Claude-compatible canonical protocol, with driver adapters for multiple model
providers and built-in middleware/observability hooks.

## Installation

```bash
pip install -e .
```

Optional observability support:

```bash
pip install -e .[otel]
```

## Quick Start

```python
import os

from uniagent import UniAgent

agent = UniAgent(
    provider="claude",
    model="claude-sonnet-4-5-20250929",
    api_key=os.getenv("ANTHROPIC_API_KEY"),
)

response = await agent.run([agent.user("Hello")])

print(response)
```

## Tool Registration

```python
from uniagent import UniAgent

@UniAgent.tool
def get_weather(city: str) -> str:
    """Get weather for a city."""
    return f"Sunny in {city}"

agent = UniAgent(
    provider="claude",
    model="claude-sonnet-4-5-20250929",
    api_key="YOUR_ANTHROPIC_API_KEY",
    tools=[get_weather],
)
```

## Streaming

```python
async for event in agent.stream(messages):
    print(event.event, event.data)
```

## Provider Examples

### Anthropic Claude (Unified Factory)

```python
import asyncio
import os

from uniagent import UniAgent


@UniAgent.tool
def get_weather(city: str) -> str:
    """Get weather for a city."""
    return f"Sunny in {city}"


async def main() -> None:
    agent = UniAgent(
        provider="claude",
        model="claude-sonnet-4-5-20250929",
        api_key=os.getenv("ANTHROPIC_API_KEY"),
        tools=[get_weather],
    )

    response = await agent.run(
        [agent.user("Weather in Tokyo?")],
        config={"max_tokens": 256, "enable_betas": ["structured-outputs-2025-11-13"]},
    )
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

### Google Gemini (Unified Factory)

```python
import asyncio
import os

from uniagent import UniAgent


@UniAgent.tool
def multiply(a: int, b: int) -> int:
    """Multiply two integers."""
    return a * b


async def main() -> None:
    agent = UniAgent(
        provider="gemini",
        model="gemini-1.5-pro",
        api_key=os.getenv("GOOGLE_API_KEY"),
        tools=[multiply],
    )

    response = await agent.run(
        [agent.user("2 * 21")],
        config={"generation_config": {"max_output_tokens": 256}},
    )
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

### OpenAI (Unified Factory)

```python
import asyncio
import os

from uniagent import UniAgent


async def main() -> None:
    agent = UniAgent(
        provider="openai",
        model="gpt-5.2",
        api_key=os.getenv("OPENAI_API_KEY"),
    )

    response = await agent.run([agent.user("Hello")])
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```

### DeepAgents / LangGraph (Unified Factory)

```python
import asyncio
from typing import Dict, List

from uniagent import UniAgent


def build_graph():
    from langgraph.graph import END, StateGraph

    class State(Dict):
        messages: List[UniAgent.Message]

    def final_node(state: State) -> str:
        return "DeepAgent output"

    graph = StateGraph(State)
    graph.add_node("final", final_node)
    graph.set_entry_point("final")
    graph.add_edge("final", END)
    return graph.compile()


async def main() -> None:
    agent = UniAgent(
        provider="deep_agent",
        graph_builder="examples.deep_agent_basic:build_graph",
    )

    response = await agent.run([agent.user("Run the graph")])
    print(response)


if __name__ == "__main__":
    asyncio.run(main())
```
