Skip to main content

llm-stopcheck

EN: A tiny, dependency-free Python library and CLI that catches silent LLM failures: a response with HTTP 200 that is cut off at max_tokens, empty because a reasoning model spent its whole budget thinking, content-filtered, or missing a finish reason. It returns a stable error code and a retry hint instead of letting half an answer flow downstream.

Quick start (English)

pip install .        # no dependencies, Python 3.10+
import llm_stopcheck as sc

verdict = sc.check(response, max_tokens=3000)   # never raises; bad input gives malformed_response
if not verdict.ok:
    print(sc.format_record(verdict, model="my-model"))
    if verdict.hint == sc.HINT_RAISE_MAX_TOKENS:
        ...  # retry with a higher output cap

text = sc.ensure(response)   # returns the text, or raises TruncatedError / EmptyOutputError / ...

Retry with a higher output cap when check() says raise_max_tokens (call is your own function that sends the request with the given max_tokens and returns the response):

import llm_stopcheck as sc

def complete_with_retry(call, max_tokens=1000, attempts=3):
    for attempt in range(attempts):
        response = call(max_tokens=max_tokens)
        verdict = sc.check(response, max_tokens=max_tokens)
        if verdict.hint != sc.HINT_RAISE_MAX_TOKENS or attempt == attempts - 1:
            break
        max_tokens *= 2   # truncated: try again with a doubled cap
    return sc.ensure(response, max_tokens=max_tokens)   # text, or a typed error if still failing

response is parsed OpenAI-compatible JSON (OpenAI, LiteLLM, OpenRouter, vLLM, Ollama, DeepSeek) or an object with model_dump(), to_dict() or dict(). native_finish_reason is checked too, because LiteLLM and OpenRouter can normalise a MAX_TOKENS stop to stop.

code meaning hint
ok fine (warnings near_limit / at_limit when max_tokens is given) -
truncated output cap reached, the answer is cut off raise_max_tokens
truncated_empty output cap reached with empty content raise_max_tokens
reasoning_exhausted the budget went to reasoning, no answer raise_max_tokens
tool_call_truncated tool-call arguments are incomplete raise_max_tokens
empty_output normal stop but empty content retry
content_filtered blocked by a provider filter fail
refusal the model refused fail
missing_finish_reason no finish reason (cut off?) retry
unknown_finish_reason unrecognised value retry
malformed_response not the expected shape retry

CLI: llm-stopcheck response.json --max-tokens 3000 or curl ... | llm-stopcheck - --json. Exit code 0 = ok, 1 = failed verdict, 2 = usage or unreadable input. Log lines are sanitised (ASCII, no newlines, = replaced), so model output cannot forge a log record. Tests: python -m unittest discover -s tests -t .

Miksi

LLM-kutsu voi onnistua (HTTP 200) ja silti olla käyttökelvoton. Oikea tapaus: reasoning-malli käytti koko max_tokens-budjetin ajatteluun, content oli tyhjä ja finish_reason oli length. Päivittäinen raportti lähetettiin ilman tiivistystä, eikä mikään kertonut miksi. llm-stopcheck muuttaa vastauksen pieneksi tuomioksi (Verdict), jonka koodi on vakaa ja jonka voi kirjata lokiin ja hälyttää.

Asennus

pip install .

Ei riippuvuuksia, Python 3.10+.

Käyttö

import llm_stopcheck as sc

response = client.chat.completions.create(..., max_tokens=3000)

verdict = sc.check(response, max_tokens=3000)   # ei koskaan heitä poikkeusta
if not verdict.ok:
    log.error(sc.format_record(verdict, model="gpt-x"))
    if verdict.hint == sc.HINT_RAISE_MAX_TOKENS:
        ...  # yritä uudelleen isommalla rajalla

text = sc.ensure(response)  # palauttaa tekstin tai heittää TruncatedError / EmptyOutputError / ...

Uudelleenyritys isommalla rajalla: katso complete_with_retry englanninkielisestä pikaoppaasta ylhäällä. Se kaksinkertaistaa max_tokens-rajan niin kauan kuin check() antaa vihjeen raise_max_tokens (enintään attempts yritystä) ja palauttaa tekstin tai heittää tyypitetyn virheen.

Toimii jäsennetyllä OpenAI-yhteensopivalla JSONilla (OpenAI, LiteLLM, OpenRouter, vLLM, Ollama, DeepSeek) sekä olioilla, joilla on model_dump(), to_dict() tai dict(). Lisäksi native_finish_reason tarkistetaan: LiteLLM/OpenRouter voi normalisoida MAX_TOKENS-lopetuksen muotoon stop.

Koodit

code merkitys hint
ok kunnossa (varoitukset near_limit / at_limit) -
truncated token-raja täyttyi, vastaus katkesi raise_max_tokens
truncated_empty raja täyttyi, sisältö tyhjä raise_max_tokens
reasoning_exhausted budjetti meni ajatteluun, vastausta ei tullut raise_max_tokens
tool_call_truncated työkalukutsun argumentit keskeneräiset raise_max_tokens
empty_output normaali lopetus mutta tyhjä sisältö retry
content_filtered palveluntarjoajan suodatin esti fail
refusal malli kieltäytyi fail
missing_finish_reason ei finish_reasonia (katkennut?) retry
unknown_finish_reason tuntematon arvo retry
malformed_response vastaus ei ole odotettua muotoa retry

CLI

llm-stopcheck response.json --max-tokens 3000
curl ... | llm-stopcheck - --json

Tulostus: stopcheck=reasoning_exhausted finish=length native=- tokens=3000/3000 reasoning_tokens=3000 hint=raise_max_tokens. Poistumiskoodi 0 = ok, 1 = epäonnistunut tuomio, 2 = käyttö- tai lukuvirhe.

format_record puhdistaa arvot (vain ASCII, ei rivinvaihtoja, = korvataan), joten lokirivin väärentäminen mallin tuotoksella ei onnistu.

Vaihtoehtoja ja miksi tämä

Tarkistus löytyy yleensä kehyskohtaisina korjauksina tai blogiohjeina, ei pienenä erillisenä kirjastona. Tämä on tarkoituksella pieni: ei riippuvuuksia, ei verkkoa, ei kehysriippuvuutta. Hälytys (Telegram, healthchecks.io) jätetään kutsujan tehtäväksi; format_record ja poistumiskoodit riittävät sen kytkemiseen.

Testit

python -m unittest discover -s tests -t .

Lisenssi

MIT

Metadata

Release files for llm-stopcheck 0.1.0

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

Source distribution (sdist)

Source distribution for llm-stopcheck 0.1.0
File Size Uploaded Provenance
llm_stopcheck-0.1.0.tar.gz 15.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for llm-stopcheck 0.1.0
File Interpreter ABI Platform
llm_stopcheck-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.9 kB

Release files / llm_stopcheck-0.1.0.tar.gz

Download URL llm_stopcheck-0.1.0.tar.gz
Size 15.8 kB
Tags Source
SHA-256 checksum
How to use checksums
ab7eee8db702b58641085afed0fab9510a2716ab34802cb237aaa60e282ad38b
BLAKE2b-256 checksum
How to use checksums
de2106b36441bac4de865450c1b391f58439d52f64b560cff4ba1162aae772f2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / llm_stopcheck-0.1.0-py3-none-any.whl

Download URL llm_stopcheck-0.1.0-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af9c4617c3589b08b7af1baae475bb372cec711732c7f7e8668ba7d0866aced2
BLAKE2b-256 checksum
How to use checksums
aeeec4c928b3a78205fe52c9044c690f06df75f8b290c0e2bed1f90f0ee5466b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for llm-stopcheck 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for llm_stopcheck-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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