Developers

Install. Point. Harvest.

Kultivait.ai is a local-first routing proxy: an OpenAI- and Anthropic-compatible endpoint on localhost:4114 that weighs every prompt with a local embedding model and routes it to the cheapest model that can carry it. This page is the whole setup.

Install

One command

curl -fsSL https://kultivait.ai/install.sh | sh

Or by hand:

uv tool install --from git+https://github.com/Standard-Pentest/kultivaite kultivait

Source, issues, and roadmap live on GitHub.

What you need

ollama

With at least one general model pulled — kultivait init adapts to whatever you have. An 8–14B model on a 16–24 GB machine is a sweet spot.

An embedding model

ollama pull nomic-embed-text (274 MB). The installer handles this. It's the whole routing brain — classification runs locally in milliseconds.

Optional: cloud CLIs

claude or gemini CLIs on PATH become cloud tiers. Without them, local-only mode still recognizes cloud-worthy prompts and packages escalation briefs.

Quickstart

Three commands to routing

kultivait init      # surveys YOUR machine: models, CLIs, sizes — writes config
kultivait serve     # proxy on http://localhost:4114
kultivait harvest   # watch the savings grow

init explains its decisions: your smallest capable model becomes the simple tier, your largest becomes the reasoning tier, and cloud CLIs become cloud tiers if present. Everything lands in ~/.kultivait/config.toml — edit freely, re-run init anytime.

Then point any OpenAI-compatible client at http://localhost:4114/v1 with model: auto. Anthropic-API clients work too:

ANTHROPIC_BASE_URL=http://localhost:4114 <your-tool>
Reference

Commands

CommandWhat it does
kultivait serveRun the routing proxy on :4114
kultivait route "why does this test deadlock?"Dry-run a classification — see the tier and margin without sending anything
kultivait prune --from explore --to plan transcript.txtPhase-gate brief: distill a transcript into FINDINGS / DECISIONS / CONSTRAINTS / OPEN QUESTIONS using a local model
kultivait escalations [--brief]List cloud-worthy prompts that were served locally; --brief distills the latest into a paste-ready handoff
kultivait harvest [--json]Cumulative savings vs. frontier baseline pricing ($3/M input, $15/M output), plus escalation and truncation counts

Endpoints

EndpointNotes
POST /v1/chat/completionsOpenAI-compatible; model: auto; streaming (SSE); client-side tool calls pass through
POST /v1/messagesAnthropic-compatible; streaming and non-streaming; content blocks and system param handled; tool support not yet implemented
POST /gateThe prune operation as an API: distill a transcript at a phase boundary
GET /harvestThe savings ledger as JSON

Every response carries kultivait metadata: the tier requested, the tier served, the classification margin, and an honest fallback_reason when a tool-bearing request was kept local (cloud CLIs run their own agent loops and can't return client-side tool calls).

Agent integration

Run a full agentic loop through the router

Tool calls pass through on the OpenAI endpoint, so an agent's whole read / bash / edit / write loop runs through the proxy — every turn routed and tallied. Example: the Pi coding agent, via ~/.pi/agent/models.json:

"kultivait": {
  "api": "openai-completions",
  "apiKey": "kultivait",
  "baseUrl": "http://127.0.0.1:4114/v1",
  "models": [{ "contextWindow": 131072, "id": "auto", "input": ["text"] }]
}

Then: pi --provider kultivait --model auto.

When a cloud-worthy prompt arrives mid-loop, it's served by your best local tool-capable tier and archived as an escalation — instantly, off the request path. If the local answer wasn't enough, kultivait escalations --brief hands you a distilled TASK / CONTEXT / PROGRESS / NEEDED brief to paste into a frontier model. One paste, not a re-explanation.

Evals

Every default was chosen by an experiment

Routing: before anything shipped, the embedding-centroid approach was validated on held-out prompts — 24/24 classified correctly with zero dangerous misroutes (cloud-worthy work sent to a weaker model). Thin-margin classifications escalate one tier up by design.

Distillation: the default distiller model was chosen by a planted-fact recall eval (5 models × 2 prompts × 3 transcripts). Recall beats speed at a phase gate: a dropped constraint is catastrophic, a slow gate is a coffee sip.

ModelMean recallTokens keptAvg time
gemma4:latest (default)100%61%29s
qwen3:14b96.3%44%15s
phi4:14b92.6%65%18s
qwen2.5:14b90.2%49%16s
llama3.1:8b86.5%44%8s

Prefer the faster, tighter-compressing runner-up? KULTIVAIT_DISTILL_MODEL=qwen3:14b. Full transcripts are always composted to ~/.kultivait/compost/ before distillation — lossy compression deserves an escape hatch.

Roadmap

Where this is going

Learned centroids

Routing seeds tuned from your own ledger history — every noticed misroute is a labeled example.

Ambient gates

Pruning at phase boundaries via agent-framework hooks (e.g. Claude Code hooks), no manual invocation.

Anthropic-endpoint tools

Tool-use support on /v1/messages to match the OpenAI endpoint.

Watt-hour estimation

Energy accounting in the ledger, so the sustainability claim gets a number too.

Teams

Kultivait.ai for Teams — interested?

The proxy is free and stays free. We're gauging demand for a team layer on top: ledgers rolled up across your engineers, org-wide routing policy, per-team cost visibility, and routing tuned from your own usage history. Nothing built yet — your interest decides whether it gets built.

Thanks — you're on the Teams waitlist. We'll reach out as it takes shape. 🌱
Get started

Two minutes from routing.

curl -fsSL https://kultivait.ai/install.sh | sh

Questions, bugs, ideas? Email sales@standardpentest.com — early-access feedback shapes the roadmap.