Compare commits

..
1022 changed files with 20466 additions and 203560 deletions

No files matched your search

-2
View File
@@ -1,2 +0,0 @@
patreon: MervinPraison
ko_fi: MervinPraison
-37
View File
@@ -1,37 +0,0 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@beta
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
-44
View File
@@ -1,44 +0,0 @@
name: Daily Publish Docker
on:
push:
branches:
- main
schedule:
- cron: '0 0 * * *'
jobs:
check-and-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Check last commit time
id: check_commit
run: |
last_commit_time=$(git log -1 --format=%ct)
current_time=$(date +%s)
time_diff=$((current_time - last_commit_time))
if [ $time_diff -ge 120 ] && [ $time_diff -lt 240 ]; then
echo "should_run=true" >> $GITHUB_OUTPUT
else
echo "should_run=false" >> $GITHUB_OUTPUT
fi
- name: Set up Docker Buildx
if: steps.check_commit.outputs.should_run == 'true'
uses: docker/setup-buildx-action@v1
- name: Log in to the GitHub Container Registry
if: steps.check_commit.outputs.should_run == 'true'
run: echo ${{ secrets.GH_TOKEN }} | docker login ghcr.io -u USERNAME --password-stdin
- name: Build and push Docker image
if: steps.check_commit.outputs.should_run == 'true'
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ghcr.io/mervinpraison/praisonai:latest
-66
View File
@@ -1,66 +0,0 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python package
on:
push:
branches: [ "develop" ]
pull_request:
branches: [ "develop" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
- name: Install dependencies
run: |
cd src/praisonai
python -m pip install --upgrade pip
python -m pip install flake8 pytest
python -m pip install ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
python -m pip install duckduckgo_search
python -m pip install pytest-asyncio pytest-cov
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
# - name: Lint with flake8
# run: |
# # stop the build if there are Python syntax errors or undefined names
# flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
cd src/praisonai && python -m pytest
-40
View File
@@ -1,40 +0,0 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Upload Python Package
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build src/praisonai
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: src/praisonai/dist/
-524
View File
@@ -1,524 +0,0 @@
name: Release Workflow
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to create release with (e.g., v2.0.10)'
required: true
fork_owner:
description: 'GitHub username of the fork owner'
required: true
default: 'tosin2013'
jobs:
test-ubuntu:
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-24.04]
framework: ['crewai', 'autogen']
fail-fast: false
runs-on: ${{ matrix.os }}
timeout-minutes: 90
steps:
# First checkout the upstream repo at the specified tag
- name: Checkout upstream repo
uses: actions/checkout@v4
with:
repository: MervinPraison/PraisonAI
ref: ${{ github.event.inputs.tag }}
fetch-depth: 0
# Get the commit hash from the tag
- name: Get commit hash
id: get_commit
run: |
COMMIT_HASH=$(git rev-parse HEAD)
echo "commit_hash=$COMMIT_HASH" >> $GITHUB_OUTPUT
echo "Found commit: $COMMIT_HASH for tag ${{ github.event.inputs.tag }}"
# Now checkout the fork at main branch
- name: Checkout fork
uses: actions/checkout@v4
with:
repository: ${{ github.event.inputs.fork_owner }}/PraisonAI
ref: main
fetch-depth: 0
clean: true
# Sync with upstream commit
- name: Sync with upstream
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "[email protected]"
# Add upstream remote
git remote add upstream https://github.com/MervinPraison/PraisonAI.git
# Fetch from upstream
git fetch upstream --tags --force
# Reset to upstream commit
git reset --hard ${{ steps.get_commit.outputs.commit_hash }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install Poetry
run: |
curl -sSL https://install.python-poetry.org | python3 -
echo "$HOME/.local/bin" >> $GITHUB_PATH
poetry config virtualenvs.in-project true
poetry config virtualenvs.create true
poetry --version
poetry config --list
- name: Install Dependencies
run: |
poetry lock #--no-update
poetry install --all-extras
poetry env info
# Verify venv exists
test -d .venv || { echo "Virtual environment not created!"; exit 1; }
test -f .venv/bin/activate || { echo "Activation script not found!"; exit 1; }
- name: Run setup script
timeout-minutes: 20
run: |
set -e # Exit on any error
curl -OL https://raw.githubusercontent.com/tosin2013/PraisonAI/refs/heads/main/setup.sh
chmod +x setup.sh
./setup.sh --all --cicd || { echo "Setup script failed"; exit 1; }
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Basic Functionality
run: |
set -e # Exit on any error
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
lsof -ti:8084 | xargs -r kill -9 || true
source .venv/bin/activate || { echo "Failed to activate virtual environment"; exit 1; }
mkdir -p test_output || { echo "Failed to create test_output directory"; exit 1; }
echo "Testing basic CLI functionality..."
# Test auto generation with explicit framework
praisonai --framework ${{ matrix.framework }} --auto "create a short test script" 2>&1 | tee test_output/auto_test.log
# Verify the output file exists and has content
if [[ ! -s test_output/auto_test.log ]]; then
echo "Error: No output generated from auto test"
exit 1
fi
# Test auto generation without framework
echo "Basic functionality tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Framework-specific Features
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
lsof -ti:8084 | xargs -r kill -9 || true
praisonai --framework ${{ matrix.framework }} --auto "create a movie script about Robots in Mars" 2>&1 | tee test_output/framework_output.txt || echo "Framework-specific test failed" >> test_output/errors.log
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Core Functionality
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing core functionality..."
# Test package imports
python3 -c "from praisonai.cli import PraisonAI; from praisonai.auto import AutoGenerator; from praisonai.agents_generator import AgentsGenerator" || exit 1
# Test configuration loading
python3 -c "from praisonai.inc.config import generate_config; print(generate_config())" || exit 1
# Test tools loading
python3 -c "from praisonai.inbuilt_tools import *" || exit 1
echo "Core functionality tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Agent Generation
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing agent generation..."
# Create a test YAML file
cat > test_agents.yaml <<EOF
topic: "Test automation task"
framework: "${{ matrix.framework }} "
roles:
- name: "Tester"
goal: "Test the system"
backstory: "Expert system tester"
tasks:
- description: "Verify system functionality"
expected_output: "Test results"
EOF
# Test YAML loading and agent generation
python3 -c '
from praisonai.agents_generator import AgentsGenerator
config = [{"model": "llama-3.3-70b-versatile", "base_url": "https://api.groq.com/openai/v1/"}]
generator = AgentsGenerator("test_agents.yaml", "${{ matrix.framework }} ", config)
print("Agent generation test passed!")
' || exit 1
echo "Agent generation tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test Custom Tools Integration
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing custom tools integration..."
# Create a test tool
cat > test_tool.py <<EOF
from duckduckgo_search import DDGS
from praisonai_tools import BaseTool
class InternetSearchTool(BaseTool):
name: str = "Internet Search Tool"
description: str = "Search Internet for relevant information"
def _run(self, query: str):
return {"status": "success", "query": query}
def test(self):
"""Test method to verify tool setup"""
test_query = "test query"
result = self._run(test_query)
assert result["status"] == "success"
assert result["query"] == test_query
return True
EOF
# Test tool loading and initialization
python3 -c '
import importlib.util
import sys
# Load the test tool
spec = importlib.util.spec_from_file_location("test_tool", "test_tool.py")
module = importlib.util.module_from_spec(spec)
sys.modules["test_tool"] = module
spec.loader.exec_module(module)
# Initialize and test the tool
tool = module.InternetSearchTool()
assert tool.test(), "Tool test failed"
print("Custom tool test passed!")
' || exit 1
echo "Custom tools integration test passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Test PraisonAI Agents Configuration
continue-on-error: false
run: |
source .venv/bin/activate
# Random sleep between 60-120 seconds to avoid API rate limits
SLEEP_TIME=$((RANDOM % 61 + 60))
echo "Sleeping for $SLEEP_TIME seconds to avoid API rate limits..."
sleep $SLEEP_TIME
echo "Testing agents configuration..."
mkdir -p test_output || { echo "Failed to create test_output directory"; exit 1; }
# Create test script
cat > test_agents.py <<EOF
from langchain_openai import ChatOpenAI
from crewai import Agent, Task, Crew
import os
import logging
import time
import random
logging.basicConfig(level="DEBUG")
logger = logging.getLogger(__name__)
def random_sleep(min_seconds=15, max_seconds=30):
"""Sleep for a random duration to prevent API rate limiting"""
duration = random.uniform(min_seconds, max_seconds)
logger.info(f"Rate limit protection: Sleeping for {duration:.2f} seconds...")
time.sleep(duration)
class RateLimitedChatOpenAI(ChatOpenAI):
"""ChatOpenAI with built-in rate limiting"""
def __call__(self, *args, **kwargs):
random_sleep()
return super().__call__(*args, **kwargs)
def run_test():
logger.info("Initializing test components...")
# Initialize the LLM with rate limiting
llm = RateLimitedChatOpenAI(
model=os.getenv('OPENAI_MODEL_NAME', 'llama-3.3-70b-versatile'),
base_url=os.getenv('OPENAI_API_BASE', 'https://api.groq.com/openai/v1/'),
api_key=os.getenv('OPENAI_API_KEY'),
temperature=0.7
)
random_sleep()
logger.info("Creating researcher agent...")
researcher = Agent(
role="Test Automation Expert",
goal="Verify system functionality and performance",
backstory="""You are an expert in test automation and system verification,
skilled in identifying potential issues and validating functionality.""",
verbose=True,
allow_delegation=False,
llm=llm
)
random_sleep()
logger.info("Creating validator agent...")
validator = Agent(
role="Quality Assurance Specialist",
goal="Validate test results and ensure system reliability",
backstory="""You are a QA specialist focused on ensuring
system reliability and proper functionality.""",
verbose=True,
allow_delegation=False,
llm=llm
)
random_sleep()
logger.info("Creating test tasks...")
test_task = Task(
description="Run a basic system verification test",
expected_output="A report on system functionality verification",
agent=researcher
)
random_sleep()
validation_task = Task(
description="Validate the test results and compile findings",
expected_output="A validation report of test findings",
agent=validator
)
random_sleep()
logger.info("Initializing crew...")
crew = Crew(
agents=[researcher, validator],
tasks=[test_task, validation_task],
verbose=2
)
logger.info("Starting crew execution...")
result = crew.kickoff()
logger.info("Test execution completed.")
logger.info(f"Result: {result}")
return result
if __name__ == "__main__":
try:
run_test()
except Exception as e:
logger.error(f"Test failed with error: {str(e)}", exc_info=True)
raise
EOF
# Run the test script with increased timeout
echo "Testing with Python API..."
timeout 1800 python3 test_agents.py 2>&1 | tee test_output/agents_test.log
# Verify the output
if [[ ! -s test_output/agents_test.log ]]; then
echo "Error: No output generated from agents test"
exit 1
fi
echo "Agents configuration tests passed!"
env:
OPENAI_API_KEY: ${{ secrets.GROQ_API_KEY }}
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
OPENAI_MODEL_NAME: "llama-3.3-70b-versatile"
OPENAI_API_BASE: "https://api.groq.com/openai/v1/"
OPENAI_API_BASE_URL: "https://api.groq.com/openai/v1/"
LOGLEVEL: "debug"
PRAISONAI_NON_INTERACTIVE: "true"
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: praisonai-output-${{ matrix.os }}-${{ matrix.framework }}
path: test_output/
retention-days: 14
create-release:
needs: [test-ubuntu]
runs-on: ubuntu-latest
if: success()
steps:
# First checkout the fork's main branch
- name: Checkout fork repo
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.PAT_TOKEN }}
repository: ${{ github.event.inputs.fork_owner }}/PraisonAI
ref: main
# Add upstream and get commit from tag
- name: Get upstream tag commit
id: get_upstream_commit
run: |
# Add upstream remote
git remote add upstream https://github.com/MervinPraison/PraisonAI.git
# Delete local tag if it exists
git tag -d ${{ github.event.inputs.tag }} || true
# Fetch from upstream including tags with force
git fetch upstream --tags --force
# Verify tag exists in upstream
if ! git ls-remote --tags upstream | grep -q "refs/tags/${{ github.event.inputs.tag }}$"; then
echo "::error::Tag ${{ github.event.inputs.tag }} not found in upstream repository"
exit 1
fi
# Get the commit hash from the upstream tag
UPSTREAM_COMMIT=$(git rev-list -n 1 refs/tags/${{ github.event.inputs.tag }})
if [ -z "$UPSTREAM_COMMIT" ]; then
echo "::error::Could not find commit for tag ${{ github.event.inputs.tag }}"
exit 1
fi
echo "upstream_commit=$UPSTREAM_COMMIT" >> $GITHUB_OUTPUT
echo "Found commit: $UPSTREAM_COMMIT for tag ${{ github.event.inputs.tag }}"
# Create tag at the same commit
- name: Create tag at commit
run: |
git config --global user.name "GitHub Actions"
git config --global user.email "[email protected]"
# Remove tag if it exists locally
git tag -d ${{ github.event.inputs.tag }} || true
# Remove tag if it exists remotely
git push origin :refs/tags/${{ github.event.inputs.tag }} || true
# Fetch the specific commit from upstream
git fetch upstream ${{ steps.get_upstream_commit.outputs.upstream_commit }} --force
# Reset to upstream commit
git reset --hard ${{ steps.get_upstream_commit.outputs.upstream_commit }}
# Create and push tag
git tag -a ${{ github.event.inputs.tag }} -m "Release ${{ github.event.inputs.tag }} (synced from upstream MervinPraison/PraisonAI@${{ github.event.inputs.tag }})"
git push origin ${{ github.event.inputs.tag }}
env:
GIT_ASKPASS: /bin/echo
PAT_TOKEN: ${{ secrets.PAT_TOKEN }}
# Create the release
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
with:
tag_name: ${{ github.event.inputs.tag }}
release_name: Release ${{ github.event.inputs.tag }}
draft: false
prerelease: false
body: |
Release ${{ github.event.inputs.tag }} (synced from upstream)
This release is synchronized with MervinPraison/PraisonAI@${{ github.event.inputs.tag }}
Commit: ${{ steps.get_upstream_commit.outputs.upstream_commit }}
For installation:
```bash
pip install praisonai
```
Changes from upstream v2.0.10:
- Updated agent configuration tests
- Added rate limiting protection
- Improved test reliability
Forked from: MervinPraison/PraisonAI
-178
View File
@@ -1,178 +0,0 @@
name: Comprehensive Test Suite
on:
workflow_dispatch: # Allow manual triggering
inputs:
test_type:
description: 'Type of tests to run'
required: true
default: 'all'
type: choice
options:
- all
- unit
- integration
- fast
- performance
- frameworks
- autogen
- crewai
release:
types: [published, prereleased]
schedule:
# Run comprehensive tests weekly on Sundays at 3 AM UTC
- cron: '0 3 * * 0'
jobs:
comprehensive-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov pytest-benchmark
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
- name: Run Comprehensive Test Suite
run: |
# Determine test type from input or default to 'all'
TEST_TYPE="${{ github.event.inputs.test_type || 'all' }}"
echo "🧪 Running comprehensive test suite (type: $TEST_TYPE)"
case $TEST_TYPE in
"unit")
cd src/praisonai && python tests/test_runner.py --pattern unit
;;
"integration")
cd src/praisonai && python tests/test_runner.py --pattern integration
;;
"fast")
cd src/praisonai && python tests/test_runner.py --pattern fast
;;
"performance")
cd src/praisonai && python tests/test_runner.py --pattern "performance"
;;
"frameworks")
cd src/praisonai && python tests/test_runner.py --pattern frameworks
;;
"autogen")
cd src/praisonai && python tests/test_runner.py --pattern autogen
;;
"crewai")
cd src/praisonai && python tests/test_runner.py --pattern crewai
;;
"all"|*)
cd src/praisonai && python tests/test_runner.py --pattern all
;;
esac
- name: Generate Comprehensive Test Report
if: always()
run: |
echo "# 📋 Comprehensive Test Report" > comprehensive_report.md
echo "" >> comprehensive_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> comprehensive_report.md
echo "**Test Type:** ${{ github.event.inputs.test_type || 'all' }}" >> comprehensive_report.md
echo "**Trigger:** ${{ github.event_name }}" >> comprehensive_report.md
echo "**Date:** $(date -u)" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "## 🧪 Test Categories Covered:" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Unit Tests:" >> comprehensive_report.md
echo "- ✅ Core agent functionality" >> comprehensive_report.md
echo "- ✅ Async operations" >> comprehensive_report.md
echo "- ✅ Tool integrations" >> comprehensive_report.md
echo "- ✅ UI components" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Integration Tests:" >> comprehensive_report.md
echo "- ✅ MCP (Model Context Protocol)" >> comprehensive_report.md
echo "- ✅ RAG (Retrieval Augmented Generation)" >> comprehensive_report.md
echo "- ✅ Base URL API mapping" >> comprehensive_report.md
echo "- ✅ Multi-agent workflows" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
echo "- 🖥️ UI frameworks (Gradio, Streamlit)" >> comprehensive_report.md
echo "- 📊 Memory and persistence" >> comprehensive_report.md
echo "- 🌐 Multi-modal capabilities" >> comprehensive_report.md
echo "- ✅ AutoGen framework integration" >> comprehensive_report.md
echo "- ✅ CrewAI framework integration" >> comprehensive_report.md
echo "" >> comprehensive_report.md
echo "### Key Features Tested:" >> comprehensive_report.md
echo "- 🤖 Agent creation and configuration" >> comprehensive_report.md
echo "- 📋 Task management and execution" >> comprehensive_report.md
echo "- 🔄 Sync/async workflows" >> comprehensive_report.md
echo "- 🛠️ Custom tools and error handling" >> comprehensive_report.md
echo "- 🧠 Knowledge bases and RAG" >> comprehensive_report.md
echo "- 🔌 MCP server connections" >> comprehensive_report.md
echo "- 💬 LLM integrations (OpenAI, Anthropic, etc.)" >> comprehensive_report.md
- name: Upload Comprehensive Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: comprehensive-test-results-python-${{ matrix.python-version }}
path: |
comprehensive_report.md
htmlcov/
coverage.xml
.coverage
retention-days: 30
test-matrix-summary:
runs-on: ubuntu-latest
needs: comprehensive-test
if: always()
steps:
- name: Generate Matrix Summary
run: |
echo "# 🎯 Test Matrix Summary" > matrix_summary.md
echo "" >> matrix_summary.md
echo "## Python Version Results:" >> matrix_summary.md
echo "- Python 3.10: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "- Python 3.11: ${{ needs.comprehensive-test.result }}" >> matrix_summary.md
echo "" >> matrix_summary.md
echo "## Overall Status:" >> matrix_summary.md
if [ "${{ needs.comprehensive-test.result }}" == "success" ]; then
echo "✅ **All tests passed across all Python versions!**" >> matrix_summary.md
else
echo "❌ **Some tests failed. Check individual job logs for details.**" >> matrix_summary.md
fi
- name: Upload Matrix Summary
uses: actions/upload-artifact@v4
with:
name: test-matrix-summary
path: matrix_summary.md
retention-days: 30
-272
View File
@@ -1,272 +0,0 @@
name: Core Tests
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test-core:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
# Also export to current shell session for immediate availability
export OPENAI_API_KEY="${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}"
export OPENAI_API_BASE="${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}"
export OPENAI_MODEL_NAME="${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}"
export LOGLEVEL=DEBUG
# Verify immediate availability
echo "🔧 Immediate verification in same step:"
echo " OPENAI_API_KEY length in current session: ${#OPENAI_API_KEY}"
echo " OPENAI_API_KEY starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
echo "🐛 Log Level: $LOGLEVEL"
echo "📊 Environment Check:"
echo " - OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " - OPENAI_API_BASE: $OPENAI_API_BASE"
echo " - OPENAI_MODEL_NAME: $OPENAI_MODEL_NAME"
echo " - LOGLEVEL: $LOGLEVEL"
echo "🔍 Is API key actually set?"
echo " - API key starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
echo " - API key is not test key: $([ "$OPENAI_API_KEY" != 'sk-test-key-for-github-actions-testing-only-not-real' ] && echo 'YES' || echo 'NO')"
- name: Debug Environment Variables Raw
run: |
echo "🔧 Raw environment variable check:"
echo "OPENAI_API_KEY set: $(if [ -n "$OPENAI_API_KEY" ]; then echo 'YES'; else echo 'NO'; fi)"
echo "OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo "OPENAI_API_KEY first 10 chars: ${OPENAI_API_KEY:0:10}"
echo "OPENAI_API_KEY last 5 chars: ${OPENAI_API_KEY: -5}"
printenv | grep OPENAI || echo "No OPENAI env vars found"
- name: Debug Python Environment Variables
run: |
python -c "
import os
print('🐍 Python Environment Variable Check:')
api_key = os.environ.get('OPENAI_API_KEY', 'NOT_SET')
if api_key != 'NOT_SET':
print(f' ✅ OPENAI_API_KEY: {api_key[:7]}... (length: {len(api_key)})')
else:
print(' ❌ OPENAI_API_KEY: NOT_SET')
print(f' 🌐 OPENAI_API_BASE: {os.environ.get(\"OPENAI_API_BASE\", \"NOT_SET\")}')
print(f' 🤖 OPENAI_MODEL_NAME: {os.environ.get(\"OPENAI_MODEL_NAME\", \"NOT_SET\")}')
print(f' 📋 All OPENAI env vars:')
for key, value in os.environ.items():
if key.startswith('OPENAI'):
print(f' {key}: {value[:10] if len(value) > 10 else value}...')
"
- name: Validate API Key
run: |
echo "🔑 Testing API key validity with minimal OpenAI call..."
python -c "
import os
try:
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
response = client.models.list()
print('✅ API Key is VALID - OpenAI responded successfully')
print(f'📊 Available models: {len(list(response.data))} models found')
except Exception as e:
print(f'❌ API Key is INVALID - Error: {e}')
print('🔍 This explains why all API-dependent tests are failing')
print('💡 The GitHub secret OPENAI_API_KEY needs to be updated with a valid key')
"
continue-on-error: true
- name: Debug PraisonAI API Key Usage
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}
OPENAI_API_BASE: ${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}
OPENAI_MODEL_NAME: ${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}
LOGLEVEL: DEBUG
run: |
echo "🔍 Testing PraisonAI API key usage directly..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
# Attempt to import SecretStr, otherwise use a dummy class
try:
from pydantic.types import SecretStr
except ImportError:
class SecretStr: # Dummy class if pydantic is not available in this minimal context
def __init__(self, value): self._value = value
def get_secret_value(self): return self._value
def get_key_display_value(key_value):
if isinstance(key_value, SecretStr):
return key_value.get_secret_value()[:10] if key_value.get_secret_value() else 'EMPTY_SECRET'
elif isinstance(key_value, str):
return key_value[:10] if key_value != 'nokey' and key_value != 'NOT_SET' else key_value
return 'INVALID_TYPE'
print('🔧 Direct PraisonAI API Key Check:')
env_api_key = os.environ.get(\\"OPENAI_API_KEY\\", \\"NOT_SET\\")
print(f'Environment OPENAI_API_KEY: {get_key_display_value(env_api_key)}...')
from praisonai import PraisonAI
praisonai = PraisonAI()
print(f'PraisonAI config_list: {praisonai.config_list}')
api_key_from_config = praisonai.config_list[0].get('api_key', 'NOT_SET')
print(f'API key from PraisonAI config: {get_key_display_value(api_key_from_config)}...')
from praisonai.inc.models import PraisonAIModel
print('\\\\n🧪 Testing PraisonAIModel with explicit API key (CrewAI method):')
model_with_explicit_key = PraisonAIModel(
model='openai/gpt-4o-mini',
base_url=praisonai.config_list[0].get('base_url'),
api_key=api_key_from_config # This will be a string from praisonai.config_list
)
print(f' Model: {model_with_explicit_key.model}')
print(f' Model name: {model_with_explicit_key.model_name}')
print(f' API key var: {model_with_explicit_key.api_key_var}')
# model_with_explicit_key.api_key is now a string, or 'nokey'
print(f' API key (explicitly passed to PraisonAIModel): {get_key_display_value(model_with_explicit_key.api_key)}...')
print(f' Base URL: {model_with_explicit_key.base_url}')
try:
llm_instance = model_with_explicit_key.get_model()
print(f' ✅ LLM instance created successfully: {type(llm_instance).__name__}')
# langchain_openai.ChatOpenAI stores the key in openai_api_key as SecretStr
llm_api_key_attr = getattr(llm_instance, 'openai_api_key', 'NOT_FOUND')
if llm_api_key_attr != 'NOT_FOUND':
print(f' LLM instance API key: {get_key_display_value(llm_api_key_attr)}...')
else:
print(f' LLM instance API key attribute not found.')
except Exception as e:
print(f' ❌ Failed to create LLM instance: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Run Unit Tests
run: |
cd src/praisonai && python -m pytest tests/unit/ -v --tb=short --disable-warnings --cov=praisonai --cov-report=term-missing
- name: Run Integration Tests
run: |
cd src/praisonai && python -m pytest tests/integration/ -v --tb=short --disable-warnings
- name: Debug Directory Structure
run: |
echo "🔍 Debugging directory structure for CrewAI tests..."
cd src/praisonai
echo "Current working directory: $(pwd)"
echo "📁 Contents of current directory:"
ls -la
echo ""
echo "📁 Contents of tests directory:"
ls -la tests/ || echo "❌ tests/ directory not found"
echo ""
echo "📁 Contents of tests/integration:"
ls -la tests/integration/ || echo "❌ tests/integration/ directory not found"
echo ""
echo "📁 Looking for crewai directory:"
find . -name "crewai" -type d 2>/dev/null || echo "❌ No crewai directories found"
echo ""
echo "📁 Full directory tree of tests:"
tree tests/ || find tests/ -type d 2>/dev/null || echo "❌ Cannot explore tests directory"
- name: Test AutoGen Framework
run: |
echo "🤖 Testing AutoGen Framework Integration..."
cd src/praisonai && python tests/test_runner.py --pattern autogen --verbose
- name: Test CrewAI Framework
run: |
echo "⛵ Testing CrewAI Framework Integration..."
cd src/praisonai
echo "🔍 Trying test runner first..."
python tests/test_runner.py --pattern crewai --verbose || {
echo "❌ Test runner failed, trying direct pytest..."
echo "📁 Current directory: $(pwd)"
echo "📁 Looking for CrewAI tests..."
find . -name "*crewai*" -type f 2>/dev/null
echo "🧪 Trying direct pytest on integration/crewai..."
python -m pytest tests/integration/crewai/ -v --tb=short --disable-warnings || {
echo "❌ Direct path failed, trying relative path..."
python -m pytest integration/crewai/ -v --tb=short --disable-warnings || {
echo "❌ All CrewAI test attempts failed"
exit 1
}
}
}
- name: Run Legacy Tests with API Key
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}
OPENAI_API_BASE: ${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}
OPENAI_MODEL_NAME: ${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}
LOGLEVEL: DEBUG
run: |
echo "🧪 Running legacy tests with real API key..."
echo "🔧 Final environment check before pytest:"
echo " OPENAI_API_KEY set: $([ -n "$OPENAI_API_KEY" ] && echo 'YES' || echo 'NO')"
echo " OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " OPENAI_API_KEY starts with sk-: $(echo "$OPENAI_API_KEY" | grep -q '^sk-' && echo 'YES' || echo 'NO')"
export OPENAI_API_KEY="$OPENAI_API_KEY"
export OPENAI_API_BASE="$OPENAI_API_BASE"
export OPENAI_MODEL_NAME="$OPENAI_MODEL_NAME"
cd src/praisonai && python -m pytest tests/test.py -v --tb=short --disable-warnings
- name: Upload Coverage Reports
if: matrix.python-version == '3.11'
uses: actions/upload-artifact@v4
with:
name: coverage-reports
path: |
.coverage
htmlcov/
retention-days: 7
-160
View File
@@ -1,160 +0,0 @@
name: Extended Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
# Run nightly at 2 AM UTC
- cron: '0 2 * * *'
workflow_dispatch: # Allow manual triggering
jobs:
test-examples:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Test Key Example Scripts
run: |
echo "🧪 Testing key example scripts from praisonai-agents..."
# Create a timeout function for consistent handling
timeout_run() {
timeout 30s "$@" || echo "⏱️ $1 test completed/timed out"
}
# Test basic agent functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/basic-agents.py
# Test async functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/async_example.py
# Test knowledge/RAG functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/knowledge-agents.py
# Test MCP functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/mcp-basic.py
# Test UI functionality
timeout_run python ${{ github.workspace }}/src/praisonai-agents/ui.py
echo "✅ Example script testing completed"
continue-on-error: true
performance-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-benchmark
- name: Run Performance Benchmarks
run: |
echo "🏃 Running performance benchmarks..."
python -c "
import time
import sys
import statistics
sys.path.insert(0, 'src/praisonai')
print('🏃 Testing agent creation performance...')
times = []
try:
from praisonaiagents import Agent
for i in range(5):
start_time = time.time()
agent = Agent(name=f'PerfAgent{i}')
times.append(time.time() - start_time)
avg_time = statistics.mean(times)
print(f'✅ Average agent creation time: {avg_time:.3f}s')
print(f'📊 Min: {min(times):.3f}s, Max: {max(times):.3f}s')
except Exception as e:
print(f'❌ Agent creation benchmark failed: {e}')
print('🏃 Testing import performance...')
start_time = time.time()
try:
import praisonaiagents
import_time = time.time() - start_time
print(f'✅ Import completed in {import_time:.3f}s')
except Exception as e:
print(f'❌ Import benchmark failed: {e}')
print('🏃 Testing memory usage...')
try:
import psutil
import os
process = psutil.Process(os.getpid())
memory_mb = process.memory_info().rss / 1024 / 1024
print(f'📊 Memory usage: {memory_mb:.1f} MB')
except ImportError:
print('⚠️ psutil not available for memory testing')
except Exception as e:
print(f'❌ Memory benchmark failed: {e}')
"
continue-on-error: true
- name: Generate Performance Report
run: |
echo "## 📊 Performance Test Results" > performance_report.md
echo "" >> performance_report.md
echo "### Benchmarks Run:" >> performance_report.md
echo "- ⚡ Agent creation speed" >> performance_report.md
echo "- 📦 Import performance" >> performance_report.md
echo "- 💾 Memory usage" >> performance_report.md
echo "- 🧪 Example script execution" >> performance_report.md
echo "" >> performance_report.md
echo "_Performance results are logged in the CI output above._" >> performance_report.md
- name: Upload Performance Report
uses: actions/upload-artifact@v4
with:
name: performance-report
path: performance_report.md
retention-days: 30
-153
View File
@@ -1,153 +0,0 @@
name: Framework Integration Tests
on:
workflow_dispatch: # Allow manual triggering
inputs:
framework:
description: 'Framework to test'
required: true
default: 'all'
type: choice
options:
- all
- autogen
- crewai
schedule:
# Run framework tests daily at 6 AM UTC
- cron: '0 6 * * *'
push:
paths:
- 'tests/integration/autogen/**'
- 'tests/integration/crewai/**'
- '.github/workflows/test-frameworks.yml'
jobs:
framework-tests:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.11]
framework: [autogen, crewai]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
- name: Test ${{ matrix.framework }} Framework
run: |
echo "🧪 Testing ${{ matrix.framework }} framework integration with Python ${{ matrix.python-version }}"
cd src/praisonai && python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose --coverage
continue-on-error: false
- name: Generate Framework Test Report
if: always()
run: |
echo "# 🤖 ${{ matrix.framework }} Framework Test Report" > ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
echo "**Framework:** ${{ matrix.framework }}" >> ${{ matrix.framework }}_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> ${{ matrix.framework }}_report.md
echo "**Date:** $(date -u)" >> ${{ matrix.framework }}_report.md
echo "**Trigger:** ${{ github.event_name }}" >> ${{ matrix.framework }}_report.md
echo "" >> ${{ matrix.framework }}_report.md
if [ "${{ matrix.framework }}" == "autogen" ]; then
echo "## AutoGen Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ AutoGen import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic agent creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Conversation flow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
elif [ "${{ matrix.framework }}" == "crewai" ]; then
echo "## CrewAI Integration Tests" >> ${{ matrix.framework }}_report.md
echo "- ✅ CrewAI import verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Basic crew creation through PraisonAI" >> ${{ matrix.framework }}_report.md
echo "- ✅ Multi-agent workflow testing" >> ${{ matrix.framework }}_report.md
echo "- ✅ Agent collaboration verification" >> ${{ matrix.framework }}_report.md
echo "- ✅ Configuration validation" >> ${{ matrix.framework }}_report.md
fi
echo "" >> ${{ matrix.framework }}_report.md
echo "## Test Commands" >> ${{ matrix.framework }}_report.md
echo '```bash' >> ${{ matrix.framework }}_report.md
echo "# Run ${{ matrix.framework }} tests locally:" >> ${{ matrix.framework }}_report.md
echo "python tests/test_runner.py --pattern ${{ matrix.framework }} --verbose" >> ${{ matrix.framework }}_report.md
echo '```' >> ${{ matrix.framework }}_report.md
- name: Upload Framework Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: ${{ matrix.framework }}-test-results-python-${{ matrix.python-version }}
path: |
${{ matrix.framework }}_report.md
htmlcov/
coverage.xml
.coverage
retention-days: 14
framework-summary:
runs-on: ubuntu-latest
needs: framework-tests
if: always()
steps:
- name: Generate Framework Summary
run: |
echo "# 🚀 Framework Integration Test Summary" > framework_summary.md
echo "" >> framework_summary.md
echo "## Test Results by Framework and Python Version:" >> framework_summary.md
echo "" >> framework_summary.md
echo "### AutoGen Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "### CrewAI Framework:" >> framework_summary.md
echo "- Python 3.11: ${{ needs.framework-tests.result }}" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Overall Status:" >> framework_summary.md
if [ "${{ needs.framework-tests.result }}" == "success" ]; then
echo "✅ **All framework integration tests passed!**" >> framework_summary.md
else
echo "❌ **Some framework tests failed. Check individual job logs for details.**" >> framework_summary.md
fi
echo "" >> framework_summary.md
echo "## Frameworks Tested:" >> framework_summary.md
echo "- **AutoGen**: Microsoft's conversational AI framework" >> framework_summary.md
echo "- **CrewAI**: Multi-agent collaboration framework" >> framework_summary.md
echo "" >> framework_summary.md
echo "## Test Coverage:" >> framework_summary.md
echo "- Import verification" >> framework_summary.md
echo "- Agent/crew creation" >> framework_summary.md
echo "- Workflow execution" >> framework_summary.md
echo "- Configuration validation" >> framework_summary.md
echo "- Integration with PraisonAI" >> framework_summary.md
- name: Upload Framework Summary
uses: actions/upload-artifact@v4
with:
name: framework-test-summary
path: framework_summary.md
retention-days: 30
-165
View File
@@ -1,165 +0,0 @@
name: Real End-to-End Tests
# ⚠️ WARNING: This workflow makes real API calls and incurs costs!
# Only runs when manually triggered to prevent accidental charges
on:
workflow_dispatch: # Manual trigger only
inputs:
framework:
description: 'Framework to test (⚠️ Will incur API costs!)'
required: true
default: 'none'
type: choice
options:
- none
- autogen
- crewai
- all
confirm_costs:
description: 'I understand this will make real API calls and may incur costs'
required: true
type: boolean
default: false
jobs:
real-tests:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs == 'true' && github.event.inputs.framework != 'none' }}
strategy:
matrix:
python-version: [3.11] # Single version to minimize costs
steps:
- name: 🚨 Cost Warning
run: |
echo "⚠️ WARNING: This workflow will make real API calls!"
echo "💰 This may incur charges on your API accounts"
echo "🎯 Framework: ${{ github.event.inputs.framework }}"
echo "✅ Cost confirmation: ${{ github.event.inputs.confirm_costs }}"
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system pytest pytest-asyncio pytest-cov
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}" >> $GITHUB_ENV
echo "ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}" >> $GITHUB_ENV
echo "GOOGLE_API_KEY=${{ secrets.GOOGLE_API_KEY }}" >> $GITHUB_ENV
- name: Verify API Keys
run: |
if [ -z "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "❌ OPENAI_API_KEY not set in secrets"
echo "🔧 Add your API key to repository secrets"
exit 1
fi
echo "✅ API keys configured"
- name: Run Real AutoGen Tests
if: ${{ github.event.inputs.framework == 'autogen' || github.event.inputs.framework == 'all' }}
run: |
echo "🤖 Running REAL AutoGen tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/autogen/ -v -m real --tb=short
continue-on-error: false
- name: Run Real CrewAI Tests
if: ${{ github.event.inputs.framework == 'crewai' || github.event.inputs.framework == 'all' }}
run: |
echo "⛵ Running REAL CrewAI tests (⚠️ API costs may apply)"
cd src/praisonai && python -m pytest tests/e2e/crewai/ -v -m real --tb=short
continue-on-error: false
- name: Generate Real Test Report
if: always()
run: |
echo "# 🔥 Real End-to-End Test Report" > real_test_report.md
echo "" >> real_test_report.md
echo "⚠️ **WARNING: This report represents tests that made real API calls**" >> real_test_report.md
echo "" >> real_test_report.md
echo "**Framework Tested:** ${{ github.event.inputs.framework }}" >> real_test_report.md
echo "**Python Version:** ${{ matrix.python-version }}" >> real_test_report.md
echo "**Date:** $(date -u)" >> real_test_report.md
echo "**Triggered by:** ${{ github.actor }}" >> real_test_report.md
echo "" >> real_test_report.md
echo "## 🧪 Test Results" >> real_test_report.md
echo "" >> real_test_report.md
if [ "${{ github.event.inputs.framework }}" == "autogen" ] || [ "${{ github.event.inputs.framework }}" == "all" ]; then
echo "### AutoGen Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Agent creation with real API calls" >> real_test_report.md
echo "- Configuration validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
if [ "${{ github.event.inputs.framework }}" == "crewai" ] || [ "${{ github.event.inputs.framework }}" == "all" ]; then
echo "### CrewAI Real Tests:" >> real_test_report.md
echo "- Environment verification" >> real_test_report.md
echo "- Crew creation with real API calls" >> real_test_report.md
echo "- Multi-agent setup validation" >> real_test_report.md
echo "" >> real_test_report.md
fi
echo "## 💰 Cost Considerations" >> real_test_report.md
echo "- These tests made actual API calls to LLM providers" >> real_test_report.md
echo "- Costs depend on your API pricing tier" >> real_test_report.md
echo "- Tests are designed to be minimal to reduce costs" >> real_test_report.md
echo "- Check your API provider dashboard for actual usage" >> real_test_report.md
echo "## 📋 Next Steps" >> real_test_report.md
echo "- Review test results for any failures" >> real_test_report.md
echo "- Check API usage in your provider dashboard" >> real_test_report.md
echo "- Use mock tests (tests/integration/) for routine testing" >> real_test_report.md
- name: Upload Real Test Results
uses: actions/upload-artifact@v4
if: always()
with:
name: real-test-results-${{ github.event.inputs.framework }}-python-${{ matrix.python-version }}
path: |
real_test_report.md
retention-days: 30
# Safety job that runs when costs not confirmed
safety-check:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.confirm_costs != 'true' || github.event.inputs.framework == 'none' }}
steps:
- name: 🛡️ Safety Check Failed
run: |
echo "🚨 Real tests not executed due to safety checks:"
echo ""
echo "✅ Costs confirmed: ${{ github.event.inputs.confirm_costs }}"
echo "✅ Framework selected: ${{ github.event.inputs.framework }}"
echo ""
echo "To run real tests:"
echo "1. Select a framework (autogen, crewai, or all)"
echo "2. Check 'I understand this will make real API calls and may incur costs'"
echo "3. Ensure API keys are set in repository secrets"
echo ""
echo "💡 For cost-free testing, use mock tests instead:"
echo " - Run 'python -m pytest tests/integration/' locally"
echo " - Or trigger other workflows that use mock tests"
exit 1
-503
View File
@@ -1,503 +0,0 @@
name: Quick Validation Tests
on: [push, pull_request]
jobs:
quick-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install UV
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
cd src/praisonai
uv pip install --system ."[ui,gradio,api,agentops,google,openai,anthropic,cohere,chat,code,realtime,call,crewai,autogen]"
uv pip install --system duckduckgo_search
uv pip install --system pytest pytest-asyncio pytest-cov
- name: Set environment variables
run: |
echo "OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY || 'sk-test-key-for-github-actions-testing-only-not-real' }}" >> $GITHUB_ENV
echo "OPENAI_API_BASE=${{ secrets.OPENAI_API_BASE || 'https://api.openai.com/v1' }}" >> $GITHUB_ENV
echo "OPENAI_MODEL_NAME=${{ secrets.OPENAI_MODEL_NAME || 'gpt-4o-mini' }}" >> $GITHUB_ENV
echo "LOGLEVEL=DEBUG" >> $GITHUB_ENV
echo "PYTHONPATH=${{ github.workspace }}/src/praisonai-agents:$PYTHONPATH" >> $GITHUB_ENV
- name: Backup Root Config Files
run: |
echo "🔄 Backing up root configuration files to prevent default file resolution interference..."
echo "ℹ️ PraisonAI automatically uses 'agents.yaml' in working directory when no file specified"
echo "ℹ️ This can interfere with test files that specify their own YAML files"
if [ -f "agents.yaml" ]; then
mv agents.yaml agents.yaml.backup
echo "✅ Moved root agents.yaml to agents.yaml.backup"
echo " - This prevents default file fallback during tests"
fi
if [ -f "tools.py" ]; then
mv tools.py tools.py.backup
echo "✅ Moved tools.py to tools.py.backup"
fi
- name: Debug API Key Status
run: |
echo "🔍 Checking API key availability..."
if [ -n "${{ secrets.OPENAI_API_KEY }}" ]; then
echo "✅ GitHub secret OPENAI_API_KEY is available"
echo "🔑 API key starts with: $(echo "$OPENAI_API_KEY" | cut -c1-7)..."
else
echo "⚠️ GitHub secret OPENAI_API_KEY is NOT set - using fallback"
echo "🔑 Using fallback key: sk-test-key..."
fi
echo "🌐 API Base: $OPENAI_API_BASE"
echo "🤖 Model: $OPENAI_MODEL_NAME"
echo "🐛 Log Level: $LOGLEVEL"
echo "📊 Environment Check:"
echo " - OPENAI_API_KEY length: ${#OPENAI_API_KEY}"
echo " - OPENAI_API_BASE: $OPENAI_API_BASE"
echo " - OPENAI_MODEL_NAME: $OPENAI_MODEL_NAME"
echo " - LOGLEVEL: $LOGLEVEL"
- name: Debug Python Environment Variables
run: |
python -c "
import os
print('🐍 Python Environment Variable Check:')
api_key = os.environ.get('OPENAI_API_KEY', 'NOT_SET')
if api_key != 'NOT_SET':
print(f' ✅ OPENAI_API_KEY: {api_key[:7]}... (length: {len(api_key)})')
else:
print(' ❌ OPENAI_API_KEY: NOT_SET')
print(f' 🌐 OPENAI_API_BASE: {os.environ.get(\"OPENAI_API_BASE\", \"NOT_SET\")}')
print(f' 🤖 OPENAI_MODEL_NAME: {os.environ.get(\"OPENAI_MODEL_NAME\", \"NOT_SET\")}')
print(f' 📋 All OPENAI env vars:')
for key, value in os.environ.items():
if key.startswith('OPENAI'):
print(f' {key}: {value[:10] if len(value) > 10 else value}...')
"
- name: Find Researcher Role Source
run: |
echo "🔍 Hunting for the mysterious 'Researcher' role..."
cd src/praisonai
python -c "
import os
import yaml
import glob
print('📋 Searching for Researcher role in all YAML files:')
yaml_files = glob.glob('src/praisonai/tests/*.yaml')
for yaml_file in yaml_files:
try:
with open(yaml_file, 'r') as f:
config = yaml.safe_load(f)
# Check if any role contains 'researcher'
roles = config.get('roles', {})
for role_key, role_data in roles.items():
role_name = role_data.get('role', '')
if 'researcher' in role_key.lower() or 'researcher' in role_name.lower():
print(f' 🎯 FOUND in {yaml_file}:')
print(f' Framework: {config.get(\"framework\", \"NOT_SET\")}')
print(f' Role key: {role_key}')
print(f' Role name: {role_name}')
print(f' All roles: {list(roles.keys())}')
print()
except Exception as e:
print(f' ❌ Error reading {yaml_file}: {e}')
print('🔍 Checking for default configurations...')
# Check if there are any default configs or hardcoded roles
try:
import praisonai
print(f' PraisonAI package location: {praisonai.__file__}')
# Check if there are any example YAML files in the package
package_dir = os.path.dirname(praisonai.__file__)
for root, dirs, files in os.walk(package_dir):
for file in files:
if file.endswith(('.yaml', '.yml')):
file_path = os.path.join(root, file)
print(f' 📁 Found YAML in package: {file_path}')
except Exception as e:
print(f' ❌ Error checking package: {e}')
"
continue-on-error: true
- name: Trace AutoGen Execution Path
run: |
echo "🔍 Tracing AutoGen execution to find where it diverges..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test the exact execution path
print('🎯 Testing AutoGen execution path:')
praisonai = PraisonAI(agent_file='tests/autogen-agents.yaml')
print(f' 1. PraisonAI framework: \"{praisonai.framework}\"')
agents_gen = AgentsGenerator(
agent_file='tests/autogen-agents.yaml',
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' 2. AgentsGenerator framework: \"{agents_gen.framework}\"')
# Load the YAML to check what it contains
import yaml
with open('src/praisonai/tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
framework = agents_gen.framework or config.get('framework')
print(f' 3. Final framework decision: \"{framework}\"')
print(f' 4. Available frameworks:')
# Check framework availability
try:
import autogen
print(f' ✅ AutoGen available')
except ImportError:
print(f' ❌ AutoGen NOT available')
try:
from praisonaiagents import Agent
print(f' ✅ PraisonAI agents available')
except ImportError:
print(f' ❌ PraisonAI agents NOT available')
try:
from crewai import Agent
print(f' ✅ CrewAI available')
except ImportError:
print(f' ❌ CrewAI NOT available')
print(f' 5. Roles in YAML: {list(config.get(\"roles\", {}).keys())}')
# Now test the actual framework execution
if framework == 'autogen':
print(f' 6. ✅ Should execute _run_autogen')
elif framework == 'praisonai':
print(f' 6. ❌ Would execute _run_praisonai (WRONG!)')
else:
print(f' 6. ❌ Would execute _run_crewai (DEFAULT FALLBACK)')
except Exception as e:
print(f'❌ Error tracing execution: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Debug YAML Loading and Roles
run: |
echo "🔍 Tracing YAML file loading and role creation..."
cd src/praisonai
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('📁 Available YAML files in src/praisonai/tests/:')
import glob
yaml_files = glob.glob('tests/*.yaml')
for f in yaml_files:
print(f' {f}')
print()
print('📋 Content of autogen-agents.yaml:')
with open('tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
print(f' Framework: {config.get(\"framework\")}')
print(f' Topic: {config.get(\"topic\")}')
print(f' Roles: {list(config.get(\"roles\", {}).keys())}')
for role_key, role_data in config.get('roles', {}).items():
print(f' {role_key} -> {role_data.get(\"role\", \"NO_ROLE\")}')
print()
print('🔍 Checking if execution uses a different YAML:')
# Check other YAML files for 'Researcher' role
for yaml_file in yaml_files:
try:
with open(yaml_file, 'r') as f:
test_config = yaml.safe_load(f)
roles = test_config.get('roles', {})
for role_key, role_data in roles.items():
if 'researcher' in role_key.lower() or 'researcher' in role_data.get('role', '').lower():
print(f' 🎯 FOUND Researcher in {yaml_file}!')
print(f' Framework: {test_config.get(\"framework\")}')
print(f' Role key: {role_key} -> {role_data.get(\"role\")}')
except:
pass
"
continue-on-error: true
- name: Debug Framework Detection
run: |
echo "🔍 Testing framework detection and config flow..."
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('🔧 Testing framework detection:')
# Load the YAML file
with open('tests/autogen-agents.yaml', 'r') as f:
config = yaml.safe_load(f)
print(f' 📋 YAML framework: {config.get(\"framework\", \"NOT_SET\")}')
print(f' 📋 YAML topic: {config.get(\"topic\", \"NOT_SET\")}')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test PraisonAI initialization
praisonai = PraisonAI(agent_file='tests/autogen-agents.yaml')
print(f' 🎯 PraisonAI framework: {praisonai.framework}')
# Test AgentsGenerator initialization
agents_gen = AgentsGenerator(
agent_file='tests/autogen-agents.yaml',
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' ⚙️ AgentsGenerator framework: {agents_gen.framework}')
print(f' ⚙️ Final framework decision: {agents_gen.framework or config.get(\"framework\")}')
# Check config_list
print(f' 🔑 Config list model: {praisonai.config_list[0].get(\"model\")}')
print(f' 🔑 Config list API key: {praisonai.config_list[0].get(\"api_key\", \"NOT_SET\")[:10]}...')
except Exception as e:
print(f'❌ Error in framework detection: {e}')
"
continue-on-error: true
- name: Debug PraisonAIModel API Key Flow
run: |
echo "🔍 Testing PraisonAIModel API key handling..."
cd src/praisonai
python -c "
import os
import sys
sys.path.insert(0, '.')
print('🔑 Environment API Key Check:')
env_key = os.environ.get('OPENAI_API_KEY', 'NOT_FOUND')
print(f' OPENAI_API_KEY: {env_key[:10] if env_key != \"NOT_FOUND\" else \"NOT_FOUND\"}...')
try:
from praisonai.inc.models import PraisonAIModel
# Test PraisonAIModel with openai/gpt-4o-mini (from YAML)
model = PraisonAIModel(model='openai/gpt-4o-mini')
print('🤖 PraisonAIModel Configuration:')
print(f' model: {model.model}')
print(f' model_name: {model.model_name}')
print(f' api_key_var: {model.api_key_var}')
print(f' api_key: {model.api_key[:10] if model.api_key != \"nokey\" else \"DEFAULT_NOKEY\"}...')
print(f' base_url: {model.base_url}')
if model.api_key == 'nokey':
print('❌ FOUND THE ISSUE: PraisonAIModel is using default \"nokey\" instead of environment variable!')
else:
print('✅ PraisonAIModel has valid API key from environment')
except Exception as e:
print(f'❌ Error testing PraisonAIModel: {e}')
"
continue-on-error: true
- name: Validate API Key
run: |
echo "🔑 Testing API key validity with minimal OpenAI call..."
python -c "
import os
try:
from openai import OpenAI
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
# Make a minimal API call to test key validity
response = client.models.list()
print('✅ API Key is VALID - OpenAI responded successfully')
print(f'📊 Available models: {len(list(response.data))} models found')
except Exception as e:
print(f'❌ API Key is INVALID - Error: {e}')
print('🔍 This explains why all API-dependent tests are failing')
print('💡 The GitHub secret OPENAI_API_KEY needs to be updated with a valid key')
"
continue-on-error: true
- name: Test Direct PraisonAI Execution
run: |
echo "🧪 Testing direct PraisonAI execution (what works locally)..."
python -m praisonai src/praisonai/tests/autogen-agents.yaml
continue-on-error: true
- name: Comprehensive Execution Debug
run: |
echo "🔍 Comprehensive debugging of PraisonAI execution path..."
cd src/praisonai
python -c "
import os
import sys
import yaml
sys.path.insert(0, '.')
print('=' * 60)
print('🔍 COMPREHENSIVE EXECUTION DEBUG')
print('=' * 60)
# Check current working directory
print(f'📁 Current working directory: {os.getcwd()}')
# List files in current directory
print('📋 Files in current directory:')
for f in os.listdir('.'):
print(f' {f}')
print()
print('📋 Files in src/praisonai/tests/ directory:')
for f in os.listdir('tests'):
if f.endswith('.yaml'):
print(f' src/praisonai/tests/{f}')
# Check if root agents.yaml exists
print()
if os.path.exists('agents.yaml'):
print('❌ ROOT agents.yaml EXISTS (this is the problem!)')
with open('agents.yaml', 'r') as f:
root_config = yaml.safe_load(f)
print(f' Root framework: {root_config.get(\"framework\")}')
print(f' Root roles: {list(root_config.get(\"roles\", {}).keys())}')
else:
print('✅ ROOT agents.yaml does NOT exist (good!)')
# Test the actual execution path
print()
print('🎯 Testing EXACT execution path:')
try:
from praisonai import PraisonAI
from praisonai.agents_generator import AgentsGenerator
# Test with full path
test_file = 'src/praisonai/tests/autogen-agents.yaml'
print(f' Using test file: {test_file}')
print(f' File exists: {os.path.exists(test_file)}')
# Load the test file directly
with open(test_file, 'r') as f:
test_config = yaml.safe_load(f)
print(f' Test file framework: {test_config.get(\"framework\")}')
print(f' Test file roles: {list(test_config.get(\"roles\", {}).keys())}')
# Create PraisonAI instance
praisonai = PraisonAI(agent_file=test_file)
print(f' PraisonAI.agent_file: {praisonai.agent_file}')
print(f' PraisonAI.framework: {praisonai.framework}')
# Create AgentsGenerator
agents_gen = AgentsGenerator(
agent_file=test_file,
framework=praisonai.framework,
config_list=praisonai.config_list
)
print(f' AgentsGenerator.agent_file: {agents_gen.agent_file}')
print(f' AgentsGenerator.framework: {agents_gen.framework}')
# Test what would happen in generate_crew_and_kickoff
print()
print('🔧 Testing generate_crew_and_kickoff logic:')
# Simulate the loading logic
if agents_gen.agent_yaml:
loaded_config = yaml.safe_load(agents_gen.agent_yaml)
print(' Would load from agent_yaml')
else:
if agents_gen.agent_file == '/app/api:app' or agents_gen.agent_file == 'api:app':
agents_gen.agent_file = 'agents.yaml'
print(f' Would change agent_file to: {agents_gen.agent_file}')
try:
with open(agents_gen.agent_file, 'r') as f:
loaded_config = yaml.safe_load(f)
print(f' Successfully loaded: {agents_gen.agent_file}')
except FileNotFoundError:
print(f' FileNotFoundError: {agents_gen.agent_file}')
loaded_config = None
if loaded_config:
final_framework = agents_gen.framework or loaded_config.get('framework')
print(f' Final framework decision: {final_framework}')
print(f' Loaded roles: {list(loaded_config.get(\"roles\", {}).keys())}')
if 'researcher' in loaded_config.get('roles', {}):
print(' ❌ FOUND Researcher role in loaded config!')
else:
print(' ✅ No Researcher role in loaded config')
except Exception as e:
print(f'❌ Error during execution debug: {e}')
import traceback
traceback.print_exc()
"
continue-on-error: true
- name: Run Fast Tests
run: |
# Run the fastest, most essential tests
cd src/praisonai && python tests/test_runner.py --pattern fast
- name: Run Real API Tests
run: |
echo "🔑 Running real API tests with actual OpenAI API key..."
cd src/praisonai && python -m pytest tests/test_agents_playbook.py -v --tb=short --disable-warnings -m real
continue-on-error: true
- name: Run E2E Real Tests
run: |
echo "🧪 Running E2E real tests..."
cd src/praisonai && python -m pytest tests/e2e/ -v --tb=short --disable-warnings -m real
continue-on-error: true
- name: Run Legacy Example Tests
run: |
cd src/praisonai && python -m pytest tests/test.py -v --tb=short --disable-warnings
continue-on-error: true
- name: Restore Root Config Files
run: |
echo "🔄 Restoring root configuration files..."
if [ -f "agents.yaml.backup" ]; then
mv agents.yaml.backup agents.yaml
echo "✅ Restored agents.yaml"
fi
if [ -f "tools.py.backup" ]; then
mv tools.py.backup tools.py
echo "✅ Restored tools.py"
fi
if: always() # Always run this step, even if previous steps failed
+21 -75
View File
@@ -1,77 +1,23 @@
workspace.code-workspace
.vscode
crewai
.cache
__pycache__
chroma.sqlite3
test
dist
.env
assets
.idea
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.pytest_cache
praisonAI.egg-info
flagged
test.yaml
db
praisonai_prompt.txt
watch.sh
docs.sh
other
output
.env.local
.env.development.local
.env.test.local
.env.production.local
.files
threads.db
threads.db-journal
.chainlit
!praisonai/ui/config/.chainlit
site
# Ignore Sphinx build directory
docs/_build/
docs/source/
docs/build/
# Ignore Sphinx cache
docs/_build/doctrees/
docs/_build/doctrees/*
docs/_build/doctrees/.doctrees
# Ignore Sphinx logs and local build files
docs/_build/.buildinfo
docs/_build/.buildinfo/*
docs/_build/.buildinfo/.buildinfo
praisonai/doc
# agentops
trained_agents_data.pkl
agentops.log
# crewAI
crewAI
!tests/integration/crewai
!tests/e2e/crewai
!src/praisonai/tests/integration/crewai
!src/praisonai/tests/e2e/crewai
# virtualenv
.venv
# Credentials
credentials.json
# node_modules
node_modules
outputs
agents/praisonaiagents/build
agents/praisonaiagents/dist
agents/praisonaiagents/praisonaiagents.egg-info
.codegpt
.praison
# Local Netlify folder
.netlify
.qodo
npm-debug.log*
yarn-debug.log*
yarn-error.log*
-20
View File
@@ -1,20 +0,0 @@
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+69 -589
View File
@@ -1,590 +1,70 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/logo/dark.png" />
<source media="(prefers-color-scheme: light)" srcset="docs/logo/light.png" />
<img alt="PraisonAI Logo" src="docs/logo/light.png" />
</picture>
</p>
<p align="center">
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://static.pepy.tech/badge/PraisonAI" alt="Total Downloads" /></a>
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://img.shields.io/github/v/release/MervinPraison/PraisonAI" alt="Latest Stable Version" /></a>
<a href="https://github.com/MervinPraison/PraisonAI"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License" /></a>
</p>
<div align="center">
# Praison AI
<a href="https://trendshift.io/repositories/9130" target="_blank"><img src="https://trendshift.io/api/badge/repositories/9130" alt="MervinPraison%2FPraisonAI | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</div>
PraisonAI is a production-ready Multi-AI Agents framework with self-reflection, designed to create AI Agents to automate and solve problems ranging from simple tasks to complex challenges. By integrating PraisonAI Agents, AG2 (Formerly AutoGen), and CrewAI into a low-code solution, it streamlines the building and management of multi-agent LLM systems, emphasising simplicity, customisation, and effective human-agent collaboration.
<div align="center">
<a href="https://docs.praison.ai">
<p align="center">
<img src="https://img.shields.io/badge/📚_Documentation-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Documentation" />
</p>
</a>
</div>
## Key Features
- 🤖 Automated AI Agents Creation
- 🔄 Self Reflection AI Agents
- 🧠 Reasoning AI Agents
- 👁️ Multi Modal AI Agents
- 🤝 Multi Agent Collaboration
- 🎭 AI Agent Workflow
- 📚 Add Custom Knowledge
- 🧠 Agents with Short and Long Term Memory
- 📄 Chat with PDF Agents
- 💻 Code Interpreter Agents
- 📚 RAG Agents
- 🤔 Async & Parallel Processing
- 🔄 Auto Agents
- 🔢 Math Agents
- 🎯 Structured Output Agents
- 🔗 LangChain Integrated Agents
- 📞 Callback Agents
- 🤏 Mini AI Agents
- 🛠️ 100+ Custom Tools
- 📄 YAML Configuration
- 💯 100+ LLM Support
## Using Python Code
Light weight package dedicated for coding:
```bash
pip install praisonaiagents
```
```bash
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
### 1. Single Agent
Create app.py file and add the code below:
```python
from praisonaiagents import Agent
agent = Agent(instructions="Your are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
Run:
```bash
python app.py
```
### 2. Multi Agents
Create app.py file and add the code below:
```python
from praisonaiagents import Agent, PraisonAIAgents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
Run:
```bash
python app.py
```
## Using No Code
### Auto Mode:
```bash
pip install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
praisonai --auto create a movie script about Robots in Mars
```
## Using JavaScript Code
```bash
npm install praisonai
export OPENAI_API_KEY=xxxxxxxxxxxxxxxxxxxxxx
```
```javascript
const { Agent } = require('praisonai');
const agent = new Agent({ instructions: 'You are a helpful AI assistant' });
agent.start('Write a movie script about a robot in Mars');
```
![PraisonAI CLI Demo](docs/demo/praisonai-cli-demo.gif)
## AI Agents Flow
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## AI Agents with Tools
Create AI agents that can use tools to interact with external systems and perform actions.
```mermaid
flowchart TB
subgraph Tools
direction TB
T3[Internet Search]
T1[Code Execution]
T2[Formatting]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
T3 --> A1
T1 --> A2
T2 --> A3
style Tools fill:#189AB4,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Memory
Create AI agents with memory capabilities for maintaining context and information across tasks.
```mermaid
flowchart TB
subgraph Memory
direction TB
STM[Short Term]
LTM[Long Term]
end
subgraph Store
direction TB
DB[(Vector DB)]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
Memory <--> Store
Store <--> A1
Store <--> A2
Store <--> A3
style Memory fill:#189AB4,color:#fff
style Store fill:#2E8B57,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
## AI Agents with Different Processes
### Sequential Process
The simplest form of task execution where tasks are performed one after another.
```mermaid
graph LR
Input[Input] --> A1
subgraph Agents
direction LR
A1[Agent 1] --> A2[Agent 2] --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class A1,A2,A3 process
class Agents transparent
```
### Hierarchical Process
Uses a manager agent to coordinate task execution and agent assignments.
```mermaid
graph TB
Input[Input] --> Manager
subgraph Agents
Manager[Manager Agent]
subgraph Workers
direction LR
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
end
Manager --> W1
Manager --> W2
Manager --> W3
end
W1 --> Manager
W2 --> Manager
W3 --> Manager
Manager --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Manager,W1,W2,W3 process
class Agents,Workers transparent
```
### Workflow Process
Advanced process type supporting complex task relationships and conditional execution.
```mermaid
graph LR
Input[Input] --> Start
subgraph Workflow
direction LR
Start[Start] --> C1{Condition}
C1 --> |Yes| A1[Agent 1]
C1 --> |No| A2[Agent 2]
A1 --> Join
A2 --> Join
Join --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef decision fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Start,A1,A2,A3,Join process
class C1 decision
class Workflow transparent
```
#### Agentic Routing Workflow
Create AI agents that can dynamically route tasks to specialized LLM instances.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Out[Out]
LLM2 --> Out
LLM3 --> Out
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Orchestrator Worker
Create AI agents that orchestrate and distribute tasks among specialized workers.
```mermaid
flowchart LR
In[In] --> Router[LLM Call Router]
Router --> LLM1[LLM Call 1]
Router --> LLM2[LLM Call 2]
Router --> LLM3[LLM Call 3]
LLM1 --> Synthesizer[Synthesizer]
LLM2 --> Synthesizer
LLM3 --> Synthesizer
Synthesizer --> Out[Out]
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Agentic Autonomous Workflow
Create AI agents that can autonomously monitor, act, and adapt based on environment feedback.
```mermaid
flowchart LR
Human[Human] <--> LLM[LLM Call]
LLM -->|ACTION| Environment[Environment]
Environment -->|FEEDBACK| LLM
LLM --> Stop[Stop]
style Human fill:#8B0000,color:#fff
style LLM fill:#2E8B57,color:#fff
style Environment fill:#8B0000,color:#fff
style Stop fill:#333,color:#fff
```
#### Agentic Parallelization
Create AI agents that can execute tasks in parallel for improved performance.
```mermaid
flowchart LR
In[In] --> LLM2[LLM Call 2]
In --> LLM1[LLM Call 1]
In --> LLM3[LLM Call 3]
LLM1 --> Aggregator[Aggregator]
LLM2 --> Aggregator
LLM3 --> Aggregator
Aggregator --> Out[Out]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Aggregator fill:#fff,color:#000
style Out fill:#8B0000,color:#fff
```
#### Agentic Prompt Chaining
Create AI agents with sequential prompt chaining for complex workflows.
```mermaid
flowchart LR
In[In] --> LLM1[LLM Call 1] --> Gate{Gate}
Gate -->|Pass| LLM2[LLM Call 2] -->|Output 2| LLM3[LLM Call 3] --> Out[Out]
Gate -->|Fail| Exit[Exit]
style In fill:#8B0000,color:#fff
style LLM1 fill:#2E8B57,color:#fff
style LLM2 fill:#2E8B57,color:#fff
style LLM3 fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
style Exit fill:#8B0000,color:#fff
```
#### Agentic Evaluator Optimizer
Create AI agents that can generate and optimize solutions through iterative feedback.
```mermaid
flowchart LR
In[In] --> Generator[LLM Call Generator]
Generator -->|SOLUTION| Evaluator[LLM Call Evaluator] -->|ACCEPTED| Out[Out]
Evaluator -->|REJECTED + FEEDBACK| Generator
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Evaluator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
#### Repetitive Agents
Create AI agents that can efficiently handle repetitive tasks through automated loops.
```mermaid
flowchart LR
In[Input] --> LoopAgent[("Looping Agent")]
LoopAgent --> Task[Task]
Task --> |Next iteration| LoopAgent
Task --> |Done| Out[Output]
style In fill:#8B0000,color:#fff
style LoopAgent fill:#2E8B57,color:#fff,shape:circle
style Task fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
## Adding Models
<div align="center">
<a href="https://docs.praison.ai/models">
<p align="center">
<img src="https://img.shields.io/badge/%F0%9F%93%9A_Models-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Models" />
</p>
</a>
</div>
## Ollama Integration
```bash
export OPENAI_BASE_URL=http://localhost:11434/v1
```
## Groq Integration
Replace xxxx with Groq API KEY:
```bash
export OPENAI_API_KEY=xxxxxxxxxxx
export OPENAI_BASE_URL=https://api.groq.com/openai/v1
```
## No Code Options
## Agents Playbook
### Simple Playbook Example
Create `agents.yaml` file and add the code below:
```yaml
framework: praisonai
topic: Artificial Intelligence
roles:
screenwriter:
backstory: "Skilled in crafting scripts with engaging dialogue about {topic}."
goal: Create scripts from concepts.
role: Screenwriter
tasks:
scriptwriting_task:
description: "Develop scripts with compelling characters and dialogue about {topic}."
expected_output: "Complete script ready for production."
```
*To run the playbook:*
```bash
praisonai agents.yaml
```
## Use 100+ Models
- https://docs.praison.ai/models/
<div align="center">
<a href="https://docs.praison.ai">
<p align="center">
<img src="https://img.shields.io/badge/📚_Documentation-Visit_docs.praison.ai-blue?style=for-the-badge&logo=bookstack&logoColor=white" alt="Documentation" />
</p>
</a>
</div>
## Development:
Below is used for development only.
### Using uv
```bash
# Install uv if you haven't already
pip install uv
# Install from requirements
uv pip install -r pyproject.toml
# Install with extras
uv pip install -r pyproject.toml --extra code
uv pip install -r pyproject.toml --extra "crewai,autogen"
```
## Contributing
- Fork on GitHub: Use the "Fork" button on the repository page.
- Clone your fork: `git clone https://github.com/yourusername/praisonAI.git`
- Create a branch: `git checkout -b new-feature`
- Make changes and commit: `git commit -am "Add some feature"`
- Push to your fork: `git push origin new-feature`
- Submit a pull request via GitHub's web interface.
- Await feedback from project maintainers.
## Other Features
- 🔄 Use CrewAI or AG2 (Formerly AutoGen) Framework
- 💻 Chat with ENTIRE Codebase
- 🎨 Interactive UIs
- 📄 YAML-based Configuration
- 🛠️ Custom Tool Integration
- 🔍 Internet Search Capability (using Crawl4AI and Tavily)
- 🖼️ Vision Language Model (VLM) Support
- 🎙️ Real-time Voice Interaction
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=MervinPraison/PraisonAI&type=Date)](https://docs.praison.ai)
## Video Tutorials
| Topic | Video |
|-------|--------|
| AI Agents with Self Reflection | [![Self Reflection](https://img.youtube.com/vi/vLXobEN2Vc8/0.jpg)](https://www.youtube.com/watch?v=vLXobEN2Vc8) |
| Reasoning Data Generating Agent | [![Reasoning Data](https://img.youtube.com/vi/fUT332Y2zA8/0.jpg)](https://www.youtube.com/watch?v=fUT332Y2zA8) |
| AI Agents with Reasoning | [![Reasoning](https://img.youtube.com/vi/KNDVWGN3TpM/0.jpg)](https://www.youtube.com/watch?v=KNDVWGN3TpM) |
| Multimodal AI Agents | [![Multimodal](https://img.youtube.com/vi/hjAWmUT1qqY/0.jpg)](https://www.youtube.com/watch?v=hjAWmUT1qqY) |
| AI Agents Workflow | [![Workflow](https://img.youtube.com/vi/yWTH44QPl2A/0.jpg)](https://www.youtube.com/watch?v=yWTH44QPl2A) |
| Async AI Agents | [![Async](https://img.youtube.com/vi/VhVQfgo00LE/0.jpg)](https://www.youtube.com/watch?v=VhVQfgo00LE) |
| Mini AI Agents | [![Mini](https://img.youtube.com/vi/OkvYp5aAGSg/0.jpg)](https://www.youtube.com/watch?v=OkvYp5aAGSg) |
| AI Agents with Memory | [![Memory](https://img.youtube.com/vi/1hVfVxvPnnQ/0.jpg)](https://www.youtube.com/watch?v=1hVfVxvPnnQ) |
| Repetitive Agents | [![Repetitive](https://img.youtube.com/vi/dAYGxsjDOPg/0.jpg)](https://www.youtube.com/watch?v=dAYGxsjDOPg) |
| Introduction | [![Introduction](https://img.youtube.com/vi/Fn1lQjC0GO0/0.jpg)](https://www.youtube.com/watch?v=Fn1lQjC0GO0) |
| Tools Overview | [![Tools Overview](https://img.youtube.com/vi/XaQRgRpV7jo/0.jpg)](https://www.youtube.com/watch?v=XaQRgRpV7jo) |
| Custom Tools | [![Custom Tools](https://img.youtube.com/vi/JSU2Rndh06c/0.jpg)](https://www.youtube.com/watch?v=JSU2Rndh06c) |
| Firecrawl Integration | [![Firecrawl](https://img.youtube.com/vi/UoqUDcLcOYo/0.jpg)](https://www.youtube.com/watch?v=UoqUDcLcOYo) |
| User Interface | [![UI](https://img.youtube.com/vi/tg-ZjNl3OCg/0.jpg)](https://www.youtube.com/watch?v=tg-ZjNl3OCg) |
| Crawl4AI Integration | [![Crawl4AI](https://img.youtube.com/vi/KAvuVUh0XU8/0.jpg)](https://www.youtube.com/watch?v=KAvuVUh0XU8) |
| Chat Interface | [![Chat](https://img.youtube.com/vi/sw3uDqn2h1Y/0.jpg)](https://www.youtube.com/watch?v=sw3uDqn2h1Y) |
| Code Interface | [![Code](https://img.youtube.com/vi/_5jQayO-MQY/0.jpg)](https://www.youtube.com/watch?v=_5jQayO-MQY) |
| Mem0 Integration | [![Mem0](https://img.youtube.com/vi/KIGSgRxf1cY/0.jpg)](https://www.youtube.com/watch?v=KIGSgRxf1cY) |
| Training | [![Training](https://img.youtube.com/vi/aLawE8kwCrI/0.jpg)](https://www.youtube.com/watch?v=aLawE8kwCrI) |
| Realtime Voice Interface | [![Realtime](https://img.youtube.com/vi/frRHfevTCSw/0.jpg)](https://www.youtube.com/watch?v=frRHfevTCSw) |
| Call Interface | [![Call](https://img.youtube.com/vi/m1cwrUG2iAk/0.jpg)](https://www.youtube.com/watch?v=m1cwrUG2iAk) |
| Reasoning Extract Agents | [![Reasoning Extract](https://img.youtube.com/vi/2PPamsADjJA/0.jpg)](https://www.youtube.com/watch?v=2PPamsADjJA) |
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
The page will reload when you make changes.\
You may also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
-53
View File
@@ -1,53 +0,0 @@
# 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
-45
View File
@@ -1,45 +0,0 @@
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.22" \
"praisonai[api]" \
gunicorn \
markdown
# Copy application code
COPY . .
# 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"]
-33
View File
@@ -1,33 +0,0 @@
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 \
praisonai_tools \
"praisonai>=2.2.22" \
"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"]
-47
View File
@@ -1,47 +0,0 @@
FROM python:3.11-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
portaudio19-dev \
python3-pyaudio \
curl \
git \
vim \
nano \
&& 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 \
praisonai_tools \
"praisonai>=2.2.22" \
"praisonai[ui]" \
"praisonai[chat]" \
"praisonai[realtime]" \
"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
@@ -1,32 +0,0 @@
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')"]
-33
View File
@@ -1,33 +0,0 @@
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 \
praisonai_tools \
"praisonai>=2.2.22" \
"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
@@ -1,265 +0,0 @@
# 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.22`
- 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.22" "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.
-23
View File
@@ -1,23 +0,0 @@
# Use an official Python runtime as a parent image
FROM python:3.11-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install PraisonAI with the 'call' extra and ensure it's the latest version
RUN pip install --no-cache-dir --upgrade "praisonai[call]"
# Expose the port the app runs on
EXPOSE 8090
# Run the application
CMD ["praisonai", "call"]
-13
View File
@@ -1,13 +0,0 @@
# Praison AI Call Docker
1. Build the Docker image:
```
docker build -t praisonai-call .
```
2. Run the container:
```
docker run -d -p 8090:8090 praisonai-call -e OPENAI_API_KEY=your_api_key_here
```
Make sure to replace your_api_key_here with your actual OpenAI API key.
-184
View File
@@ -1,184 +0,0 @@
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
-99
View File
@@ -1,99 +0,0 @@
version: '3.8'
services:
# PraisonAI UI Service
ui:
build:
context: ..
dockerfile: docker/Dockerfile.ui
volumes:
- praison_data:/root/.praison
- .:/app
ports:
- "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
command: praisonai ui --host 0.0.0.0
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8082"]
interval: 10s
timeout: 5s
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
@@ -1,289 +0,0 @@
#!/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
-5
View File
@@ -1,5 +0,0 @@
framework: praisonaiagents
services:
- ui
- chat
- realtime
-3
View File
@@ -1,3 +0,0 @@
code:
ignore_files:
- "*/__pycache__/*"
-23
View File
@@ -1,23 +0,0 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
jobs:
post_install:
- bash docs/generate_docs.sh
mkdocs:
configuration: mkdocs.yml
fail_on_warning: true
python:
install:
- requirements: docs/requirements.txt
-1
View File
@@ -1 +0,0 @@
docs.praison.ai
-20
View File
@@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-124
View File
@@ -1,124 +0,0 @@
---
title: "AI Agents"
description: "Overview of all available PraisonAI agents and their capabilities"
icon: "robot"
---
PraisonAI provides a diverse set of specialized agents for various tasks. Each agent is designed with specific capabilities and tools to handle different types of tasks effectively.
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## Data & Analysis
<CardGroup cols={2}>
<Card title="Data Analyst" icon="chart-line" href="/agents/data-analyst">
Analyze data from various sources, create visualizations, and generate insights.
</Card>
<Card title="Finance" icon="money-bill-trend-up" href="/agents/finance">
Track stocks, analyze financial data, and provide investment recommendations.
</Card>
<Card title="Research" icon="magnifying-glass-chart" href="/agents/research">
Conduct comprehensive research and analysis across various topics.
</Card>
<Card title="Wikipedia" icon="book" href="/agents/wikipedia">
Search and extract information from Wikipedia articles.
</Card>
</CardGroup>
## Media & Content
<CardGroup cols={2}>
<Card title="Image Analysis" icon="image" href="/agents/image">
Analyze and understand visual content from images.
</Card>
<Card title="Image to Text" icon="text" href="/agents/image-to-text">
Convert images to textual descriptions and extract text content.
</Card>
<Card title="Video" icon="video" href="/agents/video">
Analyze video content and extract meaningful information.
</Card>
<Card title="Markdown" icon="markdown" href="/agents/markdown">
Generate and format content in Markdown syntax.
</Card>
</CardGroup>
## Search & Recommendations
<CardGroup cols={2}>
<Card title="Web Search" icon="globe" href="/agents/websearch">
Perform intelligent web searches and gather information.
</Card>
<Card title="Recommendation" icon="thumbs-up" href="/agents/recommendation">
Generate personalized recommendations based on preferences.
</Card>
<Card title="Shopping" icon="shop" href="/agents/shopping">
Compare prices and find the best deals across stores.
</Card>
<Card title="Planning" icon="calendar" href="/agents/planning">
Create travel plans and detailed itineraries.
</Card>
</CardGroup>
## Development
<CardGroup cols={2}>
<Card title="Programming" icon="code" href="/agents/programming">
Write, analyze, and debug code across multiple languages.
</Card>
<Card title="Single Agent" icon="circle-1" href="/agents/single">
Simple, focused agent for basic tasks without external tools.
</Card>
</CardGroup>
## Getting Started
Each agent can be easily initialized and customized for your specific needs. Here's a basic example:
```python
from praisonaiagents import Agent
# Create an agent with specific instructions
agent = Agent(instructions="Your task-specific instructions")
# Start the agent with a task
response = agent.start("Your task description")
```
For more detailed information about each agent, click on the respective cards above.
-120
View File
@@ -1,120 +0,0 @@
---
title: "Data Analyst Agent"
sidebarTitle: "Data Analyst"
description: "Learn how to create AI agents for data analysis and insights generation."
icon: "chart-line"
---
```mermaid
flowchart LR
In[Data Source] --> Reader[Data Reader]
Reader --> Analyzer[Data Analyzer]
Analyzer --> Generator[Insights Generator]
Generator --> Out[Output]
style In fill:#8B0000,color:#fff
style Reader fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Data Analyst Agent can read data from various sources, analyze it, and generate insights.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `data_analysis.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import (
read_csv, read_excel, write_csv, write_excel,
filter_data, get_summary, group_by, pivot_table
)
agent = Agent(
instructions="You are a Data Analyst Agent",
tools=[
read_csv, read_excel, write_csv, write_excel,
filter_data, get_summary, group_by, pivot_table
]
)
# Start analysis with a specific task
agent.start(f"""
Read the data from the csv file {os.path.join(os.path.dirname(__file__), "tesla-stock-price.csv")}
Analyse the data and give me the insights
read_csv to read the file
""")
```
</Step>
</Steps>
## Understanding Data Analysis Workflow
The Data Analyst Agent is designed to perform comprehensive data analysis tasks using a suite of specialized tools. Here's how it works:
1. **Data Reading**: The agent can read data from various sources:
- CSV files using `read_csv`
- Excel files using `read_excel`
2. **Data Analysis**: Multiple analysis tools are available:
- `filter_data`: Filter datasets based on conditions
- `get_summary`: Generate statistical summaries
- `group_by`: Group data by specific columns
- `pivot_table`: Create pivot tables for analysis
3. **Data Export**: Results can be exported to:
- CSV format using `write_csv`
- Excel format using `write_excel`
## Features
<CardGroup cols={2}>
<Card title="Multiple Data Sources" icon="table">
Support for both CSV and Excel file formats.
</Card>
<Card title="Analysis Tools" icon="calculator">
Comprehensive suite of analysis tools including filtering, summarization, and pivoting.
</Card>
<Card title="Data Export" icon="file-export">
Export capabilities to various formats.
</Card>
<Card title="Automated Insights" icon="lightbulb">
Automatic generation of data insights and patterns.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing stock data
agent.start("""
1. Read 'stock_data.csv'
2. Filter data for the last 30 days
3. Calculate daily returns
4. Generate summary statistics
5. Export results to 'analysis_results.xlsx'
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex analysis workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out other specialized agents like the [Finance Agent](/agents/finance) for specific use cases
-97
View File
@@ -1,97 +0,0 @@
---
title: "Finance Agent"
sidebarTitle: "Finance"
description: "Learn how to create AI agents for financial analysis and investment recommendations."
icon: "money-bill-trend-up"
---
```mermaid
flowchart LR
In[Request] --> Price[Stock Price]
Price --> Info[Stock Info]
Info --> History[Historical Data]
History --> Out[Investment Advice]
style In fill:#8B0000,color:#fff
style Price fill:#2E8B57,color:#fff
style Info fill:#2E8B57,color:#fff
style History fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Finance Agent can analyze stock market data and provide investment recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `finance_analysis.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
agent = Agent(
instructions="You are a Research Agent",
tools=[get_stock_price, get_stock_info, get_historical_data]
)
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
```
</Step>
</Steps>
## Understanding Financial Analysis
The Finance Agent specializes in stock market analysis and investment recommendations using three key components:
1. **Real-time Price Data**: Uses `get_stock_price` to fetch current market prices
2. **Company Information**: Retrieves company details using `get_stock_info`
3. **Historical Analysis**: Analyzes trends with `get_historical_data`
## Features
<CardGroup cols={2}>
<Card title="Real-time Data" icon="clock">
Access to current stock market prices and information.
</Card>
<Card title="Company Analysis" icon="building">
Detailed company information and fundamentals.
</Card>
<Card title="Historical Trends" icon="chart-line">
Analysis of historical price movements and patterns.
</Card>
<Card title="Investment Advice" icon="money-bill">
AI-powered investment recommendations.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing specific stocks
agent.start("""
1. Get current prices for AAPL and GOOGL
2. Retrieve company information
3. Analyze 6-month historical data
4. Provide investment recommendations
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex financial analysis
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
- Check out the [Data Analyst Agent](/agents/data-analyst) for detailed data analysis capabilities
-140
View File
@@ -1,140 +0,0 @@
---
title: "Image to Text Agent"
sidebarTitle: "Image to Text"
description: "Learn how to create AI agents for converting images to textual descriptions and extracting text from images."
icon: "text"
---
```mermaid
flowchart LR
In[Image Input] --> OCR[Text Extractor]
OCR --> Analyzer[Content Analyzer]
Analyzer --> Generator[Description Generator]
Generator --> Out[Text Output]
style In fill:#8B0000,color:#fff
style OCR fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Image-to-Text Agent can extract text from images and generate comprehensive descriptions.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `image_to_text.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Image-to-Text Agent
image_text_agent = Agent(
name="ImageTextConverter",
role="Image Text Extraction Specialist",
goal="Convert image content to textual descriptions and extract text",
backstory="""You are an expert in OCR and image understanding.
You excel at extracting text from images and generating detailed descriptions.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create text extraction task
extraction_task = Task(
name="extract_text",
description="Extract all text from this image and describe its layout.",
expected_output="Extracted text and layout description",
agent=image_text_agent,
images=["document.jpg"]
)
# Create description task
description_task = Task(
name="generate_description",
description="Generate a detailed description of the image content.",
expected_output="Comprehensive description of visual elements",
agent=image_text_agent,
images=["scene.jpg"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[extraction_task, description_task],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Image-to-Text Conversion
The Image-to-Text Agent combines multiple capabilities to convert visual content into textual form:
1. **OCR Processing**: Extracts text from images using optical character recognition
2. **Layout Analysis**: Understands the spatial arrangement of text and visual elements
3. **Content Description**: Generates natural language descriptions of image content
4. **Text Formatting**: Preserves text formatting and structure where possible
## Features
<CardGroup cols={2}>
<Card title="Text Extraction" icon="text">
Advanced OCR capabilities for text extraction.
</Card>
<Card title="Layout Understanding" icon="table-layout">
Analysis of text and content layout.
</Card>
<Card title="Content Description" icon="pen-to-square">
Detailed descriptions of visual content.
</Card>
<Card title="Format Preservation" icon="paragraph">
Maintains text formatting and structure.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Processing a document image
document_task = Task(
name="process_document",
description="Extract text and analyze document layout",
expected_output="Extracted text with layout information",
agent=image_text_agent,
images=["business_document.jpg"]
)
# Run single task
agents = PraisonAIAgents(
agents=[image_text_agent],
tasks=[document_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex document processing
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving text extraction accuracy
- Check out the [Image Agent](/agents/image) for pure image analysis capabilities
-139
View File
@@ -1,139 +0,0 @@
---
title: "Image Analysis Agent"
sidebarTitle: "Image Analysis"
description: "Learn how to create AI agents for image analysis and visual content understanding."
icon: "image"
---
```mermaid
flowchart LR
In[Image Input] --> Analyzer[Image Analyzer]
Analyzer --> Detector[Object Detector]
Detector --> Generator[Description Generator]
Generator --> Out[Analysis Output]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Detector fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Image Analysis Agent can process and analyze visual content, detect objects, and generate detailed descriptions.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `image_analysis.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Image Analysis Agent
image_agent = Agent(
name="ImageAnalyst",
role="Image Analysis Specialist",
goal="Analyze images and videos to extract meaningful information",
backstory="""You are an expert in computer vision and image analysis.
You excel at describing images, detecting objects, and understanding visual content.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create tasks for different types of analysis
task1 = Task(
name="analyze_landmark",
description="Describe this famous landmark and its architectural features.",
expected_output="Detailed description of the landmark's architecture and significance",
agent=image_agent,
images=["https://example.com/landmark.jpg"]
)
task2 = Task(
name="analyze_local_image",
description="What objects can you see in this image? Describe their arrangement.",
expected_output="Detailed description of objects and their spatial relationships",
agent=image_agent,
images=["local_image.jpg"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[image_agent],
tasks=[task1, task2],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Image Analysis
The Image Analysis Agent is designed to process and understand visual content through several key capabilities:
1. **Image Input**: Supports both URL and local file inputs
2. **Object Detection**: Identifies and locates objects within images
3. **Architectural Analysis**: Specialized in analyzing architectural features
4. **Spatial Understanding**: Describes spatial relationships between objects
## Features
<CardGroup cols={2}>
<Card title="Multiple Input Sources" icon="images">
Support for both URL and local image files.
</Card>
<Card title="Object Detection" icon="magnifying-glass">
Advanced object detection and recognition.
</Card>
<Card title="Architectural Analysis" icon="building">
Specialized analysis of architectural features.
</Card>
<Card title="Detailed Descriptions" icon="pen">
Generation of comprehensive visual descriptions.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyzing a landmark image
landmark_task = Task(
name="analyze_famous_landmark",
description="Analyze this historical landmark",
expected_output="Architectural details and historical significance",
agent=image_agent,
images=["https://example.com/landmark.jpg"]
)
# Run single task
agents = PraisonAIAgents(
agents=[image_agent],
tasks=[landmark_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex image analysis workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out the [Video Agent](/agents/video) for video content analysis
-120
View File
@@ -1,120 +0,0 @@
---
title: "Markdown Agent"
sidebarTitle: "Markdown"
description: "Learn how to create AI agents for generating and formatting content in Markdown."
icon: "markdown"
---
```mermaid
flowchart LR
In[Content Request] --> Generator[Content Generator]
Generator --> Formatter[Markdown Formatter]
Formatter --> Validator[Format Validator]
Validator --> Out[Markdown Output]
style In fill:#8B0000,color:#fff
style Generator fill:#2E8B57,color:#fff
style Formatter fill:#2E8B57,color:#fff
style Validator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Markdown Agent can generate and format content in Markdown syntax.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `markdown_generator.py`:
```python
from praisonaiagents import Agent
# Create Markdown Agent
markdown_agent = Agent(
name="MarkdownWriter",
role="Markdown Content Specialist",
goal="Generate well-formatted content in Markdown syntax",
instructions="You are a Markdown Agent, output in markdown format",
llm="gpt-4o-mini",
self_reflect=False
)
# Generate content
response = markdown_agent.start(
"Write a blog post about artificial intelligence"
)
# Save to file
with open('blog_post.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Markdown Generation
The Markdown Agent specializes in creating properly formatted Markdown content:
1. **Content Generation**: Creates original content based on prompts
2. **Markdown Formatting**: Applies proper Markdown syntax
3. **Structure Validation**: Ensures correct formatting
4. **Document Organization**: Creates well-structured documents
## Features
<CardGroup cols={2}>
<Card title="Content Creation" icon="pen-to-square">
Generates original, well-structured content.
</Card>
<Card title="Markdown Syntax" icon="code">
Proper implementation of Markdown formatting.
</Card>
<Card title="Document Structure" icon="sitemap">
Organized document hierarchy and sections.
</Card>
<Card title="Format Validation" icon="check">
Ensures correct Markdown syntax usage.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Generate a technical documentation
agent = Agent(
instructions="You are a Markdown Agent, output in markdown format"
)
# Generate API documentation
response = agent.start("""
Create technical documentation for a REST API with:
- Introduction
- Authentication
- Endpoints
- Examples
""")
# Save documentation
with open('api_docs.md', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex document generation
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving content quality
- Check out the [Documentation Agent](/agents/documentation) for specialized documentation generation
-109
View File
@@ -1,109 +0,0 @@
---
title: "Planning Agent"
sidebarTitle: "Planning"
description: "Learn how to create AI agents for trip planning and itinerary generation."
icon: "calendar"
---
```mermaid
flowchart LR
In[Request] --> Search[Web Search]
Search --> Analyzer[Options Analyzer]
Analyzer --> Generator[Plan Generator]
Generator --> Out[Itinerary]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Planning Agent can search for travel options and create detailed itineraries.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `travel_planner.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Planning Agent
planning_agent = Agent(
name="TravelPlanner",
role="Travel Planning Specialist",
goal="Create comprehensive travel plans and itineraries",
instructions="You are a Planning Agent",
tools=[duckduckgo]
)
# Generate travel plan
response = planning_agent.start(
"I want to go to London next week, find me a good hotel and flight"
)
# Save plan
with open('travel_plan.txt', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Travel Planning
The Planning Agent combines multiple capabilities to create comprehensive travel plans:
1. **Web Search**: Uses DuckDuckGo to find current travel options
2. **Options Analysis**: Evaluates and compares different choices
3. **Plan Generation**: Creates detailed itineraries
4. **Recommendations**: Provides personalized suggestions
## Features
<CardGroup cols={2}>
<Card title="Flight Search" icon="plane">
Finds and compares flight options.
</Card>
<Card title="Hotel Booking" icon="hotel">
Recommends suitable accommodations.
</Card>
<Card title="Itinerary Creation" icon="calendar-days">
Generates detailed travel schedules.
</Card>
<Card title="Real-time Data" icon="clock">
Uses current pricing and availability.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create a weekend trip plan
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Planning Agent", tools=[duckduckgo])
agent.start("I want to go London next week, find me a good hotel and flight")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex travel planning
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendations
- Check out the [Research Agent](/agents/research) for detailed destination research
-125
View File
@@ -1,125 +0,0 @@
---
title: "Programming Agent"
sidebarTitle: "Programming"
description: "Learn how to create AI agents for code development, analysis, and execution."
icon: "code"
---
```mermaid
flowchart LR
In[Code Request] --> Analyzer[Code Analyzer]
Analyzer --> Generator[Code Generator]
Generator --> Executor[Code Executor]
Executor --> Debugger[Code Debugger]
Debugger --> Out[Output]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Executor fill:#2E8B57,color:#fff
style Debugger fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Programming Agent can analyze, generate, execute, and debug code.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `code_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import execute_code, analyze_code, format_code, lint_code, disassemble_code # Code Tools
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info # Shell Tools
from praisonaiagents.tools import duckduckgo # Web Search Tool
agent = Agent(
instructions="You are a Programming Agent", self_reflect=True, min_reflect=5, max_reflect=10,
tools=[execute_code, analyze_code, format_code, lint_code, disassemble_code, execute_command, list_processes, kill_process, get_system_info, duckduckgo]
)
agent.start(
"Write a python script using yfinance to find the stock price of Tesla"
"First check if required packages are installed"
"Run it using execute_code"
"execute_command if you want to run any terminal command"
"search internet using duckduckgo if you want to know update python package information"
"Analyse the output using analyze_code and fix error if required"
"if no package is installed, install it"
"then run the code"
)
```
</Step>
</Steps>
## Understanding Code Development
The Programming Agent combines multiple tools for comprehensive code development:
1. **Code Tools**:
- `execute_code`: Run Python code
- `analyze_code`: Analyze code structure
- `format_code`: Format code to standards
- `lint_code`: Check code quality
- `disassemble_code`: View bytecode
2. **Shell Tools**:
- `execute_command`: Run terminal commands
- `list_processes`: View running processes
- `kill_process`: Terminate processes
- `get_system_info`: System information
3. **Web Tools**:
- `duckduckgo`: Search for programming resources
## Features
<CardGroup cols={2}>
<Card title="Code Execution" icon="play">
Run and test code directly.
</Card>
<Card title="Code Analysis" icon="magnifying-glass-code">
Analyze and improve code quality.
</Card>
<Card title="System Integration" icon="terminal">
Execute system commands and manage processes.
</Card>
<Card title="Package Management" icon="box">
Handle dependencies and installations.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create and run a data analysis script
response = agent.start("""
1. Create a script that:
- Uses pandas for data analysis
- Reads a CSV file
- Performs basic statistics
- Creates a visualization
2. Check and install required packages
3. Execute and analyze the results
""")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex development workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving code quality
- Check out the [Data Analyst Agent](/agents/data-analyst) for specialized data analysis
-109
View File
@@ -1,109 +0,0 @@
---
title: "Recommendation Agent"
sidebarTitle: "Recommendation"
description: "Learn how to create AI agents for personalized recommendations across various domains."
icon: "thumbs-up"
---
```mermaid
flowchart LR
In[User Preferences] --> Search[Content Search]
Search --> Analyzer[Preference Analyzer]
Analyzer --> Generator[Recommendation Generator]
Generator --> Out[Recommendations]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Generator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Recommendation Agent can analyze preferences and generate personalized recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `recommendation_system.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Recommendation Agent
recommendation_agent = Agent(
name="RecommendationEngine",
role="Recommendation Specialist",
goal="Generate personalized recommendations based on preferences",
instructions="You are a Recommendation Agent",
tools=[duckduckgo]
)
# Get recommendations
response = recommendation_agent.start(
"Recommend me a good movie to watch in 2025"
)
# Save recommendations
with open('recommendations.txt', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Recommendation System
The Recommendation Agent uses multiple approaches to generate personalized suggestions:
1. **Content Search**: Uses DuckDuckGo to find current options
2. **Preference Analysis**: Understands user preferences
3. **Recommendation Generation**: Creates personalized suggestions
4. **Content Filtering**: Filters based on relevance and quality
## Features
<CardGroup cols={2}>
<Card title="Personalization" icon="user">
Tailored recommendations based on preferences.
</Card>
<Card title="Real-time Data" icon="clock">
Up-to-date content and information.
</Card>
<Card title="Multi-domain" icon="layer-group">
Recommendations across various categories.
</Card>
<Card title="Content Filtering" icon="filter">
Quality-based content selection.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Get personalized recommendations
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Recommendation Agent", tools=[duckduckgo])
agent.start("Recommend me a good movie to watch in 2025")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex recommendation systems
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
- Check out the [Research Agent](/agents/research) for detailed content research
-108
View File
@@ -1,108 +0,0 @@
---
title: "Research Agent"
sidebarTitle: "Research"
description: "Learn how to create AI agents for conducting comprehensive research and analysis."
icon: "magnifying-glass-chart"
---
```mermaid
flowchart LR
In[Research Query] --> Search[Web Search]
Search --> Analyzer[Content Analyzer]
Analyzer --> Synthesizer[Information Synthesizer]
Synthesizer --> Out[Research Report]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Synthesizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Research Agent can gather, analyze, and synthesize information from various sources.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `research_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Research Agent
research_agent = Agent(
name="ResearchAssistant",
role="Research Specialist",
goal="Conduct comprehensive research and analysis",
instructions="You are a Research Agent",
tools=[duckduckgo]
)
# Conduct research
response = research_agent.start(
"Research about AI developments in 2024"
)
# Save research findings
with open('research_report.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Research Process
The Research Agent employs a systematic approach to information gathering and analysis:
1. **Web Search**: Uses DuckDuckGo to find relevant sources
2. **Content Analysis**: Evaluates source credibility and relevance
3. **Information Synthesis**: Combines findings into coherent insights
4. **Report Generation**: Creates structured research reports
## Features
<CardGroup cols={2}>
<Card title="Web Research" icon="globe">
Comprehensive online information gathering.
</Card>
<Card title="Content Analysis" icon="microscope">
In-depth evaluation of sources.
</Card>
<Card title="Information Synthesis" icon="layer-group">
Integration of multiple sources.
</Card>
<Card title="Report Generation" icon="file-lines">
Structured research documentation.
</Card>
</CardGroup>
## Example Usage
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
agent.start("Research about AI 2024")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex research projects
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
- Check out the [Data Analyst Agent](/agents/data-analyst) for data-driven research
-109
View File
@@ -1,109 +0,0 @@
---
title: "Shopping Agent"
sidebarTitle: "Shopping"
description: "Learn how to create AI agents for price comparison and shopping assistance."
icon: "shop"
---
```mermaid
flowchart LR
In[Product Query] --> Search[Store Search]
Search --> Analyzer[Price Analyzer]
Analyzer --> Comparator[Price Comparator]
Comparator --> Out[Price Report]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Comparator fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Shopping Agent can search for products, compare prices, and provide shopping recommendations.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `shopping_assistant.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Shopping Agent
shopping_agent = Agent(
name="ShoppingAssistant",
role="Shopping Specialist",
goal="Find the best prices and deals across stores",
instructions="You are a Shopping Agent",
tools=[duckduckgo]
)
# Search for product prices
response = shopping_agent.start(
"I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table"
)
# Save price comparison
with open('price_comparison.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Shopping Assistant
The Shopping Agent combines multiple capabilities for effective price comparison:
1. **Store Search**: Uses DuckDuckGo to find retailers
2. **Price Analysis**: Gathers pricing information
3. **Price Comparison**: Compares prices across stores
4. **Deal Finding**: Identifies special offers and discounts
## Features
<CardGroup cols={2}>
<Card title="Price Comparison" icon="scale-balanced">
Compare prices across multiple stores.
</Card>
<Card title="Deal Detection" icon="tag">
Find special offers and discounts.
</Card>
<Card title="Store Analysis" icon="store">
Evaluate retailer reliability.
</Card>
<Card title="Price Tracking" icon="chart-line">
Monitor price changes over time.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Compare product prices
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(instructions="You are a Shopping Agent", tools=[duckduckgo])
agent.start("I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table")
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex shopping research
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving price accuracy
- Check out the [Research Agent](/agents/research) for detailed product research
-102
View File
@@ -1,102 +0,0 @@
---
title: "Single Agent"
sidebarTitle: "Single"
description: "Learn how to create a basic single-purpose AI agent for simple tasks."
icon: "circle-1"
---
```mermaid
flowchart LR
In[Input] --> Agent[Single Agent]
Agent --> Out[Output]
style In fill:#8B0000,color:#fff
style Agent fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how to create and use a simple single-purpose agent.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `simple_agent.py`:
```python
from praisonaiagents import Agent
agent = Agent(instructions="You are a Markdown Agent, output in markdown format")
agent.start("Write a blog post about AI")
```
</Step>
</Steps>
## Understanding Single Agent
The Single Agent is the simplest form of PraisonAI agent:
1. **Simple Setup**: Minimal configuration required
2. **Single Purpose**: Focused on one specific task
3. **Direct Execution**: Straightforward input-output flow
4. **No Dependencies**: No external tools required
## Features
<CardGroup cols={2}>
<Card title="Simple Setup" icon="square-1">
Minimal configuration needed.
</Card>
<Card title="Focused Task" icon="bullseye">
Single-purpose execution.
</Card>
<Card title="Quick Start" icon="bolt">
Rapid implementation.
</Card>
<Card title="No Tools" icon="toolbox">
No external dependencies.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Create a content generation agent
from praisonaiagents import Agent
# Create content agent
agent = Agent(
instructions="You are a Content Generation Agent, create engaging content"
)
# Generate content
response = agent.start("""
Write a short story about:
- A future world
- With advanced AI
- And human collaboration
""")
# Save the story
with open('ai_story.txt', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for more complex workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving output quality
- Check out other specialized agents like the [Markdown Agent](/agents/markdown) for specific use cases
-149
View File
@@ -1,149 +0,0 @@
---
title: "Video Agent"
sidebarTitle: "Video"
description: "Learn how to create AI agents for video analysis and content understanding."
icon: "video"
---
```mermaid
flowchart LR
In[Video Input] --> Analyzer[Content Analyzer]
Analyzer --> Detector[Object Detector]
Detector --> Transcriber[Text Transcriber]
Transcriber --> Out[Analysis Report]
style In fill:#8B0000,color:#fff
style Analyzer fill:#2E8B57,color:#fff
style Detector fill:#2E8B57,color:#fff
style Transcriber fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Video Agent can analyze video content, detect objects, and extract meaningful information.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `video_analyzer.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create Video Analysis Agent
video_agent = Agent(
name="VideoAnalyst",
role="Video Analysis Specialist",
goal="Analyze videos to extract meaningful information",
backstory="""You are an expert in computer vision and video analysis.
You excel at describing content, detecting objects, and understanding context.""",
llm="gpt-4o-mini",
self_reflect=False
)
# Create video analysis task
analysis_task = Task(
name="analyze_video",
description="""Analyze this video and provide:
1. Summary of main events
2. Key objects and people
3. Text and important information
4. Context and setting""",
expected_output="Comprehensive video analysis",
agent=video_agent,
images=["video.mp4"]
)
# Create PraisonAIAgents instance
agents = PraisonAIAgents(
agents=[video_agent],
tasks=[analysis_task],
process="sequential",
verbose=1
)
# Run analysis
agents.start()
```
</Step>
</Steps>
## Understanding Video Analysis
The Video Agent combines multiple capabilities for comprehensive video understanding:
1. **Content Analysis**: Analyzes video scenes and events
2. **Object Detection**: Identifies objects and people
3. **Text Extraction**: Captures text shown in videos
4. **Context Understanding**: Interprets settings and situations
## Features
<CardGroup cols={2}>
<Card title="Scene Analysis" icon="film">
Detailed analysis of video scenes.
</Card>
<Card title="Object Detection" icon="cube">
Identification of objects and people.
</Card>
<Card title="Text Extraction" icon="closed-captioning">
Capture of text and captions.
</Card>
<Card title="Context Analysis" icon="sitemap">
Understanding of video context.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Analyze a presentation video
from praisonaiagents import Agent, Task, PraisonAIAgents
video_agent = Agent(
name="VideoAnalyst",
role="Video Analysis Specialist",
goal="Extract information from presentation videos",
llm="gpt-4o-mini"
)
# Create presentation analysis task
presentation_task = Task(
name="analyze_presentation",
description="""Analyze this presentation video:
1. Extract key points
2. Capture slide content
3. Note speaker's main arguments
4. Summarize Q&A session""",
expected_output="Detailed presentation summary",
agent=video_agent,
images=["presentation.mp4"]
)
# Run analysis
agents = PraisonAIAgents(
agents=[video_agent],
tasks=[presentation_task],
process="sequential"
)
agents.start()
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex video analysis
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
- Check out the [Image Agent](/agents/image) for still image analysis
-124
View File
@@ -1,124 +0,0 @@
---
title: "Web Search Agent"
sidebarTitle: "Web Search"
description: "Learn how to create AI agents for intelligent web searching and information gathering."
icon: "globe"
---
```mermaid
flowchart LR
In[Search Query] --> Search[Web Search]
Search --> Filter[Content Filter]
Filter --> Summarizer[Content Summarizer]
Summarizer --> Out[Search Results]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Filter fill:#2E8B57,color:#fff
style Summarizer fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Web Search Agent can perform intelligent searches and process web content.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `web_search.py`:
```python
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
# Create Web Search Agent
search_agent = Agent(
name="WebSearcher",
role="Web Search Specialist",
goal="Perform intelligent web searches and gather information",
instructions="You are a Web Search Agent",
tools=[duckduckgo]
)
# Perform search
response = search_agent.start(
"Search about AI developments in 2024"
)
# Save search results
with open('search_results.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Web Search
The Web Search Agent employs sophisticated search strategies:
1. **Query Processing**: Optimizes search queries
2. **Content Filtering**: Filters relevant results
3. **Information Extraction**: Extracts key information
4. **Result Summarization**: Summarizes findings
## Features
<CardGroup cols={2}>
<Card title="Smart Search" icon="magnifying-glass">
Intelligent query processing.
</Card>
<Card title="Content Filtering" icon="filter">
Relevance-based filtering.
</Card>
<Card title="Information Extraction" icon="scissors">
Key information extraction.
</Card>
<Card title="Result Summary" icon="list">
Concise result summaries.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Perform topic research
from praisonaiagents import Agent, Tools
from praisonaiagents.tools import duckduckgo
agent = Agent(
instructions="You are a Web Search Agent",
tools=[duckduckgo]
)
# Research specific topic
response = agent.start("""
Search for information about quantum computing:
- Recent breakthroughs
- Leading companies
- Current applications
- Future predictions
""")
# Save research results
with open('quantum_computing_research.md', 'w') as f:
f.write(response)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex search workflows
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving search relevance
- Check out the [Research Agent](/agents/research) for comprehensive research capabilities
-139
View File
@@ -1,139 +0,0 @@
---
title: "Wikipedia Agent"
sidebarTitle: "Wikipedia"
description: "Learn how to create AI agents for searching and extracting information from Wikipedia."
icon: "book"
---
```mermaid
flowchart LR
In[Query] --> Search[Wiki Search]
Search --> Page[Page Retrieval]
Page --> Summary[Content Summary]
Summary --> Out[Knowledge Output]
style In fill:#8B0000,color:#fff
style Search fill:#2E8B57,color:#fff
style Page fill:#2E8B57,color:#fff
style Summary fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
A workflow demonstrating how the Wikipedia Agent can search, retrieve, and summarize Wikipedia content.
## Quick Start
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install praisonaiagents
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create Script">
Create a new file `wikipedia_assistant.py`:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import (
wiki_search,
wiki_summary,
wiki_page,
wiki_random,
wiki_language
)
# Create Wikipedia Agent
wiki_agent = Agent(
name="WikipediaAssistant",
role="Wikipedia Research Specialist",
goal="Extract and summarize Wikipedia content",
instructions="You are a Wikipedia Agent",
tools=[
wiki_search,
wiki_summary,
wiki_page,
wiki_random,
wiki_language
],
self_reflect=True,
min_reflect=3,
max_reflect=5
)
# Research a topic
response = wiki_agent.start("""
What is the history of AI?
First search the history of AI
Read the page of the history of AI
Get the summary of the page
""")
# Save research results
with open('ai_history.md', 'w') as f:
f.write(response)
```
</Step>
</Steps>
## Understanding Wikipedia Research
The Wikipedia Agent provides comprehensive Wikipedia access through multiple tools:
1. **Wiki Search**: `wiki_search` for finding relevant articles
2. **Page Access**: `wiki_page` for retrieving full articles
3. **Summarization**: `wiki_summary` for concise overviews
4. **Random Articles**: `wiki_random` for discovering content
5. **Language Support**: `wiki_language` for multilingual access
## Features
<CardGroup cols={2}>
<Card title="Article Search" icon="magnifying-glass">
Find relevant Wikipedia articles.
</Card>
<Card title="Content Retrieval" icon="book-open">
Access complete article content.
</Card>
<Card title="Summarization" icon="compress">
Generate concise article summaries.
</Card>
<Card title="Multilingual" icon="language">
Access content in multiple languages.
</Card>
</CardGroup>
## Example Usage
```python
# Example: Research a scientific topic
from praisonaiagents import Agent
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
agent = Agent(
instructions="You are a Wikipedia Agent",
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
self_reflect=True,
min_reflect=3,
max_reflect=5,
)
agent.start(
"What is the history of AI?"
"First search the history of AI"
"Read the page of the history of AI"
"Get the summary of the page"
)
```
## Next Steps
- Learn about [Prompt Chaining](/features/promptchaining) for complex Wikipedia research
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
- Check out the [Research Agent](/agents/research) for broader research capabilities
-45
View File
@@ -1,45 +0,0 @@
---
title: 'API Reference'
description: 'PraisonAI API documentation with framework-specific details'
icon: "book-open"
---
# API Reference
This section provides detailed information about the PraisonAI API and its framework-specific implementations.
## Core Modules
- [praisonai](../api/praisonai/index) - Core package functionality
- [praisonai.auto](../api/praisonai/auto) - Automated agent generation
- [praisonai.agents_generator](../api/praisonai/agents_generator) - Framework-specific agent generation
- [praisonai.cli](../api/praisonai/cli) - Command-line interface
- [praisonai.deploy](../api/praisonai/deploy) - Deployment utilities
## Framework Support
### CrewAI Integration
Requires installation with:
```bash
pip install "praisonai[crewai]"
```
Features:
- Task delegation
- Sequential/parallel execution
- Built-in tools
- Structured workflows
### AG2 (Formerly AutoGen) Integration
Requires installation with:
```bash
pip install "praisonai[autogen]"
```
Features:
- Multi-agent conversations
- Code execution
- Built-in tools
- Flexible interactions
For detailed API documentation of each module, please refer to the generated files in the `api` folder.
-79
View File
@@ -1,79 +0,0 @@
---
title: "API Reference"
description: "Complete API reference for PraisonAI, including core modules, installation options, and framework-specific features"
icon: "code"
---
## Core Modules
### praisonai
The main package containing core functionality.
```python
from praisonai import PraisonAI
```
### praisonai.auto
Automated agent generation functionality.
```python
from praisonai.auto import AutoGenerator
```
### praisonai.agents_generator
Framework-specific agent generation and orchestration:
- CrewAI support (requires `praisonai[crewai]`)
- AG2 (Formerly AutoGen) support (requires `praisonai[autogen]`)
```python
from praisonai.agents_generator import AgentsGenerator
```
### praisonai.cli
Command-line interface with framework-specific handling.
```python
from praisonai.cli import PraisonAI
```
### praisonai.deploy
Deployment utilities.
```python
from praisonai.deploy import CloudDeployer
```
## Installation Options
```bash
# Basic installation
pip install praisonai
# Framework-specific installations
pip install "praisonai[crewai]" # Install with CrewAI support
pip install "praisonai[autogen]" # Install with AG2 support
pip install "praisonai[crewai,autogen]" # Install both frameworks
# Additional features
pip install "praisonai[ui]" # Install UI support
pip install "praisonai[chat]" # Install Chat interface
pip install "praisonai[code]" # Install Code interface
pip install "praisonai[realtime]" # Install Realtime voice interaction
pip install "praisonai[call]" # Install Call feature
```
## Framework-specific Features
### CrewAI
When installing with `pip install "praisonai[crewai]"`, you get:
- CrewAI framework support
- PraisonAI tools integration
- Task delegation capabilities
- Sequential and parallel task execution
### AG2 (Formerly AutoGen)
When installing with `pip install "praisonai[autogen]"`, you get:
- AG2 framework support
- PraisonAI tools integration
- Multi-agent conversation capabilities
- Code execution environment
-566
View File
@@ -1,566 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.agents_generator API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.agents_generator</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.agents_generator.disable_crewai_telemetry"><code class="name flex">
<span>def <span class="ident">disable_crewai_telemetry</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.agents_generator.noop"><code class="name flex">
<span>def <span class="ident">noop</span></span>(<span>*args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator"><code class="flex name class">
<span>class <span class="ident">AgentsGenerator</span></span>
<span>(</span><span>agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AgentsGenerator object.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The path to the agent file.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to be used for the agents.</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configurations for the agents.</dd>
<dt><strong><code>log_level</code></strong> :&ensp;<code>int</code></dt>
<dd>The logging level to use.</dd>
<dt><strong><code>agent_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each agent step.</dd>
<dt><strong><code>task_callback</code></strong> :&ensp;<code>callable</code>, optional</dt>
<dd>A callback function to be executed after each tool run.</dd>
<dt><strong><code>tools</code></strong> :&ensp;<code>dict</code></dt>
<dd>A dictionary containing the tools to be used for the agents.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AgentsGenerator:
def __init__(self, agent_file, framework, config_list, log_level=None, agent_callback=None, task_callback=None, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the AgentsGenerator object.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int, optional): The logging level to use. Defaults to logging.INFO.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
tools (dict, optional): A dictionary containing the tools to be used for the agents. Defaults to None.
Attributes:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
log_level (int): The logging level to use.
agent_callback (callable, optional): A callback function to be executed after each agent step.
task_callback (callable, optional): A callback function to be executed after each tool run.
tools (dict): A dictionary containing the tools to be used for the agents.
&#34;&#34;&#34;
self.agent_file = agent_file
self.framework = framework
self.config_list = config_list
self.log_level = log_level
self.agent_callback = agent_callback
self.task_callback = task_callback
self.agent_yaml = agent_yaml
self.tools = tools or [] # Store tool class names as a list
self.log_level = log_level or logging.getLogger().getEffectiveLevel()
if self.log_level == logging.NOTSET:
self.log_level = os.environ.get(&#39;LOGLEVEL&#39;, &#39;INFO&#39;).upper()
logging.basicConfig(level=self.log_level, format=&#39;%(asctime)s - %(levelname)s - %(message)s&#39;)
self.logger = logging.getLogger(__name__)
self.logger.setLevel(self.log_level)
def is_function_or_decorated(self, obj):
&#34;&#34;&#34;
Checks if the given object is a function or has a __call__ method.
Parameters:
obj (object): The object to be checked.
Returns:
bool: True if the object is a function or has a __call__ method, False otherwise.
&#34;&#34;&#34;
return inspect.isfunction(obj) or hasattr(obj, &#39;__call__&#39;)
def load_tools_from_module(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj for name, obj in inspect.getmembers(module, self.is_function_or_decorated)}
def load_tools_from_module_class(self, module_path):
&#34;&#34;&#34;
Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.
Parameters:
module_path (str): The path to the module containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified module path does not exist.
&#34;&#34;&#34;
spec = importlib.util.spec_from_file_location(&#34;tools_module&#34;, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return {name: obj() for name, obj in inspect.getmembers(module, lambda x: inspect.isclass(x) and (x.__module__.startswith(&#39;langchain_community.tools&#39;) or issubclass(x, BaseTool)) and x is not BaseTool)}
def load_tools_from_package(self, package_path):
&#34;&#34;&#34;
Loads tools from a specified package path containing modules with functions or classes.
Parameters:
package_path (str): The path to the package containing the tools.
Returns:
dict: A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
Raises:
FileNotFoundError: If the specified package path does not exist.
This function iterates through all the .py files in the specified package path, excluding those that start with &#34;__&#34;. For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.
&#34;&#34;&#34;
tools_dict = {}
for module_file in os.listdir(package_path):
if module_file.endswith(&#39;.py&#39;) and not module_file.startswith(&#39;__&#39;):
module_name = f&#34;{package_path.name}.{module_file[:-3]}&#34; # Remove .py for import
module = importlib.import_module(module_name)
for name, obj in inspect.getmembers(module, self.is_function_or_decorated):
tools_dict[name] = obj
return tools_dict
def generate_crew_and_kickoff(self):
&#34;&#34;&#34;
Generates a crew of agents and initiates tasks based on the provided configuration.
Parameters:
agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.
Returns:
str: The output of the tasks performed by the crew of agents.
Raises:
FileNotFoundError: If the specified agent file does not exist.
This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is &#34;autogen&#34;, it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not &#34;autogen&#34;, it creates a crew of agents and initiates tasks based on the configuration.
&#34;&#34;&#34;
if self.agent_yaml:
config = yaml.safe_load(self.agent_yaml)
else:
if self.agent_file == &#39;/app/api:app&#39; or self.agent_file == &#39;api:app&#39;:
self.agent_file = &#39;agents.yaml&#39;
try:
with open(self.agent_file, &#39;r&#39;) as f:
config = yaml.safe_load(f)
except FileNotFoundError:
print(f&#34;File not found: {self.agent_file}&#34;)
return
topic = config[&#39;topic&#39;]
tools_dict = {
&#39;CodeDocsSearchTool&#39;: CodeDocsSearchTool(),
&#39;CSVSearchTool&#39;: CSVSearchTool(),
&#39;DirectorySearchTool&#39;: DirectorySearchTool(),
&#39;DOCXSearchTool&#39;: DOCXSearchTool(),
&#39;DirectoryReadTool&#39;: DirectoryReadTool(),
&#39;FileReadTool&#39;: FileReadTool(),
# &#39;GithubSearchTool&#39;: GithubSearchTool(),
# &#39;SeperDevTool&#39;: SeperDevTool(),
&#39;TXTSearchTool&#39;: TXTSearchTool(),
&#39;JSONSearchTool&#39;: JSONSearchTool(),
&#39;MDXSearchTool&#39;: MDXSearchTool(),
&#39;PDFSearchTool&#39;: PDFSearchTool(),
# &#39;PGSearchTool&#39;: PGSearchTool(),
&#39;RagTool&#39;: RagTool(),
&#39;ScrapeElementFromWebsiteTool&#39;: ScrapeElementFromWebsiteTool(),
&#39;ScrapeWebsiteTool&#39;: ScrapeWebsiteTool(),
&#39;WebsiteSearchTool&#39;: WebsiteSearchTool(),
&#39;XMLSearchTool&#39;: XMLSearchTool(),
&#39;YoutubeChannelSearchTool&#39;: YoutubeChannelSearchTool(),
&#39;YoutubeVideoSearchTool&#39;: YoutubeVideoSearchTool(),
}
# Add tools from class names
for tool_class in self.tools:
if isinstance(tool_class, type) and issubclass(tool_class, BaseTool):
tool_name = tool_class.__name__
tools_dict[tool_name] = tool_class()
self.logger.debug(f&#34;Added tool: {tool_name}&#34;)
root_directory = os.getcwd()
tools_py_path = os.path.join(root_directory, &#39;tools.py&#39;)
tools_dir_path = Path(root_directory) / &#39;tools&#39;
if os.path.isfile(tools_py_path):
tools_dict.update(self.load_tools_from_module_class(tools_py_path))
self.logger.debug(&#34;tools.py exists in the root directory. Loading tools.py and skipping tools folder.&#34;)
elif tools_dir_path.is_dir():
tools_dict.update(self.load_tools_from_module_class(tools_dir_path))
self.logger.debug(&#34;tools folder exists in the root directory&#34;)
framework = self.framework or config.get(&#39;framework&#39;)
agents = {}
tasks = []
if framework == &#34;autogen&#34;:
# Load the LLM configuration dynamically
# print(self.config_list)
llm_config = {&#34;config_list&#34;: self.config_list}
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;autogen&#34;])
# Assuming the user proxy agent is set up as per your requirements
user_proxy = autogen.UserProxyAgent(
name=&#34;User&#34;,
human_input_mode=&#34;NEVER&#34;,
is_termination_msg=lambda x: (x.get(&#34;content&#34;) or &#34;&#34;).rstrip().rstrip(&#34;.&#34;).lower().endswith(&#34;terminate&#34;) or &#34;TERMINATE&#34; in (x.get(&#34;content&#34;) or &#34;&#34;),
code_execution_config={
&#34;work_dir&#34;: &#34;coding&#34;,
&#34;use_docker&#34;: False,
},
# additional setup for the user proxy agent
)
for role, details in config[&#39;roles&#39;].items():
agent_name = details[&#39;role&#39;].format(topic=topic).replace(&#34;{topic}&#34;, topic)
agent_goal = details[&#39;goal&#39;].format(topic=topic)
# Creating an AssistantAgent for each role dynamically
agents[role] = autogen.AssistantAgent(
name=agent_name,
llm_config=llm_config,
system_message=details[&#39;backstory&#39;].format(topic=topic)+&#34;. Must Reply \&#34;TERMINATE\&#34; in the end when everything is done.&#34;,
)
for tool in details.get(&#39;tools&#39;, []):
if tool in tools_dict:
try:
tool_class = globals()[f&#39;autogen_{type(tools_dict[tool]).__name__}&#39;]
print(f&#34;Found {tool_class.__name__} for {tool}&#34;)
except KeyError:
print(f&#34;Warning: autogen_{type(tools_dict[tool]).__name__} function not found. Skipping this tool.&#34;)
continue
tool_class(agents[role], user_proxy)
# Preparing tasks for initiate_chats
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
chat_task = {
&#34;recipient&#34;: agents[role],
&#34;message&#34;: description_filled,
&#34;summary_method&#34;: &#34;last_msg&#34;,
# Additional fields like carryover can be added based on dependencies
}
tasks.append(chat_task)
response = user_proxy.initiate_chats(tasks)
result = &#34;### Output ###\n&#34;+response[-1].summary if hasattr(response[-1], &#39;summary&#39;) else &#34;&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
else: # framework=crewai
if agentops_exists:
agentops.init(os.environ.get(&#34;AGENTOPS_API_KEY&#34;), tags=[&#34;crewai&#34;])
tasks_dict = {}
for role, details in config[&#39;roles&#39;].items():
role_filled = details[&#39;role&#39;].format(topic=topic)
goal_filled = details[&#39;goal&#39;].format(topic=topic)
backstory_filled = details[&#39;backstory&#39;].format(topic=topic)
# Adding tools to the agent if exists
agent_tools = [tools_dict[tool] for tool in details.get(&#39;tools&#39;, []) if tool in tools_dict]
llm_model = details.get(&#39;llm&#39;) # Get the llm configuration
if llm_model:
llm = PraisonAIModel(
model=llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
llm = PraisonAIModel().get_model()
function_calling_llm_model = details.get(&#39;function_calling_llm&#39;)
if function_calling_llm_model:
function_calling_llm = PraisonAIModel(
model=function_calling_llm_model.get(&#34;model&#34;, os.environ.get(&#34;MODEL_NAME&#34;, &#34;openai/gpt-4o&#34;)),
).get_model()
else:
function_calling_llm = PraisonAIModel().get_model()
agent = Agent(
role=role_filled,
goal=goal_filled,
backstory=backstory_filled,
tools=agent_tools,
allow_delegation=details.get(&#39;allow_delegation&#39;, False),
llm=llm,
function_calling_llm=function_calling_llm,
max_iter=details.get(&#39;max_iter&#39;, 15),
max_rpm=details.get(&#39;max_rpm&#39;),
max_execution_time=details.get(&#39;max_execution_time&#39;),
verbose=details.get(&#39;verbose&#39;, True),
cache=details.get(&#39;cache&#39;, True),
system_template=details.get(&#39;system_template&#39;),
prompt_template=details.get(&#39;prompt_template&#39;),
response_template=details.get(&#39;response_template&#39;),
)
# Set agent callback if provided
if self.agent_callback:
agent.step_callback = self.agent_callback
agents[role] = agent
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
description_filled = task_details[&#39;description&#39;].format(topic=topic)
expected_output_filled = task_details[&#39;expected_output&#39;].format(topic=topic)
task = Task(
description=description_filled, # Clear, concise statement of what the task entails
expected_output=expected_output_filled, # Detailed description of what task&#39;s completion looks like
agent=agent, # The agent responsible for the task
tools=task_details.get(&#39;tools&#39;, []), # Functions or capabilities the agent can utilize
async_execution=task_details.get(&#39;async_execution&#39;) if task_details.get(&#39;async_execution&#39;) is not None else False, # Execute asynchronously if set
context=[], ## TODO:
config=task_details.get(&#39;config&#39;) if task_details.get(&#39;config&#39;) is not None else {}, # Additional configuration details
output_json=task_details.get(&#39;output_json&#39;) if task_details.get(&#39;output_json&#39;) is not None else None, # Outputs a JSON object
output_pydantic=task_details.get(&#39;output_pydantic&#39;) if task_details.get(&#39;output_pydantic&#39;) is not None else None, # Outputs a Pydantic model object
output_file=task_details.get(&#39;output_file&#39;) if task_details.get(&#39;output_file&#39;) is not None else &#34;&#34;, # Saves the task output to a file
callback=task_details.get(&#39;callback&#39;) if task_details.get(&#39;callback&#39;) is not None else None, # Python callable executed with the task&#39;s output
human_input=task_details.get(&#39;human_input&#39;) if task_details.get(&#39;human_input&#39;) is not None else False, # Indicates if the task requires human feedback
create_directory=task_details.get(&#39;create_directory&#39;) if task_details.get(&#39;create_directory&#39;) is not None else False # Indicates if a directory needs to be created
)
# Set tool callback if provided
if self.task_callback:
task.callback = self.task_callback
tasks.append(task)
tasks_dict[task_name] = task
for role, details in config[&#39;roles&#39;].items():
for task_name, task_details in details.get(&#39;tasks&#39;, {}).items():
task = tasks_dict[task_name]
context_tasks = [tasks_dict[ctx] for ctx in task_details.get(&#39;context&#39;, []) if ctx in tasks_dict]
task.context = context_tasks
crew = Crew(
agents=list(agents.values()),
tasks=tasks,
verbose=2
)
self.logger.debug(&#34;Final Crew Configuration:&#34;)
self.logger.debug(f&#34;Agents: {crew.agents}&#34;)
self.logger.debug(f&#34;Tasks: {crew.tasks}&#34;)
response = crew.kickoff()
result = f&#34;### Task Output ###\n{response}&#34;
if agentops_exists:
agentops.end_session(&#34;Success&#34;)
return result</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff"><code class="name flex">
<span>def <span class="ident">generate_crew_and_kickoff</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a crew of agents and initiates tasks based on the provided configuration.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The path to the agent file.
framework (str): The framework to be used for the agents.
config_list (list): A list of configurations for the agents.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The output of the tasks performed by the crew of agents.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified agent file does not exist.</dd>
</dl>
<p>This function first loads the agent configuration from the specified file. It then initializes the tools required for the agents based on the specified framework. If the specified framework is "autogen", it loads the LLM configuration dynamically and creates an AssistantAgent for each role in the configuration. It then adds tools to the agents if specified in the configuration. Finally, it prepares tasks for the agents based on the configuration and initiates the tasks using the crew of agents. If the specified framework is not "autogen", it creates a crew of agents and initiates tasks based on the configuration.</p></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated"><code class="name flex">
<span>def <span class="ident">is_function_or_decorated</span></span>(<span>self, obj)</span>
</code></dt>
<dd>
<div class="desc"><p>Checks if the given object is a function or has a <strong>call</strong> method.</p>
<h2 id="parameters">Parameters</h2>
<p>obj (object): The object to be checked.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>bool</code></dt>
<dd>True if the object is a function or has a <strong>call</strong> method, False otherwise.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module"><code class="name flex">
<span>def <span class="ident">load_tools_from_module</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding functions or objects as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class"><code class="name flex">
<span>def <span class="ident">load_tools_from_module_class</span></span>(<span>self, module_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified module path containing classes that inherit from BaseTool or are part of langchain_community.tools package.</p>
<h2 id="parameters">Parameters</h2>
<p>module_path (str): The path to the module containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified module path does not exist.</dd>
</dl></div>
</dd>
<dt id="praisonai.agents_generator.AgentsGenerator.load_tools_from_package"><code class="name flex">
<span>def <span class="ident">load_tools_from_package</span></span>(<span>self, package_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads tools from a specified package path containing modules with functions or classes.</p>
<h2 id="parameters">Parameters</h2>
<p>package_path (str): The path to the package containing the tools.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>dict</code></dt>
<dd>A dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>FileNotFoundError</code></dt>
<dd>If the specified package path does not exist.</dd>
</dl>
<p>This function iterates through all the .py files in the specified package path, excluding those that start with "__". For each file, it imports the corresponding module and checks if it contains any functions or classes that can be loaded as tools. The function then returns a dictionary containing the names of the tools as keys and the corresponding initialized instances of the classes as values.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.agents_generator.disable_crewai_telemetry" href="#praisonai.agents_generator.disable_crewai_telemetry">disable_crewai_telemetry</a></code></li>
<li><code><a title="praisonai.agents_generator.noop" href="#praisonai.agents_generator.noop">noop</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.agents_generator.AgentsGenerator" href="#praisonai.agents_generator.AgentsGenerator">AgentsGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff" href="#praisonai.agents_generator.AgentsGenerator.generate_crew_and_kickoff">generate_crew_and_kickoff</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.is_function_or_decorated" href="#praisonai.agents_generator.AgentsGenerator.is_function_or_decorated">is_function_or_decorated</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module">load_tools_from_module</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_module_class">load_tools_from_module_class</a></code></li>
<li><code><a title="praisonai.agents_generator.AgentsGenerator.load_tools_from_package" href="#praisonai.agents_generator.AgentsGenerator.load_tools_from_package">load_tools_from_package</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-622
View File
@@ -1,622 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.auto API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.auto</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.auto.AutoGenerator"><code class="flex name class">
<span>class <span class="ident">AutoGenerator</span></span>
<span>(</span><span>topic='Movie Story writing about AI', agent_file='test.yaml', framework='crewai', config_list: Optional[List[Dict]] = None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic for the generated team structure. Defaults to "Movie Story writing about AI".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save the generated team structure. Defaults to "test.yaml".</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The framework for the generated team structure. Defaults to "crewai".</dd>
<dt><strong><code>config_list</code></strong> :&ensp;<code>Optional[List[Dict]]</code>, optional</dt>
<dd>A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.</dd>
</dl>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the configuration details for the OpenAI API.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified topic for the generated team structure.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified name of the YAML file to save the generated team structure.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The specified framework for the generated team structure.</dd>
<dt><strong><code>client</code></strong> :&ensp;<code>instructor.Client</code></dt>
<dd>An instance of the instructor.Client class initialized with the specified OpenAI API configuration.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class AutoGenerator:
def __init__(self, topic=&#34;Movie Story writing about AI&#34;, agent_file=&#34;test.yaml&#34;, framework=&#34;crewai&#34;, config_list: Optional[List[Dict]] = None):
&#34;&#34;&#34;
Initialize the AutoGenerator class with the specified topic, agent file, and framework.
Note: autogen framework is different from this AutoGenerator class.
Args:
topic (str, optional): The topic for the generated team structure. Defaults to &#34;Movie Story writing about AI&#34;.
agent_file (str, optional): The name of the YAML file to save the generated team structure. Defaults to &#34;test.yaml&#34;.
framework (str, optional): The framework for the generated team structure. Defaults to &#34;crewai&#34;.
config_list (Optional[List[Dict]], optional): A list containing the configuration details for the OpenAI API.
If None, it defaults to using environment variables or hardcoded values.
Attributes:
config_list (list): A list containing the configuration details for the OpenAI API.
topic (str): The specified topic for the generated team structure.
agent_file (str): The specified name of the YAML file to save the generated team structure.
framework (str): The specified framework for the generated team structure.
client (instructor.Client): An instance of the instructor.Client class initialized with the specified OpenAI API configuration.
&#34;&#34;&#34;
self.config_list = config_list or [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.topic = topic
self.agent_file = agent_file
self.framework = framework or &#34;crewai&#34;
self.client = instructor.patch(
OpenAI(
base_url=self.config_list[0][&#39;base_url&#39;],
api_key=os.getenv(&#34;OPENAI_API_KEY&#34;),
),
mode=instructor.Mode.JSON,
)
def generate(self):
&#34;&#34;&#34;
Generates a team structure for the specified topic.
Args:
None
Returns:
str: The full path of the YAML file containing the generated team structure.
Raises:
Exception: If the generation process fails.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
path = generator.generate()
print(path)
&#34;&#34;&#34;
response = self.client.chat.completions.create(
model=self.config_list[0][&#39;model&#39;],
response_model=TeamStructure,
max_retries=10,
messages=[
{&#34;role&#34;: &#34;system&#34;, &#34;content&#34;: &#34;You are a helpful assistant designed to output complex team structures.&#34;},
{&#34;role&#34;: &#34;user&#34;, &#34;content&#34;: self.get_user_content()}
]
)
json_data = json.loads(response.model_dump_json())
self.convert_and_save(json_data)
full_path = os.path.abspath(self.agent_file)
return full_path
def convert_and_save(self, json_data):
&#34;&#34;&#34;Converts the provided JSON data into the desired YAML format and saves it to a file.
Args:
json_data (dict): The JSON data representing the team structure.
topic (str, optional): The topic to be inserted into the YAML. Defaults to &#34;Artificial Intelligence&#34;.
agent_file (str, optional): The name of the YAML file to save. Defaults to &#34;test.yaml&#34;.
&#34;&#34;&#34;
yaml_data = {
&#34;framework&#34;: self.framework,
&#34;topic&#34;: self.topic,
&#34;roles&#34;: {},
&#34;dependencies&#34;: []
}
for role_id, role_details in json_data[&#39;roles&#39;].items():
yaml_data[&#39;roles&#39;][role_id] = {
&#34;backstory&#34;: &#34;&#34; + role_details[&#39;backstory&#39;],
&#34;goal&#34;: role_details[&#39;goal&#39;],
&#34;role&#34;: role_details[&#39;role&#39;],
&#34;tasks&#34;: {},
# &#34;tools&#34;: role_details.get(&#39;tools&#39;, []),
&#34;tools&#34;: [&#39;&#39;]
}
for task_id, task_details in role_details[&#39;tasks&#39;].items():
yaml_data[&#39;roles&#39;][role_id][&#39;tasks&#39;][task_id] = {
&#34;description&#34;: &#34;&#34; + task_details[&#39;description&#39;],
&#34;expected_output&#34;: &#34;&#34; + task_details[&#39;expected_output&#39;]
}
# Save to YAML file, maintaining the order
with open(self.agent_file, &#39;w&#39;) as f:
yaml.dump(yaml_data, f, allow_unicode=True, sort_keys=False)
def get_user_content(self):
&#34;&#34;&#34;
Generates a prompt for the OpenAI API to generate a team structure.
Args:
None
Returns:
str: The prompt for the OpenAI API.
Usage:
generator = AutoGenerator(framework=&#34;crewai&#34;, topic=&#34;Create a movie script about Cat in Mars&#34;)
prompt = generator.get_user_content()
print(prompt)
&#34;&#34;&#34;
user_content = &#34;&#34;&#34;Generate a team structure for \&#34;&#34;&#34;&#34; + self.topic + &#34;&#34;&#34;\&#34; task.
No Input data will be provided to the team.
The team will work in sequence. First role will pass the output to the next role, and so on.
The last role will generate the final output.
Think step by step.
With maximum 3 roles, each with 1 task. Include role goals, backstories, task descriptions, and expected outputs.
List of Available Tools: CodeDocsSearchTool, CSVSearchTool, DirectorySearchTool, DOCXSearchTool, DirectoryReadTool, FileReadTool, TXTSearchTool, JSONSearchTool, MDXSearchTool, PDFSearchTool, RagTool, ScrapeElementFromWebsiteTool, ScrapeWebsiteTool, WebsiteSearchTool, XMLSearchTool, YoutubeChannelSearchTool, YoutubeVideoSearchTool.
Only use Available Tools. Do Not use any other tools.
Example Below:
Use below example to understand the structure of the output.
The final role you create should satisfy the provided task: &#34;&#34;&#34; + self.topic + &#34;&#34;&#34;.
{
&#34;roles&#34;: {
&#34;narrative_designer&#34;: {
&#34;role&#34;: &#34;Narrative Designer&#34;,
&#34;goal&#34;: &#34;Create AI storylines&#34;,
&#34;backstory&#34;: &#34;Skilled in narrative development for AI, with a focus on story resonance.&#34;,
&#34;tools&#34;: [&#34;ScrapeWebsiteTool&#34;],
&#34;tasks&#34;: {
&#34;story_concept_development&#34;: {
&#34;description&#34;: &#34;Craft a unique AI story concept with depth and engagement using concept from this page the content https://www.asthebirdfliesblog.com/posts/how-to-write-book-story-development .&#34;,
&#34;expected_output&#34;: &#34;Document with narrative arcs, character bios, and settings.&#34;
}
}
},
&#34;scriptwriter&#34;: {
&#34;role&#34;: &#34;Scriptwriter&#34;,
&#34;goal&#34;: &#34;Write scripts from AI concepts&#34;,
&#34;backstory&#34;: &#34;Expert in dialogue and script structure, translating concepts into scripts.&#34;,
&#34;tasks&#34;: {
&#34;scriptwriting_task&#34;: {
&#34;description&#34;: &#34;Turn narrative concepts into scripts, including dialogue and scenes.&#34;,
&#34;expected_output&#34;: &#34;Production-ready script with dialogue and scene details.&#34;
}
}
}
}
}
&#34;&#34;&#34;
return user_content</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.auto.AutoGenerator.convert_and_save"><code class="name flex">
<span>def <span class="ident">convert_and_save</span></span>(<span>self, json_data)</span>
</code></dt>
<dd>
<div class="desc"><p>Converts the provided JSON data into the desired YAML format and saves it to a file.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>json_data</code></strong> :&ensp;<code>dict</code></dt>
<dd>The JSON data representing the team structure.</dd>
<dt><strong><code>topic</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The topic to be inserted into the YAML. Defaults to "Artificial Intelligence".</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the YAML file to save. Defaults to "test.yaml".</dd>
</dl></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.generate"><code class="name flex">
<span>def <span class="ident">generate</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a team structure for the specified topic.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The full path of the YAML file containing the generated team structure.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>Exception</code></dt>
<dd>If the generation process fails.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
path = generator.generate()
print(path)</p></div>
</dd>
<dt id="praisonai.auto.AutoGenerator.get_user_content"><code class="name flex">
<span>def <span class="ident">get_user_content</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates a prompt for the OpenAI API to generate a team structure.</p>
<h2 id="args">Args</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>str</code></dt>
<dd>The prompt for the OpenAI API.</dd>
</dl>
<h2 id="usage">Usage</h2>
<p>generator = AutoGenerator(framework="crewai", topic="Create a movie script about Cat in Mars")
prompt = generator.get_user_content()
print(prompt)</p></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.RoleDetails"><code class="flex name class">
<span>class <span class="ident">RoleDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class RoleDetails(BaseModel):
role: str
goal: str
backstory: str
tasks: Dict[str, TaskDetails]
tools: List[str]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.RoleDetails.backstory"><code class="name">var <span class="ident">backstory</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.goal"><code class="name">var <span class="ident">goal</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.role"><code class="name">var <span class="ident">role</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tasks"><code class="name">var <span class="ident">tasks</span> : Dict[str, <a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.RoleDetails.tools"><code class="name">var <span class="ident">tools</span> : List[str]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TaskDetails"><code class="flex name class">
<span>class <span class="ident">TaskDetails</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TaskDetails(BaseModel):
description: str
expected_output: str</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TaskDetails.description"><code class="name">var <span class="ident">description</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.expected_output"><code class="name">var <span class="ident">expected_output</span> : str</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TaskDetails.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
<dt id="praisonai.auto.TeamStructure"><code class="flex name class">
<span>class <span class="ident">TeamStructure</span></span>
<span>(</span><span>**data: Any)</span>
</code></dt>
<dd>
<div class="desc"><p>Usage docs: <a href="https://docs.pydantic.dev/2.9/concepts/models/">https://docs.pydantic.dev/2.9/concepts/models/</a></p>
<p>A base class for creating Pydantic models.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>__class_vars__</code></strong></dt>
<dd>The names of the class variables defined on the model.</dd>
<dt><strong><code>__private_attributes__</code></strong></dt>
<dd>Metadata about the private attributes of the model.</dd>
<dt><strong><code>__signature__</code></strong></dt>
<dd>The synthesized <code>__init__</code> [<code>Signature</code>][inspect.Signature] of the model.</dd>
<dt><strong><code>__pydantic_complete__</code></strong></dt>
<dd>Whether model building is completed, or if there are still undefined fields.</dd>
<dt><strong><code>__pydantic_core_schema__</code></strong></dt>
<dd>The core schema of the model.</dd>
<dt><strong><code>__pydantic_custom_init__</code></strong></dt>
<dd>Whether the model has a custom <code>__init__</code> function.</dd>
<dt><strong><code>__pydantic_decorators__</code></strong></dt>
<dd>Metadata containing the decorators defined on the model.
This replaces <code>Model.__validators__</code> and <code>Model.__root_validators__</code> from Pydantic V1.</dd>
<dt><strong><code>__pydantic_generic_metadata__</code></strong></dt>
<dd>Metadata for generic models; contains data used for a similar purpose to
<strong>args</strong>, <strong>origin</strong>, <strong>parameters</strong> in typing-module generics. May eventually be replaced by these.</dd>
<dt><strong><code>__pydantic_parent_namespace__</code></strong></dt>
<dd>Parent namespace of the model, used for automatic rebuilding of models.</dd>
<dt><strong><code>__pydantic_post_init__</code></strong></dt>
<dd>The name of the post-init method for the model, if defined.</dd>
<dt><strong><code>__pydantic_root_model__</code></strong></dt>
<dd>Whether the model is a [<code>RootModel</code>][pydantic.root_model.RootModel].</dd>
<dt><strong><code>__pydantic_serializer__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaSerializer</code> used to dump instances of the model.</dd>
<dt><strong><code>__pydantic_validator__</code></strong></dt>
<dd>The <code>pydantic-core</code> <code>SchemaValidator</code> used to validate instances of the model.</dd>
<dt><strong><code>__pydantic_extra__</code></strong></dt>
<dd>A dictionary containing extra values, if [<code>extra</code>][pydantic.config.ConfigDict.extra]
is set to <code>'allow'</code>.</dd>
<dt><strong><code>__pydantic_fields_set__</code></strong></dt>
<dd>The names of fields explicitly set during instantiation.</dd>
<dt><strong><code>__pydantic_private__</code></strong></dt>
<dd>Values of private attributes set on the model instance.</dd>
</dl>
<p>Create a new model by parsing and validating input data from keyword arguments.</p>
<p>Raises [<code>ValidationError</code>][pydantic_core.ValidationError] if the input data cannot be
validated to form a valid model.</p>
<p><code>self</code> is explicitly positional-only to allow <code>self</code> as a field name.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class TeamStructure(BaseModel):
roles: Dict[str, RoleDetails]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>pydantic.main.BaseModel</li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="praisonai.auto.TeamStructure.model_computed_fields"><code class="name">var <span class="ident">model_computed_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_config"><code class="name">var <span class="ident">model_config</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.model_fields"><code class="name">var <span class="ident">model_fields</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.auto.TeamStructure.roles"><code class="name">var <span class="ident">roles</span> : Dict[str, <a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a>]</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.auto.AutoGenerator" href="#praisonai.auto.AutoGenerator">AutoGenerator</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.AutoGenerator.convert_and_save" href="#praisonai.auto.AutoGenerator.convert_and_save">convert_and_save</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.generate" href="#praisonai.auto.AutoGenerator.generate">generate</a></code></li>
<li><code><a title="praisonai.auto.AutoGenerator.get_user_content" href="#praisonai.auto.AutoGenerator.get_user_content">get_user_content</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.RoleDetails" href="#praisonai.auto.RoleDetails">RoleDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.RoleDetails.backstory" href="#praisonai.auto.RoleDetails.backstory">backstory</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.goal" href="#praisonai.auto.RoleDetails.goal">goal</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_computed_fields" href="#praisonai.auto.RoleDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_config" href="#praisonai.auto.RoleDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.model_fields" href="#praisonai.auto.RoleDetails.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.role" href="#praisonai.auto.RoleDetails.role">role</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tasks" href="#praisonai.auto.RoleDetails.tasks">tasks</a></code></li>
<li><code><a title="praisonai.auto.RoleDetails.tools" href="#praisonai.auto.RoleDetails.tools">tools</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TaskDetails" href="#praisonai.auto.TaskDetails">TaskDetails</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TaskDetails.description" href="#praisonai.auto.TaskDetails.description">description</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.expected_output" href="#praisonai.auto.TaskDetails.expected_output">expected_output</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_computed_fields" href="#praisonai.auto.TaskDetails.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_config" href="#praisonai.auto.TaskDetails.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TaskDetails.model_fields" href="#praisonai.auto.TaskDetails.model_fields">model_fields</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="praisonai.auto.TeamStructure" href="#praisonai.auto.TeamStructure">TeamStructure</a></code></h4>
<ul class="">
<li><code><a title="praisonai.auto.TeamStructure.model_computed_fields" href="#praisonai.auto.TeamStructure.model_computed_fields">model_computed_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_config" href="#praisonai.auto.TeamStructure.model_config">model_config</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.model_fields" href="#praisonai.auto.TeamStructure.model_fields">model_fields</a></code></li>
<li><code><a title="praisonai.auto.TeamStructure.roles" href="#praisonai.auto.TeamStructure.roles">roles</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-664
View File
@@ -1,664 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.cli API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.cli</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.cli.stream_subprocess"><code class="name flex">
<span>def <span class="ident">stream_subprocess</span></span>(<span>command, env=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Execute a subprocess command and stream the output to the terminal in real-time.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>command</code></strong> :&ensp;<code>list</code></dt>
<dd>A list containing the command and its arguments.</dd>
<dt><strong><code>env</code></strong> :&ensp;<code>dict</code>, optional</dt>
<dd>Environment variables for the subprocess.</dd>
</dl></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.cli.PraisonAI"><code class="flex name class">
<span>class <span class="ident">PraisonAI</span></span>
<span>(</span><span>agent_file='agents.yaml', framework='', auto=False, init=False, agent_yaml=None, tools=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initialize the PraisonAI object with default parameters.</p>
<h2 id="parameters">Parameters</h2>
<p>agent_file (str): The default agent file to use. Defaults to "agents.yaml".
framework (str): The default framework to use. Defaults to "crewai".
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.</p>
<h2 id="attributes">Attributes</h2>
<dl>
<dt><strong><code>config_list</code></strong> :&ensp;<code>list</code></dt>
<dd>A list of configuration dictionaries for the OpenAI API.</dd>
<dt><strong><code>agent_file</code></strong> :&ensp;<code>str</code></dt>
<dd>The agent file to use.</dd>
<dt><strong><code>framework</code></strong> :&ensp;<code>str</code></dt>
<dd>The framework to use.</dd>
<dt><strong><code>auto</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable auto mode.</dd>
<dt><strong><code>init</code></strong> :&ensp;<code>bool</code></dt>
<dd>A flag indicating whether to enable initialization mode.</dd>
<dt><strong><code>agent_yaml</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The content of the YAML file. Defaults to None.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PraisonAI:
def __init__(self, agent_file=&#34;agents.yaml&#34;, framework=&#34;&#34;, auto=False, init=False, agent_yaml=None, tools=None):
&#34;&#34;&#34;
Initialize the PraisonAI object with default parameters.
Parameters:
agent_file (str): The default agent file to use. Defaults to &#34;agents.yaml&#34;.
framework (str): The default framework to use. Defaults to &#34;crewai&#34;.
auto (bool): A flag indicating whether to enable auto mode. Defaults to False.
init (bool): A flag indicating whether to enable initialization mode. Defaults to False.
Attributes:
config_list (list): A list of configuration dictionaries for the OpenAI API.
agent_file (str): The agent file to use.
framework (str): The framework to use.
auto (bool): A flag indicating whether to enable auto mode.
init (bool): A flag indicating whether to enable initialization mode.
agent_yaml (str, optional): The content of the YAML file. Defaults to None.
&#34;&#34;&#34;
self.agent_yaml = agent_yaml
self.config_list = [
{
&#39;model&#39;: os.environ.get(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;),
&#39;base_url&#39;: os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;),
&#39;api_key&#39;: os.environ.get(&#34;OPENAI_API_KEY&#34;)
}
]
self.agent_file = agent_file
self.framework = framework
self.auto = auto
self.init = init
self.tools = tools or [] # Store tool class names as a list
def run(self):
&#34;&#34;&#34;
Run the PraisonAI application.
&#34;&#34;&#34;
self.main()
def main(self):
&#34;&#34;&#34;
The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
Any: Depending on the arguments provided, the function may return a result from the
AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.
&#34;&#34;&#34;
args = self.parse_args()
if args is None:
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
if args.deploy:
from .deploy import CloudDeployer
deployer = CloudDeployer()
deployer.run_commands()
return
if getattr(args, &#39;chat&#39;, False):
self.create_chainlit_chat_interface()
return
if getattr(args, &#39;code&#39;, False):
self.create_code_interface()
return
if getattr(args, &#39;realtime&#39;, False):
self.create_realtime_interface()
return
if getattr(args, &#39;call&#39;, False):
call_args = []
if args.public:
call_args.append(&#39;--public&#39;)
call_module.main(call_args)
return
if args.agent_file == &#39;train&#39;:
package_root = os.path.dirname(os.path.abspath(__file__))
config_yaml_destination = os.path.join(os.getcwd(), &#39;config.yaml&#39;)
# Create config.yaml only if it doesn&#39;t exist or --model or --dataset is provided
if not os.path.exists(config_yaml_destination) or args.model or args.dataset:
config = generate_config(
model_name=args.model,
hf_model_name=args.hf,
ollama_model_name=args.ollama,
dataset=[{
&#34;name&#34;: args.dataset
}]
)
with open(&#39;config.yaml&#39;, &#39;w&#39;) as f:
yaml.dump(config, f, default_flow_style=False, indent=2)
# Overwrite huggingface_save and ollama_save if --hf or --ollama are provided
if args.hf:
config[&#34;huggingface_save&#34;] = &#34;true&#34;
if args.ollama:
config[&#34;ollama_save&#34;] = &#34;true&#34;
if &#39;init&#39; in sys.argv:
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed&#34;)
return
try:
result = subprocess.check_output([&#39;conda&#39;, &#39;env&#39;, &#39;list&#39;])
if &#39;praison_env&#39; in result.decode(&#39;utf-8&#39;):
print(&#34;Conda environment &#39;praison_env&#39; found.&#34;)
else:
raise subprocess.CalledProcessError(1, &#39;grep&#39;)
except subprocess.CalledProcessError:
print(&#34;Conda environment &#39;praison_env&#39; not found. Setting it up...&#34;)
from praisonai.setup.setup_conda_env import main as setup_conda_main
setup_conda_main()
print(&#34;All packages installed.&#34;)
train_args = sys.argv[2:] # Get all arguments after &#39;train&#39;
train_script_path = os.path.join(package_root, &#39;train.py&#39;)
# Set environment variables
env = os.environ.copy()
env[&#39;PYTHONUNBUFFERED&#39;] = &#39;1&#39;
stream_subprocess([&#39;conda&#39;, &#39;run&#39;, &#39;--no-capture-output&#39;, &#39;--name&#39;, &#39;praison_env&#39;, &#39;python&#39;, &#39;-u&#39;, train_script_path, &#39;train&#39;], env=env)
return
invocation_cmd = &#34;praisonai&#34;
version_string = f&#34;PraisonAI version {__version__}&#34;
self.framework = args.framework or self.framework
if args.agent_file:
if args.agent_file.startswith(&#34;tests.test&#34;): # Argument used for testing purposes. eg: python -m unittest tests.test
print(&#34;test&#34;)
else:
self.agent_file = args.agent_file
if args.auto or args.init:
temp_topic = &#39; &#39;.join(args.auto) if args.auto else &#39; &#39;.join(args.init)
self.topic = temp_topic
elif self.auto or self.init: # Use the auto attribute if args.auto is not provided
self.topic = self.auto
if args.auto or self.auto:
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
elif args.init or self.init:
self.agent_file = &#34;agents.yaml&#34;
generator = AutoGenerator(topic=self.topic , framework=self.framework, agent_file=self.agent_file)
self.agent_file = generator.generate()
print(&#34;File {} created successfully&#34;.format(self.agent_file))
return &#34;File {} created successfully&#34;.format(self.agent_file)
if args.ui:
if args.ui == &#34;gradio&#34;:
self.create_gradio_interface()
elif args.ui == &#34;chainlit&#34;:
self.create_chainlit_interface()
else:
# Modify below code to allow default ui
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
else:
agents_generator = AgentsGenerator(
self.agent_file,
self.framework,
self.config_list,
agent_yaml=self.agent_yaml,
tools=self.tools # Pass tools to AgentsGenerator
)
result = agents_generator.generate_crew_and_kickoff()
return result
def parse_args(self):
&#34;&#34;&#34;
Parse the command-line arguments for the PraisonAI CLI.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
argparse.Namespace: An object containing the parsed command-line arguments.
Raises:
argparse.ArgumentError: If the arguments provided are invalid.
Example:
&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: &#39;agents.yaml&#39;
&#34;&#34;&#34;
parser = argparse.ArgumentParser(prog=&#34;praisonai&#34;, description=&#34;praisonAI command-line interface&#34;)
parser.add_argument(&#34;--framework&#34;, choices=[&#34;crewai&#34;, &#34;autogen&#34;], help=&#34;Specify the framework&#34;)
parser.add_argument(&#34;--ui&#34;, choices=[&#34;chainlit&#34;, &#34;gradio&#34;], help=&#34;Specify the UI framework (gradio or chainlit).&#34;)
parser.add_argument(&#34;--auto&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;--init&#34;, nargs=argparse.REMAINDER, help=&#34;Enable auto mode and pass arguments for it&#34;)
parser.add_argument(&#34;agent_file&#34;, nargs=&#34;?&#34;, help=&#34;Specify the agent file&#34;)
parser.add_argument(&#34;--deploy&#34;, action=&#34;store_true&#34;, help=&#34;Deploy the application&#34;)
parser.add_argument(&#34;--model&#34;, type=str, help=&#34;Model name&#34;)
parser.add_argument(&#34;--hf&#34;, type=str, help=&#34;Hugging Face model name&#34;)
parser.add_argument(&#34;--ollama&#34;, type=str, help=&#34;Ollama model name&#34;)
parser.add_argument(&#34;--dataset&#34;, type=str, help=&#34;Dataset name for training&#34;, default=&#34;yahma/alpaca-cleaned&#34;)
parser.add_argument(&#34;--realtime&#34;, action=&#34;store_true&#34;, help=&#34;Start the realtime voice interaction interface&#34;)
parser.add_argument(&#34;--call&#34;, action=&#34;store_true&#34;, help=&#34;Start the PraisonAI Call server&#34;)
parser.add_argument(&#34;--public&#34;, action=&#34;store_true&#34;, help=&#34;Use ngrok to expose the server publicly (only with --call)&#34;)
args, unknown_args = parser.parse_known_args()
if unknown_args and unknown_args[0] == &#39;-b&#39; and unknown_args[1] == &#39;api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;api:app&#39; or args.agent_file == &#39;/app/api:app&#39;:
args.agent_file = &#39;agents.yaml&#39;
if args.agent_file == &#39;ui&#39;:
args.ui = &#39;chainlit&#39;
if args.agent_file == &#39;chat&#39;:
args.ui = &#39;chainlit&#39;
args.chat = True
if args.agent_file == &#39;code&#39;:
args.ui = &#39;chainlit&#39;
args.code = True
if args.agent_file == &#39;realtime&#39;:
args.realtime = True
if args.agent_file == &#39;call&#39;:
args.call = True
return args
def create_chainlit_chat_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the chat application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8084&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chat_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;chat.py&#39;)
chainlit_run([chat_ui_path])
else:
print(&#34;ERROR: Chat UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[chat]\&#34;&#39; to use the chat UI.&#34;)
def create_code_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the code application.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8086&#34;
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
code_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;code.py&#39;)
chainlit_run([code_ui_path])
else:
print(&#34;ERROR: Code UI is not installed. Please install it with &#39;pip install \&#34;praisonai\[code]\&#34;&#39; to use the code UI.&#34;)
def create_gradio_interface(self):
&#34;&#34;&#34;
Create a Gradio interface for generating agents and performing tasks.
Args:
self (PraisonAI): An instance of the PraisonAI class.
Returns:
None: This method does not return any value. It launches the Gradio interface.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; praison_ai.create_gradio_interface()
&#34;&#34;&#34;
if GRADIO_AVAILABLE:
def generate_crew_and_kickoff_interface(auto_args, framework):
&#34;&#34;&#34;
Generate a crew and kick off tasks based on the provided auto arguments and framework.
Args:
auto_args (list): Topic.
framework (str): The framework to use for generating agents.
Returns:
str: A string representing the result of generating the crew and kicking off tasks.
Raises:
None: This method does not raise any exceptions.
Example:
&gt;&gt;&gt; result = generate_crew_and_kickoff_interface(&#34;Create a movie about Cat in Mars&#34;, &#34;crewai&#34;)
&gt;&gt;&gt; print(result)
&#34;&#34;&#34;
self.framework = framework
self.agent_file = &#34;test.yaml&#34;
generator = AutoGenerator(topic=auto_args , framework=self.framework)
self.agent_file = generator.generate()
agents_generator = AgentsGenerator(self.agent_file, self.framework, self.config_list)
result = agents_generator.generate_crew_and_kickoff()
return result
gr.Interface(
fn=generate_crew_and_kickoff_interface,
inputs=[gr.Textbox(lines=2, label=&#34;Auto Args&#34;), gr.Dropdown(choices=[&#34;crewai&#34;, &#34;autogen&#34;], label=&#34;Framework&#34;)],
outputs=&#34;textbox&#34;,
title=&#34;Praison AI Studio&#34;,
description=&#34;Create Agents and perform tasks&#34;,
theme=&#34;default&#34;
).launch()
else:
print(&#34;ERROR: Gradio is not installed. Please install it with &#39;pip install gradio&#39; to use this feature.&#34;)
def create_chainlit_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for generating agents and performing tasks.
This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.
Returns:
None: This function does not return any value. It starts the Chainlit application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8082&#34;
# Get the path to the &#39;public&#39; folder within the package
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(&#34;public&#34;): # Check if the folder exists in the current directory
if os.path.exists(public_folder):
shutil.copytree(public_folder, &#39;public&#39;, dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
chainlit_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;chainlit_ui.py&#39;)
chainlit_run([chainlit_ui_path])
else:
print(&#34;ERROR: Chainlit is not installed. Please install it with &#39;pip install \&#34;praisonai\[ui]\&#34;&#39; to use the UI.&#34;)
def create_realtime_interface(self):
&#34;&#34;&#34;
Create a Chainlit interface for the realtime voice interaction application.
&#34;&#34;&#34;
if CHAINLIT_AVAILABLE:
import praisonai
os.environ[&#34;CHAINLIT_PORT&#34;] = &#34;8088&#34; # Ensure this port is not in use by another service
root_path = os.path.join(os.path.expanduser(&#34;~&#34;), &#34;.praison&#34;)
os.environ[&#34;CHAINLIT_APP_ROOT&#34;] = root_path
public_folder = os.path.join(os.path.dirname(praisonai.__file__), &#39;public&#39;)
if not os.path.exists(os.path.join(root_path, &#34;public&#34;)):
if os.path.exists(public_folder):
shutil.copytree(public_folder, os.path.join(root_path, &#34;public&#34;), dirs_exist_ok=True)
logging.info(&#34;Public folder copied successfully!&#34;)
else:
logging.info(&#34;Public folder not found in the package.&#34;)
else:
logging.info(&#34;Public folder already exists.&#34;)
realtime_ui_path = os.path.join(os.path.dirname(praisonai.__file__), &#39;ui&#39;, &#39;realtime.py&#39;)
chainlit_run([realtime_ui_path])
else:
print(&#34;ERROR: Realtime UI is not installed. Please install it with &#39;pip install \&#34;praisonai[realtime]\&#34;&#39; to use the realtime UI.&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.cli.PraisonAI.create_chainlit_chat_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_chat_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the chat application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_chainlit_interface"><code class="name flex">
<span>def <span class="ident">create_chainlit_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for generating agents and performing tasks.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_code_interface"><code class="name flex">
<span>def <span class="ident">create_code_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the code application.</p>
<p>This function sets up a Chainlit application that listens for messages.
When a message is received, it runs PraisonAI with the provided message as the topic.
The generated agents are then used to perform tasks.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This function does not return any value. It starts the Chainlit application.</dd>
</dl></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_gradio_interface"><code class="name flex">
<span>def <span class="ident">create_gradio_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Gradio interface for generating agents and performing tasks.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not return any value. It launches the Gradio interface.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>None</code></dt>
<dd>This method does not raise any exceptions.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; praison_ai.create_gradio_interface()
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.create_realtime_interface"><code class="name flex">
<span>def <span class="ident">create_realtime_interface</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Create a Chainlit interface for the realtime voice interaction application.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>The main function of the PraisonAI object. It parses the command-line arguments,
initializes the necessary attributes, and then calls the appropriate methods based on the
provided arguments.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>Any</code></dt>
<dd>Depending on the arguments provided, the function may return a result from the</dd>
</dl>
<p>AgentsGenerator, a deployment result from the CloudDeployer, or a message indicating
the successful creation of a file.</p></div>
</dd>
<dt id="praisonai.cli.PraisonAI.parse_args"><code class="name flex">
<span>def <span class="ident">parse_args</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Parse the command-line arguments for the PraisonAI CLI.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>self</code></strong> :&ensp;<code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></dt>
<dd>An instance of the PraisonAI class.</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>argparse.Namespace</code></dt>
<dd>An object containing the parsed command-line arguments.</dd>
</dl>
<h2 id="raises">Raises</h2>
<dl>
<dt><code>argparse.ArgumentError</code></dt>
<dd>If the arguments provided are invalid.</dd>
</dl>
<h2 id="example">Example</h2>
<pre><code class="language-python-repl">&gt;&gt;&gt; args = praison_ai.parse_args()
&gt;&gt;&gt; print(args.agent_file) # Output: 'agents.yaml'
</code></pre></div>
</dd>
<dt id="praisonai.cli.PraisonAI.run"><code class="name flex">
<span>def <span class="ident">run</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Run the PraisonAI application.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.cli.stream_subprocess" href="#praisonai.cli.stream_subprocess">stream_subprocess</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.cli.PraisonAI" href="#praisonai.cli.PraisonAI">PraisonAI</a></code></h4>
<ul class="">
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_chat_interface" href="#praisonai.cli.PraisonAI.create_chainlit_chat_interface">create_chainlit_chat_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_chainlit_interface" href="#praisonai.cli.PraisonAI.create_chainlit_interface">create_chainlit_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_code_interface" href="#praisonai.cli.PraisonAI.create_code_interface">create_code_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_gradio_interface" href="#praisonai.cli.PraisonAI.create_gradio_interface">create_gradio_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.create_realtime_interface" href="#praisonai.cli.PraisonAI.create_realtime_interface">create_realtime_interface</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.main" href="#praisonai.cli.PraisonAI.main">main</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.parse_args" href="#praisonai.cli.PraisonAI.parse_args">parse_args</a></code></li>
<li><code><a title="praisonai.cli.PraisonAI.run" href="#praisonai.cli.PraisonAI.run">run</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-279
View File
@@ -1,279 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.deploy API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.deploy</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.deploy.CloudDeployer"><code class="flex name class">
<span>class <span class="ident">CloudDeployer</span></span>
</code></dt>
<dd>
<div class="desc"><p>A class for deploying a cloud-based application.</p>
<h2 id="attributes">Attributes</h2>
<p>None</p>
<h2 id="methods">Methods</h2>
<p><strong>init</strong>(self):
Loads environment variables from .env file or system and sets them.</p>
<p>Loads environment variables from .env file or system and sets them.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class CloudDeployer:
&#34;&#34;&#34;
A class for deploying a cloud-based application.
Attributes:
None
Methods:
__init__(self):
Loads environment variables from .env file or system and sets them.
&#34;&#34;&#34;
def __init__(self):
&#34;&#34;&#34;
Loads environment variables from .env file or system and sets them.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
&#34;&#34;&#34;
# Load environment variables from .env file or system
load_dotenv()
self.set_environment_variables()
def create_dockerfile(self):
&#34;&#34;&#34;
Creates a Dockerfile for the application.
Parameters:
self: An instance of the CloudDeployer class.
Returns:
None
Raises:
None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.
&#34;&#34;&#34;
with open(&#34;Dockerfile&#34;, &#34;w&#34;) as file:
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.22 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;)
def create_api_file(self):
&#34;&#34;&#34;
Creates an API file for the application.
Parameters:
self (CloudDeployer): An instance of the CloudDeployer class.
Returns:
None
This method creates an API file named &#34;api.py&#34; in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path (&#34;/&#34;) and uses the Markdown library to format the output.
&#34;&#34;&#34;
with open(&#34;api.py&#34;, &#34;w&#34;) as file:
file.write(&#34;from flask import Flask\n&#34;)
file.write(&#34;from praisonai import PraisonAI\n&#34;)
file.write(&#34;import markdown\n\n&#34;)
file.write(&#34;app = Flask(__name__)\n\n&#34;)
file.write(&#34;def basic():\n&#34;)
file.write(&#34; praisonai = PraisonAI(agent_file=\&#34;agents.yaml\&#34;)\n&#34;)
file.write(&#34; return praisonai.run()\n\n&#34;)
file.write(&#34;@app.route(&#39;/&#39;)\n&#34;)
file.write(&#34;def home():\n&#34;)
file.write(&#34; output = basic()\n&#34;)
file.write(&#34; html_output = markdown.markdown(output)\n&#34;)
file.write(&#34; return f&#39;&lt;html&gt;&lt;body&gt;{html_output}&lt;/body&gt;&lt;/html&gt;&#39;\n\n&#34;)
file.write(&#34;if __name__ == \&#34;__main__\&#34;:\n&#34;)
file.write(&#34; app.run(debug=True)\n&#34;)
def set_environment_variables(self):
&#34;&#34;&#34;Sets environment variables with fallback to .env values or defaults.&#34;&#34;&#34;
os.environ[&#34;OPENAI_MODEL_NAME&#34;] = os.getenv(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;)
os.environ[&#34;OPENAI_API_KEY&#34;] = os.getenv(&#34;OPENAI_API_KEY&#34;, &#34;Enter your API key&#34;)
os.environ[&#34;OPENAI_API_BASE&#34;] = os.getenv(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;)
def run_commands(self):
&#34;&#34;&#34;
Sets environment variables with fallback to .env values or defaults.
Parameters:
None
Returns:
None
Raises:
None
This method sets environment variables for the application. It uses the `os.environ` dictionary to set the following environment variables:
- `OPENAI_MODEL_NAME`: The name of the OpenAI model to use. If not specified in the .env file, it defaults to &#34;gpt-4o&#34;.
- `OPENAI_API_KEY`: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to &#34;Enter your API key&#34;.
- `OPENAI_API_BASE`: The base URL for the OpenAI API. If not specified in the .env file, it defaults to &#34;https://api.openai.com/v1&#34;.
&#34;&#34;&#34;
self.create_api_file()
self.create_dockerfile()
&#34;&#34;&#34;Runs a sequence of shell commands for deployment, continues on error.&#34;&#34;&#34;
commands = [
&#34;yes | gcloud auth configure-docker us-central1-docker.pkg.dev&#34;,
&#34;gcloud artifacts repositories create praisonai-repository --repository-format=docker --location=us-central1&#34;,
&#34;docker build --platform linux/amd64 -t gcr.io/$(gcloud config get-value project)/praisonai-app:latest .&#34;,
&#34;docker tag gcr.io/$(gcloud config get-value project)/praisonai-app:latest us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;docker push us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest&#34;,
&#34;gcloud run deploy praisonai-service --image us-central1-docker.pkg.dev/$(gcloud config get-value project)/praisonai-repository/praisonai-app:latest --platform managed --region us-central1 --allow-unauthenticated --set-env-vars OPENAI_MODEL_NAME=${OPENAI_MODEL_NAME},OPENAI_API_KEY=${OPENAI_API_KEY},OPENAI_API_BASE=${OPENAI_API_BASE}&#34;
]
for cmd in commands:
try:
subprocess.run(cmd, shell=True, check=True)
except subprocess.CalledProcessError as e:
print(f&#34;ERROR: Command &#39;{e.cmd}&#39; failed with exit status {e.returncode}&#34;)
print(f&#34;Continuing with the next command...&#34;)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.deploy.CloudDeployer.create_api_file"><code class="name flex">
<span>def <span class="ident">create_api_file</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates an API file for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self (CloudDeployer): An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None
This method creates an API file named "api.py" in the current directory. The file contains a basic Flask application that uses the PraisonAI library to run a simple agent and returns the output as an HTML page. The application listens on the root path ("/") and uses the Markdown library to format the output.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.create_dockerfile"><code class="name flex">
<span>def <span class="ident">create_dockerfile</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Creates a Dockerfile for the application.</p>
<h2 id="parameters">Parameters</h2>
<p>self: An instance of the CloudDeployer class.</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method creates a Dockerfile in the current directory with the specified content.
The Dockerfile is used to build a Docker image for the application.
The content of the Dockerfile includes instructions to use the Python 3.11-slim base image,
set the working directory to /app, copy the current directory contents into the container,
install the required Python packages (flask, praisonai, gunicorn, and markdown),
expose port 8080, and run the application using Gunicorn.</p></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.run_commands"><code class="name flex">
<span>def <span class="ident">run_commands</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p>
<h2 id="parameters">Parameters</h2>
<p>None</p>
<h2 id="returns">Returns</h2>
<p>None</p>
<h2 id="raises">Raises</h2>
<p>None
This method sets environment variables for the application. It uses the <code>os.environ</code> dictionary to set the following environment variables:</p>
<ul>
<li><code>OPENAI_MODEL_NAME</code>: The name of the OpenAI model to use. If not specified in the .env file, it defaults to "gpt-4o".</li>
<li><code>OPENAI_API_KEY</code>: The API key for accessing the OpenAI API. If not specified in the .env file, it defaults to "Enter your API key".</li>
<li><code>OPENAI_API_BASE</code>: The base URL for the OpenAI API. If not specified in the .env file, it defaults to "https://api.openai.com/v1".</li>
</ul></div>
</dd>
<dt id="praisonai.deploy.CloudDeployer.set_environment_variables"><code class="name flex">
<span>def <span class="ident">set_environment_variables</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Sets environment variables with fallback to .env values or defaults.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.deploy.CloudDeployer" href="#praisonai.deploy.CloudDeployer">CloudDeployer</a></code></h4>
<ul class="">
<li><code><a title="praisonai.deploy.CloudDeployer.create_api_file" href="#praisonai.deploy.CloudDeployer.create_api_file">create_api_file</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.create_dockerfile" href="#praisonai.deploy.CloudDeployer.create_dockerfile">create_dockerfile</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.run_commands" href="#praisonai.deploy.CloudDeployer.run_commands">run_commands</a></code></li>
<li><code><a title="praisonai.deploy.CloudDeployer.set_environment_variables" href="#praisonai.deploy.CloudDeployer.set_environment_variables">set_environment_variables</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,188 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools.autogen_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools.autogen_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CSVSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_CodeDocsSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DOCXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectoryReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool"><code class="name flex">
<span>def <span class="ident">autogen_DirectorySearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool"><code class="name flex">
<span>def <span class="ident">autogen_FileReadTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_JSONSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_MDXSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_PDFSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool"><code class="name flex">
<span>def <span class="ident">autogen_RagTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeElementFromWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool"><code class="name flex">
<span>def <span class="ident">autogen_ScrapeWebsiteTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_TXTSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_WebsiteSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_XMLSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeChannelSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool"><code class="name flex">
<span>def <span class="ident">autogen_YoutubeVideoSearchTool</span></span>(<span>assistant, user_proxy)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function"><code class="name flex">
<span>def <span class="ident">create_autogen_tool_function</span></span>(<span>tool_name)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools" href="index.html">praisonai.inbuilt_tools</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CSVSearchTool">autogen_CSVSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_CodeDocsSearchTool">autogen_CodeDocsSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DOCXSearchTool">autogen_DOCXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectoryReadTool">autogen_DirectoryReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_DirectorySearchTool">autogen_DirectorySearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_FileReadTool">autogen_FileReadTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_JSONSearchTool">autogen_JSONSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_MDXSearchTool">autogen_MDXSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_PDFSearchTool">autogen_PDFSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_RagTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_RagTool">autogen_RagTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeElementFromWebsiteTool">autogen_ScrapeElementFromWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_ScrapeWebsiteTool">autogen_ScrapeWebsiteTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_TXTSearchTool">autogen_TXTSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_WebsiteSearchTool">autogen_WebsiteSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_XMLSearchTool">autogen_XMLSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeChannelSearchTool">autogen_YoutubeChannelSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool" href="#praisonai.inbuilt_tools.autogen_tools.autogen_YoutubeVideoSearchTool">autogen_YoutubeVideoSearchTool</a></code></li>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function" href="#praisonai.inbuilt_tools.autogen_tools.create_autogen_tool_function">create_autogen_tool_function</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,67 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inbuilt_tools API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inbuilt_tools</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inbuilt_tools.autogen_tools" href="autogen_tools.html">praisonai.inbuilt_tools.autogen_tools</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-69
View File
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc.config API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc.config</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.inc.config.generate_config"><code class="name flex">
<span>def <span class="ident">generate_config</span></span>(<span>ollama_save=None, huggingface_save=None, train=None, model_name=None, hf_model_name=None, ollama_model_name=None, model_parameters=None, max_seq_length=None, load_in_4bit=None, lora_r=None, lora_target_modules=None, lora_alpha=None, lora_dropout=None, lora_bias=None, use_gradient_checkpointing=None, random_state=None, use_rslora=None, loftq_config=None, dataset=None, dataset_text_field=None, dataset_num_proc=None, packing=None, per_device_train_batch_size=None, gradient_accumulation_steps=None, warmup_steps=None, num_train_epochs=None, max_steps=None, learning_rate=None, logging_steps=None, optim=None, weight_decay=None, lr_scheduler_type=None, seed=None, output_dir=None, quantization_method=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Generates the configuration for PraisonAI with dynamic overrides.</p></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inc" href="index.html">praisonai.inc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.inc.config.generate_config" href="#praisonai.inc.config.generate_config">generate_config</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-72
View File
@@ -1,72 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.inc.config" href="config.html">praisonai.inc.config</a></code></li>
<li><code><a title="praisonai.inc.models" href="models.html">praisonai.inc.models</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-200
View File
@@ -1,200 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.inc.models API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.inc.models</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.inc.models.PraisonAIModel"><code class="flex name class">
<span>class <span class="ident">PraisonAIModel</span></span>
<span>(</span><span>model=None, api_key_var=None, base_url=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Initializes the PraisonAIModel with the provided parameters or environment variables.</p>
<h2 id="args">Args</h2>
<dl>
<dt><strong><code>model</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The name of the OpenAI model. Defaults to None.</dd>
<dt><strong><code>api_key_var</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The OpenAI API key. Defaults to None.</dd>
<dt><strong><code>base_url</code></strong> :&ensp;<code>str</code>, optional</dt>
<dd>The base URL for the OpenAI API. Defaults to None.</dd>
</dl></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class PraisonAIModel:
def __init__(self, model=None, api_key_var=None, base_url=None):
&#34;&#34;&#34;
Initializes the PraisonAIModel with the provided parameters or environment variables.
Args:
model (str, optional): The name of the OpenAI model. Defaults to None.
api_key_var (str, optional): The OpenAI API key. Defaults to None.
base_url (str, optional): The base URL for the OpenAI API. Defaults to None.
&#34;&#34;&#34;
self.model = model or os.getenv(&#34;OPENAI_MODEL_NAME&#34;, &#34;gpt-4o&#34;)
if self.model.startswith(&#34;openai/&#34;):
self.api_key_var = &#34;OPENAI_API_KEY&#34;
self.base_url = base_url or &#34;https://api.openai.com/v1&#34;
self.model_name = self.model.replace(&#34;openai/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;groq/&#34;):
self.api_key_var = &#34;GROQ_API_KEY&#34;
self.base_url = base_url or &#34;https://api.groq.com/openai/v1&#34;
self.model_name = self.model.replace(&#34;groq/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;cohere/&#34;):
self.api_key_var = &#34;COHERE_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;cohere/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;ollama/&#34;):
self.api_key_var = &#34;OLLAMA_API_KEY&#34;
self.base_url = base_url or &#34;http://localhost:11434/v1&#34;
self.model_name = self.model.replace(&#34;ollama/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;anthropic/&#34;):
self.api_key_var = &#34;ANTHROPIC_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;anthropic/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;google/&#34;):
self.api_key_var = &#34;GOOGLE_API_KEY&#34;
self.base_url = &#34;&#34;
self.model_name = self.model.replace(&#34;google/&#34;, &#34;&#34;)
elif self.model.startswith(&#34;openrouter/&#34;):
self.api_key_var = &#34;OPENROUTER_API_KEY&#34;
self.base_url = base_url or &#34;https://openrouter.ai/api/v1&#34;
self.model_name = self.model.replace(&#34;openrouter/&#34;, &#34;&#34;)
else:
self.api_key_var = api_key_var or &#34;OPENAI_API_KEY&#34;
self.base_url = base_url or os.environ.get(&#34;OPENAI_API_BASE&#34;, &#34;https://api.openai.com/v1&#34;)
self.model_name = self.model
logger.debug(f&#34;Initialized PraisonAIModel with model {self.model_name}, api_key_var {self.api_key_var}, and base_url {self.base_url}&#34;)
self.api_key = os.environ.get(self.api_key_var, &#34;nokey&#34;)
def get_model(self):
&#34;&#34;&#34;
Returns an instance of the langchain Chat client with the configured parameters.
Returns:
Chat: An instance of the langchain Chat client.
&#34;&#34;&#34;
if self.model.startswith(&#34;google/&#34;):
if GOOGLE_GENAI_AVAILABLE:
return ChatGoogleGenerativeAI(
model=self.model_name,
google_api_key=self.api_key
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-google-genai&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-google-genai&#39;&#34;
)
elif self.model.startswith(&#34;cohere/&#34;):
if COHERE_AVAILABLE:
return ChatCohere(
model=self.model_name,
cohere_api_key=self.api_key,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-cohere&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-cohere&#39;&#34;
)
elif self.model.startswith(&#34;anthropic/&#34;):
if ANTHROPIC_AVAILABLE:
return ChatAnthropic(
model=self.model_name,
anthropic_api_key=self.api_key,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-anthropic&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-anthropic&#39;&#34;
)
elif OPENAI_AVAILABLE:
return ChatOpenAI(
model=self.model_name,
api_key=self.api_key,
base_url=self.base_url,
)
else:
raise ImportError(
&#34;Required Langchain Integration &#39;langchain-openai&#39; not found. &#34;
&#34;Please install with &#39;pip install langchain-openai&#39;&#34;
)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.inc.models.PraisonAIModel.get_model"><code class="name flex">
<span>def <span class="ident">get_model</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Returns an instance of the langchain Chat client with the configured parameters.</p>
<h2 id="returns">Returns</h2>
<dl>
<dt><code>Chat</code></dt>
<dd>An instance of the langchain Chat client.</dd>
</dl></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.inc" href="index.html">praisonai.inc</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.inc.models.PraisonAIModel" href="#praisonai.inc.models.PraisonAIModel">PraisonAIModel</a></code></h4>
<ul class="">
<li><code><a title="praisonai.inc.models.PraisonAIModel.get_model" href="#praisonai.inc.models.PraisonAIModel.get_model">get_model</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-107
View File
@@ -1,107 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Package <code>praisonai</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.agents_generator" href="agents_generator.html">praisonai.agents_generator</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.auto" href="auto.html">praisonai.auto</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.cli" href="cli.html">praisonai.cli</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.deploy" href="deploy.html">praisonai.deploy</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inbuilt_tools" href="inbuilt_tools/index.html">praisonai.inbuilt_tools</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.inc" href="inc/index.html">praisonai.inc</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup" href="setup/index.html">praisonai.setup</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.test" href="test.html">praisonai.test</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui" href="ui/index.html">praisonai.ui</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.version" href="version.html">praisonai.version</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.agents_generator" href="agents_generator.html">praisonai.agents_generator</a></code></li>
<li><code><a title="praisonai.auto" href="auto.html">praisonai.auto</a></code></li>
<li><code><a title="praisonai.cli" href="cli.html">praisonai.cli</a></code></li>
<li><code><a title="praisonai.deploy" href="deploy.html">praisonai.deploy</a></code></li>
<li><code><a title="praisonai.inbuilt_tools" href="inbuilt_tools/index.html">praisonai.inbuilt_tools</a></code></li>
<li><code><a title="praisonai.inc" href="inc/index.html">praisonai.inc</a></code></li>
<li><code><a title="praisonai.setup" href="setup/index.html">praisonai.setup</a></code></li>
<li><code><a title="praisonai.test" href="test.html">praisonai.test</a></code></li>
<li><code><a title="praisonai.ui" href="ui/index.html">praisonai.ui</a></code></li>
<li><code><a title="praisonai.version" href="version.html">praisonai.version</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-69
View File
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.build API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.build</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.build.build"><code class="name flex">
<span>def <span class="ident">build</span></span>(<span>setup_kwargs)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.build.build" href="#praisonai.setup.build.build">build</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-77
View File
@@ -1,77 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.setup.build" href="build.html">praisonai.setup.build</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup.post_install" href="post_install.html">praisonai.setup.post_install</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.setup.setup_conda_env" href="setup_conda_env.html">praisonai.setup.setup_conda_env</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.setup.build" href="build.html">praisonai.setup.build</a></code></li>
<li><code><a title="praisonai.setup.post_install" href="post_install.html">praisonai.setup.post_install</a></code></li>
<li><code><a title="praisonai.setup.setup_conda_env" href="setup_conda_env.html">praisonai.setup.setup_conda_env</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.post_install API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.post_install</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.post_install.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.post_install.main" href="#praisonai.setup.post_install.main">main</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
@@ -1,69 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.setup.setup_conda_env API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.setup.setup_conda_env</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.setup.setup_conda_env.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.setup" href="index.html">praisonai.setup</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.setup.setup_conda_env.main" href="#praisonai.setup.setup_conda_env.main">main</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-73
View File
@@ -1,73 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.test API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.test</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.test.generate_crew_and_kickoff"><code class="name flex">
<span>def <span class="ident">generate_crew_and_kickoff</span></span>(<span>agent_file)</span>
</code></dt>
<dd>
<div class="desc"><p>This function generates a crew of agents and kicks off tasks based on the configuration provided in a YAML file.</p>
<p>Parameters:
agent_file (str): The path to the YAML file containing the configuration for the agents and tasks.</p>
<p>Returns:
str: The result of the last task executed by the crew.</p></div>
</dd>
</dl>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.test.generate_crew_and_kickoff" href="#praisonai.test.generate_crew_and_kickoff">generate_crew_and_kickoff</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-428
View File
@@ -1,428 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui.context API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.ui.context</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="praisonai.ui.context.main"><code class="name flex">
<span>def <span class="ident">main</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.ui.context.ContextGatherer"><code class="flex name class">
<span>class <span class="ident">ContextGatherer</span></span>
<span>(</span><span>directory='.', output_file='context.txt', relevant_extensions=None, max_file_size=1000000, max_tokens=900000)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class ContextGatherer:
def __init__(self, directory=&#39;.&#39;, output_file=&#39;context.txt&#39;,
relevant_extensions=None, max_file_size=1_000_000, max_tokens=900000):
self.directory = directory
self.output_file = output_file
self.relevant_extensions = relevant_extensions or [
&#39;.py&#39;, &#39;.js&#39;, &#39;.ts&#39;, &#39;.java&#39;, &#39;.rb&#39;, &#39;.php&#39;, &#39;.pl&#39;, &#39;.pm&#39;, &#39;.c&#39;, &#39;.h&#39;,
&#39;.cpp&#39;, &#39;.hpp&#39;, &#39;.cs&#39;, &#39;.vb&#39;, &#39;.swift&#39;, &#39;.kt&#39;, &#39;.m&#39;, &#39;.mm&#39;, &#39;.go&#39;, &#39;.rs&#39;,
&#39;.hs&#39;, &#39;.r&#39;, &#39;.lua&#39;, &#39;.sh&#39;, &#39;.bat&#39;, &#39;.clj&#39;, &#39;.scala&#39;, &#39;.erl&#39;, &#39;.ex&#39;,
&#39;.ml&#39;, &#39;.fs&#39;, &#39;.groovy&#39;, &#39;.jsm&#39;, &#39;.jsx&#39;, &#39;.tsx&#39;, &#39;.yaml&#39;
]
self.max_file_size = max_file_size
self.max_tokens = int(os.getenv(&#34;PRAISONAI_MAX_TOKENS&#34;, max_tokens))
self.ignore_patterns = self.get_ignore_patterns()
self.include_paths = self.get_include_paths()
self.included_files = []
def get_ignore_patterns(self):
&#34;&#34;&#34;
Loads ignore patterns from various sources, prioritizing them in
the following order:
1. .praisonignore
2. settings.yaml (under code.ignore_files)
3. PRAISONAI_IGNORE_FILES environment variable
4. .gitignore
5. Default patterns
&#34;&#34;&#34;
ignore_patterns = []
def load_from_file(filepath):
if os.path.exists(filepath):
with open(filepath, &#39;r&#39;) as f:
ignore_patterns.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
# 1. Load from .praisonignore
load_from_file(os.path.join(self.directory, &#39;.praisonignore&#39;))
# 2. Load from settings.yaml
settings_path = os.path.join(self.directory, &#39;settings.yaml&#39;)
if os.path.exists(settings_path):
with open(settings_path, &#39;r&#39;) as f:
settings = yaml.safe_load(f)
if &#39;code&#39; in settings and &#39;ignore_files&#39; in settings[&#39;code&#39;]:
ignore_patterns.extend(settings[&#39;code&#39;][&#39;ignore_files&#39;])
# 3. Load from environment variable
ignore_files_env = os.getenv(&#34;PRAISONAI_IGNORE_FILES&#34;)
if ignore_files_env:
ignore_patterns.extend(ignore_files_env.split(&#34;,&#34;))
# 4. Load from .gitignore
load_from_file(os.path.join(self.directory, &#39;.gitignore&#39;))
# 5. Default patterns (only if no patterns loaded from above sources)
if not ignore_patterns:
ignore_patterns = [
&#34;.*&#34;, &#34;*.pyc&#34;, &#34;__pycache__&#34;, &#34;.git&#34;, &#34;.gitignore&#34;, &#34;.vscode&#34;,
&#34;.idea&#34;, &#34;.DS_Store&#34;, &#34;*.lock&#34;, &#34;*.pyc&#34;, &#34;.env&#34;, &#34;docs&#34;, &#34;tests&#34;,
&#34;test&#34;, &#34;tmp&#34;, &#34;temp&#34;, &#34;*.txt&#34;, &#34;*.md&#34;, &#34;*.json&#34;, &#34;*.csv&#34;, &#34;*.tsv&#34;,
&#34;public&#34;, &#34;*.sql&#34;, &#34;*.sqlite&#34;, &#34;*.db&#34;, &#34;*.db3&#34;, &#34;*.sqlite3&#34;,
&#34;*.log&#34;, &#34;*.zip&#34;, &#34;*.gz&#34;, &#34;*.tar&#34;, &#34;*.rar&#34;, &#34;*.7z&#34;, &#34;*.pdf&#34;,
&#34;*.jpg&#34;, &#34;*.jpeg&#34;, &#34;*.png&#34;, &#34;*.gif&#34;, &#34;*.svg&#34;, &#34;cookbooks&#34;,
&#34;assets&#34;, &#34;__pycache__&#34;, &#34;dist&#34;, &#34;build&#34;, &#34;node_modules&#34;, &#34;venv&#34;
]
logger.debug(f&#34;Using default ignore patterns: {ignore_patterns}&#34;)
# Modify patterns to match directories and add leading &#39;*&#39; if necessary
modified_ignore_patterns = [
&#39;*&#39; + pattern if not pattern.startswith(&#39;.&#39;) and not pattern.startswith(&#39;*&#39;) else pattern
for pattern in ignore_patterns
]
logger.debug(f&#34;Final ignore patterns: {modified_ignore_patterns}&#34;)
return modified_ignore_patterns
def get_include_paths(self):
&#34;&#34;&#34;
Loads include paths from:
1. .praisoninclude (includes ONLY files/directories listed)
2. .praisoncontext (if .praisoninclude doesn&#39;t exist, this is used
to include all other relevant files, excluding ignore patterns)
&#34;&#34;&#34;
include_paths = []
include_all = False # Flag to indicate if we need to include all files
include_file = os.path.join(self.directory, &#39;.praisoncontext&#39;)
if os.path.exists(include_file):
with open(include_file, &#39;r&#39;) as f:
include_paths.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
# If .praisoncontext doesn&#39;t exist, fall back to .praisoninclude
# for including all relevant files
if not include_paths:
include_file = os.path.join(self.directory, &#39;.praisoninclude&#39;)
if os.path.exists(include_file):
with open(include_file, &#39;r&#39;) as f:
include_paths.extend(
line.strip() for line in f
if line.strip() and not line.startswith(&#39;#&#39;)
)
include_all = True # Include all files along with specified paths
return include_paths, include_all
def should_ignore(self, file_path):
&#34;&#34;&#34;
Check if a file or directory should be ignored based on patterns.
Handles both file names and directory names for more comprehensive filtering.
&#34;&#34;&#34;
relative_path = os.path.relpath(file_path, self.directory)
if relative_path.startswith(&#39;.&#39;):
return True
for pattern in self.ignore_patterns:
if fnmatch.fnmatch(relative_path, pattern) or \
fnmatch.fnmatch(os.path.basename(file_path), pattern):
return True
return False
def is_relevant_file(self, file_path):
&#34;&#34;&#34;Determine if a file is relevant for the context.&#34;&#34;&#34;
return os.path.isfile(file_path) and \
os.path.getsize(file_path) &lt;= self.max_file_size and \
any(file_path.endswith(ext) for ext in self.relevant_extensions)
def gather_context(self):
&#34;&#34;&#34;
Gather context from relevant files, respecting ignore patterns
and include options from .praisoninclude and .praisoncontext.
&#34;&#34;&#34;
context = []
total_files = 0
processed_files = 0
self.include_paths, include_all = self.get_include_paths()
def add_file_content(file_path):
&#34;&#34;&#34;Helper function to add file content to context.&#34;&#34;&#34;
try:
with open(file_path, &#39;r&#39;, encoding=&#39;utf-8&#39;) as f:
content = f.read()
context.append(
f&#34;File: {file_path}\n\n{content}\n\n{&#39;=&#39; * 50}\n&#34;
)
self.included_files.append(
Path(file_path).relative_to(self.directory)
)
except Exception as e:
logger.error(f&#34;Error reading {file_path}: {e}&#34;)
def process_path(path):
&#34;&#34;&#34;Helper function to process a single path (file or directory).&#34;&#34;&#34;
nonlocal total_files, processed_files
if os.path.isdir(path):
for root, dirs, files in os.walk(path):
total_files += len(files)
dirs[:] = [
d
for d in dirs
if not self.should_ignore(os.path.join(root, d))
]
for file in files:
file_path = os.path.join(root, file)
if not self.should_ignore(file_path) and self.is_relevant_file(file_path):
add_file_content(file_path)
processed_files += 1
print(
f&#34;\rProcessed {processed_files}/{total_files} files&#34;,
end=&#34;&#34;,
flush=True,
)
elif os.path.isfile(path) and self.is_relevant_file(path):
add_file_content(path)
processed_files += 1
print(
f&#34;\rProcessed {processed_files}/1 files&#34;,
end=&#34;&#34;,
flush=True,
)
if include_all:
# Include ALL relevant files from the entire directory
process_path(self.directory)
# Include files from .praisoninclude specifically
for include_path in self.include_paths:
full_path = os.path.join(self.directory, include_path)
process_path(full_path)
elif self.include_paths:
# Include only files specified in .praisoncontext
for include_path in self.include_paths:
full_path = os.path.join(self.directory, include_path)
process_path(full_path)
else:
# No include options, process the entire directory
process_path(self.directory)
print() # New line after progress indicator
return &#34;\n&#34;.join(context)
def count_tokens(self, text):
&#34;&#34;&#34;Count tokens using a simple whitespace-based tokenizer.&#34;&#34;&#34;
return len(text.split())
def truncate_context(self, context):
&#34;&#34;&#34;Truncate context to stay within the token limit.&#34;&#34;&#34;
tokens = context.split()
if len(tokens) &gt; self.max_tokens:
truncated_context = &#39; &#39;.join(tokens[:self.max_tokens])
logger.warning(&#34;Context truncated due to token limit.&#34;)
return truncated_context
return context
def save_context(self, context):
&#34;&#34;&#34;Save the gathered context to a file.&#34;&#34;&#34;
with open(self.output_file, &#39;w&#39;, encoding=&#39;utf-8&#39;) as f:
f.write(context)
def get_context_tree(self):
&#34;&#34;&#34;Generate a formatted tree structure of included files and folders.&#34;&#34;&#34;
tree = []
start_dir = Path(self.directory)
def add_to_tree(path, prefix=&#39;&#39;):
contents = sorted(path.iterdir())
pointers = [(&#39;└── &#39; if i == len(contents) - 1 else &#39;├── &#39;) for i in range(len(contents))]
for pointer, item in zip(pointers, contents):
rel_path = item.relative_to(start_dir)
if rel_path in self.included_files:
tree.append(f&#34;{prefix}{pointer}{rel_path}&#34;)
if item.is_dir():
add_to_tree(item, prefix + (&#39; &#39; if pointer == &#39;└── &#39; else &#39;│ &#39;))
add_to_tree(start_dir)
return &#39;\n&#39;.join(tree)
def run(self):
&#34;&#34;&#34;Execute the context gathering, truncation, and reporting.&#34;&#34;&#34;
context = self.gather_context()
context = self.truncate_context(context)
token_count = self.count_tokens(context)
print(f&#34;Context gathered successfully.&#34;)
print(f&#34;Total number of tokens (estimated): {token_count}&#34;)
# self.save_context(context)
context_tree = self.get_context_tree()
logger.debug(f&#34;Context tree:\n{context_tree}&#34;)
return context, token_count, context_tree</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="praisonai.ui.context.ContextGatherer.count_tokens"><code class="name flex">
<span>def <span class="ident">count_tokens</span></span>(<span>self, text)</span>
</code></dt>
<dd>
<div class="desc"><p>Count tokens using a simple whitespace-based tokenizer.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.gather_context"><code class="name flex">
<span>def <span class="ident">gather_context</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Gather context from relevant files, respecting ignore patterns
and include options from .praisoninclude and .praisoncontext.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_context_tree"><code class="name flex">
<span>def <span class="ident">get_context_tree</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Generate a formatted tree structure of included files and folders.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_ignore_patterns"><code class="name flex">
<span>def <span class="ident">get_ignore_patterns</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads ignore patterns from various sources, prioritizing them in
the following order:
1. .praisonignore
2. settings.yaml (under code.ignore_files)
3. PRAISONAI_IGNORE_FILES environment variable
4. .gitignore
5. Default patterns</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.get_include_paths"><code class="name flex">
<span>def <span class="ident">get_include_paths</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Loads include paths from:
1. .praisoninclude (includes ONLY files/directories listed)
2. .praisoncontext (if .praisoninclude doesn't exist, this is used
to include all other relevant files, excluding ignore patterns)</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.is_relevant_file"><code class="name flex">
<span>def <span class="ident">is_relevant_file</span></span>(<span>self, file_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Determine if a file is relevant for the context.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.run"><code class="name flex">
<span>def <span class="ident">run</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Execute the context gathering, truncation, and reporting.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.save_context"><code class="name flex">
<span>def <span class="ident">save_context</span></span>(<span>self, context)</span>
</code></dt>
<dd>
<div class="desc"><p>Save the gathered context to a file.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.should_ignore"><code class="name flex">
<span>def <span class="ident">should_ignore</span></span>(<span>self, file_path)</span>
</code></dt>
<dd>
<div class="desc"><p>Check if a file or directory should be ignored based on patterns.
Handles both file names and directory names for more comprehensive filtering.</p></div>
</dd>
<dt id="praisonai.ui.context.ContextGatherer.truncate_context"><code class="name flex">
<span>def <span class="ident">truncate_context</span></span>(<span>self, context)</span>
</code></dt>
<dd>
<div class="desc"><p>Truncate context to stay within the token limit.</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.ui" href="index.html">praisonai.ui</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="praisonai.ui.context.main" href="#praisonai.ui.context.main">main</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.ui.context.ContextGatherer" href="#praisonai.ui.context.ContextGatherer">ContextGatherer</a></code></h4>
<ul class="two-column">
<li><code><a title="praisonai.ui.context.ContextGatherer.count_tokens" href="#praisonai.ui.context.ContextGatherer.count_tokens">count_tokens</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.gather_context" href="#praisonai.ui.context.ContextGatherer.gather_context">gather_context</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_context_tree" href="#praisonai.ui.context.ContextGatherer.get_context_tree">get_context_tree</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_ignore_patterns" href="#praisonai.ui.context.ContextGatherer.get_ignore_patterns">get_ignore_patterns</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.get_include_paths" href="#praisonai.ui.context.ContextGatherer.get_include_paths">get_include_paths</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.is_relevant_file" href="#praisonai.ui.context.ContextGatherer.is_relevant_file">is_relevant_file</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.run" href="#praisonai.ui.context.ContextGatherer.run">run</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.save_context" href="#praisonai.ui.context.ContextGatherer.save_context">save_context</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.should_ignore" href="#praisonai.ui.context.ContextGatherer.should_ignore">should_ignore</a></code></li>
<li><code><a title="praisonai.ui.context.ContextGatherer.truncate_context" href="#praisonai.ui.context.ContextGatherer.truncate_context">truncate_context</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-77
View File
@@ -1,77 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Namespace <code>praisonai.ui</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="praisonai.ui.context" href="context.html">praisonai.ui.context</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui.realtimeclient" href="realtimeclient/index.html">praisonai.ui.realtimeclient</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="praisonai.ui.sql_alchemy" href="sql_alchemy.html">praisonai.ui.sql_alchemy</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="../index.html">praisonai</a></code></li>
</ul>
</li>
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="praisonai.ui.context" href="context.html">praisonai.ui.context</a></code></li>
<li><code><a title="praisonai.ui.realtimeclient" href="realtimeclient/index.html">praisonai.ui.realtimeclient</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy" href="sql_alchemy.html">praisonai.ui.sql_alchemy</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
File diff suppressed because it is too large. Load diff
-898
View File
@@ -1,898 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.ui.sql_alchemy API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.ui.sql_alchemy</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer"><code class="flex name class">
<span>class <span class="ident">SQLAlchemyDataLayer</span></span>
<span>(</span><span>conninfo: str, ssl_require: bool = False, storage_provider: Optional[chainlit.data.base.BaseStorageClient] = None, user_thread_limit: Optional[int] = 1000, show_logger: Optional[bool] = False)</span>
</code></dt>
<dd>
<div class="desc"><p>Base class for data persistence.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class SQLAlchemyDataLayer(BaseDataLayer):
def __init__(
self,
conninfo: str,
ssl_require: bool = False,
storage_provider: Optional[BaseStorageClient] = None,
user_thread_limit: Optional[int] = 1000,
show_logger: Optional[bool] = False,
):
self._conninfo = conninfo
self.user_thread_limit = user_thread_limit
self.show_logger = show_logger
ssl_args = {}
if ssl_require:
# Create an SSL context to require an SSL connection
ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
ssl_args[&#34;ssl&#34;] = ssl_context
self.engine: AsyncEngine = create_async_engine(
self._conninfo, connect_args=ssl_args
)
self.async_session = sessionmaker(
bind=self.engine, expire_on_commit=False, class_=AsyncSession
) # type: ignore
if storage_provider:
self.storage_provider: Optional[BaseStorageClient] = storage_provider
if self.show_logger:
logger.info(&#34;SQLAlchemyDataLayer storage client initialized&#34;)
else:
self.storage_provider = None
logger.warn(
&#34;SQLAlchemyDataLayer storage client is not initialized and elements will not be persisted!&#34;
)
async def build_debug_url(self) -&gt; str:
return &#34;&#34;
###### SQL Helpers ######
async def execute_sql(
self, query: str, parameters: dict
) -&gt; Union[List[Dict[str, Any]], int, None]:
parameterized_query = text(query)
async with self.async_session() as session:
try:
await session.begin()
result = await session.execute(parameterized_query, parameters)
await session.commit()
if result.returns_rows:
json_result = [dict(row._mapping) for row in result.fetchall()]
clean_json_result = self.clean_result(json_result)
assert isinstance(clean_json_result, list) or isinstance(
clean_json_result, int
)
return clean_json_result
else:
return result.rowcount
except SQLAlchemyError as e:
await session.rollback()
logger.warn(f&#34;An error occurred: {e}&#34;)
return None
except Exception as e:
await session.rollback()
logger.warn(f&#34;An unexpected error occurred: {e}&#34;)
return None
async def get_current_timestamp(self) -&gt; str:
return datetime.now().isoformat() + &#34;Z&#34;
def clean_result(self, obj):
&#34;&#34;&#34;Recursively change UUID -&gt; str and serialize dictionaries&#34;&#34;&#34;
if isinstance(obj, dict):
return {k: self.clean_result(v) for k, v in obj.items()}
elif isinstance(obj, list):
return [self.clean_result(item) for item in obj]
elif isinstance(obj, uuid.UUID):
return str(obj)
return obj
###### User ######
async def get_user(self, identifier: str) -&gt; Optional[PersistedUser]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_user, identifier={identifier}&#34;)
query = &#34;SELECT * FROM users WHERE identifier = :identifier&#34;
parameters = {&#34;identifier&#34;: identifier}
result = await self.execute_sql(query=query, parameters=parameters)
if result and isinstance(result, list):
user_data = result[0]
# SQLite returns JSON as string, we most convert it. (#1137)
metadata = user_data.get(&#34;metadata&#34;, {})
if isinstance(metadata, str):
metadata = json.loads(metadata)
assert isinstance(metadata, dict)
assert isinstance(user_data[&#34;id&#34;], str)
assert isinstance(user_data[&#34;identifier&#34;], str)
assert isinstance(user_data[&#34;createdAt&#34;], str)
return PersistedUser(
id=user_data[&#34;id&#34;],
identifier=user_data[&#34;identifier&#34;],
createdAt=user_data[&#34;createdAt&#34;],
metadata=metadata,
)
return None
async def _get_user_identifer_by_id(self, user_id: str) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: _get_user_identifer_by_id, user_id={user_id}&#34;)
query = &#34;SELECT identifier FROM users WHERE id = :user_id&#34;
parameters = {&#34;user_id&#34;: user_id}
result = await self.execute_sql(query=query, parameters=parameters)
assert result
assert isinstance(result, list)
return result[0][&#34;identifier&#34;]
async def _get_user_id_by_thread(self, thread_id: str) -&gt; Optional[str]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: _get_user_id_by_thread, thread_id={thread_id}&#34;)
query = &#34;SELECT userId FROM threads WHERE id = :thread_id&#34;
parameters = {&#34;thread_id&#34;: thread_id}
result = await self.execute_sql(query=query, parameters=parameters)
if result:
assert isinstance(result, list)
return result[0][&#34;userId&#34;]
return None
async def create_user(self, user: User) -&gt; Optional[PersistedUser]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_user, user_identifier={user.identifier}&#34;)
existing_user: Optional[&#34;PersistedUser&#34;] = await self.get_user(user.identifier)
user_dict: Dict[str, Any] = {
&#34;identifier&#34;: str(user.identifier),
&#34;metadata&#34;: json.dumps(user.metadata) or {},
}
if not existing_user: # create the user
if self.show_logger:
logger.info(&#34;SQLAlchemy: create_user, creating the user&#34;)
user_dict[&#34;id&#34;] = str(uuid.uuid4())
user_dict[&#34;createdAt&#34;] = await self.get_current_timestamp()
query = &#34;&#34;&#34;INSERT INTO users (&#34;id&#34;, &#34;identifier&#34;, &#34;createdAt&#34;, &#34;metadata&#34;) VALUES (:id, :identifier, :createdAt, :metadata)&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=user_dict)
else: # update the user
if self.show_logger:
logger.info(&#34;SQLAlchemy: update user metadata&#34;)
query = &#34;&#34;&#34;UPDATE users SET &#34;metadata&#34; = :metadata WHERE &#34;identifier&#34; = :identifier&#34;&#34;&#34;
await self.execute_sql(
query=query, parameters=user_dict
) # We want to update the metadata
return await self.get_user(user.identifier)
###### Threads ######
async def get_thread_author(self, thread_id: str) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_thread_author, thread_id={thread_id}&#34;)
query = &#34;&#34;&#34;SELECT &#34;userIdentifier&#34; FROM threads WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: thread_id}
result = await self.execute_sql(query=query, parameters=parameters)
if isinstance(result, list) and result:
author_identifier = result[0].get(&#34;userIdentifier&#34;)
if author_identifier is not None:
return author_identifier
raise ValueError(f&#34;Author not found for thread_id {thread_id}&#34;)
async def get_thread(self, thread_id: str) -&gt; Optional[ThreadDict]:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: get_thread, thread_id={thread_id}&#34;)
user_threads: Optional[List[ThreadDict]] = await self.get_all_user_threads(
thread_id=thread_id
)
if user_threads:
return user_threads[0]
else:
return None
async def update_thread(
self,
thread_id: str,
name: Optional[str] = None,
user_id: Optional[str] = None,
metadata: Optional[Dict] = None,
tags: Optional[List[str]] = None,
):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: update_thread, thread_id={thread_id}&#34;)
user_identifier = None
if user_id:
user_identifier = await self._get_user_identifer_by_id(user_id)
data = {
&#34;id&#34;: thread_id,
&#34;createdAt&#34;: (
await self.get_current_timestamp() if metadata is None else None
),
&#34;name&#34;: (
name
if name is not None
else (metadata.get(&#34;name&#34;) if metadata and &#34;name&#34; in metadata else None)
),
&#34;userId&#34;: user_id,
&#34;userIdentifier&#34;: user_identifier,
&#34;tags&#34;: tags,
&#34;metadata&#34;: json.dumps(metadata) if metadata else None,
}
parameters = {
key: value for key, value in data.items() if value is not None
} # Remove keys with None values
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = EXCLUDED.&#34;{key}&#34;&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO threads ({columns})
VALUES ({values})
ON CONFLICT (&#34;id&#34;) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
async def delete_thread(self, thread_id: str):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_thread, thread_id={thread_id}&#34;)
# Delete feedbacks/elements/steps/thread
feedbacks_query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;forId&#34; IN (SELECT &#34;id&#34; FROM steps WHERE &#34;threadId&#34; = :id)&#34;&#34;&#34;
elements_query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;threadId&#34; = :id&#34;&#34;&#34;
steps_query = &#34;&#34;&#34;DELETE FROM steps WHERE &#34;threadId&#34; = :id&#34;&#34;&#34;
thread_query = &#34;&#34;&#34;DELETE FROM threads WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: thread_id}
await self.execute_sql(query=feedbacks_query, parameters=parameters)
await self.execute_sql(query=elements_query, parameters=parameters)
await self.execute_sql(query=steps_query, parameters=parameters)
await self.execute_sql(query=thread_query, parameters=parameters)
async def list_threads(
self, pagination: Pagination, filters: ThreadFilter
) -&gt; PaginatedResponse:
if self.show_logger:
logger.info(
f&#34;SQLAlchemy: list_threads, pagination={pagination}, filters={filters}&#34;
)
if not filters.userId:
raise ValueError(&#34;userId is required&#34;)
all_user_threads: List[ThreadDict] = (
await self.get_all_user_threads(user_id=filters.userId) or []
)
search_keyword = filters.search.lower() if filters.search else None
feedback_value = int(filters.feedback) if filters.feedback else None
filtered_threads = []
for thread in all_user_threads:
keyword_match = True
feedback_match = True
if search_keyword or feedback_value is not None:
if search_keyword:
keyword_match = any(
search_keyword in step[&#34;output&#34;].lower()
for step in thread[&#34;steps&#34;]
if &#34;output&#34; in step
)
if feedback_value is not None:
feedback_match = False # Assume no match until found
for step in thread[&#34;steps&#34;]:
feedback = step.get(&#34;feedback&#34;)
if feedback and feedback.get(&#34;value&#34;) == feedback_value:
feedback_match = True
break
if keyword_match and feedback_match:
filtered_threads.append(thread)
start = 0
if pagination.cursor:
for i, thread in enumerate(filtered_threads):
if (
thread[&#34;id&#34;] == pagination.cursor
): # Find the start index using pagination.cursor
start = i + 1
break
end = start + pagination.first
paginated_threads = filtered_threads[start:end] or []
has_next_page = len(filtered_threads) &gt; end
start_cursor = paginated_threads[0][&#34;id&#34;] if paginated_threads else None
end_cursor = paginated_threads[-1][&#34;id&#34;] if paginated_threads else None
return PaginatedResponse(
pageInfo=PageInfo(
hasNextPage=has_next_page,
startCursor=start_cursor,
endCursor=end_cursor,
),
data=paginated_threads,
)
###### Steps ######
@queue_until_user_message()
async def create_step(self, step_dict: &#34;StepDict&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_step, step_id={step_dict.get(&#39;id&#39;)}&#34;)
step_dict[&#34;showInput&#34;] = (
str(step_dict.get(&#34;showInput&#34;, &#34;&#34;)).lower()
if &#34;showInput&#34; in step_dict
else None
)
parameters = {
key: value
for key, value in step_dict.items()
if value is not None and not (isinstance(value, dict) and not value)
}
parameters[&#34;metadata&#34;] = json.dumps(step_dict.get(&#34;metadata&#34;, {}))
parameters[&#34;generation&#34;] = json.dumps(step_dict.get(&#34;generation&#34;, {}))
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = :{key}&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO steps ({columns})
VALUES ({values})
ON CONFLICT (id) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
@queue_until_user_message()
async def update_step(self, step_dict: &#34;StepDict&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: update_step, step_id={step_dict.get(&#39;id&#39;)}&#34;)
await self.create_step(step_dict)
@queue_until_user_message()
async def delete_step(self, step_id: str):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_step, step_id={step_id}&#34;)
# Delete feedbacks/elements/steps
feedbacks_query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;forId&#34; = :id&#34;&#34;&#34;
elements_query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;forId&#34; = :id&#34;&#34;&#34;
steps_query = &#34;&#34;&#34;DELETE FROM steps WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: step_id}
await self.execute_sql(query=feedbacks_query, parameters=parameters)
await self.execute_sql(query=elements_query, parameters=parameters)
await self.execute_sql(query=steps_query, parameters=parameters)
###### Feedback ######
async def upsert_feedback(self, feedback: Feedback) -&gt; str:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: upsert_feedback, feedback_id={feedback.id}&#34;)
feedback.id = feedback.id or str(uuid.uuid4())
feedback_dict = asdict(feedback)
parameters = {
key: value for key, value in feedback_dict.items() if value is not None
}
columns = &#34;, &#34;.join(f&#39;&#34;{key}&#34;&#39; for key in parameters.keys())
values = &#34;, &#34;.join(f&#34;:{key}&#34; for key in parameters.keys())
updates = &#34;, &#34;.join(
f&#39;&#34;{key}&#34; = :{key}&#39; for key in parameters.keys() if key != &#34;id&#34;
)
query = f&#34;&#34;&#34;
INSERT INTO feedbacks ({columns})
VALUES ({values})
ON CONFLICT (id) DO UPDATE
SET {updates};
&#34;&#34;&#34;
await self.execute_sql(query=query, parameters=parameters)
return feedback.id
async def delete_feedback(self, feedback_id: str) -&gt; bool:
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_feedback, feedback_id={feedback_id}&#34;)
query = &#34;&#34;&#34;DELETE FROM feedbacks WHERE &#34;id&#34; = :feedback_id&#34;&#34;&#34;
parameters = {&#34;feedback_id&#34;: feedback_id}
await self.execute_sql(query=query, parameters=parameters)
return True
###### Elements ######
async def get_element(
self, thread_id: str, element_id: str
) -&gt; Optional[&#34;ElementDict&#34;]:
if self.show_logger:
logger.info(
f&#34;SQLAlchemy: get_element, thread_id={thread_id}, element_id={element_id}&#34;
)
query = &#34;&#34;&#34;SELECT * FROM elements WHERE &#34;threadId&#34; = :thread_id AND &#34;id&#34; = :element_id&#34;&#34;&#34;
parameters = {&#34;thread_id&#34;: thread_id, &#34;element_id&#34;: element_id}
element: Union[List[Dict[str, Any]], int, None] = await self.execute_sql(
query=query, parameters=parameters
)
if isinstance(element, list) and element:
element_dict: Dict[str, Any] = element[0]
return ElementDict(
id=element_dict[&#34;id&#34;],
threadId=element_dict.get(&#34;threadId&#34;),
type=element_dict[&#34;type&#34;],
chainlitKey=element_dict.get(&#34;chainlitKey&#34;),
url=element_dict.get(&#34;url&#34;),
objectKey=element_dict.get(&#34;objectKey&#34;),
name=element_dict[&#34;name&#34;],
display=element_dict[&#34;display&#34;],
size=element_dict.get(&#34;size&#34;),
language=element_dict.get(&#34;language&#34;),
page=element_dict.get(&#34;page&#34;),
autoPlay=element_dict.get(&#34;autoPlay&#34;),
playerConfig=element_dict.get(&#34;playerConfig&#34;),
forId=element_dict.get(&#34;forId&#34;),
mime=element_dict.get(&#34;mime&#34;),
)
else:
return None
@queue_until_user_message()
async def create_element(self, element: &#34;Element&#34;):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: create_element, element_id = {element.id}&#34;)
if not self.storage_provider:
logger.warn(
&#34;SQLAlchemy: create_element error. No blob_storage_client is configured!&#34;
)
return
if not element.for_id:
return
content: Optional[Union[bytes, str]] = None
if element.path:
async with aiofiles.open(element.path, &#34;rb&#34;) as f:
content = await f.read()
elif element.url:
async with aiohttp.ClientSession() as session:
async with session.get(element.url) as response:
if response.status == 200:
content = await response.read()
else:
content = None
elif element.content:
content = element.content
else:
raise ValueError(&#34;Element url, path or content must be provided&#34;)
if content is None:
raise ValueError(&#34;Content is None, cannot upload file&#34;)
user_id: str = await self._get_user_id_by_thread(element.thread_id) or &#34;unknown&#34;
file_object_key = f&#34;{user_id}/{element.id}&#34; + (
f&#34;/{element.name}&#34; if element.name else &#34;&#34;
)
if not element.mime:
element.mime = &#34;application/octet-stream&#34;
uploaded_file = await self.storage_provider.upload_file(
object_key=file_object_key, data=content, mime=element.mime, overwrite=True
)
if not uploaded_file:
raise ValueError(
&#34;SQLAlchemy Error: create_element, Failed to persist data in storage_provider&#34;
)
element_dict: ElementDict = element.to_dict()
element_dict[&#34;url&#34;] = uploaded_file.get(&#34;url&#34;)
element_dict[&#34;objectKey&#34;] = uploaded_file.get(&#34;object_key&#34;)
element_dict_cleaned = {k: v for k, v in element_dict.items() if v is not None}
columns = &#34;, &#34;.join(f&#39;&#34;{column}&#34;&#39; for column in element_dict_cleaned.keys())
placeholders = &#34;, &#34;.join(f&#34;:{column}&#34; for column in element_dict_cleaned.keys())
query = f&#34;INSERT INTO elements ({columns}) VALUES ({placeholders})&#34;
await self.execute_sql(query=query, parameters=element_dict_cleaned)
@queue_until_user_message()
async def delete_element(self, element_id: str, thread_id: Optional[str] = None):
if self.show_logger:
logger.info(f&#34;SQLAlchemy: delete_element, element_id={element_id}&#34;)
query = &#34;&#34;&#34;DELETE FROM elements WHERE &#34;id&#34; = :id&#34;&#34;&#34;
parameters = {&#34;id&#34;: element_id}
await self.execute_sql(query=query, parameters=parameters)
async def get_all_user_threads(
self, user_id: Optional[str] = None, thread_id: Optional[str] = None
) -&gt; Optional[List[ThreadDict]]:
&#34;&#34;&#34;Fetch all user threads up to self.user_thread_limit, or one thread by id if thread_id is provided.&#34;&#34;&#34;
if self.show_logger:
logger.info(&#34;SQLAlchemy: get_all_user_threads&#34;)
user_threads_query = &#34;&#34;&#34;
SELECT
&#34;id&#34; AS thread_id,
&#34;createdAt&#34; AS thread_createdat,
&#34;name&#34; AS thread_name,
&#34;userId&#34; AS user_id,
&#34;userIdentifier&#34; AS user_identifier,
&#34;tags&#34; AS thread_tags,
&#34;metadata&#34; AS thread_metadata
FROM threads
WHERE &#34;userId&#34; = :user_id OR &#34;id&#34; = :thread_id
ORDER BY &#34;createdAt&#34; DESC
LIMIT :limit
&#34;&#34;&#34;
user_threads = await self.execute_sql(
query=user_threads_query,
parameters={
&#34;user_id&#34;: user_id,
&#34;limit&#34;: self.user_thread_limit,
&#34;thread_id&#34;: thread_id,
},
)
if not isinstance(user_threads, list):
return None
if not user_threads:
return []
else:
thread_ids = (
&#34;(&#39;&#34;
+ &#34;&#39;,&#39;&#34;.join(map(str, [thread[&#34;thread_id&#34;] for thread in user_threads]))
+ &#34;&#39;)&#34;
)
steps_feedbacks_query = f&#34;&#34;&#34;
SELECT
s.&#34;id&#34; AS step_id,
s.&#34;name&#34; AS step_name,
s.&#34;type&#34; AS step_type,
s.&#34;threadId&#34; AS step_threadid,
s.&#34;parentId&#34; AS step_parentid,
s.&#34;streaming&#34; AS step_streaming,
s.&#34;waitForAnswer&#34; AS step_waitforanswer,
s.&#34;isError&#34; AS step_iserror,
s.&#34;metadata&#34; AS step_metadata,
s.&#34;tags&#34; AS step_tags,
s.&#34;input&#34; AS step_input,
s.&#34;output&#34; AS step_output,
s.&#34;createdAt&#34; AS step_createdat,
s.&#34;start&#34; AS step_start,
s.&#34;end&#34; AS step_end,
s.&#34;generation&#34; AS step_generation,
s.&#34;showInput&#34; AS step_showinput,
s.&#34;language&#34; AS step_language,
s.&#34;indent&#34; AS step_indent,
f.&#34;value&#34; AS feedback_value,
f.&#34;comment&#34; AS feedback_comment,
f.&#34;id&#34; AS feedback_id
FROM steps s LEFT JOIN feedbacks f ON s.&#34;id&#34; = f.&#34;forId&#34;
WHERE s.&#34;threadId&#34; IN {thread_ids}
ORDER BY s.&#34;createdAt&#34; ASC
&#34;&#34;&#34;
steps_feedbacks = await self.execute_sql(
query=steps_feedbacks_query, parameters={}
)
elements_query = f&#34;&#34;&#34;
SELECT
e.&#34;id&#34; AS element_id,
e.&#34;threadId&#34; as element_threadid,
e.&#34;type&#34; AS element_type,
e.&#34;chainlitKey&#34; AS element_chainlitkey,
e.&#34;url&#34; AS element_url,
e.&#34;objectKey&#34; as element_objectkey,
e.&#34;name&#34; AS element_name,
e.&#34;display&#34; AS element_display,
e.&#34;size&#34; AS element_size,
e.&#34;language&#34; AS element_language,
e.&#34;page&#34; AS element_page,
e.&#34;forId&#34; AS element_forid,
e.&#34;mime&#34; AS element_mime
FROM elements e
WHERE e.&#34;threadId&#34; IN {thread_ids}
&#34;&#34;&#34;
elements = await self.execute_sql(query=elements_query, parameters={})
thread_dicts = {}
for thread in user_threads:
thread_id = thread[&#34;thread_id&#34;]
if thread_id is not None:
# Ensure metadata is a dictionary
metadata = thread[&#34;thread_metadata&#34;]
if isinstance(metadata, str):
try:
metadata = json.loads(metadata)
except json.JSONDecodeError:
metadata = {}
elif metadata is None:
metadata = {}
thread_dicts[thread_id] = ThreadDict(
id=thread_id,
createdAt=thread[&#34;thread_createdat&#34;],
name=thread[&#34;thread_name&#34;],
userId=thread[&#34;user_id&#34;],
userIdentifier=thread[&#34;user_identifier&#34;],
tags=thread[&#34;thread_tags&#34;],
metadata=metadata,
steps=[],
elements=[],
)
# Process steps_feedbacks to populate the steps in the corresponding ThreadDict
if isinstance(steps_feedbacks, list):
for step_feedback in steps_feedbacks:
thread_id = step_feedback[&#34;step_threadid&#34;]
if thread_id is not None:
feedback = None
if step_feedback[&#34;feedback_value&#34;] is not None:
feedback = FeedbackDict(
forId=step_feedback[&#34;step_id&#34;],
id=step_feedback.get(&#34;feedback_id&#34;),
value=step_feedback[&#34;feedback_value&#34;],
comment=step_feedback.get(&#34;feedback_comment&#34;),
)
step_dict = StepDict(
id=step_feedback[&#34;step_id&#34;],
name=step_feedback[&#34;step_name&#34;],
type=step_feedback[&#34;step_type&#34;],
threadId=thread_id,
parentId=step_feedback.get(&#34;step_parentid&#34;),
streaming=step_feedback.get(&#34;step_streaming&#34;, False),
waitForAnswer=step_feedback.get(&#34;step_waitforanswer&#34;),
isError=step_feedback.get(&#34;step_iserror&#34;),
metadata=(
step_feedback[&#34;step_metadata&#34;]
if step_feedback.get(&#34;step_metadata&#34;) is not None
else {}
),
tags=step_feedback.get(&#34;step_tags&#34;),
input=(
step_feedback.get(&#34;step_input&#34;, &#34;&#34;)
if step_feedback.get(&#34;step_showinput&#34;)
not in [None, &#34;false&#34;]
else &#34;&#34;
),
output=step_feedback.get(&#34;step_output&#34;, &#34;&#34;),
createdAt=step_feedback.get(&#34;step_createdat&#34;),
start=step_feedback.get(&#34;step_start&#34;),
end=step_feedback.get(&#34;step_end&#34;),
generation=step_feedback.get(&#34;step_generation&#34;),
showInput=step_feedback.get(&#34;step_showinput&#34;),
language=step_feedback.get(&#34;step_language&#34;),
indent=step_feedback.get(&#34;step_indent&#34;),
feedback=feedback,
)
# Append the step to the steps list of the corresponding ThreadDict
thread_dicts[thread_id][&#34;steps&#34;].append(step_dict)
if isinstance(elements, list):
for element in elements:
thread_id = element[&#34;element_threadid&#34;]
if thread_id is not None:
element_dict = ElementDict(
id=element[&#34;element_id&#34;],
threadId=thread_id,
type=element[&#34;element_type&#34;],
chainlitKey=element.get(&#34;element_chainlitkey&#34;),
url=element.get(&#34;element_url&#34;),
objectKey=element.get(&#34;element_objectkey&#34;),
name=element[&#34;element_name&#34;],
display=element[&#34;element_display&#34;],
size=element.get(&#34;element_size&#34;),
language=element.get(&#34;element_language&#34;),
autoPlay=element.get(&#34;element_autoPlay&#34;),
playerConfig=element.get(&#34;element_playerconfig&#34;),
page=element.get(&#34;element_page&#34;),
forId=element.get(&#34;element_forid&#34;),
mime=element.get(&#34;element_mime&#34;),
)
thread_dicts[thread_id][&#34;elements&#34;].append(element_dict) # type: ignore
return list(thread_dicts.values())</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>chainlit.data.base.BaseDataLayer</li>
<li>abc.ABC</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url"><code class="name flex">
<span>async def <span class="ident">build_debug_url</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result"><code class="name flex">
<span>def <span class="ident">clean_result</span></span>(<span>self, obj)</span>
</code></dt>
<dd>
<div class="desc"><p>Recursively change UUID -&gt; str and serialize dictionaries</p></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element"><code class="name flex">
<span>async def <span class="ident">create_element</span></span>(<span>self, element: Element)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step"><code class="name flex">
<span>async def <span class="ident">create_step</span></span>(<span>self, step_dict: StepDict)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user"><code class="name flex">
<span>async def <span class="ident">create_user</span></span>(<span>self, user: chainlit.user.User) ‑> Optional[chainlit.user.PersistedUser]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element"><code class="name flex">
<span>async def <span class="ident">delete_element</span></span>(<span>self, element_id: str, thread_id: Optional[str] = None)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback"><code class="name flex">
<span>async def <span class="ident">delete_feedback</span></span>(<span>self, feedback_id: str) ‑> bool</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step"><code class="name flex">
<span>async def <span class="ident">delete_step</span></span>(<span>self, step_id: str)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread"><code class="name flex">
<span>async def <span class="ident">delete_thread</span></span>(<span>self, thread_id: str)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql"><code class="name flex">
<span>async def <span class="ident">execute_sql</span></span>(<span>self, query: str, parameters: dict) ‑> Union[List[Dict[str, Any]], int, ForwardRef(None)]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads"><code class="name flex">
<span>async def <span class="ident">get_all_user_threads</span></span>(<span>self, user_id: Optional[str] = None, thread_id: Optional[str] = None) ‑> Optional[List[chainlit.types.ThreadDict]]</span>
</code></dt>
<dd>
<div class="desc"><p>Fetch all user threads up to self.user_thread_limit, or one thread by id if thread_id is provided.</p></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp"><code class="name flex">
<span>async def <span class="ident">get_current_timestamp</span></span>(<span>self) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element"><code class="name flex">
<span>async def <span class="ident">get_element</span></span>(<span>self, thread_id: str, element_id: str) ‑> Optional[chainlit.element.ElementDict]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread"><code class="name flex">
<span>async def <span class="ident">get_thread</span></span>(<span>self, thread_id: str) ‑> Optional[chainlit.types.ThreadDict]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author"><code class="name flex">
<span>async def <span class="ident">get_thread_author</span></span>(<span>self, thread_id: str) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user"><code class="name flex">
<span>async def <span class="ident">get_user</span></span>(<span>self, identifier: str) ‑> Optional[chainlit.user.PersistedUser]</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads"><code class="name flex">
<span>async def <span class="ident">list_threads</span></span>(<span>self, pagination: chainlit.types.Pagination, filters: chainlit.types.ThreadFilter) ‑> chainlit.types.PaginatedResponse</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step"><code class="name flex">
<span>async def <span class="ident">update_step</span></span>(<span>self, step_dict: StepDict)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread"><code class="name flex">
<span>async def <span class="ident">update_thread</span></span>(<span>self, thread_id: str, name: Optional[str] = None, user_id: Optional[str] = None, metadata: Optional[Dict] = None, tags: Optional[List[str]] = None)</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback"><code class="name flex">
<span>async def <span class="ident">upsert_feedback</span></span>(<span>self, feedback: chainlit.types.Feedback) ‑> str</span>
</code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai.ui" href="index.html">praisonai.ui</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer">SQLAlchemyDataLayer</a></code></h4>
<ul class="">
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.build_debug_url">build_debug_url</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.clean_result">clean_result</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_element">create_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_step">create_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.create_user">create_user</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_element">delete_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_feedback">delete_feedback</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_step">delete_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.delete_thread">delete_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.execute_sql">execute_sql</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_all_user_threads">get_all_user_threads</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_current_timestamp">get_current_timestamp</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_element">get_element</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread">get_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_thread_author">get_thread_author</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.get_user">get_user</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.list_threads">list_threads</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_step">update_step</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.update_thread">update_thread</a></code></li>
<li><code><a title="praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback" href="#praisonai.ui.sql_alchemy.SQLAlchemyDataLayer.upsert_feedback">upsert_feedback</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-55
View File
@@ -1,55 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
<meta name="generator" content="pdoc3 0.11.1">
<title>praisonai.version API documentation</title>
<meta name="description" content="">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/sanitize.min.css" integrity="sha512-y1dtMcuvtTMJc1yPgEqF0ZjQbhnc/bFhyvIyVNb9Zk5mIGtqVaAB1Ttl28su8AvFMOY0EwRbAe+HCLqj6W7/KA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/13.0.0/typography.min.css" integrity="sha512-Y1DYSb995BAfxobCkKepB1BqJJTPrOp3zPL74AWFugHHmmdcvO+C48WLrUOlhGMc0QG7AE3f7gmvvcrmX2fDoA==" crossorigin>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/default.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:1.5em;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:2em 0 .50em 0}h3{font-size:1.4em;margin:1.6em 0 .7em 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .2s ease-in-out}a:visited{color:#503}a:hover{color:#b62}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900;font-weight:bold}pre code{font-size:.8em;line-height:1.4em;padding:1em;display:block}code{background:#f3f3f3;font-family:"DejaVu Sans Mono",monospace;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em 1em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul ul{padding-left:1em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" integrity="sha512-D9gUyxqja7hBtkWpPWGt9wfbfaMGVt9gnyCvYa+jojwwPHLCzUm5i8rpk7vD7wNee9bA35eYIjobYPaQuKS1MQ==" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => {
hljs.configure({languages: ['bash', 'css', 'diff', 'graphql', 'ini', 'javascript', 'json', 'plaintext', 'python', 'python-repl', 'rust', 'shell', 'sql', 'typescript', 'xml', 'yaml']});
hljs.highlightAll();
})</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>praisonai.version</code></h1>
</header>
<section id="section-intro">
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="praisonai" href="index.html">praisonai</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.11.1</a>.</p>
</footer>
</body>
</html>
-79
View File
@@ -1,79 +0,0 @@
---
title: "Agent Module"
description: "Documentation for the praisonaiagents.agent.agent module"
icon: "user"
---
# Module praisonaiagents.agent.agent
## Classes
### Agent
The main class representing an AI agent with specific role, goal, and capabilities.
#### Parameters
- `name: str` - Name of the agent
- `role: str` - Role of the agent
- `goal: str` - Goal the agent aims to achieve
- `backstory: str` - Background story of the agent
- `llm: str | Any | None = 'gpt-4o'` - Language model to use
- `tools: List[Any] | None = None` - List of tools available to the agent
- `function_calling_llm: Any | None = None` - LLM for function calling
- `max_iter: int = 20` - Maximum iterations
- `max_rpm: int | None = None` - Maximum requests per minute
- `max_execution_time: int | None = None` - Maximum execution time
- `memory: bool = True` - Enable memory
- `verbose: bool = True` - Enable verbose output
- `allow_delegation: bool = False` - Allow task delegation
- `step_callback: Any | None = None` - Callback for each step
- `cache: bool = True` - Enable caching
- `system_template: str | None = None` - System prompt template
- `prompt_template: str | None = None` - Prompt template
- `response_template: str | None = None` - Response template
- `allow_code_execution: bool | None = False` - Allow code execution
- `max_retry_limit: int = 2` - Maximum retry attempts
- `respect_context_window: bool = True` - Respect context window size
- `code_execution_mode: Literal['safe', 'unsafe'] = 'safe'` - Code execution mode
- `embedder_config: Dict[str, Any] | None = None` - Embedder configuration
- `knowledge_sources: List[Any] | None = None` - Knowledge sources
- `use_system_prompt: bool | None = True` - Use system prompt
- `markdown: bool = True` - Enable markdown
- `self_reflect: bool = True` - Enable self reflection
- `max_reflect: int = 3` - Maximum reflections
- `min_reflect: int = 1` - Minimum reflections
- `reflect_llm: str | None = None` - LLM for reflection
#### Methods
- `chat(self, prompt, temperature=0.2, tools=None, output_json=None)` - Chat with the agent
- `achat(self, prompt, temperature=0.2, tools=None, output_json=None)` - Async version of chat method
- `clean_json_output(self, output: str) → str` - Clean and extract JSON from response text
- `clear_history(self)` - Clear chat history
- `execute_tool(self, function_name, arguments)` - Execute a tool dynamically based on the function name and arguments
- `_achat_completion(self, response, tools)` - Async version of _chat_completion method
#### Async Support
The Agent class provides async support through the following methods:
- `achat`: Async version of the chat method for non-blocking communication
- `_achat_completion`: Internal async method for handling chat completions
Example usage:
```python
async def main():
agent = Agent(
name="AsyncAgent",
role="Async Specialist",
goal="Handle async operations",
backstory="Expert in async processing"
)
# Use async chat
result = await agent.achat(
prompt="Your prompt here",
tools=your_tools,
output_json=your_schema
)
print(result)
asyncio.run(main())
```
-113
View File
@@ -1,113 +0,0 @@
---
title: "Agents Module"
description: "Documentation for the praisonaiagents.agents.agents module"
icon: "users"
---
# Module praisonaiagents.agents.agents
## Functions
### encode_file_to_base64(file_path: str) → str
Base64-encode a file.
### process_video(video_path: str, seconds_per_frame=2)
Split video into frames (base64-encoded).
## Classes
### LoopItems
A Pydantic model for handling loop items.
#### Class Variables
- `items: List[Any]` - List of items to loop through
- `model_config` - Model configuration
### PraisonAIAgents
The main class for managing agents and tasks execution.
#### Parameters
- `agents: List[Agent]` - List of agents
- `tasks: List[Task]` - List of tasks
- `verbose: int = 0` - Verbosity level
- `completion_checker: Optional[Callable] = None` - Custom completion checker
- `max_retries: int = 5` - Maximum retry attempts
- `process: str = "sequential"` - Process type (sequential, workflow, hierarchical)
- `manager_llm: Optional[str] = None` - Language model for manager agent
#### Methods
- `add_task(self, task)` - Add a task to the crew
- `clean_json_output(self, output: str) → str` - Clean JSON output
- `clear_state(self) → None` - Clear all state values
- `default_completion_checker(self, task, agent_output)` - Default completion checker
- `execute_task(self, task_id)` - Execute a specific task
- `get_agent_details(self, agent_name)` - Get agent details
- `get_all_tasks_status(self)` - Get status of all tasks
- `get_state(self, key: str, default: Any = None) → Any` - Get a state value
- `get_task_details(self, task_id)` - Get task details
- `get_task_result(self, task_id)` - Get task result
- `get_task_status(self, task_id)` - Get task status
- `run_all_tasks(self)` - Execute tasks based on execution mode
- `run_task(self, task_id)` - Run a specific task
- `save_output_to_file(self, task, task_output)` - Save task output to file
- `set_state(self, key: str, value: Any) → None` - Set a state value
- `start(self)` - Start the crew execution
- `update_state(self, updates: Dict) → None` - Update multiple state values
#### Async Methods
- `astart(self)` - Async version of start method
- `aexecute_task(self, task_id)` - Async version of execute_task
- `arun_task(self, task_id)` - Async version of run_task
- `arun_all_tasks(self)` - Async version of run_all_tasks
#### Async Support
The PraisonAIAgents class provides comprehensive async support through the following methods:
```python
class PraisonAIAgents:
async def astart(self):
"""Async version of start method"""
await self.arun_all_tasks()
return {
"task_status": self.get_all_tasks_status(),
"task_results": self.get_task_results()
}
async def aexecute_task(self, task_id):
"""Async version of execute_task method"""
# Async task execution implementation
async def arun_task(self, task_id):
"""Async version of run_task method"""
# Async task running with retries
async def arun_all_tasks(self):
"""Async version of run_all_tasks method"""
# Async execution of all tasks
```
Example usage:
```python
async def main():
# Initialize agents and tasks
agents = PraisonAIAgents(
agents=[async_agent1, async_agent2],
tasks=[async_task1, async_task2],
process="workflow"
)
# Start async execution
result = await agents.astart()
print(result)
# Run the async workflow
asyncio.run(main())
```
#### Async Features
- Full async/await support
- Parallel task execution
- Non-blocking operations
- Efficient resource utilization
- Mixed sync/async task handling
- Async process management
@@ -1,187 +0,0 @@
---
title: "AutoAgents Module"
description: "Documentation for the praisonaiagents.agents.autoagents module"
icon: "robot"
---
# Module praisonaiagents.agents.autoagents
The AutoAgents module provides automatic creation and management of AI agents and tasks based on high-level instructions.
## Classes
### AutoAgents
The main class for automatically creating and managing AI agents and tasks.
#### Parameters
- `instructions: str` - High-level task description for the agents
- `tools: Optional[List[Any]] = None` - List of tools available to the agents
- `verbose: bool = False` - Enable detailed logging
- `process: str = "sequential"` - Process type (sequential or hierarchical)
- `manager_llm: Optional[str] = None` - Language model for manager agent
- `max_retries: int = 5` - Maximum retry attempts
- `completion_checker: Optional[Any] = None` - Custom completion checker
- `allow_code_execution: bool = False` - Allow code execution
- `memory: bool = True` - Enable agent memory
- `markdown: bool = True` - Enable markdown formatting
- `self_reflect: bool = False` - Enable agent self-reflection
- `max_reflect: int = 3` - Maximum reflection iterations
- `min_reflect: int = 1` - Minimum reflection iterations
- `llm: Optional[str] = None` - Language model for agents
- `function_calling_llm: Optional[str] = None` - Language model for tool calling
- `respect_context_window: bool = True` - Respect model context window
- `code_execution_mode: str = "safe"` - Code execution mode (safe/unsafe)
- `embedder_config: Optional[Dict[str, Any]] = None` - Embedder configuration
- `knowledge_sources: Optional[List[Any]] = None` - Knowledge sources
- `use_system_prompt: bool = True` - Use system prompts
- `cache: bool = True` - Enable caching
- `allow_delegation: bool = False` - Allow task delegation
- `step_callback: Optional[Any] = None` - Callback for each step
- `system_template: Optional[str] = None` - Custom system template
- `prompt_template: Optional[str] = None` - Custom prompt template
- `response_template: Optional[str] = None` - Custom response template
- `max_rpm: Optional[int] = None` - Maximum requests per minute
- `max_execution_time: Optional[int] = None` - Maximum execution time
- `max_iter: int = 20` - Maximum iterations
- `reflect_llm: Optional[str] = None` - Language model for reflection
- `max_agents: int = 3` - Maximum number of agents to create
#### Methods
##### start()
Start the agents synchronously.
```python
def start(self):
"""
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return super().start()
```
##### astart()
Start the agents asynchronously.
```python
async def astart(self):
"""
Async version of start() method.
Creates tasks based on the instructions, then starts execution.
Returns the task status and results dictionary.
"""
return await super().astart()
```
#### Internal Methods
##### _generate_config()
Generate the configuration for agents and tasks.
```python
def _generate_config(self) -> AutoAgentsConfig:
"""
Generate the configuration for agents and tasks based on instructions.
Returns AutoAgentsConfig object containing agent and task configurations.
"""
```
##### _create_agents_and_tasks()
Create agents and tasks from configuration.
```python
def _create_agents_and_tasks(self, config: AutoAgentsConfig) -> tuple[List[Agent], List[Task]]:
"""
Create agents and tasks based on the generated configuration.
Returns tuple of (agents, tasks).
"""
```
##### _assign_tools_to_agent()
Assign appropriate tools to an agent.
```python
def _assign_tools_to_agent(self, agent_config: AgentConfig) -> List[Any]:
"""
Assign tools to an agent based on its role and tasks.
Returns list of assigned tools.
"""
```
## Pydantic Models
### TaskConfig
Configuration for a task.
#### Attributes
- `name: str` - Task name
- `description: str` - Task description
- `expected_output: str` - Expected output description
- `tools: List[str]` - Required tools for the task
### AgentConfig
Configuration for an agent.
#### Attributes
- `name: str` - Agent name
- `role: str` - Agent role
- `goal: str` - Agent goal
- `backstory: str` - Agent backstory
- `tools: List[str]` - Required tools
- `tasks: List[TaskConfig]` - Tasks assigned to the agent
### AutoAgentsConfig
Overall configuration for AutoAgents.
#### Attributes
- `main_instruction: str` - Main instruction for the agents
- `process_type: str` - Process type (sequential/hierarchical)
- `agents: List[AgentConfig]` - List of agent configurations
## Example Usage
### Basic Usage
```python
from praisonaiagents import AutoAgents
from praisonaiagents.tools import SerperDevTool
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
verbose=True
)
result = agents.start()
```
### Async Usage
```python
async def main():
agents = AutoAgents(
instructions="Research recent AI developments",
tools=[SerperDevTool()],
process="hierarchical"
)
result = await agents.astart()
import asyncio
asyncio.run(main())
```
### Advanced Configuration
```python
agents = AutoAgents(
instructions="Complex research task",
tools=[SerperDevTool()],
max_agents=5,
process="hierarchical",
manager_llm="gpt-4o",
memory=True,
allow_delegation=True,
max_execution_time=600,
self_reflect=True
)
```
<Note>
For optimal results, provide clear instructions and appropriate tools for your use case.
</Note>
-52
View File
@@ -1,52 +0,0 @@
---
title: "API Reference"
description: "Praison AI Agents - SDK Documentation"
icon: "code"
---
<CardGroup cols={2}>
<Card title="Agent" icon="user" href="/api/praisonaiagents/agent/agent">
Documentation for individual AI agents and their capabilities
</Card>
<Card title="Agents" icon="users" href="/api/praisonaiagents/agents/agents">
Documentation for managing multiple agents and their interactions
</Card>
<Card title="Task" icon="list-check" href="/api/praisonaiagents/task/task">
Documentation for defining and managing tasks
</Card>
<Card title="Process" icon="diagram-project" href="/api/praisonaiagents/process/process">
Documentation for handling task execution flows
</Card>
</CardGroup>
# Module praisonaiagents
## Sub-modules
* praisonaiagents.agent - Agent module for defining individual AI agents
* praisonaiagents.agents - Agents module for managing multiple agents
* praisonaiagents.task - Task module for defining and managing tasks
* praisonaiagents.process - Process module for handling task execution flows
* praisonaiagents.main - Main module containing utility functions
## Functions
### clean_triple_backticks(text: str) → str
Clean triple backticks from text output.
### display_error(message: str, console=None)
Display error messages in the console.
### display_generating(content: str = '', start_time: float | None = None)
Display generation status with optional timing information.
### display_instruction(message: str, console=None)
Display instruction messages in the console.
### display_interaction(message, response, markdown=True, generation_time=None, console=None)
Display interaction between user and agent.
### display_self_reflection(message: str, console=None)
Display agent self-reflection messages.
### display_tool_call(message: str, console=None)
Display tool call messages.
@@ -1,98 +0,0 @@
---
title: "Process Module"
description: "Documentation for the praisonaiagents.process.process module"
icon: "diagram-project"
---
# Module praisonaiagents.process.process
## Classes
### Process
The main class for handling task execution processes in different modes (sequential, hierarchical, workflow).
#### Parameters
- `tasks: Dict[str, Task]` - Dictionary of tasks to be executed
- `agents: List[Agent]` - List of available agents
- `manager_llm: Optional[str] = None` - Language model for manager agent in hierarchical process
- `verbose: bool = False` - Enable verbose logging
#### Methods
- `workflow(self)` - Execute tasks in a workflow pattern with support for loops and conditions
- `sequential(self)` - Execute tasks in sequential order
- `hierarchical(self)` - Execute tasks in hierarchical order with a manager agent
#### Async Methods
- `aworkflow(self) -> AsyncGenerator[str, None]` - Async version of workflow process
- `asequential(self) -> AsyncGenerator[str, None]` - Async version of sequential process
- `ahierarchical(self) -> AsyncGenerator[str, None]` - Async version of hierarchical process
#### Async Process Support
Each process type has an async counterpart that supports non-blocking execution:
```python
class Process:
async def aworkflow(self):
"""Async workflow process execution"""
# Async workflow implementation
async def asequential(self):
"""Async sequential process execution"""
# Async sequential implementation
async def ahierarchical(self):
"""Async hierarchical process execution"""
# Async hierarchical implementation
```
Example usage:
```python
# Create process instance
process = Process(tasks=tasks, agents=agents)
# Use async workflow
async for task_id in process.aworkflow():
# Handle task execution
if tasks[task_id].async_execution:
await handle_async_task(task_id)
else:
handle_sync_task(task_id)
```
#### Async Process Features
- Non-blocking task execution
- Parallel task processing
- Mixed sync/async task support
- Efficient resource utilization
- Async manager coordination (hierarchical)
- Dynamic task scheduling (workflow)
### LoopItems
A Pydantic model for handling loop data in workflow process.
#### Parameters
- `items: List[Any]` - List of items to be processed in a loop
## Process Types
### Sequential Process
- Tasks are executed one after another in a linear fashion
- Each task is completed before moving to the next one
- Simplest form of task execution
### Hierarchical Process
- Uses a manager agent to coordinate task execution
- Manager decides task order and agent assignments
- Provides more complex task orchestration
- Requires manager_llm parameter
- Supports dynamic agent assignment
### Workflow Process
- Supports complex task relationships
- Features:
- Task dependencies
- Conditional execution
- Loops
- Context sharing between tasks
- Maintains task state and relationships
- Handles data flow between tasks
-78
View File
@@ -1,78 +0,0 @@
---
title: "Task Module"
description: "Documentation for the praisonaiagents.task.task module"
icon: "list-check"
---
# Module praisonaiagents.task.task
## Classes
### Task
Represents a task to be executed by an agent.
#### Parameters
- `description: str` - Task description
- `expected_output: str` - Expected output description
- `agent: Agent | None = None` - Agent assigned to the task
- `name: str | None = None` - Task name
- `tools: List[Any] | None = None` - Tools available for the task
- `context: List[Task] | None = None` - Context from other tasks
- `async_execution: bool | None = False` - Enable async execution
- `config: Dict[str, Any] | None = None` - Task configuration
- `output_file: str | None = None` - Output file path
- `output_json: Type[BaseModel] | None = None` - JSON output schema
- `output_pydantic: Type[BaseModel] | None = None` - Pydantic output schema
- `callback: Any | None = None` - Task callback
- `status: str = 'not started'` - Task status
- `result: TaskOutput | None = None` - Task result
- `create_directory: bool | None = False` - Create output directory
- `id: int | None = None` - Task ID
- `images: List[str] | None = None` - Task images
- `next_tasks: List[str] | None = None` - Next tasks
- `task_type: str = 'task'` - Task type
- `condition: Dict[str, List[str]] | None = None` - Task conditions
- `is_start: bool = False` - Is start task
- `loop_state: Dict[str, str | int] | None = None` - Loop state
#### Async Support
The Task class supports asynchronous execution through the following features:
- `async_execution`: Boolean flag to enable async execution
- `callback`: Supports both sync and async callback functions
- `execute_callback`: Internal async method for handling callbacks
Example usage:
```python
from typing import Coroutine
from praisonaiagents import Task, TaskOutput
# Define an async callback
async def async_callback(output: TaskOutput):
await some_async_operation()
print(f"Processed: {output.raw}")
# Create task with async execution
task = Task(
description="Async task example",
expected_output="Async result",
async_execution=True, # Enable async execution
callback=async_callback # Async callback
)
```
#### Callback Types
The Task class supports both synchronous and asynchronous callbacks:
```python
# Type definition
callback: Optional[Union[
Callable[[TaskOutput], Any], # Sync callback
Callable[[TaskOutput], Coroutine[Any, Any, Any]] # Async callback
]]
```
#### Async Task States
- `not started`: Initial state
- `in progress`: Task is being executed
- `completed`: Task finished successfully
- `failed`: Task execution failed
-126
View File
@@ -1,126 +0,0 @@
---
title: "PraisonAI Call"
description: "Guide to PraisonAI's voice-based interaction feature enabling AI customer service through phone calls, including setup and tool integration"
icon: "phone"
---
<iframe width="560" height="315" src="https://www.youtube.com/embed/m1cwrUG2iAk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
## AI Customer Service
PraisonAI Call is a feature that enables voice-based interaction with AI models through phone calls. This functionality allows users to have natural conversations with AI agents over traditional phone lines.
## Installation
### Step 1
```bash
pip install "praisonai[call]"
export OPENAI_API_KEY="enter your openai api key here"
export NGROK_AUTH_TOKEN="enter your ngrok auth token here"
praisonai call --public
```
### Step 2
Buy a number at [PraisonAI Dashboard](https://dashboard.praison.ai/)
### Step 3
Enter the Public URL in the PraisonAI Dashboard phone number field
## Features
- Make and receive phone calls with AI agents
- Natural language processing for voice interactions
- Support for multiple phone carriers and providers
- Call recording and transcription capabilities
- Integration with other PraisonAI features
## Adding Tools
1. Create a file called `tools.py`
2. Add the following code:
```python
import yfinance as yf
# Get Stock Price definition
get_stock_price_def = {
"name": "get_stock_price",
"description": "Get the current stock price for a given ticker symbol",
"parameters": {
"type": "object",
"properties": {
"ticker_symbol": {
"type": "string",
"description": "The ticker symbol of the stock (e.g., AAPL, GOOGL)"
}
},
"required": ["ticker_symbol"]
}
}
# Get Stock Price function / Tool
async def get_stock_price_handler(ticker_symbol):
try:
stock = yf.Ticker(ticker_symbol)
hist = stock.history(period="1d")
if hist.empty:
return {"error": f"No data found for ticker {ticker_symbol}"}
current_price = hist['Close'].iloc[-1] # Using -1 is safer than 0
return {"price": str(current_price)}
except Exception as e:
return {"error": str(e)}
get_stock_price = (get_stock_price_def, get_stock_price_handler)
tools = [
get_stock_price
]
```
3. ```bash
pip install yfinance
```
4. ```bash
export OPENAI_API_KEY="enter your openai api key here"
export NGROK_AUTH_TOKEN="enter your ngrok auth token here"
praisonai call --public
```
## Manage Google Calendar Events
See [Google Calendar Tools](tools/googlecalendar.md)
## Deploy
### Docker Deployment
```dockerfile
# Use an official Python runtime as a parent image
FROM python:3.11-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
# Install PraisonAI with the 'call' extra and ensure it's the latest version
RUN pip install --no-cache-dir --upgrade "praisonai[call]"
# Expose the port the app runs on
EXPOSE 8090
# Run the application
CMD ["praisonai", "call"]
```
-368
View File
@@ -1,368 +0,0 @@
---
title: "Agents"
description: "Understanding Agents in PraisonAI"
icon: "user"
---
# Understanding Agents
Agents are the core building blocks of PraisonAI. Each agent is an autonomous AI entity with specific roles, goals, and capabilities.
```mermaid
graph LR
%% Define the main flow
Start([▶ Start]) --> Agent1
Agent1 --> Process[⚙ Process]
Process --> Agent2
Agent2 --> Output([✓ Output])
Process -.-> Agent1
%% Define subgraphs for agents and their tasks
subgraph Agent1[ ]
Task1[📋 Task]
AgentIcon1[🤖 AI Agent]
Tools1[🔧 Tools]
Task1 --- AgentIcon1
AgentIcon1 --- Tools1
end
subgraph Agent2[ ]
Task2[📋 Task]
AgentIcon2[🤖 AI Agent]
Tools2[🔧 Tools]
Task2 --- AgentIcon2
AgentIcon2 --- Tools2
end
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Start,Output,Task1,Task2 input
class Process,AgentIcon1,AgentIcon2 process
class Tools1,Tools2 tools
class Agent1,Agent2 transparent
```
## Key Components
<CardGroup cols={2}>
<Card title="Role & Goal" icon="target">
Defines the agent's purpose and objectives through role definition and specific goals
</Card>
<Card title="Capabilities" icon="toolbox">
Tools and functions available to the agent for task execution
</Card>
<Card title="Memory" icon="brain">
Context retention and learning capabilities across interactions
</Card>
<Card title="Language Model" icon="microchip">
The underlying AI model powering the agent's intelligence
</Card>
</CardGroup>
## Component Details
### Role and Goal
<Tip>
Clear role and goal definitions are crucial for optimal agent performance.
</Tip>
| Component | Description | Example |
|:----------|:------------|:--------|
| **Role** | Agent's function and expertise | Research Analyst, Code Developer |
| **Goal** | Specific objectives to achieve | Analyze market trends, Generate reports |
| **Backstory** | Contextual background | Expert with 10 years of experience |
### Capabilities
<CodeGroup>
```python Basic
agent = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
```
</CodeGroup>
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent
agent = Agent(instructions="Your are a helpful AI assistant")
agent.start("Write a movie script about a robot in Mars")
```
```python Multi Agents
from praisonaiagents import Agent, PraisonAIAgents
research_agent = Agent(instructions="Research about AI")
summarise_agent = Agent(instructions="Summarise research agent's findings")
agents = PraisonAIAgents(agents=[research_agent, summarise_agent])
agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
You should see:
- Agent initialization
- Agents progress
- Final results
- Generated report
</Step>
</Steps>
## Agent Types
<CardGroup cols={3}>
<Card title="Basic Agent" icon="user" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Perfect for straightforward tasks and direct interactions
</Accordion>
<Accordion title="Features">
- Single-purpose focus
- Direct user interaction
- Limited tool set
- Ideal for simple tasks
</Accordion>
</AccordionGroup>
</Card>
<Card title="Specialized Agent" icon="user-gear" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Experts in specific domains with advanced capabilities
</Accordion>
<Accordion title="Features">
- Domain expertise
- Advanced capabilities
- Custom tools
- Deep knowledge base
</Accordion>
</AccordionGroup>
</Card>
<Card title="Collaborative Agent" icon="users" iconType="solid">
<AccordionGroup>
<Accordion title="Overview">
Designed for team-based operations and complex workflows
</Accordion>
<Accordion title="Features">
- Team interaction
- Task delegation
- Shared context
- Coordinated actions
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Best Practices
<Note>
Always implement proper error handling and resource management in your agent configurations.
</Note>
<CardGroup cols={2}>
<Card title="Agent Design" icon="compass-drafting" iconType="solid">
<Steps>
<Step title="Role Definition">
Define clear, specific roles for each agent
</Step>
<Step title="Goal Setting">
Set specific, measurable goals
</Step>
<Step title="Tool Selection">
Choose relevant tools for the task
</Step>
<Step title="Memory Setup">
Configure appropriate memory settings
</Step>
</Steps>
</Card>
<Card title="Agent Interaction" icon="network-wired" iconType="solid">
<Steps>
<Step title="Communication">
Establish clear communication protocols
</Step>
<Step title="Delegation">
Define explicit delegation rules
</Step>
<Step title="Error Handling">
Implement robust error handling
</Step>
<Step title="Resource Management">
Set up efficient resource allocation
</Step>
</Steps>
</Card>
</CardGroup>
## Async Capabilities
<CardGroup cols={1}>
<Card title="Key Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Async Support">
```python
async def main():
agent = Agent(name="AsyncAgent")
result = await agent.aprocess_task()
```
- Full async/await support
- Non-blocking operations
- Enhanced performance
</Tab>
<Tab title="Parallel Execution">
```python
async def parallel_tasks():
tasks = [agent1.task(), agent2.task()]
results = await asyncio.gather(*tasks)
```
- Parallel task execution
- Efficient resource usage
- Improved throughput
</Tab>
<Tab title="Integration">
```python
@agent.async_tool
async def custom_tool():
async with aiohttp.ClientSession() as session:
# Async operations
pass
```
- Async tool integration
- Callback support
- Mixed sync/async operations
</Tab>
</Tabs>
</Card>
</CardGroup>
## Advanced Features
<CardGroup cols={2}>
<Card title="Memory Management" icon="brain">
- Short-term conversation memory
- Long-term knowledge retention
- Context preservation
</Card>
<Card title="Tool Integration" icon="plug">
- Custom tool development
- External API integration
- Resource access control
</Card>
</CardGroup>
## Async Support
Agents now support asynchronous operations through the following methods:
- `achat`: Async version of the chat method
- `astart`: Async version of start method
- `aexecute_task`: Async version of execute_task method
- `arun_task`: Async version of run_task method
- `arun_all_tasks`: Async version of run_all_tasks method
### Example Usage:
```python
import asyncio
from praisonaiagents import Agent, Task, PraisonAIAgents
async def main():
# Create an async agent
async_agent = Agent(
name="AsyncAgent",
role="Async Task Specialist",
goal="Perform async operations",
backstory="Expert in async operations",
tools=[async_search_tool], # Your async tool
verbose=True
)
# Create an async task
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True # Enable async execution
)
# Create and start agents with async support
agents = PraisonAIAgents(
agents=[async_agent],
tasks=[async_task],
verbose=True
)
# Start async execution
result = await agents.astart()
print(result)
# Run the async main function
if __name__ == "__main__":
asyncio.run(main())
```
### Key Features:
- Full async/await support
- Parallel task execution
- Async tool integration
- Async callback support
- Mixed sync/async operations
## Next Steps
<CardGroup cols={2}>
<Card
title="Create Your First Agent"
icon="code"
href="/code/quickstart"
>
Follow our quickstart guide to create your first agent
</Card>
<Card
title="API Reference"
icon="book"
href="/api/praisonaiagents/agent/agent"
>
Explore the complete Agent API documentation
</Card>
</CardGroup>
-241
View File
@@ -1,241 +0,0 @@
---
title: "AI Agents with Knowledge"
sidebarTitle: "Knowledge"
description: "Learn how to create AI agents with custom knowledge bases"
icon: "book"
---
```mermaid
flowchart LR
subgraph In[Input]
PDF[PDF]
TXT[TXT]
MD[MD]
end
subgraph Router[Vector Store]
DB[(Vector DB)]
end
subgraph Out[Agents]
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
In --> Router
Router --> A1
Router --> A2
Router --> A3
style In fill:#8B0000,color:#fff
style Router fill:#2E8B57,color:#fff
style Out fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Memory](/concepts/memory) |
|---------|--------------------------------|---------------------------|
| When Used | Pre-loaded before agent execution | Created and updated during runtime |
| Purpose | Provide static reference information | Store dynamic context and interactions |
| Storage | Read-only knowledge base | Read-write memory store |
| Persistence | Permanent until explicitly changed | Can be temporary (STM) or persistent (LTM) |
| Updates | Manual updates through knowledge files | Automatic updates during agent execution |
## Quick Start
<Steps>
<Step title="Install Package">
Install PraisonAI Agents with knowledge support:
```bash
pip install "praisonaiagents[knowledge]"
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key:
```bash
export OPENAI_API_KEY=xxxxx
```
</Step>
<Step title="Create Script">
Create a new file `app.py`:
```python
from praisonaiagents import Agent
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
```
</Step>
</Steps>
## Basic Usage
The simplest way to create a knowledge-based agent is without any configuration:
```python
from praisonaiagents import Agent
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
```
## Advanced Configuration
For more control over the knowledge base, you can specify a configuration:
```python
from praisonaiagents import Agent
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "custom_knowledge",
"path": ".praison",
}
}
}
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"],
knowledge_config=config
)
agent.start("What is KAG in one line?")
```
## Multi-Agent Knowledge System
For more complex scenarios, you can create a knowledge-based system with multiple agents:
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
import logging
import os
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
# Define the configuration for the Knowledge instance
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "knowledge_test",
"path": ".praison",
}
}
}
# Create an agent with knowledge capabilities
knowledge_agent = Agent(
name="KnowledgeAgent",
role="Information Specialist",
goal="Store and retrieve knowledge efficiently",
backstory="Expert in managing and utilizing stored knowledge",
knowledge=["sample.pdf"],
knowledge_config=config,
verbose=True
)
# Define a task for the agent
knowledge_task = Task(
name="knowledge_task",
description="Who is Mervin Praison?",
expected_output="Answer to the question",
agent=knowledge_agent
)
# Create and start the agents
agents = PraisonAIAgents(
agents=[knowledge_agent],
tasks=[knowledge_task],
process="sequential",
user_id="user1"
)
# Start execution
result = agents.start()
```
## Understanding Knowledge Configuration
<AccordionGroup>
<Accordion title="Vector Store Options">
- **Provider**: Choose between different vector store backends (e.g., "chroma")
- **Collection Name**: Name for your knowledge collection
- **Path**: Location to store the vector database
</Accordion>
<Accordion title="Supported File Types">
- PDF documents (*.pdf)
- Text files (*.txt)
- Markdown files (*.md, *.mdx)
- And more...
</Accordion>
<Accordion title="Multi-Agent Setup">
- **Role**: Define specialized roles for knowledge agents
- **Goal**: Set specific knowledge management objectives
- **Process**: Choose between sequential or parallel execution
</Accordion>
</AccordionGroup>
## Features
<CardGroup cols={2}>
<Card title="Custom Knowledge" icon="book">
Import your own documents and data as knowledge sources
</Card>
<Card title="Vector Storage" icon="database">
Efficient storage and retrieval of knowledge embeddings
</Card>
<Card title="Multiple Sources" icon="layer-group">
Combine multiple documents and file types
</Card>
<Card title="Persistent Storage" icon="hard-drive">
Save and reuse knowledge bases across sessions
</Card>
</CardGroup>
## Best Practices
1. **Document Preparation**
- Clean and well-formatted documents work best
- Break large documents into smaller chunks
- Use consistent formatting
2. **Knowledge Organization**
- Group related documents together
- Use meaningful file names
- Keep knowledge bases focused and relevant
3. **Performance Optimization**
- Monitor vector store size
- Clean up unused collections
- Use appropriate chunk sizes
4. **Multi-Agent Coordination**
- Define clear roles and responsibilities
- Set appropriate logging levels for debugging
- Use unique collection names for different agent groups
## Next Steps
- Learn about [Memory Management](/concepts/memory) for long-term recall
- Explore [Tool Integration](/concepts/tools) for enhanced capabilities
- Check out [Examples](/examples) for implementation ideas
-472
View File
@@ -1,472 +0,0 @@
---
title: "AI Agents with Memory"
sidebarTitle: "Memory"
description: "Learn how to create AI agents with memory capabilities for maintaining context and information across tasks."
icon: "brain"
---
```mermaid
flowchart TB
subgraph Memory
direction TB
STM[Short Term]
LTM[Long Term]
end
subgraph Store
direction TB
DB[(Vector DB)]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
Memory <--> Store
Store <--> A1
Store <--> A2
Store <--> A3
style Memory fill:#189AB4,color:#fff
style Store fill:#2E8B57,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Memory](/concepts/memory) |
|---------|--------------------------------|---------------------------|
| When Used | Pre-loaded before agent execution | Created and updated during runtime |
| Purpose | Provide static reference information | Store dynamic context and interactions |
| Storage | Read-only knowledge base | Read-write memory store |
| Persistence | Permanent until explicitly changed | Can be temporary (STM) or persistent (LTM) |
| Updates | Manual updates through knowledge files | Automatic updates during agent execution |
## Quick Start
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install Package">
First, install the PraisonAI Agents package:
```bash
pip install "praisonaiagents[memory]" duckduckgo_search
```
duckduckgo_search is a tool that allows agents to search the web.
It is required for the multiple agents example shown below.
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `app.py` with the basic setup:
<CodeGroup>
```python Single Agent
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about AI",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about AI trends",
expected_output="Well-written blog post about AI trends",
agent=blog_agent
)
# Create and start the agents with memory enabled
agents = PraisonAIAgents(
agents=[blog_agent],
tasks=[blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
```python Multiple Agents
from praisonaiagents.agents.agents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create research agent with memory
research_agent = Agent(
role="Research Analyst",
goal="Research and document key information about topics",
backstory="Expert at analyzing and storing information in memory",
llm="gpt-4o-mini",
tools=[duckduckgo]
)
# Create blog writer agent
blog_agent = Agent(
role="Blog Writer",
goal="Write a blog post about the research",
backstory="Expert at writing blog posts",
llm="gpt-4o-mini"
)
# Create research task
research_task = Task(
description="Research and document key information about AI trends",
expected_output="Detailed research findings about AI trends",
agent=research_agent
)
# Create blog writing task
blog_task = Task(
description="Write a blog post about the research findings",
expected_output="Well-written blog post based on research",
agent=blog_agent
)
# Create and start the agents with advanced memory configuration
agents = PraisonAIAgents(
agents=[research_agent, blog_agent],
tasks=[research_task, blog_task],
memory=True
)
# Start execution
result = agents.start()
print(result)
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install Package">
Install the PraisonAI package:
```bash
pip install praisonai
```
</Step>
<Step title="Set API Key">
Set your OpenAI API key as an environment variable in your terminal:
```bash
export OPENAI_API_KEY=your_api_key_here
```
</Step>
<Step title="Create a file">
Create a new file `agents.yaml` with the basic setup:
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert at analyzing and storing information in memory.
goal: Research and document key information about topics
role: Research Analyst
llm: gpt-4o-mini
tools:
- duckduckgo
tasks:
research_task:
description: Research and document key information about topics.
expected_output: Detailed research findings.
writer:
backstory: Expert at writing blog posts.
goal: Write a blog post about the research
role: Blog Writer
llm: gpt-4o-mini
tasks:
blog_task:
description: Write a blog post about the research.
expected_output: Well-written blog post based on research.
```
</Step>
<Step title="Start Agents">
Type this in your terminal to run your agents:
```bash
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
<Note>
**Requirements**
- Python 3.10 or higher
- OpenAI API key. Generate OpenAI API key [here](https://platform.openai.com/api-keys). Use Other models using [this guide](/models).
- Basic understanding of Python
</Note>
## Understanding Memory
<Card title="What is Agent Memory?" icon="question">
Memory in AI agents enables them to:
- Maintain context across multiple tasks
- Remember previous interactions and findings
- Build upon past knowledge
- Share information between agents
- Create more coherent and contextual responses
</Card>
## Features
<CardGroup cols={2}>
<Card title="Context Retention" icon="brain">
Maintain information across multiple interactions.
</Card>
<Card title="Information Sharing" icon="share-nodes">
Share knowledge between multiple agents.
</Card>
<Card title="Long-term Storage" icon="database">
Store and retrieve information over extended periods.
</Card>
<Card title="Memory Types" icon="layer-group">
Support for different memory types (short-term, long-term).
</Card>
</CardGroup>
## Multi-Agent Memory
<Tabs>
<Tab title="Code">
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from praisonaiagents.tools import duckduckgo
# Create first agent for research
researcher = Agent(
role="Research Analyst",
goal="Research and analyze market trends",
backstory="Expert in market research and data analysis",
tools=[duckduckgo],
verbose=True
)
# Create second agent for report writing
writer = Agent(
role="Report Writer",
goal="Create comprehensive market reports",
backstory="Expert in technical writing and report creation",
verbose=True
)
# Create research task
research_task = Task(
description="Research current market trends",
expected_output="Detailed market analysis",
agent=researcher
)
# Create writing task
report_task = Task(
description="Create a market report based on research",
expected_output="Comprehensive market report",
agent=writer
)
# Create and start the agents with memory
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[research_task, report_task],
memory=True,
process="sequential"
)
# Start execution
result = agents.start()
```
</Tab>
<Tab title="No Code">
```yaml
framework: praisonai
process: sequential
memory: true
roles:
researcher:
backstory: Expert in market research and data analysis.
goal: Research and analyze market trends
role: Research Analyst
tools:
- duckduckgo
tasks:
research_task:
description: Research current market trends.
expected_output: Detailed market analysis.
writer:
backstory: Expert in technical writing and report creation.
goal: Create comprehensive market reports
role: Report Writer
tasks:
report_task:
description: Create a market report based on research.
expected_output: Comprehensive market report.
```
</Tab>
</Tabs>
### Configuration Options
```python
# Create an agent with memory configuration
agent = Agent(
role="Research Analyst",
goal="Research and retain information",
backstory="Expert in research and analysis",
tools=[duckduckgo],
verbose=True, # Enable detailed logging
llm="gpt-4o" # Language model to use
)
# Create agents with memory options
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True, # Enable memory
memory_config={
"provider": "rag", # Use RAG for semantic search
"use_embedding": True, # Enable embeddings for better search
"short_db": ".praison/short_term.db", # Path for short-term memory
"long_db": ".praison/long_term.db", # Path for long-term memory
"rag_db_path": ".praison/chroma_db" # Path for vector database
}
)
```
## Troubleshooting
<CardGroup cols={2}>
<Card title="Memory Issues" icon="triangle-exclamation">
If memory isn't working as expected:
- Check memory configuration
- Enable verbose mode for debugging
- Verify memory provider settings
</Card>
<Card title="Context Flow" icon="code">
If context isn't being maintained:
- Review task dependencies
- Check memory configuration
- Verify agent communication
</Card>
</CardGroup>
## Next Steps
<CardGroup cols={2}>
<Card title="AutoAgents" icon="robot" href="../features/autoagents">
Learn about automatically created and managed AI agents
</Card>
<Card title="Mini Agents" icon="microchip" href="../features/mini">
Explore lightweight, focused AI agents
</Card>
</CardGroup>
<Note>
For optimal results, configure memory settings based on your specific use case requirements and expected interaction patterns.
</Note>
### Memory Configuration Options
The memory system in PraisonAI supports various configuration options to customize how agents store and retrieve information:
```python
memory_config = {
# Memory Provider
"provider": "rag", # Options: "rag", "mem0", "none"
"use_embedding": True, # Enable semantic search with embeddings
# Storage Paths
"short_db": ".praison/short_term.db", # Short-term memory SQLite DB
"long_db": ".praison/long_term.db", # Long-term memory SQLite DB
"rag_db_path": ".praison/chroma_db", # Vector database path
# Memory Settings
"ttl": 3600, # Time to live for memory items (in seconds)
# Optional Mem0 Config (if using mem0 provider)
"config": {
"api_key": "...", # Mem0 API key
"org_id": "...", # Organization ID
"project_id": "..." # Project ID
}
}
# Create agents with memory configuration
agents = PraisonAIAgents(
agents=[agent],
tasks=[task],
memory=True,
memory_config=memory_config
)
```
### Memory Types
PraisonAI's memory system includes several types of memory:
<CardGroup cols={2}>
<Card title="Short-term Memory" icon="bolt">
- Temporary storage for current context
- Automatically cleared between sessions
- Fast access for immediate task context
</Card>
<Card title="Long-term Memory" icon="database">
- Persistent storage for important information
- Semantic search capabilities with RAG
- Quality-based storage decisions
</Card>
</CardGroup>
### Memory Quality Control
PraisonAI includes built-in quality control for memory storage:
```python
# Example of storing with quality metrics
agents.memory.store_long_term(
text="Important information to remember",
metadata={
"task_id": "task_123",
"agent": "research_agent"
},
completeness=0.9, # How complete is the information
relevance=0.85, # How relevant to the task
clarity=0.95, # How clear and well-structured
accuracy=0.9, # How accurate is the information
weights={ # Custom weights for quality score
"completeness": 0.3,
"relevance": 0.3,
"clarity": 0.2,
"accuracy": 0.2
}
)
# Search with quality filter
results = agents.memory.search_long_term(
query="search query",
min_quality=0.8, # Only return high-quality matches
limit=5 # Maximum number of results
)
-453
View File
@@ -1,453 +0,0 @@
---
title: "Process"
description: "Understanding Process Types in PraisonAI"
icon: "diagram-project"
---
# Understanding Process Types
Process types in PraisonAI define how tasks are executed and how agents collaborate. Each process type offers different patterns for task execution and agent coordination.
## Process Types Overview
<CardGroup cols={3}>
<Card
title="Sequential Process"
icon="arrow-right"
href="/sequential-process"
>
Linear task execution in a predefined order
</Card>
<Card
title="Hierarchical Process"
icon="sitemap"
href="/hierarchical-process"
>
Manager-coordinated task execution with dynamic assignment
</Card>
<Card
title="Workflow Process"
icon="diagram-project"
href="/workflow-process"
>
Complex task flows with conditional execution and state management
</Card>
</CardGroup>
## Sequential Process
```mermaid
graph LR
Input[Input] --> A1
subgraph Agents
direction LR
A1[Agent 1] --> A2[Agent 2] --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class A1,A2,A3 process
class Agents transparent
```
The simplest form of task execution where tasks are performed one after another.
<Card>
### Characteristics
- Linear execution flow
- Predictable order
- Simple dependency management
- Direct task progression
### Usage
```python
agents = PraisonAIAgents(
agents=[agent1, agent2],
tasks=[task1, task2, task3],
process="sequential"
)
```
</Card>
## Hierarchical Process
```mermaid
graph TB
Input[Input] --> Manager
subgraph Agents
Manager[Manager Agent]
subgraph Workers
direction LR
W1[Worker 1]
W2[Worker 2]
W3[Worker 3]
end
Manager --> W1
Manager --> W2
Manager --> W3
end
W1 --> Manager
W2 --> Manager
W3 --> Manager
Manager --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Manager,W1,W2,W3 process
class Agents,Workers transparent
```
Uses a manager agent to coordinate task execution and agent assignments.
<Card>
### Characteristics
- Manager-driven coordination
- Dynamic task assignment
- Flexible execution order
- Intelligent resource allocation
### Configuration
```python
agents = PraisonAIAgents(
agents=[manager_agent, worker_agent1, worker_agent2],
tasks=[task1, task2],
process="hierarchical",
manager_llm="gpt-4o"
)
```
</Card>
## Workflow Process
```mermaid
graph LR
Input[Input] --> Start
subgraph Workflow
direction LR
Start[Start] --> C1{Condition}
C1 --> |Yes| A1[Agent 1]
C1 --> |No| A2[Agent 2]
A1 --> Join
A2 --> Join
Join --> A3[Agent 3]
end
A3 --> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef decision fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Start,A1,A2,A3,Join process
class C1 decision
class Workflow transparent
```
Advanced process type supporting complex task relationships and conditional execution.
<Card>
### Features
- Task dependencies
- Conditional branching
- Loop handling
- Context sharing
- State management
### Implementation
```python
task_workflow = {
"start_task": {
"next": ["decision_task"],
"type": "task"
},
"decision_task": {
"type": "decision",
"conditions": {
"success": ["process_task"],
"failure": ["error_task"]
}
}
}
```
</Card>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent Sequential Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False,
process="sequential"
)
result = agents.start()
```
```python Multiple Agents Hierarchical Process
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
<br /><br />
<div className="relative w-full aspect-video">
<iframe
className="absolute top-0 left-0 w-full h-full"
src="https://www.youtube.com/embed/yWTH44QPl2A"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
</div>
<br />
## Advanced Features
<CardGroup cols={2}>
<Card title="State Management" icon="database" iconType="solid">
<AccordionGroup>
<Accordion title="Task State Tracking">
Monitor and manage the progress of each task in real-time
</Accordion>
<Accordion title="Context Preservation">
Maintain important information across different stages of execution
</Accordion>
<Accordion title="Data Flow Control">
Manage how data moves between tasks and agents efficiently
</Accordion>
</AccordionGroup>
</Card>
<Card title="Error Handling" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Graceful Recovery">
Automatically handle failures and continue execution
</Accordion>
<Accordion title="Alternative Paths">
Switch to backup plans when primary execution fails
</Accordion>
<Accordion title="Error Reporting">
Detailed error logs and diagnostic information
</Accordion>
</AccordionGroup>
</Card>
<Card title="Monitoring" icon="chart-line" iconType="solid">
<AccordionGroup>
<Accordion title="Progress Tracking">
Real-time visibility into task completion status
</Accordion>
<Accordion title="Performance Metrics">
Measure execution time and resource efficiency
</Accordion>
<Accordion title="Resource Usage">
Monitor system resource utilization
</Accordion>
</AccordionGroup>
</Card>
<Card title="Integration" icon="plug" iconType="solid">
<AccordionGroup>
<Accordion title="External Systems">
Connect with other services and platforms
</Accordion>
<Accordion title="API Sync">
Maintain data consistency across systems
</Accordion>
<Accordion title="Event Handling">
React to system and external events
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Processing
<Note>
All process types support asynchronous execution through async generators, enabling efficient parallel processing and non-blocking operations.
</Note>
### Core Async Methods
<CardGroup cols={3}>
<Card title="asequential" icon="arrow-right">
Async version of sequential process for non-blocking linear execution
</Card>
<Card title="aworkflow" icon="diagram-project">
Async workflow process for complex parallel task execution
</Card>
<Card title="ahierarchical" icon="sitemap">
Async hierarchical process for distributed task management
</Card>
</CardGroup>
### Process-Specific Features
<Tabs>
<Tab title="Sequential Process">
<Card>
- Tasks execute in order but don't block
- Maintains sequence while allowing async operations
- Perfect for I/O-heavy tasks
```python
async def main():
agents = PraisonAIAgents(
process="sequential",
async_mode=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Workflow Process">
<Card>
- Parallel execution of independent tasks
- Async branching and merging
- Dynamic task scheduling based on conditions
```python
async def main():
agents = PraisonAIAgents(
process="workflow",
async_mode=True,
parallel_tasks=True
)
await agents.astart()
```
</Card>
</Tab>
<Tab title="Hierarchical Process">
<Card>
- Async manager delegation
- Parallel subtask execution
- Dynamic worker assignment
```python
async def main():
agents = PraisonAIAgents(
process="hierarchical",
async_mode=True,
dynamic_assignment=True
)
await agents.astart()
```
</Card>
</Tab>
</Tabs>
### Key Benefits
<CardGroup cols={2}>
<Card title="Performance" icon="bolt">
- Efficient resource utilization
- Reduced waiting time
- Better throughput
</Card>
<Card title="Flexibility" icon="puzzle-piece">
- Mix sync and async tasks
- Adaptable execution patterns
- Easy scaling
</Card>
</CardGroup>
-530
View File
@@ -1,530 +0,0 @@
---
title: "Tasks"
description: "Understanding Tasks in PraisonAI"
icon: "list-check"
---
# Understanding Tasks
Tasks are units of work that agents execute. Each task has a clear goal, input requirements, and expected outputs.
```mermaid
graph LR
Input[Input] ---> Task
subgraph Task
direction LR
Role[Role]
Goal[Goal]
Story[Backstory]
Expected[Expected Output]
Role --> Goal
Goal --> Story
Story --> Expected
end
Task ---> Output[Output]
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
classDef transparent fill:none,stroke:none
class Input,Output input
class Role,Goal,Story,Expected process
class Task transparent
```
## Core Components
<CardGroup cols={2}>
<Card title="Task Definition" icon="file-lines">
Clear description of work to be done and expected outputs
</Card>
<Card title="Agent Assignment" icon="user-check">
Matching tasks with capable agents
</Card>
<Card title="Tool Access" icon="toolbox">
Resources available for task completion
</Card>
<Card title="Output Handling" icon="file-export">
Managing and formatting task results
</Card>
</CardGroup>
## Task Configuration
<CodeGroup>
```python Basic
task = Task(
description="Research AI trends",
expected_output="Summary report",
agent=research_agent
)
```
```python Advanced
task = Task(
description="Analyze market data",
expected_output="Detailed analysis",
agent=analyst_agent,
tools=[AnalysisTool()],
output_file="analysis.md",
async_execution=True
)
```
</CodeGroup>
# Understanding Tasks
<br />
```mermaid
graph LR
%% Task Flow Steps
Start([▶ Start]) --> TaskDef
TaskDef --> AgentAssign
AgentAssign --> Exec
Exec --> Output([✓ Output])
%% Define subgraphs for each step
subgraph TaskDef[" "]
TD_Icon[📋 Task Definition]
TD_Desc[Description & Requirements]
TD_Icon --- TD_Desc
style TD_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style TD_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph AgentAssign[" "]
AA_Icon[🤖 Agent Assignment]
AA_Desc[Matching & Delegation]
AA_Icon --- AA_Desc
style AA_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style AA_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph Exec[" "]
E_Icon[⚙️ Execution]
E_Desc[Processing & Tools]
E_Icon --- E_Desc
style E_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style E_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
%% Styling for main elements
style Start fill:#2D3047,stroke:#7C90A0,color:#fff
style Output fill:#2D3047,stroke:#7C90A0,color:#fff
%% Style for containers
style TaskDef fill:#1B1F3B,stroke:#7C90A0,color:#fff
style AgentAssign fill:#1B1F3B,stroke:#7C90A0,color:#fff
style Exec fill:#1B1F3B,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
<br /><br />
```mermaid
graph LR
%% Task States
Pending([📥 Pending]) --> InProgress([⚡ In Progress])
InProgress --> Completed([✅ Completed])
InProgress --> Failed([❌ Failed])
%% Styling
style Pending fill:#2D3047,stroke:#7C90A0,color:#fff
style InProgress fill:#5C80BC,stroke:#7C90A0,color:#fff
style Completed fill:#2D3047,stroke:#7C90A0,color:#fff
style Failed fill:#2D3047,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
## Task Types
<Steps>
<Step title="Basic Task">
Simple, single-operation tasks with clear inputs and outputs
</Step>
<Step title="Decision Task">
Tasks involving choices and conditional paths
```python
decision_task = Task(
type="decision",
conditions={
"success": ["next_task"],
"failure": ["error_task"]
}
)
```
</Step>
<Step title="Loop Task">
Repetitive operations over collections
```python
loop_task = Task(
type="loop",
items=data_list,
operation="process_item"
)
```
</Step>
</Steps>
## Task Relationships
<Warning>
Properly managing task dependencies is crucial for complex workflows. Always ensure proper context sharing and error handling.
</Warning>
### Context Sharing
```python
task_a = Task(name="research")
task_b = Task(
name="analyze",
context=[task_a] # Uses task_a's output
)
```
### Task Dependencies
| Relationship | Description | Example |
|:-------------|:------------|:--------|
| **Sequential** | Tasks run one after another | Research → Analysis → Report |
| **Parallel** | Independent tasks run simultaneously | Data Collection + Processing |
| **Conditional** | Tasks depend on previous results | Success → Next Task, Failure → Retry |
## Advanced Features
<CardGroup cols={2}>
<Card title="Output Handling" icon="file-code">
- Multiple output formats
- Structured data validation
- File system integration
</Card>
<Card title="Task Control" icon="sliders">
- Execution flow control
- Error recovery
- Progress tracking
</Card>
</CardGroup>
## Getting Started
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent">
Create `app.py`:
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create an agent
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o"
)
# Define a task
task = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
# Run the agents
agents = PraisonAIAgents(
agents=[researcher],
tasks=[task],
verbose=False
)
result = agents.start()
```
```python Multiple Agents
from praisonaiagents import Agent, Task, PraisonAIAgents
# Create multiple agents
researcher = Agent(
name="Researcher",
role="Senior Research Analyst",
goal="Uncover cutting-edge developments in AI",
backstory="You are an expert at a technology research group",
verbose=True,
llm="gpt-4o",
markdown=True
)
writer = Agent(
name="Writer",
role="Tech Content Strategist",
goal="Craft compelling content on tech advancements",
backstory="You are a content strategist",
llm="gpt-4o",
markdown=True
)
# Define multiple tasks
task1 = Task(
name="research_task",
description="Analyze 2024's AI advancements",
expected_output="A detailed report",
agent=researcher
)
task2 = Task(
name="writing_task",
description="Create a blog post about AI advancements",
expected_output="A blog post",
agent=writer
)
# Run with hierarchical process
agents = PraisonAIAgents(
agents=[researcher, writer],
tasks=[task1, task2],
verbose=False,
process="hierarchical",
manager_llm="gpt-4o"
)
result = agents.start()
```
</CodeGroup>
</Step>
</Steps>
## Best Practices
<Note>
Design tasks to be atomic and focused. Each task should have a single, clear responsibility.
</Note>
<CardGroup cols={2}>
<Card title="Task Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Clear Task Descriptions">
Write precise, unambiguous task descriptions that clearly state the task's purpose and requirements.
```python
task = Task(
description=(
"Analyze Q4 2024 sales data "
"and generate growth metrics"
),
expected_output="Sales growth report"
)
```
</Accordion>
<Accordion title="Success Criteria">
Define measurable success criteria to ensure task completion can be properly evaluated.
```python
task = Task(
success_criteria={
"format": "markdown",
"metrics": [
"growth_rate",
"revenue_change"
],
"min_confidence": 0.95
}
)
```
</Accordion>
<Accordion title="Task Dependencies">
Specify any dependencies or prerequisites for the task.
```python
task = Task(
description="Generate final report",
dependencies=[
data_collection_task,
analysis_task
],
wait_for_dependencies=True
)
```
</Accordion>
</AccordionGroup>
</Card>
<Card title="Resource Management" icon="server" iconType="solid">
<AccordionGroup>
<Accordion title="Tool Selection">
Choose appropriate tools that match your task's requirements.
```python
task = Task(
tools=[
DataAnalyzer(),
ReportGenerator(),
MetricsCalculator()
],
tool_config={
"timeout": 30,
"retry": True
}
)
```
</Accordion>
<Accordion title="Error Handling">
Implement comprehensive error management strategies.
```python
task = Task(
error_strategy="retry",
max_retries=3,
fallback_handler=handler,
error_callbacks=[
log_error,
notify_admin
]
)
```
</Accordion>
<Accordion title="Resource Limits">
Set appropriate resource constraints for optimal performance.
```python
task = Task(
memory_limit="2GB",
timeout=300,
max_concurrent=5,
cpu_priority="high",
auto_scale=True
)
```
</Accordion>
<Accordion title="Performance Monitoring">
Configure monitoring and logging for task execution.
```python
task = Task(
monitoring={
"metrics": ["duration", "memory", "cpu"],
"log_level": "INFO",
"trace_enabled": True,
"alert_threshold": 0.85
}
)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
## Async Task Execution
<CardGroup cols={1}>
<Card title="Async Task Features" icon="bolt" iconType="solid">
<Tabs>
<Tab title="Basic Configuration">
```python
async_task = Task(
description="Perform async operation",
expected_output="Async result",
agent=async_agent,
async_execution=True, # Enable async execution
callback=async_callback # Optional async callback
)
```
- Enable async execution with `async_execution=True`
- Perfect for I/O-heavy operations
- Supports parallel task execution
</Tab>
<Tab title="Async Callbacks">
```python
async def async_callback(output: TaskOutput):
await asyncio.sleep(1) # Simulate async operation
print(f"Processed output: {output.raw}")
task = Task(
description="Task with async callback",
expected_output="Result",
agent=agent,
async_execution=True,
callback=async_callback
)
```
- Support for async callbacks
- Process results asynchronously
- Handle task completion events
</Tab>
<Tab title="Mixed Execution">
```python
# Create mixed task types
sync_task = Task(
description="Synchronous operation",
async_execution=False
)
async_task = Task(
description="Asynchronous operation",
async_execution=True
)
# Run with mixed execution
agents = PraisonAIAgents(
agents=[sync_agent, async_agent],
tasks=[sync_task, async_task]
)
result = await agents.astart()
```
- Mix sync and async tasks
- Flexible execution patterns
- Optimal resource utilization
</Tab>
</Tabs>
</Card>
</CardGroup>
<Tip>
**Pro Tip**: Use async execution for tasks that involve I/O operations (like API calls or file operations) to improve overall performance. Keep CPU-intensive tasks synchronous.
</Tip>
## Next Steps
<CardGroup cols={2}>
<Card
title="Create Tasks"
icon="plus"
href="/code/quickstart"
>
Learn how to create and configure tasks
</Card>
<Card
title="Task API"
icon="code"
href="/api/praisonaiagents/task/task"
>
Explore the complete Task API documentation
</Card>
</CardGroup>
-647
View File
@@ -1,647 +0,0 @@
---
title: "AI Agents with Tools"
sidebarTitle: "Tools"
description: "Learn how to create AI agents that can use tools to interact with external systems and perform actions."
icon: "screwdriver-wrench"
---
```mermaid
flowchart TB
subgraph Tools
direction TB
T3[Internet Search]
T1[Code Execution]
T2[Formatting]
end
Input[Input] ---> Agents
subgraph Agents
direction LR
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
end
Agents ---> Output[Output]
T3 --> A1
T1 --> A2
T2 --> A3
style Tools fill:#189AB4,color:#fff
style Agents fill:#8B0000,color:#fff
style Input fill:#8B0000,color:#fff
style Output fill:#8B0000,color:#fff
```
| Feature | [Knowledge](/concepts/knowledge) | [Tools](/concepts/tools) |
|---------|--------------------------------|---------------------------|
| Purpose | Static reference information | Dynamic interaction capabilities |
| Access | Read-only reference | Execute actions and commands |
| Updates | Manual through files | Real-time through tool calls |
| Storage | Knowledge base | Assigned to specific agents |
| Persistence | Permanent until changed | Available during agent execution |
## Quick Start
Tools are functions that agents can use to interact with external systems and perform actions. They are essential for creating agents that can do more than just process text.
## Creating Custom Tool
<Steps>
<Step>
Create any function that you want to use as a tool, that performs a specific task.
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
Args:
query (str): The search query string
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step>
Assign the tool to an agent
```python
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool], ## Add the tool to the agent i.e the function name
)
```
</Step>
</Steps>
<Card title="That's it!">
<Check>You have created a custom tool and assigned it to an agent.</Check>
</Card>
## Implementing Tools Full Code Example
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents duckduckgo-search
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent with Tool">
Create `app.py`
```python
from praisonaiagents import Agent, Task, PraisonAIAgents
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool Implementation
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search using DuckDuckGo
Args:
query (str): The search query string
Returns:
List[Dict]: List of search results containing title, URL, and snippet
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Assign the tool to an agent
data_agent = Agent(
name="DataCollector",
role="Search Specialist",
goal="Perform internet searches to collect relevant information.",
backstory="Expert in finding and organising internet data.",
tools=[internet_search_tool],
self_reflect=False
)
# 3. Task Definition
collect_task = Task(
description="Perform an internet search using the query: 'AI job trends in 2024'. Return results as a list of title, URL, and snippet.",
expected_output="List of search results with titles, URLs, and snippets.",
agent=data_agent,
name="collect_data",
)
# 4. Start Agents
agents = PraisonAIAgents(
agents=[data_agent],
tasks=[collect_task],
process="sequential"
)
agents.start()
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package and duckduckgo_search package:
```bash Terminal
pip install praisonai duckduckgo_search
```
</Step>
<Step title="Create Custom Tool">
<Info>
To add additional tools/features you need some coding which can be generated using ChatGPT or any LLM
</Info>
Create a new file `tools.py` with the following content:
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step title="Create Agent">
Create a new file `agents.yaml` with the following content:
```yaml
framework: praisonai
topic: create movie script about cat in mars
roles:
scriptwriter:
backstory: Expert in dialogue and script structure, translating concepts into
scripts.
goal: Write a movie script about a cat in Mars
role: Scriptwriter
tools:
- internet_search_tool # <-- Tool assigned to Agent here
tasks:
scriptwriting_task:
description: Turn the story concept into a production-ready movie script,
including dialogue and scene details.
expected_output: Final movie script with dialogue and scene details.
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
## In-build Tools in PraisonAI
<CardGroup cols={2}>
<Card title="Search Tools" icon="magnifying-glass" href="/tools/search">
Tools for searching and retrieving information from various sources
</Card>
<Card title="Python Tools" icon="python" href="/tools/python_tools">
Essential Python utilities for data manipulation and scripting
</Card>
<Card title="Spider Tools" icon="spider" href="/tools/spider_tools">
Web crawling and scraping capabilities for data extraction
</Card>
<Card title="Arxiv Tools" icon="book" href="/tools/arxiv_tools">
Access and search academic papers from arXiv repository
</Card>
<Card title="Newspaper Tools" icon="newspaper" href="/tools/newspaper_tools">
Extract and parse content from news articles and websites
</Card>
<Card title="DuckDB Tools" icon="database" href="/tools/duckdb_tools">
Fast analytical SQL database operations and queries
</Card>
<Card title="DuckDuckGo Tools" icon="duck" href="/tools/duckduckgo_tools">
Web search functionality using DuckDuckGo's API
</Card>
<Card title="Calculator Tools" icon="calculator" href="/tools/calculator_tools">
Perform mathematical calculations and conversions
</Card>
<Card title="YAML Tools" icon="file-code" href="/tools/yaml_tools">
Parse and manipulate YAML format data
</Card>
<Card title="JSON Tools" icon="brackets-curly" href="/tools/json_tools">
Handle JSON data structures and operations
</Card>
<Card title="Pandas Tools" icon="table" href="/tools/pandas_tools">
Data analysis and manipulation using Pandas
</Card>
<Card title="YFinance Tools" icon="chart-line" href="/tools/yfinance_tools">
Fetch financial market data from Yahoo Finance
</Card>
<Card title="Shell Tools" icon="terminal" href="/tools/shell_tools">
Execute shell commands and system operations
</Card>
<Card title="Wikipedia Tools" icon="book-open" href="/tools/wikipedia_tools">
Access and search Wikipedia articles and data
</Card>
<Card title="XML Tools" icon="code" href="/tools/xml_tools">
Process and manipulate XML format data
</Card>
<Card title="File Tools" icon="file" href="/tools/file_tools">
File system operations and management utilities
</Card>
<Card title="Excel Tools" icon="file-excel" href="/tools/excel_tools">
Work with Excel spreadsheets and workbooks
</Card>
<Card title="CSV Tools" icon="file-csv" href="/tools/csv_tools">
Handle CSV file operations and transformations
</Card>
</CardGroup>
## Tools Overview
<CardGroup cols={3}>
<Card
title="Search Tools"
icon="magnifying-glass"
iconType="solid"
>
Tools for searching and retrieving information from various sources
</Card>
<Card
title="File Tools"
icon="file"
iconType="solid"
>
Tools for reading, writing, and manipulating files
</Card>
<Card
title="API Tools"
icon="code"
iconType="solid"
>
Tools for interacting with external APIs and services
</Card>
</CardGroup>
## Advanced Tool Features
### Tool Configuration
<Frame>
```python
def configured_tool(
query: str,
max_results: int = 5,
timeout: int = 10
) -> List[Dict]:
"""
Example of a configurable tool
Args:
query (str): Search query
max_results (int): Maximum number of results
timeout (int): Request timeout in seconds
Returns:
List[Dict]: Search results
"""
# Tool implementation
pass
```
</Frame>
### Tool Chaining
<Frame>
```python
def chain_tools(input_data: str) -> Dict:
"""
Example of chaining multiple tools
Args:
input_data (str): Input data
Returns:
Dict: Processed results
"""
# 1. Search for data
search_results = internet_search_tool(input_data)
# 2. Process results
processed_data = process_tool(search_results)
# 3. Format output
return format_tool(processed_data)
```
</Frame>
### Tool Categories
<CardGroup cols={3}>
<Card title="Data Collection Tools">
- Web scraping
- API integration
- Database queries
</Card>
<Card title="Processing Tools">
- Data transformation
- Text analysis
- Image processing
</Card>
<Card title="Output Tools">
- File generation
- Report creation
- Data visualization
</Card>
</CardGroup>
## Tool Integration
### Adding Tools to Agents
<Frame>
```python
# Multiple tools
agent = Agent(
name="MultiTool Agent",
tools=[
internet_search_tool,
file_processing_tool,
api_integration_tool
]
)
```
</Frame>
### Tool Dependencies
<Frame>
```python
# Tool with dependencies
def advanced_tool(data: Dict) -> Dict:
"""
Tool that depends on external libraries
Args:
data (Dict): Input data
Returns:
Dict: Processed data
"""
try:
import required_library
# Tool implementation
return processed_result
except ImportError:
raise Exception("Required library not installed")
```
</Frame>
## Tool Guidelines
<CardGroup cols={2}>
<Card title="Best Practices">
1. **Type Hints**
- Use Python type hints
- Define clear input/output types
- Document complex types
2. **Documentation**
- Write clear docstrings
- Explain parameters
- Provide usage examples
3. **Error Handling**
- Handle exceptions gracefully
- Return meaningful errors
- Validate inputs
</Card>
<Card title="Tool Types">
1. **Search Tools**
- Web search
- Database queries
- Document search
2. **File Tools**
- Read/write operations
- File conversion
- Data extraction
3. **API Tools**
- REST API calls
- GraphQL queries
- Service integration
</Card>
</CardGroup>
## Best Practices Summary
<Note>
Following these best practices will help you create robust, efficient, and secure tools in PraisonAI.
</Note>
<CardGroup cols={1}>
<Card title="Design Principles" icon="compass-drafting" iconType="solid">
<AccordionGroup>
<Accordion title="Single Responsibility">
Each tool should have one clear purpose and do it well. Avoid creating tools that try to do too many things.
```python
# Good Example
def process_image(image: np.array) -> np.array:
return processed_image
# Avoid
def process_and_save_and_upload(image):
# Too many responsibilities
pass
```
</Accordion>
<Accordion title="Clear Interfaces">
Define explicit input/output types and maintain consistent parameter naming.
```python
def search_tool(
query: str,
max_results: int = 10
) -> List[Dict[str, Any]]:
"""
Search for information with clear parameters
"""
pass
```
</Accordion>
<Accordion title="Documentation">
Always include detailed docstrings and type hints.
```python
def analyze_text(
text: str,
language: str = "en"
) -> Dict[str, float]:
"""
Analyze text sentiment and emotions.
Args:
text: Input text to analyze
language: ISO language code
Returns:
Dict with sentiment scores
"""
pass
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Performance Optimization" icon="bolt" iconType="solid">
<AccordionGroup>
<Accordion title="Efficient Processing">
Optimize resource usage and processing time.
```python
# Use generators for large datasets
def process_large_data():
for chunk in data_generator():
yield process_chunk(chunk)
```
</Accordion>
<Accordion title="Resource Management">
Properly handle resource allocation and cleanup.
```python
async with aiohttp.ClientSession() as session:
# Resource automatically managed
await process_data(session)
```
</Accordion>
<Accordion title="Caching">
Implement caching for frequently accessed data.
```python
@cache.memoize(timeout=300)
def expensive_operation(data: str) -> Dict:
return process_expensive(data)
```
</Accordion>
<Accordion title="Async Operations">
Use async/await for I/O-bound operations.
```python
async def fetch_data(urls: List[str]):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
return await asyncio.gather(*tasks)
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<CardGroup cols={1}>
<Card title="Security Best Practices" icon="shield-check" iconType="solid">
<AccordionGroup>
<Accordion title="Input Validation">
Always validate and sanitize inputs to prevent security vulnerabilities.
```python
def process_user_input(data: str) -> str:
if not isinstance(data, str):
raise ValueError("Input must be string")
return sanitize_input(data.strip())
```
</Accordion>
<Accordion title="Rate Limiting">
Implement rate limiting for API calls to prevent abuse.
```python
@rate_limit(calls=100, period=60)
async def api_call():
return await make_request()
```
</Accordion>
<Accordion title="API Key Management">
Securely handle API keys and credentials using environment variables.
```python
# Use environment variables
api_key = os.getenv('API_KEY')
if not api_key:
raise ConfigError("API key not found")
```
</Accordion>
<Accordion title="Error Masking">
Hide sensitive information in error messages to prevent information leakage.
```python
try:
result = process_sensitive_data()
except Exception as e:
# Log detailed error internally
logger.error(f"Detailed error: {str(e)}")
# Return sanitized error to user
raise PublicError("Processing failed")
```
</Accordion>
</AccordionGroup>
</Card>
</CardGroup>
<br />
<Tip>
**Pro Tip**: Start with these practices from the beginning of your project. It's easier to maintain good practices than to retrofit them later.
</Tip>
-28
View File
@@ -1,28 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
project = 'PraisonAI'
copyright = '2024, Mervin Praison'
author = 'Mervin Praison'
release = '7'
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx_rtd_theme']
templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
-14
View File
@@ -1,14 +0,0 @@
---
title: "Contributing"
description: "Guide for contributing to PraisonAI through GitHub, including forking, cloning, and submitting pull requests"
icon: "code-branch"
---
- Fork on GitHub: Use the "Fork" button on the repository page.
- Clone your fork: `git clone https://github.com/yourusername/praisonAI.git`
- Create a branch: `git checkout -b new-feature`
- Make changes and commit: `git commit -am "Add some feature"`
- Push to your fork: `git push origin new-feature`
- Submit a pull request via GitHub's web interface.
- Await feedback from project maintainers.
-71
View File
@@ -1,71 +0,0 @@
---
title: "Introduction to AI Agents"
description: "Welcome to the beginner's course on AI Agents"
icon: "book-open"
---
# Introduction to AI Agents
Welcome to the beginners' course on AI Agents! This course is designed to help you understand and build your own AI agents, even if you have little to no programming experience.
## What Are AI Agents?
An AI agent is a software program that can:
- Understand information from its environment
- Make decisions based on that information
- Take actions to achieve specific goals
Think of an AI agent like a helpful assistant that can perform tasks for you automatically.
```mermaid
graph TD
A[Perceive Information] --> B[Make Decisions]
B --> C[Take Actions]
C --> A
```
## Examples in Daily Life
You might already be using AI agents without realizing it:
- **Virtual Assistants**: Siri, Alexa, and Google Assistant are AI agents that respond to your voice commands
- **Recommendation Systems**: Netflix, YouTube, and Amazon use AI agents to suggest content you might like
- **Smart Home Devices**: Devices that adjust temperature or lighting based on your preferences
## What You'll Learn in This Course
Throughout this course, you will:
1. Understand the basic concepts of AI agents
2. Learn about different types of AI agents
3. Explore how AI agents make decisions
4. Discover how to build simple AI agents without complex programming
5. Create your own functional AI agents
## Who This Course Is For
This course is perfect for:
- Complete beginners with no prior knowledge of AI
- Non-technical professionals interested in how AI can solve problems
- Students curious about artificial intelligence
- Anyone who wants to understand and use AI agents in practical ways
Let's begin our journey into the fascinating world of AI agents!
<iframe
id="codeExecutionFrame"
src="https://code-execution-server-praisonai.replit.app/?code=import%20openai%0A%0Aclient%20%3D%20openai.OpenAI()%0Aresult%20%3D%20client.chat.completions.create(%0A%20%20%20%20model%3D%22gpt-3.5-turbo%22%2C%0A%20%20%20%20messages%3D%5B%0A%20%20%20%20%20%20%20%20%7B%22role%22%3A%20%22user%22%2C%20%22content%22%3A%20%22Hello%20World%22%7D%0A%20%20%20%20%5D%0A)%0A%0Aprint(result.choices%5B0%5D.message.content)"
width="100%"
height="600px"
frameborder="0"
allow="clipboard-read; clipboard-write"
scrolling="yes"
onload="resizeIframe(this)"
></iframe>
<IframeWithAutoHeight />
<CardGroup cols={1}>
<Card title="Ready to Start?" icon="rocket">
Continue to the next lesson to learn about the different types of AI agents.
</Card>
</CardGroup>
-113
View File
@@ -1,113 +0,0 @@
---
title: "Types of AI Agents"
description: "Understanding the different categories of AI agents"
icon: "sitemap"
---
# Types of AI Agents
AI agents come in different forms, each designed for specific purposes and with varying levels of complexity. Understanding these types will help you choose the right approach for your needs.
## Simple Reflex Agents
These are the most basic type of AI agents that operate using simple if-then rules.
<CardGroup cols={1}>
<Card title="Key Characteristics" icon="lightbulb">
- React directly to current input only
- No memory of past events
- No prediction of future states
- Use predefined rules to determine actions
</Card>
</CardGroup>
**Real-world example**: A basic thermostat that turns heating on when temperature drops below a set point.
```mermaid
graph LR
A[Sensor Input] --> B{If-Then Rules}
B --> C[Action]
```
## Model-Based Agents
These agents maintain an internal model of their environment to make better decisions.
<CardGroup cols={1}>
<Card title="Key Characteristics" icon="brain">
- Build and maintain an internal representation of the world
- Can work with partial information
- Can consider "what if" scenarios
- Make decisions based on their understanding of how the world works
</Card>
</CardGroup>
**Real-world example**: A GPS navigation system that models roads and traffic conditions.
## Goal-Based Agents
These agents make decisions based on how their actions will help achieve specific goals.
<CardGroup cols={1}>
<Card title="Key Characteristics" icon="bullseye">
- Consider future consequences of actions
- Evaluate which actions will lead toward goals
- Can plan sequences of actions
- Choose actions that maximize goal attainment
</Card>
</CardGroup>
**Real-world example**: A chess-playing AI that plans moves to achieve checkmate.
## Utility-Based Agents
These agents choose actions that maximize a specific utility (or happiness) function.
<CardGroup cols={1}>
<Card title="Key Characteristics" icon="chart-line">
- Assign a utility value to different possible outcomes
- Consider probability and risk
- Choose actions that maximize expected utility
- Can balance competing objectives
</Card>
</CardGroup>
**Real-world example**: An investment robo-advisor that balances risk and return.
## Learning Agents
These agents improve their performance over time through experience.
<CardGroup cols={1}>
<Card title="Key Characteristics" icon="graduation-cap">
- Learn from past experiences
- Adapt to changing environments
- Improve decision-making over time
- Can discover new strategies
</Card>
</CardGroup>
**Real-world example**: Recommendation systems that learn your preferences over time.
## Understanding Agent Complexity
<Tip>
As you move from Simple Reflex Agents toward Learning Agents, both capability and complexity increase. For beginners, starting with simpler agent types is often best.
</Tip>
## Which Agent Type Should You Build?
The best type of agent for your project depends on:
1. **The problem complexity**: Simple problems may only need reflex agents
2. **Available data**: Learning agents need training data
3. **Required adaptability**: Will your agent need to adapt to new situations?
4. **Available resources**: More complex agents require more computational power
In this course, we'll focus primarily on goal-based and simple learning agents as they provide a good balance of capability and complexity for beginners.
<CardGroup cols={1}>
<Card title="Next Steps" icon="arrow-right">
In the next lesson, we'll explore how agents process information and make decisions.
</Card>
</CardGroup>
@@ -1,157 +0,0 @@
---
title: "Agent Architecture"
description: "Understanding how AI agents are structured"
icon: "layer-group"
---
# Agent Architecture
Understanding how AI agents are structured will help you build more effective agents. This lesson covers the fundamental components of an agent's architecture.
## Basic Components of an AI Agent
Every AI agent, regardless of complexity, has these basic components:
```mermaid
graph TD
A[Sensors/Input] --> B[Processing Unit]
B --> C[Decision-Making]
C --> D[Actions/Output]
```
### 1. Input (Sensors)
This is how agents receive information from their environment.
<CardGroup cols={1}>
<Card title="Examples of Input" icon="eye">
- Text input from users
- Data from databases
- Image or audio input
- API responses
- Sensor readings (in physical agents)
</Card>
</CardGroup>
### 2. Processing Unit
This component processes information and converts it into a format the agent can understand.
<CardGroup cols={1}>
<Card title="Processing Functions" icon="gears">
- Data cleaning and transformation
- Feature extraction
- Context building
- Information retrieval
- Pattern recognition
</Card>
</CardGroup>
### 3. Decision-Making Core
The "brain" of the agent that determines what actions to take.
<CardGroup cols={1}>
<Card title="Decision Components" icon="brain">
- Language models (like GPT-4)
- Rule systems
- Planning algorithms
- Knowledge base
- Memory systems
</Card>
</CardGroup>
### 4. Output (Actions)
The actions the agent can perform to achieve its goals.
<CardGroup cols={1}>
<Card title="Action Examples" icon="hand">
- Generating text responses
- Creating visual content
- Making API calls
- Controlling other systems
- Updating databases
</Card>
</CardGroup>
## The Agent Loop
Agents operate in a continuous loop:
```mermaid
graph LR
A[Perceive] --> B[Process]
B --> C[Decide]
C --> D[Act]
D --> A
```
This cycle allows agents to continuously:
1. Gather information
2. Update their understanding
3. Make new decisions
4. Take appropriate actions
## PraisonAI Agent Architecture
In the PraisonAI framework, agents follow a specific architecture:
<CardGroup cols={1}>
<Card title="PraisonAI Agent Components" icon="puzzle-piece">
- **Instructions**: Defines the agent's purpose and behavior
- **Language Model**: Powers the agent's intelligence (e.g., GPT-4)
- **Memory**: Stores context and previous interactions
- **Tools**: Specialized capabilities an agent can use
</Card>
</CardGroup>
### Simple Agent Structure
```python
from praisonaiagents import Agent
# Create a simple agent
research_agent = Agent(
instructions="Research the latest developments in renewable energy",
name="ResearchAgent"
)
# Start the agent
research_agent.start()
```
## Understanding Agent Communication
Multi-agent systems allow agents to communicate with each other:
```mermaid
graph LR
A[Agent 1] --> B[Agent 2]
B --> C[Agent 3]
C --> A
```
Each agent can:
- Pass information to other agents
- Request assistance from specialized agents
- Collaborate on complex tasks
## Key Takeaways
<CardGroup cols={2}>
<Card title="Component Importance" icon="check">
Each component plays a vital role in the agent's functionality
</Card>
<Card title="Agent Customization" icon="gear">
You can customize each component based on your specific needs
</Card>
<Card title="Component Balance" icon="scale-balanced">
A well-designed agent balances all components effectively
</Card>
<Card title="Continuous Improvement" icon="arrow-trend-up">
Agents can be improved by enhancing individual components
</Card>
</CardGroup>
In the next lesson, we'll explore how to define effective instructions for your AI agents.
@@ -1,187 +0,0 @@
---
title: "Creating Effective Agent Instructions"
description: "How to write clear instructions for your AI agents"
icon: "file-lines"
---
# Creating Effective Agent Instructions
The instructions you give to your AI agent are crucial to its performance. Well-crafted instructions lead to agents that understand their purpose and execute tasks effectively.
## Why Instructions Matter
Instructions serve as the agent's "job description" and guide its behavior:
<CardGroup cols={2}>
<Card title="Clarity" icon="glasses">
Clear instructions reduce confusion and misinterpretation
</Card>
<Card title="Focus" icon="bullseye">
Specific instructions keep the agent on task
</Card>
<Card title="Boundaries" icon="border-all">
Good instructions define what an agent should and shouldn't do
</Card>
<Card title="Personality" icon="face-smile">
Instructions can shape how an agent communicates
</Card>
</CardGroup>
## Elements of Effective Instructions
### 1. Role Definition
Tell the agent who it is and what its expertise should be.
<CodeGroup>
```text Good Example
You are a financial analyst with expertise in market trends and investment strategies.
```
```text Weak Example
You are a helper.
```
</CodeGroup>
### 2. Purpose and Goals
Clearly state what the agent should accomplish.
<CodeGroup>
```text Good Example
Your goal is to analyze company quarterly reports and provide actionable investment insights.
```
```text Weak Example
Help with finance stuff.
```
</CodeGroup>
### 3. Process Guidelines
Explain how the agent should approach tasks.
<CodeGroup>
```text Good Example
First analyze the data trends, then identify key risk factors, and finally make recommendations based on the client's risk tolerance.
```
```text Weak Example
Just do a good analysis.
```
</CodeGroup>
### 4. Response Format
Specify how you want information presented.
<CodeGroup>
```text Good Example
Present your analysis in a structured format with: Summary, Key Findings, Risk Assessment, and Recommendations.
```
```text Weak Example
Tell me what you find.
```
</CodeGroup>
## Instructions Template
Here's a template you can use to create effective agent instructions:
```
You are a [ROLE] specializing in [EXPERTISE AREAS].
Your goal is to [MAIN OBJECTIVE].
When approaching tasks:
1. [FIRST STEP/APPROACH]
2. [SECOND STEP/APPROACH]
3. [THIRD STEP/APPROACH]
Present your results in [FORMAT PREFERENCES].
Additional guidelines:
- [SPECIFIC BEHAVIOR 1]
- [SPECIFIC BEHAVIOR 2]
- [SPECIFIC BEHAVIOR 3]
```
## Examples in PraisonAI
Let's look at how instructions are implemented in PraisonAI:
<CodeGroup>
```python Simple Example
from praisonaiagents import Agent
research_agent = Agent(
instructions="You are a research assistant specializing in climate science. Your goal is to find the latest research on rising sea levels and summarize key findings in bullet points."
)
research_agent.start()
```
```python Detailed Example
from praisonaiagents import Agent
content_agent = Agent(
name="ContentCreator",
instructions="""
You are a content creation specialist with expertise in digital marketing.
Your goal is to create engaging blog content that drives traffic and conversions.
When creating content:
1. Research the target keyword thoroughly
2. Create an attention-grabbing headline
3. Develop well-structured content with clear sections
4. Include actionable takeaways for readers
Present content in markdown format with proper headings, bullet points, and emphasis where appropriate.
Additional guidelines:
- Maintain a conversational but professional tone
- Include 2-3 relevant statistics to support key points
- Add a call-to-action at the end of each piece
"""
)
content_agent.start("Create a blog post about sustainable living tips")
```
</CodeGroup>
## Common Instruction Mistakes
<CardGroup cols={2}>
<Card title="Being Too Vague" icon="cloud">
Vague instructions lead to unpredictable outputs
</Card>
<Card title="Information Overload" icon="bomb">
Too many details can confuse the agent's priorities
</Card>
<Card title="Contradictory Guidelines" icon="arrows-split-up-and-left">
Conflicting instructions create confusion
</Card>
<Card title="Missing Context" icon="puzzle-piece-missing">
Insufficient background information leads to generic outputs
</Card>
</CardGroup>
## Refining Your Instructions
<Tip>
Good instructions often require iteration. Start with basic instructions, review the agent's performance, and refine as needed.
</Tip>
Effective instruction improvement follows this cycle:
```mermaid
graph TD
A[Write Initial Instructions] --> B[Test Agent Performance]
B --> C[Identify Issues/Gaps]
C --> D[Refine Instructions]
D --> B
```
In the next lesson, we'll explore how agents use tools to extend their capabilities.
-183
View File
@@ -1,183 +0,0 @@
---
title: "Agent Tools"
description: "Understanding how tools extend agent capabilities"
icon: "screwdriver-wrench"
---
# Agent Tools
Tools allow AI agents to interact with the world and perform specific actions. Think of tools as the "hands" of your agent that let it accomplish tasks beyond just generating text.
## What Are Agent Tools?
<CardGroup cols={1}>
<Card title="Definition" icon="toolbox">
Tools are functions or capabilities that agents can access to perform specific actions, retrieve information, or interact with external systems.
</Card>
</CardGroup>
Just as humans use tools to extend their physical abilities, AI agents use digital tools to extend their capabilities.
## Why Tools Matter
Tools transform agents from simple chat interfaces into powerful assistants that can:
<CardGroup cols={2}>
<Card title="Access Information" icon="database">
Retrieve data from various sources
</Card>
<Card title="Perform Calculations" icon="calculator">
Analyze numbers and data accurately
</Card>
<Card title="Create Content" icon="pen-to-square">
Generate images, code, or other media
</Card>
<Card title="Control Systems" icon="gears">
Interact with other software or hardware
</Card>
</CardGroup>
## Common Types of Tools
### 1. Information Retrieval Tools
These tools help agents access information beyond their training data.
**Examples:**
- Web search tools
- Database query tools
- Document retrieval tools
```python
# Example of a simple web search tool
from praisonaiagents import Agent
def web_search(query):
# Simplified example
return f"Results for: {query}"
agent = Agent(
instructions="Research assistant",
tools=[web_search]
)
```
### 2. Computation Tools
These tools perform calculations or data processing.
**Examples:**
- Calculator tools
- Data analysis tools
- Conversion tools
### 3. Content Creation Tools
These tools help generate or modify various types of content.
**Examples:**
- Image generation tools
- Code writing tools
- Document formatting tools
### 4. External API Tools
These tools connect to third-party services.
**Examples:**
- Weather API tools
- Translation API tools
- E-commerce API tools
## How Tools Work in PraisonAI
In the PraisonAI framework, tools follow a simple pattern:
1. Tools are defined as functions
2. Tools are registered with an agent
3. The agent decides when to use appropriate tools
4. Tool results are incorporated into the agent's reasoning
```mermaid
graph TD
A[Agent Receives Task] --> B{Needs a Tool?}
B -->|Yes| C[Select Appropriate Tool]
C --> D[Execute Tool]
D --> E[Process Tool Results]
E --> F[Continue Task]
B -->|No| F
```
## Creating Basic Tools
Here's a simple example of creating and using tools in PraisonAI:
```python
from praisonaiagents import Agent
# Define a simple calculator tool
def calculator(expression):
try:
return str(eval(expression))
except:
return "Error: Could not calculate"
# Create an agent with the tool
math_agent = Agent(
instructions="You are a math tutor helping students solve problems",
tools=[calculator]
)
# Use the agent
math_agent.start("Calculate 24 * 17 and explain the steps")
```
## Tool Best Practices
<CardGroup cols={2}>
<Card title="Clear Descriptions" icon="comment">
Provide detailed descriptions so the agent knows when to use each tool
</Card>
<Card title="Error Handling" icon="shield">
Make tools robust with proper error handling
</Card>
<Card title="Focused Purpose" icon="bullseye">
Each tool should do one thing well
</Card>
<Card title="Input Validation" icon="check-double">
Validate inputs to prevent misuse
</Card>
</CardGroup>
## Building a Toolbox
As you advance, you'll want to create a collection of tools your agent can use:
```python
from praisonaiagents import Agent, Tool
# Define multiple tools
def weather(location):
return f"Weather in {location}: Sunny, 75°F"
def translator(text, target_language):
return f"Translated to {target_language}: {text} (placeholder)"
def reminder(message, time):
return f"Reminder set for {time}: {message}"
# Create tool collection
tools = [
Tool(name="weather", function=weather, description="Get weather for a location"),
Tool(name="translator", function=translator, description="Translate text"),
Tool(name="reminder", function=reminder, description="Set a reminder")
]
# Create agent with multiple tools
assistant = Agent(
instructions="You are a helpful personal assistant",
tools=tools
)
```
In the next lesson, we'll explore how agents use memory to maintain context across interactions.
-167
View File
@@ -1,167 +0,0 @@
---
title: "Agent Memory"
description: "Understanding how agents maintain context and learn"
icon: "brain"
---
# Agent Memory
Memory enables AI agents to remember past interactions, maintain context, and provide more coherent responses over time. Without memory, agents would treat each interaction as if it was their first.
## Why Memory Matters
<CardGroup cols={2}>
<Card title="Context Awareness" icon="comments">
Remembers previous parts of a conversation
</Card>
<Card title="Personalization" icon="user-gear">
Recalls user preferences and history
</Card>
<Card title="Continuous Learning" icon="graduation-cap">
Builds on past experiences
</Card>
<Card title="Task Persistence" icon="list-check">
Maintains progress on long-running tasks
</Card>
</CardGroup>
## Types of Agent Memory
### 1. Short-Term Memory (Conversation Memory)
This type of memory stores recent interactions within a session.
```mermaid
graph LR
A[User Input 1] --> B[Agent Response 1]
B --> C[User Input 2]
C --> D[Agent Response 2]
D --> E[User Input 3]
```
The agent can refer back to earlier messages in the same conversation.
### 2. Long-Term Memory
This allows agents to remember information across different sessions.
<CardGroup cols={1}>
<Card title="Use Cases" icon="clock">
- Remembering user preferences
- Recalling previous tasks completed
- Storing learned information
- Maintaining relationship history
</Card>
</CardGroup>
### 3. Working Memory
This is where agents process current information and combine it with retrieved memories.
```mermaid
graph TD
A[Current Input] --> D[Working Memory]
B[Short-Term Memory] --> D
C[Long-Term Memory] --> D
D --> E[Agent Response]
```
## How Memory Works in PraisonAI
In the PraisonAI framework, memory is handled automatically for basic cases and can be customized for more advanced needs:
```python
from praisonaiagents import Agent
# Basic agent with default memory handling
agent = Agent(
instructions="You are a helpful assistant that remembers our conversations"
)
# The conversation history is maintained automatically
agent.start("My name is Alex")
agent.continue("What's my name?")# Note: TODO: This Feature yet to be developed # Agent will remember "Alex"
```
## Memory Limitations
<Tip>
All AI memories have limitations. They aren't perfect and may occasionally forget or misremember information.
</Tip>
Common limitations include:
<CardGroup cols={2}>
<Card title="Memory Capacity" icon="database">
Limit to how much information can be stored
</Card>
<Card title="Context Window" icon="window">
Only a portion of memory fits in the active context
</Card>
<Card title="Memory Decay" icon="hourglass-half">
Older memories may become less accessible
</Card>
<Card title="Memory Retrieval" icon="magnifying-glass">
Finding the right memory at the right time
</Card>
</CardGroup>
## Implementing Persistent Memory
For more advanced applications, you can implement custom memory systems:
```python
# Note: TODO: This Feature yet to be tested
from praisonaiagents import Agent, Memory
# Create a simple memory store
memory = Memory()
# Add information to memory
memory.add("user_name", "Alex")
memory.add("favorite_color", "blue")
# Create agent with this memory
agent = Agent(
instructions="You are a personal assistant",
memory=memory
)
# The agent can now access these memories
agent.start("What's my favorite color?") # Agent should respond "blue"
```
## Memory Best Practices
<CardGroup cols={2}>
<Card title="Prioritize Important Info" icon="star">
Not everything needs to be remembered
</Card>
<Card title="Verify When Uncertain" icon="question">
Have agents confirm uncertain memories
</Card>
<Card title="Structured Storage" icon="folder-tree">
Organize memories by categories
</Card>
<Card title="Regular Updates" icon="arrows-rotate">
Update memories when information changes
</Card>
</CardGroup>
## Memory in Multi-Agent Systems
In systems with multiple agents, memory can be:
1. **Private**: Each agent has its own memories
2. **Shared**: Agents have access to a common memory store
3. **Hybrid**: Some memories are private, others are shared
```mermaid
graph TD
A[Agent 1] --> B[Private Memory 1]
C[Agent 2] --> D[Private Memory 2]
A -.-> E[Shared Memory]
C -.-> E
```
In the next lesson, we'll learn about how to set up multiple agents to work together effectively.
@@ -1,171 +0,0 @@
---
title: "Multi-Agent Systems"
description: "How multiple agents can work together"
icon: "users"
---
# Multi-Agent Systems
Multi-agent systems allow multiple AI agents to work together, each handling different parts of a complex task. This approach mirrors how human teams collaborate, with each member contributing their specialized skills.
## Why Use Multiple Agents?
<CardGroup cols={2}>
<Card title="Specialization" icon="star">
Each agent can focus on its area of expertise
</Card>
<Card title="Complex Tasks" icon="puzzle-piece">
Break down difficult problems into manageable pieces
</Card>
<Card title="Scalability" icon="arrows-up-down">
Add more agents as tasks become more complex
</Card>
<Card title="Diverse Perspectives" icon="lightbulb">
Different agents can approach problems differently
</Card>
</CardGroup>
## Basic Multi-Agent Architecture
```mermaid
graph LR
A[Research Agent] --> B[Analysis Agent]
B --> C[Writing Agent]
C --> D[Final Output]
```
In this example:
1. The Research Agent gathers information
2. The Analysis Agent processes and interprets the data
3. The Writing Agent creates the final content
## Multi-Agent Patterns
### 1. Pipeline Pattern
Agents work in sequence, with each agent handling a specific stage of the process.
```mermaid
graph LR
A[Agent 1] --> B[Agent 2]
B --> C[Agent 3]
```
**Example Use Case**: Content creation where one agent researches, another drafts, and a third edits.
### 2. Expert Panel Pattern
Multiple specialist agents work in parallel on the same problem, then their outputs are combined.
```mermaid
graph TD
Task --> A[Expert Agent 1]
Task --> B[Expert Agent 2]
Task --> C[Expert Agent 3]
A --> D[Coordination Agent]
B --> D
C --> D
D --> Result
```
**Example Use Case**: Financial analysis where different experts analyze market trends, economic indicators, and company performance.
### 3. Hierarchical Pattern
A manager agent delegates tasks to worker agents and coordinates their efforts.
```mermaid
graph TD
A[Manager Agent] --> B[Worker Agent 1]
A --> C[Worker Agent 2]
A --> D[Worker Agent 3]
B --> A
C --> A
D --> A
```
**Example Use Case**: Project management where a coordinator assigns tasks and integrates results.
## Implementing Multi-Agent Systems in PraisonAI
Here's a simple example of creating a multi-agent system:
```python
from praisonaiagents import Agent, PraisonAIAgents
# Create individual agents
research_agent = Agent(
name="Researcher",
instructions="Research the latest trends in renewable energy"
)
analysis_agent = Agent(
name="Analyst",
instructions="Analyze the research findings and identify key insights"
)
writing_agent = Agent(
name="Writer",
instructions="Create a clear, engaging report based on the analysis"
)
# Create a multi-agent system
agents = PraisonAIAgents(
agents=[research_agent, analysis_agent, writing_agent]
)
# Start the agents
agents.start()
```
## Agent Communication
For agents to work together effectively, they need to communicate. This happens through:
<CardGroup cols={2}>
<Card title="Output Passing" icon="arrow-right">
One agent's output becomes another's input
</Card>
<Card title="Shared Memory" icon="database">
Agents can access common information
</Card>
<Card title="Message Exchange" icon="comments">
Agents can send specific messages to each other
</Card>
<Card title="Coordination Protocols" icon="traffic-light">
Rules that determine how agents interact
</Card>
</CardGroup>
## Challenges in Multi-Agent Systems
<CardGroup cols={2}>
<Card title="Coordination" icon="shuffle">
Ensuring agents work together smoothly
</Card>
<Card title="Conflicting Goals" icon="arrows-split-up-and-left">
Managing agents with different objectives
</Card>
<Card title="Information Transfer" icon="exchange">
Passing information effectively between agents
</Card>
<Card title="Resource Management" icon="microchip">
Allocating computational resources efficiently
</Card>
</CardGroup>
## Designing Effective Multi-Agent Systems
<Tip>
Start simple with just 2-3 agents and a clear workflow before scaling to more complex systems.
</Tip>
Key principles for effective design:
1. **Clear Role Definition**: Each agent should have a specific and well-defined role
2. **Minimized Dependencies**: Reduce complex interdependencies between agents
3. **Standardized Communication**: Use consistent formats for information exchange
4. **Failure Handling**: Plan for cases where an agent fails to complete its task
5. **Performance Monitoring**: Track how well each agent and the overall system performs
In the next lesson, we'll explore how to create effective agent workflows using the Process component.
-152
View File
@@ -1,152 +0,0 @@
---
title: "Agent Process"
description: "Understanding agent workflows and processes"
icon: "diagram-project"
---
# Agent Process
The Process component in AI agent systems defines how agents work together and the flow of information between them. Think of it as the "playbook" that coordinates how agents complete tasks.
## What is an Agent Process?
<CardGroup cols={1}>
<Card title="Definition" icon="route">
A process is a structured workflow that defines the sequence of steps, decision points, and information flow between agents to complete a task.
</Card>
</CardGroup>
## Process Flow Basics
A simple process flow might look like this:
```mermaid
graph LR
A[Start] --> B[Gather Information]
B --> C[Process Information]
C --> D[Make Decision]
D --> E[Take Action]
E --> F[Report Results]
```
Each step could be handled by a different agent or by the same agent in different stages.
## Types of Process Flows
### 1. Sequential Process
Agents work in a straight line, one after another.
```mermaid
graph LR
A[Agent 1] --> B[Agent 2]
B --> C[Agent 3]
C --> D[Complete]
```
**Best for**: Tasks with clear, linear stages
### 2. Parallel Process
Multiple agents work simultaneously on different parts of a task.
```mermaid
graph TD
A[Start] --> B[Agent 1]
A --> C[Agent 2]
A --> D[Agent 3]
B --> E[Combine Results]
C --> E
D --> E
E --> F[Complete]
```
**Best for**: Tasks that can be broken into independent pieces
### 3. Conditional Process
The workflow changes based on decisions or conditions.
```mermaid
graph TD
A[Start] --> B{Decision Point}
B -->|Condition A| C[Agent 1]
B -->|Condition B| D[Agent 2]
C --> E[Complete]
D --> E
```
**Best for**: Tasks requiring different approaches based on circumstances
## Implementing Process in PraisonAI
Here's a simple example of creating a process in PraisonAI:
```python
from praisonaiagents import Agent, Process, PraisonAIAgents
# Create agents
research_agent = Agent(
name="Researcher",
instructions="Research the topic and gather key information about AI"
)
writing_agent = Agent(
name="Writer",
instructions="Create content based on the research"
)
editing_agent = Agent(
name="Editor",
instructions="Review and improve the content"
)
# Create the multi-agent system with the process
agents = PraisonAIAgents(
agents=[research_agent, writing_agent, editing_agent],
process="hierarchical"
)
# Start the process
agents.start()
```
## Process Best Practices
<CardGroup cols={2}>
<Card title="Clear Step Definitions" icon="list-check">
Define exactly what each step should accomplish
</Card>
<Card title="Error Handling" icon="bug">
Include steps for handling unexpected situations
</Card>
<Card title="Feedback Loops" icon="repeat">
Allow agents to request clarification when needed
</Card>
<Card title="Modular Design" icon="cubes">
Create reusable process components
</Card>
</CardGroup>
<Tip>
Start with simple processes and gradually add complexity as you become more comfortable with the system.
</Tip>
## Monitoring Process Execution
It's important to track how your processes are running:
```python
agents = PraisonAIAgents(
agents=[research_agent, writing_agent, editing_agent],
process=content_process,
verbose=True # Enables detailed logging
)
```
This will provide information about:
- Which step is currently running
- The inputs and outputs of each step
- Any errors or issues encountered
In the next lesson, we'll explore how to use knowledge bases to enhance agent capabilities.
-190
View File
@@ -1,190 +0,0 @@
---
title: "Knowledge Bases"
description: "Enhancing agents with specialized knowledge"
icon: "book"
---
# Knowledge Bases
Knowledge bases provide agents with specialized information beyond their training data. They help agents answer specific questions, follow guidelines, or work within defined domains.
## What is a Knowledge Base?
<CardGroup cols={1}>
<Card title="Definition" icon="database">
A knowledge base is a structured collection of information that an agent can access to answer questions or make decisions.
</Card>
</CardGroup>
Think of a knowledge base as a specialized reference library for your agent.
## Why Use Knowledge Bases?
<CardGroup cols={2}>
<Card title="Domain Expertise" icon="user-graduate">
Provide specialized information for specific fields
</Card>
<Card title="Current Information" icon="clock">
Include data beyond the agent's training cutoff
</Card>
<Card title="Custom Guidelines" icon="list">
Define rules and policies for the agent to follow
</Card>
<Card title="Consistent Responses" icon="equals">
Ensure agents provide standardized answers
</Card>
</CardGroup>
## Types of Knowledge Bases
### 1. Document Collections
Text documents, articles, guides, or manuals that agents can reference.
```mermaid
graph TD
A[Query] --> B[Search Documents]
B --> C[Find Relevant Content]
C --> D[Generate Response]
```
### 2. Structured Data
Databases, tables, or other structured formats that organize information systematically.
<CardGroup cols={1}>
<Card title="Examples" icon="table">
- Product catalogs with specifications
- Customer information databases
- Statistical data collections
- Reference tables for compliance information
</Card>
</CardGroup>
### 3. Vector Databases
Special databases that store information as numerical representations (vectors) for semantic search.
```mermaid
graph TD
A[User Question] --> B[Convert to Vector]
B --> C[Find Similar Vectors]
C --> D[Retrieve Related Information]
D --> E[Generate Answer]
```
## Implementing Knowledge Bases in PraisonAI
Here's an example of how to use a knowledge base with an agent:
```python
from praisonaiagents import Agent
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"]
)
agent.start("What is KAG in one line?")
```
## Advanced Configuration
For more control over the knowledge base, you can specify a configuration:
```python
from praisonaiagents import Agent
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "custom_knowledge",
"path": ".praison",
}
}
}
agent = Agent(
name="Knowledge Agent",
instructions="You answer questions based on the provided knowledge.",
knowledge=["small.pdf"],
knowledge_config=config
)
agent.start("What is KAG in one line?")
```
## Knowledge Retrieval Process
When an agent uses a knowledge base, this typical process occurs:
```mermaid
graph LR
A[User Question] --> B[Query Processing]
B --> C[Search Knowledge Base]
C --> D[Rank Results]
D --> E[Synthesize Answer]
```
1. **Query Processing**: The user's question is analyzed
2. **Search**: The system searches the knowledge base for relevant information
3. **Ranking**: Results are ranked by relevance
4. **Synthesis**: The agent creates an answer using the retrieved information
## Best Practices for Knowledge Bases
<CardGroup cols={2}>
<Card title="Keep Information Current" icon="arrows-rotate">
Regularly update your knowledge base
</Card>
<Card title="Organize Logically" icon="folder-tree">
Structure information in intuitive categories
</Card>
<Card title="Prioritize Quality" icon="star">
Focus on accurate, high-quality information
</Card>
<Card title="Include Examples" icon="list">
Add examples to illustrate complex concepts
</Card>
</CardGroup>
## When to Use Knowledge Bases
Knowledge bases are particularly valuable when:
1. Your agent needs to reference specific information that may change over time
2. You need to ensure consistent answers to common questions
3. Your agent needs to follow specific guidelines or protocols
4. You want to provide expertise in specialized domains
<Tip>
Start with a small knowledge base focusing on the most important information, then expand as needed.
</Tip>
## Creating a Simple Knowledge Base
For beginners, you can start with a simple text-based knowledge base:
```
# Company FAQ Knowledge Base
## Return Policy
Our return policy allows customers to return products within 30 days of purchase for a full refund.
## Shipping Information
Standard shipping takes 3-5 business days. Express shipping takes 1-2 business days.
## Product Warranty
All products come with a 1-year limited warranty covering manufacturing defects.
```
Save this as a text file and add it to your knowledge base:
```python
kb = KnowledgeBase()
kb.add_document("company_faq.txt")
```
In the next lesson, we'll explore how agents handle tasks and the task management process.
-274
View File
@@ -1,274 +0,0 @@
---
title: "Agent Tasks"
description: "Understanding how agents handle and manage tasks"
icon: "clipboard-list"
---
# Agent Tasks
Tasks are the specific units of work that AI agents perform. Understanding how to define and manage tasks is essential for creating effective agent systems.
## What is an Agent Task?
<CardGroup cols={1}>
<Card title="Definition" icon="list-check">
A task is a specific, well-defined piece of work assigned to an agent with clear inputs, expected outputs, and success criteria.
</Card>
</CardGroup>
Just as human jobs are broken into specific responsibilities, agent systems work best when complex goals are divided into manageable tasks.
## Anatomy of a Task
A well-defined task includes:
<CardGroup cols={2}>
<Card title="Objective" icon="bullseye">
What the task should accomplish
</Card>
<Card title="Inputs" icon="arrow-right-to-bracket">
Information provided to complete the task
</Card>
<Card title="Process" icon="gears">
Steps to follow or approach to take
</Card>
<Card title="Outputs" icon="arrow-right-from-bracket">
Expected results or deliverables
</Card>
</CardGroup>
## Task Types
### 1. Information Tasks
These tasks involve finding, analyzing, or summarizing information.
**Examples:**
- Research a topic
- Summarize a document
- Extract data from text
- Answer questions
### 2. Creation Tasks
These tasks involve generating new content.
**Examples:**
- Write an article
- Create a marketing plan
- Generate images (with appropriate tools)
- Design a workflow
### 3. Analysis Tasks
These tasks involve evaluating information and drawing conclusions.
**Examples:**
- Analyze data trends
- Review content for quality
- Evaluate options
- Identify patterns
### 4. Interaction Tasks
These tasks involve communicating or working with users or other systems.
**Examples:**
- Answer customer questions
- Guide users through processes
- Collect information from users
- Notify about events
## Creating Tasks in PraisonAI
### Task Flow
The typical lifecycle of a task follows this pattern:
```mermaid
graph LR
A[Define Task] --> B[Assign to Agent]
B --> C[Execute Task]
C --> D[Return Results]
D --> E[Evaluate Success]
```
### Task Configuration
<CodeGroup>
```python Basic
task = Task(
description="Research AI trends",
expected_output="Summary report",
agent=research_agent
)
```
```python Advanced
task = Task(
description="Analyze market data",
expected_output="Detailed analysis",
agent=analyst_agent,
tools=[AnalysisTool()],
output_file="analysis.md",
async_execution=True
)
```
</CodeGroup>
# Understanding Tasks
<br />
```mermaid
graph LR
%% Task Flow Steps
Start([▶ Start]) --> TaskDef
TaskDef --> AgentAssign
AgentAssign --> Exec
Exec --> Output([✓ Output])
%% Define subgraphs for each step
subgraph TaskDef[" "]
TD_Icon[📋 Task Definition]
TD_Desc[Description & Requirements]
TD_Icon --- TD_Desc
style TD_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style TD_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph AgentAssign[" "]
AA_Icon[🤖 Agent Assignment]
AA_Desc[Matching & Delegation]
AA_Icon --- AA_Desc
style AA_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style AA_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
subgraph Exec[" "]
E_Icon[⚙️ Execution]
E_Desc[Processing & Tools]
E_Icon --- E_Desc
style E_Icon fill:#2D3047,stroke:#7C90A0,color:#fff
style E_Desc fill:#5C80BC,stroke:#7C90A0,color:#fff
end
%% Styling for main elements
style Start fill:#2D3047,stroke:#7C90A0,color:#fff
style Output fill:#2D3047,stroke:#7C90A0,color:#fff
%% Style for containers
style TaskDef fill:#1B1F3B,stroke:#7C90A0,color:#fff
style AgentAssign fill:#1B1F3B,stroke:#7C90A0,color:#fff
style Exec fill:#1B1F3B,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
<br /><br />
```mermaid
graph LR
%% Task States
Pending([📥 Pending]) --> InProgress([⚡ In Progress])
InProgress --> Completed([✅ Completed])
InProgress --> Failed([❌ Failed])
%% Styling
style Pending fill:#2D3047,stroke:#7C90A0,color:#fff
style InProgress fill:#5C80BC,stroke:#7C90A0,color:#fff
style Completed fill:#2D3047,stroke:#7C90A0,color:#fff
style Failed fill:#2D3047,stroke:#7C90A0,color:#fff
%% Global styles
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
linkStyle default stroke:#7C90A0,stroke-width:2px
```
## Task Types
<Steps>
<Step title="Basic Task">
Simple, single-operation tasks with clear inputs and outputs
</Step>
<Step title="Decision Task">
Tasks involving choices and conditional paths
```python
decision_task = Task(
type="decision",
conditions={
"success": ["next_task"],
"failure": ["error_task"]
}
)
```
</Step>
<Step title="Loop Task">
Repetitive operations over collections
```python
loop_task = Task(
type="loop",
items=data_list,
operation="process_item"
)
```
</Step>
</Steps>
## Task Relationships
<Warning>
Properly managing task dependencies is crucial for complex workflows. Always ensure proper context sharing and error handling.
</Warning>
### Context Sharing
```python
task_a = Task(name="research")
task_b = Task(
name="analyze",
context=[task_a] # Uses task_a's output
)
```
## Task Best Practices
<CardGroup cols={2}>
<Card title="Be Specific" icon="magnifying-glass">
Clearly define what the task should accomplish
</Card>
<Card title="One Goal Per Task" icon="check-double">
Each task should focus on a single objective
</Card>
<Card title="Provide Context" icon="circle-info">
Include necessary background information
</Card>
<Card title="Define Success" icon="trophy">
Specify what a successful outcome looks like
</Card>
</CardGroup>
<Tip>
Break complex goals into multiple smaller tasks rather than creating one large, complex task.
</Tip>
## Common Task Mistakes
<CardGroup cols={2}>
<Card title="Vague Instructions" icon="question">
Unclear about what the agent should do
</Card>
<Card title="Too Many Objectives" icon="list-ol">
Asking for too many things in one task
</Card>
<Card title="Missing Context" icon="puzzle-piece-missing">
Not providing necessary background information
</Card>
<Card title="Unrealistic Expectations" icon="mountain-sun">
Asking for tasks beyond agent capabilities
</Card>
</CardGroup>
In the next lesson, we'll learn about creating your first complete agent application.
@@ -1,172 +0,0 @@
---
title: "Creating Your First Agent"
description: "A step-by-step guide to building your first AI agent"
icon: "robot"
---
# Creating Your First Agent
In this lesson, we'll walk through the process of building a simple AI agent. We'll focus on practical implementation without complex programming.
## What We'll Build
We'll create a basic research assistant agent that can:
- Understand simple instructions
- Respond to questions
- Provide helpful information
## Prerequisites
Before you begin, make sure you have:
1. A basic understanding of the concepts from previous lessons
2. Python installed on your computer (if following the code examples)
3. An OpenAI API key (or access to another supported language model)
## Step 1: Installation
First, install the PraisonAI package:
```bash
pip install praisonaiagents
```
## Step 2: Setup Your Environment
Create a file called `first_agent.py` and set up your API key:
```python
import os
from praisonaiagents import Agent
# Set your API key
# Option 1: Set it in your environment (recommended)
# export OPENAI_API_KEY=your_key_here
# Option 2: Set it in your code (not recommended for production)
# os.environ["OPENAI_API_KEY"] = "your_key_here"
```
## Step 3: Define Your Agent
Now, let's create a simple agent:
```python
# Create a research assistant agent
research_assistant = Agent(
name="ResearchAssistant",
instructions="""
You are a helpful research assistant that provides clear,
accurate information on various topics. When answering:
1. Be concise and to the point
2. Explain complex concepts in simple terms
3. When appropriate, organize information with bullet points
4. If you don't know something, admit it instead of guessing
"""
)
```
## Step 4: Start Your Agent
Now let's use our agent to answer a question:
```python
# Start the agent with a specific query
response = research_assistant.start("Explain how solar panels work in simple terms")
# Print the response
print(response)
```
## Step 5: Run Your Agent
Save the file and run it from your terminal:
```bash
python first_agent.py
```
You should see the agent's response explaining how solar panels work in simple terms.
## Experimenting with Your Agent
Try changing the question to see how your agent responds to different topics:
```python
# Try different questions
response = research_assistant.start("What are the benefits of exercise?")
# or
response = research_assistant.start("How does artificial intelligence work?")
```
## Modifying Agent Behavior
You can change how your agent behaves by adjusting its instructions:
```python
# Create an agent with different instructions
creative_writer = Agent(
name="CreativeWriter",
instructions="""
You are a creative writer that specializes in short, engaging stories.
Your writing should:
1. Include vivid descriptions
2. Have interesting characters
3. Include some dialogue
4. Have a clear beginning, middle, and end
"""
)
# Ask for a story
story = creative_writer.start("Write a short story about a lost dog finding its way home")
print(story)
```
## Examining How It Works
What's happening behind the scenes:
1. The agent receives your instructions and query
2. The language model (like GPT-4) processes the information
3. The model generates a response based on the instructions and query
4. The response is returned to you
```mermaid
graph TD
A[Your Instructions] --> B[Agent]
C[Your Query] --> B
B --> D[Language Model]
D --> E[Generated Response]
E --> F[Output to You]
```
## Common Challenges
If you encounter issues, check these common problems:
<CardGroup cols={2}>
<Card title="API Key Issues" icon="key">
Make sure your API key is set correctly
</Card>
<Card title="Connection Problems" icon="wifi">
Check your internet connection
</Card>
<Card title="Unclear Instructions" icon="circle-question">
Try making your instructions more specific
</Card>
<Card title="Rate Limits" icon="hand">
You might be making too many API calls
</Card>
</CardGroup>
## Next Steps
Now that you've created your first agent, you can:
- Experiment with different instructions
- Try more complex queries
- Add specialized capabilities (we'll cover this in upcoming lessons)
- Create agents for specific use cases
Congratulations on creating your first AI agent! In the next lesson, we'll explore how to add tools to enhance your agent's capabilities.
@@ -1,275 +0,0 @@
---
title: "Adding Tools to Agents"
description: "Enhancing your agents with specialized capabilities"
icon: "screwdriver-wrench"
---
# Adding Tools to Agents
In this lesson, we'll learn how to enhance your agents by adding tools. Tools allow agents to perform specific actions beyond just generating text, making them much more useful for real-world tasks.
## What You'll Learn
By the end of this lesson, you'll understand:
- What agent tools are and why they're useful
- How to create simple tools for your agents
- How to integrate tools with your agents
- Best practices for tool design
## Understanding Agent Tools
Tools give your agents the ability to:
- Perform calculations
- Access specific information
- Interact with external systems
- Generate different types of content
<Tabs>
<Tab title="Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package:
```bash Terminal
pip install praisonaiagents duckduckgo-search
```
</Step>
<Step title="Configure Environment">
```bash Terminal
export OPENAI_API_KEY=your_openai_key
```
Generate your OpenAI API key from [OpenAI](https://platform.openai.com/api-keys)
Use other LLM providers like Ollama, Anthropic, Groq, Google, etc. Please refer to the [Models](/models) for more information.
</Step>
<Step title="Create Agent with Tool">
Create `app.py`
<CodeGroup>
```python Single Agent
from praisonaiagents import Agent
from duckduckgo_search import DDGS
# 1. Define the tool
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Assign the tool to an agent
search_agent = Agent(
instructions="Perform internet searches to collect relevant information.",
tools=[internet_search_tool] # <--- Tool Assignment
)
# 3. Start Agent
search_agent.start("Search about AI job trends in 2025")
```
```python Multiple Agents
from praisonaiagents import Agent, PraisonAIAgents
from duckduckgo_search import DDGS
# 1. Define the tool
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
# 2. Assign the tool to an agent
search_agent = Agent(
instructions="Search about AI job trends in 2025",
tools=[internet_search_tool] # <--- Tool Assignment
)
blog_agent = Agent(
instructions="Write a blog article based on the previous agent's search results."
)
# 3. Start Agents
agents = PraisonAIAgents(agents=[search_agent, blog_agent])
agents.start()
```
</CodeGroup>
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
python app.py
```
</Step>
</Steps>
</Tab>
<Tab title="No Code">
<Steps>
<Step title="Install PraisonAI">
Install the core package and duckduckgo_search package:
```bash Terminal
pip install praisonai duckduckgo_search
```
</Step>
<Step title="Create Custom Tool">
<Info>
To add additional tools/features you need some coding which can be generated using ChatGPT or any LLM
</Info>
Create a new file `tools.py` with the following content:
```python
from duckduckgo_search import DDGS
from typing import List, Dict
# 1. Tool
def internet_search_tool(query: str) -> List[Dict]:
"""
Perform Internet Search
"""
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step title="Create Agent">
Create a new file `agents.yaml` with the following content:
```yaml
framework: praisonai
topic: create movie script about cat in mars
roles:
scriptwriter:
backstory: Expert in dialogue and script structure, translating concepts into
scripts.
goal: Write a movie script about a cat in Mars
role: Scriptwriter
tools:
- internet_search_tool # <-- Tool assigned to Agent here
tasks:
scriptwriting_task:
description: Turn the story concept into a production-ready movie script,
including dialogue and scene details.
expected_output: Final movie script with dialogue and scene details.
```
</Step>
<Step title="Start Agents">
Execute your script:
```bash Terminal
praisonai agents.yaml
```
</Step>
</Steps>
</Tab>
</Tabs>
## Creating Custom Tool
<Steps>
<Step>
Create any function that you want to use as a tool, that performs a specific task.
```python
from duckduckgo_search import DDGS
def internet_search_tool(query: str):
results = []
ddgs = DDGS()
for result in ddgs.text(keywords=query, max_results=5):
results.append({
"title": result.get("title", ""),
"url": result.get("href", ""),
"snippet": result.get("body", "")
})
return results
```
</Step>
<Step>
Assign the tool to an agent
```python
data_agent = Agent(
instructions="Search about AI job trends in 2025",
tools=[internet_search_tool], # <-- Tool Assignment
)
```
</Step>
</Steps>
<Card title="That's it!">
<Check>You have created a custom tool and assigned it to an agent.</Check>
</Card>
## When Does the Agent Use Tools?
The agent decides when to use tools based on:
1. The nature of the user's request
2. The tools available to it
3. The instructions you've provided
If your agent isn't using tools when expected, you might need to:
- Make your instructions more explicit about when to use tools
- Provide more descriptive tool definitions
- Ensure the tools are appropriate for the task
## Tool Best Practices
<CardGroup cols={2}>
<Card title="Specific Purpose" icon="bullseye">
Each tool should have a clear, specific purpose
</Card>
<Card title="Error Handling" icon="shield-check">
Tools should handle errors gracefully
</Card>
<Card title="Descriptive Names" icon="tag">
Use clear names that indicate functionality
</Card>
<Card title="Clear Documentation" icon="file-lines">
Include detailed descriptions and examples
</Card>
</CardGroup>
## Real-World Tool Examples
In production systems, you might create tools for:
<CardGroup cols={2}>
<Card title="Database Access" icon="database">
Retrieve or store information in databases
</Card>
<Card title="API Integration" icon="link">
Connect to external services
</Card>
<Card title="File Operations" icon="folder">
Read from or write to files
</Card>
<Card title="Image Generation" icon="image">
Create images based on descriptions
</Card>
</CardGroup>
## Advanced Tool Concepts
As you become more comfortable with tools, you can explore:
- Tools that call other tools
- Tools with complex parameters
- Tools that maintain state
- Dynamically generated tools
In the next lesson, we'll explore how to create a multi-agent system for more complex tasks.
@@ -1,218 +0,0 @@
---
title: "Building a Multi-Agent System"
description: "Creating a system with multiple cooperative agents"
icon: "users"
---
# Building a Multi-Agent System
In this lesson, we'll create a simple multi-agent system where several agents work together to accomplish a task. This approach allows you to divide complex problems into smaller, more manageable pieces.
## What We'll Build
We'll create a content creation system with three specialized agents:
1. A research agent to gather information
2. A writing agent to create content
3. An editing agent to improve and refine the content
## Step 1: Setting Up
First, let's import the necessary modules and set up our environment:
```python
from praisonaiagents import Agent, PraisonAIAgents
# Make sure your API key is set in your environment:
# export OPENAI_API_KEY=your_openai_key
```
## Step 2: Creating Specialized Agents
Now, let's create our three specialized agents:
```python
# Research Agent
research_agent = Agent(
name="Researcher",
instructions="""
You are a research specialist who excels at finding relevant information.
Your job is to:
1. Thoroughly research the given topic
2. Identify key facts, statistics, and insights
3. Organize the information in a clear, structured format
4. Provide accurate information with no fabrications
5. Focus on the most relevant and current information
"""
)
# Writing Agent
writing_agent = Agent(
name="Writer",
instructions="""
You are a content writer who creates engaging, reader-friendly content.
Your job is to:
1. Use the research provided to create well-structured content
2. Write in a clear, engaging style
3. Include an attention-grabbing introduction
4. Organize the content with appropriate headings
5. Conclude with a summary and call-to-action when appropriate
"""
)
# Editing Agent
editing_agent = Agent(
name="Editor",
instructions="""
You are an editor who refines and improves content.
Your job is to:
1. Correct any grammatical or spelling errors
2. Improve clarity and flow
3. Ensure consistency in tone and style
4. Check for logical structure and organization
5. Enhance readability for the target audience
"""
)
```
## Step 3: Creating the Multi-Agent System
Now, let's combine these agents into a multi-agent system:
```python
# Create a multi-agent system
content_team = PraisonAIAgents(
agents=[research_agent, writing_agent, editing_agent]
)
```
## Step 4: Setting Up the Workflow
Next, we need to define how our agents will work together:
```python
# Define a topic
topic = "The Benefits of Regular Exercise"
# Start the multi-agent process
results = content_team.start(
f"""
Task: Create a comprehensive blog post about {topic}
Process:
1. Researcher: Research {topic} and provide key information including:
- Main benefits of exercise (physical and mental)
- Recommended exercise guidelines
- Scientific studies supporting the benefits
- Common misconceptions
2. Writer: Use the research to create a 500-word blog post about {topic} with:
- An engaging introduction
- Clear sections with headings
- Practical advice for readers
- A compelling conclusion
3. Editor: Review and improve the blog post by:
- Correcting any errors
- Enhancing clarity and flow
- Ensuring a consistent tone
- Making the content more engaging
"""
)
# Print the final result
print(results)
```
## Understanding the Workflow
Let's examine how the multi-agent system works:
```mermaid
graph TD
A[Start] --> B[Research Agent]
B --> C[Writing Agent]
C --> D[Editing Agent]
D --> E[Final Output]
```
1. The research agent gathers and organizes relevant information
2. The writing agent uses that research to create the initial content
3. The editing agent refines and improves the content
4. The final polished content is returned
## Customizing Agent Interactions
You can customize how agents interact by modifying the process instructions. For example, you could add feedback loops:
```python
process_with_feedback = """
Task: Create a comprehensive blog post about {topic}
Process:
1. Researcher: Research {topic} and provide key information
2. Writer: Use the research to create a blog post
3. Editor: Review the blog post and provide feedback
4. Writer: Revise the blog post based on the editor's feedback
5. Editor: Make final improvements to the revised blog post
"""
```
## Alternative Agent Configurations
You can organize multi-agent systems in different ways:
### Parallel Processing
```python
parallel_process = """
Task: Create a marketing campaign for a new product
Process:
1. Market Researcher: Research the target market and competitors
Content Researcher: Research the product features and benefits
[These tasks happen in parallel]
2. Strategy Agent: Use both research results to create a marketing strategy
3. Content Creator: Create the marketing materials based on the strategy
"""
```
### Expert Panel
```python
expert_panel = """
Task: Evaluate a business idea
Process:
1. Financial Expert: Analyze financial viability
Market Expert: Analyze market potential
Technical Expert: Analyze technical feasibility
[These assessments happen in parallel]
2. Coordinator: Compile all expert opinions into a final recommendation
"""
```
## Best Practices for Multi-Agent Systems
<CardGroup cols={2}>
<Card title="Clear Role Definition" icon="user-tag">
Define exactly what each agent is responsible for
</Card>
<Card title="Explicit Handoffs" icon="arrow-right-arrow-left">
Specify how information passes between agents
</Card>
<Card title="Avoid Redundancy" icon="copy">
Don't have multiple agents do the same work
</Card>
<Card title="Include Error Handling" icon="triangle-exclamation">
Plan for cases where an agent might fail
</Card>
</CardGroup>
In the next lesson, we'll learn how to create a conversational agent that can maintain context across multiple interactions.
@@ -1,193 +0,0 @@
---
title: "Building Conversational Agents"
description: "Creating agents that maintain context in conversations"
icon: "comments"
---
# Building Conversational Agents
In this lesson, we'll learn how to create conversational agents that can maintain context across multiple interactions. This is essential for creating assistants that feel natural to interact with.
## What Makes a Good Conversational Agent?
A good conversational agent should:
- Remember previous parts of the conversation
- Understand context and references
- Provide coherent, relevant responses
- Maintain a consistent personality
## Creating a Simple Conversational Agent
Let's build a basic conversational agent:
```python
# Note: TODO: This Feature yet to be developed
from praisonaiagents import Agent
# Create a conversational agent
chat_agent = Agent(
name="Conversational Assistant",
instructions="""
You are a friendly, helpful conversational assistant.
When chatting with users:
1. Maintain a warm, friendly tone
2. Remember information shared earlier in the conversation
3. Ask clarifying questions when needed
4. Keep responses concise but informative
5. Be helpful while respecting boundaries
"""
)
# Start a conversation
response = chat_agent.start("Hi there! My name is Jamie.")
print(response)
# Continue the conversation
response = chat_agent.continue("What can you help me with today?")
print(response)
# The agent should remember the user's name
response = chat_agent.continue("Can you remember my name?")
print(response)
```
## How Context Works
PraisonAI automatically manages conversation context for you:
```mermaid
graph TD
A[User Message 1] --> B[Agent]
B --> C[Response 1]
D[User Message 2] --> E[Agent + Context]
E --> F[Response 2]
G[User Message 3] --> H[Agent + More Context]
H --> I[Response 3]
```
The agent maintains a memory of the conversation, allowing it to refer back to previous messages.
## Conversation Settings
You can customize how your conversational agent behaves:
```python
# Create an agent with specific conversation settings
custom_chat_agent = Agent(
name="Custom Chat Assistant",
instructions="You are a helpful assistant",
memory_size=10, # Remember the last 10 messages
temperature=0.7 # Slightly more creative in responses
)
```
## Handling Different Types of Conversations
Different use cases require different conversation styles:
<CardGroup cols={2}>
<Card title="Customer Support" icon="headset">
- Professional and helpful tone
- Focus on problem resolution
- Remember customer details
</Card>
<Card title="Educational Tutor" icon="graduation-cap">
- Patient and explanatory
- Builds on previous lessons
- Adjusts to learning pace
</Card>
<Card title="Personal Assistant" icon="calendar">
- Remembers preferences
- Provides reminders
- Handles scheduling
</Card>
<Card title="Companion Chat" icon="user-group">
- More casual tone
- Focuses on engagement
- Shows personality
</Card>
</CardGroup>
## Example: Customer Support Agent
Let's create a specialized customer support agent:
```python
support_agent = Agent(
name="Support Agent",
instructions="""
You are a customer support specialist for a tech company.
When helping customers:
1. Greet them professionally
2. Show empathy for their issues
3. Ask for necessary information to troubleshoot
4. Provide clear step-by-step solutions
5. Confirm if the issue is resolved
6. End with an offer for additional help
Remember product details and customer information throughout the conversation.
"""
)
# Example conversation
print(support_agent.start("Hi, I'm having trouble logging into my account."))
print(support_agent.continue("My username is user123."))
print(support_agent.continue("I've tried resetting my password but I'm not receiving the email."))
```
## Building Multi-Turn Conversations
To create engaging multi-turn conversations, consider:
1. **Appropriate follow-up questions**: Keep the conversation flowing
2. **Acknowledgment**: Reference what the user has said
3. **Progressive disclosure**: Don't overwhelm with information at once
4. **Conversation repair**: Gracefully handle misunderstandings
## Example: Multi-Turn Educational Conversation
```python
tutor_agent = Agent(
name="Math Tutor",
instructions="""
You are a patient, encouraging math tutor.
When teaching:
1. Gauge the student's current understanding
2. Explain concepts using clear, simple language
3. Provide examples to illustrate points
4. Ask questions to check understanding
5. Give positive reinforcement for progress
Adapt your explanations based on the student's responses.
"""
)
# Example tutoring session
print(tutor_agent.start("Can you help me understand algebra?"))
print(tutor_agent.continue("I'm struggling with equations like 2x + 5 = 13"))
print(tutor_agent.continue("So I subtract 5 from both sides first?"))
print(tutor_agent.continue("Then I divide by 2 to get x = 4?"))
print(tutor_agent.continue("Could you give me another example to practice?"))
```
## Conversation Best Practices
<CardGroup cols={2}>
<Card title="Clear Transitions" icon="arrow-right">
Signal when changing topics
</Card>
<Card title="Manageable Chunks" icon="layer-group">
Break complex information into smaller pieces
</Card>
<Card title="Engagement Checks" icon="hand">
Periodically confirm understanding
</Card>
<Card title="Personality Consistency" icon="masks-theater">
Maintain a consistent tone and style
</Card>
</CardGroup>
In the next lesson, we'll explore how to build agents that can search and retrieve information from external sources.
-216
View File
@@ -1,216 +0,0 @@
---
title: "Building Research Agents"
description: "Creating agents that can gather and analyze information"
icon: "magnifying-glass"
---
# Building Research Agents
In this lesson, we'll build agents specialized in gathering, analyzing, and summarizing information. Research agents are valuable for quickly obtaining insights on various topics.
## What is a Research Agent?
A research agent is designed to:
- Find relevant information on specific topics
- Analyze and synthesize data
- Present findings in a clear, structured format
- Answer questions based on gathered information
## Creating a Basic Research Agent
Let's start by building a simple research agent:
```python
from praisonaiagents import Agent
# Create a basic research agent
research_agent = Agent(
name="ResearchAgent",
instructions="""
You are a research specialist who finds and summarizes information.
When researching topics:
1. Focus on finding accurate, current information
2. Organize findings in a logical structure
3. Identify key points and insights
4. Cite sources when available
5. Present information in a clear, concise format
"""
)
# Use the research agent
research_results = research_agent.start("Research the impact of renewable energy on reducing carbon emissions")
print(research_results)
```
## Adding Web Search Capability
To make our research agent more powerful, let's add web search capability:
```python
from praisonaiagents import Agent, Tool
# Define a web search function (simulated for this example)
def web_search(query):
"""
Simulated web search function.
In a real application, this would connect to a search API.
Args:
query (str): The search query
Returns:
str: Search results
"""
# This is just a simulation - in a real application, you'd call a search API
if "renewable energy" in query.lower():
return """
Search results for 'renewable energy carbon emissions':
1. According to the IEA, renewable energy prevented 2.1 billion tonnes of CO2 emissions in 2022.
2. Solar and wind power generate electricity with 95-98% lower carbon emissions than coal-based electricity.
3. The IPCC reports that renewable energy could deliver more than half of the emission reductions needed by 2030.
"""
else:
return f"Search results for '{query}' (simulated data)"
# Create the web search tool
search_tool = Tool(
name="web_search",
function=web_search,
description="Search the web for current information on a topic"
)
# Create a research agent with web search capability
enhanced_research_agent = Agent(
name="EnhancedResearchAgent",
instructions="""
You are a research specialist who finds and summarizes information.
When researching topics:
1. Use the web_search tool to find current information
2. Analyze and synthesize the search results
3. Organize findings in a logical structure
4. Identify key points and insights
5. Present information in a clear, concise format
""",
tools=[search_tool]
)
# Use the enhanced research agent
enhanced_results = enhanced_research_agent.start("What is the impact of renewable energy on carbon emissions?")
print(enhanced_results)
```
## Research Agent with Structured Output
For more organized research results, we can instruct the agent to provide structured output:
```python
structured_research_agent = Agent(
name="StructuredResearchAgent",
instructions="""
You are a research specialist who finds and organizes information.
When researching topics:
1. Use available tools to find current information
2. Analyze and synthesize the findings
Always structure your response in this format:
## Summary
[Brief 2-3 sentence overview of the topic]
## Key Facts
- [Important fact 1]
- [Important fact 2]
- [Important fact 3]
## Analysis
[Deeper analysis of the information, including implications]
## Sources
[List of sources if available]
""",
tools=[search_tool]
)
# Use the structured research agent
structured_results = structured_research_agent.start("Research the latest advancements in quantum computing")
print(structured_results)
```
## Specialized Research Agents
Different research tasks require different approaches. Here are some specialized research agents:
### Comparison Research Agent
```python
comparison_agent = Agent(
name="ComparisonAgent",
instructions="""
You are a research specialist who compares different options or topics.
When comparing items:
1. Identify the key criteria for comparison
2. Research each option thoroughly
3. Create a clear side-by-side comparison
4. Highlight advantages and disadvantages of each option
5. Provide a balanced conclusion
Present your findings in a structured table format when appropriate.
""",
tools=[search_tool]
)
# Use the comparison agent
comparison_results = comparison_agent.start("Compare solar and wind energy for residential use")
print(comparison_results)
```
### Literature Review Agent
```python
literature_agent = Agent(
name="LiteratureAgent",
instructions="""
You are a research specialist who reviews academic and professional literature.
When reviewing literature:
1. Identify key papers, articles, and studies on the topic
2. Summarize the main findings and methodologies
3. Identify trends, agreements, and contradictions
4. Evaluate the strength of evidence
5. Highlight gaps in current research
Structure your review in a clear, academic format.
""",
tools=[search_tool]
)
# Use the literature review agent
literature_results = literature_agent.start("Review recent research on artificial intelligence in healthcare")
print(literature_results)
```
## Research Process Best Practices
<CardGroup cols={2}>
<Card title="Define Scope" icon="bullseye">
Set clear boundaries for the research
</Card>
<Card title="Verify Information" icon="check-double">
Cross-check facts from multiple sources
</Card>
<Card title="Consider Bias" icon="scale-balanced">
Be aware of potential biases in sources
</Card>
<Card title="Prioritize Relevance" icon="filter">
Focus on information most relevant to the query
</Card>
</CardGroup>
In the next lesson, we'll explore how to build agents that can assist with creative tasks like content creation.
@@ -1,252 +0,0 @@
---
title: "Content Creation Agents"
description: "Building agents that generate various types of content"
icon: "pen-to-square"
---
# Content Creation Agents
Content creation agents can help generate various types of content, from blog posts to marketing materials. In this lesson, we'll learn how to build effective content creation agents.
## What is a Content Creation Agent?
A content creation agent is designed to:
- Generate written content based on specific requirements
- Structure content in appropriate formats
- Adapt tone and style to match the target audience
- Create content that achieves specific goals (inform, persuade, entertain)
## Creating a Basic Content Creation Agent
Let's start with a simple content creation agent:
```python
from praisonaiagents import Agent
# Create a basic content creation agent
content_agent = Agent(
name="ContentCreator",
instructions="""
You are a versatile content creator who specializes in writing engaging material.
When creating content:
1. Understand the purpose and target audience
2. Create a logical structure with clear sections
3. Use an engaging, appropriate writing style
4. Include a strong introduction and conclusion
5. Format content for easy readability
"""
)
# Use the content creation agent
blog_post = content_agent.start(
"""
Create a blog post about the benefits of meditation.
Target audience: Busy professionals
Length: Approximately 500 words
Tone: Informative but conversational
"""
)
print(blog_post)
```
## Specialized Content Creation Agents
Different types of content require different approaches. Let's create specialized agents for various content needs:
### Blog Post Agent
```python
blog_agent = Agent(
name="BlogWriter",
instructions="""
You are a blog post writer who creates engaging, informative articles.
When writing blog posts:
1. Create attention-grabbing headlines
2. Start with a compelling introduction
3. Use subheadings to organize content
4. Include relevant examples and evidence
5. Incorporate a clear call-to-action at the end
Format your content with proper Markdown formatting including:
- Headings (## for main sections, ### for subsections)
- Bullet points for lists
- *Italic* for emphasis
- **Bold** for important points
- > Blockquotes for notable quotes
"""
)
# Use the blog agent
blog_content = blog_agent.start(
"""
Topic: 5 Ways to Improve Your Productivity
Target audience: Remote workers
Style: Practical, actionable advice
Length: 800 words
Include: Tips, examples, and research-backed information
"""
)
print(blog_content)
```
### Social Media Content Agent
```python
social_media_agent = Agent(
name="SocialMediaCreator",
instructions="""
You are a social media content creator who crafts engaging posts.
When creating social media content:
1. Create attention-grabbing, concise content
2. Adapt to the specific platform requirements
3. Include relevant hashtags when appropriate
4. Craft content that encourages engagement
5. Consider visual elements that would pair well with the text
For each platform, follow these guidelines:
- Twitter/X: 280 characters max, punchy, relevant hashtags
- LinkedIn: Professional tone, industry insights, 1-3 paragraphs
- Instagram: Visual-focused descriptions, emoji-friendly, hashtags
- Facebook: Conversational, can be longer, question-based engagement
"""
)
# Use the social media agent
social_content = social_media_agent.start(
"""
Create posts for Twitter, LinkedIn, and Facebook announcing:
Event: Free Webinar on "Future of AI in Business"
Date: March 15, 2025
Time: 2:00 PM EST
Registration link: example.com/webinar
Key speakers: Dr. Jane Smith, AI Ethics Expert & Tom Johnson, Business AI Implementation Specialist
"""
)
print(social_content)
```
### Email Campaign Agent
```python
email_agent = Agent(
name="EmailWriter",
instructions="""
You are an email marketing specialist who creates effective email campaigns.
When writing marketing emails:
1. Create compelling subject lines that increase open rates
2. Write engaging opening lines that hook the reader
3. Keep content concise and focused on a single main message
4. Include clear calls-to-action
5. Use a tone appropriate for the brand and audience
Structure your emails with:
- Subject line
- Greeting
- Opening hook
- Main content (2-3 paragraphs maximum)
- Call-to-action
- Sign-off
"""
)
# Use the email agent
email_content = email_agent.start(
"""
Create a promotional email for:
Product: Premium Fitness Subscription
Key benefit: Personalized workout plans and nutrition advice
Special offer: 30% off first 3 months
Target audience: Health-conscious professionals aged 25-45
CTA: Sign up for the discounted offer
Tone: Motivational but not aggressive
"""
)
print(email_content)
```
## Content Creation with Templates
Templates can help create more consistent content. Let's build an agent that works with templates:
```python
template_agent = Agent(
name="TemplateWriter",
instructions="""
You are a content creator who works with templates to create consistent content.
When filling a template:
1. Maintain the overall structure of the template
2. Replace placeholder text with appropriate content
3. Ensure consistency in tone and style
4. Adapt content to the specific requirements
5. Review for coherence and flow
Always preserve formatting elements like headings, lists, and emphasis.
"""
)
# Example template
product_review_template = """
# {Product Name} Review: {Brief Opinion}
## Quick Summary
**Rating:** {Rating}/10
**Price:** {Price Range}
**Recommended For:** {Target User}
## What We Liked
- {Positive Point 1}
- {Positive Point 2}
- {Positive Point 3}
## What Could Be Better
- {Negative Point 1}
- {Negative Point 2}
## Bottom Line
{Conclusion Paragraph}
"""
# Use the template agent
filled_template = template_agent.start(
f"""
Fill the following template for a product review:
{product_review_template}
Product: Wireless Noise-Cancelling Headphones XZ200
Key features: 30-hour battery life, active noise cancellation, voice assistant integration
Price: $249.99
Target audience: Commuters and office workers
Notable pros: Sound quality, comfort, battery life
Notable cons: Price, occasional Bluetooth connectivity issues
"""
)
print(filled_template)
```
## Content Creation Best Practices
<CardGroup cols={2}>
<Card title="Know Your Audience" icon="users">
Understand who will consume the content
</Card>
<Card title="Clear Purpose" icon="bullseye">
Define what the content should achieve
</Card>
<Card title="Consistent Voice" icon="comment">
Maintain a consistent tone and style
</Card>
<Card title="Readability" icon="eye">
Make content easy to scan and understand
</Card>
</CardGroup>
In the next lesson, we'll explore how to build AI agents that can analyze and work with data.
Loaded 100 of 1022 files, more files were not shown because too many files have changed in this diff. Show more