How the source_chat Workflow Differs from the General Chat Workflow in LangGraph
The source_chat workflow augments the standard chat flow with a dedicated context-building step that retrieves a specific source's text and insights, while the general chat workflow simply forwards message history to the LLM without external document retrieval.
Open‑Notebook implements two distinct LangGraph state machines to handle conversational AI: a general-purpose chat for open-ended notebook queries and a specialized source-grounded chat for document-centric interactions. Understanding how the source_chat workflow differs from the general chat workflow is essential for developers extending the lfnovo/open-notebook architecture or debugging context-retrieval issues.
State Schema and Data Model
The fundamental difference begins with the underlying state definitions.
General Chat uses ThreadState, defined in open_notebook/graphs/chat.py. This state contains:
messages– the conversation history- Optional
notebook,context,context_config model_overridefor temporary model switching
Source Chat uses SourceChatState, defined in open_notebook/graphs/source_chat.py, which extends the base structure with:
- Required
source_id– the primary key of the document to query - Optional
source,insights,context_indicators model_overrideandcontextfields
This schema difference enforces that every source_chat invocation must target a specific document, whereas the general chat operates over the notebook's message history without document constraints.
Context Building: The Key Architectural Difference
The most significant divergence occurs in the context preparation phase.
General Chat relies solely on the existing message history. As implemented in api/routers/chat.py, the system renders a static system prompt from the current state without fetching external content:
payload = [SystemMessage(content=system_prompt)] + state["messages"]
model = await provision_langchain_model(str(payload), model_id, "chat", max_tokens=8192)
Source Chat triggers an explicit retrieval pipeline. In open_notebook/graphs/source_chat.py, the workflow invokes ContextBuilder to fetch the source's full text and associated insights:
context_data = ContextBuilder(
source_id=state["source_id"],
include_insights=True,
include_notes=False,
max_tokens=50000,
).build()
The ContextBuilder (located in open_notebook/utils/context_builder.py) retrieves the document, extracts relevant insights, and formats them using _format_source_context(). This enriched data populates a prompt_data dictionary containing the source metadata, insights list, formatted context, and tracking indicators.
Prompt Templates and System Instructions
The two workflows use distinct prompt templates to handle their different data payloads.
General Chat uses the generic chat/system template, which receives only basic conversation context and notebook metadata.
Source Chat uses the specialized source_chat/system template, which expects a richer payload:
prompt_data = {
"source": source.model_dump() if source else None,
"insights": [i.model_dump() for i in insights],
"context": _format_source_context(context_data),
"context_indicators": context_indicators,
}
system_prompt = Prompter(prompt_template="source_chat/system").render(data=prompt_data)
This template renders the source content and insights directly into the system message, grounding the LLM's responses in specific document content rather than general knowledge.
Return Values and State Updates
The state update mechanisms reflect their different operational scopes.
General Chat returns a minimal state update containing only the cleaned message list:
return {"messages": cleaned}
Source Chat returns an enriched state that preserves the retrieval context for subsequent turns:
return {
"messages": cleaned_message,
"source": source,
"insights": insights,
"context": formatted_context,
"context_indicators": context_indicators,
}
This return structure allows the source_chat workflow to maintain provenance information about which sources and insights informed the current response, enabling transparency features like citation tracking.
Implementation in Code
Both workflows share the same model provisioning helper, provision_langchain_model, but differ in how they prepare the payload and handle state.
General Chat Implementation
Found in open_notebook/graphs/chat.py and exposed via api/routers/chat.py, the general chat follows a straightforward pattern:
- Render system prompt from current state
- Assemble message payload
- Invoke model via
provision_langchain_model - Return cleaned messages
This approach suits queries like "Summarize my notes" or "What did I write last Tuesday?" that require no external document retrieval.
Source Chat Implementation
Found in open_notebook/graphs/source_chat.py and exposed via api/routers/source_chat.py, the source chat adds the retrieval layer:
- Validate
source_idexists in state - Build context using
ContextBuilderwithinclude_insights=True - Format context and prepare
prompt_datadict - Render source-specific system prompt
- Invoke model via
provision_langchain_model - Return enriched state with source metadata and context indicators
This implementation handles queries like "Explain this PDF" or "What are the key insights from source X?" where the LLM must reference specific document content.
Summary
- State Structure: General chat uses
ThreadStatewith optional metadata; source chat requiresSourceChatStatewith a mandatorysource_idand fields for insights and context indicators. - Context Retrieval: Only
source_chatinvokesContextBuilderto fetch document text and insights; general chat relies entirely on existing message history. - Prompt Enrichment:
source_chatuses thesource_chat/systemtemplate with formatted document context; general chat uses the basicchat/systemtemplate. - Response Metadata:
source_chatreturns source provenance and context indicators; general chat returns messages only. - Use Cases: General chat handles open-ended notebook queries; source chat handles document-specific questions requiring grounded retrieval.
Frequently Asked Questions
Can I use the general chat workflow to query specific documents?
No. The general chat workflow in open_notebook/graphs/chat.py lacks the source_id field and ContextBuilder integration required for document retrieval. To query specific sources, you must use the source_chat workflow, which enforces a source_id parameter and retrieves document content via the ContextBuilder utility.
Does the source_chat workflow support multiple sources simultaneously?
Based on the current implementation in open_notebook/graphs/source_chat.py, the state schema accepts a single source_id and associated source object. The ContextBuilder is instantiated with one source_id per invocation. For multi-source queries, you would need to either extend the state schema to accept a list of source IDs or chain multiple context-building steps before the LLM call.
Why does source_chat return context_indicators while general chat does not?
The context_indicators field tracks which specific insights and document sections informed the LLM's response. Since the general chat workflow (chat.py) does not retrieve external documents, there are no source references to track. The source_chat workflow requires these indicators to provide transparency and citation capabilities for document-grounded answers.
Are both workflows checkpointed in the same database?
Yes. Both workflows use the same SQLite checkpoint configuration defined by LANGGRAPH_CHECKPOINT_FILE. However, because source_chat uses the expanded SourceChatState schema, its checkpointed state contains additional fields (source, insights, context_indicators) that are absent from general chat checkpoints.
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 →