Loomkit
A tiny, swappable LLM orchestration core. The seam under an agent harness — without LangChain-scale bloat.
v0 ships the smallest useful surface:
- A
ProviderProtocol — anything with the rightgenerate()signature is a provider, no inheritance. Message/Response/Usagedataclasses.- One concrete provider:
GeminiProvider(officialgoogle-genaiSDK).
That's it. Streaming, tool calling, agents, retries, and graphs are deliberately deferred — they layer on through the Provider seam without breaking call sites.
Install
pip install loomkit # core only, zero deps
pip install 'loomkit[gemini]' # adds google-genai
pip install 'loomkit[gemini,dev]' # plus pytest
Requires Python 3.10+.
Quickstart
import os
from loomkit import Message
from loomkit.providers.gemini import GeminiProvider
# Reads GEMINI_API_KEY (or GOOGLE_API_KEY) from env; or pass api_key=...
provider = GeminiProvider()
resp = provider.generate(
[
Message(role="system", content="You are concise."),
Message(role="user", content="Name three primary colors."),
],
model="gemini-2.5-flash",
temperature=0.2,
)
print(resp.text)
print(resp.finish_reason, resp.usage)
Why a Protocol, not a base class
Provider is a typing.Protocol. Adding a new backend means writing one class with a generate() method matching the signature — no imports from loomkit, no inheritance, no registration. Call sites typed against Provider accept any conforming class.
class MyProvider:
def generate(self, messages, *, model, temperature=None,
max_tokens=None, stop=None) -> Response: ...
What's deferred (and how it lands)
| Feature | How it'll be added |
|---|---|
| Streaming | generate_stream() method returning chunk iterables |
| Tool / function calling | tools= kwarg; Message.content grows to a parts list |
| Async | Sibling AsyncProvider Protocol with async def generate(...) |
| Retries / rate limiting | Decorator providers — RetryingProvider(inner, ...) |
| Tracing / observability | Same shape — TracingProvider(inner, sink) |
| Agent loops | One layer up: loomkit.agents consumes a Provider |
| Graphs | Top of the stack; consumes agents |
Development
pip install -e '.[gemini,dev]'
pytest -q
The Gemini smoke test is skipped unless GEMINI_API_KEY is set.
Metadata
Release files for loomkit 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| loomkit-0.0.2.tar.gz | 5.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| loomkit-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.5 kB
Release files / loomkit-0.0.2.tar.gz
| Download URL | loomkit-0.0.2.tar.gz |
|---|---|
| Size | 5.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a6063ead656228bcefd55ed28f78c6bb4f0a92a96e85de3131bf47e26c8eedc
|
|
BLAKE2b-256 checksum How to use checksums |
cb95445745f40431e02e106553691e567e5ee13d8f79e34e595d6ab1a435905f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / loomkit-0.0.2-py3-none-any.whl
| Download URL | loomkit-0.0.2-py3-none-any.whl |
|---|---|
| Size | 5.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
922fb3015bc6fdcd8ba83ac7a7fdf8df03c78170ac64c73c17fc0b27a61a3e9d
|
|
BLAKE2b-256 checksum How to use checksums |
da2186586a9fc9eeb88a9eaa4f3fd7afc7961c58b769b9412b2b71b3f5d82968
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|