mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-09 17:31:52 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc393e1211 | ||
|
|
fdff17faf9 | ||
|
|
b3d893fae1 | ||
|
|
d92dede515 | ||
|
|
a1882233dc | ||
|
|
c540ba34fb | ||
|
|
0abb1b659a | ||
|
|
81adb28688 | ||
|
|
5fbe6e948c | ||
|
|
6128e4c885 | ||
|
|
0e563989ed | ||
|
|
510a853e05 | ||
|
|
d6084cb7ce | ||
|
|
8d4b1c411b | ||
|
|
3be05c855b | ||
|
|
3e5a2f76f4 | ||
|
|
8eee881d2e | ||
|
|
d75f4be41a | ||
|
|
9ea89448ef | ||
|
|
0a5e2df278 | ||
|
|
cc3b64f89b | ||
|
|
546dc5a441 | ||
|
|
bd7422c7ca | ||
|
|
0c2c6da8dd | ||
|
|
b43688086f | ||
|
|
820619e8d9 | ||
|
|
798fe68908 | ||
|
|
95796cd4c7 | ||
|
|
eaf337b301 | ||
|
|
2f73cf1882 | ||
|
|
680949742e | ||
|
|
560219dcd7 |
No files matched your search
@@ -20,7 +20,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
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.
|
||||
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, AG2 (Formerly 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">
|
||||
@@ -548,7 +548,7 @@ uv pip install -r pyproject.toml --extra "crewai,autogen"
|
||||
|
||||
## Other Features
|
||||
|
||||
- 🔄 Use CrewAI or AutoGen Framework
|
||||
- 🔄 Use CrewAI or AG2 (Formerly AutoGen) Framework
|
||||
- 💻 Chat with ENTIRE Codebase
|
||||
- 🎨 Interactive UIs
|
||||
- 📄 YAML-based Configuration
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==2.1.0 gunicorn markdown
|
||||
RUN pip install flask praisonai==2.1.1 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -30,7 +30,7 @@ Features:
|
||||
- Built-in tools
|
||||
- Structured workflows
|
||||
|
||||
### AutoGen Integration
|
||||
### AG2 (Formerly AutoGen) Integration
|
||||
Requires installation with:
|
||||
```bash
|
||||
pip install "praisonai[autogen]"
|
||||
|
||||
+4
-4
@@ -23,7 +23,7 @@ from praisonai.auto import AutoGenerator
|
||||
### praisonai.agents_generator
|
||||
Framework-specific agent generation and orchestration:
|
||||
- CrewAI support (requires `praisonai[crewai]`)
|
||||
- AutoGen support (requires `praisonai[autogen]`)
|
||||
- AG2 (Formerly AutoGen) support (requires `praisonai[autogen]`)
|
||||
|
||||
```python
|
||||
from praisonai.agents_generator import AgentsGenerator
|
||||
@@ -51,7 +51,7 @@ pip install praisonai
|
||||
|
||||
# Framework-specific installations
|
||||
pip install "praisonai[crewai]" # Install with CrewAI support
|
||||
pip install "praisonai[autogen]" # Install with AutoGen support
|
||||
pip install "praisonai[autogen]" # Install with AG2 support
|
||||
pip install "praisonai[crewai,autogen]" # Install both frameworks
|
||||
|
||||
# Additional features
|
||||
@@ -71,9 +71,9 @@ When installing with `pip install "praisonai[crewai]"`, you get:
|
||||
- Task delegation capabilities
|
||||
- Sequential and parallel task execution
|
||||
|
||||
### AutoGen
|
||||
### AG2 (Formerly AutoGen)
|
||||
When installing with `pip install "praisonai[autogen]"`, you get:
|
||||
- AutoGen framework support
|
||||
- AG2 framework support
|
||||
- PraisonAI tools integration
|
||||
- Multi-agent conversation capabilities
|
||||
- Code execution environment
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
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.1.0 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.1.1 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -65,14 +65,14 @@ def basic(): # Basic Mode
|
||||
def advanced(): # Advanced Mode with options
|
||||
praisonai = PraisonAI(
|
||||
agent_file="agents.yaml",
|
||||
framework="autogen",
|
||||
framework="autogen", # use AG2 framework (Formerly AutoGen)
|
||||
)
|
||||
praisonai.run()
|
||||
|
||||
def auto(): # Full Automatic Mode
|
||||
praisonai = PraisonAI(
|
||||
auto="Create a movie script about car in mars",
|
||||
framework="autogen"
|
||||
framework="autogen" # use AG2 framework
|
||||
)
|
||||
print(praisonai.framework)
|
||||
praisonai.run()
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: "AutoGen with PraisonAI"
|
||||
description: "Guide for using AutoGen framework with PraisonAI, including installation, setup, and multi-agent conversation capabilities"
|
||||
title: "AG2 with PraisonAI"
|
||||
description: "Guide for using AG2 framework with PraisonAI, including installation, setup, and multi-agent conversation capabilities"
|
||||
icon: "robot"
|
||||
---
|
||||
|
||||
# AutoGen with PraisonAI
|
||||
# AG2 with PraisonAI
|
||||
|
||||
Low-code solution to run AutoGen with integrated tools and features.
|
||||
Low-code solution to run AG2 with integrated tools and features.
|
||||
AutoGen is being evolved into AG2, check the new look [here](https://docs.ag2.ai/docs/Home/)
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -16,7 +17,7 @@ pip install "praisonai[autogen]"
|
||||
```
|
||||
|
||||
This installation includes:
|
||||
- AutoGen framework
|
||||
- AG2 framework
|
||||
- PraisonAI tools integration
|
||||
- Multi-agent conversation capabilities
|
||||
- Code execution environment
|
||||
@@ -27,7 +28,7 @@ This installation includes:
|
||||
# Set your OpenAI API key
|
||||
export OPENAI_API_KEY=xxxxxxxxxx
|
||||
|
||||
# Initialize with AutoGen
|
||||
# Initialize with AG2
|
||||
praisonai --framework autogen --init "Create a Movie Script About Cat in Mars"
|
||||
|
||||
# Run the agents
|
||||
|
||||
+6
-6
@@ -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: "Comprehensive guide to PraisonAI - an AI Agents Framework with Self Reflection, combining PraisonAI Agents, AG2 (Formerly AutoGen), and CrewAI for building multi-agent LLM systems"
|
||||
icon: "house"
|
||||
openGraph:
|
||||
url: "/"
|
||||
@@ -46,7 +46,7 @@ seo:
|
||||
</div>
|
||||
|
||||
<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.
|
||||
PraisonAI combines PraisonAI Agents, AG2 (Formerly 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.
|
||||
</Tip>
|
||||
|
||||
## Key Features
|
||||
@@ -56,7 +56,7 @@ seo:
|
||||
Automated creation and management of AI agents with self-reflection capabilities
|
||||
</Card>
|
||||
<Card title="Framework Integration" icon="puzzle-piece">
|
||||
Seamless integration with CrewAI and AutoGen frameworks
|
||||
Seamless integration with CrewAI and AG2 frameworks
|
||||
</Card>
|
||||
<Card title="LLM Support" icon="brain">
|
||||
Support for 100+ Language Learning Models
|
||||
@@ -301,8 +301,8 @@ seo:
|
||||
<Card title="CrewAI Framework" icon="users-gear" href="/framework/crewai">
|
||||
Build collaborative AI teams with CrewAI integration
|
||||
</Card>
|
||||
<Card title="AutoGen Framework" icon="robot" href="/framework/autogen">
|
||||
Create autonomous agent networks using AutoGen
|
||||
<Card title="AG2 Framework" icon="robot" href="/framework/autogen">
|
||||
Create autonomous agent networks using AG2 (Formerly AutoGen)
|
||||
</Card>
|
||||
<Card title="Multimodal Agents" icon="icons" href="/framework/multimodalagents">
|
||||
Work with agents that can process text, images, and other data types
|
||||
@@ -316,7 +316,7 @@ seo:
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Multi Agents UI" icon="users" href="/ui/ui">
|
||||
Work with CrewAI or AutoGen multi-agent systems
|
||||
Work with CrewAI or AG2 multi-agent systems
|
||||
</Card>
|
||||
<Card title="Chat Interface" icon="comments" href="/ui/chat">
|
||||
Chat with 100+ LLMs using a single AI Agent
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: "Praison AI"
|
||||
sidebarTitle: "Home"
|
||||
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."
|
||||
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, AG2 (Formerly 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: "/"
|
||||
@@ -45,7 +45,7 @@ seo:
|
||||
Automated creation and management of AI agents with self-reflection capabilities
|
||||
</Card>
|
||||
<Card title="Framework Integration" icon="puzzle-piece">
|
||||
Seamless integration with CrewAI and AutoGen frameworks
|
||||
Seamless integration with CrewAI and AG2 frameworks
|
||||
</Card>
|
||||
<Card title="LLM Support" icon="brain">
|
||||
Support for 100+ Language Learning Models
|
||||
@@ -711,8 +711,8 @@ flowchart LR
|
||||
<Card title="CrewAI Framework" icon="users-gear" href="/framework/crewai">
|
||||
Build collaborative AI teams with CrewAI integration
|
||||
</Card>
|
||||
<Card title="AutoGen Framework" icon="robot" href="/framework/autogen">
|
||||
Create autonomous agent networks using AutoGen
|
||||
<Card title="AG2 Framework" icon="robot" href="/framework/autogen">
|
||||
Create autonomous agent networks using AG2 (Formerly AutoGen)
|
||||
</Card>
|
||||
<Card title="Multimodal Agents" icon="icons" href="/framework/multimodalagents">
|
||||
Work with agents that can process text, images, and other data types
|
||||
@@ -726,7 +726,7 @@ flowchart LR
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Multi Agents UI" icon="users" href="/ui/ui">
|
||||
Work with CrewAI or AutoGen multi-agent systems
|
||||
Work with CrewAI or AG2 multi-agent systems
|
||||
</Card>
|
||||
<Card title="Chat Interface" icon="comments" href="/ui/chat">
|
||||
Chat with 100+ LLMs using a single AI Agent
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: "Anthropic MCP Integration"
|
||||
sidebarTitle: "Anthropic"
|
||||
description: "Guide for integrating Anthropic's Claude models with PraisonAI agents using MCP"
|
||||
icon: "a"
|
||||
---
|
||||
|
||||
## Add Anthropic Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your Anthropic API key as an environment variable in your terminal:
|
||||
```zsh
|
||||
export ANTHROPIC_API_KEY=your_anthropic_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `anthropic_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
anthropic_api_key = os.environ.get("ANTHROPIC_API_KEY")
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="anthropic/claude-3-7-sonnet-20250219",
|
||||
tools=MCP(
|
||||
command="npx",
|
||||
args=["-y", "@openbnb/mcp-server-airbnb", "--ignore-robots-txt"],
|
||||
env={"ANTHROPIC_API_KEY": anthropic_api_key}
|
||||
)
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python anthropic_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- Anthropic API key
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Claude 3.7 Sonnet" icon="brain">
|
||||
Leverage Anthropic's powerful Claude 3.7 Sonnet model.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Environment Variables" icon="key">
|
||||
Securely pass API keys using environment variables.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: "Gemini MCP Integration"
|
||||
sidebarTitle: "Gemini"
|
||||
description: "Guide for integrating Google's Gemini models with PraisonAI agents using MCP"
|
||||
icon: "google"
|
||||
---
|
||||
|
||||
## Add Gemini Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your Google API key as an environment variable in your terminal:
|
||||
```zsh
|
||||
export GOOGLE_API_KEY=your_google_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `gemini_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
google_api_key = os.environ.get("GOOGLE_API_KEY")
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="gemini/gemini-2.5-pro-exp-03-25",
|
||||
tools=MCP(
|
||||
command="npx",
|
||||
args=["-y", "@openbnb/mcp-server-airbnb", "--ignore-robots-txt"],
|
||||
env={"GOOGLE_API_KEY": google_api_key}
|
||||
)
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python gemini_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- Google API key for Gemini models
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Gemini 2.5 Pro" icon="brain">
|
||||
Leverage Google's advanced Gemini 2.5 Pro model.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Environment Variables" icon="key">
|
||||
Securely pass API keys using environment variables.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "Groq MCP Integration"
|
||||
sidebarTitle: "Groq"
|
||||
description: "Guide for integrating Groq models with PraisonAI agents using MCP"
|
||||
icon: "bolt"
|
||||
---
|
||||
|
||||
## Add Groq Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your Groq API key as an environment variable in your terminal:
|
||||
```bash
|
||||
export GROQ_API_KEY=your_groq_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `groq_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="groq/llama-3.2-90b-vision-preview",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python groq_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- Groq API key
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Ultra-Fast Inference" icon="bolt">
|
||||
Utilize Groq's high-performance LPU inference for rapid responses.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Advanced Models" icon="brain">
|
||||
Access to Llama 3.2 90B and other powerful models.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: "Mistral MCP Integration"
|
||||
sidebarTitle: "Mistral"
|
||||
description: "Guide for integrating Mistral models with PraisonAI agents using MCP"
|
||||
icon: "wind"
|
||||
---
|
||||
|
||||
## Add Mistral Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your Mistral API key as an environment variable in your terminal:
|
||||
```zsh
|
||||
export MISTRAL_API_KEY=your_mistral_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `mistral_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
mistral_api_key = os.environ.get("MISTRAL_API_KEY")
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="mistral/mistral-large-latest",
|
||||
tools=MCP(
|
||||
command="npx",
|
||||
args=["-y", "@openbnb/mcp-server-airbnb", "--ignore-robots-txt"],
|
||||
env={"MISTRAL_API_KEY": mistral_api_key}
|
||||
)
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python mistral_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- Mistral API key
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Mistral Large" icon="brain">
|
||||
Leverage Mistral's powerful large language model.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Environment Variables" icon="key">
|
||||
Securely pass API keys using environment variables.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: "Ollama Python MCP Integration"
|
||||
sidebarTitle: "Ollama Python"
|
||||
description: "Guide for integrating Ollama models with Python MCP servers using PraisonAI agents"
|
||||
icon: "python"
|
||||
---
|
||||
|
||||
## Add Ollama Python Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Stock Price MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#3776AB,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set Up Ollama">
|
||||
Make sure you have Ollama installed and running locally:
|
||||
```bash
|
||||
# Install Ollama from https://ollama.ai/
|
||||
# Pull the llama3.2 model
|
||||
ollama pull llama3.2
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `ollama_stock.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
stock_agent = Agent(
|
||||
instructions="""You are a Stock Price Assistant.""",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
|
||||
)
|
||||
|
||||
# NOTE: Python Path replace with yours: /Users/praison/miniconda3/envs/mcp/bin/python
|
||||
# NOTE: app.py file path, replace it with yours: /Users/praison/stockprice/app.py
|
||||
|
||||
stock_agent.start("What is the Stock Price of Apple?")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have the required packages installed:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]" yfinance mcp
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python ollama_stock.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Ollama installed and running locally
|
||||
- yfinance and mcp packages installed
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Local LLM" icon="server">
|
||||
Run models locally using Ollama without relying on external APIs.
|
||||
</Card>
|
||||
<Card title="Stock Data" icon="chart-line">
|
||||
Retrieve real-time stock price information using the yfinance library.
|
||||
</Card>
|
||||
<Card title="Python MCP" icon="python">
|
||||
Use Python-based MCP servers for custom tool functionality.
|
||||
</Card>
|
||||
<Card title="Privacy-Focused" icon="shield-alt">
|
||||
Keep sensitive data local with on-device inference.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: "Ollama MCP Integration"
|
||||
sidebarTitle: "Ollama"
|
||||
description: "Guide for integrating Ollama models with PraisonAI agents using MCP"
|
||||
icon: "dragon"
|
||||
---
|
||||
|
||||
## Add Ollama Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set Up Ollama">
|
||||
Make sure you have Ollama installed and running locally:
|
||||
```bash
|
||||
# Install Ollama from https://ollama.ai/
|
||||
# Pull the llama3.2 model
|
||||
ollama pull llama3.2
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `ollama_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python ollama_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- Ollama installed and running locally
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Local LLM" icon="server">
|
||||
Run models locally using Ollama without relying on external APIs.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Privacy-Focused" icon="shield-alt">
|
||||
Keep sensitive data local with on-device inference.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: "OpenAI MCP Integration"
|
||||
sidebarTitle: "OpenAI"
|
||||
description: "Guide for integrating OpenAI models with PraisonAI agents using MCP"
|
||||
icon: "folder-open"
|
||||
---
|
||||
|
||||
## Add OpenAI Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable in your terminal:
|
||||
```zsh
|
||||
export OPENAI_API_KEY=your_openai_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `openai_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP(
|
||||
command="npx",
|
||||
args=["-y", "@openbnb/mcp-server-airbnb", "--ignore-robots-txt"],
|
||||
env={"OPENAI_API_KEY": openai_api_key}
|
||||
)
|
||||
)
|
||||
|
||||
search_agent.start("I want to book an apartment in Paris for 2 nights. 03/28 - 03/30 for 2 adults")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```zsh
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```zsh
|
||||
python openai_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- OpenAI API key (for the agent's LLM)
|
||||
</Note>
|
||||
|
||||
## Gradio UI
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import gradio as gr
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
openai_api_key = os.environ.get("OPENAI_API_KEY")
|
||||
|
||||
def search_airbnb(query):
|
||||
agent = Agent(
|
||||
instructions="You help book apartments on Airbnb.",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP(
|
||||
command="npx",
|
||||
args=["-y", "@openbnb/mcp-server-airbnb", "--ignore-robots-txt"],
|
||||
env={"OPENAI_API_KEY": openai_api_key}
|
||||
)
|
||||
)
|
||||
result = agent.start(query)
|
||||
return f"## Airbnb Search Results\n\n{result}"
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=search_airbnb,
|
||||
inputs=gr.Textbox(placeholder="I want to book an apartment in Paris for 2 nights..."),
|
||||
outputs=gr.Markdown(),
|
||||
title="Airbnb Booking Assistant",
|
||||
description="Enter your booking requirements below:"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="GPT-4o-mini" icon="brain">
|
||||
Uses OpenAI's efficient GPT-4o-mini model for optimal performance.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Environment Variables" icon="key">
|
||||
Securely pass API keys using environment variables.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "OpenRouter MCP Integration"
|
||||
sidebarTitle: "OpenRouter"
|
||||
description: "Guide for integrating OpenRouter models with PraisonAI agents using MCP"
|
||||
icon: "network-wired"
|
||||
---
|
||||
|
||||
## Add OpenRouter Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your OpenRouter API key as an environment variable in your terminal:
|
||||
```bash
|
||||
export OPENROUTER_API_KEY=your_openrouter_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `openrouter_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="openrouter/google/gemini-2.0-flash-exp:free",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python openrouter_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- OpenRouter API key
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Model Flexibility" icon="layer-group">
|
||||
Access to various models through OpenRouter's unified API.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="Cost Effective" icon="money-bill">
|
||||
Use free tier models like Gemini Flash through OpenRouter.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
title: "Perplexity MCP Integration"
|
||||
sidebarTitle: "Perplexity"
|
||||
description: "Guide for integrating Perplexity search with PraisonAI agents using MCP"
|
||||
icon: "magnifying-glass"
|
||||
---
|
||||
|
||||
## Add Perplexity Search Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Perplexity MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#4B0082,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your Perplexity API key as an environment variable in your terminal:
|
||||
```bash
|
||||
export PERPLEXITY_API_KEY=your_perplexity_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `perplexity_search.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Get API key from environment variable
|
||||
api_key = os.getenv("PERPLEXITY_API_KEY")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant that can search the web for information. Use the available tools when relevant to answer user questions.",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("uvx perplexity-mcp",
|
||||
env={"PERPLEXITY_API_KEY": api_key, "PERPLEXITY_MODEL": "sonar" })
|
||||
)
|
||||
|
||||
result = agent.start("What is the latest news on AI?, Pass only the query parameter to the tool")
|
||||
|
||||
print(result)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have the required packages installed:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python perplexity_search.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Perplexity API key
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Web Search" icon="globe">
|
||||
Search the web for real-time information using Perplexity's powerful search API.
|
||||
</Card>
|
||||
<Card title="Sonar Model" icon="radar">
|
||||
Utilize Perplexity's Sonar model for high-quality search results.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Environment Variables" icon="key">
|
||||
Securely pass API keys using environment variables.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,248 @@
|
||||
---
|
||||
title: "MCP SSE Integration"
|
||||
sidebarTitle: "MCP SSE"
|
||||
description: "Guide for integrating Server-Sent Events (SSE) with PraisonAI agents using MCP"
|
||||
icon: "server"
|
||||
---
|
||||
|
||||
## Add SSE Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[SSE MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#4169E1,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Create a client file">
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You are a weather agent that can provide weather information for a given city.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
search_agent.start("What is the weather in London?")
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Set Up SSE MCP Server">
|
||||
|
||||
```python
|
||||
# python mcp-sse-direct-server.py --host 127.0.0.1 --port 8080
|
||||
from typing import Any
|
||||
import httpx
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from starlette.applications import Starlette
|
||||
from mcp.server.sse import SseServerTransport
|
||||
from starlette.requests import Request
|
||||
from starlette.routing import Mount, Route
|
||||
from mcp.server import Server
|
||||
import uvicorn
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import inspect
|
||||
|
||||
# Set up logging based on environment variable
|
||||
log_level = os.environ.get("LOGLEVEL", "info").upper()
|
||||
logging.basicConfig(level=getattr(logging, log_level))
|
||||
logger = logging.getLogger("mcp-server")
|
||||
|
||||
# Initialize FastMCP server for simple tools (SSE)
|
||||
mcp = FastMCP("simple-tools")
|
||||
|
||||
@mcp.tool()
|
||||
async def get_greeting(name: str) -> str:
|
||||
"""Get a personalized greeting.
|
||||
|
||||
Args:
|
||||
name: Name of the person to greet
|
||||
"""
|
||||
logger.debug(f"get_greeting called with name: {name}")
|
||||
return f"Hello, {name}! Welcome to our MCP SSE server."
|
||||
|
||||
@mcp.tool()
|
||||
async def get_weather(city: str) -> str:
|
||||
"""Get a simulated weather report for a city.
|
||||
|
||||
Args:
|
||||
city: Name of the city
|
||||
"""
|
||||
logger.debug(f"get_weather called with city: {city}")
|
||||
# This is a mock implementation
|
||||
weather_data = {
|
||||
"Paris": "Sunny with a temperature of 22°C",
|
||||
"London": "Rainy with a temperature of 15°C",
|
||||
"New York": "Cloudy with a temperature of 18°C",
|
||||
"Tokyo": "Clear skies with a temperature of 25°C",
|
||||
"Sydney": "Partly cloudy with a temperature of 20°C"
|
||||
}
|
||||
|
||||
return weather_data.get(city, f"Weather data not available for {city}")
|
||||
|
||||
def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette:
|
||||
"""Create a Starlette application that can serve the provided mcp server with SSE."""
|
||||
sse = SseServerTransport("/messages/")
|
||||
|
||||
async def handle_sse(request: Request) -> None:
|
||||
logger.debug(f"SSE connection request received from {request.client}")
|
||||
async with sse.connect_sse(
|
||||
request.scope,
|
||||
request.receive,
|
||||
request._send, # noqa: SLF001
|
||||
) as (read_stream, write_stream):
|
||||
await mcp_server.run(
|
||||
read_stream,
|
||||
write_stream,
|
||||
mcp_server.create_initialization_options(),
|
||||
)
|
||||
|
||||
return Starlette(
|
||||
debug=debug,
|
||||
routes=[
|
||||
Route("/sse", endpoint=handle_sse),
|
||||
Mount("/messages/", app=sse.handle_post_message),
|
||||
],
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp_server = mcp._mcp_server # noqa: WPS437
|
||||
|
||||
parser = argparse.ArgumentParser(description='Run MCP SSE-based server')
|
||||
parser.add_argument('--host', default='localhost', help='Host to bind to')
|
||||
parser.add_argument('--port', type=int, default=8080, help='Port to listen on')
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"Starting MCP SSE server on {args.host}:{args.port}")
|
||||
|
||||
# Hardcode the tool names since we know what they are
|
||||
tool_names = ["get_greeting", "get_weather"]
|
||||
print(f"Available tools: {', '.join(tool_names)}")
|
||||
|
||||
# Bind SSE request handling to MCP server
|
||||
starlette_app = create_starlette_app(mcp_server, debug=True)
|
||||
|
||||
uvicorn.run(starlette_app, host=args.host, port=args.port)
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have the required packages installed:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]" mcp starlette uvicorn httpx
|
||||
```
|
||||
</Step>
|
||||
<Step title="Export API Key">
|
||||
```bash
|
||||
export OPENAI_API_KEY="your_api_key"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Server and Agent">
|
||||
First, start the SSE server:
|
||||
```bash
|
||||
python mcp-sse-direct-server.py --host 127.0.0.1 --port 8080
|
||||
```
|
||||
|
||||
Then, in a new terminal, run the agent:
|
||||
```bash
|
||||
python weather_agent.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- MCP server dependencies
|
||||
</Note>
|
||||
|
||||
## Alternative LLM Integrations
|
||||
|
||||
### Using Groq with SSE
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
weather_agent = Agent(
|
||||
instructions="""You are a weather agent that can provide weather information for a given city.""",
|
||||
llm="groq/llama-3.2-90b-vision-preview",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
weather_agent.start("What is the weather in London?")
|
||||
```
|
||||
|
||||
### Using Ollama with SSE
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
weather_agent = Agent(
|
||||
instructions="""You are a weather agent that can provide weather information for a given city.""",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
weather_agent.start("What is the weather in London? Use get_weather tool, city is the required parameter.")
|
||||
```
|
||||
|
||||
## Gradio UI Integration
|
||||
|
||||
Create a Gradio UI for your weather service:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
import gradio as gr
|
||||
|
||||
def get_weather_info(query):
|
||||
weather_agent = Agent(
|
||||
instructions="""You are a weather agent that can provide weather information for a given city.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
result = weather_agent.start(query)
|
||||
return f"## Weather Information\n\n{result}"
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=get_weather_info,
|
||||
inputs=gr.Textbox(placeholder="What's the weather in London?"),
|
||||
outputs=gr.Markdown(),
|
||||
title="Weather MCP Agent",
|
||||
description="Ask about the weather in any major city:"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Real-time Updates" icon="bolt">
|
||||
Receive server-sent events in real-time from your AI agent.
|
||||
</Card>
|
||||
<Card title="Multi-Agent Support" icon="users">
|
||||
Combine SSE with other MCP tools for complex workflows.
|
||||
</Card>
|
||||
<Card title="Multiple LLM Options" icon="brain">
|
||||
Use with OpenAI, Groq, Ollama, or other supported LLMs.
|
||||
</Card>
|
||||
<Card title="Gradio UI" icon="window">
|
||||
Create user-friendly interfaces for your SSE integrations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,185 @@
|
||||
---
|
||||
title: "WhatsApp MCP Integration"
|
||||
sidebarTitle: "WhatsApp"
|
||||
description: "Guide for integrating WhatsApp messaging with PraisonAI agents using MCP"
|
||||
icon: "whatsapp"
|
||||
---
|
||||
|
||||
## Add WhatsApp Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[WhatsApp MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#25D366,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set Up WhatsApp MCP Server">
|
||||
Clone and set up the WhatsApp MCP server:
|
||||
```bash
|
||||
git clone https://github.com/lharries/whatsapp-mcp.git
|
||||
cd whatsapp-mcp
|
||||
cd whatsapp-bridge
|
||||
go run main.go
|
||||
```
|
||||
</Step>
|
||||
<Step title="Create a file">
|
||||
Create a new file `whatsapp_message.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /path/to/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison")
|
||||
```
|
||||
|
||||
Note: Replace `/path/to/whatsapp-mcp` with the actual path to your WhatsApp MCP server.
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have the required packages installed:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]" mcp gradio
|
||||
```
|
||||
</Step>
|
||||
<Step title="Export API Key">
|
||||
```bash
|
||||
export OPENAI_API_KEY="your_api_key"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python whatsapp_message.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- WhatsApp MCP server set up and configured
|
||||
</Note>
|
||||
|
||||
## Multi-Agent Integration
|
||||
|
||||
You can also combine WhatsApp with other MCP tools, such as Airbnb search:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Agents, MCP
|
||||
|
||||
airbnb_agent = Agent(
|
||||
instructions="""Search for Apartments in Paris for 2 nights on Airbnb. 04/28 - 04/30 for 2 adults""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="""Send AirBnb Search Result to 'Mervin Praison'""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /path/to/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
agents = Agents(agents=[airbnb_agent, whatsapp_agent])
|
||||
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Alternative LLM Integrations
|
||||
|
||||
### Using Groq with WhatsApp
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="groq/llama-3.2-90b-vision-preview",
|
||||
tools=MCP("python /path/to/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison")
|
||||
```
|
||||
|
||||
### Using Ollama with WhatsApp
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("python /path/to/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison. Use send_message tool, recipient and message are the required parameters.")
|
||||
```
|
||||
|
||||
## Gradio UI Integration
|
||||
|
||||
Create a Gradio UI for your WhatsApp and Airbnb integration:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Agents, MCP
|
||||
import gradio as gr
|
||||
|
||||
def search_airbnb(query):
|
||||
airbnb_agent = Agent(
|
||||
instructions=query+" on Airbnb",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="""Send AirBnb Search Result to 'Mervin Praison'. Don't include Phone Number in Response, but include the AirBnb Search Result""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /path/to/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
agents = Agents(agents=[airbnb_agent, whatsapp_agent])
|
||||
|
||||
result = agents.start()
|
||||
return f"## Airbnb Search Results\n\n{result}"
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=search_airbnb,
|
||||
inputs=gr.Textbox(placeholder="I want to book an apartment in Paris for 2 nights..."),
|
||||
outputs=gr.Markdown(),
|
||||
title="WhatsApp MCP Agent",
|
||||
description="Enter your booking requirements below:"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="WhatsApp Messaging" icon="message">
|
||||
Send messages to WhatsApp contacts directly from your AI agent.
|
||||
</Card>
|
||||
<Card title="Multi-Agent Support" icon="users">
|
||||
Combine WhatsApp with other MCP tools for complex workflows.
|
||||
</Card>
|
||||
<Card title="Multiple LLM Options" icon="brain">
|
||||
Use with OpenAI, Groq, Ollama, or other supported LLMs.
|
||||
</Card>
|
||||
<Card title="Gradio UI" icon="window">
|
||||
Create user-friendly interfaces for your WhatsApp integrations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "xAI MCP Integration"
|
||||
sidebarTitle: "xAI"
|
||||
description: "Guide for integrating XAI's Grok model with PraisonAI agents using MCP"
|
||||
icon: "robot"
|
||||
---
|
||||
|
||||
## Add XAI Tool to AI Agent
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[In] --> Agent[AI Agent]
|
||||
Agent --> Tool[Airbnb MCP]
|
||||
Tool --> Agent
|
||||
Agent --> Out[Out]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Tool fill:#FF5A5F,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Set API Key">
|
||||
Set your XAI API key as an environment variable in your terminal:
|
||||
```bash
|
||||
export XAI_API_KEY=your_xai_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create a file">
|
||||
Create a new file `xai_airbnb.py` with the following code:
|
||||
```python
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="xai/grok-2-latest",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Install Dependencies">
|
||||
Make sure you have Node.js installed, as the MCP server requires it:
|
||||
```bash
|
||||
pip install "praisonaiagents[llm]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Run the Agent">
|
||||
Execute your script:
|
||||
```bash
|
||||
python xai_airbnb.py
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
**Requirements**
|
||||
- Python 3.10 or higher
|
||||
- Node.js installed on your system
|
||||
- XAI API key (for the Grok model)
|
||||
</Note>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Grok Integration" icon="robot">
|
||||
Uses XAI's Grok model for advanced natural language understanding.
|
||||
</Card>
|
||||
<Card title="MCP Integration" icon="plug">
|
||||
Seamless integration with Model Context Protocol.
|
||||
</Card>
|
||||
<Card title="Airbnb Search" icon="hotel">
|
||||
Search for accommodations on Airbnb with natural language queries.
|
||||
</Card>
|
||||
<Card title="NPM Package" icon="js">
|
||||
Leverages the official Airbnb MCP server package.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -238,6 +238,18 @@
|
||||
"group": "MCP",
|
||||
"pages": [
|
||||
"mcp/airbnb",
|
||||
"mcp/sse",
|
||||
"mcp/ollama",
|
||||
"mcp/groq",
|
||||
"mcp/openrouter",
|
||||
"mcp/xai",
|
||||
"mcp/openai",
|
||||
"mcp/anthropic",
|
||||
"mcp/gemini",
|
||||
"mcp/mistral",
|
||||
"mcp/whatsapp",
|
||||
"mcp/perplexity",
|
||||
"mcp/ollama-python",
|
||||
"mcp/bravesearch",
|
||||
"mcp/custom",
|
||||
"mcp/sequential-thinking",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: "Auto Generation Mode"
|
||||
description: "Guide to PraisonAI's automatic agent generation feature, supporting both CrewAI and AutoGen frameworks for automated task execution"
|
||||
description: "Guide to PraisonAI's automatic agent generation feature, supporting both CrewAI and AG2 frameworks for automated task execution"
|
||||
icon: "robot"
|
||||
---
|
||||
|
||||
PraisonAI supports automatic agent generation with PraisonAI Agents, CrewAI and AutoGen frameworks.
|
||||
PraisonAI supports automatic agent generation with PraisonAI Agents, CrewAI and AG2 frameworks.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -17,7 +17,7 @@ pip install praisonai
|
||||
# For CrewAI
|
||||
pip install "praisonai[crewai]"
|
||||
|
||||
# For AutoGen
|
||||
# For AG2 (Formerly AutoGen)
|
||||
pip install "praisonai[autogen]"
|
||||
|
||||
# For both frameworks
|
||||
@@ -36,7 +36,7 @@ praisonai --auto "create a movie script about Dog in Moon"
|
||||
praisonai --framework crewai --auto "create a movie script about Dog in Moon"
|
||||
```
|
||||
|
||||
### With AutoGen
|
||||
### With AG2
|
||||
```bash
|
||||
praisonai --framework autogen --auto "create a movie script about Dog in Moon"
|
||||
```
|
||||
@@ -49,7 +49,7 @@ praisonai --framework autogen --auto "create a movie script about Dog in Moon"
|
||||
- Built-in tools integration
|
||||
- Structured agent-task relationships
|
||||
|
||||
### AutoGen
|
||||
### AG2 (Formerly AutoGen)
|
||||
- Multi-agent conversation capabilities
|
||||
- Code execution environment
|
||||
- Built-in tools integration
|
||||
|
||||
@@ -28,13 +28,13 @@ Includes:
|
||||
- Task delegation capabilities
|
||||
- Sequential and parallel task execution
|
||||
|
||||
### AutoGen Support
|
||||
### AG2 Support
|
||||
```bash
|
||||
pip install "praisonai[autogen]"
|
||||
```
|
||||
|
||||
Includes:
|
||||
- AutoGen framework
|
||||
- AG2 framework
|
||||
- PraisonAI tools integration
|
||||
- Multi-agent conversation capabilities
|
||||
- Code execution environment
|
||||
|
||||
@@ -21,7 +21,7 @@ icon: "hand-wave"
|
||||
Create and orchestrate sophisticated multi-agent systems with ease
|
||||
</Card>
|
||||
<Card title="Framework Integration" icon="puzzle-piece">
|
||||
Seamlessly integrates AutoGen and CrewAI capabilities
|
||||
Seamlessly integrates AG2 and CrewAI capabilities
|
||||
</Card>
|
||||
<Card title="Low-Code Design" icon="code">
|
||||
Build complex AI systems with minimal coding required
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: "TL;DR"
|
||||
description: "Quick start guide for PraisonAI with CrewAI, AutoGen, and UI setup instructions"
|
||||
description: "Quick start guide for PraisonAI with CrewAI, AG2 (Formerly AutoGen), and UI setup instructions"
|
||||
icon: "bolt"
|
||||
---
|
||||
|
||||
@@ -32,10 +32,10 @@ praisonai --framework crewai --init "create a movie script about dog in moon"
|
||||
praisonai --framework crewai
|
||||
```
|
||||
|
||||
## Quick Start with AutoGen
|
||||
## Quick Start with AG2
|
||||
|
||||
```bash
|
||||
# Install with AutoGen support
|
||||
# Install with AG2 support
|
||||
pip install "praisonai[autogen]"
|
||||
|
||||
# Set your API key
|
||||
|
||||
@@ -71,7 +71,7 @@ To run the PraisonAI tool, simply type the following command in your terminal:
|
||||
praisonai
|
||||
```
|
||||
|
||||
If you want to run the `autogen` framework, use:
|
||||
If you want to run the AG2 framework (Formerly AutoGen), use:
|
||||
|
||||
```bash
|
||||
praisonai --framework autogen
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ icon: "comments"
|
||||
|
||||
| Interface | Description | URL |
|
||||
|---|---|---|
|
||||
| **UI** | Multi Agents such as CrewAI or AutoGen | [https://docs.praison.ai/ui/ui](https://docs.praison.ai/ui/ui) |
|
||||
| **UI** | Multi Agents such as CrewAI or AG2 | [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) |
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ PraisonAI Code helps you to interact with your whole codebase using the power of
|
||||
|
||||
| Interface | Description | URL |
|
||||
|---|---|---|
|
||||
| **UI** | Multi Agents such as CrewAI or AutoGen | [https://docs.praison.ai/ui/ui](https://docs.praison.ai/ui/ui) |
|
||||
| **UI** | Multi Agents such as CrewAI or AG2 | [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) |
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ icon: "browser"
|
||||
|---|---|---|
|
||||
| **Streamlit** | Create interactive web apps with Python | [https://docs.praison.ai/ui/streamlit](/ui/streamlit) |
|
||||
| **Gradio** | Build machine learning web apps rapidly | [https://docs.praison.ai/ui/gradio](/ui/gradio) |
|
||||
| **UI** | Multi Agents such as CrewAI or AutoGen | [https://docs.praison.ai/ui/ui](/ui/ui) |
|
||||
| **UI** | Multi Agents such as CrewAI or AG2 | [https://docs.praison.ai/ui/ui](/ui/ui) |
|
||||
| **Chat** | Chat with 100+ LLMs, single AI Agent | [https://docs.praison.ai/ui/chat](/ui/chat) |
|
||||
| **Code** | Chat with entire Codebase, single AI Agent | [https://docs.praison.ai/ui/code](/ui/code) |
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
# Databutton API key
|
||||
databutton_api_key = os.getenv("DATABUTTON_API_KEY")
|
||||
|
||||
# Create databutton agent
|
||||
databutton_agent = Agent(
|
||||
instructions="""You are a helpful assistant that can interact with Databutton.
|
||||
Use the available tools when relevant to answer user questions.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("uvx databutton-app-mcp@latest", env={"DATABUTTON_API_KEY": databutton_api_key})
|
||||
)
|
||||
|
||||
databutton_agent.start("Get the current stock price for AAPL, Tesla, and Amazon")
|
||||
@@ -1,9 +1,12 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
stock_agent = Agent(
|
||||
instructions="""You are a Stock Price Assistant.""",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
|
||||
)
|
||||
|
||||
search_agent.start("What is the Stock Price of Apple?")
|
||||
# NOTE: Python Path replace with yours: /Users/praison/miniconda3/envs/mcp/bin/python
|
||||
# NOTE: app.py file path, replace it with yours: /Users/praison/stockprice/app.py
|
||||
|
||||
stock_agent.start("What is the Stock Price of Apple?")
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="openrouter/google/gemini-2.0-flash-exp:free",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
@@ -0,0 +1,14 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
api_key = os.getenv("PERPLEXITY_API_KEY")
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant that can search the web for information. Use the available tools when relevant to answer user questions.",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("uvx perplexity-mcp",
|
||||
env={"PERPLEXITY_API_KEY": api_key, "PERPLEXITY_MODEL": "sonar" })
|
||||
)
|
||||
result = agent.start("What is the latest news on AI?, Pass only the query parameter to the tool")
|
||||
|
||||
print(result)
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="groq/llama-3.2-90b-vision-preview",
|
||||
tools=MCP("python /Users/praison/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison")
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /Users/praison/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison")
|
||||
@@ -0,0 +1,17 @@
|
||||
from praisonaiagents import Agent, Agents, MCP
|
||||
|
||||
airbnb_agent = Agent(
|
||||
instructions="""Search for Apartments in Paris for 2 nights on Airbnb. 04/28 - 04/30 for 2 adults""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="""Send AirBnb Search Result to 'Mervin Praison'""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /Users/praison/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
agents = Agents(agents=[airbnb_agent, whatsapp_agent])
|
||||
|
||||
agents.start()
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="Whatsapp Agent",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("python /Users/praison/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
whatsapp_agent.start("Send Hello to Mervin Praison. Use send_message tool, recipient and message are the required parameters.")
|
||||
@@ -0,0 +1,31 @@
|
||||
from praisonaiagents import Agent, Agents, MCP
|
||||
import gradio as gr
|
||||
|
||||
def search_airbnb(query):
|
||||
airbnb_agent = Agent(
|
||||
instructions=query+" on Airbnb",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
whatsapp_agent = Agent(
|
||||
instructions="""Send AirBnb Search Result to 'Mervin Praison'. Don't include Phone Number in Response, but include the AirBnb Search Result""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("python /Users/praison/whatsapp-mcp/whatsapp-mcp-server/main.py")
|
||||
)
|
||||
|
||||
agents = Agents(agents=[airbnb_agent, whatsapp_agent])
|
||||
|
||||
result = agents.start()
|
||||
return f"## Airbnb Search Results\n\n{result}"
|
||||
|
||||
demo = gr.Interface(
|
||||
fn=search_airbnb,
|
||||
inputs=gr.Textbox(placeholder="I want to book an apartment in Paris for 2 nights..."),
|
||||
outputs=gr.Markdown(),
|
||||
title="WhatsApp MCP Agent",
|
||||
description="Enter your booking requirements below:"
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You help book apartments on Airbnb.""",
|
||||
llm="xai/grok-2-latest",
|
||||
tools=MCP("npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt")
|
||||
)
|
||||
|
||||
search_agent.start("MUST USE airbnb_search Tool to Search. Search for Apartments in Paris for 2 nights. 04/28 - 04/30 for 2 adults. All Your Preference")
|
||||
Generated
+9735
File diff suppressed because it is too large.
Load diff
+1
-1
@@ -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.1.0.tar.gz"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/2.1.1.tar.gz"
|
||||
sha256 "1828fb9227d10f991522c3f24f061943a254b667196b40b1a3e4a54a8d30ce32" # Replace with actual SHA256 checksum
|
||||
license "MIT"
|
||||
|
||||
|
||||
+1
-1
@@ -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.1.0 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.1.1 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Only try to import autogen_tools if either CrewAI or AutoGen is available
|
||||
# Only try to import autogen_tools if either CrewAI or AG2 is available
|
||||
CREWAI_AVAILABLE = False
|
||||
AUTOGEN_AVAILABLE = False
|
||||
PRAISONAI_TOOLS_AVAILABLE = False
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "PraisonAI"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
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.70",
|
||||
"praisonaiagents>=0.0.71",
|
||||
"python-dotenv>=0.19.0",
|
||||
"instructor>=1.3.3",
|
||||
"PyYAML>=6.0",
|
||||
@@ -85,7 +85,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.7", "crewai"]
|
||||
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
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 = ""
|
||||
@@ -103,7 +103,7 @@ python = ">=3.10,<3.13"
|
||||
rich = ">=13.7"
|
||||
markdown = ">=3.5"
|
||||
pyparsing = ">=3.0.0"
|
||||
praisonaiagents = ">=0.0.70"
|
||||
praisonaiagents = ">=0.0.71"
|
||||
python-dotenv = ">=0.19.0"
|
||||
instructor = ">=1.3.3"
|
||||
PyYAML = ">=6.0"
|
||||
|
||||
@@ -12,7 +12,7 @@ print_message() {
|
||||
print_usage() {
|
||||
echo "Usage: $0 [-u|--ui] [-c|--chat] [-d|--code] [-r|--realtime] [-a|--all] [--run] [--quick] [--model MODEL] [--base URL]"
|
||||
echo "Options:"
|
||||
echo " -u, --ui Install UI dependencies for Multi Agents (CrewAI/AutoGen)"
|
||||
echo " -u, --ui Install UI dependencies for Multi Agents (CrewAI/AG2)"
|
||||
echo " -c, --chat Install Chat interface for single AI Agent"
|
||||
echo " -d, --code Install Code interface for codebase interaction"
|
||||
echo " -r, --realtime Install Realtime voice interaction interface"
|
||||
@@ -97,8 +97,8 @@ run_ui_interface() {
|
||||
if [ -z "$prompt" ]; then
|
||||
prompt="create a movie script about dog in moon"
|
||||
fi
|
||||
read -p "Use AutoGen framework? (y/N): " use_autogen
|
||||
if [[ $use_autogen =~ ^[Yy]$ ]]; then
|
||||
read -p "Use AG2 (Formerly AutoGen) framework? (y/N): " use_ag2
|
||||
if [[ $use_ag2 =~ ^[Yy]$ ]]; then
|
||||
praisonai --framework autogen --init "$prompt"
|
||||
else
|
||||
praisonai --init "$prompt"
|
||||
|
||||
@@ -84,4 +84,5 @@ build
|
||||
*.mp4
|
||||
*.png
|
||||
graph.py
|
||||
chroma_db/
|
||||
chroma_db/
|
||||
.qodo
|
||||
@@ -0,0 +1,83 @@
|
||||
# MCP SSE Server and Client Implementation
|
||||
|
||||
This project demonstrates a working pattern for SSE-based MCP (Model Context Protocol) servers and clients. It consists of three main components:
|
||||
|
||||
1. **server.py**: An SSE-based MCP server that provides simple tools
|
||||
2. **client.py**: A standalone client that connects to the server and uses its tools with Claude
|
||||
3. **mcp-sse.py**: A client using praisonaiagents that connects to the server and uses its tools with OpenAI
|
||||
|
||||
## Tools Provided by the Server
|
||||
|
||||
The server implements two simple tools:
|
||||
|
||||
- **get_greeting**: Returns a personalized greeting for a given name
|
||||
- **get_weather**: Returns simulated weather data for a given city
|
||||
|
||||
## Setup and Usage
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Make sure you have the required packages installed:
|
||||
|
||||
```bash
|
||||
pip install praisonaiagents mcp httpx starlette uvicorn anthropic python-dotenv
|
||||
```
|
||||
|
||||
### Running the Server
|
||||
|
||||
First, start the MCP SSE server:
|
||||
|
||||
```bash
|
||||
python server.py
|
||||
```
|
||||
|
||||
By default, the server runs on 0.0.0.0:8080, but you can customize the host and port:
|
||||
|
||||
```bash
|
||||
python server.py --host 127.0.0.1 --port 8081
|
||||
```
|
||||
|
||||
### Running the Standalone Client
|
||||
|
||||
The standalone client uses Claude to interact with the MCP server tools:
|
||||
|
||||
```bash
|
||||
# Set your Anthropic API key
|
||||
export ANTHROPIC_API_KEY=your_api_key_here
|
||||
|
||||
# Run the client
|
||||
python client.py http://0.0.0.0:8080/sse
|
||||
```
|
||||
|
||||
You'll see a prompt where you can type queries for Claude to process using the MCP tools.
|
||||
|
||||
### Running the praisonaiagents Client
|
||||
|
||||
The praisonaiagents client uses OpenAI to interact with the MCP server tools:
|
||||
|
||||
```bash
|
||||
# Set your OpenAI API key
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
|
||||
# Run the client
|
||||
python mcp-sse.py
|
||||
```
|
||||
|
||||
This will automatically send a query about the weather in Paris to the agent.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. The server exposes MCP tools via an SSE endpoint
|
||||
2. Clients connect to this endpoint and discover available tools
|
||||
3. When a user makes a query, the client:
|
||||
- For client.py: Uses Claude to determine which tool to call
|
||||
- For mcp-sse.py: Uses OpenAI to determine which tool to call
|
||||
4. The client executes the tool call against the server
|
||||
5. The result is returned to the user
|
||||
|
||||
This pattern allows for decoupled processes where the MCP server can run independently of clients, making it suitable for cloud-native applications.
|
||||
|
||||
## Customizing
|
||||
|
||||
- To add more tools to the server, define new functions with the `@mcp.tool()` decorator in `server.py`
|
||||
- To change the client's behavior, update the instructions and query in `mcp-sse.py`
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
import os
|
||||
|
||||
brave_api_key = os.getenv("BRAVE_API_KEY")
|
||||
|
||||
research_agent = Agent(
|
||||
instructions="Research Agent",
|
||||
llm="groq/meta-llama/llama-4-scout-17b-16e-instruct",
|
||||
tools=MCP("npx -y @modelcontextprotocol/server-brave-search", env={"BRAVE_API_KEY": brave_api_key})
|
||||
)
|
||||
|
||||
research_agent.start("What is the latest research on the topic of AI and its impact on society?")
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
stock_agent = Agent(
|
||||
instructions="""You are a Stock Price Assistant.""",
|
||||
llm="ollama/llama3.2",
|
||||
tools=MCP("/Users/praison/miniconda3/envs/mcp/bin/python /Users/praison/stockprice/app.py")
|
||||
)
|
||||
|
||||
stock_agent.start("What is the Stock Price of Apple?")
|
||||
@@ -0,0 +1,222 @@
|
||||
import os
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import sys
|
||||
import inspect
|
||||
import json
|
||||
from typing import List, Dict, Any, Optional, Callable
|
||||
from contextlib import AsyncExitStack
|
||||
|
||||
from mcp import ClientSession
|
||||
from mcp.client.sse import sse_client
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Set up logging based on environment variable
|
||||
log_level = os.environ.get("LOGLEVEL", "info").upper()
|
||||
logging.basicConfig(level=getattr(logging, log_level))
|
||||
logger = logging.getLogger("mcp-client")
|
||||
|
||||
# Create a custom prompt that explicitly mentions the tools
|
||||
system_prompt = """You are a helpful assistant that can provide greetings and check weather information.
|
||||
|
||||
You have access to the following tools:
|
||||
1. get_greeting(name: str) - Get a personalized greeting for a given name
|
||||
2. get_weather(city: str) - Get weather information for a city (Paris, London, New York, Tokyo, Sydney)
|
||||
|
||||
When asked about weather, always use the get_weather tool with the appropriate city.
|
||||
When asked for a greeting, always use the get_greeting tool with the appropriate name.
|
||||
"""
|
||||
|
||||
# Global event loop for async operations
|
||||
event_loop = None
|
||||
|
||||
def get_event_loop():
|
||||
"""Get or create a global event loop."""
|
||||
global event_loop
|
||||
if event_loop is None or event_loop.is_closed():
|
||||
event_loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(event_loop)
|
||||
return event_loop
|
||||
|
||||
class SSEMCPTool:
|
||||
"""A wrapper for an MCP tool that can be used with praisonaiagents."""
|
||||
|
||||
def __init__(self, name: str, description: str, session: ClientSession, input_schema: Optional[Dict[str, Any]] = None):
|
||||
self.name = name
|
||||
self.__name__ = name # Required for Agent to recognize it as a tool
|
||||
self.__qualname__ = name # Required for Agent to recognize it as a tool
|
||||
self.__doc__ = description # Required for Agent to recognize it as a tool
|
||||
self.description = description
|
||||
self.session = session
|
||||
self.input_schema = input_schema or {}
|
||||
|
||||
# Create a signature based on input schema
|
||||
params = []
|
||||
if input_schema and 'properties' in input_schema:
|
||||
for param_name in input_schema['properties']:
|
||||
params.append(
|
||||
inspect.Parameter(
|
||||
name=param_name,
|
||||
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||
default=inspect.Parameter.empty if param_name in input_schema.get('required', []) else None,
|
||||
annotation=str # Default to string
|
||||
)
|
||||
)
|
||||
|
||||
self.__signature__ = inspect.Signature(params)
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
"""Synchronous wrapper for the async call."""
|
||||
logger.debug(f"Tool {self.name} called with args: {kwargs}")
|
||||
|
||||
# Use the global event loop
|
||||
loop = get_event_loop()
|
||||
|
||||
# Run the async call in the event loop
|
||||
future = asyncio.run_coroutine_threadsafe(self._async_call(**kwargs), loop)
|
||||
try:
|
||||
# Wait for the result with a timeout
|
||||
return future.result(timeout=30)
|
||||
except Exception as e:
|
||||
logger.error(f"Error calling tool {self.name}: {e}")
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
async def _async_call(self, **kwargs):
|
||||
"""Call the tool with the provided arguments."""
|
||||
logger.debug(f"Async calling tool {self.name} with args: {kwargs}")
|
||||
try:
|
||||
result = await self.session.call_tool(self.name, kwargs)
|
||||
|
||||
# Extract text from result
|
||||
if hasattr(result, 'content') and result.content:
|
||||
if hasattr(result.content[0], 'text'):
|
||||
return result.content[0].text
|
||||
return str(result.content[0])
|
||||
return str(result)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in _async_call for {self.name}: {e}")
|
||||
raise
|
||||
|
||||
def to_openai_tool(self):
|
||||
"""Convert the tool to OpenAI format."""
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"parameters": self.input_schema
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SSEMCPClient:
|
||||
"""A client for connecting to an MCP server over SSE."""
|
||||
|
||||
def __init__(self, server_url: str):
|
||||
self.server_url = server_url
|
||||
self.session = None
|
||||
self.tools = []
|
||||
self._initialize()
|
||||
|
||||
def _initialize(self):
|
||||
"""Initialize the connection and tools."""
|
||||
# Use the global event loop
|
||||
loop = get_event_loop()
|
||||
|
||||
# Start a background thread to run the event loop
|
||||
def run_event_loop():
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_forever()
|
||||
|
||||
import threading
|
||||
self.loop_thread = threading.Thread(target=run_event_loop, daemon=True)
|
||||
self.loop_thread.start()
|
||||
|
||||
# Run the initialization in the event loop
|
||||
future = asyncio.run_coroutine_threadsafe(self._async_initialize(), loop)
|
||||
self.tools = future.result(timeout=30)
|
||||
|
||||
async def _async_initialize(self):
|
||||
"""Asynchronously initialize the connection and tools."""
|
||||
logger.debug(f"Connecting to MCP server at {self.server_url}")
|
||||
|
||||
# Create SSE client
|
||||
self._streams_context = sse_client(url=self.server_url)
|
||||
streams = await self._streams_context.__aenter__()
|
||||
|
||||
self._session_context = ClientSession(*streams)
|
||||
self.session = await self._session_context.__aenter__()
|
||||
|
||||
# Initialize
|
||||
await self.session.initialize()
|
||||
|
||||
# List available tools
|
||||
logger.debug("Listing tools...")
|
||||
response = await self.session.list_tools()
|
||||
tools_data = response.tools
|
||||
logger.debug(f"Found {len(tools_data)} tools: {[tool.name for tool in tools_data]}")
|
||||
|
||||
# Create tool wrappers
|
||||
tools = []
|
||||
for tool in tools_data:
|
||||
input_schema = tool.inputSchema if hasattr(tool, 'inputSchema') else None
|
||||
wrapper = SSEMCPTool(
|
||||
name=tool.name,
|
||||
description=tool.description if hasattr(tool, 'description') else f"Call the {tool.name} tool",
|
||||
session=self.session,
|
||||
input_schema=input_schema
|
||||
)
|
||||
tools.append(wrapper)
|
||||
|
||||
return tools
|
||||
|
||||
def __iter__(self):
|
||||
"""Return an iterator over the tools."""
|
||||
return iter(self.tools)
|
||||
|
||||
|
||||
def main():
|
||||
# Server URL
|
||||
server_url = "http://0.0.0.0:8080/sse"
|
||||
|
||||
try:
|
||||
# Connect to the MCP server
|
||||
client = SSEMCPClient(server_url)
|
||||
|
||||
if not client.tools:
|
||||
logger.error("No tools found on the server")
|
||||
return
|
||||
|
||||
logger.info(f"Connected to server with {len(client.tools)} tools: {[tool.name for tool in client.tools]}")
|
||||
|
||||
# Create OpenAI-compatible tool definitions
|
||||
openai_tools = [tool.to_openai_tool() for tool in client.tools]
|
||||
logger.debug(f"OpenAI tools: {json.dumps(openai_tools, indent=2)}")
|
||||
|
||||
# Create an agent with the tools
|
||||
assistant_agent = Agent(
|
||||
instructions=system_prompt,
|
||||
llm="openai/gpt-4o-mini",
|
||||
tools=client.tools,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Start the agent with a query
|
||||
logger.info("Starting agent with query about weather in Paris")
|
||||
result = assistant_agent.chat(
|
||||
"Hello! Can you tell me what the weather is like in Paris today?",
|
||||
tools=openai_tools
|
||||
)
|
||||
|
||||
logger.info(f"Agent response: {result}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,120 @@
|
||||
# python mcp-sse-direct-client.py http://0.0.0.0:8080/sse
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from typing import Optional
|
||||
from contextlib import AsyncExitStack
|
||||
|
||||
from mcp import ClientSession
|
||||
from mcp.client.sse import sse_client
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv() # load environment variables from .env
|
||||
|
||||
class MCPClient:
|
||||
def __init__(self):
|
||||
# Initialize session and client objects
|
||||
self.session: Optional[ClientSession] = None
|
||||
self.exit_stack = AsyncExitStack()
|
||||
|
||||
async def connect_to_sse_server(self, server_url: str):
|
||||
"""Connect to an MCP server running with SSE transport"""
|
||||
# Store the context managers so they stay alive
|
||||
self._streams_context = sse_client(url=server_url)
|
||||
streams = await self._streams_context.__aenter__()
|
||||
|
||||
self._session_context = ClientSession(*streams)
|
||||
self.session: ClientSession = await self._session_context.__aenter__()
|
||||
|
||||
# Initialize
|
||||
await self.session.initialize()
|
||||
|
||||
# List available tools to verify connection
|
||||
print("Initialized SSE client...")
|
||||
print("Listing tools...")
|
||||
response = await self.session.list_tools()
|
||||
tools = response.tools
|
||||
print("\nConnected to server with tools:", [tool.name for tool in tools])
|
||||
|
||||
# Print tool descriptions
|
||||
for tool in tools:
|
||||
print(f"\n{tool.name}: {tool.description}")
|
||||
if hasattr(tool, 'inputSchema') and tool.inputSchema:
|
||||
print(f" Parameters: {json.dumps(tool.inputSchema, indent=2)}")
|
||||
|
||||
async def cleanup(self):
|
||||
"""Properly clean up the session and streams"""
|
||||
if hasattr(self, '_session_context'):
|
||||
await self._session_context.__aexit__(None, None, None)
|
||||
if hasattr(self, '_streams_context'):
|
||||
await self._streams_context.__aexit__(None, None, None)
|
||||
|
||||
async def process_query(self, query: str) -> str:
|
||||
"""Process a query by directly calling the appropriate tool"""
|
||||
query = query.strip().lower()
|
||||
|
||||
if query.startswith("hello") or query.startswith("hi"):
|
||||
# Extract name or use a default
|
||||
parts = query.split()
|
||||
name = parts[1] if len(parts) > 1 else "there"
|
||||
|
||||
# Call the greeting tool
|
||||
print(f"\nCalling get_greeting with name: {name}")
|
||||
result = await self.session.call_tool("get_greeting", {"name": name})
|
||||
return result.content[0].text if hasattr(result, 'content') and result.content else str(result)
|
||||
|
||||
elif "weather" in query:
|
||||
# Try to extract city name
|
||||
city = None
|
||||
for known_city in ["Paris", "London", "New York", "Tokyo", "Sydney"]:
|
||||
if known_city.lower() in query.lower():
|
||||
city = known_city
|
||||
break
|
||||
|
||||
if not city:
|
||||
return "I couldn't identify a city in your query. Please mention a city like Paris, London, New York, Tokyo, or Sydney."
|
||||
|
||||
# Call the weather tool
|
||||
print(f"\nCalling get_weather with city: {city}")
|
||||
result = await self.session.call_tool("get_weather", {"city": city})
|
||||
return result.content[0].text if hasattr(result, 'content') and result.content else str(result)
|
||||
|
||||
else:
|
||||
return "I can help with greetings or weather information. Try asking something like 'Hello John' or 'What's the weather in Paris?'"
|
||||
|
||||
async def chat_loop(self):
|
||||
"""Run an interactive chat loop"""
|
||||
print("\nMCP Client Started!")
|
||||
print("Type your queries or 'quit' to exit.")
|
||||
|
||||
while True:
|
||||
try:
|
||||
query = input("\nQuery: ").strip()
|
||||
|
||||
if query.lower() == 'quit':
|
||||
break
|
||||
|
||||
response = await self.process_query(query)
|
||||
print("\n" + response)
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nError: {str(e)}")
|
||||
|
||||
|
||||
async def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: python client.py <URL of SSE MCP server (i.e. http://localhost:8081/sse)>")
|
||||
sys.exit(1)
|
||||
|
||||
client = MCPClient()
|
||||
try:
|
||||
await client.connect_to_sse_server(server_url=sys.argv[1])
|
||||
await client.chat_loop()
|
||||
finally:
|
||||
await client.cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,95 @@
|
||||
# python mcp-sse-direct-server.py --host 127.0.0.1 --port 8080
|
||||
from typing import Any
|
||||
import httpx
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from starlette.applications import Starlette
|
||||
from mcp.server.sse import SseServerTransport
|
||||
from starlette.requests import Request
|
||||
from starlette.routing import Mount, Route
|
||||
from mcp.server import Server
|
||||
import uvicorn
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import inspect
|
||||
|
||||
# Set up logging based on environment variable
|
||||
log_level = os.environ.get("LOGLEVEL", "info").upper()
|
||||
logging.basicConfig(level=getattr(logging, log_level))
|
||||
logger = logging.getLogger("mcp-server")
|
||||
|
||||
# Initialize FastMCP server for simple tools (SSE)
|
||||
mcp = FastMCP("simple-tools")
|
||||
|
||||
@mcp.tool()
|
||||
async def get_greeting(name: str) -> str:
|
||||
"""Get a personalized greeting.
|
||||
|
||||
Args:
|
||||
name: Name of the person to greet
|
||||
"""
|
||||
logger.debug(f"get_greeting called with name: {name}")
|
||||
return f"Hello, {name}! Welcome to our MCP SSE server."
|
||||
|
||||
@mcp.tool()
|
||||
async def get_weather(city: str) -> str:
|
||||
"""Get a simulated weather report for a city.
|
||||
|
||||
Args:
|
||||
city: Name of the city
|
||||
"""
|
||||
logger.debug(f"get_weather called with city: {city}")
|
||||
# This is a mock implementation
|
||||
weather_data = {
|
||||
"Paris": "Sunny with a temperature of 22°C",
|
||||
"London": "Rainy with a temperature of 15°C",
|
||||
"New York": "Cloudy with a temperature of 18°C",
|
||||
"Tokyo": "Clear skies with a temperature of 25°C",
|
||||
"Sydney": "Partly cloudy with a temperature of 20°C"
|
||||
}
|
||||
|
||||
return weather_data.get(city, f"Weather data not available for {city}")
|
||||
|
||||
def create_starlette_app(mcp_server: Server, *, debug: bool = False) -> Starlette:
|
||||
"""Create a Starlette application that can serve the provided mcp server with SSE."""
|
||||
sse = SseServerTransport("/messages/")
|
||||
|
||||
async def handle_sse(request: Request) -> None:
|
||||
logger.debug(f"SSE connection request received from {request.client}")
|
||||
async with sse.connect_sse(
|
||||
request.scope,
|
||||
request.receive,
|
||||
request._send, # noqa: SLF001
|
||||
) as (read_stream, write_stream):
|
||||
await mcp_server.run(
|
||||
read_stream,
|
||||
write_stream,
|
||||
mcp_server.create_initialization_options(),
|
||||
)
|
||||
|
||||
return Starlette(
|
||||
debug=debug,
|
||||
routes=[
|
||||
Route("/sse", endpoint=handle_sse),
|
||||
Mount("/messages/", app=sse.handle_post_message),
|
||||
],
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
mcp_server = mcp._mcp_server # noqa: WPS437
|
||||
|
||||
parser = argparse.ArgumentParser(description='Run MCP SSE-based server')
|
||||
parser.add_argument('--host', default='localhost', help='Host to bind to')
|
||||
parser.add_argument('--port', type=int, default=8080, help='Port to listen on')
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"Starting MCP SSE server on {args.host}:{args.port}")
|
||||
|
||||
# Hardcode the tool names since we know what they are
|
||||
tool_names = ["get_greeting", "get_weather"]
|
||||
print(f"Available tools: {', '.join(tool_names)}")
|
||||
|
||||
# Bind SSE request handling to MCP server
|
||||
starlette_app = create_starlette_app(mcp_server, debug=True)
|
||||
|
||||
uvicorn.run(starlette_app, host=args.host, port=args.port)
|
||||
@@ -0,0 +1,9 @@
|
||||
from praisonaiagents import Agent, MCP
|
||||
|
||||
search_agent = Agent(
|
||||
instructions="""You are a weather agent that can provide weather information for a given city.""",
|
||||
llm="openai/gpt-4o-mini",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
search_agent.start("What is the weather in London?")
|
||||
@@ -530,11 +530,21 @@ Your Goal: {self.goal}
|
||||
from ..mcp.mcp import MCP
|
||||
if isinstance(self.tools, MCP):
|
||||
logging.debug(f"Looking for MCP tool {function_name}")
|
||||
# Check if any of the MCP tools match the function name
|
||||
for mcp_tool in self.tools.runner.tools:
|
||||
if hasattr(mcp_tool, 'name') and mcp_tool.name == function_name:
|
||||
logging.debug(f"Found matching MCP tool: {function_name}")
|
||||
return self.tools.runner.call_tool(function_name, arguments)
|
||||
|
||||
# Handle SSE MCP client
|
||||
if hasattr(self.tools, 'is_sse') and self.tools.is_sse:
|
||||
if hasattr(self.tools, 'sse_client'):
|
||||
for tool in self.tools.sse_client.tools:
|
||||
if tool.name == function_name:
|
||||
logging.debug(f"Found matching SSE MCP tool: {function_name}")
|
||||
return tool(**arguments)
|
||||
# Handle stdio MCP client
|
||||
elif hasattr(self.tools, 'runner'):
|
||||
# Check if any of the MCP tools match the function name
|
||||
for mcp_tool in self.tools.runner.tools:
|
||||
if hasattr(mcp_tool, 'name') and mcp_tool.name == function_name:
|
||||
logging.debug(f"Found matching MCP tool: {function_name}")
|
||||
return self.tools.runner.call_tool(function_name, arguments)
|
||||
|
||||
# Try to find the function in the agent's tools list first
|
||||
func = None
|
||||
@@ -770,7 +780,7 @@ Your Goal: {self.goal}
|
||||
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, reasoning_steps=False):
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False, stream=True):
|
||||
# Log all parameter values when in debug mode
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
param_info = {
|
||||
@@ -815,7 +825,11 @@ Your Goal: {self.goal}
|
||||
logging.debug("Converting MCP tool to OpenAI format")
|
||||
openai_tool = tool_param.to_openai_tool()
|
||||
if openai_tool:
|
||||
tool_param = [openai_tool]
|
||||
# Handle both single tool and list of tools
|
||||
if isinstance(openai_tool, list):
|
||||
tool_param = openai_tool
|
||||
else:
|
||||
tool_param = [openai_tool]
|
||||
logging.debug(f"Converted MCP tool: {tool_param}")
|
||||
|
||||
# Pass everything to LLM class
|
||||
@@ -912,7 +926,7 @@ Your Goal: {self.goal}
|
||||
agent_tools=agent_tools
|
||||
)
|
||||
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None, reasoning_steps=reasoning_steps)
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None, reasoning_steps=reasoning_steps, stream=stream)
|
||||
if not response:
|
||||
return None
|
||||
|
||||
@@ -949,7 +963,7 @@ Your Goal: {self.goal}
|
||||
"content": "Function returned an empty output"
|
||||
})
|
||||
|
||||
response = self._chat_completion(messages, temperature=temperature)
|
||||
response = self._chat_completion(messages, temperature=temperature, stream=stream)
|
||||
if not response:
|
||||
return None
|
||||
response_text = response.choices[0].message.content.strip()
|
||||
@@ -1019,7 +1033,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
logging.debug(f"{self.name} reflection count {reflection_count + 1}, continuing reflection process")
|
||||
messages.append({"role": "user", "content": "Now regenerate your response using the reflection you made"})
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=None, stream=True)
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=None, stream=stream)
|
||||
response_text = response.choices[0].message.content.strip()
|
||||
reflection_count += 1
|
||||
continue # Continue the loop for more reflections
|
||||
@@ -1199,7 +1213,7 @@ Your Goal: {self.goal}
|
||||
model=self.llm,
|
||||
messages=messages,
|
||||
temperature=temperature,
|
||||
tools=formatted_tools
|
||||
tools=formatted_tools,
|
||||
)
|
||||
result = await self._achat_completion(response, tools)
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
|
||||
@@ -45,7 +45,7 @@ def process_video(video_path: str, seconds_per_frame=2):
|
||||
return base64_frames
|
||||
|
||||
class PraisonAIAgents:
|
||||
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None, user_id=None, max_iter=10):
|
||||
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None, user_id=None, max_iter=10, stream=True):
|
||||
# Add check at the start if memory is requested
|
||||
if memory:
|
||||
try:
|
||||
@@ -68,8 +68,8 @@ class PraisonAIAgents:
|
||||
for agent in agents:
|
||||
agent.user_id = self.user_id
|
||||
|
||||
self.agents = agents
|
||||
self.tasks = {}
|
||||
self.agents: List[Agent] = agents
|
||||
self.tasks: Dict[int, Task] = {}
|
||||
if max_retries < 3:
|
||||
max_retries = 3
|
||||
self.completion_checker = completion_checker if completion_checker else self.default_completion_checker
|
||||
@@ -77,6 +77,7 @@ class PraisonAIAgents:
|
||||
self.verbose = verbose
|
||||
self.max_retries = max_retries
|
||||
self.process = process
|
||||
self.stream = stream
|
||||
|
||||
# Check for manager_llm in environment variable if not provided
|
||||
self.manager_llm = manager_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
|
||||
@@ -665,7 +666,8 @@ Context:
|
||||
task_prompt,
|
||||
tools=task.tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
output_pydantic=task.output_pydantic,
|
||||
stream=self.stream,
|
||||
)
|
||||
|
||||
if agent_output:
|
||||
|
||||
@@ -7,7 +7,6 @@ class Chunking:
|
||||
|
||||
CHUNKER_PARAMS = {
|
||||
'token': ['chunk_size', 'chunk_overlap', 'tokenizer'],
|
||||
'word': ['chunk_size', 'chunk_overlap', 'tokenizer_or_token_counter'],
|
||||
'sentence': ['chunk_size', 'chunk_overlap', 'tokenizer_or_token_counter'],
|
||||
'recursive': ['chunk_size', 'tokenizer_or_token_counter'],
|
||||
'semantic': ['chunk_size', 'embedding_model'],
|
||||
@@ -19,9 +18,8 @@ class Chunking:
|
||||
def SUPPORTED_CHUNKERS(self) -> Dict[str, Any]:
|
||||
"""Lazy load chunker classes."""
|
||||
try:
|
||||
from chonkie.chunker import (
|
||||
from chonkie import (
|
||||
TokenChunker,
|
||||
WordChunker,
|
||||
SentenceChunker,
|
||||
SemanticChunker,
|
||||
SDPMChunker,
|
||||
@@ -35,7 +33,6 @@ class Chunking:
|
||||
|
||||
return {
|
||||
'token': TokenChunker,
|
||||
'word': WordChunker,
|
||||
'sentence': SentenceChunker,
|
||||
'semantic': SemanticChunker,
|
||||
'sdpm': SDPMChunker,
|
||||
@@ -114,63 +111,82 @@ class Chunking:
|
||||
|
||||
return self._chunker
|
||||
|
||||
def _get_overlap_refinery(self, context_size: Optional[int] = None, **kwargs):
|
||||
"""Lazy load the overlap refinery."""
|
||||
try:
|
||||
from chonkie.refinery import OverlapRefinery
|
||||
except ImportError:
|
||||
raise ImportError("Failed to import OverlapRefinery from chonkie.refinery")
|
||||
# NOTE: OverlapRefinery is not supported, disabled for now
|
||||
# As soon as Chonkie is updated to support it, we can re-enable it!
|
||||
# Track in https://github.com/chonkie-inc/chonkie/issues/21
|
||||
|
||||
# def _get_overlap_refinery(self, context_size: Optional[int] = None, **kwargs):
|
||||
# """Lazy load the overlap refinery."""
|
||||
# try:
|
||||
# from chonkie.refinery import OverlapRefinery
|
||||
# except ImportError:
|
||||
# raise ImportError("Failed to import OverlapRefinery from chonkie.refinery")
|
||||
|
||||
if context_size is None:
|
||||
context_size = self.chunk_overlap
|
||||
# if context_size is None:
|
||||
# context_size = self.chunk_overlap
|
||||
|
||||
return OverlapRefinery(
|
||||
context_size=context_size,
|
||||
tokenizer=self.chunker.tokenizer,
|
||||
**kwargs
|
||||
)
|
||||
# return OverlapRefinery(
|
||||
# context_size=context_size,
|
||||
# tokenizer=self.chunker.tokenizer,
|
||||
# **kwargs
|
||||
# )
|
||||
|
||||
def add_overlap_context(
|
||||
self,
|
||||
chunks: List[Any],
|
||||
context_size: int = None,
|
||||
mode: str = "suffix",
|
||||
merge_context: bool = True
|
||||
) -> List[Any]:
|
||||
"""Add overlap context to chunks using OverlapRefinery."""
|
||||
refinery = self._get_overlap_refinery(
|
||||
context_size=context_size,
|
||||
mode=mode,
|
||||
merge_context=merge_context
|
||||
)
|
||||
return refinery.refine(chunks)
|
||||
# def add_overlap_context(
|
||||
# self,
|
||||
# chunks: List[Any],
|
||||
# context_size: int = None,
|
||||
# mode: str = "suffix",
|
||||
# merge_context: bool = True
|
||||
# ) -> List[Any]:
|
||||
# """Add overlap context to chunks using OverlapRefinery."""
|
||||
# refinery = self._get_overlap_refinery(
|
||||
# context_size=context_size,
|
||||
# mode=mode,
|
||||
# merge_context=merge_context
|
||||
# )
|
||||
# return refinery.refine(chunks)
|
||||
|
||||
def chunk(
|
||||
self,
|
||||
text: Union[str, List[str]],
|
||||
add_context: bool = False,
|
||||
context_params: Optional[Dict[str, Any]] = None
|
||||
# Disable context for now, as it's not supported
|
||||
# add_context: bool = False,
|
||||
# context_params: Optional[Dict[str, Any]] = None
|
||||
**kwargs # Added to maintain compatibility with the original `chunk` method signature
|
||||
) -> Union[List[Any], List[List[Any]]]:
|
||||
"""Chunk text using the configured chunking strategy."""
|
||||
chunks = self.chunker(text)
|
||||
|
||||
if add_context:
|
||||
context_params = context_params or {}
|
||||
if isinstance(text, str):
|
||||
chunks = self.add_overlap_context(chunks, **context_params)
|
||||
else:
|
||||
chunks = [self.add_overlap_context(c, **context_params) for c in chunks]
|
||||
# NOTE: OverlapRefinery is not supported, disabled for now
|
||||
# As soon as Chonkie is updated to support it, we can re-enable it!
|
||||
# Track in https://github.com/chonkie-inc/chonkie/issues/21
|
||||
|
||||
# if add_context:
|
||||
# context_params = context_params or {}
|
||||
# if isinstance(text, str):
|
||||
# chunks = self.add_overlap_context(chunks, **context_params)
|
||||
# else:
|
||||
# chunks = [self.add_overlap_context(c, **context_params) for c in chunks]
|
||||
|
||||
if 'add_context' in kwargs or 'context_params' in kwargs:
|
||||
import warnings
|
||||
warnings.warn(
|
||||
"The `add_context` and `context_params` parameters are currently not supported for Chonkie as of version 1.0.2. They would be added in the future. Track in https://github.com/chonkie-inc/chonkie/issues/21",
|
||||
UserWarning
|
||||
)
|
||||
|
||||
return chunks
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
text: Union[str, List[str]],
|
||||
add_context: bool = False,
|
||||
context_params: Optional[Dict[str, Any]] = None
|
||||
# Disable context for now, as it's not supported
|
||||
# add_context: bool = False,
|
||||
# context_params: Optional[Dict[str, Any]] = None
|
||||
**kwargs # Added to maintain compatibility with the original `chunk` method signature
|
||||
) -> Union[List[Any], List[List[Any]]]:
|
||||
"""Make the Chunking instance callable."""
|
||||
return self.chunk(text, add_context, context_params)
|
||||
return self.chunk(text, **kwargs)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""String representation of the Chunking instance."""
|
||||
|
||||
@@ -17,7 +17,7 @@ class CustomMemory:
|
||||
}).from_config(config)
|
||||
|
||||
@staticmethod
|
||||
def _add_to_vector_store(self, messages, metadata, filters):
|
||||
def _add_to_vector_store(self, messages, metadata, filters, infer):
|
||||
# Custom implementation that doesn't use LLM
|
||||
parsed_messages = "\n".join([msg["content"] for msg in messages])
|
||||
|
||||
|
||||
@@ -293,6 +293,12 @@ class LLM:
|
||||
if isinstance(tool, dict) and 'type' in tool and tool['type'] == 'function':
|
||||
logging.debug(f"Using pre-formatted OpenAI tool: {tool['function']['name']}")
|
||||
formatted_tools.append(tool)
|
||||
# Handle lists of tools (e.g. from MCP.to_openai_tool())
|
||||
elif isinstance(tool, list):
|
||||
for subtool in tool:
|
||||
if isinstance(subtool, dict) and 'type' in subtool and subtool['type'] == 'function':
|
||||
logging.debug(f"Using pre-formatted OpenAI tool from list: {subtool['function']['name']}")
|
||||
formatted_tools.append(subtool)
|
||||
elif callable(tool):
|
||||
tool_def = self._generate_tool_definition(tool.__name__)
|
||||
if tool_def:
|
||||
@@ -520,8 +526,16 @@ class LLM:
|
||||
if ('name' in json_response or 'function' in json_response) and not any(word in response_text.lower() for word in ['summary', 'option', 'result', 'found']):
|
||||
logging.debug("Detected Ollama returning only tool call JSON, making follow-up call to process results")
|
||||
|
||||
# Create a prompt that asks the model to process the tool results
|
||||
follow_up_prompt = f"I've searched for apartments and found these results. Please analyze them and provide a summary of the best options:\n\n{json.dumps(tool_result, indent=2)}\n\nPlease format your response as a nice summary with the top options."
|
||||
# Create a prompt that asks the model to process the tool results based on original context
|
||||
# Extract the original user query from messages
|
||||
original_query = ""
|
||||
for msg in messages:
|
||||
if msg.get("role") == "user":
|
||||
original_query = msg.get("content", "")
|
||||
break
|
||||
|
||||
# Create a shorter follow-up prompt
|
||||
follow_up_prompt = f"Results:\n{json.dumps(tool_result, indent=2)}\nProvide Answer to this Original Question based on the above results: '{original_query}'"
|
||||
|
||||
# Make a follow-up call to process the results
|
||||
follow_up_messages = [
|
||||
@@ -1091,8 +1105,16 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
if ('name' in json_response or 'function' in json_response) and not any(word in response_text.lower() for word in ['summary', 'option', 'result', 'found']):
|
||||
logging.debug("Detected Ollama returning only tool call JSON in async mode, making follow-up call to process results")
|
||||
|
||||
# Create a prompt that asks the model to process the tool results
|
||||
follow_up_prompt = f"I've searched for apartments and found these results. Please analyze them and provide a summary of the best options:\n\n{json.dumps(tool_result, indent=2)}\n\nPlease format your response as a nice summary with the top options."
|
||||
# Create a prompt that asks the model to process the tool results based on original context
|
||||
# Extract the original user query from messages
|
||||
original_query = ""
|
||||
for msg in messages:
|
||||
if msg.get("role") == "user":
|
||||
original_query = msg.get("content", "")
|
||||
break
|
||||
|
||||
# Create a shorter follow-up prompt
|
||||
follow_up_prompt = f"Results:\n{json.dumps(tool_result, indent=2)}\nProvide Answer to this Original Question based on the above results: '{original_query}'"
|
||||
|
||||
# Make a follow-up call to process the results
|
||||
follow_up_messages = [
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
"""
|
||||
Model Context Protocol (MCP) integration for PraisonAI Agents.
|
||||
|
||||
This package provides classes and utilities for connecting to MCP servers
|
||||
using different transport methods (stdio, SSE, etc.).
|
||||
"""
|
||||
from .mcp import MCP
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import inspect
|
||||
import shlex
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from typing import Any, List, Optional, Callable, Iterable, Union
|
||||
from functools import wraps, partial
|
||||
|
||||
@@ -126,6 +127,13 @@ class MCP:
|
||||
tools=MCP("/path/to/python /path/to/app.py")
|
||||
)
|
||||
|
||||
# Method 3: Using an SSE endpoint
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant...",
|
||||
llm="gpt-4o-mini",
|
||||
tools=MCP("http://localhost:8080/sse")
|
||||
)
|
||||
|
||||
agent.start("What is the stock price of Tesla?")
|
||||
```
|
||||
"""
|
||||
@@ -139,6 +147,7 @@ class MCP:
|
||||
- The command to run the MCP server (e.g., Python path)
|
||||
- A complete command string (e.g., "/path/to/python /path/to/app.py")
|
||||
- For NPX: 'npx' command with args for smithery tools
|
||||
- An SSE URL (e.g., "http://localhost:8080/sse")
|
||||
args: Arguments to pass to the command (when command_or_string is the command)
|
||||
command: Alternative parameter name for backward compatibility
|
||||
timeout: Timeout in seconds for MCP server initialization and tool calls (default: 60)
|
||||
@@ -149,7 +158,44 @@ class MCP:
|
||||
if command_or_string is None and command is not None:
|
||||
command_or_string = command
|
||||
|
||||
# Handle the single string format
|
||||
# Set up logging - default to WARNING level to hide INFO messages
|
||||
if debug:
|
||||
logging.getLogger("mcp-wrapper").setLevel(logging.DEBUG)
|
||||
logging.getLogger("mcp-sse").setLevel(logging.DEBUG)
|
||||
logging.getLogger("mcp.client").setLevel(logging.DEBUG)
|
||||
logging.getLogger("sse").setLevel(logging.DEBUG)
|
||||
logging.getLogger("mcp-server").setLevel(logging.DEBUG)
|
||||
logging.getLogger("mcp-client").setLevel(logging.DEBUG)
|
||||
logging.getLogger("_client").setLevel(logging.DEBUG)
|
||||
logging.getLogger("httpx").setLevel(logging.DEBUG)
|
||||
logging.getLogger("llm").setLevel(logging.DEBUG)
|
||||
else:
|
||||
# Set all MCP-related loggers to WARNING level by default
|
||||
logging.getLogger("mcp-wrapper").setLevel(logging.WARNING)
|
||||
logging.getLogger("mcp-sse").setLevel(logging.WARNING)
|
||||
logging.getLogger("mcp.client").setLevel(logging.WARNING)
|
||||
logging.getLogger("sse").setLevel(logging.WARNING)
|
||||
logging.getLogger("mcp-server").setLevel(logging.WARNING)
|
||||
logging.getLogger("mcp-client").setLevel(logging.WARNING)
|
||||
logging.getLogger("_client").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("llm").setLevel(logging.WARNING)
|
||||
|
||||
# Store additional parameters
|
||||
self.timeout = timeout
|
||||
self.debug = debug
|
||||
|
||||
# Check if this is an SSE URL
|
||||
if isinstance(command_or_string, str) and re.match(r'^https?://', command_or_string):
|
||||
# Import the SSE client implementation
|
||||
from .mcp_sse import SSEMCPClient
|
||||
self.sse_client = SSEMCPClient(command_or_string, debug=debug)
|
||||
self._tools = list(self.sse_client.tools)
|
||||
self.is_sse = True
|
||||
self.is_npx = False
|
||||
return
|
||||
|
||||
# Handle the single string format for stdio client
|
||||
if isinstance(command_or_string, str) and args is None:
|
||||
# Split the string into command and args using shell-like parsing
|
||||
parts = shlex.split(command_or_string)
|
||||
@@ -162,7 +208,9 @@ class MCP:
|
||||
# Use the original format with separate command and args
|
||||
cmd = command_or_string
|
||||
arguments = args or []
|
||||
|
||||
|
||||
# Set up stdio client
|
||||
self.is_sse = False
|
||||
self.server_params = StdioServerParameters(
|
||||
command=cmd,
|
||||
args=arguments,
|
||||
@@ -173,13 +221,6 @@ class MCP:
|
||||
# Wait for initialization
|
||||
if not self.runner.initialized.wait(timeout=30):
|
||||
print("Warning: MCP initialization timed out")
|
||||
|
||||
# Store additional parameters
|
||||
self.timeout = timeout
|
||||
self.debug = debug
|
||||
|
||||
if debug:
|
||||
logging.getLogger("mcp-wrapper").setLevel(logging.DEBUG)
|
||||
|
||||
# Automatically detect if this is an NPX command
|
||||
self.is_npx = cmd == 'npx' or (isinstance(cmd, str) and os.path.basename(cmd) == 'npx')
|
||||
@@ -199,6 +240,9 @@ class MCP:
|
||||
Returns:
|
||||
List[Callable]: Functions that can be used as tools
|
||||
"""
|
||||
if self.is_sse:
|
||||
return list(self.sse_client.tools)
|
||||
|
||||
tool_functions = []
|
||||
|
||||
for tool in self.runner.tools:
|
||||
@@ -303,8 +347,6 @@ class MCP:
|
||||
logging.error(f"Failed to initialize NPX MCP tools: {e}")
|
||||
raise RuntimeError(f"Failed to initialize NPX MCP tools: {e}")
|
||||
|
||||
|
||||
|
||||
def __iter__(self) -> Iterable[Callable]:
|
||||
"""
|
||||
Allow the MCP instance to be used directly as an iterable of tools.
|
||||
@@ -320,37 +362,43 @@ class MCP:
|
||||
provider/model format (e.g., "openai/gpt-4o-mini").
|
||||
|
||||
Returns:
|
||||
dict: OpenAI-compatible tool definition
|
||||
dict or list: OpenAI-compatible tool definition(s)
|
||||
"""
|
||||
if self.is_sse and hasattr(self, 'sse_client') and self.sse_client.tools:
|
||||
# Return all tools from SSE client
|
||||
return self.sse_client.to_openai_tools()
|
||||
|
||||
# For simplicity, we'll convert the first tool only if multiple exist
|
||||
# More complex implementations could handle multiple tools
|
||||
if not self.runner.tools:
|
||||
if not hasattr(self, 'runner') or not self.runner.tools:
|
||||
logging.warning("No MCP tools available to convert to OpenAI format")
|
||||
return None
|
||||
|
||||
# Get the first tool's schema
|
||||
tool = self.runner.tools[0]
|
||||
# Convert all tools to OpenAI format
|
||||
openai_tools = []
|
||||
for tool in self.runner.tools:
|
||||
# Create OpenAI tool definition
|
||||
parameters = {}
|
||||
if hasattr(tool, 'inputSchema') and tool.inputSchema:
|
||||
parameters = tool.inputSchema
|
||||
else:
|
||||
# Create a minimal schema if none exists
|
||||
parameters = {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": []
|
||||
}
|
||||
|
||||
openai_tools.append({
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": tool.name,
|
||||
"description": tool.description if hasattr(tool, 'description') else f"Call the {tool.name} tool",
|
||||
"parameters": parameters
|
||||
}
|
||||
})
|
||||
|
||||
# Create OpenAI tool definition
|
||||
parameters = {}
|
||||
if hasattr(tool, 'inputSchema') and tool.inputSchema:
|
||||
parameters = tool.inputSchema
|
||||
else:
|
||||
# Create a minimal schema if none exists
|
||||
parameters = {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"required": []
|
||||
}
|
||||
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": tool.name,
|
||||
"description": tool.description if hasattr(tool, 'description') else f"Call the {tool.name} tool",
|
||||
"parameters": parameters
|
||||
}
|
||||
}
|
||||
return openai_tools
|
||||
|
||||
def __del__(self):
|
||||
"""Clean up resources when the object is garbage collected."""
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
"""
|
||||
SSE (Server-Sent Events) client implementation for MCP (Model Context Protocol).
|
||||
This module provides the necessary classes and functions to connect to an MCP server
|
||||
over SSE transport.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import threading
|
||||
import inspect
|
||||
import json
|
||||
from typing import List, Dict, Any, Optional, Callable, Iterable
|
||||
|
||||
from mcp import ClientSession
|
||||
from mcp.client.sse import sse_client
|
||||
|
||||
logger = logging.getLogger("mcp-sse")
|
||||
|
||||
# Global event loop for async operations
|
||||
_event_loop = None
|
||||
|
||||
def get_event_loop():
|
||||
"""Get or create a global event loop."""
|
||||
global _event_loop
|
||||
if _event_loop is None or _event_loop.is_closed():
|
||||
_event_loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(_event_loop)
|
||||
return _event_loop
|
||||
|
||||
|
||||
class SSEMCPTool:
|
||||
"""A wrapper for an MCP tool that can be used with praisonaiagents."""
|
||||
|
||||
def __init__(self, name: str, description: str, session: ClientSession, input_schema: Optional[Dict[str, Any]] = None):
|
||||
self.name = name
|
||||
self.__name__ = name # Required for Agent to recognize it as a tool
|
||||
self.__qualname__ = name # Required for Agent to recognize it as a tool
|
||||
self.__doc__ = description # Required for Agent to recognize it as a tool
|
||||
self.description = description
|
||||
self.session = session
|
||||
self.input_schema = input_schema or {}
|
||||
|
||||
# Create a signature based on input schema
|
||||
params = []
|
||||
if input_schema and 'properties' in input_schema:
|
||||
for param_name in input_schema['properties']:
|
||||
params.append(
|
||||
inspect.Parameter(
|
||||
name=param_name,
|
||||
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
|
||||
default=inspect.Parameter.empty if param_name in input_schema.get('required', []) else None,
|
||||
annotation=str # Default to string
|
||||
)
|
||||
)
|
||||
|
||||
self.__signature__ = inspect.Signature(params)
|
||||
|
||||
def __call__(self, **kwargs):
|
||||
"""Synchronous wrapper for the async call."""
|
||||
logger.debug(f"Tool {self.name} called with args: {kwargs}")
|
||||
|
||||
# Use the global event loop
|
||||
loop = get_event_loop()
|
||||
|
||||
# Run the async call in the event loop
|
||||
future = asyncio.run_coroutine_threadsafe(self._async_call(**kwargs), loop)
|
||||
try:
|
||||
# Wait for the result with a timeout
|
||||
return future.result(timeout=30)
|
||||
except Exception as e:
|
||||
logger.error(f"Error calling tool {self.name}: {e}")
|
||||
return f"Error: {str(e)}"
|
||||
|
||||
async def _async_call(self, **kwargs):
|
||||
"""Call the tool with the provided arguments."""
|
||||
logger.debug(f"Async calling tool {self.name} with args: {kwargs}")
|
||||
try:
|
||||
result = await self.session.call_tool(self.name, kwargs)
|
||||
|
||||
# Extract text from result
|
||||
if hasattr(result, 'content') and result.content:
|
||||
if hasattr(result.content[0], 'text'):
|
||||
return result.content[0].text
|
||||
return str(result.content[0])
|
||||
return str(result)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in _async_call for {self.name}: {e}")
|
||||
raise
|
||||
|
||||
def to_openai_tool(self):
|
||||
"""Convert the tool to OpenAI format."""
|
||||
return {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": self.name,
|
||||
"description": self.description,
|
||||
"parameters": self.input_schema
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SSEMCPClient:
|
||||
"""A client for connecting to an MCP server over SSE."""
|
||||
|
||||
def __init__(self, server_url: str, debug: bool = False):
|
||||
"""
|
||||
Initialize an SSE MCP client.
|
||||
|
||||
Args:
|
||||
server_url: The URL of the SSE MCP server
|
||||
debug: Whether to enable debug logging
|
||||
"""
|
||||
self.server_url = server_url
|
||||
self.debug = debug
|
||||
self.session = None
|
||||
self.tools = []
|
||||
|
||||
# Set up logging
|
||||
if debug:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
else:
|
||||
# Set to WARNING by default to hide INFO messages
|
||||
logger.setLevel(logging.WARNING)
|
||||
|
||||
self._initialize()
|
||||
|
||||
def _initialize(self):
|
||||
"""Initialize the connection and tools."""
|
||||
# Use the global event loop
|
||||
loop = get_event_loop()
|
||||
|
||||
# Start a background thread to run the event loop
|
||||
def run_event_loop():
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_forever()
|
||||
|
||||
self.loop_thread = threading.Thread(target=run_event_loop, daemon=True)
|
||||
self.loop_thread.start()
|
||||
|
||||
# Run the initialization in the event loop
|
||||
future = asyncio.run_coroutine_threadsafe(self._async_initialize(), loop)
|
||||
self.tools = future.result(timeout=30)
|
||||
|
||||
async def _async_initialize(self):
|
||||
"""Asynchronously initialize the connection and tools."""
|
||||
logger.debug(f"Connecting to MCP server at {self.server_url}")
|
||||
|
||||
# Create SSE client
|
||||
self._streams_context = sse_client(url=self.server_url)
|
||||
streams = await self._streams_context.__aenter__()
|
||||
|
||||
self._session_context = ClientSession(*streams)
|
||||
self.session = await self._session_context.__aenter__()
|
||||
|
||||
# Initialize
|
||||
await self.session.initialize()
|
||||
|
||||
# List available tools
|
||||
logger.debug("Listing tools...")
|
||||
response = await self.session.list_tools()
|
||||
tools_data = response.tools
|
||||
logger.debug(f"Found {len(tools_data)} tools: {[tool.name for tool in tools_data]}")
|
||||
|
||||
# Create tool wrappers
|
||||
tools = []
|
||||
for tool in tools_data:
|
||||
input_schema = tool.inputSchema if hasattr(tool, 'inputSchema') else None
|
||||
wrapper = SSEMCPTool(
|
||||
name=tool.name,
|
||||
description=tool.description if hasattr(tool, 'description') else f"Call the {tool.name} tool",
|
||||
session=self.session,
|
||||
input_schema=input_schema
|
||||
)
|
||||
tools.append(wrapper)
|
||||
|
||||
return tools
|
||||
|
||||
def __iter__(self):
|
||||
"""Return an iterator over the tools."""
|
||||
return iter(self.tools)
|
||||
|
||||
def to_openai_tools(self):
|
||||
"""Convert all tools to OpenAI format."""
|
||||
return [tool.to_openai_tool() for tool in self.tools]
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.70"
|
||||
version = "0.0.77"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
authors = [
|
||||
{ name="Mervin Praison" }
|
||||
@@ -13,10 +13,14 @@ dependencies = [
|
||||
"pydantic",
|
||||
"rich",
|
||||
"openai",
|
||||
"mcp==1.6.0"
|
||||
"mcp>=1.6.0"
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
mcp = [
|
||||
"mcp>=1.6.0"
|
||||
]
|
||||
|
||||
memory = [
|
||||
"chromadb>=0.5.23"
|
||||
]
|
||||
@@ -24,8 +28,8 @@ memory = [
|
||||
knowledge = [
|
||||
"mem0ai>=0.1.0",
|
||||
"chromadb==0.5.23",
|
||||
"markitdown",
|
||||
"chonkie>=0.5.0"
|
||||
"markitdown[all]",
|
||||
"chonkie>=1.0.2"
|
||||
]
|
||||
|
||||
# Add LLM dependencies
|
||||
@@ -38,5 +42,6 @@ llm = [
|
||||
all = [
|
||||
"praisonaiagents[memory]",
|
||||
"praisonaiagents[knowledge]",
|
||||
"praisonaiagents[llm]"
|
||||
"praisonaiagents[llm]",
|
||||
"praisonaiagents[mcp]"
|
||||
]
|
||||
@@ -9,7 +9,7 @@ chromadb>=0.5.23
|
||||
# Knowledge dependencies
|
||||
mem0ai>=0.1.0
|
||||
markitdown
|
||||
chonkie>=0.5.0
|
||||
chonkie>=1.0.2
|
||||
|
||||
# Development dependencies
|
||||
python-dotenv>=0.19.0
|
||||
Generated
+14
-21
@@ -170,19 +170,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/35/be73b6015511aa0173ec595fc579133b797ad532996f2998fd6b8d1bbe6b/audioop_lts-0.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:78bfb3703388c780edf900be66e07de5a3d4105ca8e8720c5c4d67927e0b15d0", size = 23918 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autotiktokenizer"
|
||||
version = "0.2.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "tiktoken" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a6/1a/c6f494750dc67c2e5b06b91ae9565d46adb384f25f61a7136ff79dd02413/autotiktokenizer-0.2.2.tar.gz", hash = "sha256:f0954f14cedfe538b96ba0eed2e39996378c0bdf649fd977d6a047e419e05fdb", size = 15401 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/7b/c34469a1495d755bac1c80fbf3c0c2c29eb03ffe61172d889426025173bd/autotiktokenizer-0.2.2-py3-none-any.whl", hash = "sha256:ebbf15d9d5516fcb3287a8153bd8efbcc932f9c99089b2357255413cf37815d9", size = 8957 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backoff"
|
||||
version = "2.2.1"
|
||||
@@ -361,15 +348,15 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "chonkie"
|
||||
version = "0.4.1"
|
||||
version = "1.0.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "autotiktokenizer" },
|
||||
{ name = "tokenizers" },
|
||||
{ name = "tqdm" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2e/94/4a1bc8bdf06e7327bb256abb85767647125286c9bbc7cbcd77a550b96d63/chonkie-0.4.1.tar.gz", hash = "sha256:164216efa01af02e750e7cb218cea87918a18f83ebbd8f020b25557f1ed36aa9", size = 43284 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/7c/5fe68d5eec5e741ad63721c9ffda4264c24aeebc2bd6f545bffb710a0389/chonkie-1.0.2.tar.gz", hash = "sha256:70515ed439ca6840ab7eb0e2f5abeab6feecbfca592317b1f91dd1a7986597d4", size = 42693 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/b5/c0d77500a413794773edb630bdc7061121c237a4eaf6ce222226c200d603/chonkie-0.4.1-py3-none-any.whl", hash = "sha256:af7d95d17f4ed60a26e32f0bad60f807287e3301189114755d727657ed2ef964", size = 51193 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/21/d2785bbce3a162c675c3b719a3b6cafe3798fce75ea8af8128f7708031e1/chonkie-1.0.2-py3-none-any.whl", hash = "sha256:f8157099f22f2132395303e547232d9a4eccd9053298062ec472d9d4d88f4da9", size = 50706 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1896,7 +1883,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.70"
|
||||
version = "0.0.77"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "mcp" },
|
||||
@@ -1911,6 +1898,7 @@ all = [
|
||||
{ name = "chromadb" },
|
||||
{ name = "litellm" },
|
||||
{ name = "markitdown" },
|
||||
{ name = "mcp" },
|
||||
{ name = "mem0ai" },
|
||||
{ name = "pydantic" },
|
||||
]
|
||||
@@ -1924,22 +1912,27 @@ llm = [
|
||||
{ name = "litellm" },
|
||||
{ name = "pydantic" },
|
||||
]
|
||||
mcp = [
|
||||
{ name = "mcp" },
|
||||
]
|
||||
memory = [
|
||||
{ name = "chromadb" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "chonkie", marker = "extra == 'knowledge'" },
|
||||
{ name = "chonkie", marker = "extra == 'knowledge'", specifier = ">=1.0.2" },
|
||||
{ name = "chromadb", marker = "extra == 'knowledge'", specifier = "==0.5.23" },
|
||||
{ name = "chromadb", marker = "extra == 'memory'", specifier = ">=0.5.23" },
|
||||
{ name = "litellm", marker = "extra == 'llm'", specifier = ">=1.50.0" },
|
||||
{ name = "markitdown", marker = "extra == 'knowledge'" },
|
||||
{ name = "mcp", specifier = "==1.6.0" },
|
||||
{ name = "markitdown", extras = ["all"], marker = "extra == 'knowledge'" },
|
||||
{ name = "mcp", specifier = ">=1.6.0" },
|
||||
{ name = "mcp", marker = "extra == 'mcp'", specifier = ">=1.6.0" },
|
||||
{ name = "mem0ai", marker = "extra == 'knowledge'", specifier = ">=0.1.0" },
|
||||
{ name = "openai" },
|
||||
{ name = "praisonaiagents", extras = ["knowledge"], marker = "extra == 'all'" },
|
||||
{ name = "praisonaiagents", extras = ["llm"], marker = "extra == 'all'" },
|
||||
{ name = "praisonaiagents", extras = ["mcp"], marker = "extra == 'all'" },
|
||||
{ name = "praisonaiagents", extras = ["memory"], marker = "extra == 'all'" },
|
||||
{ name = "pydantic" },
|
||||
{ name = "pydantic", marker = "extra == 'llm'", specifier = ">=2.4.2" },
|
||||
|
||||
@@ -3079,7 +3079,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
@@ -3218,7 +3218,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.70" },
|
||||
{ name = "praisonaiagents", specifier = ">=0.0.71" },
|
||||
{ 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" },
|
||||
@@ -3271,7 +3271,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.70"
|
||||
version = "0.0.71"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mcp" },
|
||||
@@ -3279,9 +3279,9 @@ dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "rich" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a6/7f/f94506669bfff29034d7c00ac9ea3d3a15b8809fbb290d6ad9425729b73d/praisonaiagents-0.0.70.tar.gz", hash = "sha256:06335940410f644852cbcf1b38d0b13ed3a3606e217ed1d4cff0b61edd1e120e", size = 111475 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/ea/bdeaeb6f2b9d2598bc8daba175c4521f3e24e85ea26a8de90f48b1b63bd7/praisonaiagents-0.0.71.tar.gz", hash = "sha256:b6024cb73251f32a122825521a46a79519e67deb7c012f49da04f71d4d7c6b8d", size = 112123 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/da/2a11fb1338a122b7b9b17fa544d90d704a81477b9d7c723890dfa52a500d/praisonaiagents-0.0.70-py3-none-any.whl", hash = "sha256:d25b97bc3ae51d32512d373396d41068456a93194e9705a7fe70d1022db6e9a0", size = 131227 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/47/9a4e58542de19eadf4e9dc30b5e4bbbfd53fefb109a3a5c7c688de12bd1a/praisonaiagents-0.0.71-py3-none-any.whl", hash = "sha256:bc4a49b2ecddfe0a2c6cedd08d9c74467b29296810f7acc374008af515d93a9e", size = 131902 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in new issue
Block a user