mini-swe-agent 1.11.1__tar.gz → 1.13.0__tar.gz

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.
Files changed (62) hide show
  1. {mini_swe_agent-1.11.1/src/mini_swe_agent.egg-info → mini_swe_agent-1.13.0}/PKG-INFO +5 -3
  2. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/README.md +4 -2
  3. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0/src/mini_swe_agent.egg-info}/PKG-INFO +5 -3
  4. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/mini_swe_agent.egg-info/SOURCES.txt +1 -0
  5. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/__init__.py +2 -2
  6. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/agents/default.py +1 -1
  7. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/docker.py +2 -2
  8. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/extra/bubblewrap.py +2 -2
  9. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/extra/swerex_docker.py +2 -2
  10. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/local.py +2 -2
  11. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/singularity.py +2 -2
  12. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/__init__.py +1 -0
  13. mini_swe_agent-1.13.0/src/minisweagent/models/portkey_model.py +107 -0
  14. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/swebench.py +3 -2
  15. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/swebench_single.py +3 -1
  16. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/github_issue.py +3 -1
  17. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/mini.py +3 -1
  18. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/LICENSE.md +0 -0
  19. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/pyproject.toml +0 -0
  20. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/setup.cfg +0 -0
  21. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/mini_swe_agent.egg-info/dependency_links.txt +0 -0
  22. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/mini_swe_agent.egg-info/entry_points.txt +0 -0
  23. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/mini_swe_agent.egg-info/requires.txt +0 -0
  24. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/mini_swe_agent.egg-info/top_level.txt +0 -0
  25. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/__main__.py +0 -0
  26. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/agents/__init__.py +0 -0
  27. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/agents/interactive.py +0 -0
  28. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/agents/interactive_textual.py +0 -0
  29. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/README.md +0 -0
  30. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/__init__.py +0 -0
  31. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/default.yaml +0 -0
  32. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/extra/__init__.py +0 -0
  33. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/extra/swebench.yaml +0 -0
  34. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/extra/swebench_roulette.yaml +0 -0
  35. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/github_issue.yaml +0 -0
  36. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/mini.tcss +0 -0
  37. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/mini.yaml +0 -0
  38. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/config/mini_no_temp.yaml +0 -0
  39. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/__init__.py +0 -0
  40. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/environments/extra/__init__.py +0 -0
  41. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/anthropic.py +0 -0
  42. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/extra/__init__.py +0 -0
  43. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/extra/roulette.py +0 -0
  44. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/litellm_model.py +0 -0
  45. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/openrouter_model.py +0 -0
  46. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/test_models.py +0 -0
  47. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/utils/__init__.py +0 -0
  48. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/utils/cache_control.py +0 -0
  49. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/models/utils/key_per_thread.py +0 -0
  50. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/py.typed +0 -0
  51. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/__init__.py +0 -0
  52. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/__init__.py +0 -0
  53. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/config.py +0 -0
  54. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/utils/__init__.py +0 -0
  55. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/extra/utils/batch_progress.py +0 -0
  56. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/hello_world.py +0 -0
  57. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/inspector.py +0 -0
  58. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/mini_extra.py +0 -0
  59. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/utils/__init__.py +0 -0
  60. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/run/utils/save.py +0 -0
  61. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/utils/__init__.py +0 -0
  62. {mini_swe_agent-1.11.1 → mini_swe_agent-1.13.0}/src/minisweagent/utils/log.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-swe-agent
3
- Version: 1.11.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
@@ -237,7 +237,8 @@ agent.run("Write a sudoku game")
237
237
  * [Quick start](https://mini-swe-agent.com/latest/quickstart/)
238
238
  * [`mini`](https://mini-swe-agent.com/latest/usage/mini/)
239
239
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
240
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
240
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
241
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
241
242
  * [Power up](https://mini-swe-agent.com/latest/advanced/cookbook/)
242
243
 
243
244
  </td>
@@ -273,7 +274,8 @@ Read more in our [documentation](https://mini-swe-agent.com/latest/):
273
274
 
274
275
  * [Quick start guide](https://mini-swe-agent.com/latest/quickstart/)
275
276
  * More on [`mini`](https://mini-swe-agent.com/latest/usage/mini/) and [`mini -v`](https://mini-swe-agent.com/latest/usage/mini_v/)
276
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
277
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
278
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
277
279
  * [Power up with the cookbook](https://mini-swe-agent.com/latest/advanced/cookbook/)
278
280
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
279
281
  * [Contribute!](https://mini-swe-agent.com/latest/contributing/)
@@ -168,7 +168,8 @@ agent.run("Write a sudoku game")
168
168
  * [Quick start](https://mini-swe-agent.com/latest/quickstart/)
169
169
  * [`mini`](https://mini-swe-agent.com/latest/usage/mini/)
170
170
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
171
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
171
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
172
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
172
173
  * [Power up](https://mini-swe-agent.com/latest/advanced/cookbook/)
173
174
 
174
175
  </td>
@@ -204,7 +205,8 @@ Read more in our [documentation](https://mini-swe-agent.com/latest/):
204
205
 
205
206
  * [Quick start guide](https://mini-swe-agent.com/latest/quickstart/)
206
207
  * More on [`mini`](https://mini-swe-agent.com/latest/usage/mini/) and [`mini -v`](https://mini-swe-agent.com/latest/usage/mini_v/)
207
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
208
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
209
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
208
210
  * [Power up with the cookbook](https://mini-swe-agent.com/latest/advanced/cookbook/)
209
211
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
210
212
  * [Contribute!](https://mini-swe-agent.com/latest/contributing/)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mini-swe-agent
3
- Version: 1.11.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
@@ -237,7 +237,8 @@ agent.run("Write a sudoku game")
237
237
  * [Quick start](https://mini-swe-agent.com/latest/quickstart/)
238
238
  * [`mini`](https://mini-swe-agent.com/latest/usage/mini/)
239
239
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
240
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
240
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
241
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
241
242
  * [Power up](https://mini-swe-agent.com/latest/advanced/cookbook/)
242
243
 
243
244
  </td>
@@ -273,7 +274,8 @@ Read more in our [documentation](https://mini-swe-agent.com/latest/):
273
274
 
274
275
  * [Quick start guide](https://mini-swe-agent.com/latest/quickstart/)
275
276
  * More on [`mini`](https://mini-swe-agent.com/latest/usage/mini/) and [`mini -v`](https://mini-swe-agent.com/latest/usage/mini_v/)
276
- * [Configuration](https://mini-swe-agent.com/latest/advanced/configuration/)
277
+ * [Global configuration](https://mini-swe-agent.com/latest/advanced/global_configuration/)
278
+ * [Yaml configuration files](https://mini-swe-agent.com/latest/advanced/yaml_configuration/)
277
279
  * [Power up with the cookbook](https://mini-swe-agent.com/latest/advanced/cookbook/)
278
280
  * [FAQ](https://mini-swe-agent.com/latest/faq/)
279
281
  * [Contribute!](https://mini-swe-agent.com/latest/contributing/)
@@ -35,6 +35,7 @@ src/minisweagent/models/__init__.py
35
35
  src/minisweagent/models/anthropic.py
36
36
  src/minisweagent/models/litellm_model.py
37
37
  src/minisweagent/models/openrouter_model.py
38
+ src/minisweagent/models/portkey_model.py
38
39
  src/minisweagent/models/test_models.py
39
40
  src/minisweagent/models/extra/__init__.py
40
41
  src/minisweagent/models/extra/roulette.py
@@ -8,7 +8,7 @@ This file provides:
8
8
  unless you want the static type checking.
9
9
  """
10
10
 
11
- __version__ = "1.11.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"Your config is stored in [bold green]'{global_config_file}'[/bold green]"
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
 
@@ -106,7 +106,7 @@ class DefaultAgent:
106
106
 
107
107
  def parse_action(self, response: dict) -> dict:
108
108
  """Parse the action from the message. Returns the action."""
109
- actions = re.findall(r"```bash\n(.*?)\n```", response["content"], re.DOTALL)
109
+ actions = re.findall(r"```bash\s*\n(.*?)\n```", response["content"], re.DOTALL)
110
110
  if len(actions) == 1:
111
111
  return {"action": actions[0].strip(), **response}
112
112
  raise FormatError(self.render_template(self.config.format_error_template, actions=actions))
@@ -73,7 +73,7 @@ class DockerEnvironment:
73
73
  self.logger.info(f"Started container {container_name} with ID {result.stdout.strip()}")
74
74
  self.container_id = result.stdout.strip()
75
75
 
76
- def execute(self, command: str, cwd: str = "") -> dict[str, Any]:
76
+ def execute(self, command: str, cwd: str = "", *, timeout: int | None = None) -> dict[str, Any]:
77
77
  """Execute a command in the Docker container and return the result as a dict."""
78
78
  cwd = cwd or self.config.cwd
79
79
  assert self.container_id, "Container not started"
@@ -89,7 +89,7 @@ class DockerEnvironment:
89
89
  result = subprocess.run(
90
90
  cmd,
91
91
  text=True,
92
- timeout=self.config.timeout,
92
+ timeout=timeout or self.config.timeout,
93
93
  encoding="utf-8",
94
94
  errors="replace",
95
95
  stdout=subprocess.PIPE,
@@ -77,7 +77,7 @@ class BubblewrapEnvironment:
77
77
  self.working_dir = Path(tempfile.gettempdir()) / f"minisweagent-{uuid.uuid4().hex[:8]}"
78
78
  self.working_dir.mkdir(parents=True)
79
79
 
80
- def execute(self, command: str, cwd: str = "") -> dict[str, Any]:
80
+ def execute(self, command: str, cwd: str = "", *, timeout: int | None = None) -> dict[str, Any]:
81
81
  """Execute a command in the bubblewrap environment and return the result as a dict."""
82
82
  cwd = cwd or self.config.cwd or str(self.working_dir)
83
83
 
@@ -92,7 +92,7 @@ class BubblewrapEnvironment:
92
92
  result = subprocess.run(
93
93
  cmd,
94
94
  text=True,
95
- timeout=self.config.timeout,
95
+ timeout=timeout or self.config.timeout,
96
96
  encoding="utf-8",
97
97
  errors="replace",
98
98
  stdout=subprocess.PIPE,
@@ -24,7 +24,7 @@ class SwerexDockerEnvironment:
24
24
  self.deployment = DockerDeployment(image=self.config.image, **self.config.deployment_extra_kwargs)
25
25
  asyncio.run(self.deployment.start())
26
26
 
27
- def execute(self, command: str, cwd: str = "") -> dict[str, Any]:
27
+ def execute(self, command: str, cwd: str = "", *, timeout: int | None = None) -> dict[str, Any]:
28
28
  """Execute a command in the environment and return the raw output."""
29
29
  output = asyncio.run(
30
30
  self.deployment.runtime.execute(
@@ -33,7 +33,7 @@ class SwerexDockerEnvironment:
33
33
  shell=True,
34
34
  check=False,
35
35
  cwd=cwd or self.config.cwd,
36
- timeout=self.config.timeout,
36
+ timeout=timeout or self.config.timeout,
37
37
  merge_output_streams=True,
38
38
  )
39
39
  )
@@ -17,7 +17,7 @@ class LocalEnvironment:
17
17
  """This class executes bash commands directly on the local machine."""
18
18
  self.config = config_class(**kwargs)
19
19
 
20
- def execute(self, command: str, cwd: str = ""):
20
+ def execute(self, command: str, cwd: str = "", *, timeout: int | None = None):
21
21
  """Execute a command in the local environment and return the result as a dict."""
22
22
  cwd = cwd or self.config.cwd or os.getcwd()
23
23
  result = subprocess.run(
@@ -26,7 +26,7 @@ class LocalEnvironment:
26
26
  text=True,
27
27
  cwd=cwd,
28
28
  env=os.environ | self.config.env,
29
- timeout=self.config.timeout,
29
+ timeout=timeout or self.config.timeout,
30
30
  encoding="utf-8",
31
31
  errors="replace",
32
32
  stdout=subprocess.PIPE,
@@ -60,7 +60,7 @@ class SingularityEnvironment:
60
60
  def get_template_vars(self) -> dict[str, Any]:
61
61
  return asdict(self.config)
62
62
 
63
- def execute(self, command: str, cwd: str = "") -> dict[str, Any]:
63
+ def execute(self, command: str, cwd: str = "", *, timeout: int | None = None) -> dict[str, Any]:
64
64
  """Execute a command in a Singularity container and return the result as a dict."""
65
65
  cmd = [self.config.executable, "exec"]
66
66
 
@@ -81,7 +81,7 @@ class SingularityEnvironment:
81
81
  result = subprocess.run(
82
82
  cmd,
83
83
  text=True,
84
- timeout=self.config.timeout,
84
+ timeout=timeout or self.config.timeout,
85
85
  encoding="utf-8",
86
86
  errors="replace",
87
87
  stdout=subprocess.PIPE,
@@ -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 = yaml.safe_load(get_config_path(config_spec).read_text())
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
- config = yaml.safe_load(get_config_path(config_path).read_text())
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:
@@ -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
- _config = yaml.safe_load(get_config_path(config).read_text())
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"
@@ -58,7 +58,9 @@ def main(
58
58
  ) -> Any:
59
59
  # fmt: on
60
60
  configure_if_first_time()
61
- config = yaml.safe_load(get_config_path(config_spec).read_text())
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?")