eaglelandsonce commited on
Commit
c9518d7
1 Parent(s): d167f12

Delete gmixai.py

Browse files
Files changed (1) hide show
  1. gmixai.py +0 -422
gmixai.py DELETED
@@ -1,422 +0,0 @@
1
- import json
2
- import uuid
3
- from typing import Any, Dict, List, Optional, Union
4
-
5
- from pydantic_core import PydanticCustomError
6
- from crewai.agents.cache import CacheHandler
7
- from crewai.tools.agent_tools import AgentTools
8
- from typing import Any, List, Optional
9
- from langchain.agents.format_scratchpad import format_log_to_str
10
- from langchain_openai import ChatOpenAI
11
- from langchain.memory import ConversationSummaryMemory
12
- from langchain.tools.render import render_text_description
13
- from langchain_core.runnables.config import RunnableConfig
14
-
15
-
16
- # Content from crew.py
17
- from pydantic import (
18
- UUID4,
19
- BaseModel,
20
- ConfigDict,
21
- Field,
22
- InstanceOf,
23
- Json,
24
- field_validator,
25
- model_validator,
26
- )
27
-
28
- from crewai.agents import (
29
- CacheHandler,
30
- CrewAgentExecutor,
31
- CrewAgentOutputParser,
32
- ToolsHandler,
33
- )
34
- class Gmix(BaseModel):
35
- """Class that represents a group of agents, how they should work together and their tasks."""
36
-
37
- __hash__ = object.__hash__
38
- model_config = ConfigDict(arbitrary_types_allowed=True)
39
- tasks: List[Task] = Field(description="List of tasks", default_factory=list)
40
- agents: List[Agent] = Field(
41
- description="List of agents in this crew.", default_factory=list
42
- )
43
- process: Process = Field(
44
- description="Process that the crew will follow.", default=Process.sequential
45
- )
46
- verbose: Union[int, bool] = Field(
47
- description="Verbose mode for the Agent Execution", default=0
48
- )
49
- config: Optional[Union[Json, Dict[str, Any]]] = Field(
50
- description="Configuration of the crew.", default=None
51
- )
52
- cache_handler: Optional[InstanceOf[CacheHandler]] = Field(
53
- default=CacheHandler(), description="An instance of the CacheHandler class."
54
- )
55
- id: UUID4 = Field(
56
- default_factory=uuid.uuid4,
57
- frozen=True,
58
- description="Unique identifier for the object, not set by user.",
59
- )
60
-
61
- @field_validator("id", mode="before")
62
- @classmethod
63
- def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
64
- if v:
65
- raise PydanticCustomError(
66
- "may_not_set_field", "This field is not to be set by the user.", {}
67
- )
68
-
69
- @classmethod
70
- @field_validator("config", mode="before")
71
- def check_config_type(cls, v: Union[Json, Dict[str, Any]]):
72
- if isinstance(v, Json):
73
- return json.loads(v)
74
- return v
75
-
76
- @model_validator(mode="after")
77
- def check_config(self):
78
- if not self.config and not self.tasks and not self.agents:
79
- raise PydanticCustomError(
80
- "missing_keys", "Either agents and task need to be set or config.", {}
81
- )
82
-
83
- if self.config:
84
- if not self.config.get("agents") or not self.config.get("tasks"):
85
- raise PydanticCustomError(
86
- "missing_keys_in_config", "Config should have agents and tasks", {}
87
- )
88
-
89
- self.agents = [Agent(**agent) for agent in self.config["agents"]]
90
-
91
- tasks = []
92
- for task in self.config["tasks"]:
93
- task_agent = [agt for agt in self.agents if agt.role == task["agent"]][
94
- 0
95
- ]
96
- del task["agent"]
97
- tasks.append(Task(**task, agent=task_agent))
98
-
99
- self.tasks = tasks
100
-
101
- if self.agents:
102
- for agent in self.agents:
103
- agent.set_cache_handler(self.cache_handler)
104
- return self
105
-
106
- def kickoff(self) -> str:
107
- """Kickoff the crew to work on its tasks.
108
-
109
- Returns:
110
- Output of the crew for each task.
111
- """
112
- for agent in self.agents:
113
- agent.cache_handler = self.cache_handler
114
-
115
- if self.process == Process.sequential:
116
- return self.__sequential_loop()
117
-
118
- def __sequential_loop(self) -> str:
119
- """Loop that executes the sequential process.
120
-
121
- Returns:
122
- Output of the crew.
123
- """
124
- task_outcome = None
125
- for task in self.tasks:
126
- # Add delegation tools to the task if the agent allows it
127
- if task.agent.allow_delegation:
128
- tools = AgentTools(agents=self.agents).tools()
129
- task.tools += tools
130
-
131
- self.__log("debug", f"Working Agent: {task.agent.role}")
132
- self.__log("info", f"Starting Task: {task.description} ...")
133
-
134
- task_outcome = task.execute(task_outcome)
135
-
136
- self.__log("debug", f"Task output: {task_outcome}")
137
-
138
- return task_outcome
139
-
140
- def __log(self, level, message):
141
- """Log a message"""
142
- level_map = {"debug": 1, "info": 2}
143
- verbose_level = (
144
- 2 if isinstance(self.verbose, bool) and self.verbose else self.verbose
145
- )
146
- if verbose_level and level_map[level] <= verbose_level:
147
- print(message)
148
-
149
-
150
- class Agent(BaseModel):
151
- """Represents an agent in a system.
152
-
153
- Each agent has a role, a goal, a backstory, and an optional language model (llm).
154
- The agent can also have memory, can operate in verbose mode, and can delegate tasks to other agents.
155
-
156
- Attributes:
157
- agent_executor: An instance of the CrewAgentExecutor class.
158
- role: The role of the agent.
159
- goal: The objective of the agent.
160
- backstory: The backstory of the agent.
161
- llm: The language model that will run the agent.
162
- memory: Whether the agent should have memory or not.
163
- verbose: Whether the agent execution should be in verbose mode.
164
- allow_delegation: Whether the agent is allowed to delegate tasks to other agents.
165
- """
166
-
167
- __hash__ = object.__hash__
168
- model_config = ConfigDict(arbitrary_types_allowed=True)
169
- id: UUID4 = Field(
170
- default_factory=uuid.uuid4,
171
- frozen=True,
172
- description="Unique identifier for the object, not set by user.",
173
- )
174
- role: str = Field(description="Role of the agent")
175
- goal: str = Field(description="Objective of the agent")
176
- backstory: str = Field(description="Backstory of the agent")
177
- llm: Optional[Any] = Field(
178
- default_factory=lambda: ChatOpenAI(
179
- temperature=0.7,
180
- model_name="gpt-4",
181
- ),
182
- description="Language model that will run the agent.",
183
- )
184
- memory: bool = Field(
185
- default=True, description="Whether the agent should have memory or not"
186
- )
187
- verbose: bool = Field(
188
- default=False, description="Verbose mode for the Agent Execution"
189
- )
190
- allow_delegation: bool = Field(
191
- default=True, description="Allow delegation of tasks to agents"
192
- )
193
- tools: List[Any] = Field(
194
- default_factory=list, description="Tools at agents disposal"
195
- )
196
- agent_executor: Optional[InstanceOf[CrewAgentExecutor]] = Field(
197
- default=None, description="An instance of the CrewAgentExecutor class."
198
- )
199
- tools_handler: Optional[InstanceOf[ToolsHandler]] = Field(
200
- default=None, description="An instance of the ToolsHandler class."
201
- )
202
- cache_handler: Optional[InstanceOf[CacheHandler]] = Field(
203
- default=CacheHandler(), description="An instance of the CacheHandler class."
204
- )
205
-
206
- @field_validator("id", mode="before")
207
- @classmethod
208
- def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
209
- if v:
210
- raise PydanticCustomError(
211
- "may_not_set_field", "This field is not to be set by the user.", {}
212
- )
213
-
214
- @model_validator(mode="after")
215
- def check_agent_executor(self) -> "Agent":
216
- if not self.agent_executor:
217
- self.set_cache_handler(self.cache_handler)
218
- return self
219
-
220
- def execute_task(
221
- self, task: str, context: str = None, tools: List[Any] = None
222
- ) -> str:
223
- """Execute a task with the agent.
224
-
225
- Args:
226
- task: Task to execute.
227
- context: Context to execute the task in.
228
- tools: Tools to use for the task.
229
-
230
- Returns:
231
- Output of the agent
232
- """
233
- if context:
234
- task = "\n".join(
235
- [task, "\nThis is the context you are working with:", context]
236
- )
237
-
238
- tools = tools or self.tools
239
- self.agent_executor.tools = tools
240
-
241
- return self.agent_executor.invoke(
242
- {
243
- "input": task,
244
- "tool_names": self.__tools_names(tools),
245
- "tools": render_text_description(tools),
246
- },
247
- RunnableConfig(callbacks=[self.tools_handler]),
248
- )["output"]
249
-
250
- def set_cache_handler(self, cache_handler) -> None:
251
- self.cache_handler = cache_handler
252
- self.tools_handler = ToolsHandler(cache=self.cache_handler)
253
- self.__create_agent_executor()
254
-
255
- def __create_agent_executor(self) -> CrewAgentExecutor:
256
- """Create an agent executor for the agent.
257
-
258
- Returns:
259
- An instance of the CrewAgentExecutor class.
260
- """
261
- agent_args = {
262
- "input": lambda x: x["input"],
263
- "tools": lambda x: x["tools"],
264
- "tool_names": lambda x: x["tool_names"],
265
- "agent_scratchpad": lambda x: format_log_to_str(x["intermediate_steps"]),
266
- }
267
- executor_args = {
268
- "tools": self.tools,
269
- "verbose": self.verbose,
270
- "handle_parsing_errors": True,
271
- }
272
-
273
- if self.memory:
274
- summary_memory = ConversationSummaryMemory(
275
- llm=self.llm, memory_key="chat_history", input_key="input"
276
- )
277
- executor_args["memory"] = summary_memory
278
- agent_args["chat_history"] = lambda x: x["chat_history"]
279
- prompt = Prompts.TASK_EXECUTION_WITH_MEMORY_PROMPT
280
- else:
281
- prompt = Prompts.TASK_EXECUTION_PROMPT
282
-
283
- execution_prompt = prompt.partial(
284
- goal=self.goal,
285
- role=self.role,
286
- backstory=self.backstory,
287
- )
288
-
289
- bind = self.llm.bind(stop=["\nObservation"])
290
- inner_agent = (
291
- agent_args
292
- | execution_prompt
293
- | bind
294
- | CrewAgentOutputParser(
295
- tools_handler=self.tools_handler, cache=self.cache_handler
296
- )
297
- )
298
- self.agent_executor = CrewAgentExecutor(agent=inner_agent, **executor_args)
299
-
300
- @staticmethod
301
- def __tools_names(tools) -> str:
302
- return ", ".join([t.name for t in tools])
303
-
304
-
305
- # Content from task.py
306
- class Task(BaseModel):
307
- """Class that represent a task to be executed."""
308
- __hash__ = object.__hash__
309
- description: str = Field(description="Description of the actual task.")
310
- agent: Optional[Agent] = Field(
311
- description="Agent responsible for the task.", default=None
312
- )
313
- tools: List[Any] = Field(
314
- default_factory=list,
315
- description="Tools the agent are limited to use for this task.",
316
- )
317
- id: UUID4 = Field(
318
- default_factory=uuid.uuid4,
319
- frozen=True,
320
- description="Unique identifier for the object, not set by user.",
321
- )
322
- @field_validator("id", mode="before")
323
- @classmethod
324
- def _deny_user_set_id(cls, v: Optional[UUID4]) -> None:
325
- if v:
326
- raise PydanticCustomError(
327
- "may_not_set_field", "This field is not to be set by the user.", {}
328
- )
329
- @model_validator(mode="after")
330
- def check_tools(self):
331
- if not self.tools and (self.agent and self.agent.tools):
332
- self.tools.extend(self.agent.tools)
333
- return self
334
- def execute(self, context: str = None) -> str:
335
- """Execute the task.
336
- Returns:
337
- Output of the task.
338
- """
339
- if self.agent:
340
- return self.agent.execute_task(
341
- task=self.description, context=context, tools=self.tools
342
- )
343
- else:
344
- raise Exception(
345
- f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Gmix using a specific process that support that, either consensual or hierarchical."
346
- )
347
-
348
-
349
-
350
- # Content from process.py
351
- class Process(str, Enum):
352
- """
353
- Class representing the different processes that can be used to tackle tasks
354
- """
355
- sequential = "sequential"
356
- # TODO: consensual = 'consensual'
357
- # TODO: hierarchical = 'hierarchical'
358
-
359
-
360
- # Content from prompts.py
361
- """Prompts for generic agent."""
362
- class Prompts(BaseModel):
363
- """Prompts for generic agent."""
364
- TASK_SLICE: ClassVar[str] = dedent(
365
- """\
366
- Begin! This is VERY important to you, your job depends on it!
367
- Current Task: {input}"""
368
- )
369
- SCRATCHPAD_SLICE: ClassVar[str] = "\n{agent_scratchpad}"
370
- MEMORY_SLICE: ClassVar[str] = dedent(
371
- """\
372
- This is the summary of your work so far:
373
- {chat_history}"""
374
- )
375
- ROLE_PLAYING_SLICE: ClassVar[str] = dedent(
376
- """\
377
- You are {role}.
378
- {backstory}
379
- Your personal goal is: {goal}"""
380
- )
381
- TOOLS_SLICE: ClassVar[str] = dedent(
382
- """\
383
- TOOLS:
384
- ------
385
- You have access to the following tools:
386
- {tools}
387
- To use a tool, please use the exact following format:
388
- ```
389
- Thought: Do I need to use a tool? Yes
390
- Action: the action to take, should be one of [{tool_names}], just the name.
391
- Action Input: the input to the action
392
- Observation: the result of the action
393
- ```
394
- When you have a response for your task, or if you do not need to use a tool, you MUST use the format:
395
- ```
396
- Thought: Do I need to use a tool? No
397
- Final Answer: [your response here]
398
- ```"""
399
- )
400
- VOTING_SLICE: ClassVar[str] = dedent(
401
- """\
402
- You are working on a crew with your co-workers and need to decide who will execute the task.
403
- These are your format instructions:
404
- {format_instructions}
405
- These are your co-workers and their roles:
406
- {coworkers}"""
407
- )
408
- TASK_EXECUTION_WITH_MEMORY_PROMPT: ClassVar[str] = PromptTemplate.from_template(
409
- ROLE_PLAYING_SLICE + TOOLS_SLICE + MEMORY_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
410
- )
411
- TASK_EXECUTION_PROMPT: ClassVar[str] = PromptTemplate.from_template(
412
- ROLE_PLAYING_SLICE + TOOLS_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
413
- )
414
- CONSENSUNS_VOTING_PROMPT: ClassVar[str] = PromptTemplate.from_template(
415
- ROLE_PLAYING_SLICE + VOTING_SLICE + TASK_SLICE + SCRATCHPAD_SLICE
416
- )
417
-
418
-
419
-
420
-
421
-
422
-