Compare commits

...
31 Commits
Author SHA1 Message Date
Mervin Praison faa014b8b0 Merge pull request #333 from MervinPraison/develop
2.0.59
2025-01-24 17:17:53 +00:00
MervinPraison 6d454d0c6e Update PraisonAI to version 2.0.59 and enhance dependencies
- Bumped PraisonAI version from 2.0.58 to 2.0.59 in `Dockerfile`, `pyproject.toml`, and `uv.lock` to reflect the latest updates.
- Updated the `praisonaiagents` dependency version from `0.0.53` to `0.0.56` across relevant files for improved functionality.
- Modified agent task descriptions in `repetitive-agents.py` to clarify expected outputs.
- Enhanced the `process.py` file to improve task handling and expected output management.

These changes aim to refine the PraisonAI framework's capabilities and ensure compatibility with the latest dependencies.
2025-01-24 17:17:32 +00:00
MervinPraison 0ec3fe3510 Add new agent scripts and update version to 0.0.55
- Introduced three new Python scripts: `deepseek-reasoning-output-tokens.py`, `llm-deepseek-reasoning-steps.py`, and `llm-langchain-toolcall.py` to enhance reasoning capabilities and multi-source information retrieval.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.55.
- Enhanced `wikipedia-agent.py` to utilize the new `gpt-4o-mini` model for improved performance.
- Improved `agent.py` to support tool calls in chat completions, refining the overall functionality of the agent framework.

These changes aim to expand the capabilities of the PraisonAI framework by integrating new reasoning features and improving user experience with updated versioning.
2025-01-24 13:04:34 +00:00
MervinPraison 707888cdf9 Remove deprecated agent scripts and update version to 0.0.54
- Deleted `any-llm-agents.py` and `any-llm-agents-advanced.py` scripts to streamline the agent framework.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.54.
- Enhanced `agent.py` and `llm.py` to improve handling of reasoning steps by ensuring `reasoning_steps` is properly managed in API calls.

These changes aim to simplify the agent framework and improve the overall functionality of the PraisonAI system.
2025-01-24 10:35:42 +00:00
Mervin Praison 42051630bc Merge pull request #331 from MervinPraison/develop
Develop
2025-01-23 17:19:08 +00:00
MervinPraison bfcccb6355 Update PraisonAI to version 2.0.58 and enhance reasoning capabilities
- Bumped PraisonAI version from 2.0.57 to 2.0.58 in `Dockerfile`, `pyproject.toml`, and `uv.lock` to reflect the latest updates.
- Updated the `praisonaiagents` dependency version from `0.0.50` to `0.0.53` across relevant files for improved functionality.
- Enhanced reasoning features by modifying agent initialization parameters to use `reasoning_steps` instead of `show_reasoning`, improving clarity in agent behavior.
- Introduced a new script `deepseek-reasoning-multi-agents.py` for multi-agent reasoning tasks, showcasing the integration of reasoning agents.
- Added documentation for new reasoning features, including a detailed guide on creating reasoning extract agents.

These changes aim to refine the reasoning capabilities and improve the overall user experience within the PraisonAI framework.
2025-01-23 17:18:54 +00:00
MervinPraison e329afc394 Refactor reasoning capabilities and update version to 0.0.52
- Removed the `any-llm-think.py` script to streamline the agent framework.
- Enhanced `deepseek-reasoning-agents.py` to include reasoning display options and updated the method for starting agents.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.52.
- Improved `agent.py` and `llm.py` to support reasoning content in both synchronous and asynchronous calls, enhancing the overall functionality of the agent framework.

These changes aim to refine the reasoning features and improve the user experience within the PraisonAI framework.
2025-01-23 13:52:58 +00:00
MervinPraison 9417cc6457 Add new reasoning agents and update version to 0.0.51
- Introduced three new Python scripts: `any-llm-think.py`, `deepseek-reasoning-agents.py`, and `deepseek-think.py` for enhanced reasoning capabilities using the `deepseek-reasoner` model.
- Updated `pyproject.toml` and `uv.lock` to reflect the new version 0.0.51.
- Enhanced the `agent.py` file with new data classes and methods to support reasoning content in chat completions, improving the overall functionality of the agent framework.

These changes aim to expand the capabilities of the PraisonAI framework by integrating reasoning features and improving the user experience with updated versioning.
2025-01-23 10:52:15 +00:00
Mervin Praison 10a3d279ae Merge pull request #329 from MervinPraison/develop
Update index.mdx description to enhance clarity and detail
2025-01-23 06:40:49 +00:00
MervinPraison 2a916208e1 Update index.mdx description to enhance clarity and detail
- Revised the description of PraisonAI to emphasize its capabilities as a production-ready Multi-AI Agents framework with self-reflection.
- Highlighted the integration of PraisonAI Agents, AutoGen, and CrewAI as a low-code solution for automating tasks and solving complex challenges.
- Focused on the framework's strengths in simplicity, customization, and effective human-agent collaboration.

These changes aim to provide users with a clearer understanding of PraisonAI's functionalities and benefits.
2025-01-23 06:40:23 +00:00
Mervin Praison bcd0bbbd24 Merge pull request #328 from MervinPraison/develop
Refactor documentation for agent setup and usage
2025-01-23 06:38:06 +00:00
MervinPraison 5701a40f11 Refactor documentation for agent setup and usage
- Updated the introduction.mdx file to streamline the steps for installing the PraisonAI package and configuring the environment.
- Revised agent creation examples to simplify the process for both single and multiple agents, enhancing clarity and usability.
- Added a new section for creating an `agents.yaml` configuration file for no-code users, including automatic generation instructions.
- Improved the overall structure and readability of the documentation to facilitate a better user experience.

These changes aim to provide clearer guidance for users in setting up and utilizing the PraisonAI framework effectively.
2025-01-23 06:37:49 +00:00
Mervin Praison 3ffac395bb Merge pull request #327 from MervinPraison/develop
Update README and documentation with new video tutorials
2025-01-23 06:34:56 +00:00
MervinPraison 37119aa3ac Update README and documentation with new video tutorials
- Removed the License section from README.md to streamline content.
- Added a comprehensive list of video tutorials to docs/index.mdx, covering various AI agent functionalities such as self-reflection, reasoning, and multimodal capabilities.
- Enhanced the documentation's educational resources, providing users with visual aids to better understand the Praison AI framework.

These changes aim to improve user engagement and learning through accessible video content.
2025-01-23 06:34:36 +00:00
Mervin Praison 8b2d324d3b Merge pull request #326 from MervinPraison/develop
Enhance README with new AI agent video resources
2025-01-23 06:30:01 +00:00
MervinPraison 6d0b29e60d Enhance README with new AI agent video resources
- Added multiple new video links to the README.md, showcasing various AI agent functionalities including self-reflection, reasoning, multimodal capabilities, and more.
- Improved the documentation's educational value by providing visual resources for users to better understand the Praison AI framework.

These changes aim to enrich the user experience by offering accessible learning materials related to AI agents.
2025-01-23 06:29:44 +00:00
Mervin Praison 583cbc5efa Merge pull request #325 from MervinPraison/develop
Update documentation and examples for agent initialization and usage
2025-01-23 06:21:43 +00:00
MervinPraison 90dd84a152 Update documentation and examples for agent initialization and usage
- Revised the README.md to reflect the updated method for starting agents, changing `agent.chat` to `agent.start` for clarity and accuracy.
- Added a new section in the README.md for creating an `agents.yaml` file, enhancing the setup instructions for users.
- Updated the installation instructions in `docs/index.mdx` to clarify package names and improve the overall structure of the documentation.
- Streamlined code examples in `docs/concepts/agents.mdx` to focus on single and multiple agent initialization, ensuring users have clear and concise guidance.

These changes improve the clarity and usability of the documentation, making it easier for users to understand and implement the PraisonAI framework.
2025-01-23 06:21:25 +00:00
Mervin Praison ef7fa66e33 Merge pull request #324 from MervinPraison/develop
Update PraisonAI to version 2.0.57 and enhance documentation
2025-01-23 06:06:43 +00:00
MervinPraison 1659ed61bc Update PraisonAI to version 2.0.57 and enhance documentation
- Bumped PraisonAI version from 2.0.56 to 2.0.57 in `Dockerfile`, `pyproject.toml`, and `uv.lock` to reflect the latest updates.
- Updated the `praisonaiagents` dependency version from `0.0.49` to `0.0.50` across relevant files for improved functionality.
- Added a new `docker-compose.yml` file and multiple Dockerfiles for different services (UI, chat, development) to streamline deployment.
- Enhanced the README.md with new sections on AI agents flow, tools, memory, and various processing types, improving clarity and usability.
- Introduced a new test script `cl-test.py` for validating chat functionalities with the Gemini API.

These changes improve the overall functionality, usability, and deployment processes of the PraisonAI framework.
2025-01-23 06:06:23 +00:00
Mervin Praison b8939ef439 Merge pull request #323 from MervinPraison/develop
adding chat with pdf
2025-01-22 18:37:48 +00:00
MervinPraison 4bada9e5fc adding chat with pdf 2025-01-22 18:37:27 +00:00
Mervin Praison 51c4cb00b0 Merge pull request #322 from MervinPraison/develop
updating docs
2025-01-22 18:32:20 +00:00
MervinPraison ad96549ea3 updating docs 2025-01-22 18:32:03 +00:00
Mervin Praison 183d10d7cc Merge pull request #321 from MervinPraison/develop
Develop
2025-01-22 18:29:04 +00:00
MervinPraison bce1559ab5 docs update 2025-01-22 18:28:46 +00:00
MervinPraison 6f3fb87ba3 Update README and local development documentation for improved clarity and logging instructions
- Revised section headings in README.md to number the agent categories for better organization.
- Added logging configuration instructions to the local-development.mdx file, detailing how to set log levels for both standard and advanced logging.
- Removed outdated logging instructions from README.md to streamline the documentation.

These changes enhance the clarity of the documentation and provide users with essential logging setup information for local development.
2025-01-22 18:24:24 +00:00
Mervin Praison e7f6b2df67 Merge pull request #320 from MervinPraison/develop
Update README and agent initialization for enhanced clarity and funct…
2025-01-22 18:07:29 +00:00
MervinPraison 08d72eeb80 Update README and agent initialization for enhanced clarity and functionality
- Revised the README.md to better describe PraisonAI as a production-ready Multi-AI Agents framework, emphasizing its capabilities in automating tasks and problem-solving.
- Updated the list of features to include new agent types and functionalities, such as Code Interpreter Agents and Async & Parallel Processing.
- Simplified the agent initialization examples in the README, providing clearer instructions for users to create and run agents.
- Modified the agent client initialization in main.py to handle missing API keys more gracefully.
- Added "developers/local-development" to mint.json for improved documentation structure.

These changes enhance the user experience by providing clearer documentation and improving the robustness of agent initialization.
2025-01-22 18:07:15 +00:00
Mervin Praison 11aefae90f Merge pull request #319 from MervinPraison/develop
Enhance Streamlit UIs and Add New Model Integrations
2025-01-22 13:07:45 +00:00
MervinPraison 10d5158d27 Enhance Streamlit UIs and Add New Model Integrations
- Updated `mint.json` to include new Streamlit UIs for Deepseek, Gemini, and Ollama models, improving model accessibility.
- Expanded documentation in `models.mdx` and `google.mdx` to provide detailed setup instructions for integrating OpenAI, Litellm, and Gemini models.
- Introduced new example scripts for Gemini and Ollama Streamlit applications, showcasing interactive chat capabilities.
- Added comprehensive features and prerequisites sections in the new UI documentation to guide users in setting up their environments.

These changes enhance the usability and functionality of the PraisonAI framework, particularly in model integration and user interface development.
2025-01-22 13:07:31 +00:00
51 changed files with 3288 additions and 1037 deletions

No files matched your search

+434 -443
View File
@@ -20,7 +20,7 @@
</div>
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.
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AutoGen, and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
<div align="center">
<a href="https://docs.praison.ai">
@@ -37,35 +37,24 @@ PraisonAI is an AI Agents Framework with Self Reflection. PraisonAI application
- 🧠 Reasoning AI Agents
- 👁️ Multi Modal AI Agents
- 🤝 Multi Agent Collaboration
- ⚡ AI Agent Workflow
- 🔄 Use CrewAI or AutoGen Framework
- 🎭 AI Agent Workflow
- 📚 Add Custom Knowledge
- 🧠 Agents with Short and Long Term Memory
- 📄 Chat with PDF Agents
- 💻 Code Interpreter Agents
- 📚 RAG Agents
- 🤔 Async & Parallel Processing
- 🔄 Auto Agents
- 🔢 Math Agents
- 🎯 Structured Output Agents
- 🔗 LangChain Integrated Agents
- 📞 Callback Agents
- 🤏 Mini AI Agents
- 🛠️ 100+ Custom Tools
- 📄 YAML Configuration
- 💯 100+ LLM Support
- 💻 Chat with ENTIRE Codebase
- 🎨 Interactive UIs
- 📄 YAML-based Configuration
- 🛠️ Custom Tool Integration
- 🔍 Internet Search Capability (using Crawl4AI and Tavily)
- 🖼️ Vision Language Model (VLM) Support
- 🎙️ Real-time Voice Interaction
## Using No Code
### Auto Mode:
```bash
pip install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
praisonai --auto create a movie script about Robots in Mars
```
### Initialise Mode:
```bash
pip install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
praisonai --init create a movie script about Robots in Mars
praisonai
```
## Using Coding
## Using Code
Light weight package dedicated for coding:
```bash
@@ -76,58 +65,13 @@ pip install praisonaiagents
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
### 1. Single Agent
Create app.py file and add the code below:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# 1. Create agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI and data science",
backstory="""You are an expert at a technology research group,
skilled in identifying trends and analyzing complex data.""",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="""You are a content strategist known for
making complex tech topics interesting and easy to understand.""",
llm="gpt-4o",
markdown=True
)
# 2. Define Tasks
task1 = Task(
name="research_task",
description="""Analyze 2024's AI advancements.
Find major trends, new technologies, and their effects.""",
expected_output="""A detailed report on 2024 AI advancements""",
agent=researcher
)
task2 = Task(
name="writing_task",
description="""Create a blog post about major AI advancements using the insights you have.
Make it interesting, clear, and suited for tech enthusiasts.
It should be at least 4 paragraphs long.""",
expected_output="A blog post of at least 4 paragraphs",
agent=writer,
)
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
from praisonaiagents import Agent
agent = Agent(instructions="Your are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
Run:
@@ -135,6 +79,381 @@ Run:
python app.py
```
### 2. Multi Agents
Create app.py file and add the code below:
```python
from praisonaiagents import Agent, PraisonAIAgents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
Run:
```bash
python app.py
```
## Using No Code
### Auto Mode:
```bash
pip install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
praisonai --auto create a movie script about Robots in Mars
```
## AI Agents Flow
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## AI Agents with Tools
Create AI agents that can use tools to interact with external systems and perform actions.
```mermaid
flowchart TB
subgraph Tools
direction TB
T3[Internet Search]
T1[Code Execution]
T2[Formatting]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
T3 --> A1
T1 --> A2
T2 --> A3
style Tools fill:#189AB4,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Memory
Create AI agents with memory capabilities for maintaining context and information across tasks.
```mermaid
flowchart TB
subgraph Memory
direction TB
STM[Short Term]
LTM[Long Term]
end
subgraph Store
direction TB
DB[(Vector DB)]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
Memory <--> Store
Store <--> A1
Store <--> A2
Store <--> A3
style Memory fill:#189AB4,color:#fff
style Store fill:#2E8B57,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Different Processes
### Sequential Process
The simplest form of task execution where tasks are performed one after another.
```mermaid
graph LR
Input[Input] --> A1
subgraph Agents
direction LR
A1[Agent 1] --> A2[Agent 2] --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class A1,A2,A3 process
class Agents transparent
```
### Hierarchical Process
Uses a manager agent to coordinate task execution and agent assignments.
```mermaid
graph TB
Input[Input] --> Manager
subgraph Agents
Manager[Manager Agent]
subgraph Workers
direction LR
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
end
Manager --> W1
Manager --> W2
Manager --> W3
end
W1 --> Manager
W2 --> Manager
W3 --> Manager
Manager --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Manager,W1,W2,W3 process
class Agents,Workers transparent
```
### Workflow Process
Advanced process type supporting complex task relationships and conditional execution.
```mermaid
graph LR
Input[Input] --> Start
subgraph Workflow
direction LR
Start[Start] --> C1{Condition}
C1 --> |Yes| A1[Agent 1]
C1 --> |No| A2[Agent 2]
A1 --> Join
A2 --> Join
Join --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef decision fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Start,A1,A2,A3,Join process
class C1 decision
class Workflow transparent
```
#### Agentic Routing Workflow
Create AI agents that can dynamically route tasks to specialized LLM instances.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Out[Out]
LLM2 --> Out
LLM3 --> Out
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Orchestrator Worker
Create AI agents that orchestrate and distribute tasks among specialized workers.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Synthesizer[Synthesizer]
LLM2 --> Synthesizer
LLM3 --> Synthesizer
Synthesizer --> Out[Out]
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Autonomous Workflow
Create AI agents that can autonomously monitor, act, and adapt based on environment feedback.
```mermaid
flowchart LR
Human[Human] <--> LLM[LLM Call]
LLM -->|ACTION| Environment[Environment]
Environment -->|FEEDBACK| LLM
LLM --> Stop[Stop]
style Human fill:#8B0000,color:#fff
style LLM fill:#2E8B57,color:#fff
style Environment fill:#8B0000,color:#fff
style Stop fill:#333,color:#fff
```
#### Agentic Parallelization
Create AI agents that can execute tasks in parallel for improved performance.
```mermaid
flowchart LR
In[In] --> LLM2[LLM Call 2]
In --> LLM1[LLM Call 1]
In --> LLM3[LLM Call 3]
LLM1 --> Aggregator[Aggregator]
LLM2 --> Aggregator
LLM3 --> Aggregator
Aggregator --> Out[Out]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Aggregator fill:#fff,color:#000
style Out fill:#8B0000,color:#fff
```
#### Agentic Prompt Chaining
Create AI agents with sequential prompt chaining for complex workflows.
```mermaid
flowchart LR
In[In] --> LLM1[LLM Call 1] --> Gate{Gate}
Gate -->|Pass| LLM2[LLM Call 2] -->|Output 2| LLM3[LLM Call 3] --> Out[Out]
Gate -->|Fail| Exit[Exit]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
style Exit fill:#8B0000,color:#fff
```
#### Agentic Evaluator Optimizer
Create AI agents that can generate and optimize solutions through iterative feedback.
```mermaid
flowchart LR
In[In] --> Generator[LLM Call Generator]
Generator -->|SOLUTION| Evaluator[LLM Call Evaluator] -->|ACCEPTED| Out[Out]
Evaluator -->|REJECTED + FEEDBACK| Generator
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Evaluator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Repetitive Agents
Create AI agents that can efficiently handle repetitive tasks through automated loops.
```mermaid
flowchart LR
In[Input] --> LoopAgent[("Looping Agent")]
LoopAgent --> Task[Task]
Task --> |Next iteration| LoopAgent
Task --> |Done| Out[Output]
style In fill:#8B0000,color:#fff
style LoopAgent fill:#2E8B57,color:#fff,shape:circle
style Task fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
## Adding Models
<div align="center">
<a href="https://docs.praison.ai/models">
<p align="center">
<img src="https://img.shields.io/badge/%F0%9F%93%9A_Models-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Models" />
</p>
</a>
</div>
## Ollama Integration
```bash
export OPENAI_BASE_URL=http://localhost:11434/v1
@@ -147,267 +466,16 @@ export OPENAI_API_KEY=xxxxxxxxxxx
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
```
## Logging
```bash
export LOGLEVEL=info
```
Advanced logging:
```bash
export LOGLEVEL=debug
```
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/images/architecture-dark.png" />
<source media="(prefers-color-scheme: light)" srcset="docs/images/architecture-light.png" />
<img alt="PraisonAI Architecture" src="docs/images/architecture-light.png" />
</picture>
</div>
## Different User Interfaces:
| Interface | Description | URL |
|---|---|---|
| **UI** | Multi Agents such as CrewAI or AutoGen | [https://docs.praison.ai/ui/ui](https://docs.praison.ai/ui/ui) |
| **Chat** | Chat with 100+ LLMs, single AI Agent | [https://docs.praison.ai/ui/chat](https://docs.praison.ai/ui/chat) |
| **Code** | Chat with entire Codebase, single AI Agent | [https://docs.praison.ai/ui/code](https://docs.praison.ai/ui/code) |
| **Realtime** | Real-time voice interaction with AI | [https://docs.praison.ai/ui/realtime](https://docs.praison.ai/ui/realtime) |
| Other Features | Description | Docs |
|---|---|---|
| **Train** | Fine-tune LLMs using your custom data | [https://docs.praison.ai/train](https://docs.praison.ai/train) |
## Google Colab Multi Agents
| | Cookbook | Open in Colab |
| ------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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> |
## Installation Options
### Using pip
```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
## TL;DR Multi Agents
```bash
pip install praisonai
export OPENAI_API_KEY="Enter your API key"
praisonai --init create a movie script about dog in moon
praisonai
```
## Table of Contents
- [Installation](#installation)
- [Initialise](#initialise)
- [Run](#run)
- [Full Automatic Mode](#full-automatic-mode)
- [User Interface](#user-interface)
- [Praison AI Chat](#praison-ai-chat)
- [Create Custom Tools](#create-custom-tools)
- [Agents Playbook](#agents-playbook)
- [Include praisonai package in your project](#include-praisonai-package-in-your-project)
- [Commands to Install Dev Dependencies](#commands-to-install-dependencies)
- [Other Models](#other-models)
- [Contributing](#contributing)
- [Star History](#star-history)
## Installation Multi Agents
```bash
pip install praisonai
```
## Initialise
```bash
export OPENAI_API_KEY="Enter your API key"
```
Generate your OPENAI API KEY from here: https://platform.openai.com/api-keys
Note: You can use other providers such as Ollama, Mistral ... etc. Details are provided at the bottom.
```bash
praisonai --init create a movie script about dog in moon
```
This will automatically create agents.yaml file in the current directory.
### To initialise with a specific agent framework (Optional):
```bash
praisonai --framework autogen --init create movie script about cat in mars
```
## Run
```bash
praisonai
```
or
```bash
python -m praisonai
```
### Specify the agent framework (Optional):
```bash
praisonai --framework autogen
```
### Full Automatic Mode
```bash
praisonai --auto create a movie script about Dog in Moon
```
## User Interface
## PraisonAI User Interfaces:
| Interface | Description | URL |
| --------- | ------------------------------------------ | --------------------------------------------------------------------- |
| **UI** | Multi Agents such as CrewAI or AutoGen | [https://docs.praisonai.com/ui/ui](https://docs.praison.ai/ui/ui) |
| **Chat** | Chat with 100+ LLMs, single AI Agent | [https://docs.praisonai.com/ui/chat](https://docs.praison.ai/ui/chat) |
| **Code** | Chat with entire Codebase, single AI Agent | [https://docs.praisonai.com/ui/code](https://docs.praison.ai/ui/code) |
```bash
pip install -U "praisonai[ui]"
export OPENAI_API_KEY="Enter your API key"
chainlit create-secret
export CHAINLIT_AUTH_SECRET=xxxxxxxx
praisonai ui
```
or
```
python -m praisonai ui
```
## Praison AI Chat
- https://docs.praison.ai/chat/
```bash
pip install "praisonai[chat]"
export OPENAI_API_KEY="Enter your API key"
praisonai chat
```
### Internet Search
Praison AI Chat and Praison AI Code now includes internet search capabilities using Crawl4AI and Tavily, allowing you to retrieve up-to-date information during your conversations.
### Vision Language Model Support
You can now upload images and ask questions based on them using Vision Language Models. This feature enables visual understanding and analysis within your chat sessions.
## Praison AI Code
```bash
pip install "praisonai[code]"
export OPENAI_API_KEY="Enter your API key"
praisonai code
```
### Internet Search
Praison AI Code also includes internet search functionality, enabling you to find relevant code snippets and programming information online.
## Create Custom Tools
- https://docs.praison.ai/tools/custom/
## No Code Options
## Agents Playbook
### Simple Playbook Example
Create `agents.yaml` file and add the code below:
```yaml
framework: crewai
framework: praisonai
topic: Artificial Intelligence
roles:
screenwriter:
@@ -420,62 +488,25 @@ roles:
expected_output: "Complete script ready for production."
```
*To run the playbook:*
```bash
praisonai agents.yaml
```
## Use 100+ Models
- https://docs.praison.ai/models/
<div align="center">
<a href="https://docs.praison.ai">
<p align="center">
<img src="https://img.shields.io/badge/📚_Documentation-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Documentation" />
</p>
</a>
</div>
## Include praisonai package in your project
## Development:
- https://docs.praison.ai/developers/wrapper
- https://docs.praison.ai/developers/wrapper-tools/
## Option 1: Using RAW YAML
```python
from praisonai import PraisonAI
# Example agent_yaml content
agent_yaml = """
framework: "crewai"
topic: "Space Exploration"
roles:
astronomer:
role: "Space Researcher"
goal: "Discover new insights about {topic}"
backstory: "You are a curious and dedicated astronomer with a passion for unraveling the mysteries of the cosmos."
tasks:
investigate_exoplanets:
description: "Research and compile information about exoplanets discovered in the last decade."
expected_output: "A summarized report on exoplanet discoveries, including their size, potential habitability, and distance from Earth."
"""
# Create a PraisonAI instance with the agent_yaml content
praisonai = PraisonAI(agent_yaml=agent_yaml)
# Run PraisonAI
result = praisonai.run()
# Print the result
print(result)
```
## Option 2: Using separate agents.yaml file
Note: Please create agents.yaml file before hand.
```python
from praisonai import PraisonAI
def basic(): # Basic Mode
praisonai = PraisonAI(agent_file="agents.yaml")
praisonai.run()
if __name__ == "__main__":
basic()
```
## Commands to Install Dependencies:
Below is used for development only.
### Using uv
```bash
@@ -500,18 +531,33 @@ uv pip install -r pyproject.toml --extra "crewai,autogen"
- Submit a pull request via GitHub's web interface.
- Await feedback from project maintainers.
## Other Features
- 🔄 Use CrewAI or AutoGen Framework
- 💻 Chat with ENTIRE Codebase
- 🎨 Interactive UIs
- 📄 YAML-based Configuration
- 🛠️ Custom Tool Integration
- 🔍 Internet Search Capability (using Crawl4AI and Tavily)
- 🖼️ Vision Language Model (VLM) Support
- 🎙️ Real-time Voice Interaction
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=MervinPraison/PraisonAI&type=Date)](https://docs.praison.ai)
## License
Praison AI is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
## Video Tutorials
| Topic | Video |
|-------|--------|
| AI Agents with Self Reflection | [![Self Reflection](https://img.youtube.com/vi/vLXobEN2Vc8/0.jpg)](https://www.youtube.com/watch?v=vLXobEN2Vc8) |
| AI Agents with Reasoning | [![Reasoning](https://img.youtube.com/vi/KNDVWGN3TpM/0.jpg)](https://www.youtube.com/watch?v=KNDVWGN3TpM) |
| Multimodal AI Agents | [![Multimodal](https://img.youtube.com/vi/hjAWmUT1qqY/0.jpg)](https://www.youtube.com/watch?v=hjAWmUT1qqY) |
| AI Agents Workflow | [![Workflow](https://img.youtube.com/vi/yWTH44QPl2A/0.jpg)](https://www.youtube.com/watch?v=yWTH44QPl2A) |
| Async AI Agents | [![Async](https://img.youtube.com/vi/VhVQfgo00LE/0.jpg)](https://www.youtube.com/watch?v=VhVQfgo00LE) |
| Mini AI Agents | [![Mini](https://img.youtube.com/vi/OkvYp5aAGSg/0.jpg)](https://www.youtube.com/watch?v=OkvYp5aAGSg) |
| AI Agents with Memory | [![Memory](https://img.youtube.com/vi/1hVfVxvPnnQ/0.jpg)](https://www.youtube.com/watch?v=1hVfVxvPnnQ) |
| Repetitive Agents | [![Repetitive](https://img.youtube.com/vi/dAYGxsjDOPg/0.jpg)](https://www.youtube.com/watch?v=dAYGxsjDOPg) |
| Introduction | [![Introduction](https://img.youtube.com/vi/Fn1lQjC0GO0/0.jpg)](https://www.youtube.com/watch?v=Fn1lQjC0GO0) |
| Tools Overview | [![Tools Overview](https://img.youtube.com/vi/XaQRgRpV7jo/0.jpg)](https://www.youtube.com/watch?v=XaQRgRpV7jo) |
| Custom Tools | [![Custom Tools](https://img.youtube.com/vi/JSU2Rndh06c/0.jpg)](https://www.youtube.com/watch?v=JSU2Rndh06c) |
@@ -525,58 +571,3 @@ Praison AI is an open-sourced software licensed under the **[MIT license](https:
| Realtime Voice Interface | [![Realtime](https://img.youtube.com/vi/frRHfevTCSw/0.jpg)](https://www.youtube.com/watch?v=frRHfevTCSw) |
| Call Interface | [![Call](https://img.youtube.com/vi/m1cwrUG2iAk/0.jpg)](https://www.youtube.com/watch?v=m1cwrUG2iAk) |
## License
Praison AI is an open-sourced software licensed under the **[MIT license](https://opensource.org/licenses/MIT)**.
## Local Docker Development with Live Reload
To facilitate local development with live reload, you can use Docker. Follow the steps below:
1. **Create a `Dockerfile.dev`**:
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
EXPOSE 5555
ENV FLASK_ENV=development
CMD ["flask", "run", "--host=0.0.0.0"]
```
2. **Create a `docker-compose.yml`**:
```yaml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
ports:
- "5555:5555"
environment:
FLASK_ENV: development
command: flask run --host=0.0.0.0
watch:
image: alpine:latest
volumes:
- .:/app
command: sh -c "apk add --no-cache inotify-tools && while inotifywait -r -e modify,create,delete /app; do kill -HUP 1; done"
```
3. **Run Docker Compose**:
```bash
docker-compose up
```
This setup will allow you to develop locally with live reload, making it easier to test and iterate on your code.
+127
View File
@@ -0,0 +1,127 @@
import asyncio
import logging
from typing import List, Dict, Any
from pydantic import BaseModel
from praisonaiagents import Agent, Task, PraisonAIAgents, TaskOutput
from tavily import AsyncTavilyClient
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
llm_config = {
"model": "gemini/gemini-1.5-flash-8b",
"response_format": {
"type": "text"
}
}
# Define output model
class SearchResult(BaseModel):
query: str
results: List[Dict[str, Any]]
total_results: int
# Define Tavily search tool
async def tavily_search(query) -> Dict[str, Any]:
"""Async Tavily search tool that returns structured results"""
client = AsyncTavilyClient()
try:
results = await client.search(query)
print(f"Tavily search results: {results}")
return {
"query": query,
"results": results.get("results", []),
"total_results": len(results.get("results", []))
}
except Exception as e:
logging.error(f"Tavily search error: {e}")
return {
"query": query,
"results": [],
"total_results": 0
}
# Define async callback
async def async_callback(output: TaskOutput):
if output.output_format == "JSON":
logging.info(f"Search completed: {output.json_dict.get('query', '')}")
elif output.output_format == "Pydantic":
logging.info(f"Search completed: {output.pydantic}")
async def run_parallel_searches():
# Create search agent with direct tool function
search_agent = Agent(
name="TavilySearchAgent",
role="Search Specialist",
goal="Perform parallel web searches with high accuracy",
backstory="Expert in web search and information retrieval",
tools=[tavily_search],
llm=llm_config
)
# Create summary agent
summary_agent = Agent(
name="ContentSynthesizer",
role="Research Analyst",
goal="Synthesize search results into coherent insights",
backstory="Expert in analyzing and combining multiple sources of information",
llm=llm_config
)
# Define search topics
search_topics = [
"Latest AI breakthroughs 2024",
"Future of quantum computing",
"Advancements in robotics"
]
# Create parallel search tasks
search_tasks = [
Task(
name=f"search_{i}",
description=f"Search and analyze: {topic}",
expected_output="Comprehensive search results with analysis",
agent=search_agent,
async_execution=True,
callback=async_callback,
) for i, topic in enumerate(search_topics)
]
# Create summary task
summary_task = Task(
name="synthesize_results",
description="Create a comprehensive summary of all search findings",
expected_output="Synthesized insights from all searches",
agent=summary_agent,
async_execution=False,
context=search_tasks
)
# Initialize agents manager
agents = PraisonAIAgents(
agents=[search_agent, summary_agent],
tasks=search_tasks + [summary_task]
)
# Execute tasks
results = await agents.astart()
return {
"search_results": [str(results["task_results"][i]) for i in range(len(search_tasks))],
"summary": str(results["task_results"][summary_task.id]),
"topics": search_topics
}
async def main():
try:
logging.info("Starting parallel Tavily searches...")
results = await run_parallel_searches()
logging.info("Search process completed successfully")
print("\nResults Summary:")
for topic, result in zip(results["topics"], results["search_results"]):
print(f"\n{topic}:\n{result}")
print(f"\nFinal Summary:\n{results['summary']}")
except Exception as e:
logging.error(f"Error in execution: {e}")
if __name__ == "__main__":
asyncio.run(main())
+119
View File
@@ -0,0 +1,119 @@
import asyncio
import logging
from typing import List, Dict, Any
from pydantic import BaseModel
from praisonaiagents import Agent, Task, PraisonAIAgents, TaskOutput
from tavily import AsyncTavilyClient
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Define output model
class SearchResult(BaseModel):
query: str
results: List[Dict[str, Any]]
total_results: int
# Define Tavily search tool
async def tavily_search(query: str) -> Dict[str, Any]:
"""Async Tavily search tool that returns structured results"""
client = AsyncTavilyClient()
try:
results = await client.search(query)
print(f"Tavily search results: {results}")
return {
"query": query,
"results": results.get("results", []),
"total_results": len(results.get("results", []))
}
except Exception as e:
logging.error(f"Tavily search error: {e}")
return {
"query": query,
"results": [],
"total_results": 0
}
# Define async callback
async def async_callback(output: TaskOutput):
if output.output_format == "JSON":
logging.info(f"Search completed: {output.json_dict.get('query', '')}")
elif output.output_format == "Pydantic":
logging.info(f"Search completed: {output.pydantic}")
async def run_parallel_searches():
# Create search agent with direct tool function
search_agent = Agent(
name="TavilySearchAgent",
role="Search Specialist",
goal="Perform parallel web searches with high accuracy",
backstory="Expert in web search and information retrieval",
tools=[tavily_search]
)
# Create summary agent
summary_agent = Agent(
name="ContentSynthesizer",
role="Research Analyst",
goal="Synthesize search results into coherent insights",
backstory="Expert in analyzing and combining multiple sources of information"
)
# Define search topics
search_topics = [
"Latest AI breakthroughs 2024",
"Future of quantum computing",
"Advancements in robotics"
]
# Create parallel search tasks
search_tasks = [
Task(
name=f"search_{i}",
description=f"Search and analyze: {topic}",
expected_output="Comprehensive search results with analysis",
agent=search_agent,
async_execution=True,
callback=async_callback,
output_json=SearchResult
) for i, topic in enumerate(search_topics)
]
# Create summary task
summary_task = Task(
name="synthesize_results",
description="Create a comprehensive summary of all search findings",
expected_output="Synthesized insights from all searches",
agent=summary_agent,
async_execution=False,
context=search_tasks
)
# Initialize agents manager
agents = PraisonAIAgents(
agents=[search_agent, summary_agent],
tasks=search_tasks + [summary_task]
)
# Execute tasks
results = await agents.astart()
return {
"search_results": [str(results["task_results"][i]) for i in range(len(search_tasks))],
"summary": str(results["task_results"][summary_task.id]),
"topics": search_topics
}
async def main():
try:
logging.info("Starting parallel Tavily searches...")
results = await run_parallel_searches()
logging.info("Search process completed successfully")
print("\nResults Summary:")
for topic, result in zip(results["topics"], results["search_results"]):
print(f"\n{topic}:\n{result}")
print(f"\nFinal Summary:\n{results['summary']}")
except Exception as e:
logging.error(f"Error in execution: {e}")
if __name__ == "__main__":
asyncio.run(main())
+6
View File
@@ -0,0 +1,6 @@
from praisonaiagents import Agent
agent = Agent(instructions="You are helpful Assisant", llm="deepseek-reasoner", reasoning_steps=True)
result = agent.start("Why sky is Blue?")
print(result)
+14
View File
@@ -0,0 +1,14 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
reasoning_agent = Agent(role="Helpful Assistant", reasoning_steps=True, llm="deepseek/deepseek-reasoner")
small_agent = Agent(role="Helpful Assistant", llm="gpt-3.5-turbo")
reasoning_task = Task(description="How many r's in the word 'Strawberry'?", agent=reasoning_agent)
small_task = Task(description="With the provided reasoning tell me how many r's in the word 'Strawberry'?", agent=small_agent)
agents = PraisonAIAgents(
agents=[reasoning_agent, small_agent],
tasks=[reasoning_task, small_task]
)
agents.start()
@@ -0,0 +1,19 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
llm_config = {
"model": "deepseek/deepseek-reasoner",
"max_tokens": 1
}
reasoning_agent = Agent(role="Helpful Assistant", llm=llm_config, reasoning_steps=True)
small_agent = Agent(role="Helpful Assistant", llm="openai/gpt-3.5-turbo")
reasoning_task = Task(description="How many r's in the word 'Strawberry'?", agent=reasoning_agent)
small_task = Task(description="With the provided reasoning tell me how many r's in the word 'Strawberry'?", agent=small_agent)
agents = PraisonAIAgents(
agents=[reasoning_agent, small_agent],
tasks=[reasoning_task, small_task]
)
agents.start()
+18
View File
@@ -0,0 +1,18 @@
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="deepseek-reasoner",
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "Why sky is Blue?"},
],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.choices[0].delta.reasoning_content is not None:
print(chunk.choices[0].delta.reasoning_content, end="", flush=True)
+14
View File
@@ -0,0 +1,14 @@
from litellm import completion
messages = [{"role": "user", "content": "What is 1+1?"}]
resp = completion(
model="deepseek/deepseek-reasoner",
messages=messages,
stream=False
)
reasoning_content = resp.choices[0].message.provider_specific_fields["reasoning_content"]
content = resp.choices[0].message.content
print(reasoning_content)
print(content)
+9
View File
@@ -0,0 +1,9 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are helpful Assisant",
llm="deepseek/deepseek-reasoner"
)
result = agent.start("Why sky is Blue?")
print(result)
+10
View File
@@ -0,0 +1,10 @@
from praisonaiagents import Agent
agent = Agent(
instructions="You are helpful Assisant",
llm="deepseek/deepseek-reasoner",
reasoning_steps=True
)
result = agent.start("Why sky is Blue?")
print(result)
+14
View File
@@ -0,0 +1,14 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
reasoning_agent = Agent(role="Helpful Assistant", reasoning_steps=True, llm="deepseek/deepseek-reasoner")
small_agent = Agent(role="Helpful Assistant", llm="openai/gpt-3.5-turbo")
reasoning_task = Task(description="How many r's in the word 'Strawberry'?", agent=reasoning_agent)
small_task = Task(description="With the provided reasoning tell me how many r's in the word 'Strawberry'?", agent=small_agent)
agents = PraisonAIAgents(
agents=[reasoning_agent, small_agent],
tasks=[reasoning_task, small_task]
)
agents.start()
File renamed without changes.
File renamed without changes.
+30
View File
@@ -0,0 +1,30 @@
from praisonaiagents import Agent, Task, PraisonAIAgents
from langchain_community.tools import YouTubeSearchTool
from langchain_community.utilities import WikipediaAPIWrapper
# Create an agent with both tools
agent = Agent(
name="SearchAgent",
role="Research Assistant",
goal="Search for information from multiple sources",
backstory="I am an AI assistant that can search YouTube and Wikipedia.",
tools=[YouTubeSearchTool, WikipediaAPIWrapper],
llm="openai/gpt-4o-mini"
)
# Create tasks to demonstrate both tools
task = Task(
name="search_task",
description="Search for information about 'AI advancements' on both YouTube and Wikipedia",
expected_output="Combined information from YouTube videos and Wikipedia articles",
agent=agent
)
# Create and start the workflow
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
verbose=True
)
agents.start()
+345 -102
View File
@@ -21,10 +21,180 @@ from ..main import (
)
import inspect
import uuid
from dataclasses import dataclass
if TYPE_CHECKING:
from ..task.task import Task
@dataclass
class ChatCompletionMessage:
content: str
role: str = "assistant"
refusal: Optional[str] = None
audio: Optional[str] = None
function_call: Optional[dict] = None
tool_calls: Optional[List] = None
reasoning_content: Optional[str] = None
@dataclass
class Choice:
finish_reason: Optional[str]
index: int
message: ChatCompletionMessage
logprobs: Optional[dict] = None
@dataclass
class CompletionTokensDetails:
accepted_prediction_tokens: Optional[int] = None
audio_tokens: Optional[int] = None
reasoning_tokens: Optional[int] = None
rejected_prediction_tokens: Optional[int] = None
@dataclass
class PromptTokensDetails:
audio_tokens: Optional[int] = None
cached_tokens: int = 0
@dataclass
class CompletionUsage:
completion_tokens: int = 0
prompt_tokens: int = 0
total_tokens: int = 0
completion_tokens_details: Optional[CompletionTokensDetails] = None
prompt_tokens_details: Optional[PromptTokensDetails] = None
prompt_cache_hit_tokens: int = 0
prompt_cache_miss_tokens: int = 0
@dataclass
class ChatCompletion:
id: str
choices: List[Choice]
created: int
model: str
object: str = "chat.completion"
system_fingerprint: Optional[str] = None
service_tier: Optional[str] = None
usage: Optional[CompletionUsage] = None
def process_stream_chunks(chunks):
"""Process streaming chunks into combined response"""
if not chunks:
return None
try:
first_chunk = chunks[0]
last_chunk = chunks[-1]
# Basic metadata
id = getattr(first_chunk, "id", None)
created = getattr(first_chunk, "created", None)
model = getattr(first_chunk, "model", None)
system_fingerprint = getattr(first_chunk, "system_fingerprint", None)
# Track usage
completion_tokens = 0
prompt_tokens = 0
content_list = []
reasoning_list = []
tool_calls = []
current_tool_call = None
# First pass: Get initial tool call data
for chunk in chunks:
if not hasattr(chunk, "choices") or not chunk.choices:
continue
delta = getattr(chunk.choices[0], "delta", None)
if not delta:
continue
# Handle content and reasoning
if hasattr(delta, "content") and delta.content:
content_list.append(delta.content)
if hasattr(delta, "reasoning_content") and delta.reasoning_content:
reasoning_list.append(delta.reasoning_content)
# Handle tool calls
if hasattr(delta, "tool_calls") and delta.tool_calls:
for tool_call_delta in delta.tool_calls:
if tool_call_delta.index is not None and tool_call_delta.id:
# Found the initial tool call
current_tool_call = {
"id": tool_call_delta.id,
"type": "function",
"function": {
"name": tool_call_delta.function.name,
"arguments": ""
}
}
while len(tool_calls) <= tool_call_delta.index:
tool_calls.append(None)
tool_calls[tool_call_delta.index] = current_tool_call
current_tool_call = tool_calls[tool_call_delta.index]
elif current_tool_call is not None and hasattr(tool_call_delta.function, "arguments"):
if tool_call_delta.function.arguments:
current_tool_call["function"]["arguments"] += tool_call_delta.function.arguments
# Remove any None values and empty tool calls
tool_calls = [tc for tc in tool_calls if tc and tc["id"] and tc["function"]["name"]]
combined_content = "".join(content_list) if content_list else ""
combined_reasoning = "".join(reasoning_list) if reasoning_list else None
finish_reason = getattr(last_chunk.choices[0], "finish_reason", None) if hasattr(last_chunk, "choices") and last_chunk.choices else None
# Create ToolCall objects
processed_tool_calls = []
if tool_calls:
try:
from openai.types.chat import ChatCompletionMessageToolCall
for tc in tool_calls:
tool_call = ChatCompletionMessageToolCall(
id=tc["id"],
type=tc["type"],
function={
"name": tc["function"]["name"],
"arguments": tc["function"]["arguments"]
}
)
processed_tool_calls.append(tool_call)
except Exception as e:
print(f"Error processing tool call: {e}")
message = ChatCompletionMessage(
content=combined_content,
role="assistant",
reasoning_content=combined_reasoning,
tool_calls=processed_tool_calls if processed_tool_calls else None
)
choice = Choice(
finish_reason=finish_reason or "tool_calls" if processed_tool_calls else None,
index=0,
message=message
)
usage = CompletionUsage(
completion_tokens=completion_tokens,
prompt_tokens=prompt_tokens,
total_tokens=completion_tokens + prompt_tokens,
completion_tokens_details=CompletionTokensDetails(),
prompt_tokens_details=PromptTokensDetails()
)
return ChatCompletion(
id=id,
choices=[choice],
created=created,
model=model,
system_fingerprint=system_fingerprint,
usage=usage
)
except Exception as e:
print(f"Error processing chunks: {e}")
return None
class Agent:
def _generate_tool_definition(self, function_name):
"""
@@ -190,7 +360,8 @@ class Agent:
max_reflect: int = 3,
min_reflect: int = 1,
reflect_llm: Optional[str] = None,
user_id: Optional[str] = None
user_id: Optional[str] = None,
reasoning_steps: bool = False
):
# Add check at start if memory is requested
if memory is not None:
@@ -297,7 +468,8 @@ Your Goal: {self.goal}
self.agent_id = str(uuid.uuid4())
# Store user_id
self.user_id = user_id
self.user_id = user_id or "praison"
self.reasoning_steps = reasoning_steps
# Check if knowledge parameter has any values
if not knowledge:
@@ -399,7 +571,54 @@ Your Goal: {self.goal}
def __str__(self):
return f"Agent(name='{self.name}', role='{self.role}', goal='{self.goal}')"
def _chat_completion(self, messages, temperature=0.2, tools=None, stream=True):
def _process_stream_response(self, messages, temperature, start_time, formatted_tools=None, reasoning_steps=False):
"""Process streaming response and return final response"""
try:
# Create the response stream
response_stream = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
tools=formatted_tools if formatted_tools else None,
stream=True
)
full_response_text = ""
reasoning_content = ""
chunks = []
# Create Live display with proper configuration
with Live(
display_generating("", start_time),
console=self.console,
refresh_per_second=4,
transient=True,
vertical_overflow="ellipsis",
auto_refresh=True
) as live:
for chunk in response_stream:
chunks.append(chunk)
if chunk.choices[0].delta.content:
full_response_text += chunk.choices[0].delta.content
live.update(display_generating(full_response_text, start_time))
# Update live display with reasoning content if enabled
if reasoning_steps and hasattr(chunk.choices[0].delta, "reasoning_content"):
rc = chunk.choices[0].delta.reasoning_content
if rc:
reasoning_content += rc
live.update(display_generating(f"{full_response_text}\n[Reasoning: {reasoning_content}]", start_time))
# Clear the last generating display with a blank line
self.console.print()
final_response = process_stream_chunks(chunks)
return final_response
except Exception as e:
display_error(f"Error in stream processing: {e}")
return None
def _chat_completion(self, messages, temperature=0.2, tools=None, stream=True, reasoning_steps=False):
start_time = time.time()
logging.debug(f"{self.name} sending messages to LLM: {messages}")
@@ -425,20 +644,31 @@ Your Goal: {self.goal}
logging.warning(f"Tool {tool} not recognized")
try:
initial_response = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
tools=formatted_tools if formatted_tools else None,
stream=False
)
if stream:
# Process as streaming response with formatted tools
final_response = self._process_stream_response(
messages,
temperature,
start_time,
formatted_tools=formatted_tools if formatted_tools else None,
reasoning_steps=reasoning_steps
)
else:
# Process as regular non-streaming response
final_response = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
tools=formatted_tools if formatted_tools else None,
stream=False
)
tool_calls = getattr(initial_response.choices[0].message, 'tool_calls', None)
tool_calls = getattr(final_response.choices[0].message, 'tool_calls', None)
if tool_calls:
messages.append({
"role": "assistant",
"content": initial_response.choices[0].message.content,
"role": "assistant",
"content": final_response.choices[0].message.content,
"tool_calls": tool_calls
})
@@ -461,56 +691,31 @@ Your Goal: {self.goal}
"content": results_str
})
if stream:
response_stream = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
stream=True
)
full_response_text = ""
# Create Live display with proper configuration
with Live(
display_generating("", start_time),
console=self.console,
refresh_per_second=4,
transient=True, # Changed to False to preserve output
vertical_overflow="ellipsis",
auto_refresh=True
) as live:
for chunk in response_stream:
if chunk.choices[0].delta.content:
full_response_text += chunk.choices[0].delta.content
live.update(display_generating(full_response_text, start_time))
# Clear the last generating display with a blank line
self.console.print()
final_response = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
stream=False
)
return final_response
else:
if tool_calls:
# Get final response after tool calls
if stream:
final_response = self._process_stream_response(
messages,
temperature,
start_time,
formatted_tools=formatted_tools if formatted_tools else None,
reasoning_steps=reasoning_steps
)
else:
final_response = client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
stream=False
)
return final_response
else:
return initial_response
return final_response
except Exception as e:
display_error(f"Error in chat completion: {e}")
return None
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None):
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False):
reasoning_steps = reasoning_steps or self.reasoning_steps
# Search for existing knowledge if any knowledge is provided
if self.knowledge:
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
@@ -546,7 +751,8 @@ Your Goal: {self.goal}
agent_name=self.name,
agent_role=self.role,
agent_tools=[t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools],
execute_tool_fn=self.execute_tool # Pass tool execution function
execute_tool_fn=self.execute_tool, # Pass tool execution function
reasoning_steps=reasoning_steps
)
self.chat_history.append({"role": "user", "content": prompt})
@@ -616,14 +822,13 @@ Your Goal: {self.goal}
agent_tools=agent_tools
)
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None)
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None, reasoning_steps=reasoning_steps)
if not response:
return None
tool_calls = getattr(response.choices[0].message, 'tool_calls', None)
response_text = response.choices[0].message.content.strip()
if tool_calls:
if tool_calls: ## TODO: Most likely this tool call is already called in _chat_completion, so maybe we can remove this.
messages.append({
"role": "assistant",
"content": response_text,
@@ -675,6 +880,9 @@ Your Goal: {self.goal}
if self.verbose:
logging.debug(f"Agent {self.name} final response: {response_text}")
display_interaction(original_prompt, response_text, markdown=self.markdown, generation_time=time.time() - start_time, console=self.console)
# Return only reasoning content if reasoning_steps is True
if reasoning_steps and hasattr(response.choices[0].message, 'reasoning_content'):
return response.choices[0].message.reasoning_content
return response_text
reflection_prompt = f"""
@@ -749,8 +957,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
cleaned = cleaned[:-3].strip()
return cleaned
async def achat(self, prompt: str, temperature=0.2, tools=None, output_json=None, output_pydantic=None):
async def achat(self, prompt: str, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False):
"""Async version of chat method. TODO: Requires Syncing with chat method."""
reasoning_steps = reasoning_steps or self.reasoning_steps
try:
# Search for existing knowledge if any knowledge is provided
if self.knowledge:
@@ -781,7 +990,8 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
agent_name=self.name,
agent_role=self.role,
agent_tools=[t.__name__ if hasattr(t, '__name__') else str(t) for t in self.tools],
execute_tool_fn=self.execute_tool_async
execute_tool_fn=self.execute_tool_async,
reasoning_steps=reasoning_steps
)
self.chat_history.append({"role": "user", "content": prompt})
@@ -847,48 +1057,48 @@ Your Goal: {self.goal}
)
# Format tools if provided
formatted_tools = []
if tools:
for tool in tools:
if isinstance(tool, str):
tool_def = self._generate_tool_definition(tool)
if tool_def:
formatted_tools.append(tool_def)
elif isinstance(tool, dict):
formatted_tools.append(tool)
elif hasattr(tool, "to_openai_tool"):
formatted_tools.append(tool.to_openai_tool())
elif callable(tool):
formatted_tools.append(self._generate_tool_definition(tool.__name__))
formatted_tools = []
if tools:
for tool in tools:
if isinstance(tool, str):
tool_def = self._generate_tool_definition(tool)
if tool_def:
formatted_tools.append(tool_def)
elif isinstance(tool, dict):
formatted_tools.append(tool)
elif hasattr(tool, "to_openai_tool"):
formatted_tools.append(tool.to_openai_tool())
elif callable(tool):
formatted_tools.append(self._generate_tool_definition(tool.__name__))
# Create async OpenAI client
async_client = AsyncOpenAI()
# Create async OpenAI client
async_client = AsyncOpenAI()
# Make the API call based on the type of request
if tools:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
tools=formatted_tools
)
return await self._achat_completion(response, tools)
elif output_json or output_pydantic:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
response_format={"type": "json_object"}
)
# Return the raw response
return response.choices[0].message.content
else:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature
)
return response.choices[0].message.content
# Make the API call based on the type of request
if tools:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
tools=formatted_tools
)
return await self._achat_completion(response, tools)
elif output_json or output_pydantic:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature,
response_format={"type": "json_object"}
)
# Return the raw response
return response.choices[0].message.content
else:
response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=temperature
)
return response.choices[0].message.content
except Exception as e:
display_error(f"Error in chat completion: {e}")
return None
@@ -896,7 +1106,7 @@ Your Goal: {self.goal}
display_error(f"Error in achat: {e}")
return None
async def _achat_completion(self, response, tools):
async def _achat_completion(self, response, tools, reasoning_steps=False):
"""Async version of _chat_completion method"""
try:
message = response.choices[0].message
@@ -942,9 +1152,42 @@ Your Goal: {self.goal}
final_response = await async_client.chat.completions.create(
model=self.llm,
messages=messages,
temperature=0.2
temperature=0.2,
stream=True
)
return final_response.choices[0].message.content
full_response_text = ""
reasoning_content = ""
chunks = []
start_time = time.time()
with Live(
display_generating("", start_time),
console=self.console,
refresh_per_second=4,
transient=True,
vertical_overflow="ellipsis",
auto_refresh=True
) as live:
async for chunk in final_response:
chunks.append(chunk)
if chunk.choices[0].delta.content:
full_response_text += chunk.choices[0].delta.content
live.update(display_generating(full_response_text, start_time))
if reasoning_steps and hasattr(chunk.choices[0].delta, "reasoning_content"):
rc = chunk.choices[0].delta.reasoning_content
if rc:
reasoning_content += rc
live.update(display_generating(f"{full_response_text}\n[Reasoning: {reasoning_content}]", start_time))
self.console.print()
final_response = process_stream_chunks(chunks)
# Return only reasoning content if reasoning_steps is True
if reasoning_steps and hasattr(final_response.choices[0].message, 'reasoning_content'):
return final_response.choices[0].message.reasoning_content
return final_response.choices[0].message.content if final_response else full_response_text
except Exception as e:
display_error(f"Error in final chat completion: {e}")
return formatted_results
@@ -952,7 +1195,7 @@ Your Goal: {self.goal}
return None
except Exception as e:
display_error(f"Error in _achat_completion: {e}")
return None
return None
async def astart(self, prompt: str, **kwargs):
"""Async version of start method"""
+4 -18
View File
@@ -390,15 +390,8 @@ Context:
task.status = "completed"
# Run execute_callback for memory operations
try:
try:
# If a loop is already running, just create the task
loop = asyncio.get_running_loop()
loop.create_task(task.execute_callback(task_output))
except RuntimeError:
# Otherwise, create and set a new loop, and run the callback
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(task.execute_callback(task_output))
# Use the new sync wrapper to avoid pending coroutine issues
task.execute_callback_sync(task_output)
except Exception as e:
logger.error(f"Error executing memory callback for task {task_id}: {e}")
logger.exception(e)
@@ -720,15 +713,8 @@ Context:
task.status = "completed"
# Run execute_callback for memory operations
try:
try:
# If a loop is already running, just create the task
loop = asyncio.get_running_loop()
loop.create_task(task.execute_callback(task_output))
except RuntimeError:
# Otherwise, create and set a new loop, and run the callback
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.create_task(task.execute_callback(task_output))
# Use the new sync wrapper to avoid pending coroutine issues
task.execute_callback_sync(task_output)
except Exception as e:
logger.error(f"Error executing memory callback for task {task_id}: {e}")
logger.exception(e)
+331 -128
View File
@@ -17,6 +17,8 @@ from ..main import (
from rich.console import Console
from rich.live import Live
# TODO: Include in-build tool calling in LLM class
# TODO: Restructure so that duplicate calls are not made (Sync with agent.py)
class LLMContextLengthExceededException(Exception):
"""Raised when LLM context length is exceeded"""
def __init__(self, message: str):
@@ -113,6 +115,7 @@ class LLM:
litellm.callbacks = []
# Additional logging suppression
litellm.suppress_debug_messages = True
litellm._logging._disable_debugging()
logging.getLogger("litellm.utils").setLevel(logging.WARNING)
logging.getLogger("litellm.main").setLevel(logging.WARNING)
except ImportError:
@@ -147,6 +150,7 @@ class LLM:
self.self_reflect = extra_settings.get('self_reflect', False)
self.max_reflect = extra_settings.get('max_reflect', 3)
self.min_reflect = extra_settings.get('min_reflect', 1)
self.reasoning_steps = extra_settings.get('reasoning_steps', False)
# Enable error dropping for cleaner output
litellm.drop_params = True
@@ -176,7 +180,8 @@ class LLM:
"""Enhanced get_response with all OpenAI-like features"""
try:
import litellm
# This below **kwargs** is passed to .completion() directly. so reasoning_steps has to be popped. OR find alternate best way of handling this.
reasoning_steps = kwargs.pop('reasoning_steps', self.reasoning_steps)
# Disable litellm debug messages
litellm.set_verbose = False
@@ -230,8 +235,55 @@ class LLM:
# Get response from LiteLLM
start_time = time.time()
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
# If reasoning_steps is True, do a single non-streaming call
if reasoning_steps:
resp = litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=False, # force non-streaming
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
reasoning_content = resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
response_text = resp["choices"][0]["message"]["content"]
# Optionally display reasoning if present
if verbose and reasoning_content:
display_interaction(
original_prompt,
f"Reasoning:\n{reasoning_content}\n\nAnswer:\n{response_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
display_interaction(
original_prompt,
response_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
# Otherwise do the existing streaming approach
else:
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
# Non-verbose mode, just collect the response
response_text = ""
for chunk in litellm.completion(
model=self.model,
@@ -241,23 +293,9 @@ class LLM:
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
# Non-verbose mode, just collect the response
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
response_text = response_text.strip()
# Get final completion to check for tool calls
final_response = litellm.completion(
@@ -302,9 +340,53 @@ class LLM:
"content": "Function returned an empty output"
})
# Get response after tool calls with streaming
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
# If reasoning_steps is True, do a single non-streaming call
if reasoning_steps:
resp = litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=False, # force non-streaming
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
reasoning_content = resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
response_text = resp["choices"][0]["message"]["content"]
# Optionally display reasoning if present
if verbose and reasoning_content:
display_interaction(
original_prompt,
f"Reasoning:\n{reasoning_content}\n\nAnswer:\n{response_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
display_interaction(
original_prompt,
response_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
# Otherwise do the existing streaming approach
else:
# Get response after tool calls with streaming
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
@@ -313,21 +395,9 @@ class LLM:
stream=True
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
live.update(display_generating(response_text, start_time))
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
response_text = response_text.strip()
# Handle output formatting
if output_json or output_pydantic:
@@ -342,6 +412,9 @@ class LLM:
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
# Return reasoning content if reasoning_steps is True
if reasoning_steps and reasoning_content:
return reasoning_content
return response_text
# Handle self-reflection
@@ -357,32 +430,66 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
{"role": "user", "content": reflection_prompt}
]
# Get reflection response with streaming
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
# If reasoning_steps is True, do a single non-streaming call to capture reasoning
if reasoning_steps:
reflection_resp = litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=False, # Force non-streaming
response_format={"type": "json_object"},
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
# Grab reflection text and optional reasoning
reasoning_content = reflection_resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
reflection_text = reflection_resp["choices"][0]["message"]["content"]
# Optionally display reasoning if present
if verbose and reasoning_content:
display_interaction(
"Reflection reasoning:",
f"{reasoning_content}\n\nReflection result:\n{reflection_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
elif verbose:
display_interaction(
"Self-reflection (non-streaming):",
reflection_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
# Existing streaming approach
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
live.update(display_generating(reflection_text, start_time))
else:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"}
response_format={"type": "json_object"},
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
live.update(display_generating(reflection_text, start_time))
else:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
reflection_text += chunk.choices[0].delta.content
reflection_text += chunk.choices[0].delta.content
try:
reflection_data = json.loads(reflection_text)
@@ -453,6 +560,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
"""Async version of get_response with identical functionality."""
try:
import litellm
reasoning_steps = kwargs.pop('reasoning_steps', self.reasoning_steps)
litellm.set_verbose = False
# Build messages list
@@ -490,10 +598,10 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
# Format tools for LiteLLM
formatted_tools = None
if tools:
logging.info(f"Starting tool formatting for {len(tools)} tools")
logging.debug(f"Starting tool formatting for {len(tools)} tools")
formatted_tools = []
for tool in tools:
logging.info(f"Processing tool: {tool.__name__ if hasattr(tool, '__name__') else str(tool)}")
logging.debug(f"Processing tool: {tool.__name__ if hasattr(tool, '__name__') else str(tool)}")
if hasattr(tool, '__name__'):
tool_name = tool.__name__
tool_doc = tool.__doc__ or "No description available"
@@ -539,10 +647,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
}
}
# Ensure tool definition is JSON serializable
print(f"Generated tool definition: {tool_def}")
try:
json.dumps(tool_def) # Test serialization
logging.info(f"Generated tool definition: {tool_def}")
logging.debug(f"Generated tool definition: {tool_def}")
formatted_tools.append(tool_def)
except TypeError as e:
logging.error(f"Tool definition not JSON serializable: {e}")
@@ -552,38 +659,67 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
if formatted_tools:
try:
json.dumps(formatted_tools) # Final serialization check
logging.info(f"Final formatted tools: {json.dumps(formatted_tools, indent=2)}")
logging.debug(f"Final formatted tools: {json.dumps(formatted_tools, indent=2)}")
except TypeError as e:
logging.error(f"Final tools list not JSON serializable: {e}")
formatted_tools = None
response_text = ""
if verbose:
# ----------------------------------------------------
# 1) Make the streaming call WITHOUT tools
# ----------------------------------------------------
async for chunk in await litellm.acompletion(
if reasoning_steps:
# Non-streaming call to capture reasoning
resp = await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
print("\033[K", end="\r")
print(f"Generating... {time.time() - start_time:.1f}s", end="\r")
stream=False, # force non-streaming
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
reasoning_content = resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
response_text = resp["choices"][0]["message"]["content"]
if verbose and reasoning_content:
display_interaction(
"Initial reasoning:",
f"Reasoning:\n{reasoning_content}\n\nAnswer:\n{response_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
elif verbose:
display_interaction(
"Initial response:",
response_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
# Non-verbose streaming call, still no tools
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
if verbose:
# ----------------------------------------------------
# 1) Make the streaming call WITHOUT tools
# ----------------------------------------------------
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
print("\033[K", end="\r")
print(f"Generating... {time.time() - start_time:.1f}s", end="\r")
else:
# Non-verbose streaming call, still no tools
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
@@ -598,7 +734,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
temperature=temperature,
stream=False,
tools=formatted_tools, # We safely pass tools here
**kwargs
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
# handle tool_calls from tool_response as usual...
tool_calls = tool_response.choices[0].message.get("tool_calls")
@@ -634,35 +770,66 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
"content": "Function returned an empty output"
})
# Get response after tool calls with streaming
# Get response after tool calls
response_text = ""
if verbose:
async for chunk in await litellm.acompletion(
if reasoning_steps:
# Non-streaming call to capture reasoning
resp = await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
tools=formatted_tools,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
print("\033[K", end="\r")
print(f"Reflecting... {time.time() - start_time:.1f}s", end="\r")
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
stream=False, # force non-streaming
tools=formatted_tools, # Include tools
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
reasoning_content = resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
response_text = resp["choices"][0]["message"]["content"]
if verbose and reasoning_content:
display_interaction(
"Tool response reasoning:",
f"Reasoning:\n{reasoning_content}\n\nAnswer:\n{response_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
elif verbose:
display_interaction(
"Tool response:",
response_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
# Get response after tool calls with streaming
if verbose:
async for chunk in await litellm.acompletion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
tools=formatted_tools,
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
response_text += content
print("\033[K", end="\r")
print(f"Reflecting... {time.time() - start_time:.1f}s", end="\r")
else:
response_text = ""
for chunk in litellm.completion(
model=self.model,
messages=messages,
temperature=temperature,
stream=True,
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
response_text += chunk.choices[0].delta.content
response_text = response_text.strip()
response_text = response_text.strip()
# Handle output formatting
if output_json or output_pydantic:
@@ -677,6 +844,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
if verbose:
display_interaction(original_prompt, response_text, markdown=markdown,
generation_time=time.time() - start_time, console=console)
# Return reasoning content if reasoning_steps is True
if reasoning_steps and reasoning_content:
return reasoning_content
return response_text
# Handle self-reflection
@@ -692,33 +862,66 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
{"role": "user", "content": reflection_prompt}
]
# Get reflection response
reflection_text = ""
if verbose:
async for chunk in await litellm.acompletion(
# If reasoning_steps is True, do a single non-streaming call to capture reasoning
if reasoning_steps:
reflection_resp = litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
stream=False, # Force non-streaming
response_format={"type": "json_object"},
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
print("\033[K", end="\r")
print(f"Reflecting... {time.time() - start_time:.1f}s", end="\r")
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
)
# Grab reflection text and optional reasoning
reasoning_content = reflection_resp["choices"][0]["message"].get("provider_specific_fields", {}).get("reasoning_content")
reflection_text = reflection_resp["choices"][0]["message"]["content"]
# Optionally display reasoning if present
if verbose and reasoning_content:
display_interaction(
"Reflection reasoning:",
f"{reasoning_content}\n\nReflection result:\n{reflection_text}",
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
elif verbose:
display_interaction(
"Self-reflection (non-streaming):",
reflection_text,
markdown=markdown,
generation_time=time.time() - start_time,
console=console
)
else:
async for chunk in await litellm.acompletion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**kwargs
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
reflection_text += chunk.choices[0].delta.content
# Existing streaming approach
if verbose:
with Live(display_generating("", start_time), console=console, refresh_per_second=4) as live:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
reflection_text += content
live.update(display_generating(reflection_text, start_time))
else:
reflection_text = ""
for chunk in litellm.completion(
model=self.model,
messages=reflection_messages,
temperature=temperature,
stream=True,
response_format={"type": "json_object"},
**{k:v for k,v in kwargs.items() if k != 'reasoning_steps'}
):
if chunk and chunk.choices and chunk.choices[0].delta.content:
reflection_text += chunk.choices[0].delta.content
while True: # Add loop for reflection handling
try:
+1 -1
View File
@@ -353,7 +353,7 @@ class ReflectionOutput(BaseModel):
reflection: str
satisfactory: Literal["yes", "no"]
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
client = OpenAI(api_key=(os.environ["OPENAI_API_KEY"] if os.environ.get("OPENAI_API_KEY") else "xxxx"))
class TaskOutput(BaseModel):
description: str
+8 -4
View File
@@ -44,6 +44,8 @@ class Process:
current_task = start_task
visited_tasks = set()
loop_data = {} # Store loop-specific data
# TODO: start task with loop feature is not available in aworkflow method
while current_task:
current_iter += 1
@@ -350,9 +352,10 @@ Provide a JSON with the structure:
if row: # Skip empty rows
task_desc = row[0] # Take first column
row_task = Task(
description=task_desc, # Keep full row as description
description=f"{start_task.description}\n{task_desc}" if start_task.description else task_desc,
agent=start_task.agent,
name=task_desc, # Use first column as name
name=f"{start_task.name}_{i+1}" if start_task.name else task_desc,
expected_output=getattr(start_task, 'expected_output', None),
is_start=(i == 0),
task_type="task",
condition={
@@ -374,9 +377,10 @@ Provide a JSON with the structure:
previous_task = None
for i, line in enumerate(lines):
row_task = Task(
description=line.strip(),
description=f"{start_task.description}\n{line.strip()}" if start_task.description else line.strip(),
agent=start_task.agent,
name=line.strip(),
name=f"{start_task.name}_{i+1}" if start_task.name else line.strip(),
expected_output=getattr(start_task, 'expected_output', None),
is_start=(i == 0),
task_type="task",
condition={
+18 -1
View File
@@ -302,4 +302,21 @@ Expected Output: {self.expected_output}.
Context:
{' '.join(unique_contexts)}
"""
"""
def execute_callback_sync(self, task_output: TaskOutput) -> None:
"""
Synchronous wrapper to ensure that execute_callback is awaited,
preventing 'Task was destroyed but pending!' warnings if called
from non-async code.
"""
import asyncio
try:
loop = asyncio.get_running_loop()
if loop.is_running():
loop.create_task(self.execute_callback(task_output))
else:
loop.run_until_complete(self.execute_callback(task_output))
except RuntimeError:
# If no loop is running in this context
asyncio.run(self.execute_callback(task_output))
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.49"
version = "0.0.56"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
authors = [
{ name="Mervin Praison" }
+2 -1
View File
@@ -6,7 +6,8 @@ agent = Agent(
)
task = Task(
description="Create the list of tasks to be looped through.",
description="complete the task",
expected_output="task completed",
agent=agent,
task_type="loop",
input_file="tasks.csv"
+1 -1
View File
@@ -1868,7 +1868,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.49"
version = "0.0.56"
source = { editable = "." }
dependencies = [
{ name = "openai" },
+1
View File
@@ -7,6 +7,7 @@ agent = Agent(
self_reflect=True,
min_reflect=3,
max_reflect=5,
llm="gpt-4o-mini"
)
agent.start(
"What is the history of AI?"
+1 -1
View File
@@ -1,6 +1,6 @@
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.56 gunicorn markdown
RUN pip install flask praisonai==2.0.59 gunicorn markdown
EXPOSE 8080
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+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==2.0.56 gunicorn markdown\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.0.59 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;)
+12 -76
View File
@@ -112,86 +112,22 @@ graph LR
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
```python Single Agent
from praisonaiagents import Agent
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
agent = Agent(instructions="Your are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
```python Multi Agents
from praisonaiagents import Agent, PraisonAIAgents
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
</CodeGroup>
</Step>
+75
View File
@@ -0,0 +1,75 @@
---
title: 'Local Development'
description: 'Set up local development environment with Docker and live reload'
---
## Logging
```bash
export LOGLEVEL=info
```
Advanced logging:
```bash
export LOGLEVEL=debug
```
## Local Docker Development with Live Reload
To facilitate local development with live reload, you can use Docker. Follow the steps below:
### 1. Create Dockerfile.dev
<CodeGroup>
```dockerfile Dockerfile.dev
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
EXPOSE 5555
ENV FLASK_ENV=development
CMD ["flask", "run", "--host=0.0.0.0"]
```
</CodeGroup>
### 2. Create docker-compose.yml
<CodeGroup>
```yaml docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
volumes:
- .:/app
ports:
- "5555:5555"
environment:
FLASK_ENV: development
command: flask run --host=0.0.0.0
watch:
image: alpine:latest
volumes:
- .:/app
command: sh -c "apk add --no-cache inotify-tools && while inotifywait -r -e modify,create,delete /app; do kill -HUP 1; done"
```
</CodeGroup>
### 3. Run Docker Compose
<CodeGroup>
```bash Terminal
docker-compose up
```
</CodeGroup>
This setup will allow you to develop locally with live reload, making it easier to test and iterate on your code.
+244
View File
@@ -0,0 +1,244 @@
---
title: "Chat with PDF Agents"
sidebarTitle: "Chat with PDF"
description: "Learn how to create AI agents that can intelligently chat with PDF documents using vector databases for efficient information retrieval."
icon: "file-pdf"
---
```mermaid
flowchart LR
PDF[PDF Document] --> PDFAgent[("PDF Chat Agent")]
VDB[(Vector DB)] --> PDFAgent
PDFAgent --> Chat[Chat Interface]
Chat --> |Query| VDB
Chat --> Out[Response]
style PDF fill:#8B0000,color:#fff
style PDFAgent fill:#2E8B57,color:#fff,shape:circle
style VDB fill:#4169E1,color:#fff,shape:cylinder
style Chat fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A PDF-centric workflow where Chat agents interact with vector databases to store and retrieve information from PDF documents, enabling natural conversations and intelligent question-answering capabilities.
## Quick Start
<Steps>
<Step title="Install Package">
Install PraisonAI Agents with PDF chat support:
```bash
pip install "praisonaiagents[knowledge]"
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key:
```bash
export OPENAI_API_KEY=xxxxx
```
</Step>
<Step title="Create Script">
Create a new file `chat_with_pdf.py`:
```python
from praisonaiagents import Agent
agent = Agent(
name="PDF Chat Agent",
instructions="You answer questions based on the provided PDF document.",
knowledge=["document.pdf"], # PDF Indexing
)
agent.start("What is the main topic of this PDF?") # Chat Query
```
</Step>
</Steps>
## PDF Processing and Chat Agents
<Note>
PDF processing involves indexing the document content for efficient retrieval during chat.
</Note>
```mermaid
flowchart LR
subgraph In[Input]
PDF[PDF Documents]
end
subgraph Router[Vector Store]
DB[(Vector DB)]
end
subgraph Out[Chat Agents]
A1[Chat Agent 1]
A2[Chat Agent 2]
A3[Chat Agent 3]
end
In --> Router
Router --> A1
Router --> A2
Router --> A3
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
The simplest way to create a PDF chat agent is without any configuration:
```python
from praisonaiagents import Agent
agent = Agent(
name="PDF Chat Agent",
instructions="You answer questions based on the provided PDF document.",
knowledge=["document.pdf"] # PDF Indexing
)
agent.start("What are the key points in this document?") # Chat Query
```
### Advanced Configuration
For more control over the knowledge base, you can specify a configuration:
```python
from praisonaiagents import Agent
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "praison",
"path": ".praison",
}
}
}
agent = Agent(
name="PDF Chat Agent",
instructions="You answer questions based on the provided PDF document.",
knowledge=["document.pdf"], # PDF Indexing
knowledge_config=config # Configuration
)
agent.start("What is the main topic of this PDF?") # Chat Query
```
### Multi-Agent Knowledge System
For more complex scenarios, you can create a knowledge-based system with multiple agents:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
import logging
import os
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Define the configuration for the Knowledge instance
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "praison",
"path": ".praison",
}
}
}
# Create an agent with knowledge capabilities
knowledge_agent = Agent(
name="KnowledgeAgent",
role="Information Specialist",
goal="Store and retrieve knowledge efficiently",
backstory="Expert in managing and utilizing stored knowledge",
knowledge=["sample.pdf"], # Indexing
knowledge_config=config, # Configuration
verbose=True
)
# Define a task for the agent
knowledge_task = Task(
name="knowledge_task",
description="Who is Mervin Praison?",
expected_output="Answer to the question",
agent=knowledge_agent # Agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[knowledge_agent],
tasks=[knowledge_task],
process="sequential",
user_id="user1" # User ID
)
# Start execution
result = agents.start() # Retrieval
```
## Understanding PDF Chat Agents
<Card title="What are PDF Chat Agents?" icon="question">
PDF Chat agents enable:
- Natural conversation with PDF documents
- Intelligent information extraction
- Context-aware document understanding
- Quick answers to document-specific questions
</Card>
## Features
<CardGroup cols={2}>
<Card title="PDF Processing" icon="file-pdf">
Process and index PDF documents efficiently.
</Card>
<Card title="Natural Chat" icon="comments">
Have natural conversations about PDF content.
</Card>
<Card title="Smart Retrieval" icon="brain">
Intelligently retrieve relevant information from PDFs.
</Card>
<Card title="Context Awareness" icon="layer-group">
Maintain context throughout the conversation.
</Card>
</CardGroup>
## Troubleshooting
<CardGroup cols={2}>
<Card title="PDF Issues" icon="triangle-exclamation">
If PDF processing isn't working:
- Check PDF file format and encoding
- Verify document accessibility
- Enable verbose mode for debugging
</Card>
<Card title="Chat Issues" icon="gauge-high">
If chat responses aren't accurate:
- Check PDF indexing quality
- Verify question clarity
- Monitor context retention
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="./autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="./mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal chat experience, ensure your PDFs are properly formatted and text-searchable.
</Note>
+137
View File
@@ -0,0 +1,137 @@
---
title: "Reasoning Extract Agents"
description: "Learn how to create AI agents that can perform step-by-step reasoning and extract information"
icon: "brain-circuit"
---
```mermaid
flowchart LR
In[Input] --> RA[("Reasoning Agent")]
RA --> Steps[Reasoning Steps]
Steps --> SA[("Small Agent")]
SA --> Out[Output]
style In fill:#8B0000,color:#fff
style RA fill:#2E8B57,color:#fff,shape:circle
style Steps fill:#4169E1,color:#fff
style SA fill:#2E8B57,color:#fff,shape:circle
style Out fill:#8B0000,color:#fff
```
A workflow where a reasoning agent breaks down complex problems into steps, followed by a smaller agent that processes these steps to provide concise answers.
## Prerequisites
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[llm]"
```
<Note>
praisonaiagents[llm] includes all necessary dependencies for reasoning agents
</Note>
</Step>
<Step title="Set API Key">
Configure your API key:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create File">
Create a new file called `app.py` and add the following code:
</Step>
<Step title="Run Application">
Execute the script:
```bash
python app.py
```
</Step>
</Steps>
## Code
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
reasoning_agent = Agent(
role="Helpful Assistant",
reasoning_steps=True,
llm="deepseek/deepseek-reasoner"
)
small_agent = Agent(
role="Helpful Assistant",
llm="gpt-3.5-turbo"
)
reasoning_task = Task(
description="How many r's in the word 'Strawberry'?",
agent=reasoning_agent
)
small_task = Task(
description="With the provided reasoning tell me how many r's in the word 'Strawberry'?",
agent=small_agent
)
agents = PraisonAIAgents(
agents=[reasoning_agent, small_agent],
tasks=[reasoning_task, small_task]
)
agents.start()
```
## Features
<CardGroup cols={2}>
<Card title="Step-by-Step Reasoning" icon="list-check">
Break down complex problems into logical steps.
</Card>
<Card title="Multi-Agent Collaboration" icon="users">
Combine reasoning and processing agents.
</Card>
<Card title="Flexible Models" icon="arrows-split-up-and-left">
Use different models for reasoning and processing.
</Card>
<Card title="Task Chaining" icon="link">
Connect reasoning output to processing tasks.
</Card>
</CardGroup>
## Understanding Reasoning Agents
<Card title="What are Reasoning Agents?" icon="question">
Reasoning agents enable:
- Detailed step-by-step analysis
- Logical problem decomposition
- Clear reasoning paths
- Enhanced decision making
</Card>
## Troubleshooting
<CardGroup cols={2}>
<Card title="Reasoning Issues" icon="triangle-exclamation">
If reasoning steps aren't clear:
- Check reasoning_steps parameter
- Verify model compatibility
- Review task descriptions
</Card>
<Card title="Agent Communication" icon="messages">
If agents aren't coordinating:
- Ensure task order is correct
- Check task dependencies
- Verify agent configurations
</Card>
</CardGroup>
<Note>
The reasoning agent uses a specialized model (deepseek-reasoner) optimized for step-by-step analysis, while the small agent can use a more general-purpose model for processing the reasoning output.
</Note>
+424 -124
View File
@@ -1,7 +1,7 @@
---
title: "Praison AI"
sidebarTitle: "Home"
description: "Comprehensive guide to PraisonAI - an AI Agents Framework with Self Reflection, combining PraisonAI Agents, AutoGen, and CrewAI for building multi-agent LLM systems"
description: "PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AutoGen, and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration."
icon: "house"
openGraph:
url: "/"
@@ -66,24 +66,53 @@ seo:
Internet search using Crawl4AI and Tavily
</Card>
</CardGroup>
<br />
<div className="relative w-full aspect-video overflow-hidden rounded-lg shadow-lg mb-8">
<iframe
className="absolute top-0 left-0 w-full h-full border-0"
src="https://www.youtube.com/embed/Fn1lQjC0GO0"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
style={{
maxWidth: '100vw',
margin: '0 auto'
}}
></iframe>
</div>
## Installation Options
## Install
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
</Step>
<Step title="Create File">
Create `app.py` file
## Code Example
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent
agent = Agent(instructions="Your are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
```python Multi Agents
from praisonaiagents import Agent, PraisonAIAgents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
</CodeGroup>
</Step>
<Step title="Run Script">
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Tip>
PraisonAI combines PraisonAI Agents, AutoGen, and CrewAI into a low-code solution for building and managing multi-agent LLM systems, focusing on simplicity, customization, and efficient human-agent collaboration.
@@ -109,115 +138,361 @@ seo:
</Step>
</Steps>
</Tab>
<Tab title="Code">
<Steps>
<Step title="Install Package">
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
</Step>
<Step title="Create File">
Create `app.py` file
## Code Example
<CodeGroup>
```python Basic
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Advanced
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
<Step title="Run Script">
```bash
python app.py
```
</Step>
</Steps>
</Tab>
</Tabs>
## AI Agents Flow
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## AI Agents with Tools
Create AI agents that can use tools to interact with external systems and perform actions.
```mermaid
flowchart TB
subgraph Tools
direction TB
T3[Internet Search]
T1[Code Execution]
T2[Formatting]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
T3 --> A1
T1 --> A2
T2 --> A3
style Tools fill:#189AB4,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Memory
Create AI agents with memory capabilities for maintaining context and information across tasks.
```mermaid
flowchart TB
subgraph Memory
direction TB
STM[Short Term]
LTM[Long Term]
end
subgraph Store
direction TB
DB[(Vector DB)]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
Memory <--> Store
Store <--> A1
Store <--> A2
Store <--> A3
style Memory fill:#189AB4,color:#fff
style Store fill:#2E8B57,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Different Processes
### Sequential Process
The simplest form of task execution where tasks are performed one after another.
```mermaid
graph LR
Input[Input] --> A1
subgraph Agents
direction LR
A1[Agent 1] --> A2[Agent 2] --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class A1,A2,A3 process
class Agents transparent
```
### Hierarchical Process
Uses a manager agent to coordinate task execution and agent assignments.
```mermaid
graph TB
Input[Input] --> Manager
subgraph Agents
Manager[Manager Agent]
subgraph Workers
direction LR
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
end
Manager --> W1
Manager --> W2
Manager --> W3
end
W1 --> Manager
W2 --> Manager
W3 --> Manager
Manager --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Manager,W1,W2,W3 process
class Agents,Workers transparent
```
### Workflow Process
Advanced process type supporting complex task relationships and conditional execution.
```mermaid
graph LR
Input[Input] --> Start
subgraph Workflow
direction LR
Start[Start] --> C1{Condition}
C1 --> |Yes| A1[Agent 1]
C1 --> |No| A2[Agent 2]
A1 --> Join
A2 --> Join
Join --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef decision fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Start,A1,A2,A3,Join process
class C1 decision
class Workflow transparent
```
#### Agentic Routing Workflow
Create AI agents that can dynamically route tasks to specialized LLM instances.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Out[Out]
LLM2 --> Out
LLM3 --> Out
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Orchestrator Worker
Create AI agents that orchestrate and distribute tasks among specialized workers.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Synthesizer[Synthesizer]
LLM2 --> Synthesizer
LLM3 --> Synthesizer
Synthesizer --> Out[Out]
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Autonomous Workflow
Create AI agents that can autonomously monitor, act, and adapt based on environment feedback.
```mermaid
flowchart LR
Human[Human] <--> LLM[LLM Call]
LLM -->|ACTION| Environment[Environment]
Environment -->|FEEDBACK| LLM
LLM --> Stop[Stop]
style Human fill:#8B0000,color:#fff
style LLM fill:#2E8B57,color:#fff
style Environment fill:#8B0000,color:#fff
style Stop fill:#333,color:#fff
```
#### Agentic Parallelization
Create AI agents that can execute tasks in parallel for improved performance.
```mermaid
flowchart LR
In[In] --> LLM2[LLM Call 2]
In --> LLM1[LLM Call 1]
In --> LLM3[LLM Call 3]
LLM1 --> Aggregator[Aggregator]
LLM2 --> Aggregator
LLM3 --> Aggregator
Aggregator --> Out[Out]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Aggregator fill:#fff,color:#000
style Out fill:#8B0000,color:#fff
```
#### Agentic Prompt Chaining
Create AI agents with sequential prompt chaining for complex workflows.
```mermaid
flowchart LR
In[In] --> LLM1[LLM Call 1] --> Gate{Gate}
Gate -->|Pass| LLM2[LLM Call 2] -->|Output 2| LLM3[LLM Call 3] --> Out[Out]
Gate -->|Fail| Exit[Exit]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
style Exit fill:#8B0000,color:#fff
```
#### Agentic Evaluator Optimizer
Create AI agents that can generate and optimize solutions through iterative feedback.
```mermaid
flowchart LR
In[In] --> Generator[LLM Call Generator]
Generator -->|SOLUTION| Evaluator[LLM Call Evaluator] -->|ACCEPTED| Out[Out]
Evaluator -->|REJECTED + FEEDBACK| Generator
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Evaluator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Repetitive Agents
Create AI agents that can efficiently handle repetitive tasks through automated loops.
```mermaid
flowchart LR
In[Input] --> LoopAgent[("Looping Agent")]
LoopAgent --> Task[Task]
Task --> |Next iteration| LoopAgent
Task --> |Done| Out[Output]
style In fill:#8B0000,color:#fff
style LoopAgent fill:#2E8B57,color:#fff,shape:circle
style Task fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
<br />
<div className="relative w-full aspect-video overflow-hidden rounded-lg shadow-lg mb-8">
<iframe
className="absolute top-0 left-0 w-full h-full border-0"
src="https://www.youtube.com/embed/Fn1lQjC0GO0"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
style={{
maxWidth: '100vw',
margin: '0 auto'
}}
></iframe>
</div>
## Integration Options
<AccordionGroup>
@@ -338,4 +613,29 @@ seo:
<div className="hover:opacity-80 transition-opacity">
<img src="https://img.shields.io/github/forks/MervinPraison/PraisonAI?style=social" alt="GitHub Forks" />
</div>
</div>
</div>
## Video Tutorials
| Topic | Video |
|-------|--------|
| AI Agents with Self Reflection | [![Self Reflection](https://img.youtube.com/vi/vLXobEN2Vc8/0.jpg)](https://www.youtube.com/watch?v=vLXobEN2Vc8) |
| AI Agents with Reasoning | [![Reasoning](https://img.youtube.com/vi/KNDVWGN3TpM/0.jpg)](https://www.youtube.com/watch?v=KNDVWGN3TpM) |
| Multimodal AI Agents | [![Multimodal](https://img.youtube.com/vi/hjAWmUT1qqY/0.jpg)](https://www.youtube.com/watch?v=hjAWmUT1qqY) |
| AI Agents Workflow | [![Workflow](https://img.youtube.com/vi/yWTH44QPl2A/0.jpg)](https://www.youtube.com/watch?v=yWTH44QPl2A) |
| Async AI Agents | [![Async](https://img.youtube.com/vi/VhVQfgo00LE/0.jpg)](https://www.youtube.com/watch?v=VhVQfgo00LE) |
| Mini AI Agents | [![Mini](https://img.youtube.com/vi/OkvYp5aAGSg/0.jpg)](https://www.youtube.com/watch?v=OkvYp5aAGSg) |
| AI Agents with Memory | [![Memory](https://img.youtube.com/vi/1hVfVxvPnnQ/0.jpg)](https://www.youtube.com/watch?v=1hVfVxvPnnQ) |
| Repetitive Agents | [![Repetitive](https://img.youtube.com/vi/dAYGxsjDOPg/0.jpg)](https://www.youtube.com/watch?v=dAYGxsjDOPg) |
| Introduction | [![Introduction](https://img.youtube.com/vi/Fn1lQjC0GO0/0.jpg)](https://www.youtube.com/watch?v=Fn1lQjC0GO0) |
| Tools Overview | [![Tools Overview](https://img.youtube.com/vi/XaQRgRpV7jo/0.jpg)](https://www.youtube.com/watch?v=XaQRgRpV7jo) |
| Custom Tools | [![Custom Tools](https://img.youtube.com/vi/JSU2Rndh06c/0.jpg)](https://www.youtube.com/watch?v=JSU2Rndh06c) |
| Firecrawl Integration | [![Firecrawl](https://img.youtube.com/vi/UoqUDcLcOYo/0.jpg)](https://www.youtube.com/watch?v=UoqUDcLcOYo) |
| User Interface | [![UI](https://img.youtube.com/vi/tg-ZjNl3OCg/0.jpg)](https://www.youtube.com/watch?v=tg-ZjNl3OCg) |
| Crawl4AI Integration | [![Crawl4AI](https://img.youtube.com/vi/KAvuVUh0XU8/0.jpg)](https://www.youtube.com/watch?v=KAvuVUh0XU8) |
| Chat Interface | [![Chat](https://img.youtube.com/vi/sw3uDqn2h1Y/0.jpg)](https://www.youtube.com/watch?v=sw3uDqn2h1Y) |
| Code Interface | [![Code](https://img.youtube.com/vi/_5jQayO-MQY/0.jpg)](https://www.youtube.com/watch?v=_5jQayO-MQY) |
| Mem0 Integration | [![Mem0](https://img.youtube.com/vi/KIGSgRxf1cY/0.jpg)](https://www.youtube.com/watch?v=KIGSgRxf1cY) |
| Training | [![Training](https://img.youtube.com/vi/aLawE8kwCrI/0.jpg)](https://www.youtube.com/watch?v=aLawE8kwCrI) |
| Realtime Voice Interface | [![Realtime](https://img.youtube.com/vi/frRHfevTCSw/0.jpg)](https://www.youtube.com/watch?v=frRHfevTCSw) |
| Call Interface | [![Call](https://img.youtube.com/vi/m1cwrUG2iAk/0.jpg)](https://www.youtube.com/watch?v=m1cwrUG2iAk) |
+99 -121
View File
@@ -89,143 +89,121 @@ graph LR
## Getting Started is Easy
<Tabs>
<Tab title="Code">
<Steps>
<Steps>
<Step title="Install Package">
Install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys).
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agents">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, PraisonAIAgents
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create a simple agent
summarise_agent = Agent(instructions="Summarise Photosynthesis")
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Run the agent
agents = PraisonAIAgents(agents=[summarise_agent])
agents.start()
```
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
```python Multiple Agents
from praisonaiagents import Agent, PraisonAIAgents
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
# Create agents with specific roles
diet_agent = Agent(
instructions="Give me 5 healthy food recipes",
)
result = agents.start()
```
blog_agent = Agent(
instructions="Write a blog post about the food recipes",
)
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Run multiple agents
agents = PraisonAIAgents(agents=[diet_agent, blog_agent])
agents.start()
```
</CodeGroup>
</Step>
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
<Step title="Run Agents">
Execute your script:
```bash
python app.py
```
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
</Step>
</Steps>
</Tab>
You'll see:
- Agent initialization
- Task execution progress
- Final results
<Tip>
You have successfully CreatedAI Agents and made them work for you!
</Tip>
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the No Code PraisonAI Package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Install PraisonAI">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY=your_openai_key
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Config">
Create `agents.yaml`:
<Step title="Start AutoAgents">
Run your AutoAgents:
```bash
praisonai --auto "Create a movie script about a robot in Mars"
```
</Step>
<CodeGroup>
```yaml Single Agent
roles:
summarise_agent:
instructions: Summarise Photosynthesis
```
```yaml Multiple Agents
roles:
diet_agent:
instructions: Give me 5 healthy food recipes
blog_agent:
instructions: Write a blog post about the food recipes
```
</CodeGroup>
<Note>
You can automatically create `agents.yaml` using:
```bash
praisonai --init "your task description"
```
</Note>
</Step>
<Step title="Run Agents">
Execute your config:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
+8 -2
View File
@@ -118,6 +118,7 @@
"features/autoagents",
"features/selfreflection",
"features/rag",
"features/reasoning-extract",
"features/reasoning",
"features/multimodal",
"features/langchain",
@@ -126,7 +127,8 @@
"features/codeagent",
"features/mathagent",
"features/structured",
"features/callbacks"
"features/callbacks",
"features/chat-with-pdf"
]
},
{
@@ -251,7 +253,10 @@
"pages": [
"ui/streamlit",
"ui/streamlit/code-analysis-streamlit",
"ui/streamlit/hackathon-judge-streamlit"
"ui/streamlit/hackathon-judge-streamlit",
"ui/streamlit/ollama-streamlit",
"ui/streamlit/deepseek-streamlit",
"ui/streamlit/gemini-streamlit"
]
},
"ui/ui",
@@ -272,6 +277,7 @@
"developers/wrapper-tools",
"developers/googlecolab",
"developers/googlecolab-tools",
"developers/local-development",
"deploy"
]
},
+178 -1
View File
@@ -4,7 +4,184 @@ description: "Overview of supported language models in PraisonAI, including Open
icon: "brain"
---
## Supported Models for Code
# Code
## Set model by 3 ways
### 1. OpenAI Compatible Endpoints
<Note>By Default it uses OPENAI_BASE_URL https://api.openai.com/v1 </Note>
Example Groq Implementation:
```bash
export OPENAI_API_KEY=groq-api-key
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
```
```python
from praisonaiagents import Agent
agent = Agent(
instructions="You are a helpful assistant",
llm="llama-3.1-8b-instant",
)
agent.start("Why sky is Blue?")
```
### 2. Litellm Compatible model names (eg: gemini/gemini-1.5-flash-8b)
```bash
pip install "praisonaiagents[llm]"
```
```python
from praisonaiagents import Agent
agent = Agent(
instructions="You are a helpful assistant",
llm="gemini/gemini-1.5-flash-8b",
self_reflect=True,
verbose=True
)
agent.start("Why sky is Blue?")
```
### 3. Litellm Compatible Configuration
```bash
pip install "praisonaiagents[llm]"
```
```python
from praisonaiagents import Agent
llm_config = {
"model": "gemini/gemini-1.5-flash-latest", # Model name without provider prefix
# Core settings
"temperature": 0.7, # Controls randomness (like temperature)
"timeout": 30, # Timeout in seconds
"top_p": 0.9, # Nucleus sampling parameter
"max_tokens": 1000, # Max tokens in response
# Advanced parameters
"presence_penalty": 0.1, # Penalize repetition of topics (-2.0 to 2.0)
"frequency_penalty": 0.1, # Penalize token repetition (-2.0 to 2.0)
# API settings (optional)
"api_key": None, # Your API key (or use environment variable)
"base_url": None, # Custom API endpoint if needed
# Response formatting
"response_format": { # Force specific response format
"type": "text" # Options: "text", "json_object"
},
# Additional controls
"seed": 42, # For reproducible responses
"stop_phrases": ["##", "END"], # Custom stop sequences
}
agent = Agent(
instructions="You are a helpful Assistant."
llm=llm_config
)
agent.start()
```
## Advanced Configuration (Litellm Support)
<Note>This uses Litellm</Note>
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[llm]"
```
</Step>
<Step title="Setup Environment">
Configure environment:
```bash
export GOOGLE_API_KEY=your-api-key
```
<Note>
Get your API key from [Google AI Studio](https://makersuite.google.com/app/apikey)
</Note>
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Basic
# if json_object is supported by the model
from praisonaiagents import Agent
agent = Agent(
instructions="You are a helpful assistant",
llm="gemini/gemini-1.5-flash-8b",
self_reflect=True,
verbose=True
)
agent.start("Why sky is Blue?")
```
```python Advanced
# if json_object is not supported by the model
from praisonaiagents import Agent
# Detailed LLM configuration
llm_config = {
"model": "gemini/gemini-1.5-flash-latest", # Model name without provider prefix
# Core settings
"temperature": 0.7, # Controls randomness (like temperature)
"timeout": 30, # Timeout in seconds
"top_p": 0.9, # Nucleus sampling parameter
"max_tokens": 1000, # Max tokens in response
# Advanced parameters
"presence_penalty": 0.1, # Penalize repetition of topics (-2.0 to 2.0)
"frequency_penalty": 0.1, # Penalize token repetition (-2.0 to 2.0)
# API settings (optional)
"api_key": None, # Your API key (or use environment variable)
"base_url": None, # Custom API endpoint if needed
# Response formatting
"response_format": { # Force specific response format
"type": "text" # Options: "text", "json_object"
},
# Additional controls
"seed": 42, # For reproducible responses
"stop_phrases": ["##", "END"], # Custom stop sequences
}
agent = Agent(
instructions="You are a helpful Assistant specialized in scientific explanations. "
"Provide clear, accurate, and engaging responses.",
llm=llm_config, # Pass the detailed configuration
verbose=True, # Enable detailed output
markdown=True, # Format responses in markdown
self_reflect=True, # Enable self-reflection
max_reflect=3, # Maximum reflection iterations
min_reflect=1 # Minimum reflection iterations
)
# Test the agent
response = agent.start("Why is the sky blue? Please explain in simple terms.")
```
</CodeGroup>
</Step>
</Steps>
<AccordionGroup>
<Accordion title="Ollama Integration" defaultOpen>
+43
View File
@@ -115,6 +115,49 @@ agents.start()
This uses Litellm to connect to Google Gemini.
</Note>
## Gemini 2.0 Flash Thinking
### LLM Configuration
```python
llm_config = {
"model": "gemini/gemini-2.0-flash-thinking-exp-01-21",
"response_format": {"type": "text"} # type is text, because json_object is not supported
}
```
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[llm]"
```
</Step>
<Step title="Set API Key">
Set your Gemini API key:
```bash
export GEMINI_API_KEY=xxxxxxxxxxx
```
</Step>
<Step title="Code">
```python
from praisonaiagents import Agent
llm_config = {"model": "gemini/gemini-2.0-flash-thinking-exp-01-21","response_format": {"type": "text"}}
agent = Agent(
instructions="You are a helpful assistant",
llm=llm_config
)
result = agent.start("Why sky is Blue?")
print(result)
```
</Step>
</Steps>
## Alternative Setup
### Using Environment Variables
+158
View File
@@ -0,0 +1,158 @@
---
title: "Deepseek Streamlit UI"
description: "Create interactive chat interfaces with Deepseek models using Streamlit"
icon: "window"
---
```mermaid
flowchart LR
In[Input] --> UI[("Streamlit UI")]
VDB[(Vector DB)] --> Agent
DS[("Deepseek")] --> Agent
UI --> Agent[("Knowledge Agent")]
Agent --> |Query| VDB
Agent --> Out[Output]
Out --> UI
style In fill:#8B0000,color:#fff
style UI fill:#FF4B4B,color:#fff,shape:circle
style DS fill:#4169E1,color:#fff,shape:circle
style Agent fill:#2E8B57,color:#fff,shape:circle
style VDB fill:#4169E1,color:#fff,shape:cylinder
style Out fill:#8B0000,color:#fff
```
## Prerequisites
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[knowledge]" streamlit ollama
```
<Note>
streamlit for UI
ollama for Deepseek model hosting
praisonaiagents[knowledge] for RAG capabilities
</Note>
</Step>
<Step title="Setup Model">
Pull Deepseek model:
```bash
# Large Language Model
ollama pull deepseek-r1
# Embedding Model
ollama pull nomic-embed-text
```
</Step>
<Step title="Setup Environment">
Configure environment:
```bash
export OPENAI_BASE_URL=http://localhost:11434/v1
export OPENAI_API_KEY=fake-key
```
</Step>
<Step title="Create File">
Create a new file called `app.py` and add the following code:
</Step>
<Step title="Run Application">
Start the Streamlit application:
```bash
streamlit run app.py
```
</Step>
</Steps>
## Code
```python
import streamlit as st
from praisonaiagents import Agent
def init_agent():
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "praison",
"path": ".praison"
}
},
"llm": {
"provider": "ollama",
"config": {
"model": "deepseek-r1:latest",
"temperature": 0,
"max_tokens": 8000,
"ollama_base_url": "http://localhost:11434",
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": "nomic-embed-text:latest",
"ollama_base_url": "http://localhost:11434",
"embedding_dims": 1536
},
},
}
return Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"],
knowledge_config=config,
user_id="user1",
llm="deepseek-r1"
)
st.title("Knowledge Agent Chat")
if "agent" not in st.session_state:
st.session_state.agent = init_agent()
st.session_state.messages = []
if "messages" in st.session_state:
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
prompt = st.chat_input("Ask a question...")
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
response = st.session_state.agent.start(prompt)
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
```
## Features
<CardGroup cols={2}>
<Card title="Interactive Chat" icon="comments">
Real-time chat interface with message history.
</Card>
<Card title="Knowledge Base" icon="database">
RAG capabilities with ChromaDB integration.
</Card>
<Card title="Model Integration" icon="server">
Uses Deepseek through Ollama.
</Card>
<Card title="Session Management" icon="clock-rotate-left">
Maintains chat history in session state.
</Card>
</CardGroup>
<Note>
Make sure your system meets the requirements for running Deepseek models locally through Ollama.
</Note>
+119
View File
@@ -0,0 +1,119 @@
---
title: "Gemini Streamlit UI"
description: "Create interactive chat interfaces with Google's Gemini models using Streamlit"
icon: "window"
---
```mermaid
flowchart LR
In[Input] --> UI[("Streamlit UI")]
VDB[(Vector DB)] --> Agent
Gemini[("Gemini")] --> Agent
UI --> Agent[("Knowledge Agent")]
Agent --> |Query| VDB
Agent --> Out[Output]
Out --> UI
style In fill:#8B0000,color:#fff
style UI fill:#FF4B4B,color:#fff,shape:circle
style Gemini fill:#4169E1,color:#fff,shape:circle
style Agent fill:#2E8B57,color:#fff,shape:circle
style VDB fill:#4169E1,color:#fff,shape:cylinder
style Out fill:#8B0000,color:#fff
```
## Prerequisites
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[llm]" streamlit
```
<Note>
streamlit for UI<br />
praisonaiagents[llm] for Gemini model access (It uses Litellm)
</Note>
</Step>
<Step title="Setup Environment">
Configure environment:
```bash
export GOOGLE_API_KEY=your-api-key
```
<Note>
Get your API key from [Google AI Studio](https://makersuite.google.com/app/apikey)
</Note>
</Step>
<Step title="Create File">
Create a new file called `app.py` and add the following code:
</Step>
<Step title="Run Application">
Start the Streamlit application:
```bash
streamlit run app.py
```
</Step>
</Steps>
## Code
```python
import streamlit as st
from praisonaiagents import Agent
st.title("Gemini 2.0 Thinking AI Agent")
# Initialize the agent
@st.cache_resource
def get_agent():
llm_config = {
"model": "gemini/gemini-2.0-flash-thinking-exp-01-21",
"response_format": {"type": "text"}
}
return Agent(
instructions="You are a helpful assistant",
llm=llm_config
)
agent = get_agent()
# Create text area input field
user_question = st.text_area("Ask your question:", height=150)
# Add ask button
if st.button("Ask"):
if user_question:
with st.spinner('Thinking...'):
result = agent.start(user_question)
st.write("### Answer")
st.write(result)
else:
st.warning("Please enter a question")
```
## Features
<CardGroup cols={2}>
<Card title="Interactive Chat" icon="comments">
Real-time chat interface with message history.
</Card>
<Card title="Knowledge Base" icon="database">
RAG capabilities with ChromaDB integration.
</Card>
<Card title="Model Integration" icon="server">
Uses Google's Gemini Pro model.
</Card>
<Card title="Session Management" icon="clock-rotate-left">
Maintains chat history in session state.
</Card>
</CardGroup>
<Note>
Make sure you have a valid Google API key and sufficient quota for using Gemini models.
</Note>
+158
View File
@@ -0,0 +1,158 @@
---
title: "Ollama Streamlit UI"
description: "Create interactive chat interfaces with Ollama models using Streamlit"
icon: "window"
---
```mermaid
flowchart LR
In[Input] --> UI[("Streamlit UI")]
VDB[(Vector DB)] --> Agent
Ollama[("Ollama")] --> Agent
UI --> Agent[("Knowledge Agent")]
Agent --> |Query| VDB
Agent --> Out[Output]
Out --> UI
style In fill:#8B0000,color:#fff
style UI fill:#FF4B4B,color:#fff,shape:circle
style Ollama fill:#4169E1,color:#fff,shape:circle
style Agent fill:#2E8B57,color:#fff,shape:circle
style VDB fill:#4169E1,color:#fff,shape:cylinder
style Out fill:#8B0000,color:#fff
```
## Prerequisites
<Steps>
<Step title="Install Package">
Install required packages:
```bash
pip install "praisonaiagents[knowledge]" streamlit ollama
```
<Note>
streamlit for UI
ollama for model hosting
praisonaiagents[knowledge] for RAG capabilities
</Note>
</Step>
<Step title="Setup Model">
Pull Ollama models:
```bash
# Large Language Model
ollama pull deepseek-r1
# Embedding Model
ollama pull nomic-embed-text
```
</Step>
<Step title="Setup Environment">
Configure environment:
```bash
export OPENAI_BASE_URL=http://localhost:11434/v1
export OPENAI_API_KEY=fake-key
```
</Step>
<Step title="Create File">
Create a new file called `app.py` and add the following code:
</Step>
<Step title="Run Application">
Start the Streamlit application:
```bash
streamlit run app.py
```
</Step>
</Steps>
## Code
```python
import streamlit as st
from praisonaiagents import Agent
def init_agent():
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "praison",
"path": ".praison"
}
},
"llm": {
"provider": "ollama",
"config": {
"model": "deepseek-r1:latest",
"temperature": 0,
"max_tokens": 8000,
"ollama_base_url": "http://localhost:11434",
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": "nomic-embed-text:latest",
"ollama_base_url": "http://localhost:11434",
"embedding_dims": 1536
},
},
}
return Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"],
knowledge_config=config,
user_id="user1",
llm="deepseek-r1"
)
st.title("Knowledge Agent Chat")
if "agent" not in st.session_state:
st.session_state.agent = init_agent()
st.session_state.messages = []
if "messages" in st.session_state:
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
prompt = st.chat_input("Ask a question...")
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
response = st.session_state.agent.start(prompt)
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
```
## Features
<CardGroup cols={2}>
<Card title="Interactive Chat" icon="comments">
Real-time chat interface with message history.
</Card>
<Card title="Knowledge Base" icon="database">
RAG capabilities with ChromaDB integration.
</Card>
<Card title="Model Integration" icon="server">
Uses Ollama for local model hosting.
</Card>
<Card title="Session Management" icon="clock-rotate-left">
Maintains chat history in session state.
</Card>
</CardGroup>
<Note>
Make sure your system meets the requirements for running models locally through Ollama.
</Note>
+32
View File
@@ -0,0 +1,32 @@
import streamlit as st
from praisonaiagents import Agent
st.title("Gemini 2.0 Thinking AI Agent")
# Initialize the agent
@st.cache_resource
def get_agent():
llm_config = {
"model": "gemini/gemini-2.0-flash-thinking-exp-01-21",
"response_format": {"type": "text"}
}
return Agent(
instructions="You are a helpful assistant",
llm=llm_config
)
agent = get_agent()
# Create text area input field
user_question = st.text_area("Ask your question:", height=150)
# Add ask button
if st.button("Ask"):
if user_question:
with st.spinner('Thinking...'):
result = agent.start(user_question)
st.write("### Answer")
st.write(result)
else:
st.warning("Please enter a question")
@@ -0,0 +1,62 @@
import streamlit as st
from praisonaiagents import Agent
def init_agent():
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "praison",
"path": ".praison"
}
},
"llm": {
"provider": "ollama",
"config": {
"model": "deepseek-r1:latest",
"temperature": 0,
"max_tokens": 8000,
"ollama_base_url": "http://localhost:11434",
},
},
"embedder": {
"provider": "ollama",
"config": {
"model": "nomic-embed-text:latest",
"ollama_base_url": "http://localhost:11434",
"embedding_dims": 1536
},
},
}
return Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["kag-research-paper.pdf"],
knowledge_config=config,
user_id="user1",
llm="deepseek-r1"
)
st.title("Knowledge Agent Chat")
if "agent" not in st.session_state:
st.session_state.agent = init_agent()
st.session_state.messages = []
if "messages" in st.session_state:
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
prompt = st.chat_input("Ask a question...")
if prompt:
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
with st.chat_message("assistant"):
response = st.session_state.agent.start(prompt)
st.markdown(response)
st.session_state.messages.append({"role": "assistant", "content": response})
+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/2.0.56.tar.gz"
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.0.59.tar.gz"
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
license "MIT"
+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==2.0.56 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.0.59 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+4 -4
View File
@@ -1,6 +1,6 @@
[project]
name = "PraisonAI"
version = "2.0.56"
version = "2.0.59"
description = "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."
readme = "README.md"
license = ""
@@ -12,7 +12,7 @@ dependencies = [
"rich>=13.7",
"markdown>=3.5",
"pyparsing>=3.0.0",
"praisonaiagents>=0.0.49",
"praisonaiagents>=0.0.56",
"python-dotenv>=0.19.0",
"instructor>=1.3.3",
"PyYAML>=6.0",
@@ -84,7 +84,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.7", "crewai"]
[tool.poetry]
name = "PraisonAI"
version = "2.0.56"
version = "2.0.59"
description = "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."
authors = ["Mervin Praison"]
license = ""
@@ -102,7 +102,7 @@ python = ">=3.10,<3.13"
rich = ">=13.7"
markdown = ">=3.5"
pyparsing = ">=3.0.0"
praisonaiagents = ">=0.0.49"
praisonaiagents = ">=0.0.56"
python-dotenv = ">=0.19.0"
instructor = ">=1.3.3"
PyYAML = ">=6.0"
View File
File renamed without changes.
Generated
+5 -5
View File
@@ -3060,7 +3060,7 @@ wheels = [
[[package]]
name = "praisonai"
version = "2.0.56"
version = "2.0.59"
source = { editable = "." }
dependencies = [
{ name = "instructor" },
@@ -3197,7 +3197,7 @@ requires-dist = [
{ name = "plotly", marker = "extra == 'realtime'", specifier = ">=5.24.0" },
{ name = "praisonai-tools", marker = "extra == 'autogen'", specifier = ">=0.0.7" },
{ name = "praisonai-tools", marker = "extra == 'crewai'", specifier = ">=0.0.7" },
{ name = "praisonaiagents", specifier = ">=0.0.49" },
{ name = "praisonaiagents", specifier = ">=0.0.56" },
{ name = "pyautogen", marker = "extra == 'autogen'", specifier = ">=0.2.19" },
{ name = "pydantic", marker = "extra == 'chat'", specifier = "<=2.10.1" },
{ name = "pydantic", marker = "extra == 'code'", specifier = "<=2.10.1" },
@@ -3250,16 +3250,16 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.49"
version = "0.0.56"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "openai" },
{ name = "pydantic" },
{ name = "rich" },
]
sdist = { url = "https://files.pythonhosted.org/packages/3c/8a/521d13124d338c5b9d397214656b7f76377ef65c885bcb3859a1484997c5/praisonaiagents-0.0.49.tar.gz", hash = "sha256:257e8572866edb989ed8c3808afec66f65ccdd47f47b5e8916a319863a01cc28", size = 85081 }
sdist = { url = "https://files.pythonhosted.org/packages/1f/d0/5b3ee6832c4797cb6dd47496485789e13113014d501856c2b5b286e7108c/praisonaiagents-0.0.56.tar.gz", hash = "sha256:148b6400403a7ad05b105084640e7140799e4e3bfb23a844bb79e10ea98bf859", size = 88236 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/59/64/a80c2cbb760d4fa73383e661301cfacacb49598686fe0da79da3deed9d05/praisonaiagents-0.0.49-py3-none-any.whl", hash = "sha256:b5b1abb9dc668e0f238282c546b76ddbfc51a6d463c6cbc8cf8da4b829a14ff1", size = 103198 },
{ url = "https://files.pythonhosted.org/packages/1a/7e/1da42b51510d3bef28f4d450824d7d14fdd2358981adf7c5b8251e586526/praisonaiagents-0.0.56-py3-none-any.whl", hash = "sha256:b198c60a8909c39b2ced09e0c7cc1ad6224af15b8c743f6890ef3985fae4d036", size = 106340 },
]
[[package]]