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 with the same SDK, no vendor lock-in, and full control over your data. Agents run on PostgreSQL with optional Redis for multi-instance deployments. Key files: aegra.json (configuration), .env (environment variables), pyproject.toml (dependencies). CLI commands: aegra init (create project), aegra dev (local development), aegra serve (production), aegra up (Docker). Primary docs: https://docs.aegra.dev
When to use
Use this skill when:
- Setting up a new agent project — Initialize with
aegra init, configure graphs inaegra.json, and start developing withaegra dev - Configuring authentication — Add JWT, OAuth, Firebase, or custom auth handlers to protect API endpoints
- Managing agent conversations — Create threads, inspect state, update state, browse checkpoint history, search threads by metadata
- Implementing real-time features — Stream agent responses with SSE, handle interrupts for human-in-the-loop workflows, reconnect after network drops
- Scheduling recurring tasks — Create cron jobs with timezone support, manage stateless or thread-bound scheduled runs
- Persisting data — Store key-value data or semantic embeddings for knowledge retrieval, user preferences, conversation memory
- Deploying to production — Deploy to Docker, PaaS (Railway, Render, Fly.io), or Kubernetes with proper auth, observability, and scaling
- Debugging agent behavior — Inspect thread state at checkpoints, replay from specific points, modify state for testing
Quick reference
CLI commands
| Command | Use case |
|---|---|
aegra init |
Create new project (choose template: simple-chatbot or react-agent) |
aegra dev |
Local development with hot reload and managed PostgreSQL |
aegra serve |
Production server (requires external PostgreSQL) |
aegra up |
Docker Compose (PostgreSQL + app) |
aegra down |
Stop Docker services |
Configuration file (aegra.json)
{
"graphs": {
"agent": "./src/agent/graph.py:graph"
},
"auth": {
"path": "./my_auth.py:auth"
},
"http": {
"app": "./custom_routes.py:app",
"cors": {
"allow_origins": ["https://example.com"],
"allow_credentials": true
}
},
"store": {
"index": {
"dims": 1536,
"embed": "openai:text-embedding-3-small"
}
},
"checkpointer": {
"ttl": {
"strategy": "delete",
"default_ttl": 43200
}
}
}
Core API patterns
| Task | Pattern |
|---|---|
| Create thread | client.threads.create(metadata={...}) |
| Run agent | client.runs.stream(threadid, assistantid, input={...}) |
| Get state | client.threads.getstate(threadid) |
| Update state | client.threads.updatestate(threadid, values={...}) |
| Search threads | client.threads.search(metadata={...}, status="idle") |
| Create assistant | client.assistants.create(graph_id, name, metadata) |
| Create cron | client.crons.create(assistant_id, schedule="0 9 *", input={...}) |
| Store data | client.store.put_item(namespace=[...], key, value) |
| Search store | client.store.searchitems(namespaceprefix=[...], query) |
Environment variables (key ones)
| Variable | Default | Purpose |
|---|---|---|
DATABASE_URL |
— | PostgreSQL connection (required for aegra serve) |
OPENAIAPIKEY |
— | LLM API key |
REDISBROKERENABLED |
false |
Enable Redis for multi-instance deployments |
CRON_ENABLED |
true |
Enable background scheduler |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
ENV_MODE |
LOCAL |
LOCAL, DEVELOPMENT, or PRODUCTION (JSON logs) |
Decision guidance
When to use X vs Y
| Decision | Use X when | Use Y when |
|---|---|---|
| Static vs factory graph | Graph logic is fixed, no per-request customization needed | Graph structure changes per user/request (tools, models, resources) |
| Thread-bound vs stateless cron | You need conversation continuity across scheduled runs | Each run is independent (daily reports, batch jobs) |
| Interrupt before/after vs custom interrupt() | You want simple pause points without modifying graph code | You need complex approval logic with edits, rejections, or conditional routing |
| Stream vs wait | You need real-time feedback and token-by-token output | You only care about final result and can wait for completion |
| Key-value vs semantic store | You're storing structured data or exact lookups | You need to find data by meaning (knowledge retrieval, similarity search) |
| aegra dev vs aegra serve | Local development with auto-reload and managed DB | Production deployment with external PostgreSQL |
| User scoping vs configurable scopes | Each user has isolated data (default) | Multiple users share data by org/team/region (configurable scopes) |
Workflow
1. Initialize and configure a project
- Run
aegra initand choose a template (simple-chatbot or react-agent) - Open
aegra.jsonand verify your graph paths undergraphs - Create
.envfrom.env.exampleand add API keys (OPENAIAPIKEY, etc.) - If using auth, create
my_auth.pywith@auth.authenticatehandler and reference it inaegra.json - If using semantic store, add
store.indexconfig with embedding model and dimensions
2. Develop and test locally
- Run
aegra devto start PostgreSQL and the server with hot reload - Visit
http://localhost:2026/docsto explore the API - Create a thread:
client.threads.create() - Stream a run:
client.runs.stream(threadid, assistantid, input={...}) - Inspect state:
client.threads.getstate(threadid) - Modify graph code; server auto-reloads
3. Implement human-in-the-loop (if needed)
- In your graph, call
interrupt({payload})at decision points - Client receives interrupt and displays payload to user
- User responds with
command={"resume": [{"type": "accept|edit|response|ignore", "args": ...}]} - Resume the run with the command; graph continues from interrupt point
4. Add scheduled tasks (if needed)
- Create a cron:
client.crons.create(assistant_id, schedule="0 9 *", input={...}) - For thread-bound crons:
client.crons.createforthread(thread_id, ...) - Update schedule:
client.crons.update(cron_id, schedule="...") - Disable without deleting:
client.crons.update(cron_id, enabled=False)
5. Deploy to production
- Choose deployment target (Docker, PaaS, Kubernetes)
- Set up PostgreSQL (managed or self-hosted) and get
DATABASE_URL - For multi-instance: set up Redis and
REDISBROKERENABLED=true - Set
ENV_MODE=PRODUCTIONfor JSON logging - Use
aegra serveas the start command - Verify health:
GET /health,GET /ready,GET /live
6. Verify before submitting
- All graphs in
aegra.jsonare valid Python import paths -
.envhas all required API keys (OPENAIAPIKEY, etc.) - Auth handler (if configured) returns
identityfield - Threads can be created and runs can stream without errors
- State updates persist across runs
- Crons (if used) fire on schedule
- Store operations work (put, get, search)
- Health checks pass:
/health,/ready,/live
Common gotchas
- Graph import paths must be exact —
./src/agent/graph.py:graphmeans the variablegraphin that file. Typos silently fail at startup. - Auth handlers run on every request — Keep them fast. Slow auth blocks all API calls.
- Cron delivery is at-least-once — If a worker crashes between claiming and committing, the cron fires again. Make runs idempotent.
- Stateless cron threads delete by default — Set
onruncompleted="keep"if you need to inspect them; clean up manually or use thread TTL. - Store values must be JSON objects — Strings, numbers, and primitives are rejected. Wrap them:
{"value": "text"}. - Namespace scoping is automatic — User data is isolated under
["users", <user_id>]by default. Configurable scopes share data by org/team/region. - Stream mode
debugis always on — Checkpoint and task events are sent internally but only forwarded to client if explicitly requested. - **Interrupt before/after
"*"pauses at every node** — Use specific node names for targeted interrupts. - Factory graphs are called per-request — Expensive operations (DB queries, API calls) in factories slow down every run. Cache or defer to graph nodes.
- PostgreSQL must have pgvector — Use
pgvector/pgvector:pg18image. Semantic store won't work without it. - Redis is optional but recommended for production — Without it, runs execute as in-process asyncio tasks. Multi-instance deployments need Redis for job queue and SSE streaming.
- LangGraph Studio auth can be disabled — Set
disablestudioauth: truein config to allow Studio connections without auth (useful for local dev). - Custom routes don't inherit auth by default — Set
enablecustomroute_auth: trueto apply Aegra auth to all custom FastAPI routes.
Verification checklist
Before deploying or submitting work:
- Run
aegra devand verify server starts without errors - Create a thread and stream a run successfully
- Inspect thread state and verify it persists
- If using auth, test with valid and invalid tokens
- If using crons, verify at least one fires on schedule
- If using store, put and retrieve an item
- If using semantic search, verify embeddings are created
- If using human-in-the-loop, trigger an interrupt and resume
- Check logs for warnings or deprecations
- Verify
GET /healthreturns 200 with all components healthy - Test with LangGraph Studio or Agent Chat UI if available
- Confirm
.envhas no secrets committed to version control
Resources
- Full documentation navigation: https://docs.aegra.dev/llms.txt
- Configuration reference: https://docs.aegra.dev/reference/configuration
- Authentication guide: https://docs.aegra.dev/guides/authentication
- Streaming and real-time features: https://docs.aegra.dev/guides/streaming
For additional documentation and navigation, see: https://docs.aegra.dev/llms.txt