Commit
·
967c695
1
Parent(s):
f5ed8c8
Pushing updated budget logic
Browse filesCo-authored-by: Kunal Pai <kunpai@users.noreply.github.com>
Co-authored-by: Harshil Patel <hpppatel@ucdavis.edu>
- deleteAgents.py +4 -1
- models/system3.prompt +14 -2
- src/tool_loader.py +47 -1
- tools/agent_creater_tool.py +41 -27
- tools/ask_agent_tool.py +11 -4
- tools/fire_agent.py +1 -1
- tools/weather_tool.py +2 -1
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 |
-
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
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
|
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 |
-
|
|
|
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 |
-
|
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 |
-
|
89 |
-
"
|
90 |
-
|
91 |
-
|
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 |
-
|
46 |
budget_manager = BudgetManager()
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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]["
|
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):
|