aihi-models
[English] | 简体中文
Provider-neutral model contracts and provider adapters for AIHI.
aihi-models is the lowest Python layer in the repository. It normalizes messages, streamed output, tool definitions, usage, provider failures, and wire serialization so the agent runtime does not depend on one vendor SDK.
Why this package exists
The package deliberately owns model-facing primitives only:
- immutable request/response and content-block contracts;
- stable system blocks and provider-neutral prompt-cache hints;
- normalized streaming chunks for text and tool input;
- provider adapters and transport abstractions;
- typed provider errors and context-length classification;
- versioned message serialization and token estimation.
It does not own model routing, a gateway, application configuration, prompt policy, sessions, tools, or an agent loop. Those belong to the application/runtime layers.
Supported providers
| Adapter | Use case | Notes |
|---|---|---|
OpenAIProvider |
OpenAI Chat Completions | Configure the endpoint and API key explicitly. |
AnthropicProvider |
Anthropic Messages API | Normalizes Anthropic content blocks to the common stream model. |
DeepSeekProvider |
DeepSeek chat models | Uses DeepSeek's OpenAI-compatible API by default. |
OpenAICompatibleProvider |
Other OpenAI-compatible endpoints | Requires an explicit full base_url for the chat-completions endpoint. |
FakeProvider |
Tests and local contract fixtures | Deterministic scripted responses; no network access. |
Providers are flat modules under src/aihi/models/providers. Credentials and model selection are supplied by the application; constructors do not silently read environment variables.
Installation
Published release:
python -m pip install aihi-models==0.1.0
See the PyPI project page. For repository development:
From the repository workspace:
uv sync
For a local editable install:
uv pip install -e packages/aihi/models
The package requires Python 3.11+ and depends on httpx for the default HTTP transport.
Minimal example
import asyncio
from aihi.models import FakeProvider, FakeStep, Message, ModelRequest
provider = FakeProvider([
FakeStep(text="Hello from a deterministic provider."),
])
request = ModelRequest(
model="fake-model",
messages=[Message.text("user", "Say hello.")],
)
async def main() -> None:
chunks = [chunk async for chunk in provider.stream(request)]
print(chunks[-1])
asyncio.run(main())
Providers also expose normalized asynchronous streaming. A stream is made of typed chunks such as BlockStart, TextDelta, ToolInputDelta, and MessageEnd, allowing the runtime to render or persist output without vendor-specific branching.
Public API
The package root re-exports the stable building blocks:
- Contracts:
Message,ModelRequest,ModelResponse,ModelToolDefinition,CachePolicy,Capabilities, content blocks, andUsage. - Providers:
OpenAIProvider,AnthropicProvider,DeepSeekProvider,OpenAICompatibleProvider, andFakeProvider. - Errors:
ProviderError,ProviderHTTPError,ProviderProtocolError,ProviderTimeout, andProviderContextLengthError. - Serialization:
encode_message,decode_message,ModelMessageEnvelope, andMESSAGE_SCHEMA_VERSION. - Transport:
HttpxTransport,JsonTransport, andHttpRequest. - Token accounting:
estimate_model_request_tokenscovers compatibility/system blocks, model-visible tool definitions, and messages; Providercount_tokens()implementations use the same complete request boundary.
Import from aihi.models rather than reaching into private modules.
Prompt caching
ModelRequest.system_blocks separates one contiguous stable prefix from the dynamic system suffix.
TextBlock(stable_prefix=True) blocks must come first. CachePolicy is an optimization hint; an
adapter that does not support it sends the same semantic prompt without cache-specific fields.
from aihi.models import CachePolicy, ModelRequest, TextBlock
request = ModelRequest(
model="model-id",
messages=messages,
system_blocks=(
TextBlock("Stable base instructions", stable_prefix=True),
TextBlock("Dynamic workspace context"),
),
cache_policy=CachePolicy(key="aihi:prompt-cache:v1:..."),
)
The Agent Runtime derives the key from Provider family, Model, canonical tool definitions, and stable
system blocks. OpenAI receives a cache-family key, Anthropic receives one cache-control breakpoint,
DeepSeek relies on its automatic prefix cache, and unprofiled OpenAI-compatible endpoints remain a
semantic no-op. Usage.cached_input_tokens and Usage.cache_write_input_tokens normalize cache reads
and writes when a Provider reports them. Legacy system_prompt requests remain supported.
Cache counters are additive compatibility fields, so old persisted usage remains decodable:
from aihi.models import Usage
usage = Usage.from_dict({"input_tokens": 120, "cached_input_tokens": 80})
assert usage.cache_write_input_tokens == 0
estimate_model_request_tokens covers the compatibility system prompt, system blocks, model-visible
tool definitions and messages. Runtime pressure decisions therefore use the whole normalized request,
not message history alone.
Compatibility and errors
Provider adapters map vendor responses into one common response/stream vocabulary and classify failures into stable error types. Callers should handle ProviderTimeout, HTTP failures, protocol failures, and context-length failures separately when deciding whether to retry, compact context, or surface an error.
Message envelopes are versioned. Unknown schema versions raise UnsupportedMessageSchema; applications should persist the versioned envelope rather than relying on a provider's native JSON.
Development
Run package tests and repository-wide static checks from the root:
uv run pytest packages/aihi/models/tests
uv run ruff check packages/aihi/models
uv run mypy
Build a wheel without resolving dependencies from the network:
uv run python -m build --wheel --no-isolation packages/aihi/models
Security notes
- Pass API keys from the application boundary and keep them out of model messages and persisted events.
- Treat provider response text and tool arguments as untrusted input.
- Use the default
httpxtransport or provide a transport with equivalent timeout and TLS behavior. - The fake provider is intended for tests; it is not a fallback for production failures.
Related packages
aihi-agentbuilds the provider-neutral runtime on these contracts.aihi-code-agentcomposes providers into a coding-agent application.- Repository architecture
Metadata
Release files for aihi-models 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| aihi_models-0.2.0.tar.gz | 23.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aihi_models-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.0 kB
Release files / aihi_models-0.2.0.tar.gz
| Download URL | aihi_models-0.2.0.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
459c09003a77d1e6ef234ae947736698473bae055e3e2d24b8f7040a44c07f7a
|
|
BLAKE2b-256 checksum How to use checksums |
196dfe746eb46f3492fa0e3683cd5a59d3004b23682c17288b45847d6774ac54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / aihi_models-0.2.0-py3-none-any.whl
| Download URL | aihi_models-0.2.0-py3-none-any.whl |
|---|---|
| Size | 25.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1eb94bf9270ba9f19a7c99304c94d35947ca8b61e47648a7522c6b304d131822
|
|
BLAKE2b-256 checksum How to use checksums |
1145df29f7c3d6eb14528eaeb8631a825dd8da8a97897a411f21f99b30d82003
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for aihi-models 0.2.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.