Skip to content

Commit 3030a63

Browse files
committed
fix: DockerSetupAgent use correct LLM API (GenerationRequest) + fix publisher import
1 parent 3bfbdc3 commit 3030a63

2 files changed

Lines changed: 39 additions & 53 deletions

File tree

continuous_pipeline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def build_and_push_docker(task_dir: Path) -> bool:
8080
try:
8181
sys.path.insert(0, "src")
8282
from swe_forge.agents.docker_setup_agent import DockerSetupAgent
83-
from swe_forge.llm import OpenRouterClient
83+
from swe_forge.llm.openrouter import OpenRouterClient
8484

8585
openrouter_key = os.environ.get("OPENROUTER_API_KEY", "")
8686
if not openrouter_key:

src/swe_forge/agents/docker_setup_agent.py

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -65,58 +65,45 @@
6565
REPO: {repo_url}
6666
"""
6767

68-
TOOLS = [
69-
{
70-
"type": "function",
71-
"function": {
72-
"name": "shell",
73-
"description": "Execute a shell command in the Docker container. Returns stdout+stderr and exit code.",
74-
"parameters": {
68+
def _get_tools():
69+
from swe_forge.llm.client import ToolDefinition
70+
return [
71+
ToolDefinition.create(
72+
"shell",
73+
"Execute a shell command in the Docker container. Returns stdout+stderr and exit code.",
74+
{
7575
"type": "object",
7676
"properties": {
77-
"command": {
78-
"type": "string",
79-
"description": "The shell command to execute",
80-
},
81-
"timeout": {
82-
"type": "integer",
83-
"description": "Timeout in seconds (default 300)",
84-
},
77+
"command": {"type": "string", "description": "The shell command to execute"},
78+
"timeout": {"type": "integer", "description": "Timeout in seconds (default 300)"},
8579
},
8680
"required": ["command"],
8781
},
88-
},
89-
},
90-
{
91-
"type": "function",
92-
"function": {
93-
"name": "read_file",
94-
"description": "Read a file from the container.",
95-
"parameters": {
82+
),
83+
ToolDefinition.create(
84+
"read_file",
85+
"Read a file from the container.",
86+
{
9687
"type": "object",
9788
"properties": {
9889
"path": {"type": "string", "description": "Absolute path in the container"},
9990
},
10091
"required": ["path"],
10192
},
102-
},
103-
},
104-
{
105-
"type": "function",
106-
"function": {
107-
"name": "done",
108-
"description": "Signal that setup is complete. Call with success=true when fail_to_pass FAIL on base AND PASS after patch.",
109-
"parameters": {
93+
),
94+
ToolDefinition.create(
95+
"done",
96+
"Signal that setup is complete. Call with success=true when fail_to_pass FAIL on base AND PASS after patch.",
97+
{
11098
"type": "object",
11199
"properties": {
112100
"success": {"type": "boolean"},
113101
"error": {"type": "string", "description": "Error description if success=false"},
114102
},
115103
"required": ["success"],
116104
},
117-
},
118-
},
119-
]
105+
),
106+
]
120107

121108

122109
def _docker_exec(container: str, cmd: str, timeout: int = SHELL_TIMEOUT) -> tuple[int, str]:
@@ -259,7 +246,7 @@ async def _run_agent_loop(
259246
install_commands: list[str],
260247
) -> bool:
261248
"""Run the LLM agent loop to set up the environment."""
262-
from swe_forge.llm import Message
249+
from swe_forge.llm.client import GenerationRequest, Message
263250

264251
system = SYSTEM_PROMPT.format(
265252
max_turns=self._max_turns,
@@ -269,30 +256,33 @@ async def _run_agent_loop(
269256
repo_url=repo_url,
270257
)
271258

272-
messages: list[dict[str, Any]] = [{"role": "system", "content": system}]
273-
messages.append({"role": "user", "content": (
274-
f"Set up this repo and validate the tests. Start by exploring the repo structure "
275-
f"to understand what language/framework is used, then install dependencies."
276-
)})
259+
tools = _get_tools()
260+
messages: list[Message] = [
261+
Message.system(system),
262+
Message.user(
263+
"Set up this repo and validate the tests. Start by exploring the repo structure "
264+
"to understand what language/framework is used, then install dependencies."
265+
),
266+
]
277267

278268
for turn in range(self._max_turns):
279-
response = await self._llm.chat(
280-
messages=messages,
269+
request = GenerationRequest(
281270
model=self._model,
282-
tools=TOOLS,
271+
messages=messages,
272+
tools=tools,
283273
temperature=0.2,
284274
max_tokens=4096,
285275
)
276+
response = await self._llm.complete_with_tools(request)
286277

287278
msg = response.choices[0].message
288-
messages.append(msg.model_dump(exclude_none=True))
279+
messages.append(msg)
289280

290281
if not msg.tool_calls:
291-
# Model responded with text, no tool call -- nudge it
292282
if msg.content and ("done" in msg.content.lower() or "success" in msg.content.lower()):
293-
messages.append({"role": "user", "content": "You must call the done() tool to finish."})
283+
messages.append(Message.user("You must call the done() tool to finish."))
294284
else:
295-
messages.append({"role": "user", "content": "Continue. Use tools to make progress."})
285+
messages.append(Message.user("Continue. Use tools to make progress."))
296286
continue
297287

298288
for tc in msg.tool_calls:
@@ -326,11 +316,7 @@ async def _run_agent_loop(
326316
else:
327317
tool_result = f"Unknown tool: {fn}"
328318

329-
messages.append({
330-
"role": "tool",
331-
"tool_call_id": tc.id,
332-
"content": tool_result[:8000],
333-
})
319+
messages.append(Message(role="tool", content=tool_result[:8000], tool_call_id=tc.id))
334320

335321
logger.warning("[%s] Agent exhausted %d turns", task_id, self._max_turns)
336322
return False

0 commit comments

Comments
 (0)