mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-07 17:33:33 -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
|
||||
|
||||
@@ -120,6 +120,10 @@ agent.start('Write a movie script about a robot in Mars');
|
||||
|
||||

|
||||
|
||||
## Star History
|
||||
|
||||
[](https://docs.praison.ai)
|
||||
|
||||
## AI Agents Flow
|
||||
|
||||
```mermaid
|
||||
@@ -557,10 +561,6 @@ uv pip install -r pyproject.toml --extra "crewai,autogen"
|
||||
- 🖼️ Vision Language Model (VLM) Support
|
||||
- 🎙️ Real-time Voice Interaction
|
||||
|
||||
## Star History
|
||||
|
||||
[](https://docs.praison.ai)
|
||||
|
||||
## Video Tutorials
|
||||
|
||||
| Topic | Video |
|
||||
|
||||
+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.68" \
|
||||
"praisonai>=2.2.75" \
|
||||
"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.68" \
|
||||
"praisonai>=2.2.75" \
|
||||
"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.68" \
|
||||
"praisonai>=2.2.75" \
|
||||
"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.68" \
|
||||
"praisonai>=2.2.75" \
|
||||
"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.68`
|
||||
- PraisonAI: `>=2.2.75`
|
||||
- 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.68" "praisonaiagents==0.0.92"
|
||||
RUN pip install "praisonai==2.2.75" "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!")
|
||||
@@ -94,12 +94,17 @@ async def main():
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
results = await workflow.astart()
|
||||
results = await workflow.astart(dict_output=True)
|
||||
|
||||
print("\nParallel Processing Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
|
||||
# Handle both string and dictionary return types
|
||||
if isinstance(results, dict) and "task_results" in results:
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
else:
|
||||
print("Final result:", results)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -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,39 +2,32 @@
|
||||
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
|
||||
@@ -102,6 +95,8 @@ if _telemetry_available:
|
||||
__all__ = [
|
||||
'Agent',
|
||||
'ImageAgent',
|
||||
'ContextAgent',
|
||||
'create_context_agent',
|
||||
'PraisonAIAgents',
|
||||
'Agents',
|
||||
'Tools',
|
||||
@@ -124,7 +119,6 @@ __all__ = [
|
||||
'async_display_callbacks',
|
||||
'Knowledge',
|
||||
'Chunking',
|
||||
'MCP',
|
||||
'GuardrailResult',
|
||||
'LLMGuardrail',
|
||||
'Handoff',
|
||||
@@ -137,4 +131,8 @@ __all__ = [
|
||||
'disable_telemetry',
|
||||
'MinimalTelemetry',
|
||||
'TelemetryCollector'
|
||||
]
|
||||
]
|
||||
|
||||
# Add MCP to __all__ if available
|
||||
if _mcp_available:
|
||||
__all__.append('MCP')
|
||||
@@ -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
|
||||
@@ -653,7 +662,7 @@ Your Goal: {self.goal}
|
||||
error=f"Agent guardrail validation error: {str(e)}"
|
||||
)
|
||||
|
||||
def _apply_guardrail_with_retry(self, response_text, prompt, temperature=0.2, tools=None):
|
||||
def _apply_guardrail_with_retry(self, response_text, prompt, temperature=0.2, tools=None, task_name=None, task_description=None, task_id=None):
|
||||
"""Apply guardrail validation with retry logic.
|
||||
|
||||
Args:
|
||||
@@ -707,7 +716,7 @@ Your Goal: {self.goal}
|
||||
# Regenerate response for retry
|
||||
try:
|
||||
retry_prompt = f"{prompt}\n\nNote: Previous response failed validation due to: {guardrail_result.error}. Please provide an improved response."
|
||||
response = self._chat_completion([{"role": "user", "content": retry_prompt}], temperature, tools)
|
||||
response = self._chat_completion([{"role": "user", "content": retry_prompt}], temperature, tools, task_name=task_name, task_description=task_description, task_id=task_id)
|
||||
if response and response.choices:
|
||||
current_response = response.choices[0].message.content.strip()
|
||||
else:
|
||||
@@ -1068,11 +1077,11 @@ 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
|
||||
)
|
||||
|
||||
def _chat_completion(self, messages, temperature=0.2, tools=None, stream=True, reasoning_steps=False):
|
||||
def _chat_completion(self, messages, temperature=0.2, tools=None, stream=True, reasoning_steps=False, task_name=None, task_description=None, task_id=None):
|
||||
start_time = time.time()
|
||||
logging.debug(f"{self.name} sending messages to LLM: {messages}")
|
||||
|
||||
@@ -1107,32 +1116,53 @@ 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
|
||||
def custom_display_fn(text, start_time):
|
||||
if self.verbose:
|
||||
return display_generating(text, start_time)
|
||||
return ""
|
||||
|
||||
# Note: openai_client expects tools in various formats and will format them internally
|
||||
# But since we already have formatted_tools, we can pass them directly
|
||||
if self._openai_client is None:
|
||||
@@ -1145,8 +1175,8 @@ Your Goal: {self.goal}"""
|
||||
tools=formatted_tools, # Already formatted for OpenAI
|
||||
execute_tool_fn=self.execute_tool,
|
||||
stream=stream,
|
||||
console=self.console if self.verbose else None,
|
||||
display_fn=display_generating if stream and self.verbose else None,
|
||||
console=self.console if (self.verbose or stream) else None,
|
||||
display_fn=self.display_generating if self.verbose else None,
|
||||
reasoning_steps=reasoning_steps,
|
||||
verbose=self.verbose,
|
||||
max_iterations=10
|
||||
@@ -1158,7 +1188,7 @@ Your Goal: {self.goal}"""
|
||||
display_error(f"Error in chat completion: {e}")
|
||||
return None
|
||||
|
||||
def _execute_callback_and_display(self, prompt: str, response: str, generation_time: float):
|
||||
def _execute_callback_and_display(self, prompt: str, response: str, generation_time: float, task_name=None, task_description=None, task_id=None):
|
||||
"""Helper method to execute callbacks and display interaction.
|
||||
|
||||
This centralizes the logic for callback execution and display to avoid duplication.
|
||||
@@ -1174,12 +1204,13 @@ Your Goal: {self.goal}"""
|
||||
agent_name=self.name,
|
||||
agent_role=self.role,
|
||||
agent_tools=[t.__name__ for t in self.tools] if self.tools else None,
|
||||
task_name=None, # Not available in this context
|
||||
task_description=None, # Not available in this context
|
||||
task_id=None # Not available in this context
|
||||
task_name=task_name,
|
||||
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,
|
||||
@@ -1188,8 +1219,36 @@ Your Goal: {self.goal}"""
|
||||
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 = {
|
||||
@@ -1207,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)
|
||||
@@ -1297,7 +1359,7 @@ Your Goal: {self.goal}"""
|
||||
|
||||
# Apply guardrail validation for custom LLM response
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, prompt, temperature, tools, 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}")
|
||||
@@ -1357,7 +1419,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)
|
||||
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]
|
||||
@@ -1372,9 +1434,9 @@ Your Goal: {self.goal}"""
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
# Apply guardrail validation even for JSON output
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_prompt, validated_response, time.time() - start_time)
|
||||
self._execute_callback_and_display(original_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 JSON output: {e}")
|
||||
@@ -1391,9 +1453,9 @@ Your Goal: {self.goal}"""
|
||||
if reasoning_steps and hasattr(response.choices[0].message, 'reasoning_content'):
|
||||
# Apply guardrail to reasoning content
|
||||
try:
|
||||
validated_reasoning = self._apply_guardrail_with_retry(response.choices[0].message.reasoning_content, original_prompt, temperature, tools)
|
||||
validated_reasoning = self._apply_guardrail_with_retry(response.choices[0].message.reasoning_content, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_prompt, validated_reasoning, time.time() - start_time)
|
||||
self._execute_callback_and_display(original_prompt, validated_reasoning, time.time() - start_time, task_name, task_description, task_id)
|
||||
return validated_reasoning
|
||||
except Exception as e:
|
||||
logging.error(f"Agent {self.name}: Guardrail validation failed for reasoning content: {e}")
|
||||
@@ -1402,9 +1464,9 @@ Your Goal: {self.goal}"""
|
||||
return None
|
||||
# Apply guardrail to regular response
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_prompt, validated_response, time.time() - start_time)
|
||||
self._execute_callback_and_display(original_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: {e}")
|
||||
@@ -1426,7 +1488,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
if self._using_custom_llm or self._openai_client is None:
|
||||
# For custom LLMs, we need to handle reflection differently
|
||||
# Use non-streaming to get complete JSON response
|
||||
reflection_response = self._chat_completion(messages, temperature=temperature, tools=None, stream=False, reasoning_steps=False)
|
||||
reflection_response = self._chat_completion(messages, temperature=temperature, tools=None, stream=False, reasoning_steps=False, task_name=task_name, task_description=task_description, task_id=task_id)
|
||||
|
||||
if not reflection_response or not reflection_response.choices:
|
||||
raise Exception("No response from reflection request")
|
||||
@@ -1470,9 +1532,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
# Apply guardrail validation after satisfactory reflection
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_prompt, validated_response, time.time() - start_time)
|
||||
self._execute_callback_and_display(original_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 after reflection: {e}")
|
||||
@@ -1488,9 +1550,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
self.chat_history.append({"role": "assistant", "content": response_text})
|
||||
# Apply guardrail validation after max reflections
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_prompt, validated_response, time.time() - start_time)
|
||||
self._execute_callback_and_display(original_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 after max reflections: {e}")
|
||||
@@ -1503,7 +1565,7 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
messages.append({"role": "user", "content": "Now regenerate your response using the reflection you made"})
|
||||
# For custom LLMs during reflection, always use non-streaming to ensure complete responses
|
||||
use_stream = self.stream if not self._using_custom_llm else False
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=None, stream=use_stream)
|
||||
response = self._chat_completion(messages, temperature=temperature, tools=None, stream=use_stream, task_name=task_name, task_description=task_description, task_id=task_id)
|
||||
response_text = response.choices[0].message.content.strip()
|
||||
reflection_count += 1
|
||||
continue # Continue the loop for more reflections
|
||||
@@ -1538,6 +1600,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 = {
|
||||
@@ -1620,7 +1685,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
# Apply guardrail validation for custom LLM response
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(normalized_content, 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}")
|
||||
@@ -1697,6 +1764,8 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
total_time = time.time() - start_time
|
||||
logging.debug(f"Agent.achat completed in {total_time:.2f} seconds")
|
||||
# Execute callback after tool completion
|
||||
self._execute_callback_and_display(original_prompt, result, time.time() - start_time, task_name, task_description, task_id)
|
||||
return result
|
||||
elif output_json or output_pydantic:
|
||||
response = await self._openai_client.async_client.chat.completions.create(
|
||||
@@ -1705,11 +1774,13 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
temperature=temperature,
|
||||
response_format={"type": "json_object"}
|
||||
)
|
||||
# Return the raw response
|
||||
response_text = response.choices[0].message.content
|
||||
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
|
||||
total_time = time.time() - start_time
|
||||
logging.debug(f"Agent.achat completed in {total_time:.2f} seconds")
|
||||
return response.choices[0].message.content
|
||||
# Execute callback after JSON/Pydantic completion
|
||||
self._execute_callback_and_display(original_prompt, response_text, time.time() - start_time, task_name, task_description, task_id)
|
||||
return response_text
|
||||
else:
|
||||
response = await self._openai_client.async_client.chat.completions.create(
|
||||
model=self.llm,
|
||||
@@ -1804,7 +1875,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
# Apply guardrail validation for OpenAI client response
|
||||
try:
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools)
|
||||
validated_response = self._apply_guardrail_with_retry(response_text, original_prompt, temperature, tools, task_name, task_description, task_id)
|
||||
# Execute callback after validation
|
||||
self._execute_callback_and_display(original_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 OpenAI client: {e}")
|
||||
@@ -1835,7 +1908,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)
|
||||
@@ -1877,25 +1955,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()
|
||||
|
||||
@@ -1924,7 +1993,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}")
|
||||
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
]
|
||||
Loaded 100 of 158 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user