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 exampleCleanupInterruptedError, which lives in a private module); - the error and timeout category values in
ErrorCategoryandTimeoutCategory; ProcessingEventnames and their documented payload keys;- the artifact store format (
artifact_schema_version1) 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.observersorllm_minder.classifiers. The names work there today, but import them fromllm_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.
AttemptUsageand theGuardrailConfigfieldsmax_total_tokens,max_total_costandcost_functionare 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, theGuardrailConfigfieldsmin_cache_hit_rateandcache_hit_window, thecache_groupandcache_miss_reasonmetadata keys, thecache_groupsstatistics,LLMCallPool.cache_stats(),reset_cache_stats(), the pool'scache_trackerargument and property,ErrorCategory.CACHE_HIT_RATE_BELOW_FLOOR, the models'prompt_cache_keyandcache_groupoptions, and the per-callcache_groupconfig key are new in 0.30 and provisional. LLMCallPool.terminationandLLMCallPool.resume()are new in 0.31 and provisional.- Custom
execute()support.provider_call,attach_token_usageandModelStrategy.attempt_generation_config()are new in 0.32 and provisional. The_failed_token_usageexception attribute they rely on is stable. - Empty-response reasons.
EmptyResponseError.reasonand.provider_reason,TruncatedResponseErrorandErrorCategory.RESPONSE_TRUNCATEDare new in 1.0 and provisional. - Log probabilities.
.logprobsand thelogprobsmetadata key pass through each provider's own structure and stay provisional; the other typed views are stable (see above).