Files
nvi/Makefile

106 lines
3.8 KiB
Makefile

.PHONY: kind tilt-up tilt-down seed seed-fetch seed-push recon evals test \
run-log run-logs \
compose-up compose-down compose-clean compose-seed compose-recon compose-evals \
docs-graphs
COMPOSE := docker compose -f ctrl/docker-compose.yml
KCTX := --context kind-nvi
KNS := -n nvi
# ── kind + Tilt (primary path) ─────────────────────────────
kind:
bash ctrl/kind-config.sh
tilt-up:
cd ctrl && tilt up $(KCTX)
tilt-down:
cd ctrl && tilt down $(KCTX)
seed-fetch:
bash ctrl/seed/download.sh
# Copy the downloaded SQLite into the api pod. The file is excluded from the
# docker build context (.dockerignore) to keep the image small, so we push
# it explicitly the first time.
seed-push:
@POD=$$(kubectl $(KCTX) $(KNS) get pod -l app=api -o jsonpath='{.items[0].metadata.name}'); \
echo "pushing financial.sqlite → $$POD"; \
kubectl $(KCTX) $(KNS) exec $$POD -- mkdir -p /app/seed/data; \
kubectl $(KCTX) $(KNS) cp ctrl/seed/data/financial.sqlite $$POD:/app/seed/data/financial.sqlite
seed: seed-fetch seed-push
kubectl $(KCTX) $(KNS) exec deploy/api -- uv run python -m seed.load_bird
# Rebuild api/datasets/<name>/{extracted_schema,recon}.json from the YAML +
# live warehouse introspection. Runs inside the api pod (needs Postgres
# access), then copies the artefacts back to the host so they appear next
# to the source YAMLs.
recon:
@POD=$$(kubectl $(KCTX) $(KNS) get pod -l app=api -o jsonpath='{.items[0].metadata.name}'); \
kubectl $(KCTX) $(KNS) exec $$POD -- uv run python -m api.recon.build; \
for ds in $$(ls api/datasets); do \
[ -d "api/datasets/$$ds" ] || continue; \
case "$$ds" in __*|.*) continue ;; esac; \
for f in extracted_schema.json recon.json; do \
kubectl $(KCTX) $(KNS) cp $$POD:/app/api/datasets/$$ds/$$f api/datasets/$$ds/$$f 2>/dev/null \
&& echo " → api/datasets/$$ds/$$f" || true; \
done; \
done
evals:
kubectl $(KCTX) $(KNS) exec deploy/api -- uv run python -m api.evals.run_evals
# Pull a run's JSONL transcript from the api pod to the host. The api writes
# every published event into /app/.data/logs/<RUN>.jsonl inside the pod;
# this target copies it next to .data/logs/ on the host so it's easy to
# share / grep / paste a path to.
# Usage: make run-log RUN=<run_id>
run-log:
@[ -n "$(RUN)" ] || { echo "usage: make run-log RUN=<run_id>" >&2; exit 1; }
@mkdir -p .data/logs
@POD=$$(kubectl $(KCTX) $(KNS) get pod -l app=api -o jsonpath='{.items[0].metadata.name}'); \
kubectl $(KCTX) $(KNS) cp $$POD:/app/.data/logs/$(RUN).jsonl .data/logs/$(RUN).jsonl \
&& echo "→ .data/logs/$(RUN).jsonl"
# List the runs the api currently has log files for (most recent first).
run-logs:
@POD=$$(kubectl $(KCTX) $(KNS) get pod -l app=api -o jsonpath='{.items[0].metadata.name}'); \
kubectl $(KCTX) $(KNS) exec $$POD -- sh -c 'ls -1t /app/.data/logs 2>/dev/null || echo "(no logs yet)"'
# Unit tests run on the host venv (no postgres/llm calls needed).
# Ensures dev extras are installed first; uv is idempotent on no-ops.
test:
uv sync --extra dev
uv run pytest -q
# ── docker-compose (alternative path) ──────────────────────
compose-up:
$(COMPOSE) up -d --build
compose-down:
$(COMPOSE) down
compose-clean:
$(COMPOSE) down -v
compose-seed: seed-fetch
$(COMPOSE) exec api uv run python -m seed.load_bird
compose-recon:
$(COMPOSE) exec api uv run python -m api.recon.build
compose-evals:
$(COMPOSE) exec api uv run python -m api.evals.run_evals
# ── docs ───────────────────────────────────────────────────
docs-graphs:
@for f in docs/graphs/*.dot; do \
out=$${f%.dot}.svg; \
echo " graphviz $$f → $$out"; \
dot -Tsvg $$f -o $$out; \
done