# langchain-brainiall

LangChain integration for the [Brainiall LLM Gateway](https://brainiall.com) -- access 113+ AI models from 17 providers through a single OpenAI-compatible API.

## Installation

```bash
pip install langchain-brainiall
```

## Quick Start

```python
from langchain_brainiall import ChatBrainiall

llm = ChatBrainiall(
    model="claude-sonnet-4-6",
    api_key="your-api-key",  # or set BRAINIALL_API_KEY env var
)

response = llm.invoke("Explain quantum computing in one sentence.")
print(response.content)
```

## Features

- **113+ models** from 17 providers (Anthropic, DeepSeek, Meta, Qwen, Mistral, Amazon, and more)
- **OpenAI-compatible** -- supports all ChatOpenAI features (streaming, tools, structured output)
- **Single API key** -- one key for all models, no need to manage multiple provider accounts
- **Cost-optimized** -- powered by AWS Bedrock with automatic prompt caching and flex pricing

## Environment Variables

| Variable | Description |
|----------|-------------|
| `BRAINIALL_API_KEY` | API key for authentication |
| `BRAINIALL_API_BASE` | Override the default API base URL |

## Usage Examples

### Streaming

```python
from langchain_brainiall import ChatBrainiall

llm = ChatBrainiall(model="claude-sonnet-4-6")

for chunk in llm.stream("Tell me a joke about programming"):
    print(chunk.content, end="", flush=True)
```

### Tool Calling

```python
from pydantic import BaseModel, Field
from langchain_brainiall import ChatBrainiall

class GetWeather(BaseModel):
    """Get current weather for a location."""
    location: str = Field(description="City name")

llm = ChatBrainiall(model="claude-sonnet-4-6")
llm_with_tools = llm.bind_tools([GetWeather])

response = llm_with_tools.invoke("What's the weather in Tokyo?")
print(response.tool_calls)
```

### Structured Output

```python
from pydantic import BaseModel
from langchain_brainiall import ChatBrainiall

class MovieReview(BaseModel):
    title: str
    rating: float
    summary: str

llm = ChatBrainiall(model="claude-sonnet-4-6")
structured = llm.with_structured_output(MovieReview)

review = structured.invoke("Review the movie Inception")
print(f"{review.title}: {review.rating}/10 - {review.summary}")
```

### Multi-Model Chains

Use different models for different steps -- cheap models for drafting, powerful models for refinement:

```python
from langchain_brainiall import ChatBrainiall

fast = ChatBrainiall(model="nova-micro", temperature=0.7)
smart = ChatBrainiall(model="claude-opus-4-6", temperature=0)

# Draft with a fast, cheap model
draft = fast.invoke("Write a short product description for wireless earbuds")

# Refine with a powerful model
final = smart.invoke(f"Improve this product description:\n{draft.content}")
print(final.content)
```

### With LangGraph Agents

```python
from langchain_brainiall import ChatBrainiall
from langgraph.prebuilt import create_react_agent

llm = ChatBrainiall(model="claude-sonnet-4-6")

# Define your tools
tools = [...]

agent = create_react_agent(llm, tools)
result = agent.invoke({"messages": [("human", "Help me plan a trip to Japan")]})
```

### Embeddings

```python
from langchain_brainiall import BrainiallEmbeddings

embeddings = BrainiallEmbeddings(
    model="bge-m3",
    api_key="your-api-key",
)

vector = embeddings.embed_query("What is machine learning?")
print(f"Dimensions: {len(vector)}")
```

### Async Support

```python
import asyncio
from langchain_brainiall import ChatBrainiall

async def main():
    llm = ChatBrainiall(model="claude-haiku-4-5")
    response = await llm.ainvoke("Hello!")
    print(response.content)

asyncio.run(main())
```

## Available Models

### Chat Models

| Model | Provider | Context Window | Max Output |
|-------|----------|---------------|------------|
| `claude-opus-4-6` | Anthropic | 200K | 64K |
| `claude-opus-4-6-1m` | Anthropic | 1M | 64K |
| `claude-opus-4-5` | Anthropic | 200K | 32K |
| `claude-sonnet-4-6` | Anthropic | 200K | 64K |
| `claude-sonnet-4-6-1m` | Anthropic | 1M | 64K |
| `claude-haiku-4-5` | Anthropic | 200K | 16K |
| `claude-3-opus` | Anthropic | 200K | 4K |
| `deepseek-r1` | DeepSeek | 128K | 64K |
| `deepseek-v3` | DeepSeek | 128K | 16K |
| `llama-3.3-70b` | Meta | 128K | 4K |
| `llama-4-scout-17b` | Meta | 1M | 16K |
| `llama-4-maverick-17b` | Meta | 1M | 16K |
| `qwen-3-235b` | Qwen | 128K | 16K |
| `qwen-3-32b` | Qwen | 128K | 16K |
| `qwen-3-8b` | Qwen | 128K | 16K |
| `qwen-3-80b` | Qwen | 128K | 16K |
| `mistral-large-3` | Mistral | 128K | 16K |
| `mistral-small-3` | Mistral | 128K | 16K |
| `nova-pro` | Amazon | 300K | 5K |
| `nova-lite` | Amazon | 300K | 5K |
| `nova-micro` | Amazon | 128K | 5K |
| `minimax-m2` | MiniMax | 1M | 128K |
| `nemotron-ultra-253b` | NVIDIA | 128K | 16K |
| `kimi-k2.5` | Moonshot | 128K | 16K |

### Embedding Models

| Model | Dimensions | Max Tokens |
|-------|-----------|------------|
| `bge-m3` | 1024 | 8192 |
| `bge-large-en-v1.5` | 1024 | 512 |
| `cohere-embed-v3` | 1024 | 512 |
| `titan-embed-v2` | 1024 | 8192 |

For the complete and up-to-date model list, see [brainiall.com](https://brainiall.com).

## Getting an API Key

1. Visit [brainiall.com](https://brainiall.com)
2. Sign up for an account
3. Generate an API key from the dashboard
4. Set it as `BRAINIALL_API_KEY` environment variable

## License

MIT
