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 provider
  • POST /models/sync – runs parallel sync across all configured providers using asyncio.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 model and provides automated discovery via open_notebook/ai/model_discovery.py.
  • Register new AI models by calling POST /models/sync/{provider} for single providers or POST /models/sync for all providers.
  • The sync_provider_models function handles duplicate detection efficiently using set comparisons and persists new records via await 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 Model class 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →