Compare commits

...
12 Commits
Author SHA1 Message Date
Mervin Praison 124a95d7d0 Merge pull request #479 from MervinPraison/develop
Remove agent names and version constraints in MCP server documentation
2025-05-15 12:04:45 +01:00
MervinPraison 8ca4e3285d Remove agent names and version constraints in MCP server documentation 2025-05-15 12:04:07 +01:00
Mervin Praison 5eac60dab3 Merge pull request #478 from MervinPraison/develop
2.1.6
2025-05-15 07:54:46 +01:00
MervinPraison 59ee7cbbe5 Add MCP server examples and deployment docs with version bump to 2.1.6 2025-05-15 07:54:17 +01:00
MervinPraison 81517b58e5 Increment version to 0.0.82 in pyproject.toml and uv.lock, and enhance agent launch functionality in agents.py to support both HTTP and MCP protocols, including improved endpoint management, healthcheck capabilities, and error handling for agent execution. 2025-05-15 07:42:53 +01:00
Mervin Praison c1a8338a24 Merge pull request #477 from MervinPraison/develop
multi agents deploy
2025-05-14 13:08:57 +01:00
MervinPraison dba5a49569 multi agents deploy 2025-05-14 13:08:18 +01:00
Mervin Praison 6dab69e9d7 Merge pull request #476 from MervinPraison/develop
Add multi-agent API functionality in `multi-agents-api.py` and `multi…
2025-05-14 12:50:13 +01:00
MervinPraison 90563207f7 Add multi-agent API functionality in multi-agents-api.py and multi-agents-group-api.py, increment version to 0.0.80 in pyproject.toml and uv.lock, and enhance agent launch logic in agents.py with improved endpoint management and healthcheck capabilities. 2025-05-14 12:49:58 +01:00
Mervin Praison 46330b0487 Merge pull request #475 from MervinPraison/develop
v2.1.4
2025-05-14 10:49:01 +01:00
MervinPraison a133f0d5e2 Update package versions and add deployment documentation 2025-05-14 10:48:27 +01:00
MervinPraison fb22e6e1c7 Refactor agent launch functionality in multi-agent-api.py to remove blocking parameters, update version to 0.0.79 in pyproject.toml and uv.lock, and enhance server startup logic in agent.py with healthcheck endpoint and improved thread management. 2025-05-14 09:13:40 +01:00
36 changed files with 4201 additions and 1155 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.1.1 gunicorn markdown
RUN pip install flask praisonai==2.1.6 gunicorn markdown
EXPOSE 8080
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
+1 -1
View File
@@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai==2.1.6" \
"praisonai[chat]" \
"embedchain[github,youtube]"
+1 -1
View File
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai==2.1.6" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
+1 -1
View File
@@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
RUN pip install --no-cache-dir \
praisonaiagents>=0.0.4 \
praisonai_tools \
"praisonai==2.0.18" \
"praisonai==2.1.6" \
"praisonai[ui]" \
"praisonai[crewai]"
+1 -1
View File
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.1.1 gunicorn markdown\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.1.6 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
+416
View File
@@ -0,0 +1,416 @@
---
title: "Deploying to AWS"
sidebarTitle: "AWS"
description: "Deploy PraisonAI agents to Amazon Web Services for scalable production environments"
icon: "aws"
---
# Deploying PraisonAI Agents to AWS
This guide provides step-by-step instructions for deploying PraisonAI agents to Amazon Web Services (AWS), offering multiple deployment options to suit different requirements.
## Prerequisites
- AWS account with appropriate permissions
- AWS CLI installed and configured
- Docker installed on your local machine (for container-based deployments)
- Basic knowledge of AWS services and cloud deployment
## Deployment Options
There are several ways to deploy PraisonAI agents to AWS:
1. **AWS Lambda with API Gateway** (for serverless deployments)
2. **Amazon ECS/Fargate** (for containerized deployments)
3. **Amazon EC2** (for traditional VM-based deployments)
4. **AWS App Runner** (for simplified container deployments)
## Option 1: Deploying to EC2 (Traditional VM)
<Steps>
<Step title="Launch an EC2 Instance">
1. Go to the AWS Management Console
2. Navigate to EC2 and click "Launch Instance"
3. Choose Amazon Linux 2 or Ubuntu Server
4. Select an instance type (t2.micro for testing, t2.medium or larger for production)
5. Configure security groups to allow HTTP/HTTPS traffic
6. Launch the instance and connect to it via SSH
</Step>
<Step title="Set Up the Environment">
```bash
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install Python and pip
sudo apt install -y python3 python3-pip
# Install required packages
pip3 install "praisonaiagents[api]>=0.0.79"
```
</Step>
<Step title="Create the API Application">
Create a file named `api.py`:
```python
from praisonaiagents import Agent
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
agent.launch(path="/ask", port=8080, host="0.0.0.0")
```
</Step>
<Step title="Set Up a Systemd Service">
Create a systemd service file to run your application as a background service:
```bash
sudo nano /etc/systemd/system/praisonai-agent.service
```
Add the following content:
```ini
[Unit]
Description=PraisonAI Agent API Service
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu
Environment="OPENAI_API_KEY=your_api_key"
ExecStart=/usr/bin/python3 /home/ubuntu/api.py
Restart=always
[Install]
WantedBy=multi-user.target
```
Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable praisonai-agent
sudo systemctl start praisonai-agent
```
</Step>
<Step title="Set Up Nginx as a Reverse Proxy">
```bash
# Install Nginx
sudo apt install -y nginx
# Create a configuration file
sudo nano /etc/nginx/sites-available/praisonai-agent
```
Add the following configuration:
```nginx
server {
listen 80;
server_name your_domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
Enable the site and restart Nginx:
```bash
sudo ln -s /etc/nginx/sites-available/praisonai-agent /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```
</Step>
</Steps>
## Option 2: Deploying with Docker and ECS/Fargate
<Steps>
<Step title="Create a Dockerfile">
```dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Run the application
CMD ["python", "api.py"]
```
Create a `requirements.txt` file:
```
praisonaiagents[api]>=0.0.79
```
Create your `api.py` file:
```python
from praisonaiagents import Agent
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
agent.launch(path="/ask", port=8080, host="0.0.0.0")
```
</Step>
<Step title="Build and Push the Docker Image to ECR">
```bash
# Create an ECR repository
aws ecr create-repository --repository-name praisonai-agent
# Get the login command
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# Build the Docker image
docker build -t praisonai-agent .
# Tag the image
docker tag praisonai-agent:latest YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/praisonai-agent:latest
# Push the image to ECR
docker push YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/praisonai-agent:latest
```
</Step>
<Step title="Create an ECS Cluster and Task Definition">
```bash
# Create an ECS cluster
aws ecs create-cluster --cluster-name praisonai-cluster
# Create a task definition (JSON file)
cat > task-definition.json << EOF
{
"family": "praisonai-agent",
"networkMode": "awsvpc",
"executionRoleArn": "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "praisonai-agent",
"image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/praisonai-agent:latest",
"essential": true,
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "OPENAI_API_KEY",
"value": "your_api_key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/praisonai-agent",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "256",
"memory": "512"
}
EOF
# Register the task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json
```
</Step>
<Step title="Create a Fargate Service">
```bash
# Create a service
aws ecs create-service \
--cluster praisonai-cluster \
--service-name praisonai-service \
--task-definition praisonai-agent:1 \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:us-east-1:YOUR_AWS_ACCOUNT_ID:targetgroup/praisonai-tg/1234567890abcdef,containerName=praisonai-agent,containerPort=8080"
```
Note: You'll need to create an Application Load Balancer and target group before running this command.
</Step>
</Steps>
## Multi-Agent Deployment
For deploying multiple agents, you can use a single service with different endpoints:
```python
# multi-agent-api.py
from praisonaiagents import Agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
weather_agent.launch(path="/weather", port=8080, host="0.0.0.0")
stock_agent.launch(path="/stock", port=8080, host="0.0.0.0")
travel_agent.launch(path="/travel", port=8080, host="0.0.0.0")
```
## Option 3: Serverless Deployment with AWS Lambda
For lightweight agents that don't require long-running processes, you can use AWS Lambda with API Gateway:
```python
# lambda_function.py
from praisonaiagents import Agent
import json
# Initialize the agent outside the handler for better cold start performance
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
def lambda_handler(event, context):
try:
# Extract the message from the event
body = json.loads(event.get('body', '{}'))
message = body.get('message', '')
# Process the message with the agent
response = agent.process(message)
# Return the response
return {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'response': response
})
}
except Exception as e:
return {
'statusCode': 500,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'error': str(e)
})
}
```
## Scaling and Performance
### Auto Scaling
For EC2 deployments, set up an Auto Scaling group:
```bash
# Create a launch template
aws ec2 create-launch-template \
--launch-template-name praisonai-template \
--version-description "Initial version" \
--launch-template-data '{"ImageId":"ami-12345678","InstanceType":"t2.medium","UserData":"#!/bin/bash\ncd /home/ubuntu\npython3 api.py &"}'
# Create an Auto Scaling group
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name praisonai-asg \
--launch-template "LaunchTemplateName=praisonai-template,Version=1" \
--min-size 1 \
--max-size 5 \
--desired-capacity 2 \
--vpc-zone-identifier "subnet-12345678,subnet-87654321" \
--target-group-arns "arn:aws:elasticloadbalancing:us-east-1:YOUR_AWS_ACCOUNT_ID:targetgroup/praisonai-tg/1234567890abcdef"
```
### Load Balancing
Set up an Application Load Balancer to distribute traffic:
```bash
# Create a load balancer
aws elbv2 create-load-balancer \
--name praisonai-alb \
--subnets subnet-12345678 subnet-87654321 \
--security-groups sg-12345678
# Create a target group
aws elbv2 create-target-group \
--name praisonai-tg \
--protocol HTTP \
--port 8080 \
--vpc-id vpc-12345678 \
--target-type instance
# Create a listener
aws elbv2 create-listener \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:YOUR_AWS_ACCOUNT_ID:loadbalancer/app/praisonai-alb/1234567890abcdef \
--protocol HTTP \
--port 80 \
--default-actions Type=forward,TargetGroupArn=arn:aws:elasticloadbalancing:us-east-1:YOUR_AWS_ACCOUNT_ID:targetgroup/praisonai-tg/1234567890abcdef
```
## Security Best Practices
1. **Secret Management**: Use AWS Secrets Manager for API keys
```bash
# Store a secret
aws secretsmanager create-secret \
--name OPENAI_API_KEY \
--secret-string "your_api_key"
```
2. **IAM Roles**: Use the principle of least privilege
3. **VPC**: Deploy in a private subnet with controlled access
4. **WAF**: Set up AWS WAF to protect against common web exploits
5. **API Gateway**: Implement request validation and throttling
## Monitoring and Logging
1. **CloudWatch**: Set up dashboards and alarms
```bash
# Create a CloudWatch alarm for high CPU utilization
aws cloudwatch put-metric-alarm \
--alarm-name praisonai-high-cpu \
--alarm-description "Alarm when CPU exceeds 80%" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=AutoScalingGroupName,Value=praisonai-asg \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:us-east-1:YOUR_AWS_ACCOUNT_ID:praisonai-alerts
```
2. **X-Ray**: Enable tracing for detailed request analysis
3. **CloudTrail**: Monitor API calls for security analysis
4. **Log Insights**: Query and analyze logs with CloudWatch Log Insights
+223
View File
@@ -0,0 +1,223 @@
---
title: "Deploying PraisonAI Agents as APIs"
sidebarTitle: "API Deployment"
description: "Learn how to deploy PraisonAI agents as RESTful APIs for production environments"
icon: "server"
---
PraisonAI agents can be easily deployed as RESTful APIs, allowing you to integrate them into various applications and services. This guide covers how to deploy both single and multiple agents as APIs.
## Quick Start
<Steps>
<Step title="Install Dependencies">
Make sure you have the required packages installed:
```bash
pip install "praisonaiagents[api]"
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY="your_api_key"
```
</Step>
<Step title="Deploy a Simple Agent API">
Create a file named `simple-api.py` with the following code:
```python
from praisonaiagents import Agent
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
agent.launch(path="/ask", port=3030)
```
</Step>
<Step title="Run the API Server">
```bash
python simple-api.py
```
Your API will be available at `http://localhost:3030/ask`
</Step>
</Steps>
## Making API Requests
Once your agent is deployed, you can make POST requests to interact with it:
```bash
curl -X POST http://localhost:3030/ask \
-H "Content-Type: application/json" \
-d '{"message": "What is artificial intelligence?"}'
```
The response will be in JSON format:
```json
{
"response": "Artificial intelligence (AI) refers to the simulation of human intelligence in machines that are programmed to think and learn like humans. It encompasses various technologies including machine learning, natural language processing, computer vision, and robotics. AI systems can perform tasks that typically require human intelligence such as understanding natural language, recognizing patterns, solving problems, and making decisions."
}
```
## Multi-Agent API Deployment
You can deploy multiple agents on the same server, each with its own endpoint:
```python
from praisonaiagents import Agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
weather_agent.launch(path="/weather", port=3030)
stock_agent.launch(path="/stock", port=3030)
travel_agent.launch(path="/travel", port=3030)
```
With this setup, you can access:
- Weather agent at `http://localhost:3030/weather`
- Stock agent at `http://localhost:3030/stock`
- Travel agent at `http://localhost:3030/travel`
## Production Deployment Options
For production environments, consider the following deployment options:
### Docker Deployment
<Steps>
<Step title="Create a Dockerfile">
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 3030
CMD ["python", "api.py"]
```
</Step>
<Step title="Create requirements.txt">
```
praisonaiagents[api]>=0.0.79
```
</Step>
<Step title="Build and Run Docker Container">
```bash
docker build -t praisonai-api .
docker run -p 3030:3030 -e OPENAI_API_KEY=your_api_key praisonai-api
```
</Step>
</Steps>
### Cloud Deployment
#### Deploying to AWS
<Steps>
<Step title="Create an EC2 Instance">
Launch an EC2 instance with Ubuntu or Amazon Linux.
</Step>
<Step title="Install Dependencies">
```bash
sudo apt update
sudo apt install -y python3-pip
pip install "praisonaiagents[api]"
```
</Step>
<Step title="Configure Security Group">
Make sure to open port 3030 in your security group settings.
</Step>
<Step title="Run with Systemd">
Create a systemd service file for automatic startup and management.
</Step>
</Steps>
#### Deploying to Google Cloud Run
<Steps>
<Step title="Build Docker Image">
```bash
docker build -t gcr.io/your-project/praisonai-api .
```
</Step>
<Step title="Push to Container Registry">
```bash
docker push gcr.io/your-project/praisonai-api
```
</Step>
<Step title="Deploy to Cloud Run">
```bash
gcloud run deploy praisonai-api \
--image gcr.io/your-project/praisonai-api \
--platform managed \
--allow-unauthenticated \
--set-env-vars="OPENAI_API_KEY=your_api_key"
```
</Step>
</Steps>
## API Configuration Options
When launching your agent as an API, you can customize various parameters:
```python
agent.launch(
path="/custom-endpoint", # API endpoint path
port=8080, # Port number
host="0.0.0.0", # Host address (0.0.0.0 for external access)
debug=True, # Enable debug mode
cors_origins=["*"], # CORS configuration
api_key="your-api-key" # Optional API key for authentication
)
```
## Securing Your API
For production deployments, consider implementing:
1. **API Key Authentication**: Require API keys for all requests
2. **Rate Limiting**: Limit the number of requests per client
3. **HTTPS**: Use SSL/TLS certificates for encrypted communication
4. **Input Validation**: Validate all input data before processing
## Monitoring and Scaling
For production environments, consider:
1. **Load Balancing**: Distribute traffic across multiple instances
2. **Auto-Scaling**: Automatically adjust resources based on demand
3. **Logging**: Implement comprehensive logging for debugging
4. **Monitoring**: Set up alerts for errors and performance issues
## Features
<CardGroup cols={2}>
<Card title="RESTful API" icon="server">
Deploy your agents as standard RESTful APIs for easy integration.
</Card>
<Card title="Multi-Agent Support" icon="users">
Deploy multiple agents with different endpoints on the same server.
</Card>
<Card title="Customizable" icon="gear">
Configure ports, paths, CORS settings, and more.
</Card>
<Card title="Production-Ready" icon="rocket">
Easily deploy to Docker, AWS, Google Cloud, or other cloud platforms.
</Card>
</CardGroup>
+248
View File
@@ -0,0 +1,248 @@
---
title: "Deploying to Google Cloud"
sidebarTitle: "Google Cloud"
description: "Deploy PraisonAI agents to Google Cloud Platform for scalable production environments"
icon: "google"
---
# Deploying PraisonAI Agents to Google Cloud
This guide provides step-by-step instructions for deploying PraisonAI agents to Google Cloud Platform using Cloud Run, which offers a serverless environment for containerized applications.
## Prerequisites
- Google Cloud account with billing enabled
- Google Cloud SDK installed and configured
- Docker installed on your local machine
- Basic knowledge of containerization and cloud deployment
## Deployment Options
There are several ways to deploy PraisonAI agents to Google Cloud:
1. **Google Cloud Run** (recommended for most use cases)
2. **Google Compute Engine** (for custom VM requirements)
3. **Google Kubernetes Engine** (for complex, scalable deployments)
This guide focuses on Cloud Run as it's the simplest and most cost-effective option for most deployments.
## Deploying to Google Cloud Run
<Steps>
<Step title="Prepare Your Application">
Create a simple API file named `api.py`:
```python
from praisonaiagents import Agent
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
agent.launch(path="/ask", port=8080, host="0.0.0.0")
```
Note: Cloud Run expects your application to listen on the port defined by the `PORT` environment variable, which defaults to 8080.
</Step>
<Step title="Create a Dockerfile">
```dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Set environment variables
ENV PORT=8080
# Run the application
CMD exec python api.py
```
Create a `requirements.txt` file:
```
praisonaiagents[api]>=0.0.79
```
</Step>
<Step title="Build and Push the Docker Image">
```bash
# Build the Docker image
docker build -t gcr.io/YOUR_PROJECT_ID/praisonai-agent .
# Configure Docker to use Google Cloud credentials
gcloud auth configure-docker
# Push the image to Google Container Registry
docker push gcr.io/YOUR_PROJECT_ID/praisonai-agent
```
</Step>
<Step title="Deploy to Cloud Run">
```bash
gcloud run deploy praisonai-agent \
--image gcr.io/YOUR_PROJECT_ID/praisonai-agent \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars="OPENAI_API_KEY=your_api_key"
```
Note: For production deployments, it's recommended to use Secret Manager for API keys instead of environment variables.
</Step>
</Steps>
## Multi-Agent Deployment
For deploying multiple agents, you can use a single Cloud Run service with different endpoints:
```python
# multi-agent-api.py
from praisonaiagents import Agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
weather_agent.launch(path="/weather", port=8080, host="0.0.0.0")
stock_agent.launch(path="/stock", port=8080, host="0.0.0.0")
travel_agent.launch(path="/travel", port=8080, host="0.0.0.0")
```
## Scaling and Performance
Google Cloud Run automatically scales based on traffic, from zero to many instances. You can configure:
- **Minimum instances**: Keep a certain number of instances warm to avoid cold starts
- **Maximum instances**: Limit the number of instances to control costs
- **Memory allocation**: Allocate more memory for complex agents
- **CPU allocation**: Allocate dedicated CPUs for compute-intensive workloads
```bash
gcloud run services update praisonai-agent \
--min-instances=1 \
--max-instances=10 \
--memory=2Gi \
--cpu=1
```
## Continuous Deployment
Set up continuous deployment with Cloud Build:
```yaml
# cloudbuild.yaml
steps:
# Build the container image
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/praisonai-agent', '.']
# Push the container image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/praisonai-agent']
# Deploy container image to Cloud Run
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- 'run'
- 'deploy'
- 'praisonai-agent'
- '--image'
- 'gcr.io/$PROJECT_ID/praisonai-agent'
- '--region'
- 'us-central1'
- '--platform'
- 'managed'
- '--allow-unauthenticated'
substitutions:
_REGION: us-central1
images:
- 'gcr.io/$PROJECT_ID/praisonai-agent'
```
## Monitoring and Logging
Google Cloud provides comprehensive monitoring and logging capabilities:
- **Cloud Monitoring**: Set up dashboards and alerts for your deployed agents
- **Cloud Logging**: View and analyze logs from your applications
- **Error Reporting**: Automatically detect and group errors
Access logs through the Google Cloud Console or using the gcloud command:
```bash
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=praisonai-agent" --limit=10
```
## Cost Optimization
Cloud Run charges based on the resources your service uses only when it's processing requests. To optimize costs:
1. Set appropriate memory and CPU allocations
2. Configure minimum instances based on traffic patterns
3. Use regional deployments closest to your users
4. Implement caching for frequent requests
## Security Best Practices
1. **Secret Management**: Store API keys and credentials in Secret Manager
```bash
# Create a secret
echo -n "your_api_key" | gcloud secrets create openai-api-key --data-file=-
# Grant access to the Cloud Run service
gcloud secrets add-iam-policy-binding openai-api-key \
--member=serviceAccount:YOUR_SERVICE_ACCOUNT \
--role=roles/secretmanager.secretAccessor
# Reference in deployment
gcloud run deploy praisonai-agent \
--image gcr.io/YOUR_PROJECT_ID/praisonai-agent \
--set-secrets=OPENAI_API_KEY=openai-api-key:latest
```
2. **Service Identity**: Use dedicated service accounts with minimal permissions
3. **Network Security**: Configure VPC Service Controls for sensitive deployments
4. **API Authentication**: Implement authentication for your API endpoints
## All in One
```bash
gcloud init
gcloud services enable run.googleapis.com
gcloud services enable containerregistry.googleapis.com
gcloud services enable cloudbuild.googleapis.com
export OPENAI_MODEL_NAME="gpt-4o"
export OPENAI_API_KEY="Enter your API key"
export OPENAI_API_BASE="https://api.openai.com/v1"
yes | gcloud auth configure-docker us-central1-docker.pkg.dev
gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1
PROJECT_ID=$(gcloud config get-value project)
TAG="latest"
docker build --platform linux/amd64 -t gcr.io/${PROJECT_ID}/praisonai-app:${TAG} .
docker tag gcr.io/${PROJECT_ID}/praisonai-app:${TAG} us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG}
gcloud run deploy praisonai-service \
--image us-central1-docker.pkg.dev/${PROJECT_ID}/praisonai-repository/praisonai-app:${TAG} \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}
```
+405
View File
@@ -0,0 +1,405 @@
---
title: "Deploying MCP Servers"
sidebarTitle: "MCP Servers"
description: "Learn how to deploy Model Context Protocol (MCP) servers for production environments"
icon: "server-rack"
---
# Deploying MCP Servers
This guide focuses on deploying Model Context Protocol (MCP) servers for production environments. MCP servers allow AI models to access tools and external systems through a standardized protocol.
## Quick Start
<Steps>
<Step title="Install Dependencies">
Make sure you have the required packages installed:
```bash
pip install "praisonaiagents[mcp]"
```
For the multi-agent example with search capabilities:
```bash
pip install "praisonaiagents[mcp]" duckduckgo-search
```
</Step>
<Step title="Create MCP Server Files">
**Single Agent MCP Server**
Create a file named `simple-mcp-server.py`:
```python
from praisonaiagents import Agent
agent = Agent(instructions="Create a Tweet based on the topic provided")
agent.launch(port=8080, host="0.0.0.0", protocol="mcp")
```
**Multi-Agent MCP Server with Custom Tools**
Create a file named `simple-mcp-multi-agents-server.py`:
```python
from praisonaiagents import Agent, Agents
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
agent = Agent(instructions="You Search the internet for information", tools=[internet_search_tool])
agent2 = Agent(instructions="You Summarise the information")
agents = Agents(agents=[agent, agent2])
agents.launch(port=8080, host="0.0.0.0", protocol="mcp")
```
**Simple Multi-Agent MCP Server**
Create a file named `simple-multi-agents-server.py`:
```python
from praisonaiagents import Agent, Agents
agent = Agent(instructions="You Search the internet for information")
agent2 = Agent(instructions="You Summarise the information")
agents = Agents(agents=[agent, agent2])
agents.launch(port=8080, host="0.0.0.0", protocol="mcp")
```
```python
from praisonaiagents import Agent, Agents
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
agent = Agent(instructions="You Search the internet for information", tools=[internet_search_tool])
agent2 = Agent(instructions="You Summarise the information")
agents = Agents(agents=[agent, agent2])
agents.launch(port=8080, host="0.0.0.0", protocol="mcp")
```
</Step>
</Steps>
## Containerization with Docker
<Steps>
<Step title="Create a Dockerfile">
```dockerfile
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Expose the port
EXPOSE 8080
# Run the MCP server
CMD ["python", "simple-mcp-server.py"]
```
Create a `requirements.txt` file:
```
praisonaiagents[mcp]
duckduckgo-search # Only needed for the multi-agent example
```
</Step>
<Step title="Build and Run the Docker Container">
```bash
# Build the Docker image
docker build -t mcp-server .
# Run the container
docker run -p 8080:8080 -e OPENAI_API_KEY=your_api_key mcp-server
```
</Step>
</Steps>
## Cloud Deployment
### AWS Elastic Container Service (ECS)
<Steps>
<Step title="Push Docker Image to ECR">
```bash
# Create an ECR repository
aws ecr create-repository --repository-name mcp-server
# Authenticate Docker to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# Tag and push the image
docker tag mcp-server:latest YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/mcp-server:latest
docker push YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/mcp-server:latest
```
</Step>
<Step title="Create ECS Task Definition">
```json
{
"family": "mcp-server",
"networkMode": "awsvpc",
"executionRoleArn": "arn:aws:iam::YOUR_AWS_ACCOUNT_ID:role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "mcp-server",
"image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/mcp-server:latest",
"essential": true,
"portMappings": [
{
"containerPort": 8080,
"hostPort": 8080,
"protocol": "tcp"
}
],
"environment": [
{
"name": "OPENAI_API_KEY",
"value": "your_api_key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/mcp-server",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "ecs"
}
}
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "256",
"memory": "512"
}
```
</Step>
<Step title="Deploy to ECS">
```bash
# Create a service
aws ecs create-service \
--cluster your-cluster \
--service-name mcp-server \
--task-definition mcp-server:1 \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=arn:aws:elasticloadbalancing:us-east-1:YOUR_AWS_ACCOUNT_ID:targetgroup/mcp-server-tg/1234567890abcdef,containerName=mcp-server,containerPort=8080"
```
</Step>
</Steps>
### Google Cloud Run
<Steps>
<Step title="Push Docker Image to Google Container Registry">
```bash
# Configure Docker to use Google Cloud credentials
gcloud auth configure-docker
# Build and tag the image
docker build -t gcr.io/YOUR_PROJECT_ID/mcp-server .
# Push the image
docker push gcr.io/YOUR_PROJECT_ID/mcp-server
```
</Step>
<Step title="Deploy to Cloud Run">
```bash
gcloud run deploy mcp-server \
--image gcr.io/YOUR_PROJECT_ID/mcp-server \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars="OPENAI_API_KEY=your_api_key"
```
</Step>
</Steps>
## Production Configuration
### Security
For production deployments, implement these security measures:
1. **API Key Authentication**:
```python
agent.launch(port=8080, host="0.0.0.0", protocol="mcp", api_key="your-secret-key")
```
2. **HTTPS with SSL/TLS**:
Set up a reverse proxy like Nginx with SSL certificates:
```nginx
server {
listen 443 ssl;
server_name your-mcp-server.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
3. **Secret Management**:
Use environment variables or a secrets manager for API keys:
```bash
# AWS Secrets Manager
aws secretsmanager create-secret \
--name OPENAI_API_KEY \
--secret-string "your_api_key"
# Google Secret Manager
echo -n "your_api_key" | gcloud secrets create openai-api-key --data-file=-
```
### Scaling
For high-traffic MCP servers, consider these scaling strategies:
1. **Load Balancing**:
Deploy multiple instances behind a load balancer.
2. **Auto Scaling**:
Configure auto-scaling based on CPU/memory usage or request count.
3. **Resource Allocation**:
Allocate sufficient CPU and memory for your MCP servers:
```bash
# AWS ECS
aws ecs update-service \
--cluster your-cluster \
--service mcp-server \
--desired-count 3
# Google Cloud Run
gcloud run services update mcp-server \
--min-instances=2 \
--max-instances=10 \
--memory=2Gi \
--cpu=1
```
## Monitoring and Logging
Set up comprehensive monitoring for your MCP servers:
1. **Application Logging**:
```python
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("mcp-server.log"),
logging.StreamHandler()
]
)
logger = logging.getLogger("mcp-server")
```
2. **Health Checks**:
Create a health check endpoint:
```python
from flask import Flask
app = Flask(__name__)
@app.route('/health')
def health_check():
return {"status": "healthy"}, 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8081)
```
3. **Metrics Collection**:
Use Prometheus or similar tools to collect metrics.
## Testing MCP Servers
Before deploying to production, thoroughly test your MCP server:
```python
import requests
import json
def test_mcp_server():
url = "http://localhost:8080/v1/chat/completions"
headers = {
"Content-Type": "application/json"
}
data = {
"messages": [
{"role": "user", "content": "Create a tweet about artificial intelligence"}
]
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(f"Status Code: {response.status_code}")
print(f"Response: {response.json()}")
if __name__ == "__main__":
test_mcp_server()
```
## Deployment Checklist
Before going live with your MCP server, ensure you've addressed these items:
- [ ] Implemented proper authentication
- [ ] Set up HTTPS with valid SSL certificates
- [ ] Configured proper logging and monitoring
- [ ] Tested the server under load
- [ ] Implemented rate limiting
- [ ] Secured all API keys and credentials
- [ ] Set up automated backups
- [ ] Created a disaster recovery plan
- [ ] Documented the deployment process
## Features
<CardGroup cols={2}>
<Card title="Containerized Deployment" icon="docker">
Package your MCP servers in Docker containers for consistent deployment.
</Card>
<Card title="Cloud-Ready" icon="cloud">
Deploy to AWS, Google Cloud, or other cloud providers with ease.
</Card>
<Card title="Scalable Architecture" icon="server">
Scale your MCP servers to handle production workloads.
</Card>
<Card title="Security-Focused" icon="shield">
Implement best practices for secure MCP server deployments.
</Card>
</CardGroup>
+210
View File
@@ -0,0 +1,210 @@
---
title: "Deploying Multi-Agent Systems as APIs"
sidebarTitle: "Multi-Agent Deployment"
description: "Learn how to deploy PraisonAI multi-agent systems as RESTful APIs for production environments"
icon: "network-wired"
---
# Deploying Multi-Agent Systems as APIs
PraisonAI allows you to deploy sophisticated multi-agent systems as RESTful APIs, enabling seamless integration with various applications and services. This guide covers different approaches to deploying multi-agent systems.
## Quick Start
<Steps>
<Step title="Install Dependencies">
Make sure you have the required packages installed:
```bash
pip install "praisonaiagents[api]>=0.0.81"
```
</Step>
<Step title="Set API Key">
```bash
export OPENAI_API_KEY="your_api_key"
```
</Step>
<Step title="Deploy a Multi-Agent System">
Create a file named `multi-agents-api.py` with the following code:
```python
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents.launch(path="/agents", port=3030)
```
</Step>
<Step title="Run the API Server">
```bash
python multi-agents-api.py
```
Your multi-agent API will be available at `http://localhost:3030/agents`
</Step>
</Steps>
## Making API Requests
Once your multi-agent system is deployed, you can make POST requests to interact with it:
```bash
curl -X POST http://localhost:3030/agents \
-H "Content-Type: application/json" \
-d '{"message": "What are the latest developments in AI in 2024?"}'
```
The response will include the collaborative output from both the research and summarization agents:
```json
{
"response": "# Latest AI Developments in 2024\n\n- Multimodal AI models have become mainstream, combining text, image, audio, and video understanding\n- Significant advancements in AI reasoning capabilities with models like GPT-4o and Claude 3\n- Increased focus on AI alignment and safety research\n- Emergence of specialized AI agents for specific domains\n- Growth in open-source AI models and frameworks\n- Regulatory frameworks for AI being established globally"
}
```
## Multiple Agent Groups
You can deploy multiple agent groups on the same server, each with its own endpoint:
```python
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents2 = Agents(agents=[research_agent])
agents.launch(path="/agents", port=3030)
agents2.launch(path="/agents2", port=3030)
```
With this setup, you can access:
- The full agent group at `http://localhost:3030/agents`
- Just the research agent at `http://localhost:3030/agents2`
## Independent Multi-Agent Deployment
You can also deploy multiple independent agents on the same server:
```python
from praisonaiagents import Agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
weather_agent.launch(path="/weather", port=3030)
stock_agent.launch(path="/stock", port=3030)
travel_agent.launch(path="/travel", port=3030)
```
## Production Deployment Options
For production environments, consider the following deployment options:
### Docker Deployment
<Steps>
<Step title="Create a Dockerfile">
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 3030
CMD ["python", "multi-agents-api.py"]
```
</Step>
<Step title="Create requirements.txt">
```
praisonaiagents[api]>=0.0.81
```
</Step>
<Step title="Build and Run Docker Container">
```bash
docker build -t praisonai-multi-agent .
docker run -p 3030:3030 -e OPENAI_API_KEY=your_api_key praisonai-multi-agent
```
</Step>
</Steps>
### Cloud Deployment
For detailed cloud deployment instructions, refer to:
- [AWS Deployment Guide](/deploy/aws)
- [Google Cloud Deployment Guide](/deploy/googlecloud)
## Scaling Multi-Agent Systems
When deploying multi-agent systems to production, consider these scaling strategies:
1. **Horizontal Scaling**: Deploy multiple instances behind a load balancer
2. **Vertical Scaling**: Allocate more CPU and memory resources for complex agent interactions
3. **Caching**: Implement response caching for frequently asked questions
4. **Asynchronous Processing**: Use message queues for handling long-running agent tasks
## API Configuration Options
When launching your multi-agent system as an API, you can customize various parameters:
```python
agents.launch(
path="/custom-endpoint", # API endpoint path
port=8080, # Port number
host="0.0.0.0", # Host address (0.0.0.0 for external access)
debug=True, # Enable debug mode
cors_origins=["*"], # CORS configuration
api_key="your-api-key" # Optional API key for authentication
)
```
## Securing Your Multi-Agent API
For production deployments, consider implementing:
1. **API Key Authentication**: Require API keys for all requests
2. **Rate Limiting**: Limit the number of requests per client
3. **HTTPS**: Use SSL/TLS certificates for encrypted communication
4. **Input Validation**: Validate all input data before processing
5. **Output Filtering**: Implement content filtering for agent responses
## Monitoring and Logging
For production environments, consider:
1. **Centralized Logging**: Collect logs from all agents in a central location
2. **Performance Metrics**: Track response times and resource usage
3. **Error Tracking**: Monitor and alert on agent failures
4. **Usage Analytics**: Track which agents are used most frequently
## Features
<CardGroup cols={2}>
<Card title="Collaborative Agents" icon="users-gear">
Deploy agent systems that collaborate to solve complex problems.
</Card>
<Card title="Specialized Endpoints" icon="sitemap">
Create dedicated endpoints for different agent groups or individual agents.
</Card>
<Card title="Tool Integration" icon="screwdriver-wrench">
Deploy agents with specialized tools like web search capabilities.
</Card>
<Card title="Scalable Architecture" icon="server">
Scale your multi-agent systems to handle production workloads.
</Card>
</CardGroup>
+1 -1
View File
@@ -27,7 +27,7 @@ WORKDIR /app
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
RUN pip install flask praisonai==2.1.6 watchdog
EXPOSE 5555
+212
View File
@@ -0,0 +1,212 @@
---
title: "MCP Servers"
sidebarTitle: "MCP Servers"
description: "Learn how to create Model Context Protocol (MCP) servers with PraisonAI agents"
icon: "server"
---
# Creating MCP Servers
This guide demonstrates how to create Model Context Protocol (MCP) servers using PraisonAI agents. MCP is a protocol that enables AI models to use tools and communicate with external systems in a standardized way.
## Single Agent MCP Server
The simplest way to create an MCP server is with a single agent. This approach is ideal for specialized tasks where you need just one agent with a specific capability.
<Steps>
<Step title="Install Dependencies">
Make sure you have the required packages installed:
```bash
pip install "praisonaiagents[mcp]>=0.0.81"
```
</Step>
<Step title="Create a Simple MCP Server">
Create a file named `simple-mcp-server.py` with the following code:
```python
from praisonaiagents import Agent
agent = Agent(instructions="Create a Tweet based on the topic provided")
agent.launch(port=8080, protocol="mcp")
```
</Step>
<Step title="Run the Server">
```bash
python simple-mcp-server.py
```
Your MCP server will be available at `http://localhost:8080`
</Step>
</Steps>
## Multi-Agent MCP Server with Custom Tools
For more complex scenarios, you can create an MCP server with multiple agents and custom tools. This approach allows for collaborative problem-solving and specialized capabilities.
<Steps>
<Step title="Install Additional Dependencies">
```bash
pip install "praisonaiagents[mcp]" duckduckgo-search
```
</Step>
<Step title="Create a Multi-Agent MCP Server">
Create a file named `simple-mcp-multi-agents-server.py` with the following code:
```python
from praisonaiagents import Agent, Agents
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
agent = Agent(instructions="You Search the internet for information", tools=[internet_search_tool])
agent2 = Agent(instructions="You Summarise the information")
agents = Agents(agents=[agent, agent2])
agents.launch(port=8080, protocol="mcp")
```
</Step>
<Step title="Run the Multi-Agent Server">
```bash
python simple-mcp-multi-agents-server.py
```
Your multi-agent MCP server will be available at `http://localhost:8080`
</Step>
</Steps>
## Multi-Agent MCP Server (Simple)
For scenarios where you need multiple agents to collaborate without custom tools, you can create a simpler multi-agent MCP server:
```python
from praisonaiagents import Agent, Agents
agent = Agent(instructions="You Search the internet for information")
agent2 = Agent(instructions="You Summarise the information")
agents = Agents(agents=[agent, agent2])
agents.launch(port=8080, protocol="mcp")
```
This approach is ideal for cases where you want agents with different specializations to work together using their built-in capabilities.
## Connecting to MCP Servers
You can connect to MCP servers using various clients:
### Using PraisonAI Agents
```python
from praisonaiagents import Agent, MCP
client_agent = Agent(
instructions="Use the MCP server to complete tasks",
llm="gpt-4o-mini",
tools=MCP("http://localhost:8080")
)
response = client_agent.start("Create a tweet about artificial intelligence")
print(response)
```
### Using JavaScript/TypeScript
```typescript
import { MCPClient } from '@modelcontextprotocol/client';
async function main() {
const client = new MCPClient('http://localhost:8080');
const response = await client.chat([
{ role: 'user', content: 'Create a tweet about artificial intelligence' }
]);
console.log(response.choices[0].message.content);
}
main();
```
## Advanced Configuration
### Custom Port and Host
```python
agent.launch(port=9000, host="0.0.0.0", protocol="mcp")
```
### Authentication
```python
agent.launch(port=8080, protocol="mcp", api_key="your-secret-key")
```
### CORS Configuration
```python
agent.launch(port=8080, protocol="mcp", cors_origins=["https://yourdomain.com"])
```
## Deployment Options
For production deployments, consider:
1. **Docker Containerization**:
```dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["python", "simple-mcp-server.py"]
```
2. **Cloud Deployment**: Deploy to AWS, Google Cloud, or Azure using their container services.
3. **Kubernetes**: For scalable deployments, use Kubernetes to manage your MCP server containers.
## Security Considerations
1. **API Authentication**: Always use API keys in production
2. **Rate Limiting**: Implement rate limiting to prevent abuse
3. **Input Validation**: Validate all incoming requests
4. **HTTPS**: Use SSL/TLS for all production deployments
5. **Tool Permissions**: Limit what custom tools can access
## Features and Benefits
<CardGroup cols={2}>
<Card title="Standardized Protocol" icon="diagram-project">
MCP provides a standardized way for AI models to interact with tools and services.
</Card>
<Card title="Custom Tools" icon="screwdriver-wrench">
Easily integrate custom tools like web search, database access, or API calls.
</Card>
<Card title="Multi-Agent Collaboration" icon="users-gear">
Create systems where multiple specialized agents collaborate on complex tasks.
</Card>
<Card title="Language Agnostic" icon="language">
Connect to MCP servers from any programming language that supports HTTP.
</Card>
</CardGroup>
## Best Practices
1. **Agent Instructions**: Provide clear, specific instructions for each agent
2. **Tool Documentation**: Document your custom tools thoroughly
3. **Error Handling**: Implement robust error handling in your tools
4. **Monitoring**: Set up logging and monitoring for your MCP servers
5. **Testing**: Test your MCP servers thoroughly before deployment
+20 -10
View File
@@ -55,14 +55,6 @@
}
],
"tabs": [
{
"name": "Documentation",
"url": "/index"
},
{
"name": "Examples",
"url": "/examples"
},
{
"name": "Agents",
"url": "/agents"
@@ -79,6 +71,14 @@
"name": "MCP",
"url": "/mcp"
},
{
"name": "Deploy",
"url": "/deploy"
},
{
"name": "Examples",
"url": "/examples"
},
{
"name": "JS",
"url": "/js"
@@ -240,6 +240,7 @@
"mcp/airbnb",
"mcp/stdio",
"mcp/sse",
"mcp/mcp-server",
"mcp/ollama",
"mcp/groq",
"mcp/openrouter",
@@ -372,6 +373,16 @@
"ui/code"
]
},
{
"group": "Deploy",
"pages": [
"deploy/deploy",
"deploy/multi-agents-deploy",
"deploy/mcp-server-deploy",
"deploy/aws",
"deploy/googlecloud"
]
},
{
"group": "Monitoring",
"pages": ["monitoring/agentops"]
@@ -385,8 +396,7 @@
"developers/wrapper-tools",
"developers/googlecolab",
"developers/googlecolab-tools",
"developers/local-development",
"deploy"
"developers/local-development"
]
},
{
+1 -1
View File
@@ -155,7 +155,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
RUN pip install flask praisonai==2.1.6 watchdog
EXPOSE 5555
+1 -1
View File
@@ -208,7 +208,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
COPY . .
RUN pip install flask praisonai==2.0.18 watchdog
RUN pip install flask praisonai==2.1.6 watchdog
EXPOSE 5555
+9
View File
@@ -0,0 +1,9 @@
from praisonaiagents import Agent, MCP
qa_agent = Agent(
instructions="""You are a Question Answering Agent.""",
llm="openai/gpt-4o-mini",
tools=MCP("http://localhost:8080/agents/sse")
)
qa_agent.start("AI in 2025")
+20
View File
@@ -0,0 +1,20 @@
from praisonaiagents import Agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
weather_agent.launch(path="/weather", port=3030)
stock_agent.launch(path="/stock", port=3030)
travel_agent.launch(path="/travel", port=3030)
+6
View File
@@ -0,0 +1,6 @@
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents.launch(path="/agents", port=3030)
+8
View File
@@ -0,0 +1,8 @@
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents2 = Agents(agents=[research_agent])
agents.launch(path="/agents", port=3030)
agents2.launch(path="/agents2", port=3030)
+8
View File
@@ -0,0 +1,8 @@
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.launch(path="/weather", port=3030)
+4
View File
@@ -0,0 +1,4 @@
from praisonaiagents import Agent
agent = Agent(instructions="""You are a helpful assistant.""", llm="gpt-4o-mini")
agent.launch(path="/ask", port=3030)
@@ -0,0 +1,19 @@
from praisonaiagents import Agent, Agents
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
agent = Agent(name="SearchAgent", instructions="You Search the internet for information", tools=[internet_search_tool])
agent2 = Agent(name="SummariseAgent", instructions="You Summarise the information")
agents = Agents(name="MultiAgents", agents=[agent, agent2])
agents.launch(port=8080, protocol="mcp")
+4
View File
@@ -0,0 +1,4 @@
from praisonaiagents import Agent
agent = Agent(name="TweetAgent", instructions="Create a Tweet based on the topic provided")
agent.launch(port=8080, protocol="mcp")
+1 -1
View File
@@ -56,7 +56,7 @@ class CloudDeployer:
file.write("FROM python:3.11-slim\n")
file.write("WORKDIR /app\n")
file.write("COPY . .\n")
file.write("RUN pip install flask praisonai==2.1.1 gunicorn markdown\n")
file.write("RUN pip install flask praisonai==2.1.6 gunicorn markdown\n")
file.write("EXPOSE 8080\n")
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
+35 -31
View File
@@ -1,6 +1,6 @@
[project]
name = "PraisonAI"
version = "2.1.1"
version = "2.1.6"
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.71",
"praisonaiagents>=0.0.82",
"python-dotenv>=0.19.0",
"instructor>=1.3.3",
"PyYAML>=6.0",
@@ -21,49 +21,53 @@ dependencies = [
[project.optional-dependencies]
ui = [
"chainlit==2.0.3",
"chainlit==2.5.5",
"sqlalchemy>=2.0.36",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
"pydantic<=2.10.1"
]
gradio = ["gradio>=4.26.0"]
api = ["flask>=3.0.0"]
api = [
"flask>=3.0.0",
"fastapi>=0.115.0",
"uvicorn>=0.34.0"
]
agentops = ["agentops>=0.3.12"]
google = ["langchain-google-genai>=1.0.4"]
openai = ["langchain-openai>=0.1.7"]
anthropic = ["langchain-anthropic>=0.1.13"]
cohere = ["langchain-cohere>=0.1.4"]
google = ["langchain-google-genai>=2.1.0"]
openai = ["langchain-openai>=0.2.1,<0.3.0"]
anthropic = ["langchain-anthropic>=0.3.0"]
cohere = ["langchain-cohere>=0.3.0,<0.4.0"]
chat = [
"chainlit==2.0.3",
"chainlit==2.5.5",
"litellm>=1.41.8",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
"tavily-python==0.5.0",
"crawl4ai==0.3.4",
"crawl4ai>=0.6.0",
"sqlalchemy>=2.0.36",
"playwright>=1.47.0",
"rich",
"pydantic<=2.10.1"
]
code = [
"chainlit==2.0.3",
"chainlit==2.5.5",
"litellm>=1.41.8",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
"tavily-python==0.5.0",
"crawl4ai==0.3.4",
"crawl4ai>=0.6.0",
"sqlalchemy>=2.0.36",
"playwright>=1.47.0",
"pydantic<=2.10.1"
]
realtime = [
"chainlit==2.0.3",
"chainlit==2.5.5",
"litellm>=1.41.8",
"aiosqlite>=0.20.0",
"greenlet>=3.0.3",
"tavily-python==0.5.0",
"crawl4ai==0.3.4",
"crawl4ai>=0.6.0",
"websockets>=12.0",
"plotly>=5.24.0",
"yfinance>=0.2.44",
@@ -80,13 +84,13 @@ call = [
"rich",
"openai>=1.54.0",
]
crewai = ["crewai>=0.32.0", "praisonai-tools>=0.0.7"]
autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.7", "crewai"]
crewai = ["crewai>=0.32.0", "praisonai-tools>=0.0.15"]
autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.15", "crewai"]
[tool.poetry]
name = "PraisonAI"
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."
version = "2.1.6"
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 = ""
readme = "README.md"
@@ -103,27 +107,27 @@ python = ">=3.10,<3.13"
rich = ">=13.7"
markdown = ">=3.5"
pyparsing = ">=3.0.0"
praisonaiagents = ">=0.0.71"
praisonaiagents = ">=0.0.82"
python-dotenv = ">=0.19.0"
instructor = ">=1.3.3"
PyYAML = ">=6.0"
mcp = "==1.6.0"
pyautogen = {version = ">=0.2.19", optional = true}
crewai = {version = ">=0.32.0", optional = true}
praisonai-tools = {version = ">=0.0.7", optional = true}
chainlit = {version = "==2.0.3", optional = true}
praisonai-tools = {version = ">=0.0.15", optional = true}
chainlit = {version = "==2.5.5", optional = true}
gradio = {version = ">=4.26.0", optional = true}
flask = {version = ">=3.0.0", optional = true}
agentops = {version = ">=0.3.12", optional = true}
langchain-google-genai = {version = ">=1.0.4", optional = true}
langchain-anthropic = {version = ">=0.1.13", optional = true}
langchain-openai = {version = ">=0.1.7", optional = true}
langchain-cohere = {version = ">=0.1.4", optional = true}
langchain-google-genai = {version = ">=2.1.0", optional = true}
langchain-anthropic = {version = ">=0.3.0", optional = true}
langchain-openai = {version = ">=0.2.1,<0.3.0", optional = true}
langchain-cohere = {version = ">=0.3.0,<0.4.0", optional = true}
litellm = {version = ">=1.41.8", optional = true}
aiosqlite= {version = ">=0.20.0", optional = true}
greenlet = {version = ">=3.0.3", optional = true}
tavily-python = {version = "==0.5.0", optional=true}
crawl4ai = {version = "==0.3.4", optional = true}
crawl4ai = {version = ">=0.6.0", optional = true}
websockets = {version = ">=12.0", optional = true}
plotly = {version = ">=5.24.0", optional = true}
yfinance = {version = ">=0.2.44", optional = true}
@@ -175,14 +179,14 @@ mkdocstrings-python = "*"
pdoc3 = "*"
xmlrunner = "*"
unittest2 = "*"
chainlit = "==2.0.3"
chainlit = "==2.5.5"
gradio = ">=4.26.0"
flask = ">=3.0.0"
agentops = ">=0.3.12"
langchain-google-genai = ">=1.0.4"
langchain-anthropic = ">=0.1.13"
langchain-openai = ">=0.1.7"
langchain-cohere = ">=0.1.4"
langchain-google-genai = ">=2.1.0"
langchain-anthropic = ">=0.3.0"
langchain-openai = ">=0.2.1,<0.3.0"
langchain-cohere = ">=0.3.0,<0.4.0"
litellm = ">=1.41.8"
aiosqlite = ">=0.20.0"
greenlet = ">=3.0.3"
+9
View File
@@ -0,0 +1,9 @@
from praisonaiagents import Agent, MCP
qa_agent = Agent(
instructions="""You are a Question Answering Agent.""",
llm="openai/gpt-4o-mini",
tools=MCP("http://localhost:8080/agents/sse")
)
qa_agent.start("AI in 2025")
+3 -12
View File
@@ -1,29 +1,20 @@
from praisonaiagents import Agent
# Create a weather agent
weather_agent = Agent(
instructions="""You are a weather agent that can provide weather information for a given city.""",
llm="gpt-4o-mini"
)
# Create a stock market agent
stock_agent = Agent(
instructions="""You are a stock market agent that can provide information about stock prices and market trends.""",
llm="gpt-4o-mini"
)
# Create a travel agent
travel_agent = Agent(
instructions="""You are a travel agent that can provide recommendations for destinations, hotels, and activities.""",
llm="gpt-4o-mini"
)
# Register the first two agents with blocking=False so they don't block execution
weather_agent.launch(path="/weather", port=3030, blocking=False)
stock_agent.launch(path="/stock", port=3030, blocking=False)
# Register the last agent with blocking=True to keep the server running
# This must be the last launch() call
travel_agent.launch(path="/travel", port=3030, blocking=True)
# The script will block at the last launch() call until the user presses Ctrl+C
weather_agent.launch(path="/weather", port=3030)
stock_agent.launch(path="/stock", port=3030)
travel_agent.launch(path="/travel", port=3030)
+6
View File
@@ -0,0 +1,6 @@
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents.launch(path="/agents", port=3030)
@@ -0,0 +1,8 @@
from praisonaiagents import Agent, Agents, Tools
research_agent = Agent(name="Research", instructions="You are a research agent to search internet about AI 2024", tools=[Tools.internet_search])
summarise_agent = Agent(name="Summarise", instructions="You are a summarize agent to summarise in points")
agents = Agents(agents=[research_agent, summarise_agent])
agents2 = Agents(agents=[research_agent])
agents.launch(path="/agents", port=3030)
agents2.launch(path="/agents2", port=3030)
@@ -22,16 +22,16 @@ import inspect
import uuid
from dataclasses import dataclass
# Global variables for API server
_server_started = {} # Dict of port -> started boolean
_registered_agents = {} # Dict of port -> Dict of path -> agent_id
_shared_apps = {} # Dict of port -> FastAPI app
# Don't import FastAPI dependencies here - use lazy loading instead
if TYPE_CHECKING:
from ..task.task import Task
# Shared variables for API server
_shared_app = None
_server_started = False
_registered_agents = {}
@dataclass
class ChatCompletionMessage:
content: str
@@ -1095,6 +1095,10 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
start_time = time.time()
reasoning_steps = reasoning_steps or self.reasoning_steps
try:
# Default to self.tools if tools argument is None
if tools is None:
tools = self.tools
# Search for existing knowledge if any knowledge is provided
if self.knowledge:
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
@@ -1408,155 +1412,329 @@ Your Goal: {self.goal}
logging.error(f"Error in execute_tool_async: {str(e)}", exc_info=True)
return {"error": f"Error in execute_tool_async: {str(e)}"}
def launch(self, path: str = '/', port: int = 8000, host: str = '0.0.0.0', autostart: bool = True, debug: bool = False, blocking: bool = True):
def launch(self, path: str = '/', port: int = 8000, host: str = '0.0.0.0', debug: bool = False, protocol: str = "http"):
"""
Launch the agent as an HTTP API endpoint.
Launch the agent as an HTTP API endpoint or an MCP server.
Args:
path: API endpoint path (default: '/')
path: API endpoint path (default: '/') for HTTP, or base path for MCP.
port: Server port (default: 8000)
host: Server host (default: '0.0.0.0')
autostart: Whether to start the server automatically (default: True)
debug: Enable debug mode for uvicorn (default: False)
blocking: If True, blocks the main thread to keep the server running (default: True)
protocol: "http" to launch as FastAPI, "mcp" to launch as MCP server.
Returns:
None
"""
global _server_started, _registered_agents, _shared_app
# Try to import FastAPI dependencies - lazy loading
try:
import uvicorn
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
if protocol == "http":
global _server_started, _registered_agents, _shared_apps
# Define the request model here since we need pydantic
class AgentQuery(BaseModel):
query: str
# Try to import FastAPI dependencies - lazy loading
try:
import uvicorn
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import threading
import time
except ImportError as e:
# Check which specific module is missing
missing_module = str(e).split("No module named '")[-1].rstrip("'")
display_error(f"Missing dependency: {missing_module}. Required for launch() method.")
logging.error(f"Missing dependency: {missing_module}. Required for launch() method.")
print(f"\nTo add API capabilities, install the required dependencies:")
print(f"pip install {missing_module}")
print("\nOr install all API dependencies with:")
print("pip install 'praisonaiagents[api]'")
# Define the request model here since we need pydantic
class AgentQuery(BaseModel):
query: str
except ImportError as e:
# Check which specific module is missing
missing_module = str(e).split("No module named '")[-1].rstrip("'")
display_error(f"Missing dependency: {missing_module}. Required for launch() method with HTTP mode.")
logging.error(f"Missing dependency: {missing_module}. Required for launch() method with HTTP mode.")
print(f"\nTo add API capabilities, install the required dependencies:")
print(f"pip install {missing_module}")
print("\nOr install all API dependencies with:")
print("pip install 'praisonaiagents[api]'")
return None
# Initialize port-specific collections if needed
if port not in _registered_agents:
_registered_agents[port] = {}
# Initialize shared FastAPI app if not already created for this port
if _shared_apps.get(port) is None:
_shared_apps[port] = FastAPI(
title=f"PraisonAI Agents API (Port {port})",
description="API for interacting with PraisonAI Agents"
)
# Add a root endpoint with a welcome message
@_shared_apps[port].get("/")
async def root():
return {
"message": f"Welcome to PraisonAI Agents API on port {port}. See /docs for usage.",
"endpoints": list(_registered_agents[port].keys())
}
# Add healthcheck endpoint
@_shared_apps[port].get("/health")
async def healthcheck():
return {
"status": "ok",
"endpoints": list(_registered_agents[port].keys())
}
# Normalize path to ensure it starts with /
if not path.startswith('/'):
path = f'/{path}'
# Check if path is already registered for this port
if path in _registered_agents[port]:
logging.warning(f"Path '{path}' is already registered on port {port}. Please use a different path.")
print(f"⚠️ Warning: Path '{path}' is already registered on port {port}.")
# Use a modified path to avoid conflicts
original_path = path
path = f"{path}_{self.agent_id[:6]}"
logging.warning(f"Using '{path}' instead of '{original_path}'")
print(f"🔄 Using '{path}' instead")
# Register the agent to this path
_registered_agents[port][path] = self.agent_id
# Define the endpoint handler
@_shared_apps[port].post(path)
async def handle_agent_query(request: Request, query_data: Optional[AgentQuery] = None):
# Handle both direct JSON with query field and form data
if query_data is None:
try:
request_data = await request.json()
if "query" not in request_data:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
query = request_data["query"]
except:
# Fallback to form data or query params
form_data = await request.form()
if "query" in form_data:
query = form_data["query"]
else:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
else:
query = query_data.query
try:
# Use async version if available, otherwise use sync version
if asyncio.iscoroutinefunction(self.chat):
response = await self.achat(query)
else:
# Run sync function in a thread to avoid blocking
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, lambda p=query: self.chat(p))
return {"response": response}
except Exception as e:
logging.error(f"Error processing query: {str(e)}", exc_info=True)
return JSONResponse(
status_code=500,
content={"error": f"Error processing query: {str(e)}"}
)
print(f"🚀 Agent '{self.name}' available at http://{host}:{port}")
# Start the server if it's not already running for this port
if not _server_started.get(port, False):
# Mark the server as started first to prevent duplicate starts
_server_started[port] = True
# Start the server in a separate thread
def run_server():
try:
print(f"✅ FastAPI server started at http://{host}:{port}")
print(f"📚 API documentation available at http://{host}:{port}/docs")
print(f"🔌 Available endpoints: {', '.join(list(_registered_agents[port].keys()))}")
uvicorn.run(_shared_apps[port], host=host, port=port, log_level="debug" if debug else "info")
except Exception as e:
logging.error(f"Error starting server: {str(e)}", exc_info=True)
print(f"❌ Error starting server: {str(e)}")
# Run server in a background thread
server_thread = threading.Thread(target=run_server, daemon=True)
server_thread.start()
# Wait for a moment to allow the server to start and register endpoints
time.sleep(0.5)
else:
# If server is already running, wait a moment to make sure the endpoint is registered
time.sleep(0.1)
print(f"🔌 Available endpoints on port {port}: {', '.join(list(_registered_agents[port].keys()))}")
# Get the stack frame to check if this is the last launch() call in the script
import inspect
stack = inspect.stack()
# If this is called from a Python script (not interactive), try to detect if it's the last launch call
if len(stack) > 1 and stack[1].filename.endswith('.py'):
caller_frame = stack[1]
caller_line = caller_frame.lineno
try:
# Read the file to check if there are more launch calls after this one
with open(caller_frame.filename, 'r') as f:
lines = f.readlines()
# Check if there are more launch() calls after the current line
has_more_launches = False
for line_content in lines[caller_line:]: # renamed line to line_content
if '.launch(' in line_content and not line_content.strip().startswith('#'):
has_more_launches = True
break
# If this is the last launch call, block the main thread
if not has_more_launches:
try:
print("\nAll agents registered for HTTP mode. Press Ctrl+C to stop the servers.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nServers stopped")
except Exception as e:
# If something goes wrong with detection, block anyway to be safe
logging.error(f"Error in launch detection: {e}")
try:
print("\nKeeping HTTP servers alive. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nServers stopped")
return None
# Initialize shared FastAPI app if not already created
if _shared_app is None:
_shared_app = FastAPI(
title="PraisonAI Agents API",
description="API for interacting with PraisonAI Agents"
)
# Add a root endpoint with a welcome message
@_shared_app.get("/")
async def root():
return {"message": "Welcome to PraisonAI Agents API. See /docs for usage."}
# Normalize path to ensure it starts with /
if not path.startswith('/'):
path = f'/{path}'
# Check if path is already registered by another agent
if path in _registered_agents and _registered_agents[path] != self.agent_id:
existing_agent = _registered_agents[path]
logging.warning(f"Path '{path}' is already registered by another agent. Please use a different path.")
print(f"⚠️ Warning: Path '{path}' is already registered by another agent.")
# Use a modified path to avoid conflicts
original_path = path
path = f"{path}_{self.agent_id[:6]}"
logging.warning(f"Using '{path}' instead of '{original_path}'")
print(f"🔄 Using '{path}' instead")
# Register the agent to this path
_registered_agents[path] = self.agent_id
# Define the endpoint handler
@_shared_app.post(path)
async def handle_agent_query(request: Request, query_data: Optional[AgentQuery] = None):
# Handle both direct JSON with query field and form data
if query_data is None:
try:
request_data = await request.json()
if "query" not in request_data:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
query = request_data["query"]
except:
# Fallback to form data or query params
form_data = await request.form()
if "query" in form_data:
query = form_data["query"]
else:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
else:
query = query_data.query
elif protocol == "mcp":
try:
# Use async version if available, otherwise use sync version
if asyncio.iscoroutinefunction(self.chat):
response = await self.achat(query)
else:
# Run sync function in a thread to avoid blocking
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, lambda: self.chat(query))
import uvicorn
from mcp.server.fastmcp import FastMCP
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.routing import Mount, Route
from mcp.server import Server as MCPServer # Alias to avoid conflict
import threading
import time
import inspect
import asyncio # Ensure asyncio is imported
# logging is already imported at the module level
return {"response": response}
except Exception as e:
logging.error(f"Error processing query: {str(e)}", exc_info=True)
return JSONResponse(
status_code=500,
content={"error": f"Error processing query: {str(e)}"}
)
print(f"🚀 Agent '{self.name}' available at http://{host}:{port}{path}")
# Start the server if this is the first launch call and autostart is True
if autostart and not _server_started:
_server_started = True
# Add healthcheck endpoint
@_shared_app.get("/health")
async def healthcheck():
return {"status": "ok", "agents": list(_registered_agents.keys())}
# Start the server in a separate thread to not block execution
import threading
def run_server():
except ImportError as e:
missing_module = str(e).split("No module named '")[-1].rstrip("'")
display_error(f"Missing dependency: {missing_module}. Required for launch() method with MCP mode.")
logging.error(f"Missing dependency: {missing_module}. Required for launch() method with MCP mode.")
print(f"\nTo add MCP capabilities, install the required dependencies:")
print(f"pip install {missing_module} mcp praison-mcp starlette uvicorn") # Added mcp, praison-mcp, starlette, uvicorn
print("\nOr install all MCP dependencies with relevant packages.")
return None
mcp_server_instance_name = f"{self.name}_mcp_server" if self.name else "agent_mcp_server"
mcp = FastMCP(mcp_server_instance_name)
# Determine the MCP tool name based on self.name
actual_mcp_tool_name = f"execute_{self.name.lower().replace(' ', '_').replace('-', '_')}_task" if self.name \
else "execute_task"
@mcp.tool(name=actual_mcp_tool_name)
async def execute_agent_task(prompt: str) -> str:
"""Executes the agent's primary task with the given prompt."""
logging.info(f"MCP tool '{actual_mcp_tool_name}' called with prompt: {prompt}")
try:
uvicorn.run(_shared_app, host=host, port=port, log_level="debug" if debug else "info")
# Ensure self.achat is used as it's the async version and pass its tools
if hasattr(self, 'achat') and asyncio.iscoroutinefunction(self.achat):
response = await self.achat(prompt, tools=self.tools)
elif hasattr(self, 'chat'): # Fallback for synchronous chat
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, lambda p=prompt: self.chat(p, tools=self.tools))
else:
logging.error(f"Agent {self.name} has no suitable chat or achat method for MCP tool.")
return f"Error: Agent {self.name} misconfigured for MCP."
return response if response is not None else "Agent returned no response."
except Exception as e:
logging.error(f"Error starting server: {str(e)}", exc_info=True)
print(f"❌ Error starting server: {str(e)}")
logging.error(f"Error in MCP tool '{actual_mcp_tool_name}': {e}", exc_info=True)
return f"Error executing task: {str(e)}"
# Normalize base_path for MCP routes
base_path = path.rstrip('/')
sse_path = f"{base_path}/sse"
messages_path_prefix = f"{base_path}/messages" # Prefix for message posting
server_thread = threading.Thread(target=run_server, daemon=True)
server_thread.start()
# Ensure messages_path ends with a slash for Mount
if not messages_path_prefix.endswith('/'):
messages_path_prefix += '/'
sse_transport = SseServerTransport(messages_path_prefix) # Pass the full prefix
async def handle_sse_connection(request: Request) -> None:
logging.debug(f"SSE connection request received from {request.client} for path {request.url.path}")
async with sse_transport.connect_sse(
request.scope,
request.receive,
request._send, # noqa: SLF001
) as (read_stream, write_stream):
await mcp._mcp_server.run( # Use the underlying server from FastMCP
read_stream,
write_stream,
mcp._mcp_server.create_initialization_options(),
)
# Give the server a moment to start up
import time
time.sleep(0.5)
print(f"✅ FastAPI server started at http://{host}:{port}")
print(f"📚 API documentation available at http://{host}:{port}/docs")
# If blocking is True, keep the main thread alive
if blocking:
print("\nServer is running in blocking mode. Press Ctrl+C to stop...")
starlette_app = Starlette(
debug=debug,
routes=[
Route(sse_path, endpoint=handle_sse_connection),
Mount(messages_path_prefix, app=sse_transport.handle_post_message),
],
)
print(f"🚀 Agent '{self.name}' MCP server starting on http://{host}:{port}")
print(f"📡 MCP SSE endpoint available at {sse_path}")
print(f"📢 MCP messages post to {messages_path_prefix}")
# Instead of trying to extract tool names, hardcode the known tool name
tool_names = [actual_mcp_tool_name] # Use the determined dynamic tool name
print(f"🛠️ Available MCP tools: {', '.join(tool_names)}")
# Uvicorn server running logic (similar to HTTP mode but standalone for MCP)
def run_mcp_server():
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nServer stopped")
else:
# Note for non-blocking mode
print("\nNote: Server is running in a background thread. To keep it alive, either:")
print("1. Set blocking=True when calling launch()")
print("2. Keep your main application running")
print("3. Use a loop in your code to prevent the program from exiting")
return None
uvicorn.run(starlette_app, host=host, port=port, log_level="debug" if debug else "info")
except Exception as e:
logging.error(f"Error starting MCP server: {str(e)}", exc_info=True)
print(f"❌ Error starting MCP server: {str(e)}")
server_thread = threading.Thread(target=run_mcp_server, daemon=True)
server_thread.start()
time.sleep(0.5) # Allow server to start
# Blocking logic for MCP mode
import inspect # Already imported but good for clarity
stack = inspect.stack()
if len(stack) > 1 and stack[1].filename.endswith('.py'):
caller_frame = stack[1]
caller_line = caller_frame.lineno
try:
with open(caller_frame.filename, 'r') as f:
lines = f.readlines()
has_more_launches = False
for line_content in lines[caller_line:]: # renamed line to line_content
if '.launch(' in line_content and not line_content.strip().startswith('#'):
has_more_launches = True
break
if not has_more_launches:
try:
print("\nAgent MCP server running. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nMCP Server stopped")
except Exception as e:
logging.error(f"Error in MCP launch detection: {e}")
try:
print("\nKeeping MCP server alive. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nMCP Server stopped")
return None
else:
display_error(f"Invalid protocol: {protocol}. Choose 'http' or 'mcp'.")
return None
@@ -17,6 +17,11 @@ import uuid
# Set up logger
logger = logging.getLogger(__name__)
# Global variables for managing the shared servers
_agents_server_started = {} # Dict of port -> started boolean
_agents_registered_endpoints = {} # Dict of port -> Dict of path -> endpoint_id
_agents_shared_apps = {} # Dict of port -> FastAPI app
def encode_file_to_base64(file_path: str) -> str:
"""Base64-encode a file."""
import base64
@@ -45,7 +50,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, stream=True):
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, name: Optional[str] = None):
# Add check at the start if memory is requested
if memory:
try:
@@ -78,6 +83,7 @@ class PraisonAIAgents:
self.max_retries = max_retries
self.process = process
self.stream = stream
self.name = name # Store the name for the Agents collection
# Check for manager_llm in environment variable if not provided
self.manager_llm = manager_llm or os.getenv('OPENAI_MODEL_NAME', 'gpt-4o')
@@ -878,4 +884,383 @@ Context:
def clear_state(self) -> None:
"""Clear all state values"""
self._state.clear()
self._state.clear()
def launch(self, path: str = '/agents', port: int = 8000, host: str = '0.0.0.0', debug: bool = False, protocol: str = "http"):
"""
Launch all agents as a single API endpoint (HTTP) or an MCP server.
In HTTP mode, the endpoint accepts a query and processes it through all agents in sequence.
In MCP mode, an MCP server is started, exposing a tool to run the agent workflow.
Args:
path: API endpoint path (default: '/agents') for HTTP, or base path for MCP.
port: Server port (default: 8000)
host: Server host (default: '0.0.0.0')
debug: Enable debug mode for uvicorn (default: False)
protocol: "http" to launch as FastAPI, "mcp" to launch as MCP server.
Returns:
None
"""
if protocol == "http":
global _agents_server_started, _agents_registered_endpoints, _agents_shared_apps
if not self.agents:
logging.warning("No agents to launch for HTTP mode. Add agents to the Agents instance first.")
return
# Try to import FastAPI dependencies - lazy loading
try:
import uvicorn
from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import threading
import time
import asyncio # Ensure asyncio is imported for HTTP mode too
# Define the request model here since we need pydantic
class AgentQuery(BaseModel):
query: str
except ImportError as e:
# Check which specific module is missing
missing_module = str(e).split("No module named '")[-1].rstrip("'")
display_error(f"Missing dependency: {missing_module}. Required for launch() method with HTTP mode.")
logging.error(f"Missing dependency: {missing_module}. Required for launch() method with HTTP mode.")
print(f"\nTo add API capabilities, install the required dependencies:")
print(f"pip install {missing_module}")
print("\nOr install all API dependencies with:")
print("pip install 'praisonaiagents[api]'")
return None
# Initialize port-specific collections if needed
if port not in _agents_registered_endpoints:
_agents_registered_endpoints[port] = {}
# Initialize shared FastAPI app if not already created for this port
if _agents_shared_apps.get(port) is None:
_agents_shared_apps[port] = FastAPI(
title=f"PraisonAI Agents API (Port {port})",
description="API for interacting with multiple PraisonAI Agents"
)
# Add a root endpoint with a welcome message
@_agents_shared_apps[port].get("/")
async def root():
return {
"message": f"Welcome to PraisonAI Agents API on port {port}. See /docs for usage.",
"endpoints": list(_agents_registered_endpoints[port].keys())
}
# Add healthcheck endpoint
@_agents_shared_apps[port].get("/health")
async def healthcheck():
return {
"status": "ok",
"endpoints": list(_agents_registered_endpoints[port].keys())
}
# Normalize path to ensure it starts with /
if not path.startswith('/'):
path = f'/{path}'
# Check if path is already registered for this port
if path in _agents_registered_endpoints[port]:
logging.warning(f"Path '{path}' is already registered on port {port}. Please use a different path.")
print(f"⚠️ Warning: Path '{path}' is already registered on port {port}.")
# Use a modified path to avoid conflicts
original_path = path
instance_id = str(uuid.uuid4())[:6]
path = f"{path}_{instance_id}"
logging.warning(f"Using '{path}' instead of '{original_path}'")
print(f"🔄 Using '{path}' instead")
# Generate a unique ID for this agent group's endpoint
endpoint_id = str(uuid.uuid4())
_agents_registered_endpoints[port][path] = endpoint_id
# Define the endpoint handler
@_agents_shared_apps[port].post(path)
async def handle_query(request: Request, query_data: Optional[AgentQuery] = None):
# Handle both direct JSON with query field and form data
if query_data is None:
try:
request_data = await request.json()
if "query" not in request_data:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
query = request_data["query"]
except:
# Fallback to form data or query params
form_data = await request.form()
if "query" in form_data:
query = form_data["query"]
else:
raise HTTPException(status_code=400, detail="Missing 'query' field in request")
else:
query = query_data.query
try:
# Process the query sequentially through all agents
current_input = query
results = []
for agent_instance in self.agents: # Corrected variable name to agent_instance
try:
# Use async version if available, otherwise use sync version
if asyncio.iscoroutinefunction(agent_instance.chat):
response = await agent_instance.achat(current_input)
else:
# Run sync function in a thread to avoid blocking
loop = asyncio.get_event_loop()
# Correctly pass current_input to the lambda for closure
response = await loop.run_in_executor(None, lambda ci=current_input: agent_instance.chat(ci))
# Store this agent's result
results.append({
"agent": agent_instance.name,
"response": response
})
# Use this response as input to the next agent
current_input = response
except Exception as e:
logging.error(f"Error with agent {agent_instance.name}: {str(e)}", exc_info=True)
results.append({
"agent": agent_instance.name,
"error": str(e)
})
# Decide error handling: continue with original input, last good input, or stop?
# For now, let's continue with the last successful 'current_input' or original 'query' if first agent fails
# This part might need refinement based on desired behavior.
# If an agent fails, its 'response' might be None or an error string.
# current_input will carry that forward. Or, we could choose to halt or use last good input.
# Return all results and the final output
return {
"query": query,
"results": results,
"final_response": current_input
}
except Exception as e:
logging.error(f"Error processing query: {str(e)}", exc_info=True)
return JSONResponse(
status_code=500,
content={"error": f"Error processing query: {str(e)}"}
)
print(f"🚀 Multi-Agent HTTP API available at http://{host}:{port}{path}")
agent_names = ", ".join([agent.name for agent in self.agents])
print(f"📊 Available agents for this endpoint ({len(self.agents)}): {agent_names}")
# Start the server if it's not already running for this port
if not _agents_server_started.get(port, False):
# Mark the server as started first to prevent duplicate starts
_agents_server_started[port] = True
# Start the server in a separate thread
def run_server():
try:
print(f"✅ FastAPI server started at http://{host}:{port}")
print(f"📚 API documentation available at http://{host}:{port}/docs")
print(f"🔌 Registered HTTP endpoints on port {port}: {', '.join(list(_agents_registered_endpoints[port].keys()))}")
uvicorn.run(_agents_shared_apps[port], host=host, port=port, log_level="debug" if debug else "info")
except Exception as e:
logging.error(f"Error starting server: {str(e)}", exc_info=True)
print(f"❌ Error starting server: {str(e)}")
# Run server in a background thread
server_thread = threading.Thread(target=run_server, daemon=True)
server_thread.start()
# Wait for a moment to allow the server to start and register endpoints
time.sleep(0.5)
else:
# If server is already running, wait a moment to make sure the endpoint is registered
time.sleep(0.1)
print(f"🔌 Registered HTTP endpoints on port {port}: {', '.join(list(_agents_registered_endpoints[port].keys()))}")
# Get the stack frame to check if this is the last launch() call in the script
import inspect
stack = inspect.stack()
# If this is called from a Python script (not interactive), try to detect if it's the last launch call
if len(stack) > 1 and stack[1].filename.endswith('.py'):
caller_frame = stack[1]
caller_line = caller_frame.lineno
try:
# Read the file to check if there are more launch calls after this one
with open(caller_frame.filename, 'r') as f:
lines = f.readlines()
# Check if there are more launch() calls after the current line
has_more_launches = False
for line_content in lines[caller_line:]: # Renamed variable
if '.launch(' in line_content and not line_content.strip().startswith('#'):
has_more_launches = True
break
# If this is the last launch call, block the main thread
if not has_more_launches:
try:
print("\nAll agent groups registered for HTTP mode. Press Ctrl+C to stop the servers.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nServers stopped")
except Exception as e:
# If something goes wrong with detection, block anyway to be safe
logging.error(f"Error in HTTP launch detection: {e}")
try:
print("\nKeeping HTTP servers alive. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nServers stopped")
return None
elif protocol == "mcp":
if not self.agents:
logging.warning("No agents to launch for MCP mode. Add agents to the Agents instance first.")
return
try:
import uvicorn
from mcp.server.fastmcp import FastMCP
from mcp.server.sse import SseServerTransport
from starlette.applications import Starlette
from starlette.requests import Request
from starlette.routing import Mount, Route
# from mcp.server import Server as MCPServer # Not directly needed if using FastMCP's server
import threading
import time
import inspect
import asyncio
# logging is already imported at the module level
except ImportError as e:
missing_module = str(e).split("No module named '")[-1].rstrip("'")
display_error(f"Missing dependency: {missing_module}. Required for launch() method with MCP mode.")
logging.error(f"Missing dependency: {missing_module}. Required for launch() method with MCP mode.")
print(f"\nTo add MCP capabilities, install the required dependencies:")
print(f"pip install {missing_module} mcp praison-mcp starlette uvicorn")
print("\nOr install all MCP dependencies with relevant packages.")
return None
mcp_instance = FastMCP("praisonai_workflow_mcp_server")
# Determine the MCP tool name for the workflow based on self.name
actual_mcp_tool_name = (f"execute_{self.name.lower().replace(' ', '_').replace('-', '_')}_workflow" if self.name
else "execute_workflow")
@mcp_instance.tool(name=actual_mcp_tool_name)
async def execute_workflow_tool(query: str) -> str: # Renamed for clarity
"""Executes the defined agent workflow with the given query."""
logging.info(f"MCP tool '{actual_mcp_tool_name}' called with query: {query}")
current_input = query
final_response = "No agents in workflow or workflow did not produce a final response."
for agent_instance in self.agents:
try:
logging.debug(f"Processing with agent: {agent_instance.name}")
if hasattr(agent_instance, 'achat') and asyncio.iscoroutinefunction(agent_instance.achat):
response = await agent_instance.achat(current_input, tools=agent_instance.tools)
elif hasattr(agent_instance, 'chat'): # Fallback to sync chat if achat not suitable
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, lambda ci=current_input: agent_instance.chat(ci, tools=agent_instance.tools))
else:
logging.warning(f"Agent {agent_instance.name} has no suitable chat or achat method.")
response = f"Error: Agent {agent_instance.name} has no callable chat method."
current_input = response if response is not None else "Agent returned no response."
final_response = current_input # Keep track of the last valid response
logging.debug(f"Agent {agent_instance.name} responded. Current intermediate output: {current_input}")
except Exception as e:
logging.error(f"Error during agent {agent_instance.name} execution in MCP workflow: {str(e)}", exc_info=True)
current_input = f"Error from agent {agent_instance.name}: {str(e)}"
final_response = current_input # Update final response to show error
# Optionally break or continue based on desired error handling for the workflow
# For now, we continue, and the error is passed to the next agent or returned.
logging.info(f"MCP tool '{actual_mcp_tool_name}' completed. Final response: {final_response}")
return final_response
base_mcp_path = path.rstrip('/')
sse_mcp_path = f"{base_mcp_path}/sse"
messages_mcp_path_prefix = f"{base_mcp_path}/messages"
if not messages_mcp_path_prefix.endswith('/'):
messages_mcp_path_prefix += '/'
sse_transport_mcp = SseServerTransport(messages_mcp_path_prefix)
async def handle_mcp_sse_connection(request: Request) -> None:
logging.debug(f"MCP SSE connection request from {request.client} for path {request.url.path}")
async with sse_transport_mcp.connect_sse(
request.scope, request.receive, request._send,
) as (read_stream, write_stream):
await mcp_instance._mcp_server.run(
read_stream, write_stream, mcp_instance._mcp_server.create_initialization_options(),
)
starlette_mcp_app = Starlette(
debug=debug,
routes=[
Route(sse_mcp_path, endpoint=handle_mcp_sse_connection),
Mount(messages_mcp_path_prefix, app=sse_transport_mcp.handle_post_message),
],
)
print(f"🚀 PraisonAIAgents MCP Workflow server starting on http://{host}:{port}")
print(f"📡 MCP SSE endpoint available at {sse_mcp_path}")
print(f"📢 MCP messages post to {messages_mcp_path_prefix}")
# Instead of trying to extract tool names, hardcode the known tool name
mcp_tool_names = [actual_mcp_tool_name] # Use the determined dynamic tool name
print(f"🛠️ Available MCP tools: {', '.join(mcp_tool_names)}")
agent_names_in_workflow = ", ".join([a.name for a in self.agents])
print(f"🔄 Agents in MCP workflow: {agent_names_in_workflow}")
def run_praison_mcp_server():
try:
uvicorn.run(starlette_mcp_app, host=host, port=port, log_level="debug" if debug else "info")
except Exception as e:
logging.error(f"Error starting PraisonAIAgents MCP server: {str(e)}", exc_info=True)
print(f"❌ Error starting PraisonAIAgents MCP server: {str(e)}")
mcp_server_thread = threading.Thread(target=run_praison_mcp_server, daemon=True)
mcp_server_thread.start()
time.sleep(0.5)
import inspect
stack = inspect.stack()
if len(stack) > 1 and stack[1].filename.endswith('.py'):
caller_frame = stack[1]
caller_line = caller_frame.lineno
try:
with open(caller_frame.filename, 'r') as f:
lines = f.readlines()
has_more_launches = False
for line_content in lines[caller_line:]:
if '.launch(' in line_content and not line_content.strip().startswith('#'):
has_more_launches = True
break
if not has_more_launches:
try:
print("\nPraisonAIAgents MCP server running. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nPraisonAIAgents MCP Server stopped")
except Exception as e:
logging.error(f"Error in PraisonAIAgents MCP launch detection: {e}")
try:
print("\nKeeping PraisonAIAgents MCP server alive. Press Ctrl+C to stop.")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nPraisonAIAgents MCP Server stopped")
return None
else:
display_error(f"Invalid protocol: {protocol}. Choose 'http' or 'mcp'.")
return None
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "praisonaiagents"
version = "0.0.78"
version = "0.0.82"
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
authors = [
{ name="Mervin Praison" }
@@ -0,0 +1,19 @@
from praisonaiagents import Agent, Agents
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
agent = Agent(name="SearchAgent", instructions="You Search the internet for information", tools=[internet_search_tool])
agent2 = Agent(name="SummariseAgent", instructions="You Summarise the information")
agents = Agents(name="MultiAgents", agents=[agent, agent2])
agents.launch(port=8080, protocol="mcp")
@@ -0,0 +1,4 @@
from praisonaiagents import Agent
agent = Agent(name="TweetAgent", instructions="Create a Tweet based on the topic provided")
agent.launch(port=8080, protocol="mcp")
+1 -1
View File
@@ -1883,7 +1883,7 @@ wheels = [
[[package]]
name = "praisonaiagents"
version = "0.0.78"
version = "0.0.82"
source = { editable = "." }
dependencies = [
{ name = "mcp" },
Generated
+1593 -953
View File
File diff suppressed because it is too large. Load diff