# vario ng CLI + UI Design

Date: 2026-03-06. Updated: 2026-03-07.

## Core Principle

`vario` = ng. One engine. The old vario CLI (`cli.py`, `cli_ng.py`, strategies executor) is retired.

## CLI: What's Built

The CLI already works (`python -m vario.ng` / `variong`):

```bash
variong run best_of_n "What causes tides?"               # named recipe
variong run best_of_n "Explain quicksort" -c fast         # modifier override
variong run summarize "Summarize this" -i README.md       # input files
variong run best_of_n "Review" -i old:v1.md -i new:v2.md  # tagged inputs
variong run confirm "Is P=NP?"                            # output-first-confirmed
variong recipes                                            # list recipes
variong log                                                # run history
variong log a1b2c3                                         # run details
```

**Flags on `run`:**
```
-i FILE               # input (repeatable). Text inlined, binary attached.
-c MODIFIER           # model tier: fast, maxthink, allthink, code
--budget 0.05         # budget in USD
--models opus,grok    # explicit model override
-n 3                  # candidate count override
--temperature 0.7     # temperature override
--jsonl               # output as JSONL for piping
-v                    # verbose
```

**Infrastructure built:**
- `modifiers.py` — `-c fast/maxthink/code/allthink` with multimodal input validation
- `db.py` — SQLite persistence (`~/.vario/ng_runs.db`) with runs, things, traces
- 9 recipes, 206 tests passing

## What's Still Needed

### 1. `variong design` — NL → recipe YAML

The missing piece. Compose with `run` via process substitution:

```bash
variong run <(variong design "do best models, try hard") "probe collatz conjecture"
variong design "refine until score > 85" | variong run - "write a haiku"
variong design "debate across 3 models" > my_debate.yaml
```

**Files:**
- `vario/interpret.py` — INTERPRET_PROMPT (updated for ng blocks) + `async def interpret(description: str) -> str`
- `vario/cli.py` — add `interpret` command

### 2. Recipe from file path or stdin

`run` currently only accepts recipe names. Add:
- File path: `variong run ./my_recipe.yaml "prompt"` (has `/` or `.yaml`)
- Stdin: `variong run - "prompt" < recipe.yaml`

**File:** `vario/executor.py` — extend `load_recipe()` to accept paths and stdin.

### 3. Wire as main `vario` command

Make `vario run` → `variong run`. Either:
- Rewire `vario/cli.py:_register_extra_commands()` to import from `vario.cli`
- Or: change the `vario` entry point to `vario.cli:main` directly

## Recipe YAML: Stage Descriptions

Add a `desc` field to stages — human-readable, shown in UI and CLI:

```yaml
name: best_of_n
description: Generate N candidates, score them, pick the best.
stages:
  - type: produce
    desc: "Generate 4 candidate answers"
    params: { n: 4 }
  - type: score
    desc: "Rate each answer on accuracy and clarity"
    params: { rubric: "accuracy, clarity, completeness" }
  - type: reduce
    desc: "Pick the best one"
    params: { method: top_k, k: 1 }
```

```yaml
name: refine_until_converged
description: Generate, then iteratively score and improve until stable.
stages:
  - type: produce
    desc: "Draft initial answer"
    params: { n: 1 }
  - type: repeat
    desc: "Score → improve loop until quality plateaus"
    stages:
      - type: score
        desc: "Evaluate current draft"
        params: { rubric: "correctness, depth" }
      - type: revise
        desc: "Improve using score feedback"
    stop: { score_threshold: 85, max_rounds: 5, drift_window: 3 }
```

The `desc` is optional — blocks have sensible defaults ("Produce N candidates",
"Score on rubric", "Pick top K"). But explicit descriptions make the pipeline
self-documenting and drive the UI.

### Data flow annotation

Each stage's desc can note what it adds/changes. But the more interesting question
is: **can the pipeline structure show what flows between stages?**

The data flow is implicit in the block types — each block type has a known
effect on Things:

```
produce:  () → [Thing{content, model}]           # creates from nothing
score:    [Thing] → [Thing{+score, +reason}]      # adds props
revise:   [Thing] → [Thing{content', +prev}]      # replaces content
reduce:   [Thing...] → [Thing...]                  # selects/combines
repeat:   [Thing...] → [Thing...]                  # iterates sub-pipeline
```

The UI can show this automatically — no annotation needed in the YAML.
Given a stage's `type`, we know what props exist before and after.

### Flow visualization format

A recipe's data flow can be rendered as a prop-accumulation diagram:

```
best_of_n:

  produce(n=4)
  ├─ Thing { content, model: opus }
  ├─ Thing { content, model: grok }
  ├─ Thing { content, model: gemini }
  └─ Thing { content, model: haiku }
       │
  score(rubric)
  ├─ Thing { content, model, score: 87, reason: "..." }
  ├─ Thing { content, model, score: 72, reason: "..." }
  ├─ Thing { content, model, score: 91, reason: "..." }
  └─ Thing { content, model, score: 65, reason: "..." }
       │
  reduce(top_k=1)
  └─ Thing { content, model, score: 91, reason: "..." }
```

```
refine_until_converged:

  produce(n=1)
  └─ Thing { content, model: sonnet }
       │
  ┌─ repeat ───────────────────────────────┐
  │  score                                 │
  │  └─ Thing { content, +score, +reason } │
  │       │                                │
  │  revise                                │
  │  └─ Thing { content', +previous }      │
  │       │                                │
  │  [round 1: 62 → round 2: 78 → r3: 84]  │
  └────────────────────────────────────────┘
       │
  └─ Thing { content''', score: 84 }
```

This shows:
- What props exist at each boundary
- Cardinality changes (4 Things → 1 Thing after reduce)
- Score progression in repeat loops
- What `+` means new prop, what `'` means content was replaced

## UI: Two-Column Layout

### Left: Input + Results

The primary workspace. Problem input, recipe selector, budget, run button.
Below that: the final results (best Thing content, score).

This is where you read and write — the creative side.

### Right: Pipeline Graph + Stage Detail

The pipeline visualization — what's happening and what happened.

```
┌──────────────────────────────────────┬─────────────────────────────────────────┐
│                                      │ Recipe: best_of_n            [YAML ▾]   │
│  Problem:                            │                                         │
│  "What causes tides?"                │ ✨ "Generate 4 candidate answers"        │
│                                      │    n=4  opus, grok, gemini, haiku       │
│  Recipe: [best_of_n ▾]  $[0.05]      │       ▼ 4 Things {content, model}       │
│  [Run]                               │                                         │
│                                      │ 🔍 "Rate on accuracy and clarity"        │
│  ═══════════════════════════         │    rubric: accuracy, clarity   $0.002   │
│  Result:                             │       ▼ 4 Things {+score, +reason}      │
│  Tides are caused primarily          │                                         │
│  by the gravitational pull           │ 🎯 "Pick the best one"                   │
│  of the Moon...                      │    method: top_k, k=1                   │
│              score: 91 opus          │       ▼ 1 Thing                         │
│                                      │                                         │
│                                      │ ─────────────────────                   │
│                                      │ $0.0034 · 2.1s · score: 91              │
│                                      │                                         │
│                                      │ Stage detail:                           │
│                                      │   [clicked stage output here]           │
│                                      │   Thing cards / score bars /            │
│                                      │   diffs / round progression             │
└──────────────────────────────────────┴─────────────────────────────────────────┘
```

### Right column details

**Before execution**: shows the recipe structure with descriptions — a preview
of what will happen. This might be all the user needs to understand the pipeline.

**During execution**: stages light up as they complete. Cost/duration/score
badges fill in. The flow arrows show data accumulation in real time.

**After execution**: full pipeline with results. Clicking a stage opens its
detail panel below the graph:
- produce/reduce → Thing cards with content preview
- score → Score breakdown with dimension bars
- revise → Before/after diff
- repeat → Round-by-round score progression

Uses the existing viewer dispatch (`ui_viewers.py`).

### The "descriptions might be enough" insight

For many users, the left column alone tells the whole story:

```
✨ "Generate 4 candidate answers"
🔍 "Rate on accuracy and clarity"
🎯 "Pick the best one"
```

That's the pipeline. The types, params, and data flow are details for power users.
The descriptions are the primary interface. This means:

1. Recipes should always have good `desc` fields
2. `interpret` should generate descriptions alongside stages
3. The UI's primary view is **descriptions + flow arrows + status badges**
4. Raw YAML is a collapsible detail, not the main view

### YAML source toggle

A "Show YAML" toggle reveals the raw recipe source in `gr.Code(language="yaml")`.
For debugging and understanding, not primary interaction.

## Implementation Order

### Already done
- [x] `run` command with `-i`, `-c`, `--models`, `-n`, `--budget`, `--jsonl`
- [x] `recipes` command (list)
- [x] `log` command (history + detail)
- [x] Modifiers (`modifiers.py`) with multimodal validation
- [x] DB persistence (`db.py`)
- [x] 9 recipes, 206 tests

### Phase 1: CLI completion
- [ ] `interpret` command — NL → recipe YAML
- [ ] Recipe from file path or stdin in `run`
- [ ] Add `desc` field to Stage dataclass in executor.py
- [ ] Add `desc` to all 9 existing recipes
- [ ] Wire `vario` → `variong`

### Phase 2: UI — two-column pipeline view
- [ ] Left column: rendered pipeline (descriptions + flow arrows + status)
- [ ] Right column: stage detail (existing viewers)
- [ ] Wire into main app as "Pipeline" tab
- [ ] Stage-by-stage progress (stages light up as they complete)
- [ ] YAML source toggle

### Phase 3: Recipe evolution
- [ ] `interpret` generates `desc` fields
- [ ] Preset recipes (fast, maxthink, code) — if not already covered by modifiers
- [ ] `explore_then_refine` recipe
