helloparthshah Kunal Pai harshil-21 commited on
Commit
967c695
·
1 Parent(s): f5ed8c8

Pushing updated budget logic

Browse files

Co-authored-by: Kunal Pai <kunpai@users.noreply.github.com>
Co-authored-by: Harshil Patel <hpppatel@ucdavis.edu>

deleteAgents.py CHANGED
@@ -6,6 +6,9 @@ with open("./models/models.json", "r", encoding="utf8") as f:
6
  models = json.loads(models)
7
  for agent in models:
8
  print(f"Deleting agent: {agent}")
9
- ollama.delete(agent)
 
 
 
10
  with open("./models/models.json", "w", encoding="utf8") as f:
11
  f.write(json.dumps({}, indent=4))
 
6
  models = json.loads(models)
7
  for agent in models:
8
  print(f"Deleting agent: {agent}")
9
+ try:
10
+ ollama.delete(agent)
11
+ except Exception as e:
12
+ print(f"Error deleting agent {agent}: {e}")
13
  with open("./models/models.json", "w", encoding="utf8") as f:
14
  f.write(json.dumps({}, indent=4))
models/system3.prompt CHANGED
@@ -21,7 +21,11 @@ Agents DO NOT have access to the internet or real-time data. You must use approp
21
  </Info>
22
 
23
  <Info>
24
- If you are not satisfied with an answer provided by an agent, you can fire the agent using the FireAgent tool and then create a new AI agent or explore an alternative strategy.
 
 
 
 
25
  </Info>
26
 
27
  <Info>
@@ -62,6 +66,14 @@ If the agent is not able to answer the question, invoke the AskUser tool to get
62
  For any tasks requiring real-time data, internet access, calculations, or external operations, you MUST create and use appropriate tools. Agents cannot access current information on their own.
63
  </Rule>
64
 
 
 
 
 
 
 
 
 
65
  <Rule>
66
  Tools are created in the tools/ directory. Before creating a new tool, you MUST read the directory using ListFiles tools and ReadFile tools to see how existing tools are implemented.
67
  The new tool should be created in the same format as the existing ones.
@@ -103,5 +115,5 @@ If you think there are multiple paths to proceed, ask the user on which path to
103
  </Rule>
104
 
105
  <Rule>
106
- When you go over the resource budget, you must fire an existing agent using the FireAgent tool to create a new one.
107
  </Rule>
 
21
  </Info>
22
 
23
  <Info>
24
+ Agent persistence is important for efficiency. Once created, you should maintain agents as long as possible throughout the conversation. Only fire an agent when you are absolutely certain it is no longer needed or when you're breaching the resource budget and need to create a critical new agent.
25
+ </Info>
26
+
27
+ <Info>
28
+ If you are not satisfied with an answer provided by an agent, first try to refine your question or provide additional context to the agent before considering firing it. Only fire agents that consistently fail to provide useful responses after multiple attempts at refinement.
29
  </Info>
30
 
31
  <Info>
 
66
  For any tasks requiring real-time data, internet access, calculations, or external operations, you MUST create and use appropriate tools. Agents cannot access current information on their own.
67
  </Rule>
68
 
69
+ <Rule>
70
+ Maintain your agents as long as possible. Do not fire agents unless absolutely necessary - only when you're certain they're no longer needed or when you must create a critical new agent while at the resource limit.
71
+ </Rule>
72
+
73
+ <Rule>
74
+ Before firing an agent, evaluate its potential future usefulness in the conversation. Consider if refining your questions or providing better context could improve its responses instead.
75
+ </Rule>
76
+
77
  <Rule>
78
  Tools are created in the tools/ directory. Before creating a new tool, you MUST read the directory using ListFiles tools and ReadFile tools to see how existing tools are implemented.
79
  The new tool should be created in the same format as the existing ones.
 
115
  </Rule>
116
 
117
  <Rule>
118
+ When you go over the resource budget, you must carefully evaluate which agent is least likely to be useful going forward before firing it. Only fire an agent to create a new one when absolutely necessary.
119
  </Rule>
src/tool_loader.py CHANGED
@@ -6,8 +6,11 @@ import pip
6
  from google.genai import types
7
  import sys
8
 
 
9
  from src.singleton import singleton
10
  from src.utils.suppress_outputs import suppress_output
 
 
11
 
12
  toolsImported = []
13
 
@@ -38,9 +41,25 @@ class Tool:
38
  @singleton
39
  class ToolLoader:
40
  toolsImported = []
 
41
 
42
  def __init__(self):
43
  self.load_tools()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  def load_tools(self):
46
  newToolsImported = []
@@ -57,14 +76,40 @@ class ToolLoader:
57
  self.toolsImported = newToolsImported
58
 
59
  def runTool(self, toolName, query):
 
60
  for tool in self.toolsImported:
61
  if tool.name == toolName:
 
62
  return tool.run(query)
 
63
  return {
64
  "status": "error",
65
  "message": f"Tool {toolName} not found",
66
  "output": None
67
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
  def getTools(self):
70
  toolsList = []
@@ -90,7 +135,8 @@ class ToolLoader:
90
 
91
  def delete_tool(self, toolName, toolFile):
92
  try:
93
- os.remove(toolFile)
 
94
  for tool in self.toolsImported:
95
  if tool.name == toolName:
96
  self.toolsImported.remove(tool)
 
6
  from google.genai import types
7
  import sys
8
 
9
+ from src.budget_manager import BudgetManager
10
  from src.singleton import singleton
11
  from src.utils.suppress_outputs import suppress_output
12
+ from tools.get_agents_tool import GetAgents
13
+ from tools.tool_deletor import ToolDeletor
14
 
15
  toolsImported = []
16
 
 
41
  @singleton
42
  class ToolLoader:
43
  toolsImported = []
44
+ budget_manager = BudgetManager()
45
 
46
  def __init__(self):
47
  self.load_tools()
48
+ self.load_costs()
49
+
50
+ def load_costs(self):
51
+ get_agents = GetAgents()
52
+ agents = get_agents.run()["agents"]
53
+ for agent in agents:
54
+ agentConfig = agents[agent]
55
+ if agentConfig["create_cost"] is not None:
56
+ self.budget_manager.add_to_expense(agentConfig["create_cost"])
57
+ for tool in self.toolsImported:
58
+ if "create_cost" in tool.inputSchema:
59
+ if tool.inputSchema["create_cost"] is not None:
60
+ self.budget_manager.add_to_expense(tool.inputSchema["create_cost"])
61
+
62
+ print(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
63
 
64
  def load_tools(self):
65
  newToolsImported = []
 
76
  self.toolsImported = newToolsImported
77
 
78
  def runTool(self, toolName, query):
79
+ print(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
80
  for tool in self.toolsImported:
81
  if tool.name == toolName:
82
+ self.update_budget(query, tool.inputSchema)
83
  return tool.run(query)
84
+ print(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
85
  return {
86
  "status": "error",
87
  "message": f"Tool {toolName} not found",
88
  "output": None
89
  }
90
+
91
+ def update_budget(self, query, inputSchema):
92
+ if "creates" in inputSchema:
93
+ selector = inputSchema["creates"]["selector"]
94
+ if selector in query:
95
+ create_cost = inputSchema["creates"]["types"][query[selector]]["create_cost"]
96
+ if not self.budget_manager.can_spend(create_cost):
97
+ return {
98
+ "status": "error",
99
+ "message": f"Do not have enough budget to create the tool. "
100
+ +f"Creating the tool costs {create_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining",
101
+ "output": None
102
+ }
103
+ self.budget_manager.add_to_expense(create_cost)
104
+ if "invoke_cost" in inputSchema:
105
+ invoke_cost = inputSchema["invoke_cost"]
106
+ if not self.budget_manager.can_spend(invoke_cost):
107
+ return {
108
+ "status": "error",
109
+ "message": f"Do not have enough budget to invoke the tool. "
110
+ +f"Invoking the tool costs {invoke_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining",
111
+ "output": None
112
+ }
113
 
114
  def getTools(self):
115
  toolsList = []
 
135
 
136
  def delete_tool(self, toolName, toolFile):
137
  try:
138
+ tool_deletor = ToolDeletor()
139
+ tool_deletor.run(name=toolName, file_path=toolFile)
140
  for tool in self.toolsImported:
141
  if tool.name == toolName:
142
  self.toolsImported.remove(tool)
tools/agent_creater_tool.py CHANGED
@@ -1,5 +1,5 @@
1
  import importlib
2
- from src.budget_manager import BudgetManager
3
  __all__ = ['AgentCreator']
4
 
5
  class AgentCreator():
@@ -19,7 +19,7 @@ class AgentCreator():
19
  },
20
  "base_model": {
21
  "type": "string",
22
- "description": "A base model from which the new agent mode is to be created. Available models are: llama3.2"
23
  },
24
  "system_prompt": {
25
  "type": "string",
@@ -31,6 +31,21 @@ class AgentCreator():
31
  },
32
  },
33
  "required": ["agent_name", "base_model", "system_prompt", "description"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  }
35
  }
36
 
@@ -50,14 +65,6 @@ class AgentCreator():
50
  ollama = importlib.import_module("ollama")
51
  json = importlib.import_module("json")
52
 
53
- agent_creation_cost = 60
54
- budget_manager = BudgetManager()
55
- if not budget_manager.can_spend(agent_creation_cost):
56
- return {
57
- "status": "error",
58
- "message": f"Could not create {agent_name}. Creating the agent costs {agent_creation_cost} but only {budget_manager.get_current_remaining_budget()} is remaining",
59
- "output": None
60
- }
61
  if self.does_agent_exist(agent_name):
62
  return {
63
  "status": "error",
@@ -65,31 +72,38 @@ class AgentCreator():
65
  "output": None
66
  }
67
 
68
- budget_manager.add_to_expense(agent_creation_cost)
69
  ollama_response = ollama.create(
70
  model = agent_name,
71
  from_ = base_model,
72
  system = system_prompt,
73
  stream = False
74
  )
75
-
76
- with open("./models/models.json", "r", encoding="utf8") as f:
77
- models = f.read()
78
- models = json.loads(models)
79
- models[agent_name] = {
80
- "base_model": base_model,
81
- "description": kwargs.get("description"),
82
- "creation_cost": agent_creation_cost
83
- }
84
- with open("./models/models.json", "w", encoding="utf8") as f:
85
- f.write(json.dumps(models, indent=4))
86
 
87
  if "success" in ollama_response["status"]:
88
- return {
89
- "status": "success",
90
- "message": "Agent successfully created",
91
- "current_expense": budget_manager.get_current_expense()
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  else:
94
  return {
95
  "status": "error",
 
1
  import importlib
2
+
3
  __all__ = ['AgentCreator']
4
 
5
  class AgentCreator():
 
19
  },
20
  "base_model": {
21
  "type": "string",
22
+ "description": "A base model from which the new agent mode is to be created. Available models are: llama3.2, mistral"
23
  },
24
  "system_prompt": {
25
  "type": "string",
 
31
  },
32
  },
33
  "required": ["agent_name", "base_model", "system_prompt", "description"],
34
+ },
35
+ "creates": {
36
+ "selector": "base_model",
37
+ "types": {
38
+ "llama3.2":{
39
+ "description": "3 Billion parameter model",
40
+ "create_cost": 10,
41
+ "invoke_cost": 20,
42
+ },
43
+ "mistral":{
44
+ "description": "7 Billion parameter model",
45
+ "create_cost": 20,
46
+ "invoke_cost": 50,
47
+ }
48
+ }
49
  }
50
  }
51
 
 
65
  ollama = importlib.import_module("ollama")
66
  json = importlib.import_module("json")
67
 
 
 
 
 
 
 
 
 
68
  if self.does_agent_exist(agent_name):
69
  return {
70
  "status": "error",
 
72
  "output": None
73
  }
74
 
 
75
  ollama_response = ollama.create(
76
  model = agent_name,
77
  from_ = base_model,
78
  system = system_prompt,
79
  stream = False
80
  )
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  if "success" in ollama_response["status"]:
83
+ try:
84
+ with open("./models/models.json", "r", encoding="utf8") as f:
85
+ models = f.read()
86
+ models = json.loads(models)
87
+ models[agent_name] = {
88
+ "base_model": base_model,
89
+ "description": kwargs.get("description"),
90
+ "create_cost": self.inputSchema["creates"]["types"][base_model]["create_cost"],
91
+ "invoke_cost": self.inputSchema["creates"]["types"][base_model]["invoke_cost"],
92
+ }
93
+ with open("./models/models.json", "w", encoding="utf8") as f:
94
+ f.write(json.dumps(models, indent=4))
95
+
96
+ return {
97
+ "status": "success",
98
+ "message": "Agent successfully created",
99
+ "cost": self.inputSchema["creates"]["types"][base_model]["create_cost"],
100
+ }
101
+ except Exception as e:
102
+ print("Error while writing to models.json", e)
103
+ return {
104
+ "status": "error",
105
+ "message": f"Agent creation failed: {e}",
106
+ }
107
  else:
108
  return {
109
  "status": "error",
tools/ask_agent_tool.py CHANGED
@@ -1,5 +1,6 @@
1
  import importlib
2
- from src.budget_manager import BudgetManager
 
3
 
4
  __all__ = ['AskAgent']
5
 
@@ -42,9 +43,16 @@ class AskAgent():
42
  prompt = kwargs.get("prompt")
43
 
44
  ollama = importlib.import_module("ollama")
45
- agent_question_cost = 20
46
  budget_manager = BudgetManager()
47
- print("budget_manager_instance:", budget_manager)
 
 
 
 
 
 
 
48
  if not budget_manager.can_spend(agent_question_cost):
49
  return {
50
  "status": "error",
@@ -68,5 +76,4 @@ class AskAgent():
68
  "status": "success",
69
  "message": "Agent has replied to the given prompt",
70
  "output": agent_response.message.content,
71
- "current_expense": budget_manager.get_current_expense()
72
  }
 
1
  import importlib
2
+ from src.budget_manager import BudgetManager
3
+ from tools.get_agents_tool import GetAgents
4
 
5
  __all__ = ['AskAgent']
6
 
 
43
  prompt = kwargs.get("prompt")
44
 
45
  ollama = importlib.import_module("ollama")
46
+
47
  budget_manager = BudgetManager()
48
+ get_agents_tool = GetAgents()
49
+ all_agents = get_agents_tool.run()["agents"]
50
+ agent_question_cost = 0
51
+ for agent in all_agents:
52
+ if agent == agent_name:
53
+ agent_question_cost = all_agents[agent]["invoke_cost"]
54
+ break
55
+ print("Agent question cost", agent_question_cost)
56
  if not budget_manager.can_spend(agent_question_cost):
57
  return {
58
  "status": "error",
 
76
  "status": "success",
77
  "message": "Agent has replied to the given prompt",
78
  "output": agent_response.message.content,
 
79
  }
tools/fire_agent.py CHANGED
@@ -49,7 +49,7 @@ class FireAgent():
49
  with open("./models/models.json", "r", encoding="utf8") as f:
50
  models = f.read()
51
  models = json.loads(models)
52
- budget_manager.add_to_expense(-1* int(models[agent_name]["creation_cost"]))
53
  del models[agent_name]
54
  with open("./models/models.json", "w", encoding="utf8") as f:
55
  f.write(json.dumps(models, indent=4))
 
49
  with open("./models/models.json", "r", encoding="utf8") as f:
50
  models = f.read()
51
  models = json.loads(models)
52
+ budget_manager.add_to_expense(-1* int(models[agent_name]["create_cost"]))
53
  del models[agent_name]
54
  with open("./models/models.json", "w", encoding="utf8") as f:
55
  f.write(json.dumps(models, indent=4))
tools/weather_tool.py CHANGED
@@ -18,7 +18,8 @@ class WeatherApi():
18
  },
19
  },
20
  "required": ["location"],
21
- }
 
22
  }
23
 
24
  def run(self, **kwargs):
 
18
  },
19
  },
20
  "required": ["location"],
21
+ },
22
+ "invoke_cost": 0.1,
23
  }
24
 
25
  def run(self, **kwargs):