# Understanding the Architecture of Open SWE: A Modular Framework for Coding Agents

> Explore the modular architecture of Open SWE. Discover its Deep Agents, LangGraph orchestration, sandboxes, and middleware for autonomous software engineering.

- Repository: [LangChain/open-swe](https://github.com/langchain-ai/open-swe)
- Tags: architecture
- Published: 2026-03-19

---

**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`](https://github.com/langchain-ai/open-swe/blob/main/agent/server.py), the function `get_agent` creates the agent with `create_deep_agent(...)`:

```python
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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/agent/utils/sandbox.py) lines 1-20 and is instantiated via `create_sandbox` in [`agent/server.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/server.py) line 46. Multiple providers are supported out of the box:

- **Modal** ([`agent/integrations/modal.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/integrations/modal.py))
- **Daytona** ([`agent/integrations/daytona.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/integrations/daytona.py))
- **Runloop** ([`agent/integrations/runloop.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/integrations/runloop.py))
- **LangSmith** (built-in integration)

### Path Resolution Utilities

Path handling is centralised in [`agent/utils/sandbox_paths.py`](https://github.com/langchain-ai/open-swe/blob/main/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:

```python
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`](https://github.com/langchain-ai/open-swe/blob/main/agent/tools/fetch_url.py) |
| `http_request` | Generic HTTP API call (GET/POST/…) | [`agent/tools/http_request.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/tools/http_request.py) |
| `commit_and_open_pr` | Git commit, push, and open a draft PR | [`agent/tools/commit_and_open_pr.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/tools/commit_and_open_pr.py) |
| `linear_comment` | Post a comment to a Linear ticket | [`agent/tools/linear_comment.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/tools/linear_comment.py) |
| `slack_thread_reply` | Reply in a Slack thread | [`agent/tools/slack_thread_reply.py`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/agent/middleware/open_pr.py))
- **`ToolErrorMiddleware`** – catches and logs tool failures gracefully ([`agent/middleware/tool_error_handler.py`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/agent/webapp.py) lines 65-70 and 115-130.

Posting a Slack reply uses the utility function in [`agent/utils/slack.py`](https://github.com/langchain-ai/open-swe/blob/main/agent/utils/slack.py):

```python
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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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.md`](https://github.com/langchain-ai/open-swe/blob/main/AGENTS.md) and 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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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`](https://github.com/langchain-ai/open-swe/blob/main/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.