Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ Add your adapter to the switch statement that dispatches on `-a <adapter>`.

If your framework has a config file format, add an exporter in `commands/export.ts` or `src/adapters/`.

If your example directory commits an `expected_output.py` (or similar) snapshot, regenerate it whenever you change the adapter so it does not drift:

```bash
opengap export --dir examples/<name> --format <name> --output examples/<name>/expected_output.py
```

### 4. Document what's lossy

Every adapter loses something — that's expected. Please document it clearly:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ Adapters are used by both `export` and `run`. Available adapters:
| `codex` | OpenAI Codex CLI instructions (export only) |
| `kiro` | Kiro agent format (export only) |
| `gitclaw` | GitClaw agent format |
| `deepagents` | LangChain DeepAgents harness (`create_deep_agent(...)`) — skills, tools, sub-agents |

```bash
# Export to system prompt
Expand Down
37 changes: 37 additions & 0 deletions examples/deepagents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# DeepAgents example

A research agent with a fact-checker sub-agent, demonstrating the DeepAgents adapter:

- `agent.yaml` — manifest (model, skills, tools, sub-agent declaration)
- `SOUL.md` — agent identity, embedded in the generated `system_prompt`
- `skills/web-research/`, `skills/summarize/` — passed via a `skills=` path resolved next to the generated module (`Path(__file__).parent / "skills"`), so discovery works from any working directory; DeepAgents loads each `SKILL.md` natively
- `tools/web-search.yaml` — emitted as a `@tool` function bound into `tools=[...]`
- `agents/fact-checker/` — emitted as a `SubAgent` dict in `subagents=[...]`. By default a sub-agent inherits the full parent `TOOLS` list; add a `tools:` list to the sub-agent's own `agent.yaml` to narrow it to a subset.
- `expected_output.py` — the Python module the adapter produces

DeepAgents is a filesystem-shaped harness — there is no graph wiring. The
agent directory maps straight onto `create_deep_agent(...)`, and the model
decides at runtime when to plan, when to delegate to sub-agents, and when to
call tools. Nothing here needs a step graph, which is why this is the only
LangChain-family adapter opengap ships.

## Regenerate

```bash
opengap export --dir examples/deepagents --format deepagents --output examples/deepagents/expected_output.py
```

## Run the generated agent

```bash
pip install deepagents langchain-anthropic
python examples/deepagents/expected_output.py
```

Or let gitagent generate and run it for you (pass an initial message with `-p`, read from `GITAGENT_PROMPT`):

```bash
opengap run --dir examples/deepagents --adapter deepagents -p "Who won the 2022 World Cup?"
```

The generated file leaves tool implementations as `NotImplementedError` stubs — replace them with your own logic before invoking.
5 changes: 5 additions & 0 deletions examples/deepagents/SOUL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Research Assistant

You are a research assistant. Find authoritative sources, extract the relevant
facts, and summarize them honestly. Delegate to the `fact-checker` sub-agent
whenever a claim warrants independent verification. Cite every claim.
16 changes: 16 additions & 0 deletions examples/deepagents/agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
spec_version: "0.1.0"
name: research-assistant
version: 1.0.0
description: Research assistant with a fact-checker sub-agent
author: gitagent-examples
license: MIT
model:
preferred: anthropic:claude-sonnet-4-5
skills:
- web-research
- summarize
tools:
- web-search
agents:
fact-checker:
description: Verifies factual claims against authoritative sources
4 changes: 4 additions & 0 deletions examples/deepagents/agents/fact-checker/SOUL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Fact-Checker

You are a pedantic fact-checker. Treat every claim as unverified until you
locate a primary source. If a claim cannot be substantiated, say so plainly.
4 changes: 4 additions & 0 deletions examples/deepagents/agents/fact-checker/agent.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
spec_version: "0.1.0"
name: fact-checker
version: 1.0.0
description: Verifies factual claims against authoritative sources
87 changes: 87 additions & 0 deletions examples/deepagents/expected_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
DeepAgents definition for research-assistant v1.0.0
Generated by gitagent export --format deepagents
"""

from __future__ import annotations

from deepagents import create_deep_agent
from langchain_core.tools import tool
from pathlib import Path

# Agent metadata
AGENT_NAME = "research-assistant"
AGENT_VERSION = "1.0.0"
MODEL = "anthropic:claude-sonnet-4-5"

# System prompt (SOUL.md + RULES.md + DUTIES.md + compliance)
SYSTEM_PROMPT = """# research-assistant
Research assistant with a fact-checker sub-agent

# Research Assistant

You are a research assistant. Find authoritative sources, extract the relevant
facts, and summarize them honestly. Delegate to the `fact-checker` sub-agent
whenever a claim warrants independent verification. Cite every claim.
"""

# Hooks (pre_tool_use scripts run before every tool call)
def _run_pre_tool_use_hooks(tool_name: str) -> None:
"""No pre_tool_use hooks configured in hooks/hooks.yaml."""
return None

# NOTE: other hook events (post_tool_use, on_session_start, etc.) have no
# DeepAgents equivalent and are intentionally skipped.
# NOTE: memory/ has no direct DeepAgents equivalent — wire a checkpointer if needed.

# Tools (from tools/*.yaml)
@tool
def web_search(query: str) -> str:
"""Search the public web for a query"""
_run_pre_tool_use_hooks("web-search")
# TODO: replace this stub with a real implementation of "web-search"
raise NotImplementedError("Implement tool: web-search")

TOOLS = [web_search]

# Skills (skills/<name>/SKILL.md — DeepAgents loads these natively)
# Resolved relative to this file so discovery works from any working directory.
SKILLS = [str(Path(__file__).resolve().parent / "skills")]

# For reference, the skills available in this agent:
# - summarize: Condense the gathered sources into a faithful, cited summary
# - web-research: Search the web for sources relevant to the user's question

# Sub-agents (agents/<name>/ → SubAgent dicts)
fact_checker_subagent = {
"name": "fact-checker",
"description": "Verifies factual claims against authoritative sources",
"system_prompt": """# fact-checker
Verifies factual claims against authoritative sources

# Fact-Checker

You are a pedantic fact-checker. Treat every claim as unverified until you
locate a primary source. If a claim cannot be substantiated, say so plainly.
""",
"tools": TOOLS, # inherits the full parent toolset (default) — add `tools: [...]` to
# this sub-agent's agent.yaml (agents/fact-checker/agent.yaml) to narrow it
}

SUBAGENTS = [fact_checker_subagent]

# Agent
agent = create_deep_agent(
model=MODEL,
system_prompt=SYSTEM_PROMPT,
tools=TOOLS,
skills=SKILLS,
subagents=SUBAGENTS,
)

if __name__ == "__main__":
import os
user_input = os.environ.get("GITAGENT_PROMPT", "Hello")
result = agent.invoke({"messages": [{"role": "user", "content": user_input}]})
for message in result["messages"]:
print(message)
8 changes: 8 additions & 0 deletions examples/deepagents/skills/summarize/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: summarize
description: Condense the gathered sources into a faithful, cited summary
---

Produce a concise summary of the gathered material. Every factual claim must
be attributed to a specific source URL. If sources disagree, surface the
disagreement explicitly.
8 changes: 8 additions & 0 deletions examples/deepagents/skills/web-research/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: web-research
description: Search the web for sources relevant to the user's question
allowed-tools: web-search
---

Use the `web-search` tool to find authoritative sources. Capture the URL of
every source consulted; downstream skills will cite them.
10 changes: 10 additions & 0 deletions examples/deepagents/tools/web-search.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: web-search
description: Search the public web for a query
input_schema:
type: object
properties:
query:
type: string
description: The search query
required:
- query
Loading