Skip to content

Commit fd51bac

Browse files
committed
Refactor agent definitions to use dict keys by name
1 parent b56e173 commit fd51bac

File tree

7 files changed

+54
-23
lines changed

7 files changed

+54
-23
lines changed

agents.yaml.example

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
agents:
1313
# Example 1: Simple custom research agent with overrides
14-
- name: "custom_research_agent"
14+
custom_research_agent:
1515
base_class: "SGRResearchAgent"
1616

1717
# Optional: Override LLM settings for this agent
@@ -68,7 +68,7 @@ agents:
6868
- "FinalAnswerTool"
6969

7070
# Example 2: Minimal agent with defaults
71-
- name: "simple_agent"
71+
simple_agent:
7272
base_class: "SGRToolCallingResearchAgent"
7373

7474
# Only override what's needed
@@ -80,7 +80,7 @@ agents:
8080
- "FinalAnswerTool"
8181

8282
# Example 3: Fast research agent optimized for speed
83-
- name: "fast_research_agent"
83+
fast_research_agent:
8484
base_class: "SGRToolCallingResearchAgent"
8585

8686
llm:
@@ -101,7 +101,7 @@ agents:
101101
- "ReasoningTool"
102102

103103
# Example 4: Specialized technical analyst with custom prompts
104-
- name: "technical_analyst"
104+
technical_analyst:
105105
base_class: "SGRResearchAgent"
106106

107107
llm:
@@ -125,7 +125,7 @@ agents:
125125
- "FinalAnswerTool"
126126

127127
# Example 5: Agent using inline prompts instead of files
128-
- name: "inline_prompt_agent"
128+
inline_prompt_agent:
129129
base_class: "SGRResearchAgent"
130130

131131
prompts:

sgr_deep_research/__main__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from sgr_deep_research.api.endpoints import router
1111
from sgr_deep_research.core import AgentRegistry, ToolRegistry
1212
from sgr_deep_research.core.agent_config import GlobalConfig
13+
from sgr_deep_research.default_definitions import get_default_agents_definitions
1314
from sgr_deep_research.settings import ServerConfig, setup_logging
1415

1516
setup_logging()
@@ -30,8 +31,9 @@ async def lifespan(app: FastAPI):
3031
def main():
3132
"""Запуск FastAPI сервера."""
3233
args = ServerConfig()
33-
GlobalConfig.from_yaml(args.config_file)
34-
GlobalConfig.definitions_from_yaml(args.agents_file)
34+
config = GlobalConfig.from_yaml(args.config_file)
35+
config.agents.update(get_default_agents_definitions())
36+
config.definitions_from_yaml(args.agents_file)
3537
app = FastAPI(title="SGR Deep Research API", version=__version__, lifespan=lifespan)
3638
app.include_router(router)
3739
uvicorn.run(app, host=args.host, port=args.port, log_level="info")

sgr_deep_research/core/agent_config.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
from pathlib import Path
23
from typing import ClassVar, Self
34

@@ -6,6 +7,8 @@
67

78
from sgr_deep_research.core.agent_definition import AgentConfig, Definitions
89

10+
logger = logging.getLogger(__name__)
11+
912

1013
class GlobalConfig(BaseSettings, AgentConfig, Definitions):
1114
_instance: ClassVar[Self | None] = None
@@ -44,8 +47,39 @@ def from_yaml(cls, yaml_path: str) -> Self:
4447

4548
@classmethod
4649
def definitions_from_yaml(cls, agents_yaml_path: str) -> Self:
50+
"""Load agent definitions from YAML file and merge with existing
51+
agents.
52+
53+
Args:
54+
agents_yaml_path: Path to YAML file with agent definitions
55+
56+
Returns:
57+
GlobalConfig instance with merged agents
58+
59+
Raises:
60+
FileNotFoundError: If YAML file not found
61+
ValueError: If YAML file doesn't contain 'agents' key
62+
"""
4763
agents_yaml_path = Path(agents_yaml_path)
4864
if not agents_yaml_path.exists():
4965
raise FileNotFoundError(f"Agents definitions file not found: {agents_yaml_path}")
50-
cls._instance.agents = Definitions(**yaml.safe_load(agents_yaml_path.read_text(encoding="utf-8"))).agents
66+
67+
yaml_data = yaml.safe_load(agents_yaml_path.read_text(encoding="utf-8"))
68+
if not yaml_data.get("agents"):
69+
raise ValueError(f"Agents definitions file must contain 'agents' key: {agents_yaml_path}")
70+
71+
for agent_name, agent_config in yaml_data.get("agents").items():
72+
agent_config["name"] = agent_name
73+
74+
custom_agents = Definitions(**yaml_data).agents
75+
76+
# Check for agents that will be overridden
77+
overridden = set(cls._instance.agents.keys()) & set(custom_agents.keys())
78+
if overridden:
79+
logger.warning(
80+
f"Custom agents from {agents_yaml_path.name} will override existing agents: "
81+
f"{', '.join(sorted(overridden))}"
82+
)
83+
84+
cls._instance.agents.update(custom_agents)
5185
return cls._instance

sgr_deep_research/core/agent_definition.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,6 @@ def from_yaml(cls, yaml_path: str) -> Self:
176176

177177

178178
class Definitions(BaseModel):
179-
agents: list[AgentDefinition] = Field(default_factory=list, description="List of agent definitions")
179+
agents: dict[str, AgentDefinition] = Field(
180+
default_factory=dict, description="Dictionary of agent definitions by name"
181+
)

sgr_deep_research/core/agent_factory.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
from sgr_deep_research.core.agent_config import GlobalConfig
1010
from sgr_deep_research.core.agent_definition import AgentDefinition, LLMConfig
11-
from sgr_deep_research.core.agents.definitions import get_default_agents_definitions
1211
from sgr_deep_research.core.base_agent import BaseAgent
1312
from sgr_deep_research.core.services import AgentRegistry, MCP2ToolConverter, ToolRegistry
1413

@@ -108,15 +107,10 @@ async def create(cls, agent_def: AgentDefinition, task: str) -> Agent:
108107

109108
@classmethod
110109
def get_definitions_list(cls) -> list[AgentDefinition]:
111-
"""Get all agent definitions (default + custom from config).
110+
"""Get all agent definitions from config.
112111
113112
Returns:
114-
List of agent definitions (default agents + custom agents from config)
113+
List of agent definitions from config
115114
"""
116115
config = GlobalConfig()
117-
118-
all_agents = {agent.name: agent for agent in get_default_agents_definitions()}
119-
if will_be_rewritten := set(all_agents.keys()).intersection({agent.name for agent in config.agents}):
120-
logger.warning(f"Custom agents with names {', '.join(will_be_rewritten)} will override default agents.")
121-
all_agents.update({agent.name: agent for agent in config.agents})
122-
return list(all_agents.values())
116+
return list(config.agents.values())

sgr_deep_research/core/agents/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Agents module for SGR Deep Research."""
22

3-
from sgr_deep_research.core.agents.definitions import get_default_agents_definitions
43
from sgr_deep_research.core.agents.sgr_agent import SGRResearchAgent
54
from sgr_deep_research.core.agents.sgr_auto_tools_agent import SGRAutoToolCallingResearchAgent
65
from sgr_deep_research.core.agents.sgr_so_tools_agent import SGRSOToolCallingResearchAgent
@@ -13,5 +12,4 @@
1312
"SGRAutoToolCallingResearchAgent",
1413
"ToolCallingResearchAgent",
1514
"SGRSOToolCallingResearchAgent",
16-
"get_default_agents_definitions",
1715
]

sgr_deep_research/core/agents/definitions.py renamed to sgr_deep_research/default_definitions.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
]
1818

1919

20-
def get_default_agents_definitions() -> list[AgentDefinition]:
20+
def get_default_agents_definitions() -> dict[str, AgentDefinition]:
2121
"""Get default agent definitions.
2222
2323
This function creates agent definitions lazily to avoid issues with
2424
configuration initialization order.
2525
2626
Returns:
27-
List of default agent definitions
27+
Dictionary of default agent definitions keyed by agent name
2828
"""
29-
return [
29+
agents = [
3030
AgentDefinition(
3131
name="sgr_agent",
3232
base_class=SGRResearchAgent,
@@ -53,3 +53,4 @@ def get_default_agents_definitions() -> list[AgentDefinition]:
5353
tools=DEFAULT_TOOLKIT,
5454
),
5555
]
56+
return {agent.name: agent for agent in agents}

0 commit comments

Comments
 (0)