Compare commits

...
38 Commits
Author SHA1 Message Date
Mervin Praison 89f48cf7a2 Merge pull request #553 from MervinPraison/develop
chore: update PraisonAI version to 2.2.20 across Dockerfiles and docu…
2025-05-30 14:16:47 +01:00
MervinPraison 97fb7fdd52 chore: update PraisonAI version to 2.2.20 across Dockerfiles and documentation
- Updated the version of PraisonAI from 2.2.19 to 2.2.20 in all relevant Dockerfiles.
- Adjusted README and local development documentation to reflect the new version.
- Ensured consistency in versioning across all instances where PraisonAI is referenced.
2025-05-30 14:16:19 +01:00
Mervin Praison ea4cb42324 Merge pull request #552 from MervinPraison/claude/issue-115-20250530_125352
fix: resolve ForwardRef TypeError for praisonai code command
2025-05-30 14:14:11 +01:00
Mervin Praison 71c5b929b7 Merge pull request #551 from MervinPraison/develop
Develop
2025-05-30 13:57:04 +01:00
claude[bot]andMervinPraison c9edf19907 fix: resolve ForwardRef TypeError for praisonai code command
Fixes #115

Resolves TypeError: ForwardRef._evaluate() missing recursive_guard argument when running `praisonai code`.

## Changes
- Moved crewai import from module level to conditional import in handle_direct_prompt
- The `code` command doesn't need crewai, only chainlit and other UI dependencies
- Follows existing pattern for optional dependencies

## Testing
- `praisonai code` now works without requiring crewai installation
- Direct prompt functionality still works when crewai is available

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 12:56:57 +00:00
MervinPraison 6cdc79f4a2 fix: update import path for database_config module in unit tests
- Adjusted the import statement in test_database_config.py to reference the correct module path.
- Ensures that the tests can locate the database_config functionalities properly.
2025-05-30 13:56:49 +01:00
MervinPraison fdda350b72 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 13:33:56 +01:00
Mervin Praison 85f748d5d1 Merge pull request #549 from DhivyaBharathy-web/add-langchain-praisonai-agents-notebook
Add LangChain + PraisonAI agents Colab notebook
2025-05-30 13:33:50 +01:00
MervinPraison bf24548598 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 13:33:24 +01:00
Mervin Praison a1622a2a79 Merge pull request #550 from MervinPraison/claude/issue-17-20250530_113738
feat: add piped input support to CLI
2025-05-30 13:32:57 +01:00
DhivyaBharathy-web 209faff03c Add LangChain + PraisonAI agents Colab notebook 2025-05-30 11:49:03 +00:00
Mervin Praison ad67089813 Merge pull request #548 from MervinPraison/claude/issue-201-20250530_113510
fix: move OpenAI API key validation from import-time to runtime
2025-05-30 12:41:49 +01:00
claude[bot]andMervinPraison 3e44eadd37 feat: add piped input support to CLI
Implement piped command functionality similar to fabric project, allowing:
- echo "content" | praisonai "command"
- cat file.txt | praisonai --auto "task"
- echo "question" | praisonai

Added read_stdin_if_available() method to detect and read piped input,
and modified main() to handle piped content in three scenarios:
1. Command + piped input
2. Direct prompt + piped input  
3. Only piped input

Fixes #17

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:39:42 +00:00
claude[bot]andMervinPraison 764e9aa838 fix: move OpenAI API key validation from import-time to runtime in call.py
- Removes import-time API key requirement that prevented GUI startup
- Moves validation to run_server() function where it's actually needed
- Allows PraisonAI to start without OpenAI API key for non-voice features
- Users can now configure API key through existing GUI interfaces
- Follows existing codebase patterns for conditional feature validation

Fixes #201

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:39:28 +00:00
Mervin Praison ccfc92564e Merge pull request #547 from MervinPraison/claude/issue-140-20250529_041935
fix: add fallback mechanism for conda run failure in training
2025-05-30 12:33:06 +01:00
MervinPraison 1f61000922 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:30:26 +01:00
Mervin Praison 2164f3e658 Merge pull request #546 from MervinPraison/claude/issue-190-20250530_111525
fix: add console scripts to project.scripts section for pip compatibility
2025-05-30 12:30:18 +01:00
MervinPraison 739a9ff8b5 docker 2025-05-30 12:28:49 +01:00
MervinPraison dbe63cbbc9 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:27:33 +01:00
Mervin Praison f4bff11e83 Merge pull request #545 from MervinPraison/claude/issue-130-20250530_105428
feat: implement comprehensive Docker support and package publishing for issue #130
2025-05-30 12:27:23 +01:00
Mervin Praison 6552f61322 Update __init__.py 2025-05-30 12:26:57 +01:00
Mervin Praison d5d898ff1b Update __init__.py 2025-05-30 12:26:15 +01:00
Mervin Praison 4df8d122fc Update __init__.py 2025-05-30 12:25:51 +01:00
Mervin Praison 766e5789e3 Update __init__.py 2025-05-30 12:25:14 +01:00
Mervin Praison f9585e83cb Delete src/praisonai/praisonai/inc/directory_manager.py 2025-05-30 12:24:57 +01:00
claude[bot]andMervinPraison e019bab987 fix: address critical security and implementation issues
- Remove automatic directory initialization on package import to prevent unexpected file operations
- Add DOCKER_CONTAINER=true environment variable to all Dockerfiles
- Fix hardcoded password security issue in docker-compose.dev.yml
- Prevent api.py overwrite in main Dockerfile by checking if file exists
- Use non-editable pip install in production Dockerfile for praisonaiagents
- Move package installations from runtime commands to Dockerfile build stage for better efficiency

These fixes address the critical issues identified in the code review while maintaining the core functionality.

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:20:27 +00:00
claude[bot]andMervinPraison 54072a1d55 fix: add console scripts to project.scripts section for pip compatibility
- Add [project.scripts] section with praisonai, setup-conda-env, and praisonai-call entry points
- Fixes issue where praisonai command was not found when installing with pip instead of Poetry
- Entry points were only defined in [tool.poetry.scripts] which pip ignores
- Maintains compatibility with both pip and Poetry installation methods

Fixes #190

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:17:09 +00:00
Mervin Praison 16ddcb8644 Merge pull request #544 from MervinPraison/claude/issue-246-20250530_105609
fix: add targeted o1 model support for system messages
2025-05-30 12:06:16 +01:00
MervinPraison e0b9739b66 Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 12:04:03 +01:00
claude[bot]andMervinPraison 1bb6c8ca61 fix: add targeted o1 model support for system messages
- Add `_needs_system_message_skip()` method to detect legacy o1 models
- Skip system messages only for specific models: o1-preview, o1-mini, o1-mini-2024-09-12
- Update all 4 system message handling locations in LLM class
- Maintains backward compatibility for all other models
- Fixes 400 error for legacy o1 models that don't support system messages

Fixes #246

Co-authored-by: MervinPraison <[email protected]>
2025-05-30 11:03:18 +00:00
claude[bot]andMervinPraison a242a26353 feat: implement directory management solution for issue #130
- Add DirectoryManager class to organize files in ~/.praison/
- Automatic migration of existing configuration files from root
- Environment variable management for proper config paths
- Solves directory clutter issue (chainlit.md, .chainlit, public)

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:42 +00:00
claude[bot]andMervinPraison ff4f63fc54 feat: add Docker documentation and development setup
- Comprehensive Docker setup guide and documentation
- Environment template for easy configuration
- Development Docker Compose with hot reload
- Interactive quick-start script for user convenience

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:35 +00:00
claude[bot]andMervinPraison 48707686f0 feat: update Docker configurations for improved multi-service setup
- Add new praisonaiagents Dockerfile
- Update docker-compose.yml with multi-service orchestration
- Align versions across all Dockerfiles
- Add directory management environment variables
- Support for ~/.praison/ configuration directory

Co-Authored-By: MervinPraison <[email protected]>
2025-05-30 11:01:23 +00:00
MervinPraison 1a414989bf Merge branch 'main' of https://github.com/MervinPraison/PraisonAI into develop 2025-05-30 11:59:17 +01:00
Mervin Praison 141535c160 Merge pull request #543 from MervinPraison/claude/issue-238-20250528_161801
feat: add camera integration examples and documentation
2025-05-30 11:58:29 +01:00
MervinPraison 6911d6ad64 fix: Update import path for database_config module in unit tests
- Adjusted the sys.path in test_database_config.py to correctly locate the database_config module.
- Ensured compatibility with the module's new location for improved test functionality.
2025-05-30 11:51:29 +01:00
claude[bot]andMervinPraison ba5af94dcb fix: add fallback mechanism for conda run failure in training
- Add robust conda environment detection and setup validation
- Implement fallback to direct Python execution when conda fails
- Maintain backward compatibility while improving reliability
- Handle cases where conda is not available or environment setup fails

Fixes #140

Co-authored-by: MervinPraison <[email protected]>
2025-05-29 04:20:59 +00:00
claude[bot]andMervinPraison 955a05be59 feat: add camera integration examples and documentation
- Add comprehensive camera integration examples in examples/python/camera/
  - camera-basic.py: Single frame capture and analysis
  - camera-continuous.py: Continuous monitoring system
  - camera-multi-agent.py: Multi-agent parallel analysis
  - camera-video-analysis.py: Video recording and temporal analysis
  - README.md: Complete documentation for all examples

- Add camera integration documentation in docs/features/camera-integration.mdx
  - Complete integration patterns and use cases
  - Configuration options and best practices
  - Troubleshooting guide and security considerations
  - Links to example code

- Update docs/mint.json to include camera integration in navigation

Addresses issue #238 regarding multimodel agent camera input

Co-authored-by: MervinPraison <[email protected]>
2025-05-28 16:22:02 +00:00
32 changed files with 2697 additions and 48 deletions

No files matched your search

+53
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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"]
+32
View File
@@ -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
View File
@@ -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"]
+265
View File
@@ -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.
+184
View File
@@ -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
+81 -3
View File
@@ -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
+289
View File
@@ -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
+1 -1
View File
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
file.write(&#34;FROM python:3.11-slim\n&#34;)
file.write(&#34;WORKDIR /app\n&#34;)
file.write(&#34;COPY . .\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.2.19 gunicorn markdown\n&#34;)
file.write(&#34;RUN pip install flask praisonai==2.2.20 gunicorn markdown\n&#34;)
file.write(&#34;EXPOSE 8080\n&#34;)
file.write(&#39;CMD [&#34;gunicorn&#34;, &#34;-b&#34;, &#34;0.0.0.0:8080&#34;, &#34;api:app&#34;]\n&#39;)
+1 -1
View File
@@ -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
+423
View File
@@ -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
View File
@@ -143,7 +143,8 @@
"features/mathagent",
"features/structured",
"features/callbacks",
"features/chat-with-pdf"
"features/chat-with-pdf",
"features/camera-integration"
]
},
{
+1 -1
View File
@@ -155,7 +155,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
COPY . .
RUN pip install flask praisonai==2.2.19 watchdog
RUN pip install flask praisonai==2.2.20 watchdog
EXPOSE 5555
+1 -1
View File
@@ -208,7 +208,7 @@ To facilitate local development with live reload, you can use Docker. Follow the
COPY . .
RUN pip install flask praisonai==2.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
}
+173
View File
@@ -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!
+102
View File
@@ -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()
+142
View File
@@ -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):
+2 -2
View File
@@ -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]"
+1 -1
View File
@@ -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__
+3 -3
View File
@@ -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:
+69 -10
View File
@@ -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",
+1 -1
View File
@@ -56,7 +56,7 @@ class CloudDeployer:
file.write("FROM python:3.11-slim\n")
file.write("WORKDIR /app\n")
file.write("COPY . .\n")
file.write("RUN pip install flask praisonai==2.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')
+7 -2
View File
@@ -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 = ""
+5 -2
View File
@@ -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...")
+1 -1
View File
@@ -3931,7 +3931,7 @@ wheels = [
[[package]]
name = "praisonai"
version = "2.2.19"
version = "2.2.20"
source = { editable = "." }
dependencies = [
{ name = "instructor" },