Local development setup
Run Omnia on a local cluster so you can change the operator or dashboard and see the result.
Prerequisites
Section titled “Prerequisites”- Go 1.27 or later (download)
- Docker (install)
- kubectl (install)
- kind (install)
- Helm (install)
- Tilt (install), recommended
- Node.js 20 or later (download), for dashboard development
Quick start with Tilt (recommended)
Section titled “Quick start with Tilt (recommended)”1. Create a local cluster
Section titled “1. Create a local cluster”kind create cluster --name omnia-devThe Tiltfile refuses any context except kind-omnia-dev, kind-kind, docker-desktop, minikube and orbstack.
2. Start Tilt
Section titled “2. Start Tilt”# Core features onlytilt up
# With enterprise featuresENABLE_ENTERPRISE=true tilt upTilt builds the operator, facade, runtime and dashboard images, installs the CRDs with make install, renders charts/omnia with charts/omnia/values-dev.yaml, and sets up port forwards.
Set these environment variables before tilt up to add components.
| Variable | Default | Adds |
|---|---|---|
ENABLE_ENTERPRISE | false | The arena-controller, promptkit-lsp and policy-broker, with Enterprise in dev mode (no licence) |
ENABLE_ARENA_BUILDER | false | The Arena builder module in the omnia-demo namespace, on a local build of Dockerfile.promptarena-sandbox. Needs ENABLE_ENTERPRISE and an existing Provider named by ARENA_BUILDER_PROVIDER (default arena-builder-haiku) |
ENABLE_DEMO | false | The demo workspace, skills, and its managed session-api and memory-api. The Ollama-backed agents also need ENABLE_OLLAMA |
ENABLE_OLLAMA | false | Ollama model servers and the four demos that use them (11Gi of memory requests). Needs ENABLE_DEMO |
ENABLE_OBSERVABILITY | false | Prometheus, Grafana, Loki, Tempo and Alloy |
ENABLE_FULL_STACK | false | Istio and the Gateway API |
ENABLE_AUDIO_DEMO, ENABLE_VOICE_DEMO | false | The Gemini audio and Gemini Live voice agents. Each needs a gemini-credentials Secret in omnia-demo |
ENABLE_MEMORY_DEMO | false | A seeded memory galaxy across all tiers. Needs the embedding Secret that make dev-embedding-secret creates |
ENABLE_LANGCHAIN | false | The LangChain runtime demo agents |
Redis and the NFS-backed workspace storage are always on under Tilt.
The demo toggles set *.enabled values of the omnia-dev-content chart, whose README lists what each deploys. The public demos (mortgage underwriting, claims triage, PII chat, the Larkmere portal, SharePoint/RAG) come from the charts/omnia-demo chart in AltairaLabs/omnia-demo.
3. Access the services
Section titled “3. Access the services”| Service | URL | Present when |
|---|---|---|
| Dashboard | http://localhost:3000 | Always |
| Operator API | http://localhost:8082 | Always |
| pgweb | http://localhost:8081 | Always |
| VS Code Server | http://localhost:8888 | Always |
| Grafana | http://localhost:3001 | ENABLE_OBSERVABILITY |
4. Develop with hot reload
Section titled “4. Develop with hot reload”Edit files in dashboard/src/. The change syncs into the pod and Next.js reloads it, with no image rebuild. Set DASHBOARD_PROD=1 to build the production dashboard image instead, which has no hot reload and enables the Monaco LSP editor.
Tilt rebuilds the operator image when Go source changes.
5. View logs and stop
Section titled “5. View logs and stop”Press s in the Tilt UI to stream logs, or open http://localhost:10350. Run tilt down to stop.
Manual setup (without Tilt)
Section titled “Manual setup (without Tilt)”Create a local cluster
Section titled “Create a local cluster”kind create cluster --name omnia-devBuild and load images
Section titled “Build and load images”make docker-build IMG=omnia-operator:devdocker build -t omnia-dashboard:dev ./dashboard
kind load docker-image omnia-operator:dev --name omnia-devkind load docker-image omnia-dashboard:dev --name omnia-devInstall with Helm
Section titled “Install with Helm”Install the CRDs first, as their own release. The app chart fails to render without them, and helm upgrade of the app chart never updates them.
helm install omnia-crds charts/omnia-crds -n omnia-system --create-namespaceThis installs every kind, including the Enterprise ones. Pass --set enterprise.enabled=false to leave them out.
helm install omnia charts/omnia -n omnia-system \ --set image.repository=omnia-operator \ --set image.tag=dev \ --set image.pullPolicy=Never \ --set dashboard.enabled=true \ --set dashboard.image.repository=omnia-dashboard \ --set dashboard.image.tag=dev \ --set dashboard.image.pullPolicy=NeverReach the dashboard with a port-forward:
kubectl port-forward -n omnia-system deployment/omnia-dashboard 3000:3000Using Ollama for local LLM development
Section titled “Using Ollama for local LLM development”Ollama gives agents a local model with no API costs. Start Tilt with it:
make dev-ollamaThis runs ENABLE_DEMO=true ENABLE_OLLAMA=true tilt up. It deploys two Ollama instances into omnia-demo: ollama-chat (llama3.2:3b) and ollama-vision (llava:7b). Each pulls its model on first start, which takes several minutes.
| Instance | Memory request | Volume |
|---|---|---|
ollama-chat | 4Gi | 8Gi |
ollama-vision | 7Gi | 12Gi |
In the cluster the servers answer at http://ollama-chat.omnia-demo:11434 and http://ollama-vision.omnia-demo:11434. On the host, localhost:11434 is chat and localhost:11435 is vision.
The vision-demo agent in the demo workspace uses the vision instance and needs no API key. Open it from the dashboard to chat or send an image.
Deploy Redis (optional)
Section titled “Deploy Redis (optional)”Tilt runs Redis for you. For a manual install, the chart runs none, so deploy one and point the chart at it:
kubectl create namespace redishelm repo add bitnami https://charts.bitnami.com/bitnamihelm install redis bitnami/redis -n redis \ --set auth.enabled=false \ --set architecture=standalone
helm upgrade omnia charts/omnia -n omnia-system --reuse-values \ --set redis.default.host=redis-master.redis.svc.cluster.localEncrypt without a KMS (development only)
Section titled “Encrypt without a KMS (development only)”Browser sessions (a browserSession Connection) and an encrypting SessionPrivacyPolicy need a KMS key. On a laptop or in a test cluster, the local provider stands in for one: a 32-byte AES key in a Kubernetes Secret.
Create the Secret in the namespace of the object that encrypts:
hack/dev-kms-secret.sh <kube-context> agents dev-kmsThen name it:
encryption: kmsProvider: local keyID: dev secretRef: name: dev-kmsThe script leaves an existing Secret alone, because a new key would make everything sealed under the old one unreadable.
Deploy test resources
Section titled “Deploy test resources”Apply the sample manifests:
kubectl apply -k config/samples/The samples include Enterprise kinds, so install the Enterprise CRDs first.
Using demo mode for testing
Section titled “Using demo mode for testing”To exercise an agent without LLM API costs, set the facade handler to demo or echo:
apiVersion: omnia.altairalabs.ai/v1alpha1kind: AgentRuntimemetadata: name: test-agentspec: promptPackRef: name: test-prompts facades: - type: websocket handler: demo # echo returns each input message unchanged context: type: memoryThe demo handler streams canned responses and sends simulated tool_call and tool_result messages. Neither handler needs an API key.
Verify
Section titled “Verify”Check that the operator and dashboard pods are running:
kubectl get pods -n omnia-systemThen open the dashboard at http://localhost:3000.
Troubleshooting
Section titled “Troubleshooting”Tilt not detecting file changes
Section titled “Tilt not detecting file changes”Check the Tilt UI for sync status.
Dashboard not hot-reloading
Section titled “Dashboard not hot-reloading”The dashboard runs npm run dev, which uses Next.js Fast Refresh. Check the browser console for errors. A DASHBOARD_PROD=1 build has no hot reload.
Operator not starting
Section titled “Operator not starting”kubectl logs -n omnia-system deployment/omnia-controller-managerImage not found / ImagePullBackOff
Section titled “Image not found / ImagePullBackOff”Set image.pullPolicy=Never and load the image into kind:
kind load docker-image <image>:<tag> --name omnia-devWebSocket connection refused
Section titled “WebSocket connection refused”Check that the agent Service has endpoints. The Service is named after the AgentRuntime:
kubectl get endpoints <agent-name> -n <agent-namespace>