Open SWE Documentation

repository·main·Indexed 27 days ago

https://github.com/langchain-ai/open-swe

An open-source framework for building internal coding agents for organizations. Open SWE enables agents to operate within sandboxed environments (supporting Modal, Daytona, Runloop, E2B, and LangSmith), interact with tools like Slack, Linear, and GitHub, and perform complex software engineering tasks. It features a Deep Agents composition framework using create_deep_agent, middleware hooks for deterministic agent loops, and a Reviewer Eval system for benchmarking code reviews.

Tokens
20.7K
Snippets
37
Records
111
Agent score
95%

What's inside Open SWE

  1. Bootstrap repo analysis skill

    main

    The bootstrap-repo-analysis skill is used for the first-time analysis of a repository that has no prior reviewer outcomes. It performs a cold-start analysis by crawling historical merged PR review feedback using the gh CLI to extract team review norms and synthesize an initial per-repo review-style prompt.

    Note: Do not call read_finding_outcomes in this mode as it will be empty. Once the reviewer has accumulated finding outcomes, switch to continual-learning instead.

  2. Understand the Dashboard and API Architecture

    main

    The Open SWE dashboard is a Vite/TanStack Start application located in ui/. It is an authenticated client that communicates with a FastAPI backend.

    Key architectural details:

    • Client Routes: File-based routes are located under ui/src/routes/.
    • API Communication: The client calls FastAPI endpoints at /dashboard/api/*. API calls are managed via ui/src/lib/api.ts and ui/src/features/agents/lib/api.ts.
    • Backend Implementation: The backend routes are defined in agent/dashboard/routes.py and mounted by agent/api/app.py.
    • Production Deployment: In Vercel, /dashboard/api/* is rewritten to the hosted LangGraph application to ensure same-origin operation.
    • Local Development: You can point the client at a separate API base URL, provided explicit CORS configuration is set up.
  3. Implement a New Webhook Source

    main

    When adding a new webhook trigger, adhere to these security requirements:

    1. Verify signatures at the route boundary.
    2. Validate allowed repositories and users.
    3. Treat all incoming remote text as untrusted data.
    4. Construct deterministic thread IDs to connect messages to the correct run.
    5. Use agent/dispatch.py for dispatching.
  4. Configure and extend the coding agent graph

    main

    The coding agent is built using agent/server.py:get_agent, which produces a Deep Agent with filesystem, shell, todo, and subagent capabilities.

    Key Architectural Concepts

    • Thread-based State: The meaningful state boundary is per thread. While the agent factory is fresh per run, the sandbox identity and run metadata persist with the LangGraph thread.
    • Sandbox Management: ensure_sandbox_for_thread is used to reuse, ping, reconnect, or recreate the backend sandbox for a specific thread.
    • Middleware Order: The get_agent function uses a specific middleware sequence (including input sanitization, model-call limits, tool error handling, and AGENTS.md context). Do not change the order of middleware, as it affects security and behavioral logic.

    How to modify the coding agent

    To change the coding-agent policy, you must review the following components together:

    1. get_agent in agent/server.py
    2. agent/prompt.py
    3. Registered tools
    4. The complete middleware sequence
  5. Add a new invocation trigger (e.g., Jira, Discord)

    main

    To add a new trigger, you must implement a webhook endpoint and a processing function to start the agent run.

    1. Add a webhook endpoint in agent/webapp.py to receive and parse the payload.
    2. Create a processing function that uses a langgraph_client to create a run with the necessary config.configurable fields.

    Required config.configurable fields:

    • repo: {"owner": "...", "name": "..."} — The target GitHub repo.
    • source: A string identifying the trigger (used for auth and communication).
    • user_email: The triggering user's email (used for GitHub OAuth resolution).

    Example Implementation:

    # 1. Webhook endpoint in agent/webapp.py
    @app.post("/webhooks/my-trigger")
    async def my_trigger_webhook(request: Request, background_tasks: BackgroundTasks):
        payload = await request.json()
        task_description = payload["description"]
        repo_config = {"owner": "my-org", "name": "my-repo"}
        background_tasks.add_task(process_my_trigger, task_description, repo_config)
        return {"status": "accepted"}
    
    # 2. Processing function
    async def process_my_trigger(task_description: str, repo_config: dict):
        thread_id = generate_deterministic_id(task_description)
        langgraph_client = get_client(url=LANGGRAPH_URL)
        
        await langgraph_client.runs.create(
            thread_id,
            "agent",
            input={"messages": [{"role": "user", "content": task_description}]},
            config={"configurable": {
                "repo": repo_config,
                "source": "my-trigger",
                "user_email": "user@example.com",
            }},
            if_not_exists="create",
        )
    # 1. Webhook endpoint in agent/webapp.py
    @app.post("/webhooks/my-trigger")
    async def my_trigger_webhook(request: Request, background_tasks: BackgroundTasks):
        payload = await request.json()
        task_description = payload["description"]
        repo_config = {"owner": "my-org", "name": "my-repo"}
        background_tasks.add_task(process_my_trigger, task_description, repo_config)
        return {"status": "accepted"}
    
    # 2. Processing function
    async def process_my_trigger(task_description: str, repo_config: dict):
        thread_id = generate_deterministic_id(task_description)
        langgraph_client = get_client(url=LANGGRAPH_URL)
        
        await langgraph_client.runs.create(
            thread_id,
            "agent",
            input={"messages": [{"role": "user", "content": task_description}]},
            config={"configurable": {
                "repo": repo_config,
                "source": "my-trigger",
                "user_email": "user@example.com",
            }},
            if_not_exists="create",
        )
  6. Run the Web Dashboard

    main

    The dashboard is a static TanStack Start client located in the ui/ directory. It requires a connection to the FastAPI backend.

    1. Navigate to the ui directory.
    2. Install dependencies using pnpm.
    3. Create a .env file in ui/ containing VITE_DASHBOARD_API_BASE_URL pointing to your backend (e.g., http://localhost:2024).
    4. Start the development server.

    Note on CORS: If the UI and API are on different origins (e.g., :3000 vs :2024), you must set DASHBOARD_ALLOWED_ORIGINS in your backend .env to include the UI origin.

    cd ui
    pnpm install
    cat > .env <<'EOF'
    VITE_DASHBOARD_API_BASE_URL="http://localhost:2024"
    EOF
    pnpm run dev
  7. Navigate User-facing Workflows in the Dashboard

    main

    The dashboard provides several views for managing agents and workflows. The root path / redirects to /agents, which is the primary authenticated workspace.

    Available views and routes:

    • Agent Landing/New Work: ui/src/routes/agents/index.tsx
    • Thread/Chat & Plan Views: agents/$threadId.tsx and agents/$threadId_.plan.tsx (supports streaming).
    • Thread History: agents/threads.tsx (searchable).
    • Automation/Schedule: agents/automations/.
    • PR Review History/Detail: agents/reviews/.

    User settings within these areas allow for configuring GitHub-linked preferences, Slack mapping, notifications, and integrations.

  8. Configure GitHub OAuth for Agent-Runtime

    main

    To allow agents to perform actions using the triggering user's identity (rather than the GitHub App's shared bot identity), configure GitHub OAuth in LangSmith. This ensures PRs and commits reflect the user's identity and respect their permissions.

    1. In LangSmith, go to Settings → OAuth Providers → Add Provider.
    2. Set Provider ID to the value you intend to use for GITHUB_OAUTH_PROVIDER_ID.
    3. Enter the Client ID and Client Secret from your GitHub App's OAuth credentials page.
    4. Set Authorization URL to https://github.com/login/oauth/authorize.
    5. Set Token URL to https://github.com/login/oauth/access_token.
    6. Leave Enable PKCE unchecked.
    7. Save and set the GITHUB_OAUTH_PROVIDER_ID environment variable to match the Provider ID used in LangSmith.
  9. Deploy the Backend to LangGraph Cloud

    main

    To deploy the backend in production, use LangGraph Cloud.

    1. Push your code to a GitHub repository.
    2. Connect the repository to LangGraph Cloud.
    3. Configure the following environment variables in your deployment:
      • Set DASHBOARD_BASE_URL and LANGGRAPH_URL to your production https:// URLs.
      • Set DASHBOARD_API_BASE_URL to the URL used by browsers for dashboard API requests and OAuth callbacks. This should be either the backend URL (for direct cross-origin calls) or the dashboard/Vercel URL (if using a same-origin rewrite via /dashboard/api/*).
    4. Update all webhook URLs (Linear, Slack, GitHub App) and OAuth callback URLs to use production https:// instead of ngrok or localhost values.

    Note: The GitHub App dashboard callback must be set to <DASHBOARD_API_BASE_URL>/dashboard/api/auth/callback.

    {
      "graphs": {
        "agent": "agent.server:traced_agent",
        "reviewer": "agent.reviewer:traced_reviewer_agent",
        "analyzer": "agent.analyzer:traced_analyzer"
      },
      "http": {
        "app": "agent.webapp:app"
      }
    }
  10. Configure GitHub triggering for Open SWE

    main

    Open SWE can be triggered by tagging @openswe in GitHub issue titles, issue bodies, or PR review comments.

    User Mapping

    To control which GitHub users can trigger the agent, manage user mappings (GitHub login ⇄ work email ⇄ optional Slack ID) in the dashboard under Admin → User mappings.

    Users can also self-onboard by tagging the agent in Slack; the agent will prompt them to link their GitHub account via an org-gated OAuth login.

    Repository Access Control

    You can restrict the agent to specific organizations or repositories using environment variables:

    • ALLOWED_GITHUB_ORGS: A comma-separated list of allowed organizations.
    • ALLOWED_GITHUB_REPOS: A comma-separated list of specific owner/repo pairs.

    If both are empty, all repositories are allowed. Note that ALLOWED_GITHUB_ORGS also gates dashboard login; users must be members of the listed orgs to log in.

    Required Permissions

    To support the membership check used by ALLOWED_GITHUB_ORGS, your GitHub App must have the Organization → Members: Read-only permission.

    # Allow all repos in these orgs
    ALLOWED_GITHUB_ORGS="langchain-ai,anthropics"
    
    # Allow specific repos (owner/repo format)
    ALLOWED_GITHUB_REPOS="some-user/their-repo,another-org/specific-repo"
  11. Configure Sandbox Providers via SANDBOX_TYPE

    main

    Open SWE executes repository work within isolated sandboxes. The specific backend is determined by the SANDBOX_TYPE environment variable.

    Supported sandbox providers include:

    • LangSmith (Default): Configures a GitHub proxy for Git and API operations using a GitHub App installation token, rather than placing a real GitHub token inside the sandbox.
    • Daytona
    • Modal
    • Runloop
    • E2B
    • Local: Warning: This provider has no isolation and is for development only. It should not be used in production.

    The coding graph maintains sandbox stability across a thread using LangGraph thread metadata to retain a durable sandbox ID, allowing for reconnection and reuse of the working environment.