Re-implementation of deepagents using Google ADK primitives
Project description
adk-deepagents
Re-implementation of deepagents using Google ADK primitives.
Build autonomous, tool-using AI agents with filesystem access, shell execution, sub-agent delegation, conversation summarization, persistent memory, and skills integration — all powered by Google's Agent Development Kit.
Features
- Filesystem tools —
ls,read_file,write_file,edit_file,glob,grepbacked by pluggable storage - Shell execution — Local subprocess or sandboxed execution via Heimdall MCP
- Browser automation — Navigate websites, fill forms, extract data via @playwright/mcp or agent-browser CLI skill
- Sub-agent delegation — Spawn child agents for isolated, parallelizable sub-tasks
- Conversation summarization — Automatic context window management for long-running sessions
- Persistent memory — Load
AGENTS.mdfiles into the system prompt across sessions - Todo tracking — Built-in
write_todos/read_todostools for task management - Human-in-the-loop — Interrupt specific tools to require human approval before execution
- Pluggable backends —
StateBackend(in-memory),FilesystemBackend(local disk),CompositeBackend(path-based routing) - Skills integration — Optional integration with adk-skills-agent
Installation
Requires Python 3.11+.
uv pip install adk-deepagents
Or add it to a project with uv:
uv add adk-deepagents
Optional dependencies
# For skills integration
uv pip install "adk-deepagents[skills]"
# For Heimdall MCP sandboxed execution
uv pip install "google-adk[mcp]"
npm i -g @heimdall-ai/heimdall
# For browser automation via Playwright MCP
uv pip install "adk-deepagents[browser]"
# For Temporal-backed dynamic task delegation
uv pip install "adk-deepagents[temporal]"
CLI Quickstart (adk-deepagents)
The package installs an adk-deepagents CLI for interactive and non-interactive workflows.
# Interactive REPL (default mode)
adk-deepagents
# Interactive REPL with an auto-submitted first prompt
adk-deepagents -m "Summarize this repository"
# One-shot non-interactive run
adk-deepagents -n "Run tests and summarize failures"
# Piped stdin non-interactive run (automation-friendly output)
printf 'Summarize README.md\n' | adk-deepagents -q
For the full command/flag reference, see docs/cli.md.
Python Quickstart
from adk_deepagents import create_deep_agent
# Create an agent with default settings:
# - Gemini 2.5 Flash model
# - Filesystem tools (ls, read, write, edit, glob, grep)
# - Todo tools (write_todos, read_todos)
# - StateBackend (in-memory file storage)
agent = create_deep_agent(
name="my_agent",
instruction="You are a helpful coding assistant.",
)
Running interactively
import asyncio
from google.adk.runners import InMemoryRunner
async def main():
runner = InMemoryRunner(agent=agent, app_name="demo")
session = await runner.session_service.create_session(
app_name="demo", user_id="user",
)
async for event in runner.run_async(
session_id=session.id,
user_id="user",
new_message="List the files in /",
):
if event.content and event.content.parts:
for part in event.content.parts:
if hasattr(part, "text") and part.text:
print(part.text)
asyncio.run(main())
Using with ADK CLI
Create an agent.py in a directory with a top-level root_agent:
# my_project/agent.py
from adk_deepagents import create_deep_agent
root_agent = create_deep_agent(
name="my_agent",
instruction="You are a helpful assistant.",
)
Then run:
uv run adk run my_project/
API Reference
create_deep_agent()
The main synchronous factory function. Returns a configured google.adk.agents.LlmAgent.
from adk_deepagents import create_deep_agent
agent = create_deep_agent(
model="gemini-2.5-flash", # LLM model string
tools=None, # Additional tool functions
instruction=None, # Custom system instruction
subagents=None, # Sub-agent specifications
skills=None, # Skill directory paths
skills_config=None, # SkillsConfig for adk-skills
memory=None, # AGENTS.md file paths to load
output_schema=None, # Pydantic BaseModel for structured output
backend=None, # Backend instance or factory
execution=None, # "local", "heimdall", or MCP config dict
browser=None, # "playwright" or BrowserConfig
summarization=None, # SummarizationConfig
delegation_mode="static", # "static", "dynamic", or "both"
dynamic_task_config=None, # DynamicTaskConfig (includes optional Temporal backend)
interrupt_on=None, # Tool names requiring approval
name="deep_agent", # Agent name
)
create_deep_agent_async()
Async variant that resolves MCP tools before creating the agent. Required for execution="heimdall", dict-based MCP configs, or browser="playwright".
from adk_deepagents import create_deep_agent_async
agent, cleanup = await create_deep_agent_async(
execution="heimdall",
# ... same parameters as create_deep_agent()
)
# When done:
if cleanup:
await cleanup()
# Browser automation
from adk_deepagents import BrowserConfig, create_deep_agent_async
agent, cleanup = await create_deep_agent_async(
browser="playwright", # or BrowserConfig(headless=False)
)
# When done:
if cleanup:
await cleanup()
Returns (LlmAgent, cleanup_fn | None).
Configuration
Backends
Backends control how the agent reads and writes files.
StateBackend (default)
In-memory file storage backed by the ADK session state dict. Files persist for the duration of the session.
agent = create_deep_agent() # Uses StateBackend by default
FilesystemBackend
Reads and writes to the local filesystem.
from adk_deepagents.backends.filesystem import FilesystemBackend
agent = create_deep_agent(
backend=FilesystemBackend(root_dir="/path/to/project"),
)
CompositeBackend
Routes file operations to different backends based on path prefixes. Longer prefixes take priority.
from adk_deepagents.backends import StateBackend, CompositeBackend
from adk_deepagents.backends.filesystem import FilesystemBackend
def my_backend_factory(state):
return CompositeBackend(
default=StateBackend(state),
routes={
"/workspace": FilesystemBackend(root_dir="./workspace"),
},
)
agent = create_deep_agent(backend=my_backend_factory)
You can also pass a BackendFactory — a callable (state: dict) -> Backend — for deferred construction from session state.
Execution
Local (subprocess)
Runs shell commands directly on the host. Suitable for development and testing.
agent = create_deep_agent(execution="local")
Heimdall MCP (sandboxed)
Sandboxed Python (Pyodide/WASM) and Bash execution via the Heimdall MCP server.
agent, cleanup = await create_deep_agent_async(execution="heimdall")
Or with custom MCP server config:
agent, cleanup = await create_deep_agent_async(
execution={
"command": "npx",
"args": ["@heimdall-ai/heimdall"],
"env": {"HEIMDALL_WORKSPACE": "/workspace"},
},
)
# SSE transport
agent, cleanup = await create_deep_agent_async(
execution={"uri": "http://localhost:8080"},
)
Sub-agents
Delegate isolated sub-tasks to child agents. A general-purpose sub-agent is always included by default.
from adk_deepagents import create_deep_agent, SubAgentSpec
agent = create_deep_agent(
subagents=[
SubAgentSpec(
name="researcher",
description="Searches the codebase for relevant files and patterns.",
system_prompt="You are a code research assistant.",
),
SubAgentSpec(
name="writer",
description="Writes and edits code files.",
model="gemini-2.5-pro",
),
],
)
By default (delegation_mode="static"), each sub-agent is exposed as its own tool
(researcher, writer, etc.) and the parent delegates by calling those tools.
Dynamic Task Delegation
Use delegation_mode="dynamic" to expose a single task tool that routes work
to sub-agents at runtime (LangChain deepagents-style). The tool supports task_id
to continue the same delegated sub-session across turns.
DynamicTaskConfig also lets you enforce runtime guardrails like max_depth
(recursive delegation depth) and max_parallel (simultaneous running tasks).
from adk_deepagents import DynamicTaskConfig, SubAgentSpec, create_deep_agent
agent = create_deep_agent(
subagents=[
SubAgentSpec(name="explore", description="Searches files and code patterns."),
SubAgentSpec(name="coder", description="Writes and edits files."),
],
delegation_mode="dynamic",
dynamic_task_config=DynamicTaskConfig(
timeout_seconds=90,
allow_model_override=False,
),
)
Use delegation_mode="both" to keep static sub-agent tools and add the dynamic
task tool side by side.
Temporal-backed dynamic tasks
To run delegated task() turns on Temporal workers instead of in-process
sessions, set DynamicTaskConfig.temporal:
from adk_deepagents import create_deep_agent
from adk_deepagents.types import DynamicTaskConfig, TemporalTaskConfig
agent = create_deep_agent(
delegation_mode="dynamic",
dynamic_task_config=DynamicTaskConfig(
temporal=TemporalTaskConfig(
target_host="127.0.0.1:7233",
namespace="default",
task_queue="adk-deepagents-tasks",
)
),
)
See docs/temporal.md for worker setup, devenv services,
and integration test instructions.
Summarization
Automatic context window management. When the conversation exceeds a configurable fraction of the context window, older messages are replaced with a condensed summary.
from adk_deepagents import create_deep_agent, SummarizationConfig
agent = create_deep_agent(
summarization=SummarizationConfig(
model="gemini-2.5-flash",
trigger=("fraction", 0.85), # Trigger at 85% of context window
keep=("messages", 6), # Keep 6 most recent messages
history_path_prefix="/conversation_history",
),
)
Offloaded conversation history is saved to the backend at the configured path prefix for later reference.
Memory
Load persistent AGENTS.md files into the agent's system prompt. Memory is loaded once on the first agent invocation and cached in session state.
agent = create_deep_agent(
memory=["/AGENTS.md", "/docs/CONTEXT.md"],
)
Memory files should contain project context, role descriptions, coding conventions, or other persistent knowledge the agent should always have access to.
Human-in-the-loop
Require human approval before specific tools execute. When a tool is interrupted, its invocation is stored in session state under _pending_approval.
agent = create_deep_agent(
interrupt_on={
"write_file": True,
"execute": True,
"read_file": False, # Explicitly allow (no interruption)
},
)
Structured output
Use a Pydantic BaseModel subclass to constrain the agent's final output format.
from pydantic import BaseModel
class AnalysisResult(BaseModel):
summary: str
issues: list[str]
confidence: float
agent = create_deep_agent(
output_schema=AnalysisResult,
instruction="Analyze the given code and return structured results.",
)
Built-in Tools
Every agent created with create_deep_agent() includes these tools:
| Tool | Description |
|---|---|
ls |
List files and directories at a path |
read_file |
Read file contents with optional pagination |
write_file |
Create a new file (no overwrites) |
edit_file |
Edit a file via string replacement |
glob |
Find files matching a glob pattern |
grep |
Search for text patterns within files |
write_todos |
Create or update a todo list |
read_todos |
Read the current todo list |
With execution="local" or execution="heimdall", an execute tool is also available for shell commands.
With summarization=SummarizationConfig(...), a compact_conversation tool is added for
manual context compaction on the next model turn.
With browser="playwright", browser tools (browser_navigate, browser_snapshot, browser_click, browser_type, etc.) are added for web page interaction.
With subagents=[...] and delegation_mode="static" (default), one tool is generated per sub-agent specification.
With delegation_mode="dynamic" or "both", a single task tool is added for runtime delegation.
Project Structure
adk_deepagents/
├── __init__.py # Public API exports
├── graph.py # create_deep_agent() and create_deep_agent_async()
├── types.py # SubAgentSpec, SummarizationConfig, SkillsConfig, BrowserConfig
├── prompts.py # System prompt templates
├── memory.py # AGENTS.md loading and formatting
├── summarization.py # Context window management
├── backends/
│ ├── protocol.py # Backend ABC and data types
│ ├── state.py # StateBackend (in-memory)
│ ├── filesystem.py # FilesystemBackend (local disk)
│ ├── composite.py # CompositeBackend (path-based routing)
│ └── utils.py # Shared utilities
├── callbacks/
│ ├── before_agent.py # Memory loading on first invocation
│ ├── before_model.py # Prompt injection and summarization
│ ├── before_tool.py # Human-in-the-loop interrupts
│ └── after_tool.py # Post-tool processing and eviction
├── execution/
│ ├── local.py # Local subprocess execution
│ ├── heimdall.py # Heimdall MCP integration
│ └── bridge.py # Skills-to-Heimdall script execution bridge
├── browser/
│ ├── __init__.py # Browser module exports
│ ├── playwright_mcp.py # Playwright MCP integration
│ └── prompts.py # Browser agent system prompts
├── skills/
│ └── integration.py # adk-skills registry integration
├── temporal/
│ ├── client.py # Temporal workflow dispatch client
│ ├── workflows.py # Dynamic task workflow definition
│ ├── activities.py # Dynamic task activity implementation
│ └── worker.py # Temporal worker factory
└── tools/
├── compact.py # Manual conversation compaction tool
├── filesystem.py # Filesystem tool implementations
├── todos.py # Todo tool implementations
└── task.py # Sub-agent delegation tools
Development
Setup
git clone https://github.com/anthropics/adk-deepagents.git
cd adk-deepagents
uv sync
Commands
# Run all tests
uv run pytest
# Run a specific test file
uv run pytest tests/unit_tests/test_summarization.py
# Lint
uv run ruff check .
# Format
uv run ruff format .
# Type check
uv run ty check
Testing
Tests use pytest with pytest-asyncio (asyncio_mode = "auto"). Unit tests are in tests/unit_tests/, integration tests in tests/integration_tests/.
# Run with verbose output
uv run pytest -v
# Run only unit tests
uv run pytest tests/unit_tests/
# Run tests matching a pattern
uv run pytest -k "test_summarization"
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file adk_deepagents-0.1.0.tar.gz.
File metadata
- Download URL: adk_deepagents-0.1.0.tar.gz
- Upload date:
- Size: 566.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe4de58a402bd70ce4553d8c9078d5ed283b97e1a9f3c475a0227503c7ec48ba
|
|
| MD5 |
040ec98497dd5f10d7d32ba848060976
|
|
| BLAKE2b-256 |
e6b7bd3664e81cde76b4b3d2fe16c7a3bb6579b7d0c96e7b138eadd1200133d8
|
Provenance
The following attestation bundles were made for adk_deepagents-0.1.0.tar.gz:
Publisher:
publish.yml on manojlds/adk-deepagents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adk_deepagents-0.1.0.tar.gz -
Subject digest:
fe4de58a402bd70ce4553d8c9078d5ed283b97e1a9f3c475a0227503c7ec48ba - Sigstore transparency entry: 1152963377
- Sigstore integration time:
-
Permalink:
manojlds/adk-deepagents@782cf3964f16755c375e1fad8346b9bbc8f4d967 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/manojlds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@782cf3964f16755c375e1fad8346b9bbc8f4d967 -
Trigger Event:
release
-
Statement type:
File details
Details for the file adk_deepagents-0.1.0-py3-none-any.whl.
File metadata
- Download URL: adk_deepagents-0.1.0-py3-none-any.whl
- Upload date:
- Size: 162.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1461bca2f9d2dcd9d7c135214df3437f4fe43775a88366307b8979be4727ebcc
|
|
| MD5 |
2d722b8d86855cb2a4f8976c2c617403
|
|
| BLAKE2b-256 |
b7347f5de1392b4b44aa70b050c0066c41e59e0c8031e81ba70e7fc8f504481f
|
Provenance
The following attestation bundles were made for adk_deepagents-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on manojlds/adk-deepagents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
adk_deepagents-0.1.0-py3-none-any.whl -
Subject digest:
1461bca2f9d2dcd9d7c135214df3437f4fe43775a88366307b8979be4727ebcc - Sigstore transparency entry: 1152963436
- Sigstore integration time:
-
Permalink:
manojlds/adk-deepagents@782cf3964f16755c375e1fad8346b9bbc8f4d967 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/manojlds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@782cf3964f16755c375e1fad8346b9bbc8f4d967 -
Trigger Event:
release
-
Statement type: