Skip to content

Latest commit

Β 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

OttoFlow: AI Workflows for Kubernetes

OttoFlow Logo

Release License Go Kubernetes

πŸš€ What is OttoFlow?

OttoFlow enables scalable and production-ready AI workflows on Kubernetes. You define a workflow as a Kubernetes CRD, and OttoFlow executes it as a DAG (directed acyclic graph) that mixes deterministic CEL, PromQL, K8s API queries, and LLM agents β€” with LLM calls constrained to the steps that actually need AI. Data collection, aggregation, and publication steps stay deterministic; the LLM is spent only on analysis, and it sees computed summaries rather than raw tool data that blow your context.

πŸ”₯ Why OttoFlow?

Kubernetes agentic applications generally follow a predictable pattern. They:

  1. Collect: query cluster and workload data.
  2. Analyze: process and synthesize that data, and
  3. Publish: execute an action, or publish data or an event.

Offloading this entire loop to high-level prompts or unconstrained agents with cluster access is an anti-pattern: it makes every run non-deterministic, widens the attack surface, and drives up token cost.

OttoFlow codifies the Collect β†’ Analyze β†’ Publish loop into a deterministic execution pattern, bringing reviewable engineering practices to the AI orchestration layer. OttoFlow is not a general-purpose agent framework β€” if you want free-form agents, use one of those instead.

✨ Key Features

  • βœ… Declarative Kubernetes-native workflows β€” define workflows as CRDs in YAML.
  • βœ… Fast DAG execution β€” explicit dependency resolution with parallel step batches.
  • βœ… Multi-provider LLM support β€” use OpenAI, Anthropic, etc. or local models with vLLM.
  • βœ… Kubernetes and CNCF integrations β€” query API resources, PromQL, Kagent using A2A, otel, and more.
  • βœ… Compiled CEL expressions β€” sandboxed execution with full K8s and Kyverno CEL library support
  • βœ… Multiple step types β€” ResourceQuery, AgentRef, MCPToolCall, and more (full list).
  • βœ… Context optimization β€” agent steps receive agregated computed summaries, never raw data dumps.
  • βœ… Retry & conditional execution β€” retry policies and matchConditions gating per step.
  • βœ… CLI with local mode β€” execute workflows locally against your kubecontext.
  • βœ… Extensive samples β€” ready-to-run workflows under samples/.

⚑ Quick Start - Your first AI workflow in under ~60 seconds

Install the CLI

brew install nirmata/tap/ottoflow

See installation guide for additional options.

Create a test cluster (optional)

The demo OttoFlow workflows used below are safe to execute on your clusters.

If you need a test cluster create one:

kind create cluster --name=ottoflow

The cluster-overview and pod-triage help identify issues. Seed a few deliberately-broken pods first:

kubectl apply -f https://raw.githubusercontent.com/nirmata/ottoflow/main/samples/fixtures/failing-pods.yaml

This creates a crash-looping (OOMKilled) pod, an ImagePullBackOff pod, and two healthy ones β€” real, differing failures for the workflows to prioritize.

Execute a CEL workflow

Start with a pure-CEL workflow β€” no LLM, no API key, nothing to install:

ottoflow run https://raw.githubusercontent.com/nirmata/ottoflow/refs/heads/main/samples/workflows/production/cluster-overview.yaml

This runs in-process against your current kubecontext, read-only β€” no controller, no CRDs, nothing installed in your cluster, nothing to uninstall.

For details on the data collection, analysis, and reporting view the workflow source.

Execute an AI workflow

AI workflows include steps that call LLMs.

Pick your LLM provider

pod-triage adds an LLM step. The sample's Agent defaults to Gemini β€” set an API key and run it by path, no cloning or --workflow-dir needed:

GEMINI_API_KEY=AIza... \
  ottoflow run -f https://raw.githubusercontent.com/nirmata/ottoflow/main/samples/workflows/production/pod-triage.yaml

Use https://aistudio.google.com/api-keys to get an API key.

Prefer OpenAI, Anthropic, or no cloud key at all? Override with --provider/--model and the matching environment variable β€” no editing the workflow required. (-n ottoflow is optional here: with -f the workflow loads under its own metadata.namespace, and -n is only a hint to disambiguate when several same-named workflows are loaded at once. Either way it never changes which namespace pod-triage scans β€” that's always default.)

# OpenAI -- OPENAI_API_KEY must be set; --model optional (defaults to gpt-4o)
OPENAI_API_KEY=sk-... \
  ottoflow run -f https://raw.githubusercontent.com/nirmata/ottoflow/main/samples/workflows/production/pod-triage.yaml -n ottoflow --provider openai
# Anthropic -- ANTHROPIC_API_KEY must be set; --model optional (defaults to a current Claude model)
ANTHROPIC_API_KEY=sk-ant-... \
  ottoflow run -f https://raw.githubusercontent.com/nirmata/ottoflow/main/samples/workflows/production/pod-triage.yaml -n ottoflow --provider anthropic
# Local -- no cloud key, no cluster data leaves your machine. --model is required
# here; there is no default local model.
LLAMACPP_HOST=http://127.0.0.1:11434/ \
  ottoflow run -f https://raw.githubusercontent.com/nirmata/ottoflow/main/samples/workflows/production/pod-triage.yaml -n ottoflow \
  --provider local --model gemma3:4b

Point LLAMACPP_HOST at any llama.cpp-compatible server β€” llama.cpp, ollama, vLLM, or LM Studio. The local run above produces the transcript shown below.

Agent steps need an LLM: set modelProvider on the Agent CRD to openai, anthropic, azure-openai, google/gemini, or local (any llama.cpp-compatible server), or override it per run with --provider/--model as shown above. API keys come from the process environment β€” OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, AZURE_OPENAI_API_KEY β€” not from Agent.spec.config. In-cluster, set them on the agent-executor pod via agentExecutor.env in the Helm chart; in local mode they come from your shell.

collectPods                    βœ… Succeeded          24ms
triagePods                     βœ… Succeeded          1.13s
publishTriage                  βœ… Succeeded          414Β΅s

Outputs:
  triageSummary:
  4 pods scanned, 2 flagged unhealthy. Verdict: The crashy pod is the highest
  priority due to its significantly higher restart count (4), indicating a
  persistent issue requiring immediate attention.

  **Next Action:** Investigate the crashy pod's underlying cause by checking
  system logs for crash reasons and potential resource constraints.

For details view the complete workflow source.

πŸ› οΈ Five workflows you'll actually use

All paths are under samples/workflows/production/.

Workflow What it does You get
cluster-overview.yaml Pure-CEL cluster snapshot β€” pod phases, per-namespace CPU/memory requests and limits, health verdict. No LLM, runs anywhere. Structured report, zero prerequisites.
pod-triage.yaml Collect β†’ Analyze β†’ Publish; CEL extracts per-pod failure signals (restarts, OOMKilled, ImagePullBackOff), the LLM picks the single highest-priority pod and the concrete next action. Prioritized verdict + next step.
resource-hygiene.yaml Detects 14 categories of unused or stale resources; LLM writes the cleanup report, Prometheus gauges track it. Prioritized markdown report + metrics.
cost-analyzer.yaml Right-sizing from resource specs plus metrics-server/Prometheus P95 usage, per-workload savings. Markdown report + estimated monthly $ savings.
workload-troubleshooter.yaml One failing pod: events + logs β†’ LLM root-cause. ⚠ in-cluster only (needs pod logs; not available in CLI local mode). Root cause + remediation.

There are 70+ more workflows in samples/ covering cost, security, and compliance automation.

☸️ Install in your cluster

helm install ottoflow oci://ghcr.io/nirmata/ottoflow \
  --version 0.1.0-rc1 --namespace ottoflow --create-namespace

kubectl apply -f samples/workflows/production/cluster-overview.yaml
ottoflow run cluster-overview -n ottoflow

The controller reconciles Workflows/WorkflowRuns and runs the leader-elected scheduler; agent steps execute via the agent-executor pod (set LLM keys via agentExecutor.env in the chart).

For an LLM-driven root cause of a single failing pod β€” events and logs in, cause and remediation out β€” see workload-troubleshooter.yaml. It's in-cluster only (it needs pod logs, unavailable in local --workflow-dir mode) and runs the agent on the agent-executor, so it uses the LLM you configured there rather than the --provider/--model flags (which apply to local runs only).

πŸ“š Documentation Β· Help Β· Contributing Β· License

Questions? Open a GitHub Issue β€” Discussions are disabled.

Contributions are welcome β€” see CONTRIBUTING.md for setup, style and the PR process, and GOVERNANCE.md for how decisions get made.


Built with ❀️ by the Nirmata team

Report Bug Β· Request Feature

About

AI Workflows For Kubernetes

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

12 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages