Skip to content

Commit 16667e3

Browse files
authored
Clean up (#231)
* Updates * Lots of clean up * Tell me how prompt * Remove unnecessary ref * Add custom prompt injection * Lint, clean up
1 parent 8e39326 commit 16667e3

File tree

6 files changed

+101
-115
lines changed

6 files changed

+101
-115
lines changed

AgentLLM.py

Lines changed: 75 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from json.decoder import JSONDecodeError
1515
import spacy
1616
from spacy.cli import download
17+
from CustomPrompt import CustomPrompt
1718

1819
try:
1920
nlp = spacy.load("en_core_web_sm")
@@ -27,7 +28,7 @@ class AgentLLM:
2728
def __init__(self, agent_name: str = "AgentLLM", primary_objective=None):
2829
self.CFG = Agent(agent_name)
2930
self.primary_objective = primary_objective
30-
self.initialize_task_list()
31+
self.task_list = deque([])
3132
self.commands = Commands(agent_name)
3233
self.available_commands = self.commands.get_available_commands()
3334
self.web_requests = web_requests()
@@ -60,60 +61,56 @@ def __init__(self, agent_name: str = "AgentLLM", primary_objective=None):
6061
self.agent_config = self.CFG.load_agent_config(self.agent_name)
6162
self.output_list = []
6263
self.stop_running_event = None
63-
self.instruct = self.CFG.instruct
6464

6565
def get_output_list(self):
6666
return self.output_list
6767

68-
def trim_context(self, context: List[str], max_tokens: int) -> List[str]:
69-
trimmed_context = []
70-
total_tokens = 0
71-
for item in context:
72-
item_tokens = len(nlp(item))
73-
if total_tokens + item_tokens <= max_tokens:
74-
trimmed_context.append(item)
75-
total_tokens += item_tokens
76-
else:
77-
break
78-
return trimmed_context
68+
def get_commands_string(self):
69+
if len(self.available_commands) == 0:
70+
return "No commands."
71+
72+
enabled_commands = filter(
73+
lambda command: command.get("enabled", True), self.available_commands
74+
)
75+
76+
friendly_names = map(
77+
lambda command: f"{command['friendly_name']} - {command['name']}({command['args']})",
78+
enabled_commands,
79+
)
80+
return "\n".join(friendly_names)
7981

8082
def run(
8183
self,
8284
task: str,
8385
max_context_tokens: int = 500,
8486
long_term_access: bool = False,
8587
commands_enabled: bool = True,
86-
instruction: bool = False,
88+
prompt: str = "",
89+
**kwargs,
8790
):
88-
if self.CFG.NO_MEMORY:
91+
cp = CustomPrompt()
92+
if prompt == "":
8993
prompt = task
94+
elif prompt in ["execute", "task", "priority"]:
95+
prompt = cp.get_model_prompt(prompt_name=prompt, model=self.CFG.AI_MODEL)
9096
else:
91-
self.CFG.log_interaction("USER", task)
92-
context = self.context_agent(
93-
query=task, top_results_num=3, long_term_access=long_term_access
94-
)
95-
context = self.trim_context(context, max_context_tokens)
96-
prompt = self.get_prompt_with_context(task=task, context=context)
97-
if instruction:
98-
# Command and prompt injection for instruction mode
99-
instruction_prompt = self.CFG.INSTRUCT_PROMPT
100-
prompt = instruction_prompt.replace("{task}", task)
101-
prompt = prompt.replace("{AGENT_NAME}", self.agent_name)
102-
103-
enabled_commands = filter(
104-
lambda command: command.get("enabled", True), self.available_commands
105-
)
106-
107-
friendly_names = map(
108-
lambda command: f"{command['friendly_name']} - {command['name']}({command['args']})",
109-
enabled_commands,
110-
)
97+
prompt = CustomPrompt().get_prompt(prompt)
11198

112-
if len(self.available_commands) == 0:
113-
prompt = prompt.replace("{COMMANDS}", "No commands.")
114-
else:
115-
prompt = prompt.replace("{COMMANDS}", "\n".join(friendly_names))
116-
self.response = self.instruct(prompt)
99+
context = self.context_agent(
100+
query=task,
101+
top_results_num=3,
102+
long_term_access=long_term_access,
103+
max_tokens=max_context_tokens,
104+
)
105+
formatted_prompt = prompt.format(
106+
task=task,
107+
agent_name=self.agent_name,
108+
commands=self.get_commands_string(),
109+
context=context,
110+
**kwargs,
111+
)
112+
self.CFG.log_interaction("USER", task)
113+
self.response = self.CFG.instruct(formatted_prompt)
117114
if not self.CFG.NO_MEMORY:
118115
self.store_result(task, self.response)
119116
self.CFG.log_interaction(self.agent_name, self.response)
@@ -190,7 +187,11 @@ def store_result(self, task_name: str, result: str):
190187
)
191188

192189
def context_agent(
193-
self, query: str, top_results_num: int, long_term_access: bool = False
190+
self,
191+
query: str,
192+
top_results_num: int,
193+
long_term_access: bool = False,
194+
max_tokens: int = 500,
194195
) -> List[str]:
195196
if long_term_access:
196197
interactions = self.CFG.memory["interactions"]
@@ -209,12 +210,16 @@ def context_agent(
209210
include=["metadatas"],
210211
)
211212
context = [item["result"] for item in results["metadatas"][0]]
212-
return context
213-
214-
def get_prompt_with_context(self, task: str, context: List[str]) -> str:
215-
context_str = "\n\n".join(context)
216-
prompt = f"Task: {task}\n\nContext: {context_str}\n\nResponse:"
217-
return prompt
213+
trimmed_context = []
214+
total_tokens = 0
215+
for item in context:
216+
item_tokens = len(nlp(item))
217+
if total_tokens + item_tokens <= max_tokens:
218+
trimmed_context.append(item)
219+
total_tokens += item_tokens
220+
else:
221+
break
222+
return "\n".join(trimmed_context)
218223

219224
def chunk_content(self, content: str, max_length: int = 500) -> List[str]:
220225
content_chunks = []
@@ -233,40 +238,30 @@ def chunk_content(self, content: str, max_length: int = 500) -> List[str]:
233238
content_chunks.append(" ".join(chunk))
234239
return content_chunks
235240

236-
def set_agent_name(self, agent_name):
237-
self.agent_name = agent_name
238-
239241
def get_status(self):
240242
try:
241243
return not self.stop_running_event.is_set()
242244
except:
243245
return False
244246

245-
def initialize_task_list(self):
246-
self.task_list = deque([])
247-
248247
def update_output_list(self, output):
249248
print(
250249
self.CFG.save_task_output(self.agent_name, output, self.primary_objective)
251250
)
252-
# self.output_list.append(output)
253-
254-
def set_objective(self, new_objective):
255-
self.primary_objective = new_objective
256251

257252
def task_creation_agent(
258253
self, result: Dict, task_description: str, task_list: List[str]
259254
) -> List[Dict]:
260-
prompt = self.CFG.TASK_PROMPT
261-
# Prompt Engineering - Objective
262-
prompt = prompt.replace("{objective}", self.primary_objective)
263-
# Prompt Engineering - Result
264-
prompt = prompt.replace("{result}", str(result))
265-
# Prompt Engineering - Task Description
266-
prompt = prompt.replace("{task_description}", task_description)
267-
# Prompt Engineering - Task List
268-
prompt = prompt.replace("{tasks}", ", ".join(task_list))
269-
response = self.run(prompt, commands_enabled=False)
255+
response = self.run(
256+
task=self.primary_objective,
257+
commands_enabled=False,
258+
prompt="task",
259+
objective=self.primary_objective,
260+
result=result,
261+
task_description=task_description,
262+
tasks=", ".join(task_list),
263+
)
264+
270265
lines = response.split("\n") if "\n" in response else [response]
271266
new_tasks = [
272267
re.sub(r"^.*?(\d)", r"\1", line)
@@ -278,14 +273,16 @@ def task_creation_agent(
278273
def prioritization_agent(self):
279274
task_names = [t["task_name"] for t in self.task_list]
280275
next_task_id = len(self.task_list) + 1
281-
prompt = self.CFG.PRIORITY_PROMPT
282-
# Prompt Engineering - Objective
283-
prompt = prompt.replace("{objective}", self.primary_objective)
284-
# Prompt Engineering - Task ID
285-
prompt = prompt.replace("{next_task_id}", str(next_task_id))
286-
# Prompt Engineering - Task Names
287-
prompt = prompt.replace("{task_names}", ", ".join(task_names))
288-
response = self.run(prompt, commands_enabled=False)
276+
277+
response = self.run(
278+
task=self.primary_objective,
279+
commands_enabled=False,
280+
prompt="priority",
281+
objective=self.primary_objective,
282+
tasks=", ".join(task_names),
283+
next_task_id=next_task_id,
284+
)
285+
289286
lines = response.split("\n") if "\n" in response else [response]
290287
new_tasks = [
291288
re.sub(r"^.*?(\d)", r"\1", line)
@@ -300,35 +297,8 @@ def prioritization_agent(self):
300297
task_name = task_parts[1].strip()
301298
self.task_list.append({"task_id": task_id, "task_name": task_name})
302299

303-
def execution_agent(self, task: str, task_id: int) -> str:
304-
context = self.context_agent(
305-
query=f"{self.primary_objective} {task}", top_results_num=5
306-
)
307-
prompt = self.CFG.EXECUTION_PROMPT
308-
# Prompt Engineering - Objective
309-
prompt = prompt.replace("{objective}", self.primary_objective)
310-
# Prompt Engineering - Task
311-
prompt = prompt.replace("{task}", task)
312-
# Prompt Engineering - Context
313-
prompt = prompt.replace("{context}", "\n".join(context))
314-
# Prompt Engineering - Commands
315-
316-
enabled_commands = filter(
317-
lambda command: command.get("enabled", True), self.available_commands
318-
)
319-
320-
friendly_names = map(
321-
lambda command: f"{command['friendly_name']} - {command['name']}({command['args']})",
322-
enabled_commands,
323-
)
324-
325-
if task_id == 0 or len(self.available_commands) == 0:
326-
prompt = prompt.replace("{COMMANDS}", "No commands.")
327-
else:
328-
prompt = prompt.replace("{COMMANDS}", "\n".join(friendly_names))
329-
return self.run(prompt)
330-
331-
def run_task(self, stop_event):
300+
def run_task(self, stop_event, objective):
301+
self.primary_objective = objective
332302
self.update_output_list(
333303
f"Starting task with objective: {self.primary_objective}.\n\n"
334304
)
@@ -343,7 +313,7 @@ def run_task(self, stop_event):
343313
self.update_output_list(
344314
f"\nExecuting task {task['task_id']}: {task['task_name']}\n"
345315
)
346-
result = self.execution_agent(task["task_name"], task["task_id"])
316+
result = self.run(task=task["task_name"], prompt="execution")
347317
self.update_output_list(f"\nTask Result:\n\n{result}\n")
348318
new_tasks = self.task_creation_agent(
349319
{"data": result},

CustomPrompt.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,7 @@ def delete_prompt(self, prompt_name):
3232
def update_prompt(self, prompt_name, prompt):
3333
with open(os.path.join("prompts", f"{prompt_name}.txt"), "w") as f:
3434
f.write(prompt)
35+
36+
def get_model_prompt(self, prompt_name, model="default"):
37+
with open(f"model-prompts/{model}/{prompt_name}.txt", "r") as f:
38+
return f.read()

app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,11 @@ async def start_task_agent(agent_name: str, objective: Objective) -> ResponseMes
263263
# If it doesn't exist, create it.
264264
if agent_name not in CFG.agent_instances:
265265
CFG.agent_instances[agent_name] = AgentLLM(agent_name)
266-
CFG.agent_instances[agent_name].set_objective(objective.objective)
267266
stop_event = threading.Event()
268267
agent_stop_events[agent_name] = stop_event
269268
agent_thread = threading.Thread(
270-
target=CFG.agent_instances[agent_name].run_task, args=(stop_event,)
269+
target=CFG.agent_instances[agent_name].run_task,
270+
args=(stop_event, objective.objective),
271271
)
272272
agent_threads[agent_name] = agent_thread
273273
agent_thread.start()

prompts/Tell Me How.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Mark: Tony, help!
2+
Tony: What's wrong, Mark?
3+
Mark: I forgot how to {task}!
4+
Tony: That's easy! Do you want me to show you how?
5+
Mark: Sure!
6+
(continue as Tony)

provider/gpt4free.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import gpt4free
22

3+
34
class Gpt4freeProvider:
45
def __init__(
56
self,
@@ -8,11 +9,13 @@ def __init__(
89
MAX_TOKENS: int = 4096,
910
**kwargs
1011
):
11-
self.requirements = ['gpt4free']
12+
self.requirements = ["gpt4free"]
1213
self.AI_MODEL = AI_MODEL
1314
self.AI_TEMPERATURE = AI_TEMPERATURE
1415
self.MAX_TOKENS = MAX_TOKENS
1516

1617
def instruct(self, prompt):
17-
response = gpt4free.Completion.create(gpt4free.Provider.UseLess, prompt=prompt, model=self.AI_MODEL)
18+
response = gpt4free.Completion.create(
19+
gpt4free.Provider.UseLess, prompt=prompt, model=self.AI_MODEL
20+
)
1821
return response["text"]

provider/huggingface.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,17 @@
55
AutoModel,
66
AutoModelForSeq2SeqLM,
77
T5Tokenizer,
8-
AutoConfig
8+
AutoConfig,
99
)
1010

11+
1112
class HuggingfaceProvider:
1213
def __init__(
1314
self,
1415
AI_MODEL: str = "gpt2",
1516
AI_TEMPERATURE: float = 0.7,
1617
MAX_TOKENS: int = 1024,
17-
**kwargs
18+
**kwargs,
1819
):
1920
self.requirements = ["transformers", "torch", "accelerate"]
2021
self.AI_MODEL = AI_MODEL
@@ -25,7 +26,9 @@ def instruct(self, prompt):
2526
try:
2627
model_path = self.AI_MODEL
2728
if "chatglm" in model_path:
28-
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
29+
tokenizer = AutoTokenizer.from_pretrained(
30+
model_path, trust_remote_code=True
31+
)
2932
model = AutoModel.from_pretrained(model_path, trust_remote_code=True)
3033
elif "dolly" in model_path:
3134
tokenizer = AutoTokenizer.from_pretrained(model_path, use_fast=True)
@@ -50,18 +53,18 @@ def instruct(self, prompt):
5053
model_path, low_cpu_mem_usage=True
5154
)
5255

53-
input_ids = tokenizer(prompt, return_tensors='pt').input_ids
56+
input_ids = tokenizer(prompt, return_tensors="pt").input_ids
5457

5558
output_ids = model.generate(
5659
input_ids,
5760
pad_token_id=tokenizer.eos_token_id,
5861
temperature=self.AI_TEMPERATURE,
5962
max_new_tokens=self.MAX_TOKENS,
60-
no_repeat_ngram_size=2
63+
no_repeat_ngram_size=2,
6164
)
6265
input_length = 1 if model.config.is_encoder_decoder else len(input_ids[0])
6366
output_ids = output_ids[0][input_length:]
64-
67+
6568
return tokenizer.decode(output_ids, skip_special_tokens=True).strip()
6669
except Exception as e:
6770
return f"Transformer Error: {e}"

0 commit comments

Comments
 (0)