PraisonAI 2.0.23__cp312-cp312-manylinux_2_39_x86_64.whl → 2.0.25__cp312-cp312-manylinux_2_39_x86_64.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.

Potentially problematic release.


This version of PraisonAI might be problematic. Click here for more details.

praisonai/deploy.py CHANGED
@@ -56,7 +56,7 @@ class CloudDeployer:
56
56
  file.write("FROM python:3.11-slim\n")
57
57
  file.write("WORKDIR /app\n")
58
58
  file.write("COPY . .\n")
59
- file.write("RUN pip install flask praisonai==2.0.23 gunicorn markdown\n")
59
+ file.write("RUN pip install flask praisonai==2.0.25 gunicorn markdown\n")
60
60
  file.write("EXPOSE 8080\n")
61
61
  file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
62
62
 
praisonai/ui/agents.py CHANGED
@@ -5,7 +5,7 @@ import chainlit as cl
5
5
  import os
6
6
  from chainlit.types import ThreadDict
7
7
  from chainlit.input_widget import Select, TextInput
8
- from typing import Optional, Dict, Any
8
+ from typing import Optional, Dict, Any, AsyncGenerator, List, Callable
9
9
  from dotenv import load_dotenv
10
10
  from datetime import datetime
11
11
  import json
@@ -18,6 +18,9 @@ from contextlib import redirect_stdout, asynccontextmanager
18
18
  from db import DatabaseManager
19
19
  import time
20
20
  import sqlite3
21
+ from openai import AsyncOpenAI
22
+ from functools import partial
23
+ import yaml
21
24
 
22
25
  # Load environment variables
23
26
  load_dotenv()
@@ -354,37 +357,193 @@ async def on_chat_resume(thread: ThreadDict):
354
357
  # async def tool(data: Optional[str] = None, language: Optional[str] = None):
355
358
  # return cl.Message(content=data, language=language)
356
359
 
360
+ # Add callback handler class
361
+ class ChainlitCallbackHandler:
362
+ """Callback handler for streaming agent execution to Chainlit"""
363
+
364
+ def __init__(self, parent_step: Optional[cl.Step] = None):
365
+ self.parent_step = parent_step
366
+ self.current_step = None
367
+ self._steps = {}
368
+
369
+ async def on_agent_start(self, agent_name: str):
370
+ """Called when an agent starts execution"""
371
+ self.current_step = cl.Step(
372
+ name=f"Agent: {agent_name}",
373
+ type="agent",
374
+ show_input=True,
375
+ parent_id=self.parent_step.id if self.parent_step else None
376
+ )
377
+ await self.current_step.start()
378
+ await self.current_step.stream_token(f"🤖 Agent {agent_name} started\n")
379
+ self._steps[agent_name] = self.current_step
380
+
381
+ async def on_agent_action(self, agent_name: str, action: str):
382
+ """Called when an agent performs an action"""
383
+ step = self._steps.get(agent_name, self.current_step)
384
+ if step:
385
+ await step.stream_token(f"⚡ {action}\n")
386
+
387
+ async def on_agent_finish(self, agent_name: str, output: Any):
388
+ """Called when an agent finishes execution"""
389
+ step = self._steps.get(agent_name)
390
+ if step:
391
+ await step.stream_token(f"\n✅ Agent {agent_name} finished\n")
392
+ step.output = str(output)
393
+ await step.end()
394
+ self._steps.pop(agent_name, None)
395
+
396
+ async def on_task_start(self, task_id: str, task_name: str):
397
+ """Called when a task starts execution"""
398
+ self.current_step = cl.Step(
399
+ name=f"Task: {task_name}",
400
+ type="task",
401
+ show_input=True,
402
+ parent_id=self.parent_step.id if self.parent_step else None
403
+ )
404
+ await self.current_step.start()
405
+ await self.current_step.stream_token(f"📋 Starting task: {task_name}\n")
406
+ self._steps[task_id] = self.current_step
407
+
408
+ async def on_task_finish(self, task_id: str, output: Any):
409
+ """Called when a task finishes execution"""
410
+ step = self._steps.get(task_id, self.current_step)
411
+ if step:
412
+ await step.stream_token(f"\n✅ Task completed\n")
413
+ step.output = str(output)
414
+ await step.end()
415
+ self._steps.pop(task_id, None)
416
+
417
+ async def on_error(self, error: str):
418
+ """Called when an error occurs"""
419
+ if self.current_step:
420
+ await self.current_step.stream_token(f"\n❌ Error: {error}\n")
421
+ await self.current_step.end()
422
+
357
423
  @cl.step(type="tool", show_input=False)
358
424
  async def run_agents(agent_file: str, framework: str):
359
425
  """Runs the agents and returns the result."""
360
426
  try:
361
427
  logger.debug(f"Running agents with file: {agent_file}, framework: {framework}")
362
- agents_generator = AgentsGenerator(agent_file, framework, config_list)
363
- current_step = cl.context.current_step
364
- logger.debug(f"Current Step: {current_step}")
365
-
366
- stdout_buffer = StringIO()
367
- with redirect_stdout(stdout_buffer):
368
- result = agents_generator.generate_crew_and_kickoff()
428
+
429
+ # Create main execution step
430
+ async with cl.Step(name="Agents Execution", type="agents") as agents_step:
431
+ agents_step.input = f"Running agents from {agent_file}"
369
432
 
370
- complete_output = stdout_buffer.getvalue()
371
- logger.debug(f"Agent execution output: {complete_output}")
372
-
373
- async with cl.Step(name="gpt4", type="llm", show_input=True) as step:
374
- step.input = ""
433
+ # Initialize callback handler
434
+ callback_handler = ChainlitCallbackHandler(parent_step=agents_step)
375
435
 
376
- for line in stdout_buffer.getvalue().splitlines():
377
- logger.debug(f"Agent output line: {line}")
378
- await step.stream_token(line)
436
+ try:
437
+ # Load YAML config first
438
+ with open(agent_file, 'r') as f:
439
+ config = yaml.safe_load(f)
440
+
441
+ # Get topic from message content
442
+ topic = cl.user_session.get("message_history", [{}])[-1].get("content", "")
443
+
444
+ # Create agents generator with loaded config
445
+ agents_generator = AgentsGenerator(
446
+ agent_file=agent_file,
447
+ framework=framework,
448
+ config_list=config_list,
449
+ agent_yaml=yaml.dump(config) # Pass the loaded config as YAML string
450
+ )
451
+
452
+ # Execute based on framework
453
+ if framework == "crewai":
454
+ result = agents_generator._run_crewai(config, topic, [])
455
+ elif framework == "autogen":
456
+ result = agents_generator._run_autogen(config, topic, [])
457
+ elif framework == "praisonai":
458
+ result = agents_generator._run_praisonai(config, topic, [])
459
+ else:
460
+ raise ValueError(f"Unsupported framework: {framework}")
461
+
462
+ # Process the result if it has tasks
463
+ if hasattr(result, 'tasks') and result.tasks:
464
+ for task in result.tasks:
465
+ task_id = getattr(task, 'id', str(id(task)))
466
+ task_desc = getattr(task, 'description', 'Executing task...')
467
+
468
+ # Signal task start
469
+ await callback_handler.on_task_start(
470
+ task_id,
471
+ task_desc[:50] + "..." if len(task_desc) > 50 else task_desc
472
+ )
473
+
474
+ try:
475
+ # Handle agent actions if present
476
+ agent = getattr(task, 'agent', None)
477
+ if agent:
478
+ agent_name = getattr(agent, 'name', 'Unknown Agent')
479
+ await callback_handler.on_agent_start(agent_name)
480
+ await callback_handler.on_agent_action(
481
+ agent_name,
482
+ f"Working on task: {task_desc[:50]}..."
483
+ )
484
+
485
+ # Get task output
486
+ task_output = getattr(task, 'output', str(task))
487
+
488
+ # Signal agent completion if exists
489
+ if agent:
490
+ await callback_handler.on_agent_finish(agent_name, task_output)
491
+
492
+ # Signal task completion
493
+ await callback_handler.on_task_finish(task_id, task_output)
494
+
495
+ except Exception as e:
496
+ await callback_handler.on_error(f"Error in task {task_id}: {str(e)}")
497
+ raise
379
498
 
380
- tool_res = await output(complete_output)
499
+ # Return the final result
500
+ agents_step.output = "Agents execution completed"
501
+ return result if isinstance(result, str) else str(result)
502
+
503
+ except Exception as e:
504
+ await callback_handler.on_error(str(e))
505
+ raise
381
506
 
382
- return result
383
507
  except Exception as e:
384
508
  error_msg = f"Error running agents: {str(e)}"
385
509
  logger.error(error_msg)
386
510
  raise Exception(error_msg)
387
511
 
512
+ async def stream_agents_execution(agents) -> AsyncGenerator[tuple[str, str, str], None]:
513
+ """
514
+ Generator to stream agents execution status and messages.
515
+ Yields tuples of (task_id, status, message)
516
+ """
517
+ try:
518
+ for task_id in agents.tasks:
519
+ task = agents.tasks[task_id]
520
+
521
+ # Signal task start
522
+ yield task_id, "start", ""
523
+
524
+ if task.async_execution:
525
+ # Execute async task
526
+ result = await agents.aexecute_task(task_id)
527
+ else:
528
+ # Execute sync task in thread pool
529
+ result = await cl.make_async(agents.execute_task)(task_id)
530
+
531
+ if result:
532
+ # Stream agent messages
533
+ if isinstance(result, str):
534
+ yield task_id, "agent_message", result
535
+ else:
536
+ yield task_id, "agent_message", result.raw
537
+
538
+ # Signal completion
539
+ yield task_id, "complete", ""
540
+ else:
541
+ yield task_id, "error", "Task execution failed"
542
+
543
+ except Exception as e:
544
+ logger.error(f"Error in stream_agents_execution: {e}")
545
+ yield task_id, "error", str(e)
546
+
388
547
  @cl.step(type="tool", show_input=False, language="yaml")
389
548
  async def output(output):
390
549
  return output
@@ -405,17 +564,38 @@ def task(output):
405
564
  {output}
406
565
  """)
407
566
 
567
+ # Add retry decorator for database operations
568
+ def with_retries(max_retries=3, delay=1):
569
+ def decorator(func):
570
+ async def wrapper(*args, **kwargs):
571
+ for attempt in range(max_retries):
572
+ try:
573
+ return await func(*args, **kwargs)
574
+ except sqlite3.OperationalError as e:
575
+ if "database is locked" in str(e) and attempt < max_retries - 1:
576
+ await asyncio.sleep(delay)
577
+ continue
578
+ raise
579
+ return await func(*args, **kwargs)
580
+ return wrapper
581
+ return decorator
582
+
583
+ @with_retries(max_retries=3, delay=1)
584
+ async def update_thread_metadata(thread_id: str, metadata: dict):
585
+ """Update thread metadata with retry logic"""
586
+ await cl_data.update_thread(thread_id, metadata=metadata)
587
+
408
588
  @cl.on_message
409
589
  async def main(message: cl.Message):
410
- """Run PraisonAI with the provided message as the topic."""
411
590
  try:
412
- # Get or initialize message history
413
- message_history = cl.user_session.get("message_history")
414
- if message_history is None:
415
- message_history = []
416
- cl.user_session.set("message_history", message_history)
591
+ # Get settings and chat profile
592
+ settings = cl.user_session.get("settings")
593
+ chat_profile = cl.user_session.get("chat_profile")
417
594
 
418
- # Add current message to history
595
+ # Get message history or initialize if not exists
596
+ message_history = cl.user_session.get("message_history", [])
597
+
598
+ # Format user message with context
419
599
  now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
420
600
  user_message = f"""
421
601
  Answer the question and use tools if needed:
@@ -424,54 +604,27 @@ async def main(message: cl.Message):
424
604
 
425
605
  User Question: {message.content}
426
606
  """
607
+
608
+ # Add to message history
427
609
  message_history.append({"role": "user", "content": user_message})
428
610
 
429
- # Get chat profile and process accordingly
611
+ # Get configuration
612
+ framework = settings["Framework"]
430
613
  topic = message.content
431
- chat_profile = cl.user_session.get("chat_profile")
432
- logger.debug(f"Processing message with chat profile: {chat_profile}")
433
614
 
434
615
  if chat_profile == "Auto":
435
616
  agent_file = "agents.yaml"
436
617
  logger.info(f"Generating agents for topic: {topic}")
437
618
  generator = AutoGenerator(topic=topic, agent_file=agent_file, framework=framework, config_list=config_list)
619
+
438
620
  await cl.sleep(2)
439
621
  agent_file = generator.generate()
440
622
 
441
- logger.debug("Starting agents execution")
442
- agents_generator = AgentsGenerator(
443
- agent_file,
444
- framework,
445
- config_list
446
- )
623
+ # Run agents with streaming while preserving context
624
+ result = await run_agents(agent_file, framework)
625
+ await cl.Message(content=result).send()
447
626
 
448
- # Capture stdout
449
- stdout_buffer = StringIO()
450
- with redirect_stdout(stdout_buffer):
451
- result = agents_generator.generate_crew_and_kickoff()
452
-
453
- complete_output = stdout_buffer.getvalue()
454
- logger.debug(f"Agents execution output: {complete_output}")
455
-
456
- tool_res = await output(complete_output)
457
- msg = cl.Message(content=result)
458
- await msg.send()
459
-
460
- # Save to message history
461
- message_history.append({"role": "assistant", "content": result})
462
- cl.user_session.set("message_history", message_history)
463
-
464
- # Update thread metadata if exists
465
- thread_id = cl.user_session.get("thread_id")
466
- if thread_id:
467
- metadata = {
468
- "last_response": result,
469
- "timestamp": now,
470
- "mode": "auto"
471
- }
472
- await cl_data.update_thread(thread_id, metadata=metadata)
473
-
474
- else: # chat_profile == "Manual"
627
+ else: # Manual mode
475
628
  agent_file = "agents.yaml"
476
629
  full_agent_file_path = os.path.abspath(agent_file)
477
630
  full_tools_file_path = os.path.abspath("tools.py")
@@ -487,31 +640,25 @@ async def main(message: cl.Message):
487
640
  tools_content = f.read()
488
641
  msg_tools = cl.Message(content=tools_content, language="python")
489
642
  await msg_tools.send()
490
- else:
491
- logger.info("Generating agents for manual mode")
492
- generator = AutoGenerator(topic=topic, agent_file=agent_file, framework=framework, config_list=config_list)
493
- agent_file = generator.generate()
494
-
495
- logger.debug("Starting agents execution for manual mode")
496
- agents_generator = AgentsGenerator(agent_file, framework, config_list)
497
- result = agents_generator.generate_crew_and_kickoff()
498
- msg = cl.Message(content=result, actions=actions)
499
- await msg.send()
500
-
501
- # Save to message history
502
- message_history.append({"role": "assistant", "content": result})
503
- cl.user_session.set("message_history", message_history)
504
643
 
505
- # Update thread metadata if exists
506
- thread_id = cl.user_session.get("thread_id")
507
- if thread_id:
508
- metadata = {
509
- "last_response": result,
510
- "timestamp": now,
511
- "mode": "manual"
512
- }
513
- await cl_data.update_thread(thread_id, metadata=metadata)
514
-
644
+ # Run agents with streaming while preserving context
645
+ result = await run_agents(agent_file, framework)
646
+ await cl.Message(content=result, actions=actions).send()
647
+
648
+ # Update message history
649
+ message_history.append({"role": "assistant", "content": result})
650
+ cl.user_session.set("message_history", message_history)
651
+
652
+ # Update thread metadata with retry logic
653
+ thread_id = cl.user_session.get("thread_id")
654
+ if thread_id:
655
+ metadata = {
656
+ "last_response": result,
657
+ "timestamp": now,
658
+ "mode": chat_profile.lower()
659
+ }
660
+ await update_thread_metadata(thread_id, metadata)
661
+
515
662
  except Exception as e:
516
663
  error_msg = f"Error processing message: {str(e)}"
517
664
  logger.error(error_msg)
@@ -0,0 +1,57 @@
1
+ import logging
2
+ from typing import Dict, Any, Callable, Optional, Union
3
+ import asyncio
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ class CallbackManager:
8
+ """Manages callbacks for the PraisonAI UI"""
9
+
10
+ def __init__(self):
11
+ self._callbacks: Dict[str, Dict[str, Union[Callable, bool]]] = {}
12
+
13
+ def register(self, name: str, callback: Callable, is_async: bool = False) -> None:
14
+ """Register a callback function"""
15
+ self._callbacks[name] = {
16
+ 'func': callback,
17
+ 'is_async': is_async
18
+ }
19
+
20
+ async def call(self, name: str, **kwargs) -> None:
21
+ """Call a registered callback"""
22
+ if name not in self._callbacks:
23
+ logger.warning(f"No callback registered for {name}")
24
+ return
25
+
26
+ callback_info = self._callbacks[name]
27
+ func = callback_info['func']
28
+ is_async = callback_info['is_async']
29
+
30
+ try:
31
+ if is_async:
32
+ await func(**kwargs)
33
+ else:
34
+ if asyncio.iscoroutinefunction(func):
35
+ await func(**kwargs)
36
+ else:
37
+ await asyncio.get_event_loop().run_in_executor(None, lambda: func(**kwargs))
38
+ except Exception as e:
39
+ logger.error(f"Error in callback {name}: {str(e)}")
40
+
41
+ # Global callback manager instance
42
+ callback_manager = CallbackManager()
43
+
44
+ def register_callback(name: str, callback: Callable, is_async: bool = False) -> None:
45
+ """Register a callback with the global callback manager"""
46
+ callback_manager.register(name, callback, is_async)
47
+
48
+ async def trigger_callback(name: str, **kwargs) -> None:
49
+ """Trigger a callback from the global callback manager"""
50
+ await callback_manager.call(name, **kwargs)
51
+
52
+ # Decorator for registering callbacks
53
+ def callback(name: str, is_async: bool = False):
54
+ def decorator(func):
55
+ register_callback(name, func, is_async)
56
+ return func
57
+ return decorator
praisonai/ui/colab.py ADDED
@@ -0,0 +1,474 @@
1
+ from praisonaiagents import Agent, Task, PraisonAIAgents
2
+ import os
3
+ import importlib
4
+ import inspect
5
+ import yaml
6
+ import logging
7
+ from .callbacks import trigger_callback
8
+ import asyncio
9
+ import chainlit as cl
10
+ from queue import Queue
11
+
12
+ logger = logging.getLogger(__name__)
13
+ agent_file = "agents.yaml"
14
+
15
+ with open(agent_file, 'r') as f:
16
+ config = yaml.safe_load(f)
17
+
18
+ topic = "get from the message content from the chainlit user message"
19
+
20
+ # Create a message queue
21
+ message_queue = Queue()
22
+
23
+ async def process_message_queue():
24
+ """Process messages in the queue and send them to Chainlit"""
25
+ while True:
26
+ try:
27
+ if not message_queue.empty():
28
+ msg_data = message_queue.get()
29
+ await cl.Message(**msg_data).send()
30
+ await asyncio.sleep(0.1) # Small delay to prevent busy waiting
31
+ except Exception as e:
32
+ logger.error(f"Error processing message queue: {e}")
33
+
34
+ def load_tools_from_tools_py():
35
+ """
36
+ Imports and returns all contents from tools.py file.
37
+ Also adds the tools to the global namespace.
38
+
39
+ Returns:
40
+ list: A list of callable functions with proper formatting
41
+ """
42
+ tools_list = []
43
+ try:
44
+ # Try to import tools.py from current directory
45
+ spec = importlib.util.spec_from_file_location("tools", "tools.py")
46
+ logger.info(f"Spec: {spec}")
47
+ if spec is None:
48
+ logger.info("tools.py not found in current directory")
49
+ return tools_list
50
+
51
+ module = importlib.util.module_from_spec(spec)
52
+ spec.loader.exec_module(module)
53
+
54
+ # Get all module attributes except private ones and classes
55
+ for name, obj in inspect.getmembers(module):
56
+ if (not name.startswith('_') and
57
+ callable(obj) and
58
+ not inspect.isclass(obj)):
59
+ # Add the function to global namespace
60
+ globals()[name] = obj
61
+ # Format the tool as an OpenAI function
62
+ tool = {
63
+ "type": "function",
64
+ "function": {
65
+ "name": name,
66
+ "description": obj.__doc__ or f"Function to {name.replace('_', ' ')}",
67
+ "parameters": {
68
+ "type": "object",
69
+ "properties": {
70
+ "query": {
71
+ "type": "string",
72
+ "description": "The search query to look up information about"
73
+ }
74
+ },
75
+ "required": ["query"]
76
+ }
77
+ }
78
+ }
79
+ # Add formatted tool to tools list
80
+ tools_list.append(tool)
81
+ logger.info(f"Loaded and globalized tool function: {name}")
82
+
83
+ logger.info(f"Loaded {len(tools_list)} tool functions from tools.py")
84
+ logger.info(f"Tools list: {tools_list}")
85
+
86
+ except Exception as e:
87
+ logger.warning(f"Error loading tools from tools.py: {e}")
88
+
89
+ return tools_list
90
+
91
+ async def step_callback(step_details):
92
+ """Callback for agent steps"""
93
+ logger.info(f"[CALLBACK DEBUG] Step callback triggered with details: {step_details}")
94
+ try:
95
+ # Queue message for agent response
96
+ if step_details.get("response"):
97
+ message_queue.put({
98
+ "content": f"Agent Response: {step_details.get('response')}",
99
+ "author": step_details.get("agent_name", "Agent")
100
+ })
101
+ logger.info("[CALLBACK DEBUG] Queued agent response message")
102
+
103
+ # Queue message for tool usage
104
+ if step_details.get("tool_name"):
105
+ message_queue.put({
106
+ "content": f"🛠️ Using tool: {step_details.get('tool_name')}",
107
+ "author": "System"
108
+ })
109
+ logger.info("[CALLBACK DEBUG] Queued tool usage message")
110
+
111
+ except Exception as e:
112
+ logger.error(f"[CALLBACK DEBUG] Error in step callback: {str(e)}", exc_info=True)
113
+
114
+ async def task_callback(task_output):
115
+ """Callback for task completion"""
116
+ logger.info(f"[CALLBACK DEBUG] Task callback triggered with output: {task_output}")
117
+ try:
118
+ # Create message content
119
+ if hasattr(task_output, 'raw'):
120
+ content = task_output.raw
121
+ elif hasattr(task_output, 'content'):
122
+ content = task_output.content
123
+ else:
124
+ content = str(task_output)
125
+
126
+ # Queue the message
127
+ message_queue.put({
128
+ "content": f"Task Output: {content}",
129
+ "author": "Task"
130
+ })
131
+ logger.info("[CALLBACK DEBUG] Queued task completion message")
132
+
133
+ except Exception as e:
134
+ logger.error(f"[CALLBACK DEBUG] Error in task callback: {str(e)}", exc_info=True)
135
+
136
+ async def step_callback_wrapper(step_details):
137
+ logger.info(f"[CALLBACK DEBUG] Step callback wrapper triggered with details: {step_details}")
138
+ try:
139
+ # Check if we have a Chainlit context
140
+ if not cl.context.context_var.get():
141
+ logger.warning("[CALLBACK DEBUG] No Chainlit context available in wrapper")
142
+ return
143
+ logger.info("[CALLBACK DEBUG] Chainlit context found in wrapper")
144
+
145
+ # Create a message for the agent's response
146
+ if step_details.get("response"):
147
+ logger.info(f"[CALLBACK DEBUG] Sending agent response from wrapper: {step_details.get('response')}")
148
+ try:
149
+ await cl.Message(
150
+ content=f"{role_name}: {step_details.get('response')}",
151
+ author=role_name,
152
+ ).send()
153
+ logger.info("[CALLBACK DEBUG] Successfully sent agent response message from wrapper")
154
+ except Exception as e:
155
+ logger.error(f"[CALLBACK DEBUG] Error sending agent response message from wrapper: {str(e)}")
156
+
157
+ # Create a message for any tool usage
158
+ if step_details.get("tool_name"):
159
+ logger.info(f"[CALLBACK DEBUG] Sending tool usage from wrapper: {step_details.get('tool_name')}")
160
+ try:
161
+ await cl.Message(
162
+ content=f"🛠️ {role_name} is using tool: {step_details.get('tool_name')}",
163
+ author="System",
164
+ ).send()
165
+ logger.info("[CALLBACK DEBUG] Successfully sent tool usage message from wrapper")
166
+ except Exception as e:
167
+ logger.error(f"[CALLBACK DEBUG] Error sending tool usage message from wrapper: {str(e)}")
168
+
169
+ # Create a message for any thoughts or reasoning
170
+ if step_details.get("thought"):
171
+ logger.info(f"[CALLBACK DEBUG] Sending thought from wrapper: {step_details.get('thought')}")
172
+ try:
173
+ await cl.Message(
174
+ content=f"💭 {role_name}'s thought: {step_details.get('thought')}",
175
+ author=role_name,
176
+ ).send()
177
+ logger.info("[CALLBACK DEBUG] Successfully sent thought message from wrapper")
178
+ except Exception as e:
179
+ logger.error(f"[CALLBACK DEBUG] Error sending thought message from wrapper: {str(e)}")
180
+
181
+ except Exception as e:
182
+ logger.error(f"[CALLBACK DEBUG] Error in step callback wrapper: {str(e)}", exc_info=True)
183
+ try:
184
+ await cl.Message(
185
+ content=f"Error in step callback: {str(e)}",
186
+ author="System",
187
+ ).send()
188
+ except Exception as send_error:
189
+ logger.error(f"[CALLBACK DEBUG] Error sending error message: {str(send_error)}")
190
+
191
+ async def task_callback_wrapper(task_output):
192
+ logger.info(f"[CALLBACK DEBUG] Task callback wrapper triggered with output type: {type(task_output)}")
193
+ try:
194
+ # Check if we have a Chainlit context
195
+ if not cl.context.context_var.get():
196
+ logger.warning("[CALLBACK DEBUG] No Chainlit context available in task wrapper")
197
+ return
198
+ logger.info("[CALLBACK DEBUG] Chainlit context found in task wrapper")
199
+
200
+ # Create a message for task completion
201
+ if hasattr(task_output, 'raw'):
202
+ content = task_output.raw
203
+ logger.info("[CALLBACK DEBUG] Using raw output")
204
+ elif hasattr(task_output, 'content'):
205
+ content = task_output.content
206
+ logger.info("[CALLBACK DEBUG] Using content output")
207
+ else:
208
+ content = str(task_output)
209
+ logger.info("[CALLBACK DEBUG] Using string representation of output")
210
+
211
+ logger.info(f"[CALLBACK DEBUG] Sending task completion message from wrapper: {content[:100]}...")
212
+ try:
213
+ await cl.Message(
214
+ content=f"✅ {role_name} completed task:\n{content}",
215
+ author=role_name,
216
+ ).send()
217
+ logger.info("[CALLBACK DEBUG] Successfully sent task completion message from wrapper")
218
+ except Exception as e:
219
+ logger.error(f"[CALLBACK DEBUG] Error sending task completion message from wrapper: {str(e)}")
220
+
221
+ # If there are any additional task details
222
+ if hasattr(task_output, 'details'):
223
+ logger.info("[CALLBACK DEBUG] Task has additional details")
224
+ try:
225
+ await cl.Message(
226
+ content=f"📝 Additional details:\n{task_output.details}",
227
+ author=role_name,
228
+ ).send()
229
+ logger.info("[CALLBACK DEBUG] Successfully sent additional details message")
230
+ except Exception as e:
231
+ logger.error(f"[CALLBACK DEBUG] Error sending additional details message: {str(e)}")
232
+
233
+ except Exception as e:
234
+ logger.error(f"[CALLBACK DEBUG] Error in task callback wrapper: {str(e)}", exc_info=True)
235
+ try:
236
+ await cl.Message(
237
+ content=f"Error in task callback: {str(e)}",
238
+ author="System",
239
+ ).send()
240
+ except Exception as send_error:
241
+ logger.error(f"[CALLBACK DEBUG] Error sending error message: {str(send_error)}")
242
+
243
+ def sync_task_callback_wrapper(task_output):
244
+ logger.info("[CALLBACK DEBUG] Sync task callback wrapper triggered")
245
+ try:
246
+ # Create a new event loop for this thread if there isn't one
247
+ try:
248
+ loop = asyncio.get_event_loop()
249
+ logger.info("[CALLBACK DEBUG] Got existing event loop")
250
+ except RuntimeError:
251
+ loop = asyncio.new_event_loop()
252
+ asyncio.set_event_loop(loop)
253
+ logger.info("[CALLBACK DEBUG] Created new event loop")
254
+
255
+ if loop.is_running():
256
+ # If loop is running, schedule the callback
257
+ logger.info("[CALLBACK DEBUG] Loop is running, scheduling callback")
258
+ asyncio.run_coroutine_threadsafe(
259
+ task_callback_wrapper(task_output),
260
+ loop
261
+ )
262
+ else:
263
+ # If loop is not running, run it directly
264
+ logger.info("[CALLBACK DEBUG] Loop is not running, running callback directly")
265
+ loop.run_until_complete(task_callback_wrapper(task_output))
266
+
267
+ except Exception as e:
268
+ logger.error(f"[CALLBACK DEBUG] Error in sync task callback: {str(e)}", exc_info=True)
269
+
270
+ def sync_step_callback_wrapper(step_details):
271
+ logger.info("[CALLBACK DEBUG] Sync step callback wrapper triggered")
272
+ try:
273
+ # Create a new event loop for this thread if there isn't one
274
+ try:
275
+ loop = asyncio.get_event_loop()
276
+ logger.info("[CALLBACK DEBUG] Got existing event loop")
277
+ except RuntimeError:
278
+ loop = asyncio.new_event_loop()
279
+ asyncio.set_event_loop(loop)
280
+ logger.info("[CALLBACK DEBUG] Created new event loop")
281
+
282
+ if loop.is_running():
283
+ # If loop is running, schedule the callback
284
+ logger.info("[CALLBACK DEBUG] Loop is running, scheduling callback")
285
+ asyncio.run_coroutine_threadsafe(
286
+ step_callback_wrapper(step_details),
287
+ loop
288
+ )
289
+ else:
290
+ # If loop is not running, run it directly
291
+ logger.info("[CALLBACK DEBUG] Loop is not running, running callback directly")
292
+ loop.run_until_complete(step_callback_wrapper(step_details))
293
+
294
+ except Exception as e:
295
+ logger.error(f"[CALLBACK DEBUG] Error in sync step callback: {str(e)}", exc_info=True)
296
+
297
+ async def ui_run_praisonai(config, topic, tools_dict):
298
+ """Run PraisonAI with the given configuration and topic."""
299
+ logger = logging.getLogger(__name__)
300
+ logger.setLevel(logging.DEBUG)
301
+ agents = {}
302
+ tasks = []
303
+ tasks_dict = {}
304
+
305
+ try:
306
+ # Start message queue processor
307
+ queue_processor = asyncio.create_task(process_message_queue())
308
+
309
+ # Create agents for each role
310
+ for role, details in config['roles'].items():
311
+ # Format the role name and other details
312
+ role_name = details.get('name', role).format(topic=topic)
313
+ role_filled = details.get('role', role).format(topic=topic)
314
+ goal_filled = details['goal'].format(topic=topic)
315
+ backstory_filled = details['backstory'].format(topic=topic)
316
+
317
+ # Test message to verify Chainlit is working
318
+ await cl.Message(
319
+ content=f"[DEBUG] Creating agent: {role_name}",
320
+ author="System"
321
+ ).send()
322
+
323
+ # Create a sync wrapper for the step callback
324
+ def step_callback_sync(step_details):
325
+ try:
326
+ # Create a new event loop for this thread
327
+ loop = asyncio.new_event_loop()
328
+ asyncio.set_event_loop(loop)
329
+
330
+ # Add agent name to step details
331
+ step_details["agent_name"] = role_name
332
+
333
+ # Run the callback
334
+ loop.run_until_complete(step_callback(step_details))
335
+ loop.close()
336
+ except Exception as e:
337
+ logger.error(f"[CALLBACK DEBUG] Error in step callback: {str(e)}", exc_info=True)
338
+
339
+ agent = Agent(
340
+ name=role_name,
341
+ role=role_filled,
342
+ goal=goal_filled,
343
+ backstory=backstory_filled,
344
+ llm=details.get('llm', 'gpt-4o'),
345
+ verbose=True,
346
+ allow_delegation=details.get('allow_delegation', False),
347
+ max_iter=details.get('max_iter', 15),
348
+ max_rpm=details.get('max_rpm'),
349
+ max_execution_time=details.get('max_execution_time'),
350
+ cache=details.get('cache', True),
351
+ step_callback=step_callback_sync
352
+ )
353
+ agents[role] = agent
354
+
355
+ # Create tasks for each role
356
+ for role, details in config['roles'].items():
357
+ agent = agents[role]
358
+ tools_list = []
359
+
360
+ # Get tools for this role
361
+ for tool_name in details.get('tools', []):
362
+ if tool_name in tools_dict:
363
+ tool_func = tools_dict[tool_name]
364
+ tools_list.append(tool_func)
365
+
366
+ # Create tasks for the agent
367
+ for task_name, task_details in details.get('tasks', {}).items():
368
+ description_filled = task_details['description'].format(topic=topic)
369
+ expected_output_filled = task_details['expected_output'].format(topic=topic)
370
+
371
+ # Test message to verify task creation
372
+ await cl.Message(
373
+ content=f"[DEBUG] Created task: {task_name} for agent {role_name}",
374
+ author="System"
375
+ ).send()
376
+
377
+ # Create a sync wrapper for the task callback
378
+ def task_callback_sync(task_output):
379
+ try:
380
+ # Create a new event loop for this thread
381
+ loop = asyncio.new_event_loop()
382
+ asyncio.set_event_loop(loop)
383
+
384
+ # Run the callback
385
+ loop.run_until_complete(task_callback(task_output))
386
+ loop.close()
387
+ except Exception as e:
388
+ logger.error(f"[CALLBACK DEBUG] Error in task callback: {str(e)}", exc_info=True)
389
+
390
+ task = Task(
391
+ description=description_filled,
392
+ expected_output=expected_output_filled,
393
+ agent=agent,
394
+ tools=tools_list,
395
+ async_execution=True,
396
+ context=[],
397
+ config=task_details.get('config', {}),
398
+ output_json=task_details.get('output_json'),
399
+ output_pydantic=task_details.get('output_pydantic'),
400
+ output_file=task_details.get('output_file', ""),
401
+ callback=task_callback_sync,
402
+ create_directory=task_details.get('create_directory', False)
403
+ )
404
+
405
+ tasks.append(task)
406
+ tasks_dict[task_name] = task
407
+
408
+ # Set up task contexts
409
+ for role, details in config['roles'].items():
410
+ for task_name, task_details in details.get('tasks', {}).items():
411
+ task = tasks_dict[task_name]
412
+ context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', [])
413
+ if ctx in tasks_dict]
414
+ task.context = context_tasks
415
+
416
+ # Send the start message
417
+ await cl.Message(
418
+ content="Starting PraisonAI agents execution...",
419
+ author="System"
420
+ ).send()
421
+
422
+ # Create and run the PraisonAI agents
423
+ if config.get('process') == 'hierarchical':
424
+ crew = PraisonAIAgents(
425
+ agents=list(agents.values()),
426
+ tasks=tasks,
427
+ verbose=True,
428
+ process="hierarchical",
429
+ manager_llm=config.get('manager_llm', 'gpt-4o')
430
+ )
431
+ else:
432
+ crew = PraisonAIAgents(
433
+ agents=list(agents.values()),
434
+ tasks=tasks,
435
+ verbose=2
436
+ )
437
+
438
+ # Store the crew in the user session
439
+ cl.user_session.set("crew", crew)
440
+
441
+ # Run the agents in a separate thread
442
+ loop = asyncio.get_event_loop()
443
+ response = await loop.run_in_executor(None, crew.start)
444
+
445
+ logger.debug(f"[CALLBACK DEBUG] Result: {response}")
446
+
447
+ # Convert response to string if it's not already
448
+ if hasattr(response, 'raw'):
449
+ result = response.raw
450
+ elif hasattr(response, 'content'):
451
+ result = response.content
452
+ else:
453
+ result = str(response)
454
+
455
+ # Send the completion message
456
+ await cl.Message(
457
+ content="PraisonAI agents execution completed.",
458
+ author="System"
459
+ ).send()
460
+
461
+ # After getting the response, wait a bit for remaining messages
462
+ await asyncio.sleep(1) # Give time for final messages to be processed
463
+ queue_processor.cancel() # Stop the queue processor
464
+
465
+ return result
466
+
467
+ except Exception as e:
468
+ error_msg = f"Error in ui_run_praisonai: {str(e)}"
469
+ logger.error(error_msg, exc_info=True)
470
+ await cl.Message(
471
+ content=error_msg,
472
+ author="System"
473
+ ).send()
474
+ raise
@@ -0,0 +1,81 @@
1
+ import os
2
+ import logging
3
+ from dotenv import load_dotenv
4
+ import chainlit as cl
5
+ from chainlit.types import ThreadDict
6
+ import yaml
7
+ import sys
8
+ import os
9
+ from datetime import datetime
10
+
11
+ # Add the parent directory to sys.path to allow imports
12
+ sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
13
+
14
+ from praisonai.ui.colab import ui_run_praisonai, load_tools_from_tools_py
15
+ from praisonai.ui.callbacks import callback, trigger_callback
16
+
17
+ # Load environment variables
18
+ load_dotenv()
19
+
20
+ # Set up logging
21
+ logger = logging.getLogger(__name__)
22
+ log_level = os.getenv("LOGLEVEL", "INFO").upper()
23
+ logger.setLevel(log_level)
24
+
25
+ # Load agent configuration
26
+ agent_file = "agents.yaml"
27
+ with open(agent_file, 'r') as f:
28
+ config = yaml.safe_load(f)
29
+
30
+ # Load tools
31
+ tools_dict = load_tools_from_tools_py()
32
+
33
+ @cl.on_message
34
+ async def main(message: cl.Message):
35
+ """Main message handler for Chainlit"""
36
+ try:
37
+ logger.info(f"Processing message: {message.content}")
38
+ await cl.Message(
39
+ content=f"🔄 Processing your request about: {message.content}...",
40
+ author="System"
41
+ ).send()
42
+
43
+ await cl.Message(
44
+ content="Using Running PraisonAI Agents...",
45
+ author="System"
46
+ ).send()
47
+
48
+ # Run PraisonAI with the message content as the topic
49
+ result = await ui_run_praisonai(config, message.content, tools_dict)
50
+
51
+ # Send the final result
52
+ await cl.Message(
53
+ content=result,
54
+ author="System"
55
+ ).send()
56
+
57
+ except Exception as e:
58
+ error_msg = f"Error running PraisonAI agents: {str(e)}"
59
+ logger.error(error_msg, exc_info=True)
60
+ await cl.Message(
61
+ content=error_msg,
62
+ author="System"
63
+ ).send()
64
+
65
+ @cl.on_chat_start
66
+ async def start():
67
+ """Handler for chat start"""
68
+ await cl.Message(
69
+ content="👋 Welcome! I'm your AI assistant. What would you like to work on?",
70
+ author="System"
71
+ ).send()
72
+
73
+ # Authentication setup (optional)
74
+ if os.getenv("CHAINLIT_AUTH_SECRET"):
75
+ @cl.password_auth_callback
76
+ def auth_callback(username: str, password: str) -> cl.User:
77
+ # Replace with your authentication logic
78
+ if username == os.getenv("CHAINLIT_USERNAME", "admin") and \
79
+ password == os.getenv("CHAINLIT_PASSWORD", "admin"):
80
+ return cl.User(identifier=username, metadata={"role": "user"})
81
+ return None
@@ -1 +1 @@
1
- # Welcome to Praison AI! 🚀🤖
1
+ # Welcome to PraisonAI! 🚀
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: PraisonAI
3
- Version: 2.0.23
3
+ Version: 2.0.25
4
4
  Summary: PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customisation, and efficient human–agent collaboration.
5
5
  Author: Mervin Praison
6
6
  Requires-Python: >=3.10,<3.13
@@ -21,43 +21,68 @@ Provides-Extra: google
21
21
  Provides-Extra: gradio
22
22
  Provides-Extra: openai
23
23
  Provides-Extra: realtime
24
- Provides-Extra: train
25
24
  Provides-Extra: ui
26
25
  Requires-Dist: PyYAML (>=6.0)
27
26
  Requires-Dist: agentops (>=0.3.12) ; extra == "agentops"
28
- Requires-Dist: aiosqlite (>=0.20.0) ; extra == "ui" or extra == "chat" or extra == "code" or extra == "realtime"
29
- Requires-Dist: chainlit (==2.0rc1) ; extra == "ui" or extra == "chat" or extra == "code" or extra == "realtime"
30
- Requires-Dist: crawl4ai (==0.3.4) ; extra == "chat" or extra == "code" or extra == "realtime"
31
- Requires-Dist: crewai (>=0.32.0) ; extra == "crewai" or extra == "autogen"
27
+ Requires-Dist: aiosqlite (>=0.20.0) ; extra == "chat"
28
+ Requires-Dist: aiosqlite (>=0.20.0) ; extra == "code"
29
+ Requires-Dist: aiosqlite (>=0.20.0) ; extra == "realtime"
30
+ Requires-Dist: aiosqlite (>=0.20.0) ; extra == "ui"
31
+ Requires-Dist: chainlit (==1.3.2) ; extra == "chat"
32
+ Requires-Dist: chainlit (==1.3.2) ; extra == "code"
33
+ Requires-Dist: chainlit (==1.3.2) ; extra == "realtime"
34
+ Requires-Dist: chainlit (==1.3.2) ; extra == "ui"
35
+ Requires-Dist: crawl4ai (==0.3.4) ; extra == "chat"
36
+ Requires-Dist: crawl4ai (==0.3.4) ; extra == "code"
37
+ Requires-Dist: crawl4ai (==0.3.4) ; extra == "realtime"
38
+ Requires-Dist: crewai (>=0.32.0) ; extra == "crewai"
39
+ Requires-Dist: crewai ; extra == "autogen"
32
40
  Requires-Dist: duckduckgo_search (>=6.3.0) ; extra == "realtime"
33
41
  Requires-Dist: fastapi (>=0.95.0) ; extra == "call"
34
42
  Requires-Dist: flaml[automl] (>=2.3.1) ; extra == "call"
35
43
  Requires-Dist: flask (>=3.0.0) ; extra == "api"
36
44
  Requires-Dist: gradio (>=4.26.0) ; extra == "gradio"
37
- Requires-Dist: greenlet (>=3.0.3) ; extra == "ui" or extra == "chat" or extra == "code" or extra == "realtime"
45
+ Requires-Dist: greenlet (>=3.0.3) ; extra == "chat"
46
+ Requires-Dist: greenlet (>=3.0.3) ; extra == "code"
47
+ Requires-Dist: greenlet (>=3.0.3) ; extra == "realtime"
48
+ Requires-Dist: greenlet (>=3.0.3) ; extra == "ui"
38
49
  Requires-Dist: instructor (>=1.3.3)
39
50
  Requires-Dist: langchain-anthropic (>=0.1.13) ; extra == "anthropic"
40
51
  Requires-Dist: langchain-cohere (>=0.1.4) ; extra == "cohere"
41
52
  Requires-Dist: langchain-google-genai (>=1.0.4) ; extra == "google"
42
53
  Requires-Dist: langchain-openai (>=0.1.7) ; extra == "openai"
43
- Requires-Dist: litellm (>=1.41.8) ; extra == "chat" or extra == "code" or extra == "realtime"
54
+ Requires-Dist: litellm (>=1.41.8) ; extra == "chat"
55
+ Requires-Dist: litellm (>=1.41.8) ; extra == "code"
56
+ Requires-Dist: litellm (>=1.41.8) ; extra == "realtime"
44
57
  Requires-Dist: markdown (>=3.5)
45
58
  Requires-Dist: openai (>=1.54.0) ; extra == "call"
46
- Requires-Dist: playwright (>=1.47.0) ; extra == "chat" or extra == "code"
59
+ Requires-Dist: playwright (>=1.47.0) ; extra == "chat"
60
+ Requires-Dist: playwright (>=1.47.0) ; extra == "code"
47
61
  Requires-Dist: plotly (>=5.24.0) ; extra == "realtime"
48
- Requires-Dist: praisonai-tools (>=0.0.7) ; extra == "crewai" or extra == "autogen"
49
- Requires-Dist: praisonaiagents (>=0.0.17)
62
+ Requires-Dist: praisonai-tools (>=0.0.7) ; extra == "autogen"
63
+ Requires-Dist: praisonai-tools (>=0.0.7) ; extra == "crewai"
64
+ Requires-Dist: praisonaiagents (>=0.0.20)
50
65
  Requires-Dist: pyautogen (>=0.2.19) ; extra == "autogen"
51
- Requires-Dist: pydantic (<=2.10.1) ; extra == "ui" or extra == "chat" or extra == "code"
66
+ Requires-Dist: pydantic (<=2.10.1) ; extra == "chat"
67
+ Requires-Dist: pydantic (<=2.10.1) ; extra == "code"
68
+ Requires-Dist: pydantic (<=2.10.1) ; extra == "ui"
52
69
  Requires-Dist: pyngrok (>=1.4.0) ; extra == "call"
53
70
  Requires-Dist: pyparsing (>=3.0.0)
54
71
  Requires-Dist: python-dotenv (>=0.19.0)
55
- Requires-Dist: rich (>=13.7) ; extra == "chat" or extra == "call"
56
- Requires-Dist: sqlalchemy (>=2.0.36) ; extra == "ui" or extra == "chat" or extra == "code" or extra == "realtime"
57
- Requires-Dist: tavily-python (==0.5.0) ; extra == "chat" or extra == "code" or extra == "realtime"
72
+ Requires-Dist: rich (>=13.7)
73
+ Requires-Dist: rich ; extra == "call"
74
+ Requires-Dist: rich ; extra == "chat"
75
+ Requires-Dist: sqlalchemy (>=2.0.36) ; extra == "chat"
76
+ Requires-Dist: sqlalchemy (>=2.0.36) ; extra == "code"
77
+ Requires-Dist: sqlalchemy (>=2.0.36) ; extra == "realtime"
78
+ Requires-Dist: sqlalchemy (>=2.0.36) ; extra == "ui"
79
+ Requires-Dist: tavily-python (==0.5.0) ; extra == "chat"
80
+ Requires-Dist: tavily-python (==0.5.0) ; extra == "code"
81
+ Requires-Dist: tavily-python (==0.5.0) ; extra == "realtime"
58
82
  Requires-Dist: twilio (>=7.0.0) ; extra == "call"
59
83
  Requires-Dist: uvicorn (>=0.20.0) ; extra == "call"
60
- Requires-Dist: websockets (>=12.0) ; extra == "realtime" or extra == "call"
84
+ Requires-Dist: websockets (>=12.0) ; extra == "call"
85
+ Requires-Dist: websockets (>=12.0) ; extra == "realtime"
61
86
  Requires-Dist: yfinance (>=0.2.44) ; extra == "realtime"
62
87
  Project-URL: Homepage, https://docs.praison.ai
63
88
  Project-URL: Repository, https://github.com/mervinpraison/PraisonAI
@@ -5,7 +5,7 @@ praisonai/api/call.py,sha256=iHdAlgIH_oTsEbjaGGu1Jjo6DTfMR-SfFdtSxnOLCeY,11032
5
5
  praisonai/auto.py,sha256=uLDm8CU3L_3amZsd55yzf9RdBF1uW-BGSx7nl9ctNZ4,8680
6
6
  praisonai/chainlit_ui.py,sha256=bNR7s509lp0I9JlJNvwCZRUZosC64qdvlFCt8NmFamQ,12216
7
7
  praisonai/cli.py,sha256=M69ji9gQGzWVLewNhTwH5kYZuj63TzlcishxoRx18ug,21210
8
- praisonai/deploy.py,sha256=8SOCR6yRAaoX-EpF6Snqfr_O8rfnbcOA3SAdWmLrxuk,6028
8
+ praisonai/deploy.py,sha256=gBNkHaAdp27OeMcG42wudtqW7BSIH2DbM87bzoB2F2M,6028
9
9
  praisonai/inbuilt_tools/__init__.py,sha256=fai4ZJIKz7-iOnGZv5jJX0wmT77PKa4x2jqyaJddKFA,569
10
10
  praisonai/inbuilt_tools/autogen_tools.py,sha256=kJdEv61BTYvdHOaURNEpBcWq8Rs-oC03loNFTIjT-ak,4687
11
11
  praisonai/inc/__init__.py,sha256=sPDlYBBwdk0VlWzaaM_lG0_LD07lS2HRGvPdxXJFiYg,62
@@ -35,9 +35,12 @@ praisonai/setup.py,sha256=0jHgKnIPCtBZiGYaYyTz3PzrJI6nBy55VXk2UctXlDo,373
35
35
  praisonai/test.py,sha256=OL-wesjA5JTohr8rtr6kWoaS4ImkJg2l0GXJ-dUUfRU,4090
36
36
  praisonai/train.py,sha256=DvORlrwKOD-2v4r_z84eV3LsfzpNs-WnPKb5cQB3_t4,11071
37
37
  praisonai/ui/README.md,sha256=QG9yucvBieVjCjWFzu6hL9xNtYllkoqyJ_q1b0YYAco,1124
38
- praisonai/ui/agents.py,sha256=VDBm4Yp6jSllUMwDmv2UleTPmPepy8zMcMZ4G4lanKA,21381
38
+ praisonai/ui/agents.py,sha256=ayrxHw4SCdpye5FewGQyG9cBmzzJhmataX4_6X4VNtU,27530
39
+ praisonai/ui/callbacks.py,sha256=V4_-GjxmjDFmugUZGfQHKtNSysx7rT6i1UblbM_8lIM,1968
39
40
  praisonai/ui/chat.py,sha256=rlYwhTd3giBuvtK4Yc9kf6N9jfVT0VrZ-mLIzhANGiQ,13565
40
41
  praisonai/ui/code.py,sha256=GD_xQTo7qzpOM98tu4MOPsviJdXU__Ta3JIfsjoRe6U,15797
42
+ praisonai/ui/colab.py,sha256=A2NceDVazMy53mIpp-NIn5w3y8aQKwQu5LmHTepVwlo,19584
43
+ praisonai/ui/colab_chainlit.py,sha256=wrB1O0ttRlmOH8aMxU8QdGpse-X54U87ZcEEA3R1aFg,2432
41
44
  praisonai/ui/components/aicoder.py,sha256=Xh95RSEJCel5mEGic4vdtzyNpHNULF3ymft9nbwglXY,11155
42
45
  praisonai/ui/config/.chainlit/config.toml,sha256=kxb2APgVauLtfxlcEMlv8GHse6p8AbNTsJhIfZF38bg,3824
43
46
  praisonai/ui/config/.chainlit/translations/bn.json,sha256=m2TAaGMS-18_siW5dw4sbosh0Wn8ENWWzdGYkHaBrXw,22679
@@ -51,7 +54,7 @@ praisonai/ui/config/.chainlit/translations/mr.json,sha256=JaU16y5uW-cH0x7w6RDztE
51
54
  praisonai/ui/config/.chainlit/translations/ta.json,sha256=8JPW6BwLN2dl9wuq5wSkMvazcY8lM5v1pqbBxwObGUw,24724
52
55
  praisonai/ui/config/.chainlit/translations/te.json,sha256=JzW2YXWg1qqvWgIvEgMelQz5s6EzTb_uD_3TEHAHiQw,23526
53
56
  praisonai/ui/config/.chainlit/translations/zh-CN.json,sha256=aLBSSSQ0yojlYGuMMlOYvkD_ruG9-d2AgnjJWhPODVw,11737
54
- praisonai/ui/config/chainlit.md,sha256=zhT-Le2gShsByFXBKfayO6sM29fs3PWTfy6fG93sNJ8,33
57
+ praisonai/ui/config/chainlit.md,sha256=YCjGjkKOeW0w711tkAdEfC6sPgBRm6G3bxYPFeHx72U,28
55
58
  praisonai/ui/config/translations/bn.json,sha256=m2TAaGMS-18_siW5dw4sbosh0Wn8ENWWzdGYkHaBrXw,22679
56
59
  praisonai/ui/config/translations/en-US.json,sha256=QoQAg8P5Q5gbGASc-HAHcfhufk71-Uc1u_ewIBfHuLc,9821
57
60
  praisonai/ui/config/translations/gu.json,sha256=9wE-NsHf7j5VUFzfE-cCpESTyHtzVHRcZXAwC3ACMl0,21660
@@ -78,8 +81,8 @@ praisonai/ui/realtimeclient/realtimedocs.txt,sha256=hmgd8Uwy2SkjSndyyF_-ZOaNxiyH
78
81
  praisonai/ui/realtimeclient/tools.py,sha256=IJOYwVOBW5Ocn5_iV9pFkmSKR3WU3YpX3kwF0I3jikQ,7855
79
82
  praisonai/ui/sql_alchemy.py,sha256=cfyL9uFfuizKFvW0aZfUBlJWPQYI-YBi1v4vxlkb1BQ,29615
80
83
  praisonai/version.py,sha256=ugyuFliEqtAwQmH4sTlc16YXKYbFWDmfyk87fErB8-8,21
81
- praisonai-2.0.23.dist-info/LICENSE,sha256=kqvFysVlnFxYOu0HxCe2HlmZmJtdmNGOxWRRkT9TsWc,1035
82
- praisonai-2.0.23.dist-info/METADATA,sha256=NpgHSV1m0uAXmleDA-HPpZXGcr0Wtlb7konsxQTbgqo,20940
83
- praisonai-2.0.23.dist-info/WHEEL,sha256=x1HiyTP_r-PIOu3STHzjukjf5kVLXzgVftSXf5bl8AU,110
84
- praisonai-2.0.23.dist-info/entry_points.txt,sha256=I_xc6a6MNTTfLxYmAxe0rgey0G-_hbY07oFW-ZDnkw4,135
85
- praisonai-2.0.23.dist-info/RECORD,,
84
+ praisonai-2.0.25.dist-info/LICENSE,sha256=kqvFysVlnFxYOu0HxCe2HlmZmJtdmNGOxWRRkT9TsWc,1035
85
+ praisonai-2.0.25.dist-info/METADATA,sha256=dPOcVl-6dVUSktySry3AaxyKJkb0ItVOtOLM5-5MVJo,21774
86
+ praisonai-2.0.25.dist-info/WHEEL,sha256=rqU-pzVJ6on7cnU-SP20blBtY1yM7u0ejCbKCZ5K36I,110
87
+ praisonai-2.0.25.dist-info/entry_points.txt,sha256=I_xc6a6MNTTfLxYmAxe0rgey0G-_hbY07oFW-ZDnkw4,135
88
+ praisonai-2.0.25.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.1
2
+ Generator: poetry-core 2.0.0
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-manylinux_2_39_x86_64