Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.

Commit 3785a85

Browse files
authored
refactor: introduce AgentSystem class (#83)
1 parent de0c366 commit 3785a85

11 files changed

Lines changed: 196 additions & 183 deletions

File tree

examples/atomic/IOAgent.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import logging
44

5+
from litemultiagent.core.agent_system import AgentSystem
6+
57
# Configure logging
68
logging.basicConfig(
79
level=logging.INFO,
@@ -15,34 +17,32 @@
1517
# Create a logger
1618
logger = logging.getLogger(__name__)
1719
def main():
18-
agent_manager = AgentManager()
1920
io_agent_config = {
2021
"name": "io_agent",
2122
"type": "atomic",
2223
"agent_class": "FunctionCallingAgent",
23-
"meta_data":
24-
{
25-
"meta_task_id": "io_subtask",
26-
"task_id": 1,
27-
"save_to": "supabase",
28-
"log": "log",
29-
"model_name": "gpt-4o-mini",
30-
"tool_choice": "auto"
31-
},
24+
"meta_data":{},
3225
"tool_names": ["read_file", "write_to_file", "generate_and_download_image"],
3326
"agent_description": "Read or write content from/to a file, or generate and save an image using text input",
3427
"parameter_description": "The task description detailing what to read, write, or generate. This can include file operations or image generation requests."
3528
}
36-
io_agent = agent_manager.get_agent(io_agent_config)
29+
system_config = {
30+
"meta_task_id": "io_subtask",
31+
"save_to": "csv",
32+
"log_dir": "log",
33+
"model_name": "gpt-4o-mini",
34+
"tool_choice": "auto"
35+
}
36+
agent_system = AgentSystem(io_agent_config, system_config)
3737

3838
# Example usage
3939
task = "write aaa to 1.txt, bbb to 2.txt, ccc to 3.txt"
40-
result = io_agent.execute(task)
40+
result = agent_system.execute(task)
4141
print("IO Agent Result:", result)
4242

4343

4444
task = "generate a image of a ginger cat and save it as ginger_cat.png"
45-
result = io_agent.execute(task)
45+
result = agent_system.execute(task)
4646
print("IO Agent Result:", result)
4747

4848

examples/composite/MasterAgent.py

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from litemultiagent.core.agent_manager import AgentManager
2+
from litemultiagent.core.agent_system import AgentSystem
23
from litemultiagent.tools.registry import ToolRegistry, Tool
34
import logging
45

@@ -15,22 +16,15 @@
1516
# Create a logger
1617
logger = logging.getLogger(__name__)
1718
def main():
18-
agent_manager = AgentManager()
19-
meta_task_id = "master_agent_task"
20-
task_id = 1
2119
io_agent_config = {
2220
"name": "io_agent",
2321
"type": "atomic",
2422
"agent_class": "FunctionCallingAgent",
2523
"meta_data":
26-
{
27-
"meta_task_id": meta_task_id,
28-
"task_id": task_id,
29-
"save_to": "csv",
30-
"log": "log",
31-
"model_name": "gpt-4o-mini",
32-
"tool_choice": "auto"
33-
},
24+
{
25+
"model_name": "gpt-4o-mini",
26+
"tool_choice": "auto"
27+
},
3428
"tool_names": ["read_file", "write_to_file", "generate_and_download_image"], # Changed from "write_file" to "write_to_file"
3529
"agent_description": "Read or write content from/to a file, or generate and save an image using text input",
3630
"parameter_description": "The task description detailing what to read, write, or generate. This can include file operations or image generation requests."
@@ -40,15 +34,7 @@ def main():
4034
"name": "db_retrieval_agent",
4135
"type": "atomic",
4236
"agent_class": "FunctionCallingAgent",
43-
"meta_data":
44-
{
45-
"meta_task_id": meta_task_id,
46-
"task_id": task_id,
47-
"save_to": "csv",
48-
"log": "log",
49-
"model_name": "gpt-4o-mini",
50-
"tool_choice": "auto"
51-
},
37+
"meta_data": {},
5238
"tool_names": ["retrieve_db"], # Changed from "write_file" to "write_to_file"
5339
"agent_description": "Use a database retrieval agent to fetch information based on a given query.",
5440
"parameter_description": "The query to be processed by the database retrieval agent."
@@ -58,15 +44,7 @@ def main():
5844
"name": "file_retrieval_agent",
5945
"type": "atomic",
6046
"agent_class": "FunctionCallingAgent",
61-
"meta_data":
62-
{
63-
"meta_task_id": meta_task_id,
64-
"task_id": task_id,
65-
"save_to": "csv",
66-
"log": "log",
67-
"model_name": "gpt-4o-mini",
68-
"tool_choice": "auto"
69-
},
47+
"meta_data": {},
7048
"tool_names": ["retrieve_file"], # Changed from "write_file" to "write_to_file"
7149
"agent_description": "Retrieve information from local documents to answer questions or perform tasks.",
7250
"parameter_description": "The task description specifying the local file and the question to be answered. specify this in natural language"
@@ -76,15 +54,7 @@ def main():
7654
"name": "web_retrieval_agent",
7755
"type": "atomic",
7856
"agent_class": "FunctionCallingAgent",
79-
"meta_data":
80-
{
81-
"meta_task_id": meta_task_id,
82-
"task_id": task_id,
83-
"save_to": "csv",
84-
"log": "log",
85-
"model_name": "gpt-4o-mini",
86-
"tool_choice": "auto"
87-
},
57+
"meta_data": {},
8858
"tool_names": ["bing_search", "scrape"], # Changed from "write_file" to "write_to_file"
8959
"agent_description": "Perform a search using API and return the searched results.",
9060
"parameter_description": "The task description describing what to read or write."
@@ -94,15 +64,7 @@ def main():
9464
"name": "exec_agent",
9565
"type": "atomic",
9666
"agent_class": "FunctionCallingAgent",
97-
"meta_data":
98-
{
99-
"meta_task_id": meta_task_id,
100-
"task_id": task_id,
101-
"save_to": "csv",
102-
"log": "log",
103-
"model_name": "gpt-4o-mini",
104-
"tool_choice": "auto"
105-
},
67+
"meta_data": {},
10668
"tool_names": ["execute_shell_command", "run_python_script"], # Changed from "write_file" to "write_to_file"
10769
"agent_description": "Execute some script in a subprocess, either run a bash script, or run a python script ",
10870
"parameter_description": "The task description describing what to execute in the subprocess."
@@ -112,15 +74,7 @@ def main():
11274
"name": "retrieval_agent",
11375
"type": "composite",
11476
"agent_class": "FunctionCallingAgent",
115-
"meta_data":
116-
{
117-
"meta_task_id": meta_task_id,
118-
"task_id": task_id,
119-
"save_to": "csv",
120-
"log": "log",
121-
"model_name": "gpt-4o-mini",
122-
"tool_choice": "auto"
123-
},
77+
"meta_data": {},
12478
"tool_names": [],
12579
"sub_agents": [
12680
web_retrieval_agent_config,
@@ -132,18 +86,10 @@ def main():
13286
}
13387

13488
main_agent_config = {
135-
"name": "retrieval_agent",
89+
"name": "main_agent",
13690
"type": "composite",
13791
"agent_class": "FunctionCallingAgent",
138-
"meta_data":
139-
{
140-
"meta_task_id": meta_task_id,
141-
"task_id": task_id,
142-
"save_to": "csv",
143-
"log": "log",
144-
"model_name": "gpt-4o-mini",
145-
"tool_choice": "auto"
146-
},
92+
"meta_data": {},
14793
"tool_names": ["scan_folder"],
14894
"sub_agents": [
14995
retrieval_agent_config,
@@ -153,20 +99,27 @@ def main():
15399
"agent_description": None,
154100
"parameter_description": None
155101
}
156-
# Create the master agent
157-
main_agent = agent_manager.get_agent(main_agent_config)
158102

159-
# # # Example usage
103+
system_config = {
104+
"meta_task_id": "master_agent_task",
105+
"save_to": "csv",
106+
"log_dir": "log",
107+
"model_name": "gpt-4o-mini",
108+
"tool_choice": "auto"
109+
}
110+
agent_system = AgentSystem(main_agent_config, system_config)
111+
112+
# # Example usage
160113
task = "generate a image of a ginger cat and save it as ginger_cat.png"
161-
result = main_agent.execute(task)
114+
result = agent_system.execute(task)
162115
print("IO Agent Result:", result)
163116

164117
task = "write python script to calculate the sum from 1 to 10, and run the python script to get result"
165-
result = main_agent.execute(task)
166-
print("IO Agent Result:", result)
118+
result = agent_system.execute(task)
119+
print("Exec Agent Result:", result)
167120

168121
task = "browse web to search and check the brands of dining table, and summarize the results in a table, save the table into a markdown file called summary.md"
169-
result = main_agent.execute(task)
122+
result = agent_system.execute(task)
170123
print("Agent Result:", result)
171124

172125

litemultiagent/agents/agent_class/base.py

Lines changed: 21 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
from openai import OpenAI
44
import json
55
from concurrent.futures import ThreadPoolExecutor, as_completed
6-
from supabase import create_client, Client
76
from litellm import completion
8-
import os
97
from dotenv import load_dotenv
108
from litellm import completion
119
from datetime import datetime
12-
import csv
10+
11+
from litemultiagent.core.agent_system import AgentSystem
1312

1413
_ = load_dotenv()
1514

@@ -40,17 +39,6 @@
4039
},
4140
}
4241

43-
# Initialize Supabase client
44-
url = os.getenv("SUPABASE_URL")
45-
key = os.getenv("SUPABASE_ANON_KEY")
46-
supabase: Optional[Client] = None
47-
if url and key:
48-
try:
49-
supabase = create_client(url, key)
50-
except Exception as e:
51-
logger.error(f"Failed to initialize Supabase client: {e}")
52-
53-
5442
class BaseAgent:
5543
def __init__(self, agent_name: str, agent_description, parameter_description, tools: List[Dict[str, Any]],
5644
available_tools: Dict[str, callable],
@@ -59,12 +47,8 @@ def __init__(self, agent_name: str, agent_description, parameter_description, to
5947
self.tools = tools
6048
self.available_tools = available_tools
6149
self.messages = []
62-
self.model_name = meta_data["model_name"]
63-
self.tool_choice = meta_data["tool_choice"]
64-
self.meta_task_id = meta_data["meta_task_id"]
65-
self.task_id = meta_data["task_id"]
66-
self.save_to = meta_data.get("save_to", "csv")
67-
self.log = meta_data["log"]
50+
self.model_name = meta_data.get("model_name", None)
51+
self.tool_choice = meta_data.get("tool_choice", None)
6852
self.agent_description = agent_description
6953
self.parameter_description = parameter_description
7054
self.goal = None
@@ -98,6 +82,11 @@ def send_prompt(self, goal: str) -> str:
9882
self.goal = goal
9983
return self._send_completion_request(plan=goal, depth=0)
10084

85+
def set_system(self, system: AgentSystem):
86+
self.system = system
87+
self.model_name = self.model_name or self.system.model_name
88+
self.tool_choice = self.tool_choice or self.system.tool_choice
89+
10190
def _send_completion_request(self, plan, depth: int = 0) -> str:
10291
pass
10392

@@ -139,11 +128,17 @@ def _log_response(self, response, depth):
139128
f'Agent: {self.agent_name}, prompt tokens: {response.usage.prompt_tokens}, completion tokens: {response.usage.completion_tokens}')
140129
logger.info(f'Agent: {self.agent_name}, depth: {depth}, response: {response}')
141130

131+
def _save_response(self, response, depth):
132+
if self.system.save_to == "supabase":
133+
self._save_to_supabase(response, depth)
134+
if self.system.save_to == "csv":
135+
self._save_to_csv(response, depth)
136+
142137
def _save_to_csv(self, response, depth):
143138
usage_dict = self._extract_cost(response)
144139
data = {
145-
"meta_task_id": self.meta_task_id,
146-
"task_id": self.task_id,
140+
"meta_task_id": self.system.meta_task_id,
141+
"task_id": self.system.task_id,
147142
"agent": self.agent_name,
148143
"depth": depth,
149144
"role": "assistant",
@@ -156,38 +151,13 @@ def _save_to_csv(self, response, depth):
156151
"model_name": self.model_name,
157152
"timestamp": datetime.now().isoformat()
158153
}
159-
160-
filename = os.path.join(self.log, f"multiagent_data_{datetime.now().strftime('%Y%m%d')}.csv")
161-
file_exists = os.path.isfile(filename)
162-
163-
# Ensure the directory exists
164-
os.makedirs(os.path.dirname(filename), exist_ok=True)
165-
166-
# If file doesn't exist, create it with header
167-
if not file_exists:
168-
with open(filename, 'w', newline='') as csvfile:
169-
fieldnames = list(data.keys())
170-
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
171-
writer.writeheader()
172-
logger.info(f"Created new CSV file with header: {filename}")
173-
174-
# Append data to the file
175-
with open(filename, 'a', newline='') as csvfile:
176-
fieldnames = list(data.keys())
177-
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
178-
writer.writerow(data)
179-
180-
logger.info(f"Data saved to CSV: {filename}")
154+
self.system.save_to_csv(data)
181155

182156
def _save_to_supabase(self, response, depth):
183-
if supabase is None:
184-
logger.warning("Supabase client is not initialized. Skipping database save.")
185-
return
186-
187157
usage_dict = self._extract_cost(response)
188158
data = {
189-
"meta_task_id": self.meta_task_id,
190-
"task_id": self.task_id,
159+
"meta_task_id": self.system.meta_task_id,
160+
"task_id": self.system.task_id,
191161
"agent": self.agent_name,
192162
"depth": depth,
193163
"role": "assistant",
@@ -199,11 +169,7 @@ def _save_to_supabase(self, response, depth):
199169
"total_cost": usage_dict["total_cost"],
200170
"model_name": self.model_name,
201171
}
202-
203-
try:
204-
supabase.table("multiagent").insert(data).execute()
205-
except Exception as e:
206-
logger.error(f"Failed to save data to Supabase: {e}")
172+
self.system.save_to_csv(data)
207173

208174
def _extract_cost(self, response):
209175
prompt_tokens = response.usage.prompt_tokens

0 commit comments

Comments
 (0)