> built 2026-09-22 15:02 UTC from 3840e31 (master) · aix 0.0.42. Details: build_info.json

# index.html.md

<!-- generated by epythet -->

# AIX: Artificial Intelligence eXtensions

A clean, pythonic facade for common AI operations that abstracts away provider-specific details and complexities.

**Philosophy**: Make AI interactions as simple and intuitive as Python itself, while maintaining the power and flexibility needed for production use.

## Installation

```bash
pip install aix
```

`aix` is a headless facade and keeps its hard dependencies minimal — the base
install only pulls in [`litellm`](https://github.com/BerriAI/litellm) (the
provider backend) and `config2py` (for reading API keys / config). Optional
capabilities live in extras and are imported lazily, raising a clear install
hint if their backend is missing:

```bash
pip install "aix[image]"      # image generation helpers (Pillow)
pip install "aix[video]"      # local text-to-video (diffusers, torch)
pip install "aix[discovery]"  # model discovery via OpenRouter / Ollama (requests)
pip install "aix[google]"     # legacy Google Gemini backend
pip install "aix[openai]"     # legacy OpenAI (oa) backend
pip install "aix[all]"        # all optional backends
```

## Quick Start

```python
from aix import chat, embeddings, prompt_func, models
from aix import generate_image, text_to_speech, transcribe

# Simple chat
response = chat("What is 2+2?")
print(response)  # "The answer is 4."

# Create prompt-based functions
translate = prompt_func("Translate to French: {text}")
result = translate(text="Hello world")
print(result)  # "Bonjour le monde"

# Get embeddings
vecs = list(embeddings(["hello", "world"]))
print(len(vecs))  # 2

# Generate images
image = generate_image("A serene mountain landscape")
image.save("landscape.png")

# Text to speech
audio = text_to_speech("Hello, world!")
audio.save("hello.mp3")

# Speech to text
text = transcribe("recording.mp3")

# Discover available models
models.discover()
print(list(models)[:5])  # ['openai/gpt-4o', 'openai/gpt-4o-mini', ...]
```

## Configuration

`aix` works with zero configuration — every function ships with sensible default
models. When you want to change *which model a function uses by default* (and
related parameters like temperature, image size, or TTS voice), there is a single
source of truth: `aix.config`.

Defaults are resolved in layers, **highest precedence first**:

1. **Explicit call argument** — `chat("hi", model="...")` always wins.
2. **Runtime override** — `aix.configure(...)` (persistent) or `aix.using(...)` (scoped).
3. **Environment variables** — `AIX_CHAT_MODEL`, `AIX_CHAT_TEMPERATURE`,
   `AIX_EMBEDDING_MODEL`, `AIX_IMAGE_MODEL`, `AIX_TTS_MODEL`, `AIX_TTS_VOICE`,
   `AIX_TRANSCRIPTION_MODEL`, …
4. **User config file** — a TOML file (see below).
5. **Shipped defaults** — the built-in values.

```python
import aix

# Inspect the active configuration
cfg = aix.get_config()
cfg.chat.model  # 'gpt-4.1-mini'
cfg.embeddings.model  # 'text-embedding-3-small'

# Persistently change a default (everything below an explicit arg still respects it)
aix.configure(chat_model="anthropic/claude-sonnet-4", chat_temperature=0.2)

# Scoped override that restores on exit
with aix.using(chat_model="openai/gpt-4o-mini"):
    aix.chat("quick + cheap question")
# back to the configured default here
```

### Semantic aliases

Pass an intent-level name instead of a concrete model id. Shipped aliases:
`fast` (cheap/low-latency), `best` (highest quality), `cheap` (cheapest).

```python
aix.chat("hard question", model="best")  # -> resolves via the alias table
aix.chat("quick question", model="fast")

# Add or override aliases (merges with the shipped set)
aix.configure(aliases={"smart": "anthropic/claude-sonnet-4"})
aix.resolve_model("smart")  # 'anthropic/claude-sonnet-4'
```

Aliases share a namespace with literal model ids: a name that is not a registered
alias (e.g. `"gpt-4o"`) is passed through unchanged. Inspect available aliases via
`aix.get_config().aliases`.

### Config file

Create a TOML file at your platform’s app-config dir (or point `AIX_CONFIG_FILE`
at any path):

```toml
[chat]
model = "gpt-4.1-mini"
temperature = 1.0

[embeddings]
model = "text-embedding-3-small"

[image]
model = "dall-e-3"
size = "1024x1024"

[audio]
tts_model = "gpt-4o-mini-tts"
tts_voice = "alloy"
transcription_model = "whisper-1"

[aliases]              # semantic names -> concrete ids (override the shipped set)
fast = "gpt-4.1-mini"
best = "anthropic/claude-sonnet-4"
```

Find the active path with `aix.config.config_file_path()`. Environment variables
override file values; explicit call arguments override everything.

## Providing credentials

Every key-requiring function (`chat`, `embeddings`, `generate_image`,
`text_to_speech`, `transcribe`, `generate_video`, …) resolves its API key
through one documented path. The resolution order, highest precedence first:

1. **Explicit argument** — `chat("hi", api_key="sk-...")` (keyword-only, on every
   key-requiring function).
2. **Provider environment variable** — the canonical name for the model’s
   provider (see the table below). A project `.env` is *softly* discovered when
   `python-dotenv` is installed; an explicitly exported variable always wins over
   a `.env` value.
3. **AIX config store** — a per-user store in your app-config folder, keyed by the
   canonical env-var name (so the store and the env layer share one namespace).
4. **(Interactive only) prompt + persist** — in a REPL, AIX can ask once and save
   the key to the config store.

The provider is inferred from the model id, so you rarely name it yourself:

```python
import aix

aix.chat("Hello", model="gpt-4o")  # uses OPENAI_API_KEY
aix.chat("Hi", model="claude-sonnet-4")  # uses ANTHROPIC_API_KEY
aix.chat("Yo", api_key="sk-...")  # explicit key wins

# Check what's discoverable (values are never shown — availability only):
aix.check_keys()
# {'openai': {'available': True, 'env_vars': ['OPENAI_API_KEY'], 'source': 'env'}, ...}
```

When a required key is missing, you get an actionable `MissingCredentialError`
naming *which* key, *how* to set it, and *where* to get one — instead of a cryptic
provider error:

```python
>>> aix.chat("hi", model="gpt-4o")
aix.credentials.MissingCredentialError: No API key found for provider 'openai'
(model 'gpt-4o'). Set OPENAI_API_KEY via one of:
  - export it:  export OPENAI_API_KEY=...
  - add it to a .env file in your project, or
  - store it in the AIX config store under the key 'OPENAI_API_KEY'.
Get a key at: https://platform.openai.com/api-keys
```

### Provider → environment variable

| Provider       | Environment variable                   | Get a key                                   |
|----------------|----------------------------------------|---------------------------------------------|
| OpenAI         | `OPENAI_API_KEY`                       | https://platform.openai.com/api-keys        |
| Anthropic      | `ANTHROPIC_API_KEY`                    | https://console.anthropic.com/settings/keys |
| Google Gemini  | `GEMINI_API_KEY` (or `GOOGLE_API_KEY`) | https://aistudio.google.com/apikey          |
| OpenRouter     | `OPENROUTER_API_KEY`                   | https://openrouter.ai/keys                  |
| Mistral        | `MISTRAL_API_KEY`                      | https://console.mistral.ai/api-keys/        |
| Cohere         | `COHERE_API_KEY`                       | https://dashboard.cohere.com/api-keys       |
| Groq           | `GROQ_API_KEY`                         | https://console.groq.com/keys               |
| DeepSeek       | `DEEPSEEK_API_KEY`                     | https://platform.deepseek.com/api_keys      |
| xAI            | `XAI_API_KEY`                          | https://console.x.ai/                       |
| Perplexity     | `PERPLEXITYAI_API_KEY`                 | https://www.perplexity.ai/settings/api      |
| Runway (video) | `RUNWAY_API_KEY`                       | https://app.runwayml.com/                   |

The full mapping is `aix.PROVIDER_ENV_VARS`. Keys are never logged, and the config
store lives in your user app-config folder — never in the repo.

## Core Features

### 1. Chat Interface

Clean, provider-agnostic chat completions:

```python
from aix import chat

# Simple text prompt
response = chat("Explain quantum computing in one sentence")

# With specific model
response = chat("Hello!", model="gpt-4o-mini")

# With message history
messages = [
    {"role": "user", "content": "My name is Alice"},
    {"role": "assistant", "content": "Nice to meet you, Alice!"},
    {"role": "user", "content": "What's my name?"},
]
response = chat(messages, model="gpt-4o")

# Streaming responses
for chunk in chat("Count to 5", stream=True):
    print(chunk, end="", flush=True)

# Stateful conversations
from aix import chat_with_history

session = chat_with_history("You are a helpful math tutor")
response = session.send("What is 2+2?")
response = session.send("And if I add 3 to that?")  # Remembers context
```

### 2. Embeddings

Generate vector embeddings for semantic search and similarity:

```python
from aix import embeddings, embed, cosine_similarity, find_most_similar

# Batch embeddings
texts = ["cat", "dog", "bird"]
vecs = list(embeddings(texts))

# Single text
vec = embed("Hello, world!")

# Compute similarity
v1 = embed("cat")
v2 = embed("kitten")
similarity = cosine_similarity(v1, v2)  # High similarity

# Find most similar documents
query = "What is machine learning?"
docs = [
    "Machine learning is a type of AI",
    "Python is a programming language",
    "Neural networks are used in deep learning",
]
results = find_most_similar(query, docs, top_k=2)
# Returns: [('Machine learning is a type of AI', 0.95), ...]

# Caching for efficiency
from aix import EmbeddingCache

cache = EmbeddingCache()
v1 = cache.embed("hello")  # API call
v2 = cache.embed("hello")  # From cache
```

### 3. Prompt-Based Functions

Transform natural language prompts into reusable Python functions:

```python
from aix import prompt_func, prompt_to_text, prompt_to_json

# Simple text generation
summarize = prompt_func("Summarize this text: {text}")
summary = summarize(text="Long article...")

# Structured output
extract_person = prompt_func(
    "Extract person information from: {text}",
    output_schema={"name": str, "age": int, "email": str},
)
result = extract_person(text="Contact John at john@example.com. He is 30 years old.")
# Returns: {'name': 'John', 'age': 30, 'email': 'john@example.com'}

# Multiple parameters
compare = prompt_func("Compare {item1} and {item2} in terms of {aspect}")
result = compare(item1="Python", item2="JavaScript", aspect="learning curve")

# Pre-built common functions
from aix import common_funcs

summary = common_funcs.summarize(text="Long article...")
keywords = common_funcs.extract_keywords(text="Article about AI and ML")
sentiment = common_funcs.sentiment(text="I love this product!")

# Create custom collections
from aix import PromptFuncs

my_funcs = PromptFuncs(model="gpt-4o")
my_funcs.add("analyze", "Analyze this code: {code}")
my_funcs.add("fix_bugs", "Fix bugs in: {code}")

result = my_funcs.analyze(code="def foo(): return bar")
```

### 4. Model Discovery & Selection

Discover and filter models across providers:

```python
from aix import models

# Discover available models
models.discover("openrouter")  # Fetch 400+ models from OpenRouter

# List all models
all_models = list(models)

# Get specific model info
info = models["openai/gpt-4o"]
print(info.provider)  # 'openai'
print(info.context_size)  # 128000

# Filter models
openai_models = models.filter(provider="openai")
cheap_models = models.filter(
    custom_filter=lambda m: m.cost_per_token.get("input", 0) < 0.001
)
local_models = models.filter(is_local=True)

# Search models
results = models.search("gpt-4")
results = models.search("claude")

# Get recommendations
recommended = models.recommend(
    task="chat", max_cost_per_mtok=5.0, min_context_size=16000
)

# Use with chat
model = models["gpt-4o-mini"]
response = chat("Hello", model=model.id)
```

### 5. Batch Operations

Process multiple requests efficiently:

```python
from aix import batch_chat, batch_embeddings, BatchProcessor

# Batch chat
prompts = ["What is 2+2?", "What is 3+3?", "What is 5+5?"]
results = list(batch_chat(prompts, batch_size=10, max_workers=5))

# Batch embeddings
texts = ["hello", "world", "foo", "bar"] * 100
vectors = list(batch_embeddings(texts, batch_size=20, show_progress=True))

# Generic batch processing
from aix import batch_process


def analyze(text):
    return chat(f"Analyze sentiment: {text}")


texts = ["I love it!", "It's okay", "Terrible"]
results = list(batch_process(texts, analyze, batch_size=5, retry_attempts=3))

# Stateful batch processor
processor = BatchProcessor(show_progress=True)
results = processor.process_chats(prompts)
processor.save_results("output.json")
```

### 6. Image Generation

Generate images from text descriptions:

```python
from aix import generate_image, generate_images

# Simple image generation
image = generate_image("A serene mountain landscape at sunset")
image.save("landscape.png")

# High quality with DALL-E 3
image = generate_image(
    "Abstract art with vibrant colors", model="dall-e-3", quality="hd", style="vivid"
)

# Generate multiple variations
images = generate_images("A cute robot waving hello", n=3, size="512x512")
for i, img in enumerate(images):
    img.save(f"robot_{i}.png")

# Edit existing images
from aix import edit_image

edited = edit_image("photo.jpg", "Add a rainbow in the sky", mask_path="sky_mask.png")

# Create variations
from aix import create_variation

variations = create_variation("original.png", n=3)
```

### 7. Audio Operations

Text-to-speech and speech-to-text:

```python
from aix import text_to_speech, transcribe, transcribe_with_timestamps

# Text to speech
audio = text_to_speech("Hello, world!")
audio.save("hello.mp3")

# Different voices
audio = text_to_speech("This is a test", voice="nova", speed=1.2)

# Transcribe audio
text = transcribe("recording.mp3")
print(text)  # "This is the transcribed text"

# With language hint
text = transcribe("spanish_audio.mp3", language="es")

# Detailed transcription with timestamps
result = transcribe_with_timestamps("lecture.mp3")
for segment in result.segments:
    print(f"[{segment['start']:.2f}] {segment['text']}")

# Translate audio to English
from aix import translate_audio

english_text = translate_audio("spanish_audio.mp3")
```

### 8. Video Generation (Coming Soon)

Video generation with provider-specific implementations:

```python
from aix import generate_video, get_video_providers

# Check available providers
providers = get_video_providers()
print(providers)  # ['runway', 'pika', ...]

# Generate video (requires provider setup)
video = generate_video(
    "A cat walking through a garden", duration=5, resolution="1920x1080"
)
video.save("cat_video.mp4")

# Animate static image
from aix import animate_image_to_video

video = animate_image_to_video(
    "landscape.jpg", prompt="Gentle camera pan across the scene"
)
```

**Note**: Video generation requires additional provider setup (Runway, Pika, etc.) and API keys.

## OpenRouter Integration

[OpenRouter](https://openrouter.ai) provides a single API key for 400+ models from 60+ providers. This is recommended for:

- **Getting started quickly** - One key vs. managing many
- **Experimenting** - Easy access to models from OpenAI, Anthropic, Google, etc.
- **Production flexibility** - Switch providers without code changes

### Setup

1. Get API key from https://openrouter.ai
2. Set environment variable:
   ```bash
   export OPENROUTER_API_KEY=your-key-here
   ```
3. Use OpenRouter models:
   ```python
   # Prefix models with 'openrouter/'
   chat("Hello", model="openrouter/openai/gpt-4o")
   chat("Hello", model="openrouter/anthropic/claude-3.5-sonnet")

   # Discover available models
   models.discover("openrouter")
   ```

All standard AIX features work with OpenRouter models.

## Architecture

AIX follows the **i2mint philosophy** of clean, functional interfaces:

- **Mapping interfaces** for collections (models, registries)
- **Functional approach** over verbose OOP
- **Lazy evaluation** via generators where appropriate
- **Protocol-based design** for flexibility

### Backend: LiteLLM

AIX uses [LiteLLM](https://github.com/BerriAI/litellm) as the backend for provider interactions, but wraps it in clean, pythonic interfaces. Users never need to interact with LiteLLM directly.

**Supported Providers** (via LiteLLM):

- OpenAI
- Anthropic (Claude)
- Google (Gemini)
- Mistral
- Cohere
- And 100+ more

#### `import aix` does not touch the network

LiteLLM fetches its model-cost map over HTTPS **as a side effect of being
imported**. `aix` therefore resolves LiteLLM on the *first call* rather than at
import time, so importing `aix` (or any of its submodules) opens no outbound
connection: a server cold start doesn’t block on it, an offline or
restricted-egress deployment doesn’t eat a connect timeout, and a test suite
that merely imports `aix` stays hermetic. The first actual provider call pays
the import, and gets the live cost map — so provider resolution is unaffected.

If you also want the *first call* to stay offline, set LiteLLM’s own knob in
your environment. `aix` deliberately never sets it for you — it is a
whole-process setting, so the choice is the operator’s:

```bash
export LITELLM_LOCAL_MODEL_COST_MAP=1
```

The trade-off: LiteLLM then reads the cost map bundled in its wheel, which is a
snapshot. Bare model names newer than your installed `litellm` release may stop
resolving — pass those provider-prefixed (`"openai/gpt-5.2"` rather than
`"gpt-5.2"`), which works either way.

## Design Patterns

### From `oa` (OpenAI facade)

AIX builds on patterns from the `oa` package:OpenRouter

- Simple chat interface with smart defaults
- Template-based function creation
- Structured output support
- Batch processing capabilities

### From `i2` (Signature manipulation)

- Clean function signatures
- Flexible parameter handling
- Decorator-based composition

### From `dol` (Storage abstraction)

- Mapping-based interfaces
- Persistent storage options
- Cache management

## Advanced Usage

### Custom Model Sources

```python
from aix.ai_models import ModelManager, OpenRouterSource

manager = ModelManager()
source = OpenRouterSource()
models = manager.discover_from_source("openrouter")
```

### Connector-Specific Metadata

```python
# Get provider-specific parameters
metadata = models.get_connector_metadata("openai/gpt-4o", "openai")
# Use with native SDK: openai.ChatCompletion.create(**metadata, messages=[...])
```

### Error Handling

```python
from aix import chat

try:
    response = chat("Hello", model="nonexistent-model")
except Exception as e:
    print(f"Error: {e}")
```

## Backward Compatibility

The legacy `chat_funcs` and `chat_models` interfaces are still available:

```python
from aix import chat_funcs, chat_models

# Old style (still works)
list(chat_funcs)  # ['gpt-4o', 'gpt-4o-mini', ...]
response = chat_funcs.gpt_4o("Hello")

# Model metadata
info = chat_models["gpt-4o"]
# {'price_per_million_tokens': 5.0, 'provider': 'openai', ...}
```

However, the new interfaces (`chat`, `embeddings`, `prompt_func`, `models`) are recommended for new code.

## Examples

### Semantic Search

```python
from aix import embed, cosine_similarity

# Build document index
docs = ["AI is the future", "Python is great", "Machine learning works"]
doc_vecs = [embed(doc) for doc in docs]

# Search
query_vec = embed("artificial intelligence")
similarities = [cosine_similarity(query_vec, dv) for dv in doc_vecs]
best_match = docs[similarities.index(max(similarities))]
print(best_match)  # "AI is the future"
```

### Data Extraction Pipeline

```python
from aix import prompt_func, batch_process

# Define extraction function
extract = prompt_func(
    "Extract product info from: {text}",
    output_schema={"name": str, "price": float, "category": str},
)

# Process many product descriptions
descriptions = [...]  # Your data
results = list(
    batch_process(
        descriptions, lambda d: extract(text=d), batch_size=10, show_progress=True
    )
)
```

### Multi-Model Comparison

```python
from aix import chat

prompt = "Explain quantum computing in one sentence"

# Try different models
for model_id in ["gpt-4o-mini", "claude-sonnet-4", "gemini-1.5-flash"]:
    response = chat(prompt, model=model_id)
    print(f"{model_id}: {response}")
```

## Documentation

- **API Reference**: See docstrings in each module
- **Examples**: Check `examples/` directory
- **GitHub**: https://github.com/thorwhalen/aix

## Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

## License

Apache 2.0

## Credits

Built with:

- [LiteLLM](https://github.com/BerriAI/litellm) - Multi-provider backend
- [i2](https://github.com/i2mint/i2) - Signature manipulation utilities
- [dol](https://github.com/i2mint/dol) - Storage abstraction patterns
- [oa](https://github.com/thorwhalen/oa) - OpenAI facade inspiration

## What AIX is NOT

AIX is NOT an AI agent framework. For that, see the separate `aw` package. AIX focuses on foundational AI operations (chat, embeddings, etc.) that can be used to build agents and other applications.

<p class="epythet-aggregates">This documentation as a single file: <a href="aix.md">aix.md</a> (Markdown, for agents).</p>


# _autosummary/aix.ai_models.base.html.md

# aix.ai_models.base

Core types for AI model management.

This module provides a unified interface for managing, discovering, and
connecting to AI models across multiple providers and deployment methods.

### Classes

| [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)()                              | Abstract base for model connectors/clients.              |
|-------------------------------------------------------------------------------------------|----------------------------------------------------------|
| [`ConnectorRegistry`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ConnectorRegistry)()                      | Registry for managing model connectors.                  |
| [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)(id, provider[, context_size, ...]) | Represents an AI model with its metadata.                |
| [`ModelRegistry`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelRegistry)(\*[, storage_path])        | Registry for managing AI models using Mapping interface. |
| [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)()                            | Abstract base for model discovery sources.               |

### *class* aix.ai_models.base.Connector

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for model connectors/clients.

#### *abstractmethod* format_metadata(model)

Format model metadata for this connector.

Returns a dict that can be used to instantiate/connect via this connector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *abstract property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.base.ConnectorRegistry

Bases: [`MutableMapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableMapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)]

Registry for managing model connectors.

```pycon
>>> registry = ConnectorRegistry()
>>> class MyConnector(Connector):
...     @property
...     def name(self) -> str:
...         return "my_connector"
...     def format_metadata(self, model: Model) -> dict[str, Any]:
...         return {"model": model.id}
>>> connector = MyConnector()
>>> registry[connector.name] = connector
>>> "my_connector" in registry
True
```

### *class* aix.ai_models.base.Model(id, provider, context_size=None, is_local=False, capabilities=<factory>, cost_per_token=<factory>, tags=<factory>, connector_metadata=<factory>, custom_metadata=<factory>)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Represents an AI model with its metadata.

```pycon
>>> model = Model(
...     id="gpt-4",
...     provider="openai",
...     context_size=8192,
...     is_local=False
... )
>>> model.id
'gpt-4'
```

#### matches_filter(\*\*criteria)

Check if model matches given criteria.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

```pycon
>>> model = Model(id="gpt-4", provider="openai", is_local=False)
>>> model.matches_filter(provider="openai")
True
>>> model.matches_filter(is_local=True)
False
```

#### to_dict()

Convert model to dictionary representation.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

### *class* aix.ai_models.base.ModelRegistry(, storage_path=None)

Bases: [`MutableMapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableMapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

Registry for managing AI models using Mapping interface.

```pycon
>>> registry = ModelRegistry()
>>> registry["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> "gpt-4" in registry
True
>>> len(registry)
1
```

#### filter(, provider=None, is_local=None, min_context_size=None, max_context_size=None, has_capabilities=None, tags=None, custom_filter=None)

Filter models by multiple criteria.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> registry = ModelRegistry()
>>> registry["gpt-4"] = Model(id="gpt-4", provider="openai", context_size=8192)
>>> registry["llama2"] = Model(id="llama2", provider="ollama", is_local=True)
>>> local_models = registry.filter(is_local=True)
>>> len(local_models)
1
```

### *class* aix.ai_models.base.ModelSource

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for model discovery sources.

#### *abstractmethod* discover_models()

Discover available models from this source.

Yields Model instances for each discovered model.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]


# _autosummary/aix.ai_models.html.md

# aix.ai_models

AI Model Management Module.

A unified interface for managing AI models across multiple providers.

Basic usage:

```pycon
>>> from aix.ai_models import get_manager
>>> manager = get_manager()
>>> _ = manager.discover_from_source("openrouter", auto_register=True, verbose=False)
>>> models = manager.list_models(provider="openai")
```

Custom filtering:

```pycon
>>> cheap_models = manager.list_models(
...     custom_filter=lambda m: m.cost_per_token.get("input", 0) < 0.001
... )
```

Get connector-specific metadata:

```pycon
>>> openai_meta = manager.get_connector_metadata("openai/gpt-4", "openai")
>>> # Use with: openai.ChatCompletion.create(**openai_meta, messages=[...])
```

### Functions

| [`get_manager`](_autosummary/aix.ai_models.html.md#aix.ai_models.get_manager)([storage_path])   | Get a pre-configured model manager.   |
|--------------------------------------------------------------------------------|---------------------------------------|

### Classes

| [`Model`](_autosummary/aix.ai_models.html.md#aix.ai_models.Model)(id, provider[, context_size, ...])    | Represents an AI model with its metadata.                        |
|----------------------------------------------------------------------------------------------|------------------------------------------------------------------|
| [`ModelRegistry`](_autosummary/aix.ai_models.html.md#aix.ai_models.ModelRegistry)(\*[, storage_path])           | Registry for managing AI models using Mapping interface.         |
| [`ModelSource`](_autosummary/aix.ai_models.html.md#aix.ai_models.ModelSource)()                               | Abstract base for model discovery sources.                       |
| [`Connector`](_autosummary/aix.ai_models.html.md#aix.ai_models.Connector)()                                 | Abstract base for model connectors/clients.                      |
| [`ConnectorRegistry`](_autosummary/aix.ai_models.html.md#aix.ai_models.ConnectorRegistry)()                         | Registry for managing model connectors.                          |
| [`OpenRouterSource`](_autosummary/aix.ai_models.html.md#aix.ai_models.OpenRouterSource)(\*[, timeout])             | Discover models from OpenRouter's public API.                    |
| [`OllamaSource`](_autosummary/aix.ai_models.html.md#aix.ai_models.OllamaSource)(\*[, base_url, timeout])       | Discover locally installed Ollama models.                        |
| [`ProviderAPISource`](_autosummary/aix.ai_models.html.md#aix.ai_models.ProviderAPISource)(provider_name, \*[, ...]) | Discover models from a provider's API (OpenAI, Anthropic, etc.). |
| [`OpenAIConnector`](_autosummary/aix.ai_models.html.md#aix.ai_models.OpenAIConnector)()                           | Format metadata for OpenAI Python client.                        |
| [`OpenRouterConnector`](_autosummary/aix.ai_models.html.md#aix.ai_models.OpenRouterConnector)()                       | Connector for OpenRouter API.                                    |
| [`LangChainConnector`](_autosummary/aix.ai_models.html.md#aix.ai_models.LangChainConnector)()                        | Connector for LangChain library.                                 |
| [`OllamaConnector`](_autosummary/aix.ai_models.html.md#aix.ai_models.OllamaConnector)()                           | Format metadata for direct Ollama API calls.                     |
| [`DSPyConnector`](_autosummary/aix.ai_models.html.md#aix.ai_models.DSPyConnector)()                             | Format metadata for DSPy framework.                              |
| [`ModelManager`](_autosummary/aix.ai_models.html.md#aix.ai_models.ModelManager)(\*[, storage_path])            | Unified interface for AI model management.                       |

### *class* aix.ai_models.Connector

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for model connectors/clients.

#### *abstractmethod* format_metadata(model)

Format model metadata for this connector.

Returns a dict that can be used to instantiate/connect via this connector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *abstract property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.ConnectorRegistry

Bases: [`MutableMapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableMapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)]

Registry for managing model connectors.

```pycon
>>> registry = ConnectorRegistry()
>>> class MyConnector(Connector):
...     @property
...     def name(self) -> str:
...         return "my_connector"
...     def format_metadata(self, model: Model) -> dict[str, Any]:
...         return {"model": model.id}
>>> connector = MyConnector()
>>> registry[connector.name] = connector
>>> "my_connector" in registry
True
```

### *class* aix.ai_models.DSPyConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for DSPy framework.

#### format_metadata(model)

Format for DSPy.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = DSPyConnector()
>>> model = Model(id="gpt-4", provider="openai")
>>> metadata = connector.format_metadata(model)
>>> "model" in metadata
True
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.LangChainConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Connector for LangChain library.

#### format_metadata(model)

Format for LangChain.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = LangChainConnector()
>>> model = Model(id="gpt-4", provider="openai")
>>> metadata = connector.format_metadata(model)
>>> metadata["model_name"]
'gpt-4'
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.Model(id, provider, context_size=None, is_local=False, capabilities=<factory>, cost_per_token=<factory>, tags=<factory>, connector_metadata=<factory>, custom_metadata=<factory>)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Represents an AI model with its metadata.

```pycon
>>> model = Model(
...     id="gpt-4",
...     provider="openai",
...     context_size=8192,
...     is_local=False
... )
>>> model.id
'gpt-4'
```

#### matches_filter(\*\*criteria)

Check if model matches given criteria.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

```pycon
>>> model = Model(id="gpt-4", provider="openai", is_local=False)
>>> model.matches_filter(provider="openai")
True
>>> model.matches_filter(is_local=True)
False
```

#### to_dict()

Convert model to dictionary representation.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

### *class* aix.ai_models.ModelManager(, storage_path=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Unified interface for AI model management.

Combines model registry, sources, and connectors into a single facade.

```pycon
>>> manager = ModelManager()
>>> manager.register_connector(OpenAIConnector())
>>> len(manager.connectors)
1
```

#### add_model_tag(model_id, \*tags)

Add tags to a model.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.add_model_tag("gpt-4", "fast", "expensive")
>>> "fast" in manager.models["gpt-4"].tags
True
```

#### *property* connectors *: [ConnectorRegistry](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ConnectorRegistry)*

Access to connector registry.

#### create_model_group(group_name, model_ids)

Create a named group of models using tags.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.models["claude-3"] = Model(id="claude-3", provider="anthropic")
>>> manager.create_model_group("premium", ["gpt-4", "claude-3"])
>>> premium = manager.list_models(tags=["group:premium"])
>>> len(premium)
2
```

#### discover_all(, auto_register=True)

Discover models from all registered sources.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]]
* **Returns:**
  Dict mapping source name to list of discovered models

#### discover_from_source(source_name, , auto_register=True, verbose=True)

Discover models from a registered source.

* **Parameters:**
  * **source_name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Name of registered source
  * **auto_register** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, automatically add discovered models to registry
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of discovered models

#### get_connector_metadata(model_id, connector_name)

Get formatted metadata for a specific connector.

* **Parameters:**
  * **model_id** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – ID of the model
  * **connector_name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Name of the connector to format for
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]
* **Returns:**
  Dict with metadata formatted for the specified connector

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.register_connector(OpenAIConnector())
>>> meta = manager.get_connector_metadata("gpt-4", "openai")
>>> meta["model"]
'gpt-4'
```

#### get_model(model_id)

Get a specific model by ID.

* **Return type:**
  [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> model = manager.get_model("gpt-4")
>>> model.id
'gpt-4'
```

#### list_model_groups()

List all model groups.

* **Returns:**
  ‘ prefix)
* **Return type:**
  [`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### list_models(, provider=None, is_local=None, min_context_size=None, max_context_size=None, has_capabilities=None, tags=None, custom_filter=None)

List models with optional filtering.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.models["llama2"] = Model(id="llama2", provider="ollama", is_local=True)
>>> local = manager.list_models(is_local=True)
>>> len(local)
1
>>> local[0].id
'llama2'
```

#### list_sources()

List registered source names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### *property* models *: [ModelRegistry](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelRegistry)*

Access to model registry for direct manipulation.

```pycon
>>> manager = ModelManager()
>>> manager.models["test"] = Model(id="test", provider="test")
>>> "test" in manager.models
True
```

#### register_connector(connector)

Register a model connector.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> connector = OpenAIConnector()
>>> manager.register_connector(connector)
>>> connector.name in manager.connectors
True
```

#### register_source(name, source)

Register a model discovery source.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> source = OpenRouterSource()
>>> manager.register_source("openrouter", source)
>>> "openrouter" in manager.list_sources()
True
```

#### set_custom_metadata(model_id, key, value)

Set custom metadata on a model.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.set_custom_metadata("gpt-4", "my_note", "Use for production")
>>> manager.models["gpt-4"].custom_metadata["my_note"]
'Use for production'
```

### *class* aix.ai_models.ModelRegistry(, storage_path=None)

Bases: [`MutableMapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableMapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

Registry for managing AI models using Mapping interface.

```pycon
>>> registry = ModelRegistry()
>>> registry["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> "gpt-4" in registry
True
>>> len(registry)
1
```

#### filter(, provider=None, is_local=None, min_context_size=None, max_context_size=None, has_capabilities=None, tags=None, custom_filter=None)

Filter models by multiple criteria.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> registry = ModelRegistry()
>>> registry["gpt-4"] = Model(id="gpt-4", provider="openai", context_size=8192)
>>> registry["llama2"] = Model(id="llama2", provider="ollama", is_local=True)
>>> local_models = registry.filter(is_local=True)
>>> len(local_models)
1
```

### *class* aix.ai_models.ModelSource

Bases: [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for model discovery sources.

#### *abstractmethod* discover_models()

Discover available models from this source.

Yields Model instances for each discovered model.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

### *class* aix.ai_models.OllamaConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for direct Ollama API calls.

#### format_metadata(model)

Format for Ollama API.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = OllamaConnector()
>>> model = Model(id="ollama/llama2", provider="ollama", is_local=True)
>>> model.connector_metadata["ollama"] = {"name": "llama2"}
>>> metadata = connector.format_metadata(model)
>>> metadata["model"]
'llama2'
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.OllamaSource(, base_url='http://localhost:11434', timeout=10)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover locally installed Ollama models.

Queries the Ollama API for models available on the local machine.

#### discover_models()

Fetch locally installed Ollama models.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> source = OllamaSource()
>>> models = list(source.discover_models())  # May be empty if Ollama not running
>>> all(m.is_local for m in models)
True
```

### *class* aix.ai_models.OpenAIConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for OpenAI Python client.

Provides model metadata in format expected by openai.ChatCompletion.create().

#### format_metadata(model)

Format model metadata for this connector.

Returns a dict that can be used to instantiate/connect via this connector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.OpenRouterConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Connector for OpenRouter API.

#### format_metadata(model)

Formats metadata for OpenRouter, which uses the model ID directly.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.OpenRouterSource(, timeout=30)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover models from OpenRouter’s public API.

OpenRouter maintains a comprehensive registry of models across providers.

#### discover_models()

Fetch models from OpenRouter API.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> source = OpenRouterSource()
>>> models = list(source.discover_models())
>>> len(models) > 0  # Should find many models
True
```

### *class* aix.ai_models.ProviderAPISource(provider_name, , api_key=None, base_url='https://api.openai.com/v1', timeout=30)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover models from a provider’s API (OpenAI, Anthropic, etc.).

Generic source for providers with /v1/models endpoint.

#### discover_models()

Fetch models from provider API.

Requires valid API key for the provider.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

### aix.ai_models.get_manager(storage_path=None)

Get a pre-configured model manager.

* **Return type:**
  [`ModelManager`](_autosummary/aix.ai_models.manager.html.md#aix.ai_models.manager.ModelManager)

```pycon
>>> manager = get_manager()
>>> len(manager.connectors) > 0
True
```

### Modules

| [`base`](_autosummary/aix.ai_models.base.html.md#module-aix.ai_models.base)       | Core types for AI model management.                       |
|---------------------------------------------------------------------------------------|-----------------------------------------------------------|
| [`manager`](_autosummary/aix.ai_models.manager.html.md#module-aix.ai_models.manager) | Unified model management interface.                       |
| [`sources`](_autosummary/aix.ai_models.sources.html.md#module-aix.ai_models.sources) | Concrete implementations of model sources and connectors. |


# _autosummary/aix.ai_models.manager.html.md

# aix.ai_models.manager

Unified model management interface.

Provides a high-level API for managing AI models across providers.

### Functions

| [`get_manager`](_autosummary/aix.ai_models.manager.html.md#aix.ai_models.manager.get_manager)([storage_path])   | Get a pre-configured model manager.   |
|--------------------------------------------------------------------------------|---------------------------------------|

### Classes

| [`ModelManager`](_autosummary/aix.ai_models.manager.html.md#aix.ai_models.manager.ModelManager)(\*[, storage_path])   | Unified interface for AI model management.   |
|-------------------------------------------------------------------------------------|----------------------------------------------|

### *class* aix.ai_models.manager.ModelManager(, storage_path=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Unified interface for AI model management.

Combines model registry, sources, and connectors into a single facade.

```pycon
>>> manager = ModelManager()
>>> manager.register_connector(OpenAIConnector())
>>> len(manager.connectors)
1
```

#### add_model_tag(model_id, \*tags)

Add tags to a model.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.add_model_tag("gpt-4", "fast", "expensive")
>>> "fast" in manager.models["gpt-4"].tags
True
```

#### *property* connectors *: [ConnectorRegistry](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ConnectorRegistry)*

Access to connector registry.

#### create_model_group(group_name, model_ids)

Create a named group of models using tags.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.models["claude-3"] = Model(id="claude-3", provider="anthropic")
>>> manager.create_model_group("premium", ["gpt-4", "claude-3"])
>>> premium = manager.list_models(tags=["group:premium"])
>>> len(premium)
2
```

#### discover_all(, auto_register=True)

Discover models from all registered sources.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]]
* **Returns:**
  Dict mapping source name to list of discovered models

#### discover_from_source(source_name, , auto_register=True, verbose=True)

Discover models from a registered source.

* **Parameters:**
  * **source_name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Name of registered source
  * **auto_register** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, automatically add discovered models to registry
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of discovered models

#### get_connector_metadata(model_id, connector_name)

Get formatted metadata for a specific connector.

* **Parameters:**
  * **model_id** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – ID of the model
  * **connector_name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Name of the connector to format for
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]
* **Returns:**
  Dict with metadata formatted for the specified connector

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.register_connector(OpenAIConnector())
>>> meta = manager.get_connector_metadata("gpt-4", "openai")
>>> meta["model"]
'gpt-4'
```

#### get_model(model_id)

Get a specific model by ID.

* **Return type:**
  [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> model = manager.get_model("gpt-4")
>>> model.id
'gpt-4'
```

#### list_model_groups()

List all model groups.

* **Returns:**
  ‘ prefix)
* **Return type:**
  [`set`](https://docs.python.org/3/builtins/stdtypes.html#set)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### list_models(, provider=None, is_local=None, min_context_size=None, max_context_size=None, has_capabilities=None, tags=None, custom_filter=None)

List models with optional filtering.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.models["llama2"] = Model(id="llama2", provider="ollama", is_local=True)
>>> local = manager.list_models(is_local=True)
>>> len(local)
1
>>> local[0].id
'llama2'
```

#### list_sources()

List registered source names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### *property* models *: [ModelRegistry](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelRegistry)*

Access to model registry for direct manipulation.

```pycon
>>> manager = ModelManager()
>>> manager.models["test"] = Model(id="test", provider="test")
>>> "test" in manager.models
True
```

#### register_connector(connector)

Register a model connector.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> connector = OpenAIConnector()
>>> manager.register_connector(connector)
>>> connector.name in manager.connectors
True
```

#### register_source(name, source)

Register a model discovery source.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> source = OpenRouterSource()
>>> manager.register_source("openrouter", source)
>>> "openrouter" in manager.list_sources()
True
```

#### set_custom_metadata(model_id, key, value)

Set custom metadata on a model.

* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

```pycon
>>> manager = ModelManager()
>>> manager.models["gpt-4"] = Model(id="gpt-4", provider="openai")
>>> manager.set_custom_metadata("gpt-4", "my_note", "Use for production")
>>> manager.models["gpt-4"].custom_metadata["my_note"]
'Use for production'
```

### aix.ai_models.manager.get_manager(storage_path=None)

Get a pre-configured model manager.

* **Return type:**
  [`ModelManager`](_autosummary/aix.ai_models.manager.html.md#aix.ai_models.manager.ModelManager)

```pycon
>>> manager = get_manager()
>>> len(manager.connectors) > 0
True
```


# _autosummary/aix.ai_models.sources.html.md

# aix.ai_models.sources

Concrete implementations of model sources and connectors.

This module provides ready-to-use sources for discovering models
and connectors for formatting metadata for different clients.

### Classes

| [`DSPyConnector`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.DSPyConnector)()                             | Format metadata for DSPy framework.                              |
|----------------------------------------------------------------------------------------------|------------------------------------------------------------------|
| [`LangChainConnector`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.LangChainConnector)()                        | Connector for LangChain library.                                 |
| [`OllamaConnector`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.OllamaConnector)()                           | Format metadata for direct Ollama API calls.                     |
| [`OllamaSource`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.OllamaSource)(\*[, base_url, timeout])       | Discover locally installed Ollama models.                        |
| [`OpenAIConnector`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.OpenAIConnector)()                           | Format metadata for OpenAI Python client.                        |
| [`OpenRouterConnector`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.OpenRouterConnector)()                       | Connector for OpenRouter API.                                    |
| [`OpenRouterSource`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.OpenRouterSource)(\*[, timeout])             | Discover models from OpenRouter's public API.                    |
| [`ProviderAPISource`](_autosummary/aix.ai_models.sources.html.md#aix.ai_models.sources.ProviderAPISource)(provider_name, \*[, ...]) | Discover models from a provider's API (OpenAI, Anthropic, etc.). |

### *class* aix.ai_models.sources.DSPyConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for DSPy framework.

#### format_metadata(model)

Format for DSPy.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = DSPyConnector()
>>> model = Model(id="gpt-4", provider="openai")
>>> metadata = connector.format_metadata(model)
>>> "model" in metadata
True
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.sources.LangChainConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Connector for LangChain library.

#### format_metadata(model)

Format for LangChain.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = LangChainConnector()
>>> model = Model(id="gpt-4", provider="openai")
>>> metadata = connector.format_metadata(model)
>>> metadata["model_name"]
'gpt-4'
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.sources.OllamaConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for direct Ollama API calls.

#### format_metadata(model)

Format for Ollama API.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

```pycon
>>> connector = OllamaConnector()
>>> model = Model(id="ollama/llama2", provider="ollama", is_local=True)
>>> model.connector_metadata["ollama"] = {"name": "llama2"}
>>> metadata = connector.format_metadata(model)
>>> metadata["model"]
'llama2'
```

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.sources.OllamaSource(, base_url='http://localhost:11434', timeout=10)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover locally installed Ollama models.

Queries the Ollama API for models available on the local machine.

#### discover_models()

Fetch locally installed Ollama models.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> source = OllamaSource()
>>> models = list(source.discover_models())  # May be empty if Ollama not running
>>> all(m.is_local for m in models)
True
```

### *class* aix.ai_models.sources.OpenAIConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Format metadata for OpenAI Python client.

Provides model metadata in format expected by openai.ChatCompletion.create().

#### format_metadata(model)

Format model metadata for this connector.

Returns a dict that can be used to instantiate/connect via this connector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.sources.OpenRouterConnector

Bases: [`Connector`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Connector)

Connector for OpenRouter API.

#### format_metadata(model)

Formats metadata for OpenRouter, which uses the model ID directly.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

#### *property* name *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Unique identifier for this connector.

### *class* aix.ai_models.sources.OpenRouterSource(, timeout=30)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover models from OpenRouter’s public API.

OpenRouter maintains a comprehensive registry of models across providers.

#### discover_models()

Fetch models from OpenRouter API.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]

```pycon
>>> source = OpenRouterSource()
>>> models = list(source.discover_models())
>>> len(models) > 0  # Should find many models
True
```

### *class* aix.ai_models.sources.ProviderAPISource(provider_name, , api_key=None, base_url='https://api.openai.com/v1', timeout=30)

Bases: [`ModelSource`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.ModelSource)

Discover models from a provider’s API (OpenAI, Anthropic, etc.).

Generic source for providers with /v1/models endpoint.

#### discover_models()

Fetch models from provider API.

Requires valid API key for the provider.

* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]


# _autosummary/aix.audio.html.md

# aix.audio

Audio operations interface for AIX.

Provides text-to-speech (TTS) and speech-to-text (transcription) capabilities.

### Examples

Text to speech:

```pycon
>>> from aix.audio import text_to_speech
>>> audio = text_to_speech("Hello, world!")
>>> audio.save("hello.mp3")
```

Transcription:

```pycon
>>> from aix.audio import transcribe
>>> text = transcribe("speech.mp3")
>>> print(text)
'Hello, this is a test recording.'
```

### Functions

| [`text_to_speech`](_autosummary/aix.audio.html.md#aix.audio.text_to_speech)(text, \*[, model, voice, ...])    | Convert text to speech audio.                 |
|---------------------------------------------------------------------------------------------------|-----------------------------------------------|
| [`transcribe`](_autosummary/aix.audio.html.md#aix.audio.transcribe)(audio, \*[, engine, model, ...])      | Transcribe audio to text.                     |
| [`transcribe_with_timestamps`](_autosummary/aix.audio.html.md#aix.audio.transcribe_with_timestamps)(audio, \*[, ...])     | Transcribe audio with detailed timestamps.    |
| [`translate_audio`](_autosummary/aix.audio.html.md#aix.audio.translate_audio)(audio, \*[, model, prompt, ...]) | Translate audio from any language to English. |

### Classes

| [`GeneratedAudio`](_autosummary/aix.audio.html.md#aix.audio.GeneratedAudio)(data[, model, text, voice, ...])   | Wrapper for generated audio.   |
|----------------------------------------------------------------------------------------------------|--------------------------------|
| [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult)(text[, language, ...])        | Result of audio transcription. |

### *class* aix.audio.GeneratedAudio(data, model=None, text=None, voice=None, format='mp3')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated audio.

Provides convenient access to audio data and saving.

### Examples

```pycon
>>> audio = GeneratedAudio(data=b'...', model="tts-1")
>>> audio.save("output.mp3")
>>> data = audio.as_bytes()
```

#### as_bytes()

Get audio as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Audio data as bytes

#### play()

Play the audio.

Requires a system audio player or library like pygame/pyaudio.

### Examples

```pycon
>>> audio.play()
```

#### save(path)

Save audio to file.

* **Parameters:**
  **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path

### Examples

```pycon
>>> audio.save("output.mp3")
>>> audio.save("speech.wav")
```

### *class* aix.audio.TranscriptionResult(text, language=None, duration=None, segments=None, model=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Result of audio transcription.

Contains the transcribed text and optional metadata like segments and timestamps.

### Examples

```pycon
>>> result = TranscriptionResult(text="Hello world")
>>> print(result.text)
'Hello world'
```

### aix.audio.text_to_speech(text, , model=None, voice=None, speed=None, response_format='mp3', api_key=None, \*\*kwargs)

Convert text to speech audio.

* **Parameters:**
  * **text** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text to convert to speech
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – TTS model to use (e.g., ‘tts-1’, ‘tts-1-hd’)
  * **voice** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Voice to use (‘alloy’, ‘echo’, ‘fable’, ‘onyx’, ‘nova’, ‘shimmer’)
  * **speed** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Playback speed (0.25 to 4.0)
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Audio format (‘mp3’, ‘opus’, ‘aac’, ‘flac’)
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedAudio`](_autosummary/aix.audio.html.md#aix.audio.GeneratedAudio)
* **Returns:**
  GeneratedAudio object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed

### Examples

```pycon
>>> from aix.audio import text_to_speech
>>> audio = text_to_speech("Hello, how are you?")
>>> audio.save("greeting.mp3")
```

```pycon
>>> # Different voice and speed
>>> audio = text_to_speech(
...     "This is a test.",
...     voice="nova",
...     speed=1.2
... )
```

```pycon
>>> # High quality
>>> audio = text_to_speech(
...     "Important announcement",
...     model="tts-1-hd",
...     voice="onyx"
... )
```

### aix.audio.transcribe(audio, , engine=None, model=None, language=None, prompt=None, response_format='text', temperature=None, timestamp_granularities=None, api_key=None, \*\*kwargs)

Transcribe audio to text.

By default this routes through LiteLLM (OpenAI-style transcription). Pass
`engine=` to instead delegate to a `scribed` backend — one façade over
many ASR engines (local Whisper / faster-whisper / vosk, or cloud Deepgram /
AssemblyAI / Groq / ElevenLabs / Google …) with speaker diarization and
SRT/VTT output. The return type is unchanged either way, so existing callers
are unaffected.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes.
  * **engine** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional `scribed` backend id (e.g. `"faster-whisper"`,
    `"deepgram"`). When given, transcription is delegated to scribed
    (which resolves that engine’s own credentials); the LiteLLM path is
    bypassed. Requires `pip install 'aix[scribed]'`. See
    `scribed.list_backends()`.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Transcription model (e.g. `'whisper-1'`); for a scribed engine,
    the engine-specific model (e.g. a Whisper size).
  * **language** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Source language (ISO-639-1 code, e.g. `'en'`, `'es'`).
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text to guide the model’s style (LiteLLM path).
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – `'text'` (default) → `str`; `'srt'`/`'vtt'` →
    subtitle `str` (scribed path); else → [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Sampling temperature (LiteLLM path).
  * **timestamp_granularities** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Timestamp types (‘word’, ‘segment’) (LiteLLM path).
  * **\*\*kwargs** – Additional parameters (forwarded to LiteLLM, or to the scribed
    backend — e.g. `diarize=True`).
* **Return type:**
  `Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult)]
* **Returns:**
  `str` for `response_format` in {text, srt, vtt}, else a
  [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult).

### Examples

```pycon
>>> from aix.audio import transcribe
>>> text = transcribe("recording.mp3")
>>> # delegate to a scribed engine (local, free, diarized SRT):
>>> srt = transcribe(
...     "meeting.wav", engine="faster-whisper", response_format="srt"
... )
>>> dg = transcribe(
...     "call.mp3", engine="deepgram", diarize=True,
...     response_format="verbose_json",
... )
```

### aix.audio.transcribe_with_timestamps(audio, , granularity='segment', model=None, \*\*kwargs)

Transcribe audio with detailed timestamps.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes
  * **granularity** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Timestamp granularity (‘word’ or ‘segment’)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Transcription model
  * **\*\*kwargs** – Additional parameters for transcribe()
* **Return type:**
  [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult)
* **Returns:**
  TranscriptionResult with detailed segments

### Examples

```pycon
>>> from aix.audio import transcribe_with_timestamps
>>> result = transcribe_with_timestamps("lecture.mp3")
>>> for segment in result.segments:
...     start = segment['start']
...     end = segment['end']
...     text = segment['text']
...     print(f"[{start:.2f}-{end:.2f}] {text}")
```

### aix.audio.translate_audio(audio, , model=None, prompt=None, api_key=None, \*\*kwargs)

Translate audio from any language to English.

#### NOTE
Currently uses Whisper’s translation capability which translates to English.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Translation model (typically ‘whisper-1’)
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text to guide translation
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  Translated text in English

### Examples

```pycon
>>> from aix.audio import translate_audio
>>> english_text = translate_audio("spanish_audio.mp3")
>>> print(english_text)
'This is the English translation.'
```


# _autosummary/aix.batches.html.md

# aix.batches

Batch processing interface for AIX.

Efficiently process multiple prompts or embeddings in batches.

An item whose call raises does not stop the batch: its slot holds a
[`BatchError`](_autosummary/aix.batches.html.md#aix.batches.BatchError) – a `str` subclass equal to the `"ERROR: <message>"`
text these functions have always produced, but carrying the real exception so a
failure can be told apart from a model reply that happens to start “ERROR:”.
Pass `on_error='raise'` or `on_error='skip'` to opt out of that slot.

### Examples

Batch chat:

```pycon
>>> from aix.batches import batch_chat
>>> prompts = ["What is 2+2?", "What is 3+3?", "What is 4+4?"]
>>> results = list(batch_chat(prompts))
>>> len(results)
3
```

Batch embeddings:

```pycon
>>> from aix.batches import batch_embeddings
>>> texts = ["hello", "world", "foo", "bar"]
>>> vectors = list(batch_embeddings(texts))
>>> len(vectors)
4
```

### Functions

| [`batch_chat`](_autosummary/aix.batches.html.md#aix.batches.batch_chat)(prompts, \*[, model, batch_size, ...])   | Process multiple chat prompts in batches.                     |
|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|
| [`batch_embeddings`](_autosummary/aix.batches.html.md#aix.batches.batch_embeddings)(segments, \*[, model, ...])        | Generate embeddings for multiple texts in batches.            |
| [`batch_process`](_autosummary/aix.batches.html.md#aix.batches.batch_process)(items, process_func, \*[, ...])       | Generic batch processing with parallel execution and retries. |

### Classes

| [`BatchError`](_autosummary/aix.batches.html.md#aix.batches.BatchError)(exception, \*[, index, message])        | A batch result slot standing in for an item that raised.       |
|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------------|
| [`BatchProcessor`](_autosummary/aix.batches.html.md#aix.batches.BatchProcessor)(\*[, batch_size, max_workers, ...]) | Stateful batch processor for managing long-running operations. |

### *class* aix.batches.BatchError(exception, , index=None, message=None)

Bases: [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

A batch result slot standing in for an item that raised.

Subclasses `str` so it *is* the `"ERROR: ..."` string these functions
have always put in the failed slot – comparisons, `.startswith`,
slicing, JSON serialisation and logging all behave identically. What it
adds is the ability to tell a failure apart from a model that legitimately
replied with text starting “ERROR:”, and to reach the original exception.

#### exception

The exception that was caught.

#### index

Position of the failed item in the input, when known.

### Examples

```pycon
>>> err = BatchError(RuntimeError("rate limit exceeded"), index=1)
>>> err == "ERROR: rate limit exceeded"
True
>>> isinstance(err, str), isinstance(err.exception, RuntimeError)
(True, True)
>>> err.index
1
```

### *class* aix.batches.BatchProcessor(, batch_size=None, max_workers=None, show_progress=True)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Stateful batch processor for managing long-running operations.

Provides a higher-level interface for batch processing with
progress tracking, error handling, and result caching.

### Examples

```pycon
>>> processor = BatchProcessor(show_progress=True)
>>> results = processor.process_chats(prompts)
>>> processor.save_results("output.json")
```

#### clear()

Clear stored results and errors.

#### process_chats(prompts, \*\*kwargs)

Process chat prompts and store results.

* **Parameters:**
  * **prompts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]]]) – Prompts to process
  * **\*\*kwargs** – Additional parameters for batch_chat()
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  List of results

#### process_embeddings(texts, \*\*kwargs)

Process embeddings and store results.

* **Parameters:**
  * **texts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Texts to embed
  * **\*\*kwargs** – Additional parameters for batch_embeddings()
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]
* **Returns:**
  List of embedding vectors

#### save_results(filepath)

Save results to file.

* **Parameters:**
  **filepath** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Path to save results (JSON)

### aix.batches.batch_chat(prompts, , model=None, batch_size=None, max_workers=None, show_progress=False, on_error='return', \*\*chat_kwargs)

Process multiple chat prompts in batches.

This function processes multiple prompts efficiently by:

1. Chunking prompts into batches
2. Processing batches in parallel where possible
3. Yielding results in the same order as input

* **Parameters:**
  * **prompts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]]]) – Iterable of prompts (strings or message lists)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use for all prompts
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of prompts to process in each batch
  * **max_workers** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of parallel workers
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print progress information
  * **on_error** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'return'`, `'raise'`, `'skip'`]) – What to do with a prompt whose call raised.
    `'return'` (default) yields a `BatchError` in that slot, keeping
    the stream the same length and order as the input.
    `'raise'` stops after the batch in which the first failure landed
    and re-raises the lowest-indexed exception of that batch.
    `'skip'` omits the failed slots from the stream.
  * **\*\*chat_kwargs** – Additional parameters passed to chat()
* **Yields:**
  Responses in the same order as input prompts. A prompt that raised
  yields a `BatchError` – a `str` subclass equal to `"ERROR: <message>"`,
  carrying the original exception on `.exception`.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `on_error` is not one of ‘return’, ‘raise’, ‘skip’.
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### Examples

```pycon
>>> from aix.batches import batch_chat
>>> prompts = [
...     "What is 2+2?",
...     "What is 3+3?",
...     "What is 5+5?"
... ]
>>> results = list(batch_chat(prompts))
>>> len(results)
3
```

```pycon
>>> # With specific model
>>> results = list(batch_chat(
...     prompts,
...     model="gpt-4o-mini",
...     batch_size=5
... ))
```

```pycon
>>> # Process large dataset
>>> def generate_prompts():
...     for i in range(100):
...         yield f"Explain concept {i}"
>>> results = batch_chat(
...     generate_prompts(),
...     show_progress=True
... )
>>> for i, result in enumerate(results):
...     print(f"Result {i}: {result[:50]}...")
```

```pycon
>>> # Tell a failure apart from a reply that starts with "ERROR:"
>>> for result in batch_chat(prompts):
...     if isinstance(result, BatchError):
...         raise result.exception
```

### aix.batches.batch_embeddings(segments, , model=None, batch_size=None, show_progress=False, \*\*embedding_kwargs)

Generate embeddings for multiple texts in batches.

For efficiency, this function processes embeddings in chunks,
as most embedding APIs can handle multiple texts per request.

* **Parameters:**
  * **segments** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Iterable of text strings to embed
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Embedding model to use
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of texts per batch
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print progress information
  * **\*\*embedding_kwargs** – Additional parameters for embeddings()
* **Yields:**
  Vector embeddings in the same order as input
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]

### Examples

```pycon
>>> from aix.batches import batch_embeddings
>>> texts = ["hello", "world", "foo", "bar"] * 25  # 100 texts
>>> vectors = list(batch_embeddings(
...     texts,
...     batch_size=10,
...     show_progress=True
... ))
>>> len(vectors)
100
```

```pycon
>>> # Process large dataset efficiently
>>> def read_documents():
...     # Generator that yields documents
...     for i in range(1000):
...         yield f"Document {i} content"
>>> all_vectors = []
>>> for vec in batch_embeddings(read_documents()):
...     all_vectors.append(vec)
```

### aix.batches.batch_process(items, process_func, , batch_size=None, max_workers=None, show_progress=False, retry_attempts=None, retry_delay=None, on_error='return')

Generic batch processing with parallel execution and retries.

This is a general-purpose batch processor that can be used for
any operation, not just chat or embeddings.

* **Parameters:**
  * **items** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – Items to process
  * **process_func** (`callable`) – Function to apply to each item
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Batch size for chunking
  * **max_workers** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum parallel workers
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Show progress information
  * **retry_attempts** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of retry attempts on failure
  * **retry_delay** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Delay between retries (seconds)
  * **on_error** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'return'`, `'raise'`, `'skip'`]) – What to do with an item still failing after every retry.
    `'return'` (default) yields a `BatchError` in that slot, `'raise'`
    re-raises, `'skip'` omits it. See [`batch_chat()`](_autosummary/aix.batches.html.md#aix.batches.batch_chat).
* **Yields:**
  Results in same order as input. An item that raised yields a
  `BatchError` – a `str` subclass equal to `"ERROR: <message>"`,
  carrying the original exception on `.exception`.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `on_error` is not one of ‘return’, ‘raise’, ‘skip’.
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

### Examples

```pycon
>>> from aix.batches import batch_process
>>> from aix.chat import chat
```

```pycon
>>> # Custom processing function
>>> def analyze_sentiment(text):
...     return chat(f"Analyze sentiment: {text}")
```

```pycon
>>> texts = ["I love this!", "This is terrible", "It's okay"]
>>> results = list(batch_process(
...     texts,
...     analyze_sentiment,
...     batch_size=5
... ))
```

```pycon
>>> # With retries for flaky operations
>>> def flaky_api_call(item):
...     # Some API that might fail
...     return call_api(item)
```

```pycon
>>> results = batch_process(
...     items,
...     flaky_api_call,
...     retry_attempts=3,
...     retry_delay=2.0
... )
```


# _autosummary/aix.config.html.md

# aix.config

Central configuration for AIX (single source of truth for defaults).

This module is the SSOT for \*what model (and related parameters) each AIX
function uses by default\*. Instead of scattering hardcoded `DFLT_*` constants
across modules, every function resolves its defaults from a single, layered
configuration.

Resolution layers, highest precedence first:

1. **Explicit call argument** – e.g. `chat(..., model=...)` always wins
   (handled at the call site, not here).
2. **Runtime override** – [`configure()`](_autosummary/aix.config.html.md#aix.config.configure) swaps the active config; [`using()`](_autosummary/aix.config.html.md#aix.config.using)
   scopes an override to a `with` block.
3. **Environment variables** – `AIX_CHAT_MODEL`, `AIX_CHAT_TEMPERATURE`,
   `AIX_EMBEDDING_MODEL`, `AIX_IMAGE_MODEL`, `AIX_TTS_MODEL`,
   `AIX_TTS_VOICE`, `AIX_TRANSCRIPTION_MODEL`, …
4. **User config file** – a TOML file at `<app config dir>/config.toml`
   (override the path with the `AIX_CONFIG_FILE` environment variable).
5. **Shipped defaults** – the dataclass field defaults below.

The schema is a set of frozen dataclasses (immutable). A module-level \*active
config\* pointer holds the currently resolved [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig); [`configure()`](_autosummary/aix.config.html.md#aix.config.configure)
and [`using()`](_autosummary/aix.config.html.md#aix.config.using) swap that pointer rather than mutating in place.

### Examples

```pycon
>>> from aix import config
>>> c = config.get_config()
>>> isinstance(c.chat.model, str)
True
```

Scoped override (does not leak outside the block):

```pycon
>>> with config.using(chat_model="some/model"):
...     config.get_config().chat.model
'some/model'
>>> config.get_config().chat.model == c.chat.model
True
```

TOML config file shape:

```default
[chat]
model = "openai/gpt-4o-mini"
temperature = 1.0

[embeddings]
model = "text-embedding-3-small"

[image]
model = "dall-e-3"
size = "1024x1024"

[audio]
tts_model = "tts-1"
tts_voice = "alloy"
transcription_model = "whisper-1"

[vision]
model = "gpt-4o-mini"

[aliases]
fast = "openai/gpt-4o-mini"
best = "anthropic/claude-sonnet-4"
```

### Functions

| [`load_config`](_autosummary/aix.config.html.md#aix.config.load_config)([path, environ])       | Resolve an [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig) from shipped defaults, TOML file, and env.   |
|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| [`get_config`](_autosummary/aix.config.html.md#aix.config.get_config)()                       | Return the current active [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig).                              |
| [`set_config`](_autosummary/aix.config.html.md#aix.config.set_config)(config)                 | Replace the active config wholesale.                                                                               |
| [`configure`](_autosummary/aix.config.html.md#aix.config.configure)(\*\*overrides)           | Apply runtime overrides to the active config and return it.                                                        |
| [`using`](_autosummary/aix.config.html.md#aix.config.using)(\*\*overrides)               | Context manager applying scoped overrides, restored on exit.                                                       |
| [`config_file_path`](_autosummary/aix.config.html.md#aix.config.config_file_path)()                 | Path to the user config file (env `AIX_CONFIG_FILE` overrides default).                                            |
| [`resolve_model`](_autosummary/aix.config.html.md#aix.config.resolve_model)(model, \*[, config]) | Resolve a semantic alias (`"fast"`, `"best"`, ...) to a concrete model id.                                         |

### Classes

| [`ChatConfig`](_autosummary/aix.config.html.md#aix.config.ChatConfig)([model, temperature, max_tokens])     | Defaults for `chat` / `ask` / `prompt_func`.                       |
|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| [`EmbeddingConfig`](_autosummary/aix.config.html.md#aix.config.EmbeddingConfig)([model, batch_size])             | Defaults for `embeddings` / `embed`.                               |
| [`ImageConfig`](_autosummary/aix.config.html.md#aix.config.ImageConfig)([model, size, quality, num_images])  | Defaults for `generate_image` / `generate_images`.                 |
| [`AudioConfig`](_autosummary/aix.config.html.md#aix.config.AudioConfig)([tts_model, tts_voice, ...])         | Defaults for `text_to_speech` / `transcribe` / `translate_audio`.  |
| [`VideoConfig`](_autosummary/aix.config.html.md#aix.config.VideoConfig)([provider])                          | Defaults for `generate_video` (provider-dependent).                |
| [`VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)([model])                            | Defaults for `describe_image` (image→text).                        |
| [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)([chat, embeddings, image, audio, ...]) | Top-level AIX configuration (single source of truth for defaults). |

### *class* aix.config.AixConfig(chat=<factory>, embeddings=<factory>, image=<factory>, audio=<factory>, video=<factory>, vision=<factory>, aliases=<factory>)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Top-level AIX configuration (single source of truth for defaults).

### *class* aix.config.AudioConfig(tts_model='gpt-4o-mini-tts', tts_voice='alloy', tts_speed=1.0, transcription_model='whisper-1')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `text_to_speech` / `transcribe` / `translate_audio`.

### *class* aix.config.ChatConfig(model='gpt-4.1-mini', temperature=1.0, max_tokens=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `chat` / `ask` / `prompt_func`.

### *class* aix.config.EmbeddingConfig(model='text-embedding-3-small', batch_size=512)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `embeddings` / `embed`.

### *class* aix.config.ImageConfig(model='dall-e-3', size='1024x1024', quality='standard', num_images=1)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `generate_image` / `generate_images`.

### *class* aix.config.VideoConfig(provider=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `generate_video` (provider-dependent).

### *class* aix.config.VisionConfig(model='gpt-4o-mini')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Defaults for `describe_image` (image→text).

The default is a cheap, vision-capable OpenAI model so it works with the
same `OPENAI_API_KEY` most users already have; override per call
(`describe_image(..., model=...)`), via `configure(vision_model=...)`,
or the `[vision]` TOML section to route to Claude / Gemini / etc.

### aix.config.config_file_path()

Path to the user config file (env `AIX_CONFIG_FILE` overrides default).

* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

### aix.config.configure(\*\*overrides)

Apply runtime overrides to the active config and return it.

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### Examples

```pycon
>>> from aix import config
>>> _ = config.configure(chat_model="openai/gpt-4o-mini")
>>> config.get_config().chat.model
'openai/gpt-4o-mini'
>>> _ = config.configure(chat={"temperature": 0.2})
>>> config.get_config().chat.temperature
0.2
```

### aix.config.get_config()

Return the current active [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig).

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### aix.config.load_config(path=None, , environ=None)

Resolve an [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig) from shipped defaults, TOML file, and env.

Precedence (low to high): shipped defaults < TOML file < environment variables.
Runtime overrides ([`configure()`](_autosummary/aix.config.html.md#aix.config.configure)/[`using()`](_autosummary/aix.config.html.md#aix.config.using)) and explicit call arguments
sit above this and are applied elsewhere.

* **Parameters:**
  * **path** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional explicit TOML path. Defaults to [`config_file_path()`](_autosummary/aix.config.html.md#aix.config.config_file_path).
  * **environ** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Mapping`](https://docs.python.org/3/library/typing.html#typing.Mapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional environment mapping (defaults to `os.environ`).
* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)
* **Returns:**
  A fully resolved [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig).

### aix.config.resolve_model(model, , config=None)

Resolve a semantic alias (`"fast"`, `"best"`, …) to a concrete model id.

Plain substitution: if `model` is a key in the active `aliases` table it is
replaced (following chains, with cycle protection). Anything that is not an
alias – including every literal model id like `"gpt-4o"` – is returned
unchanged. `None` passes through (callers apply their own default first).

#### NOTE
aliases share a namespace with literal model ids, so an unknown name is
treated as a literal id, not an error. Inspect available aliases via
`aix.get_config().aliases`.

### Examples

```pycon
>>> from aix import config
>>> config.resolve_model("fast") in config.DEFAULT_ALIASES.values()
True
>>> config.resolve_model("gpt-4o")  # not an alias -> unchanged
'gpt-4o'
>>> config.resolve_model(None) is None
True
```

* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### aix.config.set_config(config)

Replace the active config wholesale. Returns the new active config.

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### aix.config.using(\*\*overrides)

Context manager applying scoped overrides, restored on exit.

* **Return type:**
  [`Iterator`](https://docs.python.org/3/library/typing.html#typing.Iterator)[[`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)]

### Examples

```pycon
>>> from aix import config
>>> with config.using(chat_temperature=0.0) as c:
...     c.chat.temperature
0.0
```


# _autosummary/aix.credentials.html.md

# aix.credentials

Unified, discoverable API-key / secret resolution for AIX.

Every key-requiring function in AIX (`chat`, `embeddings`, `generate_image`,
`text_to_speech`, `transcribe`, `generate_video`, …) resolves its
credentials through a single, documented path – instead of relying on LiteLLM’s
implicit environment reading, scattered `os.getenv` calls, or an orphaned
config getter.

Resolution layers, highest precedence first:

1. **Explicit argument** – `chat(..., api_key=...)`.
2. **Provider environment variable** – the canonical name for the inferred
   provider (e.g. `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`).
   A project `.env` is *softly* discovered when `python-dotenv` is installed
   (no hard dependency); explicit env vars always win over `.env` values.
3. **AIX config store** – a config2py central store in the user app-config
   folder, keyed by the canonical env-var name (so the store and the env layer
   share one namespace). See [`aix.util`](_autosummary/aix.util.html.md#module-aix.util).
4. **(REPL only) interactive prompt** – when `prompt_if_missing=True` *and*
   running interactively, ask once and persist to the config store.

The provider for a model id is inferred via LiteLLM’s `get_llm_provider`; a
small curated `PROVIDER_ENV_VARS` table maps each documented provider to
its env-var name(s) and console URL.

When a required key is genuinely absent, [`check_requirements()`](_autosummary/aix.credentials.html.md#aix.credentials.check_requirements) raises
[`MissingCredentialError`](_autosummary/aix.credentials.html.md#aix.credentials.MissingCredentialError) – naming *which* key is missing, *how* to set
it, and *where* to obtain one – rather than letting a cryptic, provider-specific
LiteLLM error surface late. This preflight is wired in via the
[`requires_credentials()`](_autosummary/aix.credentials.html.md#aix.credentials.requires_credentials) decorator so error-raising stays separate from
business logic.

### Examples

```pycon
>>> from aix.credentials import resolve_api_key, PROVIDER_ENV_VARS
>>> resolve_api_key("gpt-4o", api_key="sk-explicit")  # explicit wins
'sk-explicit'
>>> "openai" in PROVIDER_ENV_VARS
True
```

Security:
: Resolved key *values* are never logged or returned by diagnostics;
  [`check_keys()`](_autosummary/aix.credentials.html.md#aix.credentials.check_keys) reports availability only. Keys live in the user
  app-config folder, never in the repo.

### Functions

| [`infer_provider`](_autosummary/aix.credentials.html.md#aix.credentials.infer_provider)(model_or_provider)                | Infer the provider name from a model id (or pass through a provider name).   |
|---------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| [`provider_env_vars`](_autosummary/aix.credentials.html.md#aix.credentials.provider_env_vars)(provider)                      | Return the env-var name(s) for `provider` as a list (possibly empty).        |
| [`resolve_api_key`](_autosummary/aix.credentials.html.md#aix.credentials.resolve_api_key)(model_or_provider, \*[, ...])    | Resolve an API key for `model_or_provider` through the documented layers.    |
| [`check_requirements`](_autosummary/aix.credentials.html.md#aix.credentials.check_requirements)(model_or_provider, \*[, ...]) | Presence-only preflight: ensure a key for `model_or_provider` is resolvable. |
| [`requires_credentials`](_autosummary/aix.credentials.html.md#aix.credentials.requires_credentials)(default_model)              | Decorator: preflight credentials before the wrapped function runs.           |
| [`check_keys`](_autosummary/aix.credentials.html.md#aix.credentials.check_keys)([providers])                          | Report, per provider, whether a usable API key is discoverable.              |

### Exceptions

| [`MissingCredentialError`](_autosummary/aix.credentials.html.md#aix.credentials.MissingCredentialError)(model_or_provider, \*)   | Raised when a required API key cannot be resolved.   |
|--------------------------------------------------------------------------------------------------|------------------------------------------------------|

### *exception* aix.credentials.MissingCredentialError(model_or_provider, , provider=None, env_names=None)

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Raised when a required API key cannot be resolved.

The message names which key is missing, how to set it, and (when known)
where to obtain one. Key *values* are never included.

### aix.credentials.check_keys(providers=None)

Report, per provider, whether a usable API key is discoverable.

Never returns or logs key *values* – only availability and the env-var
name(s) checked. Useful for quick setup debugging.

* **Parameters:**
  **providers** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Providers to check; defaults to every provider in
  `PROVIDER_ENV_VARS`.
* **Returns:**
  bool, “env_vars”: […],
  “source”: <where-found-or-None>}\`\`. `source` is `"env"`, `"store"`,
  or `None` (never the value itself).
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]

### Examples

```pycon
>>> report = check_keys(["openai"])
>>> report["openai"]["available"]
True
```

### aix.credentials.check_requirements(model_or_provider, , api_key=None)

Presence-only preflight: ensure a key for `model_or_provider` is resolvable.

Does *not* validate the key over the network – only that one is discoverable
via [`resolve_api_key()`](_autosummary/aix.credentials.html.md#aix.credentials.resolve_api_key) (explicit arg, env/.env, or store). Raises
[`MissingCredentialError`](_autosummary/aix.credentials.html.md#aix.credentials.MissingCredentialError) with actionable guidance when absent.

Returns `True` when a key is available.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

### Examples

```pycon
>>> check_requirements("gpt-4o", api_key="sk-explicit")
True
```

### aix.credentials.infer_provider(model_or_provider)

Infer the provider name from a model id (or pass through a provider name).

Uses LiteLLM’s `get_llm_provider` when available. If `model_or_provider`
is already a known provider name (a key in `PROVIDER_ENV_VARS`), it is
returned as-is. Returns `None` if the provider cannot be determined.

* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### Examples

```pycon
>>> infer_provider("gpt-4o")
'openai'
>>> infer_provider("openrouter")  # already a provider name
'openrouter'
>>> infer_provider(None) is None
True
```

### aix.credentials.provider_env_vars(provider)

Return the env-var name(s) for `provider` as a list (possibly empty).

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### Examples

```pycon
>>> provider_env_vars("openai")
['OPENAI_API_KEY']
>>> provider_env_vars("gemini")
['GEMINI_API_KEY', 'GOOGLE_API_KEY']
>>> provider_env_vars("totally-unknown-provider")
[]
```

### aix.credentials.requires_credentials(default_model)

Decorator: preflight credentials before the wrapped function runs.

Separates error-raising from business logic (per the AIX coding principles).
The wrapped function is expected to take keyword-only `model` and
`api_key` parameters. `default_model` is a zero-arg callable returning the
model the function would default to (read from the active config at call
time), so the preflight checks the *same* model the function will use.

* **Parameters:**
  **default_model** ([`Callable`](https://docs.python.org/3/library/typing.html#typing.Callable)[[], [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Callable returning the default model id when the caller
  passes `model=None`.

### Examples

```pycon
>>> from aix import config
>>> @requires_credentials(lambda: config.get_config().chat.model)
... def f(*, model=None, api_key=None):
...     return "ran"
>>> f(api_key="sk-explicit")
'ran'
```

### aix.credentials.resolve_api_key(model_or_provider, , api_key=None, prompt_if_missing=False)

Resolve an API key for `model_or_provider` through the documented layers.

Layers, highest precedence first: explicit `api_key` argument, provider
environment variable (with soft `.env` discovery), the AIX config store,
and – only when `prompt_if_missing` is true *and* running interactively –
an interactive prompt that persists the answer.

* **Parameters:**
  * **model_or_provider** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – A model id (provider inferred via LiteLLM) or a
    provider name directly (e.g. `"openai"`).
  * **api_key** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – An explicit key; when given (non-empty) it is returned verbatim.
  * **prompt_if_missing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If true, fall back to a REPL prompt + persist when no
    key is found elsewhere. Off by default so the common path never
    blocks on input.
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  The resolved key, or `None` if genuinely absent.

### Examples

```pycon
>>> resolve_api_key("gpt-4o", api_key="sk-explicit")
'sk-explicit'
```


# _autosummary/aix.gen_ai.google_genai.html.md

# aix.gen_ai.google_genai

Google GenAI API functionality.

### Classes

| `Const`()   |    |
|-------------|----|


# _autosummary/aix.gen_ai.html.md

# aix.gen_ai

Generative AI modules.

### Functions

| [`chat`](_autosummary/aix.gen_ai.html.md#aix.gen_ai.chat)(prompt, \*, model, \*\*kwargs)   | Chat with the specified model.                    |
|----------------------------------------------------------------------------------------|---------------------------------------------------|
| [`chat_function_for_model`](_autosummary/aix.gen_ai.html.md#aix.gen_ai.chat_function_for_model)(model)        | Return the chat function for the specified model. |

### aix.gen_ai.chat(prompt, , model, \*\*kwargs)

Chat with the specified model.

### aix.gen_ai.chat_function_for_model(model)

Return the chat function for the specified model.

### Modules

| [`google_genai`](_autosummary/aix.gen_ai.google_genai.html.md#module-aix.gen_ai.google_genai)   | Google GenAI API functionality.   |
|------------------------------------------------------------------------------------------------|-----------------------------------|
| [`openai_genai`](_autosummary/aix.gen_ai.openai_genai.html.md#module-aix.gen_ai.openai_genai)   | OpenAI GenAI API functionality.   |


# _autosummary/aix.gen_ai.openai_genai.html.md

# aix.gen_ai.openai_genai

OpenAI GenAI API functionality.


# _autosummary/aix.html.md

# aix

AIX: Artificial Intelligence eXtensions

A clean, pythonic facade for common AI operations that abstracts away
provider-specific details and complexities.

Quick Start:

> ```pycon
> >>> from aix import chat, embeddings, prompt_func, models
> ```

> ### Simple chat

> ```pycon
> >>> response = chat("What is 2+2?")
> 'The answer is 4.'
> ```

> ### Create prompt-based functions

> ```pycon
> >>> translate = prompt_func("Translate to French: {text}")
> >>> translate(text="Hello world")
> 'Bonjour le monde'
> ```

> ### Get embeddings

> ```pycon
> >>> vecs = list(embeddings(["hello", "world"]))
> >>> len(vecs)
> 2
> ```

> ### Discover models

> ```pycon
> >>> models.discover()
> >>> list(models)[:5]
> ['openai/gpt-4o', 'openai/gpt-4o-mini', ...]
> ```

Main Features:

> - chat(): Simple chat interface across providers
> - embeddings(): Vector embeddings for text
> - prompt_func(): Create functions from prompt templates
> - models: Model discovery and selection
> - generate_image(): Text-to-image generation
> - text_to_speech(), transcribe(): Audio operations
> - generate_video(): Text-to-video generation (provider-dependent)
> - Batch operations for efficiency
> - Clean, i2mint-style Mapping interfaces

Backends:

> - Uses LiteLLM for provider interactions
> - Supports OpenAI, Anthropic, Google, and 100+ models
> - OpenRouter integration for multi-provider access

For detailed documentation, see: [https://github.com/thorwhalen/aix](https://github.com/thorwhalen/aix)

### Functions

| [`get_config`](_autosummary/aix.html.md#aix.get_config)()                                       | Return the current active [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig).                            |
|-----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| [`set_config`](_autosummary/aix.html.md#aix.set_config)(config)                                 | Replace the active config wholesale.                                                                             |
| [`configure`](_autosummary/aix.html.md#aix.configure)(\*\*overrides)                           | Apply runtime overrides to the active config and return it.                                                      |
| [`using`](_autosummary/aix.html.md#aix.using)(\*\*overrides)                               | Context manager applying scoped overrides, restored on exit.                                                     |
| [`load_config`](_autosummary/aix.html.md#aix.load_config)([path, environ])                       | Resolve an [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig) from shipped defaults, TOML file, and env. |
| [`resolve_model`](_autosummary/aix.html.md#aix.resolve_model)(model, \*[, config])                 | Resolve a semantic alias (`"fast"`, `"best"`, ...) to a concrete model id.                                       |
| [`resolve_api_key`](_autosummary/aix.html.md#aix.resolve_api_key)(model_or_provider, \*[, ...])      | Resolve an API key for `model_or_provider` through the documented layers.                                        |
| [`check_requirements`](_autosummary/aix.html.md#aix.check_requirements)(model_or_provider, \*[, ...])   | Presence-only preflight: ensure a key for `model_or_provider` is resolvable.                                     |
| [`check_keys`](_autosummary/aix.html.md#aix.check_keys)([providers])                            | Report, per provider, whether a usable API key is discoverable.                                                  |
| [`chat`](_autosummary/aix.html.md#aix.chat)(prompt, \*[, model, temperature, ...])        | Send a chat prompt and get a response.                                                                           |
| [`ask`](_autosummary/aix.html.md#aix.ask)(question[, model])                             | Ask a single question and get an answer.                                                                         |
| [`chat_with_history`](_autosummary/aix.html.md#aix.chat_with_history)([system_prompt, model])          | Create a stateful chat session that maintains conversation history.                                              |
| [`embeddings`](_autosummary/aix.html.md#aix.embeddings)(segments, \*[, model, api_key])         | Generate embeddings for multiple text segments.                                                                  |
| [`embed`](_autosummary/aix.html.md#aix.embed)(text, \*[, model])                           | Generate embedding for a single text.                                                                            |
| [`cosine_similarity`](_autosummary/aix.html.md#aix.cosine_similarity)(vec1, vec2)                      | Compute cosine similarity between two vectors.                                                                   |
| [`find_most_similar`](_autosummary/aix.html.md#aix.find_most_similar)(query, candidates, \*[, ...])    | Find most similar texts to a query.                                                                              |
| [`prompt_func`](_autosummary/aix.html.md#aix.prompt_func)(template, \*[, output_schema, ...])    | Create a callable function from a prompt template.                                                               |
| [`prompt_to_text`](_autosummary/aix.html.md#aix.prompt_to_text)(template, \*\*kwargs)               | Create a function that returns text output.                                                                      |
| [`prompt_to_json`](_autosummary/aix.html.md#aix.prompt_to_json)(template, schema, \*\*kwargs)       | Create a function that returns structured JSON output.                                                           |
| [`constrained_answer`](_autosummary/aix.html.md#aix.constrained_answer)(prompt, valid_answers, \*)      | Get an answer from the LLM constrained to a set of valid answers or types.                                       |
| [`discover_available_models`](_autosummary/aix.html.md#aix.discover_available_models)([source, verbose])       | Discover available models from a source.                                                                         |
| [`get_model_info`](_autosummary/aix.html.md#aix.get_model_info)(model_id)                           | Get information about a specific model.                                                                          |
| [`find_models`](_autosummary/aix.html.md#aix.find_models)(query)                                 | Search for models matching a query.                                                                              |
| [`batch_chat`](_autosummary/aix.html.md#aix.batch_chat)(prompts, \*[, model, batch_size, ...])  | Process multiple chat prompts in batches.                                                                        |
| [`batch_embeddings`](_autosummary/aix.html.md#aix.batch_embeddings)(segments, \*[, model, ...])       | Generate embeddings for multiple texts in batches.                                                               |
| [`batch_process`](_autosummary/aix.html.md#aix.batch_process)(items, process_func, \*[, ...])      | Generic batch processing with parallel execution and retries.                                                    |
| [`generate_image`](_autosummary/aix.html.md#aix.generate_image)(prompt, \*[, model, size, ...])     | Generate a single image from a text prompt.                                                                      |
| [`generate_images`](_autosummary/aix.html.md#aix.generate_images)(prompt, \*[, n, model, size, ...]) | Generate multiple images from a text prompt.                                                                     |
| [`edit_image`](_autosummary/aix.html.md#aix.edit_image)(image_path, prompt, \*[, ...])          | Edit an existing image based on a prompt.                                                                        |
| [`create_variation`](_autosummary/aix.html.md#aix.create_variation)(image_path, \*[, model, ...])     | Create variations of an existing image.                                                                          |
| [`text_to_speech`](_autosummary/aix.html.md#aix.text_to_speech)(text, \*[, model, voice, ...])      | Convert text to speech audio.                                                                                    |
| [`transcribe`](_autosummary/aix.html.md#aix.transcribe)(audio, \*[, engine, model, ...])        | Transcribe audio to text.                                                                                        |
| [`transcribe_with_timestamps`](_autosummary/aix.html.md#aix.transcribe_with_timestamps)(audio, \*[, ...])       | Transcribe audio with detailed timestamps.                                                                       |
| [`translate_audio`](_autosummary/aix.html.md#aix.translate_audio)(audio, \*[, model, prompt, ...])   | Translate audio from any language to English.                                                                    |
| [`generate_video`](_autosummary/aix.html.md#aix.generate_video)(prompt, \*[, model, duration, ...]) | Generate a video from a text prompt.                                                                             |
| [`animate_image_to_video`](_autosummary/aix.html.md#aix.animate_image_to_video)(image_path[, prompt, ...])  | Animate a static image into a video.                                                                             |
| [`extend_video`](_autosummary/aix.html.md#aix.extend_video)(video_path[, prompt, ...])            | Extend an existing video with additional generated content.                                                      |
| [`get_video_providers`](_autosummary/aix.html.md#aix.get_video_providers)()                              | Get list of available video generation providers.                                                                |
| [`describe_image`](_autosummary/aix.html.md#aix.describe_image)(image, \*[, prompt, model, ...])    | Describe (or answer a question about) `image` and return the text.                                               |
| [`to_image_content`](_autosummary/aix.html.md#aix.to_image_content)(image, \*[, detail])              | Build a multimodal `image_url` content block for `image`.                                                        |
| [`compare_images`](_autosummary/aix.html.md#aix.compare_images)(candidate, reference, \*[, ...])    | Compare a `candidate` image to `reference` image(s) on a rubric.                                                 |

### Classes

| [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig)([chat, embeddings, image, audio, ...])   | Top-level AIX configuration (single source of truth for defaults).   |
|-----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| [`ChatSession`](_autosummary/aix.html.md#aix.ChatSession)([system_prompt, model])                | Stateful chat session that maintains conversation history.           |
| [`EmbeddingCache`](_autosummary/aix.html.md#aix.EmbeddingCache)([model])                            | Cache for embeddings to avoid redundant API calls.                   |
| [`PromptFuncs`](_autosummary/aix.html.md#aix.PromptFuncs)([model])                               | Collection of prompt-based functions.                                |
| [`ModelStore`](_autosummary/aix.html.md#aix.ModelStore)([storage_path, auto_discover])          | User-friendly interface for model discovery and selection.           |
| [`BatchProcessor`](_autosummary/aix.html.md#aix.BatchProcessor)(\*[, batch_size, max_workers, ...]) | Stateful batch processor for managing long-running operations.       |
| [`BatchError`](_autosummary/aix.html.md#aix.BatchError)(exception, \*[, index, message])        | A batch result slot standing in for an item that raised.             |
| [`GeneratedImage`](_autosummary/aix.html.md#aix.GeneratedImage)([url, b64_json, model, ...])        | Wrapper for generated images.                                        |
| [`GeneratedAudio`](_autosummary/aix.html.md#aix.GeneratedAudio)(data[, model, text, voice, ...])    | Wrapper for generated audio.                                         |
| [`TranscriptionResult`](_autosummary/aix.html.md#aix.TranscriptionResult)(text[, language, ...])         | Result of audio transcription.                                       |
| [`GeneratedVideo`](_autosummary/aix.html.md#aix.GeneratedVideo)([url, data, model, prompt, ...])    | Wrapper for generated videos.                                        |
| [`RubricVerdict`](_autosummary/aix.html.md#aix.RubricVerdict)(aspect, match, confidence[, note])   | A vision model's verdict on a single rubric aspect.                  |
| [`ImageComparison`](_autosummary/aix.html.md#aix.ImageComparison)(match, confidence, explanation)    | Structured result of comparing a candidate image to reference(s).    |

### Exceptions

| [`MissingCredentialError`](_autosummary/aix.html.md#aix.MissingCredentialError)(model_or_provider, \*)   | Raised when a required API key cannot be resolved.                   |
|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| [`ConstraintViolation`](_autosummary/aix.html.md#aix.ConstraintViolation)(message, \*[, answer, ...]) | Raised when an LLM answer does not satisfy the requested constraint. |

### *class* aix.AixConfig(chat=<factory>, embeddings=<factory>, image=<factory>, audio=<factory>, video=<factory>, vision=<factory>, aliases=<factory>)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Top-level AIX configuration (single source of truth for defaults).

### *class* aix.BatchError(exception, , index=None, message=None)

Bases: [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

A batch result slot standing in for an item that raised.

Subclasses `str` so it *is* the `"ERROR: ..."` string these functions
have always put in the failed slot – comparisons, `.startswith`,
slicing, JSON serialisation and logging all behave identically. What it
adds is the ability to tell a failure apart from a model that legitimately
replied with text starting “ERROR:”, and to reach the original exception.

#### exception

The exception that was caught.

#### index

Position of the failed item in the input, when known.

### Examples

```pycon
>>> err = BatchError(RuntimeError("rate limit exceeded"), index=1)
>>> err == "ERROR: rate limit exceeded"
True
>>> isinstance(err, str), isinstance(err.exception, RuntimeError)
(True, True)
>>> err.index
1
```

### *class* aix.BatchProcessor(, batch_size=None, max_workers=None, show_progress=True)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Stateful batch processor for managing long-running operations.

Provides a higher-level interface for batch processing with
progress tracking, error handling, and result caching.

### Examples

```pycon
>>> processor = BatchProcessor(show_progress=True)
>>> results = processor.process_chats(prompts)
>>> processor.save_results("output.json")
```

#### clear()

Clear stored results and errors.

#### process_chats(prompts, \*\*kwargs)

Process chat prompts and store results.

* **Parameters:**
  * **prompts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]]]) – Prompts to process
  * **\*\*kwargs** – Additional parameters for batch_chat()
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  List of results

#### process_embeddings(texts, \*\*kwargs)

Process embeddings and store results.

* **Parameters:**
  * **texts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Texts to embed
  * **\*\*kwargs** – Additional parameters for batch_embeddings()
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]
* **Returns:**
  List of embedding vectors

#### save_results(filepath)

Save results to file.

* **Parameters:**
  **filepath** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Path to save results (JSON)

### *class* aix.ChatSession(system_prompt=None, , model=None, \*\*chat_kwargs)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Stateful chat session that maintains conversation history.

This class provides a convenient way to have multi-turn conversations
without manually managing message history.

### Examples

```pycon
>>> session = ChatSession()
>>> response = session.send("My name is Alice")
>>> response = session.send("What's my name?")
'Your name is Alice.'
```

#### clear_history(keep_system=True)

Clear conversation history.

* **Parameters:**
  **keep_system** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, preserve system message (if any)

#### send(message, \*\*kwargs)

Send a message and get a response.

* **Parameters:**
  * **message** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – User message to send
  * **\*\*kwargs** – Override chat parameters for this message
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  Assistant’s response

### *exception* aix.ConstraintViolation(message, , answer=None, valid_answers=None)

Bases: [`ValueError`](https://docs.python.org/3/builtins/exceptions.html#ValueError)

Raised when an LLM answer does not satisfy the requested constraint.

A subclass of `ValueError` so that callers who already guard
[`constrained_answer()`](_autosummary/aix.html.md#aix.constrained_answer) with `except ValueError` keep working.

#### answer

The offending value, as it came back from the model.

#### valid_answers

The constraint the value failed, verbatim as passed in.

### Examples

```pycon
>>> violation = ConstraintViolation("nope", answer="nope", valid_answers=["a"])
>>> violation.answer, violation.valid_answers
('nope', ['a'])
>>> isinstance(violation, ValueError)
True
```

### *class* aix.EmbeddingCache(model=None, \*\*embedding_kwargs)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Cache for embeddings to avoid redundant API calls.

Useful when you need to embed the same texts multiple times.

### Examples

```pycon
>>> cache = EmbeddingCache()
>>> vec1 = cache.embed("hello")  # API call
>>> vec2 = cache.embed("hello")  # From cache
>>> vec1 == vec2
True
```

#### clear()

Clear the cache.

#### embed(text, force_refresh=False)

Get embedding for text, using cache if available.

* **Parameters:**
  * **text** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text to embed
  * **force_refresh** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, bypass cache and get fresh embedding
* **Return type:**
  [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]
* **Returns:**
  Vector embedding

#### embed_batch(texts, force_refresh=False)

Get embeddings for multiple texts, using cache when possible.

* **Parameters:**
  * **texts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Texts to embed
  * **force_refresh** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, bypass cache
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]
* **Returns:**
  List of embeddings in same order as input texts

### *class* aix.GeneratedAudio(data, model=None, text=None, voice=None, format='mp3')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated audio.

Provides convenient access to audio data and saving.

### Examples

```pycon
>>> audio = GeneratedAudio(data=b'...', model="tts-1")
>>> audio.save("output.mp3")
>>> data = audio.as_bytes()
```

#### as_bytes()

Get audio as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Audio data as bytes

#### play()

Play the audio.

Requires a system audio player or library like pygame/pyaudio.

### Examples

```pycon
>>> audio.play()
```

#### save(path)

Save audio to file.

* **Parameters:**
  **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path

### Examples

```pycon
>>> audio.save("output.mp3")
>>> audio.save("speech.wav")
```

### *class* aix.GeneratedImage(url=None, b64_json=None, model=None, prompt=None, revised_prompt=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated images.

Provides convenient access to image data in various formats.

### Examples

```pycon
>>> img = GeneratedImage(url="https://...", model="dall-e-3")
>>> img.save("output.png")
>>> img.show()
>>> data = img.as_bytes()
```

#### as_bytes()

Get image as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Image data as bytes

#### as_pil_image()

Get image as PIL Image object.

* **Returns:**
  PIL.Image object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If PIL is not installed

#### save(path, format=None)

Save image to file.

* **Parameters:**
  * **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image format (e.g., ‘PNG’, ‘JPEG’). Auto-detected from path if None.

### Examples

```pycon
>>> img.save("output.png")
>>> img.save("output.jpg", format="JPEG")
```

#### show()

Display the image.

Requires PIL (Pillow) to be installed.

### Examples

```pycon
>>> img.show()
```

### *class* aix.GeneratedVideo(url=None, data=None, model=None, prompt=None, duration=None, resolution=None, status='completed', task_id=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated videos.

Provides convenient access to video data and metadata.

### Examples

```pycon
>>> video = GeneratedVideo(url="https://...")
>>> video.save("output.mp4")
>>> print(video.duration)
5.0
```

#### as_bytes()

Get video as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Video data as bytes

#### save(path)

Save video to file.

* **Parameters:**
  **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path

### Examples

```pycon
>>> video.save("output.mp4")
```

#### wait_until_complete(max_wait=300, poll_interval=5)

Wait for video generation to complete (for async operations).

* **Parameters:**
  * **max_wait** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum time to wait in seconds
  * **poll_interval** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Time between status checks in seconds
* **Raises:**
  * [**TimeoutError**](https://docs.python.org/3/builtins/exceptions.html#TimeoutError) – If generation doesn’t complete within max_wait
  * [**RuntimeError**](https://docs.python.org/3/builtins/exceptions.html#RuntimeError) – If generation fails

### *class* aix.ImageComparison(match, confidence, explanation, aspects=<factory>, model=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Structured result of comparing a candidate image to reference(s).

Behaves like an ordered, read-only mapping of `aspect -> RubricVerdict`
(`comparison["identity"]`, `in`, iteration, `len`) so per-aspect
lookups read naturally, while also carrying the overall verdict.

#### match

Overall pass/fail across the whole rubric.

#### confidence

Overall confidence in `[0.0, 1.0]`.

#### explanation

A short overall summary of the comparison.

#### aspects

The per-aspect verdicts, one [`RubricVerdict`](_autosummary/aix.html.md#aix.RubricVerdict) per
rubric item, in rubric order.

#### model

The vision model id that produced the verdict.

#### get(aspect, default=None)

Return the verdict for `aspect`, or `default` if absent.

* **Return type:**
  [`RubricVerdict`](_autosummary/aix.vision.html.md#aix.vision.RubricVerdict) | [`None`](https://docs.python.org/3/builtins/constants.html#None)

### *exception* aix.MissingCredentialError(model_or_provider, , provider=None, env_names=None)

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Raised when a required API key cannot be resolved.

The message names which key is missing, how to set it, and (when known)
where to obtain one. Key *values* are never included.

### *class* aix.ModelStore(storage_path=None, auto_discover=False)

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping)

User-friendly interface for model discovery and selection.

Provides a Mapping interface over the ModelManager with convenient
access patterns and integration with chat/embeddings functions.

### Examples

```pycon
>>> models = ModelStore()
>>> models.discover()  # Fetch available models
```

```pycon
>>> # List all models
>>> list(models)[:5]
['openai/gpt-4o', 'openai/gpt-4o-mini', ...]
```

```pycon
>>> # Get model info
>>> info = models['openai/gpt-4o']
>>> info.provider
'openai'
```

```pycon
>>> # Filter models
>>> openai_models = models.filter(provider='openai')
>>> local_models = models.filter(is_local=True)
```

```pycon
>>> # Use with chat
>>> from aix.chat import chat
>>> model = models['gpt-4o-mini']
>>> chat("Hello", model=model.id)
'Hello! How can I help you?'
```

#### by_provider(provider)

Get all models from a specific provider.

* **Parameters:**
  **provider** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Provider name
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of models

### Examples

```pycon
>>> models = ModelStore()
>>> openai_models = models.by_provider('openai')
```

#### by_task(task)

Get models suitable for a specific task.

* **Parameters:**
  **task** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Task name (‘chat’, ‘embedding’, ‘image’, etc.)
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of suitable models

### Examples

```pycon
>>> models = ModelStore()
>>> chat_models = models.by_task('chat')
```

#### discover(source='openrouter', auto_register=True, verbose=False)

Discover models from a source.

* **Parameters:**
  * **source** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Source name (‘openrouter’, ‘ollama’, etc.)
  * **auto_register** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, add discovered models to registry
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print progress information
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of discovered models

### Examples

```pycon
>>> models = ModelStore()
>>> discovered = models.discover('openrouter')
>>> len(discovered) > 100
True
```

#### filter(, provider=None, is_local=None, min_context_size=None, max_context_size=None, has_capabilities=None, tags=None, custom_filter=None)

Filter models by criteria.

* **Parameters:**
  * **provider** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Filter by provider name (‘openai’, ‘anthropic’, etc.)
  * **is_local** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Filter by local vs remote
  * **min_context_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Minimum context window size
  * **max_context_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum context window size
  * **has_capabilities** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Required capabilities
  * **tags** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Required tags
  * **custom_filter** (`callable`) – Custom filter function: f(Model) -> bool
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of models matching criteria

### Examples

```pycon
>>> models = ModelStore()
>>> models.discover(verbose=False)
```

```pycon
>>> # Get OpenAI models
>>> openai = models.filter(provider='openai')
```

```pycon
>>> # Get local models
>>> local = models.filter(is_local=True)
```

```pycon
>>> # Get cheap models
>>> cheap = models.filter(
...     custom_filter=lambda m: m.cost_per_token.get('input', 0) < 0.001
... )
```

```pycon
>>> # Combine criteria
>>> good_models = models.filter(
...     provider='openai',
...     min_context_size=8000,
...     custom_filter=lambda m: 'gpt-4' in m.id
... )
```

#### get_connector_metadata(model_id, connector)

Get connector-specific metadata for a model.

* **Parameters:**
  * **model_id** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier
  * **connector** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Connector name (‘openai’, ‘openrouter’, etc.)
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]
* **Returns:**
  Dict with connector-specific parameters

### Examples

```pycon
>>> models = ModelStore()
>>> meta = models.get_connector_metadata(
...     'openai/gpt-4o',
...     'openai'
... )
>>> meta['model']
'gpt-4o'
```

#### get_info(model_id)

Get detailed information about a model.

* **Parameters:**
  **model_id** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier
* **Return type:**
  [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)
* **Returns:**
  Model object with full metadata

### Examples

```pycon
>>> models = ModelStore()
>>> models.discover(verbose=False)
>>> info = models.get_info('openai/gpt-4o')
>>> info.context_size
128000
```

#### recommend(, task='chat', max_cost_per_mtok=None, min_context_size=None, prefer_local=False)

Get recommended models based on requirements.

* **Parameters:**
  * **task** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Primary task (‘chat’, ‘embedding’, etc.)
  * **max_cost_per_mtok** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Maximum cost per million tokens
  * **min_context_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Minimum required context size
  * **prefer_local** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Prefer local models if available
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of recommended models, sorted by suitability

### Examples

```pycon
>>> models = ModelStore()
>>> recommendations = models.recommend(
...     task='chat',
...     max_cost_per_mtok=5.0,
...     min_context_size=16000
... )
```

#### search(query)

Search models by text query.

Searches in model ID, provider, and tags.

* **Parameters:**
  **query** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Search query
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of matching models

### Examples

```pycon
>>> models = ModelStore()
>>> models.discover(verbose=False)
>>> results = models.search('gpt-4')
>>> len(results) > 0
True
```

### *class* aix.PromptFuncs(model=None, \*\*default_kwargs)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Collection of prompt-based functions.

Provides a namespace for organizing related prompt functions with
attribute-based access.

### Examples

```pycon
>>> funcs = PromptFuncs()
>>> funcs.add('summarize', "Summarize: {text}")
>>> funcs.add('translate', "Translate {text} to {language}")
>>> funcs.summarize(text="Long article...")
'Summary...'
>>> funcs.translate(text="Hello", language="Spanish")
'Hola'
```

#### add(name, template, , output_schema=None, \*\*kwargs)

Add a function to the collection.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Function name (will be accessible as attribute)
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **output_schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Optional schema for structured output
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

#### keys()

Get all function names.

### *class* aix.RubricVerdict(aspect, match, confidence, note='')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

A vision model’s verdict on a single rubric aspect.

#### aspect

The rubric item this verdict is about (e.g. `"identity"`).

#### match

Whether the candidate matches the reference for this aspect.

#### confidence

The model’s self-reported confidence in `[0.0, 1.0]`.

#### note

A short free-text explanation of the verdict.

### *class* aix.TranscriptionResult(text, language=None, duration=None, segments=None, model=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Result of audio transcription.

Contains the transcribed text and optional metadata like segments and timestamps.

### Examples

```pycon
>>> result = TranscriptionResult(text="Hello world")
>>> print(result.text)
'Hello world'
```

### aix.animate_image_to_video(image_path, prompt=None, , model=None, duration=3.0, motion_strength=0.5, \*\*kwargs)

Animate a static image into a video.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source image
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text prompt to guide the animation
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model to use
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Animation duration in seconds
  * **motion_strength** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Strength of motion (0.0 to 1.0)
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object

### Examples

```pycon
>>> from aix.video import animate_image
>>> video = animate_image(
...     "landscape.jpg",
...     prompt="Gentle camera pan across the scene",
...     duration=4
... )
>>> video.save("animated_landscape.mp4")
```

### aix.ask(question, model=None, \*\*kwargs)

Ask a single question and get an answer.

This is a convenience wrapper around chat() for simple Q&A.

* **Parameters:**
  * **question** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The question to ask
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use
  * **\*\*kwargs** – Additional parameters for chat()
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The answer as a string

### Examples

```pycon
>>> from aix.chat import ask
>>> ask("What is the capital of France?")
'The capital of France is Paris.'
```

### aix.batch_chat(prompts, , model=None, batch_size=None, max_workers=None, show_progress=False, on_error='return', \*\*chat_kwargs)

Process multiple chat prompts in batches.

This function processes multiple prompts efficiently by:

1. Chunking prompts into batches
2. Processing batches in parallel where possible
3. Yielding results in the same order as input

* **Parameters:**
  * **prompts** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]]]) – Iterable of prompts (strings or message lists)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use for all prompts
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of prompts to process in each batch
  * **max_workers** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum number of parallel workers
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print progress information
  * **on_error** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'return'`, `'raise'`, `'skip'`]) – What to do with a prompt whose call raised.
    `'return'` (default) yields a `BatchError` in that slot, keeping
    the stream the same length and order as the input.
    `'raise'` stops after the batch in which the first failure landed
    and re-raises the lowest-indexed exception of that batch.
    `'skip'` omits the failed slots from the stream.
  * **\*\*chat_kwargs** – Additional parameters passed to chat()
* **Yields:**
  Responses in the same order as input prompts. A prompt that raised
  yields a `BatchError` – a `str` subclass equal to `"ERROR: <message>"`,
  carrying the original exception on `.exception`.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `on_error` is not one of ‘return’, ‘raise’, ‘skip’.
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### Examples

```pycon
>>> from aix.batches import batch_chat
>>> prompts = [
...     "What is 2+2?",
...     "What is 3+3?",
...     "What is 5+5?"
... ]
>>> results = list(batch_chat(prompts))
>>> len(results)
3
```

```pycon
>>> # With specific model
>>> results = list(batch_chat(
...     prompts,
...     model="gpt-4o-mini",
...     batch_size=5
... ))
```

```pycon
>>> # Process large dataset
>>> def generate_prompts():
...     for i in range(100):
...         yield f"Explain concept {i}"
>>> results = batch_chat(
...     generate_prompts(),
...     show_progress=True
... )
>>> for i, result in enumerate(results):
...     print(f"Result {i}: {result[:50]}...")
```

```pycon
>>> # Tell a failure apart from a reply that starts with "ERROR:"
>>> for result in batch_chat(prompts):
...     if isinstance(result, BatchError):
...         raise result.exception
```

### aix.batch_embeddings(segments, , model=None, batch_size=None, show_progress=False, \*\*embedding_kwargs)

Generate embeddings for multiple texts in batches.

For efficiency, this function processes embeddings in chunks,
as most embedding APIs can handle multiple texts per request.

* **Parameters:**
  * **segments** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Iterable of text strings to embed
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Embedding model to use
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of texts per batch
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, print progress information
  * **\*\*embedding_kwargs** – Additional parameters for embeddings()
* **Yields:**
  Vector embeddings in the same order as input
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]

### Examples

```pycon
>>> from aix.batches import batch_embeddings
>>> texts = ["hello", "world", "foo", "bar"] * 25  # 100 texts
>>> vectors = list(batch_embeddings(
...     texts,
...     batch_size=10,
...     show_progress=True
... ))
>>> len(vectors)
100
```

```pycon
>>> # Process large dataset efficiently
>>> def read_documents():
...     # Generator that yields documents
...     for i in range(1000):
...         yield f"Document {i} content"
>>> all_vectors = []
>>> for vec in batch_embeddings(read_documents()):
...     all_vectors.append(vec)
```

### aix.batch_process(items, process_func, , batch_size=None, max_workers=None, show_progress=False, retry_attempts=None, retry_delay=None, on_error='return')

Generic batch processing with parallel execution and retries.

This is a general-purpose batch processor that can be used for
any operation, not just chat or embeddings.

* **Parameters:**
  * **items** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – Items to process
  * **process_func** (`callable`) – Function to apply to each item
  * **batch_size** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Batch size for chunking
  * **max_workers** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum parallel workers
  * **show_progress** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Show progress information
  * **retry_attempts** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of retry attempts on failure
  * **retry_delay** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Delay between retries (seconds)
  * **on_error** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'return'`, `'raise'`, `'skip'`]) – What to do with an item still failing after every retry.
    `'return'` (default) yields a `BatchError` in that slot, `'raise'`
    re-raises, `'skip'` omits it. See [`batch_chat()`](_autosummary/aix.html.md#aix.batch_chat).
* **Yields:**
  Results in same order as input. An item that raised yields a
  `BatchError` – a `str` subclass equal to `"ERROR: <message>"`,
  carrying the original exception on `.exception`.
* **Raises:**
  [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `on_error` is not one of ‘return’, ‘raise’, ‘skip’.
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]

### Examples

```pycon
>>> from aix.batches import batch_process
>>> from aix.chat import chat
```

```pycon
>>> # Custom processing function
>>> def analyze_sentiment(text):
...     return chat(f"Analyze sentiment: {text}")
```

```pycon
>>> texts = ["I love this!", "This is terrible", "It's okay"]
>>> results = list(batch_process(
...     texts,
...     analyze_sentiment,
...     batch_size=5
... ))
```

```pycon
>>> # With retries for flaky operations
>>> def flaky_api_call(item):
...     # Some API that might fail
...     return call_api(item)
```

```pycon
>>> results = batch_process(
...     items,
...     flaky_api_call,
...     retry_attempts=3,
...     retry_delay=2.0
... )
```

### aix.chat(prompt, , model=None, temperature=None, max_tokens=None, stream=False, api_key=None, \*\*kwargs)

Send a chat prompt and get a response.

This is the main chat interface for AIX. It abstracts away provider-specific
details and provides a clean, consistent API across all models.

* **Parameters:**
  * **prompt** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]]) – Either a string (becomes a user message) or a list of message dicts
    with ‘role’ and ‘content’ keys
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier (e.g., ‘gpt-4o’, ‘claude-sonnet-4’,
    ‘openrouter/anthropic/claude-3.5-sonnet’). If None, uses default.
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Sampling temperature (0.0 = deterministic, 2.0 = creative).
    If None, uses default (1.0).
  * **max_tokens** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum tokens to generate. If None, uses model’s default.
  * **stream** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, return an iterator of text chunks. If False, return
    complete response as string.
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key. If None, resolved from the environment / .env
    / AIX config store for the model’s provider (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters passed to LiteLLM
* **Returns:**
  Complete response as string
  If stream=True: Iterator yielding text chunks as they arrive
* **Return type:**
  `Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]
* **Raises:**
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If prompt format is invalid

### Examples

```pycon
>>> chat("What is Python?")
'Python is a high-level programming language...'
```

```pycon
>>> chat("Hello", model="gpt-4o")
'Hello! How can I assist you today?'
```

```pycon
>>> # Streaming response
>>> for chunk in chat("Count to 5", stream=True):
...     print(chunk, end='', flush=True)
1, 2, 3, 4, 5
```

```pycon
>>> # With message history
>>> messages = [
...     {"role": "system", "content": "You are a helpful assistant."},
...     {"role": "user", "content": "What is 2+2?"}
... ]
>>> chat(messages)
'2+2 equals 4.'
```

### aix.chat_with_history(system_prompt=None, , model=None, \*\*chat_kwargs)

Create a stateful chat session that maintains conversation history.

* **Parameters:**
  * **system_prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional system message to set context/behavior
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use for this session
  * **\*\*chat_kwargs** – Additional parameters passed to chat()
* **Return type:**
  [`ChatSession`](_autosummary/aix.html.md#aix.ChatSession)
* **Returns:**
  ChatSession object with send() method

### Examples

```pycon
>>> session = chat_with_history("You are a helpful math tutor")
>>> session.send("What is 2+2?")
'The answer is 4.'
>>> session.send("And if I add 3 to that?")
'That would be 7.'
>>> len(session.history)
5
```

### aix.check_keys(providers=None)

Report, per provider, whether a usable API key is discoverable.

Never returns or logs key *values* – only availability and the env-var
name(s) checked. Useful for quick setup debugging.

* **Parameters:**
  **providers** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Providers to check; defaults to every provider in
  `PROVIDER_ENV_VARS`.
* **Returns:**
  bool, “env_vars”: […],
  “source”: <where-found-or-None>}\`\`. `source` is `"env"`, `"store"`,
  or `None` (never the value itself).
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]

### Examples

```pycon
>>> report = check_keys(["openai"])
>>> report["openai"]["available"]
True
```

### aix.check_requirements(model_or_provider, , api_key=None)

Presence-only preflight: ensure a key for `model_or_provider` is resolvable.

Does *not* validate the key over the network – only that one is discoverable
via [`resolve_api_key()`](_autosummary/aix.html.md#aix.resolve_api_key) (explicit arg, env/.env, or store). Raises
[`MissingCredentialError`](_autosummary/aix.html.md#aix.MissingCredentialError) with actionable guidance when absent.

Returns `True` when a key is available.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

### Examples

```pycon
>>> check_requirements("gpt-4o", api_key="sk-explicit")
True
```

### aix.compare_images(candidate, reference, , rubric=('identity', 'costume', 'setting', 'lighting', 'props'), model=None, api_key=None, max_tokens=None, temperature=0.0, detail=None, instruction='You are a strict visual continuity supervisor. The FIRST image is the CANDIDATE; the remaining image(s) are the locked REFERENCE the candidate must match. Judge each rubric aspect INDEPENDENTLY (do not let one aspect color another). For each aspect decide whether the candidate matches the reference, give a confidence in [0.0, 1.0], and a short note explaining what matches or drifts. Then give an overall match (true only if every important aspect matches), an overall confidence, and a one-sentence explanation.', \*\*kwargs)

Compare a `candidate` image to `reference` image(s) on a rubric.

The explainable half of a reference supervisor: a vision model returns a
per-aspect pass/fail checklist (does the face match? the costume? the set?
the lighting? the props?) plus an overall verdict — the explainable layer
over a cheap numeric identity-cosine gate (which lives elsewhere, e.g.
lookbook). Built on [`to_image_content()`](_autosummary/aix.html.md#aix.to_image_content) (multi-image content block)
and the same multimodal `completion` path as [`describe_image()`](_autosummary/aix.html.md#aix.describe_image),
asked via a JSON contract for a structured answer.

The comparison is *pointwise* (each aspect judged on its own), not a ranked
pairwise comparison, to avoid position bias.

* **Parameters:**
  * **candidate** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – The image under review (URL / path / bytes / PIL image /
    `data:` URI — anything [`to_image_content()`](_autosummary/aix.html.md#aix.to_image_content) accepts).
  * **reference** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any), [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]]) – The locked reference — a single image *or* a sequence of
    images (a locked set) in the same flexible formats. An empty
    sequence is an error.
  * **rubric** ([`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The aspects to evaluate, one verdict per item. Defaults to
    `DFLT_COMPARE_RUBRIC`; pass `DFLT_FILM_RUBRIC` (or any
    custom sequence) to override — e.g. `("face", "architecture",
    "props", "lighting")`. Must be non-empty.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Vision-capable model id or alias. `None` → the configured
    default ([`aix.config.VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)).
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Explicit API key; `None` resolves it for the model’s
    provider from the environment / `.env` / config store.
  * **max_tokens** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Cap on generated tokens (`None` → provider default).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Sampling temperature (default `0.0` for a stable,
    reproducible verdict; `None` → provider default).
  * **detail** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Image detail hint (`"low"` | `"high"` | `"auto"`),
    applied to every image block.
  * **instruction** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The system-style framing prepended to the rubric. Has a
    sensible default; override to retune the supervisor’s strictness.
  * **\*\*kwargs** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Extra provider-specific params forwarded to LiteLLM.
* **Return type:**
  [`ImageComparison`](_autosummary/aix.vision.html.md#aix.vision.ImageComparison)
* **Returns:**
  An [`ImageComparison`](_autosummary/aix.html.md#aix.ImageComparison) — overall `match` / `confidence` /
  `explanation` plus an ordered, mapping-like collection of
  [`RubricVerdict`](_autosummary/aix.html.md#aix.RubricVerdict) (one per rubric aspect, keyed by aspect).
* **Raises:**
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `rubric` is empty or `reference` is an empty
        sequence, or if the model’s reply can’t be parsed as the expected
        JSON verdict.

### Examples

Default rubric, single reference:

```pycon
>>> compare_images("gen.png", "ref.png")
ImageComparison(match=True, confidence=0.9, ...)
```

Filmmaking rubric, a locked reference *set*:

```pycon
>>> from aix.vision import DFLT_FILM_RUBRIC
>>> compare_images(
...     candidate="frame_042.png",
...     reference=["ref_front.png", "ref_side.png"],
...     rubric=DFLT_FILM_RUBRIC,
... )["face_identity"].match
True
```

### aix.configure(\*\*overrides)

Apply runtime overrides to the active config and return it.

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### Examples

```pycon
>>> from aix import config
>>> _ = config.configure(chat_model="openai/gpt-4o-mini")
>>> config.get_config().chat.model
'openai/gpt-4o-mini'
>>> _ = config.configure(chat={"temperature": 0.2})
>>> config.get_config().chat.temperature
0.2
```

### aix.constrained_answer(prompt, valid_answers, , model=None, temperature=None, enhance_prompt=False, n=1, on_violation='raise', max_retries=0)

Get an answer from the LLM constrained to a set of valid answers or types.

Uses JSON mode to ensure the LLM returns a valid response based on constraints.
More flexible than the oa version - works with any model that supports JSON mode
via LiteLLM.

This can be seen as a facade for some common structured output use cases, as well
as a convenient tool to do response statistics and validation (via n>1).

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The question or prompt to ask the LLM
  * **valid_answers** (`Union`[[`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)], [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`int`](https://docs.python.org/3/builtins/functions.html#int)], [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`float`](https://docs.python.org/3/builtins/functions.html#float)], [`type`](https://docs.python.org/3/builtins/functions.html#type), [`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`float`](https://docs.python.org/3/builtins/functions.html#float), [`float`](https://docs.python.org/3/builtins/functions.html#float)]]) – 

    Can be:
    - list[str]: List of valid string options
    - list[int]: List of valid integer options
    - list[float]: List of valid float options
    - bool: Constrains answer to True or False
    - int: Any integer
    - float: Any number
    - tuple[float, float]: Numerical range (min, max) inclusive
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The model to use for the LLM (default: uses DFLT_CHAT_MODEL)
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Temperature for sampling (default: None, uses model’s default).
    Higher values (e.g., 1.0) give more random/varied results.
    Lower values (e.g., 0.0) give more deterministic results.
  * **enhance_prompt** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, adds explicit instructions to the prompt about
    JSON formatting and constraints. If False (default), relies on
    response_format alone. Default is False to match oa behavior.
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of times to call the LLM (default: 1)
  * **on_violation** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'raise'`, `'return'`]) – What to do when the model’s answer does not satisfy
    `valid_answers`. `'raise'` (default) raises `ConstraintViolation`.
    `'return'` returns the model’s value unchecked – the behaviour of
    this function before enforcement existed, kept as an escape hatch.
  * **max_retries** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – How many times to re-ask the model after a violation
    before giving up (default: 0, i.e. ask exactly once). Ignored when
    `on_violation='return'`, which never detects a violation.
* **Returns:**
  One of the valid answers, respecting the type constraint.
  If n > 1, returns a list of answers.
* **Raises:**
  * [**ConstraintViolation**](_autosummary/aix.html.md#aix.ConstraintViolation) – If the answer is not a member of an options list,
        falls outside a `(min, max)` range, or cannot be converted to the
        declared type – unless `on_violation='return'`.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the response is not JSON, or has no “answer” field.

### Examples

```pycon
>>> # String options
>>> answer = constrained_answer(
...     "Is Python compiled or interpreted?",
...     ["compiled", "interpreted", "both"]
... )
>>> answer in ["compiled", "interpreted", "both"]
True
```

```pycon
>>> # Boolean
>>> answer = constrained_answer(
...     "Is Python dynamically typed?",
...     bool
... )
>>> isinstance(answer, bool)
True
```

```pycon
>>> # Integer options
>>> answer = constrained_answer(
...     "How many wheels does a car have?",
...     [2, 3, 4, 6, 8]
... )
>>> answer in [2, 3, 4, 6, 8]
True
```

```pycon
>>> # Numerical range
>>> answer = constrained_answer(
...     "What is a reasonable hourly rate for a senior Python developer? (USD)",
...     (50.0, 300.0)
... )
>>> 50.0 <= answer <= 300.0
True
```

```pycon
>>> # Multiple samples for statistics
>>> answers = constrained_answer(
...     "Which is better: cats or dogs?",
...     ["cats", "dogs"],
...     n=10
... )
>>> len(answers)
10
```

```pycon
>>> # Tolerate an off-constraint answer instead of raising
>>> answer = constrained_answer(
...     "Is Python compiled or interpreted?",
...     ["compiled", "interpreted"],
...     on_violation="return",
... )
```

### aix.cosine_similarity(vec1, vec2)

Compute cosine similarity between two vectors.

* **Parameters:**
  * **vec1** ([`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]) – First vector
  * **vec2** ([`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]) – Second vector
* **Return type:**
  [`float`](https://docs.python.org/3/builtins/functions.html#float)
* **Returns:**
  Cosine similarity (between -1 and 1)

### Examples

```pycon
>>> from aix.embeddings import embed, cosine_similarity
>>> v1 = embed("cat")
>>> v2 = embed("kitten")
>>> similarity = cosine_similarity(v1, v2)
>>> similarity > 0.8
True
```

### aix.create_variation(image_path, , model=None, size=None, n=1, api_key=None, \*\*kwargs)

Create variations of an existing image.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source image
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (typically ‘dall-e-2’)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Output image size
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of variations to generate
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  `Union`[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]]
* **Returns:**
  GeneratedImage or list of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import create_variation
>>> variations = create_variation(
...     "original.png",
...     n=3,
...     size="512x512"
... )
>>> for i, var in enumerate(variations):
...     var.save(f"variation_{i}.png")
```

### aix.describe_image(image, , prompt='Describe this image in detail.', model=None, api_key=None, max_tokens=None, temperature=None, detail=None, \*\*kwargs)

Describe (or answer a question about) `image` and return the text.

The image→text primitive. `image` accepts a URL, a local path, raw bytes,
a PIL image, or a `data:` URI (see [`to_image_content()`](_autosummary/aix.html.md#aix.to_image_content)). `prompt` is
the instruction (default: a generic “describe this image”); pass a question
for VQA or a rubric for a judgement. Everything past `image` is keyword.

* **Parameters:**
  * **image** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – The image (URL / path / bytes / PIL image / `data:` URI).
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The text instruction accompanying the image.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Vision-capable model id (e.g. `gpt-4o`, `claude-sonnet-4-6`,
    `gemini/gemini-1.5-pro`) or an alias. `None` → the configured
    default ([`aix.config.VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)).
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Explicit API key; `None` resolves it from the environment /
    `.env` / config store for the model’s provider.
  * **max_tokens** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Cap on generated tokens (`None` → provider default).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Sampling temperature (`None` → provider default).
  * **detail** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Image detail hint (`"low"` | `"high"` | `"auto"`).
  * **\*\*kwargs** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Extra provider-specific params forwarded to LiteLLM.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The model’s text response.
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed.

```pycon
>>> describe_image("cat.jpg", prompt="Caption it.")
'A cat on a sofa.'
```

### aix.discover_available_models(source='openrouter', verbose=True)

Discover available models from a source.

Convenience function that uses the global models instance.

* **Parameters:**
  * **source** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Source name (‘openrouter’, ‘ollama’, etc.)
  * **verbose** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – Print progress information
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of discovered models

### Examples

```pycon
>>> from aix.models import discover_available_models
>>> models = discover_available_models('openrouter')
>>> len(models) > 100
True
```

### aix.edit_image(image_path, prompt, , mask_path=None, model=None, size=None, n=1, api_key=None, \*\*kwargs)

Edit an existing image based on a prompt.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the image to edit
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Description of the desired edit
  * **mask_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Optional path to mask image (transparent areas will be edited)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (typically ‘dall-e-2’ for edits)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Output image size
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of variations to generate
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  `Union`[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]]
* **Returns:**
  GeneratedImage or list of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import edit_image
>>> edited = edit_image(
...     "photo.png",
...     "Add a rainbow in the sky",
...     mask_path="sky_mask.png"
... )
>>> edited.save("edited_photo.png")
```

### aix.embed(text, , model=None, \*\*kwargs)

Generate embedding for a single text.

Convenience function for embedding a single text string.

* **Parameters:**
  * **text** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text string to embed
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier
  * **\*\*kwargs** – Additional parameters for embeddings()
* **Return type:**
  [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]
* **Returns:**
  Vector embedding as sequence of floats

### Examples

```pycon
>>> from aix.embeddings import embed
>>> vec = embed("Hello, world!")
>>> len(vec)
1536
```

```pycon
>>> # Compare similarity
>>> import numpy as np
>>> v1 = np.array(embed("cat"))
>>> v2 = np.array(embed("kitten"))
>>> v3 = np.array(embed("computer"))
>>> # Cosine similarity
>>> np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
0.92  # High similarity
>>> np.dot(v1, v3) / (np.linalg.norm(v1) * np.linalg.norm(v3))
0.23  # Low similarity
```

### aix.embeddings(segments, , model=None, api_key=None, \*\*kwargs)

Generate embeddings for multiple text segments.

This is the main embedding interface for AIX. It abstracts away provider-specific
details and provides a clean, consistent API across all embedding models.

* **Parameters:**
  * **segments** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Iterable of text strings to embed
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier (e.g., ‘text-embedding-3-small’, ‘text-embedding-ada-002’,
    ‘openrouter/openai/text-embedding-3-small’). If None, uses default.
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key. If None, resolved from the environment / .env
    / AIX config store for the model’s provider (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters passed to LiteLLM
* **Yields:**
  Vector embeddings as sequences of floats. Each embedding corresponds to
  one input segment in the same order.
* **Raises:**
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If segments is empty or invalid
* **Return type:**
  [`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]

### Examples

```pycon
>>> from aix.embeddings import embeddings
>>> texts = ["cat", "dog", "bird"]
>>> vecs = list(embeddings(texts))
>>> len(vecs)
3
```

```pycon
>>> # With specific model
>>> vecs = list(embeddings(
...     ["hello", "world"],
...     model="text-embedding-3-large"
... ))
```

```pycon
>>> # Process in chunks for large datasets
>>> def chunk_texts(texts, size=100):
...     for i in range(0, len(texts), size):
...         yield texts[i:i+size]
>>> all_vecs = []
>>> for chunk in chunk_texts(large_dataset):
...     all_vecs.extend(embeddings(chunk))
```

### aix.extend_video(video_path, prompt=None, , extend_duration=2.0, model=None, \*\*kwargs)

Extend an existing video with additional generated content.

* **Parameters:**
  * **video_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source video
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text prompt to guide the extension
  * **extend_duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – How many seconds to add
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object with extended content

### Examples

```pycon
>>> from aix.video import extend_video
>>> extended = extend_video(
...     "original.mp4",
...     prompt="Continue the same scene",
...     extend_duration=3
... )
```

### aix.find_models(query)

Search for models matching a query.

Convenience function that uses the global models instance.

* **Parameters:**
  **query** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Search query
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)]
* **Returns:**
  List of matching models

### Examples

```pycon
>>> from aix.models import find_models
>>> results = find_models('claude')
>>> any('claude' in m.id.lower() for m in results)
True
```

### aix.find_most_similar(query, candidates, , model=None, top_k=5, \*\*kwargs)

Find most similar texts to a query.

* **Parameters:**
  * **query** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Sequence`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Sequence)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]]) – Query text or pre-computed embedding vector
  * **candidates** ([`Iterable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Iterable)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Candidate texts to compare against
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Embedding model to use
  * **top_k** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of top results to return
  * **\*\*kwargs** – Additional parameters for embeddings()
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`float`](https://docs.python.org/3/builtins/functions.html#float)]]
* **Returns:**
  List of (text, similarity_score) tuples, sorted by similarity (highest first)

### Examples

```pycon
>>> query = "What is machine learning?"
>>> docs = [
...     "Machine learning is a type of AI",
...     "Python is a programming language",
...     "Neural networks are used in deep learning",
... ]
>>> results = find_most_similar(query, docs, top_k=2)
>>> results[0][0]  # Most similar doc
'Machine learning is a type of AI'
```

### aix.generate_image(prompt, , model=None, size=None, quality=None, style=None, response_format='url', api_key=None, \*\*kwargs)

Generate a single image from a text prompt.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of the image to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (e.g., ‘dall-e-2’, ‘dall-e-3’, ‘stable-diffusion’)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image size (e.g., ‘1024x1024’, ‘512x512’, ‘1792x1024’)
  * **quality** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image quality (‘standard’ or ‘hd’ for DALL-E 3)
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image style (‘vivid’ or ‘natural’ for DALL-E 3)
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format of response (‘url’ or ‘b64_json’)
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key. If None, resolved from the environment / .env
    / AIX config store for the model’s provider (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)
* **Returns:**
  GeneratedImage object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed

### Examples

```pycon
>>> from aix.image import generate_image
>>> image = generate_image("A serene mountain landscape")
>>> image.save("landscape.png")
```

```pycon
>>> # High quality with DALL-E 3
>>> image = generate_image(
...     "Abstract art with vibrant colors",
...     model="dall-e-3",
...     quality="hd",
...     style="vivid"
... )
```

```pycon
>>> # Specific size
>>> image = generate_image(
...     "A futuristic city",
...     size="1792x1024"
... )
```

### aix.generate_images(prompt, , n=None, model=None, size=None, quality=None, style=None, response_format='url', api_key=None, \*\*kwargs)

Generate multiple images from a text prompt.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of images to generate
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of images to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image size
  * **quality** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image quality
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image style
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format of response
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]
* **Returns:**
  List of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import generate_images
>>> images = generate_images(
...     "A cute robot",
...     n=3,
...     size="512x512"
... )
>>> for i, img in enumerate(images):
...     img.save(f"robot_{i}.png")
```

### aix.generate_video(prompt, , model=None, duration=5.0, resolution='1280x720', fps=24, aspect_ratio=None, style=None, seed=None, api_key=None, \*\*kwargs)

Generate a video from a text prompt.

#### NOTE
This is a high-level interface. Actual implementation depends on
available video generation providers (Runway, Pika, etc.) and may require
provider-specific API keys.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of the video to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model to use
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration in seconds (typically 2-10 seconds)
  * **resolution** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video resolution (‘1280x720’, ‘1920x1080’, etc.)
  * **fps** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Frames per second
  * **aspect_ratio** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Aspect ratio (‘16:9’, ‘9:16’, ‘1:1’, etc.)
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video style hint (provider-specific)
  * **seed** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Random seed for reproducibility
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key for the video provider. If None, resolved from
    the environment / .env / AIX config store (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object
* **Raises:**
  * [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError) – If no video provider is configured
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If required provider SDK is not installed

### Examples

```pycon
>>> from aix.video import generate_video
>>> video = generate_video(
...     "A serene ocean sunset with gentle waves",
...     duration=5,
...     resolution="1920x1080"
... )
>>> video.save("sunset.mp4")
```

```pycon
>>> # Specific style
>>> video = generate_video(
...     "A futuristic city",
...     style="cyberpunk",
...     duration=4
... )
```

### aix.get_config()

Return the current active [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig).

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### aix.get_model_info(model_id)

Get information about a specific model.

Convenience function that uses the global models instance.

* **Parameters:**
  **model_id** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model identifier
* **Return type:**
  [`Model`](_autosummary/aix.ai_models.base.html.md#aix.ai_models.base.Model)
* **Returns:**
  Model object

### Examples

```pycon
>>> from aix.models import get_model_info
>>> info = get_model_info('openai/gpt-4o')
>>> info.provider
'openai'
```

### aix.get_video_providers()

Get list of available video generation providers.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  List of provider names that are configured

### Examples

```pycon
>>> from aix.video import get_available_providers
>>> providers = get_available_providers()
>>> print(providers)
['runway', 'pika']
```

### aix.load_config(path=None, , environ=None)

Resolve an [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig) from shipped defaults, TOML file, and env.

Precedence (low to high): shipped defaults < TOML file < environment variables.
Runtime overrides ([`configure()`](_autosummary/aix.html.md#aix.configure)/[`using()`](_autosummary/aix.html.md#aix.using)) and explicit call arguments
sit above this and are applied elsewhere.

* **Parameters:**
  * **path** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional explicit TOML path. Defaults to `config_file_path()`.
  * **environ** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Mapping`](https://docs.python.org/3/library/typing.html#typing.Mapping)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – Optional environment mapping (defaults to `os.environ`).
* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)
* **Returns:**
  A fully resolved [`AixConfig`](_autosummary/aix.html.md#aix.AixConfig).

### aix.prompt_func(template, , output_schema=None, egress=None, model=None, temperature=None, name=None, \*\*chat_kwargs)

Create a callable function from a prompt template.

This is the main function for creating prompt-based functions. It automatically
detects parameters from the template and creates a function with those parameters.

Without output_schema: Returns text
With output_schema: Returns structured data (dict, list, etc.)
With egress: Returns whatever the egress post-processor returns.

Templates use the default-aware `{name:default}` dialect (matching
`oa.prompt_function`): `{name}` is a required parameter, `{name:default}`
supplies a default value (the text after the colon), and braces inside
`` fenced `` regions are left literal. Plain `{name}`-only templates behave
exactly as before.

```pycon
>>> greet = prompt_func("Greet {name} in {language:English}")
>>> greet.param_names
['name', 'language']
```

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template with {var} placeholders for parameters
  * **output_schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Optional schema for structured output. Can be:
    - Dict mapping field names to types: {“name”: str, “age”: int}
    - A single type for simple outputs: str, int, list, etc.
    - None for plain text output (default)
  * **egress** ([`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – Optional post-processor `(result) -> Any` applied to the output
    before returning — on both the text and structured paths. Lets a caller
    keep “prompt → typed Python value” inside the facade (e.g. parse the
    LLM text into a list of lines/ids) instead of wrapping the returned
    function. `None` (default) returns the raw result unchanged.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use for this function
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Temperature for generation
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional `__name__` for the generated function (for tracing /
    identity). Defaults to `"prompt_based_function"`.
  * **\*\*chat_kwargs** – Additional parameters passed to chat()
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Callable function with parameters derived from template

### Examples

```pycon
>>> # Simple text generation
>>> summarize = prompt_func("Summarize this text: {text}")
>>> summarize(text="Long article...")
'Brief summary...'
```

```pycon
>>> # Structured output
>>> extract = prompt_func(
...     "Extract contact info from: {text}",
...     output_schema={"name": str, "email": str, "phone": str}
... )
>>> result = extract(text="Contact John at john@example.com, 555-1234")
>>> result['name']
'John'
```

```pycon
>>> # Multiple parameters
>>> compare = prompt_func(
...     "Compare {item1} and {item2} in terms of {aspect}. "
...     "Keep it under {word_limit} words."
... )
>>> compare(
...     item1="Python",
...     item2="Java",
...     aspect="learning curve",
...     word_limit=50
... )
'Python has a gentler learning curve...'
```

```pycon
>>> # With specific model
>>> creative_writer = prompt_func(
...     "Write a creative story about {topic}",
...     model="gpt-4o",
...     temperature=1.5
... )
>>> creative_writer(topic="a time-traveling cat")
'Once upon a time, there was a cat named Whiskers...'
```

### aix.prompt_to_json(template, schema, \*\*kwargs)

Create a function that returns structured JSON output.

This is an explicit alias for prompt_func with output_schema.

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Output schema
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Function that returns structured data

### Examples

```pycon
>>> extract = prompt_to_json(
...     "Extract name and age from: {text}",
...     schema={"name": str, "age": int}
... )
>>> result = extract(text="Alice is 30")
>>> isinstance(result, dict)
True
```

### aix.prompt_to_text(template, \*\*kwargs)

Create a function that returns text output.

This is an explicit alias for prompt_func without output_schema.

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Function that returns text

### Examples

```pycon
>>> summarize = prompt_to_text("Summarize: {text}")
>>> result = summarize(text="Long text...")
>>> isinstance(result, str)
True
```

### aix.resolve_api_key(model_or_provider, , api_key=None, prompt_if_missing=False)

Resolve an API key for `model_or_provider` through the documented layers.

Layers, highest precedence first: explicit `api_key` argument, provider
environment variable (with soft `.env` discovery), the AIX config store,
and – only when `prompt_if_missing` is true *and* running interactively –
an interactive prompt that persists the answer.

* **Parameters:**
  * **model_or_provider** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – A model id (provider inferred via LiteLLM) or a
    provider name directly (e.g. `"openai"`).
  * **api_key** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – An explicit key; when given (non-empty) it is returned verbatim.
  * **prompt_if_missing** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If true, fall back to a REPL prompt + persist when no
    key is found elsewhere. Off by default so the common path never
    blocks on input.
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  The resolved key, or `None` if genuinely absent.

### Examples

```pycon
>>> resolve_api_key("gpt-4o", api_key="sk-explicit")
'sk-explicit'
```

### aix.resolve_model(model, , config=None)

Resolve a semantic alias (`"fast"`, `"best"`, …) to a concrete model id.

Plain substitution: if `model` is a key in the active `aliases` table it is
replaced (following chains, with cycle protection). Anything that is not an
alias – including every literal model id like `"gpt-4o"` – is returned
unchanged. `None` passes through (callers apply their own default first).

#### NOTE
aliases share a namespace with literal model ids, so an unknown name is
treated as a literal id, not an error. Inspect available aliases via
`aix.get_config().aliases`.

### Examples

```pycon
>>> from aix import config
>>> config.resolve_model("fast") in config.DEFAULT_ALIASES.values()
True
>>> config.resolve_model("gpt-4o")  # not an alias -> unchanged
'gpt-4o'
>>> config.resolve_model(None) is None
True
```

* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

### aix.set_config(config)

Replace the active config wholesale. Returns the new active config.

* **Return type:**
  [`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)

### aix.text_to_speech(text, , model=None, voice=None, speed=None, response_format='mp3', api_key=None, \*\*kwargs)

Convert text to speech audio.

* **Parameters:**
  * **text** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text to convert to speech
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – TTS model to use (e.g., ‘tts-1’, ‘tts-1-hd’)
  * **voice** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Voice to use (‘alloy’, ‘echo’, ‘fable’, ‘onyx’, ‘nova’, ‘shimmer’)
  * **speed** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Playback speed (0.25 to 4.0)
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Audio format (‘mp3’, ‘opus’, ‘aac’, ‘flac’)
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedAudio`](_autosummary/aix.audio.html.md#aix.audio.GeneratedAudio)
* **Returns:**
  GeneratedAudio object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed

### Examples

```pycon
>>> from aix.audio import text_to_speech
>>> audio = text_to_speech("Hello, how are you?")
>>> audio.save("greeting.mp3")
```

```pycon
>>> # Different voice and speed
>>> audio = text_to_speech(
...     "This is a test.",
...     voice="nova",
...     speed=1.2
... )
```

```pycon
>>> # High quality
>>> audio = text_to_speech(
...     "Important announcement",
...     model="tts-1-hd",
...     voice="onyx"
... )
```

### aix.to_image_content(image, , detail=None)

Build a multimodal `image_url` content block for `image`.

`image` may be:

- an `http(s)://` URL or a `data:` URI — passed through verbatim;
- a local file path (`str` or [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) — read and inlined
  as a base64 `data:` URI with a guessed MIME type;
- raw `bytes` — base64-inlined (MIME sniffed from magic bytes, else JPEG);
- a PIL `Image` — encoded to PNG and inlined.

`detail` (`"low"` | `"high"` | `"auto"`) is forwarded when set; the
block is the OpenAI/LiteLLM multimodal shape understood across providers.

```pycon
>>> to_image_content("https://x/y.jpg")
{'type': 'image_url', 'image_url': {'url': 'https://x/y.jpg'}}
>>> to_image_content("data:image/png;base64,AAAA")["image_url"]["url"][:10]
'data:image'
```

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### aix.transcribe(audio, , engine=None, model=None, language=None, prompt=None, response_format='text', temperature=None, timestamp_granularities=None, api_key=None, \*\*kwargs)

Transcribe audio to text.

By default this routes through LiteLLM (OpenAI-style transcription). Pass
`engine=` to instead delegate to a `scribed` backend — one façade over
many ASR engines (local Whisper / faster-whisper / vosk, or cloud Deepgram /
AssemblyAI / Groq / ElevenLabs / Google …) with speaker diarization and
SRT/VTT output. The return type is unchanged either way, so existing callers
are unaffected.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes.
  * **engine** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional `scribed` backend id (e.g. `"faster-whisper"`,
    `"deepgram"`). When given, transcription is delegated to scribed
    (which resolves that engine’s own credentials); the LiteLLM path is
    bypassed. Requires `pip install 'aix[scribed]'`. See
    `scribed.list_backends()`.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Transcription model (e.g. `'whisper-1'`); for a scribed engine,
    the engine-specific model (e.g. a Whisper size).
  * **language** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Source language (ISO-639-1 code, e.g. `'en'`, `'es'`).
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text to guide the model’s style (LiteLLM path).
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – `'text'` (default) → `str`; `'srt'`/`'vtt'` →
    subtitle `str` (scribed path); else → [`TranscriptionResult`](_autosummary/aix.html.md#aix.TranscriptionResult).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Sampling temperature (LiteLLM path).
  * **timestamp_granularities** ([`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Timestamp types (‘word’, ‘segment’) (LiteLLM path).
  * **\*\*kwargs** – Additional parameters (forwarded to LiteLLM, or to the scribed
    backend — e.g. `diarize=True`).
* **Return type:**
  `Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult)]
* **Returns:**
  `str` for `response_format` in {text, srt, vtt}, else a
  [`TranscriptionResult`](_autosummary/aix.html.md#aix.TranscriptionResult).

### Examples

```pycon
>>> from aix.audio import transcribe
>>> text = transcribe("recording.mp3")
>>> # delegate to a scribed engine (local, free, diarized SRT):
>>> srt = transcribe(
...     "meeting.wav", engine="faster-whisper", response_format="srt"
... )
>>> dg = transcribe(
...     "call.mp3", engine="deepgram", diarize=True,
...     response_format="verbose_json",
... )
```

### aix.transcribe_with_timestamps(audio, , granularity='segment', model=None, \*\*kwargs)

Transcribe audio with detailed timestamps.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes
  * **granularity** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Timestamp granularity (‘word’ or ‘segment’)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Transcription model
  * **\*\*kwargs** – Additional parameters for transcribe()
* **Return type:**
  [`TranscriptionResult`](_autosummary/aix.audio.html.md#aix.audio.TranscriptionResult)
* **Returns:**
  TranscriptionResult with detailed segments

### Examples

```pycon
>>> from aix.audio import transcribe_with_timestamps
>>> result = transcribe_with_timestamps("lecture.mp3")
>>> for segment in result.segments:
...     start = segment['start']
...     end = segment['end']
...     text = segment['text']
...     print(f"[{start:.2f}-{end:.2f}] {text}")
```

### aix.translate_audio(audio, , model=None, prompt=None, api_key=None, \*\*kwargs)

Translate audio from any language to English.

#### NOTE
Currently uses Whisper’s translation capability which translates to English.

* **Parameters:**
  * **audio** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`BinaryIO`](https://docs.python.org/3/library/typing.html#typing.BinaryIO), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)]) – Audio file path, file object, or bytes
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Translation model (typically ‘whisper-1’)
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text to guide translation
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  Translated text in English

### Examples

```pycon
>>> from aix.audio import translate_audio
>>> english_text = translate_audio("spanish_audio.mp3")
>>> print(english_text)
'This is the English translation.'
```

### aix.using(\*\*overrides)

Context manager applying scoped overrides, restored on exit.

* **Return type:**
  [`Iterator`](https://docs.python.org/3/library/typing.html#typing.Iterator)[[`AixConfig`](_autosummary/aix.config.html.md#aix.config.AixConfig)]

### Examples

```pycon
>>> from aix import config
>>> with config.using(chat_temperature=0.0) as c:
...     c.chat.temperature
0.0
```

### Modules

| [`config`](_autosummary/aix.config.html.md#module-aix.config)           | Central configuration for AIX (single source of truth for defaults).   |
|-------------------------------------------------------------------------------------|------------------------------------------------------------------------|
| [`ai_models`](_autosummary/aix.ai_models.html.md#module-aix.ai_models)     | AI Model Management Module.                                            |
| [`audio`](_autosummary/aix.audio.html.md#module-aix.audio)             | Audio operations interface for AIX.                                    |
| [`batches`](_autosummary/aix.batches.html.md#module-aix.batches)         | Batch processing interface for AIX.                                    |
| [`credentials`](_autosummary/aix.credentials.html.md#module-aix.credentials) | Unified, discoverable API-key / secret resolution for AIX.             |
| [`gen_ai`](_autosummary/aix.gen_ai.html.md#module-aix.gen_ai)           | Generative AI modules.                                                 |
| [`image`](_autosummary/aix.image.html.md#module-aix.image)             | Image generation interface for AIX.                                    |
| [`misc`](_autosummary/aix.misc.html.md#module-aix.misc)               | Misc AIX functions.                                                    |
| [`models`](_autosummary/aix.models.html.md#aix.models)                  | User-friendly interface for model discovery and selection.             |
| [`prompts`](_autosummary/aix.prompts.html.md#module-aix.prompts)         | Prompt-based function creation for AIX.                                |
| [`stores`](_autosummary/aix.stores.html.md#module-aix.stores)           | Storage layers for AIX.                                                |
| [`util`](_autosummary/aix.util.html.md#module-aix.util)               | Utils for AIX.                                                         |
| [`video`](_autosummary/aix.video.html.md#module-aix.video)             | Video generation interface for AIX.                                    |
| [`vision`](_autosummary/aix.vision.html.md#module-aix.vision)           | Image-to-text (vision) interface for AIX.                              |


# _autosummary/aix.image.html.md

# aix.image

Image generation interface for AIX.

Generate images from text descriptions using various AI models.

### Examples

Simple image generation:

```pycon
>>> from aix.image import generate_image
>>> image = generate_image("A serene mountain landscape at sunset")
>>> image.save("landscape.png")
```

Multiple images:

```pycon
>>> images = generate_images(
...     "A cute cat wearing a hat",
...     n=3,
...     size="1024x1024"
... )
>>> for i, img in enumerate(images):
...     img.save(f"cat_{i}.png")
```

With specific model:

```pycon
>>> image = generate_image(
...     "Abstract art with vibrant colors",
...     model="dall-e-3"
... )
```

### Functions

| [`create_variation`](_autosummary/aix.image.html.md#aix.image.create_variation)(image_path, \*[, model, ...])     | Create variations of an existing image.      |
|-----------------------------------------------------------------------------------------------------|----------------------------------------------|
| [`edit_image`](_autosummary/aix.image.html.md#aix.image.edit_image)(image_path, prompt, \*[, ...])          | Edit an existing image based on a prompt.    |
| [`generate_image`](_autosummary/aix.image.html.md#aix.image.generate_image)(prompt, \*[, model, size, ...])     | Generate a single image from a text prompt.  |
| [`generate_images`](_autosummary/aix.image.html.md#aix.image.generate_images)(prompt, \*[, n, model, size, ...]) | Generate multiple images from a text prompt. |

### Classes

| [`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)([url, b64_json, model, ...])   | Wrapper for generated images.   |
|------------------------------------------------------------------------------------------------|---------------------------------|

### *class* aix.image.GeneratedImage(url=None, b64_json=None, model=None, prompt=None, revised_prompt=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated images.

Provides convenient access to image data in various formats.

### Examples

```pycon
>>> img = GeneratedImage(url="https://...", model="dall-e-3")
>>> img.save("output.png")
>>> img.show()
>>> data = img.as_bytes()
```

#### as_bytes()

Get image as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Image data as bytes

#### as_pil_image()

Get image as PIL Image object.

* **Returns:**
  PIL.Image object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If PIL is not installed

#### save(path, format=None)

Save image to file.

* **Parameters:**
  * **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image format (e.g., ‘PNG’, ‘JPEG’). Auto-detected from path if None.

### Examples

```pycon
>>> img.save("output.png")
>>> img.save("output.jpg", format="JPEG")
```

#### show()

Display the image.

Requires PIL (Pillow) to be installed.

### Examples

```pycon
>>> img.show()
```

### aix.image.create_variation(image_path, , model=None, size=None, n=1, api_key=None, \*\*kwargs)

Create variations of an existing image.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source image
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (typically ‘dall-e-2’)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Output image size
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of variations to generate
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  `Union`[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]]
* **Returns:**
  GeneratedImage or list of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import create_variation
>>> variations = create_variation(
...     "original.png",
...     n=3,
...     size="512x512"
... )
>>> for i, var in enumerate(variations):
...     var.save(f"variation_{i}.png")
```

### aix.image.edit_image(image_path, prompt, , mask_path=None, model=None, size=None, n=1, api_key=None, \*\*kwargs)

Edit an existing image based on a prompt.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the image to edit
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Description of the desired edit
  * **mask_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Optional path to mask image (transparent areas will be edited)
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (typically ‘dall-e-2’ for edits)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Output image size
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of variations to generate
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  `Union`[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage), [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]]
* **Returns:**
  GeneratedImage or list of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import edit_image
>>> edited = edit_image(
...     "photo.png",
...     "Add a rainbow in the sky",
...     mask_path="sky_mask.png"
... )
>>> edited.save("edited_photo.png")
```

### aix.image.generate_image(prompt, , model=None, size=None, quality=None, style=None, response_format='url', api_key=None, \*\*kwargs)

Generate a single image from a text prompt.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of the image to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use (e.g., ‘dall-e-2’, ‘dall-e-3’, ‘stable-diffusion’)
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image size (e.g., ‘1024x1024’, ‘512x512’, ‘1792x1024’)
  * **quality** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image quality (‘standard’ or ‘hd’ for DALL-E 3)
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image style (‘vivid’ or ‘natural’ for DALL-E 3)
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format of response (‘url’ or ‘b64_json’)
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key. If None, resolved from the environment / .env
    / AIX config store for the model’s provider (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)
* **Returns:**
  GeneratedImage object
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed

### Examples

```pycon
>>> from aix.image import generate_image
>>> image = generate_image("A serene mountain landscape")
>>> image.save("landscape.png")
```

```pycon
>>> # High quality with DALL-E 3
>>> image = generate_image(
...     "Abstract art with vibrant colors",
...     model="dall-e-3",
...     quality="hd",
...     style="vivid"
... )
```

```pycon
>>> # Specific size
>>> image = generate_image(
...     "A futuristic city",
...     size="1792x1024"
... )
```

### aix.image.generate_images(prompt, , n=None, model=None, size=None, quality=None, style=None, response_format='url', api_key=None, \*\*kwargs)

Generate multiple images from a text prompt.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of images to generate
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of images to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use
  * **size** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image size
  * **quality** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image quality
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Image style
  * **response_format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format of response
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`GeneratedImage`](_autosummary/aix.image.html.md#aix.image.GeneratedImage)]
* **Returns:**
  List of GeneratedImage objects

### Examples

```pycon
>>> from aix.image import generate_images
>>> images = generate_images(
...     "A cute robot",
...     n=3,
...     size="512x512"
... )
>>> for i, img in enumerate(images):
...     img.save(f"robot_{i}.png")
```


# _autosummary/aix.misc.html.md

# aix.misc

Misc AIX functions.

### Functions

| [`get_llm_leaderboards`](_autosummary/aix.misc.html.md#aix.misc.get_llm_leaderboards)()   | Get the LLM leaderboards.   |
|---------------------------------------------------------------------------|-----------------------------|

### aix.misc.get_llm_leaderboards()

Get the LLM leaderboards.

Requires the optional `tabled` dependency (`pip install aix[tables]`).


# _autosummary/aix.models.html.md

# aix.models

### aix.models *= ModelStore(0 models)*

User-friendly interface for model discovery and selection.

Provides a Mapping interface over the ModelManager with convenient
access patterns and integration with chat/embeddings functions.

### Examples

```pycon
>>> models = ModelStore()
>>> models.discover()  # Fetch available models
```

```pycon
>>> # List all models
>>> list(models)[:5]
['openai/gpt-4o', 'openai/gpt-4o-mini', ...]
```

```pycon
>>> # Get model info
>>> info = models['openai/gpt-4o']
>>> info.provider
'openai'
```

```pycon
>>> # Filter models
>>> openai_models = models.filter(provider='openai')
>>> local_models = models.filter(is_local=True)
```

```pycon
>>> # Use with chat
>>> from aix.chat import chat
>>> model = models['gpt-4o-mini']
>>> chat("Hello", model=model.id)
'Hello! How can I help you?'
```


# _autosummary/aix.prompts.html.md

# aix.prompts

Prompt-based function creation for AIX.

Transform text prompts into callable Python functions with automatic parameter extraction.

This module provides the core functionality for creating reusable AI-powered functions
from natural language prompts. It supports both text generation and structured output.

### Examples

Create a simple text function:

```pycon
>>> from aix.prompts import prompt_func
>>> translate = prompt_func("Translate to French: {text}")
>>> translate(text="Hello world")
'Bonjour le monde'
```

Create a function with structured output:

```pycon
>>> extract_person = prompt_func(
...     "Extract person information from: {text}",
...     output_schema={"name": str, "age": int}
... )
>>> extract_person(text="Alice is 30 years old")
{'name': 'Alice', 'age': 30}
```

Multiple parameters:

```pycon
>>> compare = prompt_func(
...     "Compare {item1} and {item2} in terms of {aspect}"
... )
>>> compare(item1="Python", item2="JavaScript", aspect="performance")
'Python generally has better...'
```

### Functions

| [`constrained_answer`](_autosummary/aix.prompts.html.md#aix.prompts.constrained_answer)(prompt, valid_answers, \*)   | Get an answer from the LLM constrained to a set of valid answers or types.   |
|--------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| [`prompt_func`](_autosummary/aix.prompts.html.md#aix.prompts.prompt_func)(template, \*[, output_schema, ...]) | Create a callable function from a prompt template.                           |
| [`prompt_to_json`](_autosummary/aix.prompts.html.md#aix.prompts.prompt_to_json)(template, schema, \*\*kwargs)    | Create a function that returns structured JSON output.                       |
| [`prompt_to_text`](_autosummary/aix.prompts.html.md#aix.prompts.prompt_to_text)(template, \*\*kwargs)            | Create a function that returns text output.                                  |

### Classes

| [`CommonFuncs`](_autosummary/aix.prompts.html.md#aix.prompts.CommonFuncs)([model])   | Collection of commonly used prompt functions.   |
|-------------------------------------------------------------------------|-------------------------------------------------|
| [`PromptFuncs`](_autosummary/aix.prompts.html.md#aix.prompts.PromptFuncs)([model])   | Collection of prompt-based functions.           |

### Exceptions

| [`ConstraintViolation`](_autosummary/aix.prompts.html.md#aix.prompts.ConstraintViolation)(message, \*[, answer, ...])   | Raised when an LLM answer does not satisfy the requested constraint.   |
|----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------|

### *class* aix.prompts.CommonFuncs(model=None)

Bases: [`PromptFuncs`](_autosummary/aix.prompts.html.md#aix.prompts.PromptFuncs)

Collection of commonly used prompt functions.

### Examples

```pycon
>>> from aix.prompts import common_funcs
>>> common_funcs.summarize(text="Long article...")
'Summary...'
>>> common_funcs.extract_keywords(text="Article about AI")
['AI', 'artificial', 'intelligence']
```

### *exception* aix.prompts.ConstraintViolation(message, , answer=None, valid_answers=None)

Bases: [`ValueError`](https://docs.python.org/3/builtins/exceptions.html#ValueError)

Raised when an LLM answer does not satisfy the requested constraint.

A subclass of `ValueError` so that callers who already guard
[`constrained_answer()`](_autosummary/aix.prompts.html.md#aix.prompts.constrained_answer) with `except ValueError` keep working.

#### answer

The offending value, as it came back from the model.

#### valid_answers

The constraint the value failed, verbatim as passed in.

### Examples

```pycon
>>> violation = ConstraintViolation("nope", answer="nope", valid_answers=["a"])
>>> violation.answer, violation.valid_answers
('nope', ['a'])
>>> isinstance(violation, ValueError)
True
```

### *class* aix.prompts.PromptFuncs(model=None, \*\*default_kwargs)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Collection of prompt-based functions.

Provides a namespace for organizing related prompt functions with
attribute-based access.

### Examples

```pycon
>>> funcs = PromptFuncs()
>>> funcs.add('summarize', "Summarize: {text}")
>>> funcs.add('translate', "Translate {text} to {language}")
>>> funcs.summarize(text="Long article...")
'Summary...'
>>> funcs.translate(text="Hello", language="Spanish")
'Hola'
```

#### add(name, template, , output_schema=None, \*\*kwargs)

Add a function to the collection.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Function name (will be accessible as attribute)
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **output_schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Optional schema for structured output
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`None`](https://docs.python.org/3/builtins/constants.html#None)

#### keys()

Get all function names.

### aix.prompts.constrained_answer(prompt, valid_answers, , model=None, temperature=None, enhance_prompt=False, n=1, on_violation='raise', max_retries=0)

Get an answer from the LLM constrained to a set of valid answers or types.

Uses JSON mode to ensure the LLM returns a valid response based on constraints.
More flexible than the oa version - works with any model that supports JSON mode
via LiteLLM.

This can be seen as a facade for some common structured output use cases, as well
as a convenient tool to do response statistics and validation (via n>1).

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The question or prompt to ask the LLM
  * **valid_answers** (`Union`[[`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)], [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`int`](https://docs.python.org/3/builtins/functions.html#int)], [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`float`](https://docs.python.org/3/builtins/functions.html#float)], [`type`](https://docs.python.org/3/builtins/functions.html#type), [`tuple`](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[`float`](https://docs.python.org/3/builtins/functions.html#float), [`float`](https://docs.python.org/3/builtins/functions.html#float)]]) – 

    Can be:
    - list[str]: List of valid string options
    - list[int]: List of valid integer options
    - list[float]: List of valid float options
    - bool: Constrains answer to True or False
    - int: Any integer
    - float: Any number
    - tuple[float, float]: Numerical range (min, max) inclusive
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The model to use for the LLM (default: uses DFLT_CHAT_MODEL)
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Temperature for sampling (default: None, uses model’s default).
    Higher values (e.g., 1.0) give more random/varied results.
    Lower values (e.g., 0.0) give more deterministic results.
  * **enhance_prompt** ([`bool`](https://docs.python.org/3/builtins/functions.html#bool)) – If True, adds explicit instructions to the prompt about
    JSON formatting and constraints. If False (default), relies on
    response_format alone. Default is False to match oa behavior.
  * **n** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Number of times to call the LLM (default: 1)
  * **on_violation** ([`Literal`](https://docs.python.org/3/library/typing.html#typing.Literal)[`'raise'`, `'return'`]) – What to do when the model’s answer does not satisfy
    `valid_answers`. `'raise'` (default) raises `ConstraintViolation`.
    `'return'` returns the model’s value unchecked – the behaviour of
    this function before enforcement existed, kept as an escape hatch.
  * **max_retries** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – How many times to re-ask the model after a violation
    before giving up (default: 0, i.e. ask exactly once). Ignored when
    `on_violation='return'`, which never detects a violation.
* **Returns:**
  One of the valid answers, respecting the type constraint.
  If n > 1, returns a list of answers.
* **Raises:**
  * [**ConstraintViolation**](_autosummary/aix.prompts.html.md#aix.prompts.ConstraintViolation) – If the answer is not a member of an options list,
        falls outside a `(min, max)` range, or cannot be converted to the
        declared type – unless `on_violation='return'`.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If the response is not JSON, or has no “answer” field.

### Examples

```pycon
>>> # String options
>>> answer = constrained_answer(
...     "Is Python compiled or interpreted?",
...     ["compiled", "interpreted", "both"]
... )
>>> answer in ["compiled", "interpreted", "both"]
True
```

```pycon
>>> # Boolean
>>> answer = constrained_answer(
...     "Is Python dynamically typed?",
...     bool
... )
>>> isinstance(answer, bool)
True
```

```pycon
>>> # Integer options
>>> answer = constrained_answer(
...     "How many wheels does a car have?",
...     [2, 3, 4, 6, 8]
... )
>>> answer in [2, 3, 4, 6, 8]
True
```

```pycon
>>> # Numerical range
>>> answer = constrained_answer(
...     "What is a reasonable hourly rate for a senior Python developer? (USD)",
...     (50.0, 300.0)
... )
>>> 50.0 <= answer <= 300.0
True
```

```pycon
>>> # Multiple samples for statistics
>>> answers = constrained_answer(
...     "Which is better: cats or dogs?",
...     ["cats", "dogs"],
...     n=10
... )
>>> len(answers)
10
```

```pycon
>>> # Tolerate an off-constraint answer instead of raising
>>> answer = constrained_answer(
...     "Is Python compiled or interpreted?",
...     ["compiled", "interpreted"],
...     on_violation="return",
... )
```

### aix.prompts.prompt_func(template, , output_schema=None, egress=None, model=None, temperature=None, name=None, \*\*chat_kwargs)

Create a callable function from a prompt template.

This is the main function for creating prompt-based functions. It automatically
detects parameters from the template and creates a function with those parameters.

Without output_schema: Returns text
With output_schema: Returns structured data (dict, list, etc.)
With egress: Returns whatever the egress post-processor returns.

Templates use the default-aware `{name:default}` dialect (matching
`oa.prompt_function`): `{name}` is a required parameter, `{name:default}`
supplies a default value (the text after the colon), and braces inside
`` fenced `` regions are left literal. Plain `{name}`-only templates behave
exactly as before.

```pycon
>>> greet = prompt_func("Greet {name} in {language:English}")
>>> greet.param_names
['name', 'language']
```

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template with {var} placeholders for parameters
  * **output_schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Optional schema for structured output. Can be:
    - Dict mapping field names to types: {“name”: str, “age”: int}
    - A single type for simple outputs: str, int, list, etc.
    - None for plain text output (default)
  * **egress** ([`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)[[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)], [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – Optional post-processor `(result) -> Any` applied to the output
    before returning — on both the text and structured paths. Lets a caller
    keep “prompt → typed Python value” inside the facade (e.g. parse the
    LLM text into a list of lines/ids) instead of wrapping the returned
    function. `None` (default) returns the raw result unchanged.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Model to use for this function
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Temperature for generation
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional `__name__` for the generated function (for tracing /
    identity). Defaults to `"prompt_based_function"`.
  * **\*\*chat_kwargs** – Additional parameters passed to chat()
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Callable function with parameters derived from template

### Examples

```pycon
>>> # Simple text generation
>>> summarize = prompt_func("Summarize this text: {text}")
>>> summarize(text="Long article...")
'Brief summary...'
```

```pycon
>>> # Structured output
>>> extract = prompt_func(
...     "Extract contact info from: {text}",
...     output_schema={"name": str, "email": str, "phone": str}
... )
>>> result = extract(text="Contact John at john@example.com, 555-1234")
>>> result['name']
'John'
```

```pycon
>>> # Multiple parameters
>>> compare = prompt_func(
...     "Compare {item1} and {item2} in terms of {aspect}. "
...     "Keep it under {word_limit} words."
... )
>>> compare(
...     item1="Python",
...     item2="Java",
...     aspect="learning curve",
...     word_limit=50
... )
'Python has a gentler learning curve...'
```

```pycon
>>> # With specific model
>>> creative_writer = prompt_func(
...     "Write a creative story about {topic}",
...     model="gpt-4o",
...     temperature=1.5
... )
>>> creative_writer(topic="a time-traveling cat")
'Once upon a time, there was a cat named Whiskers...'
```

### aix.prompts.prompt_to_json(template, schema, \*\*kwargs)

Create a function that returns structured JSON output.

This is an explicit alias for prompt_func with output_schema.

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **schema** (`Union`[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict), [`type`](https://docs.python.org/3/builtins/functions.html#type)]) – Output schema
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Function that returns structured data

### Examples

```pycon
>>> extract = prompt_to_json(
...     "Extract name and age from: {text}",
...     schema={"name": str, "age": int}
... )
>>> result = extract(text="Alice is 30")
>>> isinstance(result, dict)
True
```

### aix.prompts.prompt_to_text(template, \*\*kwargs)

Create a function that returns text output.

This is an explicit alias for prompt_func without output_schema.

* **Parameters:**
  * **template** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Prompt template
  * **\*\*kwargs** – Additional parameters for prompt_func
* **Return type:**
  [`Callable`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Callable)
* **Returns:**
  Function that returns text

### Examples

```pycon
>>> summarize = prompt_to_text("Summarize: {text}")
>>> result = summarize(text="Long text...")
>>> isinstance(result, str)
True
```


# _autosummary/aix.stores.html.md

# aix.stores

Storage layers for AIX.

### Functions

| [`add_extension_based_decoder`](_autosummary/aix.stores.html.md#aix.stores.add_extension_based_decoder)(ext, decoder)   | Register a decoder function for a given file extension.                                  |
|----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------|
| [`extension_based_decode_to_text`](_autosummary/aix.stores.html.md#aix.stores.extension_based_decode_to_text)(k, v)        | Decode the given bytes `v` to a string based on the file extension extracted from `key`. |
| `get_extension`(string)                                                                      |                                                                                          |

### aix.stores.add_extension_based_decoder(ext, decoder)

Register a decoder function for a given file extension.

* **Parameters:**
  * **ext** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str)) – The file extension (without the leading dot), e.g., “pdf”.
  * **decoder** (*Callable* *[* *[*[*bytes*](https://docs.python.org/3/builtins/stdtypes.html#bytes) *]* *,* [*str*](https://docs.python.org/3/builtins/stdtypes.html#str) *]*) – A function that takes bytes and returns a decoded string.

### aix.stores.extension_based_decode_to_text(k, v)

Decode the given bytes `v` to a string based on the file extension extracted from `key`.

If a decoder is registered for the extension, it is used.
Otherwise, the bytes are decoded using v.decode(‘utf-8’).

* **Parameters:**
  * **key** ([*str*](https://docs.python.org/3/builtins/stdtypes.html#str)) – The key (typically a filename) from which to extract the extension.
  * **v** ([*bytes*](https://docs.python.org/3/builtins/stdtypes.html#bytes)) – The value to decode.
* **Returns:**
  The decoded text.
* **Return type:**
  [*str*](https://docs.python.org/3/builtins/stdtypes.html#str)


# _autosummary/aix.util.html.md

# aix.util

Utils for AIX.


# _autosummary/aix.video.html.md

# aix.video

Video generation interface for AIX.

Generate videos from text descriptions or images.

#### NOTE
Video generation support varies by provider and may require additional
API keys and configuration. This module provides a unified interface but
implementation depends on available providers.

### Examples

Text to video:

```pycon
>>> from aix.video import generate_video
>>> video = generate_video(
...     "A cat walking through a garden",
...     duration=5
... )
>>> video.save("cat_video.mp4")
```

Image to video:

```pycon
>>> video = animate_image(
...     "static_image.jpg",
...     prompt="Make the clouds move gently"
... )
```

### Functions

| [`animate_image`](_autosummary/aix.video.html.md#aix.video.animate_image)(image_path[, prompt, model, ...])    | Animate a static image into a video.                        |
|-----------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
| [`estimate_cost`](_autosummary/aix.video.html.md#aix.video.estimate_cost)(duration[, resolution, provider])    | Estimate the cost of video generation.                      |
| [`extend_video`](_autosummary/aix.video.html.md#aix.video.extend_video)(video_path[, prompt, ...])            | Extend an existing video with additional generated content. |
| [`generate_video`](_autosummary/aix.video.html.md#aix.video.generate_video)(prompt, \*[, model, duration, ...]) | Generate a video from a text prompt.                        |
| [`generate_video_pika`](_autosummary/aix.video.html.md#aix.video.generate_video_pika)(prompt, \*[, duration])        | Generate video using Pika Labs.                             |
| [`generate_video_runway`](_autosummary/aix.video.html.md#aix.video.generate_video_runway)(prompt, \*[, duration])      | Generate video using Runway ML.                             |
| [`generate_video_stable_diffusion`](_autosummary/aix.video.html.md#aix.video.generate_video_stable_diffusion)(prompt, \*[, ...]) | Generate video using Stable Diffusion Video.                |
| [`get_available_providers`](_autosummary/aix.video.html.md#aix.video.get_available_providers)()                          | Get list of available video generation providers.           |
| [`interpolate_frames`](_autosummary/aix.video.html.md#aix.video.interpolate_frames)(video_path, \*[, ...])          | Interpolate frames to create smoother video.                |

### Classes

| [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)([url, data, model, prompt, ...])   | Wrapper for generated videos.   |
|----------------------------------------------------------------------------------------------------|---------------------------------|

### *class* aix.video.GeneratedVideo(url=None, data=None, model=None, prompt=None, duration=None, resolution=None, status='completed', task_id=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Wrapper for generated videos.

Provides convenient access to video data and metadata.

### Examples

```pycon
>>> video = GeneratedVideo(url="https://...")
>>> video.save("output.mp4")
>>> print(video.duration)
5.0
```

#### as_bytes()

Get video as bytes.

* **Return type:**
  [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes)
* **Returns:**
  Video data as bytes

#### save(path)

Save video to file.

* **Parameters:**
  **path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Output file path

### Examples

```pycon
>>> video.save("output.mp4")
```

#### wait_until_complete(max_wait=300, poll_interval=5)

Wait for video generation to complete (for async operations).

* **Parameters:**
  * **max_wait** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Maximum time to wait in seconds
  * **poll_interval** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Time between status checks in seconds
* **Raises:**
  * [**TimeoutError**](https://docs.python.org/3/builtins/exceptions.html#TimeoutError) – If generation doesn’t complete within max_wait
  * [**RuntimeError**](https://docs.python.org/3/builtins/exceptions.html#RuntimeError) – If generation fails

### aix.video.animate_image(image_path, prompt=None, , model=None, duration=3.0, motion_strength=0.5, \*\*kwargs)

Animate a static image into a video.

* **Parameters:**
  * **image_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source image
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text prompt to guide the animation
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model to use
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Animation duration in seconds
  * **motion_strength** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Strength of motion (0.0 to 1.0)
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object

### Examples

```pycon
>>> from aix.video import animate_image
>>> video = animate_image(
...     "landscape.jpg",
...     prompt="Gentle camera pan across the scene",
...     duration=4
... )
>>> video.save("animated_landscape.mp4")
```

### aix.video.estimate_cost(duration, resolution='1280x720', provider=None)

Estimate the cost of video generation.

* **Parameters:**
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration in seconds
  * **resolution** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video resolution
  * **provider** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Provider name (or None for all)
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Dict with cost estimates

### Examples

```pycon
>>> from aix.video import estimate_cost
>>> cost = estimate_cost(duration=5, resolution="1920x1080")
>>> print(cost)
{'runway': 0.05, 'pika': 0.03}
```

### aix.video.extend_video(video_path, prompt=None, , extend_duration=2.0, model=None, \*\*kwargs)

Extend an existing video with additional generated content.

* **Parameters:**
  * **video_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source video
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Optional text prompt to guide the extension
  * **extend_duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – How many seconds to add
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object with extended content

### Examples

```pycon
>>> from aix.video import extend_video
>>> extended = extend_video(
...     "original.mp4",
...     prompt="Continue the same scene",
...     extend_duration=3
... )
```

### aix.video.generate_video(prompt, , model=None, duration=5.0, resolution='1280x720', fps=24, aspect_ratio=None, style=None, seed=None, api_key=None, \*\*kwargs)

Generate a video from a text prompt.

#### NOTE
This is a high-level interface. Actual implementation depends on
available video generation providers (Runway, Pika, etc.) and may require
provider-specific API keys.

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description of the video to generate
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video generation model to use
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration in seconds (typically 2-10 seconds)
  * **resolution** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video resolution (‘1280x720’, ‘1920x1080’, etc.)
  * **fps** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Frames per second
  * **aspect_ratio** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Aspect ratio (‘16:9’, ‘9:16’, ‘1:1’, etc.)
  * **style** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Video style hint (provider-specific)
  * **seed** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Random seed for reproducibility
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Explicit API key for the video provider. If None, resolved from
    the environment / .env / AIX config store (see aix.credentials).
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object
* **Raises:**
  * [**NotImplementedError**](https://docs.python.org/3/builtins/exceptions.html#NotImplementedError) – If no video provider is configured
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If required provider SDK is not installed

### Examples

```pycon
>>> from aix.video import generate_video
>>> video = generate_video(
...     "A serene ocean sunset with gentle waves",
...     duration=5,
...     resolution="1920x1080"
... )
>>> video.save("sunset.mp4")
```

```pycon
>>> # Specific style
>>> video = generate_video(
...     "A futuristic city",
...     style="cyberpunk",
...     duration=4
... )
```

### aix.video.generate_video_pika(prompt, , duration=3.0, \*\*kwargs)

Generate video using Pika Labs.

Requires: PIKA_API_KEY environment variable

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration
  * **\*\*kwargs** – Pika-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object

### aix.video.generate_video_runway(prompt, , duration=5.0, \*\*kwargs)

Generate video using Runway ML.

Requires: RUNWAY_API_KEY environment variable

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration
  * **\*\*kwargs** – Runway-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object

### aix.video.generate_video_stable_diffusion(prompt, , duration=2.0, \*\*kwargs)

Generate video using Stable Diffusion Video.

Requires: Stable Diffusion Video model setup

* **Parameters:**
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Text description
  * **duration** ([`float`](https://docs.python.org/3/builtins/functions.html#float)) – Video duration
  * **\*\*kwargs** – SD-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo object

### aix.video.get_available_providers()

Get list of available video generation providers.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  List of provider names that are configured

### Examples

```pycon
>>> from aix.video import get_available_providers
>>> providers = get_available_providers()
>>> print(providers)
['runway', 'pika']
```

### aix.video.interpolate_frames(video_path, , target_fps=60, model=None, \*\*kwargs)

Interpolate frames to create smoother video.

* **Parameters:**
  * **video_path** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]) – Path to the source video
  * **target_fps** ([`int`](https://docs.python.org/3/builtins/functions.html#int)) – Target frames per second
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Frame interpolation model
  * **\*\*kwargs** – Additional provider-specific parameters
* **Return type:**
  [`GeneratedVideo`](_autosummary/aix.video.html.md#aix.video.GeneratedVideo)
* **Returns:**
  GeneratedVideo with interpolated frames

### Examples

```pycon
>>> from aix.video import interpolate_frames
>>> smooth_video = interpolate_frames(
...     "choppy.mp4",
...     target_fps=60
... )
```


# _autosummary/aix.vision.html.md

# aix.vision

Image-to-text (vision) interface for AIX.

The cross-modal counterpart to [`aix.image`](_autosummary/aix.image.html.md#module-aix.image) (which is text→image): given an
image, produce text — a caption, an answer to a question about it, or a
structured judgement. Like the rest of AIX it is a thin, provider-neutral facade
over LiteLLM’s multimodal `completion` (the same backend `chat` uses), so the
same call routes to any vision-capable provider (OpenAI, Anthropic, Gemini,
OpenRouter, …) by model id alone.

[`describe_image()`](_autosummary/aix.vision.html.md#aix.vision.describe_image) is the primitive: image (URL / local path / bytes / PIL
image / `data:` URI) + a prompt → text. [`to_image_content()`](_autosummary/aix.vision.html.md#aix.vision.to_image_content) exposes the
multimodal content block builder so callers can assemble richer messages (e.g.
multiple images in one turn) and pass them straight to [`aix.chat()`](_autosummary/aix.html.md#aix.chat).

### Examples

Caption an image (any vision-capable model):

```pycon
>>> from aix.vision import describe_image
>>> describe_image("https://example.com/cat.jpg")
'A grey tabby cat sitting on a windowsill in afternoon light.'
```

Ask a specific question:

```pycon
>>> describe_image("photo.png", prompt="What colour is the car?")
'The car is red.'
```

Build a multi-image message yourself and hand it to `chat`:

```pycon
>>> from aix import chat
>>> from aix.vision import to_image_content
>>> msg = [{"role": "user", "content": [
...     {"type": "text", "text": "Which is brighter?"},
...     to_image_content("a.jpg"), to_image_content("b.jpg"),
... ]}]
>>> chat(msg, model="gpt-4o")
'The second image is brighter.'
```

[`compare_images()`](_autosummary/aix.vision.html.md#aix.vision.compare_images) builds on these primitives: it puts a *candidate* image
beside one or more *reference* images and asks a vision model, via a structured
JSON path, for an explainable per-aspect likeness verdict — the “explain the
drift” half of a reference supervisor (face / costume / setting / lighting /
props matched?). The numeric identity-cosine gate lives elsewhere (lookbook);
this layer is the explainable checklist on top of it.

```pycon
>>> from aix.vision import compare_images
>>> verdict = compare_images("gen.png", "locked_ref.png")
>>> verdict.match, verdict["identity"].match
(True, True)
```

### Module Attributes

| [`DFLT_VISION_MODEL`](_autosummary/aix.vision.html.md#aix.vision.DFLT_VISION_MODEL)   | Shipped-default vision model, kept for reference.                                                                    |
|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| [`DFLT_VISION_PROMPT`](_autosummary/aix.vision.html.md#aix.vision.DFLT_VISION_PROMPT)  | Default instruction when the caller doesn't supply one.                                                              |
| [`DFLT_COMPARE_RUBRIC`](_autosummary/aix.vision.html.md#aix.vision.DFLT_COMPARE_RUBRIC) | Default rubric for [`compare_images()`](_autosummary/aix.vision.html.md#aix.vision.compare_images) — a generic likeness checklist. |
| [`DFLT_FILM_RUBRIC`](_autosummary/aix.vision.html.md#aix.vision.DFLT_FILM_RUBRIC)    | the locked face, the architecture/set, the lighting, and the props.                                                  |

### Functions

| [`describe_image`](_autosummary/aix.vision.html.md#aix.vision.describe_image)(image, \*[, prompt, model, ...])   | Describe (or answer a question about) `image` and return the text.   |
|----------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|
| [`to_image_content`](_autosummary/aix.vision.html.md#aix.vision.to_image_content)(image, \*[, detail])             | Build a multimodal `image_url` content block for `image`.            |
| [`compare_images`](_autosummary/aix.vision.html.md#aix.vision.compare_images)(candidate, reference, \*[, ...])   | Compare a `candidate` image to `reference` image(s) on a rubric.     |

### Classes

| [`RubricVerdict`](_autosummary/aix.vision.html.md#aix.vision.RubricVerdict)(aspect, match, confidence[, note])   | A vision model's verdict on a single rubric aspect.               |
|-----------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|
| [`ImageComparison`](_autosummary/aix.vision.html.md#aix.vision.ImageComparison)(match, confidence, explanation)    | Structured result of comparing a candidate image to reference(s). |

### aix.vision.DFLT_COMPARE_RUBRIC *= ('identity', 'costume', 'setting', 'lighting', 'props')*

Default rubric for [`compare_images()`](_autosummary/aix.vision.html.md#aix.vision.compare_images) — a generic likeness checklist.
Each entry is one aspect the vision model judges independently.

### aix.vision.DFLT_FILM_RUBRIC *= ('face_identity', 'costume', 'setting_architecture', 'lighting', 'props', 'skin_realism')*

the
locked face, the architecture/set, the lighting, and the props. Pass it as
`rubric=` when comparing a generated frame against a locked reference.

* **Type:**
  Filmmaking-oriented rubric (Noel’s reference-supervisor checklist)

### aix.vision.DFLT_VISION_MODEL *= 'gpt-4o-mini'*

Shipped-default vision model, kept for reference. The *active* default is
resolved from `aix.config` at call time (see [`aix.config.VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)).

### aix.vision.DFLT_VISION_PROMPT *= 'Describe this image in detail.'*

Default instruction when the caller doesn’t supply one.

### *class* aix.vision.ImageComparison(match, confidence, explanation, aspects=<factory>, model=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Structured result of comparing a candidate image to reference(s).

Behaves like an ordered, read-only mapping of `aspect -> RubricVerdict`
(`comparison["identity"]`, `in`, iteration, `len`) so per-aspect
lookups read naturally, while also carrying the overall verdict.

#### match

Overall pass/fail across the whole rubric.

#### confidence

Overall confidence in `[0.0, 1.0]`.

#### explanation

A short overall summary of the comparison.

#### aspects

The per-aspect verdicts, one [`RubricVerdict`](_autosummary/aix.vision.html.md#aix.vision.RubricVerdict) per
rubric item, in rubric order.

#### model

The vision model id that produced the verdict.

#### get(aspect, default=None)

Return the verdict for `aspect`, or `default` if absent.

* **Return type:**
  [`RubricVerdict`](_autosummary/aix.vision.html.md#aix.vision.RubricVerdict) | [`None`](https://docs.python.org/3/builtins/constants.html#None)

### *class* aix.vision.RubricVerdict(aspect, match, confidence, note='')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

A vision model’s verdict on a single rubric aspect.

#### aspect

The rubric item this verdict is about (e.g. `"identity"`).

#### match

Whether the candidate matches the reference for this aspect.

#### confidence

The model’s self-reported confidence in `[0.0, 1.0]`.

#### note

A short free-text explanation of the verdict.

### aix.vision.compare_images(candidate, reference, , rubric=('identity', 'costume', 'setting', 'lighting', 'props'), model=None, api_key=None, max_tokens=None, temperature=0.0, detail=None, instruction='You are a strict visual continuity supervisor. The FIRST image is the CANDIDATE; the remaining image(s) are the locked REFERENCE the candidate must match. Judge each rubric aspect INDEPENDENTLY (do not let one aspect color another). For each aspect decide whether the candidate matches the reference, give a confidence in [0.0, 1.0], and a short note explaining what matches or drifts. Then give an overall match (true only if every important aspect matches), an overall confidence, and a one-sentence explanation.', \*\*kwargs)

Compare a `candidate` image to `reference` image(s) on a rubric.

The explainable half of a reference supervisor: a vision model returns a
per-aspect pass/fail checklist (does the face match? the costume? the set?
the lighting? the props?) plus an overall verdict — the explainable layer
over a cheap numeric identity-cosine gate (which lives elsewhere, e.g.
lookbook). Built on [`to_image_content()`](_autosummary/aix.vision.html.md#aix.vision.to_image_content) (multi-image content block)
and the same multimodal `completion` path as [`describe_image()`](_autosummary/aix.vision.html.md#aix.vision.describe_image),
asked via a JSON contract for a structured answer.

The comparison is *pointwise* (each aspect judged on its own), not a ranked
pairwise comparison, to avoid position bias.

* **Parameters:**
  * **candidate** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – The image under review (URL / path / bytes / PIL image /
    `data:` URI — anything [`to_image_content()`](_autosummary/aix.vision.html.md#aix.vision.to_image_content) accepts).
  * **reference** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any), [`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]]) – The locked reference — a single image *or* a sequence of
    images (a locked set) in the same flexible formats. An empty
    sequence is an error.
  * **rubric** ([`Sequence`](https://docs.python.org/3/library/typing.html#typing.Sequence)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – The aspects to evaluate, one verdict per item. Defaults to
    [`DFLT_COMPARE_RUBRIC`](_autosummary/aix.vision.html.md#aix.vision.DFLT_COMPARE_RUBRIC); pass [`DFLT_FILM_RUBRIC`](_autosummary/aix.vision.html.md#aix.vision.DFLT_FILM_RUBRIC) (or any
    custom sequence) to override — e.g. `("face", "architecture",
    "props", "lighting")`. Must be non-empty.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Vision-capable model id or alias. `None` → the configured
    default ([`aix.config.VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)).
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Explicit API key; `None` resolves it for the model’s
    provider from the environment / `.env` / config store.
  * **max_tokens** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Cap on generated tokens (`None` → provider default).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Sampling temperature (default `0.0` for a stable,
    reproducible verdict; `None` → provider default).
  * **detail** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Image detail hint (`"low"` | `"high"` | `"auto"`),
    applied to every image block.
  * **instruction** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The system-style framing prepended to the rubric. Has a
    sensible default; override to retune the supervisor’s strictness.
  * **\*\*kwargs** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Extra provider-specific params forwarded to LiteLLM.
* **Return type:**
  [`ImageComparison`](_autosummary/aix.vision.html.md#aix.vision.ImageComparison)
* **Returns:**
  An [`ImageComparison`](_autosummary/aix.vision.html.md#aix.vision.ImageComparison) — overall `match` / `confidence` /
  `explanation` plus an ordered, mapping-like collection of
  [`RubricVerdict`](_autosummary/aix.vision.html.md#aix.vision.RubricVerdict) (one per rubric aspect, keyed by aspect).
* **Raises:**
  * [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed.
  * [**ValueError**](https://docs.python.org/3/builtins/exceptions.html#ValueError) – If `rubric` is empty or `reference` is an empty
        sequence, or if the model’s reply can’t be parsed as the expected
        JSON verdict.

### Examples

Default rubric, single reference:

```pycon
>>> compare_images("gen.png", "ref.png")
ImageComparison(match=True, confidence=0.9, ...)
```

Filmmaking rubric, a locked reference *set*:

```pycon
>>> from aix.vision import DFLT_FILM_RUBRIC
>>> compare_images(
...     candidate="frame_042.png",
...     reference=["ref_front.png", "ref_side.png"],
...     rubric=DFLT_FILM_RUBRIC,
... )["face_identity"].match
True
```

### aix.vision.describe_image(image, , prompt='Describe this image in detail.', model=None, api_key=None, max_tokens=None, temperature=None, detail=None, \*\*kwargs)

Describe (or answer a question about) `image` and return the text.

The image→text primitive. `image` accepts a URL, a local path, raw bytes,
a PIL image, or a `data:` URI (see [`to_image_content()`](_autosummary/aix.vision.html.md#aix.vision.to_image_content)). `prompt` is
the instruction (default: a generic “describe this image”); pass a question
for VQA or a rubric for a judgement. Everything past `image` is keyword.

* **Parameters:**
  * **image** (`Union`[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str), [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path), [`bytes`](https://docs.python.org/3/builtins/stdtypes.html#bytes), [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)]) – The image (URL / path / bytes / PIL image / `data:` URI).
  * **prompt** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – The text instruction accompanying the image.
  * **model** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Vision-capable model id (e.g. `gpt-4o`, `claude-sonnet-4-6`,
    `gemini/gemini-1.5-pro`) or an alias. `None` → the configured
    default ([`aix.config.VisionConfig`](_autosummary/aix.config.html.md#aix.config.VisionConfig)).
  * **api_key** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Explicit API key; `None` resolves it from the environment /
    `.env` / config store for the model’s provider.
  * **max_tokens** ([`int`](https://docs.python.org/3/builtins/functions.html#int) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Cap on generated tokens (`None` → provider default).
  * **temperature** ([`float`](https://docs.python.org/3/builtins/functions.html#float) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Sampling temperature (`None` → provider default).
  * **detail** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str) | [`None`](https://docs.python.org/3/builtins/constants.html#None)) – Image detail hint (`"low"` | `"high"` | `"auto"`).
  * **\*\*kwargs** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Extra provider-specific params forwarded to LiteLLM.
* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)
* **Returns:**
  The model’s text response.
* **Raises:**
  [**ImportError**](https://docs.python.org/3/builtins/exceptions.html#ImportError) – If LiteLLM is not installed.

```pycon
>>> describe_image("cat.jpg", prompt="Caption it.")
'A cat on a sofa.'
```

### aix.vision.to_image_content(image, , detail=None)

Build a multimodal `image_url` content block for `image`.

`image` may be:

- an `http(s)://` URL or a `data:` URI — passed through verbatim;
- a local file path (`str` or [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) — read and inlined
  as a base64 `data:` URI with a guessed MIME type;
- raw `bytes` — base64-inlined (MIME sniffed from magic bytes, else JPEG);
- a PIL `Image` — encoded to PNG and inlined.

`detail` (`"low"` | `"high"` | `"auto"`) is forwarded when set; the
block is the OpenAI/LiteLLM multimodal shape understood across providers.

```pycon
>>> to_image_content("https://x/y.jpg")
{'type': 'image_url', 'image_url': {'url': 'https://x/y.jpg'}}
>>> to_image_content("data:image/png;base64,AAAA")["image_url"]["url"][:10]
'data:image'
```

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# about-this-build.html.md

<!-- generated by epythet -->

# About this build

This documentation was built on **2026-09-22 15:02 UTC** from commit <a href="https://github.com/thorwhalen/aix/commit/3840e312c0e554616d473678a2ed8ac7b03e96fc"><code>3840e31</code></a> on branch <code>master</code>, for **aix 0.0.42** (from <code>pyproject.toml</code>).

#### WARNING
The documentation and the package may be misaligned:

- The documented version (0.0.42) is behind the latest release on PyPI (0.0.43): `pip install aix` gives newer code than these docs describe.

## Source

|                     |                                                                                                                                                       |
|---------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| Commit              | <a href="https://github.com/thorwhalen/aix/commit/3840e312c0e554616d473678a2ed8ac7b03e96fc"><code>3840e312c0e554616d473678a2ed8ac7b03e96fc</code></a> |
| Branch              | <code>master</code>                                                                                                                                   |
| Tags at this commit | none                                                                                                                                                  |
| Working tree        | clean                                                                                                                                                 |
| Remote              | <code>https://github.com/thorwhalen/aix</code>                                                                                                        |

## Continuous integration

|              |                                                                                            |
|--------------|--------------------------------------------------------------------------------------------|
| Repository   | <code>thorwhalen/aix</code>                                                                |
| Run          | <a href="https://github.com/thorwhalen/aix/actions/runs/35744280418">35744280418</a>       |
| Ref          | <code>refs/heads/master</code>                                                             |
| Event commit | <code>3840e312c0e554616d473678a2ed8ac7b03e96fc</code> (in the history of the built commit) |

## Tools

|          |         |
|----------|---------|
| epythet  | 0.2.12  |
| Sphinx   | 9.1.0   |
| docutils | 0.22.4  |
| Python   | 3.12.14 |

## Configuration as resolved

|               |                                                                  |
|---------------|------------------------------------------------------------------|
| theme         | <code>auto</code> (Sphinx theme <code>furo</code>)               |
| accent        | <code>#2b559f</code>                                             |
| api_generator | <code>autosummary</code>                                         |
| ignore        | <code>tests/</code>, <code>scrap/</code>, <code>examples/</code> |
| agent_outputs | <code>true</code>                                                |
| aggregates    | <code>md</code>                                                  |
| ai_artifacts  | <code>true</code>                                                |

## Package on PyPI

Latest release: <a href="https://pypi.org/project/aix/0.0.43/">0.0.43</a>, newer than the documented version (0.0.42).

## Reproduce

```bash
git clone https://github.com/thorwhalen/aix && cd aix
git checkout 3840e312c0e554616d473678a2ed8ac7b03e96fc
pip install "epythet==0.2.12"
epythet quickstart . --ignore tests/ scrap/ examples/
```

The same data, for machines: <a href="build_info.json"><code>build_info.json</code></a> (schema version 1).


# ai-agents.html.md

<!-- generated by epythet -->

# For AI agents

`aix` ships artifacts for coding agents alongside its code. This page lists
them, says where each lives in the repository, and points at the
machine-readable copies of this documentation.

## Instruction files

Files agents read before working in this repository.

- [`.claude/CLAUDE.md`](https://github.com/thorwhalen/aix/tree/HEAD/.claude/CLAUDE.md): read by Claude Code

## Machine-readable documentation

This site publishes the same documentation in forms that fit an agent’s context window:

- [`llms.txt`](https://thorwhalen.github.io/aix/llms.txt): an index of every page with a one-line description ([llms.txt](https://llmstxt.org) format)
- [`aix.md`](https://thorwhalen.github.io/aix/aix.md): the whole documentation as one Markdown file
- `<page>.html.md`: a rendered Markdown twin of every page, advertised from each page’s `<head>` with `<link rel="alternate" type="text/markdown">`
- [`objects.inv`](https://thorwhalen.github.io/aix/objects.inv): the Sphinx inventory: a symbol-to-URL index (`sphobjinv convert plain objects.inv -`)


# api.html.md

# API reference

| [`aix`](_autosummary/aix.html.md#module-aix)   | AIX: Artificial Intelligence eXtensions   |
|-------------------------------------------------------------------|-------------------------------------------|


