praisonaiagents 0.0.130__py3-none-any.whl → 0.0.132__py3-none-any.whl
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/agent/agent.py +95 -18
- praisonaiagents/agent/image_agent.py +12 -3
- praisonaiagents/agents/agents.py +32 -7
- praisonaiagents/guardrails/llm_guardrail.py +44 -2
- praisonaiagents/llm/llm.py +273 -44
- praisonaiagents/main.py +91 -45
- praisonaiagents/memory/memory.py +16 -6
- praisonaiagents/process/process.py +88 -4
- praisonaiagents/task/task.py +62 -6
- {praisonaiagents-0.0.130.dist-info → praisonaiagents-0.0.132.dist-info}/METADATA +1 -1
- {praisonaiagents-0.0.130.dist-info → praisonaiagents-0.0.132.dist-info}/RECORD +13 -13
- {praisonaiagents-0.0.130.dist-info → praisonaiagents-0.0.132.dist-info}/WHEEL +0 -0
- {praisonaiagents-0.0.130.dist-info → praisonaiagents-0.0.132.dist-info}/top_level.txt +0 -0
praisonaiagents/main.py
CHANGED
@@ -62,6 +62,30 @@ def register_approval_callback(callback_fn):
|
|
62
62
|
global approval_callback
|
63
63
|
approval_callback = callback_fn
|
64
64
|
|
65
|
+
def execute_sync_callback(display_type: str, **kwargs):
|
66
|
+
"""Execute synchronous callback for a given display type without displaying anything.
|
67
|
+
|
68
|
+
This function is used to trigger callbacks even when verbose=False.
|
69
|
+
|
70
|
+
Args:
|
71
|
+
display_type (str): Type of display event
|
72
|
+
**kwargs: Arguments to pass to the callback function
|
73
|
+
"""
|
74
|
+
if display_type in sync_display_callbacks:
|
75
|
+
callback = sync_display_callbacks[display_type]
|
76
|
+
import inspect
|
77
|
+
sig = inspect.signature(callback)
|
78
|
+
|
79
|
+
# Filter kwargs to what the callback accepts to maintain backward compatibility
|
80
|
+
if any(p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()):
|
81
|
+
# Callback accepts **kwargs, so pass all arguments
|
82
|
+
supported_kwargs = kwargs
|
83
|
+
else:
|
84
|
+
# Only pass arguments that the callback signature supports
|
85
|
+
supported_kwargs = {k: v for k, v in kwargs.items() if k in sig.parameters}
|
86
|
+
|
87
|
+
callback(**supported_kwargs)
|
88
|
+
|
65
89
|
async def execute_callback(display_type: str, **kwargs):
|
66
90
|
"""Execute both sync and async callbacks for a given display type.
|
67
91
|
|
@@ -69,16 +93,38 @@ async def execute_callback(display_type: str, **kwargs):
|
|
69
93
|
display_type (str): Type of display event
|
70
94
|
**kwargs: Arguments to pass to the callback functions
|
71
95
|
"""
|
96
|
+
import inspect
|
97
|
+
|
72
98
|
# Execute synchronous callback if registered
|
73
99
|
if display_type in sync_display_callbacks:
|
74
100
|
callback = sync_display_callbacks[display_type]
|
101
|
+
sig = inspect.signature(callback)
|
102
|
+
|
103
|
+
# Filter kwargs to what the callback accepts to maintain backward compatibility
|
104
|
+
if any(p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()):
|
105
|
+
# Callback accepts **kwargs, so pass all arguments
|
106
|
+
supported_kwargs = kwargs
|
107
|
+
else:
|
108
|
+
# Only pass arguments that the callback signature supports
|
109
|
+
supported_kwargs = {k: v for k, v in kwargs.items() if k in sig.parameters}
|
110
|
+
|
75
111
|
loop = asyncio.get_event_loop()
|
76
|
-
await loop.run_in_executor(None, lambda: callback(**
|
112
|
+
await loop.run_in_executor(None, lambda: callback(**supported_kwargs))
|
77
113
|
|
78
114
|
# Execute asynchronous callback if registered
|
79
115
|
if display_type in async_display_callbacks:
|
80
116
|
callback = async_display_callbacks[display_type]
|
81
|
-
|
117
|
+
sig = inspect.signature(callback)
|
118
|
+
|
119
|
+
# Filter kwargs to what the callback accepts to maintain backward compatibility
|
120
|
+
if any(p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()):
|
121
|
+
# Callback accepts **kwargs, so pass all arguments
|
122
|
+
supported_kwargs = kwargs
|
123
|
+
else:
|
124
|
+
# Only pass arguments that the callback signature supports
|
125
|
+
supported_kwargs = {k: v for k, v in kwargs.items() if k in sig.parameters}
|
126
|
+
|
127
|
+
await callback(**supported_kwargs)
|
82
128
|
|
83
129
|
def _clean_display_content(content: str, max_length: int = 20000) -> str:
|
84
130
|
"""Helper function to clean and truncate content for display."""
|
@@ -101,7 +147,7 @@ def _clean_display_content(content: str, max_length: int = 20000) -> str:
|
|
101
147
|
|
102
148
|
return content.strip()
|
103
149
|
|
104
|
-
def display_interaction(message, response, markdown=True, generation_time=None, console=None):
|
150
|
+
def display_interaction(message, response, markdown=True, generation_time=None, console=None, agent_name=None, agent_role=None, agent_tools=None, task_name=None, task_description=None, task_id=None):
|
105
151
|
"""Synchronous version of display_interaction."""
|
106
152
|
if console is None:
|
107
153
|
console = Console()
|
@@ -113,15 +159,20 @@ def display_interaction(message, response, markdown=True, generation_time=None,
|
|
113
159
|
message = _clean_display_content(str(message))
|
114
160
|
response = _clean_display_content(str(response))
|
115
161
|
|
116
|
-
# Execute synchronous
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
162
|
+
# Execute synchronous callbacks
|
163
|
+
execute_sync_callback(
|
164
|
+
'interaction',
|
165
|
+
message=message,
|
166
|
+
response=response,
|
167
|
+
markdown=markdown,
|
168
|
+
generation_time=generation_time,
|
169
|
+
agent_name=agent_name,
|
170
|
+
agent_role=agent_role,
|
171
|
+
agent_tools=agent_tools,
|
172
|
+
task_name=task_name,
|
173
|
+
task_description=task_description,
|
174
|
+
task_id=task_id
|
175
|
+
)
|
125
176
|
# Rest of the display logic...
|
126
177
|
if generation_time:
|
127
178
|
console.print(Text(f"Response generated in {generation_time:.1f}s", style="dim"))
|
@@ -140,9 +191,8 @@ def display_self_reflection(message: str, console=None):
|
|
140
191
|
console = Console()
|
141
192
|
message = _clean_display_content(str(message))
|
142
193
|
|
143
|
-
# Execute
|
144
|
-
|
145
|
-
sync_display_callbacks['self_reflection'](message=message)
|
194
|
+
# Execute synchronous callbacks
|
195
|
+
execute_sync_callback('self_reflection', message=message)
|
146
196
|
|
147
197
|
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
|
148
198
|
|
@@ -153,9 +203,8 @@ def display_instruction(message: str, console=None, agent_name: str = None, agen
|
|
153
203
|
console = Console()
|
154
204
|
message = _clean_display_content(str(message))
|
155
205
|
|
156
|
-
# Execute
|
157
|
-
|
158
|
-
sync_display_callbacks['instruction'](message=message)
|
206
|
+
# Execute synchronous callbacks
|
207
|
+
execute_sync_callback('instruction', message=message, agent_name=agent_name, agent_role=agent_role, agent_tools=agent_tools)
|
159
208
|
|
160
209
|
# Display agent info if available
|
161
210
|
if agent_name:
|
@@ -181,9 +230,8 @@ def display_tool_call(message: str, console=None):
|
|
181
230
|
message = _clean_display_content(str(message))
|
182
231
|
logging.debug(f"Cleaned message in display_tool_call: {repr(message)}")
|
183
232
|
|
184
|
-
# Execute
|
185
|
-
|
186
|
-
sync_display_callbacks['tool_call'](message=message)
|
233
|
+
# Execute synchronous callbacks
|
234
|
+
execute_sync_callback('tool_call', message=message)
|
187
235
|
|
188
236
|
console.print(Panel.fit(Text(message, style="bold cyan"), title="Tool Call", border_style="green"))
|
189
237
|
|
@@ -194,9 +242,8 @@ def display_error(message: str, console=None):
|
|
194
242
|
console = Console()
|
195
243
|
message = _clean_display_content(str(message))
|
196
244
|
|
197
|
-
# Execute
|
198
|
-
|
199
|
-
sync_display_callbacks['error'](message=message)
|
245
|
+
# Execute synchronous callbacks
|
246
|
+
execute_sync_callback('error', message=message)
|
200
247
|
|
201
248
|
console.print(Panel.fit(Text(message, style="bold red"), title="Error", border_style="red"))
|
202
249
|
error_logs.append(message)
|
@@ -213,17 +260,13 @@ def display_generating(content: str = "", start_time: Optional[float] = None):
|
|
213
260
|
|
214
261
|
content = _clean_display_content(str(content))
|
215
262
|
|
216
|
-
# Execute
|
217
|
-
|
218
|
-
sync_display_callbacks['generating'](
|
219
|
-
content=content,
|
220
|
-
elapsed_time=elapsed_str.strip() if elapsed_str else None
|
221
|
-
)
|
263
|
+
# Execute synchronous callbacks
|
264
|
+
execute_sync_callback('generating', content=content, elapsed_time=elapsed_str.strip() if elapsed_str else None)
|
222
265
|
|
223
266
|
return Panel(Markdown(content), title=f"Generating...{elapsed_str}", border_style="green")
|
224
267
|
|
225
268
|
# Async versions with 'a' prefix
|
226
|
-
async def adisplay_interaction(message, response, markdown=True, generation_time=None, console=None):
|
269
|
+
async def adisplay_interaction(message, response, markdown=True, generation_time=None, console=None, agent_name=None, agent_role=None, agent_tools=None, task_name=None, task_description=None, task_id=None):
|
227
270
|
"""Async version of display_interaction."""
|
228
271
|
if console is None:
|
229
272
|
console = Console()
|
@@ -241,7 +284,13 @@ async def adisplay_interaction(message, response, markdown=True, generation_time
|
|
241
284
|
message=message,
|
242
285
|
response=response,
|
243
286
|
markdown=markdown,
|
244
|
-
generation_time=generation_time
|
287
|
+
generation_time=generation_time,
|
288
|
+
agent_name=agent_name,
|
289
|
+
agent_role=agent_role,
|
290
|
+
agent_tools=agent_tools,
|
291
|
+
task_name=task_name,
|
292
|
+
task_description=task_description,
|
293
|
+
task_id=task_id
|
245
294
|
)
|
246
295
|
|
247
296
|
# Rest of the display logic...
|
@@ -263,8 +312,8 @@ async def adisplay_self_reflection(message: str, console=None):
|
|
263
312
|
console = Console()
|
264
313
|
message = _clean_display_content(str(message))
|
265
314
|
|
266
|
-
|
267
|
-
|
315
|
+
# Execute callbacks
|
316
|
+
await execute_callback('self_reflection', message=message)
|
268
317
|
|
269
318
|
console.print(Panel.fit(Text(message, style="bold yellow"), title="Self Reflection", border_style="magenta"))
|
270
319
|
|
@@ -276,8 +325,8 @@ async def adisplay_instruction(message: str, console=None, agent_name: str = Non
|
|
276
325
|
console = Console()
|
277
326
|
message = _clean_display_content(str(message))
|
278
327
|
|
279
|
-
|
280
|
-
|
328
|
+
# Execute callbacks
|
329
|
+
await execute_callback('instruction', message=message, agent_name=agent_name, agent_role=agent_role, agent_tools=agent_tools)
|
281
330
|
|
282
331
|
# Display agent info if available
|
283
332
|
if agent_name:
|
@@ -304,8 +353,8 @@ async def adisplay_tool_call(message: str, console=None):
|
|
304
353
|
message = _clean_display_content(str(message))
|
305
354
|
logging.debug(f"Cleaned message in adisplay_tool_call: {repr(message)}")
|
306
355
|
|
307
|
-
|
308
|
-
|
356
|
+
# Execute callbacks
|
357
|
+
await execute_callback('tool_call', message=message)
|
309
358
|
|
310
359
|
console.print(Panel.fit(Text(message, style="bold cyan"), title="Tool Call", border_style="green"))
|
311
360
|
|
@@ -317,8 +366,8 @@ async def adisplay_error(message: str, console=None):
|
|
317
366
|
console = Console()
|
318
367
|
message = _clean_display_content(str(message))
|
319
368
|
|
320
|
-
|
321
|
-
|
369
|
+
# Execute callbacks
|
370
|
+
await execute_callback('error', message=message)
|
322
371
|
|
323
372
|
console.print(Panel.fit(Text(message, style="bold red"), title="Error", border_style="red"))
|
324
373
|
error_logs.append(message)
|
@@ -336,11 +385,8 @@ async def adisplay_generating(content: str = "", start_time: Optional[float] = N
|
|
336
385
|
|
337
386
|
content = _clean_display_content(str(content))
|
338
387
|
|
339
|
-
|
340
|
-
|
341
|
-
content=content,
|
342
|
-
elapsed_time=elapsed_str.strip() if elapsed_str else None
|
343
|
-
)
|
388
|
+
# Execute callbacks
|
389
|
+
await execute_callback('generating', content=content, elapsed_time=elapsed_str.strip() if elapsed_str else None)
|
344
390
|
|
345
391
|
return Panel(Markdown(content), title=f"Generating...{elapsed_str}", border_style="green")
|
346
392
|
|
praisonaiagents/memory/memory.py
CHANGED
@@ -116,6 +116,16 @@ class Memory:
|
|
116
116
|
self.use_mem0 = (self.provider.lower() == "mem0") and MEM0_AVAILABLE
|
117
117
|
self.use_rag = (self.provider.lower() == "rag") and CHROMADB_AVAILABLE and self.cfg.get("use_embedding", False)
|
118
118
|
self.graph_enabled = False # Initialize graph support flag
|
119
|
+
|
120
|
+
# Extract embedding model from config
|
121
|
+
self.embedder_config = self.cfg.get("embedder", {})
|
122
|
+
if isinstance(self.embedder_config, dict):
|
123
|
+
embedder_model_config = self.embedder_config.get("config", {})
|
124
|
+
self.embedding_model = embedder_model_config.get("model", "text-embedding-3-small")
|
125
|
+
else:
|
126
|
+
self.embedding_model = "text-embedding-3-small"
|
127
|
+
|
128
|
+
self._log_verbose(f"Using embedding model: {self.embedding_model}")
|
119
129
|
|
120
130
|
# Create .praison directory if it doesn't exist
|
121
131
|
os.makedirs(".praison", exist_ok=True)
|
@@ -355,7 +365,7 @@ class Memory:
|
|
355
365
|
import litellm
|
356
366
|
|
357
367
|
response = litellm.embedding(
|
358
|
-
model=
|
368
|
+
model=self.embedding_model,
|
359
369
|
input=query
|
360
370
|
)
|
361
371
|
query_embedding = response.data[0]["embedding"]
|
@@ -366,7 +376,7 @@ class Memory:
|
|
366
376
|
|
367
377
|
response = client.embeddings.create(
|
368
378
|
input=query,
|
369
|
-
model=
|
379
|
+
model=self.embedding_model
|
370
380
|
)
|
371
381
|
query_embedding = response.data[0].embedding
|
372
382
|
else:
|
@@ -496,7 +506,7 @@ class Memory:
|
|
496
506
|
logger.debug(f"Embedding input text: {text}")
|
497
507
|
|
498
508
|
response = litellm.embedding(
|
499
|
-
model=
|
509
|
+
model=self.embedding_model,
|
500
510
|
input=text
|
501
511
|
)
|
502
512
|
embedding = response.data[0]["embedding"]
|
@@ -513,7 +523,7 @@ class Memory:
|
|
513
523
|
|
514
524
|
response = client.embeddings.create(
|
515
525
|
input=text,
|
516
|
-
model=
|
526
|
+
model=self.embedding_model
|
517
527
|
)
|
518
528
|
embedding = response.data[0].embedding
|
519
529
|
logger.info("Successfully got embeddings from OpenAI")
|
@@ -576,7 +586,7 @@ class Memory:
|
|
576
586
|
import litellm
|
577
587
|
|
578
588
|
response = litellm.embedding(
|
579
|
-
model=
|
589
|
+
model=self.embedding_model,
|
580
590
|
input=query
|
581
591
|
)
|
582
592
|
query_embedding = response.data[0]["embedding"]
|
@@ -587,7 +597,7 @@ class Memory:
|
|
587
597
|
|
588
598
|
response = client.embeddings.create(
|
589
599
|
input=query,
|
590
|
-
model=
|
600
|
+
model=self.embedding_model
|
591
601
|
)
|
592
602
|
query_embedding = response.data[0].embedding
|
593
603
|
else:
|
@@ -59,10 +59,90 @@ class Process:
|
|
59
59
|
|
60
60
|
def _create_loop_subtasks(self, loop_task: Task):
|
61
61
|
"""Create subtasks for a loop task from input file."""
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
if not loop_task.input_file:
|
63
|
+
logging.warning(f"_create_loop_subtasks called for {loop_task.name} but no input_file specified")
|
64
|
+
return
|
65
|
+
|
66
|
+
try:
|
67
|
+
file_ext = os.path.splitext(loop_task.input_file)[1].lower()
|
68
|
+
new_tasks = []
|
69
|
+
|
70
|
+
if file_ext == ".csv":
|
71
|
+
with open(loop_task.input_file, "r", encoding="utf-8") as f:
|
72
|
+
reader = csv.reader(f, quotechar='"', escapechar='\\')
|
73
|
+
previous_task = None
|
74
|
+
task_count = 0
|
75
|
+
|
76
|
+
for i, row in enumerate(reader):
|
77
|
+
if not row: # Skip empty rows
|
78
|
+
continue
|
79
|
+
|
80
|
+
# Handle Q&A pairs with potential commas
|
81
|
+
task_desc = row[0].strip() if row else ""
|
82
|
+
if len(row) > 1:
|
83
|
+
question = row[0].strip()
|
84
|
+
answer = ",".join(field.strip() for field in row[1:])
|
85
|
+
task_desc = f"Question: {question}\nAnswer: {answer}"
|
86
|
+
|
87
|
+
if not task_desc: # Skip rows with empty content
|
88
|
+
continue
|
89
|
+
|
90
|
+
task_count += 1
|
91
|
+
logging.debug(f"Creating subtask from CSV row {i+1}: {task_desc}")
|
92
|
+
|
93
|
+
row_task = Task(
|
94
|
+
description=f"{loop_task.description}\n{task_desc}" if loop_task.description else task_desc,
|
95
|
+
agent=loop_task.agent,
|
96
|
+
name=f"{loop_task.name}_{task_count}" if loop_task.name else task_desc,
|
97
|
+
expected_output=getattr(loop_task, 'expected_output', None),
|
98
|
+
callback=loop_task.callback, # Inherit callback from parent loop task
|
99
|
+
is_start=(task_count == 1),
|
100
|
+
task_type="task"
|
101
|
+
)
|
102
|
+
self.tasks[row_task.id] = row_task
|
103
|
+
new_tasks.append(row_task)
|
104
|
+
|
105
|
+
if previous_task:
|
106
|
+
previous_task.next_tasks = [row_task.name]
|
107
|
+
previous_task = row_task
|
108
|
+
|
109
|
+
logging.info(f"Created {task_count} subtasks from CSV file for {loop_task.name}")
|
110
|
+
else:
|
111
|
+
# Handle text files
|
112
|
+
with open(loop_task.input_file, "r", encoding="utf-8") as f:
|
113
|
+
lines = f.read().splitlines()
|
114
|
+
previous_task = None
|
115
|
+
for i, line in enumerate(lines):
|
116
|
+
if not line.strip(): # Skip empty lines
|
117
|
+
continue
|
118
|
+
|
119
|
+
row_task = Task(
|
120
|
+
description=f"{loop_task.description}\n{line.strip()}" if loop_task.description else line.strip(),
|
121
|
+
agent=loop_task.agent,
|
122
|
+
name=f"{loop_task.name}_{i+1}" if loop_task.name else line.strip(),
|
123
|
+
expected_output=getattr(loop_task, 'expected_output', None),
|
124
|
+
callback=loop_task.callback, # Inherit callback from parent loop task
|
125
|
+
is_start=(i == 0),
|
126
|
+
task_type="task"
|
127
|
+
)
|
128
|
+
self.tasks[row_task.id] = row_task
|
129
|
+
new_tasks.append(row_task)
|
130
|
+
|
131
|
+
if previous_task:
|
132
|
+
previous_task.next_tasks = [row_task.name]
|
133
|
+
previous_task = row_task
|
134
|
+
|
135
|
+
logging.info(f"Created {len(new_tasks)} subtasks from text file for {loop_task.name}")
|
136
|
+
|
137
|
+
if new_tasks and loop_task.next_tasks:
|
138
|
+
# Connect last subtask to loop task's next tasks
|
139
|
+
last_task = new_tasks[-1]
|
140
|
+
last_task.next_tasks = loop_task.next_tasks
|
141
|
+
|
142
|
+
except Exception as e:
|
143
|
+
logging.error(f"Failed to create subtasks for loop task {loop_task.name}: {e}")
|
144
|
+
import traceback
|
145
|
+
traceback.print_exc()
|
66
146
|
|
67
147
|
def _build_task_context(self, current_task: Task) -> str:
|
68
148
|
"""Build context for a task based on its retain_full_context setting"""
|
@@ -809,6 +889,7 @@ Provide a JSON with the structure:
|
|
809
889
|
agent=start_task.agent,
|
810
890
|
name=f"{start_task.name}_{task_count}" if start_task.name else task_desc,
|
811
891
|
expected_output=getattr(start_task, 'expected_output', None),
|
892
|
+
callback=start_task.callback, # Inherit callback from parent loop task
|
812
893
|
is_start=(task_count == 1),
|
813
894
|
task_type="decision", # Change to decision type
|
814
895
|
next_tasks=inherited_next_tasks, # Inherit parent's next tasks
|
@@ -842,6 +923,7 @@ Provide a JSON with the structure:
|
|
842
923
|
agent=start_task.agent,
|
843
924
|
name=f"{start_task.name}_{i+1}" if start_task.name else line.strip(),
|
844
925
|
expected_output=getattr(start_task, 'expected_output', None),
|
926
|
+
callback=start_task.callback, # Inherit callback from parent loop task
|
845
927
|
is_start=(i == 0),
|
846
928
|
task_type="task",
|
847
929
|
condition={
|
@@ -925,6 +1007,7 @@ Tasks by type:
|
|
925
1007
|
agent=current_task.agent,
|
926
1008
|
name=f"{current_task.name}_{i+1}" if current_task.name else task_desc,
|
927
1009
|
expected_output=getattr(current_task, 'expected_output', None),
|
1010
|
+
callback=current_task.callback, # Inherit callback from parent loop task
|
928
1011
|
is_start=(i == 0),
|
929
1012
|
task_type="task",
|
930
1013
|
condition={
|
@@ -949,6 +1032,7 @@ Tasks by type:
|
|
949
1032
|
agent=current_task.agent,
|
950
1033
|
name=f"{current_task.name}_{i+1}" if current_task.name else line.strip(),
|
951
1034
|
expected_output=getattr(current_task, 'expected_output', None),
|
1035
|
+
callback=current_task.callback, # Inherit callback from parent loop task
|
952
1036
|
is_start=(i == 0),
|
953
1037
|
task_type="task",
|
954
1038
|
condition={
|
praisonaiagents/task/task.py
CHANGED
@@ -381,13 +381,10 @@ class Task:
|
|
381
381
|
logger.exception(e) # Print full stack trace
|
382
382
|
# Continue execution even if memory operations fail
|
383
383
|
|
384
|
-
# Execute original callback
|
384
|
+
# Execute original callback with metadata support
|
385
385
|
if self.callback:
|
386
386
|
try:
|
387
|
-
|
388
|
-
await self.callback(task_output)
|
389
|
-
else:
|
390
|
-
self.callback(task_output)
|
387
|
+
await self._execute_callback_with_metadata(task_output)
|
391
388
|
except Exception as e:
|
392
389
|
logger.error(f"Task {self.id}: Failed to execute callback: {e}")
|
393
390
|
logger.exception(e)
|
@@ -470,4 +467,63 @@ Context:
|
|
470
467
|
success=False,
|
471
468
|
result=None,
|
472
469
|
error=f"Guardrail validation error: {str(e)}"
|
473
|
-
)
|
470
|
+
)
|
471
|
+
|
472
|
+
async def _execute_callback_with_metadata(self, task_output):
|
473
|
+
"""Execute callback with metadata support while maintaining backward compatibility.
|
474
|
+
|
475
|
+
This method automatically detects the callback signature:
|
476
|
+
- Single parameter callbacks receive only TaskOutput (backward compatible)
|
477
|
+
- Two parameter callbacks receive TaskOutput and metadata dict (enhanced)
|
478
|
+
|
479
|
+
Args:
|
480
|
+
task_output: The TaskOutput object to pass to the callback
|
481
|
+
"""
|
482
|
+
if not self.callback:
|
483
|
+
return
|
484
|
+
|
485
|
+
try:
|
486
|
+
# Inspect the callback signature to determine parameter count
|
487
|
+
sig = inspect.signature(self.callback)
|
488
|
+
param_count = len(sig.parameters)
|
489
|
+
|
490
|
+
if param_count == 1:
|
491
|
+
# Backward compatible: single parameter callback
|
492
|
+
if asyncio.iscoroutinefunction(self.callback):
|
493
|
+
await self.callback(task_output)
|
494
|
+
else:
|
495
|
+
self.callback(task_output)
|
496
|
+
elif param_count >= 2:
|
497
|
+
# Enhanced: two parameter callback with metadata
|
498
|
+
metadata = {
|
499
|
+
'task_id': self.id,
|
500
|
+
'task_name': self.name,
|
501
|
+
'agent_name': self.agent.name if self.agent else None,
|
502
|
+
'task_type': self.task_type,
|
503
|
+
'task_status': self.status,
|
504
|
+
'task_description': self.description,
|
505
|
+
'expected_output': self.expected_output,
|
506
|
+
'input_file': getattr(self, 'input_file', None),
|
507
|
+
'loop_state': self.loop_state,
|
508
|
+
'retry_count': getattr(self, 'retry_count', 0),
|
509
|
+
'async_execution': self.async_execution
|
510
|
+
}
|
511
|
+
|
512
|
+
if asyncio.iscoroutinefunction(self.callback):
|
513
|
+
await self.callback(task_output, metadata)
|
514
|
+
else:
|
515
|
+
self.callback(task_output, metadata)
|
516
|
+
else:
|
517
|
+
# No parameter callback - unusual but handle gracefully
|
518
|
+
if asyncio.iscoroutinefunction(self.callback):
|
519
|
+
await self.callback()
|
520
|
+
else:
|
521
|
+
self.callback()
|
522
|
+
|
523
|
+
except TypeError as e:
|
524
|
+
# Fallback for signature inspection issues
|
525
|
+
logger.warning(f"Task {self.id}: Callback signature inspection failed, falling back to single parameter: {e}")
|
526
|
+
if asyncio.iscoroutinefunction(self.callback):
|
527
|
+
await self.callback(task_output)
|
528
|
+
else:
|
529
|
+
self.callback(task_output)
|
@@ -1,23 +1,23 @@
|
|
1
1
|
praisonaiagents/__init__.py,sha256=7DZJjhHa1_OeP0aiR5_iXINXYiug_gtbOuh_ylad6Uc,3847
|
2
2
|
praisonaiagents/approval.py,sha256=UJ4OhfihpFGR5CAaMphqpSvqdZCHi5w2MGw1MByZ1FQ,9813
|
3
|
-
praisonaiagents/main.py,sha256=
|
3
|
+
praisonaiagents/main.py,sha256=b5dKlkf6NMeumSzixreHB9ui90f8YMAi5r1fCbTpQVw,17225
|
4
4
|
praisonaiagents/session.py,sha256=d-CZPYikOHb0q-H9f_IWKJsypnQfz1YKeLLkyxs6oDo,15532
|
5
5
|
praisonaiagents/agent/__init__.py,sha256=FkjW6f3EU8heQ9tvctfLbOWV9_dOXmS1PcFNgcStns8,403
|
6
|
-
praisonaiagents/agent/agent.py,sha256=
|
6
|
+
praisonaiagents/agent/agent.py,sha256=1m9s6irqenYatuoGHHS1DX913rm9QpjcJHJjvPH6_QE,123338
|
7
7
|
praisonaiagents/agent/handoff.py,sha256=Saq0chqfvC6Zf5UbXvmctybbehqnotrXn72JsS-76Q0,13099
|
8
|
-
praisonaiagents/agent/image_agent.py,sha256
|
8
|
+
praisonaiagents/agent/image_agent.py,sha256=Bbwg_h3qhjhG7gMH8sdcQXhcOFgE_wSvcdhtqH5f2UM,9145
|
9
9
|
praisonaiagents/agent/router_agent.py,sha256=a_b6w5Ti05gvK80uKGMIcT14fiCTKv8rCQPCWAUfIiE,12713
|
10
10
|
praisonaiagents/agents/__init__.py,sha256=_1d6Pqyk9EoBSo7E68sKyd1jDRlN1vxvVIRpoMc0Jcw,168
|
11
|
-
praisonaiagents/agents/agents.py,sha256=
|
11
|
+
praisonaiagents/agents/agents.py,sha256=WfzlnwiqiEdU6z-6j_Xp0LyhIApKNj0G6L0Hlr418yE,64420
|
12
12
|
praisonaiagents/agents/autoagents.py,sha256=v5pJfTgHnFzG5K2gHwfRA0nZ7Ikptir6hUNvOZ--E44,20777
|
13
13
|
praisonaiagents/guardrails/__init__.py,sha256=HA8zhp-KRHTxo0194MUwXOUJjPyjOu7E3d7xUIKYVVY,310
|
14
14
|
praisonaiagents/guardrails/guardrail_result.py,sha256=2K1WIYRyT_s1H6vBGa-7HEHzXCFIyZXZVY4f0hnQyWc,1352
|
15
|
-
praisonaiagents/guardrails/llm_guardrail.py,sha256=
|
15
|
+
praisonaiagents/guardrails/llm_guardrail.py,sha256=czdOIoY-3PZOchX317tz4O2h2WYE42Ua4tqVzyuoNlI,4859
|
16
16
|
praisonaiagents/knowledge/__init__.py,sha256=xL1Eh-a3xsHyIcU4foOWF-JdWYIYBALJH9bge0Ujuto,246
|
17
17
|
praisonaiagents/knowledge/chunking.py,sha256=G6wyHa7_8V0_7VpnrrUXbEmUmptlT16ISJYaxmkSgmU,7678
|
18
18
|
praisonaiagents/knowledge/knowledge.py,sha256=-di_h9HxXQfAhTMMerhK16tfw8DtUndp44TGkBOzkZs,15539
|
19
19
|
praisonaiagents/llm/__init__.py,sha256=tHvWq5mv4K4MhWr0s6rqox8UnJ5RK0kXhYuD40WkZQA,1747
|
20
|
-
praisonaiagents/llm/llm.py,sha256=
|
20
|
+
praisonaiagents/llm/llm.py,sha256=UAoezf_FF435xNCpOq1TtuEngInIobgBGZiLSX2d8Wg,122381
|
21
21
|
praisonaiagents/llm/model_capabilities.py,sha256=MrEDLpYk9U_xzvXXIKYD4-bnNQg_W4bnaoTPyBUHfcs,3231
|
22
22
|
praisonaiagents/llm/model_router.py,sha256=Jy2pShlkLxqXF3quz-MRB3-6L9vaUSgUrf2YJs_Tsg0,13995
|
23
23
|
praisonaiagents/llm/openai_client.py,sha256=6KANw9SNiglvfJvTcpDPZjuTKG6cThD1t-ZqgKvmZiw,45356
|
@@ -26,11 +26,11 @@ praisonaiagents/mcp/mcp.py,sha256=T0G0rQotHxk9qTnG1tjQLr4c0BUSLnEqz9sIMx4F954,21
|
|
26
26
|
praisonaiagents/mcp/mcp_http_stream.py,sha256=Yh-69eIlLQS_M0bd__y7NzSjOqqX6R8Ed4eJQw6xXgg,18314
|
27
27
|
praisonaiagents/mcp/mcp_sse.py,sha256=KO10tAgZ5vSKeRhkJIZcdJ0ZmhRybS39i1KybWt4D7M,9128
|
28
28
|
praisonaiagents/memory/__init__.py,sha256=aEFdhgtTqDdMhc_JCWM-f4XI9cZIj7Wz5g_MUa-0amg,397
|
29
|
-
praisonaiagents/memory/memory.py,sha256=
|
29
|
+
praisonaiagents/memory/memory.py,sha256=hbqPQj6gvTq3pIO9Ww75xWSZJbVwjTPGvLZX0vZBIrI,44748
|
30
30
|
praisonaiagents/process/__init__.py,sha256=lkYbL7Hn5a0ldvJtkdH23vfIIZLIcanK-65C0MwaorY,52
|
31
|
-
praisonaiagents/process/process.py,sha256=
|
31
|
+
praisonaiagents/process/process.py,sha256=wXKZ2Z26vB9osmVbD5xqkUlUQRvWEpvL8j9hiuiHrQ0,78246
|
32
32
|
praisonaiagents/task/__init__.py,sha256=VL5hXVmyGjINb34AalxpBMl-YW9m5EDcRkMTKkSSl7c,80
|
33
|
-
praisonaiagents/task/task.py,sha256
|
33
|
+
praisonaiagents/task/task.py,sha256=-EXxw3czWZdAK1WWI6Dvga5CujsItgk9RWYD_CdW47w,24075
|
34
34
|
praisonaiagents/telemetry/__init__.py,sha256=5iAOrj_N_cKMmh2ltWGYs3PfOYt_jcwUoElW8fTAIsc,3062
|
35
35
|
praisonaiagents/telemetry/integration.py,sha256=8h8TDlPFTbsBmU5rIYNOibJbwEEEWmzS1ENE9uPTvvg,8696
|
36
36
|
praisonaiagents/telemetry/telemetry.py,sha256=SAEK5lrHn-Rb3nk_Yx1sjAdRxqT63ycyNRv3ZGh9Rck,11812
|
@@ -57,7 +57,7 @@ praisonaiagents/tools/xml_tools.py,sha256=iYTMBEk5l3L3ryQ1fkUnNVYK-Nnua2Kx2S0dxN
|
|
57
57
|
praisonaiagents/tools/yaml_tools.py,sha256=uogAZrhXV9O7xvspAtcTfpKSQYL2nlOTvCQXN94-G9A,14215
|
58
58
|
praisonaiagents/tools/yfinance_tools.py,sha256=s2PBj_1v7oQnOobo2fDbQBACEHl61ftG4beG6Z979ZE,8529
|
59
59
|
praisonaiagents/tools/train/data/generatecot.py,sha256=H6bNh-E2hqL5MW6kX3hqZ05g9ETKN2-kudSjiuU_SD8,19403
|
60
|
-
praisonaiagents-0.0.
|
61
|
-
praisonaiagents-0.0.
|
62
|
-
praisonaiagents-0.0.
|
63
|
-
praisonaiagents-0.0.
|
60
|
+
praisonaiagents-0.0.132.dist-info/METADATA,sha256=J1a0z43TLhbIkkirbvjHsaM4eyhTOAFV1B08QXo4pmE,1699
|
61
|
+
praisonaiagents-0.0.132.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
62
|
+
praisonaiagents-0.0.132.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
|
63
|
+
praisonaiagents-0.0.132.dist-info/RECORD,,
|
File without changes
|
File without changes
|