mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 12:47:55 -10:00
Compare commits
No files matched your search
@@ -11,6 +11,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
@@ -10,6 +10,7 @@ jobs:
|
||||
test:
|
||||
name: Run tests and collect coverage
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
||||
@@ -26,6 +26,7 @@ on:
|
||||
jobs:
|
||||
comprehensive-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.11"]
|
||||
|
||||
@@ -9,6 +9,7 @@ on:
|
||||
jobs:
|
||||
test-core:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.11]
|
||||
|
||||
@@ -13,6 +13,7 @@ on:
|
||||
jobs:
|
||||
test-examples:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -43,6 +44,9 @@ jobs:
|
||||
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
|
||||
echo "PRAISONAI_TELEMETRY_DISABLED=true" >> $GITHUB_ENV
|
||||
echo "PRAISONAI_DISABLE_TELEMETRY=true" >> $GITHUB_ENV
|
||||
echo "DO_NOT_TRACK=true" >> $GITHUB_ENV
|
||||
|
||||
- name: Test Key Example Scripts
|
||||
run: |
|
||||
@@ -73,6 +77,7 @@ jobs:
|
||||
|
||||
performance-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
@@ -97,6 +102,12 @@ jobs:
|
||||
# Install knowledge dependencies from praisonai-agents
|
||||
uv pip install --system "praisonaiagents[knowledge]"
|
||||
|
||||
- name: Set environment variables
|
||||
run: |
|
||||
echo "PRAISONAI_TELEMETRY_DISABLED=true" >> $GITHUB_ENV
|
||||
echo "PRAISONAI_DISABLE_TELEMETRY=true" >> $GITHUB_ENV
|
||||
echo "DO_NOT_TRACK=true" >> $GITHUB_ENV
|
||||
|
||||
- name: Run Performance Benchmarks
|
||||
run: |
|
||||
echo "🏃 Running performance benchmarks..."
|
||||
@@ -161,4 +172,4 @@ jobs:
|
||||
with:
|
||||
name: performance-report
|
||||
path: performance_report.md
|
||||
retention-days: 30
|
||||
retention-days: 5
|
||||
@@ -24,6 +24,7 @@ on:
|
||||
jobs:
|
||||
framework-tests:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.11]
|
||||
|
||||
@@ -26,6 +26,7 @@ jobs:
|
||||
real-tests:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.inputs.confirm_costs == 'true' && github.event.inputs.framework != 'none' }}
|
||||
timeout-minutes: 15
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
|
||||
@@ -5,6 +5,7 @@ on: [push, pull_request]
|
||||
jobs:
|
||||
quick-test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
flask \
|
||||
"praisonai>=2.2.69" \
|
||||
"praisonai>=2.2.77" \
|
||||
"praisonai[api]" \
|
||||
gunicorn \
|
||||
markdown
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.69" \
|
||||
"praisonai>=2.2.77" \
|
||||
"praisonai[chat]" \
|
||||
"embedchain[github,youtube]"
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.69" \
|
||||
"praisonai>=2.2.77" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[chat]" \
|
||||
"praisonai[realtime]" \
|
||||
|
||||
@@ -16,7 +16,7 @@ RUN mkdir -p /root/.praison
|
||||
# Install Python packages (using latest versions)
|
||||
RUN pip install --no-cache-dir \
|
||||
praisonai_tools \
|
||||
"praisonai>=2.2.69" \
|
||||
"praisonai>=2.2.77" \
|
||||
"praisonai[ui]" \
|
||||
"praisonai[crewai]"
|
||||
|
||||
|
||||
+2
-2
@@ -121,7 +121,7 @@ healthcheck:
|
||||
## 📦 Package Versions
|
||||
|
||||
All Docker images use consistent, up-to-date versions:
|
||||
- PraisonAI: `>=2.2.69`
|
||||
- PraisonAI: `>=2.2.77`
|
||||
- PraisonAI Agents: `>=0.0.92`
|
||||
- Python: `3.11-slim`
|
||||
|
||||
@@ -218,7 +218,7 @@ docker-compose up -d
|
||||
### Version Pinning
|
||||
To use specific versions, update the Dockerfile:
|
||||
```dockerfile
|
||||
RUN pip install "praisonai==2.2.69" "praisonaiagents==0.0.92"
|
||||
RUN pip install "praisonai==2.2.77" "praisonaiagents==0.0.92"
|
||||
```
|
||||
|
||||
## 🌐 Production Deployment
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Context Agent Example - Basic Usage
|
||||
|
||||
This example demonstrates how to use the ContextAgent for automated context generation.
|
||||
The ContextAgent implements Context Engineering principles to generate comprehensive
|
||||
context for AI coding assistants, enabling first-try implementation success.
|
||||
|
||||
Key features demonstrated:
|
||||
- Basic ContextAgent instantiation
|
||||
- Codebase pattern analysis
|
||||
- Context document generation
|
||||
- Validation loop creation
|
||||
- Prompt enhancement with context
|
||||
- PRP (Product Requirements Prompt) generation
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add the src directory to Python path for imports
|
||||
project_root = Path(__file__).parent.parent.parent.parent / "src" / "praisonai-agents"
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from praisonaiagents import create_context_agent
|
||||
|
||||
def demonstrate_basic_context_generation():
|
||||
"""Demonstrate basic context generation capabilities."""
|
||||
print("🔧 Context Engineering Example: Basic Usage")
|
||||
print("=" * 60)
|
||||
|
||||
# Create a ContextAgent using the factory function
|
||||
context_agent = create_context_agent(
|
||||
llm="gpt-4o-mini",
|
||||
name="Basic Context Engineer",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Example 1: Analyze codebase patterns
|
||||
print("\n📁 Example 1: Analyzing Codebase Patterns")
|
||||
print("-" * 40)
|
||||
|
||||
# Use current project as example (adjust path as needed)
|
||||
project_path = str(project_root)
|
||||
analysis = context_agent.analyze_codebase_patterns(
|
||||
project_path=project_path,
|
||||
file_patterns=["*.py"]
|
||||
)
|
||||
|
||||
print(f"✅ Analyzed project at: {project_path}")
|
||||
print(f" Project structure: {len(analysis.get('project_structure', {}).get('directories', []))} directories")
|
||||
print(f" Code patterns identified: {len(analysis.get('code_patterns', {}))}")
|
||||
print(f" Architecture: {analysis.get('architecture_insights', {}).get('primary_pattern', 'Unknown')}")
|
||||
|
||||
# Example 2: Generate context document
|
||||
print("\n📄 Example 2: Generating Context Document")
|
||||
print("-" * 40)
|
||||
|
||||
feature_request = "Add user authentication system with JWT tokens and role-based access control"
|
||||
context_doc = context_agent.generate_context_document(
|
||||
project_path=project_path,
|
||||
requirements=feature_request,
|
||||
analysis=analysis
|
||||
)
|
||||
|
||||
print(f"✅ Generated context document for: {feature_request}")
|
||||
print(f" Document length: {len(context_doc)} characters")
|
||||
print(f" Contains architecture patterns: {'Architecture Patterns' in context_doc}")
|
||||
print(f" Contains validation criteria: {'Validation Criteria' in context_doc}")
|
||||
|
||||
# Example 3: Create validation loop
|
||||
print("\n✅ Example 3: Creating Validation Loop")
|
||||
print("-" * 40)
|
||||
|
||||
success_criteria = [
|
||||
"Authentication system accepts valid JWT tokens",
|
||||
"Role-based access control blocks unauthorized users",
|
||||
"User registration and login endpoints work correctly",
|
||||
"Password hashing follows security best practices",
|
||||
"Session management handles token expiration"
|
||||
]
|
||||
|
||||
validation_config = context_agent.create_validation_loop(
|
||||
implementation_requirements=feature_request,
|
||||
success_criteria=success_criteria
|
||||
)
|
||||
|
||||
print(f"✅ Created validation loop with {len(validation_config['validation_steps'])} steps")
|
||||
print(f" Success criteria: {len(success_criteria)}")
|
||||
print(f" Executable tests: {len(validation_config['executable_tests'])}")
|
||||
print(f" Quality gates: {len(validation_config['quality_gates'])}")
|
||||
|
||||
# Example 4: Enhance prompt with context
|
||||
print("\n🚀 Example 4: Enhancing Prompt with Context")
|
||||
print("-" * 40)
|
||||
|
||||
basic_prompt = "Implement user authentication"
|
||||
enhanced_prompt = context_agent.enhance_prompt_with_context(
|
||||
base_prompt=basic_prompt,
|
||||
context_data=analysis
|
||||
)
|
||||
|
||||
print(f"✅ Enhanced prompt from {len(basic_prompt)} to {len(enhanced_prompt)} characters")
|
||||
print(f" Original: '{basic_prompt}'")
|
||||
print(" Enhanced includes: Context Engineering, Implementation Context, Quality Requirements")
|
||||
|
||||
# Example 5: Generate PRP (Product Requirements Prompt)
|
||||
print("\n📋 Example 5: Generating PRP")
|
||||
print("-" * 40)
|
||||
|
||||
documentation_links = [
|
||||
"https://jwt.io/introduction/",
|
||||
"https://fastapi.tiangolo.com/tutorial/security/",
|
||||
"https://passlib.readthedocs.io/en/stable/"
|
||||
]
|
||||
|
||||
prp = context_agent.generate_prp(
|
||||
feature_request=feature_request,
|
||||
context_analysis=analysis,
|
||||
documentation_links=documentation_links
|
||||
)
|
||||
|
||||
print("✅ Generated comprehensive PRP")
|
||||
print(f" PRP length: {len(prp)} characters")
|
||||
print(f" Contains feature request: {feature_request in prp}")
|
||||
print(f" Contains documentation links: {len(documentation_links)} links included")
|
||||
print(f" Contains implementation blueprint: {'Implementation Blueprint' in prp}")
|
||||
print(f" Confidence score: {'9/10' in prp}")
|
||||
|
||||
def demonstrate_context_agent_as_tool():
|
||||
"""Demonstrate using ContextAgent as a tool in a multi-agent workflow."""
|
||||
print("\n🔗 Context Engineering Example: Multi-Agent Integration")
|
||||
print("=" * 60)
|
||||
|
||||
# Create ContextAgent
|
||||
context_agent = create_context_agent(llm="gpt-4o-mini")
|
||||
|
||||
# Example scenario: Product planning workflow
|
||||
project_path = str(project_root)
|
||||
feature_request = "Build a real-time chat system with WebSocket support"
|
||||
|
||||
# Step 1: Context analysis
|
||||
print("\n1️⃣ Step 1: Context Analysis")
|
||||
analysis = context_agent.analyze_codebase_patterns(project_path)
|
||||
print(f"✅ Analyzed codebase architecture and patterns")
|
||||
|
||||
# Step 2: Generate implementation blueprint
|
||||
print("\n2️⃣ Step 2: Implementation Blueprint")
|
||||
blueprint = context_agent.create_implementation_blueprint(feature_request, analysis)
|
||||
print(f"✅ Created implementation blueprint with {len(blueprint['implementation_steps'])} steps")
|
||||
|
||||
# Step 3: Generate comprehensive PRP
|
||||
print("\n3️⃣ Step 3: Generate PRP")
|
||||
prp = context_agent.generate_prp(feature_request, analysis) # Generated PRP for implementation guidance
|
||||
print(f"✅ Generated PRP for implementation guidance")
|
||||
|
||||
# Step 4: Create validation framework
|
||||
print("\n4️⃣ Step 4: Validation Framework")
|
||||
criteria = [
|
||||
"WebSocket connections establish successfully",
|
||||
"Messages broadcast to all connected clients",
|
||||
"Chat history persists and loads correctly",
|
||||
"User authentication works with WebSocket",
|
||||
"Connection handling is robust with reconnection"
|
||||
]
|
||||
validation = context_agent.create_validation_loop(feature_request, criteria) # Validation framework for QA
|
||||
print(f"✅ Created validation framework with {len(criteria)} criteria")
|
||||
|
||||
print("\n🎯 Context Engineering Workflow Complete!")
|
||||
print(f" Feature: {feature_request}")
|
||||
print(" Implementation ready with comprehensive context")
|
||||
print(" Validation criteria defined for quality assurance")
|
||||
|
||||
def show_context_engineering_benefits():
|
||||
"""Demonstrate the benefits of Context Engineering vs traditional approaches."""
|
||||
print("\n📊 Context Engineering Benefits")
|
||||
print("=" * 60)
|
||||
|
||||
# Traditional prompt engineering approach
|
||||
print("\n❌ Traditional Prompt Engineering:")
|
||||
traditional_prompt = "Create a user authentication system"
|
||||
print(f" Prompt: '{traditional_prompt}'")
|
||||
print(f" Length: {len(traditional_prompt)} characters")
|
||||
print(f" Context: Minimal - relies on AI's general knowledge")
|
||||
print(f" Success Rate: Variable - depends on AI model's training")
|
||||
|
||||
# Context Engineering approach
|
||||
print("\n✅ Context Engineering Approach:")
|
||||
context_agent = create_context_agent(llm="gpt-4o-mini")
|
||||
|
||||
# Generate comprehensive context
|
||||
analysis = context_agent.analyze_codebase_patterns(str(project_root))
|
||||
enhanced_prompt = context_agent.enhance_prompt_with_context(
|
||||
traditional_prompt, analysis
|
||||
)
|
||||
|
||||
print(f" Enhanced Prompt Length: {len(enhanced_prompt)} characters")
|
||||
print(f" Context: Comprehensive - includes:")
|
||||
print(f" • Codebase architecture analysis")
|
||||
print(f" • Existing patterns and conventions")
|
||||
print(f" • Implementation guidance")
|
||||
print(f" • Quality requirements")
|
||||
print(f" • Validation criteria")
|
||||
print(f" Success Rate: Higher - AI has all necessary context")
|
||||
|
||||
print(f"\n🎯 Context Engineering provides:")
|
||||
print(" 📈 10x better than prompt engineering (comprehensive vs clever wording)")
|
||||
print(" 📈 100x better than vibe coding (structured vs ad-hoc)")
|
||||
print(" 🎯 First-try implementation success through complete context")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 PraisonAI Context Engineering Examples")
|
||||
print("=========================================")
|
||||
|
||||
try:
|
||||
# Run all examples
|
||||
demonstrate_basic_context_generation()
|
||||
demonstrate_context_agent_as_tool()
|
||||
show_context_engineering_benefits()
|
||||
|
||||
print("\n🎉 All Context Engineering examples completed successfully!")
|
||||
print("\n💡 Key Takeaways:")
|
||||
print(" • ContextAgent automates comprehensive context generation")
|
||||
print(" • Context Engineering enables first-try implementation success")
|
||||
print(" • Integration with existing PraisonAI agents is seamless")
|
||||
print(" • Validation frameworks ensure quality and completeness")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error running examples: {e}")
|
||||
print(" Make sure you have the PraisonAI package installed and configured")
|
||||
sys.exit(1)
|
||||
@@ -0,0 +1,469 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Context Engineering Workflow - Advanced Multi-Agent Example
|
||||
|
||||
This example demonstrates advanced Context Engineering workflows using ContextAgent
|
||||
in combination with other PraisonAI agents. It shows how Context Engineering can
|
||||
dramatically improve AI implementation success rates through comprehensive context
|
||||
generation and validation loops.
|
||||
|
||||
Workflow demonstrated:
|
||||
1. Product Manager Agent defines requirements
|
||||
2. ContextAgent analyzes codebase and generates comprehensive context
|
||||
3. Architecture Agent designs implementation using context
|
||||
4. Developer Agent implements using context-enhanced prompts
|
||||
5. QA Agent validates using context-generated criteria
|
||||
|
||||
This represents the full Context Engineering methodology in action.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Add the src directory to Python path for imports
|
||||
project_root = Path(__file__).parent.parent.parent.parent / "src" / "praisonai-agents"
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents, create_context_agent
|
||||
|
||||
class ContextEngineeringWorkflow:
|
||||
"""
|
||||
Advanced Context Engineering workflow demonstrating the full methodology.
|
||||
|
||||
This class orchestrates multiple agents using Context Engineering principles
|
||||
to achieve higher success rates in AI-driven development tasks.
|
||||
"""
|
||||
|
||||
def __init__(self, project_path: str, llm: str = "gpt-4o-mini"):
|
||||
self.project_path = project_path
|
||||
self.llm = llm
|
||||
self.context_data = {}
|
||||
self.setup_agents()
|
||||
|
||||
def setup_agents(self):
|
||||
"""Setup the multi-agent team with Context Engineering support."""
|
||||
|
||||
# 1. Product Manager Agent - Defines requirements
|
||||
self.product_manager = Agent(
|
||||
name="Product Manager",
|
||||
role="Product Requirements Specialist",
|
||||
goal="Define clear, comprehensive product requirements and user stories",
|
||||
backstory="""You are an experienced product manager who specializes in
|
||||
creating detailed, actionable requirements. You understand that clear
|
||||
requirements are the foundation of successful implementation.""",
|
||||
instructions="""
|
||||
When defining requirements:
|
||||
1. Be specific and measurable
|
||||
2. Include user acceptance criteria
|
||||
3. Consider edge cases and error scenarios
|
||||
4. Define success metrics
|
||||
5. Specify technical constraints
|
||||
""",
|
||||
llm=self.llm,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# 2. Context Engineering Agent - Generates comprehensive context
|
||||
self.context_engineer = create_context_agent(
|
||||
llm=self.llm,
|
||||
name="Context Engineering Specialist",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# 3. Software Architect Agent - Designs implementation using context
|
||||
self.architect = Agent(
|
||||
name="Software Architect",
|
||||
role="System Architecture Specialist",
|
||||
goal="Design robust, scalable system architecture based on comprehensive context",
|
||||
backstory="""You are a senior software architect with expertise in
|
||||
designing systems that follow established patterns and best practices.
|
||||
You excel at creating architectures that integrate seamlessly with
|
||||
existing codebases.""",
|
||||
instructions="""
|
||||
When designing architecture:
|
||||
1. Follow the patterns identified in the context analysis
|
||||
2. Ensure compatibility with existing systems
|
||||
3. Design for scalability and maintainability
|
||||
4. Consider security and performance implications
|
||||
5. Document architectural decisions and rationale
|
||||
""",
|
||||
llm=self.llm,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# 4. Senior Developer Agent - Implements using context-enhanced guidance
|
||||
self.developer = Agent(
|
||||
name="Senior Developer",
|
||||
role="Implementation Specialist",
|
||||
goal="Implement features following context-guided best practices",
|
||||
backstory="""You are a senior developer who excels at implementing
|
||||
features that follow established codebase patterns. You understand
|
||||
that consistency and quality are paramount.""",
|
||||
instructions="""
|
||||
When implementing features:
|
||||
1. Follow the codebase patterns identified in context analysis
|
||||
2. Maintain consistency with existing code style
|
||||
3. Implement comprehensive error handling
|
||||
4. Write clean, maintainable code
|
||||
5. Follow the implementation blueprint exactly
|
||||
""",
|
||||
llm=self.llm,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# 5. QA Engineer Agent - Validates using context-generated criteria
|
||||
self.qa_engineer = Agent(
|
||||
name="QA Engineer",
|
||||
role="Quality Assurance Specialist",
|
||||
goal="Ensure implementation meets all quality criteria and requirements",
|
||||
backstory="""You are an experienced QA engineer who specializes in
|
||||
comprehensive testing and validation. You understand that quality
|
||||
is built in, not bolted on.""",
|
||||
instructions="""
|
||||
When validating implementations:
|
||||
1. Use the validation criteria from context analysis
|
||||
2. Test both happy path and edge cases
|
||||
3. Verify integration with existing systems
|
||||
4. Check for security vulnerabilities
|
||||
5. Validate performance requirements
|
||||
""",
|
||||
llm=self.llm,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
def run_context_engineering_workflow(self, feature_request: str):
|
||||
"""
|
||||
Execute the complete Context Engineering workflow.
|
||||
|
||||
Args:
|
||||
feature_request (str): The feature to be implemented
|
||||
|
||||
Returns:
|
||||
dict: Complete workflow results with context and implementation
|
||||
"""
|
||||
print(f"🚀 Starting Context Engineering Workflow")
|
||||
print(f"Feature Request: {feature_request}")
|
||||
print("=" * 80)
|
||||
|
||||
# Phase 1: Requirements Analysis
|
||||
print("\n📋 Phase 1: Product Requirements Analysis")
|
||||
print("-" * 50)
|
||||
|
||||
requirements_task = Task(
|
||||
name="requirements_analysis",
|
||||
description=f"""
|
||||
Analyze and refine the feature request: '{feature_request}'
|
||||
|
||||
Create comprehensive requirements including:
|
||||
- Detailed feature description
|
||||
- User acceptance criteria
|
||||
- Technical requirements
|
||||
- Success metrics
|
||||
- Edge cases and constraints
|
||||
""",
|
||||
expected_output="Comprehensive product requirements document",
|
||||
agent=self.product_manager
|
||||
)
|
||||
|
||||
# Phase 2: Context Engineering Analysis
|
||||
print("\n🔧 Phase 2: Context Engineering Analysis")
|
||||
print("-" * 50)
|
||||
|
||||
# Generate comprehensive context using ContextAgent
|
||||
codebase_analysis = self.context_engineer.analyze_codebase_patterns(
|
||||
project_path=self.project_path
|
||||
)
|
||||
|
||||
context_document = self.context_engineer.generate_context_document(
|
||||
project_path=self.project_path,
|
||||
requirements=feature_request,
|
||||
analysis=codebase_analysis
|
||||
)
|
||||
|
||||
validation_framework = self.context_engineer.create_validation_loop(
|
||||
implementation_requirements=feature_request,
|
||||
success_criteria=[
|
||||
"Feature implements all specified requirements",
|
||||
"Code follows existing patterns and conventions",
|
||||
"Implementation includes comprehensive error handling",
|
||||
"All tests pass and coverage meets standards",
|
||||
"Integration with existing systems is seamless"
|
||||
]
|
||||
)
|
||||
|
||||
implementation_blueprint = self.context_engineer.create_implementation_blueprint(
|
||||
feature_request=feature_request,
|
||||
context_analysis=codebase_analysis
|
||||
)
|
||||
|
||||
# Generate PRP for complete context
|
||||
prp = self.context_engineer.generate_prp(
|
||||
feature_request=feature_request,
|
||||
context_analysis=codebase_analysis,
|
||||
documentation_links=[
|
||||
"https://docs.praisonai.com/",
|
||||
"https://pydantic-docs.helpmanual.io/",
|
||||
"https://fastapi.tiangolo.com/"
|
||||
]
|
||||
)
|
||||
|
||||
print(f"✅ Context Engineering Analysis Complete:")
|
||||
print(f" • Codebase analysis: {len(str(codebase_analysis))} chars")
|
||||
print(f" • Context document: {len(context_document)} chars")
|
||||
print(f" • Validation framework: {len(validation_framework['validation_steps'])} steps")
|
||||
print(f" • Implementation blueprint: {len(implementation_blueprint['implementation_steps'])} steps")
|
||||
print(f" • PRP generated: {len(prp)} chars")
|
||||
|
||||
# Store context data for subsequent phases
|
||||
self.context_data = {
|
||||
"codebase_analysis": codebase_analysis,
|
||||
"context_document": context_document,
|
||||
"validation_framework": validation_framework,
|
||||
"implementation_blueprint": implementation_blueprint,
|
||||
"prp": prp
|
||||
}
|
||||
|
||||
# Phase 3: Architecture Design with Context
|
||||
print("\n🏗️ Phase 3: Architecture Design with Context")
|
||||
print("-" * 50)
|
||||
|
||||
architecture_task = Task(
|
||||
name="architecture_design",
|
||||
description=f"""
|
||||
Design system architecture for: '{feature_request}'
|
||||
|
||||
Use the comprehensive context provided:
|
||||
{context_document}
|
||||
|
||||
Implementation Blueprint:
|
||||
{implementation_blueprint}
|
||||
|
||||
Design architecture that:
|
||||
- Follows identified codebase patterns
|
||||
- Integrates with existing systems
|
||||
- Meets all technical requirements
|
||||
- Is scalable and maintainable
|
||||
""",
|
||||
expected_output="Detailed system architecture design with component specifications",
|
||||
agent=self.architect,
|
||||
context=[requirements_task]
|
||||
)
|
||||
|
||||
# Phase 4: Implementation with Context-Enhanced Guidance
|
||||
print("\n💻 Phase 4: Implementation with Context")
|
||||
print("-" * 50)
|
||||
|
||||
# Enhance the implementation prompt with context
|
||||
enhanced_prompt = self.context_engineer.enhance_prompt_with_context(
|
||||
base_prompt=f"Implement {feature_request}",
|
||||
context_data=codebase_analysis
|
||||
)
|
||||
|
||||
implementation_task = Task(
|
||||
name="feature_implementation",
|
||||
description=f"""
|
||||
Implement the feature using context-enhanced guidance:
|
||||
|
||||
{enhanced_prompt}
|
||||
|
||||
Product Requirements Prompt (PRP):
|
||||
{prp}
|
||||
|
||||
Architecture Design: Reference the architecture task output
|
||||
|
||||
Implementation must:
|
||||
- Follow the implementation blueprint exactly
|
||||
- Use patterns identified in codebase analysis
|
||||
- Meet all requirements from Phase 1
|
||||
- Include comprehensive error handling
|
||||
""",
|
||||
expected_output="Complete feature implementation with code and documentation",
|
||||
agent=self.developer,
|
||||
context=[requirements_task, architecture_task]
|
||||
)
|
||||
|
||||
# Phase 5: Quality Assurance with Context-Generated Criteria
|
||||
print("\n🔍 Phase 5: Quality Assurance with Context")
|
||||
print("-" * 50)
|
||||
|
||||
qa_task = Task(
|
||||
name="quality_validation",
|
||||
description=f"""
|
||||
Validate the implementation using context-generated criteria:
|
||||
|
||||
Validation Framework:
|
||||
{validation_framework}
|
||||
|
||||
Verify that implementation:
|
||||
- Meets all success criteria defined in validation framework
|
||||
- Follows codebase patterns and conventions
|
||||
- Integrates properly with existing systems
|
||||
- Handles edge cases and error scenarios
|
||||
- Meets performance and security requirements
|
||||
|
||||
Use the validation steps provided to systematically check each criterion.
|
||||
""",
|
||||
expected_output="Comprehensive quality validation report with pass/fail status",
|
||||
agent=self.qa_engineer,
|
||||
context=[requirements_task, architecture_task, implementation_task]
|
||||
)
|
||||
|
||||
# Execute the complete workflow
|
||||
print("\n⚙️ Executing Context Engineering Workflow")
|
||||
print("-" * 50)
|
||||
|
||||
agents_workflow = PraisonAIAgents(
|
||||
agents=[
|
||||
self.product_manager,
|
||||
self.architect,
|
||||
self.developer,
|
||||
self.qa_engineer
|
||||
],
|
||||
tasks=[
|
||||
requirements_task,
|
||||
architecture_task,
|
||||
implementation_task,
|
||||
qa_task
|
||||
],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute workflow
|
||||
workflow_results = agents_workflow.start()
|
||||
|
||||
# Compile complete results
|
||||
complete_results = {
|
||||
"feature_request": feature_request,
|
||||
"context_engineering": self.context_data,
|
||||
"workflow_results": workflow_results,
|
||||
"methodology": "Context Engineering - 10x better than prompt engineering"
|
||||
}
|
||||
|
||||
return complete_results
|
||||
|
||||
def demonstrate_context_engineering_benefits():
|
||||
"""
|
||||
Demonstrate the benefits of Context Engineering methodology.
|
||||
"""
|
||||
print("\n📊 Context Engineering vs Traditional Approaches")
|
||||
print("=" * 60)
|
||||
|
||||
# Traditional approach simulation
|
||||
print("\n❌ Traditional AI Coding Approach:")
|
||||
print(" 1. Write basic prompt: 'Implement user authentication'")
|
||||
print(" 2. AI uses general knowledge to implement")
|
||||
print(" 3. Result often doesn't fit existing codebase patterns")
|
||||
print(" 4. Multiple iterations needed to fix integration issues")
|
||||
print(" 5. Success rate: ~30-40% first-try success")
|
||||
|
||||
# Context Engineering approach
|
||||
print("\n✅ Context Engineering Approach:")
|
||||
print(" 1. Analyze codebase patterns and architecture")
|
||||
print(" 2. Generate comprehensive context document")
|
||||
print(" 3. Create validation framework with success criteria")
|
||||
print(" 4. Enhance prompts with rich contextual information")
|
||||
print(" 5. Generate PRP (Product Requirements Prompt)")
|
||||
print(" 6. AI implements using complete context")
|
||||
print(" 7. Success rate: ~90%+ first-try success")
|
||||
|
||||
print("\n📈 Context Engineering Advantages:")
|
||||
print(" • 10x better than prompt engineering (context vs clever wording)")
|
||||
print(" • 100x better than vibe coding (structured vs ad-hoc)")
|
||||
print(" • Enables first-try implementation success")
|
||||
print(" • Reduces development iteration cycles")
|
||||
print(" • Ensures consistency with existing codebase")
|
||||
print(" • Provides built-in quality validation")
|
||||
|
||||
def run_example_workflow():
|
||||
"""Run an example Context Engineering workflow."""
|
||||
|
||||
# Setup workflow with current project
|
||||
project_path = str(project_root)
|
||||
workflow = ContextEngineeringWorkflow(
|
||||
project_path=project_path,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Example feature request
|
||||
feature_request = """
|
||||
Implement a real-time notification system that:
|
||||
- Sends notifications via WebSocket connections
|
||||
- Supports different notification types (info, warning, error)
|
||||
- Persists notifications in database for offline users
|
||||
- Includes user preference management for notification settings
|
||||
- Provides REST API for notification management
|
||||
"""
|
||||
|
||||
print("🎯 Running Example Context Engineering Workflow")
|
||||
print("=" * 60)
|
||||
|
||||
try:
|
||||
# Execute the complete workflow
|
||||
results = workflow.run_context_engineering_workflow(feature_request)
|
||||
|
||||
print("\n🎉 Context Engineering Workflow Completed Successfully!")
|
||||
print("=" * 60)
|
||||
|
||||
print(f"\n📊 Workflow Summary:")
|
||||
print(f" • Feature: Real-time notification system")
|
||||
print(f" • Context generated: ✅ Complete")
|
||||
print(f" • Architecture designed: ✅ With context")
|
||||
print(f" • Implementation: ✅ Context-guided")
|
||||
print(f" • Quality validation: ✅ Context-criteria")
|
||||
|
||||
print(f"\n🔧 Context Engineering Data:")
|
||||
context_data = results["context_engineering"]
|
||||
print(f" • Codebase analysis: {len(str(context_data['codebase_analysis']))} chars")
|
||||
print(f" • Context document: {len(context_data['context_document'])} chars")
|
||||
print(f" • Validation framework: {len(context_data['validation_framework']['validation_steps'])} steps")
|
||||
print(f" • Implementation blueprint: {len(context_data['implementation_blueprint']['implementation_steps'])} steps")
|
||||
print(f" • PRP: {len(context_data['prp'])} chars")
|
||||
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error in workflow execution: {e}")
|
||||
print(" Note: This is a demonstration - actual execution requires proper environment setup")
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("🚀 Advanced Context Engineering Workflow Example")
|
||||
print("================================================")
|
||||
|
||||
print("\n💡 This example demonstrates the complete Context Engineering methodology:")
|
||||
print(" • Comprehensive codebase analysis")
|
||||
print(" • Context document generation")
|
||||
print(" • Validation framework creation")
|
||||
print(" • Multi-agent workflow with context integration")
|
||||
print(" • Quality assurance with context-generated criteria")
|
||||
|
||||
# Show benefits comparison
|
||||
demonstrate_context_engineering_benefits()
|
||||
|
||||
# Run example workflow (demo mode)
|
||||
print("\n🎭 Demo Mode: Context Engineering Workflow Structure")
|
||||
print("(Note: Full execution requires complete environment setup)")
|
||||
|
||||
project_path = str(project_root)
|
||||
workflow = ContextEngineeringWorkflow(project_path, "gpt-4o-mini")
|
||||
|
||||
print(f"\n✅ Workflow Setup Complete:")
|
||||
print(f" • Project path: {project_path}")
|
||||
print(f" • Agents configured: 5 (PM, Context Engineer, Architect, Developer, QA)")
|
||||
print(f" • Context Engineering agent: ✅ Ready")
|
||||
print(f" • Multi-agent workflow: ✅ Configured")
|
||||
|
||||
print(f"\n🎯 Ready to execute Context Engineering workflow!")
|
||||
print(f" Use workflow.run_context_engineering_workflow(feature_request)")
|
||||
print(f" to execute the complete methodology.")
|
||||
|
||||
print(f"\n📚 Key Context Engineering Concepts Demonstrated:")
|
||||
print(f" • Pattern extraction from existing codebase")
|
||||
print(f" • Comprehensive context document generation")
|
||||
print(f" • Validation loop creation with success criteria")
|
||||
print(f" • PRP (Product Requirements Prompt) generation")
|
||||
print(f" • Context-enhanced prompt engineering")
|
||||
print(f" • Multi-agent workflow integration")
|
||||
|
||||
print(f"\n🎉 Context Engineering: 10x better than prompt engineering, 100x better than vibe coding!")
|
||||
@@ -130,9 +130,11 @@ def example_mcp_tracking():
|
||||
)
|
||||
plan = agent.chat("Plan: Search for Python documentation")
|
||||
|
||||
# Track tool usage
|
||||
# Track tool usage (this will now have actual timing)
|
||||
with tracker.track("tool_usage", request_id):
|
||||
# Simulate tool execution
|
||||
# Simulate tool execution with realistic timing
|
||||
import time
|
||||
time.sleep(0.1) # Simulate some work
|
||||
tool_result = "Found 5 relevant documentation pages"
|
||||
|
||||
# Track LLM generation
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a creative designer AI agent. "
|
||||
"Help users with graphic design concepts, branding strategies, "
|
||||
"visual communication, and creative problem-solving. Provide guidance "
|
||||
"on design principles, color theory, typography, and user experience.",
|
||||
llm="anthropic/claude-3-5-sonnet-20241022"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your creative designer assistant. "
|
||||
"How can I help you with your design projects today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are an educational tutor AI agent. "
|
||||
"Help students learn various subjects, explain complex concepts, "
|
||||
"provide step-by-step solutions, and create personalized learning "
|
||||
"materials for different educational levels.",
|
||||
llm="anthropic/claude-3-5-sonnet-20241022"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your educational tutor assistant. "
|
||||
"How can I help you learn today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a financial advisor AI agent. "
|
||||
"Help users understand financial concepts, analyze investment opportunities, "
|
||||
"and provide guidance on personal finance, budgeting, and financial planning. "
|
||||
"Note: This is for educational purposes only, not financial advice.",
|
||||
llm="anthropic/claude-3-5-sonnet-20241022"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your financial advisor assistant. "
|
||||
"How can I help you understand financial concepts today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a legal advisor AI agent. "
|
||||
"Help users understand legal concepts, review contracts, "
|
||||
"analyze legal documents, and provide guidance on compliance "
|
||||
"and regulatory requirements. Note: This is for educational purposes only.",
|
||||
llm="anthropic/claude-3-5-sonnet-20241022"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your legal advisor assistant. "
|
||||
"How can I help you understand legal concepts today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a medical research AI agent. "
|
||||
"Help users understand medical concepts, analyze research papers, "
|
||||
"and provide insights on healthcare trends and developments. "
|
||||
"Note: This is for educational purposes only, not medical advice.",
|
||||
llm="anthropic/claude-3-5-sonnet-20241022"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your medical research assistant. "
|
||||
"How can I help you understand medical concepts today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a cybersecurity AI agent. "
|
||||
"Help users understand security concepts, analyze security threats, "
|
||||
"and provide guidance on security best practices, risk assessment, "
|
||||
"and security architecture design.",
|
||||
llm="openai/gpt-4o"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your cybersecurity assistant. "
|
||||
"How can I help you with security concepts today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a data engineer AI agent. "
|
||||
"Help users design data pipelines, optimize database performance, "
|
||||
"create ETL processes, and provide guidance on data architecture, "
|
||||
"data modeling, and big data technologies.",
|
||||
llm="openai/gpt-4o"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your data engineer assistant. "
|
||||
"How can I help you with your data engineering projects today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a marketing strategist AI agent. "
|
||||
"Help users develop marketing strategies, analyze market trends, "
|
||||
"create campaign plans, and provide guidance on digital marketing, "
|
||||
"brand positioning, and customer acquisition strategies.",
|
||||
llm="openai/gpt-4o"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your marketing strategist assistant. "
|
||||
"How can I help you with your marketing strategy today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a product manager AI agent. "
|
||||
"Help users with product strategy, feature prioritization, "
|
||||
"user research analysis, and product roadmap planning. Provide "
|
||||
"guidance on market analysis, competitive positioning, and user experience.",
|
||||
llm="openai/gpt-4o"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your product manager assistant. "
|
||||
"How can I help you with your product strategy today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a software architect AI agent. "
|
||||
"Help users design software systems, create architecture diagrams, "
|
||||
"plan system integrations, and provide guidance on scalability, "
|
||||
"security, and best practices for software development.",
|
||||
llm="openai/gpt-4o"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your software architect assistant. "
|
||||
"How can I help you design your software system today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a business analyst AI agent. "
|
||||
"Help users analyze business performance, market trends, "
|
||||
"competitive landscape, and strategic opportunities. Provide insights "
|
||||
"on business metrics, financial analysis, and growth strategies.",
|
||||
llm="meta-llama/Llama-3.1-8B-Instruct"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your business analyst assistant. "
|
||||
"How can I help you analyze your business data and strategies today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a code review AI agent. "
|
||||
"Help developers review code for best practices, security vulnerabilities, "
|
||||
"performance issues, and maintainability. Provide constructive feedback "
|
||||
"and suggest improvements for code quality and efficiency.",
|
||||
llm="meta-llama/Llama-3.1-8B-Instruct"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your code review assistant. "
|
||||
"How can I help you improve your code quality today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a content writing AI agent. "
|
||||
"Help users create engaging blog posts, articles, marketing copy, "
|
||||
"and social media content. Provide guidance on SEO optimization, "
|
||||
"content structure, tone adjustment, and audience targeting.",
|
||||
llm="meta-llama/Llama-3.1-8B-Instruct"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your content writing assistant. "
|
||||
"How can I help you create compelling content today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a data science AI agent. "
|
||||
"Help users with data analysis, machine learning model development, "
|
||||
"statistical analysis, and data visualization. Provide guidance on "
|
||||
"data preprocessing, feature engineering, model selection, and evaluation.",
|
||||
llm="meta-llama/Llama-3.1-8B-Instruct"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your data science assistant. "
|
||||
"How can I help you with your data analysis and machine learning projects today?")
|
||||
@@ -0,0 +1,12 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a research assistant AI agent. "
|
||||
"Help users conduct comprehensive research on various topics, "
|
||||
"analyze academic papers, synthesize information, and provide "
|
||||
"evidence-based insights and recommendations.",
|
||||
llm="meta-llama/Llama-3.1-8B-Instruct"
|
||||
)
|
||||
|
||||
response = agent.start("Hello! I'm your research assistant. "
|
||||
"How can I help you with your research project today?")
|
||||
@@ -0,0 +1,315 @@
|
||||
# MongoDB Integration Examples for PraisonAI Agents
|
||||
|
||||
This directory contains comprehensive examples demonstrating how to integrate MongoDB with PraisonAI agents for memory, knowledge, and data operations.
|
||||
|
||||
## Features
|
||||
|
||||
MongoDB integration with PraisonAI provides:
|
||||
|
||||
- **Memory Provider**: Use MongoDB as a persistent memory store for agents
|
||||
- **Knowledge Store**: Store and retrieve documents with vector search capabilities
|
||||
- **Tools Integration**: Perform MongoDB operations directly from agents
|
||||
- **Vector Search**: Leverage MongoDB Atlas Vector Search for semantic similarity
|
||||
- **Scalability**: Handle large datasets with MongoDB's scalable architecture
|
||||
- **Flexibility**: Use MongoDB as both key-value store and vector database
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Install PraisonAI with MongoDB support
|
||||
pip install 'praisonaiagents[mongodb]'
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
- **MongoDB**: Local MongoDB instance or MongoDB Atlas
|
||||
- **OpenAI API Key**: For embeddings and LLM operations
|
||||
- **Python 3.10+**: Required for PraisonAI
|
||||
|
||||
### Environment Setup
|
||||
|
||||
```bash
|
||||
# Set your OpenAI API key
|
||||
export OPENAI_API_KEY="your-openai-api-key"
|
||||
|
||||
# Optional: Set MongoDB connection string
|
||||
export MONGODB_CONNECTION_STRING="mongodb://localhost:27017/"
|
||||
```
|
||||
|
||||
## Examples Overview
|
||||
|
||||
### 1. [mongodb_memory_example.py](mongodb_memory_example.py)
|
||||
|
||||
Demonstrates using MongoDB as a memory provider for PraisonAI agents.
|
||||
|
||||
**Features:**
|
||||
- MongoDB as persistent memory storage
|
||||
- Quality scoring and filtering
|
||||
- Vector search for memory retrieval
|
||||
- Multi-session memory persistence
|
||||
- Memory search and context building
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python mongodb_memory_example.py
|
||||
```
|
||||
|
||||
### 2. [mongodb_knowledge_example.py](mongodb_knowledge_example.py)
|
||||
|
||||
Shows how to use MongoDB as a knowledge store with vector search capabilities.
|
||||
|
||||
**Features:**
|
||||
- MongoDB as knowledge vector store
|
||||
- Document processing and storage
|
||||
- Vector search for knowledge retrieval
|
||||
- Knowledge-based agent interactions
|
||||
- File processing with MongoDB storage
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python mongodb_knowledge_example.py
|
||||
```
|
||||
|
||||
### 3. [mongodb_tools_example.py](mongodb_tools_example.py)
|
||||
|
||||
Demonstrates MongoDB tools integration for database operations.
|
||||
|
||||
**Features:**
|
||||
- MongoDB CRUD operations
|
||||
- Vector search with embeddings
|
||||
- Data analysis and aggregation
|
||||
- Collection management
|
||||
- Index creation and optimization
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python mongodb_tools_example.py
|
||||
```
|
||||
|
||||
### 4. [mongodb_comprehensive_example.py](mongodb_comprehensive_example.py)
|
||||
|
||||
Complete business scenario simulation using all MongoDB features.
|
||||
|
||||
**Features:**
|
||||
- Full MongoDB integration (memory + knowledge + tools)
|
||||
- Multi-agent business workflow
|
||||
- Real-world e-commerce simulation
|
||||
- Business intelligence analytics
|
||||
- Customer service automation
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
python mongodb_comprehensive_example.py
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### MongoDB Memory Configuration
|
||||
|
||||
```python
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"database": "praisonai_memory",
|
||||
"use_vector_search": True, # Enable Atlas Vector Search
|
||||
"max_pool_size": 50,
|
||||
"min_pool_size": 10,
|
||||
"server_selection_timeout": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### MongoDB Knowledge Configuration
|
||||
|
||||
```python
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"database": "praisonai_knowledge",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## MongoDB Atlas Vector Search
|
||||
|
||||
For production use with advanced vector search capabilities:
|
||||
|
||||
### Setup
|
||||
|
||||
1. **Create MongoDB Atlas Cluster**
|
||||
- Sign up for MongoDB Atlas
|
||||
- Create a new cluster
|
||||
- Get your connection string
|
||||
|
||||
2. **Enable Vector Search**
|
||||
- Create vector search indexes
|
||||
- Configure embedding dimensions (1536 for OpenAI)
|
||||
- Set similarity metric (cosine, euclidean, dotProduct)
|
||||
|
||||
3. **Update Connection String**
|
||||
```python
|
||||
"connection_string": "mongodb+srv://username:[email protected]/"
|
||||
```
|
||||
|
||||
### Vector Search Index Creation
|
||||
|
||||
```python
|
||||
# Vector search index definition
|
||||
{
|
||||
"mappings": {
|
||||
"dynamic": True,
|
||||
"fields": {
|
||||
"embedding": {
|
||||
"type": "knnVector",
|
||||
"dimensions": 1536,
|
||||
"similarity": "cosine"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Connection Management
|
||||
|
||||
```python
|
||||
# Use connection pooling
|
||||
mongodb_config = {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"max_pool_size": 50,
|
||||
"min_pool_size": 10,
|
||||
"maxIdleTimeMS": 30000,
|
||||
"serverSelectionTimeoutMS": 5000
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Indexing Strategy
|
||||
|
||||
```python
|
||||
# Create appropriate indexes
|
||||
collection.create_index([("content", "text")]) # Text search
|
||||
collection.create_index([("created_at", -1)]) # Time-based queries
|
||||
collection.create_index([("metadata.category", 1)]) # Category filtering
|
||||
```
|
||||
|
||||
### 3. Error Handling
|
||||
|
||||
```python
|
||||
try:
|
||||
# MongoDB operations
|
||||
result = collection.insert_one(document)
|
||||
except PyMongoError as e:
|
||||
logger.error(f"MongoDB error: {e}")
|
||||
# Implement fallback strategy
|
||||
```
|
||||
|
||||
### 4. Data Validation
|
||||
|
||||
```python
|
||||
# Validate data before storage
|
||||
def validate_document(doc):
|
||||
required_fields = ["content", "metadata", "created_at"]
|
||||
return all(field in doc for field in required_fields)
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### 1. Indexing
|
||||
|
||||
- Create indexes on frequently queried fields
|
||||
- Use compound indexes for complex queries
|
||||
- Monitor index usage with MongoDB profiler
|
||||
|
||||
### 2. Vector Search Optimization
|
||||
|
||||
- Use appropriate vector dimensions
|
||||
- Optimize numCandidates parameter
|
||||
- Consider filtering to reduce search space
|
||||
|
||||
### 3. Connection Pooling
|
||||
|
||||
- Configure appropriate pool sizes
|
||||
- Use connection pooling for high-concurrency scenarios
|
||||
- Monitor connection metrics
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Connection Errors**
|
||||
- Check MongoDB server is running
|
||||
- Verify connection string format
|
||||
- Ensure network connectivity
|
||||
|
||||
2. **Vector Search Issues**
|
||||
- Verify Atlas Vector Search indexes exist
|
||||
- Check embedding dimensions match
|
||||
- Ensure proper index configuration
|
||||
|
||||
3. **Memory Issues**
|
||||
- Monitor memory usage with large datasets
|
||||
- Use appropriate batch sizes
|
||||
- Consider data pagination
|
||||
|
||||
### Debugging
|
||||
|
||||
```python
|
||||
# Enable detailed logging
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
# Monitor MongoDB operations
|
||||
from pymongo import monitoring
|
||||
monitoring.register(CommandLogger())
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### 1. Security
|
||||
|
||||
```python
|
||||
# Use authentication
|
||||
connection_string = "mongodb://username:password@host:port/database"
|
||||
|
||||
# Enable SSL/TLS
|
||||
client = MongoClient(connection_string, tls=True)
|
||||
```
|
||||
|
||||
### 2. Monitoring
|
||||
|
||||
- Use MongoDB Atlas monitoring
|
||||
- Implement application-level metrics
|
||||
- Set up alerting for critical issues
|
||||
|
||||
### 3. Backup and Recovery
|
||||
|
||||
- Configure automated backups
|
||||
- Test restore procedures
|
||||
- Implement disaster recovery plans
|
||||
|
||||
## Support
|
||||
|
||||
For additional support:
|
||||
|
||||
- [PraisonAI Documentation](https://docs.praisonai.com)
|
||||
- [MongoDB Documentation](https://docs.mongodb.com)
|
||||
- [MongoDB Atlas Vector Search](https://docs.atlas.mongodb.com/atlas-vector-search/)
|
||||
|
||||
## License
|
||||
|
||||
These examples are provided under the same license as PraisonAI.
|
||||
@@ -0,0 +1,20 @@
|
||||
# PraisonAI Documentation
|
||||
|
||||
## Docs
|
||||
|
||||
- [AI Agents](https://docs.praison.ai/docs/agents/agents.md): Overview of all available PraisonAI agents and their capabilities
|
||||
- [Data Analyst Agent](https://docs.praison.ai/docs/agents/data-analyst.md): Learn how to create AI agents for data analysis and insights generation.
|
||||
- [Finance Agent](https://docs.praison.ai/docs/agents/finance.md): Learn how to create AI agents for financial analysis and investment recommendations.
|
||||
- [Image Analysis Agent](https://docs.praison.ai/docs/agents/image.md): Learn how to create AI agents for image analysis and visual content understanding.
|
||||
- [Image to Text Agent](https://docs.praison.ai/docs/agents/image-to-text.md): Learn how to create AI agents for converting images to textual descriptions and extracting text from images.
|
||||
- [Markdown Agent](https://docs.praison.ai/docs/agents/markdown.md): Learn how to create AI agents for generating and formatting content in Markdown.
|
||||
- [Planning Agent](https://docs.praison.ai/docs/agents/planning.md): Learn how to create AI agents for trip planning and itinerary generation.
|
||||
- [Programming Agent](https://docs.praison.ai/docs/agents/programming.md): Learn how to create AI agents for code development, analysis, and execution.
|
||||
- [Recommendation Agent](https://docs.praison.ai/docs/agents/recommendation.md): Learn how to create AI agents for personalized recommendations across various domains.
|
||||
- [Research Agent](https://docs.praison.ai/docs/agents/research.md): Learn how to create AI agents for conducting comprehensive research and analysis.
|
||||
- [Shopping Agent](https://docs.praison.ai/docs/agents/shopping.md): Learn how to create AI agents for price comparison and shopping assistance.
|
||||
- [Single Agent](https://docs.praison.ai/docs/agents/single.md): Learn how to create a basic single-purpose AI agent for simple tasks.
|
||||
- [Video Agent](https://docs.praison.ai/docs/agents/video.md): Learn how to create AI agents for video analysis and content understanding.
|
||||
- [Web Search Agent](https://docs.praison.ai/docs/agents/websearch.md): Learn how to create AI agents for intelligent web searching and information gathering.
|
||||
- [Wikipedia Agent](https://docs.praison.ai/docs/agents/wikipedia.md): Learn how to create AI agents for searching and extracting information from Wikipedia.
|
||||
- [Agent Module](https://docs.praison.ai/docs/api/praisonaiagents/agent/agent.md): Documentation for the praisonaiagents.agent.agent module
|
||||
@@ -0,0 +1,297 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Comprehensive MongoDB Integration Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates a complete MongoDB integration with PraisonAI agents,
|
||||
combining memory, knowledge, and tools for a comprehensive data management system.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as memory provider
|
||||
- MongoDB as knowledge store
|
||||
- MongoDB tools for data operations
|
||||
- Vector search capabilities
|
||||
- Multi-agent coordination with MongoDB
|
||||
- Real-world business scenario simulation
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import mongodb_tools
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB configuration for different components
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your connection string
|
||||
"database": "praisonai_comprehensive",
|
||||
"use_vector_search": True,
|
||||
"max_pool_size": 50
|
||||
}
|
||||
}
|
||||
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"database": "praisonai_comprehensive",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": os.getenv("OPENAI_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create specialized agents for different business functions
|
||||
|
||||
# 1. Data Manager Agent - handles data operations
|
||||
data_manager = Agent(
|
||||
name="Data Manager",
|
||||
role="Senior Data Operations Manager",
|
||||
goal="Manage and organize all data operations using MongoDB",
|
||||
backstory="""You are an expert data operations manager who specializes in
|
||||
MongoDB database management. You handle data ingestion, organization,
|
||||
indexing, and ensure data quality and accessibility across the organization.""",
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 2. Knowledge Curator Agent - manages knowledge base
|
||||
knowledge_curator = Agent(
|
||||
name="Knowledge Curator",
|
||||
role="Knowledge Management Specialist",
|
||||
goal="Curate and maintain organizational knowledge using MongoDB",
|
||||
backstory="""You are a knowledge management specialist who excels at
|
||||
organizing, categorizing, and retrieving information from the knowledge base.
|
||||
You ensure that knowledge is properly stored, indexed, and accessible.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 3. Business Analyst Agent - analyzes data and provides insights
|
||||
business_analyst = Agent(
|
||||
name="Business Analyst",
|
||||
role="Senior Business Intelligence Analyst",
|
||||
goal="Analyze business data and provide actionable insights",
|
||||
backstory="""You are a senior business analyst who specializes in extracting
|
||||
insights from data stored in MongoDB. You create reports, identify trends,
|
||||
and provide strategic recommendations based on data analysis.""",
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 4. Customer Service Agent - handles customer interactions
|
||||
customer_service = Agent(
|
||||
name="Customer Service Agent",
|
||||
role="Customer Service Representative",
|
||||
goal="Provide excellent customer service using stored knowledge and data",
|
||||
backstory="""You are a customer service representative who uses the
|
||||
knowledge base and customer data to provide excellent support. You can
|
||||
access customer history, product information, and troubleshooting guides.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create comprehensive business tasks
|
||||
business_tasks = [
|
||||
Task(
|
||||
description="""Set up comprehensive business data infrastructure:
|
||||
1. Create collections for customers, products, orders, and support tickets
|
||||
2. Insert sample business data for an e-commerce platform
|
||||
3. Set up appropriate indexes for performance optimization
|
||||
4. Create vector indexes for product descriptions and customer support
|
||||
5. Implement data validation and business rules
|
||||
|
||||
Focus on creating a realistic business data structure.
|
||||
""",
|
||||
expected_output="Complete business data infrastructure with sample data",
|
||||
agent=data_manager
|
||||
),
|
||||
Task(
|
||||
description="""Build organizational knowledge base:
|
||||
1. Store product documentation and specifications
|
||||
2. Create customer service guidelines and FAQs
|
||||
3. Add troubleshooting guides and best practices
|
||||
4. Include company policies and procedures
|
||||
5. Organize knowledge by categories and tags
|
||||
|
||||
Ensure knowledge is searchable and well-organized.
|
||||
""",
|
||||
expected_output="Comprehensive knowledge base with categorized information",
|
||||
agent=knowledge_curator
|
||||
),
|
||||
Task(
|
||||
description="""Perform business intelligence analysis:
|
||||
1. Analyze customer purchase patterns and behavior
|
||||
2. Calculate key business metrics (revenue, conversion rates, etc.)
|
||||
3. Identify top-selling products and categories
|
||||
4. Analyze customer support ticket trends
|
||||
5. Generate insights for business optimization
|
||||
|
||||
Use MongoDB aggregation and analytics capabilities.
|
||||
""",
|
||||
expected_output="Business intelligence report with actionable insights",
|
||||
agent=business_analyst
|
||||
),
|
||||
Task(
|
||||
description="""Handle customer service scenarios:
|
||||
1. Process customer inquiries using knowledge base
|
||||
2. Look up customer order history and preferences
|
||||
3. Provide product recommendations based on customer data
|
||||
4. Access troubleshooting guides for technical issues
|
||||
5. Update customer records and interaction history
|
||||
|
||||
Demonstrate excellent customer service with data-driven support.
|
||||
""",
|
||||
expected_output="Customer service interactions with knowledge-based responses",
|
||||
agent=customer_service
|
||||
),
|
||||
Task(
|
||||
description="""Generate comprehensive business report:
|
||||
1. Combine insights from all data sources
|
||||
2. Create executive summary with key findings
|
||||
3. Provide recommendations for business improvement
|
||||
4. Include data visualizations and metrics
|
||||
5. Store report in knowledge base for future reference
|
||||
|
||||
Create a comprehensive business intelligence report.
|
||||
""",
|
||||
expected_output="Executive business report with comprehensive insights",
|
||||
agent=business_analyst
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the comprehensive business system
|
||||
print("🚀 Starting Comprehensive MongoDB Business System...")
|
||||
print("=" * 60)
|
||||
|
||||
business_system = PraisonAIAgents(
|
||||
agents=[data_manager, knowledge_curator, business_analyst, customer_service],
|
||||
tasks=business_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the comprehensive business pipeline
|
||||
try:
|
||||
results = business_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Comprehensive Business System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 Comprehensive MongoDB Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate system integration
|
||||
print("\n🔍 Demonstrating System Integration:")
|
||||
print("-" * 40)
|
||||
|
||||
# Access different components
|
||||
# Note: Direct memory access not available through business_system.memory
|
||||
print("📋 Memory integration enabled through memory_config...")
|
||||
print("Memory operations are handled internally by the agents")
|
||||
|
||||
# Access memory system directly
|
||||
from praisonaiagents.memory import Memory
|
||||
memory_system = Memory(config=mongodb_memory_config)
|
||||
|
||||
# Search business memories
|
||||
print("\n📋 Searching business memories...")
|
||||
business_memories = memory_system.search_long_term("business analysis", limit=3)
|
||||
print(f"Found {len(business_memories)} business-related memories")
|
||||
|
||||
# Access knowledge system
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
knowledge_system = Knowledge(config=mongodb_knowledge_config)
|
||||
|
||||
# Search knowledge base
|
||||
print("\n📚 Searching knowledge base...")
|
||||
knowledge_results = knowledge_system.search("customer service", limit=3)
|
||||
print(f"Found {len(knowledge_results)} knowledge entries")
|
||||
|
||||
# Direct MongoDB operations
|
||||
print("\n🔧 Direct MongoDB operations...")
|
||||
mongo_client = mongodb_tools.connect_mongodb(
|
||||
"mongodb://localhost:27017/",
|
||||
"praisonai_comprehensive"
|
||||
)
|
||||
|
||||
# Get database statistics
|
||||
stats = mongo_client.get_stats("customers")
|
||||
print(f"Customer collection stats: {stats}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎉 Comprehensive MongoDB Example Completed Successfully!")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n📈 System Overview:")
|
||||
print("- Memory System: MongoDB-based persistent memory")
|
||||
print("- Knowledge Base: MongoDB vector search enabled")
|
||||
print("- Tools Integration: Full MongoDB CRUD operations")
|
||||
print("- Multi-Agent Coordination: Business workflow simulation")
|
||||
print("- Vector Search: Semantic search capabilities")
|
||||
print("- Data Analytics: Business intelligence insights")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Comprehensive MongoDB Integration Example")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates complete MongoDB integration with PraisonAI")
|
||||
print("Features:")
|
||||
print("- MongoDB Memory Provider")
|
||||
print("- MongoDB Knowledge Store")
|
||||
print("- MongoDB Tools Integration")
|
||||
print("- Vector Search Capabilities")
|
||||
print("- Multi-Agent Business Simulation")
|
||||
print("=" * 50)
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Knowledge Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB as a knowledge store for PraisonAI agents.
|
||||
MongoDB can store and retrieve knowledge documents with vector search capabilities.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as knowledge vector store
|
||||
- Document processing and storage
|
||||
- Vector search for knowledge retrieval
|
||||
- Knowledge-based agent interactions
|
||||
- File processing with MongoDB storage
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB knowledge configuration
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your MongoDB connection string
|
||||
"database": "praisonai_knowledge",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True # Enable Atlas Vector Search
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": os.getenv("OPENAI_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create a knowledge agent with MongoDB knowledge store
|
||||
knowledge_agent = Agent(
|
||||
name="MongoDB Knowledge Agent",
|
||||
role="Knowledge Specialist",
|
||||
goal="Provide accurate information from MongoDB knowledge base",
|
||||
backstory="""You are an expert knowledge specialist who can access and
|
||||
retrieve information from a comprehensive MongoDB knowledge base. You excel
|
||||
at finding relevant information, synthesizing knowledge from multiple sources,
|
||||
and providing accurate, context-aware responses.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create a research assistant agent
|
||||
research_agent = Agent(
|
||||
name="Research Assistant",
|
||||
role="Research Assistant",
|
||||
goal="Gather information and store it in the knowledge base",
|
||||
backstory="""You are a research assistant who specializes in gathering
|
||||
information from various sources and organizing it for storage in the
|
||||
knowledge base. You ensure information is accurate, well-structured,
|
||||
and properly categorized.""",
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create tasks for knowledge management
|
||||
knowledge_tasks = [
|
||||
Task(
|
||||
description="""Research and store information about MongoDB Atlas Vector Search:
|
||||
1. Gather comprehensive information about MongoDB Atlas Vector Search
|
||||
2. Include technical specifications, use cases, and best practices
|
||||
3. Store the information in the MongoDB knowledge base
|
||||
4. Organize information by categories (features, performance, integration)
|
||||
""",
|
||||
expected_output="MongoDB Atlas Vector Search information stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research and store information about AI agent frameworks:
|
||||
1. Research popular AI agent frameworks (LangChain, AutoGen, etc.)
|
||||
2. Compare their features, capabilities, and use cases
|
||||
3. Store comparative analysis in the knowledge base
|
||||
4. Include code examples and best practices
|
||||
""",
|
||||
expected_output="AI agent framework comparison stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for MongoDB information:
|
||||
1. Search for information about MongoDB Atlas Vector Search
|
||||
2. Extract key features and capabilities
|
||||
3. Provide a comprehensive summary
|
||||
4. Include technical recommendations
|
||||
""",
|
||||
expected_output="Comprehensive MongoDB Atlas Vector Search summary from knowledge base",
|
||||
agent=knowledge_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for AI agent framework information:
|
||||
1. Search for information about AI agent frameworks
|
||||
2. Compare different frameworks based on stored knowledge
|
||||
3. Provide recommendations for different use cases
|
||||
4. Include best practices and examples
|
||||
""",
|
||||
expected_output="AI agent framework comparison and recommendations from knowledge base",
|
||||
agent=knowledge_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB knowledge
|
||||
print("🚀 Starting MongoDB Knowledge Management System...")
|
||||
print("=" * 60)
|
||||
|
||||
knowledge_system = PraisonAIAgents(
|
||||
agents=[research_agent, knowledge_agent],
|
||||
tasks=knowledge_tasks,
|
||||
memory=True,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the knowledge management pipeline
|
||||
try:
|
||||
results = knowledge_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Knowledge Management System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Knowledge Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate direct knowledge access
|
||||
print("\n🔍 Demonstrating Direct Knowledge Access:")
|
||||
print("-" * 40)
|
||||
|
||||
# Access knowledge system directly
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
|
||||
knowledge_system = Knowledge(config=mongodb_knowledge_config)
|
||||
|
||||
# Store a sample document
|
||||
sample_doc = """
|
||||
MongoDB is a document-oriented database that provides high performance,
|
||||
high availability, and easy scalability. It works on the concept of
|
||||
collections and documents, using a flexible, JSON-like document model.
|
||||
"""
|
||||
|
||||
print("📄 Storing sample document...")
|
||||
knowledge_system.store(sample_doc, metadata={"category": "database", "type": "overview"})
|
||||
|
||||
# Search for stored knowledge
|
||||
print("\n🔍 Searching knowledge base...")
|
||||
results = knowledge_system.search("MongoDB document database", limit=3)
|
||||
|
||||
print(f"Found {len(results)} knowledge entries:")
|
||||
for result in results:
|
||||
print(f" - {result.get('memory', '')[:100]}...")
|
||||
print(f" Score: {result.get('score', 'N/A')}")
|
||||
|
||||
print("\n✅ MongoDB Knowledge Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Knowledge Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB integration for knowledge management")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Memory Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB as a memory provider for PraisonAI agents.
|
||||
MongoDB can be used as both a key-value store and a vector database for memory operations.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as memory provider
|
||||
- Vector search with Atlas Vector Search
|
||||
- Quality scoring and filtering
|
||||
- User-specific memory storage
|
||||
- Persistent memory across sessions
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB memory configuration
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your MongoDB connection string
|
||||
"database": "praisonai_memory",
|
||||
"use_vector_search": True, # Enable Atlas Vector Search (requires MongoDB Atlas)
|
||||
"max_pool_size": 50,
|
||||
"min_pool_size": 10,
|
||||
"server_selection_timeout": 5000
|
||||
}
|
||||
}
|
||||
|
||||
# Create a research agent with MongoDB memory
|
||||
research_agent = Agent(
|
||||
name="MongoDB Research Agent",
|
||||
role="Senior Research Specialist",
|
||||
goal="Research topics and maintain persistent memory using MongoDB",
|
||||
backstory="""You are an expert researcher who specializes in collecting,
|
||||
analyzing, and storing information using advanced MongoDB-based memory systems.
|
||||
You excel at maintaining context across multiple research sessions and can
|
||||
retrieve relevant information from your persistent memory store.""",
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create research tasks
|
||||
research_tasks = [
|
||||
Task(
|
||||
description="""Research the latest developments in AI/ML for 2024:
|
||||
1. Identify major AI breakthroughs and trends
|
||||
2. Analyze the impact on various industries
|
||||
3. Store key findings in MongoDB memory with quality scores
|
||||
4. Identify emerging technologies and their potential applications
|
||||
""",
|
||||
expected_output="Comprehensive AI/ML research report with key findings stored in MongoDB",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research MongoDB Atlas Vector Search capabilities:
|
||||
1. Explore vector search features and use cases
|
||||
2. Compare with other vector databases
|
||||
3. Analyze performance and scalability
|
||||
4. Store technical insights in MongoDB memory
|
||||
""",
|
||||
expected_output="Technical analysis of MongoDB Atlas Vector Search with stored insights",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research AI agent frameworks and tools:
|
||||
1. Compare popular AI agent frameworks
|
||||
2. Analyze their strengths and weaknesses
|
||||
3. Identify best practices for agent development
|
||||
4. Store comparative analysis in MongoDB memory
|
||||
""",
|
||||
expected_output="Comparative analysis of AI agent frameworks with stored insights",
|
||||
agent=research_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB memory
|
||||
print("🚀 Starting MongoDB Memory Research System...")
|
||||
print("=" * 60)
|
||||
|
||||
research_system = PraisonAIAgents(
|
||||
agents=[research_agent],
|
||||
tasks=research_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the research pipeline
|
||||
try:
|
||||
results = research_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Research System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'agent'):
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Memory Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate memory retrieval
|
||||
print("\n🔍 Demonstrating Memory Retrieval:")
|
||||
print("-" * 40)
|
||||
|
||||
# Note: Direct memory access not available through research_system.memory
|
||||
# Instead, use Memory class directly for verification
|
||||
try:
|
||||
from praisonaiagents.memory import Memory
|
||||
|
||||
# Create Memory instance with MongoDB config for verification
|
||||
memory_system = Memory(mongodb_memory_config)
|
||||
|
||||
# Search for AI-related memories
|
||||
ai_memories = memory_system.search_long_term("AI machine learning", limit=3)
|
||||
print(f"Found {len(ai_memories)} AI-related memories:")
|
||||
for memory in ai_memories:
|
||||
if hasattr(memory, 'get'):
|
||||
print(f" - {memory.get('text', '')[:100]}...")
|
||||
else:
|
||||
print(f" - {str(memory)[:100]}...")
|
||||
|
||||
# Search for MongoDB-related memories
|
||||
mongo_memories = memory_system.search_long_term("MongoDB vector search", limit=3)
|
||||
print(f"\nFound {len(mongo_memories)} MongoDB-related memories:")
|
||||
for memory in mongo_memories:
|
||||
if hasattr(memory, 'get'):
|
||||
print(f" - {memory.get('text', '')[:100]}...")
|
||||
else:
|
||||
print(f" - {str(memory)[:100]}...")
|
||||
|
||||
except ImportError:
|
||||
print("Memory features not available - install with: pip install 'praisonaiagents[memory]'")
|
||||
except Exception as mem_error:
|
||||
print(f"Memory verification error: {mem_error}")
|
||||
|
||||
print("\n✅ MongoDB Memory Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Memory Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB integration for persistent memory")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Tools Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB tools with PraisonAI agents.
|
||||
Agents can perform MongoDB operations like inserting, querying, and vector search.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB tools integration
|
||||
- Document CRUD operations
|
||||
- Vector search with embeddings
|
||||
- Data analysis with MongoDB
|
||||
- Agent-driven database operations
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import mongodb_tools
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# Create a MongoDB Database Agent with MongoDB tools
|
||||
db_agent = Agent(
|
||||
name="MongoDB Database Agent",
|
||||
role="Database Operations Specialist",
|
||||
goal="Manage MongoDB operations and data analysis",
|
||||
backstory="""You are an expert database administrator who specializes in
|
||||
MongoDB operations. You can perform complex database queries, manage
|
||||
collections, and analyze data patterns. You excel at using MongoDB tools
|
||||
for data management and retrieval.""",
|
||||
tools=[mongodb_tools],
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create a Data Analysis Agent
|
||||
analysis_agent = Agent(
|
||||
name="Data Analysis Agent",
|
||||
role="Data Analyst",
|
||||
goal="Analyze data stored in MongoDB and provide insights",
|
||||
backstory="""You are a data analyst who specializes in extracting insights
|
||||
from MongoDB databases. You can query data, perform aggregations, and
|
||||
identify patterns and trends in the stored information.""",
|
||||
tools=[mongodb_tools],
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create tasks for MongoDB operations
|
||||
mongodb_tasks = [
|
||||
Task(
|
||||
description="""Set up MongoDB collections and insert sample data:
|
||||
1. Create a collection called 'products' for e-commerce data
|
||||
2. Insert sample product documents with fields: name, price, category, description
|
||||
3. Create a collection called 'users' for user data
|
||||
4. Insert sample user documents with fields: name, email, age, preferences
|
||||
5. Create appropriate indexes for better query performance
|
||||
|
||||
Use the MongoDB tools to perform these operations.
|
||||
""",
|
||||
expected_output="MongoDB collections created with sample data and indexes",
|
||||
agent=db_agent
|
||||
),
|
||||
Task(
|
||||
description="""Perform vector search operations:
|
||||
1. Create a vector index for product descriptions
|
||||
2. Store products with text embeddings for vector search
|
||||
3. Demonstrate vector similarity search for product recommendations
|
||||
4. Show how to find similar products based on description embeddings
|
||||
|
||||
Use the MongoDB vector search tools for these operations.
|
||||
""",
|
||||
expected_output="Vector search implementation with product recommendations",
|
||||
agent=db_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query and analyze the stored data:
|
||||
1. Find all products in a specific category
|
||||
2. Calculate average price by category
|
||||
3. Find users with specific preferences
|
||||
4. Perform text search on product descriptions
|
||||
5. Generate insights about the data patterns
|
||||
|
||||
Use MongoDB query tools to perform these analyses.
|
||||
""",
|
||||
expected_output="Data analysis report with insights from MongoDB queries",
|
||||
agent=analysis_agent
|
||||
),
|
||||
Task(
|
||||
description="""Demonstrate advanced MongoDB operations:
|
||||
1. Update product prices based on specific criteria
|
||||
2. Perform aggregation operations for statistical analysis
|
||||
3. Create reports on user demographics and preferences
|
||||
4. Implement data validation and error handling
|
||||
5. Show MongoDB best practices for data management
|
||||
|
||||
Use MongoDB tools for these advanced operations.
|
||||
""",
|
||||
expected_output="Advanced MongoDB operations report with best practices",
|
||||
agent=db_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB tools
|
||||
print("🚀 Starting MongoDB Tools Demo System...")
|
||||
print("=" * 60)
|
||||
|
||||
mongodb_system = PraisonAIAgents(
|
||||
agents=[db_agent, analysis_agent],
|
||||
tasks=mongodb_tasks,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the MongoDB operations pipeline
|
||||
try:
|
||||
results = mongodb_system.start(return_dict=True)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 MongoDB Tools System Results:")
|
||||
print("=" * 60)
|
||||
print(results)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, dict) and 'task_results' in results:
|
||||
task_results = results['task_results']
|
||||
for i, result in task_results.items():
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Result: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Tools Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate direct MongoDB tools usage
|
||||
print("\n🔍 Demonstrating Direct MongoDB Tools Usage:")
|
||||
print("-" * 40)
|
||||
|
||||
# Connect to MongoDB
|
||||
mongo_client = mongodb_tools.connect_mongodb(
|
||||
"mongodb://localhost:27017/", # Replace with your connection string
|
||||
"praisonai_tools_demo"
|
||||
)
|
||||
|
||||
# Insert a sample document
|
||||
print("📄 Inserting sample document...")
|
||||
result = mongo_client.insert_document(
|
||||
"demo_collection",
|
||||
{
|
||||
"title": "MongoDB Tools Demo",
|
||||
"description": "Demonstration of MongoDB tools with PraisonAI",
|
||||
"category": "database",
|
||||
"tags": ["mongodb", "praisonai", "tools", "demo"]
|
||||
},
|
||||
metadata={"created_by": "demo", "version": "1.0"}
|
||||
)
|
||||
print(f" Result: {result}")
|
||||
|
||||
# Query documents
|
||||
print("\n🔍 Querying documents...")
|
||||
documents = mongo_client.find_documents(
|
||||
"demo_collection",
|
||||
{"category": "database"},
|
||||
limit=5
|
||||
)
|
||||
print(f" Found {len(documents)} documents")
|
||||
for doc in documents:
|
||||
print(f" - {doc.get('title', 'N/A')}: {doc.get('description', '')[:50]}...")
|
||||
|
||||
# Get collection statistics
|
||||
print("\n📈 Getting collection statistics...")
|
||||
stats = mongo_client.get_stats("demo_collection")
|
||||
print(f" Collection stats: {stats}")
|
||||
|
||||
print("\n✅ MongoDB Tools Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Tools Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB tools integration")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,143 @@
|
||||
"""
|
||||
Multi-Agent Workflow with Performance Monitoring - Example 2
|
||||
|
||||
Demonstrates performance monitoring in a multi-agent workflow:
|
||||
- Multiple agents with different roles
|
||||
- Inter-agent communication tracking
|
||||
- Workflow performance analysis
|
||||
- Task delegation timing
|
||||
|
||||
Shows how to monitor complex multi-agent systems.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
analyze_function_flow, generate_comprehensive_report
|
||||
)
|
||||
import time
|
||||
|
||||
@monitor_function("research_task")
|
||||
def setup_research_task():
|
||||
"""Set up research task with monitoring."""
|
||||
return Task(
|
||||
name="research_task",
|
||||
description="Research the topic of renewable energy trends",
|
||||
expected_output="A comprehensive research summary"
|
||||
)
|
||||
|
||||
@monitor_function("analysis_task")
|
||||
def setup_analysis_task():
|
||||
"""Set up analysis task with monitoring."""
|
||||
return Task(
|
||||
name="analysis_task",
|
||||
description="Analyze the research data and identify key trends",
|
||||
expected_output="Key insights and trend analysis"
|
||||
)
|
||||
|
||||
@monitor_function("report_task")
|
||||
def setup_report_task():
|
||||
"""Set up report generation task with monitoring."""
|
||||
return Task(
|
||||
name="report_task",
|
||||
description="Create a final report combining research and analysis",
|
||||
expected_output="A well-structured final report"
|
||||
)
|
||||
|
||||
@monitor_function("agent_creation")
|
||||
def create_agents():
|
||||
"""Create specialized agents with monitoring."""
|
||||
|
||||
researcher = Agent(
|
||||
name="researcher",
|
||||
role="Research Specialist",
|
||||
goal="Gather comprehensive information on renewable energy",
|
||||
backstory="Expert researcher with deep knowledge of energy sector",
|
||||
instructions="You are a thorough researcher. Provide detailed, fact-based information.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
analyst = Agent(
|
||||
name="analyst",
|
||||
role="Data Analyst",
|
||||
goal="Analyze trends and patterns in renewable energy data",
|
||||
backstory="Experienced data analyst specializing in energy markets",
|
||||
instructions="You are an analytical thinker. Focus on trends, patterns, and insights.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
name="writer",
|
||||
role="Report Writer",
|
||||
goal="Create clear, compelling reports",
|
||||
backstory="Professional technical writer with expertise in energy sector",
|
||||
instructions="You are a skilled writer. Create clear, well-structured reports.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
return researcher, analyst, writer
|
||||
|
||||
@monitor_function("workflow_execution")
|
||||
def main():
|
||||
"""Main function demonstrating multi-agent workflow with performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 2: Multi-Agent Workflow with Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Create agents with monitoring
|
||||
researcher, analyst, writer = create_agents()
|
||||
|
||||
# Set up tasks with monitoring
|
||||
research_task = setup_research_task()
|
||||
analysis_task = setup_analysis_task()
|
||||
report_task = setup_report_task()
|
||||
|
||||
# Assign agents to tasks
|
||||
research_task.agent = researcher
|
||||
analysis_task.agent = analyst
|
||||
report_task.agent = writer
|
||||
|
||||
# Create workflow
|
||||
with track_api_call("multi_agent_workflow"):
|
||||
print("\n🚀 Starting multi-agent workflow...")
|
||||
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[researcher, analyst, writer],
|
||||
tasks=[research_task, analysis_task, report_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
result = workflow.start()
|
||||
|
||||
# Display comprehensive performance analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 MULTI-AGENT PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Function statistics
|
||||
print("\n📈 Function Performance Statistics:")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Flow analysis
|
||||
print("\n🔄 Execution Flow Analysis:")
|
||||
flow_analysis = analyze_function_flow()
|
||||
print(f" Total Functions Monitored: {len(flow_analysis.get('functions', []))}")
|
||||
print(f" Execution Chains: {len(flow_analysis.get('call_chains', []))}")
|
||||
|
||||
# Comprehensive report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = generate_comprehensive_report()
|
||||
print(report[:500] + "..." if len(report) > 500 else report)
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Multi-agent workflow completed successfully!")
|
||||
@@ -0,0 +1,119 @@
|
||||
"""
|
||||
Agent with Tools Performance Monitoring - Example 3
|
||||
|
||||
Demonstrates performance monitoring for agents using tools:
|
||||
- Tool execution timing
|
||||
- Search operation performance
|
||||
- Tool call success/failure tracking
|
||||
- Tool usage analysis
|
||||
|
||||
Shows how to monitor agent performance when using external tools.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import duckduckgo, wikipedia
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_api_stats,
|
||||
get_slowest_functions, performance_monitor
|
||||
)
|
||||
import time
|
||||
|
||||
@monitor_function("search_with_duckduckgo")
|
||||
def perform_web_search(query):
|
||||
"""Perform web search with performance monitoring."""
|
||||
print(f"🔍 Searching web for: {query}")
|
||||
with track_api_call("duckduckgo_search"):
|
||||
# Simulate search time
|
||||
time.sleep(0.2)
|
||||
return f"Search results for: {query}"
|
||||
|
||||
@monitor_function("wikipedia_lookup")
|
||||
def perform_wikipedia_search(topic):
|
||||
"""Perform Wikipedia search with performance monitoring."""
|
||||
print(f"📚 Looking up Wikipedia for: {topic}")
|
||||
with track_api_call("wikipedia_search"):
|
||||
# Simulate Wikipedia lookup
|
||||
time.sleep(0.15)
|
||||
return f"Wikipedia information about: {topic}"
|
||||
|
||||
@monitor_function("agent_with_tools_execution")
|
||||
def main():
|
||||
"""Main function demonstrating agent with tools and performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 3: Agent with Tools Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Create agent with tools
|
||||
agent = Agent(
|
||||
instructions="""You are a research assistant that helps find information.
|
||||
Use the available tools to search for information and provide comprehensive answers.
|
||||
Be thorough in your research and cite your sources.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=[duckduckgo, wikipedia] # Add search tools
|
||||
)
|
||||
|
||||
# Test queries to demonstrate tool performance monitoring
|
||||
queries = [
|
||||
"What are the latest developments in artificial intelligence?",
|
||||
"Tell me about renewable energy innovations in 2024",
|
||||
"How do neural networks work?"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for i, query in enumerate(queries, 1):
|
||||
print(f"\n🎯 Query {i}: {query}")
|
||||
|
||||
# Monitor the search operations
|
||||
perform_web_search(query)
|
||||
perform_wikipedia_search(query)
|
||||
|
||||
# Track the full agent execution
|
||||
with track_api_call(f"agent_query_{i}"):
|
||||
print(f"\n🚀 Processing with agent...")
|
||||
|
||||
# Note: In a real implementation, the agent would use the tools automatically
|
||||
# For demo purposes, we're simulating the tool usage
|
||||
result = agent.start(f"Research and answer: {query}")
|
||||
results.append(result)
|
||||
|
||||
print(f"📝 Agent Response: {result[:200]}..." if len(result) > 200 else f"📝 Agent Response: {result}")
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 TOOLS PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# API call statistics
|
||||
print("\n📈 API Call Performance:")
|
||||
api_stats = get_api_stats()
|
||||
for api_name, stats in api_stats.items():
|
||||
print(f" {api_name}:")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
print(f" Avg Response Time: {stats['total_time']/stats['call_count']:.3f}s")
|
||||
print(f" Success Rate: {stats['success_count']/stats['call_count']*100:.1f}%")
|
||||
print(f" Total Time: {stats['total_time']:.3f}s")
|
||||
|
||||
# Slowest functions analysis
|
||||
print("\n🐌 Slowest Functions:")
|
||||
slowest = get_slowest_functions()
|
||||
for func_name, avg_time in slowest:
|
||||
print(f" {func_name}: {avg_time:.3f}s average")
|
||||
|
||||
# Real-time performance data
|
||||
print("\n⚡ Real-time Performance Data:")
|
||||
current_stats = performance_monitor.get_function_performance()
|
||||
print(f" Functions Monitored: {len(current_stats)}")
|
||||
|
||||
total_function_calls = sum(stats['call_count'] for stats in current_stats.values())
|
||||
total_execution_time = sum(stats['total_time'] for stats in current_stats.values())
|
||||
|
||||
print(f" Total Function Calls: {total_function_calls}")
|
||||
print(f" Total Execution Time: {total_execution_time:.3f}s")
|
||||
print(f" Average Time per Call: {total_execution_time/total_function_calls:.3f}s" if total_function_calls > 0 else " No calls recorded")
|
||||
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
results = main()
|
||||
print(f"\n✅ Tool monitoring example completed! Processed {len(results)} queries.")
|
||||
@@ -0,0 +1,167 @@
|
||||
"""
|
||||
Async Agent with Performance Monitoring - Example 4
|
||||
|
||||
Demonstrates performance monitoring for asynchronous agent operations:
|
||||
- Async function execution timing
|
||||
- Concurrent task performance
|
||||
- Async API call tracking
|
||||
- Parallel operation analysis
|
||||
|
||||
Shows how to monitor performance in async/await workflows.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_performance_report,
|
||||
get_function_stats, visualize_execution_flow
|
||||
)
|
||||
|
||||
@monitor_function("async_data_processing")
|
||||
async def process_data_async(data_id: int):
|
||||
"""Async data processing with performance monitoring."""
|
||||
print(f"⚙️ Processing data {data_id} asynchronously...")
|
||||
await asyncio.sleep(0.1) # Simulate async processing
|
||||
return f"Processed data {data_id}"
|
||||
|
||||
@monitor_function("async_api_call")
|
||||
async def simulate_api_call(endpoint: str, delay: float = 0.2):
|
||||
"""Simulate async API call with performance monitoring."""
|
||||
print(f"🌐 Calling API endpoint: {endpoint}")
|
||||
await asyncio.sleep(delay) # Simulate network delay
|
||||
return f"Response from {endpoint}"
|
||||
|
||||
@monitor_function("batch_processing")
|
||||
async def process_batch(batch_size: int = 3):
|
||||
"""Process multiple items concurrently with monitoring."""
|
||||
print(f"📦 Processing batch of {batch_size} items...")
|
||||
|
||||
# Create concurrent tasks
|
||||
tasks = []
|
||||
for i in range(batch_size):
|
||||
tasks.append(process_data_async(i + 1))
|
||||
|
||||
# Wait for all tasks to complete
|
||||
results = await asyncio.gather(*tasks)
|
||||
print(f"✅ Batch processing completed: {len(results)} items processed")
|
||||
return results
|
||||
|
||||
@monitor_function("async_agent_execution")
|
||||
async def run_async_agent(query: str):
|
||||
"""Run agent with async operations and monitoring."""
|
||||
|
||||
# Create agent
|
||||
agent = Agent(
|
||||
instructions="You are an efficient AI assistant that processes requests quickly",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Track the agent execution
|
||||
with track_api_call("async_agent_request"):
|
||||
print(f"🚀 Running async agent for query: {query}")
|
||||
|
||||
# For demo purposes, we simulate async agent execution
|
||||
# In real scenarios, you'd use agent.astart() or similar async method when available
|
||||
await asyncio.sleep(0.1) # Simulate async processing time
|
||||
result = agent.start(query)
|
||||
|
||||
# Simulate some async post-processing
|
||||
await asyncio.sleep(0.05)
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("concurrent_agents")
|
||||
async def run_concurrent_agents():
|
||||
"""Run multiple agents concurrently with monitoring."""
|
||||
print("🔄 Running multiple agents concurrently...")
|
||||
|
||||
queries = [
|
||||
"What is machine learning?",
|
||||
"Explain quantum computing",
|
||||
"How does blockchain work?"
|
||||
]
|
||||
|
||||
# Create concurrent agent tasks
|
||||
agent_tasks = []
|
||||
for i, query in enumerate(queries):
|
||||
task = run_async_agent(query)
|
||||
agent_tasks.append(task)
|
||||
|
||||
# Execute all agents concurrently
|
||||
results = await asyncio.gather(*agent_tasks)
|
||||
return results
|
||||
|
||||
async def main():
|
||||
"""Main async function demonstrating async agent performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 4: Async Agent Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
# Run async operations with monitoring
|
||||
print("\n📊 Phase 1: Batch Processing")
|
||||
batch_results = await process_batch(3)
|
||||
|
||||
print("\n🌐 Phase 2: API Calls")
|
||||
api_tasks = [
|
||||
simulate_api_call("user-service", 0.1),
|
||||
simulate_api_call("data-service", 0.15),
|
||||
simulate_api_call("analytics-service", 0.2)
|
||||
]
|
||||
api_results = await asyncio.gather(*api_tasks)
|
||||
|
||||
print("\n🤖 Phase 3: Concurrent Agents")
|
||||
agent_results = await run_concurrent_agents()
|
||||
|
||||
total_time = time.time() - start_time
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 ASYNC PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
print(f"\n⏱️ Total Execution Time: {total_time:.3f}s")
|
||||
|
||||
# Function statistics
|
||||
print("\n📈 Function Performance:")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Execution flow visualization
|
||||
print("\n🔄 Execution Flow:")
|
||||
try:
|
||||
flow_viz = visualize_execution_flow()
|
||||
print(" Flow visualization generated successfully")
|
||||
print(f" Flow data length: {len(str(flow_viz))}")
|
||||
except Exception as e:
|
||||
print(f" Flow visualization: {str(e)}")
|
||||
|
||||
# Performance report
|
||||
print("\n📋 Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:300] + "..." if len(report) > 300 else report)
|
||||
|
||||
# Results summary
|
||||
print(f"\n✅ Results Summary:")
|
||||
print(f" Batch items processed: {len(batch_results)}")
|
||||
print(f" API calls completed: {len(api_results)}")
|
||||
print(f" Agent queries processed: {len(agent_results)}")
|
||||
|
||||
return {
|
||||
'batch_results': batch_results,
|
||||
'api_results': api_results,
|
||||
'agent_results': agent_results,
|
||||
'total_time': total_time
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the async main function
|
||||
result = asyncio.run(main())
|
||||
print(f"\n🎉 Async monitoring example completed successfully!")
|
||||
@@ -0,0 +1,195 @@
|
||||
"""
|
||||
Error Handling with Performance Monitoring - Example 5
|
||||
|
||||
Demonstrates performance monitoring for error scenarios:
|
||||
- Error rate tracking
|
||||
- Failed operation timing
|
||||
- Recovery mechanism performance
|
||||
- Exception handling with monitoring
|
||||
|
||||
Shows how to monitor performance when things go wrong.
|
||||
"""
|
||||
|
||||
import random
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
get_api_stats, performance_monitor
|
||||
)
|
||||
|
||||
@monitor_function("unreliable_operation")
|
||||
def simulate_unreliable_operation(operation_id: int, failure_rate: float = 0.3):
|
||||
"""Simulate an operation that sometimes fails."""
|
||||
print(f"⚙️ Running operation {operation_id}...")
|
||||
|
||||
# Simulate processing time
|
||||
time.sleep(random.uniform(0.05, 0.2))
|
||||
|
||||
# Random failure simulation
|
||||
if random.random() < failure_rate:
|
||||
raise RuntimeError(f"Operation {operation_id} failed!")
|
||||
|
||||
return f"Operation {operation_id} succeeded"
|
||||
|
||||
@monitor_function("retry_with_backoff")
|
||||
def retry_operation(operation_id: int, max_retries: int = 3):
|
||||
"""Retry an operation with exponential backoff and monitoring."""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
print(f"🔄 Attempt {attempt + 1} for operation {operation_id}")
|
||||
result = simulate_unreliable_operation(operation_id)
|
||||
print(f"✅ Operation {operation_id} succeeded on attempt {attempt + 1}")
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"❌ Attempt {attempt + 1} failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
# Exponential backoff
|
||||
sleep_time = 2 ** attempt * 0.1
|
||||
print(f"⏳ Waiting {sleep_time:.1f}s before retry...")
|
||||
time.sleep(sleep_time)
|
||||
else:
|
||||
print(f"💥 All {max_retries} attempts failed for operation {operation_id}")
|
||||
raise
|
||||
|
||||
@monitor_function("robust_agent_execution")
|
||||
def run_robust_agent(query: str, with_error_simulation: bool = True):
|
||||
"""Run agent with error handling and performance monitoring."""
|
||||
|
||||
agent = Agent(
|
||||
instructions="""You are a resilient AI assistant.
|
||||
Even when facing challenges, you provide helpful responses.
|
||||
If you encounter errors, acknowledge them and offer alternatives.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
try:
|
||||
with track_api_call("robust_agent_request"):
|
||||
print(f"🚀 Processing query: {query}")
|
||||
|
||||
if with_error_simulation and random.random() < 0.2:
|
||||
# Simulate API error
|
||||
raise Exception("Simulated API error")
|
||||
|
||||
result = agent.start(query)
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error during agent execution: {e}")
|
||||
|
||||
# Fallback response with monitoring
|
||||
with track_api_call("fallback_response"):
|
||||
print("🔄 Using fallback response mechanism...")
|
||||
time.sleep(0.1) # Simulate fallback processing
|
||||
return f"I encountered an error while processing '{query}', but I'm designed to be resilient. Let me provide a general response about this topic."
|
||||
|
||||
@monitor_function("batch_processing_with_errors")
|
||||
def process_batch_with_error_handling(batch_size: int = 5):
|
||||
"""Process a batch of operations with comprehensive error handling."""
|
||||
print(f"📦 Processing batch of {batch_size} operations with error monitoring...")
|
||||
|
||||
results = []
|
||||
errors = []
|
||||
|
||||
for i in range(batch_size):
|
||||
try:
|
||||
result = retry_operation(i + 1)
|
||||
results.append(result)
|
||||
except Exception as e:
|
||||
errors.append(f"Operation {i + 1}: {str(e)}")
|
||||
|
||||
return results, errors
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating error handling with performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 5: Error Handling Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Batch processing with errors
|
||||
print("\n📊 Phase 1: Batch Processing with Error Handling")
|
||||
successes, failures = process_batch_with_error_handling(5)
|
||||
|
||||
print(f"\n📈 Batch Results:")
|
||||
print(f" Successful operations: {len(successes)}")
|
||||
print(f" Failed operations: {len(failures)}")
|
||||
|
||||
# Phase 2: Agent execution with error scenarios
|
||||
print("\n🤖 Phase 2: Agent Execution with Error Scenarios")
|
||||
|
||||
test_queries = [
|
||||
"What is artificial intelligence?",
|
||||
"How do computers work?",
|
||||
"Explain quantum physics",
|
||||
]
|
||||
|
||||
agent_results = []
|
||||
for query in test_queries:
|
||||
try:
|
||||
result = run_robust_agent(query, with_error_simulation=True)
|
||||
agent_results.append(result)
|
||||
print(f"✅ Query processed: '{query[:30]}...'")
|
||||
except Exception as e:
|
||||
print(f"❌ Query failed: '{query[:30]}...' - {e}")
|
||||
|
||||
# Performance Analysis with Error Metrics
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 ERROR HANDLING PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Function performance with error rates
|
||||
print("\n📈 Function Performance (including errors):")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
error_rate = data['error_count'] / data['call_count'] * 100 if data['call_count'] > 0 else 0
|
||||
success_rate = 100 - error_rate
|
||||
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Errors: {data['error_count']}")
|
||||
print(f" Success Rate: {success_rate:.1f}%")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
|
||||
# API call reliability
|
||||
print("\n🌐 API Call Reliability:")
|
||||
api_stats = get_api_stats()
|
||||
for api_name, stats in api_stats.items():
|
||||
success_rate = stats['success_count'] / stats['call_count'] * 100 if stats['call_count'] > 0 else 0
|
||||
avg_time = stats['total_time'] / stats['call_count'] if stats['call_count'] > 0 else 0
|
||||
|
||||
print(f" {api_name}:")
|
||||
print(f" Success Rate: {success_rate:.1f}%")
|
||||
print(f" Average Response Time: {avg_time:.3f}s")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
|
||||
# Error patterns analysis
|
||||
print("\n⚠️ Error Patterns:")
|
||||
total_operations = sum(s['call_count'] for s in api_stats.values())
|
||||
total_errors = sum(s['error_count'] for s in api_stats.values())
|
||||
overall_success_rate = ((total_operations - total_errors) / total_operations * 100) if total_operations > 0 else 0
|
||||
|
||||
print(f" Total Operations: {total_operations}")
|
||||
print(f" Total Errors: {total_errors}")
|
||||
print(f" Overall Success Rate: {overall_success_rate:.1f}%")
|
||||
|
||||
# Recommendations
|
||||
print(f"\n💡 Performance Recommendations:")
|
||||
if overall_success_rate < 90:
|
||||
print(" - Consider implementing more robust error handling")
|
||||
print(" - Review retry strategies and backoff algorithms")
|
||||
if total_errors > 0:
|
||||
print(f" - Investigate {total_errors} errors for root cause analysis")
|
||||
print(" - Monitor error patterns for system reliability improvements")
|
||||
|
||||
return {
|
||||
'successful_operations': len(successes),
|
||||
'failed_operations': len(failures),
|
||||
'agent_results': len(agent_results),
|
||||
'overall_success_rate': overall_success_rate
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Error handling monitoring completed!")
|
||||
print(f"Success rate: {result['overall_success_rate']:.1f}%")
|
||||
@@ -0,0 +1,218 @@
|
||||
"""
|
||||
Memory Agent with Performance Monitoring - Example 6
|
||||
|
||||
Demonstrates performance monitoring for agents with memory capabilities:
|
||||
- Memory storage and retrieval timing
|
||||
- Knowledge base operations
|
||||
- Session persistence performance
|
||||
- Memory search optimization
|
||||
|
||||
Shows how to monitor performance in stateful agents.
|
||||
"""
|
||||
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_performance_report,
|
||||
get_slowest_functions, analyze_performance_trends
|
||||
)
|
||||
|
||||
# Simulate memory operations since actual memory might not be available
|
||||
@monitor_function("memory_storage")
|
||||
def store_memory(key: str, value: str, memory_type: str = "short_term"):
|
||||
"""Simulate memory storage operation with monitoring."""
|
||||
print(f"💾 Storing {memory_type} memory: {key}")
|
||||
# Simulate storage time - short term is faster
|
||||
storage_time = 0.05 if memory_type == "short_term" else 0.15
|
||||
time.sleep(storage_time)
|
||||
return f"Stored {key} in {memory_type} memory"
|
||||
|
||||
@monitor_function("memory_retrieval")
|
||||
def retrieve_memory(key: str, memory_type: str = "short_term"):
|
||||
"""Simulate memory retrieval operation with monitoring."""
|
||||
print(f"🔍 Retrieving {memory_type} memory: {key}")
|
||||
# Simulate retrieval time
|
||||
retrieval_time = 0.03 if memory_type == "short_term" else 0.12
|
||||
time.sleep(retrieval_time)
|
||||
return f"Retrieved {key} from {memory_type} memory"
|
||||
|
||||
@monitor_function("knowledge_search")
|
||||
def search_knowledge_base(query: str):
|
||||
"""Simulate knowledge base search with monitoring."""
|
||||
print(f"📚 Searching knowledge base for: {query}")
|
||||
# Simulate vector search time
|
||||
time.sleep(0.08)
|
||||
return f"Knowledge search results for: {query}"
|
||||
|
||||
@monitor_function("memory_consolidation")
|
||||
def consolidate_memories(session_id: str):
|
||||
"""Simulate memory consolidation process."""
|
||||
print(f"🔄 Consolidating memories for session: {session_id}")
|
||||
|
||||
# Simulate consolidation steps
|
||||
store_memory("consolidated_session", session_id, "long_term")
|
||||
retrieve_memory("recent_interactions", "short_term")
|
||||
|
||||
time.sleep(0.1)
|
||||
return f"Memories consolidated for session: {session_id}"
|
||||
|
||||
@monitor_function("stateful_agent_interaction")
|
||||
def run_stateful_agent(query: str, session_id: str, conversation_turn: int):
|
||||
"""Run agent with memory operations and monitoring."""
|
||||
|
||||
# Simulate memory-enabled agent
|
||||
agent = Agent(
|
||||
instructions="""You are a memory-enabled AI assistant. You can remember
|
||||
previous conversations and build on past interactions. Use your memory
|
||||
to provide personalized and contextual responses.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Pre-processing: retrieve relevant memories
|
||||
with track_api_call("memory_preprocessing"):
|
||||
print(f"🧠 Pre-processing memories for turn {conversation_turn}")
|
||||
|
||||
# Retrieve session context
|
||||
if conversation_turn > 1:
|
||||
retrieve_memory(f"session_{session_id}", "short_term")
|
||||
|
||||
# Search for relevant knowledge
|
||||
search_knowledge_base(query)
|
||||
|
||||
time.sleep(0.05) # Simulate context preparation
|
||||
|
||||
# Main agent execution
|
||||
with track_api_call("memory_agent_execution"):
|
||||
print(f"🚀 Processing query with memory context...")
|
||||
result = agent.start(query)
|
||||
|
||||
# Post-processing: store new memories
|
||||
with track_api_call("memory_postprocessing"):
|
||||
print(f"💭 Post-processing: storing interaction memories")
|
||||
|
||||
# Store the interaction
|
||||
store_memory(f"interaction_{conversation_turn}", query, "short_term")
|
||||
store_memory(f"response_{conversation_turn}", result, "short_term")
|
||||
|
||||
# Update session memory
|
||||
store_memory(f"session_{session_id}", f"Turn {conversation_turn} completed", "short_term")
|
||||
|
||||
time.sleep(0.03) # Simulate memory update
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("multi_turn_conversation")
|
||||
def simulate_multi_turn_conversation():
|
||||
"""Simulate a multi-turn conversation with memory."""
|
||||
session_id = "demo_session_001"
|
||||
|
||||
conversation = [
|
||||
"Hello, I'm interested in learning about machine learning",
|
||||
"What are the main types of machine learning algorithms?",
|
||||
"Can you give me examples of supervised learning?",
|
||||
"How does this relate to what we discussed about machine learning earlier?"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for turn, query in enumerate(conversation, 1):
|
||||
print(f"\n💬 Conversation Turn {turn}")
|
||||
print(f"User: {query}")
|
||||
|
||||
result = run_stateful_agent(query, session_id, turn)
|
||||
results.append(result)
|
||||
|
||||
print(f"Agent: {result[:100]}..." if len(result) > 100 else f"Agent: {result}")
|
||||
|
||||
# Simulate user thinking time
|
||||
time.sleep(0.1)
|
||||
|
||||
# End of conversation: consolidate memories
|
||||
consolidate_memories(session_id)
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating memory agent performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 6: Memory Agent Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Warm up the memory system
|
||||
print("\n🚀 Phase 1: Memory System Initialization")
|
||||
store_memory("system_initialized", "true", "long_term")
|
||||
search_knowledge_base("initialization")
|
||||
|
||||
# Run multi-turn conversation
|
||||
print("\n💬 Phase 2: Multi-Turn Conversation with Memory")
|
||||
conversation_results = simulate_multi_turn_conversation()
|
||||
|
||||
# Memory performance analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 MEMORY PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Performance trends analysis
|
||||
print("\n📈 Performance Trends:")
|
||||
try:
|
||||
trends = analyze_performance_trends()
|
||||
print(f" Performance trend analysis completed")
|
||||
if trends:
|
||||
print(f" Functions analyzed: {len(trends.get('functions', []))}")
|
||||
except Exception as e:
|
||||
print(f" Trends analysis: {str(e)}")
|
||||
|
||||
# Slowest operations
|
||||
print("\n🐌 Slowest Memory Operations:")
|
||||
slowest = get_slowest_functions()
|
||||
for func_name, avg_time in slowest[:5]: # Top 5 slowest
|
||||
print(f" {func_name}: {avg_time:.3f}s average")
|
||||
|
||||
# Memory operation breakdown
|
||||
print("\n💾 Memory Operation Breakdown:")
|
||||
from praisonaiagents.telemetry import get_function_stats
|
||||
stats = get_function_stats()
|
||||
|
||||
memory_operations = {k: v for k, v in stats.items() if 'memory' in k.lower()}
|
||||
|
||||
for op_name, data in memory_operations.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {op_name}:")
|
||||
print(f" Operations: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Session efficiency metrics
|
||||
total_memory_ops = sum(data['call_count'] for data in memory_operations.values())
|
||||
total_memory_time = sum(data['total_time'] for data in memory_operations.values())
|
||||
|
||||
print(f"\n🔍 Session Efficiency:")
|
||||
print(f" Total Memory Operations: {total_memory_ops}")
|
||||
print(f" Total Memory Time: {total_memory_time:.3f}s")
|
||||
print(f" Avg Time per Memory Op: {total_memory_time/total_memory_ops:.3f}s" if total_memory_ops > 0 else " No memory operations")
|
||||
|
||||
# Performance report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:400] + "..." if len(report) > 400 else report)
|
||||
|
||||
# Memory optimization suggestions
|
||||
print(f"\n💡 Memory Optimization Suggestions:")
|
||||
if total_memory_time > 1.0:
|
||||
print(" - Consider implementing memory caching strategies")
|
||||
print(" - Optimize vector search indexes for faster retrieval")
|
||||
if total_memory_ops > 10:
|
||||
print(" - Consider batching memory operations for efficiency")
|
||||
print(" - Monitor memory consolidation frequency vs performance")
|
||||
|
||||
return {
|
||||
'conversation_turns': len(conversation_results),
|
||||
'memory_operations': total_memory_ops,
|
||||
'total_memory_time': total_memory_time
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Memory agent monitoring completed!")
|
||||
print(f"Processed {result['conversation_turns']} conversation turns")
|
||||
print(f"Executed {result['memory_operations']} memory operations in {result['total_memory_time']:.3f}s")
|
||||
@@ -0,0 +1,264 @@
|
||||
"""
|
||||
Hierarchical Agents with Performance Monitoring - Example 7
|
||||
|
||||
Demonstrates performance monitoring for hierarchical agent systems:
|
||||
- Manager-worker agent relationships
|
||||
- Task delegation timing
|
||||
- Hierarchical decision making performance
|
||||
- Cross-level communication monitoring
|
||||
|
||||
Shows how to monitor complex organizational agent structures.
|
||||
"""
|
||||
|
||||
import time
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
visualize_execution_flow, generate_comprehensive_report
|
||||
)
|
||||
|
||||
@monitor_function("manager_decision_making")
|
||||
def make_management_decision(task_description: str):
|
||||
"""Simulate manager decision making process."""
|
||||
print(f"👔 Manager analyzing task: {task_description}")
|
||||
# Simulate decision complexity
|
||||
time.sleep(0.1)
|
||||
|
||||
# Simple task routing logic
|
||||
if "research" in task_description.lower():
|
||||
return "research_worker"
|
||||
elif "analysis" in task_description.lower():
|
||||
return "analysis_worker"
|
||||
elif "report" in task_description.lower():
|
||||
return "writing_worker"
|
||||
else:
|
||||
return "general_worker"
|
||||
|
||||
@monitor_function("task_delegation")
|
||||
def delegate_task(task: str, worker_type: str):
|
||||
"""Simulate task delegation to workers."""
|
||||
print(f"📤 Delegating to {worker_type}: {task}")
|
||||
time.sleep(0.05) # Delegation overhead
|
||||
return f"Task delegated to {worker_type}"
|
||||
|
||||
@monitor_function("worker_execution")
|
||||
def execute_worker_task(worker_name: str, task_description: str):
|
||||
"""Simulate worker executing assigned task."""
|
||||
print(f"⚙️ {worker_name} executing: {task_description}")
|
||||
|
||||
# Different workers have different execution times
|
||||
if "research" in worker_name:
|
||||
time.sleep(0.2) # Research takes longer
|
||||
elif "analysis" in worker_name:
|
||||
time.sleep(0.15) # Analysis is moderate
|
||||
elif "writing" in worker_name:
|
||||
time.sleep(0.1) # Writing is relatively quick
|
||||
else:
|
||||
time.sleep(0.12) # General tasks
|
||||
|
||||
return f"{worker_name} completed: {task_description}"
|
||||
|
||||
@monitor_function("result_aggregation")
|
||||
def aggregate_results(results: list):
|
||||
"""Simulate aggregating results from multiple workers."""
|
||||
print(f"📊 Aggregating {len(results)} worker results...")
|
||||
time.sleep(0.08) # Aggregation time
|
||||
return f"Aggregated {len(results)} results into final output"
|
||||
|
||||
@monitor_function("hierarchical_workflow")
|
||||
def run_hierarchical_workflow():
|
||||
"""Run a complete hierarchical workflow with monitoring."""
|
||||
|
||||
# Create manager agent
|
||||
manager = Agent(
|
||||
name="project_manager",
|
||||
role="Project Manager",
|
||||
goal="Efficiently coordinate team efforts and ensure project success",
|
||||
backstory="Experienced project manager with expertise in team coordination",
|
||||
instructions="""You are a project manager. Break down complex projects into tasks,
|
||||
assign them to appropriate team members, and coordinate the overall effort.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create worker agents
|
||||
research_worker = Agent(
|
||||
name="research_specialist",
|
||||
role="Research Specialist",
|
||||
goal="Conduct thorough research on assigned topics",
|
||||
backstory="Expert researcher with deep analytical skills",
|
||||
instructions="You are a research specialist. Provide detailed, factual information.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
analysis_worker = Agent(
|
||||
name="data_analyst",
|
||||
role="Data Analyst",
|
||||
goal="Analyze data and identify patterns and insights",
|
||||
backstory="Experienced data analyst with strong analytical thinking",
|
||||
instructions="You are a data analyst. Focus on patterns, trends, and insights.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
writing_worker = Agent(
|
||||
name="technical_writer",
|
||||
role="Technical Writer",
|
||||
goal="Create clear, well-structured documentation and reports",
|
||||
backstory="Professional writer specializing in technical content",
|
||||
instructions="You are a technical writer. Create clear, comprehensive reports.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Project tasks
|
||||
project_tasks = [
|
||||
"Research current trends in artificial intelligence",
|
||||
"Analyze the impact of AI on business productivity",
|
||||
"Write a comprehensive report on AI implementation strategies"
|
||||
]
|
||||
|
||||
# Execute hierarchical workflow
|
||||
with track_api_call("hierarchical_project_execution"):
|
||||
print("🏢 Starting hierarchical project execution...")
|
||||
|
||||
all_results = []
|
||||
|
||||
for task_desc in project_tasks:
|
||||
print(f"\n📋 Processing project task: {task_desc}")
|
||||
|
||||
# Manager makes decision
|
||||
assigned_worker = make_management_decision(task_desc)
|
||||
|
||||
# Delegate task
|
||||
delegation_result = delegate_task(task_desc, assigned_worker)
|
||||
|
||||
# Select appropriate worker
|
||||
if "research" in assigned_worker:
|
||||
worker = research_worker
|
||||
worker_name = "research_specialist"
|
||||
elif "analysis" in assigned_worker:
|
||||
worker = analysis_worker
|
||||
worker_name = "data_analyst"
|
||||
elif "writing" in assigned_worker:
|
||||
worker = writing_worker
|
||||
worker_name = "technical_writer"
|
||||
else:
|
||||
worker = research_worker # Default
|
||||
worker_name = "research_specialist"
|
||||
|
||||
# Worker executes task
|
||||
worker_result = execute_worker_task(worker_name, task_desc)
|
||||
|
||||
# Simulate actual agent execution
|
||||
with track_api_call(f"{worker_name}_llm_execution"):
|
||||
agent_result = worker.start(task_desc)
|
||||
all_results.append(agent_result)
|
||||
|
||||
# Manager aggregates results
|
||||
final_result = aggregate_results(all_results)
|
||||
|
||||
# Final manager review
|
||||
with track_api_call("manager_final_review"):
|
||||
print("👔 Manager conducting final review...")
|
||||
manager_review = manager.start(
|
||||
f"Review and synthesize these team outputs: {[r[:100] + '...' for r in all_results]}"
|
||||
)
|
||||
|
||||
return all_results, manager_review
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating hierarchical agents performance monitoring."""
|
||||
print("=" * 75)
|
||||
print("EXAMPLE 7: Hierarchical Agents Performance Monitoring")
|
||||
print("=" * 75)
|
||||
|
||||
# Run hierarchical workflow
|
||||
print("\n🏢 Running Hierarchical Agent Workflow")
|
||||
worker_results, manager_review = run_hierarchical_workflow()
|
||||
|
||||
print(f"\n✅ Workflow completed with {len(worker_results)} task results")
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 75)
|
||||
print("📊 HIERARCHICAL PERFORMANCE ANALYSIS")
|
||||
print("=" * 75)
|
||||
|
||||
# Role-based performance breakdown
|
||||
print("\n👥 Role-Based Performance:")
|
||||
stats = get_function_stats()
|
||||
|
||||
# Categorize functions by role
|
||||
management_functions = [f for f in stats.keys() if 'manager' in f or 'decision' in f or 'delegation' in f or 'aggregation' in f]
|
||||
worker_functions = [f for f in stats.keys() if 'worker' in f or 'execution' in f]
|
||||
coordination_functions = [f for f in stats.keys() if 'hierarchical' in f or 'workflow' in f]
|
||||
|
||||
print(" 📋 Management Functions:")
|
||||
for func in management_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
print("\n ⚙️ Worker Functions:")
|
||||
for func in worker_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
print("\n 🔄 Coordination Functions:")
|
||||
for func in coordination_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
# Hierarchy efficiency metrics
|
||||
total_management_time = sum(stats[f]['total_time'] for f in management_functions)
|
||||
total_worker_time = sum(stats[f]['total_time'] for f in worker_functions)
|
||||
total_coordination_time = sum(stats[f]['total_time'] for f in coordination_functions)
|
||||
|
||||
print(f"\n⚖️ Hierarchy Efficiency Metrics:")
|
||||
print(f" Management Overhead: {total_management_time:.3f}s")
|
||||
print(f" Worker Execution Time: {total_worker_time:.3f}s")
|
||||
print(f" Coordination Overhead: {total_coordination_time:.3f}s")
|
||||
|
||||
total_time = total_management_time + total_worker_time + total_coordination_time
|
||||
if total_time > 0:
|
||||
print(f" Worker Efficiency: {total_worker_time/total_time*100:.1f}%")
|
||||
print(f" Management Overhead: {total_management_time/total_time*100:.1f}%")
|
||||
print(f" Coordination Overhead: {total_coordination_time/total_time*100:.1f}%")
|
||||
|
||||
# Execution flow visualization
|
||||
print("\n🔄 Execution Flow Analysis:")
|
||||
try:
|
||||
flow_viz = visualize_execution_flow()
|
||||
print(" Hierarchical flow visualization generated")
|
||||
print(f" Flow complexity: {len(str(flow_viz)) // 100} units")
|
||||
except Exception as e:
|
||||
print(f" Flow visualization: {str(e)}")
|
||||
|
||||
# Comprehensive report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = generate_comprehensive_report()
|
||||
print(report[:500] + "..." if len(report) > 500 else report)
|
||||
|
||||
# Optimization recommendations
|
||||
print(f"\n💡 Hierarchical Optimization Recommendations:")
|
||||
|
||||
if total_time > 0:
|
||||
if total_management_time / total_time > 0.3:
|
||||
print(" - High management overhead detected - consider task batching")
|
||||
if total_coordination_time / total_time > 0.2:
|
||||
print(" - Consider reducing coordination complexity")
|
||||
if len(worker_results) > 0:
|
||||
print(f" - Successfully processed {len(worker_results)} tasks hierarchically")
|
||||
print(" - Monitor delegation efficiency vs direct execution trade-offs")
|
||||
|
||||
return {
|
||||
'tasks_completed': len(worker_results),
|
||||
'management_time': total_management_time,
|
||||
'worker_time': total_worker_time,
|
||||
'coordination_time': total_coordination_time,
|
||||
'efficiency_ratio': total_worker_time / total_time if total_time > 0 else 0
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Hierarchical monitoring completed!")
|
||||
print(f"Tasks: {result['tasks_completed']}, Efficiency: {result['efficiency_ratio']*100:.1f}%")
|
||||
@@ -0,0 +1,314 @@
|
||||
"""
|
||||
Custom Tools with Performance Monitoring - Example 8
|
||||
|
||||
Demonstrates performance monitoring for agents using custom tools:
|
||||
- Custom tool execution timing
|
||||
- Tool creation and registration performance
|
||||
- Tool usage pattern analysis
|
||||
- Tool efficiency optimization
|
||||
|
||||
Shows how to monitor performance with custom-built tools.
|
||||
"""
|
||||
|
||||
import time
|
||||
import random
|
||||
from praisonaiagents import Agent, tool
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
get_slowest_functions, performance_monitor
|
||||
)
|
||||
|
||||
# Custom Tool 1: Data Processor
|
||||
@tool
|
||||
@monitor_function("data_processor_tool")
|
||||
def process_data(data: str, operation: str = "analyze") -> str:
|
||||
"""
|
||||
Process data with specified operation.
|
||||
|
||||
Args:
|
||||
data: The data to process
|
||||
operation: Type of operation (analyze, transform, validate)
|
||||
"""
|
||||
print(f"🔧 Processing data with operation: {operation}")
|
||||
|
||||
# Simulate different processing times based on operation
|
||||
processing_times = {
|
||||
"analyze": 0.15,
|
||||
"transform": 0.2,
|
||||
"validate": 0.1
|
||||
}
|
||||
|
||||
time.sleep(processing_times.get(operation, 0.12))
|
||||
|
||||
return f"Data processed with {operation}: {data[:50]}{'...' if len(data) > 50 else ''}"
|
||||
|
||||
# Custom Tool 2: API Simulator
|
||||
@tool
|
||||
@monitor_function("api_simulator_tool")
|
||||
def call_external_api(endpoint: str, method: str = "GET", payload: str = "") -> str:
|
||||
"""
|
||||
Simulate calling an external API.
|
||||
|
||||
Args:
|
||||
endpoint: API endpoint to call
|
||||
method: HTTP method (GET, POST, PUT, DELETE)
|
||||
payload: Request payload for POST/PUT
|
||||
"""
|
||||
print(f"🌐 Calling API: {method} {endpoint}")
|
||||
|
||||
# Simulate variable API response times
|
||||
base_time = 0.1
|
||||
if method == "POST":
|
||||
base_time += 0.05
|
||||
if payload:
|
||||
base_time += len(payload) * 0.001
|
||||
|
||||
# Add random variation
|
||||
response_time = base_time + random.uniform(0, 0.1)
|
||||
time.sleep(response_time)
|
||||
|
||||
# Simulate occasional API failures
|
||||
if random.random() < 0.1: # 10% failure rate
|
||||
raise Exception(f"API call to {endpoint} failed")
|
||||
|
||||
return f"API Response from {endpoint}: {{'status': 'success', 'method': '{method}'}}"
|
||||
|
||||
# Custom Tool 3: Database Simulator
|
||||
@tool
|
||||
@monitor_function("database_simulator_tool")
|
||||
def query_database(query: str, database: str = "main") -> str:
|
||||
"""
|
||||
Simulate database query execution.
|
||||
|
||||
Args:
|
||||
query: SQL query to execute
|
||||
database: Database name to query
|
||||
"""
|
||||
print(f"🗄️ Executing database query on {database}")
|
||||
|
||||
# Simulate query complexity based on keywords
|
||||
complexity_keywords = {
|
||||
"JOIN": 0.08,
|
||||
"GROUP BY": 0.06,
|
||||
"ORDER BY": 0.04,
|
||||
"WHERE": 0.03
|
||||
}
|
||||
|
||||
query_time = 0.05 # Base query time
|
||||
for keyword, additional_time in complexity_keywords.items():
|
||||
if keyword in query.upper():
|
||||
query_time += additional_time
|
||||
|
||||
time.sleep(query_time)
|
||||
|
||||
return f"Query executed on {database}: Found {random.randint(1, 100)} results"
|
||||
|
||||
# Custom Tool 4: File Operations
|
||||
@tool
|
||||
@monitor_function("file_operations_tool")
|
||||
def file_operation(operation: str, filename: str, content: str = "") -> str:
|
||||
"""
|
||||
Simulate file operations.
|
||||
|
||||
Args:
|
||||
operation: Operation type (read, write, delete, copy)
|
||||
filename: Target filename
|
||||
content: Content for write operations
|
||||
"""
|
||||
print(f"📁 File operation: {operation} on {filename}")
|
||||
|
||||
# Simulate different operation times
|
||||
operation_times = {
|
||||
"read": 0.03,
|
||||
"write": 0.05,
|
||||
"delete": 0.02,
|
||||
"copy": 0.07
|
||||
}
|
||||
|
||||
time.sleep(operation_times.get(operation, 0.04))
|
||||
|
||||
if operation == "write" and content:
|
||||
time.sleep(len(content) * 0.0001) # Simulate write time based on content size
|
||||
|
||||
return f"File {operation} completed for {filename}"
|
||||
|
||||
@monitor_function("tool_performance_test")
|
||||
def test_tool_performance():
|
||||
"""Test individual tool performance."""
|
||||
print("🧪 Testing individual tool performance...")
|
||||
|
||||
# Test each tool multiple times
|
||||
tools_results = []
|
||||
|
||||
# Test data processor
|
||||
for op in ["analyze", "transform", "validate"]:
|
||||
result = process_data("Sample data for testing", op)
|
||||
tools_results.append(f"DataProcessor[{op}]: {result}")
|
||||
|
||||
# Test API simulator
|
||||
for method in ["GET", "POST"]:
|
||||
try:
|
||||
result = call_external_api("/api/test", method, "test payload" if method == "POST" else "")
|
||||
tools_results.append(f"APISimulator[{method}]: {result}")
|
||||
except Exception as e:
|
||||
tools_results.append(f"APISimulator[{method}]: Failed - {e}")
|
||||
|
||||
# Test database operations
|
||||
queries = [
|
||||
"SELECT * FROM users",
|
||||
"SELECT COUNT(*) FROM orders WHERE date > '2024-01-01'",
|
||||
"SELECT u.name, COUNT(o.id) FROM users u JOIN orders o GROUP BY u.id"
|
||||
]
|
||||
|
||||
for query in queries:
|
||||
result = query_database(query)
|
||||
tools_results.append(f"Database: {result}")
|
||||
|
||||
# Test file operations
|
||||
for op in ["read", "write", "copy"]:
|
||||
result = file_operation(op, "test_file.txt", "Test content" if op == "write" else "")
|
||||
tools_results.append(f"FileOps[{op}]: {result}")
|
||||
|
||||
return tools_results
|
||||
|
||||
@monitor_function("agent_with_custom_tools")
|
||||
def run_agent_with_custom_tools():
|
||||
"""Run agent using custom tools with performance monitoring."""
|
||||
|
||||
# Create agent with custom tools
|
||||
agent = Agent(
|
||||
instructions="""You are a technical assistant with access to various tools.
|
||||
Use the appropriate tools to help with data processing, API calls, database queries,
|
||||
and file operations. Always explain what tools you're using and why.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=[process_data, call_external_api, query_database, file_operation]
|
||||
)
|
||||
|
||||
# Test scenarios for the agent
|
||||
scenarios = [
|
||||
"I need to analyze some customer data and store the results",
|
||||
"Please fetch user information from the API and save it to a file",
|
||||
"Query the database for recent orders and process the results"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for i, scenario in enumerate(scenarios, 1):
|
||||
print(f"\n🎯 Scenario {i}: {scenario}")
|
||||
|
||||
with track_api_call(f"custom_tools_scenario_{i}"):
|
||||
try:
|
||||
result = agent.start(scenario)
|
||||
results.append(result)
|
||||
print(f"✅ Scenario {i} completed")
|
||||
except Exception as e:
|
||||
print(f"❌ Scenario {i} failed: {e}")
|
||||
results.append(f"Failed: {e}")
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating custom tools performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 8: Custom Tools Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Individual tool performance testing
|
||||
print("\n🔧 Phase 1: Individual Tool Performance Testing")
|
||||
tool_test_results = test_tool_performance()
|
||||
|
||||
print(f"\n📊 Tool Test Summary:")
|
||||
print(f" Total tool operations: {len(tool_test_results)}")
|
||||
for result in tool_test_results[:5]: # Show first 5 results
|
||||
print(f" - {result}")
|
||||
if len(tool_test_results) > 5:
|
||||
print(f" ... and {len(tool_test_results) - 5} more")
|
||||
|
||||
# Phase 2: Agent using custom tools
|
||||
print("\n🤖 Phase 2: Agent with Custom Tools")
|
||||
agent_results = run_agent_with_custom_tools()
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 CUSTOM TOOLS PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Tool-specific performance
|
||||
print("\n🔧 Tool Performance Breakdown:")
|
||||
stats = get_function_stats()
|
||||
tool_functions = {k: v for k, v in stats.items() if 'tool' in k.lower()}
|
||||
|
||||
for tool_name, data in tool_functions.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {tool_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
if data['error_count'] > 0:
|
||||
print(f" Errors: {data['error_count']}")
|
||||
|
||||
# Tool efficiency ranking
|
||||
print("\n🏆 Tool Efficiency Ranking (by average execution time):")
|
||||
tool_efficiency = []
|
||||
for tool_name, data in tool_functions.items():
|
||||
if data['call_count'] > 0:
|
||||
avg_time = data['total_time'] / data['call_count']
|
||||
tool_efficiency.append((tool_name, avg_time))
|
||||
|
||||
tool_efficiency.sort(key=lambda x: x[1])
|
||||
|
||||
for rank, (tool_name, avg_time) in enumerate(tool_efficiency, 1):
|
||||
print(f" {rank}. {tool_name}: {avg_time:.3f}s")
|
||||
|
||||
# Slowest operations
|
||||
print("\n🐌 Slowest Tool Operations:")
|
||||
slowest = get_slowest_functions()
|
||||
tool_slowest = [(name, time) for name, time in slowest if 'tool' in name.lower()]
|
||||
|
||||
for tool_name, avg_time in tool_slowest[:3]:
|
||||
print(f" {tool_name}: {avg_time:.3f}s")
|
||||
|
||||
# Usage patterns
|
||||
total_tool_calls = sum(data['call_count'] for data in tool_functions.values())
|
||||
total_tool_time = sum(data['total_time'] for data in tool_functions.values())
|
||||
|
||||
print(f"\n📈 Tool Usage Summary:")
|
||||
print(f" Total Tool Calls: {total_tool_calls}")
|
||||
print(f" Total Tool Execution Time: {total_tool_time:.3f}s")
|
||||
print(f" Average Time per Tool Call: {total_tool_time/total_tool_calls:.3f}s" if total_tool_calls > 0 else " No tool calls")
|
||||
|
||||
# Tool reliability
|
||||
total_tool_errors = sum(data['error_count'] for data in tool_functions.values())
|
||||
reliability = ((total_tool_calls - total_tool_errors) / total_tool_calls * 100) if total_tool_calls > 0 else 100
|
||||
|
||||
print(f" Tool Reliability: {reliability:.1f}%")
|
||||
if total_tool_errors > 0:
|
||||
print(f" Total Errors: {total_tool_errors}")
|
||||
|
||||
# Optimization recommendations
|
||||
print(f"\n💡 Custom Tools Optimization Recommendations:")
|
||||
|
||||
if tool_efficiency:
|
||||
slowest_tool = tool_efficiency[-1]
|
||||
if slowest_tool[1] > 0.2:
|
||||
print(f" - Optimize {slowest_tool[0]} (slowest at {slowest_tool[1]:.3f}s)")
|
||||
|
||||
if total_tool_errors > 0:
|
||||
print(f" - Investigate {total_tool_errors} tool errors for stability improvements")
|
||||
|
||||
if total_tool_calls > 20:
|
||||
print(" - Consider tool caching for frequently used operations")
|
||||
|
||||
print(" - Monitor tool usage patterns for optimization opportunities")
|
||||
|
||||
return {
|
||||
'tool_operations': len(tool_test_results),
|
||||
'agent_scenarios': len(agent_results),
|
||||
'total_tool_calls': total_tool_calls,
|
||||
'tool_reliability': reliability
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Custom tools monitoring completed!")
|
||||
print(f"Operations: {result['tool_operations']}, Reliability: {result['tool_reliability']:.1f}%")
|
||||
@@ -0,0 +1,286 @@
|
||||
"""
|
||||
Streaming & Real-Time Performance Monitoring - Example 9
|
||||
|
||||
Demonstrates performance monitoring for streaming and real-time operations:
|
||||
- Real-time performance tracking
|
||||
- Streaming response monitoring
|
||||
- Live performance metrics
|
||||
- Continuous performance analysis
|
||||
|
||||
Shows how to monitor performance during streaming operations.
|
||||
"""
|
||||
|
||||
import time
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
get_performance_report, get_function_stats
|
||||
)
|
||||
|
||||
# Global variables for streaming simulation
|
||||
streaming_active = False
|
||||
streaming_stats = {
|
||||
'messages_processed': 0,
|
||||
'total_latency': 0.0,
|
||||
'errors': 0,
|
||||
'start_time': None
|
||||
}
|
||||
|
||||
@monitor_function("stream_message_processing")
|
||||
def process_stream_message(message_id: int, content: str):
|
||||
"""Process a single streaming message with monitoring."""
|
||||
processing_start = time.time()
|
||||
|
||||
print(f"📨 Processing stream message {message_id}: {content[:30]}...")
|
||||
|
||||
# Simulate variable processing time
|
||||
processing_time = 0.05 + (message_id % 3) * 0.02 # Simulate varying complexity
|
||||
time.sleep(processing_time)
|
||||
|
||||
# Simulate occasional errors
|
||||
if message_id % 20 == 0: # Every 20th message fails
|
||||
raise Exception(f"Processing error for message {message_id}")
|
||||
|
||||
processing_end = time.time()
|
||||
latency = processing_end - processing_start
|
||||
|
||||
# Update streaming stats
|
||||
streaming_stats['messages_processed'] += 1
|
||||
streaming_stats['total_latency'] += latency
|
||||
|
||||
return f"Processed message {message_id} in {latency:.3f}s"
|
||||
|
||||
@monitor_function("real_time_agent_response")
|
||||
def get_real_time_agent_response(query: str, response_id: int):
|
||||
"""Simulate real-time agent response with monitoring."""
|
||||
print(f"🤖 Generating real-time response {response_id} for: {query}")
|
||||
|
||||
# Create a lightweight agent for streaming
|
||||
agent = Agent(
|
||||
instructions="You are a real-time assistant. Provide quick, helpful responses.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
with track_api_call(f"streaming_response_{response_id}"):
|
||||
# Simulate streaming response generation
|
||||
time.sleep(0.1) # Base response time
|
||||
|
||||
# In real implementation, this would be actual agent.start()
|
||||
response = agent.start(f"Quickly respond to: {query}")
|
||||
|
||||
return response
|
||||
|
||||
@monitor_function("performance_metrics_collector")
|
||||
def collect_live_metrics():
|
||||
"""Collect live performance metrics during streaming."""
|
||||
|
||||
while streaming_active:
|
||||
current_time = time.time()
|
||||
|
||||
# Collect current performance data
|
||||
current_stats = performance_monitor.get_function_performance()
|
||||
api_stats = performance_monitor.get_api_call_performance()
|
||||
|
||||
# Calculate streaming metrics
|
||||
if streaming_stats['start_time']:
|
||||
elapsed_time = current_time - streaming_stats['start_time']
|
||||
messages_per_second = streaming_stats['messages_processed'] / elapsed_time if elapsed_time > 0 else 0
|
||||
avg_latency = streaming_stats['total_latency'] / streaming_stats['messages_processed'] if streaming_stats['messages_processed'] > 0 else 0
|
||||
|
||||
print(f"📊 Live Metrics - Messages/sec: {messages_per_second:.2f}, Avg Latency: {avg_latency:.3f}s")
|
||||
|
||||
time.sleep(2) # Update every 2 seconds
|
||||
|
||||
@monitor_function("streaming_simulation")
|
||||
def simulate_streaming_workload():
|
||||
"""Simulate a streaming workload with continuous monitoring."""
|
||||
global streaming_active, streaming_stats
|
||||
|
||||
print("🌊 Starting streaming simulation...")
|
||||
streaming_active = True
|
||||
streaming_stats['start_time'] = time.time()
|
||||
|
||||
# Start metrics collector in background
|
||||
metrics_thread = threading.Thread(target=collect_live_metrics)
|
||||
metrics_thread.daemon = True
|
||||
metrics_thread.start()
|
||||
|
||||
# Simulate incoming stream messages
|
||||
messages = [
|
||||
"User question about AI",
|
||||
"Request for weather information",
|
||||
"Help with programming",
|
||||
"General knowledge query",
|
||||
"Technical support request",
|
||||
"Creative writing assistance",
|
||||
"Data analysis question",
|
||||
"Research inquiry"
|
||||
]
|
||||
|
||||
processed_responses = []
|
||||
|
||||
try:
|
||||
for i in range(20): # Process 20 streaming messages
|
||||
message = messages[i % len(messages)]
|
||||
|
||||
try:
|
||||
# Process the stream message
|
||||
result = process_stream_message(i + 1, message)
|
||||
|
||||
# Generate real-time response every 3rd message
|
||||
if (i + 1) % 3 == 0:
|
||||
response = get_real_time_agent_response(message, i + 1)
|
||||
processed_responses.append(response)
|
||||
|
||||
# Brief pause between messages
|
||||
time.sleep(0.1)
|
||||
|
||||
except Exception as e:
|
||||
streaming_stats['errors'] += 1
|
||||
print(f"❌ Error processing message {i + 1}: {e}")
|
||||
|
||||
finally:
|
||||
streaming_active = False
|
||||
print("🛑 Streaming simulation completed")
|
||||
|
||||
return processed_responses
|
||||
|
||||
@monitor_function("batch_vs_streaming_comparison")
|
||||
def compare_batch_vs_streaming():
|
||||
"""Compare batch vs streaming performance."""
|
||||
|
||||
print("\n🔄 Comparing Batch vs Streaming Performance...")
|
||||
|
||||
# Batch processing simulation
|
||||
print("\n📦 Batch Processing Test:")
|
||||
batch_start = time.time()
|
||||
|
||||
batch_messages = [f"Batch message {i}" for i in range(10)]
|
||||
batch_results = []
|
||||
|
||||
with track_api_call("batch_processing"):
|
||||
for i, message in enumerate(batch_messages):
|
||||
# Simulate batch processing (all at once)
|
||||
time.sleep(0.08) # Batch processing time
|
||||
batch_results.append(f"Batch processed: {message}")
|
||||
|
||||
batch_time = time.time() - batch_start
|
||||
|
||||
# Streaming processing test (already done above)
|
||||
streaming_time = streaming_stats['total_latency']
|
||||
streaming_count = streaming_stats['messages_processed']
|
||||
|
||||
print(f"\n📊 Batch vs Streaming Comparison:")
|
||||
print(f" Batch Processing:")
|
||||
print(f" Messages: {len(batch_results)}")
|
||||
print(f" Total Time: {batch_time:.3f}s")
|
||||
print(f" Avg per Message: {batch_time/len(batch_results):.3f}s")
|
||||
|
||||
print(f" Streaming Processing:")
|
||||
print(f" Messages: {streaming_count}")
|
||||
print(f" Total Processing Time: {streaming_time:.3f}s")
|
||||
print(f" Avg per Message: {streaming_time/streaming_count:.3f}s" if streaming_count > 0 else " No messages processed")
|
||||
|
||||
return batch_time, streaming_time
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating streaming performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 9: Streaming & Real-Time Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Streaming simulation
|
||||
print("\n🌊 Phase 1: Streaming Workload Simulation")
|
||||
streaming_responses = simulate_streaming_workload()
|
||||
|
||||
# Phase 2: Batch vs Streaming comparison
|
||||
print("\n📊 Phase 2: Batch vs Streaming Comparison")
|
||||
batch_time, streaming_time = compare_batch_vs_streaming()
|
||||
|
||||
# Real-time Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 STREAMING PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Streaming-specific metrics
|
||||
print("\n🌊 Streaming Metrics:")
|
||||
elapsed_total = time.time() - streaming_stats['start_time'] if streaming_stats['start_time'] else 0
|
||||
throughput = streaming_stats['messages_processed'] / elapsed_total if elapsed_total > 0 else 0
|
||||
avg_latency = streaming_stats['total_latency'] / streaming_stats['messages_processed'] if streaming_stats['messages_processed'] > 0 else 0
|
||||
error_rate = streaming_stats['errors'] / streaming_stats['messages_processed'] * 100 if streaming_stats['messages_processed'] > 0 else 0
|
||||
|
||||
print(f" Messages Processed: {streaming_stats['messages_processed']}")
|
||||
print(f" Total Processing Time: {streaming_stats['total_latency']:.3f}s")
|
||||
print(f" Average Latency: {avg_latency:.3f}s")
|
||||
print(f" Throughput: {throughput:.2f} messages/second")
|
||||
print(f" Error Rate: {error_rate:.2f}%")
|
||||
print(f" Errors: {streaming_stats['errors']}")
|
||||
|
||||
# Function performance during streaming
|
||||
print("\n⚡ Real-Time Function Performance:")
|
||||
stats = get_function_stats()
|
||||
streaming_functions = {k: v for k, v in stats.items() if 'stream' in k.lower() or 'real_time' in k.lower()}
|
||||
|
||||
for func_name, data in streaming_functions.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Performance trend analysis
|
||||
print("\n📈 Performance Trends:")
|
||||
recent_performance = performance_monitor.get_function_performance()
|
||||
total_functions = len(recent_performance)
|
||||
total_calls = sum(data['call_count'] for data in recent_performance.values())
|
||||
|
||||
print(f" Functions Monitored: {total_functions}")
|
||||
print(f" Total Function Calls: {total_calls}")
|
||||
print(f" Average Calls per Function: {total_calls/total_functions:.1f}" if total_functions > 0 else " No functions monitored")
|
||||
|
||||
# Real-time vs Batch efficiency
|
||||
print(f"\n⚖️ Efficiency Analysis:")
|
||||
if batch_time > 0 and streaming_time > 0:
|
||||
efficiency_gain = (batch_time - streaming_time) / batch_time * 100
|
||||
print(f" Streaming vs Batch Efficiency: {efficiency_gain:+.1f}%")
|
||||
|
||||
if avg_latency > 0:
|
||||
if avg_latency < 0.1:
|
||||
print(" ✅ Excellent real-time performance (< 100ms)")
|
||||
elif avg_latency < 0.2:
|
||||
print(" ⚡ Good real-time performance (< 200ms)")
|
||||
else:
|
||||
print(" ⚠️ Consider optimization for better real-time performance")
|
||||
|
||||
# Current performance report
|
||||
print("\n📋 Current Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:400] + "..." if len(report) > 400 else report)
|
||||
|
||||
# Real-time optimization suggestions
|
||||
print(f"\n💡 Real-Time Optimization Recommendations:")
|
||||
|
||||
if avg_latency > 0.15:
|
||||
print(f" - Optimize message processing (current avg: {avg_latency:.3f}s)")
|
||||
if error_rate > 5:
|
||||
print(f" - Investigate error patterns (current rate: {error_rate:.1f}%)")
|
||||
if throughput < 10:
|
||||
print(f" - Consider parallel processing for better throughput")
|
||||
|
||||
print(" - Monitor memory usage during extended streaming")
|
||||
print(" - Implement adaptive batching for optimal performance")
|
||||
|
||||
return {
|
||||
'streaming_responses': len(streaming_responses),
|
||||
'messages_processed': streaming_stats['messages_processed'],
|
||||
'throughput': throughput,
|
||||
'average_latency': avg_latency,
|
||||
'error_rate': error_rate
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Streaming monitoring completed!")
|
||||
print(f"Throughput: {result['throughput']:.2f} msg/s, Latency: {result['average_latency']:.3f}s")
|
||||
@@ -0,0 +1,433 @@
|
||||
"""
|
||||
Comprehensive Performance Dashboard - Example 10
|
||||
|
||||
Demonstrates comprehensive performance monitoring dashboard:
|
||||
- Complete performance analytics
|
||||
- Advanced reporting and visualization
|
||||
- Performance trends and insights
|
||||
- System-wide monitoring overview
|
||||
|
||||
Shows how to create a comprehensive performance monitoring solution.
|
||||
"""
|
||||
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
get_performance_report, get_function_stats, get_api_stats,
|
||||
get_slowest_functions, get_slowest_apis,
|
||||
analyze_function_flow, visualize_execution_flow,
|
||||
analyze_performance_trends, generate_comprehensive_report,
|
||||
clear_performance_data
|
||||
)
|
||||
|
||||
@monitor_function("dashboard_data_collection")
|
||||
def collect_comprehensive_data():
|
||||
"""Collect comprehensive performance data for dashboard."""
|
||||
|
||||
print("📊 Collecting comprehensive performance data...")
|
||||
|
||||
# Generate diverse workload for demonstration
|
||||
test_scenarios = [
|
||||
("Quick query", "What is AI?"),
|
||||
("Complex analysis", "Analyze the impact of artificial intelligence on modern business practices"),
|
||||
("Research task", "Research the latest developments in quantum computing"),
|
||||
("Creative task", "Write a creative story about space exploration"),
|
||||
("Technical query", "Explain how neural networks process information")
|
||||
]
|
||||
|
||||
# Create different types of agents for variety
|
||||
agents = {
|
||||
'quick_agent': Agent(
|
||||
instructions="You are a quick-response agent. Provide concise answers.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'analytical_agent': Agent(
|
||||
instructions="You are an analytical agent. Provide detailed analysis.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'research_agent': Agent(
|
||||
instructions="You are a research agent. Provide comprehensive information.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'creative_agent': Agent(
|
||||
instructions="You are a creative agent. Provide imaginative responses.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
}
|
||||
|
||||
results = []
|
||||
|
||||
for i, (scenario_type, query) in enumerate(test_scenarios):
|
||||
print(f"\n🎯 Scenario {i+1}: {scenario_type}")
|
||||
|
||||
# Select appropriate agent
|
||||
agent_type = list(agents.keys())[i % len(agents)]
|
||||
agent = agents[agent_type]
|
||||
|
||||
with track_api_call(f"{scenario_type.lower().replace(' ', '_')}_execution"):
|
||||
try:
|
||||
result = agent.start(query)
|
||||
results.append({
|
||||
'scenario': scenario_type,
|
||||
'agent': agent_type,
|
||||
'query': query,
|
||||
'result': result[:200] + '...' if len(result) > 200 else result,
|
||||
'success': True
|
||||
})
|
||||
except Exception as e:
|
||||
results.append({
|
||||
'scenario': scenario_type,
|
||||
'agent': agent_type,
|
||||
'query': query,
|
||||
'error': str(e),
|
||||
'success': False
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
@monitor_function("multi_agent_workflow_simulation")
|
||||
def simulate_complex_workflow():
|
||||
"""Simulate complex multi-agent workflow for comprehensive data."""
|
||||
|
||||
print("🔄 Simulating complex multi-agent workflow...")
|
||||
|
||||
# Create specialized agents
|
||||
planner = Agent(
|
||||
name="planner",
|
||||
instructions="You are a project planner. Break down tasks and plan execution.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
executor = Agent(
|
||||
name="executor",
|
||||
instructions="You are a task executor. Complete assigned tasks efficiently.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
reviewer = Agent(
|
||||
name="reviewer",
|
||||
instructions="You are a quality reviewer. Review and improve work.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create workflow tasks
|
||||
planning_task = Task(
|
||||
name="planning",
|
||||
description="Plan a comprehensive report on renewable energy trends",
|
||||
expected_output="A detailed project plan with timeline and milestones"
|
||||
)
|
||||
|
||||
execution_task = Task(
|
||||
name="execution",
|
||||
description="Execute the planned research and compile findings",
|
||||
expected_output="Research findings and data compilation"
|
||||
)
|
||||
|
||||
review_task = Task(
|
||||
name="review",
|
||||
description="Review the research and provide quality assessment",
|
||||
expected_output="Quality review and improvement recommendations"
|
||||
)
|
||||
|
||||
# Assign agents to tasks
|
||||
planning_task.agent = planner
|
||||
execution_task.agent = executor
|
||||
review_task.agent = reviewer
|
||||
|
||||
# Execute workflow
|
||||
with track_api_call("complex_workflow_execution"):
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[planner, executor, reviewer],
|
||||
tasks=[planning_task, execution_task, review_task],
|
||||
process="sequential",
|
||||
verbose=False
|
||||
)
|
||||
|
||||
result = workflow.start()
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("performance_benchmarking")
|
||||
def run_performance_benchmarks():
|
||||
"""Run performance benchmarks for various operations."""
|
||||
|
||||
print("⚡ Running performance benchmarks...")
|
||||
|
||||
benchmark_results = {}
|
||||
|
||||
# Benchmark 1: Response time under different loads
|
||||
print(" 📈 Benchmarking response times...")
|
||||
response_times = []
|
||||
|
||||
for i in range(10):
|
||||
start_time = time.time()
|
||||
with track_api_call(f"benchmark_response_{i}"):
|
||||
# Simulate quick agent response
|
||||
time.sleep(0.05 + (i % 3) * 0.02) # Variable response time
|
||||
response_times.append(time.time() - start_time)
|
||||
|
||||
benchmark_results['response_times'] = {
|
||||
'min': min(response_times),
|
||||
'max': max(response_times),
|
||||
'avg': sum(response_times) / len(response_times),
|
||||
'samples': len(response_times)
|
||||
}
|
||||
|
||||
# Benchmark 2: Concurrent operations
|
||||
print(" 🔄 Benchmarking concurrent operations...")
|
||||
concurrent_start = time.time()
|
||||
|
||||
# Simulate concurrent operations
|
||||
for i in range(5):
|
||||
with track_api_call(f"concurrent_op_{i}"):
|
||||
time.sleep(0.1) # Simulate concurrent work
|
||||
|
||||
concurrent_time = time.time() - concurrent_start
|
||||
benchmark_results['concurrent_operations'] = {
|
||||
'total_time': concurrent_time,
|
||||
'operations': 5,
|
||||
'avg_per_operation': concurrent_time / 5
|
||||
}
|
||||
|
||||
# Benchmark 3: Memory usage simulation
|
||||
print(" 💾 Benchmarking memory operations...")
|
||||
memory_ops = []
|
||||
|
||||
for i in range(8):
|
||||
start = time.time()
|
||||
with track_api_call(f"memory_benchmark_{i}"):
|
||||
# Simulate memory-intensive operation
|
||||
time.sleep(0.03 + (i % 2) * 0.02)
|
||||
memory_ops.append(time.time() - start)
|
||||
|
||||
benchmark_results['memory_operations'] = {
|
||||
'operations': len(memory_ops),
|
||||
'total_time': sum(memory_ops),
|
||||
'avg_time': sum(memory_ops) / len(memory_ops)
|
||||
}
|
||||
|
||||
return benchmark_results
|
||||
|
||||
@monitor_function("generate_dashboard_report")
|
||||
def generate_dashboard_report():
|
||||
"""Generate comprehensive dashboard report."""
|
||||
|
||||
print("📋 Generating comprehensive dashboard report...")
|
||||
|
||||
# Collect all performance data
|
||||
function_stats = get_function_stats()
|
||||
api_stats = get_api_stats()
|
||||
slowest_functions = get_slowest_functions()
|
||||
slowest_apis = get_slowest_apis()
|
||||
|
||||
# Generate reports
|
||||
basic_report = get_performance_report()
|
||||
comprehensive_report = generate_comprehensive_report()
|
||||
|
||||
# Analyze trends and flows
|
||||
try:
|
||||
flow_analysis = analyze_function_flow()
|
||||
performance_trends = analyze_performance_trends()
|
||||
flow_visualization = visualize_execution_flow()
|
||||
except Exception as e:
|
||||
flow_analysis = {"error": str(e)}
|
||||
performance_trends = {"error": str(e)}
|
||||
flow_visualization = {"error": str(e)}
|
||||
|
||||
dashboard_data = {
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'summary': {
|
||||
'total_functions': len(function_stats),
|
||||
'total_api_calls': len(api_stats),
|
||||
'total_function_calls': sum(stats['call_count'] for stats in function_stats.values()),
|
||||
'total_api_requests': sum(stats['call_count'] for stats in api_stats.values()),
|
||||
'total_execution_time': sum(stats['total_time'] for stats in function_stats.values()),
|
||||
'total_errors': sum(stats['error_count'] for stats in function_stats.values())
|
||||
},
|
||||
'performance_data': {
|
||||
'function_stats': function_stats,
|
||||
'api_stats': api_stats,
|
||||
'slowest_functions': slowest_functions,
|
||||
'slowest_apis': slowest_apis
|
||||
},
|
||||
'analysis': {
|
||||
'flow_analysis': flow_analysis,
|
||||
'performance_trends': performance_trends,
|
||||
'flow_visualization': len(str(flow_visualization)) if flow_visualization else 0
|
||||
},
|
||||
'reports': {
|
||||
'basic_report': basic_report,
|
||||
'comprehensive_report': comprehensive_report[:500] + '...' if len(comprehensive_report) > 500 else comprehensive_report
|
||||
}
|
||||
}
|
||||
|
||||
return dashboard_data
|
||||
|
||||
def display_dashboard(dashboard_data, benchmark_results):
|
||||
"""Display comprehensive performance dashboard."""
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("📊 COMPREHENSIVE PERFORMANCE DASHBOARD")
|
||||
print("=" * 80)
|
||||
|
||||
# Executive Summary
|
||||
summary = dashboard_data['summary']
|
||||
print(f"\n📈 EXECUTIVE SUMMARY")
|
||||
print(f" Report Generated: {dashboard_data['timestamp']}")
|
||||
print(f" Functions Monitored: {summary['total_functions']}")
|
||||
print(f" API Endpoints: {summary['total_api_calls']}")
|
||||
print(f" Total Function Calls: {summary['total_function_calls']}")
|
||||
print(f" Total API Requests: {summary['total_api_requests']}")
|
||||
print(f" Total Execution Time: {summary['total_execution_time']:.3f}s")
|
||||
print(f" Total Errors: {summary['total_errors']}")
|
||||
|
||||
# Performance Overview
|
||||
print(f"\n⚡ PERFORMANCE OVERVIEW")
|
||||
avg_function_time = 0
|
||||
if summary['total_function_calls'] > 0:
|
||||
avg_function_time = summary['total_execution_time'] / summary['total_function_calls']
|
||||
print(f" Average Function Execution: {avg_function_time:.3f}s")
|
||||
|
||||
if summary['total_errors'] > 0 and summary['total_function_calls'] > 0:
|
||||
error_rate = summary['total_errors'] / summary['total_function_calls'] * 100
|
||||
print(f" Error Rate: {error_rate:.2f}%")
|
||||
else:
|
||||
print(f" Error Rate: 0.00%")
|
||||
|
||||
# Top Performers and Issues
|
||||
print(f"\n🏆 TOP PERFORMERS")
|
||||
perf_data = dashboard_data['performance_data']
|
||||
|
||||
print(" Fastest Functions:")
|
||||
fastest_functions = sorted(perf_data['slowest_functions'], key=lambda x: x[1])[:3]
|
||||
for name, time in fastest_functions:
|
||||
print(f" {name}: {time:.3f}s")
|
||||
|
||||
print(" Slowest Functions:")
|
||||
for name, time in perf_data['slowest_functions'][:3]:
|
||||
print(f" {name}: {time:.3f}s")
|
||||
|
||||
# Benchmark Results
|
||||
print(f"\n⚡ BENCHMARK RESULTS")
|
||||
print(f" Response Time Benchmarks:")
|
||||
rt = benchmark_results['response_times']
|
||||
print(f" Min: {rt['min']:.3f}s, Max: {rt['max']:.3f}s, Avg: {rt['avg']:.3f}s")
|
||||
|
||||
print(f" Concurrent Operations:")
|
||||
co = benchmark_results['concurrent_operations']
|
||||
print(f" {co['operations']} operations in {co['total_time']:.3f}s")
|
||||
print(f" Avg per operation: {co['avg_per_operation']:.3f}s")
|
||||
|
||||
print(f" Memory Operations:")
|
||||
mo = benchmark_results['memory_operations']
|
||||
print(f" {mo['operations']} operations, {mo['avg_time']:.3f}s average")
|
||||
|
||||
# System Health
|
||||
print(f"\n🏥 SYSTEM HEALTH")
|
||||
|
||||
# Calculate health score
|
||||
health_score = 100
|
||||
if avg_function_time > 0.2:
|
||||
health_score -= 20
|
||||
if summary['total_errors'] > 0:
|
||||
health_score -= summary['total_errors'] * 10
|
||||
if rt['avg'] > 0.1:
|
||||
health_score -= 15
|
||||
|
||||
health_score = max(0, health_score)
|
||||
|
||||
if health_score >= 90:
|
||||
status = "🟢 Excellent"
|
||||
elif health_score >= 70:
|
||||
status = "🟡 Good"
|
||||
elif health_score >= 50:
|
||||
status = "🟠 Fair"
|
||||
else:
|
||||
status = "🔴 Needs Attention"
|
||||
|
||||
print(f" Overall Health Score: {health_score}/100 - {status}")
|
||||
|
||||
# Analysis Results
|
||||
print(f"\n🔍 ANALYSIS RESULTS")
|
||||
analysis = dashboard_data['analysis']
|
||||
|
||||
if 'error' not in analysis['flow_analysis']:
|
||||
flow_data = analysis['flow_analysis']
|
||||
print(f" Flow Analysis: {len(flow_data.get('functions', []))} functions analyzed")
|
||||
else:
|
||||
print(f" Flow Analysis: {analysis['flow_analysis']['error']}")
|
||||
|
||||
if analysis['flow_visualization']:
|
||||
print(f" Flow Visualization: Generated ({analysis['flow_visualization']} chars)")
|
||||
|
||||
# Recommendations
|
||||
print(f"\n💡 PERFORMANCE RECOMMENDATIONS")
|
||||
|
||||
if avg_function_time > 0.15:
|
||||
print(" 🔧 Optimize slow functions for better response times")
|
||||
if summary['total_errors'] > 0:
|
||||
print(" 🚨 Investigate and resolve error sources")
|
||||
if rt['avg'] > 0.08:
|
||||
print(" ⚡ Consider response time optimization strategies")
|
||||
if summary['total_function_calls'] > 50:
|
||||
print(" 📊 Implement performance caching for high-volume functions")
|
||||
|
||||
print(" 📈 Continue monitoring trends for proactive optimization")
|
||||
print(" 🔄 Regular performance reviews recommended")
|
||||
|
||||
def main():
|
||||
"""Main function for comprehensive performance dashboard."""
|
||||
print("=" * 80)
|
||||
print("EXAMPLE 10: Comprehensive Performance Dashboard")
|
||||
print("=" * 80)
|
||||
print("This example demonstrates a complete performance monitoring solution")
|
||||
print("with advanced analytics, benchmarking, and dashboard reporting.\n")
|
||||
|
||||
# Clear previous data for clean demo
|
||||
clear_performance_data()
|
||||
|
||||
# Phase 1: Data Collection
|
||||
print("📊 Phase 1: Comprehensive Data Collection")
|
||||
collection_results = collect_comprehensive_data()
|
||||
|
||||
# Phase 2: Complex Workflow
|
||||
print("\n🔄 Phase 2: Complex Multi-Agent Workflow")
|
||||
workflow_result = simulate_complex_workflow()
|
||||
|
||||
# Phase 3: Performance Benchmarking
|
||||
print("\n⚡ Phase 3: Performance Benchmarking")
|
||||
benchmark_results = run_performance_benchmarks()
|
||||
|
||||
# Phase 4: Dashboard Generation
|
||||
print("\n📋 Phase 4: Dashboard Report Generation")
|
||||
dashboard_data = generate_dashboard_report()
|
||||
|
||||
# Phase 5: Display Comprehensive Dashboard
|
||||
display_dashboard(dashboard_data, benchmark_results)
|
||||
|
||||
# Final Summary
|
||||
print(f"\n🎯 EXECUTION SUMMARY")
|
||||
print(f" Scenarios Executed: {len(collection_results)}")
|
||||
successful_scenarios = sum(1 for r in collection_results if r['success'])
|
||||
print(f" Successful Scenarios: {successful_scenarios}/{len(collection_results)}")
|
||||
print(f" Workflow Completed: {'✅ Yes' if workflow_result else '❌ No'}")
|
||||
print(f" Benchmarks Run: {len(benchmark_results)}")
|
||||
print(f" Dashboard Generated: ✅ Complete")
|
||||
|
||||
return {
|
||||
'scenarios': len(collection_results),
|
||||
'success_rate': successful_scenarios / len(collection_results) * 100,
|
||||
'dashboard_data': dashboard_data,
|
||||
'benchmark_results': benchmark_results
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Comprehensive dashboard monitoring completed!")
|
||||
print(f"Success Rate: {result['success_rate']:.1f}%")
|
||||
print(f"Total Functions Monitored: {result['dashboard_data']['summary']['total_functions']}")
|
||||
print(f"Performance Health Score Available in Dashboard Above ⬆️")
|
||||
print("\n💡 This dashboard provides real-time insights into your PraisonAI system performance!")
|
||||
@@ -0,0 +1,238 @@
|
||||
# PraisonAI Performance Monitoring Examples
|
||||
|
||||
This directory contains 10 comprehensive examples demonstrating how to integrate performance monitoring with PraisonAI agents. Each example builds upon the basic pattern while showcasing different aspects of the monitoring system.
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
All examples follow this basic pattern:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import monitor_function, track_api_call
|
||||
|
||||
@monitor_function("my_function")
|
||||
def my_function():
|
||||
# Your function code here
|
||||
pass
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
with track_api_call("agent_request"):
|
||||
result = agent.start("Your question here")
|
||||
```
|
||||
|
||||
## 📊 Examples Overview
|
||||
|
||||
### 1. Basic Agent with Monitoring (`01_basic_agent_with_monitoring.py`)
|
||||
**Purpose:** Introduction to performance monitoring fundamentals
|
||||
- Function execution timing with `@monitor_function` decorator
|
||||
- API call tracking with `track_api_call` context manager
|
||||
- Basic performance statistics retrieval
|
||||
|
||||
### 2. Multi-Agent Workflow Monitoring (`02_multi_agent_workflow_monitoring.py`)
|
||||
**Purpose:** Monitor complex multi-agent systems
|
||||
- Multiple agents with different roles
|
||||
- Inter-agent communication tracking
|
||||
- Workflow performance analysis
|
||||
- Task delegation timing
|
||||
|
||||
### 3. Agent with Tools Monitoring (`03_agent_with_tools_monitoring.py`)
|
||||
**Purpose:** Monitor performance when using external tools
|
||||
- Tool execution timing
|
||||
- Search operation performance
|
||||
- Tool call success/failure tracking
|
||||
- Tool usage analysis
|
||||
|
||||
### 4. Async Agent Monitoring (`04_async_agent_monitoring.py`)
|
||||
**Purpose:** Performance monitoring in asynchronous workflows
|
||||
- Async function execution timing
|
||||
- Concurrent task performance
|
||||
- Async API call tracking
|
||||
- Parallel operation analysis
|
||||
|
||||
### 5. Error Handling Monitoring (`05_error_handling_monitoring.py`)
|
||||
**Purpose:** Monitor performance during error scenarios
|
||||
- Error rate tracking
|
||||
- Failed operation timing
|
||||
- Recovery mechanism performance
|
||||
- Exception handling with monitoring
|
||||
|
||||
### 6. Memory Agent Monitoring (`06_memory_agent_monitoring.py`)
|
||||
**Purpose:** Monitor stateful agents with memory
|
||||
- Memory storage and retrieval timing
|
||||
- Knowledge base operations
|
||||
- Session persistence performance
|
||||
- Memory search optimization
|
||||
|
||||
### 7. Hierarchical Agents Monitoring (`07_hierarchical_agents_monitoring.py`)
|
||||
**Purpose:** Monitor complex organizational agent structures
|
||||
- Manager-worker agent relationships
|
||||
- Task delegation timing
|
||||
- Hierarchical decision making performance
|
||||
- Cross-level communication monitoring
|
||||
|
||||
### 8. Custom Tools Monitoring (`08_custom_tools_monitoring.py`)
|
||||
**Purpose:** Monitor performance with custom-built tools
|
||||
- Custom tool execution timing
|
||||
- Tool creation and registration performance
|
||||
- Tool usage pattern analysis
|
||||
- Tool efficiency optimization
|
||||
|
||||
### 9. Streaming Monitoring (`09_streaming_monitoring.py`)
|
||||
**Purpose:** Monitor real-time and streaming operations
|
||||
- Real-time performance tracking
|
||||
- Streaming response monitoring
|
||||
- Live performance metrics
|
||||
- Continuous performance analysis
|
||||
|
||||
### 10. Comprehensive Dashboard (`10_comprehensive_dashboard.py`)
|
||||
**Purpose:** Complete performance monitoring solution
|
||||
- Advanced analytics and reporting
|
||||
- Performance trends and insights
|
||||
- System-wide monitoring overview
|
||||
- Executive dashboard with health scores
|
||||
|
||||
## 🎯 Key Monitoring Features Demonstrated
|
||||
|
||||
### Core Monitoring Tools
|
||||
- **`@monitor_function(name)`** - Decorates functions for timing and statistics
|
||||
- **`track_api_call(name)`** - Context manager for API call monitoring
|
||||
- **`get_performance_report()`** - Generate comprehensive performance reports
|
||||
- **`get_function_stats()`** - Retrieve detailed function performance data
|
||||
- **`get_api_stats()`** - Get API call performance metrics
|
||||
|
||||
### Advanced Analytics
|
||||
- **`analyze_function_flow()`** - Analyze execution flow and bottlenecks
|
||||
- **`visualize_execution_flow()`** - Generate flow visualization
|
||||
- **`analyze_performance_trends()`** - Identify performance trends
|
||||
- **`generate_comprehensive_report()`** - Complete analysis with recommendations
|
||||
|
||||
### Performance Metrics Tracked
|
||||
- **Execution Time:** Min, max, average, and total execution times
|
||||
- **Call Counts:** Number of function calls and API requests
|
||||
- **Error Rates:** Success/failure ratios and error tracking
|
||||
- **Throughput:** Operations per second and message processing rates
|
||||
- **Flow Analysis:** Function call chains and execution patterns
|
||||
|
||||
## 📈 Usage Patterns
|
||||
|
||||
### Basic Monitoring Pattern
|
||||
```python
|
||||
@monitor_function("function_name")
|
||||
def your_function():
|
||||
# Function implementation
|
||||
pass
|
||||
|
||||
with track_api_call("api_operation"):
|
||||
result = some_api_call()
|
||||
```
|
||||
|
||||
### Performance Analysis Pattern
|
||||
```python
|
||||
# After running monitored operations
|
||||
stats = get_function_stats()
|
||||
report = get_performance_report()
|
||||
trends = analyze_performance_trends()
|
||||
```
|
||||
|
||||
### Real-time Monitoring Pattern
|
||||
```python
|
||||
# For streaming or real-time operations
|
||||
while streaming_active:
|
||||
with track_api_call("stream_message"):
|
||||
process_message()
|
||||
|
||||
# Check performance in real-time
|
||||
current_stats = performance_monitor.get_function_performance()
|
||||
```
|
||||
|
||||
## 🔍 Performance Insights
|
||||
|
||||
Each example provides insights into different aspects:
|
||||
|
||||
- **Response Times:** How fast your agents respond
|
||||
- **Bottlenecks:** Where delays occur in your workflow
|
||||
- **Error Patterns:** What fails and how often
|
||||
- **Resource Usage:** Efficiency of different operations
|
||||
- **Scaling Behavior:** How performance changes with load
|
||||
|
||||
## 🚀 Running the Examples
|
||||
|
||||
1. **Install PraisonAI with performance monitoring support:**
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
|
||||
2. **Set up your environment:**
|
||||
```bash
|
||||
export OPENAI_API_KEY="your-api-key-here"
|
||||
# or
|
||||
export ANTHROPIC_API_KEY="your-anthropic-key-here"
|
||||
```
|
||||
|
||||
3. **Run any example:**
|
||||
```bash
|
||||
python 01_basic_agent_with_monitoring.py
|
||||
python 10_comprehensive_dashboard.py
|
||||
```
|
||||
|
||||
## 📊 Sample Output
|
||||
|
||||
Each example provides detailed performance output like:
|
||||
|
||||
```
|
||||
📊 PERFORMANCE MONITORING RESULTS
|
||||
==================================================
|
||||
📈 Function Performance Statistics:
|
||||
question_processing:
|
||||
Calls: 1
|
||||
Avg Time: 0.100s
|
||||
Total Time: 0.100s
|
||||
agent_execution:
|
||||
Calls: 1
|
||||
Avg Time: 1.250s
|
||||
Total Time: 1.250s
|
||||
|
||||
🌐 API Call Performance:
|
||||
sky_explanation_request:
|
||||
Success Rate: 100.0%
|
||||
Average Response Time: 1.200s
|
||||
Total Calls: 1
|
||||
```
|
||||
|
||||
## 💡 Best Practices
|
||||
|
||||
1. **Strategic Monitoring:** Don't monitor everything - focus on critical paths
|
||||
2. **Performance Baselines:** Establish baseline metrics for comparison
|
||||
3. **Error Handling:** Always monitor error rates alongside performance
|
||||
4. **Real-time Analysis:** Use streaming monitoring for production systems
|
||||
5. **Regular Reviews:** Analyze trends and patterns regularly
|
||||
|
||||
## 🔧 Customization
|
||||
|
||||
You can customize monitoring by:
|
||||
|
||||
- **Custom Metrics:** Add your own performance counters
|
||||
- **Alert Thresholds:** Set up alerts for performance degradation
|
||||
- **Export Data:** Export performance data to external monitoring systems
|
||||
- **Dashboard Integration:** Build custom dashboards using the monitoring APIs
|
||||
|
||||
## 📚 Further Reading
|
||||
|
||||
- [PraisonAI Documentation](https://docs.praisonai.com)
|
||||
- [Performance Monitoring Guide](../../../src/praisonai-agents/praisonaiagents/telemetry/README.md)
|
||||
- [API Reference](../../../src/praisonai-agents/praisonaiagents/telemetry/__init__.py)
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
These examples are designed to be educational and extensible. Feel free to:
|
||||
- Add new monitoring scenarios
|
||||
- Improve existing examples
|
||||
- Share your performance optimization discoveries
|
||||
|
||||
---
|
||||
|
||||
**Note:** Performance monitoring is optional and can be disabled by setting `PRAISONAI_TELEMETRY_DISABLED=true` if needed.
|
||||
@@ -0,0 +1,321 @@
|
||||
"""
|
||||
PraisonAI Performance Monitoring Demo
|
||||
|
||||
This example demonstrates how to use PraisonAI's comprehensive performance monitoring
|
||||
capabilities to answer the key questions from Issue #1035:
|
||||
|
||||
1. How to evaluate how each function is performing
|
||||
2. Function flow analysis
|
||||
3. How fast each function is executing
|
||||
4. API call performance monitoring (fast vs slow calls)
|
||||
5. How to see all API calls
|
||||
|
||||
Features Demonstrated:
|
||||
- Function performance evaluation with detailed statistics
|
||||
- Function execution flow analysis and visualization
|
||||
- API call tracking and performance comparison
|
||||
- Real-time performance monitoring
|
||||
- Bottleneck identification and optimization recommendations
|
||||
- Comprehensive performance reporting
|
||||
"""
|
||||
|
||||
import time
|
||||
import random
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
analyze_function_flow,
|
||||
visualize_execution_flow, generate_comprehensive_report
|
||||
)
|
||||
|
||||
print("=" * 80)
|
||||
print("PRAISONAI PERFORMANCE MONITORING DEMONSTRATION")
|
||||
print("=" * 80)
|
||||
print("This demo answers the key questions from Issue #1035:")
|
||||
print("1. How to evaluate how each function is performing")
|
||||
print("2. Function flow analysis")
|
||||
print("3. How fast each function is executing")
|
||||
print("4. API call performance monitoring (fast vs slow calls)")
|
||||
print("5. How to see all API calls")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# Example 1: Function Performance Evaluation
|
||||
print("📊 EXAMPLE 1: Function Performance Evaluation")
|
||||
print("-" * 50)
|
||||
|
||||
# Demonstrate function monitoring with decorators
|
||||
@monitor_function("data_processing")
|
||||
def process_data(data_size: int):
|
||||
"""Simulate data processing with variable performance."""
|
||||
processing_time = 0.1 + (data_size * 0.01) # Simulate work
|
||||
time.sleep(processing_time)
|
||||
return f"Processed {data_size} items"
|
||||
|
||||
@monitor_function("model_inference")
|
||||
def run_model_inference(complexity: str):
|
||||
"""Simulate model inference with different complexities."""
|
||||
if complexity == "simple":
|
||||
time.sleep(0.05)
|
||||
elif complexity == "medium":
|
||||
time.sleep(0.2)
|
||||
else: # complex
|
||||
time.sleep(0.5)
|
||||
return f"Inference completed for {complexity} model"
|
||||
|
||||
@monitor_function("database_query")
|
||||
def query_database(query_type: str):
|
||||
"""Simulate database queries with different performance characteristics."""
|
||||
if query_type == "fast":
|
||||
time.sleep(0.02)
|
||||
elif query_type == "medium":
|
||||
time.sleep(0.1)
|
||||
else: # slow
|
||||
time.sleep(0.3)
|
||||
return f"Query {query_type} completed"
|
||||
|
||||
# Run functions with different performance characteristics
|
||||
print("Running functions to generate performance data...")
|
||||
for _ in range(5):
|
||||
process_data(random.randint(10, 100))
|
||||
run_model_inference(random.choice(["simple", "medium", "complex"]))
|
||||
query_database(random.choice(["fast", "medium", "slow"]))
|
||||
|
||||
# Show function performance statistics
|
||||
print("\n📈 Function Performance Statistics:")
|
||||
function_stats = performance_monitor.get_function_performance()
|
||||
for func_name, stats in function_stats.items():
|
||||
print(f"\n🔧 {func_name}:")
|
||||
print(f" Calls: {stats['call_count']}")
|
||||
print(f" Average Time: {stats.get('average_time', 0):.3f}s")
|
||||
print(f" Min/Max Time: {stats['min_time']:.3f}s / {stats['max_time']:.3f}s")
|
||||
print(f" Success Rate: {stats.get('success_rate', 0)*100:.1f}%")
|
||||
|
||||
# Example 2: Function Flow Analysis
|
||||
print("\n\n🔄 EXAMPLE 2: Function Flow Analysis")
|
||||
print("-" * 50)
|
||||
|
||||
@monitor_function("workflow_step_1")
|
||||
def workflow_step_1():
|
||||
time.sleep(0.1)
|
||||
workflow_step_2()
|
||||
workflow_step_3()
|
||||
|
||||
@monitor_function("workflow_step_2")
|
||||
def workflow_step_2():
|
||||
time.sleep(0.05)
|
||||
workflow_step_4()
|
||||
|
||||
@monitor_function("workflow_step_3")
|
||||
def workflow_step_3():
|
||||
time.sleep(0.08)
|
||||
|
||||
@monitor_function("workflow_step_4")
|
||||
def workflow_step_4():
|
||||
time.sleep(0.03)
|
||||
|
||||
print("Running workflow to demonstrate flow analysis...")
|
||||
workflow_step_1()
|
||||
|
||||
# Analyze execution flow
|
||||
print("\n📊 Function Execution Flow Analysis:")
|
||||
flow_analysis = analyze_function_flow()
|
||||
if "bottlenecks" in flow_analysis:
|
||||
bottlenecks = flow_analysis["bottlenecks"]
|
||||
if bottlenecks:
|
||||
print("🚨 Identified Bottlenecks:")
|
||||
for bottleneck in bottlenecks:
|
||||
print(f" • {bottleneck['function']}: {bottleneck['average_duration']:.3f}s average")
|
||||
else:
|
||||
print("✅ No significant bottlenecks identified")
|
||||
|
||||
# Visualize execution flow
|
||||
print("\n🎨 Function Execution Flow Visualization:")
|
||||
flow_viz = visualize_execution_flow(format="text")
|
||||
print(flow_viz)
|
||||
|
||||
# Example 3: API Call Performance Monitoring
|
||||
print("\n\n🌐 EXAMPLE 3: API Call Performance Monitoring")
|
||||
print("-" * 50)
|
||||
|
||||
# Simulate different API calls with various performance characteristics
|
||||
def simulate_api_calls():
|
||||
"""Simulate API calls to demonstrate tracking."""
|
||||
|
||||
# Fast API calls
|
||||
with track_api_call("openai_api", "/v1/models"):
|
||||
time.sleep(0.05) # Fast call
|
||||
|
||||
with track_api_call("openai_api", "/v1/chat/completions"):
|
||||
time.sleep(0.3) # Medium call
|
||||
|
||||
# Slow API call
|
||||
with track_api_call("anthropic_api", "/v1/messages"):
|
||||
time.sleep(0.6) # Slow call
|
||||
|
||||
# Another fast call
|
||||
with track_api_call("gemini_api", "/v1/generate"):
|
||||
time.sleep(0.08) # Fast call
|
||||
|
||||
# Simulate error case
|
||||
try:
|
||||
with track_api_call("unreliable_api", "/v1/endpoint"):
|
||||
time.sleep(0.2)
|
||||
if random.random() < 0.3: # 30% chance of error
|
||||
raise Exception("API Error")
|
||||
except Exception:
|
||||
pass # Error is already tracked
|
||||
|
||||
print("Simulating API calls with different performance characteristics...")
|
||||
for _ in range(8):
|
||||
simulate_api_calls()
|
||||
|
||||
# Show API performance statistics
|
||||
print("\n📊 API Call Performance Statistics:")
|
||||
api_stats = performance_monitor.get_api_call_performance()
|
||||
for api_name, stats in api_stats.items():
|
||||
print(f"\n🔗 {api_name}:")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
print(f" Average Time: {stats.get('average_time', 0):.3f}s")
|
||||
print(f" Min/Max Time: {stats['min_time']:.3f}s / {stats['max_time']:.3f}s")
|
||||
print(f" Success Rate: {stats.get('success_rate', 0)*100:.1f}%")
|
||||
print(f" Successful: {stats['success_count']} | Failed: {stats['error_count']}")
|
||||
|
||||
# Show fastest vs slowest APIs
|
||||
print("\n🏁 Fastest vs Slowest API Calls:")
|
||||
slowest_apis = performance_monitor.get_slowest_api_calls(10)
|
||||
for i, api in enumerate(slowest_apis, 1):
|
||||
speed_indicator = "🐌" if api['average_time'] > 0.3 else "⚡" if api['average_time'] < 0.1 else "🚀"
|
||||
print(f"{i}. {speed_indicator} {api['api']}: {api['average_time']:.3f}s avg (Success: {api['success_rate']*100:.1f}%)")
|
||||
|
||||
# Example 4: Real-time Performance Monitoring with Agents
|
||||
print("\n\n🤖 EXAMPLE 4: Real-time Performance Monitoring with AI Agents")
|
||||
print("-" * 50)
|
||||
|
||||
# Create agents with performance monitoring
|
||||
research_agent = Agent(
|
||||
name="PerformanceResearcher",
|
||||
role="Performance Research Specialist",
|
||||
goal="Research and analyze performance topics quickly",
|
||||
backstory="You are an expert at researching performance optimization topics.",
|
||||
tools=[duckduckgo],
|
||||
verbose=False # Reduce output for cleaner demo
|
||||
)
|
||||
|
||||
# Monitor agent operations
|
||||
@monitor_function("agent_task_execution")
|
||||
def execute_monitored_task(agent, task_description):
|
||||
"""Execute an agent task with performance monitoring."""
|
||||
task = Task(
|
||||
description=task_description,
|
||||
expected_output="Brief research summary with key insights",
|
||||
agent=agent
|
||||
)
|
||||
|
||||
agents_workflow = PraisonAIAgents(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
verbose=False
|
||||
)
|
||||
|
||||
# Simulate API calls during agent execution
|
||||
with track_api_call("llm_provider", "/v1/chat/completions"):
|
||||
time.sleep(0.2) # Simulate LLM call
|
||||
|
||||
result = agents_workflow.start()
|
||||
return result
|
||||
|
||||
print("Running AI agent with performance monitoring...")
|
||||
result = execute_monitored_task(
|
||||
research_agent,
|
||||
"Research the latest trends in AI performance optimization"
|
||||
)
|
||||
|
||||
# Example 5: Comprehensive Performance Report
|
||||
print("\n\n📋 EXAMPLE 5: Comprehensive Performance Report")
|
||||
print("-" * 50)
|
||||
|
||||
# Generate comprehensive performance report
|
||||
comprehensive_report = generate_comprehensive_report()
|
||||
print(comprehensive_report)
|
||||
|
||||
# Example 6: Using CLI Interface Programmatically
|
||||
print("\n\n💻 EXAMPLE 6: CLI Interface Usage")
|
||||
print("-" * 50)
|
||||
print("You can also use the CLI interface from command line:")
|
||||
print()
|
||||
print("# Show performance report")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli report")
|
||||
print()
|
||||
print("# Show function statistics")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli functions")
|
||||
print()
|
||||
print("# Show API call statistics")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli apis")
|
||||
print()
|
||||
print("# Show slowest functions")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli slowest-functions 5")
|
||||
print()
|
||||
print("# Analyze function flow")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli analyze-flow")
|
||||
print()
|
||||
print("# Show execution flow visualization")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli flow --format text")
|
||||
print()
|
||||
print("# Export all data to JSON")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli export --format json --output performance_data.json")
|
||||
|
||||
# Example 7: Integration with Existing Code
|
||||
print("\n\n🔧 EXAMPLE 7: Easy Integration with Existing Code")
|
||||
print("-" * 50)
|
||||
print("To integrate performance monitoring into your existing PraisonAI code:")
|
||||
print()
|
||||
print("1. Import the performance monitoring tools:")
|
||||
print(" from praisonaiagents.telemetry import monitor_function, track_api_call")
|
||||
print()
|
||||
print("2. Add decorators to your functions:")
|
||||
print(" @monitor_function('my_function')")
|
||||
print(" def my_function():")
|
||||
print(" return 'result'")
|
||||
print()
|
||||
print("3. Track API calls:")
|
||||
print(" with track_api_call('openai', '/v1/chat/completions'):")
|
||||
print(" response = openai_client.chat.completions.create(...)")
|
||||
print()
|
||||
print("4. Get performance reports:")
|
||||
print(" from praisonaiagents.telemetry import get_performance_report")
|
||||
print(" print(get_performance_report())")
|
||||
|
||||
# Summary of capabilities
|
||||
print("\n\n✅ SUMMARY: Questions from Issue #1035 - ANSWERED!")
|
||||
print("=" * 80)
|
||||
print("1. ✅ How to evaluate how each function is performing:")
|
||||
print(" → Use @monitor_function decorator and get_function_stats()")
|
||||
print(" → View detailed statistics: calls, timing, success rates, errors")
|
||||
print()
|
||||
print("2. ✅ Function flow analysis:")
|
||||
print(" → Use analyze_function_flow() for bottleneck identification")
|
||||
print(" → Use visualize_execution_flow() for flow visualization")
|
||||
print(" → Get call chains and execution patterns")
|
||||
print()
|
||||
print("3. ✅ How fast each function is executing:")
|
||||
print(" → Automatic timing collection with min/max/average/recent stats")
|
||||
print(" → Use get_slowest_functions() to find performance bottlenecks")
|
||||
print(" → Real-time active call monitoring")
|
||||
print()
|
||||
print("4. ✅ API call performance monitoring (fast vs slow calls):")
|
||||
print(" → Use track_api_call() context manager for API monitoring")
|
||||
print(" → Compare API performance with get_slowest_apis()")
|
||||
print(" → Success/error rate tracking")
|
||||
print()
|
||||
print("5. ✅ How to see all API calls:")
|
||||
print(" → Use get_api_stats() to see all tracked APIs")
|
||||
print(" → View recent call history and detailed metrics")
|
||||
print(" → CLI interface for easy access: performance_cli apis")
|
||||
print()
|
||||
print("🎉 All requested features are now available with backward compatibility!")
|
||||
print("🔧 Easy integration with existing code using decorators and context managers")
|
||||
print("📊 Comprehensive reporting and analysis capabilities")
|
||||
print("💻 CLI interface for command-line access")
|
||||
print("=" * 80)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Basic example of using AI21 with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with AI21
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="ai21/j2-ultra",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a writing task?")
|
||||
|
||||
# Example with creative writing
|
||||
writing_task = """
|
||||
Write a short story about a time traveler who discovers
|
||||
they can only travel to moments of great historical significance.
|
||||
Make it engaging and about 200 words.
|
||||
"""
|
||||
|
||||
response = agent.start(writing_task)
|
||||
|
||||
# Example with reasoning
|
||||
reasoning_task = """
|
||||
Explain the concept of quantum entanglement in simple terms,
|
||||
and then discuss its potential applications in quantum computing.
|
||||
"""
|
||||
|
||||
response = agent.start(reasoning_task)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Basic example of using AWS Bedrock with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with AWS Bedrock (Claude)
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a writing task?")
|
||||
|
||||
# Example with creative writing
|
||||
writing_task = """
|
||||
Write a short story about a time traveler who discovers
|
||||
they can only travel to moments of great historical significance.
|
||||
Make it engaging and about 200 words.
|
||||
"""
|
||||
|
||||
response = agent.start(writing_task)
|
||||
|
||||
# Example with reasoning
|
||||
reasoning_task = """
|
||||
Explain the concept of quantum entanglement in simple terms,
|
||||
and then discuss its potential applications in quantum computing.
|
||||
"""
|
||||
|
||||
response = agent.start(reasoning_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Azure OpenAI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Azure OpenAI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="azure/gpt-4",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a coding task?")
|
||||
|
||||
# Example with code generation
|
||||
coding_task = """
|
||||
Write a Python function that implements a binary search algorithm.
|
||||
Include proper documentation and error handling.
|
||||
"""
|
||||
|
||||
response = agent.start(coding_task)
|
||||
|
||||
# Example with analysis
|
||||
analysis_task = """
|
||||
Analyze the pros and cons of using microservices architecture
|
||||
for a large-scale e-commerce application.
|
||||
"""
|
||||
|
||||
response = agent.start(analysis_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Cloudflare AI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Cloudflare AI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="cloudflare/@cf/meta/llama-3.1-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a coding task?")
|
||||
|
||||
# Example with code generation
|
||||
coding_task = """
|
||||
Write a Python function that implements a binary search algorithm.
|
||||
Include proper documentation and error handling.
|
||||
"""
|
||||
|
||||
response = agent.start(coding_task)
|
||||
|
||||
# Example with analysis
|
||||
analysis_task = """
|
||||
Analyze the pros and cons of using microservices architecture
|
||||
for a large-scale e-commerce application.
|
||||
"""
|
||||
|
||||
response = agent.start(analysis_task)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Basic example of using Databricks with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Databricks
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="databricks/databricks-llama-3.1-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a data analysis task?")
|
||||
|
||||
# Example with data analysis
|
||||
analysis_task = """
|
||||
Analyze the potential market opportunities for a new AI-powered
|
||||
productivity tool targeting remote workers. Include market size,
|
||||
competitive landscape, and go-to-market strategy recommendations.
|
||||
"""
|
||||
|
||||
response = agent.start(analysis_task)
|
||||
|
||||
# Example with business intelligence
|
||||
business_task = """
|
||||
Provide insights on how AI can transform customer service operations
|
||||
in the next 5 years, including specific use cases and implementation strategies.
|
||||
"""
|
||||
|
||||
response = agent.start(business_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Fireworks AI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Fireworks AI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="fireworks/accounts/fireworks/models/llama-v3-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a coding task?")
|
||||
|
||||
# Example with code generation
|
||||
coding_task = """
|
||||
Write a Python function that implements a binary search algorithm.
|
||||
Include proper documentation and error handling.
|
||||
"""
|
||||
|
||||
response = agent.start(coding_task)
|
||||
|
||||
# Example with creative writing
|
||||
creative_task = """
|
||||
Write a short story about a time traveler who discovers
|
||||
they can only travel to moments of great historical significance.
|
||||
"""
|
||||
|
||||
response = agent.start(creative_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Hugging Face with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Hugging Face
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="huggingface/meta-llama/Llama-3.1-8B-Instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a language translation task?")
|
||||
|
||||
# Example with language translation
|
||||
translation_task = """
|
||||
Translate the following text to French and explain any cultural nuances:
|
||||
"The early bird catches the worm, but the second mouse gets the cheese."
|
||||
"""
|
||||
|
||||
response = agent.start(translation_task)
|
||||
|
||||
# Example with creative content generation
|
||||
creative_task = """
|
||||
Write a haiku about artificial intelligence and its impact on society.
|
||||
Then explain the symbolism in your haiku.
|
||||
"""
|
||||
|
||||
response = agent.start(creative_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Moonshot AI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Moonshot AI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="moonshot/moonshot-v1-8k",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a research task?")
|
||||
|
||||
# Example with research and analysis
|
||||
research_task = """
|
||||
Research and provide insights on the latest developments in
|
||||
artificial intelligence, focusing on recent breakthroughs and trends.
|
||||
"""
|
||||
|
||||
response = agent.start(research_task)
|
||||
|
||||
# Example with creative content
|
||||
creative_task = """
|
||||
Write a haiku about artificial intelligence and its impact on society.
|
||||
Then explain the symbolism in your haiku.
|
||||
"""
|
||||
|
||||
response = agent.start(creative_task)
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Basic example of using OpenRouter with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with OpenRouter
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="openrouter/meta-llama/llama-3.1-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a creative writing task?")
|
||||
|
||||
# Example with creative writing
|
||||
writing_task = """
|
||||
Write a short story about a time traveler who discovers
|
||||
they can only travel to moments of great historical significance.
|
||||
Make it engaging and about 200 words.
|
||||
"""
|
||||
|
||||
response = agent.start(writing_task)
|
||||
|
||||
# Example with reasoning
|
||||
reasoning_task = """
|
||||
Explain the concept of quantum entanglement in simple terms,
|
||||
and then discuss its potential applications in quantum computing.
|
||||
"""
|
||||
|
||||
response = agent.start(reasoning_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Perplexity with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Perplexity
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="perplexity/llama-3.1-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a research task?")
|
||||
|
||||
# Example with research and analysis
|
||||
research_task = """
|
||||
Research and provide insights on the latest developments in
|
||||
artificial intelligence, focusing on recent breakthroughs and trends.
|
||||
"""
|
||||
|
||||
response = agent.start(research_task)
|
||||
|
||||
# Example with document analysis
|
||||
analysis_task = """
|
||||
Analyze the potential market opportunities for a new AI-powered
|
||||
productivity tool targeting remote workers.
|
||||
"""
|
||||
|
||||
response = agent.start(analysis_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Replicate with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Replicate
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="replicate/meta/llama-3.1-8b-instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a creative task?")
|
||||
|
||||
# Example with creative writing
|
||||
creative_task = """
|
||||
Write a short story about a robot learning to paint.
|
||||
Make it engaging and about 100 words.
|
||||
"""
|
||||
|
||||
response = agent.start(creative_task)
|
||||
|
||||
# Example with problem solving
|
||||
problem_task = """
|
||||
Solve this problem step by step:
|
||||
If a train travels at 60 mph for 2.5 hours, how far does it travel?
|
||||
"""
|
||||
|
||||
response = agent.start(problem_task)
|
||||
@@ -0,0 +1,32 @@
|
||||
"""
|
||||
Basic example of using AWS SageMaker with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with AWS SageMaker
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="sagemaker/meta-llama/Llama-3.1-8B-Instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a business analysis task?")
|
||||
|
||||
# Example with business analysis
|
||||
business_task = """
|
||||
Analyze the potential market opportunities for a new AI-powered
|
||||
productivity tool targeting remote workers. Include market size,
|
||||
competitive landscape, and go-to-market strategy recommendations.
|
||||
"""
|
||||
|
||||
response = agent.start(business_task)
|
||||
|
||||
# Example with document summarization
|
||||
summary_task = """
|
||||
Summarize the key points from this business proposal:
|
||||
Our company proposes to develop an AI-powered customer service chatbot
|
||||
that can handle 80% of common customer inquiries automatically.
|
||||
"""
|
||||
|
||||
response = agent.start(summary_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Together AI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Together AI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="together_ai/meta-llama/Llama-3.1-8B-Instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a research task?")
|
||||
|
||||
# Example with research and analysis
|
||||
research_task = """
|
||||
Research and provide insights on the latest developments in
|
||||
renewable energy technology, focusing on solar and wind power innovations.
|
||||
"""
|
||||
|
||||
response = agent.start(research_task)
|
||||
|
||||
# Example with creative content
|
||||
creative_task = """
|
||||
Write a haiku about artificial intelligence and its impact on society.
|
||||
Then explain the symbolism in your haiku.
|
||||
"""
|
||||
|
||||
response = agent.start(creative_task)
|
||||
@@ -0,0 +1,30 @@
|
||||
"""
|
||||
Basic example of using Google Vertex AI with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with Google Vertex AI
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="vertex_ai/gemini-1.5-pro",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a research task?")
|
||||
|
||||
# Example with research and analysis
|
||||
research_task = """
|
||||
Research and provide insights on the latest developments in
|
||||
renewable energy technology, focusing on solar and wind power innovations.
|
||||
"""
|
||||
|
||||
response = agent.start(research_task)
|
||||
|
||||
# Example with multimodal capabilities (text-based for now)
|
||||
multimodal_task = """
|
||||
Describe how you would analyze an image of a city skyline
|
||||
and provide insights about urban development patterns.
|
||||
"""
|
||||
|
||||
response = agent.start(multimodal_task)
|
||||
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
Basic example of using vLLM with PraisonAI
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Initialize Agent with vLLM
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="vllm/meta-llama/Llama-3.1-8B-Instruct",
|
||||
)
|
||||
|
||||
# Example conversation
|
||||
response = agent.start("Hello! Can you help me with a mathematical problem?")
|
||||
|
||||
# Example with mathematical reasoning
|
||||
math_task = """
|
||||
Solve this calculus problem step by step:
|
||||
Find the derivative of f(x) = x^3 * e^(2x) using the product rule.
|
||||
"""
|
||||
|
||||
response = agent.start(math_task)
|
||||
|
||||
# Example with code optimization
|
||||
code_task = """
|
||||
Optimize this Python function for better performance:
|
||||
def find_duplicates(arr):
|
||||
duplicates = []
|
||||
for i in range(len(arr)):
|
||||
for j in range(i+1, len(arr)):
|
||||
if arr[i] == arr[j] and arr[i] not in duplicates:
|
||||
duplicates.append(arr[i])
|
||||
return duplicates
|
||||
"""
|
||||
|
||||
response = agent.start(code_task)
|
||||
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
Basic Agent with Performance Monitoring - Example 1
|
||||
|
||||
Simple agent demonstrating performance monitoring basics:
|
||||
- Function execution timing with @monitor_function decorator
|
||||
- API call tracking with track_api_call context manager
|
||||
- Basic performance statistics retrieval
|
||||
|
||||
This example shows the fundamental pattern for adding performance monitoring
|
||||
to any PraisonAI agent workflow.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import monitor_function, track_api_call, get_performance_report
|
||||
import time
|
||||
|
||||
# Monitored function to demonstrate timing
|
||||
@monitor_function("question_processing")
|
||||
def process_question(question):
|
||||
"""Process the incoming question with performance tracking."""
|
||||
print(f"Processing question: {question}")
|
||||
# Simulate some processing time
|
||||
time.sleep(0.1)
|
||||
return f"Processed: {question}"
|
||||
|
||||
# Main execution function with monitoring
|
||||
@monitor_function("agent_execution")
|
||||
def main():
|
||||
"""Main function demonstrating basic agent with performance monitoring."""
|
||||
print("=" * 60)
|
||||
print("EXAMPLE 1: Basic Agent with Performance Monitoring")
|
||||
print("=" * 60)
|
||||
|
||||
# Process the question with monitoring
|
||||
question = "Why is the sky blue?"
|
||||
processed_question = process_question(question)
|
||||
|
||||
# Create agent
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant that explains scientific concepts simply",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Track the API call performance
|
||||
with track_api_call("sky_explanation_request"):
|
||||
print("\n🚀 Starting agent execution...")
|
||||
result = agent.start(processed_question)
|
||||
print(f"\n📝 Agent Response:\n{result}")
|
||||
|
||||
# Display performance statistics
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 PERFORMANCE MONITORING RESULTS")
|
||||
print("=" * 60)
|
||||
|
||||
# Get and display performance report
|
||||
report = get_performance_report()
|
||||
print(report)
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Example completed successfully!")
|
||||
@@ -0,0 +1,143 @@
|
||||
"""
|
||||
Multi-Agent Workflow with Performance Monitoring - Example 2
|
||||
|
||||
Demonstrates performance monitoring in a multi-agent workflow:
|
||||
- Multiple agents with different roles
|
||||
- Inter-agent communication tracking
|
||||
- Workflow performance analysis
|
||||
- Task delegation timing
|
||||
|
||||
Shows how to monitor complex multi-agent systems.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
analyze_function_flow, generate_comprehensive_report
|
||||
)
|
||||
import time
|
||||
|
||||
@monitor_function("research_task")
|
||||
def setup_research_task():
|
||||
"""Set up research task with monitoring."""
|
||||
return Task(
|
||||
name="research_task",
|
||||
description="Research the topic of renewable energy trends",
|
||||
expected_output="A comprehensive research summary"
|
||||
)
|
||||
|
||||
@monitor_function("analysis_task")
|
||||
def setup_analysis_task():
|
||||
"""Set up analysis task with monitoring."""
|
||||
return Task(
|
||||
name="analysis_task",
|
||||
description="Analyze the research data and identify key trends",
|
||||
expected_output="Key insights and trend analysis"
|
||||
)
|
||||
|
||||
@monitor_function("report_task")
|
||||
def setup_report_task():
|
||||
"""Set up report generation task with monitoring."""
|
||||
return Task(
|
||||
name="report_task",
|
||||
description="Create a final report combining research and analysis",
|
||||
expected_output="A well-structured final report"
|
||||
)
|
||||
|
||||
@monitor_function("agent_creation")
|
||||
def create_agents():
|
||||
"""Create specialized agents with monitoring."""
|
||||
|
||||
researcher = Agent(
|
||||
name="researcher",
|
||||
role="Research Specialist",
|
||||
goal="Gather comprehensive information on renewable energy",
|
||||
backstory="Expert researcher with deep knowledge of energy sector",
|
||||
instructions="You are a thorough researcher. Provide detailed, fact-based information.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
analyst = Agent(
|
||||
name="analyst",
|
||||
role="Data Analyst",
|
||||
goal="Analyze trends and patterns in renewable energy data",
|
||||
backstory="Experienced data analyst specializing in energy markets",
|
||||
instructions="You are an analytical thinker. Focus on trends, patterns, and insights.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
writer = Agent(
|
||||
name="writer",
|
||||
role="Report Writer",
|
||||
goal="Create clear, compelling reports",
|
||||
backstory="Professional technical writer with expertise in energy sector",
|
||||
instructions="You are a skilled writer. Create clear, well-structured reports.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
return researcher, analyst, writer
|
||||
|
||||
@monitor_function("workflow_execution")
|
||||
def main():
|
||||
"""Main function demonstrating multi-agent workflow with performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 2: Multi-Agent Workflow with Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Create agents with monitoring
|
||||
researcher, analyst, writer = create_agents()
|
||||
|
||||
# Set up tasks with monitoring
|
||||
research_task = setup_research_task()
|
||||
analysis_task = setup_analysis_task()
|
||||
report_task = setup_report_task()
|
||||
|
||||
# Assign agents to tasks
|
||||
research_task.agent = researcher
|
||||
analysis_task.agent = analyst
|
||||
report_task.agent = writer
|
||||
|
||||
# Create workflow
|
||||
with track_api_call("multi_agent_workflow"):
|
||||
print("\n🚀 Starting multi-agent workflow...")
|
||||
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[researcher, analyst, writer],
|
||||
tasks=[research_task, analysis_task, report_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
result = workflow.start()
|
||||
|
||||
# Display comprehensive performance analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 MULTI-AGENT PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Function statistics
|
||||
print("\n📈 Function Performance Statistics:")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Flow analysis
|
||||
print("\n🔄 Execution Flow Analysis:")
|
||||
flow_analysis = analyze_function_flow()
|
||||
print(f" Total Functions Monitored: {len(flow_analysis.get('functions', []))}")
|
||||
print(f" Execution Chains: {len(flow_analysis.get('call_chains', []))}")
|
||||
|
||||
# Comprehensive report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = generate_comprehensive_report()
|
||||
print(report[:500] + "..." if len(report) > 500 else report)
|
||||
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Multi-agent workflow completed successfully!")
|
||||
@@ -0,0 +1,119 @@
|
||||
"""
|
||||
Agent with Tools Performance Monitoring - Example 3
|
||||
|
||||
Demonstrates performance monitoring for agents using tools:
|
||||
- Tool execution timing
|
||||
- Search operation performance
|
||||
- Tool call success/failure tracking
|
||||
- Tool usage analysis
|
||||
|
||||
Shows how to monitor agent performance when using external tools.
|
||||
"""
|
||||
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import duckduckgo, wikipedia
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_api_stats,
|
||||
get_slowest_functions, performance_monitor
|
||||
)
|
||||
import time
|
||||
|
||||
@monitor_function("search_with_duckduckgo")
|
||||
def perform_web_search(query):
|
||||
"""Perform web search with performance monitoring."""
|
||||
print(f"🔍 Searching web for: {query}")
|
||||
with track_api_call("duckduckgo_search"):
|
||||
# Simulate search time
|
||||
time.sleep(0.2)
|
||||
return f"Search results for: {query}"
|
||||
|
||||
@monitor_function("wikipedia_lookup")
|
||||
def perform_wikipedia_search(topic):
|
||||
"""Perform Wikipedia search with performance monitoring."""
|
||||
print(f"📚 Looking up Wikipedia for: {topic}")
|
||||
with track_api_call("wikipedia_search"):
|
||||
# Simulate Wikipedia lookup
|
||||
time.sleep(0.15)
|
||||
return f"Wikipedia information about: {topic}"
|
||||
|
||||
@monitor_function("agent_with_tools_execution")
|
||||
def main():
|
||||
"""Main function demonstrating agent with tools and performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 3: Agent with Tools Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Create agent with tools
|
||||
agent = Agent(
|
||||
instructions="""You are a research assistant that helps find information.
|
||||
Use the available tools to search for information and provide comprehensive answers.
|
||||
Be thorough in your research and cite your sources.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=[duckduckgo, wikipedia] # Add search tools
|
||||
)
|
||||
|
||||
# Test queries to demonstrate tool performance monitoring
|
||||
queries = [
|
||||
"What are the latest developments in artificial intelligence?",
|
||||
"Tell me about renewable energy innovations in 2024",
|
||||
"How do neural networks work?"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for i, query in enumerate(queries, 1):
|
||||
print(f"\n🎯 Query {i}: {query}")
|
||||
|
||||
# Monitor the search operations
|
||||
perform_web_search(query)
|
||||
perform_wikipedia_search(query)
|
||||
|
||||
# Track the full agent execution
|
||||
with track_api_call(f"agent_query_{i}"):
|
||||
print(f"\n🚀 Processing with agent...")
|
||||
|
||||
# Note: In a real implementation, the agent would use the tools automatically
|
||||
# For demo purposes, we're simulating the tool usage
|
||||
result = agent.start(f"Research and answer: {query}")
|
||||
results.append(result)
|
||||
|
||||
print(f"📝 Agent Response: {result[:200]}..." if len(result) > 200 else f"📝 Agent Response: {result}")
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 TOOLS PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# API call statistics
|
||||
print("\n📈 API Call Performance:")
|
||||
api_stats = get_api_stats()
|
||||
for api_name, stats in api_stats.items():
|
||||
print(f" {api_name}:")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
print(f" Avg Response Time: {stats['total_time']/stats['call_count']:.3f}s")
|
||||
print(f" Success Rate: {stats['success_count']/stats['call_count']*100:.1f}%")
|
||||
print(f" Total Time: {stats['total_time']:.3f}s")
|
||||
|
||||
# Slowest functions analysis
|
||||
print("\n🐌 Slowest Functions:")
|
||||
slowest = get_slowest_functions()
|
||||
for func_name, avg_time in slowest:
|
||||
print(f" {func_name}: {avg_time:.3f}s average")
|
||||
|
||||
# Real-time performance data
|
||||
print("\n⚡ Real-time Performance Data:")
|
||||
current_stats = performance_monitor.get_function_performance()
|
||||
print(f" Functions Monitored: {len(current_stats)}")
|
||||
|
||||
total_function_calls = sum(stats['call_count'] for stats in current_stats.values())
|
||||
total_execution_time = sum(stats['total_time'] for stats in current_stats.values())
|
||||
|
||||
print(f" Total Function Calls: {total_function_calls}")
|
||||
print(f" Total Execution Time: {total_execution_time:.3f}s")
|
||||
print(f" Average Time per Call: {total_execution_time/total_function_calls:.3f}s" if total_function_calls > 0 else " No calls recorded")
|
||||
|
||||
return results
|
||||
|
||||
if __name__ == "__main__":
|
||||
results = main()
|
||||
print(f"\n✅ Tool monitoring example completed! Processed {len(results)} queries.")
|
||||
@@ -0,0 +1,167 @@
|
||||
"""
|
||||
Async Agent with Performance Monitoring - Example 4
|
||||
|
||||
Demonstrates performance monitoring for asynchronous agent operations:
|
||||
- Async function execution timing
|
||||
- Concurrent task performance
|
||||
- Async API call tracking
|
||||
- Parallel operation analysis
|
||||
|
||||
Shows how to monitor performance in async/await workflows.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_performance_report,
|
||||
get_function_stats, visualize_execution_flow
|
||||
)
|
||||
|
||||
@monitor_function("async_data_processing")
|
||||
async def process_data_async(data_id: int):
|
||||
"""Async data processing with performance monitoring."""
|
||||
print(f"⚙️ Processing data {data_id} asynchronously...")
|
||||
await asyncio.sleep(0.1) # Simulate async processing
|
||||
return f"Processed data {data_id}"
|
||||
|
||||
@monitor_function("async_api_call")
|
||||
async def simulate_api_call(endpoint: str, delay: float = 0.2):
|
||||
"""Simulate async API call with performance monitoring."""
|
||||
print(f"🌐 Calling API endpoint: {endpoint}")
|
||||
await asyncio.sleep(delay) # Simulate network delay
|
||||
return f"Response from {endpoint}"
|
||||
|
||||
@monitor_function("batch_processing")
|
||||
async def process_batch(batch_size: int = 3):
|
||||
"""Process multiple items concurrently with monitoring."""
|
||||
print(f"📦 Processing batch of {batch_size} items...")
|
||||
|
||||
# Create concurrent tasks
|
||||
tasks = []
|
||||
for i in range(batch_size):
|
||||
tasks.append(process_data_async(i + 1))
|
||||
|
||||
# Wait for all tasks to complete
|
||||
results = await asyncio.gather(*tasks)
|
||||
print(f"✅ Batch processing completed: {len(results)} items processed")
|
||||
return results
|
||||
|
||||
@monitor_function("async_agent_execution")
|
||||
async def run_async_agent(query: str):
|
||||
"""Run agent with async operations and monitoring."""
|
||||
|
||||
# Create agent
|
||||
agent = Agent(
|
||||
instructions="You are an efficient AI assistant that processes requests quickly",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Track the agent execution
|
||||
with track_api_call("async_agent_request"):
|
||||
print(f"🚀 Running async agent for query: {query}")
|
||||
|
||||
# For demo purposes, we simulate async agent execution
|
||||
# In real scenarios, you'd use agent.astart() or similar async method when available
|
||||
await asyncio.sleep(0.1) # Simulate async processing time
|
||||
result = agent.start(query)
|
||||
|
||||
# Simulate some async post-processing
|
||||
await asyncio.sleep(0.05)
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("concurrent_agents")
|
||||
async def run_concurrent_agents():
|
||||
"""Run multiple agents concurrently with monitoring."""
|
||||
print("🔄 Running multiple agents concurrently...")
|
||||
|
||||
queries = [
|
||||
"What is machine learning?",
|
||||
"Explain quantum computing",
|
||||
"How does blockchain work?"
|
||||
]
|
||||
|
||||
# Create concurrent agent tasks
|
||||
agent_tasks = []
|
||||
for i, query in enumerate(queries):
|
||||
task = run_async_agent(query)
|
||||
agent_tasks.append(task)
|
||||
|
||||
# Execute all agents concurrently
|
||||
results = await asyncio.gather(*agent_tasks)
|
||||
return results
|
||||
|
||||
async def main():
|
||||
"""Main async function demonstrating async agent performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 4: Async Agent Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
start_time = time.time()
|
||||
|
||||
# Run async operations with monitoring
|
||||
print("\n📊 Phase 1: Batch Processing")
|
||||
batch_results = await process_batch(3)
|
||||
|
||||
print("\n🌐 Phase 2: API Calls")
|
||||
api_tasks = [
|
||||
simulate_api_call("user-service", 0.1),
|
||||
simulate_api_call("data-service", 0.15),
|
||||
simulate_api_call("analytics-service", 0.2)
|
||||
]
|
||||
api_results = await asyncio.gather(*api_tasks)
|
||||
|
||||
print("\n🤖 Phase 3: Concurrent Agents")
|
||||
agent_results = await run_concurrent_agents()
|
||||
|
||||
total_time = time.time() - start_time
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 ASYNC PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
print(f"\n⏱️ Total Execution Time: {total_time:.3f}s")
|
||||
|
||||
# Function statistics
|
||||
print("\n📈 Function Performance:")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Execution flow visualization
|
||||
print("\n🔄 Execution Flow:")
|
||||
try:
|
||||
flow_viz = visualize_execution_flow()
|
||||
print(" Flow visualization generated successfully")
|
||||
print(f" Flow data length: {len(str(flow_viz))}")
|
||||
except Exception as e:
|
||||
print(f" Flow visualization: {str(e)}")
|
||||
|
||||
# Performance report
|
||||
print("\n📋 Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:300] + "..." if len(report) > 300 else report)
|
||||
|
||||
# Results summary
|
||||
print(f"\n✅ Results Summary:")
|
||||
print(f" Batch items processed: {len(batch_results)}")
|
||||
print(f" API calls completed: {len(api_results)}")
|
||||
print(f" Agent queries processed: {len(agent_results)}")
|
||||
|
||||
return {
|
||||
'batch_results': batch_results,
|
||||
'api_results': api_results,
|
||||
'agent_results': agent_results,
|
||||
'total_time': total_time
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the async main function
|
||||
result = asyncio.run(main())
|
||||
print(f"\n🎉 Async monitoring example completed successfully!")
|
||||
@@ -0,0 +1,195 @@
|
||||
"""
|
||||
Error Handling with Performance Monitoring - Example 5
|
||||
|
||||
Demonstrates performance monitoring for error scenarios:
|
||||
- Error rate tracking
|
||||
- Failed operation timing
|
||||
- Recovery mechanism performance
|
||||
- Exception handling with monitoring
|
||||
|
||||
Shows how to monitor performance when things go wrong.
|
||||
"""
|
||||
|
||||
import random
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
get_api_stats, performance_monitor
|
||||
)
|
||||
|
||||
@monitor_function("unreliable_operation")
|
||||
def simulate_unreliable_operation(operation_id: int, failure_rate: float = 0.3):
|
||||
"""Simulate an operation that sometimes fails."""
|
||||
print(f"⚙️ Running operation {operation_id}...")
|
||||
|
||||
# Simulate processing time
|
||||
time.sleep(random.uniform(0.05, 0.2))
|
||||
|
||||
# Random failure simulation
|
||||
if random.random() < failure_rate:
|
||||
raise RuntimeError(f"Operation {operation_id} failed!")
|
||||
|
||||
return f"Operation {operation_id} succeeded"
|
||||
|
||||
@monitor_function("retry_with_backoff")
|
||||
def retry_operation(operation_id: int, max_retries: int = 3):
|
||||
"""Retry an operation with exponential backoff and monitoring."""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
print(f"🔄 Attempt {attempt + 1} for operation {operation_id}")
|
||||
result = simulate_unreliable_operation(operation_id)
|
||||
print(f"✅ Operation {operation_id} succeeded on attempt {attempt + 1}")
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"❌ Attempt {attempt + 1} failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
# Exponential backoff
|
||||
sleep_time = 2 ** attempt * 0.1
|
||||
print(f"⏳ Waiting {sleep_time:.1f}s before retry...")
|
||||
time.sleep(sleep_time)
|
||||
else:
|
||||
print(f"💥 All {max_retries} attempts failed for operation {operation_id}")
|
||||
raise
|
||||
|
||||
@monitor_function("robust_agent_execution")
|
||||
def run_robust_agent(query: str, with_error_simulation: bool = True):
|
||||
"""Run agent with error handling and performance monitoring."""
|
||||
|
||||
agent = Agent(
|
||||
instructions="""You are a resilient AI assistant.
|
||||
Even when facing challenges, you provide helpful responses.
|
||||
If you encounter errors, acknowledge them and offer alternatives.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
try:
|
||||
with track_api_call("robust_agent_request"):
|
||||
print(f"🚀 Processing query: {query}")
|
||||
|
||||
if with_error_simulation and random.random() < 0.2:
|
||||
# Simulate API error
|
||||
raise Exception("Simulated API error")
|
||||
|
||||
result = agent.start(query)
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ Error during agent execution: {e}")
|
||||
|
||||
# Fallback response with monitoring
|
||||
with track_api_call("fallback_response"):
|
||||
print("🔄 Using fallback response mechanism...")
|
||||
time.sleep(0.1) # Simulate fallback processing
|
||||
return f"I encountered an error while processing '{query}', but I'm designed to be resilient. Let me provide a general response about this topic."
|
||||
|
||||
@monitor_function("batch_processing_with_errors")
|
||||
def process_batch_with_error_handling(batch_size: int = 5):
|
||||
"""Process a batch of operations with comprehensive error handling."""
|
||||
print(f"📦 Processing batch of {batch_size} operations with error monitoring...")
|
||||
|
||||
results = []
|
||||
errors = []
|
||||
|
||||
for i in range(batch_size):
|
||||
try:
|
||||
result = retry_operation(i + 1)
|
||||
results.append(result)
|
||||
except Exception as e:
|
||||
errors.append(f"Operation {i + 1}: {str(e)}")
|
||||
|
||||
return results, errors
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating error handling with performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 5: Error Handling Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Batch processing with errors
|
||||
print("\n📊 Phase 1: Batch Processing with Error Handling")
|
||||
successes, failures = process_batch_with_error_handling(5)
|
||||
|
||||
print(f"\n📈 Batch Results:")
|
||||
print(f" Successful operations: {len(successes)}")
|
||||
print(f" Failed operations: {len(failures)}")
|
||||
|
||||
# Phase 2: Agent execution with error scenarios
|
||||
print("\n🤖 Phase 2: Agent Execution with Error Scenarios")
|
||||
|
||||
test_queries = [
|
||||
"What is artificial intelligence?",
|
||||
"How do computers work?",
|
||||
"Explain quantum physics",
|
||||
]
|
||||
|
||||
agent_results = []
|
||||
for query in test_queries:
|
||||
try:
|
||||
result = run_robust_agent(query, with_error_simulation=True)
|
||||
agent_results.append(result)
|
||||
print(f"✅ Query processed: '{query[:30]}...'")
|
||||
except Exception as e:
|
||||
print(f"❌ Query failed: '{query[:30]}...' - {e}")
|
||||
|
||||
# Performance Analysis with Error Metrics
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 ERROR HANDLING PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Function performance with error rates
|
||||
print("\n📈 Function Performance (including errors):")
|
||||
stats = get_function_stats()
|
||||
for func_name, data in stats.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
error_rate = data['error_count'] / data['call_count'] * 100 if data['call_count'] > 0 else 0
|
||||
success_rate = 100 - error_rate
|
||||
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Errors: {data['error_count']}")
|
||||
print(f" Success Rate: {success_rate:.1f}%")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
|
||||
# API call reliability
|
||||
print("\n🌐 API Call Reliability:")
|
||||
api_stats = get_api_stats()
|
||||
for api_name, stats in api_stats.items():
|
||||
success_rate = stats['success_count'] / stats['call_count'] * 100 if stats['call_count'] > 0 else 0
|
||||
avg_time = stats['total_time'] / stats['call_count'] if stats['call_count'] > 0 else 0
|
||||
|
||||
print(f" {api_name}:")
|
||||
print(f" Success Rate: {success_rate:.1f}%")
|
||||
print(f" Average Response Time: {avg_time:.3f}s")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
|
||||
# Error patterns analysis
|
||||
print("\n⚠️ Error Patterns:")
|
||||
total_operations = sum(s['call_count'] for s in api_stats.values())
|
||||
total_errors = sum(s['error_count'] for s in api_stats.values())
|
||||
overall_success_rate = ((total_operations - total_errors) / total_operations * 100) if total_operations > 0 else 0
|
||||
|
||||
print(f" Total Operations: {total_operations}")
|
||||
print(f" Total Errors: {total_errors}")
|
||||
print(f" Overall Success Rate: {overall_success_rate:.1f}%")
|
||||
|
||||
# Recommendations
|
||||
print(f"\n💡 Performance Recommendations:")
|
||||
if overall_success_rate < 90:
|
||||
print(" - Consider implementing more robust error handling")
|
||||
print(" - Review retry strategies and backoff algorithms")
|
||||
if total_errors > 0:
|
||||
print(f" - Investigate {total_errors} errors for root cause analysis")
|
||||
print(" - Monitor error patterns for system reliability improvements")
|
||||
|
||||
return {
|
||||
'successful_operations': len(successes),
|
||||
'failed_operations': len(failures),
|
||||
'agent_results': len(agent_results),
|
||||
'overall_success_rate': overall_success_rate
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Error handling monitoring completed!")
|
||||
print(f"Success rate: {result['overall_success_rate']:.1f}%")
|
||||
@@ -0,0 +1,218 @@
|
||||
"""
|
||||
Memory Agent with Performance Monitoring - Example 6
|
||||
|
||||
Demonstrates performance monitoring for agents with memory capabilities:
|
||||
- Memory storage and retrieval timing
|
||||
- Knowledge base operations
|
||||
- Session persistence performance
|
||||
- Memory search optimization
|
||||
|
||||
Shows how to monitor performance in stateful agents.
|
||||
"""
|
||||
|
||||
import time
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_performance_report,
|
||||
get_slowest_functions, analyze_performance_trends
|
||||
)
|
||||
|
||||
# Simulate memory operations since actual memory might not be available
|
||||
@monitor_function("memory_storage")
|
||||
def store_memory(key: str, value: str, memory_type: str = "short_term"):
|
||||
"""Simulate memory storage operation with monitoring."""
|
||||
print(f"💾 Storing {memory_type} memory: {key}")
|
||||
# Simulate storage time - short term is faster
|
||||
storage_time = 0.05 if memory_type == "short_term" else 0.15
|
||||
time.sleep(storage_time)
|
||||
return f"Stored {key} in {memory_type} memory"
|
||||
|
||||
@monitor_function("memory_retrieval")
|
||||
def retrieve_memory(key: str, memory_type: str = "short_term"):
|
||||
"""Simulate memory retrieval operation with monitoring."""
|
||||
print(f"🔍 Retrieving {memory_type} memory: {key}")
|
||||
# Simulate retrieval time
|
||||
retrieval_time = 0.03 if memory_type == "short_term" else 0.12
|
||||
time.sleep(retrieval_time)
|
||||
return f"Retrieved {key} from {memory_type} memory"
|
||||
|
||||
@monitor_function("knowledge_search")
|
||||
def search_knowledge_base(query: str):
|
||||
"""Simulate knowledge base search with monitoring."""
|
||||
print(f"📚 Searching knowledge base for: {query}")
|
||||
# Simulate vector search time
|
||||
time.sleep(0.08)
|
||||
return f"Knowledge search results for: {query}"
|
||||
|
||||
@monitor_function("memory_consolidation")
|
||||
def consolidate_memories(session_id: str):
|
||||
"""Simulate memory consolidation process."""
|
||||
print(f"🔄 Consolidating memories for session: {session_id}")
|
||||
|
||||
# Simulate consolidation steps
|
||||
store_memory("consolidated_session", session_id, "long_term")
|
||||
retrieve_memory("recent_interactions", "short_term")
|
||||
|
||||
time.sleep(0.1)
|
||||
return f"Memories consolidated for session: {session_id}"
|
||||
|
||||
@monitor_function("stateful_agent_interaction")
|
||||
def run_stateful_agent(query: str, session_id: str, conversation_turn: int):
|
||||
"""Run agent with memory operations and monitoring."""
|
||||
|
||||
# Simulate memory-enabled agent
|
||||
agent = Agent(
|
||||
instructions="""You are a memory-enabled AI assistant. You can remember
|
||||
previous conversations and build on past interactions. Use your memory
|
||||
to provide personalized and contextual responses.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Pre-processing: retrieve relevant memories
|
||||
with track_api_call("memory_preprocessing"):
|
||||
print(f"🧠 Pre-processing memories for turn {conversation_turn}")
|
||||
|
||||
# Retrieve session context
|
||||
if conversation_turn > 1:
|
||||
retrieve_memory(f"session_{session_id}", "short_term")
|
||||
|
||||
# Search for relevant knowledge
|
||||
search_knowledge_base(query)
|
||||
|
||||
time.sleep(0.05) # Simulate context preparation
|
||||
|
||||
# Main agent execution
|
||||
with track_api_call("memory_agent_execution"):
|
||||
print(f"🚀 Processing query with memory context...")
|
||||
result = agent.start(query)
|
||||
|
||||
# Post-processing: store new memories
|
||||
with track_api_call("memory_postprocessing"):
|
||||
print(f"💭 Post-processing: storing interaction memories")
|
||||
|
||||
# Store the interaction
|
||||
store_memory(f"interaction_{conversation_turn}", query, "short_term")
|
||||
store_memory(f"response_{conversation_turn}", result, "short_term")
|
||||
|
||||
# Update session memory
|
||||
store_memory(f"session_{session_id}", f"Turn {conversation_turn} completed", "short_term")
|
||||
|
||||
time.sleep(0.03) # Simulate memory update
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("multi_turn_conversation")
|
||||
def simulate_multi_turn_conversation():
|
||||
"""Simulate a multi-turn conversation with memory."""
|
||||
session_id = "demo_session_001"
|
||||
|
||||
conversation = [
|
||||
"Hello, I'm interested in learning about machine learning",
|
||||
"What are the main types of machine learning algorithms?",
|
||||
"Can you give me examples of supervised learning?",
|
||||
"How does this relate to what we discussed about machine learning earlier?"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for turn, query in enumerate(conversation, 1):
|
||||
print(f"\n💬 Conversation Turn {turn}")
|
||||
print(f"User: {query}")
|
||||
|
||||
result = run_stateful_agent(query, session_id, turn)
|
||||
results.append(result)
|
||||
|
||||
print(f"Agent: {result[:100]}..." if len(result) > 100 else f"Agent: {result}")
|
||||
|
||||
# Simulate user thinking time
|
||||
time.sleep(0.1)
|
||||
|
||||
# End of conversation: consolidate memories
|
||||
consolidate_memories(session_id)
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating memory agent performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 6: Memory Agent Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Warm up the memory system
|
||||
print("\n🚀 Phase 1: Memory System Initialization")
|
||||
store_memory("system_initialized", "true", "long_term")
|
||||
search_knowledge_base("initialization")
|
||||
|
||||
# Run multi-turn conversation
|
||||
print("\n💬 Phase 2: Multi-Turn Conversation with Memory")
|
||||
conversation_results = simulate_multi_turn_conversation()
|
||||
|
||||
# Memory performance analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 MEMORY PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Performance trends analysis
|
||||
print("\n📈 Performance Trends:")
|
||||
try:
|
||||
trends = analyze_performance_trends()
|
||||
print(f" Performance trend analysis completed")
|
||||
if trends:
|
||||
print(f" Functions analyzed: {len(trends.get('functions', []))}")
|
||||
except Exception as e:
|
||||
print(f" Trends analysis: {str(e)}")
|
||||
|
||||
# Slowest operations
|
||||
print("\n🐌 Slowest Memory Operations:")
|
||||
slowest = get_slowest_functions()
|
||||
for func_name, avg_time in slowest[:5]: # Top 5 slowest
|
||||
print(f" {func_name}: {avg_time:.3f}s average")
|
||||
|
||||
# Memory operation breakdown
|
||||
print("\n💾 Memory Operation Breakdown:")
|
||||
from praisonaiagents.telemetry import get_function_stats
|
||||
stats = get_function_stats()
|
||||
|
||||
memory_operations = {k: v for k, v in stats.items() if 'memory' in k.lower()}
|
||||
|
||||
for op_name, data in memory_operations.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {op_name}:")
|
||||
print(f" Operations: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Session efficiency metrics
|
||||
total_memory_ops = sum(data['call_count'] for data in memory_operations.values())
|
||||
total_memory_time = sum(data['total_time'] for data in memory_operations.values())
|
||||
|
||||
print(f"\n🔍 Session Efficiency:")
|
||||
print(f" Total Memory Operations: {total_memory_ops}")
|
||||
print(f" Total Memory Time: {total_memory_time:.3f}s")
|
||||
print(f" Avg Time per Memory Op: {total_memory_time/total_memory_ops:.3f}s" if total_memory_ops > 0 else " No memory operations")
|
||||
|
||||
# Performance report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:400] + "..." if len(report) > 400 else report)
|
||||
|
||||
# Memory optimization suggestions
|
||||
print(f"\n💡 Memory Optimization Suggestions:")
|
||||
if total_memory_time > 1.0:
|
||||
print(" - Consider implementing memory caching strategies")
|
||||
print(" - Optimize vector search indexes for faster retrieval")
|
||||
if total_memory_ops > 10:
|
||||
print(" - Consider batching memory operations for efficiency")
|
||||
print(" - Monitor memory consolidation frequency vs performance")
|
||||
|
||||
return {
|
||||
'conversation_turns': len(conversation_results),
|
||||
'memory_operations': total_memory_ops,
|
||||
'total_memory_time': total_memory_time
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Memory agent monitoring completed!")
|
||||
print(f"Processed {result['conversation_turns']} conversation turns")
|
||||
print(f"Executed {result['memory_operations']} memory operations in {result['total_memory_time']:.3f}s")
|
||||
@@ -0,0 +1,264 @@
|
||||
"""
|
||||
Hierarchical Agents with Performance Monitoring - Example 7
|
||||
|
||||
Demonstrates performance monitoring for hierarchical agent systems:
|
||||
- Manager-worker agent relationships
|
||||
- Task delegation timing
|
||||
- Hierarchical decision making performance
|
||||
- Cross-level communication monitoring
|
||||
|
||||
Shows how to monitor complex organizational agent structures.
|
||||
"""
|
||||
|
||||
import time
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
visualize_execution_flow, generate_comprehensive_report
|
||||
)
|
||||
|
||||
@monitor_function("manager_decision_making")
|
||||
def make_management_decision(task_description: str):
|
||||
"""Simulate manager decision making process."""
|
||||
print(f"👔 Manager analyzing task: {task_description}")
|
||||
# Simulate decision complexity
|
||||
time.sleep(0.1)
|
||||
|
||||
# Simple task routing logic
|
||||
if "research" in task_description.lower():
|
||||
return "research_worker"
|
||||
elif "analysis" in task_description.lower():
|
||||
return "analysis_worker"
|
||||
elif "report" in task_description.lower():
|
||||
return "writing_worker"
|
||||
else:
|
||||
return "general_worker"
|
||||
|
||||
@monitor_function("task_delegation")
|
||||
def delegate_task(task: str, worker_type: str):
|
||||
"""Simulate task delegation to workers."""
|
||||
print(f"📤 Delegating to {worker_type}: {task}")
|
||||
time.sleep(0.05) # Delegation overhead
|
||||
return f"Task delegated to {worker_type}"
|
||||
|
||||
@monitor_function("worker_execution")
|
||||
def execute_worker_task(worker_name: str, task_description: str):
|
||||
"""Simulate worker executing assigned task."""
|
||||
print(f"⚙️ {worker_name} executing: {task_description}")
|
||||
|
||||
# Different workers have different execution times
|
||||
if "research" in worker_name:
|
||||
time.sleep(0.2) # Research takes longer
|
||||
elif "analysis" in worker_name:
|
||||
time.sleep(0.15) # Analysis is moderate
|
||||
elif "writing" in worker_name:
|
||||
time.sleep(0.1) # Writing is relatively quick
|
||||
else:
|
||||
time.sleep(0.12) # General tasks
|
||||
|
||||
return f"{worker_name} completed: {task_description}"
|
||||
|
||||
@monitor_function("result_aggregation")
|
||||
def aggregate_results(results: list):
|
||||
"""Simulate aggregating results from multiple workers."""
|
||||
print(f"📊 Aggregating {len(results)} worker results...")
|
||||
time.sleep(0.08) # Aggregation time
|
||||
return f"Aggregated {len(results)} results into final output"
|
||||
|
||||
@monitor_function("hierarchical_workflow")
|
||||
def run_hierarchical_workflow():
|
||||
"""Run a complete hierarchical workflow with monitoring."""
|
||||
|
||||
# Create manager agent
|
||||
manager = Agent(
|
||||
name="project_manager",
|
||||
role="Project Manager",
|
||||
goal="Efficiently coordinate team efforts and ensure project success",
|
||||
backstory="Experienced project manager with expertise in team coordination",
|
||||
instructions="""You are a project manager. Break down complex projects into tasks,
|
||||
assign them to appropriate team members, and coordinate the overall effort.""",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create worker agents
|
||||
research_worker = Agent(
|
||||
name="research_specialist",
|
||||
role="Research Specialist",
|
||||
goal="Conduct thorough research on assigned topics",
|
||||
backstory="Expert researcher with deep analytical skills",
|
||||
instructions="You are a research specialist. Provide detailed, factual information.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
analysis_worker = Agent(
|
||||
name="data_analyst",
|
||||
role="Data Analyst",
|
||||
goal="Analyze data and identify patterns and insights",
|
||||
backstory="Experienced data analyst with strong analytical thinking",
|
||||
instructions="You are a data analyst. Focus on patterns, trends, and insights.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
writing_worker = Agent(
|
||||
name="technical_writer",
|
||||
role="Technical Writer",
|
||||
goal="Create clear, well-structured documentation and reports",
|
||||
backstory="Professional writer specializing in technical content",
|
||||
instructions="You are a technical writer. Create clear, comprehensive reports.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Project tasks
|
||||
project_tasks = [
|
||||
"Research current trends in artificial intelligence",
|
||||
"Analyze the impact of AI on business productivity",
|
||||
"Write a comprehensive report on AI implementation strategies"
|
||||
]
|
||||
|
||||
# Execute hierarchical workflow
|
||||
with track_api_call("hierarchical_project_execution"):
|
||||
print("🏢 Starting hierarchical project execution...")
|
||||
|
||||
all_results = []
|
||||
|
||||
for task_desc in project_tasks:
|
||||
print(f"\n📋 Processing project task: {task_desc}")
|
||||
|
||||
# Manager makes decision
|
||||
assigned_worker = make_management_decision(task_desc)
|
||||
|
||||
# Delegate task
|
||||
delegation_result = delegate_task(task_desc, assigned_worker)
|
||||
|
||||
# Select appropriate worker
|
||||
if "research" in assigned_worker:
|
||||
worker = research_worker
|
||||
worker_name = "research_specialist"
|
||||
elif "analysis" in assigned_worker:
|
||||
worker = analysis_worker
|
||||
worker_name = "data_analyst"
|
||||
elif "writing" in assigned_worker:
|
||||
worker = writing_worker
|
||||
worker_name = "technical_writer"
|
||||
else:
|
||||
worker = research_worker # Default
|
||||
worker_name = "research_specialist"
|
||||
|
||||
# Worker executes task
|
||||
worker_result = execute_worker_task(worker_name, task_desc)
|
||||
|
||||
# Simulate actual agent execution
|
||||
with track_api_call(f"{worker_name}_llm_execution"):
|
||||
agent_result = worker.start(task_desc)
|
||||
all_results.append(agent_result)
|
||||
|
||||
# Manager aggregates results
|
||||
final_result = aggregate_results(all_results)
|
||||
|
||||
# Final manager review
|
||||
with track_api_call("manager_final_review"):
|
||||
print("👔 Manager conducting final review...")
|
||||
manager_review = manager.start(
|
||||
f"Review and synthesize these team outputs: {[r[:100] + '...' for r in all_results]}"
|
||||
)
|
||||
|
||||
return all_results, manager_review
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating hierarchical agents performance monitoring."""
|
||||
print("=" * 75)
|
||||
print("EXAMPLE 7: Hierarchical Agents Performance Monitoring")
|
||||
print("=" * 75)
|
||||
|
||||
# Run hierarchical workflow
|
||||
print("\n🏢 Running Hierarchical Agent Workflow")
|
||||
worker_results, manager_review = run_hierarchical_workflow()
|
||||
|
||||
print(f"\n✅ Workflow completed with {len(worker_results)} task results")
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 75)
|
||||
print("📊 HIERARCHICAL PERFORMANCE ANALYSIS")
|
||||
print("=" * 75)
|
||||
|
||||
# Role-based performance breakdown
|
||||
print("\n👥 Role-Based Performance:")
|
||||
stats = get_function_stats()
|
||||
|
||||
# Categorize functions by role
|
||||
management_functions = [f for f in stats.keys() if 'manager' in f or 'decision' in f or 'delegation' in f or 'aggregation' in f]
|
||||
worker_functions = [f for f in stats.keys() if 'worker' in f or 'execution' in f]
|
||||
coordination_functions = [f for f in stats.keys() if 'hierarchical' in f or 'workflow' in f]
|
||||
|
||||
print(" 📋 Management Functions:")
|
||||
for func in management_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
print("\n ⚙️ Worker Functions:")
|
||||
for func in worker_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
print("\n 🔄 Coordination Functions:")
|
||||
for func in coordination_functions:
|
||||
data = stats[func]
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func}: {data['call_count']} calls, {avg_time:.3f}s avg")
|
||||
|
||||
# Hierarchy efficiency metrics
|
||||
total_management_time = sum(stats[f]['total_time'] for f in management_functions)
|
||||
total_worker_time = sum(stats[f]['total_time'] for f in worker_functions)
|
||||
total_coordination_time = sum(stats[f]['total_time'] for f in coordination_functions)
|
||||
|
||||
print(f"\n⚖️ Hierarchy Efficiency Metrics:")
|
||||
print(f" Management Overhead: {total_management_time:.3f}s")
|
||||
print(f" Worker Execution Time: {total_worker_time:.3f}s")
|
||||
print(f" Coordination Overhead: {total_coordination_time:.3f}s")
|
||||
|
||||
total_time = total_management_time + total_worker_time + total_coordination_time
|
||||
if total_time > 0:
|
||||
print(f" Worker Efficiency: {total_worker_time/total_time*100:.1f}%")
|
||||
print(f" Management Overhead: {total_management_time/total_time*100:.1f}%")
|
||||
print(f" Coordination Overhead: {total_coordination_time/total_time*100:.1f}%")
|
||||
|
||||
# Execution flow visualization
|
||||
print("\n🔄 Execution Flow Analysis:")
|
||||
try:
|
||||
flow_viz = visualize_execution_flow()
|
||||
print(" Hierarchical flow visualization generated")
|
||||
print(f" Flow complexity: {len(str(flow_viz)) // 100} units")
|
||||
except Exception as e:
|
||||
print(f" Flow visualization: {str(e)}")
|
||||
|
||||
# Comprehensive report
|
||||
print("\n📋 Comprehensive Performance Report:")
|
||||
report = generate_comprehensive_report()
|
||||
print(report[:500] + "..." if len(report) > 500 else report)
|
||||
|
||||
# Optimization recommendations
|
||||
print(f"\n💡 Hierarchical Optimization Recommendations:")
|
||||
|
||||
if total_time > 0:
|
||||
if total_management_time / total_time > 0.3:
|
||||
print(" - High management overhead detected - consider task batching")
|
||||
if total_coordination_time / total_time > 0.2:
|
||||
print(" - Consider reducing coordination complexity")
|
||||
if len(worker_results) > 0:
|
||||
print(f" - Successfully processed {len(worker_results)} tasks hierarchically")
|
||||
print(" - Monitor delegation efficiency vs direct execution trade-offs")
|
||||
|
||||
return {
|
||||
'tasks_completed': len(worker_results),
|
||||
'management_time': total_management_time,
|
||||
'worker_time': total_worker_time,
|
||||
'coordination_time': total_coordination_time,
|
||||
'efficiency_ratio': total_worker_time / total_time if total_time > 0 else 0
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Hierarchical monitoring completed!")
|
||||
print(f"Tasks: {result['tasks_completed']}, Efficiency: {result['efficiency_ratio']*100:.1f}%")
|
||||
@@ -0,0 +1,314 @@
|
||||
"""
|
||||
Custom Tools with Performance Monitoring - Example 8
|
||||
|
||||
Demonstrates performance monitoring for agents using custom tools:
|
||||
- Custom tool execution timing
|
||||
- Tool creation and registration performance
|
||||
- Tool usage pattern analysis
|
||||
- Tool efficiency optimization
|
||||
|
||||
Shows how to monitor performance with custom-built tools.
|
||||
"""
|
||||
|
||||
import time
|
||||
import random
|
||||
from praisonaiagents import Agent, tool
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, get_function_stats,
|
||||
get_slowest_functions, performance_monitor
|
||||
)
|
||||
|
||||
# Custom Tool 1: Data Processor
|
||||
@tool
|
||||
@monitor_function("data_processor_tool")
|
||||
def process_data(data: str, operation: str = "analyze") -> str:
|
||||
"""
|
||||
Process data with specified operation.
|
||||
|
||||
Args:
|
||||
data: The data to process
|
||||
operation: Type of operation (analyze, transform, validate)
|
||||
"""
|
||||
print(f"🔧 Processing data with operation: {operation}")
|
||||
|
||||
# Simulate different processing times based on operation
|
||||
processing_times = {
|
||||
"analyze": 0.15,
|
||||
"transform": 0.2,
|
||||
"validate": 0.1
|
||||
}
|
||||
|
||||
time.sleep(processing_times.get(operation, 0.12))
|
||||
|
||||
return f"Data processed with {operation}: {data[:50]}{'...' if len(data) > 50 else ''}"
|
||||
|
||||
# Custom Tool 2: API Simulator
|
||||
@tool
|
||||
@monitor_function("api_simulator_tool")
|
||||
def call_external_api(endpoint: str, method: str = "GET", payload: str = "") -> str:
|
||||
"""
|
||||
Simulate calling an external API.
|
||||
|
||||
Args:
|
||||
endpoint: API endpoint to call
|
||||
method: HTTP method (GET, POST, PUT, DELETE)
|
||||
payload: Request payload for POST/PUT
|
||||
"""
|
||||
print(f"🌐 Calling API: {method} {endpoint}")
|
||||
|
||||
# Simulate variable API response times
|
||||
base_time = 0.1
|
||||
if method == "POST":
|
||||
base_time += 0.05
|
||||
if payload:
|
||||
base_time += len(payload) * 0.001
|
||||
|
||||
# Add random variation
|
||||
response_time = base_time + random.uniform(0, 0.1)
|
||||
time.sleep(response_time)
|
||||
|
||||
# Simulate occasional API failures
|
||||
if random.random() < 0.1: # 10% failure rate
|
||||
raise Exception(f"API call to {endpoint} failed")
|
||||
|
||||
return f"API Response from {endpoint}: {{'status': 'success', 'method': '{method}'}}"
|
||||
|
||||
# Custom Tool 3: Database Simulator
|
||||
@tool
|
||||
@monitor_function("database_simulator_tool")
|
||||
def query_database(query: str, database: str = "main") -> str:
|
||||
"""
|
||||
Simulate database query execution.
|
||||
|
||||
Args:
|
||||
query: SQL query to execute
|
||||
database: Database name to query
|
||||
"""
|
||||
print(f"🗄️ Executing database query on {database}")
|
||||
|
||||
# Simulate query complexity based on keywords
|
||||
complexity_keywords = {
|
||||
"JOIN": 0.08,
|
||||
"GROUP BY": 0.06,
|
||||
"ORDER BY": 0.04,
|
||||
"WHERE": 0.03
|
||||
}
|
||||
|
||||
query_time = 0.05 # Base query time
|
||||
for keyword, additional_time in complexity_keywords.items():
|
||||
if keyword in query.upper():
|
||||
query_time += additional_time
|
||||
|
||||
time.sleep(query_time)
|
||||
|
||||
return f"Query executed on {database}: Found {random.randint(1, 100)} results"
|
||||
|
||||
# Custom Tool 4: File Operations
|
||||
@tool
|
||||
@monitor_function("file_operations_tool")
|
||||
def file_operation(operation: str, filename: str, content: str = "") -> str:
|
||||
"""
|
||||
Simulate file operations.
|
||||
|
||||
Args:
|
||||
operation: Operation type (read, write, delete, copy)
|
||||
filename: Target filename
|
||||
content: Content for write operations
|
||||
"""
|
||||
print(f"📁 File operation: {operation} on {filename}")
|
||||
|
||||
# Simulate different operation times
|
||||
operation_times = {
|
||||
"read": 0.03,
|
||||
"write": 0.05,
|
||||
"delete": 0.02,
|
||||
"copy": 0.07
|
||||
}
|
||||
|
||||
time.sleep(operation_times.get(operation, 0.04))
|
||||
|
||||
if operation == "write" and content:
|
||||
time.sleep(len(content) * 0.0001) # Simulate write time based on content size
|
||||
|
||||
return f"File {operation} completed for {filename}"
|
||||
|
||||
@monitor_function("tool_performance_test")
|
||||
def test_tool_performance():
|
||||
"""Test individual tool performance."""
|
||||
print("🧪 Testing individual tool performance...")
|
||||
|
||||
# Test each tool multiple times
|
||||
tools_results = []
|
||||
|
||||
# Test data processor
|
||||
for op in ["analyze", "transform", "validate"]:
|
||||
result = process_data("Sample data for testing", op)
|
||||
tools_results.append(f"DataProcessor[{op}]: {result}")
|
||||
|
||||
# Test API simulator
|
||||
for method in ["GET", "POST"]:
|
||||
try:
|
||||
result = call_external_api("/api/test", method, "test payload" if method == "POST" else "")
|
||||
tools_results.append(f"APISimulator[{method}]: {result}")
|
||||
except Exception as e:
|
||||
tools_results.append(f"APISimulator[{method}]: Failed - {e}")
|
||||
|
||||
# Test database operations
|
||||
queries = [
|
||||
"SELECT * FROM users",
|
||||
"SELECT COUNT(*) FROM orders WHERE date > '2024-01-01'",
|
||||
"SELECT u.name, COUNT(o.id) FROM users u JOIN orders o GROUP BY u.id"
|
||||
]
|
||||
|
||||
for query in queries:
|
||||
result = query_database(query)
|
||||
tools_results.append(f"Database: {result}")
|
||||
|
||||
# Test file operations
|
||||
for op in ["read", "write", "copy"]:
|
||||
result = file_operation(op, "test_file.txt", "Test content" if op == "write" else "")
|
||||
tools_results.append(f"FileOps[{op}]: {result}")
|
||||
|
||||
return tools_results
|
||||
|
||||
@monitor_function("agent_with_custom_tools")
|
||||
def run_agent_with_custom_tools():
|
||||
"""Run agent using custom tools with performance monitoring."""
|
||||
|
||||
# Create agent with custom tools
|
||||
agent = Agent(
|
||||
instructions="""You are a technical assistant with access to various tools.
|
||||
Use the appropriate tools to help with data processing, API calls, database queries,
|
||||
and file operations. Always explain what tools you're using and why.""",
|
||||
llm="gpt-4o-mini",
|
||||
tools=[process_data, call_external_api, query_database, file_operation]
|
||||
)
|
||||
|
||||
# Test scenarios for the agent
|
||||
scenarios = [
|
||||
"I need to analyze some customer data and store the results",
|
||||
"Please fetch user information from the API and save it to a file",
|
||||
"Query the database for recent orders and process the results"
|
||||
]
|
||||
|
||||
results = []
|
||||
|
||||
for i, scenario in enumerate(scenarios, 1):
|
||||
print(f"\n🎯 Scenario {i}: {scenario}")
|
||||
|
||||
with track_api_call(f"custom_tools_scenario_{i}"):
|
||||
try:
|
||||
result = agent.start(scenario)
|
||||
results.append(result)
|
||||
print(f"✅ Scenario {i} completed")
|
||||
except Exception as e:
|
||||
print(f"❌ Scenario {i} failed: {e}")
|
||||
results.append(f"Failed: {e}")
|
||||
|
||||
return results
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating custom tools performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 8: Custom Tools Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Individual tool performance testing
|
||||
print("\n🔧 Phase 1: Individual Tool Performance Testing")
|
||||
tool_test_results = test_tool_performance()
|
||||
|
||||
print(f"\n📊 Tool Test Summary:")
|
||||
print(f" Total tool operations: {len(tool_test_results)}")
|
||||
for result in tool_test_results[:5]: # Show first 5 results
|
||||
print(f" - {result}")
|
||||
if len(tool_test_results) > 5:
|
||||
print(f" ... and {len(tool_test_results) - 5} more")
|
||||
|
||||
# Phase 2: Agent using custom tools
|
||||
print("\n🤖 Phase 2: Agent with Custom Tools")
|
||||
agent_results = run_agent_with_custom_tools()
|
||||
|
||||
# Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 CUSTOM TOOLS PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Tool-specific performance
|
||||
print("\n🔧 Tool Performance Breakdown:")
|
||||
stats = get_function_stats()
|
||||
tool_functions = {k: v for k, v in stats.items() if 'tool' in k.lower()}
|
||||
|
||||
for tool_name, data in tool_functions.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {tool_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
if data['error_count'] > 0:
|
||||
print(f" Errors: {data['error_count']}")
|
||||
|
||||
# Tool efficiency ranking
|
||||
print("\n🏆 Tool Efficiency Ranking (by average execution time):")
|
||||
tool_efficiency = []
|
||||
for tool_name, data in tool_functions.items():
|
||||
if data['call_count'] > 0:
|
||||
avg_time = data['total_time'] / data['call_count']
|
||||
tool_efficiency.append((tool_name, avg_time))
|
||||
|
||||
tool_efficiency.sort(key=lambda x: x[1])
|
||||
|
||||
for rank, (tool_name, avg_time) in enumerate(tool_efficiency, 1):
|
||||
print(f" {rank}. {tool_name}: {avg_time:.3f}s")
|
||||
|
||||
# Slowest operations
|
||||
print("\n🐌 Slowest Tool Operations:")
|
||||
slowest = get_slowest_functions()
|
||||
tool_slowest = [(name, time) for name, time in slowest if 'tool' in name.lower()]
|
||||
|
||||
for tool_name, avg_time in tool_slowest[:3]:
|
||||
print(f" {tool_name}: {avg_time:.3f}s")
|
||||
|
||||
# Usage patterns
|
||||
total_tool_calls = sum(data['call_count'] for data in tool_functions.values())
|
||||
total_tool_time = sum(data['total_time'] for data in tool_functions.values())
|
||||
|
||||
print(f"\n📈 Tool Usage Summary:")
|
||||
print(f" Total Tool Calls: {total_tool_calls}")
|
||||
print(f" Total Tool Execution Time: {total_tool_time:.3f}s")
|
||||
print(f" Average Time per Tool Call: {total_tool_time/total_tool_calls:.3f}s" if total_tool_calls > 0 else " No tool calls")
|
||||
|
||||
# Tool reliability
|
||||
total_tool_errors = sum(data['error_count'] for data in tool_functions.values())
|
||||
reliability = ((total_tool_calls - total_tool_errors) / total_tool_calls * 100) if total_tool_calls > 0 else 100
|
||||
|
||||
print(f" Tool Reliability: {reliability:.1f}%")
|
||||
if total_tool_errors > 0:
|
||||
print(f" Total Errors: {total_tool_errors}")
|
||||
|
||||
# Optimization recommendations
|
||||
print(f"\n💡 Custom Tools Optimization Recommendations:")
|
||||
|
||||
if tool_efficiency:
|
||||
slowest_tool = tool_efficiency[-1]
|
||||
if slowest_tool[1] > 0.2:
|
||||
print(f" - Optimize {slowest_tool[0]} (slowest at {slowest_tool[1]:.3f}s)")
|
||||
|
||||
if total_tool_errors > 0:
|
||||
print(f" - Investigate {total_tool_errors} tool errors for stability improvements")
|
||||
|
||||
if total_tool_calls > 20:
|
||||
print(" - Consider tool caching for frequently used operations")
|
||||
|
||||
print(" - Monitor tool usage patterns for optimization opportunities")
|
||||
|
||||
return {
|
||||
'tool_operations': len(tool_test_results),
|
||||
'agent_scenarios': len(agent_results),
|
||||
'total_tool_calls': total_tool_calls,
|
||||
'tool_reliability': reliability
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n✅ Custom tools monitoring completed!")
|
||||
print(f"Operations: {result['tool_operations']}, Reliability: {result['tool_reliability']:.1f}%")
|
||||
@@ -0,0 +1,286 @@
|
||||
"""
|
||||
Streaming & Real-Time Performance Monitoring - Example 9
|
||||
|
||||
Demonstrates performance monitoring for streaming and real-time operations:
|
||||
- Real-time performance tracking
|
||||
- Streaming response monitoring
|
||||
- Live performance metrics
|
||||
- Continuous performance analysis
|
||||
|
||||
Shows how to monitor performance during streaming operations.
|
||||
"""
|
||||
|
||||
import time
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
get_performance_report, get_function_stats
|
||||
)
|
||||
|
||||
# Global variables for streaming simulation
|
||||
streaming_active = False
|
||||
streaming_stats = {
|
||||
'messages_processed': 0,
|
||||
'total_latency': 0.0,
|
||||
'errors': 0,
|
||||
'start_time': None
|
||||
}
|
||||
|
||||
@monitor_function("stream_message_processing")
|
||||
def process_stream_message(message_id: int, content: str):
|
||||
"""Process a single streaming message with monitoring."""
|
||||
processing_start = time.time()
|
||||
|
||||
print(f"📨 Processing stream message {message_id}: {content[:30]}...")
|
||||
|
||||
# Simulate variable processing time
|
||||
processing_time = 0.05 + (message_id % 3) * 0.02 # Simulate varying complexity
|
||||
time.sleep(processing_time)
|
||||
|
||||
# Simulate occasional errors
|
||||
if message_id % 20 == 0: # Every 20th message fails
|
||||
raise Exception(f"Processing error for message {message_id}")
|
||||
|
||||
processing_end = time.time()
|
||||
latency = processing_end - processing_start
|
||||
|
||||
# Update streaming stats
|
||||
streaming_stats['messages_processed'] += 1
|
||||
streaming_stats['total_latency'] += latency
|
||||
|
||||
return f"Processed message {message_id} in {latency:.3f}s"
|
||||
|
||||
@monitor_function("real_time_agent_response")
|
||||
def get_real_time_agent_response(query: str, response_id: int):
|
||||
"""Simulate real-time agent response with monitoring."""
|
||||
print(f"🤖 Generating real-time response {response_id} for: {query}")
|
||||
|
||||
# Create a lightweight agent for streaming
|
||||
agent = Agent(
|
||||
instructions="You are a real-time assistant. Provide quick, helpful responses.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
with track_api_call(f"streaming_response_{response_id}"):
|
||||
# Simulate streaming response generation
|
||||
time.sleep(0.1) # Base response time
|
||||
|
||||
# In real implementation, this would be actual agent.start()
|
||||
response = agent.start(f"Quickly respond to: {query}")
|
||||
|
||||
return response
|
||||
|
||||
@monitor_function("performance_metrics_collector")
|
||||
def collect_live_metrics():
|
||||
"""Collect live performance metrics during streaming."""
|
||||
|
||||
while streaming_active:
|
||||
current_time = time.time()
|
||||
|
||||
# Collect current performance data
|
||||
current_stats = performance_monitor.get_function_performance()
|
||||
api_stats = performance_monitor.get_api_call_performance()
|
||||
|
||||
# Calculate streaming metrics
|
||||
if streaming_stats['start_time']:
|
||||
elapsed_time = current_time - streaming_stats['start_time']
|
||||
messages_per_second = streaming_stats['messages_processed'] / elapsed_time if elapsed_time > 0 else 0
|
||||
avg_latency = streaming_stats['total_latency'] / streaming_stats['messages_processed'] if streaming_stats['messages_processed'] > 0 else 0
|
||||
|
||||
print(f"📊 Live Metrics - Messages/sec: {messages_per_second:.2f}, Avg Latency: {avg_latency:.3f}s")
|
||||
|
||||
time.sleep(2) # Update every 2 seconds
|
||||
|
||||
@monitor_function("streaming_simulation")
|
||||
def simulate_streaming_workload():
|
||||
"""Simulate a streaming workload with continuous monitoring."""
|
||||
global streaming_active, streaming_stats
|
||||
|
||||
print("🌊 Starting streaming simulation...")
|
||||
streaming_active = True
|
||||
streaming_stats['start_time'] = time.time()
|
||||
|
||||
# Start metrics collector in background
|
||||
metrics_thread = threading.Thread(target=collect_live_metrics)
|
||||
metrics_thread.daemon = True
|
||||
metrics_thread.start()
|
||||
|
||||
# Simulate incoming stream messages
|
||||
messages = [
|
||||
"User question about AI",
|
||||
"Request for weather information",
|
||||
"Help with programming",
|
||||
"General knowledge query",
|
||||
"Technical support request",
|
||||
"Creative writing assistance",
|
||||
"Data analysis question",
|
||||
"Research inquiry"
|
||||
]
|
||||
|
||||
processed_responses = []
|
||||
|
||||
try:
|
||||
for i in range(20): # Process 20 streaming messages
|
||||
message = messages[i % len(messages)]
|
||||
|
||||
try:
|
||||
# Process the stream message
|
||||
result = process_stream_message(i + 1, message)
|
||||
|
||||
# Generate real-time response every 3rd message
|
||||
if (i + 1) % 3 == 0:
|
||||
response = get_real_time_agent_response(message, i + 1)
|
||||
processed_responses.append(response)
|
||||
|
||||
# Brief pause between messages
|
||||
time.sleep(0.1)
|
||||
|
||||
except Exception as e:
|
||||
streaming_stats['errors'] += 1
|
||||
print(f"❌ Error processing message {i + 1}: {e}")
|
||||
|
||||
finally:
|
||||
streaming_active = False
|
||||
print("🛑 Streaming simulation completed")
|
||||
|
||||
return processed_responses
|
||||
|
||||
@monitor_function("batch_vs_streaming_comparison")
|
||||
def compare_batch_vs_streaming():
|
||||
"""Compare batch vs streaming performance."""
|
||||
|
||||
print("\n🔄 Comparing Batch vs Streaming Performance...")
|
||||
|
||||
# Batch processing simulation
|
||||
print("\n📦 Batch Processing Test:")
|
||||
batch_start = time.time()
|
||||
|
||||
batch_messages = [f"Batch message {i}" for i in range(10)]
|
||||
batch_results = []
|
||||
|
||||
with track_api_call("batch_processing"):
|
||||
for i, message in enumerate(batch_messages):
|
||||
# Simulate batch processing (all at once)
|
||||
time.sleep(0.08) # Batch processing time
|
||||
batch_results.append(f"Batch processed: {message}")
|
||||
|
||||
batch_time = time.time() - batch_start
|
||||
|
||||
# Streaming processing test (already done above)
|
||||
streaming_time = streaming_stats['total_latency']
|
||||
streaming_count = streaming_stats['messages_processed']
|
||||
|
||||
print(f"\n📊 Batch vs Streaming Comparison:")
|
||||
print(f" Batch Processing:")
|
||||
print(f" Messages: {len(batch_results)}")
|
||||
print(f" Total Time: {batch_time:.3f}s")
|
||||
print(f" Avg per Message: {batch_time/len(batch_results):.3f}s")
|
||||
|
||||
print(f" Streaming Processing:")
|
||||
print(f" Messages: {streaming_count}")
|
||||
print(f" Total Processing Time: {streaming_time:.3f}s")
|
||||
print(f" Avg per Message: {streaming_time/streaming_count:.3f}s" if streaming_count > 0 else " No messages processed")
|
||||
|
||||
return batch_time, streaming_time
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating streaming performance monitoring."""
|
||||
print("=" * 70)
|
||||
print("EXAMPLE 9: Streaming & Real-Time Performance Monitoring")
|
||||
print("=" * 70)
|
||||
|
||||
# Phase 1: Streaming simulation
|
||||
print("\n🌊 Phase 1: Streaming Workload Simulation")
|
||||
streaming_responses = simulate_streaming_workload()
|
||||
|
||||
# Phase 2: Batch vs Streaming comparison
|
||||
print("\n📊 Phase 2: Batch vs Streaming Comparison")
|
||||
batch_time, streaming_time = compare_batch_vs_streaming()
|
||||
|
||||
# Real-time Performance Analysis
|
||||
print("\n" + "=" * 70)
|
||||
print("📊 STREAMING PERFORMANCE ANALYSIS")
|
||||
print("=" * 70)
|
||||
|
||||
# Streaming-specific metrics
|
||||
print("\n🌊 Streaming Metrics:")
|
||||
elapsed_total = time.time() - streaming_stats['start_time'] if streaming_stats['start_time'] else 0
|
||||
throughput = streaming_stats['messages_processed'] / elapsed_total if elapsed_total > 0 else 0
|
||||
avg_latency = streaming_stats['total_latency'] / streaming_stats['messages_processed'] if streaming_stats['messages_processed'] > 0 else 0
|
||||
error_rate = streaming_stats['errors'] / streaming_stats['messages_processed'] * 100 if streaming_stats['messages_processed'] > 0 else 0
|
||||
|
||||
print(f" Messages Processed: {streaming_stats['messages_processed']}")
|
||||
print(f" Total Processing Time: {streaming_stats['total_latency']:.3f}s")
|
||||
print(f" Average Latency: {avg_latency:.3f}s")
|
||||
print(f" Throughput: {throughput:.2f} messages/second")
|
||||
print(f" Error Rate: {error_rate:.2f}%")
|
||||
print(f" Errors: {streaming_stats['errors']}")
|
||||
|
||||
# Function performance during streaming
|
||||
print("\n⚡ Real-Time Function Performance:")
|
||||
stats = get_function_stats()
|
||||
streaming_functions = {k: v for k, v in stats.items() if 'stream' in k.lower() or 'real_time' in k.lower()}
|
||||
|
||||
for func_name, data in streaming_functions.items():
|
||||
avg_time = data['total_time'] / data['call_count'] if data['call_count'] > 0 else 0
|
||||
print(f" {func_name}:")
|
||||
print(f" Calls: {data['call_count']}")
|
||||
print(f" Avg Time: {avg_time:.3f}s")
|
||||
print(f" Total Time: {data['total_time']:.3f}s")
|
||||
|
||||
# Performance trend analysis
|
||||
print("\n📈 Performance Trends:")
|
||||
recent_performance = performance_monitor.get_function_performance()
|
||||
total_functions = len(recent_performance)
|
||||
total_calls = sum(data['call_count'] for data in recent_performance.values())
|
||||
|
||||
print(f" Functions Monitored: {total_functions}")
|
||||
print(f" Total Function Calls: {total_calls}")
|
||||
print(f" Average Calls per Function: {total_calls/total_functions:.1f}" if total_functions > 0 else " No functions monitored")
|
||||
|
||||
# Real-time vs Batch efficiency
|
||||
print(f"\n⚖️ Efficiency Analysis:")
|
||||
if batch_time > 0 and streaming_time > 0:
|
||||
efficiency_gain = (batch_time - streaming_time) / batch_time * 100
|
||||
print(f" Streaming vs Batch Efficiency: {efficiency_gain:+.1f}%")
|
||||
|
||||
if avg_latency > 0:
|
||||
if avg_latency < 0.1:
|
||||
print(" ✅ Excellent real-time performance (< 100ms)")
|
||||
elif avg_latency < 0.2:
|
||||
print(" ⚡ Good real-time performance (< 200ms)")
|
||||
else:
|
||||
print(" ⚠️ Consider optimization for better real-time performance")
|
||||
|
||||
# Current performance report
|
||||
print("\n📋 Current Performance Report:")
|
||||
report = get_performance_report()
|
||||
print(report[:400] + "..." if len(report) > 400 else report)
|
||||
|
||||
# Real-time optimization suggestions
|
||||
print(f"\n💡 Real-Time Optimization Recommendations:")
|
||||
|
||||
if avg_latency > 0.15:
|
||||
print(f" - Optimize message processing (current avg: {avg_latency:.3f}s)")
|
||||
if error_rate > 5:
|
||||
print(f" - Investigate error patterns (current rate: {error_rate:.1f}%)")
|
||||
if throughput < 10:
|
||||
print(f" - Consider parallel processing for better throughput")
|
||||
|
||||
print(" - Monitor memory usage during extended streaming")
|
||||
print(" - Implement adaptive batching for optimal performance")
|
||||
|
||||
return {
|
||||
'streaming_responses': len(streaming_responses),
|
||||
'messages_processed': streaming_stats['messages_processed'],
|
||||
'throughput': throughput,
|
||||
'average_latency': avg_latency,
|
||||
'error_rate': error_rate
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Streaming monitoring completed!")
|
||||
print(f"Throughput: {result['throughput']:.2f} msg/s, Latency: {result['average_latency']:.3f}s")
|
||||
@@ -0,0 +1,433 @@
|
||||
"""
|
||||
Comprehensive Performance Dashboard - Example 10
|
||||
|
||||
Demonstrates comprehensive performance monitoring dashboard:
|
||||
- Complete performance analytics
|
||||
- Advanced reporting and visualization
|
||||
- Performance trends and insights
|
||||
- System-wide monitoring overview
|
||||
|
||||
Shows how to create a comprehensive performance monitoring solution.
|
||||
"""
|
||||
|
||||
import time
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
get_performance_report, get_function_stats, get_api_stats,
|
||||
get_slowest_functions, get_slowest_apis,
|
||||
analyze_function_flow, visualize_execution_flow,
|
||||
analyze_performance_trends, generate_comprehensive_report,
|
||||
clear_performance_data
|
||||
)
|
||||
|
||||
@monitor_function("dashboard_data_collection")
|
||||
def collect_comprehensive_data():
|
||||
"""Collect comprehensive performance data for dashboard."""
|
||||
|
||||
print("📊 Collecting comprehensive performance data...")
|
||||
|
||||
# Generate diverse workload for demonstration
|
||||
test_scenarios = [
|
||||
("Quick query", "What is AI?"),
|
||||
("Complex analysis", "Analyze the impact of artificial intelligence on modern business practices"),
|
||||
("Research task", "Research the latest developments in quantum computing"),
|
||||
("Creative task", "Write a creative story about space exploration"),
|
||||
("Technical query", "Explain how neural networks process information")
|
||||
]
|
||||
|
||||
# Create different types of agents for variety
|
||||
agents = {
|
||||
'quick_agent': Agent(
|
||||
instructions="You are a quick-response agent. Provide concise answers.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'analytical_agent': Agent(
|
||||
instructions="You are an analytical agent. Provide detailed analysis.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'research_agent': Agent(
|
||||
instructions="You are a research agent. Provide comprehensive information.",
|
||||
llm="gpt-4o-mini"
|
||||
),
|
||||
'creative_agent': Agent(
|
||||
instructions="You are a creative agent. Provide imaginative responses.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
}
|
||||
|
||||
results = []
|
||||
|
||||
for i, (scenario_type, query) in enumerate(test_scenarios):
|
||||
print(f"\n🎯 Scenario {i+1}: {scenario_type}")
|
||||
|
||||
# Select appropriate agent
|
||||
agent_type = list(agents.keys())[i % len(agents)]
|
||||
agent = agents[agent_type]
|
||||
|
||||
with track_api_call(f"{scenario_type.lower().replace(' ', '_')}_execution"):
|
||||
try:
|
||||
result = agent.start(query)
|
||||
results.append({
|
||||
'scenario': scenario_type,
|
||||
'agent': agent_type,
|
||||
'query': query,
|
||||
'result': result[:200] + '...' if len(result) > 200 else result,
|
||||
'success': True
|
||||
})
|
||||
except Exception as e:
|
||||
results.append({
|
||||
'scenario': scenario_type,
|
||||
'agent': agent_type,
|
||||
'query': query,
|
||||
'error': str(e),
|
||||
'success': False
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
@monitor_function("multi_agent_workflow_simulation")
|
||||
def simulate_complex_workflow():
|
||||
"""Simulate complex multi-agent workflow for comprehensive data."""
|
||||
|
||||
print("🔄 Simulating complex multi-agent workflow...")
|
||||
|
||||
# Create specialized agents
|
||||
planner = Agent(
|
||||
name="planner",
|
||||
instructions="You are a project planner. Break down tasks and plan execution.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
executor = Agent(
|
||||
name="executor",
|
||||
instructions="You are a task executor. Complete assigned tasks efficiently.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
reviewer = Agent(
|
||||
name="reviewer",
|
||||
instructions="You are a quality reviewer. Review and improve work.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create workflow tasks
|
||||
planning_task = Task(
|
||||
name="planning",
|
||||
description="Plan a comprehensive report on renewable energy trends",
|
||||
expected_output="A detailed project plan with timeline and milestones"
|
||||
)
|
||||
|
||||
execution_task = Task(
|
||||
name="execution",
|
||||
description="Execute the planned research and compile findings",
|
||||
expected_output="Research findings and data compilation"
|
||||
)
|
||||
|
||||
review_task = Task(
|
||||
name="review",
|
||||
description="Review the research and provide quality assessment",
|
||||
expected_output="Quality review and improvement recommendations"
|
||||
)
|
||||
|
||||
# Assign agents to tasks
|
||||
planning_task.agent = planner
|
||||
execution_task.agent = executor
|
||||
review_task.agent = reviewer
|
||||
|
||||
# Execute workflow
|
||||
with track_api_call("complex_workflow_execution"):
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[planner, executor, reviewer],
|
||||
tasks=[planning_task, execution_task, review_task],
|
||||
process="sequential",
|
||||
verbose=False
|
||||
)
|
||||
|
||||
result = workflow.start()
|
||||
|
||||
return result
|
||||
|
||||
@monitor_function("performance_benchmarking")
|
||||
def run_performance_benchmarks():
|
||||
"""Run performance benchmarks for various operations."""
|
||||
|
||||
print("⚡ Running performance benchmarks...")
|
||||
|
||||
benchmark_results = {}
|
||||
|
||||
# Benchmark 1: Response time under different loads
|
||||
print(" 📈 Benchmarking response times...")
|
||||
response_times = []
|
||||
|
||||
for i in range(10):
|
||||
start_time = time.time()
|
||||
with track_api_call(f"benchmark_response_{i}"):
|
||||
# Simulate quick agent response
|
||||
time.sleep(0.05 + (i % 3) * 0.02) # Variable response time
|
||||
response_times.append(time.time() - start_time)
|
||||
|
||||
benchmark_results['response_times'] = {
|
||||
'min': min(response_times),
|
||||
'max': max(response_times),
|
||||
'avg': sum(response_times) / len(response_times),
|
||||
'samples': len(response_times)
|
||||
}
|
||||
|
||||
# Benchmark 2: Concurrent operations
|
||||
print(" 🔄 Benchmarking concurrent operations...")
|
||||
concurrent_start = time.time()
|
||||
|
||||
# Simulate concurrent operations
|
||||
for i in range(5):
|
||||
with track_api_call(f"concurrent_op_{i}"):
|
||||
time.sleep(0.1) # Simulate concurrent work
|
||||
|
||||
concurrent_time = time.time() - concurrent_start
|
||||
benchmark_results['concurrent_operations'] = {
|
||||
'total_time': concurrent_time,
|
||||
'operations': 5,
|
||||
'avg_per_operation': concurrent_time / 5
|
||||
}
|
||||
|
||||
# Benchmark 3: Memory usage simulation
|
||||
print(" 💾 Benchmarking memory operations...")
|
||||
memory_ops = []
|
||||
|
||||
for i in range(8):
|
||||
start = time.time()
|
||||
with track_api_call(f"memory_benchmark_{i}"):
|
||||
# Simulate memory-intensive operation
|
||||
time.sleep(0.03 + (i % 2) * 0.02)
|
||||
memory_ops.append(time.time() - start)
|
||||
|
||||
benchmark_results['memory_operations'] = {
|
||||
'operations': len(memory_ops),
|
||||
'total_time': sum(memory_ops),
|
||||
'avg_time': sum(memory_ops) / len(memory_ops)
|
||||
}
|
||||
|
||||
return benchmark_results
|
||||
|
||||
@monitor_function("generate_dashboard_report")
|
||||
def generate_dashboard_report():
|
||||
"""Generate comprehensive dashboard report."""
|
||||
|
||||
print("📋 Generating comprehensive dashboard report...")
|
||||
|
||||
# Collect all performance data
|
||||
function_stats = get_function_stats()
|
||||
api_stats = get_api_stats()
|
||||
slowest_functions = get_slowest_functions()
|
||||
slowest_apis = get_slowest_apis()
|
||||
|
||||
# Generate reports
|
||||
basic_report = get_performance_report()
|
||||
comprehensive_report = generate_comprehensive_report()
|
||||
|
||||
# Analyze trends and flows
|
||||
try:
|
||||
flow_analysis = analyze_function_flow()
|
||||
performance_trends = analyze_performance_trends()
|
||||
flow_visualization = visualize_execution_flow()
|
||||
except Exception as e:
|
||||
flow_analysis = {"error": str(e)}
|
||||
performance_trends = {"error": str(e)}
|
||||
flow_visualization = {"error": str(e)}
|
||||
|
||||
dashboard_data = {
|
||||
'timestamp': datetime.now().isoformat(),
|
||||
'summary': {
|
||||
'total_functions': len(function_stats),
|
||||
'total_api_calls': len(api_stats),
|
||||
'total_function_calls': sum(stats['call_count'] for stats in function_stats.values()),
|
||||
'total_api_requests': sum(stats['call_count'] for stats in api_stats.values()),
|
||||
'total_execution_time': sum(stats['total_time'] for stats in function_stats.values()),
|
||||
'total_errors': sum(stats['error_count'] for stats in function_stats.values())
|
||||
},
|
||||
'performance_data': {
|
||||
'function_stats': function_stats,
|
||||
'api_stats': api_stats,
|
||||
'slowest_functions': slowest_functions,
|
||||
'slowest_apis': slowest_apis
|
||||
},
|
||||
'analysis': {
|
||||
'flow_analysis': flow_analysis,
|
||||
'performance_trends': performance_trends,
|
||||
'flow_visualization': len(str(flow_visualization)) if flow_visualization else 0
|
||||
},
|
||||
'reports': {
|
||||
'basic_report': basic_report,
|
||||
'comprehensive_report': comprehensive_report[:500] + '...' if len(comprehensive_report) > 500 else comprehensive_report
|
||||
}
|
||||
}
|
||||
|
||||
return dashboard_data
|
||||
|
||||
def display_dashboard(dashboard_data, benchmark_results):
|
||||
"""Display comprehensive performance dashboard."""
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print("📊 COMPREHENSIVE PERFORMANCE DASHBOARD")
|
||||
print("=" * 80)
|
||||
|
||||
# Executive Summary
|
||||
summary = dashboard_data['summary']
|
||||
print(f"\n📈 EXECUTIVE SUMMARY")
|
||||
print(f" Report Generated: {dashboard_data['timestamp']}")
|
||||
print(f" Functions Monitored: {summary['total_functions']}")
|
||||
print(f" API Endpoints: {summary['total_api_calls']}")
|
||||
print(f" Total Function Calls: {summary['total_function_calls']}")
|
||||
print(f" Total API Requests: {summary['total_api_requests']}")
|
||||
print(f" Total Execution Time: {summary['total_execution_time']:.3f}s")
|
||||
print(f" Total Errors: {summary['total_errors']}")
|
||||
|
||||
# Performance Overview
|
||||
print(f"\n⚡ PERFORMANCE OVERVIEW")
|
||||
avg_function_time = 0
|
||||
if summary['total_function_calls'] > 0:
|
||||
avg_function_time = summary['total_execution_time'] / summary['total_function_calls']
|
||||
print(f" Average Function Execution: {avg_function_time:.3f}s")
|
||||
|
||||
if summary['total_errors'] > 0 and summary['total_function_calls'] > 0:
|
||||
error_rate = summary['total_errors'] / summary['total_function_calls'] * 100
|
||||
print(f" Error Rate: {error_rate:.2f}%")
|
||||
else:
|
||||
print(f" Error Rate: 0.00%")
|
||||
|
||||
# Top Performers and Issues
|
||||
print(f"\n🏆 TOP PERFORMERS")
|
||||
perf_data = dashboard_data['performance_data']
|
||||
|
||||
print(" Fastest Functions:")
|
||||
fastest_functions = sorted(perf_data['slowest_functions'], key=lambda x: x[1])[:3]
|
||||
for name, time in fastest_functions:
|
||||
print(f" {name}: {time:.3f}s")
|
||||
|
||||
print(" Slowest Functions:")
|
||||
for name, time in perf_data['slowest_functions'][:3]:
|
||||
print(f" {name}: {time:.3f}s")
|
||||
|
||||
# Benchmark Results
|
||||
print(f"\n⚡ BENCHMARK RESULTS")
|
||||
print(f" Response Time Benchmarks:")
|
||||
rt = benchmark_results['response_times']
|
||||
print(f" Min: {rt['min']:.3f}s, Max: {rt['max']:.3f}s, Avg: {rt['avg']:.3f}s")
|
||||
|
||||
print(f" Concurrent Operations:")
|
||||
co = benchmark_results['concurrent_operations']
|
||||
print(f" {co['operations']} operations in {co['total_time']:.3f}s")
|
||||
print(f" Avg per operation: {co['avg_per_operation']:.3f}s")
|
||||
|
||||
print(f" Memory Operations:")
|
||||
mo = benchmark_results['memory_operations']
|
||||
print(f" {mo['operations']} operations, {mo['avg_time']:.3f}s average")
|
||||
|
||||
# System Health
|
||||
print(f"\n🏥 SYSTEM HEALTH")
|
||||
|
||||
# Calculate health score
|
||||
health_score = 100
|
||||
if avg_function_time > 0.2:
|
||||
health_score -= 20
|
||||
if summary['total_errors'] > 0:
|
||||
health_score -= summary['total_errors'] * 10
|
||||
if rt['avg'] > 0.1:
|
||||
health_score -= 15
|
||||
|
||||
health_score = max(0, health_score)
|
||||
|
||||
if health_score >= 90:
|
||||
status = "🟢 Excellent"
|
||||
elif health_score >= 70:
|
||||
status = "🟡 Good"
|
||||
elif health_score >= 50:
|
||||
status = "🟠 Fair"
|
||||
else:
|
||||
status = "🔴 Needs Attention"
|
||||
|
||||
print(f" Overall Health Score: {health_score}/100 - {status}")
|
||||
|
||||
# Analysis Results
|
||||
print(f"\n🔍 ANALYSIS RESULTS")
|
||||
analysis = dashboard_data['analysis']
|
||||
|
||||
if 'error' not in analysis['flow_analysis']:
|
||||
flow_data = analysis['flow_analysis']
|
||||
print(f" Flow Analysis: {len(flow_data.get('functions', []))} functions analyzed")
|
||||
else:
|
||||
print(f" Flow Analysis: {analysis['flow_analysis']['error']}")
|
||||
|
||||
if analysis['flow_visualization']:
|
||||
print(f" Flow Visualization: Generated ({analysis['flow_visualization']} chars)")
|
||||
|
||||
# Recommendations
|
||||
print(f"\n💡 PERFORMANCE RECOMMENDATIONS")
|
||||
|
||||
if avg_function_time > 0.15:
|
||||
print(" 🔧 Optimize slow functions for better response times")
|
||||
if summary['total_errors'] > 0:
|
||||
print(" 🚨 Investigate and resolve error sources")
|
||||
if rt['avg'] > 0.08:
|
||||
print(" ⚡ Consider response time optimization strategies")
|
||||
if summary['total_function_calls'] > 50:
|
||||
print(" 📊 Implement performance caching for high-volume functions")
|
||||
|
||||
print(" 📈 Continue monitoring trends for proactive optimization")
|
||||
print(" 🔄 Regular performance reviews recommended")
|
||||
|
||||
def main():
|
||||
"""Main function for comprehensive performance dashboard."""
|
||||
print("=" * 80)
|
||||
print("EXAMPLE 10: Comprehensive Performance Dashboard")
|
||||
print("=" * 80)
|
||||
print("This example demonstrates a complete performance monitoring solution")
|
||||
print("with advanced analytics, benchmarking, and dashboard reporting.\n")
|
||||
|
||||
# Clear previous data for clean demo
|
||||
clear_performance_data()
|
||||
|
||||
# Phase 1: Data Collection
|
||||
print("📊 Phase 1: Comprehensive Data Collection")
|
||||
collection_results = collect_comprehensive_data()
|
||||
|
||||
# Phase 2: Complex Workflow
|
||||
print("\n🔄 Phase 2: Complex Multi-Agent Workflow")
|
||||
workflow_result = simulate_complex_workflow()
|
||||
|
||||
# Phase 3: Performance Benchmarking
|
||||
print("\n⚡ Phase 3: Performance Benchmarking")
|
||||
benchmark_results = run_performance_benchmarks()
|
||||
|
||||
# Phase 4: Dashboard Generation
|
||||
print("\n📋 Phase 4: Dashboard Report Generation")
|
||||
dashboard_data = generate_dashboard_report()
|
||||
|
||||
# Phase 5: Display Comprehensive Dashboard
|
||||
display_dashboard(dashboard_data, benchmark_results)
|
||||
|
||||
# Final Summary
|
||||
print(f"\n🎯 EXECUTION SUMMARY")
|
||||
print(f" Scenarios Executed: {len(collection_results)}")
|
||||
successful_scenarios = sum(1 for r in collection_results if r['success'])
|
||||
print(f" Successful Scenarios: {successful_scenarios}/{len(collection_results)}")
|
||||
print(f" Workflow Completed: {'✅ Yes' if workflow_result else '❌ No'}")
|
||||
print(f" Benchmarks Run: {len(benchmark_results)}")
|
||||
print(f" Dashboard Generated: ✅ Complete")
|
||||
|
||||
return {
|
||||
'scenarios': len(collection_results),
|
||||
'success_rate': successful_scenarios / len(collection_results) * 100,
|
||||
'dashboard_data': dashboard_data,
|
||||
'benchmark_results': benchmark_results
|
||||
}
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = main()
|
||||
print(f"\n🎉 Comprehensive dashboard monitoring completed!")
|
||||
print(f"Success Rate: {result['success_rate']:.1f}%")
|
||||
print(f"Total Functions Monitored: {result['dashboard_data']['summary']['total_functions']}")
|
||||
print(f"Performance Health Score Available in Dashboard Above ⬆️")
|
||||
print("\n💡 This dashboard provides real-time insights into your PraisonAI system performance!")
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from praisonaiagents import Agent, force_shutdown_telemetry
|
||||
|
||||
print("Creating agent...")
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
print("Starting agent...")
|
||||
result = agent.start("Why is the sky blue?")
|
||||
|
||||
print("Agent completed successfully!")
|
||||
print(f"Result: {result}")
|
||||
|
||||
# Optional: Clean up telemetry system when script is completely done
|
||||
print("Cleaning up telemetry...")
|
||||
force_shutdown_telemetry()
|
||||
|
||||
print("Script finished normally.")
|
||||
@@ -4,5 +4,4 @@ agent = Agent(
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
agent.start("Why sky is Blue?")
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Simple syntax checker
|
||||
filename = "praisonaiagents/agent/agent.py"
|
||||
|
||||
try:
|
||||
with open(filename, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Try to compile the code
|
||||
compile(content, filename, 'exec')
|
||||
print(f"✅ {filename} has valid syntax")
|
||||
|
||||
except SyntaxError as e:
|
||||
print(f"❌ Syntax error in {filename}:")
|
||||
print(f" Line {e.lineno}: {e.text.strip() if e.text else 'N/A'}")
|
||||
print(f" Error: {e.msg}")
|
||||
if e.offset:
|
||||
print(f" {' ' * (e.offset-1)}^")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}")
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import ContextAgent
|
||||
|
||||
agent = ContextAgent(llm="gpt-4o-mini", auto_analyze=False)
|
||||
|
||||
agent.start("https://github.com/MervinPraison/PraisonAI/ Need to add Authentication")
|
||||
@@ -1,25 +1,7 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
def get_stock_price(company_name: str) -> str:
|
||||
"""
|
||||
Get the stock price of a company
|
||||
Args:
|
||||
company_name (str): The name of the company
|
||||
Returns:
|
||||
str: The stock price of the company
|
||||
"""
|
||||
return f"The stock price of {company_name} is 100"
|
||||
|
||||
def multiply(a: int, b: int) -> int:
|
||||
"""
|
||||
Multiply two numbers
|
||||
"""
|
||||
return a * b
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant. You can use the tools provided to you to help the user.",
|
||||
llm="gemini/gemini-2.5-pro",
|
||||
tools=[get_stock_price, multiply]
|
||||
instructions="You are a helpful assistant",
|
||||
llm="gemini/gemini-2.5-flash"
|
||||
)
|
||||
|
||||
result = agent.start("what is the stock price of Google? multiply the Google stock price with 2")
|
||||
agent.start("Why sky is Blue?")
|
||||
@@ -22,7 +22,7 @@ def multiply(a: int, b: int) -> int:
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a helpful assistant. You can use the tools provided to you to help the user.",
|
||||
llm="gemini/gemini-2.5-pro",
|
||||
llm="gemini/gemini-2.5-flash",
|
||||
tools=[get_stock_price, multiply]
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# PraisonAI Documentation
|
||||
|
||||
## Docs
|
||||
|
||||
- [AI Agents](https://docs.praison.ai/docs/agents/agents.md): Overview of all available PraisonAI agents and their capabilities
|
||||
- [Data Analyst Agent](https://docs.praison.ai/docs/agents/data-analyst.md): Learn how to create AI agents for data analysis and insights generation.
|
||||
- [Finance Agent](https://docs.praison.ai/docs/agents/finance.md): Learn how to create AI agents for financial analysis and investment recommendations.
|
||||
- [Image Analysis Agent](https://docs.praison.ai/docs/agents/image.md): Learn how to create AI agents for image analysis and visual content understanding.
|
||||
- [Image to Text Agent](https://docs.praison.ai/docs/agents/image-to-text.md): Learn how to create AI agents for converting images to textual descriptions and extracting text from images.
|
||||
- [Markdown Agent](https://docs.praison.ai/docs/agents/markdown.md): Learn how to create AI agents for generating and formatting content in Markdown.
|
||||
- [Planning Agent](https://docs.praison.ai/docs/agents/planning.md): Learn how to create AI agents for trip planning and itinerary generation.
|
||||
- [Programming Agent](https://docs.praison.ai/docs/agents/programming.md): Learn how to create AI agents for code development, analysis, and execution.
|
||||
- [Recommendation Agent](https://docs.praison.ai/docs/agents/recommendation.md): Learn how to create AI agents for personalized recommendations across various domains.
|
||||
- [Research Agent](https://docs.praison.ai/docs/agents/research.md): Learn how to create AI agents for conducting comprehensive research and analysis.
|
||||
- [Shopping Agent](https://docs.praison.ai/docs/agents/shopping.md): Learn how to create AI agents for price comparison and shopping assistance.
|
||||
- [Single Agent](https://docs.praison.ai/docs/agents/single.md): Learn how to create a basic single-purpose AI agent for simple tasks.
|
||||
- [Video Agent](https://docs.praison.ai/docs/agents/video.md): Learn how to create AI agents for video analysis and content understanding.
|
||||
- [Web Search Agent](https://docs.praison.ai/docs/agents/websearch.md): Learn how to create AI agents for intelligent web searching and information gathering.
|
||||
- [Wikipedia Agent](https://docs.praison.ai/docs/agents/wikipedia.md): Learn how to create AI agents for searching and extracting information from Wikipedia.
|
||||
- [Agent Module](https://docs.praison.ai/docs/api/praisonaiagents/agent/agent.md): Documentation for the praisonaiagents.agent.agent module
|
||||
@@ -0,0 +1,297 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Comprehensive MongoDB Integration Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates a complete MongoDB integration with PraisonAI agents,
|
||||
combining memory, knowledge, and tools for a comprehensive data management system.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as memory provider
|
||||
- MongoDB as knowledge store
|
||||
- MongoDB tools for data operations
|
||||
- Vector search capabilities
|
||||
- Multi-agent coordination with MongoDB
|
||||
- Real-world business scenario simulation
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import mongodb_tools
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB configuration for different components
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your connection string
|
||||
"database": "praisonai_comprehensive",
|
||||
"use_vector_search": True,
|
||||
"max_pool_size": 50
|
||||
}
|
||||
}
|
||||
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"database": "praisonai_comprehensive",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": os.getenv("OPENAI_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create specialized agents for different business functions
|
||||
|
||||
# 1. Data Manager Agent - handles data operations
|
||||
data_manager = Agent(
|
||||
name="Data Manager",
|
||||
role="Senior Data Operations Manager",
|
||||
goal="Manage and organize all data operations using MongoDB",
|
||||
backstory="""You are an expert data operations manager who specializes in
|
||||
MongoDB database management. You handle data ingestion, organization,
|
||||
indexing, and ensure data quality and accessibility across the organization.""",
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 2. Knowledge Curator Agent - manages knowledge base
|
||||
knowledge_curator = Agent(
|
||||
name="Knowledge Curator",
|
||||
role="Knowledge Management Specialist",
|
||||
goal="Curate and maintain organizational knowledge using MongoDB",
|
||||
backstory="""You are a knowledge management specialist who excels at
|
||||
organizing, categorizing, and retrieving information from the knowledge base.
|
||||
You ensure that knowledge is properly stored, indexed, and accessible.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 3. Business Analyst Agent - analyzes data and provides insights
|
||||
business_analyst = Agent(
|
||||
name="Business Analyst",
|
||||
role="Senior Business Intelligence Analyst",
|
||||
goal="Analyze business data and provide actionable insights",
|
||||
backstory="""You are a senior business analyst who specializes in extracting
|
||||
insights from data stored in MongoDB. You create reports, identify trends,
|
||||
and provide strategic recommendations based on data analysis.""",
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# 4. Customer Service Agent - handles customer interactions
|
||||
customer_service = Agent(
|
||||
name="Customer Service Agent",
|
||||
role="Customer Service Representative",
|
||||
goal="Provide excellent customer service using stored knowledge and data",
|
||||
backstory="""You are a customer service representative who uses the
|
||||
knowledge base and customer data to provide excellent support. You can
|
||||
access customer history, product information, and troubleshooting guides.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
tools=[mongodb_tools],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create comprehensive business tasks
|
||||
business_tasks = [
|
||||
Task(
|
||||
description="""Set up comprehensive business data infrastructure:
|
||||
1. Create collections for customers, products, orders, and support tickets
|
||||
2. Insert sample business data for an e-commerce platform
|
||||
3. Set up appropriate indexes for performance optimization
|
||||
4. Create vector indexes for product descriptions and customer support
|
||||
5. Implement data validation and business rules
|
||||
|
||||
Focus on creating a realistic business data structure.
|
||||
""",
|
||||
expected_output="Complete business data infrastructure with sample data",
|
||||
agent=data_manager
|
||||
),
|
||||
Task(
|
||||
description="""Build organizational knowledge base:
|
||||
1. Store product documentation and specifications
|
||||
2. Create customer service guidelines and FAQs
|
||||
3. Add troubleshooting guides and best practices
|
||||
4. Include company policies and procedures
|
||||
5. Organize knowledge by categories and tags
|
||||
|
||||
Ensure knowledge is searchable and well-organized.
|
||||
""",
|
||||
expected_output="Comprehensive knowledge base with categorized information",
|
||||
agent=knowledge_curator
|
||||
),
|
||||
Task(
|
||||
description="""Perform business intelligence analysis:
|
||||
1. Analyze customer purchase patterns and behavior
|
||||
2. Calculate key business metrics (revenue, conversion rates, etc.)
|
||||
3. Identify top-selling products and categories
|
||||
4. Analyze customer support ticket trends
|
||||
5. Generate insights for business optimization
|
||||
|
||||
Use MongoDB aggregation and analytics capabilities.
|
||||
""",
|
||||
expected_output="Business intelligence report with actionable insights",
|
||||
agent=business_analyst
|
||||
),
|
||||
Task(
|
||||
description="""Handle customer service scenarios:
|
||||
1. Process customer inquiries using knowledge base
|
||||
2. Look up customer order history and preferences
|
||||
3. Provide product recommendations based on customer data
|
||||
4. Access troubleshooting guides for technical issues
|
||||
5. Update customer records and interaction history
|
||||
|
||||
Demonstrate excellent customer service with data-driven support.
|
||||
""",
|
||||
expected_output="Customer service interactions with knowledge-based responses",
|
||||
agent=customer_service
|
||||
),
|
||||
Task(
|
||||
description="""Generate comprehensive business report:
|
||||
1. Combine insights from all data sources
|
||||
2. Create executive summary with key findings
|
||||
3. Provide recommendations for business improvement
|
||||
4. Include data visualizations and metrics
|
||||
5. Store report in knowledge base for future reference
|
||||
|
||||
Create a comprehensive business intelligence report.
|
||||
""",
|
||||
expected_output="Executive business report with comprehensive insights",
|
||||
agent=business_analyst
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the comprehensive business system
|
||||
print("🚀 Starting Comprehensive MongoDB Business System...")
|
||||
print("=" * 60)
|
||||
|
||||
business_system = PraisonAIAgents(
|
||||
agents=[data_manager, knowledge_curator, business_analyst, customer_service],
|
||||
tasks=business_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the comprehensive business pipeline
|
||||
try:
|
||||
results = business_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Comprehensive Business System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 Comprehensive MongoDB Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate system integration
|
||||
print("\n🔍 Demonstrating System Integration:")
|
||||
print("-" * 40)
|
||||
|
||||
# Access different components
|
||||
# Note: Direct memory access not available through business_system.memory
|
||||
print("📋 Memory integration enabled through memory_config...")
|
||||
print("Memory operations are handled internally by the agents")
|
||||
|
||||
# Access memory system directly
|
||||
from praisonaiagents.memory import Memory
|
||||
memory_system = Memory(config=mongodb_memory_config)
|
||||
|
||||
# Search business memories
|
||||
print("\n📋 Searching business memories...")
|
||||
business_memories = memory_system.search_long_term("business analysis", limit=3)
|
||||
print(f"Found {len(business_memories)} business-related memories")
|
||||
|
||||
# Access knowledge system
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
knowledge_system = Knowledge(config=mongodb_knowledge_config)
|
||||
|
||||
# Search knowledge base
|
||||
print("\n📚 Searching knowledge base...")
|
||||
knowledge_results = knowledge_system.search("customer service", limit=3)
|
||||
print(f"Found {len(knowledge_results)} knowledge entries")
|
||||
|
||||
# Direct MongoDB operations
|
||||
print("\n🔧 Direct MongoDB operations...")
|
||||
mongo_client = mongodb_tools.connect_mongodb(
|
||||
"mongodb://localhost:27017/",
|
||||
"praisonai_comprehensive"
|
||||
)
|
||||
|
||||
# Get database statistics
|
||||
stats = mongo_client.get_stats("customers")
|
||||
print(f"Customer collection stats: {stats}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("🎉 Comprehensive MongoDB Example Completed Successfully!")
|
||||
print("=" * 60)
|
||||
|
||||
print("\n📈 System Overview:")
|
||||
print("- Memory System: MongoDB-based persistent memory")
|
||||
print("- Knowledge Base: MongoDB vector search enabled")
|
||||
print("- Tools Integration: Full MongoDB CRUD operations")
|
||||
print("- Multi-Agent Coordination: Business workflow simulation")
|
||||
print("- Vector Search: Semantic search capabilities")
|
||||
print("- Data Analytics: Business intelligence insights")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Comprehensive MongoDB Integration Example")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates complete MongoDB integration with PraisonAI")
|
||||
print("Features:")
|
||||
print("- MongoDB Memory Provider")
|
||||
print("- MongoDB Knowledge Store")
|
||||
print("- MongoDB Tools Integration")
|
||||
print("- Vector Search Capabilities")
|
||||
print("- Multi-Agent Business Simulation")
|
||||
print("=" * 50)
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Knowledge Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB as a knowledge store for PraisonAI agents.
|
||||
MongoDB can store and retrieve knowledge documents with vector search capabilities.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as knowledge vector store
|
||||
- Document processing and storage
|
||||
- Vector search for knowledge retrieval
|
||||
- Knowledge-based agent interactions
|
||||
- File processing with MongoDB storage
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB knowledge configuration
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your MongoDB connection string
|
||||
"database": "praisonai_knowledge",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True # Enable Atlas Vector Search
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": os.getenv("OPENAI_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create a knowledge agent with MongoDB knowledge store
|
||||
knowledge_agent = Agent(
|
||||
name="MongoDB Knowledge Agent",
|
||||
role="Knowledge Specialist",
|
||||
goal="Provide accurate information from MongoDB knowledge base",
|
||||
backstory="""You are an expert knowledge specialist who can access and
|
||||
retrieve information from a comprehensive MongoDB knowledge base. You excel
|
||||
at finding relevant information, synthesizing knowledge from multiple sources,
|
||||
and providing accurate, context-aware responses.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create a research assistant agent
|
||||
research_agent = Agent(
|
||||
name="Research Assistant",
|
||||
role="Research Assistant",
|
||||
goal="Gather information and store it in the knowledge base",
|
||||
backstory="""You are a research assistant who specializes in gathering
|
||||
information from various sources and organizing it for storage in the
|
||||
knowledge base. You ensure information is accurate, well-structured,
|
||||
and properly categorized.""",
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create tasks for knowledge management
|
||||
knowledge_tasks = [
|
||||
Task(
|
||||
description="""Research and store information about MongoDB Atlas Vector Search:
|
||||
1. Gather comprehensive information about MongoDB Atlas Vector Search
|
||||
2. Include technical specifications, use cases, and best practices
|
||||
3. Store the information in the MongoDB knowledge base
|
||||
4. Organize information by categories (features, performance, integration)
|
||||
""",
|
||||
expected_output="MongoDB Atlas Vector Search information stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research and store information about AI agent frameworks:
|
||||
1. Research popular AI agent frameworks (LangChain, AutoGen, etc.)
|
||||
2. Compare their features, capabilities, and use cases
|
||||
3. Store comparative analysis in the knowledge base
|
||||
4. Include code examples and best practices
|
||||
""",
|
||||
expected_output="AI agent framework comparison stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for MongoDB information:
|
||||
1. Search for information about MongoDB Atlas Vector Search
|
||||
2. Extract key features and capabilities
|
||||
3. Provide a comprehensive summary
|
||||
4. Include technical recommendations
|
||||
""",
|
||||
expected_output="Comprehensive MongoDB Atlas Vector Search summary from knowledge base",
|
||||
agent=knowledge_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for AI agent framework information:
|
||||
1. Search for information about AI agent frameworks
|
||||
2. Compare different frameworks based on stored knowledge
|
||||
3. Provide recommendations for different use cases
|
||||
4. Include best practices and examples
|
||||
""",
|
||||
expected_output="AI agent framework comparison and recommendations from knowledge base",
|
||||
agent=knowledge_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB knowledge
|
||||
print("🚀 Starting MongoDB Knowledge Management System...")
|
||||
print("=" * 60)
|
||||
|
||||
knowledge_system = PraisonAIAgents(
|
||||
agents=[research_agent, knowledge_agent],
|
||||
tasks=knowledge_tasks,
|
||||
memory=True,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the knowledge management pipeline
|
||||
try:
|
||||
results = knowledge_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Knowledge Management System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Knowledge Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate direct knowledge access
|
||||
print("\n🔍 Demonstrating Direct Knowledge Access:")
|
||||
print("-" * 40)
|
||||
|
||||
# Access knowledge system directly
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
|
||||
knowledge_system = Knowledge(config=mongodb_knowledge_config)
|
||||
|
||||
# Store a sample document
|
||||
sample_doc = """
|
||||
MongoDB is a document-oriented database that provides high performance,
|
||||
high availability, and easy scalability. It works on the concept of
|
||||
collections and documents, using a flexible, JSON-like document model.
|
||||
"""
|
||||
|
||||
print("📄 Storing sample document...")
|
||||
knowledge_system.store(sample_doc, metadata={"category": "database", "type": "overview"})
|
||||
|
||||
# Search for stored knowledge
|
||||
print("\n🔍 Searching knowledge base...")
|
||||
results = knowledge_system.search("MongoDB document database", limit=3)
|
||||
|
||||
print(f"Found {len(results)} knowledge entries:")
|
||||
for result in results:
|
||||
print(f" - {result.get('memory', '')[:100]}...")
|
||||
print(f" Score: {result.get('score', 'N/A')}")
|
||||
|
||||
print("\n✅ MongoDB Knowledge Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Knowledge Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB integration for knowledge management")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Knowledge Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB as a knowledge store for PraisonAI agents.
|
||||
MongoDB can store and retrieve knowledge documents with vector search capabilities.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as knowledge vector store
|
||||
- Document processing and storage
|
||||
- Vector search for knowledge retrieval
|
||||
- Knowledge-based agent interactions
|
||||
- File processing with MongoDB storage
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB knowledge configuration
|
||||
mongodb_knowledge_config = {
|
||||
"vector_store": {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your MongoDB connection string
|
||||
"database": "praisonai_knowledge",
|
||||
"collection": "knowledge_base",
|
||||
"use_vector_search": True # Enable Atlas Vector Search
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"api_key": os.getenv("OPENAI_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create a knowledge agent with MongoDB knowledge store
|
||||
knowledge_agent = Agent(
|
||||
name="MongoDB Knowledge Agent",
|
||||
role="Knowledge Specialist",
|
||||
goal="Provide accurate information from MongoDB knowledge base",
|
||||
backstory="""You are an expert knowledge specialist who can access and
|
||||
retrieve information from a comprehensive MongoDB knowledge base. You excel
|
||||
at finding relevant information, synthesizing knowledge from multiple sources,
|
||||
and providing accurate, context-aware responses.""",
|
||||
knowledge_config=mongodb_knowledge_config,
|
||||
knowledge=[os.path.join(os.path.dirname(__file__), "llms.md")],
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create a research assistant agent
|
||||
research_agent = Agent(
|
||||
name="Research Assistant",
|
||||
role="Research Assistant",
|
||||
goal="Gather information and store it in the knowledge base",
|
||||
backstory="""You are a research assistant who specializes in gathering
|
||||
information from various sources and organizing it for storage in the
|
||||
knowledge base. You ensure information is accurate, well-structured,
|
||||
and properly categorized.""",
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create tasks for knowledge management
|
||||
knowledge_tasks = [
|
||||
Task(
|
||||
description="""Research and store information about MongoDB Atlas Vector Search:
|
||||
1. Gather comprehensive information about MongoDB Atlas Vector Search
|
||||
2. Include technical specifications, use cases, and best practices
|
||||
3. Store the information in the MongoDB knowledge base
|
||||
4. Organize information by categories (features, performance, integration)
|
||||
""",
|
||||
expected_output="MongoDB Atlas Vector Search information stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research and store information about AI agent frameworks:
|
||||
1. Research popular AI agent frameworks (LangChain, AutoGen, etc.)
|
||||
2. Compare their features, capabilities, and use cases
|
||||
3. Store comparative analysis in the knowledge base
|
||||
4. Include code examples and best practices
|
||||
""",
|
||||
expected_output="AI agent framework comparison stored in knowledge base",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for MongoDB information:
|
||||
1. Search for information about MongoDB Atlas Vector Search
|
||||
2. Extract key features and capabilities
|
||||
3. Provide a comprehensive summary
|
||||
4. Include technical recommendations
|
||||
""",
|
||||
expected_output="Comprehensive MongoDB Atlas Vector Search summary from knowledge base",
|
||||
agent=knowledge_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query the knowledge base for AI agent framework information:
|
||||
1. Search for information about AI agent frameworks
|
||||
2. Compare different frameworks based on stored knowledge
|
||||
3. Provide recommendations for different use cases
|
||||
4. Include best practices and examples
|
||||
""",
|
||||
expected_output="AI agent framework comparison and recommendations from knowledge base",
|
||||
agent=knowledge_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB knowledge
|
||||
print("🚀 Starting MongoDB Knowledge Management System...")
|
||||
print("=" * 60)
|
||||
|
||||
knowledge_system = PraisonAIAgents(
|
||||
agents=[research_agent, knowledge_agent],
|
||||
tasks=knowledge_tasks,
|
||||
memory=True,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the knowledge management pipeline
|
||||
try:
|
||||
results = knowledge_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Knowledge Management System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Knowledge Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate direct knowledge access
|
||||
print("\n🔍 Demonstrating Direct Knowledge Access:")
|
||||
print("-" * 40)
|
||||
|
||||
# Access knowledge system directly
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
|
||||
knowledge_system = Knowledge(config=mongodb_knowledge_config)
|
||||
|
||||
# Store a sample document
|
||||
sample_doc = """
|
||||
MongoDB is a document-oriented database that provides high performance,
|
||||
high availability, and easy scalability. It works on the concept of
|
||||
collections and documents, using a flexible, JSON-like document model.
|
||||
"""
|
||||
|
||||
print("📄 Storing sample document...")
|
||||
knowledge_system.store(sample_doc, metadata={"category": "database", "type": "overview"})
|
||||
|
||||
# Search for stored knowledge
|
||||
print("\n🔍 Searching knowledge base...")
|
||||
results = knowledge_system.search("MongoDB document database", limit=3)
|
||||
|
||||
print(f"Found {len(results)} knowledge entries:")
|
||||
for result in results:
|
||||
print(f" - {result.get('memory', '')[:100]}...")
|
||||
print(f" Score: {result.get('score', 'N/A')}")
|
||||
|
||||
print("\n✅ MongoDB Knowledge Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Knowledge Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB integration for knowledge management")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,84 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.memory import Memory
|
||||
from praisonaiagents.agent import ContextAgent
|
||||
import pymongo
|
||||
|
||||
context_agent = ContextAgent(llm="gpt-4o-mini", auto_analyze=False)
|
||||
|
||||
context_output = context_agent.start("https://github.com/MervinPraison/PraisonAI/ Need to add Authentication")
|
||||
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/",
|
||||
"database": "praisonai_memory",
|
||||
"use_vector_search": True,
|
||||
"max_pool_size": 50,
|
||||
"min_pool_size": 10,
|
||||
"server_selection_timeout": 5000
|
||||
}
|
||||
}
|
||||
|
||||
implementation_agent = Agent(
|
||||
name="Implementation Agent",
|
||||
role="Authentication Implementation Specialist",
|
||||
goal="Implement authentication features based on project requirements",
|
||||
backstory="Expert software implementer specializing in authentication systems, security features, and seamless integration with existing codebases",
|
||||
memory=True,
|
||||
llm="gpt-4o-mini",
|
||||
)
|
||||
|
||||
implementation_task = Task(
|
||||
description="Implement authentication features based on the project requirements from context analysis",
|
||||
expected_output="Authentication implementation with code, configuration, and integration details",
|
||||
agent=implementation_agent,
|
||||
context=context_output,
|
||||
)
|
||||
|
||||
implementation_system = PraisonAIAgents(
|
||||
agents=[implementation_agent],
|
||||
tasks=[implementation_task],
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config
|
||||
)
|
||||
|
||||
results = implementation_system.start()
|
||||
print(f"Results: {results}")
|
||||
|
||||
print("\n=== MEMORY VALIDATION ===")
|
||||
|
||||
try:
|
||||
# Check MongoDB connection and collections
|
||||
client = pymongo.MongoClient("mongodb://localhost:27017/")
|
||||
db = client["praisonai_memory"]
|
||||
collections = db.list_collection_names()
|
||||
print(f"Available collections: {collections}")
|
||||
|
||||
for collection_name in collections:
|
||||
count = db[collection_name].count_documents({})
|
||||
print(f"{collection_name}: {count} documents")
|
||||
if count > 0:
|
||||
sample = db[collection_name].find_one()
|
||||
print(f"Sample document: {sample}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"MongoDB direct check error: {e}")
|
||||
|
||||
try:
|
||||
# Check memory system
|
||||
memory_system = Memory(mongodb_memory_config)
|
||||
|
||||
# Try different search terms
|
||||
search_terms = ["authentication", "security", "implementation", "requirements", "PraisonAI"]
|
||||
for term in search_terms:
|
||||
memories = memory_system.search_long_term(term, limit=3)
|
||||
print(f"Search '{term}': {len(memories)} memories found")
|
||||
if memories:
|
||||
print(f" Sample: {str(memories[0])[:100]}...")
|
||||
|
||||
# Try to get all memories
|
||||
all_memories = memory_system.get_all_memories()
|
||||
print(f"Total memories: {len(all_memories)}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Memory system error: {e}")
|
||||
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Memory Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB as a memory provider for PraisonAI agents.
|
||||
MongoDB can be used as both a key-value store and a vector database for memory operations.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB as memory provider
|
||||
- Vector search with Atlas Vector Search
|
||||
- Quality scoring and filtering
|
||||
- User-specific memory storage
|
||||
- Persistent memory across sessions
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# MongoDB memory configuration
|
||||
mongodb_memory_config = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": "mongodb://localhost:27017/", # Replace with your MongoDB connection string
|
||||
"database": "praisonai_memory",
|
||||
"use_vector_search": True, # Enable Atlas Vector Search (requires MongoDB Atlas)
|
||||
"max_pool_size": 50,
|
||||
"min_pool_size": 10,
|
||||
"server_selection_timeout": 5000
|
||||
}
|
||||
}
|
||||
|
||||
# Create a research agent with MongoDB memory
|
||||
research_agent = Agent(
|
||||
name="MongoDB Research Agent",
|
||||
role="Senior Research Specialist",
|
||||
goal="Research topics and maintain persistent memory using MongoDB",
|
||||
backstory="""You are an expert researcher who specializes in collecting,
|
||||
analyzing, and storing information using advanced MongoDB-based memory systems.
|
||||
You excel at maintaining context across multiple research sessions and can
|
||||
retrieve relevant information from your persistent memory store.""",
|
||||
memory=True,
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create research tasks
|
||||
research_tasks = [
|
||||
Task(
|
||||
description="""Research the latest developments in AI/ML for 2024:
|
||||
1. Identify major AI breakthroughs and trends
|
||||
2. Analyze the impact on various industries
|
||||
3. Store key findings in MongoDB memory with quality scores
|
||||
4. Identify emerging technologies and their potential applications
|
||||
""",
|
||||
expected_output="Comprehensive AI/ML research report with key findings stored in MongoDB",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research MongoDB Atlas Vector Search capabilities:
|
||||
1. Explore vector search features and use cases
|
||||
2. Compare with other vector databases
|
||||
3. Analyze performance and scalability
|
||||
4. Store technical insights in MongoDB memory
|
||||
""",
|
||||
expected_output="Technical analysis of MongoDB Atlas Vector Search with stored insights",
|
||||
agent=research_agent
|
||||
),
|
||||
Task(
|
||||
description="""Research AI agent frameworks and tools:
|
||||
1. Compare popular AI agent frameworks
|
||||
2. Analyze their strengths and weaknesses
|
||||
3. Identify best practices for agent development
|
||||
4. Store comparative analysis in MongoDB memory
|
||||
""",
|
||||
expected_output="Comparative analysis of AI agent frameworks with stored insights",
|
||||
agent=research_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB memory
|
||||
print("🚀 Starting MongoDB Memory Research System...")
|
||||
print("=" * 60)
|
||||
|
||||
research_system = PraisonAIAgents(
|
||||
agents=[research_agent],
|
||||
tasks=research_tasks,
|
||||
memory=True,
|
||||
memory_config=mongodb_memory_config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the research pipeline
|
||||
try:
|
||||
results = research_system.start()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 Research System Results:")
|
||||
print("=" * 60)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, (list, tuple)):
|
||||
for i, result in enumerate(results, 1):
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'agent'):
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Output: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Memory Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate memory retrieval
|
||||
print("\n🔍 Demonstrating Memory Retrieval:")
|
||||
print("-" * 40)
|
||||
|
||||
# Note: Direct memory access not available through research_system.memory
|
||||
# Instead, use Memory class directly for verification
|
||||
try:
|
||||
from praisonaiagents.memory import Memory
|
||||
|
||||
# Create Memory instance with MongoDB config for verification
|
||||
memory_system = Memory(mongodb_memory_config)
|
||||
|
||||
# Search for AI-related memories
|
||||
ai_memories = memory_system.search_long_term("AI machine learning", limit=3)
|
||||
print(f"Found {len(ai_memories)} AI-related memories:")
|
||||
for memory in ai_memories:
|
||||
if hasattr(memory, 'get'):
|
||||
print(f" - {memory.get('text', '')[:100]}...")
|
||||
else:
|
||||
print(f" - {str(memory)[:100]}...")
|
||||
|
||||
# Search for MongoDB-related memories
|
||||
mongo_memories = memory_system.search_long_term("MongoDB vector search", limit=3)
|
||||
print(f"\nFound {len(mongo_memories)} MongoDB-related memories:")
|
||||
for memory in mongo_memories:
|
||||
if hasattr(memory, 'get'):
|
||||
print(f" - {memory.get('text', '')[:100]}...")
|
||||
else:
|
||||
print(f" - {str(memory)[:100]}...")
|
||||
|
||||
except ImportError:
|
||||
print("Memory features not available - install with: pip install 'praisonaiagents[memory]'")
|
||||
except Exception as mem_error:
|
||||
print(f"Memory verification error: {mem_error}")
|
||||
|
||||
print("\n✅ MongoDB Memory Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Memory Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB integration for persistent memory")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MongoDB Tools Example for PraisonAI Agents
|
||||
|
||||
This example demonstrates how to use MongoDB tools with PraisonAI agents.
|
||||
Agents can perform MongoDB operations like inserting, querying, and vector search.
|
||||
|
||||
Prerequisites:
|
||||
- Install MongoDB dependencies: pip install 'praisonaiagents[mongodb]'
|
||||
- MongoDB server running (local or Atlas)
|
||||
- OpenAI API key for embeddings
|
||||
|
||||
Features demonstrated:
|
||||
- MongoDB tools integration
|
||||
- Document CRUD operations
|
||||
- Vector search with embeddings
|
||||
- Data analysis with MongoDB
|
||||
- Agent-driven database operations
|
||||
"""
|
||||
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import mongodb_tools
|
||||
|
||||
# Ensure OpenAI API key is set
|
||||
if not os.environ.get("OPENAI_API_KEY"):
|
||||
raise ValueError("Please set the OPENAI_API_KEY environment variable")
|
||||
|
||||
def main():
|
||||
# Create a MongoDB Database Agent with MongoDB tools
|
||||
db_agent = Agent(
|
||||
name="MongoDB Database Agent",
|
||||
role="Database Operations Specialist",
|
||||
goal="Manage MongoDB operations and data analysis",
|
||||
backstory="""You are an expert database administrator who specializes in
|
||||
MongoDB operations. You can perform complex database queries, manage
|
||||
collections, and analyze data patterns. You excel at using MongoDB tools
|
||||
for data management and retrieval.""",
|
||||
tools=[mongodb_tools],
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create a Data Analysis Agent
|
||||
analysis_agent = Agent(
|
||||
name="Data Analysis Agent",
|
||||
role="Data Analyst",
|
||||
goal="Analyze data stored in MongoDB and provide insights",
|
||||
backstory="""You are a data analyst who specializes in extracting insights
|
||||
from MongoDB databases. You can query data, perform aggregations, and
|
||||
identify patterns and trends in the stored information.""",
|
||||
tools=[mongodb_tools],
|
||||
verbose=True,
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create tasks for MongoDB operations
|
||||
mongodb_tasks = [
|
||||
Task(
|
||||
description="""Set up MongoDB collections and insert sample data:
|
||||
1. Create a collection called 'products' for e-commerce data
|
||||
2. Insert sample product documents with fields: name, price, category, description
|
||||
3. Create a collection called 'users' for user data
|
||||
4. Insert sample user documents with fields: name, email, age, preferences
|
||||
5. Create appropriate indexes for better query performance
|
||||
|
||||
Use the MongoDB tools to perform these operations.
|
||||
""",
|
||||
expected_output="MongoDB collections created with sample data and indexes",
|
||||
agent=db_agent
|
||||
),
|
||||
Task(
|
||||
description="""Perform vector search operations:
|
||||
1. Create a vector index for product descriptions
|
||||
2. Store products with text embeddings for vector search
|
||||
3. Demonstrate vector similarity search for product recommendations
|
||||
4. Show how to find similar products based on description embeddings
|
||||
|
||||
Use the MongoDB vector search tools for these operations.
|
||||
""",
|
||||
expected_output="Vector search implementation with product recommendations",
|
||||
agent=db_agent
|
||||
),
|
||||
Task(
|
||||
description="""Query and analyze the stored data:
|
||||
1. Find all products in a specific category
|
||||
2. Calculate average price by category
|
||||
3. Find users with specific preferences
|
||||
4. Perform text search on product descriptions
|
||||
5. Generate insights about the data patterns
|
||||
|
||||
Use MongoDB query tools to perform these analyses.
|
||||
""",
|
||||
expected_output="Data analysis report with insights from MongoDB queries",
|
||||
agent=analysis_agent
|
||||
),
|
||||
Task(
|
||||
description="""Demonstrate advanced MongoDB operations:
|
||||
1. Update product prices based on specific criteria
|
||||
2. Perform aggregation operations for statistical analysis
|
||||
3. Create reports on user demographics and preferences
|
||||
4. Implement data validation and error handling
|
||||
5. Show MongoDB best practices for data management
|
||||
|
||||
Use MongoDB tools for these advanced operations.
|
||||
""",
|
||||
expected_output="Advanced MongoDB operations report with best practices",
|
||||
agent=db_agent
|
||||
)
|
||||
]
|
||||
|
||||
# Initialize the multi-agent system with MongoDB tools
|
||||
print("🚀 Starting MongoDB Tools Demo System...")
|
||||
print("=" * 60)
|
||||
|
||||
mongodb_system = PraisonAIAgents(
|
||||
agents=[db_agent, analysis_agent],
|
||||
tasks=mongodb_tasks,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Execute the MongoDB operations pipeline
|
||||
try:
|
||||
results = mongodb_system.start(return_dict=True)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("📊 MongoDB Tools System Results:")
|
||||
print("=" * 60)
|
||||
print(results)
|
||||
|
||||
# Handle results structure properly
|
||||
if isinstance(results, dict) and 'task_results' in results:
|
||||
task_results = results['task_results']
|
||||
for i, result in task_results.items():
|
||||
print(f"\n{i}. Task Result:")
|
||||
if hasattr(result, 'raw') and hasattr(result, 'agent'):
|
||||
print(f" Output: {result.raw[:200]}...")
|
||||
print(f" Agent: {result.agent}")
|
||||
else:
|
||||
print(f" Result: {str(result)[:200]}...")
|
||||
else:
|
||||
print(f"\n1. Task Result:")
|
||||
print(f" Output: {str(results)[:200]}...")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("💾 MongoDB Tools Integration Complete!")
|
||||
print("=" * 60)
|
||||
|
||||
# Demonstrate direct MongoDB tools usage
|
||||
print("\n🔍 Demonstrating Direct MongoDB Tools Usage:")
|
||||
print("-" * 40)
|
||||
|
||||
# Connect to MongoDB
|
||||
mongo_client = mongodb_tools.connect_mongodb(
|
||||
"mongodb://localhost:27017/", # Replace with your connection string
|
||||
"praisonai_tools_demo"
|
||||
)
|
||||
|
||||
# Insert a sample document
|
||||
print("📄 Inserting sample document...")
|
||||
result = mongo_client.insert_document(
|
||||
"demo_collection",
|
||||
{
|
||||
"title": "MongoDB Tools Demo",
|
||||
"description": "Demonstration of MongoDB tools with PraisonAI",
|
||||
"category": "database",
|
||||
"tags": ["mongodb", "praisonai", "tools", "demo"]
|
||||
},
|
||||
metadata={"created_by": "demo", "version": "1.0"}
|
||||
)
|
||||
print(f" Result: {result}")
|
||||
|
||||
# Query documents
|
||||
print("\n🔍 Querying documents...")
|
||||
documents = mongo_client.find_documents(
|
||||
"demo_collection",
|
||||
{"category": "database"},
|
||||
limit=5
|
||||
)
|
||||
print(f" Found {len(documents)} documents")
|
||||
for doc in documents:
|
||||
print(f" - {doc.get('title', 'N/A')}: {doc.get('description', '')[:50]}...")
|
||||
|
||||
# Get collection statistics
|
||||
print("\n📈 Getting collection statistics...")
|
||||
stats = mongo_client.get_stats("demo_collection")
|
||||
print(f" Collection stats: {stats}")
|
||||
|
||||
print("\n✅ MongoDB Tools Example Completed Successfully!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ Error during execution: {e}")
|
||||
print("Please check your MongoDB connection and API keys.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("MongoDB Tools Example for PraisonAI Agents")
|
||||
print("=" * 50)
|
||||
print("This example demonstrates MongoDB tools integration")
|
||||
print("Make sure you have:")
|
||||
print("1. MongoDB server running (local or Atlas)")
|
||||
print("2. OpenAI API key set in environment variables")
|
||||
print("3. MongoDB dependencies installed: pip install 'praisonaiagents[mongodb]'")
|
||||
print("=" * 50)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,321 @@
|
||||
"""
|
||||
PraisonAI Performance Monitoring Demo
|
||||
|
||||
This example demonstrates how to use PraisonAI's comprehensive performance monitoring
|
||||
capabilities to answer the key questions from Issue #1035:
|
||||
|
||||
1. How to evaluate how each function is performing
|
||||
2. Function flow analysis
|
||||
3. How fast each function is executing
|
||||
4. API call performance monitoring (fast vs slow calls)
|
||||
5. How to see all API calls
|
||||
|
||||
Features Demonstrated:
|
||||
- Function performance evaluation with detailed statistics
|
||||
- Function execution flow analysis and visualization
|
||||
- API call tracking and performance comparison
|
||||
- Real-time performance monitoring
|
||||
- Bottleneck identification and optimization recommendations
|
||||
- Comprehensive performance reporting
|
||||
"""
|
||||
|
||||
import time
|
||||
import random
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
from praisonaiagents.telemetry import (
|
||||
monitor_function, track_api_call, performance_monitor,
|
||||
analyze_function_flow,
|
||||
visualize_execution_flow, generate_comprehensive_report
|
||||
)
|
||||
|
||||
print("=" * 80)
|
||||
print("PRAISONAI PERFORMANCE MONITORING DEMONSTRATION")
|
||||
print("=" * 80)
|
||||
print("This demo answers the key questions from Issue #1035:")
|
||||
print("1. How to evaluate how each function is performing")
|
||||
print("2. Function flow analysis")
|
||||
print("3. How fast each function is executing")
|
||||
print("4. API call performance monitoring (fast vs slow calls)")
|
||||
print("5. How to see all API calls")
|
||||
print("=" * 80)
|
||||
print()
|
||||
|
||||
# Example 1: Function Performance Evaluation
|
||||
print("📊 EXAMPLE 1: Function Performance Evaluation")
|
||||
print("-" * 50)
|
||||
|
||||
# Demonstrate function monitoring with decorators
|
||||
@monitor_function("data_processing")
|
||||
def process_data(data_size: int):
|
||||
"""Simulate data processing with variable performance."""
|
||||
processing_time = 0.1 + (data_size * 0.01) # Simulate work
|
||||
time.sleep(processing_time)
|
||||
return f"Processed {data_size} items"
|
||||
|
||||
@monitor_function("model_inference")
|
||||
def run_model_inference(complexity: str):
|
||||
"""Simulate model inference with different complexities."""
|
||||
if complexity == "simple":
|
||||
time.sleep(0.05)
|
||||
elif complexity == "medium":
|
||||
time.sleep(0.2)
|
||||
else: # complex
|
||||
time.sleep(0.5)
|
||||
return f"Inference completed for {complexity} model"
|
||||
|
||||
@monitor_function("database_query")
|
||||
def query_database(query_type: str):
|
||||
"""Simulate database queries with different performance characteristics."""
|
||||
if query_type == "fast":
|
||||
time.sleep(0.02)
|
||||
elif query_type == "medium":
|
||||
time.sleep(0.1)
|
||||
else: # slow
|
||||
time.sleep(0.3)
|
||||
return f"Query {query_type} completed"
|
||||
|
||||
# Run functions with different performance characteristics
|
||||
print("Running functions to generate performance data...")
|
||||
for _ in range(5):
|
||||
process_data(random.randint(10, 100))
|
||||
run_model_inference(random.choice(["simple", "medium", "complex"]))
|
||||
query_database(random.choice(["fast", "medium", "slow"]))
|
||||
|
||||
# Show function performance statistics
|
||||
print("\n📈 Function Performance Statistics:")
|
||||
function_stats = performance_monitor.get_function_performance()
|
||||
for func_name, stats in function_stats.items():
|
||||
print(f"\n🔧 {func_name}:")
|
||||
print(f" Calls: {stats['call_count']}")
|
||||
print(f" Average Time: {stats.get('average_time', 0):.3f}s")
|
||||
print(f" Min/Max Time: {stats['min_time']:.3f}s / {stats['max_time']:.3f}s")
|
||||
print(f" Success Rate: {stats.get('success_rate', 0)*100:.1f}%")
|
||||
|
||||
# Example 2: Function Flow Analysis
|
||||
print("\n\n🔄 EXAMPLE 2: Function Flow Analysis")
|
||||
print("-" * 50)
|
||||
|
||||
@monitor_function("workflow_step_1")
|
||||
def workflow_step_1():
|
||||
time.sleep(0.1)
|
||||
workflow_step_2()
|
||||
workflow_step_3()
|
||||
|
||||
@monitor_function("workflow_step_2")
|
||||
def workflow_step_2():
|
||||
time.sleep(0.05)
|
||||
workflow_step_4()
|
||||
|
||||
@monitor_function("workflow_step_3")
|
||||
def workflow_step_3():
|
||||
time.sleep(0.08)
|
||||
|
||||
@monitor_function("workflow_step_4")
|
||||
def workflow_step_4():
|
||||
time.sleep(0.03)
|
||||
|
||||
print("Running workflow to demonstrate flow analysis...")
|
||||
workflow_step_1()
|
||||
|
||||
# Analyze execution flow
|
||||
print("\n📊 Function Execution Flow Analysis:")
|
||||
flow_analysis = analyze_function_flow()
|
||||
if "bottlenecks" in flow_analysis:
|
||||
bottlenecks = flow_analysis["bottlenecks"]
|
||||
if bottlenecks:
|
||||
print("🚨 Identified Bottlenecks:")
|
||||
for bottleneck in bottlenecks:
|
||||
print(f" • {bottleneck['function']}: {bottleneck['average_duration']:.3f}s average")
|
||||
else:
|
||||
print("✅ No significant bottlenecks identified")
|
||||
|
||||
# Visualize execution flow
|
||||
print("\n🎨 Function Execution Flow Visualization:")
|
||||
flow_viz = visualize_execution_flow(format="text")
|
||||
print(flow_viz)
|
||||
|
||||
# Example 3: API Call Performance Monitoring
|
||||
print("\n\n🌐 EXAMPLE 3: API Call Performance Monitoring")
|
||||
print("-" * 50)
|
||||
|
||||
# Simulate different API calls with various performance characteristics
|
||||
def simulate_api_calls():
|
||||
"""Simulate API calls to demonstrate tracking."""
|
||||
|
||||
# Fast API calls
|
||||
with track_api_call("openai_api", "/v1/models"):
|
||||
time.sleep(0.05) # Fast call
|
||||
|
||||
with track_api_call("openai_api", "/v1/chat/completions"):
|
||||
time.sleep(0.3) # Medium call
|
||||
|
||||
# Slow API call
|
||||
with track_api_call("anthropic_api", "/v1/messages"):
|
||||
time.sleep(0.6) # Slow call
|
||||
|
||||
# Another fast call
|
||||
with track_api_call("gemini_api", "/v1/generate"):
|
||||
time.sleep(0.08) # Fast call
|
||||
|
||||
# Simulate error case
|
||||
try:
|
||||
with track_api_call("unreliable_api", "/v1/endpoint"):
|
||||
time.sleep(0.2)
|
||||
if random.random() < 0.3: # 30% chance of error
|
||||
raise Exception("API Error")
|
||||
except Exception:
|
||||
pass # Error is already tracked
|
||||
|
||||
print("Simulating API calls with different performance characteristics...")
|
||||
for _ in range(8):
|
||||
simulate_api_calls()
|
||||
|
||||
# Show API performance statistics
|
||||
print("\n📊 API Call Performance Statistics:")
|
||||
api_stats = performance_monitor.get_api_call_performance()
|
||||
for api_name, stats in api_stats.items():
|
||||
print(f"\n🔗 {api_name}:")
|
||||
print(f" Total Calls: {stats['call_count']}")
|
||||
print(f" Average Time: {stats.get('average_time', 0):.3f}s")
|
||||
print(f" Min/Max Time: {stats['min_time']:.3f}s / {stats['max_time']:.3f}s")
|
||||
print(f" Success Rate: {stats.get('success_rate', 0)*100:.1f}%")
|
||||
print(f" Successful: {stats['success_count']} | Failed: {stats['error_count']}")
|
||||
|
||||
# Show fastest vs slowest APIs
|
||||
print("\n🏁 Fastest vs Slowest API Calls:")
|
||||
slowest_apis = performance_monitor.get_slowest_api_calls(10)
|
||||
for i, api in enumerate(slowest_apis, 1):
|
||||
speed_indicator = "🐌" if api['average_time'] > 0.3 else "⚡" if api['average_time'] < 0.1 else "🚀"
|
||||
print(f"{i}. {speed_indicator} {api['api']}: {api['average_time']:.3f}s avg (Success: {api['success_rate']*100:.1f}%)")
|
||||
|
||||
# Example 4: Real-time Performance Monitoring with Agents
|
||||
print("\n\n🤖 EXAMPLE 4: Real-time Performance Monitoring with AI Agents")
|
||||
print("-" * 50)
|
||||
|
||||
# Create agents with performance monitoring
|
||||
research_agent = Agent(
|
||||
name="PerformanceResearcher",
|
||||
role="Performance Research Specialist",
|
||||
goal="Research and analyze performance topics quickly",
|
||||
backstory="You are an expert at researching performance optimization topics.",
|
||||
tools=[duckduckgo],
|
||||
verbose=False # Reduce output for cleaner demo
|
||||
)
|
||||
|
||||
# Monitor agent operations
|
||||
@monitor_function("agent_task_execution")
|
||||
def execute_monitored_task(agent, task_description):
|
||||
"""Execute an agent task with performance monitoring."""
|
||||
task = Task(
|
||||
description=task_description,
|
||||
expected_output="Brief research summary with key insights",
|
||||
agent=agent
|
||||
)
|
||||
|
||||
agents_workflow = PraisonAIAgents(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
verbose=False
|
||||
)
|
||||
|
||||
# Simulate API calls during agent execution
|
||||
with track_api_call("llm_provider", "/v1/chat/completions"):
|
||||
time.sleep(0.2) # Simulate LLM call
|
||||
|
||||
result = agents_workflow.start()
|
||||
return result
|
||||
|
||||
print("Running AI agent with performance monitoring...")
|
||||
result = execute_monitored_task(
|
||||
research_agent,
|
||||
"Research the latest trends in AI performance optimization"
|
||||
)
|
||||
|
||||
# Example 5: Comprehensive Performance Report
|
||||
print("\n\n📋 EXAMPLE 5: Comprehensive Performance Report")
|
||||
print("-" * 50)
|
||||
|
||||
# Generate comprehensive performance report
|
||||
comprehensive_report = generate_comprehensive_report()
|
||||
print(comprehensive_report)
|
||||
|
||||
# Example 6: Using CLI Interface Programmatically
|
||||
print("\n\n💻 EXAMPLE 6: CLI Interface Usage")
|
||||
print("-" * 50)
|
||||
print("You can also use the CLI interface from command line:")
|
||||
print()
|
||||
print("# Show performance report")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli report")
|
||||
print()
|
||||
print("# Show function statistics")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli functions")
|
||||
print()
|
||||
print("# Show API call statistics")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli apis")
|
||||
print()
|
||||
print("# Show slowest functions")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli slowest-functions 5")
|
||||
print()
|
||||
print("# Analyze function flow")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli analyze-flow")
|
||||
print()
|
||||
print("# Show execution flow visualization")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli flow --format text")
|
||||
print()
|
||||
print("# Export all data to JSON")
|
||||
print("python -m praisonaiagents.telemetry.performance_cli export --format json --output performance_data.json")
|
||||
|
||||
# Example 7: Integration with Existing Code
|
||||
print("\n\n🔧 EXAMPLE 7: Easy Integration with Existing Code")
|
||||
print("-" * 50)
|
||||
print("To integrate performance monitoring into your existing PraisonAI code:")
|
||||
print()
|
||||
print("1. Import the performance monitoring tools:")
|
||||
print(" from praisonaiagents.telemetry import monitor_function, track_api_call")
|
||||
print()
|
||||
print("2. Add decorators to your functions:")
|
||||
print(" @monitor_function('my_function')")
|
||||
print(" def my_function():")
|
||||
print(" return 'result'")
|
||||
print()
|
||||
print("3. Track API calls:")
|
||||
print(" with track_api_call('openai', '/v1/chat/completions'):")
|
||||
print(" response = openai_client.chat.completions.create(...)")
|
||||
print()
|
||||
print("4. Get performance reports:")
|
||||
print(" from praisonaiagents.telemetry import get_performance_report")
|
||||
print(" print(get_performance_report())")
|
||||
|
||||
# Summary of capabilities
|
||||
print("\n\n✅ SUMMARY: Questions from Issue #1035 - ANSWERED!")
|
||||
print("=" * 80)
|
||||
print("1. ✅ How to evaluate how each function is performing:")
|
||||
print(" → Use @monitor_function decorator and get_function_stats()")
|
||||
print(" → View detailed statistics: calls, timing, success rates, errors")
|
||||
print()
|
||||
print("2. ✅ Function flow analysis:")
|
||||
print(" → Use analyze_function_flow() for bottleneck identification")
|
||||
print(" → Use visualize_execution_flow() for flow visualization")
|
||||
print(" → Get call chains and execution patterns")
|
||||
print()
|
||||
print("3. ✅ How fast each function is executing:")
|
||||
print(" → Automatic timing collection with min/max/average/recent stats")
|
||||
print(" → Use get_slowest_functions() to find performance bottlenecks")
|
||||
print(" → Real-time active call monitoring")
|
||||
print()
|
||||
print("4. ✅ API call performance monitoring (fast vs slow calls):")
|
||||
print(" → Use track_api_call() context manager for API monitoring")
|
||||
print(" → Compare API performance with get_slowest_apis()")
|
||||
print(" → Success/error rate tracking")
|
||||
print()
|
||||
print("5. ✅ How to see all API calls:")
|
||||
print(" → Use get_api_stats() to see all tracked APIs")
|
||||
print(" → View recent call history and detailed metrics")
|
||||
print(" → CLI interface for easy access: performance_cli apis")
|
||||
print()
|
||||
print("🎉 All requested features are now available with backward compatibility!")
|
||||
print("🔧 Easy integration with existing code using decorators and context managers")
|
||||
print("📊 Comprehensive reporting and analysis capabilities")
|
||||
print("💻 CLI interface for command-line access")
|
||||
print("=" * 80)
|
||||
@@ -2,43 +2,42 @@
|
||||
Praison AI Agents - A package for hierarchical AI agent task execution
|
||||
"""
|
||||
|
||||
# Configure logging before any other imports
|
||||
import os
|
||||
import logging
|
||||
from rich.logging import RichHandler
|
||||
# Apply warning patch BEFORE any imports to intercept warnings at the source
|
||||
from . import _warning_patch
|
||||
|
||||
# Get log level from environment variable
|
||||
LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper()
|
||||
# Import centralized logging configuration FIRST
|
||||
from . import _logging
|
||||
|
||||
# Configure root logger
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, LOGLEVEL, logging.INFO),
|
||||
format="%(asctime)s %(filename)s:%(lineno)d %(levelname)s %(message)s",
|
||||
datefmt="[%X]",
|
||||
handlers=[RichHandler(rich_tracebacks=True)]
|
||||
)
|
||||
|
||||
# Suppress specific noisy loggers
|
||||
logging.getLogger("litellm").setLevel(logging.WARNING)
|
||||
logging.getLogger("litellm.utils").setLevel(logging.WARNING)
|
||||
logging.getLogger("markdown_it").setLevel(logging.WARNING)
|
||||
logging.getLogger("rich.markdown").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
# Configure root logger after logging is initialized
|
||||
_logging.configure_root_logger()
|
||||
|
||||
# Now import everything else
|
||||
from .agent.agent import Agent
|
||||
from .agent.image_agent import ImageAgent
|
||||
from .agent.context_agent import ContextAgent, create_context_agent
|
||||
from .agents.agents import PraisonAIAgents
|
||||
from .task.task import Task
|
||||
from .tools.tools import Tools
|
||||
from .agents.autoagents import AutoAgents
|
||||
from .knowledge.knowledge import Knowledge
|
||||
from .knowledge.chunking import Chunking
|
||||
from .mcp.mcp import MCP
|
||||
# MCP support (optional)
|
||||
try:
|
||||
from .mcp.mcp import MCP
|
||||
_mcp_available = True
|
||||
except ImportError:
|
||||
_mcp_available = False
|
||||
MCP = None
|
||||
from .session import Session
|
||||
from .memory.memory import Memory
|
||||
from .guardrails import GuardrailResult, LLMGuardrail
|
||||
from .agent.handoff import Handoff, handoff, handoff_filters, RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions
|
||||
# Flow display
|
||||
try:
|
||||
from .flow_display import FlowDisplay, track_workflow
|
||||
except ImportError:
|
||||
FlowDisplay = None
|
||||
track_workflow = None
|
||||
from .main import (
|
||||
TaskOutput,
|
||||
ReflectionOutput,
|
||||
@@ -102,6 +101,8 @@ if _telemetry_available:
|
||||
__all__ = [
|
||||
'Agent',
|
||||
'ImageAgent',
|
||||
'ContextAgent',
|
||||
'create_context_agent',
|
||||
'PraisonAIAgents',
|
||||
'Agents',
|
||||
'Tools',
|
||||
@@ -124,7 +125,6 @@ __all__ = [
|
||||
'async_display_callbacks',
|
||||
'Knowledge',
|
||||
'Chunking',
|
||||
'MCP',
|
||||
'GuardrailResult',
|
||||
'LLMGuardrail',
|
||||
'Handoff',
|
||||
@@ -137,4 +137,13 @@ __all__ = [
|
||||
'disable_telemetry',
|
||||
'MinimalTelemetry',
|
||||
'TelemetryCollector'
|
||||
]
|
||||
]
|
||||
|
||||
# Add MCP to __all__ if available
|
||||
if _mcp_available:
|
||||
__all__.append('MCP')
|
||||
|
||||
# Add flow display if available
|
||||
if FlowDisplay is not None:
|
||||
__all__.extend(['FlowDisplay', 'track_workflow'])
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
"""
|
||||
Centralized logging configuration for PraisonAI Agents.
|
||||
This module consolidates all logging configuration in one place to avoid duplication.
|
||||
"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
# ========================================================================
|
||||
# ENVIRONMENT CONFIGURATION
|
||||
# ========================================================================
|
||||
def _configure_environment():
|
||||
"""Set environment variables to suppress debug messages at the source."""
|
||||
env_vars = {
|
||||
# LiteLLM configuration
|
||||
"LITELLM_TELEMETRY": "False",
|
||||
"LITELLM_DROP_PARAMS": "True",
|
||||
"LITELLM_LOG": "ERROR",
|
||||
"LITELLM_DEBUG": "False",
|
||||
"LITELLM_SUPPRESS_DEBUG_INFO": "True",
|
||||
"LITELLM_VERBOSE": "False",
|
||||
"LITELLM_SET_VERBOSE": "False",
|
||||
# HTTPX configuration
|
||||
"HTTPX_DISABLE_WARNINGS": "True",
|
||||
"HTTPX_LOG_LEVEL": "ERROR",
|
||||
# Pydantic configuration
|
||||
"PYDANTIC_WARNINGS_ENABLED": "False",
|
||||
}
|
||||
|
||||
for key, value in env_vars.items():
|
||||
os.environ[key] = value
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# LOGGER CONFIGURATION
|
||||
# ========================================================================
|
||||
def _get_all_noisy_loggers() -> List[str]:
|
||||
"""Get list of all loggers that should be suppressed."""
|
||||
return [
|
||||
# LiteLLM and variants
|
||||
"litellm", "LiteLLM", "LiteLLM Router", "LiteLLM Proxy",
|
||||
# HTTP libraries
|
||||
"httpx", "httpx._trace", "httpx._client",
|
||||
"httpcore", "httpcore._trace",
|
||||
# OpenAI
|
||||
"openai._base_client", "openai._client",
|
||||
# Markdown
|
||||
"markdown_it", "rich.markdown",
|
||||
# System
|
||||
"asyncio", "selector_events", "pydantic",
|
||||
"praisonaiagents.telemetry.telemetry",
|
||||
]
|
||||
|
||||
|
||||
def _configure_loggers():
|
||||
"""Configure all loggers based on LOGLEVEL environment variable."""
|
||||
loglevel = os.environ.get('LOGLEVEL', 'INFO').upper()
|
||||
|
||||
# When DEBUG is set, allow some HTTP logging for API endpoints
|
||||
if loglevel == 'DEBUG':
|
||||
allowed_debug_loggers = {"httpx", "httpx._client", "openai._client"}
|
||||
|
||||
for logger_name in _get_all_noisy_loggers():
|
||||
if logger_name not in allowed_debug_loggers:
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(logging.CRITICAL)
|
||||
logger.handlers = []
|
||||
logger.propagate = False
|
||||
|
||||
# Ensure allowed loggers are at INFO level to show API calls
|
||||
for logger_name in allowed_debug_loggers:
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(logging.INFO)
|
||||
else:
|
||||
# Suppress all noisy loggers when not in DEBUG mode
|
||||
for logger_name in _get_all_noisy_loggers():
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(logging.CRITICAL)
|
||||
logger.handlers = []
|
||||
logger.propagate = False
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# LITELLM CONFIGURATION
|
||||
# ========================================================================
|
||||
def _configure_litellm():
|
||||
"""Configure litellm after it's imported."""
|
||||
try:
|
||||
import litellm
|
||||
litellm.telemetry = False
|
||||
litellm.drop_params = True
|
||||
litellm.suppress_debug_info = True
|
||||
|
||||
if hasattr(litellm, '_logging_obj'):
|
||||
litellm._logging_obj.setLevel(logging.CRITICAL)
|
||||
|
||||
if hasattr(litellm, 'set_verbose'):
|
||||
litellm.set_verbose = False
|
||||
|
||||
except (ImportError, AttributeError):
|
||||
pass
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# ROOT LOGGER CONFIGURATION
|
||||
# ========================================================================
|
||||
def configure_root_logger():
|
||||
"""Configure the root logger with RichHandler."""
|
||||
from rich.logging import RichHandler
|
||||
|
||||
loglevel = os.environ.get('LOGLEVEL', 'INFO').upper()
|
||||
|
||||
logging.basicConfig(
|
||||
level=getattr(logging, loglevel, logging.INFO),
|
||||
format="%(asctime)s %(filename)s:%(lineno)d %(levelname)s %(message)s",
|
||||
datefmt="[%X]",
|
||||
handlers=[RichHandler(rich_tracebacks=True)],
|
||||
force=True
|
||||
)
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# INITIALIZATION
|
||||
# ========================================================================
|
||||
def initialize_logging():
|
||||
"""Initialize all logging configuration."""
|
||||
_configure_environment()
|
||||
_configure_loggers()
|
||||
_configure_litellm()
|
||||
|
||||
|
||||
# Auto-initialize on import
|
||||
initialize_logging()
|
||||
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Minimal warning patch to suppress specific third-party warnings.
|
||||
This module patches the warnings module to intercept specific messages.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
import functools
|
||||
import sys
|
||||
|
||||
# Apply aggressive warning filters first
|
||||
warnings.filterwarnings("ignore", message=".*Pydantic serializer warnings.*")
|
||||
warnings.filterwarnings("ignore", message=".*PydanticSerializationUnexpectedValue.*")
|
||||
warnings.filterwarnings("ignore", message=".*Expected 9 fields but got.*")
|
||||
warnings.filterwarnings("ignore", message=".*Expected `StreamingChoices` but got.*")
|
||||
warnings.filterwarnings("ignore", message=".*serialized value may not be as expected.*")
|
||||
warnings.filterwarnings("ignore", message=".*Use 'content=<...>' to upload raw bytes/text content.*")
|
||||
warnings.filterwarnings("ignore", message=".*The `dict` method is deprecated.*")
|
||||
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic.*")
|
||||
|
||||
# Store the original warn function
|
||||
_original_warn = warnings.warn
|
||||
_original_warn_explicit = warnings.warn_explicit
|
||||
|
||||
# Messages to suppress (partial matches)
|
||||
SUPPRESSED_PATTERNS = [
|
||||
"Use 'content=<...>' to upload raw bytes/text content",
|
||||
"The `dict` method is deprecated; use `model_dump` instead",
|
||||
"Pydantic serializer warnings",
|
||||
"PydanticSerializationUnexpectedValue",
|
||||
"Expected 9 fields but got 5 for type `Message`",
|
||||
"Expected `StreamingChoices` but got `Choices`",
|
||||
"serialized value may not be as expected"
|
||||
]
|
||||
|
||||
@functools.wraps(_original_warn)
|
||||
def _patched_warn(message, category=None, stacklevel=1, source=None):
|
||||
"""Patched warn function that suppresses specific messages."""
|
||||
msg_str = str(message)
|
||||
|
||||
for pattern in SUPPRESSED_PATTERNS:
|
||||
if pattern in msg_str:
|
||||
return
|
||||
|
||||
if category == UserWarning and "pydantic" in msg_str.lower():
|
||||
return
|
||||
|
||||
_original_warn(message, category, stacklevel, source)
|
||||
|
||||
@functools.wraps(_original_warn_explicit)
|
||||
def _patched_warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None):
|
||||
"""Patched warn_explicit function that suppresses specific messages."""
|
||||
msg_str = str(message)
|
||||
|
||||
for pattern in SUPPRESSED_PATTERNS:
|
||||
if pattern in msg_str:
|
||||
return
|
||||
|
||||
if category == UserWarning and "pydantic" in msg_str.lower():
|
||||
return
|
||||
|
||||
if module and "pydantic" in str(module):
|
||||
return
|
||||
|
||||
_original_warn_explicit(message, category, filename, lineno, module, registry, module_globals, source)
|
||||
|
||||
# Apply the patches
|
||||
warnings.warn = _patched_warn
|
||||
warnings.warn_explicit = _patched_warn_explicit
|
||||
|
||||
# Also patch sys.modules warnings if it exists
|
||||
if 'warnings' in sys.modules:
|
||||
sys.modules['warnings'].warn = _patched_warn
|
||||
sys.modules['warnings'].warn_explicit = _patched_warn_explicit
|
||||
@@ -1,7 +1,8 @@
|
||||
"""Agent module for AI agents"""
|
||||
from .agent import Agent
|
||||
from .image_agent import ImageAgent
|
||||
from .context_agent import ContextAgent, create_context_agent
|
||||
from .handoff import Handoff, handoff, handoff_filters, RECOMMENDED_PROMPT_PREFIX, prompt_with_handoff_instructions
|
||||
from .router_agent import RouterAgent
|
||||
|
||||
__all__ = ['Agent', 'ImageAgent', 'Handoff', 'handoff', 'handoff_filters', 'RECOMMENDED_PROMPT_PREFIX', 'prompt_with_handoff_instructions', 'RouterAgent']
|
||||
__all__ = ['Agent', 'ImageAgent', 'ContextAgent', 'create_context_agent', 'Handoff', 'handoff', 'handoff_filters', 'RECOMMENDED_PROMPT_PREFIX', 'prompt_with_handoff_instructions', 'RouterAgent']
|
||||
@@ -4,7 +4,7 @@ import json
|
||||
import copy
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import List, Optional, Any, Dict, Union, Literal, TYPE_CHECKING, Callable, Tuple
|
||||
from typing import List, Optional, Any, Dict, Union, Literal, TYPE_CHECKING, Callable, Tuple, Generator
|
||||
from rich.console import Console
|
||||
from rich.live import Live
|
||||
from ..llm import (
|
||||
@@ -206,7 +206,7 @@ class Agent:
|
||||
knowledge_config: Optional[Dict[str, Any]] = None,
|
||||
use_system_prompt: Optional[bool] = True,
|
||||
markdown: bool = True,
|
||||
stream: bool = True,
|
||||
stream: bool = False,
|
||||
self_reflect: bool = False,
|
||||
max_reflect: int = 3,
|
||||
min_reflect: int = 1,
|
||||
@@ -281,8 +281,8 @@ class Agent:
|
||||
conversations to establish agent behavior and context. Defaults to True.
|
||||
markdown (bool, optional): Enable markdown formatting in agent responses for better
|
||||
readability and structure. Defaults to True.
|
||||
stream (bool, optional): Enable streaming responses from the language model. Set to False
|
||||
for LLM providers that don't support streaming. Defaults to True.
|
||||
stream (bool, optional): Enable streaming responses from the language model for real-time
|
||||
output when using Agent.start() method. Defaults to False for backward compatibility.
|
||||
self_reflect (bool, optional): Enable self-reflection capabilities where the agent
|
||||
evaluates and improves its own responses. Defaults to False.
|
||||
max_reflect (int, optional): Maximum number of self-reflection iterations to prevent
|
||||
@@ -331,8 +331,15 @@ class Agent:
|
||||
|
||||
# Configure logging to suppress unwanted outputs
|
||||
logging.getLogger("litellm").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
|
||||
# Allow httpx logging when LOGLEVEL=debug, otherwise suppress it
|
||||
loglevel = os.environ.get('LOGLEVEL', 'INFO').upper()
|
||||
if loglevel == 'DEBUG':
|
||||
logging.getLogger("httpx").setLevel(logging.INFO)
|
||||
logging.getLogger("httpcore").setLevel(logging.INFO)
|
||||
else:
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
|
||||
# If instructions are provided, use them to set role, goal, and backstory
|
||||
if instructions:
|
||||
@@ -354,6 +361,8 @@ class Agent:
|
||||
self.instructions = instructions
|
||||
# Check for model name in environment variable if not provided
|
||||
self._using_custom_llm = False
|
||||
# Flag to track if final result has been displayed to prevent duplicates
|
||||
self._final_display_shown = False
|
||||
|
||||
# Store OpenAI client parameters for lazy initialization
|
||||
self._openai_api_key = api_key
|
||||
@@ -1068,7 +1077,7 @@ Your Goal: {self.goal}"""
|
||||
tools=formatted_tools,
|
||||
start_time=start_time,
|
||||
console=self.console,
|
||||
display_fn=display_generating,
|
||||
display_fn=self.display_generating if self.verbose else None,
|
||||
reasoning_steps=reasoning_steps
|
||||
)
|
||||
|
||||
@@ -1107,25 +1116,51 @@ Your Goal: {self.goal}"""
|
||||
reasoning_steps=reasoning_steps
|
||||
)
|
||||
else:
|
||||
# Non-streaming with custom LLM
|
||||
final_response = self.llm_instance.get_response(
|
||||
prompt=messages[1:],
|
||||
system_prompt=messages[0]['content'] if messages and messages[0]['role'] == 'system' else None,
|
||||
temperature=temperature,
|
||||
tools=formatted_tools if formatted_tools else None,
|
||||
verbose=self.verbose,
|
||||
markdown=self.markdown,
|
||||
stream=stream,
|
||||
console=self.console,
|
||||
execute_tool_fn=self.execute_tool,
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ for t in self.tools] if self.tools else None,
|
||||
task_name=task_name,
|
||||
task_description=task_description,
|
||||
task_id=task_id,
|
||||
reasoning_steps=reasoning_steps
|
||||
)
|
||||
# Non-streaming with custom LLM - don't show streaming-like behavior
|
||||
if False: # Don't use display_generating when stream=False to avoid streaming-like behavior
|
||||
# This block is disabled to maintain consistency with the OpenAI path fix
|
||||
with Live(
|
||||
display_generating("", start_time),
|
||||
console=self.console,
|
||||
refresh_per_second=4,
|
||||
) as live:
|
||||
final_response = self.llm_instance.get_response(
|
||||
prompt=messages[1:],
|
||||
system_prompt=messages[0]['content'] if messages and messages[0]['role'] == 'system' else None,
|
||||
temperature=temperature,
|
||||
tools=formatted_tools if formatted_tools else None,
|
||||
verbose=self.verbose,
|
||||
markdown=self.markdown,
|
||||
stream=stream,
|
||||
console=self.console,
|
||||
execute_tool_fn=self.execute_tool,
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ for t in self.tools] if self.tools else None,
|
||||
task_name=task_name,
|
||||
task_description=task_description,
|
||||
task_id=task_id,
|
||||
reasoning_steps=reasoning_steps
|
||||
)
|
||||
else:
|
||||
final_response = self.llm_instance.get_response(
|
||||
prompt=messages[1:],
|
||||
system_prompt=messages[0]['content'] if messages and messages[0]['role'] == 'system' else None,
|
||||
temperature=temperature,
|
||||
tools=formatted_tools if formatted_tools else None,
|
||||
verbose=self.verbose,
|
||||
markdown=self.markdown,
|
||||
stream=stream,
|
||||
console=self.console,
|
||||
execute_tool_fn=self.execute_tool,
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ for t in self.tools] if self.tools else None,
|
||||
task_name=task_name,
|
||||
task_description=task_description,
|
||||
task_id=task_id,
|
||||
reasoning_steps=reasoning_steps
|
||||
)
|
||||
else:
|
||||
# Use the standard OpenAI client approach with tool support
|
||||
# Note: openai_client expects tools in various formats and will format them internally
|
||||
@@ -1141,7 +1176,7 @@ Your Goal: {self.goal}"""
|
||||
execute_tool_fn=self.execute_tool,
|
||||
stream=stream,
|
||||
console=self.console if (self.verbose or stream) else None,
|
||||
display_fn=display_generating if stream else None,
|
||||
display_fn=self.display_generating if self.verbose else None,
|
||||
reasoning_steps=reasoning_steps,
|
||||
verbose=self.verbose,
|
||||
max_iterations=10
|
||||
@@ -1173,18 +1208,47 @@ Your Goal: {self.goal}"""
|
||||
task_description=task_description,
|
||||
task_id=task_id
|
||||
)
|
||||
# Only display interaction if not using custom LLM (to avoid double output) and verbose is True
|
||||
if self.verbose and not self._using_custom_llm:
|
||||
# Always display final interaction when verbose is True to ensure consistent formatting
|
||||
# This ensures both OpenAI and custom LLM providers (like Gemini) show formatted output
|
||||
if self.verbose and not self._final_display_shown:
|
||||
display_interaction(prompt, response, markdown=self.markdown,
|
||||
generation_time=generation_time, console=self.console,
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ for t in self.tools] if self.tools else None,
|
||||
task_name=task_name,
|
||||
task_description=task_description,
|
||||
task_id=task_id)
|
||||
task_name=None, # Not available in this context
|
||||
task_description=None, # Not available in this context
|
||||
task_id=None) # Not available in this context
|
||||
self._final_display_shown = True
|
||||
|
||||
def display_generating(self, content: str, start_time: float):
|
||||
"""Display function for generating animation with agent info."""
|
||||
from rich.panel import Panel
|
||||
from rich.markdown import Markdown
|
||||
elapsed = time.time() - start_time
|
||||
|
||||
# Show content if provided (for both streaming and progressive display)
|
||||
if content:
|
||||
display_content = Markdown(content) if self.markdown else content
|
||||
return Panel(
|
||||
display_content,
|
||||
title=f"[bold]{self.name}[/bold] - Generating... {elapsed:.1f}s",
|
||||
border_style="green",
|
||||
expand=False
|
||||
)
|
||||
# else:
|
||||
# # No content yet: show generating message
|
||||
# return Panel(
|
||||
# f"[bold cyan]Generating response...[/bold cyan]",
|
||||
# title=f"[bold]{self.name}[/bold] - {elapsed:.1f}s",
|
||||
# border_style="cyan",
|
||||
# expand=False
|
||||
# )
|
||||
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False, stream=True, task_name=None, task_description=None, task_id=None):
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False, stream=None, task_name=None, task_description=None, task_id=None):
|
||||
# Reset the final display flag for each new conversation
|
||||
self._final_display_shown = False
|
||||
|
||||
# Log all parameter values when in debug mode
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
param_info = {
|
||||
@@ -1202,6 +1266,9 @@ Your Goal: {self.goal}"""
|
||||
|
||||
start_time = time.time()
|
||||
reasoning_steps = reasoning_steps or self.reasoning_steps
|
||||
# Use agent's stream setting if not explicitly provided
|
||||
if stream is None:
|
||||
stream = self.stream
|
||||
# Search for existing knowledge if any knowledge is provided
|
||||
if self.knowledge:
|
||||
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
|
||||
@@ -1293,6 +1360,8 @@ Your Goal: {self.goal}"""
|
||||
# Apply guardrail validation for custom LLM response
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback and display after validation
|
||||
self._execute_callback_and_display(prompt, validated_response, time.time() - start_time, task_name, task_description, task_id)
|
||||
return validated_response
|
||||
except Exception as e:
|
||||
logging.error(f"Agent {self.name}: Guardrail validation failed for custom LLM: {e}")
|
||||
@@ -1352,7 +1421,7 @@ Your Goal: {self.goal}"""
|
||||
agent_tools=agent_tools
|
||||
)
|
||||
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None, reasoning_steps=reasoning_steps, stream=self.stream, task_name=task_name, task_description=task_description, task_id=task_id)
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=tools if tools else None, reasoning_steps=reasoning_steps, stream=stream, task_name=task_name, task_description=task_description, task_id=task_id)
|
||||
if not response:
|
||||
# Rollback chat history on response failure
|
||||
self.chat_history = self.chat_history[:chat_history_length]
|
||||
@@ -1533,6 +1602,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
async def achat(self, prompt: str, temperature=0.2, tools=None, output_json=None, output_pydantic=None, reasoning_steps=False, task_name=None, task_description=None, task_id=None):
|
||||
"""Async version of chat method with self-reflection support."""
|
||||
# Reset the final display flag for each new conversation
|
||||
self._final_display_shown = False
|
||||
|
||||
# Log all parameter values when in debug mode
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
param_info = {
|
||||
@@ -1838,7 +1910,12 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
for tool_call in message.tool_calls:
|
||||
try:
|
||||
function_name = tool_call.function.name
|
||||
arguments = json.loads(tool_call.function.arguments)
|
||||
# Parse JSON arguments safely
|
||||
try:
|
||||
arguments = json.loads(tool_call.function.arguments)
|
||||
except json.JSONDecodeError as json_error:
|
||||
logging.error(f"Failed to parse tool arguments as JSON: {json_error}")
|
||||
arguments = {}
|
||||
|
||||
# Find the matching tool
|
||||
tool = next((t for t in tools if t.__name__ == function_name), None)
|
||||
@@ -1880,25 +1957,16 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
chunks = []
|
||||
start_time = time.time()
|
||||
|
||||
with Live(
|
||||
display_generating("", start_time),
|
||||
console=self.console,
|
||||
refresh_per_second=4,
|
||||
transient=True,
|
||||
vertical_overflow="ellipsis",
|
||||
auto_refresh=True
|
||||
) as live:
|
||||
async for chunk in final_response:
|
||||
chunks.append(chunk)
|
||||
if chunk.choices[0].delta.content:
|
||||
full_response_text += chunk.choices[0].delta.content
|
||||
live.update(display_generating(full_response_text, start_time))
|
||||
|
||||
if reasoning_steps and hasattr(chunk.choices[0].delta, "reasoning_content"):
|
||||
rc = chunk.choices[0].delta.reasoning_content
|
||||
if rc:
|
||||
reasoning_content += rc
|
||||
live.update(display_generating(f"{full_response_text}\n[Reasoning: {reasoning_content}]", start_time))
|
||||
# Process stream without display_generating since streaming is active
|
||||
async for chunk in final_response:
|
||||
chunks.append(chunk)
|
||||
if chunk.choices[0].delta.content:
|
||||
full_response_text += chunk.choices[0].delta.content
|
||||
|
||||
if reasoning_steps and hasattr(chunk.choices[0].delta, "reasoning_content"):
|
||||
rc = chunk.choices[0].delta.reasoning_content
|
||||
if rc:
|
||||
reasoning_content += rc
|
||||
|
||||
self.console.print()
|
||||
|
||||
@@ -1927,7 +1995,268 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
def start(self, prompt: str, **kwargs):
|
||||
"""Start the agent with a prompt. This is a convenience method that wraps chat()."""
|
||||
return self.chat(prompt, **kwargs)
|
||||
# Check if streaming is enabled (either from kwargs or agent's stream attribute)
|
||||
stream_enabled = kwargs.get('stream', getattr(self, 'stream', False))
|
||||
|
||||
if stream_enabled:
|
||||
# Return a generator for streaming response
|
||||
return self._start_stream(prompt, **kwargs)
|
||||
else:
|
||||
# Return regular chat response for backward compatibility
|
||||
# Explicitly pass the resolved stream parameter to avoid chat() method default
|
||||
kwargs['stream'] = stream_enabled
|
||||
return self.chat(prompt, **kwargs)
|
||||
|
||||
def _start_stream(self, prompt: str, **kwargs) -> Generator[str, None, None]:
|
||||
"""Stream generator for real-time response chunks."""
|
||||
try:
|
||||
# Reset the final display flag for each new conversation
|
||||
self._final_display_shown = False
|
||||
|
||||
# Temporarily disable verbose mode to prevent console output conflicts during streaming
|
||||
original_verbose = self.verbose
|
||||
self.verbose = False
|
||||
|
||||
# For custom LLM path, use the new get_response_stream generator
|
||||
if self._using_custom_llm:
|
||||
# Handle knowledge search
|
||||
actual_prompt = prompt
|
||||
if self.knowledge:
|
||||
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
|
||||
if search_results:
|
||||
if isinstance(search_results, dict) and 'results' in search_results:
|
||||
knowledge_content = "\n".join([result['memory'] for result in search_results['results']])
|
||||
else:
|
||||
knowledge_content = "\n".join(search_results)
|
||||
actual_prompt = f"{prompt}\n\nKnowledge: {knowledge_content}"
|
||||
|
||||
# Handle tools properly
|
||||
tools = kwargs.get('tools', self.tools)
|
||||
if tools is None or (isinstance(tools, list) and len(tools) == 0):
|
||||
tool_param = self.tools
|
||||
else:
|
||||
tool_param = tools
|
||||
|
||||
# Convert MCP tools if needed
|
||||
if tool_param is not None:
|
||||
from ..mcp.mcp import MCP
|
||||
if isinstance(tool_param, MCP) and hasattr(tool_param, 'to_openai_tool'):
|
||||
openai_tool = tool_param.to_openai_tool()
|
||||
if openai_tool:
|
||||
if isinstance(openai_tool, list):
|
||||
tool_param = openai_tool
|
||||
else:
|
||||
tool_param = [openai_tool]
|
||||
|
||||
# Store chat history length for potential rollback
|
||||
chat_history_length = len(self.chat_history)
|
||||
|
||||
# Normalize prompt content for chat history
|
||||
normalized_content = actual_prompt
|
||||
if isinstance(actual_prompt, list):
|
||||
normalized_content = next((item["text"] for item in actual_prompt if item.get("type") == "text"), "")
|
||||
|
||||
# Prevent duplicate messages in chat history
|
||||
if not (self.chat_history and
|
||||
self.chat_history[-1].get("role") == "user" and
|
||||
self.chat_history[-1].get("content") == normalized_content):
|
||||
self.chat_history.append({"role": "user", "content": normalized_content})
|
||||
|
||||
try:
|
||||
# Use the new streaming generator from LLM class
|
||||
response_content = ""
|
||||
for chunk in self.llm_instance.get_response_stream(
|
||||
prompt=actual_prompt,
|
||||
system_prompt=self._build_system_prompt(tool_param),
|
||||
chat_history=self.chat_history,
|
||||
temperature=kwargs.get('temperature', 0.2),
|
||||
tools=tool_param,
|
||||
output_json=kwargs.get('output_json'),
|
||||
output_pydantic=kwargs.get('output_pydantic'),
|
||||
verbose=False, # Keep verbose false for streaming
|
||||
markdown=self.markdown,
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ if hasattr(t, '__name__') else str(t) for t in (tool_param or [])],
|
||||
task_name=kwargs.get('task_name'),
|
||||
task_description=kwargs.get('task_description'),
|
||||
task_id=kwargs.get('task_id'),
|
||||
execute_tool_fn=self.execute_tool
|
||||
):
|
||||
response_content += chunk
|
||||
yield chunk
|
||||
|
||||
# Add complete response to chat history
|
||||
if response_content:
|
||||
self.chat_history.append({"role": "assistant", "content": response_content})
|
||||
|
||||
except Exception as e:
|
||||
# Rollback chat history on error
|
||||
self.chat_history = self.chat_history[:chat_history_length]
|
||||
logging.error(f"Custom LLM streaming error: {e}")
|
||||
raise
|
||||
|
||||
else:
|
||||
# For OpenAI-style models, implement proper streaming without display
|
||||
# Handle knowledge search
|
||||
actual_prompt = prompt
|
||||
if self.knowledge:
|
||||
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
|
||||
if search_results:
|
||||
if isinstance(search_results, dict) and 'results' in search_results:
|
||||
knowledge_content = "\n".join([result['memory'] for result in search_results['results']])
|
||||
else:
|
||||
knowledge_content = "\n".join(search_results)
|
||||
actual_prompt = f"{prompt}\n\nKnowledge: {knowledge_content}"
|
||||
|
||||
# Handle tools properly
|
||||
tools = kwargs.get('tools', self.tools)
|
||||
if tools is None or (isinstance(tools, list) and len(tools) == 0):
|
||||
tool_param = self.tools
|
||||
else:
|
||||
tool_param = tools
|
||||
|
||||
# Build messages using the helper method
|
||||
messages, original_prompt = self._build_messages(actual_prompt, kwargs.get('temperature', 0.2),
|
||||
kwargs.get('output_json'), kwargs.get('output_pydantic'))
|
||||
|
||||
# Store chat history length for potential rollback
|
||||
chat_history_length = len(self.chat_history)
|
||||
|
||||
# Normalize original_prompt for consistent chat history storage
|
||||
normalized_content = original_prompt
|
||||
if isinstance(original_prompt, list):
|
||||
normalized_content = next((item["text"] for item in original_prompt if item.get("type") == "text"), "")
|
||||
|
||||
# Prevent duplicate messages in chat history
|
||||
if not (self.chat_history and
|
||||
self.chat_history[-1].get("role") == "user" and
|
||||
self.chat_history[-1].get("content") == normalized_content):
|
||||
self.chat_history.append({"role": "user", "content": normalized_content})
|
||||
|
||||
try:
|
||||
# Check if OpenAI client is available
|
||||
if self._openai_client is None:
|
||||
raise ValueError("OpenAI client is not initialized. Please provide OPENAI_API_KEY or use a custom LLM provider.")
|
||||
|
||||
# Format tools for OpenAI
|
||||
formatted_tools = self._format_tools_for_completion(tool_param)
|
||||
|
||||
# Create streaming completion directly without display function
|
||||
completion_args = {
|
||||
"model": self.llm,
|
||||
"messages": messages,
|
||||
"temperature": kwargs.get('temperature', 0.2),
|
||||
"stream": True
|
||||
}
|
||||
if formatted_tools:
|
||||
completion_args["tools"] = formatted_tools
|
||||
|
||||
completion = self._openai_client.sync_client.chat.completions.create(**completion_args)
|
||||
|
||||
# Stream the response chunks without display
|
||||
response_text = ""
|
||||
tool_calls_data = []
|
||||
|
||||
for chunk in completion:
|
||||
delta = chunk.choices[0].delta
|
||||
|
||||
# Handle text content
|
||||
if delta.content is not None:
|
||||
chunk_content = delta.content
|
||||
response_text += chunk_content
|
||||
yield chunk_content
|
||||
|
||||
# Handle tool calls (accumulate but don't yield as chunks)
|
||||
if hasattr(delta, 'tool_calls') and delta.tool_calls:
|
||||
for tool_call_delta in delta.tool_calls:
|
||||
# Extend tool_calls_data list to accommodate the tool call index
|
||||
while len(tool_calls_data) <= tool_call_delta.index:
|
||||
tool_calls_data.append({'id': '', 'function': {'name': '', 'arguments': ''}})
|
||||
|
||||
# Accumulate tool call data
|
||||
if tool_call_delta.id:
|
||||
tool_calls_data[tool_call_delta.index]['id'] = tool_call_delta.id
|
||||
if tool_call_delta.function.name:
|
||||
tool_calls_data[tool_call_delta.index]['function']['name'] = tool_call_delta.function.name
|
||||
if tool_call_delta.function.arguments:
|
||||
tool_calls_data[tool_call_delta.index]['function']['arguments'] += tool_call_delta.function.arguments
|
||||
|
||||
# Handle any tool calls that were accumulated
|
||||
if tool_calls_data:
|
||||
# Add assistant message with tool calls to chat history
|
||||
assistant_message = {"role": "assistant", "content": response_text}
|
||||
if tool_calls_data:
|
||||
assistant_message["tool_calls"] = [
|
||||
{
|
||||
"id": tc['id'],
|
||||
"type": "function",
|
||||
"function": tc['function']
|
||||
} for tc in tool_calls_data if tc['id']
|
||||
]
|
||||
self.chat_history.append(assistant_message)
|
||||
|
||||
# Execute tool calls and add results to chat history
|
||||
for tool_call in tool_calls_data:
|
||||
if tool_call['id'] and tool_call['function']['name']:
|
||||
try:
|
||||
# Parse JSON arguments safely
|
||||
try:
|
||||
parsed_args = json.loads(tool_call['function']['arguments']) if tool_call['function']['arguments'] else {}
|
||||
except json.JSONDecodeError as json_error:
|
||||
logging.error(f"Failed to parse tool arguments as JSON: {json_error}")
|
||||
parsed_args = {}
|
||||
|
||||
tool_result = self.execute_tool(
|
||||
tool_call['function']['name'],
|
||||
parsed_args
|
||||
)
|
||||
# Add tool result to chat history
|
||||
self.chat_history.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call['id'],
|
||||
"content": str(tool_result)
|
||||
})
|
||||
except Exception as tool_error:
|
||||
logging.error(f"Tool execution error in streaming: {tool_error}")
|
||||
# Add error result to chat history
|
||||
self.chat_history.append({
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call['id'],
|
||||
"content": f"Error: {str(tool_error)}"
|
||||
})
|
||||
else:
|
||||
# Add complete response to chat history (text-only response)
|
||||
if response_text:
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
|
||||
except Exception as e:
|
||||
# Rollback chat history on error
|
||||
self.chat_history = self.chat_history[:chat_history_length]
|
||||
logging.error(f"OpenAI streaming error: {e}")
|
||||
# Fall back to simulated streaming
|
||||
response = self.chat(prompt, **kwargs)
|
||||
if response:
|
||||
words = str(response).split()
|
||||
chunk_size = max(1, len(words) // 20)
|
||||
for i in range(0, len(words), chunk_size):
|
||||
chunk_words = words[i:i + chunk_size]
|
||||
chunk = ' '.join(chunk_words)
|
||||
if i + chunk_size < len(words):
|
||||
chunk += ' '
|
||||
yield chunk
|
||||
|
||||
# Restore original verbose mode
|
||||
self.verbose = original_verbose
|
||||
|
||||
except Exception as e:
|
||||
# Restore verbose mode on any error
|
||||
self.verbose = original_verbose
|
||||
# Graceful fallback to non-streaming if streaming fails
|
||||
logging.warning(f"Streaming failed, falling back to regular response: {e}")
|
||||
response = self.chat(prompt, **kwargs)
|
||||
if response:
|
||||
yield response
|
||||
|
||||
def execute(self, task, context=None):
|
||||
"""Execute a task synchronously - backward compatibility method"""
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -151,9 +151,23 @@ class ImageAgent(Agent):
|
||||
# Use the model name in config
|
||||
config['model'] = model_name
|
||||
|
||||
# Check if we're using a Gemini model and remove unsupported parameters
|
||||
if 'gemini' in model_name.lower():
|
||||
# Gemini models don't support response_format parameter
|
||||
# Filter parameters based on the provider to avoid unsupported parameter errors
|
||||
custom_llm_provider = None
|
||||
try:
|
||||
import litellm
|
||||
_, custom_llm_provider, _, _ = litellm.get_llm_provider(model=model_name)
|
||||
except (ImportError, AttributeError, ValueError, TypeError, Exception) as e:
|
||||
# Log the specific error for debugging but continue with string-based fallback
|
||||
# Include generic Exception to catch provider-specific errors like BadRequestError
|
||||
logging.debug(f"Provider detection failed for model '{model_name}': {e}")
|
||||
|
||||
if custom_llm_provider == "vertex_ai":
|
||||
# Vertex AI only supports 'n' and 'size' parameters for image generation
|
||||
supported_params = ['n', 'size', 'model']
|
||||
config = {k: v for k, v in config.items() if k in supported_params}
|
||||
elif custom_llm_provider == "gemini" or (custom_llm_provider is None and 'gemini' in model_name.lower()):
|
||||
# Gemini provider doesn't support response_format parameter
|
||||
# Apply this filter if provider is explicitly 'gemini' or as fallback for gemini models
|
||||
config.pop('response_format', None)
|
||||
|
||||
with Progress(
|
||||
@@ -165,9 +179,10 @@ class ImageAgent(Agent):
|
||||
# Add a task for image generation
|
||||
task = progress.add_task(f"[cyan]Generating image with {model_name}...", total=None)
|
||||
|
||||
# Use litellm's image generation
|
||||
# Use litellm's image generation with parameter dropping enabled as safety net
|
||||
response = self.litellm(
|
||||
prompt=prompt,
|
||||
drop_params=True,
|
||||
**config
|
||||
)
|
||||
|
||||
|
||||
@@ -81,16 +81,19 @@ def process_task_context(context_item, verbose=0, user_id=None):
|
||||
task_name = context_item.name if context_item.name else context_item.description
|
||||
|
||||
if context_item.result and task_status == TaskStatus.COMPLETED.value:
|
||||
return f"Result of previous task {task_name}:\n{context_item.result.raw}"
|
||||
# Log detailed result for debugging
|
||||
logger.debug(f"Previous task '{task_name}' result: {context_item.result.raw}")
|
||||
# Return actual result content without verbose label (essential for task chaining)
|
||||
return context_item.result.raw
|
||||
elif task_status == TaskStatus.COMPLETED.value and not context_item.result:
|
||||
return f"Previous task {task_name} completed but produced no result."
|
||||
return "" # No result to include
|
||||
else:
|
||||
return f"Previous task {task_name} is not yet completed (status: {task_status or TaskStatus.UNKNOWN.value})."
|
||||
elif isinstance(context_item, dict) and "vector_store" in context_item:
|
||||
return "" # Task not completed, no context to include
|
||||
elif isinstance(context_item, dict) and ("vector_store" in context_item or "embedding_db_config" in context_item):
|
||||
from ..knowledge.knowledge import Knowledge
|
||||
try:
|
||||
# Handle both string and dict configs
|
||||
cfg = context_item["vector_store"]
|
||||
# Handle both string and dict configs - support both vector_store and embedding_db_config keys for backward compatibility
|
||||
cfg = context_item.get("vector_store") or context_item.get("embedding_db_config")
|
||||
if isinstance(cfg, str):
|
||||
cfg = json.loads(cfg)
|
||||
|
||||
@@ -101,9 +104,19 @@ def process_task_context(context_item, verbose=0, user_id=None):
|
||||
context_item.get("query", ""), # Use query from context if available
|
||||
user_id=user_id if user_id else None
|
||||
)
|
||||
return f"[DB Context]: {str(db_results)}"
|
||||
|
||||
# Log knowledge results for debugging (always available for troubleshooting)
|
||||
logger.debug(f"Knowledge search results ({len(db_results)} items): {str(db_results)}")
|
||||
|
||||
# Return actual content without verbose "[DB Context]:" prefix
|
||||
return str(db_results)
|
||||
except Exception as e:
|
||||
return f"[Vector DB Error]: {e}"
|
||||
# Log error for debugging (always available for troubleshooting)
|
||||
logger.debug(f"Vector DB Error: {e}")
|
||||
|
||||
# Return empty string to avoid exposing error details in AI prompts
|
||||
# Error details are preserved in debug logs for troubleshooting
|
||||
return ""
|
||||
else:
|
||||
return str(context_item) # Fallback for unknown types
|
||||
|
||||
@@ -148,7 +161,9 @@ class PraisonAIAgents:
|
||||
|
||||
# Set logger level based on verbose
|
||||
if verbose >= 5:
|
||||
logger.setLevel(logging.INFO)
|
||||
logger.setLevel(logging.INFO) # keep everything ≥INFO
|
||||
elif verbose >= 3:
|
||||
logger.setLevel(logging.DEBUG) # surface DEBUG when user asks for it
|
||||
else:
|
||||
logger.setLevel(logging.WARNING)
|
||||
|
||||
@@ -312,7 +327,7 @@ Expected Output: {task.expected_output}.
|
||||
if self.verbose >= 3:
|
||||
logger.info(f"Task {task_id} context items: {len(unique_contexts)}")
|
||||
for i, ctx in enumerate(unique_contexts):
|
||||
logger.info(f"Context {i+1}: {ctx[:100]}...")
|
||||
logger.debug(f"Context {i+1}: {ctx[:100]}...")
|
||||
context_separator = '\n\n'
|
||||
task_prompt += f"""
|
||||
Context:
|
||||
@@ -635,7 +650,7 @@ Expected Output: {task.expected_output}.
|
||||
if self.verbose >= 3:
|
||||
logger.info(f"Task {task_id} context items: {len(unique_contexts)}")
|
||||
for i, ctx in enumerate(unique_contexts):
|
||||
logger.info(f"Context {i+1}: {ctx[:100]}...")
|
||||
logger.debug(f"Context {i+1}: {ctx[:100]}...")
|
||||
context_separator = '\n\n'
|
||||
task_prompt += f"""
|
||||
Context:
|
||||
@@ -648,7 +663,10 @@ Context:
|
||||
try:
|
||||
memory_context = task.memory.build_context_for_task(task.description)
|
||||
if memory_context:
|
||||
task_prompt += f"\n\nRelevant memory context:\n{memory_context}"
|
||||
# Log detailed memory context for debugging
|
||||
logger.debug(f"Memory context for task '{task.description}': {memory_context}")
|
||||
# Include actual memory content without verbose headers (essential for AI agent functionality)
|
||||
task_prompt += f"\n\n{memory_context}"
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting memory context: {e}")
|
||||
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
"""
|
||||
Flow Display for PraisonAI Agents
|
||||
|
||||
Visual display with agents in center and tools on sides.
|
||||
"""
|
||||
|
||||
from typing import Dict, List, Set, Tuple
|
||||
from collections import defaultdict
|
||||
import threading
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
from rich.align import Align
|
||||
from rich.columns import Columns
|
||||
from rich.table import Table
|
||||
from rich import box
|
||||
|
||||
class FlowDisplay:
|
||||
"""Displays agent workflow with agents centered and tools on sides."""
|
||||
|
||||
def __init__(self):
|
||||
self.console = Console()
|
||||
self.agents = [] # List of agents in order
|
||||
self.agent_tools = defaultdict(list) # agent -> [tools]
|
||||
self.tracking = False
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def start(self):
|
||||
"""Start tracking workflow."""
|
||||
self.tracking = True
|
||||
self.agents.clear()
|
||||
self.agent_tools.clear()
|
||||
|
||||
# Register callbacks
|
||||
try:
|
||||
from praisonaiagents.main import register_display_callback
|
||||
|
||||
def on_interaction(**kwargs):
|
||||
if self.tracking:
|
||||
agent = kwargs.get('agent_name', 'Unknown')
|
||||
self._add_agent(agent)
|
||||
|
||||
def on_tool_call(message, **kwargs):
|
||||
if self.tracking and "called function" in message:
|
||||
parts = message.split("'")
|
||||
if len(parts) > 1:
|
||||
tool_name = parts[1]
|
||||
agent = kwargs.get('agent_name', 'Unknown')
|
||||
self._add_tool(agent, tool_name)
|
||||
|
||||
register_display_callback('interaction', on_interaction)
|
||||
register_display_callback('tool_call', on_tool_call)
|
||||
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
"""Stop tracking and display the flow."""
|
||||
self.tracking = False
|
||||
self.display()
|
||||
|
||||
def _add_agent(self, name: str):
|
||||
"""Add an agent if not already present."""
|
||||
with self.lock:
|
||||
if name not in self.agents:
|
||||
self.agents.append(name)
|
||||
|
||||
def _add_tool(self, agent_name: str, tool_name: str):
|
||||
"""Add a tool to an agent."""
|
||||
with self.lock:
|
||||
if agent_name not in self.agents:
|
||||
self.agents.append(agent_name)
|
||||
if tool_name not in self.agent_tools[agent_name]:
|
||||
self.agent_tools[agent_name].append(tool_name)
|
||||
|
||||
def display(self):
|
||||
"""Display the flow chart with agents in center and tools on sides."""
|
||||
if not self.agents:
|
||||
return
|
||||
|
||||
self.console.print("\n[bold cyan]🔄 Agent Workflow Flow[/bold cyan]\n")
|
||||
|
||||
# Display start
|
||||
self._display_centered_node("── start ──", "grey35")
|
||||
self._display_arrow_down()
|
||||
|
||||
# Display each agent with their tools
|
||||
for i, agent in enumerate(self.agents):
|
||||
self._display_agent_with_tools(agent)
|
||||
|
||||
# Add arrow to next agent or end
|
||||
if i < len(self.agents) - 1:
|
||||
self._display_arrow_down()
|
||||
|
||||
# Display end
|
||||
self._display_arrow_down()
|
||||
self._display_centered_node("── end ──", "grey35")
|
||||
|
||||
def _display_agent_with_tools(self, agent: str):
|
||||
"""Display agent with tools on the sides."""
|
||||
tools = self.agent_tools.get(agent, [])
|
||||
|
||||
if not tools:
|
||||
# No tools - just agent
|
||||
self._display_centered_node(agent, "purple")
|
||||
else:
|
||||
# Split tools between left and right
|
||||
left_tools = tools[::2] # Even indices
|
||||
right_tools = tools[1::2] # Odd indices
|
||||
|
||||
# Create the layout
|
||||
table = Table(show_header=False, show_edge=False, box=None, padding=0)
|
||||
table.add_column(justify="center", min_width=20) # Left tools
|
||||
table.add_column(justify="center", min_width=5) # Space
|
||||
table.add_column(justify="center", min_width=20) # Agent
|
||||
table.add_column(justify="center", min_width=5) # Space
|
||||
table.add_column(justify="center", min_width=20) # Right tools
|
||||
|
||||
# Create panels
|
||||
left_panel = self._create_tools_panel(left_tools) if left_tools else ""
|
||||
agent_panel = Panel(
|
||||
Text(agent, style="white on purple", justify="center"),
|
||||
style="white on purple",
|
||||
box=box.ROUNDED,
|
||||
padding=(0, 2)
|
||||
)
|
||||
right_panel = self._create_tools_panel(right_tools) if right_tools else ""
|
||||
|
||||
# Add row
|
||||
table.add_row(left_panel, "", agent_panel, "", right_panel)
|
||||
|
||||
# Display centered
|
||||
self.console.print(Align.center(table))
|
||||
|
||||
# Show arrows
|
||||
if left_tools or right_tools:
|
||||
arrow_parts = []
|
||||
if left_tools:
|
||||
arrow_parts.append("←→")
|
||||
else:
|
||||
arrow_parts.append(" ")
|
||||
|
||||
arrow_parts.append(" ") # Center space
|
||||
|
||||
if right_tools:
|
||||
arrow_parts.append("←→")
|
||||
else:
|
||||
arrow_parts.append(" ")
|
||||
|
||||
self.console.print(Align.center(Text("".join(arrow_parts))))
|
||||
|
||||
def _create_tools_panel(self, tools: List[str]) -> Panel:
|
||||
"""Create a panel for tools."""
|
||||
if not tools:
|
||||
return ""
|
||||
|
||||
if len(tools) == 1:
|
||||
return Panel(
|
||||
Text(tools[0], style="black on yellow", justify="center"),
|
||||
style="black on yellow",
|
||||
box=box.ROUNDED,
|
||||
padding=(0, 1)
|
||||
)
|
||||
else:
|
||||
# Multiple tools
|
||||
content = "\n".join(tools)
|
||||
return Panel(
|
||||
Text(content, style="black on yellow", justify="center"),
|
||||
style="black on yellow",
|
||||
box=box.ROUNDED,
|
||||
padding=(0, 1)
|
||||
)
|
||||
|
||||
def _display_centered_node(self, label: str, color: str):
|
||||
"""Display a centered node."""
|
||||
panel = Panel(
|
||||
Text(label, style=f"white on {color}", justify="center"),
|
||||
style=f"white on {color}",
|
||||
box=box.ROUNDED,
|
||||
padding=(0, 2)
|
||||
)
|
||||
self.console.print(Align.center(panel))
|
||||
|
||||
def _display_arrow_down(self):
|
||||
"""Display a downward arrow."""
|
||||
self.console.print()
|
||||
self.console.print(Align.center("↓"))
|
||||
self.console.print()
|
||||
|
||||
|
||||
# Simple function to create and use
|
||||
def track_workflow():
|
||||
"""Create a flow display tracker."""
|
||||
return FlowDisplay()
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import logging
|
||||
import uuid
|
||||
import time
|
||||
from datetime import datetime
|
||||
from .chunking import Chunking
|
||||
from functools import cached_property
|
||||
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TaskProgressColumn
|
||||
@@ -47,6 +48,342 @@ class CustomMemory:
|
||||
"event": "ADD"
|
||||
}]
|
||||
|
||||
class MongoDBMemory:
|
||||
"""MongoDB-based memory store for knowledge management."""
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
self.vector_store_config = config.get("vector_store", {}).get("config", {})
|
||||
self.connection_string = self.vector_store_config.get("connection_string", "mongodb://localhost:27017/")
|
||||
self.database_name = self.vector_store_config.get("database", "praisonai")
|
||||
self.collection_name = self.vector_store_config.get("collection", "knowledge_base")
|
||||
self.use_vector_search = self.vector_store_config.get("use_vector_search", True)
|
||||
|
||||
# Initialize MongoDB client
|
||||
self._init_mongodb()
|
||||
|
||||
# Initialize embedding model
|
||||
self._init_embedding_model()
|
||||
|
||||
def _init_mongodb(self):
|
||||
"""Initialize MongoDB client and collection."""
|
||||
try:
|
||||
from pymongo import MongoClient
|
||||
|
||||
self.client = MongoClient(
|
||||
self.connection_string,
|
||||
maxPoolSize=50,
|
||||
retryWrites=True,
|
||||
retryReads=True
|
||||
)
|
||||
|
||||
# Test connection
|
||||
self.client.admin.command('ping')
|
||||
|
||||
# Setup database and collection
|
||||
self.db = self.client[self.database_name]
|
||||
self.collection = self.db[self.collection_name]
|
||||
|
||||
# Create indexes
|
||||
self._create_indexes()
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to initialize MongoDB: {e}")
|
||||
|
||||
def _init_embedding_model(self):
|
||||
"""Initialize embedding model from config."""
|
||||
try:
|
||||
# Set up embedding model based on config
|
||||
embedder_config = self.config.get("embedder", {})
|
||||
if embedder_config.get("provider") == "openai":
|
||||
import openai
|
||||
self.embedding_model = openai.OpenAI()
|
||||
self.embedding_model_name = embedder_config.get("config", {}).get("model", "text-embedding-3-small")
|
||||
else:
|
||||
# Default to OpenAI
|
||||
import openai
|
||||
self.embedding_model = openai.OpenAI()
|
||||
self.embedding_model_name = "text-embedding-3-small"
|
||||
except Exception as e:
|
||||
raise Exception(f"Failed to initialize embedding model: {e}")
|
||||
|
||||
def _get_embedding_dimensions(self, model_name: str) -> int:
|
||||
"""Get embedding dimensions based on model name."""
|
||||
# Common embedding model dimensions
|
||||
model_dimensions = {
|
||||
"text-embedding-3-small": 1536,
|
||||
"text-embedding-3-large": 3072,
|
||||
"text-embedding-ada-002": 1536,
|
||||
"text-embedding-002": 1536,
|
||||
# Add more models as needed
|
||||
}
|
||||
|
||||
# Check if model name contains known model identifiers
|
||||
for model_key, dimensions in model_dimensions.items():
|
||||
if model_key in model_name.lower():
|
||||
return dimensions
|
||||
|
||||
# Default to 1536 for unknown models (OpenAI standard)
|
||||
return 1536
|
||||
|
||||
def _create_indexes(self):
|
||||
"""Create necessary indexes for MongoDB."""
|
||||
try:
|
||||
# Text search index
|
||||
self.collection.create_index([("content", "text")])
|
||||
|
||||
# Metadata indexes
|
||||
self.collection.create_index([("metadata.filename", 1)])
|
||||
self.collection.create_index([("created_at", -1)])
|
||||
|
||||
# Vector search index for Atlas (if enabled)
|
||||
if self.use_vector_search:
|
||||
self._create_vector_index()
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f"Could not create MongoDB indexes: {e}")
|
||||
|
||||
def _create_vector_index(self):
|
||||
"""Create vector search index for Atlas Vector Search."""
|
||||
try:
|
||||
vector_index_def = {
|
||||
"mappings": {
|
||||
"dynamic": True,
|
||||
"fields": {
|
||||
"embedding": {
|
||||
"type": "knnVector",
|
||||
"dimensions": self._get_embedding_dimensions(self.embedding_model_name),
|
||||
"similarity": "cosine"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.collection.create_search_index(vector_index_def, "vector_index")
|
||||
|
||||
except Exception as e:
|
||||
logging.warning(f"Could not create vector search index: {e}")
|
||||
|
||||
def _get_embedding(self, text):
|
||||
"""Get embedding for text."""
|
||||
try:
|
||||
response = self.embedding_model.embeddings.create(
|
||||
input=text,
|
||||
model=self.embedding_model_name
|
||||
)
|
||||
return response.data[0].embedding
|
||||
except Exception as e:
|
||||
logging.error(f"Error getting embedding: {e}")
|
||||
return None
|
||||
|
||||
def add(self, messages, user_id=None, agent_id=None, run_id=None, metadata=None):
|
||||
"""Add memory to MongoDB."""
|
||||
try:
|
||||
# Handle different message formats
|
||||
if isinstance(messages, list):
|
||||
content = "\n".join([msg.get("content", str(msg)) if isinstance(msg, dict) else str(msg) for msg in messages])
|
||||
else:
|
||||
content = str(messages)
|
||||
|
||||
# Generate embedding
|
||||
embedding = self._get_embedding(content) if self.use_vector_search else None
|
||||
|
||||
# Create document
|
||||
doc = {
|
||||
"content": content,
|
||||
"metadata": metadata or {},
|
||||
"user_id": user_id,
|
||||
"agent_id": agent_id,
|
||||
"run_id": run_id,
|
||||
"created_at": datetime.utcnow(),
|
||||
"memory_type": "knowledge"
|
||||
}
|
||||
|
||||
if embedding:
|
||||
doc["embedding"] = embedding
|
||||
|
||||
# Insert document
|
||||
result = self.collection.insert_one(doc)
|
||||
|
||||
return [{
|
||||
"id": str(result.inserted_id),
|
||||
"memory": content,
|
||||
"event": "ADD"
|
||||
}]
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error adding memory to MongoDB: {e}")
|
||||
return []
|
||||
|
||||
def search(self, query, user_id=None, agent_id=None, run_id=None, rerank=False, **kwargs):
|
||||
"""Search memories in MongoDB."""
|
||||
try:
|
||||
results = []
|
||||
|
||||
# Vector search if enabled
|
||||
if self.use_vector_search:
|
||||
embedding = self._get_embedding(query)
|
||||
if embedding:
|
||||
pipeline = [
|
||||
{
|
||||
"$vectorSearch": {
|
||||
"index": "vector_index",
|
||||
"path": "embedding",
|
||||
"queryVector": embedding,
|
||||
"numCandidates": kwargs.get("limit", 10) * 10,
|
||||
"limit": kwargs.get("limit", 10)
|
||||
}
|
||||
},
|
||||
{
|
||||
"$addFields": {
|
||||
"score": {"$meta": "vectorSearchScore"}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
# Add filters if provided
|
||||
if user_id or agent_id or run_id:
|
||||
match_filter = {}
|
||||
if user_id:
|
||||
match_filter["user_id"] = user_id
|
||||
if agent_id:
|
||||
match_filter["agent_id"] = agent_id
|
||||
if run_id:
|
||||
match_filter["run_id"] = run_id
|
||||
|
||||
pipeline.append({"$match": match_filter})
|
||||
|
||||
for doc in self.collection.aggregate(pipeline):
|
||||
results.append({
|
||||
"id": str(doc["_id"]),
|
||||
"memory": doc["content"],
|
||||
"metadata": doc.get("metadata", {}),
|
||||
"score": doc.get("score", 1.0)
|
||||
})
|
||||
|
||||
# Fallback to text search
|
||||
if not results:
|
||||
search_filter = {"$text": {"$search": query}}
|
||||
|
||||
# Add additional filters
|
||||
if user_id:
|
||||
search_filter["user_id"] = user_id
|
||||
if agent_id:
|
||||
search_filter["agent_id"] = agent_id
|
||||
if run_id:
|
||||
search_filter["run_id"] = run_id
|
||||
|
||||
for doc in self.collection.find(search_filter).limit(kwargs.get("limit", 10)):
|
||||
results.append({
|
||||
"id": str(doc["_id"]),
|
||||
"memory": doc["content"],
|
||||
"metadata": doc.get("metadata", {}),
|
||||
"score": 1.0
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error searching MongoDB: {e}")
|
||||
return []
|
||||
|
||||
def get_all(self, user_id=None, agent_id=None, run_id=None):
|
||||
"""Get all memories from MongoDB."""
|
||||
try:
|
||||
search_filter = {}
|
||||
if user_id:
|
||||
search_filter["user_id"] = user_id
|
||||
if agent_id:
|
||||
search_filter["agent_id"] = agent_id
|
||||
if run_id:
|
||||
search_filter["run_id"] = run_id
|
||||
|
||||
results = []
|
||||
for doc in self.collection.find(search_filter):
|
||||
results.append({
|
||||
"id": str(doc["_id"]),
|
||||
"memory": doc["content"],
|
||||
"metadata": doc.get("metadata", {}),
|
||||
"created_at": doc.get("created_at")
|
||||
})
|
||||
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error getting all memories from MongoDB: {e}")
|
||||
return []
|
||||
|
||||
def get(self, memory_id):
|
||||
"""Get a specific memory by ID."""
|
||||
try:
|
||||
from bson import ObjectId
|
||||
doc = self.collection.find_one({"_id": ObjectId(memory_id)})
|
||||
if doc:
|
||||
return {
|
||||
"id": str(doc["_id"]),
|
||||
"memory": doc["content"],
|
||||
"metadata": doc.get("metadata", {}),
|
||||
"created_at": doc.get("created_at")
|
||||
}
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error getting memory from MongoDB: {e}")
|
||||
return None
|
||||
|
||||
def update(self, memory_id, data):
|
||||
"""Update a memory."""
|
||||
try:
|
||||
from bson import ObjectId
|
||||
result = self.collection.update_one(
|
||||
{"_id": ObjectId(memory_id)},
|
||||
{"$set": {"content": data, "updated_at": datetime.utcnow()}}
|
||||
)
|
||||
return result.modified_count > 0
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error updating memory in MongoDB: {e}")
|
||||
return False
|
||||
|
||||
def delete(self, memory_id):
|
||||
"""Delete a memory."""
|
||||
try:
|
||||
from bson import ObjectId
|
||||
result = self.collection.delete_one({"_id": ObjectId(memory_id)})
|
||||
return result.deleted_count > 0
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error deleting memory from MongoDB: {e}")
|
||||
return False
|
||||
|
||||
def delete_all(self, user_id=None, agent_id=None, run_id=None):
|
||||
"""Delete all memories."""
|
||||
try:
|
||||
search_filter = {}
|
||||
if user_id:
|
||||
search_filter["user_id"] = user_id
|
||||
if agent_id:
|
||||
search_filter["agent_id"] = agent_id
|
||||
if run_id:
|
||||
search_filter["run_id"] = run_id
|
||||
|
||||
result = self.collection.delete_many(search_filter)
|
||||
return result.deleted_count
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error deleting all memories from MongoDB: {e}")
|
||||
return 0
|
||||
|
||||
def reset(self):
|
||||
"""Reset all memories."""
|
||||
try:
|
||||
result = self.collection.delete_many({})
|
||||
return result.deleted_count
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error resetting MongoDB memories: {e}")
|
||||
return 0
|
||||
|
||||
class Knowledge:
|
||||
def __init__(self, config=None, verbose=None):
|
||||
self._config = config
|
||||
@@ -119,8 +456,20 @@ class Knowledge:
|
||||
if "vector_store" in self._config:
|
||||
if "provider" in self._config["vector_store"]:
|
||||
base_config["vector_store"]["provider"] = self._config["vector_store"]["provider"]
|
||||
|
||||
# Special handling for MongoDB vector store
|
||||
if self._config["vector_store"]["provider"] == "mongodb":
|
||||
base_config["vector_store"] = {
|
||||
"provider": "mongodb",
|
||||
"config": {
|
||||
"connection_string": self._config["vector_store"]["config"].get("connection_string", "mongodb://localhost:27017/"),
|
||||
"database": self._config["vector_store"]["config"].get("database", "praisonai"),
|
||||
"collection": self._config["vector_store"]["config"].get("collection", "knowledge_base"),
|
||||
"use_vector_search": self._config["vector_store"]["config"].get("use_vector_search", True)
|
||||
}
|
||||
}
|
||||
|
||||
if "config" in self._config["vector_store"]:
|
||||
if "config" in self._config["vector_store"] and self._config["vector_store"]["provider"] != "mongodb":
|
||||
config_copy = self._config["vector_store"]["config"].copy()
|
||||
# Only exclude client as it's managed internally
|
||||
if "client" in config_copy:
|
||||
@@ -146,6 +495,16 @@ class Knowledge:
|
||||
|
||||
@cached_property
|
||||
def memory(self):
|
||||
# Check if MongoDB provider is specified
|
||||
if (self.config.get("vector_store", {}).get("provider") == "mongodb"):
|
||||
try:
|
||||
return MongoDBMemory(self.config)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize MongoDB memory: {e}")
|
||||
# Fall back to default memory
|
||||
pass
|
||||
|
||||
# Default Mem0 memory
|
||||
try:
|
||||
return CustomMemory.from_config(self.config)
|
||||
except (NotImplementedError, ValueError) as e:
|
||||
@@ -355,7 +714,15 @@ class Knowledge:
|
||||
memory_result = self.store(memory, user_id=user_id, agent_id=agent_id,
|
||||
run_id=run_id, metadata=metadata)
|
||||
if memory_result:
|
||||
all_results.extend(memory_result.get('results', []))
|
||||
# Handle both dict and list formats for backward compatibility
|
||||
if isinstance(memory_result, dict):
|
||||
all_results.extend(memory_result.get('results', []))
|
||||
elif isinstance(memory_result, list):
|
||||
all_results.extend(memory_result)
|
||||
else:
|
||||
# Log warning for unexpected types but don't break
|
||||
import logging
|
||||
logging.warning(f"Unexpected memory_result type: {type(memory_result)}, skipping")
|
||||
progress.advance(store_task)
|
||||
|
||||
return {'results': all_results, 'relations': []}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Ollama Handling in LLM.py
|
||||
|
||||
The `ollama_handled` flag is used in `llm.py` (not in `agent.py`) to track whether special Ollama model handling has been applied for tool results. Here's what I found:
|
||||
|
||||
## Where it's used in llm.py:
|
||||
- **Line 863**: `ollama_handled = False` - initialized at the beginning of the tool execution loop
|
||||
- **Line 864**: Special handling logic via `_handle_ollama_model()` method
|
||||
- **Line 907**: `ollama_handled = True` - set when Ollama special handling is applied
|
||||
- **Line 928 & 959**: Checks `if not ollama_handled` to avoid duplicate processing
|
||||
|
||||
## Why it's needed:
|
||||
The flag prevents duplicate processing when Ollama models require special handling. Some Ollama models return only the tool call JSON without processing the results, requiring a follow-up prompt to get the final answer. The `ollama_handled` flag ensures this special handling happens only once.
|
||||
|
||||
## Does this contradict the requirement?
|
||||
**No, it doesn't.** The issue states:
|
||||
|
||||
> "ollama/xxxx model is already handled via llm.py via litellm, so no special condition or handling required for ollama inside agent.py"
|
||||
|
||||
✅ **Current implementation is correct:**
|
||||
|
||||
- `agent.py` has NO ollama-specific conditions (only one documentation mention as an example)
|
||||
- All ollama handling is contained within `llm.py` as intended
|
||||
- The `ollama_handled` flag is an internal implementation detail within `llm.py`
|
||||
|
||||
The codebase already follows the desired pattern where ollama models are handled through the generic LLM interface via litellm without special conditions in agent.py.
|
||||
@@ -1,21 +1,9 @@
|
||||
import logging
|
||||
import warnings
|
||||
import os
|
||||
|
||||
# Disable litellm telemetry before any imports
|
||||
# Ensure litellm telemetry is disabled before imports
|
||||
os.environ["LITELLM_TELEMETRY"] = "False"
|
||||
|
||||
# Suppress all relevant logs at module level - consistent with main __init__.py
|
||||
logging.getLogger("litellm").setLevel(logging.WARNING)
|
||||
logging.getLogger("openai").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpx").setLevel(logging.WARNING)
|
||||
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
||||
logging.getLogger("pydantic").setLevel(logging.WARNING)
|
||||
|
||||
# Suppress pydantic warnings
|
||||
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic")
|
||||
|
||||
# Import after suppressing warnings
|
||||
# Import modules
|
||||
from .llm import LLM, LLMContextLengthExceededException
|
||||
from .openai_client import (
|
||||
OpenAIClient,
|
||||
@@ -40,13 +28,6 @@ from .model_router import (
|
||||
create_routing_agent
|
||||
)
|
||||
|
||||
# Ensure telemetry is disabled after import as well
|
||||
try:
|
||||
import litellm
|
||||
litellm.telemetry = False
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__all__ = [
|
||||
"LLM",
|
||||
"LLMContextLengthExceededException",
|
||||
@@ -66,4 +47,4 @@ __all__ = [
|
||||
"ModelProfile",
|
||||
"TaskComplexity",
|
||||
"create_routing_agent"
|
||||
]
|
||||
]
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 157 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user