Python API¶
Use the Python API to embed ChemGraph in notebooks, services, or larger workflows. The standard agent is asynchronous.
Run a single-agent query¶
import asyncio
from chemgraph.agent.llm_agent import ChemGraph
async def main():
agent = ChemGraph(
model_name="gpt-4o-mini",
workflow_type="single_agent",
return_option="last_message",
)
result = await agent.run(
"Build water from SMILES O, optimize it with EMT, and report the energy."
)
print(result.content)
asyncio.run(main())
In an async notebook or application, call await agent.run(...) directly
instead of starting a second event loop.
Return values¶
Use return_option="last_message" for the final message object or
return_option="state" for the full graph state. Full state is useful when an
application must inspect tool calls, messages, or structured output.
agent = ChemGraph(return_option="state")
state = await agent.run("What is the SMILES string for aspirin?")
Threads and checkpoints¶
Pass graph configuration when a workflow needs a stable thread identity:
config = {"configurable": {"thread_id": "my-run-001"}}
result = await agent.run("Continue the analysis.", config=config)
Choose thread IDs that are unique in your application and do not contain credentials or sensitive user data.
Main-agent sessions¶
The checkpointed main_agent is not run through ChemGraph.run(). Import and
construct MainAgentSession from chemgraph.agent.main_session, then use its
session-oriented async methods. This API is
intended for durable, interactive supervisor workflows; consult the class
docstrings in the installed version for constructor and persistence options.
MainAgentSession accepts an optional on_event callback with the signature
(event_name, payload). Tagged tool_call_started payloads include
subagent_name, allowing callers to distinguish delegated tool activity from
supervisor tools. The supervisor can use read_file for checkpoint-backed
files returned by subagents, but this does not expose host files or session
artifacts.
For CLI use, the equivalent is:
Workspace Deep Agent¶
The workspace workflow is separately callable through ChemGraph.run():
import os
from deepagents.backends import LocalShellBackend
from chemgraph.agent.llm_agent import ChemGraph
agent = ChemGraph(
model_name="claude-sonnet-4-20250514",
workflow_type="deep_agent",
deepagent_backend=LocalShellBackend(
root_dir="/path/to/checkout",
virtual_mode=True,
env={
name: os.environ[name]
for name in ("PATH", "PYTHONPATH", "VIRTUAL_ENV", "CONDA_PREFIX", "TMPDIR")
if name in os.environ
},
inherit_env=False,
),
deepagent_skills=[
"/workspace/shared-skills/",
"/workspace/.agents/skills/",
],
)
result = await agent.run(
"Review the test failures.",
config={"configurable": {"thread_id": "workspace-review"}},
)
A virtual LocalShellBackend is exposed to the agent at /workspace, so file
tool path /workspace/src/example.py maps directly to
/path/to/checkout/src/example.py. The generated Deep Agents system context
also supplies that host path for shell commands. Custom backends, existing
composite backends, and non-virtual local backends are passed through unchanged.
deepagent_skills contains ordered POSIX paths interpreted by that same
backend. ChemGraph passes them to Deep Agents without scanning any implicit
user or project locations. Each source contains skill directories with a
required SKILL.md; later sources override earlier sources with the same
skill name. With StateBackend, callers invoking the graph directly must seed
the corresponding files in graph state before the skills can load.
The default approval policy interrupts before shell commands and file
mutations. Without a human_input_handler, run() raises
HumanInputRequired; its payload retains the structured Deep Agents action
requests and must be resumed with matching structured decisions. Its
interrupts tuple retains every pending request and its LangGraph interrupt
ID; callers must resume concurrent requests with an exact mapping from those
IDs to responses. question and payload continue to describe the first
request for compatibility. A configured handler may use the legacy
handler(question) signature or handler(question, payload) when it needs the
raw structured request; both synchronous and asynchronous handlers are
supported. Setting
deepagent_auto_approve=True removes this boundary and should be limited to an
externally isolated, explicitly trusted workspace.
The same constructor can be composed as a worker:
from chemgraph.graphs.deep_agent import construct_deep_agent_graph
from chemgraph.registry import AgentRegistry
standalone_graph = construct_deep_agent_graph(model, backend=backend)
worker = AgentRegistry().as_subagent(
"deepagent",
llm=model,
backend=backend,
skills=["/workspace/.agents/skills/"],
)
as_subagent() compiles the graph with checkpointer=None so it inherits its
parent checkpoint. The registry returns the canonical worker name deep_agent,
even when requested through the deepagent alias; use worker["name"] when
composing task calls. construct_main_agent_graph(enable_deepagent=True, ...)
uses this same workflow under the stable subagent name deepagent.
Caller-owned asynchronous checkpointers, including AsyncSqliteSaver, are
supported by await agent.run(...) and await agent.apersist_run_state(config).
Keep the saver open on the same event loop for the run and any resumes. The
synchronous state methods remain available for synchronous checkpointers.
Custom tools¶
ChemGraph can be extended with compatible LangChain tools. Keep tools narrow,
validate their inputs, and avoid exposing destructive filesystem or shell
operations to untrusted prompts. Optional dependencies in application code
should be imported lazily so a core installation can still load.
Human supervision¶
Supported workflows can pause for human input when supervision is enabled. Design non-interactive applications so they do not unexpectedly wait forever, and treat an approval boundary as part of the application's security model.
Artifacts¶
Set CHEMGRAPH_LOG_DIR before constructing the agent to choose the parent
directory for session artifacts:
API stability¶
ChemGraph is evolving and does not currently re-export ChemGraph from the
package root. Prefer the documented module import, pin a version for deployed
applications, and check release notes before upgrading.