This guide explains how to build and run each service locally — without Docker — and how to verify changes.
- Prerequisites
- Run everything with Docker (fast path)
- sandbox-service (Rust)
- llm-service (Python)
- llm-tui (Rust)
- Verifying your changes
- Common issues
| Tool | Version | Used by |
|---|---|---|
| Rust / Cargo | 1.88+ (edition 2024) | sandbox-service, llm-tui |
| Python | 3.12+ | llm-service |
| Docker + Compose | 20.10+ / v2+ | full stack |
| Ollama | any recent | local LLM runtime |
mluauses a vendored Lua build, andtree-sitter-luacompiles from source, so the first Rust build takes a while. No system Lua libraries are required.
# Build images and start the full stack
docker compose up --build
# Health check
curl -s http://localhost:8080/health
# Interactive TUI (in another terminal)
docker compose run --rm --no-deps -it llm-tui
# Stop
docker compose downSee the main README and configuration.md for details.
The Rust service depends on nothing external, so it can be built and run standalone.
cd sandbox-service
# Debug build
cargo build
# Release build (used in production images)
cargo build --release
# Run (listens on 0.0.0.0:6778)
cargo runOptional logging control:
RUST_LOG=debug cargo runSmoke test:
curl -s http://localhost:6778/health
# ok
curl -sS -X POST http://localhost:6778/pipeline \
-H "Content-Type: application/json" \
-d '{"code":"return 1 + 1","execute":true}'Requires a running Ollama and a running sandbox-service. Start those first.
# Ensure Ollama has the model
ollama pull qwen2.5-coder:7b
cd llm-service
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Point the service at local instances and start with auto-reload
OLLAMA_URL=http://localhost:11434 \
SANDBOX_SERVICE_URL=http://localhost:6778 \
uvicorn app.main:app --host 0.0.0.0 --port 8080 --reloadSmoke test:
curl -s http://localhost:8080/health
curl -sS -X POST http://localhost:8080/generate \
-H "Content-Type: application/json" \
-d '{"task":"Write a Lua function that doubles a number"}'| Script | Purpose |
|---|---|
app/scripts/run_model.py |
Standalone pipeline run against Ollama (plan + code for a hardcoded sample task). |
app/scripts/qdrant_delete.py |
Deletes the lua_patterns Qdrant collection (run against a local Qdrant on localhost:6333). |
Requires llm-service to be running.
cd llm-tui
# Point the TUI at a locally running llm-service
LLM_SERVICE_URL=http://localhost:8080 cargo runLogs are appended to llm-tui.log in the current working directory.
- Build checks:
cargo build(orcargo build --release) forsandbox-serviceandllm-tui;python -c "import app.main"(or runuvicorn) forllm-service. - Service health: both
/healthendpoints returnok. - End-to-end session: run the worked example against a locally started stack, including a sandbox rejection (e.g. ask for code using
os.executeand confirm the safety error is surfaced assandbox_feedback). - Sandbox edge cases:
- Syntax error: submit code with invalid syntax →
status: syntax_error. - Forbidden call:
os.execute('ls')→status: safety_error. - Timeout:
while true do endwithtimeout: 1→status: timeout. - Memory limit: allocate a large table →
memory_limit. - Context: submit
contextand referencewf.varsin code.
- Syntax error: submit code with invalid syntax →
| Symptom | Likely cause / fix |
|---|---|
/generate returns 400 "task is required for a new session" |
A task is required when creating a session; pass one. |
| Generation hangs or times out | Ollama model not pulled yet; run ollama pull qwen2.5-coder:7b. |
sandbox-service unreachable from llm-service |
Wrong SANDBOX_SERVICE_URL (use http://localhost:6778 locally). |
| RAG produces no context | Qdrant or the embeddings endpoint is unreachable — RAG silently falls back to no context. Verify QDRANT_URL/EMBEDDINGS_URL and that the collection exists. |
| LLM critic blocks all code | The critic prompt is strict; check CONFIRM_WORD or disable validation with "llm_validation": false per request. |
| Rust build fails on a fresh machine | Vendored Lua/tree-sitter compile errors are usually toolchain-related; ensure Rust 1.88+ and retry. |