How to Migrate Agent Logic from the DeepAgents SDK to the CLI for Interactive Development

To migrate from the SDK to the CLI, replace deepagents.graph.create_deep_agent with deepagents_cli.agent.create_cli_agent, which automatically wires the full middleware stack, generates interactive system prompts, and configures the Textual UI while preserving all SDK arguments.

The DeepAgents framework by LangChain provides a Python SDK for building agent graphs and a dedicated CLI for interactive development. When you need to transition from programmatic SDK usage to a terminal-based workflow with real-time streaming, human-in-the-loop approvals, and built-in memory, you must migrate your agent construction logic to use CLI-specific wrappers. This guide demonstrates the exact migration path using actual source implementations from the langchain-ai/deepagents repository.

Why Use create_cli_agent Instead of create_deep_agent

When you migrate agent logic from the SDK to the CLI, you shift from manual graph assembly to an opinionated wrapper that handles the full interactive stack. The core difference lies in how middleware, system prompts, and UI components are assembled.

create_deep_agent (SDK) requires you to manually inject every middleware component and craft your own system prompt. You must separately handle token tracking, sandbox routing, and checkpoint persistence.

create_cli_agent (CLI) wraps the SDK function while automatically injecting the complete middleware stack—including AskUserMiddleware, MemoryMiddleware, SkillsMiddleware, and SummarizationToolMiddleware—plus UI-specific hooks for SpinnerStatus and token statistics. It generates an interactive system prompt from system_prompt.md and handles local versus remote sandbox selection.

According to the source code in libs/cli/deepagents_cli/agent.py (lines 641–720), create_cli_agent accepts all SDK arguments but adds optional CLI-specific parameters like interactive, auto_approve, and enable_memory, making it future-proof against SDK updates.

Step-by-Step Migration Guide

1. Identify Your Current SDK Implementation

Locate your existing SDK entry point. A typical SDK-based agent looks like this:

from deepagents.graph import create_deep_agent

agent = create_deep_agent(
    model="gpt-4o-mini",
    tools=[my_tool],
    middleware=[my_middleware],
    system_prompt="You are a data-analysis bot...",
)

Source: libs/deepagents/deepagents/graph.py at line 82.

2. Replace the Import Statement

Change your import to use the CLI wrapper:

from deepagents_cli.agent import create_cli_agent

3. Migrate Core Arguments

Pass the same model, tools, and optional system_prompt to create_cli_agent. You should generally remove SDK-specific middleware that the CLI automatically provides—such as AskUserMiddleware, MemoryMiddleware, SkillsMiddleware, and SummarizationToolMiddleware—unless you require custom implementations.

agent_graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="my-assistant",
    tools=[my_tool],
    middleware=[my_custom_middleware],  # Only if you have custom middleware not in CLI defaults

)

4. Configure CLI-Specific Options

Set optional flags to control the interactive behavior:

  • interactive=False – Enables headless mode without human-in-the-loop instructions.
  • auto_approve=True – Skips the approval UI, useful for CI pipelines.
  • sandbox_type – Set to "modal", "runloop", or None for local filesystem.
  • enable_memory=False or enable_skills=False – Disable specific CLI features if not needed.
  • cwd=Path("my/project") – Override the working directory shown in the system prompt.
  • checkpointer=MyCheckpointSaver – Inject a custom checkpoint saver as with the SDK.
agent_graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="my-assistant",
    tools=[my_tool],
    sandbox_type="modal",
    interactive=True,
    auto_approve=False,
    enable_memory=True,
    enable_skills=True,
    cwd=Path.cwd(),
)

5. Execute the Graph

The CLI returns a LangGraph Pregel instance. For interactive use, wrap it with TextualUIAdapter:

from deepagents_cli.textual_adapter import TextualUIAdapter

ui_adapter = TextualUIAdapter(agent_graph, backend)
ui_adapter.run()  # Blocks until TUI exits

For headless execution, invoke the graph directly:

from langgraph.checkpoint.memory import MemorySaver

checkpoint = MemorySaver()
config = {"configurable": {"thread_id": "demo"}}
result = await agent_graph.ainvoke(
    {"messages": [{"role": "user", "content": "Explain recursion"}]},
    config=config,
    checkpoint=checkpoint,
)

6. Leverage Configuration Files

The CLI reads from deepagents/config.toml or ~/.deepagents/config.toml for model specifications. You can use create_model from deepagents_cli.config to respect environment variables:

from deepagents_cli.config import create_model

model = create_model("gpt-4o-mini")  # Respects env vars and config files

7. Persist Customizations

The CLI automatically creates AGENTS.md in the assistant’s directory (e.g., ~/.deepagents/<assistant_id>/AGENTS.md). Add custom system prompt sections and skill aliases here; the CLI reloads these on every start. This persistence logic is implemented in libs/cli/deepagents_cli/agent.py (lines 21–27).

Practical Code Examples

Minimal Interactive CLI Agent

This example demonstrates the most basic migration path for launching the Textual TUI:

from deepagents_cli.agent import create_cli_agent
from deepagents_cli.textual_adapter import TextualUIAdapter

# Build graph and backend with full CLI middleware

graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="research-bot",
    tools=[],  # Add custom tools here

)

# Launch interactive terminal UI

ui = TextualUIAdapter(graph, backend)
ui.run()

Headless CI Agent

For automated testing without UI interaction:

from deepagents_cli.agent import create_cli_agent
from langgraph.checkpoint.memory import MemorySaver
import asyncio

graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="ci-bot",
    interactive=False,  # Disables human-in-the-loop wording

    auto_approve=True,  # Skips approval UI

)

checkpoint = MemorySaver()
config = {"configurable": {"thread_id": "ci-run"}}

async def run_one_turn():
    result = await graph.ainvoke(
        {"messages": [{"role": "user", "content": "Summarize the latest LangChain release notes"}]},
        config=config,
        checkpoint=checkpoint,
    )
    print(result["messages"][-1].content)

asyncio.run(run_one_turn())

Custom Middleware with CLI Defaults

Add your own middleware while retaining the CLI's default stack:

from deepagents_cli.agent import create_cli_agent
from deepagents.middleware import MyAnalyticsMiddleware

graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="analytics-bot",
    middleware=[MyAnalyticsMiddleware()],  # CLI still adds its own stack

)

Remote Sandbox Configuration

Using Modal as a remote sandbox backend:

from deepagents_cli.agent import create_cli_agent
from deepagents.backends.modal import ModalBackend

remote_backend = ModalBackend(
    modal_image="ghcr.io/langchain-ai/deepagents:latest",
    env={"OPENAI_API_KEY": "..."},
)

graph, backend = create_cli_agent(
    model="gpt-4o-mini",
    assistant_id="modal-bot",
    sandbox=remote_backend,
    sandbox_type="modal",
)

The CLI automatically routes large tool results through dedicated routes like /large_tool_results/ and /conversation_history/ when using remote sandboxes.

Key Source Files Reference

Understanding these files ensures you can debug migration issues by referencing the actual implementation:

File Purpose
libs/deepagents/deepagents/graph.py Core SDK function create_deep_agent that assembles the LangGraph Pregel graph.
libs/cli/deepagents_cli/agent.py CLI wrapper create_cli_agent—builds middleware stack, selects backend, generates system prompt, and calls create_deep_agent.
libs/cli/deepagents_cli/system_prompt.md Template for interactive system prompts containing {mode_description}, {model_identity_section}, and {interactive_preamble} variables.
libs/cli/deepagents_cli/textual_adapter.py Bridges the Pregel graph to the Textual UI, handling token statistics, spinners, and rendering.
libs/cli/deepagents_cli/config.py Settings loader for deepagents/config.toml, model detection, and environment handling.

Summary

  • create_cli_agent wraps create_deep_agent while injecting CLI-specific middleware, system prompts, and UI hooks.
  • Remove SDK-only middleware (like AskUserMiddleware and MemoryMiddleware) when migrating unless you need custom behavior, as the CLI adds these automatically.
  • The assistant_id parameter is required for CLI persistence and directory creation under ~/.deepagents/<assistant_id>/.
  • Set interactive=False and auto_approve=True for headless CI usage, or keep defaults for the full Textual TUI experience.
  • The CLI handles sandbox routing, token tracking, and checkpoint configuration while remaining compatible with all SDK arguments for future-proofing.

Frequently Asked Questions

Can I use custom middleware with the CLI wrapper?

Yes. Pass a list of custom middleware to the middleware parameter in create_cli_agent. The function appends your custom middleware to the CLI's default stack, so you retain features like memory and skills while adding your own analytics or logging layers.

Do I need to rewrite my existing SDK tests after migration?

No. Existing unit tests continue to work because create_cli_agent forwards all SDK arguments to the underlying create_deep_agent function. For CLI-specific behavior—such as approval flows or UI rendering—add new tests under libs/cli/tests/ that patch functions like deepagents_cli.agent.get_system_prompt.

How does the CLI handle system prompts differently from the SDK?

The SDK requires you to manually provide a system_prompt string. The CLI generates one automatically from system_prompt.md, injecting dynamic variables like working directory, model identity, and skills path. You can override this by passing your own system_prompt argument or by editing the generated AGENTS.md file in the assistant's directory.

What is the difference between local and remote sandbox configuration?

When sandbox_type is None (default), the CLI uses the local filesystem. When set to "modal" or other remote providers, the CLI instantiates the specified backend (e.g., ModalBackend) and automatically routes large tool results and conversation history through dedicated API endpoints to avoid size limitations.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →