Skip to content

GitHub Issue

minisweagent.run.github_issue

DEFAULT_CONFIG module-attribute

DEFAULT_CONFIG = Path(
    getenv(
        "MSWEA_GITHUB_CONFIG_PATH",
        builtin_config_dir / "github_issue.yaml",
    )
)

console module-attribute

console = Console(highlight=False)

app module-attribute

app = Typer(rich_markup_mode='rich', add_completion=False)

fetch_github_issue

fetch_github_issue(issue_url: str) -> str

Fetch GitHub issue text from the URL.

Source code in src/minisweagent/run/github_issue.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def fetch_github_issue(issue_url: str) -> str:
    """Fetch GitHub issue text from the URL."""
    # Convert GitHub issue URL to API URL
    api_url = issue_url.replace("github.com", "api.github.com/repos").replace("/issues/", "/issues/")

    headers = {}
    if github_token := os.getenv("GITHUB_TOKEN"):
        headers["Authorization"] = f"token {github_token}"

    response = requests.get(api_url, headers=headers)
    issue_data = response.json()

    title = issue_data["title"]
    body = issue_data["body"] or ""

    return f"GitHub Issue: {title}\n\n{body}"

main

main(
    issue_url: str = Option(
        prompt="Enter GitHub issue URL",
        help="GitHub issue URL",
    ),
    config: Path = Option(
        DEFAULT_CONFIG,
        "-c",
        "--config",
        help="Path to config file",
    ),
    model: str | None = Option(
        None, "-m", "--model", help="Model to use"
    ),
    yolo: bool = Option(
        False,
        "-y",
        "--yolo",
        help="Run without confirmation",
    ),
) -> InteractiveAgent

Run mini-SWE-agent on a GitHub issue

Source code in src/minisweagent/run/github_issue.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
@app.command()
def main(
    issue_url: str = typer.Option(prompt="Enter GitHub issue URL", help="GitHub issue URL"),
    config: Path = typer.Option(DEFAULT_CONFIG, "-c", "--config", help="Path to config file"),
    model: str | None = typer.Option(None, "-m", "--model", help="Model to use"),
    yolo: bool = typer.Option(False, "-y", "--yolo", help="Run without confirmation"),
) -> InteractiveAgent:
    """Run mini-SWE-agent on a GitHub issue"""
    configure_if_first_time()

    _config = yaml.safe_load(get_config_path(config).read_text())
    _agent_config = _config.get("agent", {})
    if yolo:
        _agent_config["mode"] = "yolo"

    task = fetch_github_issue(issue_url)

    agent = InteractiveAgent(
        get_model(model, _config.get("model", {})),
        DockerEnvironment(**_config.get("environment", {})),
        **_agent_config,
    )

    repo_url = issue_url.split("/issues/")[0]
    if github_token := os.getenv("GITHUB_TOKEN"):
        repo_url = repo_url.replace("https://github.com/", f"https://{github_token}@github.com/") + ".git"

    agent.env.execute(f"git clone {repo_url} /testbed", cwd="/")

    exit_status, result = None, None
    try:
        exit_status, result = agent.run(task)
    except KeyboardInterrupt:
        console.print("\n[bold red]KeyboardInterrupt -- goodbye[/bold red]")
    finally:
        save_traj(agent, Path("traj.json"), exit_status=exit_status, result=result)
    return agent