Skip to main content

loom-ai

loom-ai

Pluggable AI orchestration framework with swappable backends. Zero required dependencies.

Install

pip install flossware-loom-ai              # core (stdlib only)
pip install flossware-loom-ai[server]      # + FastAPI REST server
pip install flossware-loom-ai[postgresql]  # + PostgreSQL/pgvector storage
pip install flossware-loom-ai[redis]       # + Redis queues
pip install flossware-loom-ai[all]         # everything

Quick Start

As a Python library

from loom_ai import LoomConfig, Document, ChatMessage

# Zero-config: all in-memory / no-op backends
cfg = LoomConfig.from_env()

# Store a document
doc_id = await cfg.storage.store_document(Document(
    id="doc-1", title="Example", content="Hello world"
))

# Multi-model consensus (requires LOOM_LLM_BASE_URL)
responses = await cfg.llm.consensus(
    [ChatMessage(role="user", content="Explain distributed systems")],
    models=["gemini-3.5-flash", "llama-3.3-70b", "mistral-small"],
)

As a REST server

# Minimal — just LLM routing
export LOOM_LLM_BASE_URL=http://localhost:4000/v1
python -m loom_ai

# Full stack
export LOOM_STORAGE=postgresql
export LOOM_QUEUE=redis
export LOOM_GRAPH=memory
export LOOM_LLM_BASE_URL=http://localhost:4000/v1
python -m loom_ai

Routes mount dynamically based on configuration:

Backend Routes When
Storage /knowledge/* Always
Queue /pipeline/* Always
Search /search/* Always
Secrets /secrets/* Always
LLM /llm/* LOOM_LLM_BASE_URL set
Graph /graph/* LOOM_GRAPH != disabled
Health /health Always

Configuration

All via environment variables (defaults in parentheses):

Variable Options Default
LOOM_STORAGE memory, postgresql memory
LOOM_QUEUE memory, redis memory
LOOM_SECRETS env, dotenv, postgresql env
LOOM_EMBEDDING noop, openai, litellm noop
LOOM_SEARCH memory, postgresql memory
LOOM_GRAPH disabled, memory, orientdb disabled
LOOM_LLM_BASE_URL Any OpenAI-compatible URL (none)
LOOM_LLM_API_KEY Bearer token (none)
LOOM_LLM_MODEL Default model id gpt-4o-mini
LOOM_HOST Server bind address 0.0.0.0
LOOM_PORT Server port 5000

Don't set it? Don't get it. Set nothing at all and you get a pure in-memory orchestrator.

Architecture

loom_ai/
  protocols.py          7 Protocol interfaces (async, stdlib-only)
  models.py             9 dataclasses (Document, Chunk, ChatMessage, etc.)
  config.py             LoomConfig registry with from_env() factory
  prompts.py            Built-in consensus prompt templates
  server.py             Optional FastAPI REST server
  backends/
    memory.py           In-memory implementations (zero deps)
    env_secrets.py      Environment variable secrets
    http_llm.py         HTTP LLM backend (urllib, zero deps)

7 Pluggable Protocols

Protocol Purpose Default Enterprise
StorageBackend Documents, chunks, embeddings In-memory dicts PostgreSQL + pgvector
QueueBackend Named task queues In-memory deque Redis
SecretsBackend API keys and config os.environ PostgreSQL encrypted
EmbeddingBackend Text to vectors Zero vectors OpenAI / Jina / Voyage
SearchBackend Full-text + semantic Substring + cosine tsvector + pgvector ANN
GraphBackend Knowledge graph Disabled OrientDB
LLMBackend Chat + consensus HTTP (any OpenAI-compatible) Same

Multi-Model Consensus

Fan out to N models, synthesize with an arbiter:

from loom_ai.prompts import build_worker_messages, build_arbiter_messages

# Workers respond independently
worker_msgs = build_worker_messages("review", "Check this code for bugs")
responses = await cfg.llm.consensus(
    [ChatMessage(role=m["role"], content=m["content"]) for m in worker_msgs],
    models=["gemini-3.5-flash", "llama-3.3-70b", "codestral"],
    timeout_seconds=60,
    retries=2,
)

# Arbiter synthesizes
arbiter_msgs = build_arbiter_messages(
    "Check this code for bugs",
    [{"model": r.model, "response": r.content} for r in responses],
)
synthesis = await cfg.llm.chat(
    [ChatMessage(role=m["role"], content=m["content"]) for m in arbiter_msgs],
    model="gemini-3.5-flash",
    temperature=0.3,
)

Free AI Providers

See docs/free-ai-providers.md for 20+ free model providers with signup links, compatible with the HttpLLMBackend via LiteLLM proxy.

License

Apache 2.0

Metadata

Release files for flossware-loom-ai 1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flossware-loom-ai 1.3
File Size Uploaded
flossware_loom_ai-1.3.tar.gz 46.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flossware-loom-ai 1.3
File Interpreter ABI Platform
flossware_loom_ai-1.3-py3-none-any.whl Python 3 none any Details

Total release size: 84.9 kB

Release files / flossware_loom_ai-1.3.tar.gz

Download URL flossware_loom_ai-1.3.tar.gz
Size 46.5 kB
Tags Source
SHA-256 checksum
How to use checksums
2ab86c3d1bb1d02f9b205c8fdf2e893bb8b9f0aa682438e2b5bb6ec03f1b77a9
BLAKE2b-256 checksum
How to use checksums
f4cd83e5d26216a1f3a654b4b575c935f326d39c5360f090b2cee0f3897535f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / flossware_loom_ai-1.3-py3-none-any.whl

Download URL flossware_loom_ai-1.3-py3-none-any.whl
Size 38.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ad8a49911d2d21925aef7ad38e2afe3b40465407251e5dfc81bc77884c8f1b7e
BLAKE2b-256 checksum
How to use checksums
be35018bc1f54b77852ccb3eaa08855f4b4dd5242f40561bb29a4fcaaa073475
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

This release

1.3 This release

2 release files

1.2

2 release files

1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page