Skip to content

Commit 711dd4e

Browse files
committed
Add LangGraph adapter with tests for export functionality
- Implemented and functions in to convert agent configurations into LangGraph Python code. - Created a comprehensive test suite in to validate the output of the export functions, ensuring correct handling of agent metadata, skills, tools, skillflows, and hooks. - Added helper functions for YAML rendering and agent directory structure creation to facilitate testing. - Ensured compatibility with existing agent structures by supporting both and directories.
1 parent 085954b commit 711dd4e

24 files changed

Lines changed: 1811 additions & 2 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ Adapters are used by both `export` and `run`. Available adapters:
367367
| `openclaw` | OpenClaw format |
368368
| `nanobot` | Nanobot format |
369369
| `cursor` | Cursor `.cursor/rules/*.mdc` files |
370+
| `langgraph` | LangGraph `StateGraph` Python module (skills → nodes, skillflows → edges) |
371+
| `deepagents` | LangChain DeepAgents harness (`create_deep_agent(...)`) — skills, tools, sub-agents |
370372

371373
```bash
372374
# Export to system prompt

examples/deepagents/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# DeepAgents example
2+
3+
A research agent with a fact-checker sub-agent, demonstrating the DeepAgents adapter:
4+
5+
- `agent.yaml` — manifest (model, skills, tools, sub-agent declaration)
6+
- `SOUL.md` — agent identity, embedded in the generated `system_prompt`
7+
- `skills/web-research/`, `skills/summarize/` — passed via `skills=["./skills"]`; DeepAgents loads each `SKILL.md` natively
8+
- `tools/web-search.yaml` — emitted as a `@tool` function bound into `tools=[...]`
9+
- `agents/fact-checker/` — emitted as a `SubAgent` dict in `subagents=[...]`
10+
- `expected_output.py` — the Python module the adapter produces
11+
12+
DeepAgents is a higher-level harness on top of LangGraph — there is no graph
13+
wiring: the model decides when to plan, when to delegate to sub-agents, and
14+
when to call tools. If you need explicit per-step edges, use the `langgraph`
15+
adapter instead.
16+
17+
## Regenerate
18+
19+
```bash
20+
gapman export --dir examples/deepagents --format deepagents --output examples/deepagents/expected_output.py
21+
```
22+
23+
## Run the generated agent
24+
25+
```bash
26+
pip install deepagents langchain-anthropic
27+
python examples/deepagents/expected_output.py
28+
```
29+
30+
The generated file leaves tool implementations as `NotImplementedError` stubs — replace them with your own logic before invoking.

examples/deepagents/SOUL.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Research Assistant
2+
3+
You are a research assistant. Find authoritative sources, extract the relevant
4+
facts, and summarize them honestly. Delegate to the `fact-checker` sub-agent
5+
whenever a claim warrants independent verification. Cite every claim.

examples/deepagents/agent.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
spec_version: "0.1.0"
2+
name: research-assistant
3+
version: 1.0.0
4+
description: Research assistant with a fact-checker sub-agent
5+
author: gitagent-examples
6+
license: MIT
7+
model:
8+
preferred: anthropic:claude-sonnet-4-5
9+
skills:
10+
- web-research
11+
- summarize
12+
tools:
13+
- web-search
14+
agents:
15+
fact-checker:
16+
description: Verifies factual claims against authoritative sources
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Fact-Checker
2+
3+
You are a pedantic fact-checker. Treat every claim as unverified until you
4+
locate a primary source. If a claim cannot be substantiated, say so plainly.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
spec_version: "0.1.0"
2+
name: fact-checker
3+
version: 1.0.0
4+
description: Verifies factual claims against authoritative sources
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""
2+
DeepAgents definition for research-assistant v1.0.0
3+
Generated by gitagent export --format deepagents
4+
"""
5+
6+
from __future__ import annotations
7+
8+
from deepagents import create_deep_agent
9+
from langchain_core.tools import tool
10+
11+
# Agent metadata
12+
AGENT_NAME = "research-assistant"
13+
AGENT_VERSION = "1.0.0"
14+
MODEL = "anthropic:claude-sonnet-4-5"
15+
16+
# System prompt (SOUL.md + RULES.md + DUTIES.md + compliance)
17+
SYSTEM_PROMPT = """# research-assistant
18+
Research assistant with a fact-checker sub-agent
19+
20+
# Research Assistant
21+
22+
You are a research assistant. Find authoritative sources, extract the relevant
23+
facts, and summarize them honestly. Delegate to the `fact-checker` sub-agent
24+
whenever a claim warrants independent verification. Cite every claim.
25+
"""
26+
27+
# Hooks (pre_tool_use scripts run before every tool call)
28+
def _run_pre_tool_use_hooks(tool_name: str) -> None:
29+
"""No pre_tool_use hooks configured in hooks/hooks.yaml."""
30+
return None
31+
32+
# NOTE: other hook events (post_tool_use, on_session_start, etc.) have no
33+
# DeepAgents equivalent and are intentionally skipped.
34+
# NOTE: memory/ has no direct DeepAgents equivalent — wire a checkpointer if needed.
35+
36+
# Tools (from tools/*.yaml)
37+
@tool
38+
def web_search(query: str) -> str:
39+
"""Search the public web for a query"""
40+
_run_pre_tool_use_hooks("web-search")
41+
raise NotImplementedError("Implement tool: web-search")
42+
43+
TOOLS = [web_search]
44+
45+
# Skills (skills/<name>/SKILL.md — DeepAgents loads these natively)
46+
# Pointing skills= at the directory lets DeepAgents discover every SKILL.md
47+
# without us having to inline the skill content into SYSTEM_PROMPT.
48+
SKILLS = ["./skills"]
49+
50+
# For reference, the skills available in this agent:
51+
# - summarize: Condense the gathered sources into a faithful, cited summary
52+
# - web-research: Search the web for sources relevant to the user's question
53+
54+
# Sub-agents (agents/<name>/ → SubAgent dicts)
55+
fact_checker_subagent = {
56+
"name": "fact-checker",
57+
"description": "Verifies factual claims against authoritative sources",
58+
"system_prompt": """# fact-checker
59+
Verifies factual claims against authoritative sources
60+
61+
# Fact-Checker
62+
63+
You are a pedantic fact-checker. Treat every claim as unverified until you
64+
locate a primary source. If a claim cannot be substantiated, say so plainly.
65+
""",
66+
"tools": TOOLS,
67+
}
68+
69+
SUBAGENTS = [fact_checker_subagent]
70+
71+
# Agent
72+
agent = create_deep_agent(
73+
model=MODEL,
74+
system_prompt=SYSTEM_PROMPT,
75+
tools=TOOLS,
76+
skills=SKILLS,
77+
subagents=SUBAGENTS,
78+
)
79+
80+
if __name__ == "__main__":
81+
result = agent.invoke({"messages": [{"role": "user", "content": "Hello"}]})
82+
for message in result["messages"]:
83+
print(message)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: summarize
3+
description: Condense the gathered sources into a faithful, cited summary
4+
---
5+
6+
Produce a concise summary of the gathered material. Every factual claim must
7+
be attributed to a specific source URL. If sources disagree, surface the
8+
disagreement explicitly.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: web-research
3+
description: Search the web for sources relevant to the user's question
4+
allowed-tools: web-search
5+
---
6+
7+
Use the `web-search` tool to find authoritative sources. Capture the URL of
8+
every source consulted; downstream skills will cite them.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: web-search
2+
description: Search the public web for a query
3+
input_schema:
4+
type: object
5+
properties:
6+
query:
7+
type: string
8+
description: The search query
9+
required:
10+
- query

0 commit comments

Comments
 (0)