praisonaiagents 0.0.11__tar.gz → 0.0.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/PKG-INFO +1 -1
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/agent/agent.py +63 -23
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/agents/agents.py +81 -1
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/main.py +64 -15
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/task/task.py +3 -1
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/PKG-INFO +1 -1
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/pyproject.toml +1 -1
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/agent/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/agents/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/agent/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/agent/agent.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/agents/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/agents/agents.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/main.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/task/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/task/task.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/task/__init__.py +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/SOURCES.txt +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/dependency_links.txt +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/requires.txt +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/top_level.txt +0 -0
- {praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/setup.cfg +0 -0
@@ -140,7 +140,7 @@ class Agent:
|
|
140
140
|
max_rpm: Optional[int] = None,
|
141
141
|
max_execution_time: Optional[int] = None,
|
142
142
|
memory: bool = True,
|
143
|
-
verbose: bool =
|
143
|
+
verbose: bool = True,
|
144
144
|
allow_delegation: bool = False,
|
145
145
|
step_callback: Optional[Any] = None,
|
146
146
|
cache: bool = True,
|
@@ -191,26 +191,44 @@ class Agent:
|
|
191
191
|
self.max_reflect = max_reflect
|
192
192
|
self.min_reflect = min_reflect
|
193
193
|
self.reflect_llm = reflect_llm
|
194
|
+
self.console = Console() # Create a single console instance for the agent
|
195
|
+
|
194
196
|
def execute_tool(self, function_name, arguments):
|
195
197
|
"""
|
196
198
|
Execute a tool dynamically based on the function name and arguments.
|
197
199
|
"""
|
198
200
|
logging.debug(f"{self.name} executing tool {function_name} with arguments: {arguments}")
|
199
201
|
|
200
|
-
# Try to
|
201
|
-
func =
|
202
|
+
# Try to find the function in the agent's tools list first
|
203
|
+
func = None
|
204
|
+
for tool in self.tools:
|
205
|
+
if callable(tool) and getattr(tool, '__name__', '') == function_name:
|
206
|
+
func = tool
|
207
|
+
break
|
208
|
+
|
209
|
+
logging.debug(f"Looking for {function_name} in agent tools: {func is not None}")
|
210
|
+
|
211
|
+
# If not found in tools, try globals and main
|
202
212
|
if not func:
|
203
|
-
|
204
|
-
|
205
|
-
|
213
|
+
func = globals().get(function_name)
|
214
|
+
logging.debug(f"Looking for {function_name} in globals: {func is not None}")
|
215
|
+
|
216
|
+
if not func:
|
217
|
+
import __main__
|
218
|
+
func = getattr(__main__, function_name, None)
|
219
|
+
logging.debug(f"Looking for {function_name} in __main__: {func is not None}")
|
206
220
|
|
207
221
|
if func and callable(func):
|
208
222
|
try:
|
209
223
|
return func(**arguments)
|
210
224
|
except Exception as e:
|
211
|
-
|
225
|
+
error_msg = str(e)
|
226
|
+
logging.error(f"Error executing tool {function_name}: {error_msg}")
|
227
|
+
return {"error": error_msg}
|
212
228
|
|
213
|
-
|
229
|
+
error_msg = f"Tool '{function_name}' is not callable"
|
230
|
+
logging.error(error_msg)
|
231
|
+
return {"error": error_msg}
|
214
232
|
|
215
233
|
def clear_history(self):
|
216
234
|
self.chat_history = []
|
@@ -219,7 +237,6 @@ class Agent:
|
|
219
237
|
return f"Agent(name='{self.name}', role='{self.role}', goal='{self.goal}')"
|
220
238
|
|
221
239
|
def _chat_completion(self, messages, temperature=0.2, tools=None, stream=True):
|
222
|
-
console = Console()
|
223
240
|
start_time = time.time()
|
224
241
|
logging.debug(f"{self.name} sending messages to LLM: {messages}")
|
225
242
|
|
@@ -289,12 +306,24 @@ class Agent:
|
|
289
306
|
stream=True
|
290
307
|
)
|
291
308
|
full_response_text = ""
|
292
|
-
|
309
|
+
|
310
|
+
# Create Live display with proper configuration
|
311
|
+
with Live(
|
312
|
+
display_generating("", start_time),
|
313
|
+
console=self.console,
|
314
|
+
refresh_per_second=4,
|
315
|
+
transient=False, # Changed to False to preserve output
|
316
|
+
vertical_overflow="ellipsis",
|
317
|
+
auto_refresh=True
|
318
|
+
) as live:
|
293
319
|
for chunk in response_stream:
|
294
320
|
if chunk.choices[0].delta.content:
|
295
321
|
full_response_text += chunk.choices[0].delta.content
|
296
322
|
live.update(display_generating(full_response_text, start_time))
|
297
|
-
|
323
|
+
|
324
|
+
# Clear the last generating display with a blank line
|
325
|
+
self.console.print()
|
326
|
+
|
298
327
|
final_response = client.chat.completions.create(
|
299
328
|
model=self.llm,
|
300
329
|
messages=messages,
|
@@ -331,7 +360,11 @@ Your Goal: {self.goal}
|
|
331
360
|
if system_prompt:
|
332
361
|
messages.append({"role": "system", "content": system_prompt})
|
333
362
|
messages.extend(self.chat_history)
|
334
|
-
|
363
|
+
if isinstance(prompt, list):
|
364
|
+
# If we receive a multimodal prompt list, place it directly in the user message
|
365
|
+
messages.append({"role": "user", "content": prompt})
|
366
|
+
else:
|
367
|
+
messages.append({"role": "user", "content": prompt})
|
335
368
|
|
336
369
|
final_response_text = None
|
337
370
|
reflection_count = 0
|
@@ -340,7 +373,14 @@ Your Goal: {self.goal}
|
|
340
373
|
while True:
|
341
374
|
try:
|
342
375
|
if self.verbose:
|
343
|
-
|
376
|
+
# Handle both string and list prompts for instruction display
|
377
|
+
display_text = prompt
|
378
|
+
if isinstance(prompt, list):
|
379
|
+
# Extract text content from multimodal prompt
|
380
|
+
display_text = next((item["text"] for item in prompt if item["type"] == "text"), "")
|
381
|
+
|
382
|
+
if display_text and str(display_text).strip():
|
383
|
+
display_instruction(f"Agent {self.name} is processing prompt: {display_text}", console=self.console)
|
344
384
|
|
345
385
|
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None)
|
346
386
|
if not response:
|
@@ -360,13 +400,13 @@ Your Goal: {self.goal}
|
|
360
400
|
arguments = json.loads(tool_call.function.arguments)
|
361
401
|
|
362
402
|
if self.verbose:
|
363
|
-
display_tool_call(f"Agent {self.name} is calling function '{function_name}' with arguments: {arguments}")
|
403
|
+
display_tool_call(f"Agent {self.name} is calling function '{function_name}' with arguments: {arguments}", console=self.console)
|
364
404
|
|
365
405
|
tool_result = self.execute_tool(function_name, arguments)
|
366
406
|
|
367
407
|
if tool_result:
|
368
408
|
if self.verbose:
|
369
|
-
display_tool_call(f"Function '{function_name}' returned: {tool_result}")
|
409
|
+
display_tool_call(f"Function '{function_name}' returned: {tool_result}", console=self.console)
|
370
410
|
messages.append({
|
371
411
|
"role": "tool",
|
372
412
|
"tool_call_id": tool_call.id,
|
@@ -391,7 +431,7 @@ Your Goal: {self.goal}
|
|
391
431
|
self.chat_history.append({"role": "assistant", "content": response_text})
|
392
432
|
if self.verbose:
|
393
433
|
logging.info(f"Agent {self.name} final response: {response_text}")
|
394
|
-
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time)
|
434
|
+
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time, console=self.console)
|
395
435
|
return response_text
|
396
436
|
|
397
437
|
reflection_prompt = f"""
|
@@ -414,26 +454,26 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
|
414
454
|
reflection_output = reflection_response.choices[0].message.parsed
|
415
455
|
|
416
456
|
if self.verbose:
|
417
|
-
display_self_reflection(f"Agent {self.name} self reflection (using {self.reflect_llm if self.reflect_llm else self.llm}): reflection='{reflection_output.reflection}' satisfactory='{reflection_output.satisfactory}'")
|
457
|
+
display_self_reflection(f"Agent {self.name} self reflection (using {self.reflect_llm if self.reflect_llm else self.llm}): reflection='{reflection_output.reflection}' satisfactory='{reflection_output.satisfactory}'", console=self.console)
|
418
458
|
|
419
459
|
messages.append({"role": "assistant", "content": f"Self Reflection: {reflection_output.reflection} Satisfactory?: {reflection_output.satisfactory}"})
|
420
460
|
|
421
461
|
# Only consider satisfactory after minimum reflections
|
422
462
|
if reflection_output.satisfactory == "yes" and reflection_count >= self.min_reflect - 1:
|
423
463
|
if self.verbose:
|
424
|
-
display_self_reflection("Agent marked the response as satisfactory after meeting minimum reflections")
|
464
|
+
display_self_reflection("Agent marked the response as satisfactory after meeting minimum reflections", console=self.console)
|
425
465
|
self.chat_history.append({"role": "user", "content": prompt})
|
426
466
|
self.chat_history.append({"role": "assistant", "content": response_text})
|
427
|
-
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time)
|
467
|
+
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time, console=self.console)
|
428
468
|
return response_text
|
429
469
|
|
430
470
|
# Check if we've hit max reflections
|
431
471
|
if reflection_count >= self.max_reflect - 1:
|
432
472
|
if self.verbose:
|
433
|
-
display_self_reflection("Maximum reflection count reached, returning current response")
|
473
|
+
display_self_reflection("Maximum reflection count reached, returning current response", console=self.console)
|
434
474
|
self.chat_history.append({"role": "user", "content": prompt})
|
435
475
|
self.chat_history.append({"role": "assistant", "content": response_text})
|
436
|
-
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time)
|
476
|
+
display_interaction(prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time, console=self.console)
|
437
477
|
return response_text
|
438
478
|
|
439
479
|
logging.debug(f"{self.name} reflection count {reflection_count + 1}, continuing reflection process")
|
@@ -444,12 +484,12 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
|
444
484
|
continue # Continue the loop for more reflections
|
445
485
|
|
446
486
|
except Exception as e:
|
447
|
-
display_error(f"Error in parsing self-reflection json {e}. Retrying")
|
487
|
+
display_error(f"Error in parsing self-reflection json {e}. Retrying", console=self.console)
|
448
488
|
logging.error("Reflection parsing failed.", exc_info=True)
|
449
489
|
messages.append({"role": "assistant", "content": f"Self Reflection failed."})
|
450
490
|
reflection_count += 1
|
451
491
|
continue # Continue even after error to try again
|
452
492
|
|
453
493
|
except Exception as e:
|
454
|
-
display_error(f"Error in chat: {e}")
|
494
|
+
display_error(f"Error in chat: {e}", console=self.console)
|
455
495
|
return None
|
@@ -11,6 +11,33 @@ from ..main import display_error, TaskOutput, error_logs, client
|
|
11
11
|
from ..agent.agent import Agent
|
12
12
|
from ..task.task import Task
|
13
13
|
|
14
|
+
def encode_file_to_base64(file_path: str) -> str:
|
15
|
+
"""Base64-encode a file."""
|
16
|
+
import base64
|
17
|
+
with open(file_path, "rb") as f:
|
18
|
+
return base64.b64encode(f.read()).decode("utf-8")
|
19
|
+
|
20
|
+
def process_video(video_path: str, seconds_per_frame=2):
|
21
|
+
"""Split video into frames (base64-encoded)."""
|
22
|
+
import cv2
|
23
|
+
import base64
|
24
|
+
base64_frames = []
|
25
|
+
video = cv2.VideoCapture(video_path)
|
26
|
+
total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
|
27
|
+
fps = video.get(cv2.CAP_PROP_FPS)
|
28
|
+
frames_to_skip = int(fps * seconds_per_frame)
|
29
|
+
curr_frame = 0
|
30
|
+
while curr_frame < total_frames:
|
31
|
+
video.set(cv2.CAP_PROP_POS_FRAMES, curr_frame)
|
32
|
+
success, frame = video.read()
|
33
|
+
if not success:
|
34
|
+
break
|
35
|
+
_, buffer = cv2.imencode(".jpg", frame)
|
36
|
+
base64_frames.append(base64.b64encode(buffer).decode("utf-8"))
|
37
|
+
curr_frame += frames_to_skip
|
38
|
+
video.release()
|
39
|
+
return base64_frames
|
40
|
+
|
14
41
|
class PraisonAIAgents:
|
15
42
|
def __init__(self, agents, tasks, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None):
|
16
43
|
self.agents = agents
|
@@ -58,6 +85,19 @@ class PraisonAIAgents:
|
|
58
85
|
display_error(f"Error: Task with ID {task_id} does not exist")
|
59
86
|
return
|
60
87
|
task = self.tasks[task_id]
|
88
|
+
|
89
|
+
# Only import multimodal dependencies if task has images
|
90
|
+
if task.images and task.status == "not started":
|
91
|
+
try:
|
92
|
+
import cv2
|
93
|
+
import base64
|
94
|
+
from moviepy import VideoFileClip
|
95
|
+
except ImportError as e:
|
96
|
+
display_error(f"Error: Missing required dependencies for image/video processing: {e}")
|
97
|
+
display_error("Please install with: pip install opencv-python moviepy")
|
98
|
+
task.status = "failed"
|
99
|
+
return None
|
100
|
+
|
61
101
|
if task.status == "not started":
|
62
102
|
task.status = "in progress"
|
63
103
|
|
@@ -83,7 +123,47 @@ Expected Output: {task.expected_output}.
|
|
83
123
|
if self.verbose >= 2:
|
84
124
|
logging.info(f"Executing task {task_id}: {task.description} using {executor_agent.name}")
|
85
125
|
logging.debug(f"Starting execution of task {task_id} with prompt:\n{task_prompt}")
|
86
|
-
|
126
|
+
|
127
|
+
if task.images:
|
128
|
+
def _get_multimodal_message(text_prompt, images):
|
129
|
+
content = [{"type": "text", "text": text_prompt}]
|
130
|
+
|
131
|
+
for img in images:
|
132
|
+
# If local file path for a valid image
|
133
|
+
if os.path.exists(img):
|
134
|
+
ext = os.path.splitext(img)[1].lower()
|
135
|
+
# If it's a .mp4, convert to frames
|
136
|
+
if ext == ".mp4":
|
137
|
+
frames = process_video(img, seconds_per_frame=1)
|
138
|
+
content.append({"type": "text", "text": "These are frames from the video."})
|
139
|
+
for f in frames:
|
140
|
+
content.append({
|
141
|
+
"type": "image_url",
|
142
|
+
"image_url": {"url": f"data:image/jpg;base64,{f}"}
|
143
|
+
})
|
144
|
+
else:
|
145
|
+
encoded = encode_file_to_base64(img)
|
146
|
+
content.append({
|
147
|
+
"type": "image_url",
|
148
|
+
"image_url": {
|
149
|
+
"url": f"data:image/{ext.lstrip('.')};base64,{encoded}"
|
150
|
+
}
|
151
|
+
})
|
152
|
+
else:
|
153
|
+
# Treat as a remote URL
|
154
|
+
content.append({
|
155
|
+
"type": "image_url",
|
156
|
+
"image_url": {"url": img}
|
157
|
+
})
|
158
|
+
return content
|
159
|
+
|
160
|
+
agent_output = executor_agent.chat(
|
161
|
+
_get_multimodal_message(task_prompt, task.images),
|
162
|
+
tools=task.tools
|
163
|
+
)
|
164
|
+
else:
|
165
|
+
agent_output = executor_agent.chat(task_prompt, tools=task.tools)
|
166
|
+
|
87
167
|
if agent_output:
|
88
168
|
task_output = TaskOutput(
|
89
169
|
description=task.description,
|
@@ -25,43 +25,92 @@ logging.basicConfig(
|
|
25
25
|
# Global list to store error logs
|
26
26
|
error_logs = []
|
27
27
|
|
28
|
-
def
|
29
|
-
|
30
|
-
if
|
28
|
+
def _clean_display_content(content: str, max_length: int = 20000) -> str:
|
29
|
+
"""Helper function to clean and truncate content for display."""
|
30
|
+
if not content or not str(content).strip():
|
31
|
+
return ""
|
32
|
+
|
33
|
+
content = str(content)
|
34
|
+
# Handle base64 content
|
35
|
+
if "base64" in content:
|
36
|
+
content_parts = []
|
37
|
+
for line in content.split('\n'):
|
38
|
+
if "base64" not in line:
|
39
|
+
content_parts.append(line)
|
40
|
+
content = '\n'.join(content_parts)
|
41
|
+
|
42
|
+
# Truncate if too long
|
43
|
+
if len(content) > max_length:
|
44
|
+
content = content[:max_length] + "..."
|
45
|
+
|
46
|
+
return content.strip()
|
47
|
+
|
48
|
+
def display_interaction(message, response, markdown=True, generation_time=None, console=None):
|
49
|
+
"""Display the interaction between user and assistant."""
|
50
|
+
if console is None:
|
51
|
+
console = Console()
|
52
|
+
if generation_time:
|
31
53
|
console.print(Text(f"Response generated in {generation_time:.1f}s", style="dim"))
|
32
|
-
|
33
|
-
|
54
|
+
|
55
|
+
# Handle multimodal content (list)
|
56
|
+
if isinstance(message, list):
|
57
|
+
# Extract just the text content from the multimodal message
|
58
|
+
text_content = next((item["text"] for item in message if item["type"] == "text"), "")
|
59
|
+
message = text_content
|
60
|
+
|
61
|
+
message = _clean_display_content(str(message))
|
62
|
+
response = _clean_display_content(str(response))
|
34
63
|
|
35
64
|
if markdown:
|
36
65
|
console.print(Panel.fit(Markdown(message), title="Message", border_style="cyan"))
|
37
66
|
console.print(Panel.fit(Markdown(response), title="Response", border_style="cyan"))
|
38
67
|
else:
|
39
68
|
console.print(Panel.fit(Text(message, style="bold green"), title="Message", border_style="cyan"))
|
40
|
-
console.print(Panel.fit(Text(response, style="bold
|
41
|
-
|
42
|
-
def display_self_reflection(message: str):
|
43
|
-
|
69
|
+
console.print(Panel.fit(Text(response, style="bold blue"), title="Response", border_style="cyan"))
|
70
|
+
|
71
|
+
def display_self_reflection(message: str, console=None):
|
72
|
+
if not message or not message.strip():
|
73
|
+
return
|
74
|
+
if console is None:
|
75
|
+
console = Console()
|
76
|
+
message = _clean_display_content(str(message))
|
44
77
|
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
|
45
78
|
|
46
|
-
def display_instruction(message: str):
|
47
|
-
|
79
|
+
def display_instruction(message: str, console=None):
|
80
|
+
if not message or not message.strip():
|
81
|
+
return
|
82
|
+
if console is None:
|
83
|
+
console = Console()
|
84
|
+
message = _clean_display_content(str(message))
|
48
85
|
console.print(Panel.fit(Text(message, style="bold blue"), title="Instruction", border_style="cyan"))
|
49
86
|
|
50
|
-
def display_tool_call(message: str):
|
51
|
-
|
87
|
+
def display_tool_call(message: str, console=None):
|
88
|
+
if not message or not message.strip():
|
89
|
+
return
|
90
|
+
if console is None:
|
91
|
+
console = Console()
|
92
|
+
message = _clean_display_content(str(message))
|
52
93
|
console.print(Panel.fit(Text(message, style="bold cyan"), title="Tool Call", border_style="green"))
|
53
94
|
|
54
|
-
def display_error(message: str):
|
55
|
-
|
95
|
+
def display_error(message: str, console=None):
|
96
|
+
if not message or not message.strip():
|
97
|
+
return
|
98
|
+
if console is None:
|
99
|
+
console = Console()
|
100
|
+
message = _clean_display_content(str(message))
|
56
101
|
console.print(Panel.fit(Text(message, style="bold red"), title="Error", border_style="red"))
|
57
102
|
# Store errors
|
58
103
|
error_logs.append(message)
|
59
104
|
|
60
105
|
def display_generating(content: str = "", start_time: Optional[float] = None):
|
106
|
+
if not content or not str(content).strip():
|
107
|
+
return Panel("", title="", border_style="green") # Return empty panel when no content
|
61
108
|
elapsed_str = ""
|
62
109
|
if start_time is not None:
|
63
110
|
elapsed = time.time() - start_time
|
64
111
|
elapsed_str = f" {elapsed:.1f}s"
|
112
|
+
|
113
|
+
content = _clean_display_content(str(content))
|
65
114
|
return Panel(Markdown(content), title=f"Generating...{elapsed_str}", border_style="green")
|
66
115
|
|
67
116
|
def clean_triple_backticks(text: str) -> str:
|
@@ -22,7 +22,8 @@ class Task:
|
|
22
22
|
status: str = "not started",
|
23
23
|
result: Optional[TaskOutput] = None,
|
24
24
|
create_directory: Optional[bool] = False,
|
25
|
-
id: Optional[int] = None
|
25
|
+
id: Optional[int] = None,
|
26
|
+
images: Optional[List[str]] = None
|
26
27
|
):
|
27
28
|
self.description = description
|
28
29
|
self.expected_output = expected_output
|
@@ -40,6 +41,7 @@ class Task:
|
|
40
41
|
self.result = result
|
41
42
|
self.create_directory = create_directory
|
42
43
|
self.id = id
|
44
|
+
self.images = images if images else []
|
43
45
|
|
44
46
|
if self.output_json and self.output_pydantic:
|
45
47
|
raise ValueError("Only one output type can be defined")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents/build/lib/praisonaiagents/main.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{praisonaiagents-0.0.11 → praisonaiagents-0.0.13}/praisonaiagents.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|