Metadata-Version: 2.4
Name: cortex-agent-sdk
Version: 0.2.1
Summary: Sesiones Memory y Redis para agentes multiprovider con Pydantic AI
Project-URL: Repository, https://github.com/epok200/cortex_agent_sdk
Project-URL: Issues, https://github.com/epok200/cortex_agent_sdk/issues
Author: EPOK
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agents,pydantic-ai,redis,sessions
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.13
Requires-Dist: pydantic-ai-slim[google,openai]<3,>=2.27
Provides-Extra: all
Requires-Dist: redis>=8.1.0; extra == 'all'
Provides-Extra: openai
Provides-Extra: redis
Requires-Dist: redis>=8.1.0; extra == 'redis'
Description-Content-Type: text/markdown

# Cortex Agent SDK

Cortex agrega sesiones Memory y Redis a agentes multiprovider construidos directamente con
Pydantic AI.

No implementa otro loop, otra capa de tools ni otra API de agentes. Pydantic AI conserva el control
de providers, modelos, tools, tipado, `RunContext`, hooks, límites, approvals, outputs, usage e
historial. Cortex sólo cubre la pieza que Pydantic AI no incluye: persistencia conversacional con un
turno activo por sesión.

> Cortex Agent SDK está en alfa. La API puede cambiar antes de la versión `1.0.0`.

## Requisitos

- Python `>=3.13`.
- Pydantic AI `>=2.27,<3`, con Google y OpenAI instalados por Cortex.

## Instalación

Google, OpenAI y sesiones en memoria:

```bash
uv add cortex-agent-sdk
```

Google, OpenAI y Redis:

```bash
uv add "cortex-agent-sdk[redis]"
```

La instalación base incluye Google y OpenAI, además de los endpoints compatibles con OpenAI. Otros
providers pueden agregarse desde los extras oficiales de Pydantic AI cuando un producto realmente
los necesite. Cortex no implementa adapters paralelos.

## Uso

El agente es el `Agent` nativo de Pydantic AI. El store entrega el historial bajo exclusión y lo
guarda cuando `session.replace(...)` marca un resultado completo.

```python
import asyncio

from pydantic_ai import Agent

from cortex_agent_sdk.sessions import MemorySessionStore


async def main() -> None:
    agent = Agent("openai-responses:gpt-5.6-luna")
    sessions = MemorySessionStore()

    async with agent, sessions:
        async with sessions.turn("usuario:42") as session:
            result = await agent.run(
                "Recuerda que mi color favorito es verde.",
                message_history=session.messages,
                conversation_id=session.session_id,
            )
            session.replace(result.all_messages())

    print(result.output)


asyncio.run(main())
```

`replace()` es explícito por diseño:

- Si no se llama, el store no modifica el historial.
- Si el bloque termina con una excepción, el store no guarda el reemplazo.
- Si guardar falla, la excepción se propaga.

## Redis

```python
from cortex_agent_sdk.redis import RedisSessionStore

sessions = RedisSessionStore(
    "redis://localhost:6379/0",
    key_prefix="mi-producto:sesiones:v1",
    ttl_seconds=86_400,
)
```

Redis mantiene un lease renovable durante todo el turno. Mientras conserva el lease, dos procesos no
pueden usar la misma sesión al mismo tiempo y las sesiones distintas siguen siendo concurrentes. Si
la renovación falla, Cortex interrumpe el turno propietario y no guarda como owner obsoleto. El
historial se serializa con `ModelMessagesTypeAdapter`, el formato público de Pydantic AI.

Al cambiar desde el runtime anterior, usa un prefix nuevo. Los formatos no son compatibles y Cortex
no intenta convertir el historial legacy.

## Endpoint compatible con OpenAI

Pydantic AI puede conectarse directamente. Para un endpoint que no debe reintentar peticiones,
configura el provider una vez:

```python
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIResponsesModel
from pydantic_ai.providers.openai import OpenAIProvider

provider = OpenAIProvider(
    base_url="https://example.com/v1",
    api_key="...",
)
provider.client.max_retries = 0
model = OpenAIResponsesModel("gpt-5.6-luna", provider=provider)
agent = Agent(model)
```

El context manager de `Agent` administra el transporte del provider.

## Migración desde el runtime anterior

| Antes | Ahora |
|---|---|
| `cortex_agent_sdk.Agent` | `pydantic_ai.Agent` |
| `OpenAIEngine` | `OpenAIResponsesModel` + `OpenAIProvider` |
| `OpenAICompatibleGateway` | `OpenAIProvider(base_url=..., api_key=...)` |
| `OpenAIOptions` | `OpenAIResponsesModelSettings` y argumentos de `Agent.run` |
| `@tool` e `Injected` | tools nativas + `RunContext[Deps]` |
| `ToolBinding` | `FunctionToolset` o tools preparadas por run |
| `AgentHooks` | `pydantic_ai.capabilities.Hooks` |
| `turn_finished` | `Hooks(after_run=...)` |
| `history_transform` | `Hooks(before_model_request=...)` |
| `fallback_answer` | política local del producto sobre `AgentRunResult` |
| `AgentOptions` | `UsageLimits`, settings del modelo y argumentos de `Agent` |
| `AgentResult.text` | `AgentRunResult.output` |
| `SessionStore.acquire` | `SessionStore.turn` + `Session.replace` |
| `agent.reset_session(id)` | `store.reset(id)` |

No se ofrece una capa de compatibilidad. Mantenerla volvería a duplicar la API y el runtime de
Pydantic AI.

## Superficie pública

- `cortex_agent_sdk.sessions.Session`
- `cortex_agent_sdk.sessions.SessionStore`
- `cortex_agent_sdk.sessions.MemorySessionStore`
- `cortex_agent_sdk.redis.RedisSessionStore`
- `cortex_agent_sdk.errores.AppError`
- `cortex_agent_sdk.errores.CodigoError`
- `cortex_agent_sdk.errores.Severidad`

El loop, tools, hooks, approvals, modelos y resultados se importan desde `pydantic_ai`.

## Licencia

Apache License 2.0.
