Skip to main content

A lightweight Model I/O normalization layer for OpenAI-compatible LLM calls.

Project description

llm-io-normalizer

llm-io-normalizer is a lightweight Model I/O normalization layer for OpenAI-compatible LLM calls. It is built for applications that call both tested models and judge models and need a stable result contract instead of provider-specific response parsing.

It normalizes common LLM response differences such as:

  • message.content vs message.reasoning
  • delta.content vs delta.reasoning / delta.reasoning_content
  • <think>...</think> reasoning mixed into normal content
  • stream vs non-stream completion behavior
  • successful HTTP responses that contain reasoning but no final answer
  • final JSON extraction from model output

The public contract is intentionally small and stable:

result.answer_text
result.reasoning_text
result.ok
result.error_type
result.error_message

Business code should depend on these normalized fields instead of reading raw provider fields directly.

Install

After publishing to PyPI:

pip install llm-io-normalizer

From a local checkout:

pip install -e .

For development:

pip install -e ".[dev]"

Quick start

import asyncio

from llm_io_normalizer import LLMGateway, LLMRequest, LLMRole


async def main() -> None:
    gateway = LLMGateway()

    result = await gateway.generate(
        LLMRequest(
            role=LLMRole.JUDGE_MODEL,
            model_name="your-model-name",
            base_url="https://example.com/v1",
            api_key="YOUR_API_KEY",
            messages=[
                {"role": "system", "content": "You are a strict JSON judge."},
                {"role": "user", "content": "Return {\"result\": 2}."},
            ],
            # Judge models should usually prefer stable non-stream output.
            stream=False,
            enable_thinking=False,
            temperature=0,
            max_tokens=1024,
        )
    )

    result.require_ok()
    print(result.answer_text)


asyncio.run(main())

Core concepts

Tested model calls

LLMRole.TESTED_MODEL is for the model being evaluated or observed.

Default behavior:

  • streams by default unless stream=False is provided
  • can collect native reasoning fields from compatible providers
  • can split <think>...</think> blocks out of the answer
  • returns clean answer_text and separate reasoning_text
  • can retry without thinking when the provider returns no final answer

Judge model calls

LLMRole.JUDGE_MODEL is for scoring, evaluation, moderation, ranking, or structured judgment tasks.

Default behavior:

  • uses non-stream mode by default unless stream=True is provided
  • is designed for stable final output, especially JSON scoring results
  • usually pairs well with enable_thinking=False and temperature=0
  • marks the call as ok=False with error_type="EMPTY_ANSWER" when the provider returns reasoning but no final answer

JSON output helper

from llm_io_normalizer.normalizers import extract_json_object

obj = extract_json_object('```json\n{"result": 2}\n```')
assert obj == {"result": 2}

Examples

The examples/ directory contains runnable examples for:

  • tested-model calls
  • judge-model calls
  • a tested-model → judge-model evaluation pipeline

Use environment variables for provider credentials and endpoints when running examples:

export LLM_BASE_URL="https://your-provider.example/v1"
export LLM_API_KEY="your-api-key"
export LLM_MODEL="your-model-name"
python examples/judge_model.py

Development

pip install -e ".[dev]"
ruff check .
pytest
python -m build

Release

Recommended PyPI release mode is Trusted Publishing from GitHub Actions. Configure the PyPI project to trust this repository workflow, then publish a GitHub release tag such as v0.1.0.

Scope

This package is intentionally not a full API gateway. It does not implement authentication, rate limiting, billing, routing dashboards, or multi-tenant governance. Those can be handled by an outer gateway such as Kong, APISIX, Envoy, Portkey, or other infrastructure.

llm-io-normalizer focuses on the reusable Python SDK layer:

  • Model I/O normalization
  • reasoning / answer separation
  • stream / non-stream fallback
  • tested-model and judge-model call policies
  • unified result/error contract
  • simple JSON object extraction from model output

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

llm_io_normalizer-0.1.0.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

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

llm_io_normalizer-0.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file llm_io_normalizer-0.1.0.tar.gz.

File metadata

  • Download URL: llm_io_normalizer-0.1.0.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_io_normalizer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dc710325c2af656f4c9027a9aa7dfbda916d9b65e0ccd408d771bd5ff531409f
MD5 f29257870810d999cc300fbdba256900
BLAKE2b-256 d61af4a88bd19f4f28dbb14f3240823ac4c9c0a7654a21bd551063e7a38e17cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_io_normalizer-0.1.0.tar.gz:

Publisher: publish.yml on wanghesong2019/llm-io-normalizer

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_io_normalizer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_io_normalizer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dff798bed2bacb7c4450f84bad4d3eff48059e662b0f7225c618485e26ea44b3
MD5 035349cf44427da10027e1ecea1563e3
BLAKE2b-256 0d0365ff8175dbcdcce504efdbdb63b797d212bbd33372fe9aad4ac51c0e786e

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_io_normalizer-0.1.0-py3-none-any.whl:

Publisher: publish.yml on wanghesong2019/llm-io-normalizer

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