refactor: move docs/resources/assets to domain layout

Part of the domain-reorg adoption (build plan step C1): fork content,
upstream layout. Moves INSTALLATION.md/CUSTOMIZATION.md under docs/,
static/ under assets/, and default_prompt.md under agent/resources/
(packaged via agent/resources/__init__.py), then switches prompt.py's
loader to importlib.resources with an explicit DEFAULT_PROMPT_PATH
override, matching upstream's hunk. README and CUSTOMIZATION.md links
updated for the new paths; wheel build verified to still ship
agent/resources/default_prompt.md.
This commit is contained in:
Adam Moussa 2026-07-17 13:45:39 -04:00
parent a518a1291d
commit a82da1f907
No known key found for this signature in database
8 changed files with 30 additions and 22 deletions

View file

@ -1,9 +1,9 @@
<div align="center">
<a href="https://github.com/langchain-ai/open-swe">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="static/dark.svg">
<source media="(prefers-color-scheme: light)" srcset="static/light.svg">
<img alt="Open SWE Logo" src="static/dark.svg" width="35%">
<source media="(prefers-color-scheme: dark)" srcset="assets/dark.svg">
<source media="(prefers-color-scheme: light)" srcset="assets/light.svg">
<img alt="Open SWE Logo" src="assets/dark.svg" width="35%">
</picture>
</a>
</div>
@ -54,7 +54,7 @@ create_deep_agent(
Every task runs in its own **isolated cloud sandbox** — a remote Linux environment with full shell access. The repo is cloned in, the agent gets full permissions, and the blast radius of any mistake is fully contained. No production access, no confirmation prompts.
Open SWE supports multiple sandbox providers out of the box — [Modal](https://modal.com/), [Daytona](https://www.daytona.io/), [Runloop](https://www.runloop.ai/), [E2B](https://e2b.dev/), and [LangSmith](https://smith.langchain.com/) — and you can plug in your own. See the [Customization Guide](CUSTOMIZATION.md#1-sandbox) for details.
Open SWE supports multiple sandbox providers out of the box — [Modal](https://modal.com/), [Daytona](https://www.daytona.io/), [Runloop](https://www.runloop.ai/), [E2B](https://e2b.dev/), and [LangSmith](https://smith.langchain.com/) — and you can plug in your own. See the [Customization Guide](docs/CUSTOMIZATION.md#1-sandbox) for details.
This follows the principle all three companies converge on: **isolate first, then give full permissions inside the boundary.**
@ -112,7 +112,7 @@ All three companies in the article converge on **Slack as the primary invocation
- **Confluence** — Comment `@openswe` on a page. A private Atlassian Connect app delivers the `comment_created` event; the agent acts and replies on the page.
- **GitHub** — Tag `@openswe` in PR comments on agent-created PRs to have it address review feedback and push fixes to the same branch.
See **[INSTALLATION.md](./INSTALLATION.md) §5** for per-surface trigger setup.
See **[INSTALLATION.md](./docs/INSTALLATION.md) §5** for per-surface trigger setup.
Each invocation creates a deterministic thread ID, so follow-up messages on the same issue or thread route to the same running agent.
@ -123,7 +123,7 @@ Each invocation creates a deterministic thread ID, so follow-up messages on the
### 7. Validation — Prompt-Driven
The agent is instructed to run linters, formatters, and tests before committing, and is responsible end-to-end for committing, pushing, opening/updating the draft PR, and replying in the source channel.
This is an area where you can extend Open SWE for your org: add deterministic CI checks, visual verification, or review gates as additional middleware. See the [Customization Guide](CUSTOMIZATION.md#6-middleware) for how.
This is an area where you can extend Open SWE for your org: add deterministic CI checks, visual verification, or review gates as additional middleware. See the [Customization Guide](docs/CUSTOMIZATION.md#6-middleware) for how.
---
@ -156,8 +156,8 @@ This is an area where you can extend Open SWE for your org: add deterministic CI
## Getting Started
- **[Installation Guide](INSTALLATION.md)** — local dev (backend + dashboard), GitHub App creation, LangSmith, Linear/Slack/GitHub triggers, and production deployment
- **[Customization Guide](CUSTOMIZATION.md)** — swap the sandbox, model, tools, triggers, system prompt, and middleware for your org
- **[Installation Guide](docs/INSTALLATION.md)** — local dev (backend + dashboard), GitHub App creation, LangSmith, Linear/Slack/GitHub triggers, and production deployment
- **[Customization Guide](docs/CUSTOMIZATION.md)** — swap the sandbox, model, tools, triggers, system prompt, and middleware for your org
## Deployment (Sea Haven fork)
@ -169,7 +169,7 @@ and secrets live in the LangGraph deployment config and Vercel environment
variables. Promotion from `dev` to `prod` (`main`) is handled by
[`.github/workflows/promote-to-main.yml`](.github/workflows/promote-to-main.yml).
See **[INSTALLATION.md § 10 "Production deployment"](INSTALLATION.md#10-production-deployment)**
See **[INSTALLATION.md § 10 "Production deployment"](docs/INSTALLATION.md#10-production-deployment)**
for the full backend + dashboard setup.
> The earlier self-hosted AWS stack (CDK under `infra/`, an ARM64 EC2 box + nginx

View file

@ -1,6 +1,7 @@
import logging
import os
import shlex
from importlib import resources
from pathlib import Path
from deepagents import HarnessProfile, register_harness_profile
@ -14,10 +15,7 @@ from .utils.github_comments import UNTRUSTED_GITHUB_COMMENT_OPEN_TAG
logger = logging.getLogger(__name__)
DEFAULT_PROMPT_PATH = os.environ.get(
"DEFAULT_PROMPT_PATH",
str(Path(__file__).resolve().parent.parent / "default_prompt.md"),
)
DEFAULT_PROMPT_PATH = os.environ.get("DEFAULT_PROMPT_PATH")
# Tools stripped from the agent regardless of run state (none today: plan-mode
# tool stripping is dynamic and handled by PlanModeMiddleware, not the profile).
@ -37,19 +35,28 @@ def _load_default_prompt() -> str:
Returns empty string if the file doesn't exist or can't be read.
"""
try:
path = Path(DEFAULT_PROMPT_PATH)
if path.is_file():
content = path.read_text().strip()
if content:
# Escape curly braces so .format() doesn't choke on them
escaped = content.replace("{", "{{").replace("}", "}}")
return f"""---
if DEFAULT_PROMPT_PATH:
content = Path(DEFAULT_PROMPT_PATH).read_text().strip()
else:
content = (
resources.files("agent.resources")
.joinpath("default_prompt.md")
.read_text(encoding="utf-8")
.strip()
)
if content:
# Escape curly braces so .format() doesn't choke on them
escaped = content.replace("{", "{{").replace("}", "}}")
return f"""---
### Custom Instructions
{escaped}"""
except Exception:
logger.warning("Failed to read default prompt file at %s", DEFAULT_PROMPT_PATH)
logger.warning(
"Failed to read default prompt from %s",
DEFAULT_PROMPT_PATH or "agent.resources/default_prompt.md",
)
return ""

View file

@ -0,0 +1 @@
__all__: list[str] = []

View file

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -439,7 +439,7 @@ Open SWE supports a `default_prompt.md` file for org-level instructions that app
The file is loaded at agent startup and injected into the system prompt between the task overview and repository setup sections.
**Location:** [`default_prompt.md`](./default_prompt.md) in the project root.
**Location:** [`agent/resources/default_prompt.md`](../agent/resources/default_prompt.md) for the bundled default.
**Override:** Set the `DEFAULT_PROMPT_PATH` environment variable to use a different file: