Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# QuickSilver Pro CLI

`qsp` — a command-line client for [QuickSilver Pro](https://quicksilverpro.io), one OpenAI-compatible API for top LLMs (DeepSeek, Qwen, Kimi, Gemini) **and** FLUX text-to-image — billed to a single balance. Open-source chat models run 20% below OpenRouter / Together / Fireworks.
`qsp` — a command-line client for [QuickSilver Pro](https://quicksilverpro.io), one OpenAI-compatible API for frontier and open-source LLMs (Claude, GPT, Gemini, DeepSeek, Qwen, Kimi, Muse) **and** FLUX text-to-image — all billed to a single balance. Open-source chat models run up to 20% below OpenRouter.

Designed to be **AI-agent friendly**: data commands accept `--json` for structured output, exit codes are reliable, and the API surface is intentionally small.

Expand All @@ -26,6 +26,15 @@ End-user site: <https://quicksilverpro.io>.
pip install quicksilverpro
```

Or run it with no install:

```bash
uvx quicksilverpro chat "Write me a haiku" # via uv — fetches Python for you: https://docs.astral.sh/uv/
pipx run quicksilverpro chat "Write me a haiku" # via pipx (needs Python 3.10+)
```

On Windows, `uvx` is the simplest path — uv downloads a suitable Python automatically. On macOS you can also `brew install machinefi/qspro/qspro`.

Python 3.9+. Also exports itself as `quicksilverpro` if you prefer the long name.

---
Expand Down
11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ build-backend = "hatchling.build"

[project]
name = "quicksilverpro"
version = "0.2.0"
description = "CLI for QuickSilver Pro — one OpenAI-compatible API for DeepSeek, Qwen, Kimi, Gemini chat and FLUX image generation."
version = "0.3.0"
description = "CLI for QuickSilver Pro — one OpenAI-compatible API for Claude, GPT, Gemini, DeepSeek, Qwen, Kimi and Muse chat plus FLUX image generation, on a single balance."
readme = "README.md"
requires-python = ">=3.9"
license = { text = "MIT" }
authors = [{ name = "MachineFi Inc.", email = "hello@quicksilverpro.io" }]
keywords = [
"openai", "deepseek", "qwen", "kimi", "gemini", "flux",
"llm", "inference", "api", "chatgpt", "ai", "cli",
"image-generation", "text-to-image", "openrouter-alternative", "quicksilverpro",
"openai", "claude", "anthropic", "gpt", "gemini", "deepseek", "qwen",
"kimi", "muse", "flux", "llm", "inference", "api", "chatgpt", "ai", "cli",
"coding-agent", "image-generation", "text-to-image",
"openrouter-alternative", "quicksilverpro",
]
classifiers = [
"Development Status :: 4 - Beta",
Expand Down
2 changes: 1 addition & 1 deletion src/quicksilverpro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
See https://quicksilverpro.io for docs. `qsp --help` for quick reference.
"""

__version__ = "0.2.0"
__version__ = "0.3.0"
69 changes: 35 additions & 34 deletions src/quicksilverpro/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,53 +275,54 @@ def balance(as_json: bool) -> None:
# not expose per-image pricing (its schema is per-token), so the CLI carries it
# here so `qsp models` can show image costs whether or not the user is signed in.
_IMAGE_PRICES: dict[str, float] = {
"flux.2-pro": 0.027,
"flux.1-schnell": 0.0025,
"flux.2-pro": 0.027,
}

# Hardcoded so `qsp models` works before the user has signed in. A curated view
# of the lineup — once signed in, `qsp models` shows the full live catalog
# (incl. Qwen/Kimi/Gemini variants). Keep prices in sync with the backend; CI
# smoke-tests this path. Prices verified 2026-07-31.
# Hardcoded so `qsp models` works before the user has signed in. A curated,
# hot-first view of the lineup — once signed in, `qsp models` shows the full
# live catalog (30+ models incl. every Qwen/Kimi/Gemini/Claude variant). Keep
# prices in sync with the backend; CI smoke-tests this path. Prices verified
# 2026-08-08 against qsp.gateway_model_pricing.
_MODELS_FALLBACK: list[dict] = [
{"id": "deepseek-v4-flash", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000001120", "completion": "0.0000002240"},
"best_for": "official 0731 agent model · Codex · 1M context"},
{"id": "deepseek-v4-pro", "object": "model", "owned_by": "quicksilverpro",
{"id": "claude-opus-5", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1000000,
"pricing": {"prompt": "0.0000040000", "completion": "0.0000200000"},
"best_for": "Anthropic flagship · deepest reasoning + agentic coding"},
{"id": "claude-sonnet-5", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1000000,
"pricing": {"prompt": "0.0000020000", "completion": "0.0000100000"},
"best_for": "Claude Sonnet 5 · balanced coding + long-context agents"},
{"id": "gpt-5.6-sol", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000003480", "completion": "0.0000006960"},
"best_for": "frontier reasoning + coding · 1M context"},
"pricing": {"prompt": "0.0000040000", "completion": "0.0000240000"},
"best_for": "OpenAI GPT-5.6 Sol · frontier reasoning + tool use"},
{"id": "qwen3.8-max", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000020000", "completion": "0.0000060000"},
"best_for": "flagship Qwen · autonomous coding, long-horizon agents"},
{"id": "qwen3.7-max", "object": "model", "owned_by": "quicksilverpro",
{"id": "kimi-k3", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000012500", "completion": "0.0000037500"},
"best_for": "flagship Qwen · agentic, long-context"},
{"id": "qwen3.7-flash", "object": "model", "owned_by": "quicksilverpro",
"pricing": {"prompt": "0.0000024000", "completion": "0.0000120000"},
"best_for": "Moonshot Kimi K3 · agentic coding + tool use · 1M context"},
{"id": "muse-spark-1.2", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000000240", "completion": "0.0000001040"},
"best_for": "fast multimodal agents · vision · 1M context"},
{"id": "qwen3.6-plus", "object": "model", "owned_by": "quicksilverpro",
"pricing": {"prompt": "0.0000010000", "completion": "0.0000034000"},
"best_for": "Meta Muse Spark · long-context coding agent"},
{"id": "deepseek-v4-pro", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000003480", "completion": "0.0000006960"},
"best_for": "frontier reasoning + coding · 1M context"},
{"id": "deepseek-v4-flash", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000001120", "completion": "0.0000002240"},
"best_for": "official 0731 agent model · lowest cost · 1M context"},
{"id": "gemini-3.6-flash", "object": "model", "owned_by": "quicksilverpro",
"context_length": 1048576,
"pricing": {"prompt": "0.0000002600", "completion": "0.0000015600"},
"best_for": "strong general-purpose · 1M context"},
{"id": "qwen3.6-35b", "object": "model", "owned_by": "quicksilverpro",
"context_length": 262144,
"pricing": {"prompt": "0.0000001120", "completion": "0.0000008000"},
"best_for": "efficient long-context RAG (thinking model)"},
{"id": "kimi-k2.6", "object": "model", "owned_by": "quicksilverpro",
"context_length": 256000,
"pricing": {"prompt": "0.0000005472", "completion": "0.0000027280"},
"best_for": "agentic, tool use, long-context"},
"pricing": {"prompt": "0.0000012750", "completion": "0.0000063750"},
"best_for": "Google Gemini · fast multimodal · 1M context"},
{"id": "flux.2-pro", "object": "model", "owned_by": "quicksilverpro",
"price_per_image": 0.027,
"best_for": "high-fidelity text-to-image"},
{"id": "flux.1-schnell", "object": "model", "owned_by": "quicksilverpro",
"price_per_image": 0.0025,
"best_for": "fast, cheap text-to-image"},
]


Expand Down Expand Up @@ -584,7 +585,7 @@ def _image_path(stem: Path, index: int, count: int, ext: str) -> Path:
@main.command(help="Generate an image from a text prompt and save it to disk.")
@click.argument("prompt")
@click.option("-m", "--model", default=DEFAULT_IMAGE_MODEL, show_default=True,
help="Image model, e.g. flux.2-pro or flux.1-schnell.")
help="Image model, e.g. flux.2-pro.")
@click.option("-o", "--output", default=None,
help="Output file. Default: qsp-image-<ts>.<ext> in the current dir. "
"With -n > 1 a 1-based index is inserted before the extension.")
Expand Down