Skip to main content

llm-seam

Unified LLM abstraction with a provider pattern — one interface, five backends, automatic fallback and retry.

Note on the name: this package was llm-base until 2026-08-21. It was renamed to llm-seam because the PyPI name llm-base belongs to an unrelated, older project — no relation to this package.

What's in the box

Module What it gives you
llm_seam.client LLMClient — auto-selects a provider from the environment (Anthropic, then OpenAI, then a mock fallback), or accepts an explicit provider name/instance
llm_seam.providers.base LLMProvider — the Protocol every provider implements (complete, get_name, supports_streaming)
llm_seam.providers.anthropic AnthropicProvider — wraps the anthropic SDK
llm_seam.providers.openai OpenAIProvider — wraps the openai SDK
llm_seam.providers.claude_cli ClaudeCLIProvider — shells out to the Claude Code CLI
llm_seam.providers.agent_sdk AgentSDKProvider — wraps claude-agent-sdk (requires the [sdk] extra); supports an optional can_use_tool security callback (see below); large system prompts are passed via a temp file, not argv
llm_seam.providers.ollama OllamaProvider — local models via Ollama's OpenAI-compatible API (uses the openai SDK, no extra required)
llm_seam.providers.mock MockProvider — fixed-response provider for tests and offline use
llm_seam.fallback FallbackChain — tries a list of providers in order, raises AllProvidersFailed only if every one of them fails
llm_seam.retry with_retry — decorator with exponential backoff, retries on RateLimitError by default (configurable)
llm_seam.tool_guards path_scoped_tool_guard — ready-made can_use_tool callback for AgentSDKProvider; confines a tool's path arguments to an allowlist of directories, resists .. traversal, symlink escapes, and absolute paths outside the allowlist
llm_seam.exceptions LLMError (base), RateLimitError, TokenLimitError, TimeoutError, AllProvidersFailed

Design

One interface, provider-agnostic callers. LLMClient and every provider implement the same three-method LLMProvider protocol (complete, get_name, supports_streaming), so a caller can swap Anthropic for a local Ollama model, the Claude CLI, or a mock in tests without touching call sites.

Auto-selection is a convenience, not a requirement. LLMClient() with no arguments picks Anthropic if ANTHROPIC_API_KEY is set, else OpenAI if OPENAI_API_KEY is set, else falls back to MockProvider. Pass an explicit provider= name or instance to bypass auto-selection entirely.

Provider-name convention. When constructing by name string, this portfolio distinguishes two Claude transports: "claude-sdk" selects AgentSDKProvider (the claude-agent-sdk package, preferred for new scheduled work — see libs/CLAUDE.md), and "claude-cli" selects ClaudeCLIProvider (shells out to the installed Claude Code CLI). "claude-sdk" is only registered as a valid name if claude-agent-sdk is installed (the [sdk] extra); otherwise constructing by that name raises ValueError.

AgentSDKProvider's can_use_tool is a security boundary, not a hygiene knob. It threads straight to ClaudeAgentOptions.can_use_tool. If a caller passes a callback and the installed claude-agent-sdk can't accept the field, the call raises LLMError rather than silently proceeding ungated — a caller that believes tool calls are being permission-checked must never find out otherwise the hard way. Use tool_guards.path_scoped_tool_guard(allowed_dirs) rather than hand-rolling path checks.

Fallback and retry compose, they don't replace each other. FallbackChain moves between providers; with_retry retries a single call on a transient error (rate limits by default). Wrap a FallbackChain's .complete in with_retry, or use either alone.

Install

pip install llm-seam

Optional extras:

pip install "llm-seam[sdk]"      # AgentSDKProvider (claude-agent-sdk)

Usage

from llm_seam import LLMClient, FallbackChain, with_retry

# Auto-select a provider from the environment
client = LLMClient()
response = client.complete("Hello, world!")

# Explicit provider by name
client = LLMClient(provider="anthropic")

# Fall back through providers in order
chain = FallbackChain(providers=[
    LLMClient(provider="claude-cli").provider,
    LLMClient(provider="anthropic").provider,
])
response = chain.complete("Hello")

# Retry a call with exponential backoff on rate limits
@with_retry(max_retries=3, initial_delay=1.0)
def call():
    return client.complete("Hello")

Testing

cd llm-seam
pytest tests/

Dependencies

  • anthropic>=0.122.0,<2 (1.0.0+ removed temperature/top_p/top_k from Messages.create; AnthropicProvider.complete() drops those three and emits a UserWarning if you pass them — use extra_body={"temperature": ...} if the target model still accepts it)
  • openai>=3.1.0 (also used by OllamaProvider, which talks to Ollama's OpenAI-compatible API — no extra required)
  • claude-agent-sdk>=0.2.139 (optional, [sdk] extra)

License

MIT

Download files

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

Source Distribution

llm_seam-0.3.1.tar.gz (31.5 kB view details)

Uploaded Source

Built Distribution

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

llm_seam-0.3.1-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file llm_seam-0.3.1.tar.gz.

File metadata

  • Download URL: llm_seam-0.3.1.tar.gz
  • Upload date:
  • Size: 31.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for llm_seam-0.3.1.tar.gz
Algorithm Hash digest
SHA256 b08dd98b3400b32f61bd3ce7005f7e01bdd59bce6ae5c453c1ef2c1db5c3df40
MD5 7d64e636f0aebc65a11a3fd4c1deac24
BLAKE2b-256 69ae237b57661398144b23f9beb32a3e2fa710ac8a77f7754ef175a0da6bfbbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_seam-0.3.1.tar.gz:

Publisher: release-llm-seam.yml on m0j0d/libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_seam-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: llm_seam-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for llm_seam-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 041577705fb0441fa3e815128244d4716d9e196e1223aa24c50c4e63d16748cc
MD5 c4434ab9d4dcfe3dfb325175fea75cba
BLAKE2b-256 d130fb58be35b55b8852ce4a88d52d6c0b714390d5c7c9406855d6f88f6dc0ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_seam-0.3.1-py3-none-any.whl:

Publisher: release-llm-seam.yml on m0j0d/libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 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