Watch AI agents debug, review and optimize your code β live, with the hood open.
Built for the CMRIT FDP "Agentic AI: Developing Intelligent Agents with Modern AI Frameworks."
Paste code or ask a question β a Router classifies it β RAG retrieves from a local knowledge base β a deterministic Tool runs (Python sandbox, YAML/K8s validator, Java checker) β Reviewer, Optimizer and Synthesizer agents reason over the result β every step visible in the UI.
Works with or without a cloud key. The LLM uses a fallback chain: π’ Groq β π‘ local Ollama β π΄ Tools-Only Mode. As long as one backend is reachable, the app answers β and it never crashes when none are.
No key on the command line required β paste a Groq key right in the sidebar (it stays in your session, never logged), or supply it via
.env/ a Kubernetes Secret.
- π Bring your own knowledge β upload a
.txt/.mdfile or paste text in the sidebar and the agents cite your standards/notes alongside the built-in knowledge base. Per session, in-memory, nothing written to disk. (details) - π API key from the UI β connect Groq by pasting the key in the app, not just on the command line. The
.env/ Secret path still takes precedence, so Docker and k8s are unchanged. - π³ Faster container start β the ONNX embedding model and Chroma index are now baked into the image as the runtime user, so containers no longer re-download the 79 MB model on every start. Fully offline-ready.
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Streamlit UI β
β Router β RAG β Tool β Reviewer β Optimizer β
β β Synthesizer β
ββββββββ¬ββββββββββββββββββββββββββββ¬ββββββββββββ
β β
ββββββββββββΌβββββββββββ ββββββββββββΌβββββββββββ
β RAG + Tools β β LLM Fallback Chain β
β ChromaDB (ONNX βββββββ€ Groq β Ollama β β
β MiniLM embeddings) βctx β Tools-Only β
β python/yaml/java β β llama-3.3-70b / β
β deterministic tools β β local mistral β
ββββββββββββ¬βββββββββββ ββββββββββββ¬βββββββββββ
β β (cloud, optional)
ββββββββΌββββββββ ββββββββΌββββββββ
β knowledge/ β β Groq API β
β *.md index β ββββββββββββββββ
ββββββββββββββββ
Git push βββΊ GitHub repo βββΊ ArgoCD (auto-sync) βββΊ Kubernetes
β² β
βββ self-heal ββββββββ
docker build βββΊ Docker Hub (appars/codeforge-agents)
The agentic part: each request flows through a pipeline of specialised agents. The Reviewer judges correctness against the deterministic tool result (it never guesses whether code ran), the Optimizer proposes safe improvements, and the Synthesizer merges everything β tool output, retrieved knowledge, both agents' notes β into one streamed answer. The full trace is expandable in the UI.
git clone https://github.com/appars/codeforge-agents
cd codeforge-agents
python3.11 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
# Build the knowledge index ONCE (no API key needed β embeddings are local).
# Commit the resulting chroma_db/ so cloud deploys start instantly.
python -m rag.ingest
streamlit run app.py
# β http://localhost:8501Click a Demo Scenario card to watch the full pipeline run on a planted bug.
pip install pytest
pytest -qThe app tries backends in order on every request, so a rate limit or a missing key degrades gracefully instead of failing:
| Mode | Indicator | When it runs | Features |
|---|---|---|---|
| Groq | π’ | GROQ_API_KEY set and under quota |
Full pipeline on llama-3.3-70b-versatile (fast) |
| Ollama | π‘ | Groq unavailable, local Ollama up | Full pipeline on a local model (offline, no key) |
| Tools-Only | π΄ | No LLM reachable | Sandbox + YAML/Java validation + RAG, no agents |
Get a free Groq key at https://console.groq.com/keys. Resolution order:
.envfile βcp .env.example .env, setGROQ_API_KEY=gsk_...- Environment variable β
export GROQ_API_KEY=gsk_... - Streamlit Cloud β Settings β Secrets (see below)
- App sidebar β paste the key into the π Connect an LLM field β stored in that browser session only, never logged or saved (handy when an attendee brings their own key)
- Nothing β π‘ Ollama if running, else π΄ Tools-Only
A key from sources 1β3 takes precedence, so the sidebar field only appears when no key is configured.
For the best local experience, install Ollama and pull a coder model:
ollama pull qwen2.5-coder # strong at debugging; set OLLAMA_MODEL=qwen2.5-coder
ollama serveSwitch the chain order any time with LLM_PROVIDER (auto | groq | ollama) in .env.
Beyond the built-in knowledge/*.md base, anyone can add their own material at runtime from the sidebar β a team style guide, a grading rubric, lab guidelines β and watch the agents cite it.
- Upload a
.txtor.mdfile (or several), or paste text directly β no file or markdown needed. - It is chunked and embedded with the same model as the baked index, so retrieval ranks your chunks against the built-in ones by relevance. Hits are badged π your upload vs π base in the RAG trace.
- Stored in-memory, per browser session (
chromadb.EphemeralClient): isolated between users, written to no disk, and gone when the tab closes. Nothing leaks across sessions or, in multi-replica Kubernetes, across pods. - Safeguards: tolerant decoding (Word/Windows files), 1 MB per file, ~200 chunks per session, content-hash dedup, and a Clear my knowledge button.
Plain text is chunked by paragraph; markdown with
##headings is chunked by section. The built-in knowledge base is untouched β uploads live only in your session.
# Build (the image bakes the knowledge index AND the ONNX model at build
# time, as the non-root runtime user β no key needed, no download at start)
docker build -t appars/codeforge-agents:latest .
# Run (Tools-Only Mode β no key; or paste a Groq key in the sidebar)
docker run -p 8501:8501 appars/codeforge-agents:latest
# Run (Groq Mode) β prefer --env-file over -e: a key passed with -e is
# visible in shell history and in `docker inspect`
docker run -p 8501:8501 --env-file .env appars/codeforge-agents:latest
# Push to Docker Hub
docker login
docker push appars/codeforge-agents:latestImage highlights: python:3.11-slim, non-root user (UID 10001), layer-cached deps, ONNX embeddings (no PyTorch), built-in HEALTHCHECK on Streamlit's /_stcore/health. The index and embedding model are baked as UID 10001, so the container reads them from the same home it runs as β no 79 MB download on startup, works on an airgapped network.
Streamlit Cloud runs on a small (~1 GB) container and does not use the Dockerfile, so it cannot build the index at boot without running out of memory. The fix is to commit a pre-built index:
python -m rag.ingest # builds chroma_db/ with the real ONNX model
git add chroma_db .gitignore
git commit -m "Commit pre-built knowledge index for cloud boot"
git pushThen on share.streamlit.io:
- New app β point at
appars/codeforge-agents, branchmain,app.py. - Settings β Secrets β add (TOML format):
GROQ_API_KEY = "gsk_your_key_here"
- Deploy. The app boots instantly (index already present) and answers via Groq.
Ollama isn't reachable from Streamlit Cloud, so the chain there is effectively Groq β Tools-Only. Keep
GROQ_API_KEYvalid.
- Install Rancher Desktop β enable Kubernetes.
- Verify:
kubectl get nodesshows the nodeReady. - NodePort services are reachable at
localhost:<nodePort>.
# Create the Groq secret FIRST (never put the key in a YAML file).
# Skip this to run in Tools-Only / Ollama mode.
kubectl create secret generic codeforge-secrets \
--from-literal=GROQ_API_KEY='gsk_xxx'
kubectl apply -f k8s/
kubectl get pods -l app=codeforge-agents # 2 replicas Running
# Access (NodePort)
open http://localhost:30851
# or: kubectl port-forward svc/codeforge-agents 8501:8501Manifests follow the project's own knowledge/team_standards.md rules: team label, resource requests/limits, pinned image tag, two replicas, secret injected from the cluster (never inline), non-root securityContext, readiness + liveness probes on /_stcore/health.
# Install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# UI access
kubectl port-forward svc/argocd-server -n argocd 8080:443
# initial admin password:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
# Register the app
kubectl apply -f argocd/application.yamlArgoCD now watches github.com/appars/codeforge-agents (path k8s/, branch main) with auto-sync + self-heal + prune.
Live demo moment π¬: edit k8s/deployment.yaml in GitHub (replicas: 2 β 3), commit, and watch ArgoCD detect, sync, and roll out β no kubectl. Then kubectl scale deploy codeforge-agents --replicas=1 and watch self-heal revert it. That's GitOps.
curl -fsS http://localhost:8501/_stcore/health # β "ok"Used by the Docker HEALTHCHECK and both Kubernetes probes.
| Symptom | Fix |
|---|---|
Streamlit Cloud connection refused at boot |
Commit a pre-built index: python -m rag.ingest then push chroma_db/ |
| π΄ Tools-Only despite a key | Check GROQ_API_KEY (env / .env / Secrets); on cloud it must be TOML in Secrets |
| π‘ Ollama mode locally | Expected when Groq is rate-limited (429) β the chain fell back; or start ollama serve |
ImagePullBackOff |
Image not pushed / wrong name β docker push appars/codeforge-agents:latest |
Pod OOMKilled |
Raise the memory limit in k8s/deployment.yaml (default 1Gi) |
| Probes failing | Check kubectl logs; Streamlit needs ~10β20 s to boot |
ArgoCD Unknown/ComparisonError |
Repo URL/branch/path wrong, or repo is private (add repo credentials in ArgoCD) |
| NodePort unreachable | kubectl port-forward svc/codeforge-agents 8501:8501 |
| First answer slow | Ollama loads the model into RAM on first call; later calls are fast |
| Container re-downloads 79 MB at start | Old image baked the model as root but ran as forge. Rebuild with the current Dockerfile (bakes as UID 10001). |
![]() |
![]() |
(placeholders β add after first run)
codeforge-agents/
βββ app.py # Streamlit UI (pipeline, sidebar, modes)
βββ core/
β βββ config.py # Central config, secret resolution
β βββ llm.py # LLM fallback chain (Groq β Ollama β none)
β βββ router.py # LLM + keyword intent/language classifier
β βββ memory.py # Conversation memory window
β βββ scenarios.py # Demo scenario cards
β βββ ui.py # Design system (the "forge" theme)
βββ agents/
β βββ base.py # Shared agent contract
β βββ reviewer.py # Correctness / risk review
β βββ optimizer.py # Safe improvement suggestions
β βββ synthesizer.py # Streams the final answer
βββ tools/
β βββ python_runner.py # Sandboxed subprocess execution
β βββ yaml_validator.py # YAML + Kubernetes structure checks
β βββ java_checker.py # Java heuristics
β βββ extract.py # Fenced code-block extraction
βββ rag/
β βββ embedder.py # ONNX MiniLM embeddings (no torch)
β βββ chunking.py # Markdown (per-section) + plain-text chunking
β βββ ingest.py # Build the ChromaDB index
β βββ retrieve.py # Retrieval + relevance threshold + session-KB merge
β βββ user_kb.py # Session-scoped "bring your own knowledge" store
βββ knowledge/ # *.md knowledge base (debug/optimize/standards)
βββ chroma_db/ # Pre-built index (committed for cloud boot)
βββ tests/ # Unit + fallback tests
βββ k8s/ # deployment + service (NodePort)
βββ argocd/application.yaml # GitOps app (auto-sync, self-heal, prune)
βββ Dockerfile # python:3.11-slim, non-root, healthcheck
βββ requirements.txt
βββ .env.example
MIT β built for teaching. Reuse freely in your FDP sessions.

