Metadata-Version: 2.4
Name: cogent-ai
Version: 2.0.0
Summary: A small, honest agent framework: six concepts, one loop, native OTel.
Project-URL: Homepage, https://github.com/milad-o/cogent
Project-URL: Repository, https://github.com/milad-o/cogent
Project-URL: Issues, https://github.com/milad-o/cogent/issues
Author: Milad Olad
License-Expression: MIT
License-File: LICENSE
Keywords: agents,ai,asyncio,llm,opentelemetry,tools
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: anyio>=4.6
Requires-Dist: httpx>=0.28
Requires-Dist: pydantic>=2.9
Requires-Dist: python-dotenv>=1.0
Provides-Extra: all
Requires-Dist: aiosqlite>=0.21; extra == 'all'
Requires-Dist: opentelemetry-api>=1.27; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.27; extra == 'all'
Requires-Dist: opentelemetry-semantic-conventions>=0.48b0; extra == 'all'
Requires-Dist: rich>=14; extra == 'all'
Requires-Dist: sqlite-vec>=0.1.6; extra == 'all'
Provides-Extra: anthropic
Provides-Extra: cerebras
Provides-Extra: cloudflare
Provides-Extra: cohere
Provides-Extra: custom
Provides-Extra: deepseek
Provides-Extra: gemini
Provides-Extra: groq
Provides-Extra: mistral
Provides-Extra: ollama
Provides-Extra: openai
Provides-Extra: openrouter
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.27; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.27; extra == 'otel'
Requires-Dist: opentelemetry-semantic-conventions>=0.48b0; extra == 'otel'
Provides-Extra: rich
Requires-Dist: rich>=14; extra == 'rich'
Provides-Extra: sqlite
Requires-Dist: aiosqlite>=0.21; extra == 'sqlite'
Requires-Dist: sqlite-vec>=0.1.6; extra == 'sqlite'
Provides-Extra: together
Provides-Extra: voyage
Provides-Extra: xai
Description-Content-Type: text/markdown

# Cogent

<p align="center">
  <strong>Six concepts. One loop. 10K lines. 13 providers. No vendor SDKs.</strong>
</p>

Cogent is a Python framework for building AI agents that you can
actually ship. Small, typed, composable — one runner loop, one middleware
protocol, one tool decorator, raw HTTP to every provider.

> **v2.0.0** is now the `main` branch — a ground-up rewrite that
> replaced 77,000 lines and 7 runtime dependencies with a 10,000-line
> core and 4 dependencies, while shipping more capabilities. See the
> [release notes](https://github.com/milad-o/cogent/releases/tag/v2.0.0)
> for the full story. The 1.x codebase lives on the
> [`v1`](https://github.com/milad-o/cogent/tree/v1) branch. There are
> **no compatibility shims** — pin `cogent-ai<2` if you need 1.x.

---

## Install

```bash
pip install "cogent-ai[openai]"     # anthropic, ollama, voyage, sqlite, otel, rich, all
```

Cogent targets Python 3.13+. Four runtime dependencies: `pydantic`,
`httpx`, `anyio`, `python-dotenv`. Zero vendor SDKs — all 13 providers
speak HTTP directly.

## Hello, agent

```python
import asyncio
from cogent import Agent

agent = Agent(
    model="openai/gpt-4o-mini",
    instructions="You are a Kyoto travel guide. Keep answers short and concrete.",
)

async def main() -> None:
    result = await agent.run("Where should I eat tofu in Kyoto?")
    print(result.value)

asyncio.run(main())
```

## A tool, a structured output

```python
from pydantic import BaseModel
from cogent import Agent, tool

class Recipe(BaseModel):
    name: str
    steps: list[str]

@tool
async def lookup(name: str) -> str:
    """Look up a recipe."""
    return "miso soup: warm dashi, dissolve miso, drop in tofu and wakame."

agent = Agent(
    model="openai/gpt-4o-mini",
    tools=(lookup,),
    output=Recipe,
)
recipe = (await agent.run("recipe for miso soup")).value
```

## Streaming

```python
async for event in agent.run("describe spring in Kyoto", stream=True):
    print(event)
```

## Middleware (Retry · CostBudget · Cache · Approval · …)

```python
from cogent import Agent, Approval, CostBudget

agent = Agent(
    model="openai/gpt-4o-mini",
    middleware=(
        CostBudget(limit_usd=1.00),
        Approval(predicate=lambda call: call.name == "send_email"),
    ),
)
```

Retry is built in (`retries=3`); set `retries=0` to disable or pass a
custom `Retry(...)` in middleware. Middleware composes from left to right
around every `model_call` and `tool_call`. Approvals turn into a `Paused`
result you can resume from later, in-process or across processes (set
`Agent(store=…)` and open with `agent.thread(id=…)`).

## Sub-agents

```python
from cogent import Agent, as_tool, sequential

researcher = Agent(model=..., instructions="Find sources.")
writer = Agent(model=..., instructions="Draft the brief.")

# Use one agent as a tool inside another
team = Agent(model=..., tools=(as_tool(researcher), as_tool(writer)))

# Or run them sequentially, threading each output as the next input
result = await sequential(researcher, writer, task="Outline 3 days in Kyoto.")
```

## Persistence + resume

```python
from cogent import Agent, DictStore
# from cogent.store import SQLiteStore  # durable, FTS5-backed

store = DictStore()
agent = Agent(model="openai/gpt-4o-mini", store=store)

thread = agent.thread(id="trip-1")
result = await thread.send("Plan a 3-day trip.")
# ... process exits ...

# Later — in another process, with the same store backend:
resumed = agent.thread(id="trip-1")
final = await resumed.send("Make day 2 vegetarian.")
```

`store=` covers both thread snapshots and `recall`/`remember`. Pass
`threads=` or `memory=` only when you want different backends for each.

## Testing without the network

```python
from cogent import Agent
from cogent.core.messages import ToolCall
from cogent.testing import MockModel, MockTool, expect, reply, tool_use

model = MockModel(
    responses=[
        tool_use(ToolCall(id="c1", name="fetch", args={"city": "Kyoto"})),
        reply("Kyoto is sunny."),
    ]
)
fetch = MockTool(name="fetch", returns="sunny", arg_fields={"city": str})

agent = Agent(model=model, tools=(fetch,))
result = await agent.run("how's Kyoto?")
expect(result).to_be_done().with_value_containing("sunny").with_steps(2)
assert fetch.calls == [{"city": "Kyoto"}]
```

## Observability

```python
from cogent import Agent
from cogent.middleware import JSONLogger, Logger
# OTelTracer / OTelMetrics are exposed lazily on cogent.middleware when
# the 'otel' extra is installed.

agent = Agent(
    model=...,
    middleware=(Logger(), JSONLogger(redact=lambda k, _: "secret" in k.lower())),
)
```

## What's in the box

| Area         | Modules                                                                                                                                |
|--------------|----------------------------------------------------------------------------------------------------------------------------------------|
| Core         | `Agent`, `Thread`, `Context`, `Message`, `Result`, `Event`                                                                              |
| Models       | OpenAI, Anthropic, Ollama, Groq, DeepSeek, Gemini, Mistral, Cohere, xAI, OpenRouter, Together, Cerebras, Cloudflare; embedders for OpenAI, Voyage, Ollama |
| Tools        | `@tool`, `ToolBase`, builtins (`recall`, `remember`, `update_block`)                                                                    |
| Middleware   | `Retry`, `RateLimit`, `CostBudget`, `Cache`, `Approval`, `Compact`, `AutoRecall`, `Logger`, `JSONLogger`, `OTelTracer`, `OTelMetrics` |
| Store        | `DictStore`, `SQLiteStore` (FTS5) — thread snapshots, recall, episodes                                                                  |
| Composition  | `as_tool`, `sequential`, `until`, `replay`                                                                                              |
| Testing      | `MockModel`, `MockTool`, `expect`                                                                                                       |

## Documentation

- [Getting Started](docs/getting-started.md)
- [Concepts](docs/concepts.md) — the six building blocks
- [Middleware](docs/middleware.md) — retry, rate limiting, cost, caching, approval, observability
- [Memory](docs/memory.md) — recall, remember, episodic
- [Testing](docs/testing.md) — mock models, assertions
- [Examples](docs/examples.md) — runnable notebooks

## License

MIT — see [LICENSE](LICENSE).
