How to Customize Open-Notebook: A Complete Guide to Configuration and Extensions

You can customize Open-Notebook by editing environment variables in .env, extending Python modules in the open_notebook/ package, or modifying React components in the frontend/ directory, with all core configuration centralized in open_notebook/config.py.

Open-Notebook is a modular, three-tier application (frontend → API → database) designed for extensibility. The repository lfnovo/open-notebook provides specific entry points for tailoring AI providers, content processing pipelines, and database schemas without forking the entire codebase.

Application Settings and Configuration

Environment variables drive all tunable settings in Open-Notebook. The open_notebook/config.py file defines the Config class that reads from your .env file at runtime, controlling everything from CORS policies to file upload limits.

Copy .env.example to .env and modify values such as DEFAULT_MODEL, MAX_UPLOAD_SIZE, or provider-specific API keys. For programmatic defaults, subclass the Config class in open_notebook/config.py before the FastAPI application initializes.

AI Model Customization

Open-Notebook abstracts model access through a provider pattern that supports OpenAI, Anthropic, and other backends via the open_notebook/ai/ module.

Adding New Providers and Models

To support a new provider, implement a wrapper class in open_notebook/ai/models.py that follows the BaseModel interface, then register it in open_notebook/ai/model_discovery.py. The provision.py module automatically detects available providers based on present environment variables (e.g., OPENAI_API_KEY, ANTHROPIC_API_KEY).

Runtime Model Selection

Use provision_langchain_model() from open_notebook/ai/provision.py to dynamically select models at runtime:

from open_notebook.ai.provision import provision_langchain_model

model = provision_langchain_model(
    provider="anthropic",
    model_name="claude-3-5-sonnet-20240620",
    temperature=0.2,
)
response = await model.ainvoke({"input": "Summarise this notebook"})

Credentials are stored securely via open_notebook/domain/credential.py using SurrealDB records, separating sensitive keys from configuration files.

Extending LangGraph Workflows

The application uses LangGraph for orchestrating complex AI workflows. You can extend or replace the source ingestion, chat, ask, or transformation graphs located in open_notebook/graphs/ (e.g., source.py, chat.py, ask.py, transformation.py).

To customize the ingestion pipeline, copy an existing graph and modify its nodes:


# open_notebook/graphs/custom_source.py

from .source import source_graph
from open_notebook.utils.graph_utils import add_node

custom_graph = source_graph.copy()

@add_node(custom_graph, "my_custom_step")
async def custom_step(state):
    # Custom processing logic here

    return state

custom_graph.add_edge("extract_text", "my_custom_step")
custom_graph.add_edge("my_custom_step", "embed")

Invoke custom graphs using await custom_graph.ainvoke({...}) within your API routes.

Content Processing and Embeddings

Modify text chunking strategies in open_notebook/utils/chunking.py or adjust cleanup pipelines in open_notebook/utils/text_utils.py to change how documents are split and sanitized before embedding.

For vector storage customization, edit open_notebook/utils/embedding.py, which wraps the Esperanto library. Database migration scripts for schema changes reside in migrations/ and are executed automatically by open_notebook/database/async_migrate.py.

API and Backend Extensions

Add new REST endpoints by creating router files in api/routers/ following the pattern of existing modules like sources.py or settings.py:


# api/routers/custom.py

from fastapi import APIRouter
router = APIRouter()

@router.post("/custom/process")
async def process(payload: dict):
    result = await custom_graph.ainvoke(payload)
    return result

Register the router in api/main.py:

app.include_router(router, prefix="/custom")

Background job queues for podcast generation and other async tasks can be tuned in api/podcast_service.py and the commands/ directory.

Frontend and Database Modifications

The React/Next.js frontend lives in frontend/, with reusable UI components under frontend/src/components/. You can retheme the interface, add new panels, or modify TanStack-Query hooks to connect with custom backend routes.

To extend the SurrealDB schema, create new record types by adding SurrealQL migration files in migrations/ (e.g., 001_add_projects.surql). The migration runner applies these automatically on the next API startup.

Summary

  • Configuration: Edit .env variables or subclass Config in open_notebook/config.py to modify application settings.
  • AI Models: Implement providers in open_notebook/ai/models.py and use provision_langchain_model() for runtime selection.
  • Workflows: Copy and extend LangGraph definitions in open_notebook/graphs/ to customize AI pipelines.
  • API: Add FastAPI routers in api/routers/ to expose new functionality.
  • Database: Create SurrealQL files in migrations/ to add tables or relationships.
  • Frontend: Modify React components in frontend/src/components/ to change the user interface.

Frequently Asked Questions

How do I change the default AI model in Open-Notebook?

Set the DEFAULT_MODEL environment variable in your .env file (e.g., DEFAULT_MODEL=gpt-4o), or override the value programmatically in open_notebook/config.py before the FastAPI app initializes. The system uses open_notebook/ai/provision.py to resolve the provider based on available API keys.

Can I add custom file type handlers to the ingestion pipeline?

Yes. Modify open_notebook/utils/chunking.py to adjust chunk sizes for specific file types, or extend the text cleanup logic in open_notebook/utils/text_utils.py. For complex file formats, add a new processing node to the source ingestion graph in open_notebook/graphs/source.py.

What is the best way to add new database tables to Open-Notebook?

Create a SurrealQL migration file in the migrations/ directory (e.g., 002_add_tags.surql). The open_notebook/database/async_migrate.py module automatically detects and applies these migrations when the API restarts, ensuring schema consistency across deployments.

How do I create a custom LangGraph workflow?

Copy an existing graph such as open_notebook/graphs/source.py, rename it, and use the graph utilities in open_notebook/utils/graph_utils.py to add or modify nodes. Expose the new workflow by creating a FastAPI router in api/routers/ that invokes your custom graph with await graph.ainvoke({...}).

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 →