Understanding the Architecture of Open SWE: A Modular Framework for Coding Agents
Open SWE is a modular coding-agent framework that combines Deep Agents, LangGraph orchestration, isolated cloud sandboxes, and deterministic middleware to create a secure, extensible system for autonomous software engineering tasks.
The architecture of Open SWE follows design patterns used by internal agents at Stripe, Ramp, and Coinbase, offering a production-ready foundation for building coding agents. This repository, maintained by LangChain AI, structures the system into distinct layers that handle everything from LLM reasoning to secure code execution.
Agent Harness: Deep Agents and LangGraph Integration
The core agent is built with the Deep Agents library, which itself is a thin wrapper around LangGraph’s Pregel execution engine.
Core Agent Construction
In agent/server.py, the function get_agent creates the agent with create_deep_agent(...):
from deepagents import create_deep_agent
from agent.utils.model import make_model
def get_agent(config):
# … resolve sandbox, repo_dir, etc. …
return create_deep_agent(
model=make_model("anthropic:claude-opus-4-6", temperature=0, max_tokens=20_000),
system_prompt=system_prompt,
tools=[...],
backend=sandbox_backend,
middleware=[...],
).with_config(config)
See the full implementation in agent/server.py lines 71-94.
System Prompt Engineering
The system prompt is built by prompt.construct_system_prompt, injecting repo-specific context. In agent/prompt.py lines 80-86, the function assembles instructions, safety guidelines, and repository metadata into a coherent prompt for the LLM.
Middleware Attachment
Middleware (message-queue handling, empty-message guard, PR safety net) is attached in agent/server.py lines 89-93. This ensures deterministic behavior around each model step.
Sandbox Layer: Isolated Cloud Execution
All work happens inside a sandbox – a remote Linux VM with full shell access but no access to production resources.
Sandbox Abstraction and Providers
The sandbox abstraction lives in agent/utils/sandbox.py lines 1-20 and is instantiated via create_sandbox in agent/server.py line 46. Multiple providers are supported out of the box:
- Modal (
agent/integrations/modal.py) - Daytona (
agent/integrations/daytona.py) - Runloop (
agent/integrations/runloop.py) - LangSmith (built-in integration)
Path Resolution Utilities
Path handling is centralised in agent/utils/sandbox_paths.py lines 20-35. The function aresolve_sandbox_work_dir ensures the agent writes to a consistent, writable directory inside the sandbox:
from agent.utils.sandbox_paths import aresolve_sandbox_work_dir
async def clone_repo(sandbox_backend, owner, repo, token):
work_dir = await aresolve_sandbox_work_dir(sandbox_backend)
repo_dir = posixpath.join(work_dir, repo)
# … clone logic …
Curated Toolset for Software Engineering
Open SWE ships with a small, purposeful set of tools defined in the README and implemented under agent/tools/:
| Tool | Purpose | Implementation |
|---|---|---|
execute |
Run arbitrary shell commands inside the sandbox | built-in Deep Agents tool |
fetch_url |
Retrieve a web page and convert it to markdown | agent/tools/fetch_url.py |
http_request |
Generic HTTP API call (GET/POST/…) | agent/tools/http_request.py |
commit_and_open_pr |
Git commit, push, and open a draft PR | agent/tools/commit_and_open_pr.py |
linear_comment |
Post a comment to a Linear ticket | agent/tools/linear_comment.py |
slack_thread_reply |
Reply in a Slack thread | agent/tools/slack_thread_reply.py |
These tools are listed when the agent is constructed in server.get_agent lines 79-86.
Context Engineering: AGENTS.md and Issue Payloads
When a run starts, the system prompt is enriched with two sources of context.
Repository-Specific Context
If the target repository contains an AGENTS.md at its root, the file is read from within the sandbox via read_agents_md_in_sandbox and injected into the prompt. This occurs in agent/server.py lines 68-70.
External Platform Context
Linear tickets, Slack threads, or GitHub issues are parsed (e.g., process_linear_issue, process_github_issue) and turned into a rich prompt that includes title, description, comments, and image URLs. See agent/webapp.py lines 73-89 for the payload processing logic.
Orchestration: Subagents and Deterministic Middleware
Subagent Capabilities
Deep Agents provides a task tool that lets the main agent spin up child agents for parallel subtasks (e.g., fetching external data, running a linter). No explicit code is required; the tool is available out of the box.
Safety Middleware
Deterministic hooks run around each model step:
check_message_queue_before_model– pulls in any queued Linear/Slack messages (agent/middleware/check_message_queue.py)open_pr_if_needed– ensures a PR is opened even if the LLM forgets (agent/middleware/open_pr.py)ToolErrorMiddleware– catches and logs tool failures gracefully (agent/middleware/tool_error_handler.py)
These middleware components are wired into the agent in server.get_agent lines 88-93.
Multi-Channel Invocation Surfaces
Three public entry points are provided via FastAPI routes in agent/webapp.py:
| Platform | Endpoint | Trigger |
|---|---|---|
| Slack | POST /webhooks/slack |
App-mention (@openswe) |
| Linear | POST /webhooks/linear |
Comment with @openswe |
| GitHub | POST /webhooks/github |
Comment or issue tag containing @openswe |
Each endpoint validates signatures, determines the target repository (via repo: syntax, GitHub URL parsing, or thread metadata), and schedules the appropriate processing function (process_slack_mention, process_linear_issue, process_github_issue). See agent/webapp.py lines 65-70 and 115-130.
Posting a Slack reply uses the utility function in agent/utils/slack.py:
from agent.utils.slack import post_slack_thread_reply
await post_slack_thread_reply(channel_id, thread_ts, "✅ PR opened! <pr_url>")
See lines 48-54 in agent/utils/slack.py.
Safety and Validation Mechanisms
The system prompt instructs the LLM to run linters, formatters, and tests before committing, as defined in agent/prompt.py lines 101-110.
If the LLM finishes without creating a PR, the open_pr_if_needed middleware automatically runs commit_and_open_pr as a safety net. This mirrors the "deterministic nodes" pattern used by the reference internal agents at major tech companies.
Summary
- Open SWE combines Deep Agents and LangGraph to create a deterministic, extensible agent harness.
- Isolated sandboxes from providers like Modal, Daytona, and Runloop ensure secure code execution with no production access.
- A curated toolset including
commit_and_open_pr,fetch_url, and platform-specific integrations provides focused capabilities without bloat. - Context engineering via
AGENTS.mdand rich issue payloads gives the LLM domain-specific knowledge upfront. - Deterministic middleware and subagent support enable parallel processing and safety guarantees around every model step.
- Multi-channel invocation via Slack, Linear, and GitHub webhooks allows seamless integration into existing engineering workflows.
Frequently Asked Questions
What is the core execution engine behind Open SWE's agent?
The core execution engine is LangGraph's Pregel engine, accessed through the Deep Agents library. In agent/server.py, the get_agent function calls create_deep_agent() with a LangGraph backend, allowing the system to handle complex multi-step reasoning while maintaining deterministic execution paths through middleware hooks.
How does Open SWE ensure code execution safety?
Open SWE ensures safety through isolated cloud sandboxes and deterministic middleware. All code execution happens inside remote Linux VMs (supported providers include Modal, Daytona, and Runloop) with no access to production resources. Additionally, middleware components like open_pr_if_needed and ToolErrorMiddleware provide safety nets that execute deterministically around each LLM step, ensuring actions like PR creation occur even if the model forgets.
What platforms can trigger Open SWE agents?
Open SWE agents can be triggered from Slack, Linear, and GitHub through FastAPI webhook endpoints defined in agent/webapp.py. Slack triggers via app mentions (@openswe), Linear triggers via comments containing @openswe, and GitHub triggers via issue comments or tags containing @openswe. Each endpoint validates signatures and extracts repository context before scheduling the appropriate processing function.
How does Open SWE handle repository-specific context?
Open SWE injects repository-specific context through AGENTS.md files and issue payload processing. If a repository contains an AGENTS.md file at its root, the system reads it from within the sandbox via read_agents_md_in_sandbox and injects it into the system prompt. Additionally, when triggered from Linear, Slack, or GitHub, the system parses the issue or thread data (titles, descriptions, comments, images) into a rich prompt context, giving the LLM complete domain knowledge without requiring file discovery.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →