Skip to content

API stability

This page describes llm-minder's compatibility promise from 1.0 and classifies the public API against it. Coming from 0.x? Read the 1.0 migration guide.

What semver protects

From 1.0, a minor or patch release won't break code that uses the following, except where a name or field is marked provisional below:

  • names exported from llm_minder (__all__) and their documented signatures, fields and defaults, wherever the name is defined (for example CleanupInterruptedError, which lives in a private module);
  • the error and timeout category values in ErrorCategory and TimeoutCategory;
  • ProcessingEvent names and their documented payload keys;
  • the artifact store format (artifact_schema_version 1) and the serialized result schema: files written by one 1.x release load in every later 1.x release;
  • the documented behavior of retries, deadlines, admission, replay and cleanup.

Breaking any of these requires a major release. Additions (new names, new optional parameters, new category values, new payload keys) can arrive in minor releases. A checked-in snapshot of the public API and the documented event payloads (tests/api_snapshot.txt) fails CI on any change that hasn't been reviewed on purpose.

From 1.0, the five configuration classes (ProcessorConfig, RetryConfig, RateLimitConfig, StartupRampConfig and GuardrailConfig) take keyword arguments only, so new fields can go anywhere. Other stable dataclasses, such as LLMWorkItem, can still be built positionally: their field order is frozen, and new fields are appended with defaults. Provisional dataclasses follow their provisional status.

What it doesn't cover

  • Anything in llm_minder._internal, and underscore-prefixed names anywhere.
  • Submodule import paths such as llm_minder.llm_strategies, llm_minder.observers or llm_minder.classifiers. The names work there today, but import them from llm_minder; only the top-level path is covered.
  • Log messages, warning text and exception message text. Match on types and categories, not strings.
  • Exact timing, retry scheduling jitter and performance characteristics.
  • Provisional APIs (below): they can change in a minor release, with a changelog entry.
  • The shape of provider SDK objects in LLMResponse.raw.

Deprecation policy

A name or behavior slated for removal emits a warning for at least one minor release before it is removed; after 1.0, removals happen only in a major release. DeprecationWarning is hidden outside __main__ by default, so run your tests with -W error::DeprecationWarning to catch uses early. Each release's migration guide lists its deprecations.

Deprecated names stay in __all__ until they are removed, so from llm_minder import * warns once for each of them, even if your code uses none, and raises under -W error::DeprecationWarning. Import the names you use explicitly instead. On Python 3.14 an installed google-genai also emits its own DeprecationWarning when llm_minder is imported; add -W "ignore::DeprecationWarning:google.genai.types" after the error filter.

Support policy

  • Python: each supported version until its upstream end of life. 1.0 requires Python 3.11 or newer; v0.32 is the last release for 3.10.
  • Provider SDKs: CI tests each SDK at its declared minimum and at the latest release of every supported major line. A new major line is supported once a CI leg covers it; until then it may install but is untested. A minimum can rise in a minor release when an older SDK can no longer be installed and used, or can't support a documented feature; the changelog says so.
  • Fixes: security and bug fixes go into the latest release.

Classification of the current API

Stable names are covered by the promise above. Provisional names can still change in a minor release. The names and behaviors deprecated in 0.27 and 0.28 were removed in 1.0; see Removed in 1.0.

Entry points and configuration

Name Status
process_prompts, process_stream, call, call_result, llm Stable
ParallelBatchProcessor, LLMCallPool Stable
ProcessorConfig, RetryConfig, RateLimitConfig, StartupRampConfig Stable
GuardrailConfig, AbortMode Stable
ResumePolicy Stable
LLMWorkItem, WorkItemResult, BatchResult, BatchTermination Stable
AttemptTiming, WorkItemTiming, RetryState, TokenUsage, CachedTokenRates Stable
LLMResponse Stable
SimpleBatchProcessor, SimpleWorkItem, SimpleResult Stable
PostProcessorFunc, ProgressCallbackFunc Stable
ErrorCategory, TimeoutCategory Stable
AttemptUsage Provisional (new in 0.27, with the token and cost budget)
CacheGroupTracker, CacheFloorBreach Provisional (new in 0.30, with the cache-group statistics)

Strategies, models and classifiers

Name Status
LLMCallStrategy, ModelStrategy, CallableStrategy, CallOutcome Stable
GeminiStrategy, OpenAIStrategy, OpenRouterStrategy, DeepSeekStrategy, PydanticAIStrategy Stable
GeminiModel, GeminiCachedModel, OpenAIModel, OpenAICompatibleModel, OpenRouterModel, DeepSeekModel Stable
LLMModel, ManagedLLMModel, MetadataExtractor Stable
ErrorClassifier, ErrorInfo, DefaultErrorClassifier Stable
GeminiErrorClassifier, OpenAIErrorClassifier, OpenRouterErrorClassifier, PydanticAIErrorClassifier Stable
RateLimitStrategy, ExponentialBackoffStrategy, FixedDelayStrategy Stable
TokenEstimate, TokenEstimator, CharacterTokenEstimator Stable
pydantic_json_parser, strip_code_fences Stable
provider_call, attach_token_usage Provisional (new in 0.32, for custom execute() overrides)
Grounding, GroundingSource, ToolCall Stable (typed provider-output views)

The typed provider-output views .grounding, .reasoning and .tool_calls on LLMResponse and WorkItemResult are stable, and so are the grounding, reasoning and tool_calls metadata keys they read. Real Gemini, OpenAI, OpenRouter and DeepSeek runs confirmed their shapes before 1.0. .logprobs and the logprobs key stay provisional, because they carry each provider's own structure. Other provider metadata keys (such as finish_reason or model) are provisional diagnostics. The metadata dict itself is stable.

Middleware, observers and artifacts

Name Status
Middleware, BaseMiddleware Stable
ProcessorObserver, BaseObserver, ProcessingEvent, MetricsObserver Stable
ArtifactStore, JsonlArtifactStore, SqliteArtifactStore, SqliteDurability, ArtifactIdentity Stable

Exceptions

Every exception type below subclasses LLMMinderError.

Name Status
LLMMinderError Stable
AsyncBatchLLMError Stable (the pre-1.0 name of LLMMinderError, kept as an alias through 1.x)
ItemDeadlineExceeded, BatchDeadlineExceeded, BatchAbortedError, BatchBudgetExceeded Stable
BatchAdmissionClosedError, BatchInterruptedError, StreamFinalizationError, CleanupInterruptedError Stable
FrameworkTimeoutError, RateLimitRetriesExceeded, TokenTrackingError, LLMCallError Stable
EmptyResponseError, ProviderResponseError, MiddlewareContractError, QuotaScopeError Stable
TruncatedResponseError Provisional (new in 1.0, with EmptyResponseError.reason)
StructuredOutputSchemaError, StructuredOutputValidationError Stable
TokenEstimationError, TokenEstimatorRequired, TokenEstimateExceedsLimit Stable
ArtifactError, ArtifactIdentityError, ArtifactFormatError, ArtifactIOError, ArtifactSerializationError Stable
ResultSerializationError Stable

BatchBudgetExceeded, ErrorCategory.BATCH_BUDGET_EXCEEDED and termination.kind == "budget_exceeded" are stable outcome vocabulary: code that catches or matches them keeps working. The budget configuration that produces them is provisional (below).

Testing helpers

llm_minder.testing exports MockAgent, MockResult, FakeStrategy, mock_strategy and FakeRateLimitError. They are Provisional: import them from llm_minder.testing (they aren't in the top-level __all__), and expect possible changes in a minor release, announced in the changelog.

Removed in 1.0

Everything deprecated in 0.27 and 0.28 is gone. Removed top-level names raise AttributeError with a hint naming the replacement, and the removed ProcessorConfig and ParallelBatchProcessor keyword arguments raise TypeError with one.

Removed Replacement
LLMGateway (also from llm_minder.gateway) LLMCallPool
BatchProcessor ParallelBatchProcessor
ProcessingStats The dict from get_stats()
grounding_metadata_extractor Nothing: built-in Gemini models already emit grounding
ParallelBatchProcessor(max_workers=..., timeout_per_item=..., rate_limit_cooldown=...) ParallelBatchProcessor(config=ProcessorConfig(...))
ProcessorConfig(timeout_per_item=...) and ProcessorConfig.timeout_per_item attempt_timeout
WorkItemResult.gemini_safety_ratings result.metadata["safety_ratings"]
BatchResult.cache_hit_rate() (called) BatchResult.cache_hit_rate (property)
Integer prompts in process_prompts / process_stream String prompts
2-tuple return from LLMCallStrategy.execute() (output, tokens, metadata); it now fails the item
effective_input_tokens() / estimated_cost() with no cached-token rate Pass a CachedTokenRates constant as cached_token_rate
Positional arguments to ProcessorConfig, RetryConfig, RateLimitConfig, StartupRampConfig, GuardrailConfig Keyword arguments
ProcessorConfig(enable_detailed_logging=True) (it never had an effect) Set the llm_minder logger's level (Logging)

ParallelBatchProcessor takes keyword arguments only. Removing gemini_safety_ratings shifts the positional order of the WorkItemResult fields after it; build results by keyword.

Renamed in 1.0

The package was published as async-batch-llm through v0.32. From 1.0 it is llm-minder:

Before From 1.0
pip install async-batch-llm pip install llm-minder
import async_batch_llm import llm_minder
logging.getLogger("async_batch_llm") logging.getLogger("llm_minder")
Prometheus metrics async_batch_llm_* llm_minder_*
AsyncBatchLLMError LLMMinderError (the old name still works as an alias)

Exported names, signatures and behavior don't change with the rename. Artifact and result files keep their format, including the async-batch-llm-result schema name, so files written by earlier releases still load and resume.

Provisional in 1.0

  • Budget API. AttemptUsage and the GuardrailConfig fields max_total_tokens, max_total_cost and cost_function are new in 0.27 and stay provisional in 1.0, so their shape can still change in a minor release once they have seen real use.
  • Cache-group statistics. CacheGroupTracker, CacheFloorBreach, the GuardrailConfig fields min_cache_hit_rate and cache_hit_window, the cache_group and cache_miss_reason metadata keys, the cache_groups statistics, LLMCallPool.cache_stats(), reset_cache_stats(), the pool's cache_tracker argument and property, ErrorCategory.CACHE_HIT_RATE_BELOW_FLOOR, the models' prompt_cache_key and cache_group options, and the per-call cache_group config key are new in 0.30 and provisional.
  • LLMCallPool.termination and LLMCallPool.resume() are new in 0.31 and provisional.
  • Custom execute() support. provider_call, attach_token_usage and ModelStrategy.attempt_generation_config() are new in 0.32 and provisional. The _failed_token_usage exception attribute they rely on is stable.
  • Empty-response reasons. EmptyResponseError.reason and .provider_reason, TruncatedResponseError and ErrorCategory.RESPONSE_TRUNCATED are new in 1.0 and provisional.
  • Log probabilities. .logprobs and the logprobs metadata key pass through each provider's own structure and stay provisional; the other typed views are stable (see above).