Skip to content

Commit 48b1d66

Browse files
committed
refactor configuration structure in config.py and config.example.yaml; enhance LLM and Memory handling in run_swebench_multimodal.py
1 parent 8238aae commit 48b1d66

3 files changed

Lines changed: 95 additions & 51 deletions

File tree

argus/config.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,29 @@ class AgentConfig:
4545
max_steps: int = 30
4646
log_dir: str | None = "logs/"
4747
enable_memory: bool = False
48+
LLM: LLMConfig = field(default_factory=LLMConfig)
49+
Memory: MemoryConfig = field(default_factory=MemoryConfig)
50+
51+
52+
@dataclass
53+
class WebAgentConfig:
54+
"""Configuration for the web-use verification agent."""
55+
56+
system_prompt: str = ""
57+
headless: bool = True
58+
max_steps: int = 20
59+
log_dir: str | None = "logs/"
60+
enable_memory: bool = False
61+
LLM: LLMConfig = field(default_factory=LLMConfig)
62+
Memory: MemoryConfig = field(default_factory=MemoryConfig)
4863

4964

5065
@dataclass
5166
class Config:
5267
"""Top-level Argus configuration."""
5368

54-
llm: LLMConfig = field(default_factory=LLMConfig)
5569
agent: AgentConfig = field(default_factory=AgentConfig)
56-
memory: MemoryConfig = field(default_factory=MemoryConfig)
70+
web_agent: WebAgentConfig = field(default_factory=WebAgentConfig)
5771

5872
@classmethod
5973
def from_yaml(cls, path: str | Path = "config.yaml") -> Config:
@@ -71,8 +85,23 @@ def from_yaml(cls, path: str | Path = "config.yaml") -> Config:
7185
with open(path) as f:
7286
data = yaml.safe_load(f) or {}
7387

88+
def _load_agent(d: dict) -> AgentConfig:
89+
d = d.copy()
90+
if "LLM" in d and isinstance(d["LLM"], dict):
91+
d["LLM"] = LLMConfig(**d["LLM"])
92+
if "Memory" in d and isinstance(d["Memory"], dict):
93+
d["Memory"] = MemoryConfig(**d["Memory"])
94+
return AgentConfig(**d)
95+
96+
def _load_web_agent(d: dict) -> WebAgentConfig:
97+
d = d.copy()
98+
if "LLM" in d and isinstance(d["LLM"], dict):
99+
d["LLM"] = LLMConfig(**d["LLM"])
100+
if "Memory" in d and isinstance(d["Memory"], dict):
101+
d["Memory"] = MemoryConfig(**d["Memory"])
102+
return WebAgentConfig(**d)
103+
74104
return cls(
75-
llm=LLMConfig(**{k: v for k, v in data.get("llm", {}).items()}),
76-
agent=AgentConfig(**{k: v for k, v in data.get("agent", {}).items()}),
77-
memory=MemoryConfig(**{k: v for k, v in data.get("memory", {}).items()}),
105+
agent=_load_agent(data.get("agent", {})),
106+
web_agent=_load_web_agent(data.get("web_agent", {})),
78107
)

config.example.yaml

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
llm:
2-
provider: openai # "openai" | "anthropic"
3-
model: gpt-5
4-
api_key: "" # or set via LLM_API_KEY env var
5-
base_url: "" # leave empty for default endpoint
6-
temperature: null # null = use provider default; e.g. 0.0 for deterministic output
7-
81
agent:
92
max_steps: 30
103
log_dir: logs/
@@ -15,10 +8,32 @@ agent:
158
IMPORTANT: To execute commands you MUST call the shell tool — do NOT just write bash code blocks in your response text, as those are not executed.
169
After each tool call, wait for the result before deciding the next step.
1710
Please briefly explain your reasoning before each tool call.
11+
LLM:
12+
provider: openai # "openai" | "anthropic"
13+
model: gpt-5
14+
api_key: "" # or set via LLM_API_KEY env var
15+
base_url: "" # leave empty for default endpoint
16+
temperature: null # null = use provider default; e.g. 0.0 for deterministic output
17+
Memory:
18+
user_id: default
19+
base_url: http://localhost:1995/api/v1
20+
api_key: null
21+
retrieve_method: hybrid
22+
top_k: 5
1823

19-
memory:
20-
user_id: default
21-
base_url: http://localhost:1995/api/v1
22-
api_key: null
23-
retrieve_method: hybrid
24-
top_k: 5
24+
web_agent:
25+
headless: true
26+
max_steps: 20
27+
log_dir: logs/
28+
LLM:
29+
provider: openai
30+
model: gpt-5
31+
api_key: ""
32+
base_url: ""
33+
temperature: null
34+
Memory:
35+
user_id: default
36+
base_url: http://localhost:1995/api/v1
37+
api_key: null
38+
retrieve_method: hybrid
39+
top_k: 5

run_swebench_multimodal.py

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from datasets import load_dataset
1212

1313
from argus import Agent, EverMindMemory
14-
from argus.config import Config
14+
from argus.config import AgentConfig, Config, LLMConfig
1515
from argus.llm.anthropic import AnthropicClient
1616
from argus.llm.base import LLMClient
1717
from argus.llm.openai import OpenAIClient
@@ -87,40 +87,52 @@ def _build_task_with_images(instance: dict) -> str | list:
8787
return content
8888

8989

90-
def _build_llm(cfg: Config) -> LLMClient:
91-
"""Instantiate the LLM client specified by cfg.llm.provider."""
92-
provider = cfg.llm.provider.lower()
90+
def _build_llm(cfg: LLMConfig) -> LLMClient:
91+
"""Instantiate the LLM client."""
92+
provider = cfg.provider.lower()
9393
if provider == "anthropic":
9494
return AnthropicClient(
95-
model=cfg.llm.model,
96-
api_key=cfg.llm.api_key,
97-
base_url=cfg.llm.base_url or None,
98-
temperature=cfg.llm.temperature,
95+
model=cfg.model,
96+
api_key=cfg.api_key,
97+
base_url=cfg.base_url or None,
98+
temperature=cfg.temperature,
9999
)
100100
if provider == "openai":
101101
return OpenAIClient(
102-
model=cfg.llm.model,
103-
api_key=cfg.llm.api_key,
104-
base_url=cfg.llm.base_url or None,
105-
temperature=cfg.llm.temperature,
102+
model=cfg.model,
103+
api_key=cfg.api_key,
104+
base_url=cfg.base_url or None,
105+
temperature=cfg.temperature,
106106
)
107-
raise ValueError(f"Unknown LLM provider: {cfg.llm.provider!r}. Supported: openai, anthropic")
107+
raise ValueError(f"Unknown LLM provider: {cfg.provider!r}. Supported: openai, anthropic")
108108

109109

110-
def _build_agent(
111-
cfg: Config, llm: LLMClient, instance: dict, memory: EverMindMemory | None
112-
) -> tuple[Agent, ShellTool]:
110+
def _build_agent(cfg: AgentConfig, instance: dict) -> Agent:
111+
"""Instantiate the agent with the appropriate tools, LLM, and memory (if enabled)."""
113112
shell = ShellTool(_docker_image(instance), workdir="/testbed", remove_on_cleanup=False)
114-
log_dir = Path(cfg.agent.log_dir) / instance["instance_id"] if cfg.agent.log_dir else None
113+
log_dir = Path(cfg.log_dir) / instance["instance_id"] if cfg.log_dir else None
114+
llm = _build_llm(cfg.LLM)
115+
116+
if cfg.enable_memory:
117+
memory = EverMindMemory(
118+
user_id=cfg.Memory.user_id,
119+
base_url=cfg.Memory.base_url,
120+
api_key=cfg.Memory.api_key,
121+
retrieve_method=cfg.Memory.retrieve_method,
122+
top_k=cfg.Memory.top_k,
123+
)
124+
else:
125+
memory = None
126+
115127
agent = Agent(
116128
llm=llm,
117129
tools=[shell],
118-
system_prompt=cfg.agent.system_prompt,
119-
max_steps=cfg.agent.max_steps,
130+
system_prompt=cfg.system_prompt,
131+
max_steps=cfg.max_steps,
120132
log_dir=log_dir,
121133
memory=memory,
122134
)
123-
return agent, shell
135+
return agent
124136

125137

126138
def main() -> None:
@@ -137,18 +149,6 @@ def main() -> None:
137149

138150
cfg = Config.from_yaml(Path(__file__).parent / args.config)
139151

140-
llm = _build_llm(cfg)
141-
142-
memory = None
143-
if cfg.agent.enable_memory:
144-
memory = EverMindMemory(
145-
user_id=cfg.memory.user_id,
146-
base_url=cfg.memory.base_url,
147-
api_key=cfg.memory.api_key,
148-
retrieve_method=cfg.memory.retrieve_method,
149-
top_k=cfg.memory.top_k,
150-
)
151-
152152
dataset = load_dataset(DATASET_NAME, split=args.split)
153153
if args.instance_ids:
154154
keep = set(args.instance_ids)
@@ -160,7 +160,7 @@ def main() -> None:
160160
instance_id = instance["instance_id"]
161161
logger.info("=== %s ===", instance_id)
162162

163-
agent, shell = _build_agent(cfg, llm, instance, memory)
163+
agent = _build_agent(cfg.agent, instance)
164164
agent.run(_build_task_with_images(instance))
165165

166166

0 commit comments

Comments
 (0)