v2026.2.1-beta.1 drops in — limited early-access spots. Secure yours →
v2026.2.1-beta.1 — beta dropping soon

Stop vibing with AI. Engineer it.

tuvl compiles declarative YAML into auditable, local-first FastAPI endpoints. Signal-driven routing. Streaming observability. Zero black boxes.

tuvl തൂവൽ · /ˈtuːvəl/ · feather

Three steps. One production API.

# datasources/postgres.yaml
kind: DataSource
metadata:
  name: main
spec:
  type: postgresql
  connection:
    host:     ${POSTGRES_HOST}
    port:     ${POSTGRES_PORT:5432}
    database: ${POSTGRES_DB}
    username: ${POSTGRES_USER}
    password: ${POSTGRES_PASSWORD}
# models/candidate.yaml
kind: ModelDefinition
metadata:
  name: Candidate
spec:
  table: candidates
  fields:
    - name:    full_name
      type:    str
    - name:    email
      type:    str
      unique:  true
    - name:    score
      type:    int
      default: 0

# → PostgreSQL table  ·  Pydantic schema  ·  CRUD REST routes
# workflows/screen.yaml
kind: Workflow
metadata:
  name: screen
spec:
  steps:
    - id: save
      kind: model-op
      op:   add
      model: Candidate
    - id: score
      kind: agent
      agent:
        model:  default
        prompt: "Score CV of {{ full_name }}. Return JSON: {score, route}"

# → POST /api/workflows/screen/run  (auto-mounted)
# dev — hot reload, Insight portal
$ tuvl dev
# production — multi-worker
$ tuvl run --workers 4
# curl your new endpoint
$ curl -X POST localhost:8000/api/workflows/screen/run \
     -d '{"full_name":"Jane Doe"}'
{"route": "strong", "score": 8}
Built on the boring, reliable stuff
New · Insight Developer Portal

Your AI backend,
on the table.

Every workflow, model, datasource, agent, and vector index — live in your browser. Edit YAML, trigger executions, watch every step fire. No IDE required.

127.0.0.1:8000/insight/workflows
dev
tuvl Insight portal
Edit any workflow YAML in the browser. Visual graph, live versioning, hot reload — no IDE required.
11
tools in one place — workflows, models, datasources, agents, vector indexes, IAM, OAuth2, Swagger, Spectrum, settings.
0
extra processes to run. The portal is served by your dev engine on a single port.
gRPC-Web
streams every step event from the engine to the canvas with millisecond latency.
dev only
never served in production. Zero attack surface added to your deployed engine.
Core engine

Eleven primitives.
Infinite workflows.

Every capability is a first-class primitive in the YAML. No glue code. No SDK lock-in. Mix functional Python with agentic LLM steps in the same pipeline.

workflow

YAML → Live API.

Define a workflow. Run tuvl dev. Your HTTP endpoint is live. No controllers, no boilerplate, no serialisation code — ever.

kind: Workflow
metadata:
  name: screen_candidate
spec:
  steps:
    - id: save
      kind: model-op
    - id: score
      kind: agent
      routes:
        strong:  fast_track
        weak:    reject

Any LLM, any provider.

One model: string unlocks 100+ providers via LiteLLM — Ollama, OpenAI, Anthropic, Gemini, Groq, Azure.

Signal-driven routing.

Steps return signals. Routes are explicit YAML maps. Tracing your pipeline doesn't require reading a single line of code.

Biscuit-secured.

Ed25519-signed Datalog tokens carry identity, group membership, and fine-grained resource:action scopes.

LLM-as-a-Judge testing.

Write YAML test cases with stub data. Run tuvl test. A judge model replays the trace and verifies each step against natural-language assertions. No real LLM, DB, or HTTP calls needed.

$ tuvl test
test_screen_candidate_pass (2 assertions)
test_screen_candidate_reject (2 assertions)
2 passed in 1.4s

Dynamic models.

YAML schemas auto-generate PostgreSQL tables, Pydantic schemas and full CRUD REST routes at startup.

Human-in-the-loop.

Pause any workflow for a human decision. Redis-backed state, timeouts, and a built-in review queue in the portal.

MCP & tool calls.

Model Context Protocol is a first-class step kind. Connect LLMs to any external tool or API as a workflow node.

OTel observability.

Structured logs + distributed traces. Every log carries trace_id, every node a span, every LLM call its gen_ai.* attributes.

pgvector RAG.

Embedding models and vector collections are first-class YAML. Auto-registered rag_search node ready to use.

spectrum · debugging

Watch every step fire.

Trigger a workflow with custom JSON. See nodes glow as they execute. Click any completed node for its input, output, duration, and stack trace. Set breakpoints to pause mid-execution.

save_draft score_cv fast_track notify
Two flavours, one engine

Functional logic.
Agentic decisions.

Compose deterministic Python steps with LLM-routed branches in the same YAML file. The engine streams every transition over SSE — no extra infrastructure.

workflows/screen_candidate.yaml
kind: Workflow
metadata:
  name: screen_candidate
enabled: true
spec:
  steps:
    - id: save_draft
      kind: model-op
      op: add
      model: Candidate

    - id: score_cv
      kind: agent
      agent:
        model: default           # ollama/llama3 · gpt-4o · claude-3-5
        prompt: |
          Score {{ full_name }} ({{ experience_years }}y).
          Return JSON: {"score": int, "route": "strong|weak"}
        output:
          format: json
          signal_from: route
      routes:
        strong:  fast_track
        weak:    reject
save_draft
default
score_cv ai
strong
fast_track
weak
reject
workflows/contact_intake.yaml
kind: Workflow
metadata:
  name: contact_intake
spec:
  steps:
    - id: validate
      kind: functional
      runner: validate_contact
      routes:
        valid:   save
        invalid: END

    - id: save
      kind: model-op
      op: add
      model: Contact
      routes:
        default: notify

    - id: notify
      kind: functional
      runner: send_welcome_email
validate
valid
save
default
notify
invalid
END
TypeScript SDK

@tuvl/client.
Zero plumbing.

Auth lifecycle, workflow execution, and SSE streaming — all from one npm package. Biscuit parsed server-side, no WASM in your bundle.

  • TuvlAuth — password, OAuth2 PKCE, refresh, revoke, getMe()
  • TuvlClient — one execute() call; REST · SSE · gRPC-Web auto-negotiated
  • Live step streamingonProgress fires per engine event with signal & duration
  • Full TypeScript typesStepEvent, WorkflowResult, MeResponse
app.ts TypeScript
// npm install @tuvl/client
import { TuvlAuth, TuvlClient } from "@tuvl/client";

const auth = new TuvlAuth({ baseUrl });

// password login → Biscuit bearer token
const { access_token } = await auth.loginWithPassword(
  "me@example.com", "secret"
);

// roles + scopes — no Biscuit internals
const me = await auth.getMe(access_token);
// { user_id, groups: ["hr_manager"], scopes: [...] }

// execute a workflow — streams live step events
const client = new TuvlClient({ baseUrl, token: access_token });
const result = await client.execute("screen_candidate", {
  payload:    { candidate_id: 42 },
  onProgress: (ev) => console.log(
    `[${ev.step_id}] ${ev.signal} (${ev.duration_ms}ms)`
  ),
});
Built for

Different roles.
Same source of truth.

Developers

Replace ad-hoc LLM scripts with signal-driven pipelines. YAML lives next to your code. Every execution streams structured events you can inspect.

Quickstart →

Teams & PMs

Every step is named. Every AI decision is logged with its signal and context snapshot. Know exactly what your system did — and why.

Architecture →

Founders & investors

Open-source infrastructure for production AI backends. Enterprise IAM, audit trails, data sovereignty — built in from day one.

Get in touch →
Early access

Engineer your AI backend.
Not vibe with it.

Join the vanguards shipping AI on their own terms. Local-first. Open source. No cloud required.

No spam. You'll only hear from us when it matters.