Cookbook
Remixing & extending mini
- This guide shows how to mix the different components of the
mini
agent to create your own custom version. - You might want to first take a look at the control flow of the default agent first
Development setup
Make sure to follow the dev setup instructions in quickstart.md.
We provide several different entry points to the agent,
for example hello world,
or the default when calling mini
.
Want to cook up your custom version and the config is not enough? Just follow the recipe below:
- What's the control flow you need? Pick an agent class (e.g., simplest example, with human in the loop)
- How should actions be executed? Pick an environment class (e.g., local, or docker)
- How is the LM queried? Pick a model class (e.g., litellm)
- How to invoke the agent? Bind them all together in a run script, possibly reading from a config (e.g., hello world, or
mini
entry point)
We aim to keep all of these components very simple, but offer lots of choice between them -- enough to cover a broad range of things that you might want to do.
You can override the default entry point by setting the MSWEA_DEFAULT_RUN
environment variable to the import path of your run script.
Mix & match
Models
from minisweagent.agents.default import DefaultAgent
from minisweagent.models import get_model
from minisweagent.environments.local import LocalEnvironment
model_name = "claude-sonnet-4-20250514"
agent = DefaultAgent(
get_model(model_name=model_name),
LocalEnvironment(),
)
agent.run(task)
from minisweagent.agents.default import DefaultAgent
from minisweagent.models.anthropic_model import AnthropicModel
from minisweagent.environments.local import LocalEnvironment
model_name = "claude-sonnet-4-20250514"
agent = DefaultAgent(
AnthropicModel(model_name=model_name),
LocalEnvironment(),
)
agent.run(task)
from minisweagent.agents.default import DefaultAgent
from minisweagent.models.litellm_model import LitellmModel
from minisweagent.environments.local import LocalEnvironment
model_name = "gpt-4o"
agent = DefaultAgent(
LitellmModel(model_name=model_name),
LocalEnvironment(),
)
agent.run(task)
Environments
from minisweagent.environments.local import LocalEnvironment
agent = DefaultAgent(
LitellmModel(model_name=model_name),
LocalEnvironment(),
)
from minisweagent.environments.docker import DockerEnvironment
agent = DefaultAgent(
LitellmModel(model_name=model_name),
DockerEnvironment(),
)
Agents
from minisweagent.agents.default import DefaultAgent
from minisweagent.models import get_model
from minisweagent.environments.local import LocalEnvironment
agent = DefaultAgent(
get_model(model_name=model_name),
LocalEnvironment(),
)
from minisweagent.agents.interactive import InteractiveAgent
from minisweagent.models import get_model
from minisweagent.environments.local import LocalEnvironment
agent = InteractiveAgent(
LitellmModel(model_name=model_name),
LocalEnvironment(),
)
from minisweagent.agents.interactive_textual import TextualAgent
from minisweagent.models import get_model
from minisweagent.environments.local import LocalEnvironment
agent = TextualAgent(
LitellmModel(model_name=model_name),
LocalEnvironment(),
)
Advanced
Customizing execution
An agent that uses python function for some actions:
from minisweagent.agents.default import DefaultAgent
import shlex
def python_function(*args) -> dict:
...
return {"output": "..."}
class AgentWithPythonFunctions(DefaultAgent):
def execute_action(self, action: dict) -> dict:
if action["action"].startswith("python_function"):
args = shlex.split(action["action"].removeprefix("python_function").strip())
return python_function(*args)
return super().execute_action(action)
from minisweagent.agents.default import DefaultAgent
import shlex
def python_function(*args) -> dict:
...
return {"output": "..."}
class EnvironmentWithPythonFunctions(LocalEnvironment):
def execute(self, command: str, cwd: str = "") -> dict:
if command.startswith("python_function"):
args = shlex.split(command.removeprefix("python_function").strip())
return python_function(*args)
return super().execute(command, cwd)
agent = DefaultAgent(
LitellmModel(model_name=model_name),
EnvironmentWithPythonFunctions(),
)
An agent that exits when the submit
command is issued:
from minisweagent.agents.default import DefaultAgent, Submitted
class AgentQuitsOnSubmit(DefaultAgent):
def execute_action(self, action: dict) -> dict:
if action["action"] == "submit":
# The `Submitted` exception will be caught by the agent and
# the final output will be printed.
raise Submitted("The agent has finished its task.")
return super().execute_action(action)
from minisweagent.agents.default import DefaultAgent, Submitted
from minisweagent.environments.local import LocalEnvironment
class EnvironmentQuitsOnSubmit(LocalEnvironment):
def execute(self, command: str, cwd: str = "") -> dict:
if command == "submit":
raise Submitted("The agent has finished its task.")
return super().execute(command, cwd)
agent = DefaultAgent(
LitellmModel(model_name=model_name),
EnvironmentQuitsOnSubmit(),
)
An agent that validates actions before execution (also an example of how to use an extended config class):
import re
from dataclasses import dataclass
from minisweagent.agents.default import (
DefaultAgent, NonTerminatingException, DefaultAgentConfig
)
@dataclass
class ValidatingAgentConfig(DefaultAgentConfig):
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_action(self, action: dict) -> dict:
for pattern in self.config.forbidden_patterns:
if re.search(pattern, action["action"], re.IGNORECASE):
raise NonTerminatingException("Action blocked")
return super().execute_action(action)
import re
from dataclasses import dataclass
from minisweagent.agents.default import (
DefaultAgent, NonTerminatingException, DefaultAgentConfig
)
from minisweagent.environments.local import LocalEnvironment
@dataclass
class EnvironmentWithForbiddenPatternsConfig(LocalEnvironmentConfig):
forbidden_patterns: list[str] = [
r"rm -rf /",
r"sudo.*passwd",
r"mkfs\.",
]
class EnvironmentWithForbiddenPatterns(LocalEnvironment):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs, config_class=EnvironmentWithForbiddenPatternsConfig)
def execute(self, command: str, cwd: str = "") -> dict:
for pattern in self.config.forbidden_patterns:
if re.search(pattern, command, re.IGNORECASE):
raise NonTerminatingException("Action blocked")
return super().execute(command, cwd)
agent = DefaultAgent(
LitellmModel(model_name=model_name),
EnvironmentWithForbiddenPatterns(),
)