How to Register New AI Models After Discovering Them from a Provider API in Open Notebook
Call sync_provider_models(provider, auto_register=True) or POST to /models/sync/{provider} to discover and persist new models from any configured provider API.
Open Notebook maintains a central registry of AI models in SurrealDB to power its LangGraph workflows and UI features. When you need to register new AI models discovered from a provider API, the system provides both REST endpoints and Python async functions to handle discovery, classification, and persistence automatically. This article explains the complete registration pipeline based on the actual implementation in the lfnovo/open-notebook repository.
Understanding the Model Registration Pipeline
The registration flow consists of three coordinated stages: discovery, synchronization, and API exposure.
Step 1: Model Discovery
Provider-specific async functions query external APIs and classify model types. In open_notebook/ai/model_discovery.py, functions like discover_openai_models and discover_google_models fetch available models and use the classify_model_type helper to categorize them as language, embedding, speech_to_text, or text_to_speech. Each function returns a list of DiscoveredModel objects containing the name, provider, type, and optional description.
Step 2: Synchronization and Registration
The sync_provider_models function (lines 64-88 in open_notebook/ai/model_discovery.py) handles the actual registration. It first calls discover_provider_models to get fresh data, then queries the existing model table in SurrealDB to build a set of current (name, type) tuples for O(1) duplicate detection. For each new model, it creates a Model instance and persists it with await new_model.save(). The function returns a tuple of (discovered, new, existing) counts.
Step 3: REST API Exposure
The FastAPI router in api/routers/models.py exposes two endpoints:
POST /models/sync/{provider}– triggers discovery and registration for a single providerPOST /models/sync– runs parallel sync across all configured providers usingasyncio.gather
Both endpoints first call provision_provider_keys to load stored credentials into environment variables before discovery begins.
How to Register New AI Models from the REST API
Single Provider Sync
To register models from a specific provider like OpenAI or Google, send a POST request to the sync endpoint:
curl -X POST http://localhost:5055/models/sync/openai
The response returns a JSON payload showing how many models were discovered, newly registered, and already existing:
{
"provider": "openai",
"discovered": 38,
"new": 12,
"existing": 26
}
Bulk Sync for All Providers
To refresh the model registry across all configured providers simultaneously:
curl -X POST http://localhost:5055/models/sync
This endpoint uses asyncio.gather to run discovery in parallel for every provider defined in PROVIDER_DISCOVERY_FUNCTIONS, aggregating results into a single response with per-provider totals.
Programmatic Registration in Python
Using sync_provider_models Directly
For custom scripts or automated pipelines, import the discovery module and call sync_provider_models with auto_register=True:
import asyncio
from open_notebook.ai.model_discovery import sync_provider_models
async def register_openai():
discovered, new, existing = await sync_provider_models("openai", auto_register=True)
print(f"Discovered: {discovered}, New: {new}, Existing: {existing}")
if __name__ == "__main__":
asyncio.run(register_openai())
Inspecting Before Registering
To preview discovered models without persisting them, use the discover_provider_models function directly:
from open_notebook.ai.model_discovery import discover_provider_models
async def preview_models():
models = await discover_provider_models("openai")
for model in models:
print(f"{model.name}: {model.model_type}")
Manual Model Creation
For custom models not listed by provider APIs, instantiate the Model class directly from open_notebook/ai/models.py:
from open_notebook.ai.models import Model
async def add_custom_model():
custom = Model(
name="my-custom-tts-v1",
provider="elevenlabs",
type="text_to_speech",
credential=None
)
await custom.save()
print(f"Created model ID: {custom.id}")
Behind the Scenes: Credentials and Classification
Before any discovery occurs, the system must provision API keys. The provision_provider_keys function in open_notebook/ai/key_provider.py loads stored Credential records from SurrealDB and injects them into environment variables, allowing discovery functions to authenticate via os.getenv.
The classify_model_type helper uses provider-specific pattern tables (OPENAI_MODEL_TYPES, GOOGLE_MODEL_TYPES, etc.) to map model names to supported types. This classification happens during discovery, ensuring each Model record is created with the correct type field.
Summary
- Open Notebook stores AI models in a SurrealDB table named
modeland provides automated discovery viaopen_notebook/ai/model_discovery.py. - Register new AI models by calling
POST /models/sync/{provider}for single providers orPOST /models/syncfor all providers. - The
sync_provider_modelsfunction handles duplicate detection efficiently using set comparisons and persists new records viaawait new_model.save(). - Credentials are provisioned automatically before discovery via
provision_provider_keys, which loads stored credentials into environment variables. - Custom models can be added manually by instantiating the
Modelclass directly if they are not available through provider APIs.
Frequently Asked Questions
How does Open Notebook handle duplicate models during registration?
The sync_provider_models function queries all existing models for the provider in a single SELECT statement and builds a set of (name, type) tuples. When processing discovered models, it checks membership in this set with O(1) complexity, skipping any duplicates and only persisting truly new entries.
What credentials are required to register new AI models?
The system requires valid API keys for the target provider, stored either as Credential records in SurrealDB or as environment variables. The provision_provider_keys function loads these credentials into the environment before discovery functions execute, ensuring authentication headers are available when calling provider APIs.
Can I register a model that is not returned by the provider's API?
Yes. While automatic discovery handles most cases, you can manually create Model records by instantiating the Model class from open_notebook/ai/models.py with your custom name, provider, and type. This is useful for custom fine-tuned models or private endpoints not listed in public API responses.
Why are some models classified as language while others are embedding?
The classify_model_type function in open_notebook/ai/model_discovery.py uses provider-specific pattern mappings (such as OPENAI_MODEL_TYPES) to inspect model names and assign categories. For example, models containing "embedding" in their name are classified as embedding, while others may default to language or text_to_speech based on naming conventions specific to each provider.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →