Skip to content

Commit 1338ceb

Browse files
committed
bugfixes
1 parent b1cc04a commit 1338ceb

12 files changed

+2330
-168
lines changed

agent_orchestrator.py

+45-54
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,34 @@ def __init__(self, server_url: str, model: str):
2121
self.model = model
2222
self.running = True
2323

24+
self.tool_schemas = []
25+
2426
def add_agent(self, agent: Agent):
2527
self.agents.append(agent)
2628

27-
def run(self, tool_callback: Callable, app_managers: List[AppManager]):
29+
def run(self, tool_callback: Callable, post_system_tool_calls: List[ToolCall]):
2830
while self.running:
29-
for agent in self.agents:
31+
for agent_index, agent in enumerate(self.agents):
3032
print("~"*100)
33+
print("###AGENT RUN STARTING###")
34+
print(f"###{agent_index}###")
3135
print(f"Running agent: {agent.name} \n")
3236

3337
post_system_messages = []
34-
# make assistant messages for loaded apps
35-
agent_app_manager = app_managers[agent.id]
36-
get_loaded_apps_tool_call = ToolCall(
37-
toolset_id="app_manager",
38-
name="get_loaded_apps",
39-
arguments={}
40-
)
41-
get_loaded_apps_tool_call_result = agent_app_manager.agent_tool_callback(agent, get_loaded_apps_tool_call)
42-
43-
post_system_messages.append(Message(role="assistant", tool_calls=[get_loaded_apps_tool_call]))
44-
post_system_messages.append(Message(role="tool", content=get_loaded_apps_tool_call_result))
38+
print(f"Post system tool calls:")
39+
for tool_call in post_system_tool_calls:
40+
tool_call_result = tool_callback(agent, tool_call)
41+
post_system_messages.append(Message(role="tool", content=tool_call_result))
4542

4643
agent.run(self.server_url, self.model, post_system_messages, tool_callback)
47-
44+
print("###AGENT RUN COMPLETE###")
45+
print(f"###{agent_index}###")
46+
47+
48+
# if all agents are complete, stop
49+
if all(not agent.running for agent in self.agents):
50+
self.running = False
51+
break
4852
def stop(self):
4953
self.running = False
5054

@@ -77,32 +81,6 @@ def get_agent_status(self):
7781
"running": self.get_running_agent_count(),
7882
"stopped": self.get_stopped_agent_count()
7983
}
80-
81-
############### Agent Interface ###############
82-
def get_toolset_details(self):
83-
return ToolsetDetails(
84-
toolset_id="agent_tool",
85-
name="Agent Orchestrator",
86-
description="Orchestrates agents"
87-
)
88-
89-
def get_tool_schemas(self):
90-
tool_schemas = [{
91-
"toolset_id": "agent_tool",
92-
"name": "set_name",
93-
"description": "Set your name",
94-
"arguments": [{
95-
"name": "name",
96-
"type": "string",
97-
"description": "your new name"
98-
}]
99-
}]
100-
return tool_schemas
101-
102-
def agent_tool_callback(self, agent: Agent, tool_call: ToolCall):
103-
if tool_call.name == "set_name":
104-
agent.name = tool_call.arguments["name"]
105-
return f"Name set to {tool_call.arguments['name']}"
10684

10785
def main():
10886
from tools.forum import Directory
@@ -113,6 +91,7 @@ def main():
11391
from tools.file_manager import FileManager
11492
from tools.persona import PersonaManager
11593
from tools.notes import NotesManager
94+
from tools.user_directory import UserDirectory
11695
# delete out files if they exist
11796
if os.path.exists("std_out.txt"):
11897
os.remove("std_out.txt")
@@ -144,14 +123,13 @@ def main():
144123
notes_managers = {}
145124
orchestrator = AgentOrchestrator(server_url="http://localhost:5000", model="llama3.1:8b")
146125
wiki_search = WikiSearch()
126+
user_directory = UserDirectory()
147127
def tool_callback(agent: Agent, tool_call: ToolCall):
148128
tool_results = None
149129
print(f" - {tool_call.toolset_id} - Tool call: {tool_call}")
150130
try:
151131
if tool_call.toolset_id == "forum_toolset":
152132
tool_results = forum_directory.agent_tool_callback(agent, tool_call)
153-
elif tool_call.toolset_id == "agent_tool":
154-
tool_results = orchestrator.agent_tool_callback(agent, tool_call)
155133
elif tool_call.toolset_id == "code_runner":
156134
tool_results = shared_code_runner.agent_tool_callback(agent, tool_call)
157135
elif tool_call.toolset_id == "wiki_toolset":
@@ -166,6 +144,8 @@ def tool_callback(agent: Agent, tool_call: ToolCall):
166144
tool_results = persona_managers[agent.id].agent_tool_callback(agent, tool_call)
167145
elif tool_call.toolset_id == "notes_manager":
168146
tool_results = notes_managers[agent.id].agent_tool_callback(agent, tool_call)
147+
elif tool_call.toolset_id == "messages":
148+
tool_results = user_directory.agent_tool_callback(agent, tool_call)
169149
else:
170150
print(f"APP NOT FOUND - toolset_id: {tool_call.toolset_id} not found")
171151
except Exception as e:
@@ -230,19 +210,14 @@ def tool_callback(agent: Agent, tool_call: ToolCall):
230210
name="get_current_persona",
231211
arguments={}
232212
),
233-
ToolCall(
234-
toolset_id="notes_manager",
235-
name="get_notes",
236-
arguments={}
237-
),
238213
ToolCall(
239214
toolset_id="quest_manager",
240215
name="get_quest_list",
241216
arguments={}
242217
),
243218
ToolCall(
244-
toolset_id="quest_manager",
245-
name="get_current_quest",
219+
toolset_id="messages",
220+
name="get_new_message_count",
246221
arguments={}
247222
),
248223
ToolCall(
@@ -271,24 +246,40 @@ def tool_callback(agent: Agent, tool_call: ToolCall):
271246
quest_manager = QuestManager()
272247
quest_managers[agent.id] = quest_manager
273248

249+
user_directory.add_user(agent)
274250

275251
app_manager.add_app(persona_manager.get_toolset_details(), persona_manager.get_tool_schemas())
276-
app_manager.add_app(orchestrator.get_toolset_details(), orchestrator.get_tool_schemas())
277252
app_manager.add_app(shared_code_runner.get_toolset_details(), shared_code_runner.get_tool_schemas())
278253
app_manager.add_app(quest_manager.get_toolset_details(), quest_manager.get_tool_schemas())
279-
app_manager.load_app(quest_manager.get_toolset_details().toolset_id)
254+
#app_manager.load_app(quest_manager.get_toolset_details().toolset_id)
280255
app_manager.add_app(wiki_search.get_toolset_details(), wiki_search.get_tool_schemas())
281256
app_manager.add_app(forum_directory.get_toolset_details(), forum_directory.get_tool_schemas())
282257
app_manager.add_app(file_manager.get_toolset_details(), file_manager.get_tool_schemas())
283258
app_manager.add_app(notes_manager.get_toolset_details(), notes_manager.get_tool_schemas())
284259
app_manager.load_app(notes_manager.get_toolset_details().toolset_id)
260+
app_manager.add_app(user_directory.get_toolset_details(), user_directory.get_tool_schemas())
285261
app_managers[agent.id] = app_manager
286262
orchestrator.add_agent(agent)
287263

264+
post_system_tool_calls = [
265+
ToolCall(
266+
toolset_id="app_manager",
267+
name="get_loaded_apps",
268+
arguments={}
269+
),
270+
ToolCall(
271+
toolset_id="quest_manager",
272+
name="get_current_quest",
273+
arguments={}
274+
),
275+
ToolCall(
276+
toolset_id="notes_manager",
277+
name="get_notes",
278+
arguments={}
279+
)
280+
]
288281

289-
290-
291-
orchestrator.run(tool_callback=tool_callback, app_managers=app_managers)
282+
orchestrator.run(tool_callback=tool_callback, post_system_tool_calls=post_system_tool_calls)
292283

293284
if __name__ == "__main__":
294285
main()

libs/agent.py

+15-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ class AgentSummarySchema(BaseModel):
2525
summary: str = Field(description="string of summary. This is a summary of the actions taken, including what was thought and what was done.")
2626
instructions_for_next_pass: str = Field(description="This is the prompt you will receive in the next pass as a user message.")
2727

28+
class AgentRunOutput(BaseModel): # TODO: generate and save this for each pass
29+
model: str = Field(description="The model used for the agent run.")
30+
run_messages: List[Message] = Field(description="The messages from the agent run.")
31+
agent_output: AgentOutputSchema = Field(description="The output of the agent run.")
32+
summary_messages: List[Message] = Field(description="The messages from the summary pass.")
33+
summary_output: AgentSummarySchema = Field(description="The output of the summary pass.")
34+
tool_results: List[str] = Field(description="The results from the tool calls.")
35+
2836
class Agent:
2937
def __init__(self, default_llm_url: str, name: str, private_key: str, initial_instructions: str, initial_notes: List[str], buffer_size: int = 20, running: bool = True, standing_tool_calls: List[ToolCall] = []):
3038
self.default_llm_url = default_llm_url
@@ -216,17 +224,20 @@ def run(self, llm_url: str, model: str, post_system_messages: List[Message], too
216224
raise e
217225
print()
218226
print(f"Thoughts:")
219-
print(response.thoughts)
220-
print(f"Followup thoughts:")
221-
print(response.followup_thoughts)
227+
print(" - " + response.thoughts)
228+
print(" - " + response.followup_thoughts)
222229

223230
if not response.should_continue:
224231
self.running = False
225232

226233
self.call_tools(response.tool_calls, tool_callback)
227234

235+
print("\n\nFull System Prompt:")
236+
print(system_prompt)
228237
summary = self.get_pass_summary(llm_url, response, standing_tool_results)
229-
238+
print("\n\nFull Summary:")
239+
print(summary.model_dump_json(indent=4))
240+
230241
self.pass_summaries.append(summary)
231242
self.notes.extend(summary.notes)
232243

libs/app_manager.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ def list_apps(self):
5858
result += f" [loaded] {app.toolset_id} - {app.name} - {app.description}\n"
5959
for app in unloaded_apps:
6060
result += f" [unloaded] {app.toolset_id} - {app.name} - {app.description}\n"
61-
61+
print()
62+
print(result)
6263
result += "\nApp Manager Tools:\n"
6364
for tool_schema in self.self_tool_schemas:
6465
result += f" (toolset_id: {tool_schema.toolset_id}) {tool_schema.name}({",".join([arg['name'] for arg in tool_schema.arguments])}) - description: {tool_schema.description}\n"
65-
print()
66-
print(result)
66+
6767
return result
6868

6969
def load_app(self, app_id: str):
@@ -90,7 +90,7 @@ def unload_app(self, app_id: str):
9090
{
9191
"toolset_id": "app_manager",
9292
"name": "unload_app",
93-
"description": "unloads an app.",
93+
"description": "unloads an app. do this to free up memory and resources.",
9494
"arguments": [{
9595
"name": "app_id",
9696
"type": "string",
@@ -137,9 +137,15 @@ def get_loaded_apps(self):
137137
result += "(note: these are the only tools available to you at this time)\n"
138138
for app_id in self.loaded_app_ids:
139139
for schema in self.schemas[app_id]:
140-
tool_schema = ToolSchema.model_validate_json(schema)
141-
# arguments is a list of dictionaries
142-
result += f" toolset_id='{tool_schema.toolset_id}' name='{tool_schema.name}' description='{tool_schema.description}' arguments='{tool_schema.arguments}'\n"
140+
try:
141+
tool_schema = ToolSchema.model_validate_json(schema)
142+
# arguments is a list of dictionaries
143+
result += f" toolset_id='{tool_schema.toolset_id}' name='{tool_schema.name}' description='{tool_schema.description}' arguments='{tool_schema.arguments}'\n"
144+
except Exception as e:
145+
print(f"Error validating tool schema: {e}")
146+
print(f"Schema: {schema}")
147+
print(type(schema))
148+
raise e
143149

144150
return result
145151

log_parser.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from pydantic import BaseModel
2+
3+
log_file = "std_out.txt"
4+
5+
class AgentRun(BaseModel):
6+
agent_id: str
7+
inner_text: str
8+
is_complete: bool
9+
10+
def parse_log_file(log_file: str):
11+
agent_runs = {} # key is the line after "###AGENT RUN STARTING###", looks like "###0###", array of runs
12+
13+
with open(log_file, "r") as file:
14+
lines = file.readlines()
15+
16+
previous_line = None
17+
current_agent_id = None
18+
for line in lines:
19+
if previous_line is not None and "###AGENT RUN STARTING###" in previous_line:
20+
current_agent_id = line.strip().split("###")[1]
21+
if agent_runs.get(current_agent_id) is None:
22+
agent_runs[current_agent_id] = []
23+
agent_runs[current_agent_id].append(AgentRun(agent_id=current_agent_id, inner_text="", is_complete=False))
24+
elif "###AGENT RUN COMPLETE###" in line:
25+
agent_runs[current_agent_id][-1].is_complete = True
26+
current_agent_id = None
27+
elif current_agent_id is not None and not agent_runs[current_agent_id][-1].is_complete:
28+
agent_runs[current_agent_id][-1].inner_text += line
29+
30+
previous_line = line
31+
return agent_runs
32+
33+
agent_runs = parse_log_file(log_file)
34+
35+
print(agent_runs["0"][-1].inner_text)

0 commit comments

Comments
 (0)