init commit

This commit is contained in:
2026-04-12 07:19:48 -03:00
commit 9dbf89da02
111 changed files with 14925 additions and 0 deletions

15
ctrl/Dockerfile.api Normal file
View File

@@ -0,0 +1,15 @@
FROM python:3.13-slim
WORKDIR /app
RUN pip install uv
COPY pyproject.toml ./
RUN uv sync --no-dev --no-install-project
COPY mcp_servers/ mcp_servers/
COPY agents/ agents/
COPY api/ api/
COPY irrop/ irrop/
CMD ["uv", "run", "uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]

19
ctrl/Dockerfile.ui Normal file
View File

@@ -0,0 +1,19 @@
FROM node:22-slim AS build
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /ui
COPY ui/framework/ framework/
COPY ui/app/ app/
ENV CI=true
WORKDIR /ui/framework
RUN pnpm install
WORKDIR /ui/app
RUN pnpm install && pnpm run build
FROM nginx:alpine
COPY --from=build /ui/app/dist /usr/share/nginx/html
COPY ctrl/nginx.conf /etc/nginx/conf.d/default.conf

54
ctrl/Tiltfile Normal file
View File

@@ -0,0 +1,54 @@
# UNT — Tilt development environment
# Usage: cd ctrl && tilt up
# Cluster: kind (name: unt)
# Entry point: http://localhost:8040
allow_k8s_contexts('kind-unt')
# Create namespace first to avoid race conditions
local('kubectl create namespace unt --dry-run=client -o yaml | kubectl apply -f -')
# Apply k8s manifests via kustomize (dev overlay)
k8s_yaml(kustomize('k8s/overlays/dev'))
# --- Images ---
# FastAPI + MCP servers + agents (Python backend)
docker_build(
'unt-api',
context='..',
dockerfile='Dockerfile.api',
ignore=['.git', 'def', 'ui', '.claude', 'tests', '.venv', 'node_modules'],
live_update=[
sync('../mcp_servers', '/app/mcp_servers'),
sync('../agents', '/app/agents'),
sync('../api', '/app/api'),
sync('../irrop', '/app/irrop'),
],
)
# Vue UI — context is project root so framework link resolves
docker_build(
'unt-ui',
context='..',
dockerfile='Dockerfile.ui',
live_update=[
sync('../ui/app/src', '/ui/app/src'),
sync('../ui/app/index.html', '/ui/app/index.html'),
sync('../ui/app/vite.config.ts', '/ui/app/vite.config.ts'),
sync('../ui/framework/src', '/ui/framework/src'),
],
)
# --- Resources ---
k8s_resource('postgres')
k8s_resource('langfuse', resource_deps=['postgres'], port_forwards=['3000:3000'])
k8s_resource('api', resource_deps=['langfuse'])
k8s_resource('ui', resource_deps=['api'], port_forwards=['8040:80'])
# Group infra resources
k8s_resource(
objects=['unt:namespace', 'unt-config:configmap'],
new_name='infra',
)

50
ctrl/docker-compose.yml Normal file
View File

@@ -0,0 +1,50 @@
services:
api:
build:
context: ..
dockerfile: ctrl/Dockerfile.api
ports:
- "8000:8000"
environment:
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID:-}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY:-}
- AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-us-east-1}
- USE_BEDROCK=${USE_BEDROCK:-false}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-}
- LANGFUSE_HOST=http://langfuse:3000
- DEFAULT_SCENARIO=${DEFAULT_SCENARIO:-weather_disruption_ord}
depends_on:
- langfuse
ui:
build:
context: ..
dockerfile: ctrl/Dockerfile.ui
ports:
- "8040:80"
depends_on:
- api
langfuse:
image: langfuse/langfuse:2
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgresql://langfuse:langfuse@db:5432/langfuse
- NEXTAUTH_SECRET=unt-dev-secret
- NEXTAUTH_URL=http://localhost:3000
- SALT=unt-dev-salt-not-for-production-use
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_USER=langfuse
- POSTGRES_PASSWORD=langfuse
- POSTGRES_DB=langfuse
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:

48
ctrl/k8s/base/api.yaml Normal file
View File

@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: unt
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: unt-api
command: ["uv", "run", "uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: unt-config
readinessProbe:
httpGet:
path: /scenarios
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: 512Mi
cpu: 500m
limits:
memory: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: api
namespace: unt
spec:
selector:
app: api
ports:
- port: 8000
targetPort: 8000

View File

@@ -0,0 +1,9 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: unt-config
namespace: unt
data:
DEFAULT_SCENARIO: "weather_disruption_ord"
USE_BEDROCK: "false"
LANGFUSE_HOST: "http://langfuse:3000"

View File

@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: unt
resources:
- namespace.yaml
- configmap.yaml
- postgres.yaml
- langfuse.yaml
- api.yaml
- ui.yaml

View File

@@ -0,0 +1,55 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: langfuse
namespace: unt
spec:
replicas: 1
selector:
matchLabels:
app: langfuse
template:
metadata:
labels:
app: langfuse
spec:
containers:
- name: langfuse
image: langfuse/langfuse:2
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
value: "postgresql://langfuse:langfuse@postgres:5432/langfuse"
- name: NEXTAUTH_SECRET
value: "unt-dev-secret"
- name: NEXTAUTH_URL
value: "http://localhost:3000"
- name: SALT
value: "unt-dev-salt-not-for-production-use"
readinessProbe:
httpGet:
path: /api/public/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 10
resources:
requests:
memory: 256Mi
cpu: 200m
limits:
memory: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: langfuse
namespace: unt
spec:
selector:
app: langfuse
ports:
- port: 3000
targetPort: 3000

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: unt

View File

@@ -0,0 +1,50 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
namespace: unt
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_USER
value: "langfuse"
- name: POSTGRES_PASSWORD
value: "langfuse"
- name: POSTGRES_DB
value: "langfuse"
readinessProbe:
exec:
command: ["pg_isready", "-U", "langfuse"]
initialDelaySeconds: 3
periodSeconds: 5
resources:
requests:
memory: 128Mi
cpu: 100m
limits:
memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
name: postgres
namespace: unt
spec:
selector:
app: postgres
ports:
- port: 5432
targetPort: 5432

44
ctrl/k8s/base/ui.yaml Normal file
View File

@@ -0,0 +1,44 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
namespace: unt
spec:
replicas: 1
selector:
matchLabels:
app: ui
template:
metadata:
labels:
app: ui
spec:
containers:
- name: ui
image: unt-ui
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 10
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: ui
namespace: unt
spec:
selector:
app: ui
ports:
- port: 80
targetPort: 80

16
ctrl/k8s/kind-config.yaml Normal file
View File

@@ -0,0 +1,16 @@
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: unt
nodes:
- role: control-plane
extraPortMappings:
# UI — entry point for the app
- containerPort: 30040
hostPort: 8040
listenAddress: "127.0.0.1"
protocol: TCP
# Langfuse observability
- containerPort: 30030
hostPort: 3000
listenAddress: "127.0.0.1"
protocol: TCP

View File

@@ -0,0 +1,30 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patches:
# UI service → NodePort on 30040 (mapped to host 8040 via Kind)
- target:
kind: Service
name: ui
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30040
# Langfuse service → NodePort on 30030 (mapped to host 3000 via Kind)
- target:
kind: Service
name: langfuse
patch: |
- op: replace
path: /spec/type
value: NodePort
- op: add
path: /spec/ports/0/nodePort
value: 30030

23
ctrl/nginx.conf Normal file
View File

@@ -0,0 +1,23 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /agents {
proxy_pass http://api:8000;
}
location /scenarios {
proxy_pass http://api:8000;
}
location /ws/ {
proxy_pass http://api:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

5
ctrl/tilt_config.json Normal file
View File

@@ -0,0 +1,5 @@
{
"kind_cluster_name": "unt",
"kind_config": "k8s/kind-config.yaml",
"default_registry": ""
}