Orchestrator framework¶
- class klea_utils.graph.base.BaseLangGraph(logging_level: int = 10, checkpoint: str = 'inmemory', log_file: bool = True)[source]¶
Bases:
ABCAbstract base class for LangGraph-based orchestrators.
Provides common infrastructure for: - Configuration loading from env files - MCP client creation from JSON config - LLM model setup (delegated to subclasses) - LangGraph compilation and execution - Session checkpointing - Dual-stream logging
Subclasses must implement: -
_setup_models(): Create LLM model instances -_create_graph(): Build and compile the LangGraph - Setenv_classto the appropriate Pydantic settings class- config_class: type[BaseModel]¶
Pydantic BaseModel class for configuration loading. Subclasses must set this to their AppConfig class.
- env_class: type[BaseModel]¶
Pydantic BaseSettings class for env loading. Subclasses must set this to their AppEnv class.
- env_file_default: str = 'config.env'¶
Default config file name if the environment variable is not set.
- graph_name: str = 'BaseLangGraph'¶
Logger name for this orchestrator, also used as the app name for
platformdirsdata/cache directories.
- async graph_stream(query: str, thread_id: str = 'default_thread') Any[source]¶
Run the graph and return the raw astream result.
- Parameters:
query – User query string
thread_id – Session/thread identifier for checkpointing
- Returns:
Raw async generator from
graph.astream()
- async run_graph_astream_events(query: str, thread_id: str = 'default_thread')[source]¶
Run the graph and yield structured streaming events.
Yields dicts with:
{"type": "progress", "node": "<label>"}When the graph enters a new node (via
write_custom_stream){"type": "info", "node": "<label>", "data": {...}}Structured summary data from a node after execution
{"type": "debug", "node": "<label>", "data": {...}}Full data dump from a node after execution
{"type": "token", "content": "<chunk>", "node": "<label>"}LLM token chunk from the current node
{"type": "usage", "node": "<label>", "data": {...}}Per-node token usage (input / output / total tokens)
{"type": "complete", "message_for_user": "<answer>"}Final answer from the completed graph
Uses LangGraph’s
astream_eventsv3 protocol. Progress events from all nodes (LLM and non-LLM) arrive via thecustomchannel. LLM token output is read from themessageschannel. AStreamTransformerenables the custom channel so those events flow through.Reference: https://docs.langchain.com/oss/python/langgraph/event-streaming
- Parameters:
query – User query string
thread_id – Session/thread identifier for checkpointing
- Yields:
Structured event dicts
- async run_graph_invoke(query: str, thread_id: str = 'default_thread') str[source]¶
Run the graph with a simple string query.
- Parameters:
query – User query string
thread_id – Session/thread identifier for checkpointing
- Returns:
The
message_for_userfield from the final state
- async run_graph_invoke_state(state: dict, thread_id: str = 'default_thread') dict[source]¶
Run the graph, accepting and returning full state dicts.
- Parameters:
state – Initial graph state (must contain
querykey)thread_id – Session/thread identifier for checkpointing
- Returns:
Final graph state
Shared state schemas¶
Schemas shared by LangGraph orchestrators.
File: klea_utils/graph/schemas.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- class klea_utils.graph.schemas.TokenUsage(*, input_tokens: int = 0, output_tokens: int = 0, total_tokens: int = 0)[source]¶
Bases:
BaseModelToken usage accumulated across the nodes in a graph run.
- model_config = {}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Reducers¶
Reducers shared by LangGraph orchestrators.
File: klea_utils/graph/reducers.py
Copyright 2026 Ankur Sinha Author: Ankur Sinha <sanjay DOT ankur AT gmail DOT com>
- klea_utils.graph.reducers.add_token_usage(left: TokenUsage | dict[str, int], right: TokenUsage | dict[str, int]) TokenUsage[source]¶
Add token usage updates from sequential or concurrent graph nodes.