How the Open-Notebook REST API Handles Model Configuration Overrides Per Request
The Open-Notebook REST API implements a three-tier fallback system that prioritizes request-level model overrides, falls back to session-specific configurations stored in SurrealDB, and finally defaults to global settings, injecting the resolved model ID directly into the LangGraph execution context.
The open-notebook repository provides a flexible REST API for conversational AI interactions that allows dynamic LLM selection without restarting services or modifying environment variables. By supporting per-request model configuration overrides, the system enables developers to switch between GPT-4, Claude, or other providers on a per-message basis while maintaining persistent session preferences. This architecture ensures that individual requests can specify exactly which model should handle the inference, with clear precedence rules determining the final selection.
Where the API Accepts Model Overrides
Chat Endpoints
In api/routers/chat.py, the Pydantic request models define an optional model_override field across all relevant operations. The CreateSessionRequest, UpdateSessionRequest, and ExecuteChatRequest schemas each accept this parameter, allowing clients to specify a model identifier such as "gpt-4o" or "claude-3-opus" at different stages of the conversation lifecycle.
Source Chat Endpoints
The same pattern appears in api/routers/source_chat.py, ensuring consistent behavior across different conversational interfaces. Whether initiating a new session or executing a message against an existing one, the API surface accepts the override uniformly.
The Three-Tier Resolution Order
The resolution logic follows a strict precedence hierarchy to determine the effective model:
- Request-level override – The explicit
model_overridevalue provided in the current HTTP request takes highest priority. - Session-level override – If the request omits the override, the system checks the
session.model_overrideattribute stored in the database. - Global default – When neither request nor session specifies a model, the application falls back to the
DefaultModelssingleton accessed viaopen_notebook.ai.models.DefaultModels.
This cascade ensures maximum flexibility while maintaining sensible defaults.
Propagation to LangGraph Execution
Once resolved, the model identifier propagates through the execution stack. In open_notebook/graphs/chat.py, the system injects the model_override into the LangGraph invocation via the RunnableConfig configurable dictionary:
result = chat_graph.invoke(
input=state_values,
config=RunnableConfig(
configurable={"thread_id": full_session_id, "model_id": model_override},
),
)
The Esperanto provider receives this model_id and instantiates the appropriate LLM client for that specific call, enabling true per-request model switching without thread contamination.
Persistence and Session Management
Updates to a session's default model persist to SurrealDB. When calling PUT /chat/sessions/{session_id}, the UpdateSessionRequest payload writes the model_override value directly to the ChatSession.model_override field in open_notebook/domain/notebook.py. Subsequent requests that omit an explicit override automatically inherit this stored preference.
Implementation Details
The resolution logic in api/routers/chat.py implements the fallback chain explicitly:
model_override = (
request.model_override
if request.model_override is not None
else getattr(session, "model_override", None)
)
The resolved value then populates the state dictionary passed to the graph:
state_values["model_override"] = model_override
Practical API Examples
Create a session with a specific default model:
curl -X POST http://localhost:5055/chat/sessions \
-H "Content-Type: application/json" \
-d '{
"notebook_id": "my-notebook",
"title": "Demo Session",
"model_override": "gpt-4o"
}'
Execute a message overriding the session default:
curl -X POST http://localhost:5055/chat/execute \
-H "Content-Type: application/json" \
-d '{
"session_id": "12345",
"message": "Explain quantum computing",
"model_override": "claude-3-opus"
}'
Update an existing session's default:
curl -X PUT http://localhost:5055/chat/sessions/12345 \
-H "Content-Type: application/json" \
-d '{
"model_override": "gpt-4"
}'
Rely on automatic fallback:
curl -X POST http://localhost:5055/chat/execute \
-H "Content-Type: application/json" \
-d '{
"session_id": "12345",
"message": "What is the weather today?",
"context": {}
}'
Summary
- The Open-Notebook REST API accepts
model_overridein request payloads across chat and source-chat endpoints defined inapi/routers/chat.pyandapi/routers/source_chat.py. - Resolution follows a strict hierarchy: request-level overrides take precedence over session-level settings, which supersede global defaults from
DefaultModels. - The resolved model ID propagates to LangGraph via
RunnableConfig.configurable, ensuring the correct LLM handles each specific invocation. - Session updates persist to SurrealDB, allowing durable default model preferences for ongoing conversations.
- The implementation uses explicit null-checks in Python to distinguish between omitted parameters and intentional None values.
Frequently Asked Questions
What happens if I provide an invalid model ID in the override?
The request will proceed through the resolution logic, but the LangGraph execution will likely fail when the Esperanto provider attempts to instantiate the unrecognized model. Validation occurs at the provider level rather than the API boundary.
Can I override the model for a single message without changing the session default?
Yes. By including model_override only in the ExecuteChatRequest payload, you affect that specific message's processing while leaving the underlying ChatSession.model_override unchanged in the database.
Where does the system store the global default models?
The global defaults reside in the DefaultModels singleton class located in open_notebook/ai/models.py. This serves as the final fallback when neither request nor session specifies a model override.
Does the source_chat router use the same override logic?
Yes. The api/routers/source_chat.py file implements identical request schema patterns and resolution logic, ensuring consistent model selection behavior across all conversational endpoints in the API.
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 →