Skip to content

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:

chemgraph run --interactive --workflow main_agent

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:

import os

os.environ["CHEMGRAPH_LOG_DIR"] = "/absolute/path/to/runs"

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.