Skip to content

Getting Started

Run the Kova engine against a local Qwen3.8-27B server and drive the pipeline from the embedded GUI or the REST API.

Prerequisites

  • Rust stable toolchain (workspace edition 2021).
  • A local llama.cpp server (or any OpenAI-compatible server) running Qwen3.8-27B, reachable at the URL in your config. The engine needs three endpoints on it:
  • POST /v1/chat/completions — chat turns (research loop, tool calls).
  • POST /completion with n_probs — raw token logits; this is the path that drives the logit phase-gate.
  • OpenAI-shaped tools / tool_calls in the chat response — used by the research tool loop.
  • Linux for the host-sandbox default (process-group isolation via setpgid through command-group). The youki OCI path is opt-in and needs a static youki binary (not yet vendored in the tree).

Configuration

The engine is config-driven — there are no --gui / --port / --headless flags; the server address comes from the config file. The layout the current Config (kova-core::config) honors, with defaults:

[api]
addr = "127.0.0.1:9090"     # REST + GUI listener
gui = true                  # serve the embedded GUI at /

[engine]
workdir = "."               # repository root the pipeline operates on
data_dir = "kovadb"         # where the sled state DB lives
research_dir = "research"   # plan / evidence artifacts
check_timeout_secs = 900
# dependencies_dir = "dependencies"   # optional vendored-dependency dir

[gate]
temperature = 0.0
min_confidence = 0.7

[models.research]
model = "/path/to/Qwen3.8-27B.gguf"   # model name / param path sent to the backend
url = "http://127.0.0.1:8080/v1"      # `base_url` is accepted as an alias
temperature = 0.2
max_tokens = 4096
timeout_secs = 600              # per-request HTTP timeout
# vram_gib = 0.0

[research]
model = "research"            # must name an entry under [models.*]
max_iterations = 10
max_tool_calls_per_iteration = 4
tool_result_chars = 16384
wall_timeout_secs = 600
http_timeout_secs = 30

Note: the repo-root kovarc.toml predates this layout (v2): its [engine].api_addr, [engine].gui, [engine].gate, and per-model kind / label / n_probs / optional keys are not modeled by the current Config, and because there is no deny_unknown_fields they are silently ignored on load — the corresponding defaults above apply. The keys it does drive are [engine].data_dir / research_dir / check_timeout_secs / dependencies_dir, the [models.*] entries, and [research].model.

Validation (kova-core::config::Config::load): research.model must be non-empty and must reference a defined model, and that model's url (or alias base_url) must be an http(s) address. Missing or invalid config is a hard error at startup (KovaError::Config); unknown keys elsewhere are ignored, not errors.

Run

cargo run -p kova-core -- --config kovarc.toml

The engine opens its state store under engine.data_dir (kovadb/ by default) and serves the API at api.addr. The GUI is embedded in the binary (rust-embed) and served at /.

Drive the pipeline

# Liveness
curl -s http://127.0.0.1:9090/health
# → {"service":"kova","status":"ok","version":"0.1.0"}

# Current phase + status
curl -s http://127.0.0.1:9090/pipeline/state

# Event log tail (most recent n; default 100, max 1000)
curl -s "http://127.0.0.1:9090/pipeline/events?n=50"

# Start a research run
curl -s -X POST http://127.0.0.1:9090/pipeline/research \
  -H 'content-type: application/json' \
  -d '{"task":"Add a /metrics endpoint"}'

# Advance the phase (only while status is ReadyToAdvance)
curl -s -X POST http://127.0.0.1:9090/pipeline/advance

Notes:

  • POST /pipeline/research rejects a second concurrent run while one is in flight.
  • POST /pipeline/advance is user-gated: it is rejected unless the current status is ReadyToAdvance (see the Pipeline Specification).
  • Research today runs a PlaceholderRunner — it returns a stub summary and no plan artifact. The real budget-guarded MCP tool loop is specified in plans/kova-research-phase-mcp-tool-layer.md.
  • Plan artifacts (once the real loop lands) are written only to research/plans/ with a validated kebab-case name — nothing else.

Verify

cargo check --workspace --all-targets --message-format=short
cargo test --workspace

Expected: 115 tests passing across the workspace (actor 2 · api 9 · core 33 lib + 1 bin · docs-lint 12 · gui 1 · mcp 7 · primitives 26 · router 8 · sandbox 16).