Harshil Patel commited on
Commit
98d31e7
·
1 Parent(s): 06dc658

Move cost management from tool loader to agent manager

Browse files
default_tools/agent_creater_tool.py CHANGED
@@ -65,7 +65,7 @@ class AgentCreator():
65
 
66
  agent_manager = AgentManager()
67
  try:
68
- agent_manager.create_agent(
69
  agent_name=agent_name,
70
  base_model=base_model,
71
  system_prompt=system_prompt,
@@ -83,5 +83,5 @@ class AgentCreator():
83
  return {
84
  "status": "success",
85
  "message": "Agent successfully created",
86
- "cost": create_cost,
87
  }
 
65
 
66
  agent_manager = AgentManager()
67
  try:
68
+ _, remaining_budget = agent_manager.create_agent(
69
  agent_name=agent_name,
70
  base_model=base_model,
71
  system_prompt=system_prompt,
 
83
  return {
84
  "status": "success",
85
  "message": "Agent successfully created",
86
+ "remaining_budget": remaining_budget,
87
  }
default_tools/ask_agent_tool.py CHANGED
@@ -34,10 +34,9 @@ class AskAgent():
34
  agent_name = kwargs.get("agent_name")
35
  prompt = kwargs.get("prompt")
36
  agent_manger = AgentManager()
37
- budget_manager = BudgetManager()
38
 
39
  try:
40
- agent = agent_manger.get_agent(agent_name=agent_name)
41
  except ValueError as e:
42
  return {
43
  "status": "error",
@@ -45,21 +44,10 @@ class AskAgent():
45
  "output": None
46
  }
47
 
48
- agent_costs = agent.get_costs()
49
- agent_question_cost = agent_costs["invoke_cost"]
50
- print("Agent question cost", agent_question_cost)
51
-
52
- if not budget_manager.can_spend(agent_question_cost):
53
- return {
54
- "status": "error",
55
- "message": f"Do not have enough budget to ask the agent a question. Asking the agent costs {agent_question_cost} but only {budget_manager.get_current_remaining_budget()} is remaining",
56
- "output": None
57
- }
58
-
59
- agent_response = agent.ask_agent(prompt=prompt)
60
  print("Agent response", agent_response)
61
  return {
62
  "status": "success",
63
  "message": "Agent has replied to the given prompt",
64
  "output": agent_response,
 
65
  }
 
34
  agent_name = kwargs.get("agent_name")
35
  prompt = kwargs.get("prompt")
36
  agent_manger = AgentManager()
 
37
 
38
  try:
39
+ agent_response, remaining_budget = agent_manger.ask_agent(agent_name=agent_name, prompt=prompt)
40
  except ValueError as e:
41
  return {
42
  "status": "error",
 
44
  "output": None
45
  }
46
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  print("Agent response", agent_response)
48
  return {
49
  "status": "success",
50
  "message": "Agent has replied to the given prompt",
51
  "output": agent_response,
52
+ "remaining_budget": remaining_budget
53
  }
default_tools/fire_agent.py CHANGED
@@ -28,26 +28,18 @@ class FireAgent():
28
  agent_name= kwargs.get("agent_name")
29
 
30
  agent_manager = AgentManager()
31
-
32
- agent = agent_manager.get_agent(agent_name=agent_name)
33
-
34
- agent_costs = agent.get_costs()
35
-
36
  try:
37
- agent_manager.delete_agent(agent_name=agent_name)
38
  except ValueError as e:
39
  return {
40
  "status": "error",
41
  "message": f"Error occurred: {str(e)}",
42
  "output": None
43
  }
44
-
45
- budget_manager = BudgetManager()
46
-
47
- budget_manager.add_to_expense(-1* int(agent_costs["create_cost"]))
48
 
49
  return {
50
  "status": "success",
51
  "message": "Agent successfully fired.",
52
- "current_expense": budget_manager.get_current_expense()
53
  }
 
28
  agent_name= kwargs.get("agent_name")
29
 
30
  agent_manager = AgentManager()
31
+
 
 
 
 
32
  try:
33
+ remaining_budget = agent_manager.delete_agent(agent_name=agent_name)
34
  except ValueError as e:
35
  return {
36
  "status": "error",
37
  "message": f"Error occurred: {str(e)}",
38
  "output": None
39
  }
 
 
 
 
40
 
41
  return {
42
  "status": "success",
43
  "message": "Agent successfully fired.",
44
+ "remaining_budget": remaining_budget
45
  }
src/agent_manager.py CHANGED
@@ -1,5 +1,5 @@
1
  from abc import ABC, abstractmethod
2
- from typing import Dict, Type, Any, Optional
3
  import os
4
  import json
5
  import ollama
@@ -10,6 +10,8 @@ from google.genai import types
10
  from google.genai.types import *
11
  import os
12
  from dotenv import load_dotenv
 
 
13
  class Agent(ABC):
14
 
15
  def __init__(self, agent_name: str, base_model: str, system_prompt: str, creation_cost: str, invoke_cost: str):
@@ -93,7 +95,7 @@ class GeminiAgent(Agent):
93
  self.messages = []
94
  @singleton
95
  class AgentManager():
96
-
97
  def __init__(self):
98
  self._agents = {}
99
  self._agent_types ={
@@ -104,7 +106,7 @@ class AgentManager():
104
  self._load_agents()
105
 
106
  def create_agent(self, agent_name: str, base_model: str, system_prompt: str, description: str = "", create_cost: float = 0, invoke_cost: float = 0,
107
- **additional_params) -> Agent:
108
 
109
  if agent_name in self._agents:
110
  raise ValueError(f"Agent {agent_name} already exists")
@@ -115,6 +117,11 @@ class AgentManager():
115
  if not agent_class:
116
  raise ValueError(f"Unsupported base model {base_model}")
117
 
 
 
 
 
 
118
  # create agent
119
  self._agents[agent_name] = agent_class(agent_name, base_model, system_prompt, create_cost,invoke_cost )
120
 
@@ -129,7 +136,7 @@ class AgentManager():
129
  **additional_params # For any future parameters we might want to add
130
  )
131
 
132
- return self._agents[agent_name]
133
 
134
  def get_agent(self, agent_name: str) -> Agent:
135
  """Get existing agent by name"""
@@ -159,11 +166,14 @@ class AgentManager():
159
  output_assistant_response(f"Error listing agents: {e}")
160
  return {}
161
 
162
- def delete_agent(self, agent_name: str) -> None:
163
  if agent_name not in self._agents:
164
  raise ValueError(f"Agent {agent_name} does not exist")
 
 
165
  self._agents[agent_name].delete_agent()
166
 
 
167
  del self._agents[agent_name]
168
  try:
169
  if os.path.exists("./models/models.json"):
@@ -175,7 +185,17 @@ class AgentManager():
175
  f.write(json.dumps(models, indent=4))
176
  except Exception as e:
177
  output_assistant_response(f"Error deleting agent: {e}")
 
178
 
 
 
 
 
 
 
 
 
 
179
 
180
  def _save_agent(self, agent_name: str, base_model: str, system_prompt: str,
181
  description: str = "", create_cost: float = 0, invoke_cost: float = 0,
 
1
  from abc import ABC, abstractmethod
2
+ from typing import Dict, Type, Any, Optional, Tuple
3
  import os
4
  import json
5
  import ollama
 
10
  from google.genai.types import *
11
  import os
12
  from dotenv import load_dotenv
13
+ from src.budget_manager import BudgetManager
14
+
15
  class Agent(ABC):
16
 
17
  def __init__(self, agent_name: str, base_model: str, system_prompt: str, creation_cost: str, invoke_cost: str):
 
95
  self.messages = []
96
  @singleton
97
  class AgentManager():
98
+ budget_manager = BudgetManager()
99
  def __init__(self):
100
  self._agents = {}
101
  self._agent_types ={
 
106
  self._load_agents()
107
 
108
  def create_agent(self, agent_name: str, base_model: str, system_prompt: str, description: str = "", create_cost: float = 0, invoke_cost: float = 0,
109
+ **additional_params) -> Tuple[Agent, int]:
110
 
111
  if agent_name in self._agents:
112
  raise ValueError(f"Agent {agent_name} already exists")
 
117
  if not agent_class:
118
  raise ValueError(f"Unsupported base model {base_model}")
119
 
120
+ if not self.budget_manager.can_spend(create_cost):
121
+ raise ValueError(f"Do not have enough budget to create the tool. "
122
+ +f"Creating the tool costs {create_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining")
123
+
124
+ self.budget_manager.add_to_expense(create_cost)
125
  # create agent
126
  self._agents[agent_name] = agent_class(agent_name, base_model, system_prompt, create_cost,invoke_cost )
127
 
 
136
  **additional_params # For any future parameters we might want to add
137
  )
138
 
139
+ return (self._agents[agent_name], self.budget_manager.get_current_remaining_budget())
140
 
141
  def get_agent(self, agent_name: str) -> Agent:
142
  """Get existing agent by name"""
 
166
  output_assistant_response(f"Error listing agents: {e}")
167
  return {}
168
 
169
+ def delete_agent(self, agent_name: str) -> int:
170
  if agent_name not in self._agents:
171
  raise ValueError(f"Agent {agent_name} does not exist")
172
+
173
+ self.budget_manager.add_to_expense(-1 * self._agents[agent_name].creation_cost)
174
  self._agents[agent_name].delete_agent()
175
 
176
+
177
  del self._agents[agent_name]
178
  try:
179
  if os.path.exists("./models/models.json"):
 
185
  f.write(json.dumps(models, indent=4))
186
  except Exception as e:
187
  output_assistant_response(f"Error deleting agent: {e}")
188
+ return self.budget_manager.get_current_remaining_budget()
189
 
190
+ def ask_agent(self, agent_name: str, prompt: str) -> Tuple[str,int]:
191
+ agent = self._agents[agent_name]
192
+
193
+ if not self.budget_manager.can_spend(agent.invoke_cost):
194
+ raise ValueError(f"Do not have enough budget to ask Agent {agent_name} a question. "
195
+ +f"Asking Agent {agent_name} costs {agent.invoke_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining")
196
+
197
+ response = agent.ask_agent(prompt)
198
+ return (response, self.budget_manager.get_current_remaining_budget())
199
 
200
  def _save_agent(self, agent_name: str, base_model: str, system_prompt: str,
201
  description: str = "", create_cost: float = 0, invoke_cost: float = 0,
src/tool_loader.py CHANGED
@@ -20,7 +20,7 @@ TOOLS_DIRECTORIES = [os.path.abspath("./default_tools"), os.path.abspath("./tool
20
  class Tool:
21
  def __init__(self, toolClass):
22
  suppress_output(self.load_tool)(toolClass)
23
-
24
  def load_tool(self, toolClass):
25
  self.tool = toolClass()
26
  self.inputSchema = self.tool.inputSchema
@@ -81,7 +81,6 @@ class ToolLoader:
81
  output_assistant_response(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
82
  for tool in self.toolsImported:
83
  if tool.name == toolName:
84
- self.update_budget(query, tool.inputSchema)
85
  return tool.run(query)
86
  output_assistant_response(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
87
  return {
@@ -90,28 +89,6 @@ class ToolLoader:
90
  "output": None
91
  }
92
 
93
- def update_budget(self, query, inputSchema):
94
- if "creates" in inputSchema:
95
- selector = inputSchema["creates"]["selector"]
96
- if selector in query:
97
- create_cost = inputSchema["creates"]["types"][query[selector]]["create_cost"]
98
- if not self.budget_manager.can_spend(create_cost):
99
- return {
100
- "status": "error",
101
- "message": f"Do not have enough budget to create the tool. "
102
- +f"Creating the tool costs {create_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining",
103
- "output": None
104
- }
105
- self.budget_manager.add_to_expense(create_cost)
106
- if "invoke_cost" in inputSchema:
107
- invoke_cost = inputSchema["invoke_cost"]
108
- if not self.budget_manager.can_spend(invoke_cost):
109
- return {
110
- "status": "error",
111
- "message": f"Do not have enough budget to invoke the tool. "
112
- +f"Invoking the tool costs {invoke_cost} but only {self.budget_manager.get_current_remaining_budget()} is remaining",
113
- "output": None
114
- }
115
 
116
  def getTools(self):
117
  toolsList = []
 
20
  class Tool:
21
  def __init__(self, toolClass):
22
  suppress_output(self.load_tool)(toolClass)
23
+
24
  def load_tool(self, toolClass):
25
  self.tool = toolClass()
26
  self.inputSchema = self.tool.inputSchema
 
81
  output_assistant_response(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
82
  for tool in self.toolsImported:
83
  if tool.name == toolName:
 
84
  return tool.run(query)
85
  output_assistant_response(f"Budget Remaining: {self.budget_manager.get_current_remaining_budget()}")
86
  return {
 
89
  "output": None
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  def getTools(self):
94
  toolsList = []