mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-08 17:31:00 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
89f48cf7a2 | ||
|
|
97fb7fdd52 | ||
|
|
ea4cb42324 | ||
|
|
71c5b929b7 | ||
|
|
c9edf19907 | ||
|
|
6cdc79f4a2 | ||
|
|
fdda350b72 | ||
|
|
85f748d5d1 | ||
|
|
bf24548598 | ||
|
|
a1622a2a79 | ||
|
|
209faff03c | ||
|
|
ad67089813 | ||
|
|
3e44eadd37 | ||
|
|
764e9aa838 | ||
|
|
ccfc92564e | ||
|
|
1f61000922 | ||
|
|
2164f3e658 | ||
|
|
739a9ff8b5 | ||
|
|
dbe63cbbc9 | ||
|
|
f4bff11e83 | ||
|
|
6552f61322 | ||
|
|
d5d898ff1b | ||
|
|
4df8d122fc | ||
|
|
766e5789e3 | ||
|
|
f9585e83cb | ||
|
|
e019bab987 | ||
|
|
54072a1d55 | ||
|
|
16ddcb8644 | ||
|
|
e0b9739b66 | ||
|
|
1bb6c8ca61 | ||
|
|
a242a26353 | ||
|
|
ff4f63fc54 | ||
|
|
48707686f0 | ||
|
|
1a414989bf | ||
|
|
141535c160 | ||
|
|
6911d6ad64 | ||
|
|
ba5af94dcb | ||
|
|
955a05be59 |
No files matched your search
@@ -0,0 +1,53 @@
|
||||
# PraisonAI Docker Environment Configuration
|
||||
# Copy this file to .env and update with your values
|
||||
|
||||
# Required: OpenAI API Key
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
|
||||
# Required: Chainlit Authentication Secret (generate a random string)
|
||||
CHAINLIT_AUTH_SECRET=your_chainlit_secret_here
|
||||
|
||||
# Optional: Additional API Keys
|
||||
ANTHROPIC_API_KEY=your_anthropic_api_key_here
|
||||
GOOGLE_API_KEY=your_google_api_key_here
|
||||
GROQ_API_KEY=your_groq_api_key_here
|
||||
COHERE_API_KEY=your_cohere_api_key_here
|
||||
|
||||
# Optional: Service Configuration
|
||||
FLASK_ENV=development
|
||||
CHAINLIT_HOST=0.0.0.0
|
||||
|
||||
# Optional: Port Configuration (modify if you have conflicts)
|
||||
UI_PORT=8082
|
||||
CHAT_PORT=8083
|
||||
API_PORT=8080
|
||||
|
||||
# Optional: Database Configuration
|
||||
DATABASE_URL=sqlite:///root/.praison/database.sqlite
|
||||
|
||||
# Optional: Logging Configuration
|
||||
LOG_LEVEL=INFO
|
||||
PYTHONPATH=/app
|
||||
|
||||
# Optional: Development Settings
|
||||
DEV_MODE=false
|
||||
DEBUG=false
|
||||
|
||||
# Optional: Model Configuration
|
||||
DEFAULT_MODEL=gpt-4
|
||||
DEFAULT_TEMPERATURE=0.7
|
||||
MAX_TOKENS=4000
|
||||
|
||||
# Optional: Security Settings
|
||||
CORS_ORIGINS=http://localhost:3000,http://localhost:8082,http://localhost:8083
|
||||
RATE_LIMIT=100
|
||||
|
||||
# Optional: Feature Flags
|
||||
ENABLE_CHAT=true
|
||||
ENABLE_UI=true
|
||||
ENABLE_API=true
|
||||
ENABLE_REALTIME=true
|
||||
|
||||
# Optional: Volume Paths (for custom mounting)
|
||||
PRAISON_DATA_PATH=~/.praison
|
||||
EXAMPLES_PATH=./examples
|
||||
+40
-1
@@ -1,6 +1,45 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
python3-dev \
|
||||
curl \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create praison config directory
|
||||
RUN mkdir -p /root/.praison
|
||||
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
flask \
|
||||
"praisonai>=2.2.20" \
|
||||
"praisonai[api]" \
|
||||
gunicorn \
|
||||
markdown
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==2.2.19 gunicorn markdown
|
||||
|
||||
# Set environment variables for directory management
|
||||
ENV PRAISON_CONFIG_DIR=/root/.praison
|
||||
ENV DOCKER_CONTAINER=true
|
||||
|
||||
# Create health check API if api.py doesn't exist
|
||||
RUN if [ ! -f api.py ]; then \
|
||||
echo "from flask import Flask\n\
|
||||
app = Flask(__name__)\n\
|
||||
\n\
|
||||
@app.route('/health')\n\
|
||||
def health():\n\
|
||||
return {'status': 'healthy'}, 200\n\
|
||||
\n\
|
||||
if __name__ == '__main__':\n\
|
||||
app.run()" > api.py; \
|
||||
fi
|
||||
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
+12
-3
@@ -7,18 +7,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
python3-dev \
|
||||
curl \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python packages
|
||||
# Create praison config directory
|
||||
RUN mkdir -p /root/.praison
|
||||
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonaiagents>=0.0.4 \
|
||||
praisonai_tools \
|
||||
"praisonai==2.2.19" \
|
||||
"praisonai>=2.2.20" \
|
||||
"praisonai[chat]" \
|
||||
"embedchain[github,youtube]"
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set environment variables for directory management
|
||||
ENV PRAISON_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_DB_DIR=/root/.praison
|
||||
ENV DOCKER_CONTAINER=true
|
||||
|
||||
# Default command (will be overridden by docker-compose)
|
||||
CMD ["praisonai", "chat"]
|
||||
+23
-4
@@ -9,20 +9,39 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
portaudio19-dev \
|
||||
python3-pyaudio \
|
||||
curl \
|
||||
git \
|
||||
vim \
|
||||
nano \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python packages
|
||||
# Create praison config directory
|
||||
RUN mkdir -p /root/.praison
|
||||
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonaiagents>=0.0.4 \
|
||||
praisonai_tools \
|
||||
"praisonai==2.2.19" \
|
||||
"praisonai>=2.2.20" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[chat]" \
|
||||
"praisonai[realtime]" \
|
||||
"embedchain[github,youtube]"
|
||||
"praisonai[code]" \
|
||||
"embedchain[github,youtube]" \
|
||||
jupyter \
|
||||
jupyterlab \
|
||||
notebook \
|
||||
pytest \
|
||||
pytest-asyncio \
|
||||
mkdocs \
|
||||
mkdocs-material
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set environment variables for directory management
|
||||
ENV PRAISON_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_DB_DIR=/root/.praison
|
||||
ENV DOCKER_CONTAINER=true
|
||||
|
||||
# Default command (will be overridden by docker-compose)
|
||||
CMD ["praisonai", "ui"]
|
||||
@@ -0,0 +1,32 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
python3-dev \
|
||||
curl \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create praison config directory
|
||||
RUN mkdir -p /root/.praison
|
||||
|
||||
# Copy praisonaiagents source
|
||||
COPY src/praisonai-agents/ /app/praisonaiagents/
|
||||
WORKDIR /app/praisonaiagents
|
||||
|
||||
# Install praisonaiagents with all features (non-editable for production)
|
||||
RUN pip install --no-cache-dir ".[all]"
|
||||
|
||||
# Set environment variables for directory management
|
||||
ENV PRAISON_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_DB_DIR=/root/.praison
|
||||
ENV DOCKER_CONTAINER=true
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Default command
|
||||
CMD ["python", "-c", "import praisonaiagents; print('PraisonAI Agents installed successfully')"]
|
||||
+12
-3
@@ -7,18 +7,27 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
gcc \
|
||||
python3-dev \
|
||||
curl \
|
||||
git \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python packages
|
||||
# Create praison config directory
|
||||
RUN mkdir -p /root/.praison
|
||||
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonaiagents>=0.0.4 \
|
||||
praisonai_tools \
|
||||
"praisonai==2.2.19" \
|
||||
"praisonai>=2.2.20" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[crewai]"
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Set environment variables for directory management
|
||||
ENV PRAISON_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_CONFIG_DIR=/root/.praison
|
||||
ENV CHAINLIT_DB_DIR=/root/.praison
|
||||
ENV DOCKER_CONTAINER=true
|
||||
|
||||
# Default command (will be overridden by docker-compose)
|
||||
CMD ["praisonai", "ui"]
|
||||
@@ -0,0 +1,265 @@
|
||||
# PraisonAI Docker Setup
|
||||
|
||||
This directory contains Docker configurations for running PraisonAI services in containerized environments. The setup addresses directory management issues and provides comprehensive multi-service deployment options.
|
||||
|
||||
## 🐳 Available Services
|
||||
|
||||
### Core Services
|
||||
- **UI Service** (`port 8082`) - Chainlit-based web interface
|
||||
- **Chat Service** (`port 8083`) - Dedicated chat interface
|
||||
- **API Service** (`port 8080`) - REST API endpoint
|
||||
- **Agents Service** - Standalone PraisonAI Agents runtime
|
||||
|
||||
### Docker Files
|
||||
- `Dockerfile` - Basic API service
|
||||
- `Dockerfile.ui` - UI service with web interface
|
||||
- `Dockerfile.chat` - Chat-focused service
|
||||
- `Dockerfile.dev` - Development environment with tools
|
||||
- `Dockerfile.praisonaiagents` - Standalone agents framework
|
||||
- `docker-compose.yml` - Multi-service orchestration
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Single Service
|
||||
```bash
|
||||
# Run UI service
|
||||
docker run -p 8082:8082 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:ui
|
||||
|
||||
# Run Chat service
|
||||
docker run -p 8083:8083 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:chat
|
||||
|
||||
# Run API service
|
||||
docker run -p 8080:8080 -e OPENAI_API_KEY=your_key ghcr.io/mervinpraison/praisonai:api
|
||||
```
|
||||
|
||||
### Multi-Service with Docker Compose
|
||||
```bash
|
||||
# Create environment file
|
||||
cat > .env << EOF
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
CHAINLIT_AUTH_SECRET=your_secret_here
|
||||
EOF
|
||||
|
||||
# Start all services
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
## 📁 Directory Management
|
||||
|
||||
### Problem Solved
|
||||
The original issue was that files like `chainlit.md`, `.chainlit` directory, and `public` folder were cluttering the root directory.
|
||||
|
||||
### Solution Implemented
|
||||
All PraisonAI configuration and runtime files are now stored in `~/.praison/`:
|
||||
|
||||
```bash
|
||||
~/.praison/
|
||||
├── database.sqlite # Chainlit database
|
||||
├── chainlit.md # Chainlit configuration
|
||||
├── .chainlit/ # Chainlit runtime files
|
||||
└── config/ # PraisonAI configuration
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
PRAISON_CONFIG_DIR=/root/.praison # Main config directory
|
||||
CHAINLIT_CONFIG_DIR=/root/.praison # Chainlit config location
|
||||
CHAINLIT_DB_DIR=/root/.praison # Database location
|
||||
```
|
||||
|
||||
## 🔧 Service Configuration
|
||||
|
||||
### UI Service (Port 8082)
|
||||
```yaml
|
||||
environment:
|
||||
- CHAINLIT_PORT=8082
|
||||
- CHAINLIT_HOST=0.0.0.0
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
- CHAINLIT_AUTH_SECRET=${CHAINLIT_AUTH_SECRET}
|
||||
```
|
||||
|
||||
### Chat Service (Port 8083)
|
||||
```yaml
|
||||
environment:
|
||||
- CHAINLIT_PORT=8083
|
||||
- CHAINLIT_HOST=0.0.0.0
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
```
|
||||
|
||||
### API Service (Port 8080)
|
||||
```yaml
|
||||
environment:
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
```
|
||||
|
||||
## 🎯 Service Endpoints
|
||||
|
||||
| Service | Port | Endpoint | Description |
|
||||
|---------|------|----------|-------------|
|
||||
| UI | 8082 | http://localhost:8082 | Web interface |
|
||||
| Chat | 8083 | http://localhost:8083 | Chat interface |
|
||||
| API | 8080 | http://localhost:8080 | REST API |
|
||||
| API Health | 8080 | http://localhost:8080/health | Health check |
|
||||
|
||||
## 🔍 Health Checks
|
||||
|
||||
All services include health checks:
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:PORT"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
```
|
||||
|
||||
## 📦 Package Versions
|
||||
|
||||
All Docker images use consistent, up-to-date versions:
|
||||
- PraisonAI: `>=2.2.20`
|
||||
- PraisonAI Agents: `>=0.0.92`
|
||||
- Python: `3.11-slim`
|
||||
|
||||
## 🔒 Security Features
|
||||
|
||||
- Non-root user execution where possible
|
||||
- Minimal base image (python:3.11-slim)
|
||||
- No unnecessary packages installed
|
||||
- Environment variable-based configuration
|
||||
- Volume mounting for persistent data
|
||||
|
||||
## 🛠 Development
|
||||
|
||||
### Development Environment
|
||||
```bash
|
||||
# Use development Dockerfile with additional tools
|
||||
docker build -f Dockerfile.dev -t praisonai:dev .
|
||||
docker run -it -v $(pwd):/app praisonai:dev bash
|
||||
```
|
||||
|
||||
### Custom Configuration
|
||||
```bash
|
||||
# Mount custom config directory
|
||||
docker run -v ~/.praison:/root/.praison praisonai:ui
|
||||
```
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Docker Compose Monitoring
|
||||
```bash
|
||||
# View service status
|
||||
docker-compose ps
|
||||
|
||||
# View resource usage
|
||||
docker-compose top
|
||||
|
||||
# View logs for specific service
|
||||
docker-compose logs ui
|
||||
docker-compose logs chat
|
||||
docker-compose logs api
|
||||
```
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Port conflicts**
|
||||
```bash
|
||||
# Check port usage
|
||||
netstat -tlnp | grep :8082
|
||||
|
||||
# Use different ports
|
||||
docker run -p 9082:8082 praisonai:ui
|
||||
```
|
||||
|
||||
2. **Environment variables not loading**
|
||||
```bash
|
||||
# Verify .env file
|
||||
cat .env
|
||||
|
||||
# Set variables directly
|
||||
docker run -e OPENAI_API_KEY=your_key praisonai:ui
|
||||
```
|
||||
|
||||
3. **Permission issues**
|
||||
```bash
|
||||
# Check volume permissions
|
||||
ls -la ~/.praison/
|
||||
|
||||
# Fix permissions
|
||||
sudo chown -R $(id -u):$(id -g) ~/.praison/
|
||||
```
|
||||
|
||||
4. **Service won't start**
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs service_name
|
||||
|
||||
# Restart service
|
||||
docker-compose restart service_name
|
||||
```
|
||||
|
||||
## 🔄 Updates
|
||||
|
||||
### Pulling Latest Images
|
||||
```bash
|
||||
# Pull latest images
|
||||
docker-compose pull
|
||||
|
||||
# Restart with new images
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Version Pinning
|
||||
To use specific versions, update the Dockerfile:
|
||||
```dockerfile
|
||||
RUN pip install "praisonai==2.2.20" "praisonaiagents==0.0.92"
|
||||
```
|
||||
|
||||
## 🌐 Production Deployment
|
||||
|
||||
### Recommended Production Setup
|
||||
```yaml
|
||||
# docker-compose.prod.yml
|
||||
version: '3.8'
|
||||
services:
|
||||
ui:
|
||||
image: ghcr.io/mervinpraison/praisonai:ui
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- CHAINLIT_HOST=0.0.0.0
|
||||
- CHAINLIT_PORT=8082
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
networks:
|
||||
- praison_network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
reservations:
|
||||
memory: 512M
|
||||
```
|
||||
|
||||
### Load Balancer Configuration
|
||||
For production environments, consider using nginx or similar:
|
||||
```nginx
|
||||
upstream praisonai {
|
||||
server localhost:8082;
|
||||
server localhost:8083;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
proxy_pass http://praisonai;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This Docker setup provides a clean, organized, and scalable way to deploy PraisonAI services while solving the directory management issues mentioned in the original request.
|
||||
@@ -0,0 +1,184 @@
|
||||
version: '3.8'
|
||||
|
||||
# Development Docker Compose Configuration
|
||||
# Extends the main docker-compose.yml with development-specific settings
|
||||
|
||||
services:
|
||||
# Development UI Service with hot reload
|
||||
ui-dev:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- ../src:/app/src:rw
|
||||
- ../examples:/app/examples:rw
|
||||
- ../docs:/app/docs:ro
|
||||
ports:
|
||||
- "${UI_PORT:-8082}:8082"
|
||||
environment:
|
||||
FLASK_ENV: development
|
||||
CHAINLIT_PORT: "8082"
|
||||
CHAINLIT_HOST: "0.0.0.0"
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_DB_DIR: /root/.praison
|
||||
DEBUG: "true"
|
||||
DEV_MODE: "true"
|
||||
PYTHONPATH: /app/src
|
||||
command: praisonai ui --host 0.0.0.0 --reload
|
||||
networks:
|
||||
- praison_network
|
||||
depends_on:
|
||||
- database
|
||||
|
||||
# Development Chat Service
|
||||
chat-dev:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- ../src:/app/src:rw
|
||||
- ../examples:/app/examples:rw
|
||||
ports:
|
||||
- "${CHAT_PORT:-8083}:8083"
|
||||
environment:
|
||||
CHAINLIT_PORT: "8083"
|
||||
CHAINLIT_HOST: "0.0.0.0"
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_DB_DIR: /root/.praison
|
||||
DEBUG: "true"
|
||||
DEV_MODE: "true"
|
||||
PYTHONPATH: /app/src
|
||||
command: praisonai chat --host 0.0.0.0 --port 8083 --reload
|
||||
networks:
|
||||
- praison_network
|
||||
depends_on:
|
||||
- database
|
||||
|
||||
# Development API Service with hot reload
|
||||
api-dev:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- ../src:/app/src:rw
|
||||
- ../examples:/app/examples:rw
|
||||
ports:
|
||||
- "${API_PORT:-8080}:8080"
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
FLASK_ENV: development
|
||||
DEBUG: "true"
|
||||
DEV_MODE: "true"
|
||||
PYTHONPATH: /app/src
|
||||
command: python -m flask --app api run --host 0.0.0.0 --port 8080 --debug
|
||||
networks:
|
||||
- praison_network
|
||||
depends_on:
|
||||
- database
|
||||
|
||||
# Development Jupyter Notebook Service
|
||||
jupyter:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- ../src:/app/src:rw
|
||||
- ../examples:/app/examples:rw
|
||||
- ../docs:/app/docs:rw
|
||||
ports:
|
||||
- "8888:8888"
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
JUPYTER_ENABLE_LAB: "yes"
|
||||
PYTHONPATH: /app/src
|
||||
command: jupyter lab --ip=0.0.0.0 --port=8888 --no-browser --allow-root --LabApp.token='' --LabApp.password=''
|
||||
networks:
|
||||
- praison_network
|
||||
|
||||
# Development Testing Service
|
||||
test:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- ../src:/app/src:rw
|
||||
- ../tests:/app/tests:rw
|
||||
- praison_data:/root/.praison
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
PYTHONPATH: /app/src
|
||||
PYTEST_CURRENT_TEST: "true"
|
||||
command: python -m pytest tests/ -v
|
||||
networks:
|
||||
- praison_network
|
||||
profiles:
|
||||
- test
|
||||
|
||||
# Standalone database for development
|
||||
database:
|
||||
image: postgres:15-alpine
|
||||
environment:
|
||||
POSTGRES_DB: praisonai_dev
|
||||
POSTGRES_USER: praisonai
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-praisonai_dev_pass}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5432:5432"
|
||||
networks:
|
||||
- praison_network
|
||||
profiles:
|
||||
- database
|
||||
|
||||
# Redis for caching and session management
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
networks:
|
||||
- praison_network
|
||||
profiles:
|
||||
- cache
|
||||
|
||||
# Development documentation server
|
||||
docs:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
volumes:
|
||||
- ../docs:/app/docs:rw
|
||||
- ../README.md:/app/README.md:ro
|
||||
ports:
|
||||
- "8000:8000"
|
||||
command: sh -c "cd docs && mkdocs serve --dev-addr 0.0.0.0:8000"
|
||||
networks:
|
||||
- praison_network
|
||||
profiles:
|
||||
- docs
|
||||
|
||||
volumes:
|
||||
praison_data:
|
||||
driver: local
|
||||
postgres_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
praison_network:
|
||||
driver: bridge
|
||||
@@ -1,9 +1,13 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PraisonAI UI Service
|
||||
ui:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.ui
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.ui
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- .:/app
|
||||
ports:
|
||||
- "8082:8082"
|
||||
@@ -13,9 +17,83 @@ services:
|
||||
CHAINLIT_HOST: "0.0.0.0"
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_DB_DIR: /root/.praison
|
||||
command: praisonai ui --host 0.0.0.0
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8082"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
retries: 3
|
||||
networks:
|
||||
- praison_network
|
||||
|
||||
# PraisonAI Chat Service
|
||||
chat:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.chat
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- .:/app
|
||||
ports:
|
||||
- "8083:8083"
|
||||
environment:
|
||||
CHAINLIT_PORT: "8083"
|
||||
CHAINLIT_HOST: "0.0.0.0"
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
CHAINLIT_AUTH_SECRET: ${CHAINLIT_AUTH_SECRET}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_CONFIG_DIR: /root/.praison
|
||||
CHAINLIT_DB_DIR: /root/.praison
|
||||
command: praisonai chat --host 0.0.0.0 --port 8083
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8083"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- praison_network
|
||||
|
||||
# PraisonAI API Service
|
||||
api:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- praison_network
|
||||
|
||||
# PraisonAI Agents Service (standalone)
|
||||
agents:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: docker/Dockerfile.praisonaiagents
|
||||
volumes:
|
||||
- praison_data:/root/.praison
|
||||
- ./examples:/app/examples
|
||||
environment:
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
PRAISON_CONFIG_DIR: /root/.praison
|
||||
networks:
|
||||
- praison_network
|
||||
|
||||
volumes:
|
||||
praison_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
praison_network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,289 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PraisonAI Docker Quick Start Script
|
||||
# This script helps users quickly get started with PraisonAI using Docker
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored output
|
||||
print_status() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if Docker is installed
|
||||
check_docker() {
|
||||
if ! command -v docker &> /dev/null; then
|
||||
print_error "Docker is not installed. Please install Docker first:"
|
||||
echo " - Visit: https://docs.docker.com/get-docker/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then
|
||||
print_error "Docker Compose is not available. Please install Docker Compose:"
|
||||
echo " - Visit: https://docs.docker.com/compose/install/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Docker and Docker Compose are available"
|
||||
}
|
||||
|
||||
# Check if .env file exists, create from template if not
|
||||
setup_environment() {
|
||||
if [ ! -f ".env" ]; then
|
||||
print_status "Creating .env file from template..."
|
||||
if [ -f ".env.template" ]; then
|
||||
cp .env.template .env
|
||||
else
|
||||
cat > .env << EOF
|
||||
# PraisonAI Docker Environment Configuration
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
CHAINLIT_AUTH_SECRET=$(openssl rand -hex 32 2>/dev/null || echo "your_chainlit_secret_here")
|
||||
FLASK_ENV=development
|
||||
CHAINLIT_HOST=0.0.0.0
|
||||
UI_PORT=8082
|
||||
CHAT_PORT=8083
|
||||
API_PORT=8080
|
||||
EOF
|
||||
fi
|
||||
print_warning "Please edit .env file and add your API keys before continuing"
|
||||
print_status "Required: OPENAI_API_KEY"
|
||||
read -p "Press Enter to continue after updating .env file..."
|
||||
else
|
||||
print_success ".env file already exists"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to show menu
|
||||
show_menu() {
|
||||
echo ""
|
||||
echo "=== PraisonAI Docker Quick Start ==="
|
||||
echo ""
|
||||
echo "1) Start UI Service (Web Interface) - Port 8082"
|
||||
echo "2) Start Chat Service - Port 8083"
|
||||
echo "3) Start API Service - Port 8080"
|
||||
echo "4) Start All Services (Recommended)"
|
||||
echo "5) Start Development Environment"
|
||||
echo "6) View Service Status"
|
||||
echo "7) View Logs"
|
||||
echo "8) Stop All Services"
|
||||
echo "9) Pull Latest Images"
|
||||
echo "10) Clean Up (Remove containers and volumes)"
|
||||
echo "11) Show Service URLs"
|
||||
echo "0) Exit"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Start specific service
|
||||
start_service() {
|
||||
local service=$1
|
||||
print_status "Starting $service service..."
|
||||
docker-compose up -d $service
|
||||
print_success "$service service started"
|
||||
}
|
||||
|
||||
# Start all services
|
||||
start_all_services() {
|
||||
print_status "Starting all PraisonAI services..."
|
||||
docker-compose up -d
|
||||
print_success "All services started"
|
||||
show_service_urls
|
||||
}
|
||||
|
||||
# Start development environment
|
||||
start_dev_environment() {
|
||||
print_status "Starting development environment..."
|
||||
if [ -f "docker-compose.dev.yml" ]; then
|
||||
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d ui-dev chat-dev api-dev
|
||||
print_success "Development environment started"
|
||||
echo ""
|
||||
echo "Development services available:"
|
||||
echo " - UI (with hot reload): http://localhost:${UI_PORT:-8082}"
|
||||
echo " - Chat (with hot reload): http://localhost:${CHAT_PORT:-8083}"
|
||||
echo " - API (with hot reload): http://localhost:${API_PORT:-8080}"
|
||||
echo " - Jupyter Lab: http://localhost:8888"
|
||||
echo ""
|
||||
else
|
||||
print_warning "Development configuration not found, starting regular services"
|
||||
start_all_services
|
||||
fi
|
||||
}
|
||||
|
||||
# Show service status
|
||||
show_status() {
|
||||
print_status "Service Status:"
|
||||
docker-compose ps
|
||||
}
|
||||
|
||||
# Show logs
|
||||
show_logs() {
|
||||
echo ""
|
||||
echo "Which service logs would you like to view?"
|
||||
echo "1) All services"
|
||||
echo "2) UI service"
|
||||
echo "3) Chat service"
|
||||
echo "4) API service"
|
||||
echo "5) Agents service"
|
||||
read -p "Enter choice (1-5): " log_choice
|
||||
|
||||
case $log_choice in
|
||||
1) docker-compose logs -f ;;
|
||||
2) docker-compose logs -f ui ;;
|
||||
3) docker-compose logs -f chat ;;
|
||||
4) docker-compose logs -f api ;;
|
||||
5) docker-compose logs -f agents ;;
|
||||
*) print_error "Invalid choice" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Stop all services
|
||||
stop_services() {
|
||||
print_status "Stopping all services..."
|
||||
docker-compose down
|
||||
print_success "All services stopped"
|
||||
}
|
||||
|
||||
# Pull latest images
|
||||
pull_images() {
|
||||
print_status "Pulling latest images..."
|
||||
docker-compose pull
|
||||
print_success "Images updated"
|
||||
}
|
||||
|
||||
# Clean up
|
||||
cleanup() {
|
||||
print_warning "This will remove all containers, networks, and volumes"
|
||||
read -p "Are you sure? (y/N): " confirm
|
||||
if [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
|
||||
print_status "Cleaning up..."
|
||||
docker-compose down -v --remove-orphans
|
||||
docker system prune -f
|
||||
print_success "Cleanup completed"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show service URLs
|
||||
show_service_urls() {
|
||||
local ui_port=${UI_PORT:-8082}
|
||||
local chat_port=${CHAT_PORT:-8083}
|
||||
local api_port=${API_PORT:-8080}
|
||||
|
||||
echo ""
|
||||
echo "=== Service URLs ==="
|
||||
echo "UI Service: http://localhost:$ui_port"
|
||||
echo "Chat Service: http://localhost:$chat_port"
|
||||
echo "API Service: http://localhost:$api_port"
|
||||
echo "API Health: http://localhost:$api_port/health"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Check system requirements
|
||||
check_requirements() {
|
||||
print_status "Checking system requirements..."
|
||||
|
||||
# Check available memory
|
||||
if command -v free &> /dev/null; then
|
||||
available_ram=$(free -m | awk 'NR==2{printf "%.1f", $7/1024}')
|
||||
print_status "Available RAM: ${available_ram}GB"
|
||||
if (( $(echo "$available_ram < 2.0" | bc -l 2>/dev/null || echo "1") )); then
|
||||
print_warning "Low available memory. Recommended: 2GB+ available RAM"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check disk space
|
||||
if command -v df &> /dev/null; then
|
||||
available_space=$(df -BG . | awk 'NR==2{print $4}' | sed 's/G//')
|
||||
print_status "Available disk space: ${available_space}GB"
|
||||
if [ "$available_space" -lt 5 ]; then
|
||||
print_warning "Low disk space. Recommended: 5GB+ available space"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
clear
|
||||
echo "🤖 Welcome to PraisonAI Docker Setup!"
|
||||
echo ""
|
||||
|
||||
# Check prerequisites
|
||||
check_docker
|
||||
check_requirements
|
||||
setup_environment
|
||||
|
||||
# Main loop
|
||||
while true; do
|
||||
show_menu
|
||||
read -p "Enter your choice (0-11): " choice
|
||||
|
||||
case $choice in
|
||||
1)
|
||||
start_service "ui"
|
||||
echo "UI Service: http://localhost:${UI_PORT:-8082}"
|
||||
;;
|
||||
2)
|
||||
start_service "chat"
|
||||
echo "Chat Service: http://localhost:${CHAT_PORT:-8083}"
|
||||
;;
|
||||
3)
|
||||
start_service "api"
|
||||
echo "API Service: http://localhost:${API_PORT:-8080}"
|
||||
;;
|
||||
4)
|
||||
start_all_services
|
||||
;;
|
||||
5)
|
||||
start_dev_environment
|
||||
;;
|
||||
6)
|
||||
show_status
|
||||
;;
|
||||
7)
|
||||
show_logs
|
||||
;;
|
||||
8)
|
||||
stop_services
|
||||
;;
|
||||
9)
|
||||
pull_images
|
||||
;;
|
||||
10)
|
||||
cleanup
|
||||
;;
|
||||
11)
|
||||
show_service_urls
|
||||
;;
|
||||
0)
|
||||
print_success "Thank you for using PraisonAI!"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_error "Invalid choice. Please try again."
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
read -p "Press Enter to continue..."
|
||||
done
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.2.19 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.2.20 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pip install flask praisonai==2.2.19 watchdog
|
||||
RUN pip install flask praisonai==2.2.20 watchdog
|
||||
|
||||
EXPOSE 5555
|
||||
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
---
|
||||
title: Camera Integration
|
||||
description: How to integrate camera feeds with PraisonAI multimodal agents for real-time visual analysis
|
||||
---
|
||||
|
||||
# Camera Integration
|
||||
|
||||
PraisonAI supports camera integration for real-time visual analysis through multimodal agents. While there's no built-in camera capture, you can easily integrate camera feeds by capturing frames or videos and passing them to vision agents.
|
||||
|
||||
## Overview
|
||||
|
||||
Camera integration works by:
|
||||
1. **Capturing frames/videos** from camera using OpenCV
|
||||
2. **Saving temporarily** to disk
|
||||
3. **Passing file paths** to agents via the `images` parameter
|
||||
4. **Cleaning up** temporary files after analysis
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```bash
|
||||
pip install praisonaiagents opencv-python
|
||||
export OPENAI_API_KEY=your_openai_api_key
|
||||
```
|
||||
|
||||
### Basic Camera Capture
|
||||
|
||||
```python
|
||||
import cv2
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
def capture_and_analyze():
|
||||
# Create vision agent
|
||||
vision_agent = Agent(
|
||||
name="CameraAnalyst",
|
||||
role="Camera Feed Analyzer",
|
||||
goal="Analyze camera captures in real-time",
|
||||
backstory="Expert in real-time visual analysis",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Capture from camera
|
||||
cap = cv2.VideoCapture(0) # 0 for default camera
|
||||
ret, frame = cap.read()
|
||||
|
||||
if ret:
|
||||
# Save frame temporarily
|
||||
cv2.imwrite("temp_capture.jpg", frame)
|
||||
cap.release()
|
||||
|
||||
# Create analysis task
|
||||
task = Task(
|
||||
description="Analyze what you see in this camera feed",
|
||||
expected_output="Detailed analysis of camera content",
|
||||
agent=vision_agent,
|
||||
images=["temp_capture.jpg"]
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[vision_agent],
|
||||
tasks=[task]
|
||||
)
|
||||
|
||||
return agents.start()
|
||||
|
||||
# Run analysis
|
||||
result = capture_and_analyze()
|
||||
```
|
||||
|
||||
## Integration Patterns
|
||||
|
||||
### 1. Single Frame Analysis
|
||||
|
||||
Perfect for quick snapshots and one-time analysis:
|
||||
|
||||
```python
|
||||
def single_frame_analysis():
|
||||
cap = cv2.VideoCapture(0)
|
||||
ret, frame = cap.read()
|
||||
|
||||
if ret:
|
||||
image_path = "snapshot.jpg"
|
||||
cv2.imwrite(image_path, frame)
|
||||
|
||||
# Analyze with your agent
|
||||
# ... (agent setup and task creation)
|
||||
|
||||
cap.release()
|
||||
```
|
||||
|
||||
### 2. Continuous Monitoring
|
||||
|
||||
Ideal for security systems and real-time monitoring:
|
||||
|
||||
```python
|
||||
def continuous_monitoring(interval=10):
|
||||
vision_agent = Agent(
|
||||
name="SecurityMonitor",
|
||||
role="Security Camera Analyst",
|
||||
goal="Monitor for security events",
|
||||
backstory="Expert security analyst",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
cap = cv2.VideoCapture(0)
|
||||
|
||||
while True:
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
timestamp = int(time.time())
|
||||
filename = f"capture_{timestamp}.jpg"
|
||||
cv2.imwrite(filename, frame)
|
||||
|
||||
# Analyze frame
|
||||
task = Task(
|
||||
description="Monitor for unusual activities",
|
||||
agent=vision_agent,
|
||||
images=[filename]
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[vision_agent],
|
||||
tasks=[task]
|
||||
)
|
||||
|
||||
result = agents.start()
|
||||
print(f"Analysis: {result}")
|
||||
|
||||
time.sleep(interval)
|
||||
```
|
||||
|
||||
### 3. Multi-Agent Analysis
|
||||
|
||||
Use multiple specialized agents for comprehensive analysis:
|
||||
|
||||
```python
|
||||
def multi_agent_camera_analysis():
|
||||
# Create specialized agents
|
||||
security_agent = Agent(
|
||||
name="SecurityExpert",
|
||||
role="Security Specialist",
|
||||
goal="Identify security threats",
|
||||
backstory="Expert in surveillance and threat detection",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
object_detector = Agent(
|
||||
name="ObjectDetector",
|
||||
role="Object Recognition Specialist",
|
||||
goal="Identify and catalog objects",
|
||||
backstory="Computer vision expert",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
scene_analyst = Agent(
|
||||
name="SceneAnalyst",
|
||||
role="Scene Understanding Expert",
|
||||
goal="Provide comprehensive scene analysis",
|
||||
backstory="Environmental analysis expert",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Capture frame
|
||||
cap = cv2.VideoCapture(0)
|
||||
ret, frame = cap.read()
|
||||
cap.release()
|
||||
|
||||
if ret:
|
||||
cv2.imwrite("analysis_frame.jpg", frame)
|
||||
|
||||
# Create specialized tasks
|
||||
security_task = Task(
|
||||
description="Analyze for security threats",
|
||||
agent=security_agent,
|
||||
images=["analysis_frame.jpg"]
|
||||
)
|
||||
|
||||
object_task = Task(
|
||||
description="Identify all objects in scene",
|
||||
agent=object_detector,
|
||||
images=["analysis_frame.jpg"]
|
||||
)
|
||||
|
||||
scene_task = Task(
|
||||
description="Provide comprehensive scene analysis",
|
||||
agent=scene_analyst,
|
||||
images=["analysis_frame.jpg"]
|
||||
)
|
||||
|
||||
# Run parallel analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[security_agent, object_detector, scene_analyst],
|
||||
tasks=[security_task, object_task, scene_task],
|
||||
process="parallel"
|
||||
)
|
||||
|
||||
return agents.start()
|
||||
```
|
||||
|
||||
### 4. Video Recording & Analysis
|
||||
|
||||
Analyze temporal events and activities:
|
||||
|
||||
```python
|
||||
def record_and_analyze_video(duration=10):
|
||||
cap = cv2.VideoCapture(0)
|
||||
|
||||
# Setup video writer
|
||||
fps = int(cap.get(cv2.CAP_PROP_FPS)) or 30
|
||||
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
out = cv2.VideoWriter('recording.mp4', fourcc, fps, (width, height))
|
||||
|
||||
# Record video
|
||||
start_time = time.time()
|
||||
while (time.time() - start_time) < duration:
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
out.write(frame)
|
||||
|
||||
cap.release()
|
||||
out.release()
|
||||
|
||||
# Analyze video
|
||||
video_agent = Agent(
|
||||
name="VideoAnalyst",
|
||||
role="Video Content Analyzer",
|
||||
goal="Analyze video content for activities",
|
||||
backstory="Expert in video analysis",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Analyze this video for activities and events",
|
||||
agent=video_agent,
|
||||
images=["recording.mp4"] # Video files work too!
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[video_agent],
|
||||
tasks=[task]
|
||||
)
|
||||
|
||||
return agents.start()
|
||||
```
|
||||
|
||||
## Supported Input Types
|
||||
|
||||
PraisonAI accepts various visual input formats:
|
||||
|
||||
- ✅ **Local Images**: `"camera_shot.jpg"`, `"webcam_capture.png"`
|
||||
- ✅ **Local Videos**: `"security_feed.mp4"`, `"recording.avi"`
|
||||
- ✅ **Image URLs**: `"https://example.com/live_feed.jpg"`
|
||||
- ✅ **Multiple Sources**: `["cam1.jpg", "cam2.jpg", "video.mp4"]`
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Camera Selection
|
||||
|
||||
```python
|
||||
# Different camera sources
|
||||
camera_id = 0 # Default camera
|
||||
camera_id = 1 # External USB camera
|
||||
camera_id = "rtsp://camera-ip/stream" # IP camera
|
||||
```
|
||||
|
||||
### Analysis Intervals
|
||||
|
||||
```python
|
||||
# For continuous monitoring
|
||||
analysis_interval = 5 # Every 5 seconds (high frequency)
|
||||
analysis_interval = 30 # Every 30 seconds (moderate)
|
||||
analysis_interval = 300 # Every 5 minutes (low frequency)
|
||||
```
|
||||
|
||||
### Video Recording
|
||||
|
||||
```python
|
||||
# Recording duration
|
||||
duration = 10 # 10 seconds
|
||||
duration = 60 # 1 minute
|
||||
duration = 300 # 5 minutes
|
||||
```
|
||||
|
||||
## Use Cases
|
||||
|
||||
### Security Monitoring
|
||||
- Real-time threat detection
|
||||
- Unauthorized access alerts
|
||||
- Suspicious activity identification
|
||||
- Perimeter monitoring
|
||||
|
||||
### Retail Analytics
|
||||
- Customer behavior analysis
|
||||
- Inventory monitoring
|
||||
- Queue management
|
||||
- Theft prevention
|
||||
|
||||
### Industrial Automation
|
||||
- Quality control inspection
|
||||
- Safety compliance monitoring
|
||||
- Equipment status verification
|
||||
- Process optimization
|
||||
|
||||
### Smart Home
|
||||
- Activity recognition
|
||||
- Elderly care monitoring
|
||||
- Pet monitoring
|
||||
- Energy usage optimization
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Performance Optimization
|
||||
|
||||
1. **Frame Rate Management**
|
||||
```python
|
||||
# Reduce analysis frequency for better performance
|
||||
time.sleep(5) # Analyze every 5 seconds instead of continuously
|
||||
```
|
||||
|
||||
2. **Image Size Optimization**
|
||||
```python
|
||||
# Resize frames for faster processing
|
||||
frame = cv2.resize(frame, (640, 480))
|
||||
```
|
||||
|
||||
3. **Parallel Processing**
|
||||
```python
|
||||
# Use parallel process for multiple agents
|
||||
process="parallel"
|
||||
```
|
||||
|
||||
### Memory Management
|
||||
|
||||
1. **Clean Up Temporary Files**
|
||||
```python
|
||||
import os
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
```
|
||||
|
||||
2. **Limit Video Duration**
|
||||
```python
|
||||
# Keep recordings short to avoid large files
|
||||
max_duration = 30 # seconds
|
||||
```
|
||||
|
||||
### Security Considerations
|
||||
|
||||
1. **Camera Permissions**
|
||||
- Ensure application has camera access
|
||||
- Handle permission errors gracefully
|
||||
|
||||
2. **Privacy Protection**
|
||||
- Implement data retention policies
|
||||
- Secure transmission of camera data
|
||||
- User consent for recording
|
||||
|
||||
3. **Access Control**
|
||||
- Authenticate camera access
|
||||
- Implement role-based permissions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Camera Not Found
|
||||
|
||||
```python
|
||||
# Check available cameras
|
||||
for i in range(4):
|
||||
cap = cv2.VideoCapture(i)
|
||||
if cap.isOpened():
|
||||
print(f"Camera {i} is available")
|
||||
cap.release()
|
||||
else:
|
||||
print(f"Camera {i} not available")
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
|
||||
**Linux:**
|
||||
```bash
|
||||
# Add user to video group
|
||||
sudo usermod -a -G video $USER
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
- Grant camera permissions in System Preferences > Security & Privacy
|
||||
|
||||
**Windows:**
|
||||
- Check camera privacy settings in Windows Settings
|
||||
|
||||
### Performance Issues
|
||||
|
||||
```python
|
||||
# Reduce frame size
|
||||
frame = cv2.resize(frame, (320, 240))
|
||||
|
||||
# Lower analysis frequency
|
||||
time.sleep(10) # Analyze every 10 seconds
|
||||
|
||||
# Use threading for non-blocking capture
|
||||
import threading
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Complete working examples are available in the repository:
|
||||
|
||||
- [`camera-basic.py`](../../examples/python/camera/camera-basic.py) - Basic single frame capture
|
||||
- [`camera-continuous.py`](../../examples/python/camera/camera-continuous.py) - Continuous monitoring
|
||||
- [`camera-multi-agent.py`](../../examples/python/camera/camera-multi-agent.py) - Multi-agent analysis
|
||||
- [`camera-video-analysis.py`](../../examples/python/camera/camera-video-analysis.py) - Video recording & analysis
|
||||
|
||||
## Related Features
|
||||
|
||||
- [Multimodal Agents](./multimodal) - Core multimodal capabilities
|
||||
- [Image Generation](./image-generation) - Creating images with AI
|
||||
- [Agent Memory](../concepts/memory) - Persistent agent memory
|
||||
- [Task Management](../concepts/tasks) - Task configuration and execution
|
||||
+2
-1
@@ -143,7 +143,8 @@
|
||||
"features/mathagent",
|
||||
"features/structured",
|
||||
"features/callbacks",
|
||||
"features/chat-with-pdf"
|
||||
"features/chat-with-pdf",
|
||||
"features/camera-integration"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -155,7 +155,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pip install flask praisonai==2.2.19 watchdog
|
||||
RUN pip install flask praisonai==2.2.20 watchdog
|
||||
|
||||
EXPOSE 5555
|
||||
|
||||
|
||||
+1
-1
@@ -208,7 +208,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN pip install flask praisonai==2.2.19 watchdog
|
||||
RUN pip install flask praisonai==2.2.20 watchdog
|
||||
|
||||
EXPOSE 5555
|
||||
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "M_G-1ig6-__z"
|
||||
},
|
||||
"source": [
|
||||
"# LangChain Agent with PraisonAI\n",
|
||||
"This notebook demonstrates how to use LangChain-compatible tools and PraisonAI agents to research AI-related topics using Wikipedia and YouTube.\n",
|
||||
"\n",
|
||||
"---"
|
||||
],
|
||||
"id": "M_G-1ig6-__z"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ZVBvL3zK-__3"
|
||||
},
|
||||
"source": [
|
||||
"## Dependencies"
|
||||
],
|
||||
"id": "ZVBvL3zK-__3"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "d7aUlkgM-__5"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install praisonaiagents langchain-community wikipedia youtube-search"
|
||||
],
|
||||
"id": "d7aUlkgM-__5"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "sHNzy00Q-__6"
|
||||
},
|
||||
"source": [
|
||||
"## Set API Keys"
|
||||
],
|
||||
"id": "sHNzy00Q-__6"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "xCQvYxjK-__6"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"os.environ['OPENAI_API_KEY'] = 'your_api_key_here'"
|
||||
],
|
||||
"id": "xCQvYxjK-__6"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "1CDN1gXJ-__7"
|
||||
},
|
||||
"source": [
|
||||
"## Tools and Agents Setup"
|
||||
],
|
||||
"id": "1CDN1gXJ-__7"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "pj6Djfhd-__7"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from praisonaiagents import Agent, Task, PraisonAIAgents\n",
|
||||
"from langchain_community.utilities import WikipediaAPIWrapper\n",
|
||||
"from langchain_community.tools import YouTubeSearchTool\n",
|
||||
"\n",
|
||||
"wiki_agent = Agent(\n",
|
||||
" name=\"WikiAgent\",\n",
|
||||
" role=\"Research Assistant\",\n",
|
||||
" goal=\"Search Wikipedia for accurate information\",\n",
|
||||
" backstory=\"I am an AI assistant specialized in Wikipedia research\",\n",
|
||||
" tools=[WikipediaAPIWrapper],\n",
|
||||
" self_reflect=False\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"youtube_agent = Agent(\n",
|
||||
" name=\"SearchAgent\",\n",
|
||||
" role=\"Research Assistant\",\n",
|
||||
" goal=\"Search for information from YouTube\",\n",
|
||||
" backstory=\"I am an AI assistant that can search YouTube for relevant videos.\",\n",
|
||||
" tools=[YouTubeSearchTool],\n",
|
||||
" self_reflect=False\n",
|
||||
")"
|
||||
],
|
||||
"id": "pj6Djfhd-__7"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "X5YJSOPO-__8"
|
||||
},
|
||||
"source": [
|
||||
"## Prompt and Tasks"
|
||||
],
|
||||
"id": "X5YJSOPO-__8"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "dC2fi8ZF-__9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"task1 = Task(\n",
|
||||
" name=\"wiki_task\",\n",
|
||||
" description=\"Research 'Artificial Intelligence' on Wikipedia\",\n",
|
||||
" expected_output=\"Comprehensive information from Wikipedia articles\",\n",
|
||||
" agent=wiki_agent\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"task2 = Task(\n",
|
||||
" name=\"search_task\",\n",
|
||||
" description=\"Search for information about 'AI advancements' on YouTube\",\n",
|
||||
" expected_output=\"Relevant information from YouTube videos\",\n",
|
||||
" agent=youtube_agent\n",
|
||||
")"
|
||||
],
|
||||
"id": "dC2fi8ZF-__9"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "YMFbVVTF-__-"
|
||||
},
|
||||
"source": [
|
||||
"## Main Agent Execution"
|
||||
],
|
||||
"id": "YMFbVVTF-__-"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "80jMkenz-__-"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"agents = PraisonAIAgents(\n",
|
||||
" agents=[wiki_agent, youtube_agent],\n",
|
||||
" tasks=[task1, task2],\n",
|
||||
" verbose=True\n",
|
||||
")\n",
|
||||
"agents.start()"
|
||||
],
|
||||
"id": "80jMkenz-__-"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "O13iiPNE-__-"
|
||||
},
|
||||
"source": [
|
||||
"# LangChain Agent Outputs"
|
||||
],
|
||||
"id": "O13iiPNE-__-"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "6bL4CxKD-___"
|
||||
},
|
||||
"source": [
|
||||
"## 1. Wikipedia Agent Output\n",
|
||||
"\n",
|
||||
"### Artificial Intelligence (AI)\n",
|
||||
"\n",
|
||||
"Artificial intelligence (AI) refers to the capability of computational systems to perform tasks typically associated with human intelligence, such as learning, reasoning, problem-solving, perception, and decision-making. It is a field of research in computer science focused on developing methods and software that enable machines to perceive their environment and use learning and intelligence to take actions that maximize their chances of achieving defined goals.\n",
|
||||
"\n",
|
||||
"**Applications of AI:**\n",
|
||||
"- Advanced web search engines (e.g., Google Search)\n",
|
||||
"- Recommendation systems (e.g., YouTube, Amazon, Netflix)\n",
|
||||
"- Virtual assistants (e.g., Google Assistant, Siri, Alexa)\n",
|
||||
"- Autonomous vehicles (e.g., Waymo)\n",
|
||||
"- Generative and creative tools (e.g., ChatGPT, AI art)\n",
|
||||
"- Superhuman play and analysis in strategy games (e.g., chess, Go)\n",
|
||||
"\n",
|
||||
"**Subfields and Techniques:**\n",
|
||||
"AI research is centered around goals such as learning, reasoning, knowledge representation, planning, natural language processing, perception, and robotics support. Techniques include search and mathematical optimization, formal logic, artificial neural networks, and methods based on statistics, operations research, and economics. AI also draws from psychology, linguistics, philosophy, neuroscience, and other fields.\n",
|
||||
"\n",
|
||||
"**History and Development:**\n",
|
||||
"AI was founded as an academic discipline in 1956. The field has experienced cycles of optimism and disappointment, known as AI winters. Interest and funding increased significantly after 2012 with the use of graphics processing units to accelerate neural networks and the success of deep learning. The AI boom in the 2020s was marked by advanced generative AI, raising ethical concerns and discussions about regulatory policies.\n",
|
||||
"\n",
|
||||
"**Artificial General Intelligence (AGI):**\n",
|
||||
"AGI, or human-level intelligence AI, would match or surpass human capabilities across virtually all cognitive tasks. Some researchers believe that current large language models show early signs of AGI-level capability, while others argue that genuine AGI has not yet been achieved. AGI is distinct from artificial superintelligence (ASI), which would outperform human abilities across every domain. Unlike artificial narrow intelligence (ANI), AGI can generalize knowledge, transfer skills between domains, and solve novel problems without task-specific reprogramming.\n",
|
||||
"\n",
|
||||
"Creating AGI is a major goal for companies like OpenAI, Google DeepMind, and Meta, aiming to develop AI that can complete virtually any cognitive task as well as a human."
|
||||
],
|
||||
"id": "6bL4CxKD-___"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "lS0gvGjK-___"
|
||||
},
|
||||
"source": [
|
||||
"## 2. Web Search Agent Output\n",
|
||||
"\n",
|
||||
"### Latest AI Developments\n",
|
||||
"\n",
|
||||
"New Technologies in AI: Chatbots and Virtual Assistants are personalizing user experiences by analyzing user data and behavior, recommending products, content, and services, which increases engagement and sales."
|
||||
],
|
||||
"id": "lS0gvGjK-___"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "yJqv-2Vf-___"
|
||||
},
|
||||
"source": [
|
||||
"## 3. Agent Interaction Details\n",
|
||||
"\n",
|
||||
"**Wikipedia Agent Info:** \n",
|
||||
"👤 Agent: WikiAgent \n",
|
||||
"Role: Research Assistant \n",
|
||||
"Tools: WikipediaAPIWrapper\n",
|
||||
"\n",
|
||||
"**Web Search Agent Info:** \n",
|
||||
"👤 Agent: SearchAgent \n",
|
||||
"Role: Research Assistant \n",
|
||||
"Tools: YouTubeSearchTool\n",
|
||||
"\n",
|
||||
"**Performance Metrics:**\n",
|
||||
"- Wikipedia Agent Response Time: 15.4 seconds\n",
|
||||
"- Web Search Agent Response Time: 5.7 seconds"
|
||||
],
|
||||
"id": "yJqv-2Vf-___"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Yv5abx7e-___"
|
||||
},
|
||||
"source": [
|
||||
"## LangChain Tools with Wrappers"
|
||||
],
|
||||
"id": "Yv5abx7e-___"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "3UywakPF-___"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install langchain-community google-search-results"
|
||||
],
|
||||
"id": "3UywakPF-___"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "otWS3SV0_AAA"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.environ['SERPAPI_API_KEY'] = 'your_serpapi_key_here'"
|
||||
],
|
||||
"id": "otWS3SV0_AAA"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "TE46xk8A_AAB"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.utilities import SerpAPIWrapper\n",
|
||||
"\n",
|
||||
"data_agent = Agent(\n",
|
||||
" instructions=\"Search about AI job trends in 2025\",\n",
|
||||
" tools=[SerpAPIWrapper]\n",
|
||||
")\n",
|
||||
"editor_agent = Agent(instructions=\"Write a blog article\")\n",
|
||||
"\n",
|
||||
"agents = PraisonAIAgents(agents=[data_agent, editor_agent])\n",
|
||||
"agents.start()"
|
||||
],
|
||||
"id": "TE46xk8A_AAB"
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2BqJBqaU_AAB"
|
||||
},
|
||||
"source": [
|
||||
"## Example Without Wrapper (Brave Search)"
|
||||
],
|
||||
"id": "2BqJBqaU_AAB"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "MxGyDSqY_AAC"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install langchain-community"
|
||||
],
|
||||
"id": "MxGyDSqY_AAC"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "ZoD_erO__AAC"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"os.environ['BRAVE_SEARCH_API'] = 'your_brave_api_key_here'"
|
||||
],
|
||||
"id": "ZoD_erO__AAC"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "-TQfJWzw_AAC"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.tools import BraveSearch\n",
|
||||
"\n",
|
||||
"def search_brave(query: str):\n",
|
||||
" api_key = os.environ['BRAVE_SEARCH_API']\n",
|
||||
" tool = BraveSearch.from_api_key(api_key=api_key, search_kwargs={\"count\": 3})\n",
|
||||
" return tool.run(query)\n",
|
||||
"\n",
|
||||
"data_agent = Agent(instructions=\"Search about AI job trends in 2025\", tools=[search_brave])\n",
|
||||
"editor_agent = Agent(instructions=\"Write a blog article\")\n",
|
||||
"\n",
|
||||
"agents = PraisonAIAgents(agents=[data_agent, editor_agent])\n",
|
||||
"agents.start()"
|
||||
],
|
||||
"id": "-TQfJWzw_AAC"
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"colab": {
|
||||
"provenance": []
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
# Camera Integration Examples
|
||||
|
||||
This directory contains examples demonstrating how to integrate camera feeds with PraisonAI multimodal agents for real-time visual analysis.
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
PraisonAI supports visual input through the `images` parameter in Tasks. While there's no built-in camera capture, you can integrate camera feeds by capturing frames/videos and passing them to vision agents.
|
||||
|
||||
## 🛠️ Setup
|
||||
|
||||
### Requirements
|
||||
```bash
|
||||
pip install praisonaiagents opencv-python
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_openai_api_key
|
||||
```
|
||||
|
||||
## 📁 Examples
|
||||
|
||||
### 1. `camera-basic.py` - Basic Camera Capture
|
||||
- **Purpose**: Capture a single frame and analyze it
|
||||
- **Use Case**: Quick analysis, testing camera setup
|
||||
- **Features**:
|
||||
- Single frame capture
|
||||
- Basic object and scene analysis
|
||||
- Automatic cleanup
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python camera-basic.py
|
||||
```
|
||||
|
||||
### 2. `camera-continuous.py` - Continuous Monitoring
|
||||
- **Purpose**: Continuous camera monitoring with periodic analysis
|
||||
- **Use Case**: Security monitoring, surveillance systems
|
||||
- **Features**:
|
||||
- Configurable analysis intervals
|
||||
- Real-time monitoring
|
||||
- Security-focused analysis
|
||||
- Graceful shutdown with Ctrl+C
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python camera-continuous.py
|
||||
```
|
||||
|
||||
### 3. `camera-multi-agent.py` - Multi-Agent Analysis
|
||||
- **Purpose**: Multiple specialized agents analyzing the same camera feed
|
||||
- **Use Case**: Comprehensive analysis from different perspectives
|
||||
- **Features**:
|
||||
- Security analysis agent
|
||||
- Object detection agent
|
||||
- Scene analysis agent
|
||||
- Parallel processing
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python camera-multi-agent.py
|
||||
```
|
||||
|
||||
### 4. `camera-video-analysis.py` - Video Recording & Analysis
|
||||
- **Purpose**: Record video segments and analyze temporal events
|
||||
- **Use Case**: Activity analysis, event detection
|
||||
- **Features**:
|
||||
- Video recording with configurable duration
|
||||
- Temporal event analysis
|
||||
- Timeline extraction
|
||||
- Automatic cleanup
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python camera-video-analysis.py
|
||||
```
|
||||
|
||||
## 🎯 Supported Input Types
|
||||
|
||||
- ✅ **Local Images**: `"camera_shot.jpg"`, `"webcam_capture.png"`
|
||||
- ✅ **Local Videos**: `"security_feed.mp4"`, `"recording.avi"`
|
||||
- ✅ **Image URLs**: `"https://example.com/live_feed.jpg"`
|
||||
- ✅ **Multiple Sources**: `["cam1.jpg", "cam2.jpg", "video.mp4"]`
|
||||
|
||||
## 🔧 Configuration Options
|
||||
|
||||
### Camera Settings
|
||||
```python
|
||||
camera_id = 0 # Default camera (change to 1, 2, etc. for other cameras)
|
||||
```
|
||||
|
||||
### Analysis Intervals
|
||||
```python
|
||||
analysis_interval = 10 # Seconds between analyses for continuous monitoring
|
||||
```
|
||||
|
||||
### Recording Duration
|
||||
```python
|
||||
recording_duration = 15 # Seconds for video recording
|
||||
```
|
||||
|
||||
## 💡 Integration Patterns
|
||||
|
||||
### 1. Real-time Processing
|
||||
```python
|
||||
# Capture frames periodically and process them as separate tasks
|
||||
def capture_and_analyze():
|
||||
cap = cv2.VideoCapture(0)
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
cv2.imwrite("temp_capture.jpg", frame)
|
||||
# Process with PraisonAI agent
|
||||
cap.release()
|
||||
```
|
||||
|
||||
### 2. Batch Analysis
|
||||
```python
|
||||
# Process multiple camera angles simultaneously
|
||||
task = Task(
|
||||
description="Analyze multiple camera feeds",
|
||||
agent=vision_agent,
|
||||
images=["cam1.jpg", "cam2.jpg", "cam3.jpg"]
|
||||
)
|
||||
```
|
||||
|
||||
### 3. Video Analysis
|
||||
```python
|
||||
# Save video segments and analyze them
|
||||
task = Task(
|
||||
description="Analyze this video for activities",
|
||||
agent=vision_agent,
|
||||
images=["security_footage.mp4"] # Video files work too
|
||||
)
|
||||
```
|
||||
|
||||
## 🔒 Security Considerations
|
||||
|
||||
- **Camera Permissions**: Ensure your application has camera access
|
||||
- **Privacy**: Be mindful of privacy when recording/analyzing
|
||||
- **Storage**: Clean up temporary files to avoid storage issues
|
||||
- **Access Control**: Implement proper access controls for camera systems
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Camera Not Found
|
||||
```python
|
||||
# Check available cameras
|
||||
for i in range(4): # Check first 4 camera indices
|
||||
cap = cv2.VideoCapture(i)
|
||||
if cap.isOpened():
|
||||
print(f"Camera {i} is available")
|
||||
cap.release()
|
||||
```
|
||||
|
||||
### Permission Issues
|
||||
- On Linux: Add user to `video` group
|
||||
- On macOS: Grant camera permissions in System Preferences
|
||||
- On Windows: Check camera privacy settings
|
||||
|
||||
### Performance Optimization
|
||||
- Reduce frame size for faster processing
|
||||
- Adjust analysis intervals based on requirements
|
||||
- Use parallel processing for multiple agents
|
||||
|
||||
## 📚 Related Documentation
|
||||
|
||||
- [Multimodal Features](../../docs/features/multimodal.mdx)
|
||||
- [Agent Documentation](../../docs/concepts/agents.mdx)
|
||||
- [Task Documentation](../../docs/concepts/tasks.mdx)
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Feel free to contribute additional camera integration examples or improvements to existing ones!
|
||||
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
Basic Camera Integration Example
|
||||
|
||||
This example demonstrates how to capture a single frame from a camera
|
||||
and analyze it using a PraisonAI vision agent.
|
||||
|
||||
Requirements:
|
||||
pip install praisonaiagents opencv-python
|
||||
|
||||
Usage:
|
||||
python camera-basic.py
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
"""
|
||||
|
||||
import cv2
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
|
||||
def capture_and_analyze():
|
||||
"""Capture a single frame from camera and analyze it"""
|
||||
|
||||
# Create vision agent
|
||||
vision_agent = Agent(
|
||||
name="CameraAnalyst",
|
||||
role="Camera Feed Analyzer",
|
||||
goal="Analyze camera captures in real-time",
|
||||
backstory="Expert in real-time visual analysis with computer vision skills",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Initialize camera (0 for default camera)
|
||||
cap = cv2.VideoCapture(0)
|
||||
|
||||
if not cap.isOpened():
|
||||
print("Error: Could not open camera")
|
||||
return None
|
||||
|
||||
try:
|
||||
# Capture frame
|
||||
ret, frame = cap.read()
|
||||
|
||||
if ret:
|
||||
# Save frame temporarily
|
||||
image_path = "temp_camera_capture.jpg"
|
||||
cv2.imwrite(image_path, frame)
|
||||
print(f"Frame captured and saved as {image_path}")
|
||||
|
||||
# Create analysis task
|
||||
task = Task(
|
||||
name="analyze_camera_feed",
|
||||
description="Analyze what you see in this camera capture. Identify objects, people, and activities.",
|
||||
expected_output="Detailed analysis of the camera content including objects, people, activities, and overall scene description",
|
||||
agent=vision_agent,
|
||||
images=[image_path]
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[vision_agent],
|
||||
tasks=[task],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
result = agents.start()
|
||||
|
||||
# Clean up temporary file
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
|
||||
return result
|
||||
|
||||
else:
|
||||
print("Error: Could not capture frame")
|
||||
return None
|
||||
|
||||
finally:
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
print("📸 Starting basic camera analysis...")
|
||||
print("Make sure your camera is connected and accessible")
|
||||
|
||||
result = capture_and_analyze()
|
||||
|
||||
if result:
|
||||
print("\n🔍 Analysis Results:")
|
||||
for task_id, task_result in result["task_results"].items():
|
||||
print(f"\nTask {task_id}:")
|
||||
print(task_result.raw)
|
||||
else:
|
||||
print("❌ Failed to capture and analyze camera feed")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,142 @@
|
||||
"""
|
||||
Continuous Camera Monitoring Example
|
||||
|
||||
This example demonstrates continuous camera monitoring with periodic analysis
|
||||
using PraisonAI vision agents. Perfect for security monitoring or real-time surveillance.
|
||||
|
||||
Requirements:
|
||||
pip install praisonaiagents opencv-python
|
||||
|
||||
Usage:
|
||||
python camera-continuous.py
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
"""
|
||||
|
||||
import cv2
|
||||
import time
|
||||
import os
|
||||
from datetime import datetime
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
|
||||
class ContinuousCameraMonitor:
|
||||
"""Continuous camera monitoring system"""
|
||||
|
||||
def __init__(self, camera_id=0, analysis_interval=10):
|
||||
"""
|
||||
Initialize camera monitor
|
||||
|
||||
Args:
|
||||
camera_id (int): Camera ID (0 for default)
|
||||
analysis_interval (int): Seconds between analyses
|
||||
"""
|
||||
self.camera_id = camera_id
|
||||
self.analysis_interval = analysis_interval
|
||||
self.running = False
|
||||
|
||||
# Create vision agent
|
||||
self.vision_agent = Agent(
|
||||
name="SecurityMonitor",
|
||||
role="Security Camera Analyst",
|
||||
goal="Monitor camera feeds for activities and security events",
|
||||
backstory="Expert security analyst with computer vision skills specialized in real-time monitoring",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
def capture_frame(self, cap):
|
||||
"""Capture a single frame from camera"""
|
||||
ret, frame = cap.read()
|
||||
if ret:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
filename = f"camera_capture_{timestamp}.jpg"
|
||||
cv2.imwrite(filename, frame)
|
||||
return filename
|
||||
return None
|
||||
|
||||
def analyze_frame(self, image_path):
|
||||
"""Analyze captured frame"""
|
||||
task = Task(
|
||||
name="monitor_camera_feed",
|
||||
description="""Monitor this camera feed for:
|
||||
1. Any people or unusual activities
|
||||
2. Objects that seem out of place
|
||||
3. Movement or changes in the scene
|
||||
4. Security-relevant events
|
||||
|
||||
Provide a brief but detailed security report.""",
|
||||
expected_output="Security analysis report with timestamp and observations",
|
||||
agent=self.vision_agent,
|
||||
images=[image_path]
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[self.vision_agent],
|
||||
tasks=[task],
|
||||
process="sequential",
|
||||
verbose=0 # Reduced verbosity for continuous monitoring
|
||||
)
|
||||
|
||||
return agents.start()
|
||||
|
||||
def start_monitoring(self):
|
||||
"""Start continuous monitoring"""
|
||||
print(f"🎥 Starting continuous camera monitoring...")
|
||||
print(f"📊 Analysis interval: {self.analysis_interval} seconds")
|
||||
print("🛑 Press Ctrl+C to stop")
|
||||
|
||||
cap = cv2.VideoCapture(self.camera_id)
|
||||
|
||||
if not cap.isOpened():
|
||||
print(f"❌ Error: Could not open camera {self.camera_id}")
|
||||
return
|
||||
|
||||
self.running = True
|
||||
|
||||
try:
|
||||
while self.running:
|
||||
# Capture frame
|
||||
image_path = self.capture_frame(cap)
|
||||
|
||||
if image_path:
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
print(f"\n⏰ {timestamp} - Analyzing camera feed...")
|
||||
|
||||
# Analyze frame
|
||||
result = self.analyze_frame(image_path)
|
||||
|
||||
# Display results
|
||||
if result and "task_results" in result:
|
||||
for task_id, task_result in result["task_results"].items():
|
||||
print(f"📋 Security Report: {task_result.raw}")
|
||||
|
||||
# Clean up temporary file
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
|
||||
# Wait for next analysis
|
||||
time.sleep(self.analysis_interval)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n🛑 Stopping camera monitoring...")
|
||||
finally:
|
||||
self.running = False
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
print("✅ Camera monitoring stopped")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
# Configuration
|
||||
camera_id = 0 # Default camera
|
||||
analysis_interval = 15 # Analyze every 15 seconds
|
||||
|
||||
# Create and start monitor
|
||||
monitor = ContinuousCameraMonitor(camera_id, analysis_interval)
|
||||
monitor.start_monitoring()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,164 @@
|
||||
"""
|
||||
Multi-Agent Camera Analysis Example
|
||||
|
||||
This example demonstrates using multiple specialized agents to analyze
|
||||
camera feeds from different perspectives (security, object detection, etc.).
|
||||
|
||||
Requirements:
|
||||
pip install praisonaiagents opencv-python
|
||||
|
||||
Usage:
|
||||
python camera-multi-agent.py
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
"""
|
||||
|
||||
import cv2
|
||||
import os
|
||||
from datetime import datetime
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
|
||||
def capture_camera_frame(camera_id=0):
|
||||
"""Capture a frame from camera"""
|
||||
cap = cv2.VideoCapture(camera_id)
|
||||
|
||||
if not cap.isOpened():
|
||||
print(f"Error: Could not open camera {camera_id}")
|
||||
return None
|
||||
|
||||
ret, frame = cap.read()
|
||||
cap.release()
|
||||
|
||||
if ret:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
image_path = f"camera_frame_{timestamp}.jpg"
|
||||
cv2.imwrite(image_path, frame)
|
||||
return image_path
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def analyze_with_multiple_agents():
|
||||
"""Analyze camera feed using multiple specialized agents"""
|
||||
|
||||
# Capture frame
|
||||
image_path = capture_camera_frame()
|
||||
if not image_path:
|
||||
print("Failed to capture camera frame")
|
||||
return None
|
||||
|
||||
print(f"📸 Captured frame: {image_path}")
|
||||
|
||||
# Create specialized agents
|
||||
security_agent = Agent(
|
||||
name="SecurityExpert",
|
||||
role="Security Specialist",
|
||||
goal="Identify security threats and suspicious activities",
|
||||
backstory="Expert security analyst with years of experience in surveillance and threat detection",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
object_detector = Agent(
|
||||
name="ObjectDetector",
|
||||
role="Object Recognition Specialist",
|
||||
goal="Identify and catalog all objects in the scene",
|
||||
backstory="Computer vision expert specializing in object detection and classification",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
scene_analyst = Agent(
|
||||
name="SceneAnalyst",
|
||||
role="Scene Understanding Expert",
|
||||
goal="Provide comprehensive scene analysis and context",
|
||||
backstory="Environmental analyst expert in understanding spatial relationships and scene context",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create specialized tasks
|
||||
security_task = Task(
|
||||
name="security_analysis",
|
||||
description="""Analyze this camera feed for security concerns:
|
||||
1. Identify any people and their activities
|
||||
2. Look for suspicious behavior or unauthorized access
|
||||
3. Check for potential security threats
|
||||
4. Assess overall security status of the area""",
|
||||
expected_output="Detailed security assessment with threat level and recommendations",
|
||||
agent=security_agent,
|
||||
images=[image_path]
|
||||
)
|
||||
|
||||
object_task = Task(
|
||||
name="object_detection",
|
||||
description="""Identify and catalog all objects in this image:
|
||||
1. List all visible objects with their approximate locations
|
||||
2. Identify any vehicles, electronics, or valuable items
|
||||
3. Note any objects that seem out of place
|
||||
4. Provide a comprehensive inventory""",
|
||||
expected_output="Detailed object inventory with locations and descriptions",
|
||||
agent=object_detector,
|
||||
images=[image_path]
|
||||
)
|
||||
|
||||
scene_task = Task(
|
||||
name="scene_analysis",
|
||||
description="""Provide comprehensive scene analysis:
|
||||
1. Describe the overall environment and setting
|
||||
2. Analyze lighting conditions and time of day
|
||||
3. Assess the general activity level and atmosphere
|
||||
4. Provide context about what type of location this appears to be""",
|
||||
expected_output="Complete scene description with environmental context",
|
||||
agent=scene_analyst,
|
||||
images=[image_path]
|
||||
)
|
||||
|
||||
# Run multi-agent analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[security_agent, object_detector, scene_analyst],
|
||||
tasks=[security_task, object_task, scene_task],
|
||||
process="parallel", # Run all analyses in parallel
|
||||
verbose=1
|
||||
)
|
||||
|
||||
result = agents.start()
|
||||
|
||||
# Clean up temporary file
|
||||
if os.path.exists(image_path):
|
||||
os.remove(image_path)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
print("🎯 Starting multi-agent camera analysis...")
|
||||
print("📋 This will analyze the camera feed from multiple perspectives")
|
||||
|
||||
result = analyze_with_multiple_agents()
|
||||
|
||||
if result:
|
||||
print("\n" + "="*60)
|
||||
print("📊 MULTI-AGENT ANALYSIS RESULTS")
|
||||
print("="*60)
|
||||
|
||||
# Display results by agent
|
||||
agent_names = {
|
||||
"security_analysis": "🛡️ SECURITY ANALYSIS",
|
||||
"object_detection": "🔍 OBJECT DETECTION",
|
||||
"scene_analysis": "🌍 SCENE ANALYSIS"
|
||||
}
|
||||
|
||||
for task_id, task_result in result["task_results"].items():
|
||||
print(f"\n{agent_names.get(task_id, f'Task {task_id}')}:")
|
||||
print("-" * 40)
|
||||
print(task_result.raw)
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("✅ Multi-agent analysis complete!")
|
||||
else:
|
||||
print("❌ Failed to complete camera analysis")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,206 @@
|
||||
"""
|
||||
Camera Video Recording and Analysis Example
|
||||
|
||||
This example demonstrates recording video segments from camera
|
||||
and analyzing them using PraisonAI vision agents.
|
||||
|
||||
Requirements:
|
||||
pip install praisonaiagents opencv-python
|
||||
|
||||
Usage:
|
||||
python camera-video-analysis.py
|
||||
|
||||
Environment Variables:
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
"""
|
||||
|
||||
import cv2
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
|
||||
class CameraVideoAnalyzer:
|
||||
"""Camera video recording and analysis system"""
|
||||
|
||||
def __init__(self, camera_id=0):
|
||||
"""
|
||||
Initialize video analyzer
|
||||
|
||||
Args:
|
||||
camera_id (int): Camera ID (0 for default)
|
||||
"""
|
||||
self.camera_id = camera_id
|
||||
|
||||
# Create video analysis agent
|
||||
self.video_agent = Agent(
|
||||
name="VideoAnalyst",
|
||||
role="Video Content Analyzer",
|
||||
goal="Analyze video content for activities, objects, and events",
|
||||
backstory="Expert in video analysis and temporal event detection with computer vision expertise",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
def record_video_segment(self, duration_seconds=10):
|
||||
"""
|
||||
Record a video segment from camera
|
||||
|
||||
Args:
|
||||
duration_seconds (int): Length of video to record
|
||||
|
||||
Returns:
|
||||
str: Path to recorded video file or None if failed
|
||||
"""
|
||||
cap = cv2.VideoCapture(self.camera_id)
|
||||
|
||||
if not cap.isOpened():
|
||||
print(f"Error: Could not open camera {self.camera_id}")
|
||||
return None
|
||||
|
||||
# Get video properties
|
||||
fps = int(cap.get(cv2.CAP_PROP_FPS)) or 30
|
||||
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
|
||||
# Setup video writer
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
video_path = f"camera_recording_{timestamp}.mp4"
|
||||
|
||||
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
|
||||
out = cv2.VideoWriter(video_path, fourcc, fps, (width, height))
|
||||
|
||||
print(f"🎬 Recording video for {duration_seconds} seconds...")
|
||||
print(f"📹 Resolution: {width}x{height}, FPS: {fps}")
|
||||
|
||||
start_time = time.time()
|
||||
frame_count = 0
|
||||
|
||||
try:
|
||||
while (time.time() - start_time) < duration_seconds:
|
||||
ret, frame = cap.read()
|
||||
|
||||
if ret:
|
||||
out.write(frame)
|
||||
frame_count += 1
|
||||
|
||||
# Show recording indicator
|
||||
if frame_count % fps == 0: # Update every second
|
||||
elapsed = int(time.time() - start_time)
|
||||
remaining = duration_seconds - elapsed
|
||||
print(f"⏱️ Recording... {remaining}s remaining")
|
||||
else:
|
||||
break
|
||||
|
||||
finally:
|
||||
cap.release()
|
||||
out.release()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
if frame_count > 0:
|
||||
print(f"✅ Video recorded: {video_path} ({frame_count} frames)")
|
||||
return video_path
|
||||
else:
|
||||
print("❌ Failed to record video")
|
||||
if os.path.exists(video_path):
|
||||
os.remove(video_path)
|
||||
return None
|
||||
|
||||
def analyze_video(self, video_path):
|
||||
"""
|
||||
Analyze recorded video
|
||||
|
||||
Args:
|
||||
video_path (str): Path to video file
|
||||
|
||||
Returns:
|
||||
dict: Analysis results
|
||||
"""
|
||||
task = Task(
|
||||
name="analyze_video_content",
|
||||
description="""Analyze this video recording and provide:
|
||||
1. Summary of main activities and events observed
|
||||
2. Timeline of key moments or changes
|
||||
3. Identification of people, objects, and movements
|
||||
4. Any notable interactions or behaviors
|
||||
5. Overall assessment of what happened in the video
|
||||
|
||||
Focus on providing a comprehensive temporal analysis.""",
|
||||
expected_output="Detailed video analysis with timeline and event description",
|
||||
agent=self.video_agent,
|
||||
images=[video_path] # PraisonAI supports video files in images parameter
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[self.video_agent],
|
||||
tasks=[task],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
return agents.start()
|
||||
|
||||
def record_and_analyze(self, duration=10):
|
||||
"""
|
||||
Record video and analyze it
|
||||
|
||||
Args:
|
||||
duration (int): Recording duration in seconds
|
||||
"""
|
||||
# Record video
|
||||
video_path = self.record_video_segment(duration)
|
||||
|
||||
if not video_path:
|
||||
return None
|
||||
|
||||
print(f"\n🔍 Analyzing recorded video...")
|
||||
|
||||
# Analyze video
|
||||
result = self.analyze_video(video_path)
|
||||
|
||||
# Clean up video file
|
||||
if os.path.exists(video_path):
|
||||
os.remove(video_path)
|
||||
print(f"🗑️ Cleaned up temporary video file")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function"""
|
||||
print("🎥 Camera Video Recording and Analysis")
|
||||
print("=" * 50)
|
||||
|
||||
# Configuration
|
||||
camera_id = 0
|
||||
recording_duration = 15 # seconds
|
||||
|
||||
print(f"📹 Camera: {camera_id}")
|
||||
print(f"⏱️ Recording Duration: {recording_duration} seconds")
|
||||
print("\nMake sure your camera is connected and accessible")
|
||||
print("The system will record a video segment and then analyze it")
|
||||
|
||||
input("\nPress Enter to start recording...")
|
||||
|
||||
# Create analyzer and run
|
||||
analyzer = CameraVideoAnalyzer(camera_id)
|
||||
result = analyzer.record_and_analyze(recording_duration)
|
||||
|
||||
if result:
|
||||
print("\n" + "="*60)
|
||||
print("📊 VIDEO ANALYSIS RESULTS")
|
||||
print("="*60)
|
||||
|
||||
for task_id, task_result in result["task_results"].items():
|
||||
print(f"\nTask: {task_id}")
|
||||
print("-" * 40)
|
||||
print(task_result.raw)
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("✅ Video analysis complete!")
|
||||
else:
|
||||
print("❌ Failed to record and analyze video")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -205,6 +205,20 @@ class LLM:
|
||||
}
|
||||
logging.debug(f"LLM instance initialized with: {json.dumps(debug_info, indent=2, default=str)}")
|
||||
|
||||
def _needs_system_message_skip(self) -> bool:
|
||||
"""Check if this model requires skipping system messages"""
|
||||
if not self.model:
|
||||
return False
|
||||
|
||||
# Only skip for specific legacy o1 models that don't support system messages
|
||||
legacy_o1_models = [
|
||||
"o1-preview", # 2024-09-12 version
|
||||
"o1-mini", # 2024-09-12 version
|
||||
"o1-mini-2024-09-12" # Explicit dated version
|
||||
]
|
||||
|
||||
return self.model in legacy_o1_models
|
||||
|
||||
def get_response(
|
||||
self,
|
||||
prompt: Union[str, List[Dict]],
|
||||
@@ -320,7 +334,9 @@ class LLM:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
if chat_history:
|
||||
messages.extend(chat_history)
|
||||
@@ -867,7 +883,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
if chat_history:
|
||||
messages.extend(chat_history)
|
||||
@@ -1517,7 +1535,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
@@ -1623,7 +1643,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
# Build messages list
|
||||
messages = []
|
||||
if system_prompt:
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
# Skip system messages for legacy o1 models as they don't support them
|
||||
if not self._needs_system_message_skip():
|
||||
messages.append({"role": "system", "content": system_prompt})
|
||||
|
||||
# Add prompt to messages
|
||||
if isinstance(prompt, list):
|
||||
|
||||
@@ -3,8 +3,8 @@ class Praisonai < Formula
|
||||
|
||||
desc "AI tools for various AI applications"
|
||||
homepage "https://github.com/MervinPraison/PraisonAI"
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.19.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.19.tar.gz | shasum -a 256`.split.first
|
||||
url "https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.20.tar.gz"
|
||||
sha256 `curl -sL https://github.com/MervinPraison/PraisonAI/archive/refs/tags/v2.2.20.tar.gz | shasum -a 256`.split.first
|
||||
license "MIT"
|
||||
|
||||
depends_on "[email protected]"
|
||||
|
||||
@@ -3,4 +3,4 @@ import os
|
||||
os.environ["OTEL_SDK_DISABLED"] = "true"
|
||||
os.environ["EC_TELEMETRY"] = "false"
|
||||
from .cli import PraisonAI
|
||||
from .version import __version__
|
||||
from .version import __version__
|
||||
@@ -39,9 +39,6 @@ LOG_EVENT_TYPES = [
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
if not OPENAI_API_KEY:
|
||||
raise ValueError('Missing the OpenAI API key. Please set it in the .env file.')
|
||||
|
||||
# Set up logging
|
||||
logger = logging.getLogger(__name__)
|
||||
log_level = os.getenv("LOGLEVEL", "INFO").upper()
|
||||
@@ -266,6 +263,9 @@ def setup_public_url(port):
|
||||
|
||||
def run_server(port: int, use_public: bool = False):
|
||||
"""Run the FastAPI server using uvicorn."""
|
||||
if not OPENAI_API_KEY:
|
||||
raise ValueError('Missing the OpenAI API key. Please set it in the .env file or configure it through the GUI.')
|
||||
|
||||
if use_public:
|
||||
setup_public_url(port)
|
||||
else:
|
||||
|
||||
@@ -54,7 +54,7 @@ except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
from crewai import Agent, Task, Crew
|
||||
import crewai
|
||||
CREWAI_AVAILABLE = True
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -147,6 +147,21 @@ class PraisonAI:
|
||||
"""
|
||||
return self.main()
|
||||
|
||||
def read_stdin_if_available(self):
|
||||
"""
|
||||
Read from stdin if it's available (when data is piped in).
|
||||
Returns the stdin content or None if no piped input is available.
|
||||
"""
|
||||
try:
|
||||
# Check if stdin is not a terminal (i.e., has piped input)
|
||||
if not sys.stdin.isatty():
|
||||
stdin_content = sys.stdin.read().strip()
|
||||
return stdin_content if stdin_content else None
|
||||
except Exception:
|
||||
# If there's any error reading stdin, ignore it
|
||||
pass
|
||||
return None
|
||||
|
||||
def main(self):
|
||||
"""
|
||||
The main function of the PraisonAI object. It parses the command-line arguments,
|
||||
@@ -164,21 +179,41 @@ class PraisonAI:
|
||||
|
||||
self.framework = args.framework or self.framework
|
||||
|
||||
# Check for piped input from stdin
|
||||
stdin_input = self.read_stdin_if_available()
|
||||
|
||||
if args.command:
|
||||
if args.command.startswith("tests.test") or args.command.startswith("tests/test"): # Argument used for testing purposes
|
||||
print("test")
|
||||
return "test"
|
||||
else:
|
||||
self.agent_file = args.command
|
||||
# If stdin input is available, append it to the command
|
||||
if stdin_input:
|
||||
combined_prompt = f"{args.command} {stdin_input}"
|
||||
result = self.handle_direct_prompt(combined_prompt)
|
||||
print(result)
|
||||
return result
|
||||
else:
|
||||
self.agent_file = args.command
|
||||
elif hasattr(args, 'direct_prompt') and args.direct_prompt:
|
||||
# Only handle direct prompt if agent_file wasn't explicitly set in constructor
|
||||
if original_agent_file == "agents.yaml": # Default value, so safe to use direct prompt
|
||||
result = self.handle_direct_prompt(args.direct_prompt)
|
||||
# If stdin input is available, append it to the direct prompt
|
||||
prompt = args.direct_prompt
|
||||
if stdin_input:
|
||||
prompt = f"{args.direct_prompt} {stdin_input}"
|
||||
result = self.handle_direct_prompt(prompt)
|
||||
print(result)
|
||||
return result
|
||||
else:
|
||||
# Agent file was explicitly set, ignore direct prompt and use the file
|
||||
pass
|
||||
elif stdin_input:
|
||||
# If only stdin input is provided (no command), use it as direct prompt
|
||||
if original_agent_file == "agents.yaml": # Default value, so safe to use stdin as prompt
|
||||
result = self.handle_direct_prompt(stdin_input)
|
||||
print(result)
|
||||
return result
|
||||
# If no command or direct_prompt, preserve agent_file from constructor (don't overwrite)
|
||||
|
||||
if args.deploy:
|
||||
@@ -248,17 +283,29 @@ class PraisonAI:
|
||||
print("All packages installed")
|
||||
return
|
||||
|
||||
# Check if conda is available and environment exists
|
||||
conda_available = True
|
||||
conda_env_exists = False
|
||||
|
||||
try:
|
||||
result = subprocess.check_output(['conda', 'env', 'list'])
|
||||
if 'praison_env' in result.decode('utf-8'):
|
||||
print("Conda environment 'praison_env' found.")
|
||||
conda_env_exists = True
|
||||
else:
|
||||
raise subprocess.CalledProcessError(1, 'grep')
|
||||
except subprocess.CalledProcessError:
|
||||
print("Conda environment 'praison_env' not found. Setting it up...")
|
||||
from praisonai.setup.setup_conda_env import main as setup_conda_main
|
||||
setup_conda_main()
|
||||
print("All packages installed.")
|
||||
print("Conda environment 'praison_env' not found. Setting it up...")
|
||||
from praisonai.setup.setup_conda_env import main as setup_conda_main
|
||||
setup_conda_main()
|
||||
print("All packages installed.")
|
||||
# Check again if environment was created successfully
|
||||
try:
|
||||
result = subprocess.check_output(['conda', 'env', 'list'])
|
||||
conda_env_exists = 'praison_env' in result.decode('utf-8')
|
||||
except subprocess.CalledProcessError:
|
||||
conda_env_exists = False
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
print("Conda not available or failed to check environment.")
|
||||
conda_available = False
|
||||
|
||||
train_args = sys.argv[2:] # Get all arguments after 'train'
|
||||
|
||||
@@ -278,7 +325,18 @@ class PraisonAI:
|
||||
env = os.environ.copy()
|
||||
env['PYTHONUNBUFFERED'] = '1'
|
||||
|
||||
stream_subprocess(['conda', 'run', '--no-capture-output', '--name', 'praison_env', 'python', '-u', train_script_path, 'train'], env=env)
|
||||
# Try conda run first, fallback to direct Python execution
|
||||
if conda_available and conda_env_exists:
|
||||
try:
|
||||
print("Attempting to run training using conda environment...")
|
||||
stream_subprocess(['conda', 'run', '--no-capture-output', '--name', 'praison_env', 'python', '-u', train_script_path, 'train'], env=env)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Conda run failed with error: {e}")
|
||||
print("Falling back to direct Python execution...")
|
||||
stream_subprocess([sys.executable, '-u', train_script_path, 'train'], env=env)
|
||||
else:
|
||||
print("Conda environment not available, using direct Python execution...")
|
||||
stream_subprocess([sys.executable, '-u', train_script_path, 'train'], env=env)
|
||||
return
|
||||
|
||||
if args.auto or self.auto:
|
||||
@@ -500,6 +558,7 @@ class PraisonAI:
|
||||
result = agent.start(prompt)
|
||||
return result
|
||||
elif CREWAI_AVAILABLE:
|
||||
from crewai import Agent, Task, Crew
|
||||
agent_config = {
|
||||
"name": "DirectAgent",
|
||||
"role": "Assistant",
|
||||
|
||||
@@ -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.2.19 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.2.20 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "PraisonAI"
|
||||
version = "2.2.19"
|
||||
version = "2.2.20"
|
||||
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 = ""
|
||||
@@ -19,6 +19,11 @@ dependencies = [
|
||||
"mcp>=1.6.0",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
praisonai = "praisonai.__main__:main"
|
||||
setup-conda-env = "praisonai.setup.setup_conda_env:main"
|
||||
praisonai-call = "praisonai.api.call:main"
|
||||
|
||||
[project.optional-dependencies]
|
||||
ui = [
|
||||
"chainlit==2.5.5",
|
||||
@@ -89,7 +94,7 @@ autogen = ["pyautogen>=0.2.19", "praisonai-tools>=0.0.15", "crewai"]
|
||||
|
||||
[tool.poetry]
|
||||
name = "PraisonAI"
|
||||
version = "2.2.19"
|
||||
version = "2.2.20"
|
||||
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 = ""
|
||||
|
||||
@@ -43,7 +43,7 @@ class TestPraisonAIFramework(unittest.TestCase):
|
||||
|
||||
@pytest.mark.real
|
||||
def test_main_with_built_in_tool(self):
|
||||
praisonai = PraisonAI(agent_file="tests/built-in-tools-agents.yaml")
|
||||
praisonai = PraisonAI(agent_file="tests/inbuilt-tool-agents.yaml")
|
||||
result = praisonai.run()
|
||||
print(f"Result: {result}")
|
||||
self.assertIsNotNone(result)
|
||||
@@ -77,7 +77,10 @@ class TestPraisonAICommandLine(unittest.TestCase):
|
||||
command = "praisonai --framework autogen --init \"create a 2-agent team to write a simple python game\""
|
||||
result = self.run_command(command)
|
||||
print(f"Result: {result}")
|
||||
self.assertIn('created successfully', result)
|
||||
# Check for success indicator in the output
|
||||
success_phrases = ['created successfully', 'agents.yaml created', 'File created']
|
||||
found_success = any(phrase in result for phrase in success_phrases)
|
||||
self.assertTrue(found_success, f"No success message found. Expected one of {success_phrases}. Last 1000 chars: {result[-1000:]}")
|
||||
|
||||
class TestExamples(unittest.TestCase):
|
||||
def test_advanced_example(self):
|
||||
|
||||
@@ -5,10 +5,9 @@ Test script for database_config module functionality.
|
||||
|
||||
import sys
|
||||
import os
|
||||
sys.path.insert(0, 'src/praisonai/praisonai/ui')
|
||||
|
||||
# Test the database_config module
|
||||
from database_config import should_force_sqlite, get_database_url_with_sqlite_override, get_database_config_for_sqlalchemy
|
||||
# Import from the proper module path
|
||||
from praisonai.ui.database_config import should_force_sqlite, get_database_url_with_sqlite_override, get_database_config_for_sqlalchemy
|
||||
|
||||
def test_database_config():
|
||||
print("Testing database_config utilities...")
|
||||
|
||||
Generated
+1
-1
@@ -3931,7 +3931,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "praisonai"
|
||||
version = "2.2.19"
|
||||
version = "2.2.20"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "instructor" },
|
||||
|
||||
Reference in new issue
Block a user