Composable prompt-construction library with named routes, context overlays, injections, streaming, middleware, and output validation.
Project description
promptlibretto
A prompt-engineering library — plus a browser studio to design, tune, and export that setup as a portable JSON config.
Define named routes that each compose their own system + user prompt, sampling params, and output policy. Layer transient context overlays on a long-lived base. Attach stackable injections for cross-cutting style/format tweaks. Swap providers without touching the rest.
Good fit for multi-mode assistants, agents that switch strategies per task, prompt A/B testing, and iterative refinement loops where each user follow-up becomes a reusable overlay.
- Full docs & walkthrough: sockheadrps.github.io/promptlibretto
- Design rationale: DESIGN.md
- Studio: studio/
Install
pip install promptlibretto # library only
pip install "promptlibretto[ollama]" # adds httpx for OllamaProvider
pip install "promptlibretto[studio]" # adds the browser studio
pip install "promptlibretto[dev]" # pytest + pytest-asyncio
Two paths
1. Tune in the studio, load JSON in your app
pip install "promptlibretto[studio,ollama]"
PROMPTLIBRETTO_EXPORT_DIR=. promptlibretto-studio
Design the route, mark any overlays as runtime: required/optional,
click Export as JSON → Save to disk. Then:
import asyncio
from promptlibretto import load_engine
engine, run = load_engine("my_assistant.json")
async def main():
result = await run(
"what should I cook tonight?",
location="kitchen", # required runtime slot
focus="quick weeknight meal", # optional runtime slot
dietary="vegetarian", # ad-hoc priority-10 overlay
)
print(result.text)
asyncio.run(main())
No codegen. load_engine() rebuilds the exact engine you tuned and
returns a run() closure that handles runtime slots and stray kwargs.
2. Build it in code
The smallest useful engine:
import asyncio
from promptlibretto import PromptEngine
engine = PromptEngine(routes={"default": "Say hi."})
print(asyncio.run(engine.generate_once()).text)
The constructor takes loose types: config as dict or GenerationConfig;
context_store as str, dict, or ContextStore; provider as "mock",
"ollama", or an adapter; routes as {name: str | list | dict | CompositeBuilder | PromptRoute}.
A fuller wiring:
import asyncio
from promptlibretto import (
CompositeBuilder, ContextOverlay, GenerationConfig, GenerationRequest,
MockProvider, PromptAssetRegistry, PromptEngine, PromptRoute,
PromptRouter, section, make_runtime_overlay,
)
assets = PromptAssetRegistry()
assets.add("frame.core", "You are a careful, helpful assistant.")
router = PromptRouter(default_route="default")
router.register(PromptRoute(
name="default",
builder=CompositeBuilder(
name="default",
system_sections=(lambda ctx: ctx.assets.get("frame.core"),),
user_sections=(
section(lambda ctx: f"Q:\n{ctx.request.inputs.get('input','')}"),
section("Respond now."),
),
generation_overrides={"temperature": 0.6},
output_policy={"strip_prefixes": ["```"]},
),
))
engine = PromptEngine(
config=GenerationConfig(provider="mock", model="demo"),
context_store="The assistant operates in demo mode.",
asset_registry=assets,
router=router,
provider=MockProvider(),
)
# Overlays are transient facts layered on the base, keyed by name:
engine.context_store.set_overlay(
"budget", ContextOverlay(text="Keep total under $800.", priority=20),
)
# `make_runtime_overlay` declares a slot caller fills at call time:
engine.context_store.set_overlay("location", make_runtime_overlay("required"))
asyncio.run(engine.generate_once(GenerationRequest(
inputs={"input": "What should I cook?", "location": "kitchen"},
)))
See the docs site for
streaming, middleware, injections, output policy, the prompt-size budget,
the debug trace, and export_json / load_engine internals.
Why not just f-strings?
Use this when:
- You have more than one kind of prompt and they share structure. Routes let you name and swap strategies without duplicating boilerplate.
- Follow-ups should affect future runs. Overlays let "make it shorter" stick around as a reusable piece of context.
- Output needs validation or retry — required regex, stripped code fences, banned phrases — handled once by the output processor instead of copy-pasted around call sites.
Don't use it if you send exactly one prompt shape. An f-string and a direct provider call are fine.
Development
pip install "promptlibretto[dev]"
pytest
License
MIT (see LICENSE when added).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promptlibretto-0.4.0.tar.gz.
File metadata
- Download URL: promptlibretto-0.4.0.tar.gz
- Upload date:
- Size: 99.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
27d6a6647df57c9acdcf7da8627e942bbb97aa0950d4878ce047cc471264a3b7
|
|
| MD5 |
f36ecd281331ead87a38fb69aeb09e63
|
|
| BLAKE2b-256 |
6ff0417680ca258cd98c18490b2e24acd73f3a72cddb065360cbd286e9180e9f
|
Provenance
The following attestation bundles were made for promptlibretto-0.4.0.tar.gz:
Publisher:
workflow.yml on sockheadrps/promptlibretto
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptlibretto-0.4.0.tar.gz -
Subject digest:
27d6a6647df57c9acdcf7da8627e942bbb97aa0950d4878ce047cc471264a3b7 - Sigstore transparency entry: 1361179360
- Sigstore integration time:
-
Permalink:
sockheadrps/promptlibretto@dc9204140fca818131b8872809777ab079e97f5b -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/sockheadrps
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@dc9204140fca818131b8872809777ab079e97f5b -
Trigger Event:
push
-
Statement type:
File details
Details for the file promptlibretto-0.4.0-py3-none-any.whl.
File metadata
- Download URL: promptlibretto-0.4.0-py3-none-any.whl
- Upload date:
- Size: 110.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5295d18616bda35865ce847cafa2d2930bc7dad39dc35cab4cd01b2b0ec41a88
|
|
| MD5 |
0cc72191e57c76e67b6090976642918e
|
|
| BLAKE2b-256 |
022a5a47e6a91d61d9f894adbdaa9472945028c8c33cdd59a502d4cb464d9175
|
Provenance
The following attestation bundles were made for promptlibretto-0.4.0-py3-none-any.whl:
Publisher:
workflow.yml on sockheadrps/promptlibretto
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptlibretto-0.4.0-py3-none-any.whl -
Subject digest:
5295d18616bda35865ce847cafa2d2930bc7dad39dc35cab4cd01b2b0ec41a88 - Sigstore transparency entry: 1361179390
- Sigstore integration time:
-
Permalink:
sockheadrps/promptlibretto@dc9204140fca818131b8872809777ab079e97f5b -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/sockheadrps
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@dc9204140fca818131b8872809777ab079e97f5b -
Trigger Event:
push
-
Statement type: