Spaces:
Running
A newer version of the Gradio SDK is available: 6.22.0
ADR-007: CLI Interface Layer
Status: Accepted Date: 2025-01-23 Extends: ADR-006 (adds interface layer above orchestration)
Context
prompt-prix started as a Gradio UI for visual model comparison. However, manual UI interaction is a bottleneck for:
- Automated testing β CI/CD pipelines need headless execution
- Iteration speed β Loading browser, uploading files, clicking buttons
- Scripting β Batch runs across different benchmark files
- Integration β Other tools want to invoke battery runs programmatically
The existing architecture (ADR-006) cleanly separates orchestration from adapters:
ORCHESTRATION (BatteryRunner, ComparisonSession)
β
MCP PRIMITIVES (complete, list_models)
β
ADAPTER (LMStudioAdapter)
But there's an implicit assumption: Gradio handlers are the only entry point.
Decision
The interface layer is separate from orchestration.
prompt-prix has multiple interface options that share the same orchestration and adapter stack:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β INTERFACE LAYER β
β β
β Gradio UI (ui.py, tabs/*) β CLI (scripts/run_battery.py) β
β β’ Interactive visual β β’ Headless automation β
β β’ Browser-based β β’ Terminal output β
β β’ Human-in-the-loop β β’ CI/CD friendly β
β β β’ Scriptable β
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ORCHESTRATION β
β BatteryRunner β ComparisonSession β
β (same code for both interfaces) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β
[MCP β Adapter per ADR-006]
Interface Implementations
| Interface | Location | Use Case |
|---|---|---|
| Gradio UI | ui.py, tabs/*/handlers.py |
Interactive exploration, visual comparison |
| CLI | scripts/run_battery.py |
Automation, CI/CD, scripting |
| (future) Python API | prompt_prix.api |
Library usage, custom tooling |
CLI Design
The CLI is a thin layer that:
- Parses arguments and environment
- Creates adapter and registers it
- Loads benchmark file
- Calls
BatteryRunner(same as UI) - Formats output for terminal
# Basic usage
python scripts/run_battery.py examples/tool_competence_tests.json
# Options
python scripts/run_battery.py file.json --random 2 # 2 random models per GPU
python scripts/run_battery.py file.json -v # Verbose per-test output
python scripts/run_battery.py file.json -e out.json # Export results
Rules
MUST
- Interface code lives outside core package (
scripts/for CLI,ui.pyfor Gradio) - All interfaces use the same orchestration classes (BatteryRunner, etc.)
- Adapter registration happens in interface layer (not buried in orchestration)
- CLI reads configuration from same sources as UI (
.env, environment variables)
MUST NOT
- Orchestration MUST NOT import interface code
- Orchestration MUST NOT assume Gradio is present
- CLI MUST NOT duplicate orchestration logic (reuse BatteryRunner)
Rationale
Why Not Just Gradio?
Gradio is excellent for interactive exploration but:
- Requires browser and server running
- Manual clicks for each test run
- Can't be automated in CI/CD
- Human bottleneck for iteration
Why scripts/ Not prompt_prix.cli?
- Simplicity β One-file script is easier to understand and modify
- No entry point overhead β Run directly with
python scripts/... - Separate from package β Clear that this is a tool, not library code
- Easy to add more β
scripts/compare.py,scripts/export.py, etc.
If CLI grows complex, can refactor to prompt_prix.cli module with proper entry points.
Precedent
This mirrors common patterns:
- Django:
manage.pyscripts alongside web interface - pytest: CLI runner over same core library
- alembic: CLI for migrations, programmatic API for same operations
Consequences
Positive
- Unblocks automated testing and CI/CD
- Faster iteration (no browser needed)
- Same behavior guaranteed between UI and CLI
- Foundation for future API/library usage
Negative
- Two places to update if BatteryRunner interface changes
- CLI output formatting is separate from Gradio grid display
- Need to keep CLI in sync with new features
Future Work
scripts/compare.pyβ Interactive comparison CLI- Entry point in
pyproject.tomlforprompt-prix battery ... - Python API (
from prompt_prix import run_battery)
References
- ADR-006: Adapter Resource Ownership (the layer below interfaces)
- Issue #99: Per-server queues for parallelism (affects both interfaces)
- Script:
scripts/run_battery.py