| layout | default |
|---|---|
| title | Chapter 3: Development Environment and Monorepo Setup |
| nav_order | 3 |
| parent | Open SWE Tutorial |
Welcome to Chapter 3: Development Environment and Monorepo Setup. In this part of Open SWE Tutorial: Asynchronous Cloud Coding Agent Architecture and Migration Playbook, you will build an intuitive mental model first, then move into concrete implementation details and practical production tradeoffs.
This chapter covers local development setup for teams auditing or maintaining forks.
- bootstrap the Yarn/Turbo monorepo correctly
- configure env files and secrets flow
- run web and agent services locally
- avoid setup drift across collaborators
- use Yarn workspaces and Turbo tasks from repo root
- configure both
apps/webandapps/open-sweenv files - establish GitHub App credentials before webhook testing
You now have a repeatable local setup baseline for maintenance and experimentation.
Next: Chapter 4: Usage Patterns: UI and GitHub Workflows
The get_slack_user_names function in agent/utils/slack.py handles a key part of this chapter's functionality:
async def get_slack_user_names(user_ids: list[str]) -> dict[str, str]:
"""Get display names for a set of Slack user IDs."""
unique_ids = sorted({user_id for user_id in user_ids if isinstance(user_id, str) and user_id})
if not unique_ids:
return {}
user_infos = await asyncio.gather(
*(get_slack_user_info(user_id) for user_id in unique_ids),
return_exceptions=True,
)
user_names: dict[str, str] = {}
for user_id, user_info in zip(unique_ids, user_infos, strict=True):
if isinstance(user_info, dict):
user_names[user_id] = _extract_slack_user_name(user_info)
else:
user_names[user_id] = user_id
return user_names
async def fetch_slack_thread_messages(channel_id: str, thread_ts: str) -> list[dict[str, Any]]:
"""Fetch all messages for a Slack thread."""
if not SLACK_BOT_TOKEN:
return []
messages: list[dict[str, Any]] = []
cursor: str | None = None
async with httpx.AsyncClient() as http_client:
while True:This function is important because it defines how Open SWE Tutorial: Asynchronous Cloud Coding Agent Architecture and Migration Playbook implements the patterns covered in this chapter.
The fetch_slack_thread_messages function in agent/utils/slack.py handles a key part of this chapter's functionality:
async def fetch_slack_thread_messages(channel_id: str, thread_ts: str) -> list[dict[str, Any]]:
"""Fetch all messages for a Slack thread."""
if not SLACK_BOT_TOKEN:
return []
messages: list[dict[str, Any]] = []
cursor: str | None = None
async with httpx.AsyncClient() as http_client:
while True:
params: dict[str, str | int] = {"channel": channel_id, "ts": thread_ts, "limit": 200}
if cursor:
params["cursor"] = cursor
try:
response = await http_client.get(
f"{SLACK_API_BASE_URL}/conversations.replies",
headers=_slack_headers(),
params=params,
)
response.raise_for_status()
payload = response.json()
except httpx.HTTPError:
logger.exception("Slack conversations.replies request failed")
break
if not payload.get("ok"):
logger.warning("Slack conversations.replies failed: %s", payload.get("error"))
breakThis function is important because it defines how Open SWE Tutorial: Asynchronous Cloud Coding Agent Architecture and Migration Playbook implements the patterns covered in this chapter.
The post_slack_trace_reply function in agent/utils/slack.py handles a key part of this chapter's functionality:
async def post_slack_trace_reply(channel_id: str, thread_ts: str, run_id: str) -> None:
"""Post a trace URL reply in a Slack thread."""
trace_url = get_langsmith_trace_url(run_id)
if trace_url:
await post_slack_thread_reply(
channel_id, thread_ts, f"Working on it! <{trace_url}|View trace>"
)This function is important because it defines how Open SWE Tutorial: Asynchronous Cloud Coding Agent Architecture and Migration Playbook implements the patterns covered in this chapter.
The construct_system_prompt function in agent/prompt.py handles a key part of this chapter's functionality:
def construct_system_prompt(
working_dir: str,
linear_project_id: str = "",
linear_issue_number: str = "",
agents_md: str = "",
) -> str:
agents_md_section = ""
if agents_md:
agents_md_section = (
"\nThe following text is pulled from the repository's AGENTS.md file. "
"It may contain specific instructions and guidelines for the agent.\n"
"<agents_md>\n"
f"{agents_md}\n"
"</agents_md>\n"
)
return SYSTEM_PROMPT.format(
working_dir=working_dir,
linear_project_id=linear_project_id or "<PROJECT_ID>",
linear_issue_number=linear_issue_number or "<ISSUE_NUMBER>",
agents_md_section=agents_md_section,
)This function is important because it defines how Open SWE Tutorial: Asynchronous Cloud Coding Agent Architecture and Migration Playbook implements the patterns covered in this chapter.
flowchart TD
A[get_slack_user_names]
B[fetch_slack_thread_messages]
C[post_slack_trace_reply]
D[construct_system_prompt]
E[EncryptionKeyMissingError]
A --> B
B --> C
C --> D
D --> E