K00B404 commited on
Commit
8e6a14c
1 Parent(s): c29bcdf

Create BabiStreamlit.py

Browse files
Files changed (1) hide show
  1. BabiStreamlit.py +335 -0
BabiStreamlit.py ADDED
@@ -0,0 +1,335 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import time
3
+ import logging
4
+ from dotenv import load_dotenv
5
+ from collections import deque
6
+ from typing import Dict, List, Optional
7
+ import langchain
8
+ from langchain.chains import LLMChain
9
+ from langchain.prompts import PromptTemplate
10
+ from langchain_community.vectorstores import FAISS
11
+ from langchain_community.embeddings import HuggingFaceEmbeddings, HuggingFaceHubEmbeddings, HuggingFaceInferenceAPIEmbeddings
12
+
13
+ from langchain.llms import BaseLLM
14
+
15
+ from langchain.vectorstores.base import VectorStore
16
+ from pydantic import BaseModel, Field
17
+ import gradio as gr
18
+
19
+ from credits import HUGGINGFACE_TOKEN
20
+
21
+ # Set Variables
22
+ load_dotenv()
23
+
24
+ HF_TOKEN = os.getenv("HUGGINGFACE_TOKEN", HUGGINGFACE_TOKEN)
25
+
26
+ if HF_TOKEN != "your-huggingface-token":
27
+ os.environ["HUGGINGFACE_TOKEN"] = HF_TOKEN
28
+ else:
29
+ raise ValueError(
30
+ "HuggingFace Token EMPTY. Edit the .env file and put your HuggingFace token"
31
+ )
32
+
33
+ class TaskCreationChain(LLMChain):
34
+ """Chain to create tasks."""
35
+ #def __init__(self):
36
+ # self.logger = logging.getLogger("TaskCreationChain")
37
+
38
+ @classmethod
39
+ def from_llm(cls, llm: BaseLLM, objective: str, verbose: bool = True) -> LLMChain:
40
+ """Get the response parser."""
41
+ task_creation_template = (
42
+ "You are an task creation AI that uses the result of an execution agent"
43
+ " to create new tasks with the following objective: {objective},"
44
+ " The last completed task has the result: {result}."
45
+ " This result was based on this task description: {task_description}."
46
+ " These are incomplete tasks: {incomplete_tasks}."
47
+ " Based on the result, create new tasks to be completed"
48
+ " by the AI system that do not overlap with incomplete tasks."
49
+ " Return the tasks as an array."
50
+ )
51
+ prompt = PromptTemplate(
52
+ template=task_creation_template,
53
+ partial_variables={"objective": objective},
54
+ input_variables=["result", "task_description", "incomplete_tasks"],
55
+ )
56
+ return cls(prompt=prompt, llm=llm, verbose=verbose)
57
+
58
+
59
+ def get_next_task(self, result: Dict, task_description: str, task_list: List[str]) -> List[Dict]:
60
+ """Get the next task."""
61
+ incomplete_tasks = ", ".join(task_list)
62
+ response = self.run(result=result, task_description=task_description, incomplete_tasks=incomplete_tasks)
63
+ new_tasks = response.split('\n')
64
+ return [{"task_name": task_name} for task_name in new_tasks if task_name.strip()]
65
+
66
+
67
+ class TaskPrioritizationChain(LLMChain):
68
+ """Chain to prioritize tasks."""
69
+ #def __init__(self):
70
+ # self.logger = logging.getLogger("TaskPrioritizationChain")
71
+
72
+ @classmethod
73
+ def from_llm(cls, llm: BaseLLM, objective: str, verbose: bool = True) -> LLMChain:
74
+ """Get the response parser."""
75
+ task_prioritization_template = (
76
+ "You are an task prioritization AI tasked with cleaning the formatting of and reprioritizing"
77
+ " the following tasks: {task_names}."
78
+ " Consider the ultimate objective of your team: {objective}."
79
+ " Do not remove any tasks. Return the result as a numbered list, like:"
80
+ " #. First task"
81
+ " #. Second task"
82
+ " Start the task list with number {next_task_id}."
83
+ )
84
+ prompt = PromptTemplate(
85
+ template=task_prioritization_template,
86
+ partial_variables={"objective": objective},
87
+ input_variables=["task_names", "next_task_id"],
88
+ )
89
+ return cls(prompt=prompt, llm=llm, verbose=verbose)
90
+
91
+ def prioritize_tasks(self, this_task_id: int, task_list: List[Dict]) -> List[Dict]:
92
+ """Prioritize tasks."""
93
+ task_names = [t["task_name"] for t in task_list]
94
+ next_task_id = int(this_task_id) + 1
95
+ response = self.run(task_names=task_names, next_task_id=next_task_id)
96
+ new_tasks = response.split('\n')
97
+ prioritized_task_list = []
98
+ for task_string in new_tasks:
99
+ if not task_string.strip():
100
+ continue
101
+ task_parts = task_string.strip().split(".", 1)
102
+ if len(task_parts) == 2:
103
+ task_id = task_parts[0].strip()
104
+ task_name = task_parts[1].strip()
105
+ prioritized_task_list.append({"task_id": task_id, "task_name": task_name})
106
+ return prioritized_task_list
107
+
108
+
109
+ class ExecutionChain(LLMChain):
110
+ """Chain to execute tasks."""
111
+ vectorstore: VectorStore = Field(init=False)
112
+
113
+ #def __init__(self):
114
+ # self.logger = logging.getLogger("ExecutionChain")
115
+
116
+ @classmethod
117
+ def from_llm(cls, llm: BaseLLM, vectorstore: VectorStore, verbose: bool = True) -> LLMChain:
118
+ """Get the response parser."""
119
+ execution_template = (
120
+ "You are an AI who performs one task based on the following objective: {objective}."
121
+ " Take into account these previously completed tasks: {context}."
122
+ " Your task: {task}."
123
+ " Response:"
124
+ )
125
+ prompt = PromptTemplate(
126
+ template=execution_template,
127
+ input_variables=["objective", "context", "task"],
128
+ )
129
+ return cls(prompt=prompt, llm=llm, verbose=verbose, vectorstore=vectorstore)
130
+
131
+ def _get_top_tasks(self, query: str, k: int) -> List[str]:
132
+ """Get the top k tasks based on the query."""
133
+ results = self.vectorstore.similarity_search_with_score(query, k=k)
134
+ if not results:
135
+ return []
136
+ sorted_results, _ = zip(*sorted(results, key=lambda x: x[1], reverse=True))
137
+ return [str(item.metadata['task']) for item in sorted_results]
138
+
139
+ def execute_task(self, objective: str, task: str, k: int = 5) -> str:
140
+ """Execute a task."""
141
+ context = self._get_top_tasks(query=objective, k=k)
142
+ return self.run(objective=objective, context=context, task=task)
143
+
144
+
145
+ class Message:
146
+ exp: st.expander
147
+ ai_icon = "./img/robot.png"
148
+
149
+ def __init__(self, label: str):
150
+ message_area, icon_area = st.columns([10, 1])
151
+ icon_area.image(self.ai_icon, caption="BabyAGI")
152
+
153
+ # Expander
154
+ self.exp = message_area.expander(label=label, expanded=True)
155
+
156
+ def __enter__(self):
157
+ return self
158
+
159
+ def __exit__(self, ex_type, ex_value, trace):
160
+ pass
161
+
162
+ def write(self, content):
163
+ self.exp.markdown(content)
164
+
165
+
166
+ class BabyAGI(BaseModel):
167
+ """Controller model for the BabyAGI agent."""
168
+
169
+ objective: str = Field(alias="objective")
170
+ task_list: deque = Field(default_factory=deque)
171
+ task_creation_chain: TaskCreationChain = Field(...)
172
+ task_prioritization_chain: TaskPrioritizationChain = Field(...)
173
+ execution_chain: ExecutionChain = Field(...)
174
+ task_id_counter: int = Field(1)
175
+
176
+ #def __init__(self):
177
+ # Configure loggers for each chain
178
+ #self.task_creation_logger = logging.getLogger("TaskCreationChain")
179
+ #self.task_prioritization_logger = logging.getLogger("TaskPrioritizationChain")
180
+ #self.execution_logger = logging.getLogger("ExecutionChain")
181
+
182
+ def add_task(self, task: Dict):
183
+ self.task_list.append(task)
184
+
185
+ def print_task_list(self):
186
+ with Message(label="Task List") as m:
187
+ m.write("### Task List")
188
+ for t in self.task_list:
189
+ m.write("- " + str(t["task_id"]) + ": " + t["task_name"])
190
+ m.write("")
191
+
192
+ def print_next_task(self, task: Dict):
193
+ with Message(label="Next Task") as m:
194
+ m.write("### Next Task")
195
+ m.write("- " + str(task["task_id"]) + ": " + task["task_name"])
196
+ m.write("")
197
+
198
+ def print_task_result(self, result: str):
199
+ with Message(label="Task Result") as m:
200
+ m.write("### Task Result")
201
+ m.write(result)
202
+ m.write("")
203
+
204
+ def print_task_ending(self):
205
+ with Message(label="Task Ending") as m:
206
+ m.write("### Task Ending")
207
+ m.write("")
208
+
209
+ def print_iteration_number(self, iteration_number: int):
210
+ with Message(label="Iteration Number") as m:
211
+ m.write(f"### Iteration Number: {iteration_number}")
212
+
213
+
214
+ def run(self, max_iterations: Optional[int] = None):
215
+ """Run the agent."""
216
+ num_iters = 0
217
+ while True:
218
+ self.print_iteration_number(num_iters + 1) # Add this line
219
+ if self.task_list:
220
+ self.print_task_list()
221
+
222
+ # Step 1: Pull the first task
223
+ task = self.task_list.popleft()
224
+ self.print_next_task(task)
225
+
226
+ # Step 2: Execute the task
227
+ result = self.execution_chain.execute_task(
228
+ self.objective, task["task_name"]
229
+ )
230
+ this_task_id = int(task["task_id"])
231
+ self.print_task_result(result)
232
+
233
+ # Step 3: Store the result in Pinecone
234
+ result_id = f"result_{num_iters}_{task['task_id']}"
235
+ self.execution_chain.vectorstore.add_texts(
236
+ texts=[result],
237
+ metadatas=[{"task": task["task_name"]}],
238
+ ids=[result_id],
239
+ )
240
+ #self.execution_logger.info(f"Task: {task['task_name']}, Result: {result}") # Log execution information
241
+
242
+ # Step 4: Create new tasks and reprioritize task list
243
+ new_tasks = self.task_creation_chain.get_next_task(
244
+ result, task["task_name"], [t["task_name"] for t in self.task_list]
245
+ )
246
+ for new_task in new_tasks:
247
+ self.task_id_counter += 1
248
+ new_task.update({"task_id": self.task_id_counter})
249
+ self.add_task(new_task)
250
+ self.task_list = deque(
251
+ self.task_prioritization_chain.prioritize_tasks(
252
+ this_task_id, list(self.task_list)
253
+ )
254
+ )
255
+ # Log task creation information
256
+ #self.task_creation_logger.info(f"Result: {result}, Task Description: {task['task_name']}, Incomplete Tasks: {', '.join([t['task_name'] for t in self.task_list])}")
257
+
258
+ #self.task_prioritization_logger.info(f"This Task ID: {this_task_id}, Task List: {', '.join([t['task_name'] for t in self.task_list])}")
259
+
260
+ num_iters += 1
261
+ if max_iterations is not None and num_iters == max_iterations:
262
+ self.print_task_ending()
263
+ break
264
+
265
+ @classmethod
266
+ def from_llm_and_objectives(
267
+ cls,
268
+ llm: BaseLLM,
269
+ vectorstore: VectorStore,
270
+ objective: str,
271
+ first_task: str,
272
+ verbose: bool = False,
273
+ ) -> "BabyAGI":
274
+ """Initialize the BabyAGI Controller."""
275
+ task_creation_chain = TaskCreationChain.from_llm(
276
+ llm, objective, verbose=verbose
277
+ )
278
+ task_prioritization_chain = TaskPrioritizationChain.from_llm(
279
+ llm, objective, verbose=verbose
280
+ )
281
+ execution_chain = ExecutionChain.from_llm(llm, vectorstore, verbose=verbose)
282
+ controller = cls(
283
+ objective=objective,
284
+ task_creation_chain=task_creation_chain,
285
+ task_prioritization_chain=task_prioritization_chain,
286
+ execution_chain=execution_chain,
287
+ )
288
+ #task_id = int(time.time())
289
+ #controller.add_task({"task_id": task_id, "task_name": first_task})
290
+ controller.add_task({"task_id": 1, "task_name": first_task})
291
+ return controller
292
+
293
+
294
+
295
+ def main():
296
+ with gr.Blocks() as demo:
297
+ gr.Markdown("# BabyAGI Gradio")
298
+
299
+ with gr.Row():
300
+ with gr.Column():
301
+ objective = gr.Dropdown(
302
+ choices=["Make a small shooter in python OOP scripting", "Make a streamlit cheatsheet", "Make a advanced langchain examples sheet", "End poverty"],
303
+ label="Select Ultimate goal",
304
+ )
305
+ first_task = gr.Textbox(label="Input Where to start", value="Develop a task list")
306
+ max_iterations = gr.Number(label="Max iterations", value=3, precision=0)
307
+
308
+ with gr.Column():
309
+ run_button = gr.Button("Run")
310
+
311
+ output = gr.Textbox(label="Output")
312
+
313
+ def run_baby_agi(objective, first_task, max_iterations):
314
+ embedding_model = HuggingFaceInferenceAPIEmbeddings(api_key=os.environ["HUGGINGFACE_TOKEN"])
315
+ vectorstore = FAISS.from_texts(["_"], embedding_model, metadatas=[{"task": first_task}])
316
+
317
+ try:
318
+ baby_agi = BabyAGI.from_llm_and_objectives(
319
+ llm=best_llm,
320
+ vectorstore=vectorstore,
321
+ objective=objective,
322
+ first_task=first_task,
323
+ verbose=False,
324
+ )
325
+ baby_agi.run(max_iterations=max_iterations)
326
+ return "BabyAGI completed successfully!"
327
+ except Exception as e:
328
+ return str(e)
329
+
330
+ run_button.click(run_baby_agi, inputs=[objective, first_task, max_iterations], outputs=output)
331
+
332
+ demo.launch()
333
+
334
+ if __name__ == "__main__":
335
+ main()