Skip to main content

Load, unload, and swap any number of local LLMs (LM Studio, Ollama, llama.cpp, ...) with full client-side control — plus unified streaming for local and cloud backends and an MCP server so agents can manage your VRAM.

Project description

promptchain

Load, unload, and swap any number of local LLMs on one GPU — with full, explicit control. A small library for driving LM Studio, Ollama, and any OpenAI-compatible server from Python, plus unified streaming across local and cloud backends, and an MCP server so agents can manage your VRAM for you.

Servers already handle the automatic case — LM Studio auto-evicts, Ollama's keep_alive expires, llama-swap proxies swapping for the servers it manages. What none of them give you is one client that spans LM Studio + Ollama + any OpenAI-compatible endpoint with a policy engine on top: pin a model so it's never evicted, pre-warm the next one before you need it, swap a whole working set in one call, cap residency by count or VRAM budget — and hand all of that to your agent over MCP.

pip install promptchain

Quickstart

from promptchain import ModelManager, Endpoint

# One GPU, one model resident at a time; evict after 5 min idle.
mgr = ModelManager(policy="auto", max_resident=1, idle_unload=300)

mgr.register("drafter", Endpoint("lmstudio", "gemma-4-4b"))
mgr.register("coder",   Endpoint("ollama", "qwen3-coder:30b"), priority=10)
mgr.register("reviewer", Endpoint("anthropic", "claude-sonnet-5"))  # cloud: never counts against VRAM

with mgr.use("coder") as m:            # evicts 'drafter' first if needed, loads 'coder'
    for token in m.stream(user_message="write fizzbuzz in rust"):
        print(token, end="", flush=True)

mgr.resident()        # -> ["coder"]

Full control over the GPU

mgr.load("coder", wait=True)        # pre-warm, block until the server reports it ready
mgr.preload("critic")               # pre-warm in the background
mgr.swap("drafter", "coder")        # atomic unload -> load in one call
mgr.pin("coder"); mgr.unpin("coder")# pinned models are never auto-evicted
mgr.group("review", ["critic", "fixer"])
mgr.activate("review")              # swap a whole working set in; evict everything else
mgr.unload_all()

mgr.refresh_residency()             # reconcile belief with the server (Ollama /api/ps, LM Studio REST)
mgr.stats()                         # per-model loads, evictions, tokens, est. cost
  • policy="auto" evicts other models as needed before a load — lowest priority first, least-recently-used as the tiebreak — under max_resident and/or vram_budget.
  • policy="manual" never loads or unloads implicitly; you drive every lifecycle change yourself.
  • Cloud and custom backends stream normally but never count against VRAM and are never evicted.

Unified streaming

One stream() across every backend, returning a handle you iterate for tokens:

from promptchain import stream

resp = stream(backend="ollama", model="qwen3:8b", base_url="http://localhost:11434",
              user_message="explain async/await")
text = resp.consume()
resp.usage        # {"input_tokens": ..., "output_tokens": ...} (cloud backends)
resp.reasoning    # hidden <think>...</think> reasoning, stripped from the visible text
resp.tool_calls   # parsed tool calls when tools= was passed

Reasoning models (DeepSeek-R1 / Qwen3 / GLM) have their <think> blocks stripped automatically; Hermes-format <tool_call> tags are parsed out for local tool calling.

Backends

Backend Load / unload / ps Streaming Usage reporting
lmstudio
ollama
custom (llama.cpp, vLLM, llama-swap, Jan, and any OpenAI-compatible cloud) ✅ (when keyed)
openai n/a
gemini n/a
anthropic n/a

API keys for the named clouds are read from OPENAI_API_KEY / ANTHROPIC_API_KEY / GEMINI_API_KEY. Install Anthropic support with pip install "promptchain[anthropic]" (OpenAI/Gemini need no extra — they're OpenAI-compatible).

Any OpenAI-compatible provider

Point the custom backend at any OpenAI-compatible endpoint and pass a key — DeepSeek, Groq, Together, Fireworks, OpenRouter, Mistral, DeepInfra, an authenticated vLLM, whatever:

Endpoint("custom", "deepseek-chat",   base_url="https://api.deepseek.com",  api_key="sk-...")
Endpoint("custom", "llama-3.3-70b",   base_url="https://api.groq.com/openai", api_key="gsk-...")
Endpoint("custom", "anthropic/claude-sonnet-4", base_url="https://openrouter.ai/api", api_key="sk-or-...")

Set base_url to the part before /v1 — the library appends /v1/chat/completions. Token usage is reported whenever a key is present.

Let an agent manage your GPU (MCP)

pip install "promptchain[mcp]"
promptchain-mcp        # stdio MCP server

Wire it into Hermes Agent, Claude Code, or Claude Desktop and it can ps your GPU, load/unload/swap models, and generate through them — in plain language. Models are configured in an endpoints.toml (auto-created on first run). See the agent setup guide.

The app built on this

The same repo ships the PromptChain app — a two-model Streamlit pipeline with a human review gate: a small local model drafts your prompt, you fix it, then the big (local or cloud) model writes the code. It's the flagship consumer of this library; clone the repo to run it.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

promptchain-0.1.1.tar.gz (35.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

promptchain-0.1.1-py3-none-any.whl (38.5 kB view details)

Uploaded Python 3

File details

Details for the file promptchain-0.1.1.tar.gz.

File metadata

  • Download URL: promptchain-0.1.1.tar.gz
  • Upload date:
  • Size: 35.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for promptchain-0.1.1.tar.gz
Algorithm Hash digest
SHA256 35b621da758594a474f1c51840ea867194b45a6c08ee4786a235c767737dd7a1
MD5 38117e332407108ea2a8d0fe5ab594d7
BLAKE2b-256 05f8ece2b0771d8d773e62b527864d5e4adb27ddd31458608d0bb893bf06b207

See more details on using hashes here.

File details

Details for the file promptchain-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: promptchain-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 38.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for promptchain-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b3a94d73a164e9920629ea8c8efcf83fa901f9e4fba213bec918ca858ada484f
MD5 9a156c98e6ea2863e77e089f8509b1c5
BLAKE2b-256 61e534575b424c4b6f59f6aaa0f74004c51beb31219ae6deeb1b5b56ac0cb030

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page