skyflo

Skyflo Engine

The Engine is Skyflo’s backend orchestration layer for DevOps and SRE teams. It connects the Command Center and the MCP server, turning natural language into typed, auditable Kubernetes and CI/CD operations with an approval gate for every mutating tool call.

See docs/architecture.md for full system context.

Architecture

The Engine follows a layered structure under src/api:

Execution Model (LangGraph)

The workflow is a compact graph compiled with an optional Postgres checkpointer:

Checkpointer:

Event Streaming (SSE + Redis)

All workflow events stream over SSE from /api/v1/agent/chat and /api/v1/agent/approvals/{call_id}. Internally, the Engine uses Redis pub/sub channels keyed by a unique run id. Event types include (non-exhaustive):

Features

Installation

Prerequisites

Setup

1) Create .env from the example and set required variables.

# From engine/
cp .env.example .env

Minimum to set for local dev:

2) Install dependencies and the package in editable mode.

python -m venv .venv
source .venv/bin/activate
uv pip install -e "."

3) Apply database migrations (Tortoise + Aerich).

aerich upgrade

To create new migrations during development:

aerich migrate
aerich upgrade

Optional: Start Local PostgreSQL + Redis

# From project root
docker compose -f deployment/local.docker-compose.yaml up -d

Run the Engine

# Using uv (recommended, respects uv.lock for reproducible builds)
uv run uvicorn src.api.asgi:app --host 0.0.0.0 --port 8080 --reload

Service will be available at http://localhost:8080.

Development Commands

Note: Development commands require Hatch. Install via pip install hatch or pipx install hatch.

Command Description
uv run uvicorn src.api.asgi:app --host 0.0.0.0 --port 8080 --reload Start development server with hot reload
hatch run lint Run Ruff linter to check for code issues
hatch run type-check Run mypy for type checking
hatch run format Format code with Ruff
hatch run test Run tests with pytest
hatch run test-cov Run tests with coverage report

API

Base path: /api/v1

SSE Chat Example

curl -N -H "Content-Type: application/json" \
  -X POST \
  -d '{"messages":[{"role":"user","content":"List pods in default"}]}' \
  http://localhost:8080/api/v1/agent/chat

Approvals Example

curl -N -H "Content-Type: application/json" \
  -X POST \
  -d '{"approve":true, "reason":"safe", "conversation_id":"<conversation-uuid>"}' \
  http://localhost:8080/api/v1/agent/approvals/<call_id>

Configuration

Defined in src/api/config/settings.py (Pydantic Settings, .env loaded). Key variables:

Component Structure

engine/
├── src/
│   └── api/
│       ├── agent/          # LangGraph workflow (graph, model node, state, prompts, stop)
│       ├── config/         # Settings, DB, rate limiting
│       ├── endpoints/      # FastAPI routers (agent, auth, conversations, team, integrations, health)
│       ├── integrations/   # Provider-specific helpers (Jenkins)
│       ├── middleware/     # CORS, logging
│       ├── models/         # Tortoise ORM models (User, Conversation, Message, Integration, RefreshToken)
│       ├── schemas/        # Pydantic schemas (team)
│       ├── services/       # MCP client, tool executor, approvals, limiter, persistence, titles, checkpointer, stop, tools cache
│       └── utils/          # Helpers, sanitization, time
├── migrations/              # Aerich migrations
└── pyproject.toml          # Project dependencies and tooling

Tech Stack

Component Technology
Web Framework FastAPI + Uvicorn
ORM Tortoise ORM
Migrations Aerich
Authentication fastapi-users (+ tortoise)
Streaming SSE + Redis (pub/sub)
Rate Limiting fastapi-limiter + Redis
AI Agent LangGraph
LLM Integration LiteLLM
MCP Communication FastMCP
Database PostgreSQL

Community