mini-swe-agent 1.12.0__py3-none-any.whl → 1.13.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/METADATA +1 -1
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/RECORD +13 -12
- minisweagent/__init__.py +2 -2
- minisweagent/models/__init__.py +1 -0
- minisweagent/models/portkey_model.py +107 -0
- minisweagent/run/extra/swebench.py +3 -2
- minisweagent/run/extra/swebench_single.py +3 -1
- minisweagent/run/github_issue.py +3 -1
- minisweagent/run/mini.py +3 -1
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/WHEEL +0 -0
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/entry_points.txt +0 -0
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/licenses/LICENSE.md +0 -0
- {mini_swe_agent-1.12.0.dist-info → mini_swe_agent-1.13.0.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mini-swe-agent
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.0
|
|
4
4
|
Summary: Nano SWE Agent - A simple AI software engineering agent
|
|
5
5
|
Author-email: Kilian Lieret <kilian.lieret@posteo.de>, "Carlos E. Jimenez" <carlosej@princeton.edu>
|
|
6
6
|
License: MIT License
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
mini_swe_agent-1.
|
|
2
|
-
minisweagent/__init__.py,sha256=
|
|
1
|
+
mini_swe_agent-1.13.0.dist-info/licenses/LICENSE.md,sha256=D3luWPkdHAe7LBsdD4vzqDAXw6Xewb3G-uczss0uh1s,1094
|
|
2
|
+
minisweagent/__init__.py,sha256=AV8y_FPibz99WsO-rGjKRkyf0gJhEx5RGP6IBamLGG0,2016
|
|
3
3
|
minisweagent/__main__.py,sha256=FIyAOiw--c3FQ2g240FOM1FdL0lk_PxSpixu0pQ7WFo,194
|
|
4
4
|
minisweagent/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
minisweagent/agents/__init__.py,sha256=cpjJLzg1IGxLM-tZpoMJV9S33ye13XtdBO0x7DU_Lrk,48
|
|
@@ -23,10 +23,11 @@ minisweagent/environments/singularity.py,sha256=HSwRTWef7cMCgBiGAh5DIrxW8HkZ9C9Z
|
|
|
23
23
|
minisweagent/environments/extra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
minisweagent/environments/extra/bubblewrap.py,sha256=G12Dm63N30qByfLb1SKNsI4G4gLyKBfomnOIsPqRNZk,3662
|
|
25
25
|
minisweagent/environments/extra/swerex_docker.py,sha256=WPYbohT_vqTHkde9cxpbV6chLXCpLl0PDAcgMbZsV0M,1707
|
|
26
|
-
minisweagent/models/__init__.py,sha256=
|
|
26
|
+
minisweagent/models/__init__.py,sha256=hMRTK5yfn2vymiXecZsSAGusxsTvrnQQVm8ih0y_PNM,4081
|
|
27
27
|
minisweagent/models/anthropic.py,sha256=D8nHvvbgzPjla0He8p0O9kaXASPWg1Sai0pHsAj_Yn8,855
|
|
28
28
|
minisweagent/models/litellm_model.py,sha256=RSvNzK6ksOOcTEY-kM36KJql9-iSH29kq0cKYXj2mxE,3034
|
|
29
29
|
minisweagent/models/openrouter_model.py,sha256=ugI3322pyUQ8wBOuMysPoKlp0oRAmR38a6GcdjE6qHI,3748
|
|
30
|
+
minisweagent/models/portkey_model.py,sha256=hsaZJhQvzGSM88BJqTEZGvR7G_wczdKayhbtC5jex44,3814
|
|
30
31
|
minisweagent/models/test_models.py,sha256=ItCA6ddntzkYA7dzSuUEaLMV-AE8TBuXBFP8CzpiO3U,1351
|
|
31
32
|
minisweagent/models/extra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
33
|
minisweagent/models/extra/roulette.py,sha256=SqLj_wz9Vkbxou7i9Ef4Uzmg_eheDouNySkkV7pm2Ys,2093
|
|
@@ -34,23 +35,23 @@ minisweagent/models/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
34
35
|
minisweagent/models/utils/cache_control.py,sha256=mG9cE56HQaUwXfoqvXoH6LcbMV_G1vlEE1aBBpikXYg,1608
|
|
35
36
|
minisweagent/models/utils/key_per_thread.py,sha256=Vlxt--rapNNYCgIHrMCu1WVAkuiVIhC_awbarkbnkZQ,644
|
|
36
37
|
minisweagent/run/__init__.py,sha256=WIoYgHVl7iZF2YncrfV3IttupG6P5KogroKHKECka3A,38
|
|
37
|
-
minisweagent/run/github_issue.py,sha256=
|
|
38
|
+
minisweagent/run/github_issue.py,sha256=35mZoPLc4JV6XXJKRv55lnuKbXf5lDftd51N89-x9J0,3192
|
|
38
39
|
minisweagent/run/hello_world.py,sha256=erLnEwNmPFLxq3-8zyv66Vy1kIqMqQf97vISX7LrQXg,959
|
|
39
40
|
minisweagent/run/inspector.py,sha256=QnY3oYzm-yq3w9Jzs112Lco2Rg84vSocAWrQRVz_1lc,7127
|
|
40
|
-
minisweagent/run/mini.py,sha256=
|
|
41
|
+
minisweagent/run/mini.py,sha256=m916OtSd8Wj2bUjfLGedNN-d2axTwZirM4AYmymXip8,4933
|
|
41
42
|
minisweagent/run/mini_extra.py,sha256=ecA1PnTWElpO60G9RktvVLtUOf3bZ_ESmnSttS6izhQ,1465
|
|
42
43
|
minisweagent/run/extra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
44
|
minisweagent/run/extra/config.py,sha256=L5Xe7VGX1HMBlPac9aBufPnHA9duJpZYrbqXVtr8O6w,3845
|
|
44
|
-
minisweagent/run/extra/swebench.py,sha256=
|
|
45
|
-
minisweagent/run/extra/swebench_single.py,sha256=
|
|
45
|
+
minisweagent/run/extra/swebench.py,sha256=sO3LnjLXdU6Zbo409YhxVdizU8LaQcJUdcD8Tj6saMw,11741
|
|
46
|
+
minisweagent/run/extra/swebench_single.py,sha256=KmoUkD6UQ1P0MY_73-OtYuQAsNPmOLlZIZSYKZGs5MQ,3699
|
|
46
47
|
minisweagent/run/extra/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
48
|
minisweagent/run/extra/utils/batch_progress.py,sha256=xhJ7FmsaTBGz-yh8pzYl4yMoUGjn7GA24eYrP-nHj60,6804
|
|
48
49
|
minisweagent/run/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
50
|
minisweagent/run/utils/save.py,sha256=2xd-UnUzI7Fr_AUZ5KEJ53Aa4kpuuGYxkLwyUcvqyMM,2503
|
|
50
51
|
minisweagent/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
51
52
|
minisweagent/utils/log.py,sha256=ruDMNKMrVC9NPvCeHwO3QYz5jsVNUGQB2dRAEAPAWp8,996
|
|
52
|
-
mini_swe_agent-1.
|
|
53
|
-
mini_swe_agent-1.
|
|
54
|
-
mini_swe_agent-1.
|
|
55
|
-
mini_swe_agent-1.
|
|
56
|
-
mini_swe_agent-1.
|
|
53
|
+
mini_swe_agent-1.13.0.dist-info/METADATA,sha256=Orz3vqB1mYJeHD0WXH4-IWS3GQkHKaFsd8rAxLKDItU,14102
|
|
54
|
+
mini_swe_agent-1.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
55
|
+
mini_swe_agent-1.13.0.dist-info/entry_points.txt,sha256=d1_yRbTaGjs1UXHa6JQK0sKDGBIVGm8oeW0k2kfbJgQ,182
|
|
56
|
+
mini_swe_agent-1.13.0.dist-info/top_level.txt,sha256=zKF4t8bFpV87fdVABZt2Da-vnb4Vkh_CxkwQx5YT4Ew,13
|
|
57
|
+
mini_swe_agent-1.13.0.dist-info/RECORD,,
|
minisweagent/__init__.py
CHANGED
|
@@ -8,7 +8,7 @@ This file provides:
|
|
|
8
8
|
unless you want the static type checking.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = "1.
|
|
11
|
+
__version__ = "1.13.0"
|
|
12
12
|
|
|
13
13
|
import os
|
|
14
14
|
from pathlib import Path
|
|
@@ -29,7 +29,7 @@ global_config_file = Path(global_config_dir) / ".env"
|
|
|
29
29
|
if not os.getenv("MSWEA_SILENT_STARTUP"):
|
|
30
30
|
Console().print(
|
|
31
31
|
f"👋 This is [bold green]mini-swe-agent[/bold green] version [bold green]{__version__}[/bold green].\n"
|
|
32
|
-
f"
|
|
32
|
+
f"Loading global config from [bold green]'{global_config_file}'[/bold green]"
|
|
33
33
|
)
|
|
34
34
|
dotenv.load_dotenv(dotenv_path=global_config_file)
|
|
35
35
|
|
minisweagent/models/__init__.py
CHANGED
|
@@ -75,6 +75,7 @@ _MODEL_CLASS_MAPPING = {
|
|
|
75
75
|
"anthropic": "minisweagent.models.anthropic.AnthropicModel",
|
|
76
76
|
"litellm": "minisweagent.models.litellm_model.LitellmModel",
|
|
77
77
|
"openrouter": "minisweagent.models.openrouter_model.OpenRouterModel",
|
|
78
|
+
"portkey": "minisweagent.models.portkey_model.PortkeyModel",
|
|
78
79
|
"deterministic": "minisweagent.models.test_models.DeterministicModel",
|
|
79
80
|
}
|
|
80
81
|
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import asdict, dataclass, field
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
import litellm
|
|
9
|
+
from tenacity import (
|
|
10
|
+
before_sleep_log,
|
|
11
|
+
retry,
|
|
12
|
+
retry_if_not_exception_type,
|
|
13
|
+
stop_after_attempt,
|
|
14
|
+
wait_exponential,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
from minisweagent.models import GLOBAL_MODEL_STATS
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger("portkey_model")
|
|
20
|
+
|
|
21
|
+
try:
|
|
22
|
+
from portkey_ai import Portkey
|
|
23
|
+
except ImportError:
|
|
24
|
+
Portkey = None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class PortkeyModelConfig:
|
|
29
|
+
model_name: str
|
|
30
|
+
model_kwargs: dict[str, Any] = field(default_factory=dict)
|
|
31
|
+
litellm_model_registry: Path | str | None = os.getenv("LITELLM_MODEL_REGISTRY_PATH")
|
|
32
|
+
"""We currently use litellm to calculate costs. Here you can register additional models to litellm's model registry.
|
|
33
|
+
Note that this might change if we get better support for Portkey.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class PortkeyModel:
|
|
38
|
+
def __init__(self, **kwargs):
|
|
39
|
+
if Portkey is None:
|
|
40
|
+
raise ImportError(
|
|
41
|
+
"The portkey-ai package is required to use PortkeyModel. Please install it with: pip install portkey-ai"
|
|
42
|
+
)
|
|
43
|
+
self.config = PortkeyModelConfig(**kwargs)
|
|
44
|
+
self.cost = 0.0
|
|
45
|
+
self.n_calls = 0
|
|
46
|
+
if self.config.litellm_model_registry and Path(self.config.litellm_model_registry).is_file():
|
|
47
|
+
litellm.utils.register_model(json.loads(Path(self.config.litellm_model_registry).read_text()))
|
|
48
|
+
|
|
49
|
+
# Get API key from environment or raise error
|
|
50
|
+
self._api_key = os.getenv("PORTKEY_API_KEY")
|
|
51
|
+
if not self._api_key:
|
|
52
|
+
raise ValueError(
|
|
53
|
+
"Portkey API key is required. Set it via the "
|
|
54
|
+
"PORTKEY_API_KEY environment variable. You can permanently set it with "
|
|
55
|
+
"`mini-extra config set PORTKEY_API_KEY YOUR_KEY`."
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# Get virtual key from environment
|
|
59
|
+
virtual_key = os.getenv("PORTKEY_VIRTUAL_KEY")
|
|
60
|
+
|
|
61
|
+
# Initialize Portkey client
|
|
62
|
+
client_kwargs = {"api_key": self._api_key}
|
|
63
|
+
if virtual_key:
|
|
64
|
+
client_kwargs["virtual_key"] = virtual_key
|
|
65
|
+
|
|
66
|
+
self.client = Portkey(**client_kwargs)
|
|
67
|
+
|
|
68
|
+
@retry(
|
|
69
|
+
stop=stop_after_attempt(10),
|
|
70
|
+
wait=wait_exponential(multiplier=1, min=4, max=60),
|
|
71
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
|
72
|
+
retry=retry_if_not_exception_type((KeyboardInterrupt, TypeError, ValueError)),
|
|
73
|
+
)
|
|
74
|
+
def _query(self, messages: list[dict[str, str]], **kwargs):
|
|
75
|
+
# return self.client.with_options(metadata={"request_id": request_id}).chat.completions.create(
|
|
76
|
+
return self.client.chat.completions.create(
|
|
77
|
+
model=self.config.model_name,
|
|
78
|
+
messages=messages,
|
|
79
|
+
**(self.config.model_kwargs | kwargs),
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def query(self, messages: list[dict[str, str]], **kwargs) -> dict:
|
|
83
|
+
response = self._query(messages, **kwargs)
|
|
84
|
+
try:
|
|
85
|
+
cost = litellm.cost_calculator.completion_cost(response)
|
|
86
|
+
except Exception as e:
|
|
87
|
+
logger.critical(
|
|
88
|
+
f"Error calculating cost for model {self.config.model_name}: {e}. "
|
|
89
|
+
"Please check the 'Updating the model registry' section in the documentation at "
|
|
90
|
+
"https://klieret.short.gy/litellm-model-registry Still stuck? Please open a github issue for help!"
|
|
91
|
+
)
|
|
92
|
+
raise
|
|
93
|
+
|
|
94
|
+
self.n_calls += 1
|
|
95
|
+
self.cost += cost
|
|
96
|
+
GLOBAL_MODEL_STATS.add(cost)
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
"content": response.choices[0].message.content or "",
|
|
100
|
+
"extra": {
|
|
101
|
+
"response": response.model_dump(),
|
|
102
|
+
"cost": cost,
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
def get_template_vars(self) -> dict[str, Any]:
|
|
107
|
+
return asdict(self.config) | {"n_model_calls": self.n_calls, "model_cost": self.cost}
|
|
@@ -221,8 +221,9 @@ def main(
|
|
|
221
221
|
instances = [instance for instance in instances if instance["instance_id"] not in existing_instances]
|
|
222
222
|
logger.info(f"Running on {len(instances)} instances...")
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
config
|
|
224
|
+
config_path = get_config_path(config_spec)
|
|
225
|
+
logger.info(f"Loading agent config from '{config_path}'")
|
|
226
|
+
config = yaml.safe_load(config_path.read_text())
|
|
226
227
|
if environment_class is not None:
|
|
227
228
|
config.setdefault("environment", {})["environment_class"] = environment_class
|
|
228
229
|
if model is not None:
|
|
@@ -48,7 +48,9 @@ def main(
|
|
|
48
48
|
instance_spec = sorted(instances.keys())[int(instance_spec)]
|
|
49
49
|
instance: dict = instances[instance_spec] # type: ignore
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
config_path = get_config_path(config_path)
|
|
52
|
+
logger.info(f"Loading agent config from '{config_path}'")
|
|
53
|
+
config = yaml.safe_load(config_path.read_text())
|
|
52
54
|
if environment_class is not None:
|
|
53
55
|
config.setdefault("environment", {})["environment_class"] = environment_class
|
|
54
56
|
if model_class is not None:
|
minisweagent/run/github_issue.py
CHANGED
|
@@ -50,7 +50,9 @@ def main(
|
|
|
50
50
|
"""Run mini-SWE-agent on a GitHub issue"""
|
|
51
51
|
configure_if_first_time()
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
config_path = get_config_path(config)
|
|
54
|
+
console.print(f"Loading agent config from [bold green]'{config_path}'[/bold green]")
|
|
55
|
+
_config = yaml.safe_load(config_path.read_text())
|
|
54
56
|
_agent_config = _config.setdefault("agent", {})
|
|
55
57
|
if yolo:
|
|
56
58
|
_agent_config["mode"] = "yolo"
|
minisweagent/run/mini.py
CHANGED
|
@@ -58,7 +58,9 @@ def main(
|
|
|
58
58
|
) -> Any:
|
|
59
59
|
# fmt: on
|
|
60
60
|
configure_if_first_time()
|
|
61
|
-
|
|
61
|
+
config_path = get_config_path(config_spec)
|
|
62
|
+
console.print(f"Loading agent config from [bold green]'{config_path}'[/bold green]")
|
|
63
|
+
config = yaml.safe_load(config_path.read_text())
|
|
62
64
|
|
|
63
65
|
if not task:
|
|
64
66
|
console.print("[bold yellow]What do you want to do?")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|