Aegra

SKILL.md

Aegra Skill

Product summary

Aegra is an open-source, self-hosted Agent Protocol server for running LangGraph agents on your own infrastructure. It's a drop-in replacement for LangSmith Deployments—same SDK, same APIs, no vendor lock-in. Agents use Aegra to deploy production-ready servers with full persistence, streaming, authentication, and observability. Key files: aegra.json (configuration), .env (environment variables), Dockerfile and docker-compose.yml (deployment). Primary CLI commands: aegra init, aegra dev, aegra up, aegra serve. Primary docs: https://docs.aegra.dev

When to use

Reach for this skill when:

  • Deploying agents: Setting up a production Aegra server for LangGraph agents
  • Configuring infrastructure: Defining graphs, authentication, routes, and storage in aegra.json
  • Managing state and persistence: Creating threads, running conversations, inspecting checkpoints
  • Adding authentication: Implementing JWT, OAuth, Firebase, or custom auth handlers
  • Setting up observability: Configuring OpenTelemetry tracing to Langfuse, Phoenix, or other backends
  • Building multi-turn agents: Creating assistants, managing threads, streaming responses
  • Migrating from LangSmith: Converting dashboard-based configuration to code-based setup
  • Extending the API: Adding custom FastAPI routes or shared dependencies
  • Debugging agent execution: Inspecting thread state, checkpoints, and run history

Quick reference

CLI commands

Command Use case Starts PostgreSQL? Starts app?
aegra init Create new project
aegra dev Local development with hot reload Yes (Docker) Yes (host)
aegra up Self-hosted Docker production Yes (Docker) Yes (Docker)
aegra serve PaaS, containers, bare metal (bring your own DB) No Yes (host)
aegra down Stop containers

Configuration files

File Purpose
aegra.json Define graphs, auth, HTTP routes, store, dependencies
.env Database credentials, API keys, observability settings
Dockerfile Container image for production deployment
docker-compose.yml PostgreSQL + app orchestration

Key aegra.json sections

{
  "graphs": [{"path": "./agent.py:graph"}],
  "auth": {"path": "./my_auth.py:auth"},
  "http": {"app": "./custom_routes.py:app", "cors": {...}},
  "dependencies": ["./shared", "./libs"],
  "store": {"index": {"dims": 1536, "embed": "openai:text-embedding-3-small"}}
}

Environment variables (essential)

Variable Purpose Example
DATABASE_URL PostgreSQL connection (takes precedence) postgresql://user:pass@localhost/db
POSTGRES_HOST, POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_DB Individual DB config (used if DATABASE_URL not set)
OTEL_TARGETS Observability backends LANGFUSE,PHOENIX
LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY Langfuse credentials
PHOENIX_COLLECTOR_ENDPOINT Phoenix OTLP endpoint http://127.0.0.1:6006/v1/traces

SDK essentials (LangGraph SDK)

from langgraph_sdk import get_client

client = get_client(url="http://localhost:2026")

# Create thread
thread = await client.threads.create()

# Create assistant
assistant = await client.assistants.create(
    graph_id="agent",
    name="My Agent",
    metadata={"purpose": "search"}
)

# Stream run
async for chunk in client.runs.stream(
    thread_id=thread["thread_id"],
    assistant_id=assistant["assistant_id"],
    input={"messages": [{"type": "human", "content": "Hello"}]}
):
    print(chunk)

Decision guidance

When to use each deployment command

Scenario Command Why
Local development with hot reload aegra dev Starts PostgreSQL in Docker, runs app on host with auto-reload
Self-hosted production (your infrastructure) aegra up Everything in Docker, auto-migrations, health checks, restart policies
PaaS (Railway, Render, Heroku) aegra serve No Docker needed; you provide DATABASE_URL, app runs as process
Kubernetes aegra serve Run in pod spec; external PostgreSQL; stateless app
Windows production Docker or Linux server aegra serve on Windows not supported (psycopg event loop issue)

When to use authentication vs. no auth

Situation Approach
Local development only Omit auth from aegra.json; no auth required
Production with user identity Implement Auth handler; verify JWT, OAuth, or Firebase tokens
Fine-grained access control Use permissions field in auth response; check in custom routes
Studio access during dev Set AEGRA_STUDIO_AUTH_BYPASS=true to skip auth for /studio

When to use store vs. thread state

Use case Approach
Conversation history, messages Store in thread state (automatic via LangGraph)
User preferences, knowledge base Use Store API (key-value or semantic)
Semantic search (embeddings) Configure store.index with embedding model
Simple key-value (no search) Use Store API without index config

When to stream vs. wait

Scenario Approach
Real-time UI updates, token-by-token output Use client.runs.stream() with SSE
Batch processing, fire-and-forget Use client.runs.create() (background run)
Need final output only Use client.runs.wait() (blocks until complete)
Reconnect after disconnect Use Last-Event-ID header in stream request

Workflow

1. Set up a new Aegra project

pip install aegra-cli
aegra init
# Choose location, template (simple-chatbot or react-agent), project name
cd <project>
cp .env.example .env

2. Define your agent graph

Write a LangGraph graph in agent.py (or your chosen path):

from langgraph.graph import StateGraph
from langgraph.types import BaseMessage

def agent_node(state):
    # Your agent logic
    return {"messages": [...]}

graph = StateGraph(...)
graph.add_node("agent", agent_node)
# ... add edges, compile

3. Register the graph in aegra.json

{
  "graphs": [{"path": "./agent.py:graph"}]
}

4. Add authentication (if needed)

Create my_auth.py:

from langgraph_sdk import Auth

auth = Auth()

@auth.authenticate
async def authenticate(headers: dict) -> dict:
    token = headers.get("Authorization", "").replace("Bearer ", "")
    if not token:
        raise Exception("Auth required")
    # Verify JWT, OAuth, etc.
    return {
        "identity": "user123",
        "display_name": "Jane",
        "is_authenticated": True
    }

Add to aegra.json:

{
  "auth": {"path": "./my_auth.py:auth"}
}

5. Configure observability (optional)

In .env:

OTEL_TARGETS="LANGFUSE"
LANGFUSE_PUBLIC_KEY=pk_...
LANGFUSE_SECRET_KEY=sk_...

6. Start the server

Local development:

aegra dev

Production (Docker):

aegra up

PaaS (provide your own DB):

aegra serve

7. Create an assistant and run a conversation

import asyncio
from langgraph_sdk import get_client

async def main():
    client = get_client(url="http://localhost:2026")
    
    # Create thread
    thread = await client.threads.create()
    
    # Create assistant (or use default with graph_id)
    assistant = await client.assistants.create(
        graph_id="agent",
        name="My Agent"
    )
    
    # Stream conversation
    async for chunk in client.runs.stream(
        thread_id=thread["thread_id"],
        assistant_id=assistant["assistant_id"],
        input={"messages": [{"type": "human", "content": "Hello"}]}
    ):
        print(chunk)

asyncio.run(main())

8. Inspect and debug

# Get thread state
state = await client.threads.get_state(thread_id)

# Get state at specific checkpoint
state = await client.threads.get_state(
    thread_id,
    checkpoint={"id": "checkpoint_id"}
)

# List all assistants
assistants = await client.assistants.search()

# Get subgraphs
subgraphs = await client.assistants.get_subgraphs(assistant_id, recurse=True)

Common gotchas

  • PostgreSQL not reachable: If using aegra dev or aegra up, ensure Docker is running. If using aegra serve, verify DATABASE_URL or POSTGRES_* variables in .env.

  • Wrong database credentials: Check that POSTGRES_USER and POSTGRES_PASSWORD in .env match what PostgreSQL was initialized with. Migrations fail silently if connection is wrong.

  • Migrations haven't applied: Server couldn't connect to PostgreSQL during startup. Check logs, fix connection, restart. Don't ignore migration errors.

  • Using aegra package instead of aegra-cli: The aegra meta-package on PyPI doesn't support version pinning. Always install aegra-cli directly.

  • Config file resolution order: Aegra looks for aegra.json first, then langgraph.json. Use AEGRA_CONFIG env var to override. Relative paths are resolved from the config file's directory.

  • Auth handler not called: Ensure auth is registered in aegra.json and the path is correct. If auth is omitted, no authentication is required.

  • Embedding dimensions mismatch: The dims value in store.index must match your embedding model's output exactly. text-embedding-3-small outputs 1536 dimensions.

  • Semantic store not working: Verify PostgreSQL has pgvector extension installed. Use pgvector/pgvector:pg18 image. Check that embed format is provider:model-id and API key is set.

  • Custom routes not mounted: Verify http.app path in aegra.json is correct and the FastAPI app is exported. If enable_custom_route_auth is true, auth handler must be configured.

  • Windows production deployment: aegra serve on Windows is not supported due to psycopg event loop requirements. Use Docker or deploy to Linux.

  • Interrupts not working: Ensure graph calls interrupt() from langgraph.types. Interrupts work across subgraph boundaries transparently.

  • Streaming reconnection fails: Use Last-Event-ID header in stream request to resume from a specific event after disconnect.

  • Health checks failing: If server hangs, Docker marks it unhealthy after 3 consecutive failures (every 30 seconds). Check logs for deadlocks or blocking operations.

Verification checklist

Before deploying or submitting work:

  • aegra.json is valid JSON and all paths are correct (relative to config file directory)
  • All graph paths in graphs section exist and export a compiled graph
  • Auth handler (if configured) is importable and returns required fields (identity, is_authenticated)
  • .env file has all required variables (at minimum: DATABASE_URL or POSTGRES_* variables)
  • PostgreSQL is reachable and has pgvector extension (if using semantic store)
  • Embedding model dimensions match store.index.dims (if configured)
  • Custom routes app (if configured) is a valid FastAPI instance
  • Dependencies paths exist and are importable (if configured)
  • CORS origins are correct for your frontend (if using custom routes)
  • Observability backend credentials are set (if configured)
  • Server starts without errors: aegra dev or aegra serve
  • Health endpoint responds: curl http://localhost:2026/health
  • Can create a thread and run a conversation via SDK
  • Thread state persists across runs (check with client.threads.get_state())
  • Streaming works: async for chunk in client.runs.stream(...)
  • Traces appear in observability backend (if configured)

Resources

Comprehensive navigation: https://docs.aegra.dev/llms.txt

Critical documentation pages:


For additional documentation and navigation, see: https://docs.aegra.dev/llms.txt

Weekly Installs
10
First Seen
14 days ago
Installed on
amp10
cline10
opencode10
cursor10
kimi-cli10
codex10