Spaces:
Running
Running
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 +2 -2
- default_tools/ask_agent_tool.py +2 -14
- default_tools/fire_agent.py +3 -11
- src/agent_manager.py +25 -5
- src/tool_loader.py +1 -24
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 |
-
"
|
| 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 |
-
|
| 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 |
-
"
|
| 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) ->
|
| 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 = []
|