Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/swe-agent/mini-swe-agent/llms.txt

Use this file to discover all available pages before exploring further.

mini-swe-agent is built from three loosely coupled components — an agent, an environment, and a model — assembled together in a thin run script. Each component is a plain Python class, and the interfaces between them are protocols (duck typing), not deep inheritance hierarchies. This means you can swap in a custom subclass or a completely new implementation at any layer without touching the others.
Keep your changes as minimal as possible. Override a single method, call super() for everything else, and you’ll have a maintainable extension that automatically picks up future improvements to the base classes.

The component model

To build a custom version of mini-swe-agent:
1

Pick an agent class

The agent class controls the main loop and how the model’s responses are processed.
ClassDescription
DefaultAgentAutonomous loop — the simplest option
InteractiveAgentAdds human-in-the-loop confirmation and mode switching
2

Pick an environment class

The environment class decides where and how bash commands are executed.
ClassDescription
LocalEnvironmentRuns commands on the host via subprocess.run
DockerEnvironmentRuns commands inside a Docker container
3

Pick a model class

The model class handles querying the LM, parsing actions from responses, and formatting observations.
ClassDescription
LitellmModelTool-calling via LiteLLM (default)
LitellmTextbasedModelRegex-based text parsing via LiteLLM
Use get_model(input_model_name=...) for automatic class selection.
4

Write a run script

A run script instantiates your chosen classes and calls agent.run(task). See the hello world run script for a minimal example.
from minisweagent.agents.default import DefaultAgent
from minisweagent.models import get_model
from minisweagent.environments.local import LocalEnvironment

agent = DefaultAgent(
    get_model(input_model_name="anthropic/claude-sonnet-4-5-20250929"),
    LocalEnvironment(),
)
result = agent.run(task)

Customization recipes

Custom action handling with Python functions

You can intercept specific commands and handle them in Python instead of passing them to the shell. This works from either the agent or the environment side.
Override execute_actions to intercept matching commands before falling back to super().
from minisweagent.agents.default import DefaultAgent
import shlex

def python_function(*args) -> dict:
    # your custom logic here
    return {"output": "..."}

class AgentWithPythonFunctions(DefaultAgent):
    def execute_actions(self, message: dict) -> list[dict]:
        for action in message.get("extra", {}).get("actions", []):
            command = action.get("command", "")
            if command.startswith("python_function"):
                args = shlex.split(command.removeprefix("python_function").strip())
                return self.add_messages(self.model.format_observation_messages(
                    message, [python_function(*args)], self.get_template_vars()
                ))
        return super().execute_actions(message)

Action validation — blocking forbidden patterns

Use a custom config class to make the forbidden patterns configurable, then validate every command before execution.
import re
from minisweagent.agents.default import DefaultAgent, AgentConfig
from minisweagent.exceptions import FormatError

class ValidatingAgentConfig(AgentConfig):
    forbidden_patterns: list[str] = [
        r"rm -rf /",
        r"sudo.*passwd",
        r"mkfs\.",
    ]

class ValidatingAgent(DefaultAgent):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs, config_class=ValidatingAgentConfig)

    def execute_actions(self, message: dict) -> list[dict]:
        for action in message.get("extra", {}).get("actions", []):
            command = action.get("command", "")
            for pattern in self.config.forbidden_patterns:
                if re.search(pattern, command, re.IGNORECASE):
                    raise FormatError(self.model.format_message(
                        role="user",
                        content="Action blocked: forbidden pattern detected",
                    ))
        return super().execute_actions(message)

Agent that exits on a submit command

Raise the Submitted exception from execute_actions or execute to end the run immediately when the agent issues a submit command.
from minisweagent.agents.default import DefaultAgent
from minisweagent.exceptions import Submitted

class AgentQuitsOnSubmit(DefaultAgent):
    def execute_actions(self, message: dict) -> list[dict]:
        for action in message.get("extra", {}).get("actions", []):
            if action.get("command", "") == "submit":
                raise Submitted({
                    "role": "exit",
                    "content": "The agent has finished its task.",
                    "extra": {"exit_status": "Submitted", "submission": ""},
                })
        return super().execute_actions(message)

Overriding the default entry point

When you run the mini CLI, it calls the default run script. You can replace that script with your own by setting the MSWEA_DEFAULT_RUN environment variable to the dotted import path of your run script’s main function:
export MSWEA_DEFAULT_RUN=mypackage.mymodule.main
mini -t "Fix the bug in app.py"
This lets you distribute a drop-in replacement for mini without forking the package.

Running mini-swe-agent at scale with Ray

For massively parallel agent runs (e.g., large-scale SWE-bench evaluations), mini-swe-agent can be parallelized with Ray. The Anyscale blog post on massively parallel agentic simulations walks through the approach in detail.

Build docs developers (and LLMs) love