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 — lowestpriorityfirst, least-recently-used as the tiebreak — undermax_residentand/orvram_budget.policy="manual"never loads or unloads implicitly; you drive every lifecycle change yourself.- Cloud and
custombackends 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
- Source, the app, examples, and full docs: https://github.com/atharva557/Prompt-Chaining
- Requires Python ≥ 3.10. MIT licensed.
Metadata
Release files for promptchain 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| promptchain-0.1.1.tar.gz | 35.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| promptchain-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.7 kB
Release files / promptchain-0.1.1.tar.gz
| Download URL | promptchain-0.1.1.tar.gz |
|---|---|
| Size | 35.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
35b621da758594a474f1c51840ea867194b45a6c08ee4786a235c767737dd7a1
|
|
BLAKE2b-256 checksum How to use checksums |
05f8ece2b0771d8d773e62b527864d5e4adb27ddd31458608d0bb893bf06b207
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Release files / promptchain-0.1.1-py3-none-any.whl
| Download URL | promptchain-0.1.1-py3-none-any.whl |
|---|---|
| Size | 38.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b3a94d73a164e9920629ea8c8efcf83fa901f9e4fba213bec918ca858ada484f
|
|
BLAKE2b-256 checksum How to use checksums |
61e534575b424c4b6f59f6aaa0f74004c51beb31219ae6deeb1b5b56ac0cb030
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.7
|
Security for promptchain 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.