# How to Configure Multi-Provider AI with Esperanto in Open Notebook: Complete Guide to 18+ Providers

> Configure multi-provider AI with Esperanto in Open Notebook. Integrate 18+ AI services like OpenAI, Anthropic, and Google easily. This guide details setup via credentials or environment variables.

- Repository: [Luis Novo/open-notebook](https://github.com/lfnovo/open-notebook)
- Tags: how-to-guide
- Published: 2026-06-22

---

**Open Notebook abstracts AI providers through the Esperanto library, enabling configuration of 18+ providers including OpenAI, Anthropic, Google, and Ollama via stored Credential records or environment variables.**

The open-notebook repository by lfnovo provides a unified interface for multi-provider AI with Esperanto, supporting over 18 providers through a flexible credential management system. Whether you store API keys in the database or rely on environment variables, the architecture automatically resolves provider configurations at runtime using the Esperanto abstraction layer.

## Understanding the Credential Architecture

Open Notebook utilizes a dual-layer configuration system that prioritizes database-stored credentials while falling back to environment variables when needed.

### Database Credentials with `to_esperanto_config()`

Each AI provider configuration resides in a **Credential** record defined in [`open_notebook/domain/credential.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/domain/credential.py). The model's `to_esperanto_config()` method constructs a configuration dictionary that Esperanto's `AIFactory` consumes, overriding any environment variable defaults.

The Credential model stores fields such as `api_key`, `base_url`, `endpoint`, and provider-specific extras like `num_ctx` for Ollama. These values sync automatically into a flexible `config` bag through the `CONFIG_EXTRAS` mechanism, ensuring provider-specific parameters pass directly to the underlying LangChain implementations.

### Environment Variable Fallback via `PROVIDER_CONFIG`

When database credentials are absent, the **Key Provider** at [`open_notebook/ai/key_provider.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/key_provider.py) maps providers to standardized environment variable names using the `PROVIDER_CONFIG` dictionary. This map includes entries for 18+ providers such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GROQ_API_KEY`, and `OLLAMA_API_BASE`.

The system injects these values into `os.environ` at runtime, ensuring seamless integration with existing deployment patterns without requiring database modifications.

## Runtime Configuration with `provision_provider_keys()`

Before invoking models, Open Notebook provisions credentials using the `provision_provider_keys()` function to ensure all provider keys are available in the environment.

```python
from open_notebook.ai.key_provider import provision_provider_keys

# Load DB-stored keys for a single provider (or fall back to env vars)

await provision_provider_keys("openai")

```

Complex providers like Vertex, Azure, and OpenAI-compatible endpoints have dedicated helpers that also configure URLs, project IDs, and regional endpoints. This function is called automatically if no credential exists, guaranteeing the environment variable fallback is always in place.

## Model Resolution via `ModelManager`

The `ModelManager` class in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py) serves as the central hub for resolving and instantiating AI models across providers.

### The Complete Resolution Flow

When you request a model, `ModelManager.get_model()` executes the following steps:

1. Fetches the **Model** record from the database using the provided model ID
2. Resolves the linked **Credential** record (if any)
3. Builds the Esperanto configuration using `to_esperanto_config()`
4. Normalizes the provider name (converting `_` to `-`)
5. Calls the appropriate `AIFactory.create_*` method (e.g., `create_language`, `create_embedding`)
6. Returns a concrete LangChain model ready for invocation

If no credential exists for the model's provider, `provision_provider_keys()` is invoked automatically to populate environment variables before instantiation.

### Loading Specific Models

```python
from open_notebook.ai.models import model_manager

# Ensure any DB-stored keys for the provider are available

await provision_provider_keys("openai")  # Optional if credential exists

# Load a specific model (model_id stored in the DB)

language_model = await model_manager.get_model("mdl_12345")

# Invoke the model

response = await language_model.ainvoke({
    "messages": [{"role": "user", "content": "Hello"}]
})

```

### Using Default Model Configurations

A singleton `DefaultModels` record holds user-selected defaults for chat, embedding, and TTS models. The `ModelManager.get_defaults()` method queries these settings, which admins can configure through the **Settings → Models** UI or via [`api/routers/models.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/models.py).

```python
from open_notebook.ai.models import model_manager

defaults = await model_manager.get_defaults()
chat_model = await model_manager.get_model(defaults.default_chat_model)

print(await chat_model.ainvoke(
    "Explain quantum entanglement in plain English."
))

```

## Provider-Specific Configuration Examples

### Adding MiniMax as a New Provider

To add MiniMax or any supported provider:

1. Ensure the environment variable mapping exists in `PROVIDER_CONFIG` (already present for MiniMax)
2. Create a credential via the API:

```json
POST /api/credentials
{
  "name": "MiniMax Prod",
  "provider": "minimax",
  "modalities": ["language"],
  "api_key": "your-minimax-api-key"
}

```

3. Link a model to that credential or set it as the default. The system automatically detects `MINIMAX_API_KEY` from either the stored credential or environment variables when `model_manager.get_model()` is called.

### Customizing Ollama Context Windows

For self-hosted providers like Ollama, you can override specific parameters such as the context window size:

```python

# Credential with a custom context size (stored in num_ctx)

credential = await Credential.get("cred_ollama")
credential.num_ctx = 16384  # Larger than default 8192

await credential.save()     # Persists into the flexible config bag

# Subsequent model loads receive {"num_ctx": 16384}

language_model = await model_manager.get_model("ollama_gemma")

```

## Supported Providers Reference

Open Notebook supports 18+ providers through Esperanto, including:

- **Cloud LLMs**: OpenAI, Anthropic, Google (Gemini), Groq, Mistral, DeepSeek, xAI, OpenRouter, MiniMax, DashScope
- **Embeddings**: Voyage, OpenAI, Google
- **Speech**: ElevenLabs, Deepgram
- **Self-hosted**: Ollama

Each provider follows the same configuration pattern: either store credentials in the database via the UI/API or set the corresponding environment variable listed in `PROVIDER_CONFIG` within [`open_notebook/ai/key_provider.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/key_provider.py).

## Summary

- Open Notebook uses the **Esperanto** library to abstract 18+ AI providers through a unified interface
- Configure providers via **Credential** records in [`open_notebook/domain/credential.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/domain/credential.py) or environment variables mapped in `PROVIDER_CONFIG`
- Use **`provision_provider_keys()`** from [`open_notebook/ai/key_provider.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/key_provider.py) to load credentials at runtime
- Resolve models through **`ModelManager.get_model()`** in [`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py), which automatically builds Esperanto configurations
- Set system-wide defaults using the **DefaultModels** singleton and manage them via the **Settings → Models** UI or API endpoints in [`api/routers/models.py`](https://github.com/lfnovo/open-notebook/blob/main/api/routers/models.py)
- Override provider-specific parameters (like Ollama's `num_ctx`) through the flexible `CONFIG_EXTRAS` bag in credential records

## Frequently Asked Questions

### How does Open Notebook handle missing credentials?

When a model request lacks stored credentials, the system automatically invokes `provision_provider_keys()` from [`open_notebook/ai/key_provider.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/key_provider.py). This function looks up the provider in the `PROVIDER_CONFIG` map and injects the corresponding environment variable (e.g., `OPENAI_API_KEY`) into `os.environ`, allowing the Esperanto `AIFactory` to instantiate the model without database configuration.

### Can I mix database credentials and environment variables?

Yes. The architecture prioritizes database **Credential** records through the `to_esperanto_config()` method, which overrides environment variable defaults. If no credential exists for a provider, the system transparently falls back to environment variables. This hybrid approach lets you store sensitive keys in the database for production while using environment variables for local development or specific deployment scenarios.

### What is the difference between `ModelManager` and `AIFactory`?

**`ModelManager`** ([`open_notebook/ai/models.py`](https://github.com/lfnovo/open-notebook/blob/main/open_notebook/ai/models.py)) is the high-level Open Notebook component that handles database queries, credential resolution, and user defaults. It prepares the configuration and calls **`AIFactory`**, which is part of the Esperanto library and responsible for instantiating the actual LangChain model objects. `ModelManager` manages the "where" and "how" of configuration, while `AIFactory` handles the "what" of model creation.

### How do I configure self-hosted providers like Ollama?

For Ollama and similar self-hosted solutions, set the `OLLAMA_API_BASE` environment variable or create a **Credential** record with the `base_url` field pointing to your local endpoint. You can also specify additional parameters like `num_ctx` (context window size) in the credential's `CONFIG_EXTRAS` to optimize performance for your specific hardware deployment.