Restructure the project praisonai[crewai] praisonai[autogen]

This commit is contained in:
MervinPraison committed 2024-10-31 00:41:53 +00:00
1 parent 93b5c28f65
commit 394bb0b503
25 files changed
+1829 -1410

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==0.1.10 gunicorn markdown
RUN pip install flask praisonai==1.0.0 gunicorn markdown
EXPOSE 8080
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
+77 -9
View File
@@ -49,16 +49,84 @@ Praison AI, leveraging both AutoGen and CrewAI or any other agent framework, rep
| Basic | PraisonAI | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a> |
| Include Tools | PraisonAI Tools | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-tools-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a> |
## Install
## Installation Options
| | Installation |
|---|---|
| **PraisonAI** | `pip install praisonai` |
| **PraisonAI Code** | `pip install "praisonai[code]"` |
| **PraisonAI Chat** | `pip install "praisonai[chat]"` |
| **PraisonAI Train** | `pip install "praisonai[train]"` |
| **PraisonAI Realtime** | `pip install "praisonai[realtime]"` |
| **PraisonAI Call** | `pip install "praisonai[call]"` |
### Basic Installation
```bash
pip install praisonai
```
### Framework-specific Installation
```bash
# Install with CrewAI support
pip install "praisonai[crewai]"
# Install with AutoGen support
pip install "praisonai[autogen]"
# Install with both frameworks
pip install "praisonai[crewai,autogen]"
```
### UI and Additional Features
```bash
# Install UI support
pip install "praisonai[ui]"
# Install Chat interface
pip install "praisonai[chat]"
# Install Code interface
pip install "praisonai[code]"
# Install Realtime voice interaction
pip install "praisonai[realtime]"
# Install Call feature
pip install "praisonai[call]"
```
## Quick Start
```bash
# Set your OpenAI API key
export OPENAI_API_KEY="Enter your API key"
# Initialize with CrewAI (default)
praisonai --init "create a movie script about dog in moon"
# Or initialize with AutoGen
praisonai --framework autogen --init "create a movie script about dog in moon"
# Run the agents
praisonai
```
## Full Automatic Mode
```bash
# With CrewAI (default)
praisonai --auto "create a movie script about Dog in Moon"
# With AutoGen
praisonai --framework autogen --auto "create a movie script about Dog in Moon"
```
## Framework-specific Features
### CrewAI
When installing with `pip install "praisonai[crewai]"`, you get:
- CrewAI framework support
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
### AutoGen
When installing with `pip install "praisonai[autogen]"`, you get:
- AutoGen framework support
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
## Key Features
+34 -12
View File
@@ -1,22 +1,44 @@
---
title: 'API Reference'
description: 'PraisonAI API documentation'
description: 'PraisonAI API documentation with framework-specific details'
---
{/* Replace any comments with this style */}
# API Reference
{/* Rest of the content remains the same */}
This section provides detailed information about the PraisonAI API and its framework-specific implementations.
This section provides detailed information about the PraisonAI API.
## Core Modules
## Modules
- [praisonai](../api/praisonai/index) - Core package functionality
- [praisonai.auto](../api/praisonai/auto) - Automated agent generation
- [praisonai.agents_generator](../api/praisonai/agents_generator) - Framework-specific agent generation
- [praisonai.cli](../api/praisonai/cli) - Command-line interface
- [praisonai.deploy](../api/praisonai/deploy) - Deployment utilities
- [praisonai](../api/praisonai/index)
- [praisonai.auto](../api/praisonai/auto)
- [praisonai.agents_generator](../api/praisonai/agents_generator)
- [praisonai.cli](../api/praisonai/cli)
- [praisonai.deploy](../api/praisonai/deploy)
## Framework Support
For more detailed API documentation, please refer to the generated files in the `api` folder.
### CrewAI Integration
Requires installation with:
```bash
pip install "praisonai[crewai]"
```
Features:
- Task delegation
- Sequential/parallel execution
- Built-in tools
- Structured workflows
### AutoGen Integration
Requires installation with:
```bash
pip install "praisonai[autogen]"
```
Features:
- Multi-agent conversations
- Code execution
- Built-in tools
- Flexible interactions
For detailed API documentation of each module, please refer to the generated files in the `api` folder.
+74 -5
View File
@@ -1,6 +1,75 @@
# API Reference
::: praisonai
::: praisonai.auto
::: praisonai.agents_generator
::: praisonai.cli
::: praisonai.deploy
## Core Modules
### praisonai
The main package containing core functionality.
```python
from praisonai import PraisonAI
```
### praisonai.auto
Automated agent generation functionality.
```python
from praisonai.auto import AutoGenerator
```
### praisonai.agents_generator
Framework-specific agent generation and orchestration:
- CrewAI support (requires `praisonai[crewai]`)
- AutoGen support (requires `praisonai[autogen]`)
```python
from praisonai.agents_generator import AgentsGenerator
```
### praisonai.cli
Command-line interface with framework-specific handling.
```python
from praisonai.cli import PraisonAI
```
### praisonai.deploy
Deployment utilities.
```python
from praisonai.deploy import CloudDeployer
```
## Installation Options
```bash
# Basic installation
pip install praisonai
# Framework-specific installations
pip install "praisonai[crewai]" # Install with CrewAI support
pip install "praisonai[autogen]" # Install with AutoGen support
pip install "praisonai[crewai,autogen]" # Install both frameworks
# Additional features
pip install "praisonai[ui]" # Install UI support
pip install "praisonai[chat]" # Install Chat interface
pip install "praisonai[code]" # Install Code interface
pip install "praisonai[realtime]" # Install Realtime voice interaction
pip install "praisonai[call]" # Install Call feature
```
## Framework-specific Features
### CrewAI
When installing with `pip install "praisonai[crewai]"`, you get:
- CrewAI framework support
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
### AutoGen
When installing with `pip install "praisonai[autogen]"`, you get:
- AutoGen framework support
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
+1 -1
View File
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==0.1.10 gunicorn markdown\n&#34;)
file.write(&#34;RUN pip install flask praisonai==1.0.0 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
+45 -3
View File
@@ -1,6 +1,48 @@
# Auto
## Full Automatic Mode
# Auto Generation Mode
PraisonAI supports automatic agent generation with both CrewAI and AutoGen frameworks.
## Installation
Choose your preferred framework:
```bash
praisonai --auto create a movie script about Dog in Moon
# For CrewAI
pip install "praisonai[crewai]"
# For AutoGen
pip install "praisonai[autogen]"
# For both frameworks
pip install "praisonai[crewai,autogen]"
```
## Usage
### With CrewAI (Default)
```bash
praisonai --auto "create a movie script about Dog in Moon"
```
### With AutoGen
```bash
praisonai --framework autogen --auto "create a movie script about Dog in Moon"
```
## Framework-specific Features
### CrewAI
- Task delegation capabilities
- Sequential and parallel task execution
- Built-in tools integration
- Structured agent-task relationships
### AutoGen
- Multi-agent conversation capabilities
- Code execution environment
- Built-in tools integration
- Flexible agent interactions
```bash
praisonai --auto "create a movie script about Dog in Moon"
```
+23 -8
View File
@@ -1,19 +1,34 @@
# AutoGen Low Code with Praison AI
# AutoGen with PraisonAI
Low Code solution to run AutoGen
Low-code solution to run AutoGen with integrated tools and features.
## Installation
```bash
pip install praisonai
# Install with AutoGen support
pip install "praisonai[autogen]"
```
This installation includes:
- AutoGen framework
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
## Quick Start
```bash
# Set your OpenAI API key
export OPENAI_API_KEY=xxxxxxxxxx
```
```bash
praisonai --framework autogen --init Create a Movie Script About Cat in Mars
```
# Initialize with AutoGen
praisonai --framework autogen --init "Create a Movie Script About Cat in Mars"
```bash
# Run the agents
praisonai --framework autogen
```
## Auto Mode
```bash
praisonai --framework autogen --auto "Create a Movie Script About Cat in Mars"
```
+23 -8
View File
@@ -1,19 +1,34 @@
# CrewAI Low Code with PraisonAI
# CrewAI with PraisonAI
Low Code solution to run CrewAI
Low-code solution to run CrewAI with integrated tools and features.
## Installation
```bash
pip install praisonai
# Install with CrewAI support
pip install "praisonai[crewai]"
```
This installation includes:
- CrewAI framework
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
## Quick Start
```bash
# Set your OpenAI API key
export OPENAI_API_KEY=xxxxxxxxxx
```
```bash
praisonai --framework crewai --init Create a Movie Script About Cat in Mars
```
# Initialize with CrewAI
praisonai --framework crewai --init "Create a Movie Script About Cat in Mars"
```bash
# Run the agents
praisonai --framework crewai
```
## Auto Mode
```bash
praisonai --framework crewai --auto "Create a Movie Script About Cat in Mars"
```
+26 -10
View File
@@ -41,11 +41,33 @@ Praison AI, leveraging both AutoGen and CrewAI or any other agent framework, rep
| Basic | PraisonAI | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a> |
| Include Tools | PraisonAI Tools | <a target="_blank" href="https://colab.research.google.com/github/MervinPraison/PraisonAI/blob/main/cookbooks/praisonai-tools-googlecolab.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" /></a> |
## Install
## Installation Options
| PraisonAI | PraisonAI Code | PraisonAI Chat |
| --- | --- | --- |
| `pip install praisonai` | `pip install "praisonai[code]"` | `pip install "praisonai[chat]"` |
### Basic Installation
```bash
pip install praisonai
```
### Framework-specific Installation
```bash
# Install with CrewAI support
pip install "praisonai[crewai]"
# Install with AutoGen support
pip install "praisonai[autogen]"
# Install with both frameworks
pip install "praisonai[crewai,autogen]"
```
### UI and Additional Features
```bash
pip install "praisonai[ui]" # UI support
pip install "praisonai[chat]" # Chat interface
pip install "praisonai[code]" # Code interface
pip install "praisonai[realtime]" # Realtime voice interaction
pip install "praisonai[call]" # Call feature
```
## TL;DR Multi Agents
@@ -56,12 +78,6 @@ praisonai --init create a movie script about dog in moon
praisonai
```
## Installation
```bash
pip install praisonai
```
## Initialise
```bash
+49
View File
@@ -1,5 +1,54 @@
# Installation
## Basic Installation
```bash
pip install praisonai
```
## Framework-specific Installation
### CrewAI Support
```bash
pip install "praisonai[crewai]"
```
Includes:
- CrewAI framework
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
### AutoGen Support
```bash
pip install "praisonai[autogen]"
```
Includes:
- AutoGen framework
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
### Both Frameworks
```bash
pip install "praisonai[crewai,autogen]"
```
## Additional Features
```bash
# UI support
pip install "praisonai[ui]"
# Chat interface
pip install "praisonai[chat]"
# Code interface
pip install "praisonai[code]"
# Realtime voice interaction
pip install "praisonai[realtime]"
# Call feature
pip install "praisonai[call]"
```
+28 -4
View File
@@ -1,20 +1,44 @@
# TL;DR
## Run throught Terminal
## Quick Start with CrewAI (Default)
```bash
pip install praisonai
# Install with CrewAI support
pip install "praisonai[crewai]"
# Set your API key
export OPENAI_API_KEY="Enter your API key"
praisonai --init create a movie script about dog in moon
# Initialize and run
praisonai --init "create a movie script about dog in moon"
praisonai
```
## Quick Start with AutoGen
```bash
# Install with AutoGen support
pip install "praisonai[autogen]"
# Set your API key
export OPENAI_API_KEY="Enter your API key"
# Initialize and run
praisonai --framework autogen --init "create a movie script about dog in moon"
praisonai --framework autogen
```
## User Interface
```bash
pip install -U "praisonai[ui]"
# Install UI support
pip install "praisonai[ui]"
# Set up environment
export OPENAI_API_KEY="Enter your API key"
chainlit create-secret
export CHAINLIT_AUTH_SECRET=xxxxxxxx
# Run UI
praisonai ui
```
Generated
+652 -649
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -3,7 +3,7 @@ class Praisonai < Formula
desc "AI tools for various AI applications"
homepage "https://github.com/MervinPraison/PraisonAI"
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/0.1.10.tar.gz"
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/1.0.0.tar.gz"
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
license "MIT"
+288 -206
View File
@@ -5,34 +5,55 @@ from .version import __version__
import yaml, os
from rich import print
from dotenv import load_dotenv
from crewai import Agent, Task, Crew
from crewai.telemetry import Telemetry
load_dotenv()
import autogen
import argparse
from .auto import AutoGenerator
from praisonai_tools import (
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
YoutubeVideoSearchTool
)
from .inbuilt_tools import *
from .inc import PraisonAIModel
import inspect
from pathlib import Path
import importlib
import importlib.util
from praisonai_tools import BaseTool
import os
import logging
agentops_exists = False
# Framework-specific imports with availability checks
CREWAI_AVAILABLE = False
AUTOGEN_AVAILABLE = False
PRAISONAI_TOOLS_AVAILABLE = False
AGENTOPS_AVAILABLE = False
try:
from crewai import Agent, Task, Crew
from crewai.telemetry import Telemetry
CREWAI_AVAILABLE = True
except ImportError:
pass
try:
import autogen
AUTOGEN_AVAILABLE = True
except ImportError:
pass
try:
import agentops
agentops_exists = True
AGENTOPS_AVAILABLE = True
except ImportError:
agentops_exists = False
pass
# Only try to import praisonai_tools if either CrewAI or AutoGen is available
if CREWAI_AVAILABLE or AUTOGEN_AVAILABLE:
try:
from praisonai_tools import (
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
YoutubeChannelSearchTool, YoutubeVideoSearchTool, BaseTool
)
PRAISONAI_TOOLS_AVAILABLE = True
except ImportError:
# If import fails, define BaseTool as a simple base class
class BaseTool:
pass
os.environ["OTEL_SDK_DISABLED"] = "true"
@@ -40,11 +61,14 @@ def noop(*args, **kwargs):
pass
def disable_crewai_telemetry():
for attr in dir(Telemetry):
if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
setattr(Telemetry, attr, noop)
disable_crewai_telemetry()
if CREWAI_AVAILABLE:
for attr in dir(Telemetry):
if callable(getattr(Telemetry, attr)) and not attr.startswith("__"):
setattr(Telemetry, attr, noop)
# Only disable telemetry if CrewAI is available
if CREWAI_AVAILABLE:
disable_crewai_telemetry()
class AgentsGenerator:
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
@@ -86,6 +110,12 @@ class AgentsGenerator:
self.logger = logging.getLogger(__name__)
self.logger.setLevel(self.log_level)
# Validate framework availability
if framework == "crewai" and not CREWAI_AVAILABLE:
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
elif framework == "autogen" and not AUTOGEN_AVAILABLE:
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
def is_function_or_decorated(self, obj):
"""
Checks if the given object is a function or has a __call__ method.
@@ -118,21 +148,21 @@ class AgentsGenerator:
def load_tools_from_module_class(self, module_path):
"""
Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
Loads tools from a specified module path containing classes that inherit from BaseTool
or are part of langchain_community.tools package.
"""
spec = importlib.util.spec_from_file_location("tools_module", module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith('langchain_community.tools') or issubclass(x, BaseTool)) and x is not BaseTool)}
try:
spec.loader.exec_module(module)
return {name: obj() for name, obj in inspect.getmembers(module,
lambda x: inspect.isclass(x) and (
x.__module__.startswith('langchain_community.tools') or
(PRAISONAI_TOOLS_AVAILABLE and issubclass(x, BaseTool))
) and x is not BaseTool)}
except ImportError as e:
self.logger.warning(f"Error loading tools from {module_path}: {e}")
return {}
def load_tools_from_package(self, package_path):
"""
@@ -188,36 +218,37 @@ class AgentsGenerator:
return
topic = config['topic']
tools_dict = {
'CodeDocsSearchTool': CodeDocsSearchTool(),
'CSVSearchTool': CSVSearchTool(),
'DirectorySearchTool': DirectorySearchTool(),
'DOCXSearchTool': DOCXSearchTool(),
'DirectoryReadTool': DirectoryReadTool(),
'FileReadTool': FileReadTool(),
# 'GithubSearchTool': GithubSearchTool(),
# 'SeperDevTool': SeperDevTool(),
'TXTSearchTool': TXTSearchTool(),
'JSONSearchTool': JSONSearchTool(),
'MDXSearchTool': MDXSearchTool(),
'PDFSearchTool': PDFSearchTool(),
# 'PGSearchTool': PGSearchTool(),
'RagTool': RagTool(),
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
'WebsiteSearchTool': WebsiteSearchTool(),
'XMLSearchTool': XMLSearchTool(),
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
}
# Add tools from class names
for tool_class in self.tools:
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
tool_name = tool_class.__name__
tools_dict[tool_name] = tool_class()
self.logger.debug(f"Added tool: {tool_name}")
tools_dict = {}
# Only try to use praisonai_tools if it's available and needed
if PRAISONAI_TOOLS_AVAILABLE and (CREWAI_AVAILABLE or AUTOGEN_AVAILABLE):
tools_dict = {
'CodeDocsSearchTool': CodeDocsSearchTool(),
'CSVSearchTool': CSVSearchTool(),
'DirectorySearchTool': DirectorySearchTool(),
'DOCXSearchTool': DOCXSearchTool(),
'DirectoryReadTool': DirectoryReadTool(),
'FileReadTool': FileReadTool(),
'TXTSearchTool': TXTSearchTool(),
'JSONSearchTool': JSONSearchTool(),
'MDXSearchTool': MDXSearchTool(),
'PDFSearchTool': PDFSearchTool(),
'RagTool': RagTool(),
'ScrapeElementFromWebsiteTool': ScrapeElementFromWebsiteTool(),
'ScrapeWebsiteTool': ScrapeWebsiteTool(),
'WebsiteSearchTool': WebsiteSearchTool(),
'XMLSearchTool': XMLSearchTool(),
'YoutubeChannelSearchTool': YoutubeChannelSearchTool(),
'YoutubeVideoSearchTool': YoutubeVideoSearchTool(),
}
# Add tools from class names
for tool_class in self.tools:
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
tool_name = tool_class.__name__
tools_dict[tool_name] = tool_class()
self.logger.debug(f"Added tool: {tool_name}")
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, 'tools.py')
tools_dir_path = Path(root_directory) / 'tools'
@@ -231,162 +262,213 @@ class AgentsGenerator:
framework = self.framework or config.get('framework')
if framework == "autogen":
if not AUTOGEN_AVAILABLE:
raise ImportError("AutoGen is not installed. Please install it with 'pip install praisonai[autogen]'")
if AGENTOPS_AVAILABLE:
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["autogen"])
return self._run_autogen(config, topic, tools_dict)
else: # framework=crewai
if not CREWAI_AVAILABLE:
raise ImportError("CrewAI is not installed. Please install it with 'pip install praisonai[crewai]'")
if AGENTOPS_AVAILABLE:
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["crewai"])
return self._run_crewai(config, topic, tools_dict)
def _run_autogen(self, config, topic, tools_dict):
"""
Run agents using the AutoGen framework.
Args:
config (dict): Configuration dictionary
topic (str): The topic to process
tools_dict (dict): Dictionary of available tools
Returns:
str: Result of the agent interactions
"""
llm_config = {"config_list": self.config_list}
# Set up user proxy agent
user_proxy = autogen.UserProxyAgent(
name="User",
human_input_mode="NEVER",
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
code_execution_config={
"work_dir": "coding",
"use_docker": False,
}
)
agents = {}
tasks = []
if framework == "autogen":
# Load the LLM configuration dynamically
# print(self.config_list)
llm_config = {"config_list": self.config_list}
# Create agents and tasks from config
for role, details in config['roles'].items():
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
agent_goal = details['goal'].format(topic=topic)
if agentops_exists:
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["autogen"])
# Assuming the user proxy agent is set up as per your requirements
user_proxy = autogen.UserProxyAgent(
name="User",
human_input_mode="NEVER",
is_termination_msg=lambda x: (x.get("content") or "").rstrip().rstrip(".").lower().endswith("terminate") or "TERMINATE" in (x.get("content") or ""),
code_execution_config={
"work_dir": "coding",
"use_docker": False,
},
# additional setup for the user proxy agent
# Create AutoGen assistant agent
agents[role] = autogen.AssistantAgent(
name=agent_name,
llm_config=llm_config,
system_message=details['backstory'].format(topic=topic) +
". Must Reply \"TERMINATE\" in the end when everything is done.",
)
for role, details in config['roles'].items():
agent_name = details['role'].format(topic=topic).replace("{topic}", topic)
agent_goal = details['goal'].format(topic=topic)
# Creating an AssistantAgent for each role dynamically
agents[role] = autogen.AssistantAgent(
name=agent_name,
llm_config=llm_config,
system_message=details['backstory'].format(topic=topic)+". Must Reply \"TERMINATE\" in the end when everything is done.",
)
for tool in details.get('tools', []):
if tool in tools_dict:
try:
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
print(f"Found {tool_class.__name__} for {tool}")
except KeyError:
print(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
continue
# Add tools to agent if specified
for tool in details.get('tools', []):
if tool in tools_dict:
try:
tool_class = globals()[f'autogen_{type(tools_dict[tool]).__name__}']
self.logger.debug(f"Found {tool_class.__name__} for {tool}")
tool_class(agents[role], user_proxy)
except KeyError:
self.logger.warning(f"Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.")
continue
# Preparing tasks for initiate_chats
for task_name, task_details in details.get('tasks', {}).items():
description_filled = task_details['description'].format(topic=topic)
expected_output_filled = task_details['expected_output'].format(topic=topic)
chat_task = {
"recipient": agents[role],
"message": description_filled,
"summary_method": "last_msg",
# Additional fields like carryover can be added based on dependencies
}
tasks.append(chat_task)
response = user_proxy.initiate_chats(tasks)
result = "### Output ###\n"+response[-1].summary if hasattr(response[-1], 'summary') else ""
if agentops_exists:
agentops.end_session("Success")
else: # framework=crewai
if agentops_exists:
agentops.init(os.environ.get("AGENTOPS_API_KEY"), tags=["crewai"])
tasks_dict = {}
for role, details in config['roles'].items():
role_filled = details['role'].format(topic=topic)
goal_filled = details['goal'].format(topic=topic)
backstory_filled = details['backstory'].format(topic=topic)
# Prepare tasks
for task_name, task_details in details.get('tasks', {}).items():
description_filled = task_details['description'].format(topic=topic)
expected_output_filled = task_details['expected_output'].format(topic=topic)
# Adding tools to the agent if exists
agent_tools = [tools_dict[tool] for tool in details.get('tools', []) if tool in tools_dict]
llm_model = details.get('llm') # Get the llm configuration
if llm_model:
llm = PraisonAIModel(
model=llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
).get_model()
else:
llm = PraisonAIModel().get_model()
chat_task = {
"recipient": agents[role],
"message": description_filled,
"summary_method": "last_msg",
}
tasks.append(chat_task)
function_calling_llm_model = details.get('function_calling_llm')
if function_calling_llm_model:
function_calling_llm = PraisonAIModel(
model=function_calling_llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
).get_model()
else:
function_calling_llm = PraisonAIModel().get_model()
agent = Agent(
role=role_filled,
goal=goal_filled,
backstory=backstory_filled,
tools=agent_tools,
allow_delegation=details.get('allow_delegation', False),
llm=llm,
function_calling_llm=function_calling_llm,
max_iter=details.get('max_iter', 15),
max_rpm=details.get('max_rpm'),
max_execution_time=details.get('max_execution_time'),
verbose=details.get('verbose', True),
cache=details.get('cache', True),
system_template=details.get('system_template'),
prompt_template=details.get('prompt_template'),
response_template=details.get('response_template'),
# Execute tasks
response = user_proxy.initiate_chats(tasks)
result = "### Output ###\n" + response[-1].summary if hasattr(response[-1], 'summary') else ""
if AGENTOPS_AVAILABLE:
agentops.end_session("Success")
return result
def _run_crewai(self, config, topic, tools_dict):
"""
Run agents using the CrewAI framework.
Args:
config (dict): Configuration dictionary
topic (str): The topic to process
tools_dict (dict): Dictionary of available tools
Returns:
str: Result of the agent interactions
"""
agents = {}
tasks = []
tasks_dict = {}
# Create agents from config
for role, details in config['roles'].items():
role_filled = details['role'].format(topic=topic)
goal_filled = details['goal'].format(topic=topic)
backstory_filled = details['backstory'].format(topic=topic)
# Get agent tools
agent_tools = [tools_dict[tool] for tool in details.get('tools', [])
if tool in tools_dict]
# Configure LLM
llm_model = details.get('llm')
if llm_model:
llm = PraisonAIModel(
model=llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
).get_model()
else:
llm = PraisonAIModel().get_model()
# Configure function calling LLM
function_calling_llm_model = details.get('function_calling_llm')
if function_calling_llm_model:
function_calling_llm = PraisonAIModel(
model=function_calling_llm_model.get("model", os.environ.get("MODEL_NAME", "openai/gpt-4o")),
).get_model()
else:
function_calling_llm = PraisonAIModel().get_model()
# Create CrewAI agent
agent = Agent(
role=role_filled,
goal=goal_filled,
backstory=backstory_filled,
tools=agent_tools,
allow_delegation=details.get('allow_delegation', False),
llm=llm,
function_calling_llm=function_calling_llm,
max_iter=details.get('max_iter', 15),
max_rpm=details.get('max_rpm'),
max_execution_time=details.get('max_execution_time'),
verbose=details.get('verbose', True),
cache=details.get('cache', True),
system_template=details.get('system_template'),
prompt_template=details.get('prompt_template'),
response_template=details.get('response_template'),
)
# Set agent callback if provided
if self.agent_callback:
agent.step_callback = self.agent_callback
agents[role] = agent
# Create tasks for the agent
for task_name, task_details in details.get('tasks', {}).items():
description_filled = task_details['description'].format(topic=topic)
expected_output_filled = task_details['expected_output'].format(topic=topic)
task = Task(
description=description_filled,
expected_output=expected_output_filled,
agent=agent,
tools=task_details.get('tools', []),
async_execution=task_details.get('async_execution', False),
context=[],
config=task_details.get('config', {}),
output_json=task_details.get('output_json'),
output_pydantic=task_details.get('output_pydantic'),
output_file=task_details.get('output_file', ""),
callback=task_details.get('callback'),
human_input=task_details.get('human_input', False),
create_directory=task_details.get('create_directory', False)
)
# Set agent callback if provided
if self.agent_callback:
agent.step_callback = self.agent_callback
agents[role] = agent
for task_name, task_details in details.get('tasks', {}).items():
description_filled = task_details['description'].format(topic=topic)
expected_output_filled = task_details['expected_output'].format(topic=topic)
task = Task(
description=description_filled, # Clear, concise statement of what the task entails
expected_output=expected_output_filled, # Detailed description of what task's completion looks like
agent=agent, # The agent responsible for the task
tools=task_details.get('tools', []), # Functions or capabilities the agent can utilize
async_execution=task_details.get('async_execution') if task_details.get('async_execution') is not None else False, # Execute asynchronously if set
context=[], ## TODO:
config=task_details.get('config') if task_details.get('config') is not None else {}, # Additional configuration details
output_json=task_details.get('output_json') if task_details.get('output_json') is not None else None, # Outputs a JSON object
output_pydantic=task_details.get('output_pydantic') if task_details.get('output_pydantic') is not None else None, # Outputs a Pydantic model object
output_file=task_details.get('output_file') if task_details.get('output_file') is not None else "", # Saves the task output to a file
callback=task_details.get('callback') if task_details.get('callback') is not None else None, # Python callable executed with the task's output
human_input=task_details.get('human_input') if task_details.get('human_input') is not None else False, # Indicates if the task requires human feedback
create_directory=task_details.get('create_directory') if task_details.get('create_directory') is not None else False # Indicates if a directory needs to be created
)
# Set tool callback if provided
if self.task_callback:
task.callback = self.task_callback
tasks.append(task)
tasks_dict[task_name] = task
# Set task callback if provided
if self.task_callback:
task.callback = self.task_callback
tasks.append(task)
tasks_dict[task_name] = task
# Set up task contexts
for role, details in config['roles'].items():
for task_name, task_details in details.get('tasks', {}).items():
task = tasks_dict[task_name]
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', [])
if ctx in tasks_dict]
task.context = context_tasks
# Create and run the crew
crew = Crew(
agents=list(agents.values()),
tasks=tasks,
verbose=2
)
self.logger.debug("Final Crew Configuration:")
self.logger.debug(f"Agents: {crew.agents}")
self.logger.debug(f"Tasks: {crew.tasks}")
response = crew.kickoff()
result = f"### Task Output ###\n{response}"
if AGENTOPS_AVAILABLE:
agentops.end_session("Success")
for role, details in config['roles'].items():
for task_name, task_details in details.get('tasks', {}).items():
task = tasks_dict[task_name]
context_tasks = [tasks_dict[ctx] for ctx in task_details.get('context', []) if ctx in tasks_dict]
task.context = context_tasks
crew = Crew(
agents=list(agents.values()),
tasks=tasks,
verbose=2
)
self.logger.debug("Final Crew Configuration:")
self.logger.debug(f"Agents: {crew.agents}")
self.logger.debug(f"Tasks: {crew.tasks}")
response = crew.kickoff()
result = f"### Task Output ###\n{response}"
if agentops_exists:
agentops.end_session("Success")
return result
+49 -13
View File
@@ -7,6 +7,36 @@ import json
import yaml
from rich import print
import logging
# Framework-specific imports with availability checks
CREWAI_AVAILABLE = False
AUTOGEN_AVAILABLE = False
PRAISONAI_TOOLS_AVAILABLE = False
try:
from crewai import Agent, Task, Crew
CREWAI_AVAILABLE = True
except ImportError:
pass
try:
import autogen
AUTOGEN_AVAILABLE = True
except ImportError:
pass
try:
from praisonai_tools import (
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool,
DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool,
MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool,
ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
YoutubeChannelSearchTool, YoutubeVideoSearchTool
)
PRAISONAI_TOOLS_AVAILABLE = True
except ImportError:
PRAISONAI_TOOLS_AVAILABLE = False
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO').upper(), format='%(asctime)s - %(levelname)s - %(message)s')
# Define Pydantic models outside of the generate method
@@ -29,20 +59,26 @@ class AutoGenerator:
"""
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.
Args:
topic (str, optional): The topic for the generated team structure. Defaults to "Movie Story writing about AI".
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to "test.yaml".
framework (str, optional): The framework for the generated team structure. Defaults to "crewai".
config_list (Optional[List[Dict]], optional): A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.
Attributes:
config_list (list): A list containing the configuration details for the OpenAI API.
topic (str): The specified topic for the generated team structure.
agent_file (str): The specified name of the YAML file to save the generated team structure.
framework (str): The specified framework for the generated team structure.
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
"""
# Validate framework availability and show framework-specific messages
if framework == "crewai" and not CREWAI_AVAILABLE:
raise ImportError("""
CrewAI is not installed. Please install with:
pip install "praisonai[crewai]"
""")
elif framework == "autogen" and not AUTOGEN_AVAILABLE:
raise ImportError("""
AutoGen is not installed. Please install with:
pip install "praisonai[autogen]"
""")
# Only show tools message if using a framework and tools are needed
if (framework in ["crewai", "autogen"]) and not PRAISONAI_TOOLS_AVAILABLE:
logging.warning(f"""
Tools are not available for {framework}. To use tools, install:
pip install "praisonai[{framework}]"
""")
self.config_list = config_list or [
{
'model': os.environ.get("OPENAI_MODEL_NAME", "gpt-4o"),
+181 -175
View File
@@ -1,43 +1,63 @@
# praisonai/cli.py
import sys
import argparse
from .version import __version__
import yaml, os
import yaml
import os
from rich import print
from dotenv import load_dotenv
from crewai import Agent, Task, Crew
load_dotenv()
import autogen
import argparse
from .auto import AutoGenerator
from .agents_generator import AgentsGenerator
from .inbuilt_tools import *
from .inc.config import generate_config
import shutil
import subprocess
import logging
import importlib
try:
import praisonai.api.call as call_module
CALL_MODULE_AVAILABLE = True
except ImportError:
CALL_MODULE_AVAILABLE = False
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'), format='%(asctime)s - %(levelname)s - %(message)s')
from .auto import AutoGenerator
from .agents_generator import AgentsGenerator
from .inbuilt_tools import *
from .inc.config import generate_config
# Optional module imports with availability checks
CHAINLIT_AVAILABLE = False
GRADIO_AVAILABLE = False
CALL_MODULE_AVAILABLE = False
CREWAI_AVAILABLE = False
AUTOGEN_AVAILABLE = False
try:
os.environ["CHAINLIT_APP_ROOT"] = os.path.join(os.path.expanduser("~"), ".praison")
from chainlit.cli import chainlit_run
CHAINLIT_AVAILABLE = True
except ImportError:
CHAINLIT_AVAILABLE = False
pass
try:
import gradio as gr
GRADIO_AVAILABLE = True
except ImportError:
GRADIO_AVAILABLE = False
pass
try:
import praisonai.api.call as call_module
CALL_MODULE_AVAILABLE = True
except ImportError:
pass
try:
from crewai import Agent, Task, Crew
CREWAI_AVAILABLE = True
except ImportError:
pass
try:
import autogen
AUTOGEN_AVAILABLE = True
except ImportError:
pass
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'), format='%(asctime)s - %(levelname)s - %(message)s')
def stream_subprocess(command, env=None):
"""
Execute a subprocess command and stream the output to the terminal in real-time.
@@ -70,20 +90,6 @@ class PraisonAI:
def __init__(self, agent_file="agents.yaml", framework="", auto=False, init=False, agent_yaml=None, tools=None):
"""
Initialize the PraisonAI object with default parameters.
Parameters:
agent_file (str): The default agent file to use. Defaults to "agents.yaml".
framework (str): The default framework to use. Defaults to "crewai".
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
Attributes:
config_list (list): A list of configuration dictionaries for the OpenAI API.
agent_file (str): The agent file to use.
framework (str): The framework to use.
auto (bool): A flag indicating whether to enable auto mode.
init (bool): A flag indicating whether to enable initialization mode.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
"""
self.agent_yaml = agent_yaml
self.config_list = [
@@ -110,46 +116,45 @@ class PraisonAI:
The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
Any: Depending on the arguments provided, the function may return a result from the
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.
"""
args = self.parse_args()
if args is None:
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
invocation_cmd = "praisonai"
version_string = f"PraisonAI version {__version__}"
self.framework = args.framework or self.framework
if args.command:
if args.command.startswith("tests.test"): # Argument used for testing purposes
print("test")
else:
self.agent_file = args.command
if args.deploy:
from .deploy import CloudDeployer
deployer = CloudDeployer()
deployer.run_commands()
return
if getattr(args, 'chat', False):
self.create_chainlit_chat_interface()
return
if getattr(args, 'code', False):
self.create_code_interface()
return
if getattr(args, 'realtime', False):
self.create_realtime_interface()
return
if getattr(args, 'call', False):
call_args = []
if args.public:
call_args.append('--public')
call_module.main(call_args)
return
if args.agent_file == 'train':
if args.command == 'train':
package_root = os.path.dirname(os.path.abspath(__file__))
config_yaml_destination = os.path.join(os.getcwd(), 'config.yaml')
@@ -164,9 +169,9 @@ class PraisonAI:
}]
)
with open('config.yaml', 'w') as f:
yaml.dump(config, f, default_flow_style=False, indent=2)
yaml.dump(config, f, default_flow_style=False, indent=2)
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
if args.hf:
config["huggingface_save"] = "true"
if args.ollama:
@@ -192,97 +197,79 @@ class PraisonAI:
train_args = sys.argv[2:] # Get all arguments after 'train'
train_script_path = os.path.join(package_root, 'train.py')
# Set environment variables
env = os.environ.copy()
env['PYTHONUNBUFFERED'] = '1'
stream_subprocess(['conda', 'run', '--no-capture-output', '--name', 'praison_env', 'python', '-u', train_script_path, 'train'], env=env)
return
invocation_cmd = "praisonai"
version_string = f"PraisonAI version {__version__}"
self.framework = args.framework or self.framework
if args.agent_file:
if args.agent_file.startswith("tests.test"): # Argument used for testing purposes. eg: python -m unittest tests.test
print("test")
else:
self.agent_file = args.agent_file
if args.auto or args.init:
temp_topic = ' '.join(args.auto) if args.auto else ' '.join(args.init)
self.topic = temp_topic
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
self.topic = self.auto
if args.auto or self.auto:
temp_topic = args.auto if args.auto else self.auto
if isinstance(temp_topic, list):
temp_topic = ' '.join(temp_topic)
self.topic = temp_topic
self.agent_file = "test.yaml"
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
generator = AutoGenerator(topic=self.topic, framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
print(result)
return result
elif args.init or self.init:
temp_topic = args.init if args.init else self.init
if isinstance(temp_topic, list):
temp_topic = ' '.join(temp_topic)
self.topic = temp_topic
self.agent_file = "agents.yaml"
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
generator = AutoGenerator(topic=self.topic, framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
print("File {} created successfully".format(self.agent_file))
return "File {} created successfully".format(self.agent_file)
print(f"File {self.agent_file} created successfully")
return f"File {self.agent_file} created successfully"
if args.ui:
if args.ui == "gradio":
self.create_gradio_interface()
elif args.ui == "chainlit":
self.create_chainlit_interface()
else:
# Modify below code to allow default ui
# Modify code to allow default UI
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
tools=self.tools
)
result = agents_generator.generate_crew_and_kickoff()
print(result)
return result
else:
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
tools=self.tools
)
result = agents_generator.generate_crew_and_kickoff()
print(result)
return result
def parse_args(self):
"""
Parse the command-line arguments for the PraisonAI CLI.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
argparse.Namespace: An object containing the parsed command-line arguments.
Raises:
argparse.ArgumentError: If the arguments provided are invalid.
Example:
>>> args = praison_ai.parse_args()
>>> print(args.agent_file) # Output: 'agents.yaml'
"""
parser = argparse.ArgumentParser(prog="praisonai", description="praisonAI command-line interface")
parser.add_argument("--framework", choices=["crewai", "autogen"], help="Specify the framework")
parser.add_argument("--ui", choices=["chainlit", "gradio"], help="Specify the UI framework (gradio or chainlit).")
parser.add_argument("--auto", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Enable auto mode and pass arguments for it")
parser.add_argument("agent_file", nargs="?", help="Specify the agent file")
parser.add_argument("--deploy", action="store_true", help="Deploy the application")
parser.add_argument("--init", nargs=argparse.REMAINDER, help="Initialize agents with optional topic")
parser.add_argument("command", nargs="?", help="Command to run")
parser.add_argument("--deploy", action="store_true", help="Deploy the application")
parser.add_argument("--model", type=str, help="Model name")
parser.add_argument("--hf", type=str, help="Hugging Face model name")
parser.add_argument("--ollama", type=str, help="Ollama model name")
@@ -293,34 +280,97 @@ class PraisonAI:
args, unknown_args = parser.parse_known_args()
if unknown_args and unknown_args[0] == '-b' and unknown_args[1] == 'api:app':
args.agent_file = 'agents.yaml'
if args.agent_file == 'api:app' or args.agent_file == '/app/api:app':
args.agent_file = 'agents.yaml'
if args.agent_file == 'ui':
args.command = 'agents.yaml'
if args.command == 'api:app' or args.command == '/app/api:app':
args.command = 'agents.yaml'
if args.command == 'ui':
args.ui = 'chainlit'
if args.agent_file == 'chat':
if args.command == 'chat':
args.ui = 'chainlit'
args.chat = True
if args.agent_file == 'code':
if args.command == 'code':
args.ui = 'chainlit'
args.code = True
if args.agent_file == 'realtime':
if args.command == 'realtime':
args.realtime = True
if args.agent_file == 'call':
if args.command == 'call':
args.call = True
# Handle special commands first
special_commands = ['chat', 'code', 'call', 'realtime', 'train', 'ui']
if args.command in special_commands:
if args.command == 'chat':
if not CHAINLIT_AVAILABLE:
print("[red]ERROR: Chat UI is not installed. Install with:[/red]")
print("\npip install \"praisonai[chat]\"\n")
sys.exit(1)
try:
self.create_chainlit_chat_interface()
except ModuleNotFoundError as e:
missing_module = str(e).split("'")[1]
print(f"[red]ERROR: Missing dependency {missing_module}. Install with:[/red]")
print(f"\npip install \"praisonai[chat]\"\n")
sys.exit(1)
sys.exit(0)
elif args.command == 'code':
if not CHAINLIT_AVAILABLE:
print("[red]ERROR: Code UI is not installed. Install with:[/red]")
print("\npip install \"praisonai[code]\"\n")
sys.exit(1)
try:
self.create_code_interface()
except ModuleNotFoundError as e:
missing_module = str(e).split("'")[1]
print(f"[red]ERROR: Missing dependency {missing_module}. Install with:[/red]")
print(f"\npip install \"praisonai[code]\"\n")
sys.exit(1)
sys.exit(0)
elif args.command == 'call':
if not CALL_MODULE_AVAILABLE:
print("[red]ERROR: Call feature is not installed. Install with:[/red]")
print("\npip install \"praisonai[call]\"\n")
sys.exit(1)
call_module.main()
sys.exit(0)
elif args.command == 'realtime':
if not CHAINLIT_AVAILABLE:
print("[red]ERROR: Realtime UI is not installed. Install with:[/red]")
print("\npip install \"praisonai[realtime]\"\n")
sys.exit(1)
self.create_realtime_interface()
sys.exit(0)
elif args.command == 'train':
print("[red]ERROR: Train feature is not installed. Install with:[/red]")
print("\npip install \"praisonai[train]\"\n")
sys.exit(1)
elif args.command == 'ui':
if not CHAINLIT_AVAILABLE:
print("[red]ERROR: UI is not installed. Install with:[/red]")
print("\npip install \"praisonai[ui]\"\n")
sys.exit(1)
self.create_chainlit_interface()
sys.exit(0)
# Only check framework availability for agent-related operations
if not args.command and (args.init or args.auto or args.framework):
if not CREWAI_AVAILABLE and not AUTOGEN_AVAILABLE:
print("[red]ERROR: No framework is installed. Please install at least one framework:[/red]")
print("\npip install \"praisonai\\[crewai]\" # For CrewAI")
print("pip install \"praisonai\\[autogen]\" # For AutoGen")
print("pip install \"praisonai\\[crewai,autogen]\" # For both frameworks\n")
sys.exit(1)
return args
def create_chainlit_chat_interface(self):
"""
Create a Chainlit interface for the chat application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
"""
if CHAINLIT_AVAILABLE:
import praisonai
@@ -328,7 +378,7 @@ class PraisonAI:
root_path = os.path.join(os.path.expanduser("~"), ".praison")
os.environ["CHAINLIT_APP_ROOT"] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
if not os.path.exists(os.path.join(root_path, "public")): # Check if the folder exists in the current directory
if not os.path.exists(os.path.join(root_path, "public")):
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, "public"), dirs_exist_ok=True)
logging.info("Public folder copied successfully!")
@@ -339,18 +389,11 @@ class PraisonAI:
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'chat.py')
chainlit_run([chat_ui_path])
else:
print("ERROR: Chat UI is not installed. Please install it with 'pip install \"praisonai\[chat]\"' to use the chat UI.")
print("ERROR: Chat UI is not installed. Please install it with 'pip install \"praisonai[chat]\"' to use the chat UI.")
def create_code_interface(self):
"""
Create a Chainlit interface for the code application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
"""
if CHAINLIT_AVAILABLE:
import praisonai
@@ -358,7 +401,7 @@ class PraisonAI:
root_path = os.path.join(os.path.expanduser("~"), ".praison")
os.environ["CHAINLIT_APP_ROOT"] = root_path
public_folder = os.path.join(os.path.dirname(__file__), 'public')
if not os.path.exists(os.path.join(root_path, "public")): # Check if the folder exists in the current directory
if not os.path.exists(os.path.join(root_path, "public")):
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, "public"), dirs_exist_ok=True)
logging.info("Public folder copied successfully!")
@@ -369,46 +412,17 @@ class PraisonAI:
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'ui', 'code.py')
chainlit_run([code_ui_path])
else:
print("ERROR: Code UI is not installed. Please install it with 'pip install \"praisonai\[code]\"' to use the code UI.")
print("ERROR: Code UI is not installed. Please install it with 'pip install \"praisonai[code]\"' to use the code UI.")
def create_gradio_interface(self):
"""
Create a Gradio interface for generating agents and performing tasks.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
None: This method does not return any value. It launches the Gradio interface.
Raises:
None: This method does not raise any exceptions.
Example:
>>> praison_ai.create_gradio_interface()
"""
if GRADIO_AVAILABLE:
def generate_crew_and_kickoff_interface(auto_args, framework):
"""
Generate a crew and kick off tasks based on the provided auto arguments and framework.
Args:
auto_args (list): Topic.
framework (str): The framework to use for generating agents.
Returns:
str: A string representing the result of generating the crew and kicking off tasks.
Raises:
None: This method does not raise any exceptions.
Example:
>>> result = generate_crew_and_kickoff_interface("Create a movie about Cat in Mars", "crewai")
>>> print(result)
"""
self.framework = framework
self.agent_file = "test.yaml"
generator = AutoGenerator(topic=auto_args , framework=self.framework)
generator = AutoGenerator(topic=auto_args, framework=self.framework)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
@@ -423,25 +437,17 @@ class PraisonAI:
theme="default"
).launch()
else:
print("ERROR: Gradio is not installed. Please install it with 'pip install gradio' to use this feature.")
print("ERROR: Gradio is not installed. Please install it with 'pip install gradio' to use this feature.")
def create_chainlit_interface(self):
"""
Create a Chainlit interface for generating agents and performing tasks.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
"""
if CHAINLIT_AVAILABLE:
import praisonai
os.environ["CHAINLIT_PORT"] = "8082"
# Get the path to the 'public' folder within the package
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
if not os.path.exists("public"): # Check if the folder exists in the current directory
if not os.path.exists("public"):
if os.path.exists(public_folder):
shutil.copytree(public_folder, 'public', dirs_exist_ok=True)
logging.info("Public folder copied successfully!")
@@ -452,7 +458,7 @@ class PraisonAI:
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), 'chainlit_ui.py')
chainlit_run([chainlit_ui_path])
else:
print("ERROR: Chainlit is not installed. Please install it with 'pip install \"praisonai\[ui]\"' to use the UI.")
print("ERROR: Chainlit is not installed. Please install it with 'pip install \"praisonai[ui]\"' to use the UI.")
def create_realtime_interface(self):
"""
@@ -460,7 +466,7 @@ class PraisonAI:
"""
if CHAINLIT_AVAILABLE:
import praisonai
os.environ["CHAINLIT_PORT"] = "8088" # Ensure this port is not in use by another service
os.environ["CHAINLIT_PORT"] = "8088"
root_path = os.path.join(os.path.expanduser("~"), ".praison")
os.environ["CHAINLIT_APP_ROOT"] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), 'public')
+1 -1
View File
@@ -56,7 +56,7 @@ class CloudDeployer:
file.write("FROM python:3.11-slim\n")
file.write("WORKDIR /app\n")
file.write("COPY . .\n")
file.write("RUN pip install flask praisonai==0.1.10 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==1.0.0 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+24 -2
View File
@@ -1,2 +1,24 @@
# from .base_tool import BaseTool, Tool, tool
from .autogen_tools import *
# Only try to import autogen_tools if either CrewAI or AutoGen is available
CREWAI_AVAILABLE = False
AUTOGEN_AVAILABLE = False
PRAISONAI_TOOLS_AVAILABLE = False
try:
from crewai import Agent, Task, Crew
CREWAI_AVAILABLE = True
except ImportError:
pass
try:
import autogen
AUTOGEN_AVAILABLE = True
except ImportError:
pass
# Only try to import tools if a framework is available
if CREWAI_AVAILABLE or AUTOGEN_AVAILABLE:
try:
from .autogen_tools import *
PRAISONAI_TOOLS_AVAILABLE = True
except ImportError:
pass
+110 -202
View File
@@ -1,209 +1,117 @@
# praisonai/inbuilt_tools/autogen_tools.py
from praisonai_tools import (
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool,
FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool,
ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool,
YoutubeVideoSearchTool
)
from typing import Any
from autogen import register_function
import os
import importlib
from pathlib import Path
import os
import inspect
import sys
import logging
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'), format='%(asctime)s - %(levelname)s - %(message)s')
import inspect
def create_autogen_tool_function(tool_name):
def autogen_tool(assistant, user_proxy):
def register_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(query: str) -> Any:
tool_instance = tool_class()
return tool_instance.run(query=query)
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
# Try to import praisonai_tools, but don't fail if not available
try:
from praisonai_tools import (
CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool,
DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool,
MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool,
ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool,
YoutubeChannelSearchTool, YoutubeVideoSearchTool
)
TOOLS_AVAILABLE = True
except ImportError:
TOOLS_AVAILABLE = False
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, 'tools.py')
tools_dir_path = Path(root_directory) / 'tools'
def create_autogen_tool_function(tool_class):
"""
Create a function that wraps a tool for autogen.
Args:
tool_class: The tool class to wrap
Returns:
function: A function that can be used with autogen agents
"""
if not TOOLS_AVAILABLE:
return None
def tool_function(assistant, user_proxy):
"""
Wrapper function for the tool that works with autogen.
Args:
assistant: The autogen assistant agent
user_proxy: The autogen user proxy agent
"""
tool_instance = tool_class()
# Get the tool's run method signature
sig = inspect.signature(tool_instance.run)
param_names = list(sig.parameters.keys())
def wrapped_function(*args, **kwargs):
try:
# Map positional arguments to named parameters
named_args = dict(zip(param_names, args))
# Combine with keyword arguments
all_args = {**named_args, **kwargs}
# Run the tool
result = tool_instance.run(**all_args)
return str(result)
except Exception as e:
logging.error(f"Error running {tool_class.__name__}: {str(e)}")
return f"Error: {str(e)}"
# Add the function to the assistant's function map
assistant.register_function(
function_map={
tool_class.__name__: wrapped_function
},
name_to_args={
tool_class.__name__: {
param: "" for param in param_names
}
},
description=tool_instance.__doc__ or f"Use {tool_class.__name__} to perform operations"
)
return tool_function if TOOLS_AVAILABLE else None
if os.path.isfile(tools_py_path):
print(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
tool_module = importlib.import_module("tools")
elif tools_dir_path.is_dir():
print(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
tool_module = importlib.import_module(f"tools.{tool_name}")
else:
raise ImportError("Neither tools.py nor tools directory found in the root directory.")
# Only create tool functions if praisonai_tools is available
if TOOLS_AVAILABLE:
# Create autogen wrapper functions for each tool
autogen_CSVSearchTool = create_autogen_tool_function(CSVSearchTool)
autogen_CodeDocsSearchTool = create_autogen_tool_function(CodeDocsSearchTool)
autogen_DirectorySearchTool = create_autogen_tool_function(DirectorySearchTool)
autogen_DOCXSearchTool = create_autogen_tool_function(DOCXSearchTool)
autogen_DirectoryReadTool = create_autogen_tool_function(DirectoryReadTool)
autogen_FileReadTool = create_autogen_tool_function(FileReadTool)
autogen_TXTSearchTool = create_autogen_tool_function(TXTSearchTool)
autogen_JSONSearchTool = create_autogen_tool_function(JSONSearchTool)
autogen_MDXSearchTool = create_autogen_tool_function(MDXSearchTool)
autogen_PDFSearchTool = create_autogen_tool_function(PDFSearchTool)
autogen_RagTool = create_autogen_tool_function(RagTool)
autogen_ScrapeElementFromWebsiteTool = create_autogen_tool_function(ScrapeElementFromWebsiteTool)
autogen_ScrapeWebsiteTool = create_autogen_tool_function(ScrapeWebsiteTool)
autogen_WebsiteSearchTool = create_autogen_tool_function(WebsiteSearchTool)
autogen_XMLSearchTool = create_autogen_tool_function(XMLSearchTool)
autogen_YoutubeChannelSearchTool = create_autogen_tool_function(YoutubeChannelSearchTool)
autogen_YoutubeVideoSearchTool = create_autogen_tool_function(YoutubeVideoSearchTool)
Tool = getattr(tool_module, tool_name)
register_tool(Tool, tool_name, f"Description for {tool_name}", assistant, user_proxy)
return autogen_tool
# Load tools.py
sys.path.insert(0, os.getcwd())
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, 'tools.py')
tools_dir_path = Path(root_directory) / 'tools'
tools_module = None
if os.path.isfile(tools_py_path):
logging.info(f"{tools_py_path} exists in the root directory. Loading {tools_py_path} and skipping tools folder.")
tools_module = importlib.import_module("tools")
elif tools_dir_path.is_dir():
logging.info(f"tools folder exists in the root directory. Loading {tool_name} from tools/{tool_name}.py.")
tools_module = importlib.import_module(f"tools.{tool_name}")
# Create autogen_TOOL_NAME_HERE function for each tool
if tools_module is not None:
for name, obj in inspect.getmembers(tools_module):
if inspect.isclass(obj):
globals()[f"autogen_{name}"] = create_autogen_tool_function(name)
def autogen_CodeDocsSearchTool(assistant, user_proxy):
def register_code_docs_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(docs_url: str, search_query: str) -> Any:
tool_instance = tool_class(docs_url=docs_url, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_code_docs_search_tool(CodeDocsSearchTool, "code_docs_search_tool", "Search a Code Docs content(search_query: 'string', docs_url: 'string') - A tool that can be used to semantic search a query from a Code Docs content.", assistant, user_proxy)
def autogen_CSVSearchTool(assistant, user_proxy):
def register_csv_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(csv: str, search_query: str) -> Any:
tool_instance = tool_class(csv=csv, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_csv_search_tool(CSVSearchTool, "csv_search_tool", "Search a CSV's content(search_query: 'string', csv: 'string') - A tool that can be used to semantic search a query from a CSV's content.", assistant, user_proxy)
def autogen_DirectorySearchTool(assistant, user_proxy):
def register_directory_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(directory: str, search_query: str) -> Any:
tool_instance = tool_class(directory=directory, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_directory_search_tool(DirectorySearchTool, "directory_search_tool", "Search a directory's content(search_query: 'string', directory: 'string') - A tool that can be used to semantic search a query from a directory's content.", assistant, user_proxy)
def autogen_DOCXSearchTool(assistant, user_proxy):
def register_docx_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(docx: str, search_query: str) -> Any:
tool_instance = tool_class(docx=docx, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_docx_search_tool(DOCXSearchTool, "docx_search_tool", "Search a DOCX's content(search_query: 'string', docx: 'string') - A tool that can be used to semantic search a query from a DOCX's content.", assistant, user_proxy)
# DirectoryReadTool
def autogen_DirectoryReadTool(assistant, user_proxy):
def register_directory_read_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(directory: str) -> Any:
tool_instance = tool_class(directory=directory)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_directory_read_tool(DirectoryReadTool, "directory_read_tool", "List files in directory(directory: 'string') - A tool that can be used to recursively list a directory's content.", assistant, user_proxy)
# FileReadTool
def autogen_FileReadTool(assistant, user_proxy):
def register_file_read_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(file_path: str) -> Any:
tool_instance = tool_class(file_path=file_path)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_file_read_tool(FileReadTool, "file_read_tool", "Read a file's content(file_path: 'string') - A tool that can be used to read a file's content.", assistant, user_proxy)
# TXTSearchTool
def autogen_TXTSearchTool(assistant, user_proxy):
def register_txt_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(txt: str, search_query: str) -> Any:
tool_instance = tool_class(txt=txt, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_txt_search_tool(TXTSearchTool, "txt_search_tool", "Search a txt's content(search_query: 'string', txt: 'string') - A tool that can be used to semantic search a query from a txt's content.", assistant, user_proxy)
def autogen_JSONSearchTool(assistant, user_proxy):
def register_json_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(json_path: str, search_query: str) -> Any:
tool_instance = tool_class(json_path=json_path, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_json_search_tool(JSONSearchTool, "json_search_tool", "Search a JSON's content(search_query: 'string', json_path: 'string') - A tool that can be used to semantic search a query from a JSON's content.", assistant, user_proxy)
def autogen_MDXSearchTool(assistant, user_proxy):
def register_mdx_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(mdx: str, search_query: str) -> Any:
tool_instance = tool_class(mdx=mdx, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_mdx_search_tool(MDXSearchTool, "mdx_search_tool", "Search a MDX's content(search_query: 'string', mdx: 'string') - A tool that can be used to semantic search a query from a MDX's content.", assistant, user_proxy)
def autogen_PDFSearchTool(assistant, user_proxy):
def register_pdf_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(pdf: str, search_query: str) -> Any:
tool_instance = tool_class(pdf=pdf, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_pdf_search_tool(PDFSearchTool, "pdf_search_tool", "Search a PDF's content(search_query: 'string', pdf: 'string') - A tool that can be used to semantic search a query from a PDF's content.", assistant, user_proxy)
def autogen_RagTool(assistant, user_proxy):
def register_rag_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(query: str, data: Any) -> Any:
tool_instance = tool_class(query=query, data=data)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_rag_tool(RagTool, "rag_tool", "Knowledge base(query: 'string', data: Any) - A knowledge base that can be used to answer questions.", assistant, user_proxy)
def autogen_ScrapeElementFromWebsiteTool(assistant, user_proxy):
def register_scrape_element_from_website_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(website_url: str, element_query: str) -> Any:
tool_instance = tool_class(website_url=website_url, element_query=element_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_scrape_element_from_website_tool(ScrapeElementFromWebsiteTool, "scrape_element_from_website_tool", "Scrape an element from a website(element_query: 'string', website_url: 'string') - A tool that can be used to scrape an element from a website.", assistant, user_proxy)
def autogen_ScrapeWebsiteTool(assistant, user_proxy):
def register_scrape_website_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(website_url: str) -> Any:
tool_instance = tool_class(website_url=website_url)
content = tool_instance.run()
# Ensure content is properly decoded as UTF-8 if it's a bytes object
if isinstance(content, bytes):
content = content.decode('utf-8')
return content
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_scrape_website_tool(ScrapeWebsiteTool, "scrape_website_tool", "Read website content(website_url: 'string') - A tool that can be used to read content from a specified website.", assistant, user_proxy)
def autogen_WebsiteSearchTool(assistant, user_proxy):
def register_website_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(website: str, search_query: str) -> Any:
tool_instance = tool_class(website=website, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_website_search_tool(WebsiteSearchTool, "website_search_tool", "Search in a specific website(search_query: 'string', website: 'string') - A tool that can be used to semantic search a query from a specific URL content.", assistant, user_proxy)
def autogen_XMLSearchTool(assistant, user_proxy):
def register_xml_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(xml: str, search_query: str) -> Any:
tool_instance = tool_class(xml=xml, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_xml_search_tool(XMLSearchTool, "xml_search_tool", "Search a XML's content(search_query: 'string', xml: 'string') - A tool that can be used to semantic search a query from a XML's content.", assistant, user_proxy)
def autogen_YoutubeChannelSearchTool(assistant, user_proxy):
def register_youtube_channel_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(youtube_channel_handle: str, search_query: str) -> Any:
tool_instance = tool_class(youtube_channel_handle=youtube_channel_handle, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_youtube_channel_search_tool(YoutubeChannelSearchTool, "youtube_channel_search_tool", "Search a Youtube Channels content(search_query: 'string', youtube_channel_handle: 'string') - A tool that can be used to semantic search a query from a Youtube Channels content.", assistant, user_proxy)
def autogen_YoutubeVideoSearchTool(assistant, user_proxy):
def register_youtube_video_search_tool(tool_class, tool_name, tool_description, assistant, user_proxy):
def tool_func(youtube_video_url: str, search_query: str) -> Any:
tool_instance = tool_class(youtube_video_url=youtube_video_url, search_query=search_query)
return tool_instance.run()
register_function(tool_func, caller=assistant, executor=user_proxy, name=tool_name, description=tool_description)
register_youtube_video_search_tool(YoutubeVideoSearchTool, "youtube_video_search_tool", "Search a Youtube Video content(search_query: 'string', youtube_video_url: 'string') - A tool that can be used to semantic search a query from a Youtube Video content.", assistant, user_proxy)
# Export all tool functions
__all__ = [
'autogen_CSVSearchTool',
'autogen_CodeDocsSearchTool',
'autogen_DirectorySearchTool',
'autogen_DOCXSearchTool',
'autogen_DirectoryReadTool',
'autogen_FileReadTool',
'autogen_TXTSearchTool',
'autogen_JSONSearchTool',
'autogen_MDXSearchTool',
'autogen_PDFSearchTool',
'autogen_RagTool',
'autogen_ScrapeElementFromWebsiteTool',
'autogen_ScrapeWebsiteTool',
'autogen_WebsiteSearchTool',
'autogen_XMLSearchTool',
'autogen_YoutubeChannelSearchTool',
'autogen_YoutubeVideoSearchTool',
]
else:
# If tools are not available, export an empty list
__all__ = []
+16
View File
@@ -0,0 +1,16 @@
from setuptools import setup
from setuptools.command.install import install
import subprocess
import sys
class PostInstallCommand(install):
def run(self):
install.run(self)
# Install Playwright browsers
subprocess.check_call([sys.executable, '-m', 'playwright', 'install'])
setup(
cmdclass={
'install': PostInstallCommand,
}
)
+17 -14
View File
@@ -1,20 +1,23 @@
import subprocess
import sys
import os
import sys
import subprocess
import logging
def install_playwright():
"""Install playwright browsers."""
try:
subprocess.run([sys.executable, "-m", "playwright", "install"], check=True)
logging.info("Playwright browsers installed successfully")
except subprocess.CalledProcessError as e:
logging.error(f"Failed to install playwright browsers: {e}")
except Exception as e:
logging.error(f"Unexpected error installing playwright browsers: {e}")
def main():
try:
# Get the absolute path of the current file
current_file = os.path.abspath(__file__)
# Get the directory of the current file
script_dir = os.path.dirname(current_file)
# Construct the path to setup_conda_env.py
setup_script = os.path.join(script_dir, 'setup_conda_env.py')
except subprocess.CalledProcessError as e:
print(f"Error occurred while running the setup script: {e}")
sys.exit(1)
"""Post-installation script."""
# Check if this is a chat or code installation
if any(extra in sys.argv for extra in ['chat', 'code']):
install_playwright()
if __name__ == "__main__":
main()
+27 -31
View File
@@ -15,7 +15,7 @@ import logging
import json
from sql_alchemy import SQLAlchemyDataLayer
from tavily import TavilyClient
from crawl4ai import WebCrawler
from crawl4ai import AsyncWebCrawler
import asyncio
from PIL import Image
import io
@@ -181,8 +181,8 @@ cl_data._data_layer = SQLAlchemyDataLayer(conninfo=f"sqlite+aiosqlite:///{DB_PAT
tavily_api_key = os.getenv("TAVILY_API_KEY")
tavily_client = TavilyClient(api_key=tavily_api_key) if tavily_api_key else None
# Modify the tavily_web_search function to be synchronous
def tavily_web_search(query):
# Modify the tavily_web_search function to be async
async def tavily_web_search(query):
if not tavily_client:
return json.dumps({
"query": query,
@@ -192,32 +192,28 @@ def tavily_web_search(query):
response = tavily_client.search(query)
logger.debug(f"Tavily search response: {response}")
# Create an instance of WebCrawler
crawler = WebCrawler()
# Warm up the crawler (load necessary models)
crawler.warmup()
# Prepare the results
results = []
for result in response.get('results', []):
url = result.get('url')
if url:
try:
# Run the crawler on each URL
crawl_result = crawler.run(url=url)
results.append({
"content": result.get('content'),
"url": url,
"full_content": crawl_result.markdown
})
except Exception as e:
logger.error(f"Error crawling {url}: {str(e)}")
results.append({
"content": result.get('content'),
"url": url,
"full_content": "Error: Unable to crawl this URL"
})
# Create an instance of AsyncWebCrawler
async with AsyncWebCrawler() as crawler:
# Prepare the results
results = []
for result in response.get('results', []):
url = result.get('url')
if url:
try:
# Run the crawler asynchronously on each URL
crawl_result = await crawler.arun(url=url)
results.append({
"content": result.get('content'),
"url": url,
"full_content": crawl_result.markdown
})
except Exception as e:
logger.error(f"Error crawling {url}: {str(e)}")
results.append({
"content": result.get('content'),
"url": url,
"full_content": "Error: Unable to crawl this URL"
})
return json.dumps({
"query": query,
@@ -414,8 +410,8 @@ User Question: {message.content}
if function_args:
try:
function_args = json.loads(function_args)
# Call the function synchronously
function_response = function_to_call(
# Call the function asynchronously
function_response = await function_to_call(
query=function_args.get("query"),
)
messages.append(
+26 -29
View File
@@ -17,7 +17,7 @@ from sql_alchemy import SQLAlchemyDataLayer
from context import ContextGatherer
from tavily import TavilyClient
from datetime import datetime
from crawl4ai import WebCrawler
from crawl4ai import AsyncWebCrawler
from PIL import Image
import io
import base64
@@ -244,7 +244,7 @@ tavily_api_key = os.getenv("TAVILY_API_KEY")
tavily_client = TavilyClient(api_key=tavily_api_key) if tavily_api_key else None
# Function to call Tavily Search API and crawl the results
def tavily_web_search(query):
async def tavily_web_search(query):
if not tavily_client:
return json.dumps({
"query": query,
@@ -254,32 +254,28 @@ def tavily_web_search(query):
response = tavily_client.search(query)
logger.debug(f"Tavily search response: {response}")
# Create an instance of WebCrawler
crawler = WebCrawler()
# Warm up the crawler (load necessary models)
crawler.warmup()
# Prepare the results
results = []
for result in response.get('results', []):
url = result.get('url')
if url:
try:
# Run the crawler on each URL
crawl_result = crawler.run(url=url)
results.append({
"content": result.get('content'),
"url": url,
"full_content": crawl_result.markdown
})
except Exception as e:
logger.error(f"Error crawling {url}: {str(e)}")
results.append({
"content": result.get('content'),
"url": url,
"full_content": "Error: Unable to crawl this URL"
})
# Create an instance of AsyncWebCrawler
async with AsyncWebCrawler() as crawler:
# Prepare the results
results = []
for result in response.get('results', []):
url = result.get('url')
if url:
try:
# Run the crawler asynchronously on each URL
crawl_result = await crawler.arun(url=url)
results.append({
"content": result.get('content'),
"url": url,
"full_content": crawl_result.markdown
})
except Exception as e:
logger.error(f"Error crawling {url}: {str(e)}")
results.append({
"content": result.get('content'),
"url": url,
"full_content": "Error: Unable to crawl this URL"
})
return json.dumps({
"query": query,
@@ -433,7 +429,8 @@ Context:
if function_args:
try:
function_args = json.loads(function_args)
function_response = function_to_call(
# Call the function asynchronously
function_response = await function_to_call(
query=function_args.get("query"),
)
messages.append(
+44 -10
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "PraisonAI"
version = "0.1.10"
version = "1.0.0"
description = "PraisonAI application combines AutoGen and CrewAI or similar frameworks into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customization, and efficient human-agent collaboration."
authors = ["Mervin Praison"]
license = ""
@@ -16,11 +16,13 @@ packages = ["PraisonAI"]
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
rich = ">=13.7"
pyautogen = ">=0.2.19"
crewai = ">=0.32.0"
markdown = ">=3.5"
praisonai-tools = ">=0.0.7"
pyparsing = ">=3.0.0"
python-dotenv = {version = ">=0.19.0"}
instructor = ">=0.4.8"
pyautogen = {version = ">=0.2.19", optional = true}
crewai = {version = ">=0.32.0", optional = true}
praisonai-tools = {version = ">=0.0.7", optional = true}
chainlit = {version = "==1.3.0rc1", optional = true}
gradio = {version = ">=4.26.0", optional = true}
flask = {version = ">=3.0.0", optional = true}
@@ -41,9 +43,10 @@ duckduckgo_search = {version = ">=6.3.0", optional = true}
twilio = {version = ">=7.0.0", optional = true}
fastapi = {version = ">=0.95.0", optional = true}
uvicorn = {version = ">=0.20.0", optional = true}
python-dotenv = {version = ">=0.19.0", optional = true}
flaml = {version = ">=2.3.1", extras = ["automl"], optional = true}
pyngrok = {version = ">=1.4.0", optional = true}
sqlalchemy = {version = ">=2.0.36", optional = true}
playwright = {version = ">=1.47.0", optional = true}
[tool.poetry.group.docs.dependencies]
mkdocs = "*"
@@ -95,14 +98,13 @@ aiosqlite = ">=0.20.0"
greenlet = ">=3.0.3"
[build-system]
requires = ["poetry-core"]
requires = ["poetry-core", "setuptools>=42"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
praisonai = "praisonai.__main__:main"
setup-conda-env = "setup.setup_conda_env:main"
post-install = "setup.post_install:main"
praisonai-call = "praisonai.api.call:main"
[tool.poetry.extras]
@@ -114,11 +116,43 @@ google = ["langchain-google-genai"]
openai = ["langchain-openai"]
anthropic = ["langchain-anthropic"]
cohere = ["langchain-cohere"]
chat = ["chainlit", "litellm", "aiosqlite", "greenlet", "tavily-python", "crawl4ai"]
code = ["chainlit", "litellm", "aiosqlite", "greenlet", "tavily-python", "crawl4ai"]
chat = [
"chainlit",
"litellm",
"aiosqlite",
"greenlet",
"tavily-python",
"crawl4ai",
"sqlalchemy",
"playwright"
]
code = [
"chainlit",
"litellm",
"aiosqlite",
"greenlet",
"tavily-python",
"crawl4ai",
"sqlalchemy",
"playwright"
]
train = ["setup-conda-env"]
realtime = ["chainlit", "litellm", "aiosqlite", "greenlet", "tavily-python", "crawl4ai", "websockets", "plotly", "yfinance", "duckduckgo_search"]
realtime = [
"chainlit",
"litellm",
"aiosqlite",
"greenlet",
"tavily-python",
"crawl4ai",
"websockets",
"plotly",
"yfinance",
"duckduckgo_search",
"sqlalchemy"
]
call = ["twilio", "fastapi", "uvicorn", "websockets", "python-dotenv", "flaml", "pyngrok", "rich"]
crewai = ["crewai", "praisonai-tools", "instructor"]
autogen = ["pyautogen", "praisonai-tools", "instructor", "crewai"]
[tool.poetry-dynamic-versioning]
enable = true
+12 -16
View File
@@ -1,4 +1,15 @@
# # tools.py
# tools.py
# from duckduckgo_search import DDGS
# from praisonai_tools import BaseTool
# class InternetSearchTool(BaseTool):
# name: str = "InternetSearchTool"
# description: str = "Search Internet for relevant information based on a query or latest news"
# def _run(self, query: str):
# ddgs = DDGS()
# results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
# return results
# from google.oauth2.credentials import Credentials
# from googleapiclient.discovery import build
@@ -216,21 +227,6 @@
# delete_calendar_event,
# ]
# from duckduckgo_search import DDGS
# from praisonai_tools import BaseTool
# class InternetSearchTool(BaseTool):
# name: str = "InternetSearchTool"
# description: str = "Search Internet for relevant information based on a query or latest news"
# def _run(self, query: str):
# ddgs = DDGS()
# results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
# return results
# # Add this to the imports at the top of the file if not already present
# from datetime import datetime