KGraphPlanner
A Python framework for building AI agents that plan and execute multi-step tasks using composable workers, tool integration, and LangGraph-based execution graphs.
Overview
KGraphPlanner provides a layered architecture for constructing AI agent pipelines:
- Workers encapsulate a single capability (chat, tool use, categorization) and generate their own LangGraph subgraphs.
- Agents compose workers into end-to-end workflows with state management and checkpointing.
- Programs & Execution Graphs let an LLM planner dynamically generate multi-worker pipelines at runtime — including fan-out, fan-in, and conditional routing.
Architecture
┌─────────────────────────────────────────────────┐
│ Agents │
│ ChatAgent · ToolAgent · CaseAgent · Planner │
├─────────────────────────────────────────────────┤
│ Workers │
│ ChatWorker · ToolWorker · CaseWorker │
├─────────────────────────────────────────────────┤
│ Execution Layer │
│ ExecGraphAgent · ProgramSpec · GraphSpec │
├─────────────────────────────────────────────────┤
│ Infrastructure │
│ AgentConfig · ToolManager · Checkpointer │
└─────────────────────────────────────────────────┘
Agents
| Agent | Purpose |
|---|---|
KGraphChatAgent |
Single-worker conversational agent with memory |
KGraphToolAgent |
Agent with OpenAI function-calling and external tools |
KGraphCaseAgent |
Routes requests through LLM-based categorization to specialized workers |
KGraphPlannerAgent |
Classifies user requests via LLM and routes to category-specific handlers (greeting, question, planning, etc.) |
KGraphExecGraphAgent |
Executes a declarative GraphSpec using a registry of workers (see docs/exec_graph.md) |
Workers
| Worker | Purpose |
|---|---|
KGraphChatWorker |
Single LLM call — responds to a prompt with conversation history |
KGraphToolWorker |
Multi-turn tool-calling loop — decides, calls tools, and finalizes |
KGraphCaseWorker |
Classifies input into one of N categories via structured LLM output |
KGraphStructuredWorker |
Single LLM call returning a validated pydantic model |
KGraphFunctionWorker |
Deterministic Python code as a graph node — no LLM |
Tools
Built-in tools that connect to a tool server endpoint:
google_web_search_tool— Web search via Googleserper_web_search_tool— Web, news, image, shopping and places search via Serperplace_search_tool— Place/business lookup, with Google rating and review countgoogle_address_validation_tool— Address validationweather_tool— Weather data
Tools are managed by ToolManager, which handles registration, configuration, and JWT authentication.
Installation
pip install kgraphplanner
Or from source:
git clone https://github.com/vital-ai/kgraphplanner.git
cd kgraphplanner
pip install -e ".[dev]"
Requirements
- Python >= 3.12
- OpenAI API key
- Tool server running (for tool-based agents)
Configuration
Configuration is loaded from environment variables with the KGPLAN__ prefix, using __ as the hierarchy separator.
Setup
cp .env.example .env
# Edit .env with your values
Environment Variables
# OpenAI
OPENAI_API_KEY=sk-...
# Tool subsystem
KGPLAN__TOOLS__ENDPOINT=http://localhost:8008
KGPLAN__TOOLS__ENABLED=google_web_search_tool,weather_tool
# Log tool request content (queries, error bodies). Off by default.
KGPLAN__TOOLS__LOG_CONTENT=false
# Model
KGPLAN__AGENT__MODEL__NAME=gpt-4o-mini
KGPLAN__AGENT__MODEL__TEMPERATURE=0.7
# Checkpointing
KGPLAN__CHECKPOINTING__ENABLED=true
KGPLAN__CHECKPOINTING__BACKEND=memory
Configuration can also be created programmatically:
from kgraphplanner.config.agent_config import AgentConfig, ToolConfig
# From environment
config = AgentConfig.from_env()
# From code
config = AgentConfig(
tools=ToolConfig(
endpoint="http://localhost:8008",
enabled=["weather_tool", "google_web_search_tool"],
),
)
# From YAML
config = AgentConfig.from_yaml("config.yaml")
# From dict
config = AgentConfig.from_dict({"tools": {"endpoint": "..."}})
Quick Start
Chat Agent
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage
from kgraphplanner.agent.kgraph_chat_agent import KGraphChatAgent
from kgraphplanner.worker.kgraph_chat_worker import KGraphChatWorker
from kgraphplanner.checkpointer.kgraphmemory_checkpointer import KGraphMemoryCheckpointer
from kgraphplanner.checkpointer.kgraph_serializer import KGraphSerializer
llm = ChatOpenAI(model="gpt-4o-mini")
checkpointer = KGraphMemoryCheckpointer(serde=KGraphSerializer())
worker = KGraphChatWorker(
name="assistant",
llm=llm,
system_directive="You are a helpful assistant.",
required_inputs=["message"],
)
agent = KGraphChatAgent(name="chat", checkpointer=checkpointer, chat_worker=worker)
async def main():
config = {"configurable": {"thread_id": "demo"}}
result = await agent.arun([HumanMessage(content="Hello!")], config=config)
print(result["messages"][-1].content)
asyncio.run(main())
Case Agent (Intent Routing)
from kgraphplanner.agent.kgraph_case_agent import KGraphCaseAgent
from kgraphplanner.worker.kgraph_case_worker import KGCase
cases = [
(KGCase(id="weather", name="Weather", description="weather requests"),
weather_worker),
(KGCase(id="search", name="Search", description="research requests"),
search_worker),
]
agent = KGraphCaseAgent(
name="router",
case_worker_llm=llm,
case_worker_pairs=cases,
resolve_worker=resolve_worker,
)
Tool Agent
from kgraphplanner.agent.kgraph_tool_agent import KGraphToolAgent
from kgraphplanner.config.agent_config import AgentConfig
from kgraphplanner.tool_manager.tool_manager import ToolManager
config = AgentConfig.from_env()
tm = ToolManager(config=config)
tm.load_tools_from_config()
agent = KGraphToolAgent(
name="tools",
llm=llm,
tool_manager=tm,
available_tool_ids=["weather_tool"],
)
Exec Graph Agent (Fixed Pipelines)
Wire workers into a declarative graph with bindings, conditional routing, bounded loops, per-node timeouts and retries, and a run deadline. See docs/exec_graph.md for a complete example, the routing rules, and the migration notes for v0.2.0 and v0.2.1. Later changes are in CHANGELOG.md.
agent = KGraphExecGraphAgent(name="explain", graph_spec=spec, worker_registry=workers)
result = await agent.run({"case": case_data}, timeout=40)
result.results, result.errors, result.usage
Testing
The offline pytest suite runs with pytest from the repo root.
kgraphplanner.testing provides ScriptedLLM (a fake chat model scripted per
graph node, with structured-output support) and assert_node_order.
Tests are organized into modular cases run by dedicated runners:
# List available test cases
python test_scripts/test_agent_runner.py --list
python test_scripts/test_tool_runner.py --list
python test_scripts/test_case_agent_runner.py --list
# Run all cases in a runner
python test_scripts/test_agent_runner.py
# Run specific cases by name or index
python test_scripts/test_agent_runner.py chat
python test_scripts/test_tool_runner.py 2
# Planner tests
python test_scripts_planner/test_planner_runner.py
Test Runners
| Runner | Cases |
|---|---|
test_agent_runner.py |
LangGraph agent, tool agents (web search, address, weather, place, multi), chat agent |
test_tool_runner.py |
Direct tool tests, tool manager, multi-weather, Times Square |
test_case_agent_runner.py |
Case agent routing, case worker categorization |
test_kgraphplanner_agent_runner.py |
KGraphPlanner agent |
Project Structure
kgraphplanner/
├── agent/ # Agent implementations
│ ├── kgraph_agent.py # Abstract interface
│ ├── kgraph_base_agent.py # Base class with state and checkpointing
│ ├── kgraph_chat_agent.py # Conversational agent
│ ├── kgraph_tool_agent.py # Tool-calling agent
│ ├── kgraph_case_agent.py # Intent-routing agent
│ ├── kgraph_planner_agent.py # LLM planner agent
│ └── kgraph_exec_graph_agent.py # Declarative graph executor
├── worker/ # Worker implementations
│ ├── kgraph_worker.py # Abstract base worker
│ ├── kgraph_chat_worker.py # Chat (single LLM call)
│ ├── kgraph_tool_worker.py # Tool-calling loop
│ ├── kgraph_case_worker.py # Categorization
│ ├── kgraph_structured_worker.py # Pydantic structured output
│ ├── kgraph_function_worker.py # Deterministic code node
│ └── worker_errors.py # Typed worker failures
├── config/ # Configuration
│ └── agent_config.py # Typed config with from_yaml/from_dict/from_env
├── tool_manager/ # Tool management
│ └── tool_manager.py # Registration, config loading, JWT auth
├── tools/ # Built-in tool implementations
├── graph/ # Execution graph models
│ ├── exec_graph.py # GraphSpec, EdgeSpec, Binding models
│ ├── conditions.py # Routing condition parser/evaluator
│ └── graph_hop.py # Activation merging utilities
├── program/ # Program specification
│ ├── program.py # ProgramSpec models
│ └── program_expander.py # ProgramSpec → GraphSpec expansion
└── checkpointer/ # State persistence
├── kgraph_serializer.py # Custom LangGraph serializer
└── kgraphmemory_checkpointer.py # In-memory checkpointer
License
Apache License 2.0
Metadata
Release files for kgraphplanner 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| kgraphplanner-0.2.2.tar.gz | 193.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kgraphplanner-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 467.4 kB
Release files / kgraphplanner-0.2.2.tar.gz
| Download URL | kgraphplanner-0.2.2.tar.gz |
|---|---|
| Size | 193.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
298cae8339c099093a79ef0d7f2296709a7df10fad04e493ae459466390fd10b
|
|
BLAKE2b-256 checksum How to use checksums |
fb85bedf63ce38a2b2831fae30b21070052652b14f065c8372a65012e0745713
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|
Release files / kgraphplanner-0.2.2-py3-none-any.whl
| Download URL | kgraphplanner-0.2.2-py3-none-any.whl |
|---|---|
| Size | 273.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cd8d329d0faecd1b75a9f01c47f45ffe2464cc0d89ed9dd783f6485249ebc594
|
|
BLAKE2b-256 checksum How to use checksums |
ff91b3edf828cf15d59c841e9cb1a0860f2f83b7d9b7248075d144de39b4002e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.2
|
Security for kgraphplanner 0.2.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.