Skip to main content

Cached LLM client with Ollama + Anthropic provider dispatch, fixture mode, and JSON-schema-strict completions.

Project description

llm-client-kit

Cached, fixture-aware LLM client with Ollama (default) and Anthropic provider dispatch. Carved out of resume-builder/src/resume_builder/llm_client.py so it can be shared across internal Python apps without each app rolling its own dispatch + caching layer.

PyPI: jsmithpkp-llm-client-kit. Import path stays llm_client_kit (PyPI distribution name and Python import name are allowed to differ).

Install

pip install jsmithpkp-llm-client-kit

For the Anthropic provider path, install the extra:

pip install 'jsmithpkp-llm-client-kit[anthropic]'

Public API

from llm_client_kit import (
    LLMClient,
    LLMResponse,
    LLMEndpointUnreachableError,
    AnthropicProviderError,
    PROVIDER_OLLAMA,
    PROVIDER_ANTHROPIC,
)

Construct from env (resume-builder-compatible)

client = LLMClient.from_env()  # reads RESUME_BUILDER_LLM_* env vars
result = client.complete_json(
    namespace="my_stage",
    system_prompt="You are a JSON-only classifier...",
    user_payload={"subject": "...", "body": "..."},
)

Env vars honored:

Env var Default Notes
RESUME_BUILDER_LLM_PROVIDER ollama ollama or anthropic
RESUME_BUILDER_LLM_API_URL provider-default OpenAI-compat for Ollama; ignored by Anthropic adapter
RESUME_BUILDER_LLM_MODEL llama3.1:8b / claude-sonnet-4-6 per-provider default
RESUME_BUILDER_LLM_API_KEY / ANTHROPIC_API_KEY unset required for Anthropic
RESUME_BUILDER_LLM_TIMEOUT_SECONDS 90 per-request timeout
RESUME_BUILDER_LLM_TIMEOUT_<NAMESPACE> unset per-stage timeout override
RESUME_BUILDER_LLM_MAX_TOKENS 2048 Anthropic only
RESUME_BUILDER_LLM_FIXTURE 0 fixture mode (no network calls; cache-only)
RESUME_BUILDER_LLM_CACHE_DIR .llm_cache / tests/fixtures/llm_cache (fixture mode) response cache location

The env var prefix RESUME_BUILDER_LLM_* is preserved from the carve-out source for v0.1.0 backward compat. A future release will parameterize the prefix so consumers can use their own namespace.

Construct directly (no env)

from pathlib import Path
from llm_client_kit import LLMClient, PROVIDER_OLLAMA

client = LLMClient(
    endpoint="http://localhost:11434/v1/chat/completions",
    model="llama3.2:3b",
    cache_dir=Path("./.cache"),
    fixture_mode=False,
    timeout_seconds=30.0,
    provider=PROVIDER_OLLAMA,
)

Error contract

complete_json documents three failure modes:

  • ValueError — invalid / non-object JSON response, malformed cache payload.
  • RuntimeError — provider-agnostic failures (cache I/O, fixture-mode miss) AND Ollama-path transport/parse failures.
  • LLMEndpointUnreachableError (RuntimeError subclass) — connection refused / DNS failure / host unreachable, on the Ollama path.
  • AnthropicProviderError (NOT a RuntimeError subclass) — any failure on the Anthropic path. Intentionally outside the (RuntimeError, ValueError) fallback chain: a paid API call halting loudly is better than silently degrading.

See class docstrings for the full rationale.

Releasing

Releases are automated. Tag-triggered workflow at .github/workflows/release.yml:

  1. Bump version in pyproject.toml and __version__ in src/llm_client_kit/__init__.py on a PR.
  2. After the PR merges, tag vX.Y.Z on main and push the tag.
  3. The release workflow runs gitleaks against the working tree AND full git history — any finding aborts the workflow before the build. Then python -m build produces sdist + wheel, and pypa/gh-action-pypi-publish uploads via PyPI Trusted Publisher OIDC (no API token stored in repo secrets).
# example bump-and-release flow
git switch main && git pull
# (PR merged that bumps version to 0.1.4)
git tag v0.1.4
git push origin v0.1.4
# watch: gh run watch

The secret-scan step is mandatory and is the only thing standing between an accidentally-committed credential and a published wheel. Do not edit the workflow to skip it without first understanding what it catches.

Project details


Download files

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

Source Distribution

jsmithpkp_llm_client_kit-0.1.3.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

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

jsmithpkp_llm_client_kit-0.1.3-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file jsmithpkp_llm_client_kit-0.1.3.tar.gz.

File metadata

  • Download URL: jsmithpkp_llm_client_kit-0.1.3.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for jsmithpkp_llm_client_kit-0.1.3.tar.gz
Algorithm Hash digest
SHA256 63681fed90152dc266f34aa424d679e28dfda219bfeea19e3d9aced277629fab
MD5 0b4335588d475ca94ea2f271b3beabde
BLAKE2b-256 66f0499c1df5fcd99c681e589016c8cfde48600caf457c490b439624f1ef56e6

See more details on using hashes here.

Provenance

The following attestation bundles were made for jsmithpkp_llm_client_kit-0.1.3.tar.gz:

Publisher: release.yml on jsmithpkp21/llm-client-kit

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

File details

Details for the file jsmithpkp_llm_client_kit-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for jsmithpkp_llm_client_kit-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 99d7877923c3508cc61365b920e6c50210b53f56c07d395c37cf8e1e97305b21
MD5 4b4ffc24a4da021b8491e1dcc34d9129
BLAKE2b-256 8072a6bde98f578a8634fa9e29ed855eb722213c34a9e3a0d661282471c027ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for jsmithpkp_llm_client_kit-0.1.3-py3-none-any.whl:

Publisher: release.yml on jsmithpkp21/llm-client-kit

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page