mirror of
https://github.com/MervinPraison/PraisonAI.git
synced 2026-11-08 01:08:39 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
024eaed456 | ||
|
|
4fd3a572cf | ||
|
|
baaf8b6256 | ||
|
|
fe4550d2bc | ||
|
|
db09a94425 | ||
|
|
2db36dc932 | ||
|
|
8c0e4277a4 | ||
|
|
41448617d5 | ||
|
|
49ea23c676 | ||
|
|
bb0dc63680 | ||
|
|
7774f2c565 | ||
|
|
5533fd3476 | ||
|
|
262a90a235 | ||
|
|
60928dcb90 | ||
|
|
c8552e1158 | ||
|
|
c57d7db9bb | ||
|
|
236abc2c83 | ||
|
|
76c5f8fe3f | ||
|
|
82750020d2 | ||
|
|
f49ad9fbc2 | ||
|
|
c086c60fd6 | ||
|
|
4f8f4f2036 | ||
|
|
8e91c20967 | ||
|
|
6f092c1507 | ||
|
|
8f553d3a54 | ||
|
|
2d647e25b5 | ||
|
|
039bb772f5 | ||
|
|
459c2f2b70 | ||
|
|
ee59706357 | ||
|
|
2a51644773 | ||
|
|
cce908fa22 | ||
|
|
acf476f715 | ||
|
|
e5d77de79c | ||
|
|
9ab444b54c | ||
|
|
e13f543c6d | ||
|
|
4f235d358c | ||
|
|
b7847feb1e | ||
|
|
7ac730462c | ||
|
|
9cbc8d082d | ||
|
|
7fb0aed7ac | ||
|
|
206f0d01e7 | ||
|
|
e19a310314 | ||
|
|
1ea572689e | ||
|
|
96df649b05 | ||
|
|
5aed75837a | ||
|
|
9c8f68a05f | ||
|
|
9778a69c4d | ||
|
|
73c7994380 | ||
|
|
82b83ded41 | ||
|
|
fc80db32c2 | ||
|
|
3f115ca7ba | ||
|
|
a32d45e6da | ||
|
|
8823df26ff | ||
|
|
9c2126fbd6 | ||
|
|
741b01bdf0 | ||
|
|
6ed9a69cd8 | ||
|
|
56a42e6d95 | ||
|
|
d2b4affdd1 | ||
|
|
0d5c8b478f | ||
|
|
fdfad70319 | ||
|
|
fba6b2e2a0 | ||
|
|
f9bfb85f44 | ||
|
|
aab4b5b466 | ||
|
|
7ccadde004 | ||
|
|
22a9d5ff23 | ||
|
|
98a11209ea | ||
|
|
df3c97e73a | ||
|
|
27808964be | ||
|
|
b5daf16e0d | ||
|
|
a2cac05d16 |
No files matched your search
+1
-1
@@ -1,6 +1,6 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install flask praisonai==2.0.41 gunicorn markdown
|
||||
RUN pip install flask praisonai==2.0.55 gunicorn markdown
|
||||
EXPOSE 8080
|
||||
CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]
|
||||
@@ -0,0 +1,43 @@
|
||||
FROM mcr.microsoft.com/devcontainers/python:3.11
|
||||
|
||||
# Prevent apt from showing prompts
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git \
|
||||
curl \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Create a non-root user
|
||||
ARG USERNAME=vscode
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
# Create the user and group only if they don't exist
|
||||
RUN if ! getent group $USER_GID > /dev/null 2>&1; then \
|
||||
groupadd --gid $USER_GID $USERNAME; \
|
||||
fi && \
|
||||
if ! getent passwd $USER_UID > /dev/null 2>&1; then \
|
||||
useradd --uid $USER_UID --gid $USER_GID -m $USERNAME; \
|
||||
fi && \
|
||||
apt-get update && \
|
||||
apt-get install -y sudo && \
|
||||
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME && \
|
||||
chmod 0440 /etc/sudoers.d/$USERNAME
|
||||
|
||||
# Set Python environment variables
|
||||
ENV PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt /tmp/pip-tmp/
|
||||
RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
|
||||
&& rm -rf /tmp/pip-tmp
|
||||
|
||||
# Switch to non-root user
|
||||
USER $USERNAME
|
||||
|
||||
# Set the default shell to bash
|
||||
ENV SHELL=/bin/bash
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "PraisonAI Development",
|
||||
"dockerFile": "Dockerfile",
|
||||
"context": "..",
|
||||
"runArgs": [
|
||||
"--env-file",
|
||||
".env",
|
||||
"--network=host"
|
||||
],
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"ms-python.black-formatter",
|
||||
"ms-toolsai.jupyter",
|
||||
"yzhang.markdown-all-in-one",
|
||||
"streetsidesoftware.code-spell-checker"
|
||||
],
|
||||
"settings": {
|
||||
"python.defaultInterpreterPath": "/usr/local/bin/python",
|
||||
"python.linting.enabled": true,
|
||||
"python.formatting.provider": "black",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.rulers": [88],
|
||||
"files.trimTrailingWhitespace": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"remoteUser": "vscode",
|
||||
"updateRemoteUserUID": false,
|
||||
"forwardPorts": [],
|
||||
"appPort": ["56040:56040"],
|
||||
"overrideCommand": false,
|
||||
"init": true
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import time
|
||||
|
||||
def get_environment_state():
|
||||
"""Simulates getting current environment state"""
|
||||
current_time = int(time.time())
|
||||
states = ["normal", "critical", "optimal"]
|
||||
state = states[current_time % 3]
|
||||
print(f"Environment state: {state}")
|
||||
return state
|
||||
|
||||
def perform_action(state: str):
|
||||
"""Simulates performing an action based on state"""
|
||||
actions = {
|
||||
"normal": "maintain",
|
||||
"critical": "fix",
|
||||
"optimal": "enhance"
|
||||
}
|
||||
action = actions.get(state, "observe")
|
||||
print(f"Performing action: {action} for state: {state}")
|
||||
return action
|
||||
|
||||
def get_feedback():
|
||||
"""Simulates environment feedback"""
|
||||
current_time = int(time.time())
|
||||
feedback = "positive" if current_time % 2 == 0 else "negative"
|
||||
print(f"Feedback received: {feedback}")
|
||||
return feedback
|
||||
|
||||
# Create specialized agents
|
||||
llm_caller = Agent(
|
||||
name="Environment Monitor",
|
||||
role="State analyzer",
|
||||
goal="Monitor environment and analyze state",
|
||||
instructions="Check environment state and provide analysis",
|
||||
tools=[get_environment_state]
|
||||
)
|
||||
|
||||
action_agent = Agent(
|
||||
name="Action Executor",
|
||||
role="Action performer",
|
||||
goal="Execute appropriate actions based on state",
|
||||
instructions="Determine and perform actions based on environment state",
|
||||
tools=[perform_action]
|
||||
)
|
||||
|
||||
feedback_agent = Agent(
|
||||
name="Feedback Processor",
|
||||
role="Feedback analyzer",
|
||||
goal="Process environment feedback and adapt strategy",
|
||||
instructions="Analyze feedback and provide adaptation recommendations",
|
||||
tools=[get_feedback]
|
||||
)
|
||||
|
||||
# Create tasks for autonomous workflow
|
||||
monitor_task = Task(
|
||||
name="monitor_environment",
|
||||
description="Monitor and analyze environment state",
|
||||
expected_output="Current environment state analysis",
|
||||
agent=llm_caller,
|
||||
is_start=True,
|
||||
task_type="decision",
|
||||
next_tasks=["execute_action"],
|
||||
condition={
|
||||
"normal": ["execute_action"],
|
||||
"critical": ["execute_action"],
|
||||
"optimal": "exit"
|
||||
}
|
||||
)
|
||||
|
||||
action_task = Task(
|
||||
name="execute_action",
|
||||
description="Execute appropriate action based on state",
|
||||
expected_output="Action execution result",
|
||||
agent=action_agent,
|
||||
next_tasks=["process_feedback"]
|
||||
)
|
||||
|
||||
feedback_task = Task(
|
||||
name="process_feedback",
|
||||
description="Process feedback and adapt strategy",
|
||||
expected_output="Strategy adaptation based on feedback",
|
||||
agent=feedback_agent,
|
||||
next_tasks=["monitor_environment"], # Create feedback loop
|
||||
context=[monitor_task, action_task] # Access to previous states and actions
|
||||
)
|
||||
|
||||
# Create workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[llm_caller, action_agent, feedback_agent],
|
||||
tasks=[monitor_task, action_task, feedback_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
def main():
|
||||
print("\nStarting Autonomous Agent Workflow...")
|
||||
print("=" * 50)
|
||||
|
||||
# Run autonomous workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nAutonomous Agent Results:")
|
||||
print("=" * 50)
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
task_name = result.description
|
||||
print(f"\nTask: {task_name}")
|
||||
print(f"Result: {result.raw}")
|
||||
print("-" * 50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,14 @@
|
||||
from praisonaiagents.knowledge import Chunking
|
||||
|
||||
# No heavy imports or initialization happens here
|
||||
chunking = Chunking(chunker_type='token')
|
||||
|
||||
# Chunker is only initialized when first used
|
||||
chunks = chunking.chunk("Your text here")
|
||||
|
||||
# Embedding model is only loaded if using semantic chunking
|
||||
semantic_chunking = Chunking(chunker_type='recursive')
|
||||
# Embedding model and chunker are loaded here on first use
|
||||
semantic_chunks = semantic_chunking.chunk("Your text here")
|
||||
|
||||
print(semantic_chunks)
|
||||
@@ -0,0 +1,97 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
from gitingest import ingest
|
||||
|
||||
class CodeMetrics(BaseModel):
|
||||
category: str
|
||||
score: int
|
||||
findings: List[str]
|
||||
|
||||
class CodeAnalysisReport(BaseModel):
|
||||
overall_quality: int
|
||||
code_metrics: List[CodeMetrics]
|
||||
architecture_score: int
|
||||
maintainability_score: int
|
||||
performance_score: int
|
||||
security_score: int
|
||||
test_coverage: int
|
||||
key_strengths: List[str]
|
||||
improvement_areas: List[str]
|
||||
tech_stack: List[str]
|
||||
recommendations: List[str]
|
||||
complexity_metrics: Dict[str, int]
|
||||
best_practices: List[Dict[str, str]]
|
||||
potential_risks: List[str]
|
||||
documentation_quality: int
|
||||
|
||||
code_analyzer = Agent(
|
||||
role="Code Analysis Expert",
|
||||
goal="Provide comprehensive code evaluation and recommendations",
|
||||
backstory="""Expert code analyst specializing in architecture review,
|
||||
best practices, and technical debt assessment.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
code_analysis_task = Task(
|
||||
description="""Analyze code repository and provide structured evaluation:
|
||||
|
||||
1. Overall Quality (0-100)
|
||||
2. Core Metrics Analysis:
|
||||
- Architecture and Design
|
||||
- Code Maintainability
|
||||
- Performance Optimization
|
||||
- Security Practices
|
||||
- Test Coverage
|
||||
3. Technical Assessment:
|
||||
- Technology Stack Review
|
||||
- Code Complexity Analysis
|
||||
- Best Practices Adherence
|
||||
- Risk Assessment
|
||||
4. Recommendations:
|
||||
- Key Improvements
|
||||
- Architecture Suggestions
|
||||
- Security Enhancements""",
|
||||
expected_output="Detailed code analysis report with metrics and recommendations",
|
||||
agent=code_analyzer,
|
||||
output_pydantic=CodeAnalysisReport
|
||||
)
|
||||
|
||||
def analyze_code(code_source: str) -> CodeAnalysisReport:
|
||||
"""
|
||||
Analyze code from directory path or GitHub URL
|
||||
"""
|
||||
# Ingest code content
|
||||
summary, tree, content = ingest(code_source)
|
||||
|
||||
# Concatenate context into structured format
|
||||
context_text = f"""
|
||||
CODE REPOSITORY ANALYSIS
|
||||
=======================
|
||||
|
||||
SUMMARY
|
||||
-------
|
||||
{summary}
|
||||
|
||||
REPOSITORY STRUCTURE
|
||||
-------------------
|
||||
{tree}
|
||||
|
||||
SOURCE CODE
|
||||
-----------
|
||||
{content}
|
||||
"""
|
||||
|
||||
# Initialize and run analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[code_analyzer],
|
||||
tasks=[code_analysis_task]
|
||||
)
|
||||
|
||||
return agents.start(context_text)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
code_source = "https://github.com/openai/openai-python/tree/main/src/openai/cli/_api/chat" # GitHub URL or local directory
|
||||
result = analyze_code(code_source)
|
||||
print(result)
|
||||
@@ -0,0 +1,217 @@
|
||||
import streamlit as st
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict, Any
|
||||
from gitingest import ingest
|
||||
|
||||
# Import the same classes and code from code-analysis-agents.py
|
||||
class CodeMetrics(BaseModel):
|
||||
category: str
|
||||
score: int
|
||||
findings: List[str]
|
||||
|
||||
class CodeAnalysisReport(BaseModel):
|
||||
overall_quality: int
|
||||
code_metrics: List[CodeMetrics]
|
||||
architecture_score: int
|
||||
maintainability_score: int
|
||||
performance_score: int
|
||||
security_score: int
|
||||
test_coverage: int
|
||||
key_strengths: List[str]
|
||||
improvement_areas: List[str]
|
||||
tech_stack: List[str]
|
||||
recommendations: List[str]
|
||||
complexity_metrics: Dict[str, int]
|
||||
best_practices: List[Dict[str, str]]
|
||||
potential_risks: List[str]
|
||||
documentation_quality: int
|
||||
|
||||
def analyze_code(code_source: str) -> CodeAnalysisReport:
|
||||
"""
|
||||
Analyze code from directory path or GitHub URL
|
||||
"""
|
||||
# Create code analyzer agent
|
||||
code_analyzer = Agent(
|
||||
role="Code Analysis Expert",
|
||||
goal="Provide comprehensive code evaluation and recommendations",
|
||||
backstory="""Expert code analyst specializing in architecture review,
|
||||
best practices, and technical debt assessment.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Create analysis task
|
||||
code_analysis_task = Task(
|
||||
description="""Analyze code repository and provide structured evaluation:
|
||||
|
||||
1. Overall Quality (0-100)
|
||||
2. Core Metrics Analysis:
|
||||
- Architecture and Design
|
||||
- Code Maintainability
|
||||
- Performance Optimization
|
||||
- Security Practices
|
||||
- Test Coverage
|
||||
3. Technical Assessment:
|
||||
- Technology Stack Review
|
||||
- Code Complexity Analysis
|
||||
- Best Practices Adherence
|
||||
- Risk Assessment
|
||||
4. Recommendations:
|
||||
- Key Improvements
|
||||
- Architecture Suggestions
|
||||
- Security Enhancements""",
|
||||
expected_output="Detailed code analysis report with metrics and recommendations",
|
||||
agent=code_analyzer,
|
||||
output_pydantic=CodeAnalysisReport
|
||||
)
|
||||
|
||||
# Ingest code content
|
||||
summary, tree, content = ingest(code_source)
|
||||
|
||||
# Concatenate context into structured format
|
||||
context_text = f"""
|
||||
CODE REPOSITORY ANALYSIS
|
||||
=======================
|
||||
|
||||
SUMMARY
|
||||
-------
|
||||
{summary}
|
||||
|
||||
REPOSITORY STRUCTURE
|
||||
-------------------
|
||||
{tree}
|
||||
|
||||
SOURCE CODE
|
||||
-----------
|
||||
{content}
|
||||
"""
|
||||
|
||||
# Initialize and run analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[code_analyzer],
|
||||
tasks=[code_analysis_task]
|
||||
)
|
||||
|
||||
result = agents.start(context_text)
|
||||
|
||||
# Extract the Pydantic model from the result
|
||||
if isinstance(result, dict) and 'task_results' in result:
|
||||
# Get the first task result's pydantic output
|
||||
analysis_result = result['task_results'][0].pydantic
|
||||
if isinstance(analysis_result, CodeAnalysisReport):
|
||||
return analysis_result
|
||||
|
||||
# If we can't get the Pydantic model, create one from the raw data
|
||||
return CodeAnalysisReport(**result)
|
||||
|
||||
def display_code_metrics(metrics, cols):
|
||||
"""Display code metrics in columns with color-coded scores"""
|
||||
for i, metric in enumerate(metrics):
|
||||
score = metric.score
|
||||
color = "red" if score < 60 else "orange" if score < 75 else "green"
|
||||
|
||||
# Use modulo to alternate between columns
|
||||
with cols[i % len(cols)]:
|
||||
st.markdown(f"### {metric.category}")
|
||||
st.markdown(f"**Score:** :{color}[{score}%]")
|
||||
for finding in metric.findings:
|
||||
st.markdown(f"• {finding}")
|
||||
|
||||
def display_section(title: str, items: list, icon: str = "•"):
|
||||
"""Display a section with items in a consistent format"""
|
||||
st.markdown(f"### {title}")
|
||||
for item in items:
|
||||
if isinstance(item, dict):
|
||||
for key, value in item.items():
|
||||
st.markdown(f"{icon} **{key}**: {value}")
|
||||
else:
|
||||
st.markdown(f"{icon} {item}")
|
||||
|
||||
def main():
|
||||
st.set_page_config(
|
||||
page_title="Code Analysis Agent",
|
||||
layout="wide",
|
||||
initial_sidebar_state="expanded"
|
||||
)
|
||||
|
||||
st.title("Code Analysis Agent")
|
||||
|
||||
with st.sidebar:
|
||||
st.header("Input")
|
||||
code_source = st.text_input(
|
||||
"GitHub URL or Local Path",
|
||||
placeholder="https://github.com/username/repo or /path/to/directory"
|
||||
)
|
||||
analyze_button = st.button("Analyze Code", type="primary")
|
||||
|
||||
if analyze_button and code_source:
|
||||
try:
|
||||
with st.spinner("Analyzing code..."):
|
||||
result = analyze_code(code_source)
|
||||
|
||||
# Overall Metrics
|
||||
st.header("Overall Metrics")
|
||||
cols = st.columns(6)
|
||||
metrics = {
|
||||
"Overall Quality": result.overall_quality,
|
||||
"Architecture": result.architecture_score,
|
||||
"Maintainability": result.maintainability_score,
|
||||
"Performance": result.performance_score,
|
||||
"Security": result.security_score,
|
||||
"Test Coverage": result.test_coverage
|
||||
}
|
||||
|
||||
for (metric, value), col in zip(metrics.items(), cols):
|
||||
color = "red" if value < 60 else "orange" if value < 75 else "green"
|
||||
col.metric(metric, f"{value}%")
|
||||
col.markdown(f":{color}[{'●' * (value // 20)}]")
|
||||
|
||||
# Detailed Analysis
|
||||
st.header("Detailed Analysis")
|
||||
metric_cols = st.columns(2)
|
||||
display_code_metrics(result.code_metrics, metric_cols)
|
||||
|
||||
# Technology Stack
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.header("Technology Stack")
|
||||
for tech in result.tech_stack:
|
||||
st.markdown(f"🔧 {tech}")
|
||||
|
||||
with col2:
|
||||
st.header("Complexity Metrics")
|
||||
for metric, value in result.complexity_metrics.items():
|
||||
st.metric(metric.replace('_', ' ').title(), value)
|
||||
|
||||
# Key Findings
|
||||
st.header("Key Findings")
|
||||
cols = st.columns(2)
|
||||
|
||||
with cols[0]:
|
||||
display_section("✅ Strengths", result.key_strengths)
|
||||
display_section("🔄 Best Practices", result.best_practices)
|
||||
|
||||
with cols[1]:
|
||||
display_section("⚠️ Areas for Improvement", result.improvement_areas)
|
||||
display_section("❗ Potential Risks", result.potential_risks)
|
||||
|
||||
# Recommendations
|
||||
st.header("Recommendations")
|
||||
for i, rec in enumerate(result.recommendations, 1):
|
||||
st.markdown(f"**{i}.** {rec}")
|
||||
|
||||
# Documentation Quality
|
||||
st.header("Documentation")
|
||||
doc_score = result.documentation_quality
|
||||
color = "red" if doc_score < 60 else "orange" if doc_score < 75 else "green"
|
||||
st.markdown(f"Documentation Quality: :{color}[{doc_score}%]")
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error analyzing code: {str(e)}")
|
||||
st.exception(e)
|
||||
|
||||
elif analyze_button:
|
||||
st.warning("Please enter a GitHub URL or local path")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,108 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import time
|
||||
from typing import List, Dict
|
||||
|
||||
def analyze_code_changes():
|
||||
"""Simulates code analysis"""
|
||||
issues = [
|
||||
{"type": "style", "severity": "low", "file": "main.py"},
|
||||
{"type": "security", "severity": "high", "file": "auth.py"},
|
||||
{"type": "performance", "severity": "medium", "file": "data.py"}
|
||||
]
|
||||
return issues[int(time.time()) % 3]
|
||||
|
||||
def suggest_fixes(issue: Dict):
|
||||
"""Simulates fix suggestions"""
|
||||
fixes = {
|
||||
"style": "Apply PEP 8 formatting",
|
||||
"security": "Implement input validation",
|
||||
"performance": "Use list comprehension"
|
||||
}
|
||||
return fixes.get(issue["type"], "Review manually")
|
||||
|
||||
def apply_automated_fix(fix: str):
|
||||
"""Simulates applying automated fixes"""
|
||||
success = int(time.time()) % 2 == 0
|
||||
return "fixed" if success else "manual_review"
|
||||
|
||||
# Create specialized agents
|
||||
analyzer = Agent(
|
||||
name="Code Analyzer",
|
||||
role="Code analysis",
|
||||
goal="Analyze code changes and identify issues",
|
||||
instructions="Review code changes and report issues",
|
||||
tools=[analyze_code_changes]
|
||||
)
|
||||
|
||||
fix_suggester = Agent(
|
||||
name="Fix Suggester",
|
||||
role="Solution provider",
|
||||
goal="Suggest fixes for identified issues",
|
||||
instructions="Provide appropriate fix suggestions",
|
||||
tools=[suggest_fixes]
|
||||
)
|
||||
|
||||
fix_applier = Agent(
|
||||
name="Fix Applier",
|
||||
role="Fix implementation",
|
||||
goal="Apply suggested fixes automatically when possible",
|
||||
instructions="Implement suggested fixes and report results",
|
||||
tools=[apply_automated_fix]
|
||||
)
|
||||
|
||||
# Create workflow tasks
|
||||
analysis_task = Task(
|
||||
name="analyze_code",
|
||||
description="Analyze code changes for issues",
|
||||
expected_output="Identified code issues",
|
||||
agent=analyzer,
|
||||
is_start=True,
|
||||
next_tasks=["suggest_fixes"]
|
||||
)
|
||||
|
||||
suggestion_task = Task(
|
||||
name="suggest_fixes",
|
||||
description="Suggest fixes for identified issues",
|
||||
expected_output="Fix suggestions",
|
||||
agent=fix_suggester,
|
||||
next_tasks=["apply_fixes"]
|
||||
)
|
||||
|
||||
fix_task = Task(
|
||||
name="apply_fixes",
|
||||
description="Apply suggested fixes",
|
||||
expected_output="Fix application status",
|
||||
agent=fix_applier,
|
||||
task_type="decision",
|
||||
condition={
|
||||
"fixed": "",
|
||||
"manual_review": ["suggest_fixes"] # Loop back for manual review
|
||||
}
|
||||
)
|
||||
|
||||
# Create workflow
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[analyzer, fix_suggester, fix_applier],
|
||||
tasks=[analysis_task, suggestion_task, fix_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
def main():
|
||||
print("\nStarting Code Review Workflow...")
|
||||
print("=" * 50)
|
||||
|
||||
# Run workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nCode Review Results:")
|
||||
print("=" * 50)
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"\nTask: {task_id}")
|
||||
print(f"Result: {result.raw}")
|
||||
print("-" * 50)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,98 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
|
||||
class SkillMetrics(BaseModel):
|
||||
name: str
|
||||
score: int
|
||||
comments: str
|
||||
|
||||
class CVAnalysisReport(BaseModel):
|
||||
overall_score: int
|
||||
skill_metrics: List[SkillMetrics]
|
||||
experience_score: int
|
||||
education_score: int
|
||||
presentation_score: int
|
||||
achievement_impact_score: int
|
||||
market_readiness: int
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
market_fit: str
|
||||
recommendations: List[str]
|
||||
technical_skills: List[Dict[str, int]]
|
||||
soft_skills: List[Dict[str, int]]
|
||||
skill_gaps: List[str]
|
||||
key_achievements: List[str]
|
||||
impact_metrics: List[Dict[str, str]]
|
||||
areas_of_expertise: List[str]
|
||||
|
||||
# Create single CV analysis agent
|
||||
cv_analyzer = Agent(
|
||||
role="CV Analysis Expert",
|
||||
goal="Provide comprehensive CV evaluation and recommendations",
|
||||
backstory="""You are an expert CV analyst with deep knowledge of industry requirements,
|
||||
market trends, and talent assessment. You excel at evaluating skills, experience,
|
||||
and providing actionable recommendations.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Single comprehensive analysis task
|
||||
cv_analysis_task = Task(
|
||||
description="""Perform a detailed CV analysis with scoring metrics and provide output in the following format:
|
||||
|
||||
1. Overall Score (0-100):
|
||||
- Calculate based on weighted average of all metrics
|
||||
|
||||
2. Individual Skill Metrics:
|
||||
- For each major skill found in CV:
|
||||
* Name of skill
|
||||
* Score (0-100)
|
||||
* Specific feedback/comments
|
||||
|
||||
3. Core Metrics (0-100 each):
|
||||
- Experience Score: Based on relevance and years
|
||||
- Education Score: Based on relevance and level
|
||||
- Presentation Score: CV format, clarity, structure
|
||||
- Achievement Impact Score: Measurable results
|
||||
- Market Readiness: Current market fit
|
||||
|
||||
4. Technical Skills:
|
||||
- List each skill with proficiency score (0-100)
|
||||
- Example: {"Python": 85, "AWS": 70}
|
||||
|
||||
5. Soft Skills:
|
||||
- List each skill with proficiency score (0-100)
|
||||
- Example: {"Communication": 90, "Leadership": 75}
|
||||
|
||||
6. Detailed Analysis:
|
||||
- Key Strengths: Top 3-5 standout points
|
||||
- Areas for Improvement: 3-5 specific points
|
||||
- Market Fit: Current industry alignment
|
||||
- Skill Gaps: Missing critical skills for target role
|
||||
- Key Achievements: Quantifiable accomplishments
|
||||
- Impact Metrics: {"metric": "value"}
|
||||
- Areas of Expertise: Primary domains of expertise
|
||||
|
||||
7. Recommendations:
|
||||
- 3-5 actionable steps for improvement
|
||||
|
||||
Provide clear justification for all scores and ensure feedback is specific and actionable.""",
|
||||
expected_output="Structured CV analysis report with detailed metrics and scoring justification",
|
||||
agent=cv_analyzer,
|
||||
output_pydantic=CVAnalysisReport
|
||||
)
|
||||
|
||||
# Create and run the agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[cv_analyzer],
|
||||
tasks=[cv_analysis_task]
|
||||
)
|
||||
|
||||
# Read and pass CV content through start()
|
||||
with open('cv.txt', 'r') as file:
|
||||
cv_content = file.read()
|
||||
|
||||
# Start the analysis by passing CV content
|
||||
result = agents.start(cv_content)
|
||||
|
||||
print(result)
|
||||
@@ -0,0 +1,202 @@
|
||||
import streamlit as st
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
import json
|
||||
import asyncio
|
||||
import nest_asyncio
|
||||
from functools import partial
|
||||
|
||||
# Enable nested event loops
|
||||
nest_asyncio.apply()
|
||||
|
||||
class SkillMetrics(BaseModel):
|
||||
name: str
|
||||
score: int
|
||||
comments: str
|
||||
|
||||
class CVAnalysisReport(BaseModel):
|
||||
overall_score: int
|
||||
skill_metrics: List[SkillMetrics]
|
||||
experience_score: int
|
||||
education_score: int
|
||||
presentation_score: int
|
||||
achievement_impact_score: int
|
||||
market_readiness: int
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
market_fit: str
|
||||
recommendations: List[str]
|
||||
technical_skills: List[Dict[str, int]]
|
||||
soft_skills: List[Dict[str, int]]
|
||||
skill_gaps: List[str]
|
||||
key_achievements: List[str]
|
||||
impact_metrics: List[Dict[str, str]]
|
||||
areas_of_expertise: List[str]
|
||||
|
||||
async def analyze_cv_async(cv_content):
|
||||
cv_analyzer = Agent(
|
||||
role="CV Analysis Expert",
|
||||
goal="Provide comprehensive CV evaluation and recommendations",
|
||||
backstory="""You are an expert CV analyst with deep knowledge of industry requirements,
|
||||
market trends, and talent assessment. You excel at evaluating skills, experience,
|
||||
and providing actionable recommendations.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
cv_analysis_task = Task(
|
||||
description="""Perform a detailed CV analysis with scoring metrics and provide output in the following format:
|
||||
1. Overall Score (0-100):
|
||||
- Calculate based on weighted average of all metrics
|
||||
|
||||
2. Individual Skill Metrics:
|
||||
- For each major skill found in CV:
|
||||
* Name of skill
|
||||
* Score (0-100)
|
||||
* Specific feedback/comments
|
||||
|
||||
3. Core Metrics (0-100 each):
|
||||
- Experience Score: Based on relevance and years
|
||||
- Education Score: Based on relevance and level
|
||||
- Presentation Score: CV format, clarity, structure
|
||||
- Achievement Impact Score: Measurable results
|
||||
- Market Readiness: Current market fit
|
||||
|
||||
4. Technical Skills:
|
||||
- List each skill with proficiency score (0-100)
|
||||
|
||||
5. Soft Skills:
|
||||
- List each skill with proficiency score (0-100)
|
||||
|
||||
6. Detailed Analysis sections
|
||||
|
||||
7. Recommendations:
|
||||
- 3-5 actionable steps for improvement""",
|
||||
expected_output="Structured CV analysis report with detailed metrics and scoring justification",
|
||||
agent=cv_analyzer,
|
||||
output_pydantic=CVAnalysisReport
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[cv_analyzer],
|
||||
tasks=[cv_analysis_task]
|
||||
)
|
||||
|
||||
try:
|
||||
result = await agents.astart(cv_content)
|
||||
return result['task_results'][0].pydantic
|
||||
except Exception as e:
|
||||
print(f"Error during analysis: {str(e)}")
|
||||
raise e
|
||||
|
||||
def analyze_cv(cv_content):
|
||||
async def run_analysis():
|
||||
return await analyze_cv_async(cv_content)
|
||||
|
||||
try:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
result = loop.run_until_complete(run_analysis())
|
||||
return result
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
def main():
|
||||
st.set_page_config(page_title="CV Analyzer", layout="wide")
|
||||
st.title("Professional CV Analyzer")
|
||||
|
||||
# File upload
|
||||
cv_file = st.file_uploader("Upload your CV (TXT format)", type=['txt'])
|
||||
|
||||
if cv_file:
|
||||
cv_content = cv_file.read().decode()
|
||||
|
||||
with st.spinner('Analyzing your CV...'):
|
||||
try:
|
||||
analysis = analyze_cv(cv_content)
|
||||
|
||||
# Display Overall Score
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.metric("Overall Score", f"{analysis.overall_score}/100")
|
||||
with col2:
|
||||
st.metric("Market Readiness", f"{analysis.market_readiness}/100")
|
||||
with col3:
|
||||
st.metric("Experience Score", f"{analysis.experience_score}/100")
|
||||
|
||||
# Core Metrics
|
||||
st.subheader("Core Metrics")
|
||||
metrics_cols = st.columns(4)
|
||||
with metrics_cols[0]:
|
||||
st.metric("Education", f"{analysis.education_score}/100")
|
||||
with metrics_cols[1]:
|
||||
st.metric("Presentation", f"{analysis.presentation_score}/100")
|
||||
with metrics_cols[2]:
|
||||
st.metric("Achievement Impact", f"{analysis.achievement_impact_score}/100")
|
||||
with metrics_cols[3]:
|
||||
st.metric("Market Readiness", f"{analysis.market_readiness}/100")
|
||||
|
||||
# Skill Metrics
|
||||
st.subheader("Detailed Skill Analysis")
|
||||
for skill in analysis.skill_metrics:
|
||||
with st.expander(f"{skill.name} - Score: {skill.score}/100"):
|
||||
st.write(skill.comments)
|
||||
|
||||
# Technical and Soft Skills
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.subheader("Technical Skills")
|
||||
for skill in analysis.technical_skills:
|
||||
for skill_name, score in skill.items():
|
||||
st.progress(score/100)
|
||||
st.caption(f"{skill_name}: {score}/100")
|
||||
|
||||
with col2:
|
||||
st.subheader("Soft Skills")
|
||||
for skill in analysis.soft_skills:
|
||||
for skill_name, score in skill.items():
|
||||
st.progress(score/100)
|
||||
st.caption(f"{skill_name}: {score}/100")
|
||||
|
||||
# Key Information
|
||||
st.subheader("Key Analysis")
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.write("🎯 Key Strengths")
|
||||
for strength in analysis.key_strengths:
|
||||
st.write(f"• {strength}")
|
||||
|
||||
st.write("🎮 Areas of Expertise")
|
||||
for expertise in analysis.areas_of_expertise:
|
||||
st.write(f"• {expertise}")
|
||||
|
||||
with col2:
|
||||
st.write("🔄 Areas for Improvement")
|
||||
for area in analysis.areas_for_improvement:
|
||||
st.write(f"• {area}")
|
||||
|
||||
st.write("⚠️ Skill Gaps")
|
||||
for gap in analysis.skill_gaps:
|
||||
st.write(f"• {gap}")
|
||||
|
||||
# Impact Metrics
|
||||
st.subheader("Impact Metrics")
|
||||
for metric in analysis.impact_metrics:
|
||||
for key, value in metric.items():
|
||||
st.metric(key, value)
|
||||
|
||||
# Recommendations
|
||||
st.subheader("📋 Recommendations")
|
||||
for rec in analysis.recommendations:
|
||||
st.write(f"• {rec}")
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred during analysis: {str(e)}")
|
||||
|
||||
else:
|
||||
st.info("Please upload your CV in TXT format to begin the analysis")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,61 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
|
||||
class CVAnalysisReport(BaseModel):
|
||||
overall_score: int
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
market_fit: str
|
||||
recommendations: List[str]
|
||||
technical_skills: List[str]
|
||||
soft_skills: List[str]
|
||||
skill_gaps: List[str]
|
||||
key_achievements: List[str]
|
||||
impact_metrics: List[Dict[str, str]]
|
||||
areas_of_expertise: List[str]
|
||||
|
||||
# Create single CV analysis agent
|
||||
cv_analyzer = Agent(
|
||||
role="CV Analysis Expert",
|
||||
goal="Provide comprehensive CV evaluation and recommendations",
|
||||
backstory="""You are an expert CV analyst with deep knowledge of industry requirements,
|
||||
market trends, and talent assessment. You excel at evaluating skills, experience,
|
||||
and providing actionable recommendations.""",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Read CV content first
|
||||
with open('cv.txt', 'r') as file:
|
||||
cv_content = file.read()
|
||||
|
||||
cv_key_strengths = Task(
|
||||
description="List the key strengths to look",
|
||||
expected_output="List of key strengths",
|
||||
agent=cv_analyzer,
|
||||
)
|
||||
|
||||
# Single comprehensive analysis task with CV content in context
|
||||
cv_analysis_task = Task(
|
||||
description="""Analyze the CV comprehensively including:
|
||||
1. Technical and soft skills assessment
|
||||
2. Experience and achievements evaluation
|
||||
3. Overall CV evaluation with recommendations
|
||||
Provide detailed insights and actionable recommendations.""",
|
||||
expected_output="Complete CV analysis report",
|
||||
agent=cv_analyzer,
|
||||
output_pydantic=CVAnalysisReport,
|
||||
context=[cv_content, cv_key_strengths] # Pass CV content directly in task context
|
||||
)
|
||||
|
||||
# Create and run the agent
|
||||
agents = PraisonAIAgents(
|
||||
agents=[cv_analyzer],
|
||||
tasks=[cv_key_strengths,cv_analysis_task],
|
||||
process="sequential"
|
||||
)
|
||||
|
||||
# Start the analysis - no need to pass content again since it's in task context
|
||||
result = agents.start()
|
||||
|
||||
print(result)
|
||||
@@ -0,0 +1,27 @@
|
||||
# example tools.py
|
||||
from duckduckgo_search import DDGS
|
||||
from praisonai_tools import BaseTool
|
||||
|
||||
class InternetSearchTool(BaseTool):
|
||||
name: str = "InternetSearchTool"
|
||||
description: str = "Search Internet for relevant information based on a query or latest news"
|
||||
|
||||
def _run(self, query: str):
|
||||
ddgs = DDGS()
|
||||
results = ddgs.text(keywords=query, region='wt-wt', safesearch='moderate', max_results=5)
|
||||
return results
|
||||
|
||||
# Example agent
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents import PraisonAIAgents
|
||||
agent = Agent(
|
||||
name="Internet Search Agent",
|
||||
tools=[InternetSearchTool],
|
||||
instructions="""
|
||||
You are an agent that can search the internet for relevant information based on a query or latest news.
|
||||
"""
|
||||
)
|
||||
|
||||
# Run the agent
|
||||
result = PraisonAIAgents(agents=[agent], verbose=10).start()
|
||||
print(result)
|
||||
@@ -0,0 +1,57 @@
|
||||
Name: Alex Johnson
|
||||
Location: London, UK
|
||||
|
||||
Professional Summary
|
||||
Dynamic and results-oriented leader with a proven track record of driving innovation, scaling operations, and achieving transformational growth. Over 15 years of experience in engineering, strategic management, and executive leadership in the automotive and renewable energy sectors. Passionate about sustainable technologies and visionary leadership.
|
||||
|
||||
Professional Experience
|
||||
Chief Operating Officer (COO)
|
||||
NextGen Mobility Ltd. | Palo Alto, CA | 2020 – Present
|
||||
|
||||
Spearheaded global operations for an electric vehicle company, scaling production by 200% in three years.
|
||||
Introduced automation-driven supply chain strategies, reducing costs by 15%.
|
||||
Collaborated with R&D to launch three new EV models, driving 25% revenue growth annually.
|
||||
Vice President of Engineering
|
||||
ElectroDrive Systems | San Francisco, CA | 2015 – 2020
|
||||
|
||||
Led a team of 500+ engineers in developing next-generation EV batteries, achieving a 30% increase in energy efficiency.
|
||||
Secured $50M in government funding for sustainable energy innovation.
|
||||
Drove cross-functional collaboration, aligning product development with market needs.
|
||||
Director of Renewable Energy Initiatives
|
||||
GreenTech Innovations | London, UK | 2011 – 2015
|
||||
|
||||
Oversaw £100M projects in solar and wind energy deployment across Europe.
|
||||
Established partnerships with policymakers to influence renewable energy legislation.
|
||||
Pioneered a smart energy grid system, enhancing energy distribution efficiency by 40%.
|
||||
Senior Project Manager
|
||||
Innovate Auto Ltd. | Munich, Germany | 2008 – 2011
|
||||
|
||||
Managed R&D projects for autonomous driving technologies.
|
||||
Delivered projects 20% under budget through strategic resource allocation.
|
||||
Filed 10+ patents in automotive AI and renewable integration.
|
||||
Mechanical Engineer
|
||||
AutoFusion Technologies | Berlin, Germany | 2005 – 2008
|
||||
|
||||
Designed core systems for EV powertrains, optimising energy consumption by 15%.
|
||||
Collaborated with suppliers to improve material efficiency, cutting costs by £5M annually.
|
||||
Education
|
||||
MBA in Strategic Management
|
||||
Harvard Business School | Cambridge, MA | 2015
|
||||
|
||||
MSc in Renewable Energy Engineering
|
||||
Imperial College London | London, UK | 2007
|
||||
|
||||
BSc in Mechanical Engineering
|
||||
Technical University of Munich | Munich, Germany | 2005
|
||||
|
||||
Skills
|
||||
Strategic Leadership & Visionary Thinking
|
||||
Electric Vehicle Engineering
|
||||
Renewable Energy Systems
|
||||
Global Operations Management
|
||||
Policy Advocacy & Government Relations
|
||||
Supply Chain Optimisation
|
||||
Achievements
|
||||
Featured in Forbes 30 Under 40 for innovations in EV technology.
|
||||
Author of The Future of Sustainable Mobility.
|
||||
Keynote speaker at World Energy Summit, 2023.
|
||||
@@ -0,0 +1,10 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table
|
||||
import os
|
||||
|
||||
agent = Agent(instructions="You are a Data Analyst Agent", tools=[read_csv, read_excel, write_csv, write_excel, filter_data, get_summary, group_by, pivot_table])
|
||||
agent.start(f"""
|
||||
Read the data from the csv file {os.path.join(os.path.dirname(__file__), "tesla-stock-price.csv")}
|
||||
Analyse the data and give me the insights
|
||||
read_csv to read the file
|
||||
""")
|
||||
@@ -0,0 +1,39 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent
|
||||
rag_agent = Agent(
|
||||
name="RAG Agent",
|
||||
role="Information Specialist",
|
||||
goal="Retrieve knowledge efficiently",
|
||||
llm="deepseek-r1"
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
rag_task = Task(
|
||||
name="RAG Task",
|
||||
description="What is KAG?",
|
||||
expected_output="Answer to the question",
|
||||
agent=rag_agent,
|
||||
context=[config] # Vector Database provided as context
|
||||
)
|
||||
|
||||
# Build Agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[rag_agent],
|
||||
tasks=[rag_task],
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start Agents
|
||||
agents.start()
|
||||
@@ -0,0 +1,3 @@
|
||||
I am Mervin Praison, a software engineer and entrepreneur.
|
||||
|
||||
I am the founder of Praison AI, a company that is building AI agents to help people with their daily tasks.
|
||||
@@ -0,0 +1,70 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create generator and evaluator agents
|
||||
generator = Agent(
|
||||
name="Generator",
|
||||
role="Solution generator",
|
||||
goal="Generate initial solutions and incorporate feedback",
|
||||
instructions=(
|
||||
"1. Look at the context from previous tasks.\n"
|
||||
"2. If you see that you have already produced 2 points, then add another 2 new points "
|
||||
" so that the total becomes 10.\n"
|
||||
"3. Otherwise, just produce the first 2 points.\n"
|
||||
"4. Return only the final list of points, with no extra explanation."
|
||||
)
|
||||
)
|
||||
|
||||
evaluator = Agent(
|
||||
name="Evaluator",
|
||||
role="Solution evaluator",
|
||||
goal="Evaluate solutions and provide improvement feedback",
|
||||
instructions=(
|
||||
"1. Count how many lines in the response start with a number and a period (like '1. ' or '2. ').\n"
|
||||
"2. If there are 10 or more, respond with 'done'.\n"
|
||||
"3. Otherwise, respond with 'more'.\n"
|
||||
"4. Return only the single word: 'done' or 'more'."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# Create tasks for the feedback loop
|
||||
generate_task = Task(
|
||||
name="generate",
|
||||
description="Write 2 points about AI incuding if anything exiting from previous points",
|
||||
expected_output="2 points",
|
||||
agent=generator,
|
||||
is_start=True,
|
||||
task_type="decision",
|
||||
next_tasks=["evaluate"]
|
||||
)
|
||||
|
||||
evaluate_task = Task(
|
||||
name="evaluate",
|
||||
description="Check if there are 10 points about AI",
|
||||
expected_output="more or done",
|
||||
agent=evaluator,
|
||||
next_tasks=["generate"],
|
||||
context=[generate_task],
|
||||
task_type="decision",
|
||||
condition={
|
||||
"more": ["generate"], # Continue to generate
|
||||
"done": [""] # Exit when optimization complete
|
||||
}
|
||||
)
|
||||
|
||||
# Create workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[generator, evaluator],
|
||||
tasks=[generate_task, evaluate_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Run optimization workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nEvaluator-Optimizer Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
|
||||
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[get_stock_price, get_stock_info, get_historical_data])
|
||||
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
|
||||
@@ -0,0 +1,34 @@
|
||||
import gradio as gr
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
def research(query):
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
|
||||
result = agent.start(query)
|
||||
# Format the result with enhanced markdown
|
||||
formatted_result = f"""
|
||||
{result}
|
||||
----
|
||||
*Generated by PraisonAI Research Assistant*
|
||||
"""
|
||||
return formatted_result
|
||||
|
||||
# Create a simple Gradio interface
|
||||
demo = gr.Interface(
|
||||
fn=research,
|
||||
inputs=gr.Textbox(
|
||||
label="Research Query",
|
||||
placeholder="Enter your research topic...",
|
||||
lines=2
|
||||
),
|
||||
outputs=gr.Markdown(
|
||||
show_copy_button=True,
|
||||
height=500,
|
||||
container=True
|
||||
),
|
||||
title="AI Research Assistant",
|
||||
description="Enter your research query below to get started!",
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
demo.launch()
|
||||
Whitespace-only changes.
@@ -0,0 +1,159 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
import os
|
||||
import json
|
||||
|
||||
class ProjectEvaluation(BaseModel):
|
||||
innovation_score: int # 0-100
|
||||
technical_complexity: int # 0-100
|
||||
presentation_quality: int # 0-100
|
||||
user_experience: int # 0-100
|
||||
completeness: int # 0-100
|
||||
overall_score: int # 0-100
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
notable_features: List[str]
|
||||
technical_highlights: List[str]
|
||||
recommendations: List[str]
|
||||
market_potential: str
|
||||
scalability_assessment: str
|
||||
|
||||
# Create Vision Analysis Agent
|
||||
hackathon_judge = Agent(
|
||||
name="HackathonJudge",
|
||||
role="Technical Project Evaluator",
|
||||
goal="Evaluate hackathon projects through video demonstrations",
|
||||
backstory="""You are an experienced hackathon judge and technical expert.
|
||||
You excel at evaluating innovation, technical implementation, and presentation quality.
|
||||
You provide constructive feedback and identify both strengths and areas for improvement.""",
|
||||
llm="gpt-4o-mini", # Using vision-capable model
|
||||
self_reflect=False,
|
||||
knowledge=""
|
||||
)
|
||||
|
||||
def evaluate_project(video_path: str) -> ProjectEvaluation:
|
||||
"""
|
||||
Evaluate a hackathon project based on its video demonstration
|
||||
"""
|
||||
evaluation_task = Task(
|
||||
name="project_evaluation",
|
||||
description="""Analyze this hackathon project video demonstration and provide a comprehensive evaluation:
|
||||
|
||||
1. Score the following aspects (0-100):
|
||||
- Innovation and Creativity
|
||||
- Technical Complexity
|
||||
- Presentation Quality
|
||||
- User Experience
|
||||
- Project Completeness
|
||||
|
||||
2. Identify:
|
||||
- Key strengths and standout features
|
||||
- Areas that could be improved
|
||||
- Notable technical implementations
|
||||
- Market potential and scalability
|
||||
|
||||
3. Provide:
|
||||
- Specific recommendations for improvement
|
||||
- Technical suggestions
|
||||
- Potential future enhancements""",
|
||||
expected_output="Detailed project evaluation with scores and feedback",
|
||||
agent=hackathon_judge,
|
||||
output_pydantic=ProjectEvaluation,
|
||||
images=[video_path] # Video input for multimodal analysis
|
||||
)
|
||||
|
||||
# Initialize and run evaluation
|
||||
agents = PraisonAIAgents(
|
||||
agents=[hackathon_judge],
|
||||
tasks=[evaluation_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
response = agents.start()
|
||||
|
||||
try:
|
||||
# If response contains task_results, extract the Pydantic model directly
|
||||
if isinstance(response, dict) and 'task_results' in response:
|
||||
task_output = response['task_results'][0]
|
||||
if hasattr(task_output, 'pydantic'):
|
||||
return task_output.pydantic
|
||||
elif hasattr(task_output, 'raw'):
|
||||
# Extract JSON from raw string if it's wrapped in ```json
|
||||
raw_text = task_output.raw
|
||||
if raw_text.startswith('```json'):
|
||||
raw_text = raw_text.split('\n', 1)[1].rsplit('\n', 1)[0]
|
||||
evaluation_data = json.loads(raw_text)
|
||||
else:
|
||||
evaluation_data = json.loads(task_output) if isinstance(task_output, str) else task_output
|
||||
# If response is a string, try to parse it as JSON
|
||||
elif isinstance(response, str):
|
||||
evaluation_data = json.loads(response)
|
||||
# If response is a dict with task_status
|
||||
elif isinstance(response, dict) and 'task_status' in response:
|
||||
content = response['task_status']
|
||||
if isinstance(content, dict):
|
||||
evaluation_data = content
|
||||
else:
|
||||
evaluation_data = json.loads(content) if isinstance(content, str) else content
|
||||
else:
|
||||
evaluation_data = response
|
||||
|
||||
print(f"Debug - Parsed evaluation_data: {evaluation_data}")
|
||||
|
||||
# Create and return ProjectEvaluation instance
|
||||
return ProjectEvaluation(
|
||||
innovation_score=int(evaluation_data.get('innovation_score', 0)),
|
||||
technical_complexity=int(evaluation_data.get('technical_complexity', 0)),
|
||||
presentation_quality=int(evaluation_data.get('presentation_quality', 0)),
|
||||
user_experience=int(evaluation_data.get('user_experience', 0)),
|
||||
completeness=int(evaluation_data.get('completeness', 0)),
|
||||
overall_score=int(evaluation_data.get('overall_score', 0)),
|
||||
key_strengths=evaluation_data.get('key_strengths', []),
|
||||
areas_for_improvement=evaluation_data.get('areas_for_improvement', []),
|
||||
notable_features=evaluation_data.get('notable_features', []),
|
||||
technical_highlights=evaluation_data.get('technical_highlights', []),
|
||||
recommendations=evaluation_data.get('recommendations', []),
|
||||
market_potential=str(evaluation_data.get('market_potential', '')),
|
||||
scalability_assessment=str(evaluation_data.get('scalability_assessment', ''))
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Debug - Raw response: {response}")
|
||||
print(f"Error processing response: {e}")
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
video_path = os.path.join(current_dir, "presentation.mp4")
|
||||
result = evaluate_project(video_path) # Now returns ProjectEvaluation directly
|
||||
|
||||
print("\nHackathon Project Evaluation")
|
||||
print("===========================")
|
||||
print(f"\nOverall Score: {result.overall_score}/100")
|
||||
print("\nDetailed Scores:")
|
||||
print(f"Innovation: {result.innovation_score}/100")
|
||||
print(f"Technical Complexity: {result.technical_complexity}/100")
|
||||
print(f"Presentation: {result.presentation_quality}/100")
|
||||
print(f"User Experience: {result.user_experience}/100")
|
||||
print(f"Completeness: {result.completeness}/100")
|
||||
|
||||
print("\nKey Strengths:")
|
||||
for strength in result.key_strengths:
|
||||
print(f"- {strength}")
|
||||
|
||||
print("\nAreas for Improvement:")
|
||||
for area in result.areas_for_improvement:
|
||||
print(f"- {area}")
|
||||
|
||||
print("\nTechnical Highlights:")
|
||||
for highlight in result.technical_highlights:
|
||||
print(f"- {highlight}")
|
||||
|
||||
print("\nRecommendations:")
|
||||
for rec in result.recommendations:
|
||||
print(f"- {rec}")
|
||||
|
||||
print(f"\nMarket Potential: {result.market_potential}")
|
||||
print(f"\nScalability Assessment: {result.scalability_assessment}")
|
||||
@@ -0,0 +1,159 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
import os
|
||||
import json
|
||||
|
||||
class ProjectEvaluation(BaseModel):
|
||||
innovation_score: int # 0-100
|
||||
technical_complexity: int # 0-100
|
||||
presentation_quality: int # 0-100
|
||||
user_experience: int # 0-100
|
||||
completeness: int # 0-100
|
||||
overall_score: int # 0-100
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
notable_features: List[str]
|
||||
technical_highlights: List[str]
|
||||
recommendations: List[str]
|
||||
market_potential: str
|
||||
scalability_assessment: str
|
||||
|
||||
# Create Vision Analysis Agent
|
||||
hackathon_judge = Agent(
|
||||
name="HackathonJudge",
|
||||
role="Technical Project Evaluator",
|
||||
goal="Evaluate hackathon projects through video demonstrations",
|
||||
backstory="""You are an experienced hackathon judge and technical expert.
|
||||
You excel at evaluating innovation, technical implementation, and presentation quality.
|
||||
You provide constructive feedback and identify both strengths and areas for improvement.""",
|
||||
llm="gpt-4o-mini", # Using vision-capable model
|
||||
self_reflect=False,
|
||||
knowledge=""
|
||||
)
|
||||
|
||||
def evaluate_project(video_path: str) -> ProjectEvaluation:
|
||||
"""
|
||||
Evaluate a hackathon project based on its video demonstration
|
||||
"""
|
||||
evaluation_task = Task(
|
||||
name="project_evaluation",
|
||||
description="""Analyze this hackathon project video demonstration and provide a comprehensive evaluation:
|
||||
|
||||
1. Score the following aspects (0-100):
|
||||
- Innovation and Creativity
|
||||
- Technical Complexity
|
||||
- Presentation Quality
|
||||
- User Experience
|
||||
- Project Completeness
|
||||
|
||||
2. Identify:
|
||||
- Key strengths and standout features
|
||||
- Areas that could be improved
|
||||
- Notable technical implementations
|
||||
- Market potential and scalability
|
||||
|
||||
3. Provide:
|
||||
- Specific recommendations for improvement
|
||||
- Technical suggestions
|
||||
- Potential future enhancements""",
|
||||
expected_output="Detailed project evaluation with scores and feedback",
|
||||
agent=hackathon_judge,
|
||||
output_pydantic=ProjectEvaluation,
|
||||
images=[video_path] # Video input for multimodal analysis
|
||||
)
|
||||
|
||||
# Initialize and run evaluation
|
||||
agents = PraisonAIAgents(
|
||||
agents=[hackathon_judge],
|
||||
tasks=[evaluation_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
response = agents.start()
|
||||
|
||||
try:
|
||||
# If response contains task_results, extract the Pydantic model directly
|
||||
if isinstance(response, dict) and 'task_results' in response:
|
||||
task_output = response['task_results'][0]
|
||||
if hasattr(task_output, 'pydantic'):
|
||||
return task_output.pydantic
|
||||
elif hasattr(task_output, 'raw'):
|
||||
# Extract JSON from raw string if it's wrapped in ```json
|
||||
raw_text = task_output.raw
|
||||
if raw_text.startswith('```json'):
|
||||
raw_text = raw_text.split('\n', 1)[1].rsplit('\n', 1)[0]
|
||||
evaluation_data = json.loads(raw_text)
|
||||
else:
|
||||
evaluation_data = json.loads(task_output) if isinstance(task_output, str) else task_output
|
||||
# If response is a string, try to parse it as JSON
|
||||
elif isinstance(response, str):
|
||||
evaluation_data = json.loads(response)
|
||||
# If response is a dict with task_status
|
||||
elif isinstance(response, dict) and 'task_status' in response:
|
||||
content = response['task_status']
|
||||
if isinstance(content, dict):
|
||||
evaluation_data = content
|
||||
else:
|
||||
evaluation_data = json.loads(content) if isinstance(content, str) else content
|
||||
else:
|
||||
evaluation_data = response
|
||||
|
||||
print(f"Debug - Parsed evaluation_data: {evaluation_data}")
|
||||
|
||||
# Create and return ProjectEvaluation instance
|
||||
return ProjectEvaluation(
|
||||
innovation_score=int(evaluation_data.get('innovation_score', 0)),
|
||||
technical_complexity=int(evaluation_data.get('technical_complexity', 0)),
|
||||
presentation_quality=int(evaluation_data.get('presentation_quality', 0)),
|
||||
user_experience=int(evaluation_data.get('user_experience', 0)),
|
||||
completeness=int(evaluation_data.get('completeness', 0)),
|
||||
overall_score=int(evaluation_data.get('overall_score', 0)),
|
||||
key_strengths=evaluation_data.get('key_strengths', []),
|
||||
areas_for_improvement=evaluation_data.get('areas_for_improvement', []),
|
||||
notable_features=evaluation_data.get('notable_features', []),
|
||||
technical_highlights=evaluation_data.get('technical_highlights', []),
|
||||
recommendations=evaluation_data.get('recommendations', []),
|
||||
market_potential=str(evaluation_data.get('market_potential', '')),
|
||||
scalability_assessment=str(evaluation_data.get('scalability_assessment', ''))
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Debug - Raw response: {response}")
|
||||
print(f"Error processing response: {e}")
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Example usage
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
video_path = os.path.join(current_dir, "presentation.mp4")
|
||||
result = evaluate_project(video_path) # Now returns ProjectEvaluation directly
|
||||
|
||||
print("\nHackathon Project Evaluation")
|
||||
print("===========================")
|
||||
print(f"\nOverall Score: {result.overall_score}/100")
|
||||
print("\nDetailed Scores:")
|
||||
print(f"Innovation: {result.innovation_score}/100")
|
||||
print(f"Technical Complexity: {result.technical_complexity}/100")
|
||||
print(f"Presentation: {result.presentation_quality}/100")
|
||||
print(f"User Experience: {result.user_experience}/100")
|
||||
print(f"Completeness: {result.completeness}/100")
|
||||
|
||||
print("\nKey Strengths:")
|
||||
for strength in result.key_strengths:
|
||||
print(f"- {strength}")
|
||||
|
||||
print("\nAreas for Improvement:")
|
||||
for area in result.areas_for_improvement:
|
||||
print(f"- {area}")
|
||||
|
||||
print("\nTechnical Highlights:")
|
||||
for highlight in result.technical_highlights:
|
||||
print(f"- {highlight}")
|
||||
|
||||
print("\nRecommendations:")
|
||||
for rec in result.recommendations:
|
||||
print(f"- {rec}")
|
||||
|
||||
print(f"\nMarket Potential: {result.market_potential}")
|
||||
print(f"\nScalability Assessment: {result.scalability_assessment}")
|
||||
@@ -0,0 +1,210 @@
|
||||
import streamlit as st
|
||||
import os
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Dict
|
||||
import tempfile
|
||||
import json
|
||||
|
||||
class ProjectEvaluation(BaseModel):
|
||||
innovation_score: int # 0-100
|
||||
technical_complexity: int # 0-100
|
||||
presentation_quality: int # 0-100
|
||||
user_experience: int # 0-100
|
||||
completeness: int # 0-100
|
||||
overall_score: int # 0-100
|
||||
key_strengths: List[str]
|
||||
areas_for_improvement: List[str]
|
||||
notable_features: List[str]
|
||||
technical_highlights: List[str]
|
||||
recommendations: List[str]
|
||||
market_potential: str
|
||||
scalability_assessment: str
|
||||
|
||||
# Set page config
|
||||
st.set_page_config(
|
||||
page_title="Hackathon Project Evaluator",
|
||||
page_icon="🏆",
|
||||
layout="wide"
|
||||
)
|
||||
|
||||
# Create Vision Analysis Agent
|
||||
@st.cache_resource
|
||||
def get_hackathon_judge():
|
||||
return Agent(
|
||||
name="HackathonJudge",
|
||||
role="Technical Project Evaluator",
|
||||
goal="Evaluate hackathon projects through video demonstrations",
|
||||
backstory="""You are an experienced hackathon judge and technical expert.
|
||||
You excel at evaluating innovation, technical implementation, and presentation quality.
|
||||
You provide constructive feedback and identify both strengths and areas for improvement.""",
|
||||
llm="gpt-4o-mini", # Using vision-capable model
|
||||
self_reflect=False,
|
||||
knowledge=""
|
||||
)
|
||||
|
||||
def evaluate_project(video_path: str) -> ProjectEvaluation:
|
||||
"""
|
||||
Evaluate a hackathon project based on its video demonstration
|
||||
"""
|
||||
hackathon_judge = get_hackathon_judge()
|
||||
|
||||
evaluation_task = Task(
|
||||
name="project_evaluation",
|
||||
description="""Analyze this hackathon project video demonstration and provide a comprehensive evaluation:
|
||||
|
||||
1. Score the following aspects (0-100):
|
||||
- Innovation and Creativity
|
||||
- Technical Complexity
|
||||
- Presentation Quality
|
||||
- User Experience
|
||||
- Project Completeness
|
||||
|
||||
2. Identify:
|
||||
- Key strengths and standout features
|
||||
- Areas that could be improved
|
||||
- Notable technical implementations
|
||||
- Market potential and scalability
|
||||
|
||||
3. Provide:
|
||||
- Specific recommendations for improvement
|
||||
- Technical suggestions
|
||||
- Potential future enhancements""",
|
||||
expected_output="Detailed project evaluation with scores and feedback",
|
||||
agent=hackathon_judge,
|
||||
output_pydantic=ProjectEvaluation,
|
||||
images=[video_path] # Video input for multimodal analysis
|
||||
)
|
||||
|
||||
# Initialize and run evaluation
|
||||
agents = PraisonAIAgents(
|
||||
agents=[hackathon_judge],
|
||||
tasks=[evaluation_task],
|
||||
process="sequential",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
response = agents.start()
|
||||
|
||||
try:
|
||||
# If response contains task_results, extract the Pydantic model directly
|
||||
if isinstance(response, dict) and 'task_results' in response:
|
||||
task_output = response['task_results'][0]
|
||||
if hasattr(task_output, 'pydantic'):
|
||||
return task_output.pydantic
|
||||
elif hasattr(task_output, 'raw'):
|
||||
# Extract JSON from raw string if it's wrapped in ```json
|
||||
raw_text = task_output.raw
|
||||
if raw_text.startswith('```json'):
|
||||
raw_text = raw_text.split('\n', 1)[1].rsplit('\n', 1)[0]
|
||||
evaluation_data = json.loads(raw_text)
|
||||
else:
|
||||
evaluation_data = json.loads(task_output) if isinstance(task_output, str) else task_output
|
||||
elif isinstance(response, str):
|
||||
evaluation_data = json.loads(response)
|
||||
elif isinstance(response, dict) and 'task_status' in response:
|
||||
content = response['task_status']
|
||||
if isinstance(content, dict):
|
||||
evaluation_data = content
|
||||
else:
|
||||
evaluation_data = json.loads(content) if isinstance(content, str) else content
|
||||
else:
|
||||
evaluation_data = response
|
||||
|
||||
# Create and return ProjectEvaluation instance
|
||||
return ProjectEvaluation(
|
||||
innovation_score=int(evaluation_data.get('innovation_score', 0)),
|
||||
technical_complexity=int(evaluation_data.get('technical_complexity', 0)),
|
||||
presentation_quality=int(evaluation_data.get('presentation_quality', 0)),
|
||||
user_experience=int(evaluation_data.get('user_experience', 0)),
|
||||
completeness=int(evaluation_data.get('completeness', 0)),
|
||||
overall_score=int(evaluation_data.get('overall_score', 0)),
|
||||
key_strengths=evaluation_data.get('key_strengths', []),
|
||||
areas_for_improvement=evaluation_data.get('areas_for_improvement', []),
|
||||
notable_features=evaluation_data.get('notable_features', []),
|
||||
technical_highlights=evaluation_data.get('technical_highlights', []),
|
||||
recommendations=evaluation_data.get('recommendations', []),
|
||||
market_potential=str(evaluation_data.get('market_potential', '')),
|
||||
scalability_assessment=str(evaluation_data.get('scalability_assessment', ''))
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Debug - Raw response: {response}")
|
||||
print(f"Error processing response: {e}")
|
||||
raise
|
||||
|
||||
# Title and description
|
||||
st.title("🏆 Hackathon Judge Agent")
|
||||
st.markdown("""
|
||||
Upload your hackathon project demonstration video for an AI-powered evaluation.
|
||||
Get comprehensive feedback on various aspects of your project.
|
||||
""")
|
||||
|
||||
# File uploader
|
||||
uploaded_file = st.file_uploader("Choose a video file", type=['mp4', 'avi', 'mov', 'mkv'])
|
||||
|
||||
if uploaded_file:
|
||||
# Create a temporary file to store the video
|
||||
with tempfile.NamedTemporaryFile(delete=False, suffix='.'+uploaded_file.name.split('.')[-1]) as tmp_file:
|
||||
tmp_file.write(uploaded_file.getvalue())
|
||||
video_path = tmp_file.name
|
||||
|
||||
with st.spinner("🤖 AI is evaluating your project..."):
|
||||
try:
|
||||
# Evaluate the project
|
||||
result = evaluate_project(video_path)
|
||||
|
||||
# Display results
|
||||
st.header("Overall Score")
|
||||
st.metric("Overall Score", f"{result.overall_score}/100")
|
||||
|
||||
# Display detailed scores
|
||||
st.header("Detailed Scores")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.metric("Innovation", f"{result.innovation_score}/100")
|
||||
st.metric("Technical Complexity", f"{result.technical_complexity}/100")
|
||||
with col2:
|
||||
st.metric("Presentation", f"{result.presentation_quality}/100")
|
||||
st.metric("User Experience", f"{result.user_experience}/100")
|
||||
with col3:
|
||||
st.metric("Completeness", f"{result.completeness}/100")
|
||||
|
||||
# Display qualitative feedback
|
||||
st.header("Key Strengths")
|
||||
for strength in result.key_strengths:
|
||||
st.write(f"• {strength}")
|
||||
|
||||
st.header("Areas for Improvement")
|
||||
for area in result.areas_for_improvement:
|
||||
st.write(f"• {area}")
|
||||
|
||||
st.header("Technical Highlights")
|
||||
for highlight in result.technical_highlights:
|
||||
st.write(f"• {highlight}")
|
||||
|
||||
st.header("Notable Features")
|
||||
for feature in result.notable_features:
|
||||
st.write(f"• {feature}")
|
||||
|
||||
st.header("Recommendations")
|
||||
for rec in result.recommendations:
|
||||
st.write(f"• {rec}")
|
||||
|
||||
# Market Analysis
|
||||
st.header("Market Analysis")
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.subheader("Market Potential")
|
||||
st.write(result.market_potential)
|
||||
with col2:
|
||||
st.subheader("Scalability Assessment")
|
||||
st.write(result.scalability_assessment)
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"Error evaluating the project: {str(e)}")
|
||||
finally:
|
||||
# Clean up the temporary file
|
||||
os.unlink(video_path)
|
||||
else:
|
||||
# Display placeholder content
|
||||
st.info("👆 Upload a video file to get started!")
|
||||
@@ -0,0 +1,47 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Image Analysis Agent", tools=[duckduckgo])
|
||||
agent.start("I want to go London next week, find me a good hotel and flight")
|
||||
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Image Analysis Agent
|
||||
image_agent = Agent(
|
||||
name="ImageAnalyst",
|
||||
role="Image Analysis Specialist",
|
||||
goal="Analyze images and videos to extract meaningful information",
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# 1. Task with Image URL
|
||||
task1 = Task(
|
||||
name="analyze_landmark",
|
||||
description="Describe this famous landmark and its architectural features.",
|
||||
expected_output="Detailed description of the landmark's architecture and significance",
|
||||
agent=image_agent,
|
||||
images=["https://upload.wikimedia.org/wikipedia/commons/b/bf/Krakow_-_Kosciol_Mariacki.jpg"]
|
||||
)
|
||||
|
||||
# 2. Task with Local Image File
|
||||
task2 = Task(
|
||||
name="analyze_local_image",
|
||||
description="What objects can you see in this image? Describe their arrangement.",
|
||||
expected_output="Detailed description of objects and their spatial relationships",
|
||||
agent=image_agent,
|
||||
images=["image.jpg"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_agent],
|
||||
tasks=[task1, task2],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run all tasks
|
||||
agents.start()
|
||||
@@ -0,0 +1,47 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Image Analysis Agent", tools=[duckduckgo])
|
||||
agent.start("I want to go London next week, find me a good hotel and flight")
|
||||
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Image Analysis Agent
|
||||
image_agent = Agent(
|
||||
name="ImageAnalyst",
|
||||
role="Image Analysis Specialist",
|
||||
goal="Analyze images and videos to extract meaningful information",
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# 1. Task with Image URL
|
||||
task1 = Task(
|
||||
name="analyze_landmark",
|
||||
description="Describe this famous landmark and its architectural features.",
|
||||
expected_output="Detailed description of the landmark's architecture and significance",
|
||||
agent=image_agent,
|
||||
images=["https://upload.wikimedia.org/wikipedia/commons/b/bf/Krakow_-_Kosciol_Mariacki.jpg"]
|
||||
)
|
||||
|
||||
# 2. Task with Local Image File
|
||||
task2 = Task(
|
||||
name="analyze_local_image",
|
||||
description="What objects can you see in this image? Describe their arrangement.",
|
||||
expected_output="Detailed description of objects and their spatial relationships",
|
||||
agent=image_agent,
|
||||
images=["image.jpg"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_agent],
|
||||
tasks=[task1, task2],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run all tasks
|
||||
agents.start()
|
||||
@@ -0,0 +1,70 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent with knowledge capabilities
|
||||
knowledge_agent = Agent(
|
||||
name="KnowledgeAgent",
|
||||
role="Information Specialist",
|
||||
goal="Store and retrieve knowledge efficiently",
|
||||
backstory="Expert in managing and utilizing stored knowledge",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
knowledge_task = Task(
|
||||
name="knowledge_task",
|
||||
description="KAG",
|
||||
expected_output="Answer to the question",
|
||||
agent=knowledge_agent,
|
||||
context=[
|
||||
{
|
||||
"embedding_db_config": json.dumps(config["vector_store"])
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
# Create and start the agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[knowledge_agent],
|
||||
tasks=[knowledge_task],
|
||||
process="sequential",
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start execution
|
||||
result = agents.start()
|
||||
@@ -0,0 +1,21 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["large.pdf"],
|
||||
knowledge_config=config,
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
@@ -0,0 +1,44 @@
|
||||
import logging
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
import os
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
knowledge = Knowledge(config)
|
||||
|
||||
# Search for memories based on a query
|
||||
query = "KAG"
|
||||
logger.info(f"Searching for memories with query: {query}")
|
||||
search_results = knowledge.search(query, user_id="user1")
|
||||
logger.info(f"Search results: {search_results}")
|
||||
print(f"\nSearch results for '{query}':")
|
||||
print(search_results)
|
||||
@@ -0,0 +1,171 @@
|
||||
import logging
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
import os
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
knowledge = Knowledge(config)
|
||||
|
||||
# Store memories
|
||||
logger.info("Storing memories...")
|
||||
cricket_memory = knowledge.store("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
logger.info(f"Stored cricket memory: {cricket_memory}")
|
||||
tennis_memory = knowledge.store("Enjoys playing tennis with friends", user_id="alice", metadata={"category": "hobbies"})
|
||||
logger.info(f"Stored tennis memory: {tennis_memory}")
|
||||
work_memory = knowledge.store("Works as a software engineer", user_id="alice", metadata={"category": "work"})
|
||||
logger.info(f"Stored work memory: {work_memory}")
|
||||
|
||||
print("Stored memories:")
|
||||
print(cricket_memory)
|
||||
print(tennis_memory)
|
||||
print(work_memory)
|
||||
|
||||
# Retrieve all memories for a user
|
||||
logger.info("Retrieving all memories for Alice...")
|
||||
alice_memories = knowledge.get_all(user_id="alice")
|
||||
logger.info(f"Retrieved memories for Alice: {alice_memories}")
|
||||
print("\nAll memories for Alice:")
|
||||
for memory in alice_memories:
|
||||
print(memory)
|
||||
|
||||
# Retrieve a specific memory by ID
|
||||
logger.info(f"Retrieving memory with ID: {cricket_memory['results'][0]['id']}")
|
||||
retrieved_memory = knowledge.get(cricket_memory['results'][0]["id"])
|
||||
logger.info(f"Retrieved memory: {retrieved_memory}")
|
||||
print("\nRetrieved memory:")
|
||||
print(retrieved_memory)
|
||||
|
||||
# Search for memories based on a query
|
||||
query = "What are Alice's hobbies?"
|
||||
logger.info(f"Searching for memories with query: {query}")
|
||||
search_results = knowledge.search(query, user_id="alice")
|
||||
logger.info(f"Search results: {search_results}")
|
||||
print(f"\nSearch results for '{query}':")
|
||||
for memory in search_results:
|
||||
print(memory)
|
||||
|
||||
# Update a memory
|
||||
logger.info(f"Updating memory with ID: {tennis_memory['results'][0]['id']}")
|
||||
updated_memory = knowledge.update(memory_id=tennis_memory['results'][0]["id"], data="Loves playing tennis on weekends")
|
||||
logger.info(f"Updated memory: {updated_memory}")
|
||||
print("\nUpdated memory:")
|
||||
print(updated_memory)
|
||||
|
||||
# Get memory history
|
||||
logger.info(f"Retrieving memory history for ID: {tennis_memory['results'][0]['id']}")
|
||||
memory_history = knowledge.history(memory_id=tennis_memory['results'][0]["id"])
|
||||
logger.info(f"Memory history: {memory_history}")
|
||||
print("\nMemory history:")
|
||||
for entry in memory_history:
|
||||
print(entry)
|
||||
|
||||
# Delete a memory
|
||||
logger.info(f"Deleting memory with ID: {work_memory['results'][0]['id']}")
|
||||
knowledge.delete(memory_id=work_memory['results'][0]["id"])
|
||||
logger.info("Memory deleted")
|
||||
print("\nDeleted memory")
|
||||
|
||||
# Retrieve memories after deletion
|
||||
logger.info("Retrieving memories after deletion...")
|
||||
alice_memories = knowledge.get_all(user_id="alice")
|
||||
logger.info(f"Retrieved memories after deletion: {alice_memories}")
|
||||
print("\nMemories after deletion:")
|
||||
for memory in alice_memories:
|
||||
print(memory)
|
||||
|
||||
# Delete all memories for a user
|
||||
logger.info("Deleting all memories for Alice...")
|
||||
knowledge.delete_all(user_id="alice")
|
||||
logger.info("All memories for Alice deleted")
|
||||
print("\nAll memories for Alice deleted")
|
||||
|
||||
# Retrieve memories after deleting all
|
||||
logger.info("Retrieving memories after deleting all...")
|
||||
alice_memories = knowledge.get_all(user_id="alice")
|
||||
logger.info(f"Retrieved memories after deleting all: {alice_memories}")
|
||||
print("\nMemories after deleting all:")
|
||||
print(alice_memories)
|
||||
|
||||
# Reset all memories
|
||||
logger.info("Resetting all memories...")
|
||||
knowledge.reset()
|
||||
logger.info("All memories reset")
|
||||
print("\nAll memories reset")
|
||||
|
||||
# Test file handling
|
||||
logger.info("Testing file handling...")
|
||||
|
||||
try:
|
||||
# Get absolute path to test files
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
pdf_file = os.path.join(current_dir, "small.pdf")
|
||||
txt_file = os.path.join(current_dir, "sample.txt")
|
||||
|
||||
# Test text file
|
||||
logger.info(f"Testing text file: {txt_file}")
|
||||
# Read and display content
|
||||
with open(txt_file, 'r') as file:
|
||||
txt_content = file.read()
|
||||
print("\nText file content:")
|
||||
print(txt_content)
|
||||
# Store the text file using add
|
||||
txt_memory = knowledge.add(txt_file, user_id="bob", metadata={"type": "text"})
|
||||
logger.info(f"Stored text file: {txt_memory}")
|
||||
print("\nStored text content:")
|
||||
if txt_memory and 'results' in txt_memory and txt_memory['results']:
|
||||
for mem in txt_memory['results']:
|
||||
print(mem)
|
||||
else:
|
||||
print("No valid memories were stored from the text file")
|
||||
|
||||
# Verify text memories are stored
|
||||
if txt_memory and 'results' in txt_memory and txt_memory['results']:
|
||||
logger.info("Verifying text memories...")
|
||||
for mem in txt_memory['results']:
|
||||
if isinstance(mem, dict) and 'id' in mem:
|
||||
stored = knowledge.get(mem['id'])
|
||||
logger.info(f"Verified text memory: {stored}")
|
||||
else:
|
||||
logger.warning(f"Unexpected memory format: {mem}")
|
||||
else:
|
||||
logger.warning("No valid memories were stored from the text file")
|
||||
|
||||
# Test pdf file
|
||||
logger.info(f"Testing pdf file: {pdf_file}")
|
||||
pdf_memory = knowledge.add(pdf_file, user_id="bob", metadata={"type": "pdf"})
|
||||
logger.info(f"Stored pdf file: {pdf_memory}")
|
||||
print("\nStored pdf content:")
|
||||
if pdf_memory and 'results' in pdf_memory and pdf_memory['results']:
|
||||
for mem in pdf_memory['results']:
|
||||
print(mem)
|
||||
else:
|
||||
print("No valid memories were stored from the PDF file")
|
||||
|
||||
# Verify stored content
|
||||
if pdf_memory and 'results' in pdf_memory and pdf_memory['results']:
|
||||
for memory in pdf_memory['results']:
|
||||
if isinstance(memory, dict) and 'id' in memory:
|
||||
stored_memory = knowledge.get(memory['id'])
|
||||
logger.info(f"Verified stored memory: {stored_memory}")
|
||||
print("\nVerified content:")
|
||||
print(stored_memory)
|
||||
else:
|
||||
logger.warning(f"Unexpected memory format: {memory}")
|
||||
else:
|
||||
logger.warning("No valid memories were stored from the PDF file")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during file handling test: {str(e)}")
|
||||
raise
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import logging
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
import os
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
knowledge = Knowledge()
|
||||
try:
|
||||
# Get absolute path to test files
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
pdf_file = os.path.join(current_dir, "large.pdf")
|
||||
|
||||
# Test pdf file
|
||||
logger.info(f"Testing pdf file: {pdf_file}")
|
||||
pdf_memory = knowledge.add(pdf_file, user_id="bob", metadata={"type": "pdf"})
|
||||
logger.info(f"Stored pdf file: {pdf_memory}")
|
||||
print("\nStored pdf content:")
|
||||
if pdf_memory and 'results' in pdf_memory and pdf_memory['results']:
|
||||
for mem in pdf_memory['results']:
|
||||
print(mem)
|
||||
else:
|
||||
print("No valid memories were stored from the PDF file")
|
||||
|
||||
# Verify stored content
|
||||
if pdf_memory and 'results' in pdf_memory and pdf_memory['results']:
|
||||
for memory in pdf_memory['results']:
|
||||
if isinstance(memory, dict) and 'id' in memory:
|
||||
stored_memory = knowledge.get(memory['id'])
|
||||
logger.info(f"Verified stored memory: {stored_memory}")
|
||||
print("\nVerified content:")
|
||||
print(stored_memory)
|
||||
else:
|
||||
logger.warning(f"Unexpected memory format: {memory}")
|
||||
else:
|
||||
logger.warning("No valid memories were stored from the PDF file")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error during file handling test: {str(e)}")
|
||||
raise
|
||||
Binary file not shown.
Whitespace-only changes.
@@ -0,0 +1,4 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(instructions="You are a Markdown Agent, output in markdown format")
|
||||
agent.start("Write a blog post about AI")
|
||||
@@ -0,0 +1,5 @@
|
||||
from markitdown import MarkItDown
|
||||
|
||||
md = MarkItDown()
|
||||
result = md.convert("sample.txt")
|
||||
print(result.text_content)
|
||||
@@ -0,0 +1,220 @@
|
||||
from mem0 import Memory
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MemoryManager:
|
||||
def __init__(self):
|
||||
"""Initialize Mem0 Memory manager with configuration"""
|
||||
# Define the complete configuration with only supported fields
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"custom_prompt": None,
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Ensure storage directory exists
|
||||
storage_path = os.path.abspath("./.praison/storage")
|
||||
if os.path.exists(storage_path):
|
||||
logger.info(f"Clearing existing storage at {storage_path}")
|
||||
import shutil
|
||||
shutil.rmtree(storage_path)
|
||||
os.makedirs(storage_path, exist_ok=True)
|
||||
logger.info(f"Created storage path: {storage_path}")
|
||||
|
||||
# Initialize memory
|
||||
self.memory = Memory.from_config(config)
|
||||
logger.info("Memory manager initialized")
|
||||
|
||||
def pretty_print(self, data: Any) -> None:
|
||||
"""Helper function to print memory data in a readable format"""
|
||||
if isinstance(data, (dict, list)):
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
print(data)
|
||||
|
||||
def extract_memory_id(self, result: Any) -> Optional[str]:
|
||||
"""Extract memory ID from the result, handling different formats"""
|
||||
try:
|
||||
if isinstance(result, dict):
|
||||
# v1.1 format
|
||||
memories = result.get('results', [])
|
||||
return memories[0]['id'] if memories else None
|
||||
elif isinstance(result, list):
|
||||
# v1.0 format
|
||||
return result[0]['id'] if result else None
|
||||
return None
|
||||
except (KeyError, IndexError) as e:
|
||||
logger.warning(f"Could not extract memory ID from result: {e}")
|
||||
return None
|
||||
|
||||
def prepare_metadata(self, metadata: Optional[Dict]) -> Dict:
|
||||
"""Prepare metadata by converting values to acceptable types"""
|
||||
if not metadata:
|
||||
return {}
|
||||
|
||||
clean_metadata = {}
|
||||
for key, value in metadata.items():
|
||||
if isinstance(value, (str, int, float, bool)):
|
||||
clean_metadata[key] = value
|
||||
elif isinstance(value, list):
|
||||
clean_metadata[key] = ','.join(map(str, value))
|
||||
elif isinstance(value, dict):
|
||||
clean_metadata[key] = json.dumps(value)
|
||||
else:
|
||||
clean_metadata[key] = str(value)
|
||||
return clean_metadata
|
||||
|
||||
def verify_memory_addition(self, user_id: str, max_retries: int = 3) -> bool:
|
||||
"""Verify that memory was added successfully"""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
time.sleep(0.5) # Brief pause to allow indexing
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
if len(memories.get('results', [])) > 0:
|
||||
return True
|
||||
logger.warning(f"Memory not found on attempt {attempt + 1}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Verification attempt {attempt + 1} failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(1)
|
||||
return False
|
||||
|
||||
def add_memory(self, text: str, user_id: Optional[str] = None, metadata: Optional[Dict] = None) -> Dict:
|
||||
"""Add a new memory with error handling and verification"""
|
||||
try:
|
||||
logger.info(f"Adding memory for user {user_id}")
|
||||
clean_metadata = self.prepare_metadata(metadata)
|
||||
logger.debug(f"Prepared metadata: {clean_metadata}")
|
||||
|
||||
messages = [{"role": "user", "content": text}]
|
||||
result = self.memory.add(
|
||||
messages=messages,
|
||||
user_id=user_id,
|
||||
metadata=clean_metadata
|
||||
)
|
||||
|
||||
if self.verify_memory_addition(user_id):
|
||||
logger.info("Memory added and verified successfully")
|
||||
else:
|
||||
logger.warning("Memory addition could not be verified")
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to add memory: {str(e)}")
|
||||
raise
|
||||
|
||||
def get_all_memories(self, user_id: Optional[str] = None) -> Dict:
|
||||
"""Retrieve all memories for a user"""
|
||||
try:
|
||||
logger.info(f"Retrieving all memories for user {user_id}")
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
count = len(memories.get('results', []))
|
||||
logger.info(f"Retrieved {count} memories")
|
||||
return memories
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to retrieve memories: {str(e)}")
|
||||
raise
|
||||
|
||||
def search_memories(self, query: str, user_id: Optional[str] = None, limit: int = 5) -> Dict:
|
||||
"""Search memories with a query"""
|
||||
try:
|
||||
logger.info(f"Searching memories with query: {query}")
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
limit=limit
|
||||
)
|
||||
count = len(results.get('results', []))
|
||||
logger.info(f"Found {count} matching memories")
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"Search failed: {str(e)}")
|
||||
raise
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Initialize memory manager
|
||||
manager = MemoryManager()
|
||||
|
||||
# Add a test memory
|
||||
print("\n1. Adding a new memory:")
|
||||
metadata = {
|
||||
"category": "hobbies",
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"tags": "tennis,learning",
|
||||
"priority": 1,
|
||||
"source": "user_input"
|
||||
}
|
||||
|
||||
result = manager.add_memory(
|
||||
text="I am working on improving my tennis skills. Suggest some online courses.",
|
||||
user_id="alice",
|
||||
metadata=metadata
|
||||
)
|
||||
manager.pretty_print(result)
|
||||
|
||||
# Wait briefly for indexing
|
||||
time.sleep(1)
|
||||
|
||||
print("\n2. Retrieving all memories:")
|
||||
all_memories = manager.get_all_memories(user_id="alice")
|
||||
manager.pretty_print(all_memories)
|
||||
|
||||
print("\n3. Searching memories:")
|
||||
search_results = manager.search_memories(
|
||||
query="What are Alice's hobbies?",
|
||||
user_id="alice",
|
||||
limit=5
|
||||
)
|
||||
manager.pretty_print(search_results)
|
||||
|
||||
# Print summary
|
||||
print("\nMemory Store Summary:")
|
||||
total_memories = len(all_memories.get('results', []))
|
||||
print(f"Total memories stored: {total_memories}")
|
||||
if total_memories > 0:
|
||||
print("Available memories:")
|
||||
for mem in all_memories['results']:
|
||||
print(f"- {mem.get('memory', 'No content')}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Main process failed: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,143 @@
|
||||
from mem0 import Memory
|
||||
import logging
|
||||
import json
|
||||
import os
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MemorySearcher:
|
||||
def __init__(self):
|
||||
"""Initialize Mem0 Memory searcher with configuration"""
|
||||
# Define the configuration
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage"),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small",
|
||||
"embedding_dims": 1536
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0,
|
||||
"max_tokens": 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
self.memory = Memory.from_config(config)
|
||||
logger.info("Memory searcher initialized")
|
||||
|
||||
def pretty_print(self, data: Any) -> None:
|
||||
"""Helper function to print data in a readable format"""
|
||||
if isinstance(data, (dict, list)):
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
print(data)
|
||||
|
||||
def get_all_memories(self, user_id: Optional[str] = None) -> Dict:
|
||||
"""Retrieve all memories for a user"""
|
||||
try:
|
||||
logger.info(f"Retrieving all memories for user {user_id}")
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
count = len(memories.get('results', []))
|
||||
logger.info(f"Retrieved {count} memories")
|
||||
return memories
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to retrieve memories: {str(e)}")
|
||||
raise
|
||||
|
||||
def search_memories(self, query: str, user_id: Optional[str] = None, limit: int = 5) -> Dict:
|
||||
"""Search memories with a query"""
|
||||
try:
|
||||
logger.info(f"Searching memories with query: {query}")
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
limit=limit
|
||||
)
|
||||
count = len(results.get('results', []))
|
||||
logger.info(f"Found {count} matching memories")
|
||||
return results
|
||||
except Exception as e:
|
||||
logger.error(f"Search failed: {str(e)}")
|
||||
raise
|
||||
|
||||
def list_unique_users(self) -> list:
|
||||
"""List all unique users in the memory store"""
|
||||
try:
|
||||
all_memories = self.memory.get_all()
|
||||
users = set()
|
||||
for memory in all_memories.get('results', []):
|
||||
if 'user_id' in memory:
|
||||
users.add(memory['user_id'])
|
||||
return sorted(list(users))
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to list users: {str(e)}")
|
||||
raise
|
||||
|
||||
def main():
|
||||
try:
|
||||
# Initialize memory searcher
|
||||
searcher = MemorySearcher()
|
||||
|
||||
# Get list of users
|
||||
print("\n1. Available users in the memory store:")
|
||||
users = searcher.list_unique_users()
|
||||
searcher.pretty_print(users)
|
||||
|
||||
if not users:
|
||||
print("No users found in the memory store. Please add some memories first.")
|
||||
return
|
||||
|
||||
# Example user (using first user found)
|
||||
example_user = users[0]
|
||||
|
||||
print(f"\n2. All memories for user '{example_user}':")
|
||||
all_memories = searcher.get_all_memories(user_id=example_user)
|
||||
searcher.pretty_print(all_memories)
|
||||
|
||||
print(f"\n3. Searching memories for user '{example_user}':")
|
||||
search_results = searcher.search_memories(
|
||||
query="What are their hobbies?",
|
||||
user_id=example_user,
|
||||
limit=5
|
||||
)
|
||||
searcher.pretty_print(search_results)
|
||||
|
||||
# Print summary
|
||||
print("\nMemory Store Summary:")
|
||||
total_memories = len(all_memories.get('results', []))
|
||||
print(f"Total memories for {example_user}: {total_memories}")
|
||||
if total_memories > 0:
|
||||
print("Available memories:")
|
||||
for mem in all_memories['results']:
|
||||
print(f"- {mem.get('memory', 'No content')}")
|
||||
if 'metadata' in mem:
|
||||
print(f" Metadata: {mem['metadata']}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Main process failed: {str(e)}", exc_info=True)
|
||||
raise
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,26 @@
|
||||
from mem0 import Memory
|
||||
import os
|
||||
import json
|
||||
|
||||
# Basic configuration
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Search Alice's hobbies
|
||||
search_results = memory.search(
|
||||
query="KAG",
|
||||
user_id="user1",
|
||||
limit=5
|
||||
)
|
||||
|
||||
print(search_results)
|
||||
@@ -0,0 +1,46 @@
|
||||
from mem0 import Memory
|
||||
import os
|
||||
import json
|
||||
|
||||
# Basic configuration
|
||||
config = {
|
||||
"version": "v1.1",
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": os.path.abspath("./.praison/storage")
|
||||
}
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-small"
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize memory
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Search Alice's hobbies
|
||||
search_results = memory.search(
|
||||
query="What are Alice's hobbies?",
|
||||
user_id="alice",
|
||||
limit=5
|
||||
)
|
||||
|
||||
# Print results in a readable format
|
||||
print("\nAlice's Memories:")
|
||||
for memory in search_results['results']:
|
||||
print(f"\nMemory: {memory['memory']}")
|
||||
print(f"Score: {memory['score']}")
|
||||
if 'metadata' in memory:
|
||||
print("Metadata:")
|
||||
print(json.dumps(memory['metadata'], indent=2))
|
||||
@@ -51,9 +51,4 @@ agents = PraisonAIAgents(
|
||||
)
|
||||
|
||||
# Run all tasks
|
||||
result = agents.start()
|
||||
|
||||
# Print results
|
||||
for task_id, task_result in result["task_results"].items():
|
||||
print(f"\nTask {task_id} Result:")
|
||||
print(task_result.raw)
|
||||
agents.start()
|
||||
@@ -0,0 +1,110 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import time
|
||||
|
||||
def get_time_check():
|
||||
current_time = int(time.time())
|
||||
if current_time % 3 == 0:
|
||||
result = 1
|
||||
elif current_time % 3 == 1:
|
||||
result = 2
|
||||
else:
|
||||
result = 3
|
||||
print(f"Time: {current_time}, Result: {result}")
|
||||
return result
|
||||
|
||||
# Create orchestrator and worker agents
|
||||
router = Agent(
|
||||
name="Router",
|
||||
role="Task router",
|
||||
goal="Distribute tasks to based on response from get_time_check",
|
||||
tools=[get_time_check]
|
||||
)
|
||||
|
||||
worker1 = Agent(
|
||||
name="Worker 1",
|
||||
role="Specialized worker",
|
||||
goal="Handle specific subtask type 1",
|
||||
)
|
||||
|
||||
worker2 = Agent(
|
||||
name="Worker 2",
|
||||
role="Specialized worker",
|
||||
goal="Handle specific subtask type 2",
|
||||
)
|
||||
|
||||
worker3 = Agent(
|
||||
name="Worker 3",
|
||||
role="Specialized worker",
|
||||
goal="Handle specific subtask type 3",
|
||||
)
|
||||
|
||||
synthesizer = Agent(
|
||||
name="Synthesizer",
|
||||
role="Result synthesizer",
|
||||
goal="Combine and synthesize worker outputs",
|
||||
)
|
||||
|
||||
# Create orchestrated workflow tasks
|
||||
router_task = Task(
|
||||
name="route_task",
|
||||
description="Analyze input from get_time_check and route to appropriate workers",
|
||||
expected_output="Task routing decision, 1 , 2 or 3",
|
||||
agent=router,
|
||||
is_start=True,
|
||||
task_type="decision",
|
||||
next_tasks=["worker1_task", "worker2_task", "worker3_task"],
|
||||
condition={
|
||||
"1": ["worker1_task"],
|
||||
"2": ["worker2_task"],
|
||||
"3": ["worker3_task"]
|
||||
}
|
||||
)
|
||||
|
||||
worker1_task = Task(
|
||||
name="worker1_task",
|
||||
description="Process type 1 operation",
|
||||
expected_output="Worker 1 result",
|
||||
agent=worker1,
|
||||
next_tasks=["synthesize_task"]
|
||||
)
|
||||
|
||||
worker2_task = Task(
|
||||
name="worker2_task",
|
||||
description="Process type 2 operation",
|
||||
expected_output="Worker 2 result",
|
||||
agent=worker2,
|
||||
next_tasks=["synthesize_task"]
|
||||
)
|
||||
|
||||
worker3_task = Task(
|
||||
name="worker3_task",
|
||||
description="Process type 3 operation",
|
||||
expected_output="Worker 3 result",
|
||||
agent=worker3,
|
||||
next_tasks=["synthesize_task"]
|
||||
)
|
||||
|
||||
synthesize_task = Task(
|
||||
name="synthesize_task",
|
||||
description="Synthesize worker results into final output",
|
||||
expected_output="Final synthesized result",
|
||||
agent=synthesizer,
|
||||
context=[worker1_task, worker2_task, worker3_task]
|
||||
)
|
||||
|
||||
# Create workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[router, worker1, worker2, worker3, synthesizer],
|
||||
tasks=[router_task, worker1_task, worker2_task, worker3_task, synthesize_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Run orchestrated workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nOrchestrator-Workers Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
@@ -0,0 +1,95 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from datetime import datetime
|
||||
import asyncio
|
||||
|
||||
def process_time():
|
||||
"""Simulate processing"""
|
||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
print(f"Processing at: {current_time}")
|
||||
return f"Processed at {current_time}"
|
||||
|
||||
# Create parallel processing agents
|
||||
agent1 = Agent(
|
||||
name="Processor 1",
|
||||
role="Time collector",
|
||||
goal="Get the time and return it",
|
||||
tools=[process_time]
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
name="Processor 2",
|
||||
role="Time collector",
|
||||
goal="Get the time and return it",
|
||||
tools=[process_time]
|
||||
)
|
||||
|
||||
agent3 = Agent(
|
||||
name="Processor 3",
|
||||
role="Time collector",
|
||||
goal="Get the time and return it",
|
||||
tools=[process_time]
|
||||
)
|
||||
|
||||
aggregator = Agent(
|
||||
name="Aggregator",
|
||||
role="Result aggregator",
|
||||
goal="Collect all the processed time from all tasks"
|
||||
)
|
||||
|
||||
# Create parallel tasks with memory disabled
|
||||
task1 = Task(
|
||||
name="process_1",
|
||||
description="Use process_time tool to get the time",
|
||||
expected_output="processed time",
|
||||
agent=agent1,
|
||||
is_start=True,
|
||||
async_execution=True
|
||||
)
|
||||
|
||||
task2 = Task(
|
||||
name="process_2",
|
||||
description="Use process_time tool to get the time",
|
||||
expected_output="processed time",
|
||||
agent=agent2,
|
||||
is_start=True,
|
||||
async_execution=True
|
||||
)
|
||||
|
||||
task3 = Task(
|
||||
name="process_3",
|
||||
description="Use process_time tool to get the time",
|
||||
expected_output="processed time",
|
||||
agent=agent3,
|
||||
is_start=True,
|
||||
async_execution=True
|
||||
)
|
||||
|
||||
aggregate_task = Task(
|
||||
name="aggregate",
|
||||
description="Collect all the processed time from all tasks",
|
||||
expected_output="Output all the processed time from all tasks and just the time",
|
||||
agent=aggregator,
|
||||
context=[task1, task2, task3]
|
||||
)
|
||||
|
||||
async def main():
|
||||
|
||||
# Create workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[agent1, agent2, agent3, aggregator],
|
||||
tasks=[task1, task2, task3, aggregate_task],
|
||||
process="workflow"
|
||||
)
|
||||
|
||||
# Run parallel workflow
|
||||
results = await workflow.astart()
|
||||
|
||||
# Print results
|
||||
print("\nParallel Processing Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
|
||||
# Run the async main function
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,41 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create PDF Analysis Agent
|
||||
pdf_agent = Agent(
|
||||
name="PDFAnalyst",
|
||||
role="PDF Document Specialist",
|
||||
goal="Analyze PDF documents to extract meaningful information",
|
||||
backstory="""You are an expert in PDF document analysis and text extraction.
|
||||
You excel at understanding document structure, extracting content, and analyzing textual information.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# 1. Task with PDF URL
|
||||
task1 = Task(
|
||||
name="analyze_pdf_url",
|
||||
description="Extract and analyze content from this PDF document.",
|
||||
expected_output="Detailed analysis of the PDF content and structure",
|
||||
agent=pdf_agent,
|
||||
input=["https://example.com/document.pdf"]
|
||||
)
|
||||
|
||||
# 2. Task with Local PDF File
|
||||
task2 = Task(
|
||||
name="analyze_local_pdf",
|
||||
description="What information can you extract from this PDF? Analyze its content.",
|
||||
expected_output="Detailed analysis of the PDF content and structure",
|
||||
agent=pdf_agent,
|
||||
input=["document.pdf"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[pdf_agent],
|
||||
tasks=[task1, task2],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run all tasks
|
||||
agents.start()
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Planning Agent", tools=[duckduckgo])
|
||||
agent.start("I want to go London next week, find me a good hotel and flight")
|
||||
@@ -7,7 +7,8 @@ from .agents.agents import PraisonAIAgents
|
||||
from .task.task import Task
|
||||
from .tools.tools import Tools
|
||||
from .agents.autoagents import AutoAgents
|
||||
from .memory.memory import Memory
|
||||
from .knowledge.knowledge import Knowledge
|
||||
from .knowledge.chunking import Chunking
|
||||
from .main import (
|
||||
TaskOutput,
|
||||
ReflectionOutput,
|
||||
@@ -36,7 +37,6 @@ __all__ = [
|
||||
'TaskOutput',
|
||||
'ReflectionOutput',
|
||||
'AutoAgents',
|
||||
'Memory',
|
||||
'display_interaction',
|
||||
'display_self_reflection',
|
||||
'display_instruction',
|
||||
@@ -48,4 +48,6 @@ __all__ = [
|
||||
'register_display_callback',
|
||||
'sync_display_callbacks',
|
||||
'async_display_callbacks',
|
||||
'Knowledge',
|
||||
'Chunking'
|
||||
]
|
||||
@@ -16,9 +16,11 @@ from ..main import (
|
||||
display_self_reflection,
|
||||
ReflectionOutput,
|
||||
client,
|
||||
error_logs
|
||||
error_logs,
|
||||
adisplay_instruction
|
||||
)
|
||||
import inspect
|
||||
import uuid
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..task.task import Task
|
||||
@@ -69,10 +71,15 @@ class Agent:
|
||||
|
||||
import inspect
|
||||
# Langchain tools
|
||||
if inspect.isclass(func) and hasattr(func, 'run'):
|
||||
if inspect.isclass(func) and hasattr(func, 'run') and not hasattr(func, '_run'):
|
||||
original_func = func
|
||||
func = func.run
|
||||
function_name = original_func.__name__
|
||||
# CrewAI tools
|
||||
elif inspect.isclass(func) and hasattr(func, '_run'):
|
||||
original_func = func
|
||||
func = func._run
|
||||
function_name = original_func.__name__
|
||||
|
||||
sig = inspect.signature(func)
|
||||
logging.debug(f"Function signature: {sig}")
|
||||
@@ -175,14 +182,27 @@ class Agent:
|
||||
respect_context_window: bool = True,
|
||||
code_execution_mode: Literal["safe", "unsafe"] = "safe",
|
||||
embedder_config: Optional[Dict[str, Any]] = None,
|
||||
knowledge_sources: Optional[List[Any]] = None,
|
||||
knowledge: Optional[List[str]] = None,
|
||||
knowledge_config: Optional[Dict[str, Any]] = None,
|
||||
use_system_prompt: Optional[bool] = True,
|
||||
markdown: bool = True,
|
||||
self_reflect: bool = False,
|
||||
max_reflect: int = 3,
|
||||
min_reflect: int = 1,
|
||||
reflect_llm: Optional[str] = None
|
||||
reflect_llm: Optional[str] = None,
|
||||
user_id: Optional[str] = None
|
||||
):
|
||||
# Add check at start if memory is requested
|
||||
if memory is not None:
|
||||
try:
|
||||
from ..memory.memory import Memory
|
||||
MEMORY_AVAILABLE = True
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Memory features requested in Agent but memory dependencies not installed. "
|
||||
"Please install with: pip install \"praisonaiagents[memory]\""
|
||||
)
|
||||
|
||||
# Handle backward compatibility for required fields
|
||||
if all(x is None for x in [name, role, goal, backstory, instructions]):
|
||||
raise ValueError("At least one of name, role, goal, backstory, or instructions must be provided")
|
||||
@@ -225,7 +245,7 @@ class Agent:
|
||||
self.respect_context_window = respect_context_window
|
||||
self.code_execution_mode = code_execution_mode
|
||||
self.embedder_config = embedder_config
|
||||
self.knowledge_sources = knowledge_sources
|
||||
self.knowledge = knowledge
|
||||
self.use_system_prompt = use_system_prompt
|
||||
self.chat_history = []
|
||||
self.markdown = markdown
|
||||
@@ -241,6 +261,40 @@ Your Role: {self.role}\n
|
||||
Your Goal: {self.goal}
|
||||
"""
|
||||
|
||||
# Generate unique IDs
|
||||
self.agent_id = str(uuid.uuid4())
|
||||
|
||||
# Store user_id
|
||||
self.user_id = user_id
|
||||
|
||||
# Check if knowledge parameter has any values
|
||||
if not knowledge:
|
||||
self.knowledge = None
|
||||
else:
|
||||
# Initialize Knowledge with provided or default config
|
||||
from praisonaiagents.knowledge import Knowledge
|
||||
self.knowledge = Knowledge(knowledge_config or None)
|
||||
|
||||
# Handle knowledge
|
||||
if knowledge:
|
||||
for source in knowledge:
|
||||
self._process_knowledge(source)
|
||||
|
||||
def _process_knowledge(self, knowledge_item):
|
||||
"""Process and store knowledge from a file path, URL, or string."""
|
||||
try:
|
||||
if os.path.exists(knowledge_item):
|
||||
# It's a file path
|
||||
self.knowledge.add(knowledge_item, user_id=self.user_id, agent_id=self.agent_id)
|
||||
elif knowledge_item.startswith("http://") or knowledge_item.startswith("https://"):
|
||||
# It's a URL
|
||||
pass
|
||||
else:
|
||||
# It's a string content
|
||||
self.knowledge.store(knowledge_item, user_id=self.user_id, agent_id=self.agent_id)
|
||||
except Exception as e:
|
||||
logging.error(f"Error processing knowledge item: {knowledge_item}, error: {e}")
|
||||
|
||||
def generate_task(self) -> 'Task':
|
||||
"""Generate a Task object from the agent's instructions"""
|
||||
from ..task.task import Task
|
||||
@@ -279,14 +333,22 @@ Your Goal: {self.goal}
|
||||
|
||||
if func:
|
||||
try:
|
||||
# If it's a class with run method, instantiate and call run
|
||||
if inspect.isclass(func) and hasattr(func, 'run'):
|
||||
# Langchain: If it's a class with run but not _run, instantiate and call run
|
||||
if inspect.isclass(func) and hasattr(func, 'run') and not hasattr(func, '_run'):
|
||||
instance = func()
|
||||
# Extract only the parameters that run() expects
|
||||
run_params = {k: v for k, v in arguments.items()
|
||||
if k in inspect.signature(instance.run).parameters
|
||||
and k != 'self'}
|
||||
if k in inspect.signature(instance.run).parameters
|
||||
and k != 'self'}
|
||||
return instance.run(**run_params)
|
||||
|
||||
# CrewAI: If it's a class with an _run method, instantiate and call _run
|
||||
elif inspect.isclass(func) and hasattr(func, '_run'):
|
||||
instance = func()
|
||||
run_params = {k: v for k, v in arguments.items()
|
||||
if k in inspect.signature(instance._run).parameters
|
||||
and k != 'self'}
|
||||
return instance._run(**run_params)
|
||||
|
||||
# Otherwise treat as regular function
|
||||
elif callable(func):
|
||||
return func(**arguments)
|
||||
@@ -417,15 +479,30 @@ Your Goal: {self.goal}
|
||||
return None
|
||||
|
||||
def chat(self, prompt, temperature=0.2, tools=None, output_json=None, output_pydantic=None):
|
||||
# Search for existing knowledge if any knowledge is provided
|
||||
if self.knowledge:
|
||||
search_results = self.knowledge.search(prompt, agent_id=self.agent_id)
|
||||
if search_results:
|
||||
# Check if search_results is a list of dictionaries or strings
|
||||
if isinstance(search_results, dict) and 'results' in search_results:
|
||||
# Extract memory content from the results
|
||||
knowledge_content = "\n".join([result['memory'] for result in search_results['results']])
|
||||
else:
|
||||
# If search_results is a list of strings, join them directly
|
||||
knowledge_content = "\n".join(search_results)
|
||||
|
||||
# Append found knowledge to the prompt
|
||||
prompt = f"{prompt}\n\nKnowledge: {knowledge_content}"
|
||||
|
||||
if self.use_system_prompt:
|
||||
system_prompt = f"""{self.backstory}\n
|
||||
Your Role: {self.role}\n
|
||||
Your Goal: {self.goal}
|
||||
"""
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_json.schema_json()}"
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_pydantic.schema_json()}"
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
else:
|
||||
system_prompt = None
|
||||
|
||||
@@ -615,9 +692,9 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
# Build system prompt
|
||||
system_prompt = self.system_prompt
|
||||
if output_json:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_json.schema_json()}"
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_json.model_json_schema())}"
|
||||
elif output_pydantic:
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {output_pydantic.schema_json()}"
|
||||
system_prompt += f"\nReturn ONLY a JSON object that matches this Pydantic model: {json.dumps(output_pydantic.model_json_schema())}"
|
||||
|
||||
# Build messages
|
||||
if isinstance(prompt, str):
|
||||
@@ -761,4 +838,8 @@ Output MUST be JSON with 'reflection' and 'satisfactory'.
|
||||
|
||||
def run(self):
|
||||
"""Alias for start() method"""
|
||||
return self.start()
|
||||
return self.start()
|
||||
|
||||
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)
|
||||
@@ -12,6 +12,7 @@ from ..agent.agent import Agent
|
||||
from ..task.task import Task
|
||||
from ..process.process import Process, LoopItems
|
||||
import asyncio
|
||||
import uuid
|
||||
|
||||
# Set up logger
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -44,10 +45,29 @@ def process_video(video_path: str, seconds_per_frame=2):
|
||||
return base64_frames
|
||||
|
||||
class PraisonAIAgents:
|
||||
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None):
|
||||
def __init__(self, agents, tasks=None, verbose=0, completion_checker=None, max_retries=5, process="sequential", manager_llm=None, memory=False, memory_config=None, embedder=None, user_id=None, max_iter=10):
|
||||
# Add check at the start if memory is requested
|
||||
if memory:
|
||||
try:
|
||||
from ..memory.memory import Memory
|
||||
MEMORY_AVAILABLE = True
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Memory features requested but memory dependencies not installed. "
|
||||
"Please install with: pip install \"praisonaiagents[memory]\""
|
||||
)
|
||||
|
||||
if not agents:
|
||||
raise ValueError("At least one agent must be provided")
|
||||
|
||||
|
||||
self.run_id = str(uuid.uuid4()) # Auto-generate run_id
|
||||
self.user_id = user_id or "praison" # Optional user_id
|
||||
self.max_iter = max_iter # Add max_iter parameter
|
||||
|
||||
# Pass user_id to each agent
|
||||
for agent in agents:
|
||||
agent.user_id = self.user_id
|
||||
|
||||
self.agents = agents
|
||||
self.tasks = {}
|
||||
if max_retries < 3:
|
||||
@@ -211,20 +231,56 @@ class PraisonAIAgents:
|
||||
|
||||
executor_agent = task.agent
|
||||
|
||||
# Ensure tools are available from both task and agent
|
||||
tools = task.tools or []
|
||||
if executor_agent and executor_agent.tools:
|
||||
tools.extend(executor_agent.tools)
|
||||
|
||||
task_prompt = f"""
|
||||
You need to do the following task: {task.description}.
|
||||
Expected Output: {task.expected_output}.
|
||||
"""
|
||||
if task.context:
|
||||
context_results = ""
|
||||
for context_task in task.context:
|
||||
if context_task.result:
|
||||
context_results += f"Result of previous task {context_task.name if context_task.name else context_task.description}: {context_task.result.raw}\n"
|
||||
else:
|
||||
context_results += f"Previous task {context_task.name if context_task.name else context_task.description} had no result.\n"
|
||||
context_results = [] # Use list to avoid duplicates
|
||||
for context_item in task.context:
|
||||
if isinstance(context_item, str):
|
||||
context_results.append(f"Input Content:\n{context_item}")
|
||||
elif isinstance(context_item, list):
|
||||
context_results.append(f"Input Content: {' '.join(str(x) for x in context_item)}")
|
||||
elif hasattr(context_item, 'result'): # Task object
|
||||
if context_item.result:
|
||||
context_results.append(
|
||||
f"Result of previous task {context_item.name if context_item.name else context_item.description}:\n{context_item.result.raw}"
|
||||
)
|
||||
else:
|
||||
context_results.append(
|
||||
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
|
||||
)
|
||||
elif isinstance(context_item, dict) and "vector_store" in context_item:
|
||||
from ..knowledge.knowledge import Knowledge
|
||||
try:
|
||||
# Handle both string and dict configs
|
||||
cfg = context_item["vector_store"]
|
||||
if isinstance(cfg, str):
|
||||
cfg = json.loads(cfg)
|
||||
|
||||
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
|
||||
|
||||
# Only use user_id as filter
|
||||
db_results = knowledge.search(
|
||||
task.description,
|
||||
user_id=self.user_id if self.user_id else None
|
||||
)
|
||||
context_results.append(f"[DB Context]: {str(db_results)}")
|
||||
except Exception as e:
|
||||
context_results.append(f"[Vector DB Error]: {e}")
|
||||
|
||||
# Join unique context results
|
||||
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
|
||||
task_prompt += f"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
Context:
|
||||
|
||||
{' '.join(unique_contexts)}
|
||||
"""
|
||||
task_prompt += "Please provide only the final result of your work. Do not add any conversation or extra explanation."
|
||||
|
||||
@@ -267,14 +323,14 @@ Here are the results of previous tasks that might be useful:\n
|
||||
|
||||
agent_output = await executor_agent.achat(
|
||||
_get_multimodal_message(task_prompt, task.images),
|
||||
tools=task.tools,
|
||||
tools=tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
else:
|
||||
agent_output = await executor_agent.achat(
|
||||
task_prompt,
|
||||
tools=task.tools,
|
||||
tools=tools,
|
||||
output_json=task.output_json,
|
||||
output_pydantic=task.output_pydantic
|
||||
)
|
||||
@@ -376,15 +432,30 @@ Here are the results of previous tasks that might be useful:\n
|
||||
tasks=self.tasks,
|
||||
agents=self.agents,
|
||||
manager_llm=self.manager_llm,
|
||||
verbose=self.verbose
|
||||
verbose=self.verbose,
|
||||
max_iter=self.max_iter
|
||||
)
|
||||
|
||||
if self.process == "workflow":
|
||||
# Collect all tasks that should run in parallel
|
||||
parallel_tasks = []
|
||||
async for task_id in process.aworkflow():
|
||||
if self.tasks[task_id].async_execution:
|
||||
await self.arun_task(task_id)
|
||||
else:
|
||||
self.run_task(task_id)
|
||||
if self.tasks[task_id].async_execution and self.tasks[task_id].is_start:
|
||||
parallel_tasks.append(task_id)
|
||||
elif parallel_tasks:
|
||||
# Execute collected parallel tasks
|
||||
await asyncio.gather(*[self.arun_task(t) for t in parallel_tasks])
|
||||
parallel_tasks = []
|
||||
# Run the current non-parallel task
|
||||
if self.tasks[task_id].async_execution:
|
||||
await self.arun_task(task_id)
|
||||
else:
|
||||
self.run_task(task_id)
|
||||
|
||||
# Execute any remaining parallel tasks
|
||||
if parallel_tasks:
|
||||
await asyncio.gather(*[self.arun_task(t) for t in parallel_tasks])
|
||||
|
||||
elif self.process == "sequential":
|
||||
async for task_id in process.asequential():
|
||||
if self.tasks[task_id].async_execution:
|
||||
@@ -400,8 +471,16 @@ Here are the results of previous tasks that might be useful:\n
|
||||
else:
|
||||
self.run_task(task_id)
|
||||
|
||||
async def astart(self):
|
||||
async def astart(self, content=None, **kwargs):
|
||||
"""Async version of start method"""
|
||||
if content:
|
||||
# Add content to context of all tasks
|
||||
for task in self.tasks.values():
|
||||
if isinstance(content, (str, list)):
|
||||
if not task.context:
|
||||
task.context = []
|
||||
task.context.append(content)
|
||||
|
||||
await self.arun_all_tasks()
|
||||
return {
|
||||
"task_status": self.get_all_tasks_status(),
|
||||
@@ -458,16 +537,48 @@ You need to do the following task: {task.description}.
|
||||
Expected Output: {task.expected_output}.
|
||||
"""
|
||||
if task.context:
|
||||
context_results = ""
|
||||
for context_task in task.context:
|
||||
if context_task.result:
|
||||
context_results += f"Result of previous task {context_task.name if context_task.name else context_task.description}: {context_task.result.raw}\n"
|
||||
else:
|
||||
context_results += f"Previous task {context_task.name if context_task.name else context_task.description} had no result.\n"
|
||||
context_results = [] # Use list to avoid duplicates
|
||||
for context_item in task.context:
|
||||
if isinstance(context_item, str):
|
||||
context_results.append(f"Input Content:\n{context_item}")
|
||||
elif isinstance(context_item, list):
|
||||
context_results.append(f"Input Content: {' '.join(str(x) for x in context_item)}")
|
||||
elif hasattr(context_item, 'result'): # Task object
|
||||
if context_item.result:
|
||||
context_results.append(
|
||||
f"Result of previous task {context_item.name if context_item.name else context_item.description}:\n{context_item.result.raw}"
|
||||
)
|
||||
else:
|
||||
context_results.append(
|
||||
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
|
||||
)
|
||||
elif isinstance(context_item, dict) and "vector_store" in context_item:
|
||||
from ..knowledge.knowledge import Knowledge
|
||||
try:
|
||||
# Handle both string and dict configs
|
||||
cfg = context_item["vector_store"]
|
||||
if isinstance(cfg, str):
|
||||
cfg = json.loads(cfg)
|
||||
|
||||
knowledge = Knowledge(config={"vector_store": cfg}, verbose=self.verbose)
|
||||
|
||||
# Only use user_id as filter
|
||||
db_results = knowledge.search(
|
||||
task.description,
|
||||
user_id=self.user_id if self.user_id else None
|
||||
)
|
||||
context_results.append(f"[DB Context]: {str(db_results)}")
|
||||
except Exception as e:
|
||||
context_results.append(f"[Vector DB Error]: {e}")
|
||||
|
||||
# Join unique context results
|
||||
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
|
||||
task_prompt += f"""
|
||||
Here are the results of previous tasks that might be useful:\n
|
||||
{context_results}
|
||||
Context:
|
||||
|
||||
{' '.join(unique_contexts)}
|
||||
"""
|
||||
|
||||
# Add memory context if available
|
||||
if task.memory:
|
||||
try:
|
||||
@@ -596,8 +707,12 @@ Here are the results of previous tasks that might be useful:\n
|
||||
task.status = "completed"
|
||||
# Run execute_callback for memory operations
|
||||
try:
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(task.execute_callback(task_output))
|
||||
if asyncio.get_event_loop().is_running():
|
||||
asyncio.create_task(task.execute_callback(task_output))
|
||||
else:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(task.execute_callback(task_output))
|
||||
except Exception as e:
|
||||
logger.error(f"Error executing memory callback for task {task_id}: {e}")
|
||||
logger.exception(e)
|
||||
@@ -606,7 +721,12 @@ Here are the results of previous tasks that might be useful:\n
|
||||
if task.callback:
|
||||
try:
|
||||
if asyncio.iscoroutinefunction(task.callback):
|
||||
loop.run_until_complete(task.callback(task_output))
|
||||
if asyncio.get_event_loop().is_running():
|
||||
asyncio.create_task(task.callback(task_output))
|
||||
else:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(task.callback(task_output))
|
||||
else:
|
||||
task.callback(task_output)
|
||||
except Exception as e:
|
||||
@@ -639,7 +759,8 @@ Here are the results of previous tasks that might be useful:\n
|
||||
tasks=self.tasks,
|
||||
agents=self.agents,
|
||||
manager_llm=self.manager_llm,
|
||||
verbose=self.verbose
|
||||
verbose=self.verbose,
|
||||
max_iter=self.max_iter
|
||||
)
|
||||
|
||||
if self.process == "workflow":
|
||||
@@ -678,12 +799,24 @@ Here are the results of previous tasks that might be useful:\n
|
||||
return str(agent[0])
|
||||
return None
|
||||
|
||||
def start(self):
|
||||
def start(self, content=None, **kwargs):
|
||||
"""Start agent execution with optional content and config"""
|
||||
if content:
|
||||
# Add content to context of all tasks
|
||||
for task in self.tasks.values():
|
||||
if isinstance(content, (str, list)):
|
||||
# If context is empty, initialize it
|
||||
if not task.context:
|
||||
task.context = []
|
||||
# Add content to context
|
||||
task.context.append(content)
|
||||
|
||||
# Run tasks as before
|
||||
self.run_all_tasks()
|
||||
return {
|
||||
"task_status": self.get_all_tasks_status(),
|
||||
"task_results": {task_id: self.get_task_result(task_id) for task_id in self.tasks}
|
||||
}
|
||||
}
|
||||
|
||||
def set_state(self, key: str, value: Any) -> None:
|
||||
"""Set a state value"""
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
PraisonAI Knowledge - Advanced knowledge management system with configurable features
|
||||
"""
|
||||
|
||||
from praisonaiagents.knowledge.knowledge import Knowledge
|
||||
from praisonaiagents.knowledge.chunking import Chunking
|
||||
|
||||
__all__ = ["Knowledge", "Chunking"]
|
||||
@@ -0,0 +1,182 @@
|
||||
from typing import List, Union, Optional, Dict, Any
|
||||
from functools import cached_property
|
||||
import importlib
|
||||
|
||||
class Chunking:
|
||||
"""A unified class for text chunking with various chunking strategies."""
|
||||
|
||||
CHUNKER_PARAMS = {
|
||||
'token': ['chunk_size', 'chunk_overlap', 'tokenizer'],
|
||||
'word': ['chunk_size', 'chunk_overlap', 'tokenizer'],
|
||||
'sentence': ['chunk_size', 'chunk_overlap', 'tokenizer'],
|
||||
'semantic': ['chunk_size', 'embedding_model', 'tokenizer'],
|
||||
'sdpm': ['chunk_size', 'embedding_model', 'tokenizer'],
|
||||
'late': ['chunk_size', 'embedding_model', 'tokenizer'],
|
||||
'recursive': ['chunk_size', 'tokenizer']
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def SUPPORTED_CHUNKERS(self) -> Dict[str, Any]:
|
||||
"""Lazy load chunker classes."""
|
||||
try:
|
||||
from chonkie.chunker import (
|
||||
TokenChunker,
|
||||
WordChunker,
|
||||
SentenceChunker,
|
||||
SemanticChunker,
|
||||
SDPMChunker,
|
||||
LateChunker,
|
||||
RecursiveChunker
|
||||
)
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"chonkie package not found. Please install it using: pip install 'praisonaiagents[knowledge]'"
|
||||
)
|
||||
|
||||
return {
|
||||
'token': TokenChunker,
|
||||
'word': WordChunker,
|
||||
'sentence': SentenceChunker,
|
||||
'semantic': SemanticChunker,
|
||||
'sdpm': SDPMChunker,
|
||||
'late': LateChunker,
|
||||
'recursive': RecursiveChunker
|
||||
}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
chunker_type: str = 'token',
|
||||
chunk_size: int = 512,
|
||||
chunk_overlap: int = 128,
|
||||
tokenizer: str = "gpt2",
|
||||
embedding_model: Optional[Union[str, Any]] = None,
|
||||
**kwargs
|
||||
):
|
||||
"""Initialize the Chunking class."""
|
||||
if chunker_type not in self.CHUNKER_PARAMS:
|
||||
raise ValueError(
|
||||
f"Unsupported chunker type: {chunker_type}. "
|
||||
f"Must be one of: {list(self.CHUNKER_PARAMS.keys())}"
|
||||
)
|
||||
|
||||
self.chunker_type = chunker_type
|
||||
self.chunk_size = chunk_size
|
||||
self.chunk_overlap = chunk_overlap
|
||||
self.tokenizer = tokenizer
|
||||
self._embedding_model = embedding_model
|
||||
self.kwargs = kwargs
|
||||
|
||||
# Initialize these as None for lazy loading
|
||||
self._chunker = None
|
||||
self._embeddings = None
|
||||
|
||||
@cached_property
|
||||
def embedding_model(self):
|
||||
"""Lazy load the embedding model."""
|
||||
if self._embedding_model is None and self.chunker_type in ['semantic', 'sdpm', 'late']:
|
||||
from chonkie.embeddings import AutoEmbeddings
|
||||
return AutoEmbeddings.get_embeddings("all-MiniLM-L6-v2")
|
||||
elif isinstance(self._embedding_model, str):
|
||||
from chonkie.embeddings import AutoEmbeddings
|
||||
return AutoEmbeddings.get_embeddings(self._embedding_model)
|
||||
return self._embedding_model
|
||||
|
||||
def _get_chunker_params(self) -> Dict[str, Any]:
|
||||
"""Get the appropriate parameters for the current chunker type."""
|
||||
allowed_params = self.CHUNKER_PARAMS[self.chunker_type]
|
||||
params = {'chunk_size': self.chunk_size}
|
||||
|
||||
if 'chunk_overlap' in allowed_params:
|
||||
params['chunk_overlap'] = self.chunk_overlap
|
||||
|
||||
if 'tokenizer' in allowed_params:
|
||||
if self.chunker_type in ['semantic', 'sdpm', 'late']:
|
||||
params['tokenizer'] = self.embedding_model.get_tokenizer_or_token_counter()
|
||||
else:
|
||||
params['tokenizer'] = self.tokenizer
|
||||
|
||||
if 'embedding_model' in allowed_params:
|
||||
params['embedding_model'] = self.embedding_model
|
||||
|
||||
# Add any additional kwargs that are in allowed_params
|
||||
for key, value in self.kwargs.items():
|
||||
if key in allowed_params:
|
||||
params[key] = value
|
||||
|
||||
return params
|
||||
|
||||
@cached_property
|
||||
def chunker(self):
|
||||
"""Lazy load the chunker instance."""
|
||||
if self._chunker is None:
|
||||
chunker_cls = self.SUPPORTED_CHUNKERS[self.chunker_type]
|
||||
common_params = self._get_chunker_params()
|
||||
self._chunker = chunker_cls(**common_params)
|
||||
|
||||
return self._chunker
|
||||
|
||||
def _get_overlap_refinery(self, context_size: Optional[int] = None, **kwargs):
|
||||
"""Lazy load the overlap refinery."""
|
||||
try:
|
||||
from chonkie.refinery import OverlapRefinery
|
||||
except ImportError:
|
||||
raise ImportError("Failed to import OverlapRefinery from chonkie.refinery")
|
||||
|
||||
if context_size is None:
|
||||
context_size = self.chunk_overlap
|
||||
|
||||
return OverlapRefinery(
|
||||
context_size=context_size,
|
||||
tokenizer=self.chunker.tokenizer,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def add_overlap_context(
|
||||
self,
|
||||
chunks: List[Any],
|
||||
context_size: int = None,
|
||||
mode: str = "suffix",
|
||||
merge_context: bool = True
|
||||
) -> List[Any]:
|
||||
"""Add overlap context to chunks using OverlapRefinery."""
|
||||
refinery = self._get_overlap_refinery(
|
||||
context_size=context_size,
|
||||
mode=mode,
|
||||
merge_context=merge_context
|
||||
)
|
||||
return refinery.refine(chunks)
|
||||
|
||||
def chunk(
|
||||
self,
|
||||
text: Union[str, List[str]],
|
||||
add_context: bool = False,
|
||||
context_params: Optional[Dict[str, Any]] = None
|
||||
) -> Union[List[Any], List[List[Any]]]:
|
||||
"""Chunk text using the configured chunking strategy."""
|
||||
chunks = self.chunker(text)
|
||||
|
||||
if add_context:
|
||||
context_params = context_params or {}
|
||||
if isinstance(text, str):
|
||||
chunks = self.add_overlap_context(chunks, **context_params)
|
||||
else:
|
||||
chunks = [self.add_overlap_context(c, **context_params) for c in chunks]
|
||||
|
||||
return chunks
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
text: Union[str, List[str]],
|
||||
add_context: bool = False,
|
||||
context_params: Optional[Dict[str, Any]] = None
|
||||
) -> Union[List[Any], List[List[Any]]]:
|
||||
"""Make the Chunking instance callable."""
|
||||
return self.chunk(text, add_context, context_params)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""String representation of the Chunking instance."""
|
||||
return (
|
||||
f"Chunking(chunker_type='{self.chunker_type}', "
|
||||
f"chunk_size={self.chunk_size}, "
|
||||
f"chunk_overlap={self.chunk_overlap})"
|
||||
)
|
||||
@@ -0,0 +1,321 @@
|
||||
import os
|
||||
import logging
|
||||
import uuid
|
||||
import time
|
||||
from .chunking import Chunking
|
||||
from functools import cached_property
|
||||
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn, TaskProgressColumn
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class CustomMemory:
|
||||
@classmethod
|
||||
def from_config(cls, config):
|
||||
from mem0 import Memory
|
||||
return type('CustomMemory', (Memory,), {
|
||||
'_add_to_vector_store': cls._add_to_vector_store
|
||||
}).from_config(config)
|
||||
|
||||
@staticmethod
|
||||
def _add_to_vector_store(self, messages, metadata, filters):
|
||||
# Custom implementation that doesn't use LLM
|
||||
parsed_messages = "\n".join([msg["content"] for msg in messages])
|
||||
|
||||
# Create a simple fact without using LLM
|
||||
new_retrieved_facts = [parsed_messages]
|
||||
|
||||
# Process embeddings and continue with vector store operations
|
||||
new_message_embeddings = {}
|
||||
for new_mem in new_retrieved_facts:
|
||||
messages_embeddings = self.embedding_model.embed(new_mem)
|
||||
new_message_embeddings[new_mem] = messages_embeddings
|
||||
|
||||
# Create the memory
|
||||
memory_id = self._create_memory(
|
||||
data=parsed_messages,
|
||||
existing_embeddings=new_message_embeddings,
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
return [{
|
||||
"id": memory_id,
|
||||
"memory": parsed_messages,
|
||||
"event": "ADD"
|
||||
}]
|
||||
|
||||
class Knowledge:
|
||||
def __init__(self, config=None, verbose=None):
|
||||
self._config = config
|
||||
self._verbose = verbose or 0
|
||||
os.environ['ANONYMIZED_TELEMETRY'] = 'False' # Chromadb
|
||||
|
||||
# Configure logging levels based on verbose setting
|
||||
if not self._verbose:
|
||||
# Suppress logs from all relevant dependencies
|
||||
for logger_name in [
|
||||
'mem0',
|
||||
'chromadb',
|
||||
'local_persistent_hnsw',
|
||||
'_client',
|
||||
'main'
|
||||
]:
|
||||
logging.getLogger(logger_name).setLevel(logging.WARNING)
|
||||
|
||||
# Disable OpenAI API request logging
|
||||
logging.getLogger('openai').setLevel(logging.WARNING)
|
||||
|
||||
# Set root logger to warning to catch any uncategorized logs
|
||||
logging.getLogger().setLevel(logging.WARNING)
|
||||
|
||||
@cached_property
|
||||
def _deps(self):
|
||||
try:
|
||||
from markitdown import MarkItDown
|
||||
import chromadb
|
||||
return {
|
||||
'chromadb': chromadb,
|
||||
'markdown': MarkItDown()
|
||||
}
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Required packages not installed. Please install using: "
|
||||
'pip install "praisonaiagents[knowledge]"'
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def config(self):
|
||||
# Generate unique collection name for each instance (only if not provided in config)
|
||||
default_collection = f"test_{int(time.time())}_{str(uuid.uuid4())[:8]}"
|
||||
persist_dir = ".praison"
|
||||
|
||||
# Create persistent client config
|
||||
base_config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": default_collection,
|
||||
"path": persist_dir,
|
||||
"client": self._deps['chromadb'].PersistentClient(path=persist_dir),
|
||||
"host": None,
|
||||
"port": None
|
||||
}
|
||||
},
|
||||
"version": "v1.1",
|
||||
"custom_prompt": "Return {{\"facts\": [text]}} where text is the exact input provided and json response"
|
||||
}
|
||||
|
||||
# If config is provided, merge it with base config
|
||||
if self._config:
|
||||
# Merge version if provided
|
||||
if "version" in self._config:
|
||||
base_config["version"] = self._config["version"]
|
||||
|
||||
# Merge vector_store config
|
||||
if "vector_store" in self._config:
|
||||
if "provider" in self._config["vector_store"]:
|
||||
base_config["vector_store"]["provider"] = self._config["vector_store"]["provider"]
|
||||
|
||||
if "config" in self._config["vector_store"]:
|
||||
config_copy = self._config["vector_store"]["config"].copy()
|
||||
# Only exclude client as it's managed internally
|
||||
if "client" in config_copy:
|
||||
del config_copy["client"]
|
||||
base_config["vector_store"]["config"].update(config_copy)
|
||||
|
||||
# Merge embedder config if provided
|
||||
if "embedder" in self._config:
|
||||
base_config["embedder"] = self._config["embedder"]
|
||||
|
||||
# Merge llm config if provided
|
||||
if "llm" in self._config:
|
||||
base_config["llm"] = self._config["llm"]
|
||||
return base_config
|
||||
|
||||
@cached_property
|
||||
def memory(self):
|
||||
try:
|
||||
return CustomMemory.from_config(self.config)
|
||||
except (NotImplementedError, ValueError) as e:
|
||||
if "list_collections" in str(e) or "Extra fields not allowed" in str(e):
|
||||
# Keep only allowed fields
|
||||
vector_store_config = {
|
||||
"collection_name": self.config["vector_store"]["config"]["collection_name"],
|
||||
"path": self.config["vector_store"]["config"]["path"]
|
||||
}
|
||||
self.config["vector_store"]["config"] = vector_store_config
|
||||
from mem0 import Memory
|
||||
return Memory.from_config(self.config)
|
||||
raise
|
||||
|
||||
@cached_property
|
||||
def markdown(self):
|
||||
return self._deps['markdown']
|
||||
|
||||
@cached_property
|
||||
def chunker(self):
|
||||
return Chunking(
|
||||
chunker_type='recursive',
|
||||
chunk_size=512,
|
||||
chunk_overlap=50
|
||||
)
|
||||
|
||||
def _log(self, message, level=2):
|
||||
"""Internal logging helper"""
|
||||
if self._verbose and self._verbose >= level:
|
||||
logger.info(message)
|
||||
|
||||
def store(self, content, user_id=None, agent_id=None, run_id=None, metadata=None):
|
||||
"""Store a memory."""
|
||||
try:
|
||||
if isinstance(content, str):
|
||||
if any(content.lower().endswith(ext) for ext in ['.pdf', '.doc', '.docx', '.txt']):
|
||||
self._log(f"Content appears to be a file path, processing file: {content}")
|
||||
return self.add(content, user_id=user_id, agent_id=agent_id, run_id=run_id, metadata=metadata)
|
||||
|
||||
content = content.strip()
|
||||
if not content:
|
||||
return []
|
||||
|
||||
result = self.memory.add(content, user_id=user_id, agent_id=agent_id, run_id=run_id, metadata=metadata)
|
||||
self._log(f"Store operation result: {result}")
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"Error storing content: {str(e)}")
|
||||
return []
|
||||
|
||||
def get_all(self, user_id=None, agent_id=None, run_id=None):
|
||||
"""Retrieve all memories."""
|
||||
return self.memory.get_all(user_id=user_id, agent_id=agent_id, run_id=run_id)
|
||||
|
||||
def get(self, memory_id):
|
||||
"""Retrieve a specific memory by ID."""
|
||||
return self.memory.get(memory_id)
|
||||
|
||||
def search(self, query, user_id=None, agent_id=None, run_id=None):
|
||||
"""Search for memories related to a query."""
|
||||
return self.memory.search(query, user_id=user_id, agent_id=agent_id, run_id=run_id)
|
||||
|
||||
def update(self, memory_id, data):
|
||||
"""Update a memory."""
|
||||
return self.memory.update(memory_id, data)
|
||||
|
||||
def history(self, memory_id):
|
||||
"""Get the history of changes for a memory."""
|
||||
return self.memory.history(memory_id)
|
||||
|
||||
def delete(self, memory_id):
|
||||
"""Delete a memory."""
|
||||
self.memory.delete(memory_id)
|
||||
|
||||
def delete_all(self, user_id=None, agent_id=None, run_id=None):
|
||||
"""Delete all memories."""
|
||||
self.memory.delete_all(user_id=user_id, agent_id=agent_id, run_id=run_id)
|
||||
|
||||
def reset(self):
|
||||
"""Reset all memories."""
|
||||
self.memory.reset()
|
||||
|
||||
def normalize_content(self, content):
|
||||
"""Normalize content for consistent storage."""
|
||||
# Example normalization: strip whitespace, convert to lowercase
|
||||
return content.strip().lower()
|
||||
|
||||
def add(self, file_path, user_id=None, agent_id=None, run_id=None, metadata=None):
|
||||
"""Read file content and store it in memory.
|
||||
|
||||
Args:
|
||||
file_path: Can be:
|
||||
- A string path to local file
|
||||
- A URL string
|
||||
- A list containing file paths and/or URLs
|
||||
"""
|
||||
if isinstance(file_path, (list, tuple)):
|
||||
results = []
|
||||
for path in file_path:
|
||||
result = self._process_single_input(path, user_id, agent_id, run_id, metadata)
|
||||
results.extend(result.get('results', []))
|
||||
return {'results': results, 'relations': []}
|
||||
|
||||
return self._process_single_input(file_path, user_id, agent_id, run_id, metadata)
|
||||
|
||||
def _process_single_input(self, input_path, user_id=None, agent_id=None, run_id=None, metadata=None):
|
||||
"""Process a single input which can be a file path or URL."""
|
||||
try:
|
||||
# Define supported file extensions
|
||||
DOCUMENT_EXTENSIONS = {
|
||||
'document': ('.pdf', '.ppt', '.pptx', '.doc', '.docx', '.xls', '.xlsx'),
|
||||
'media': ('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.mp3', '.wav', '.ogg', '.m4a'),
|
||||
'text': ('.txt', '.csv', '.json', '.xml', '.md', '.html', '.htm'),
|
||||
'archive': '.zip'
|
||||
}
|
||||
|
||||
# Check if input is URL
|
||||
if isinstance(input_path, str) and (input_path.startswith('http://') or input_path.startswith('https://')):
|
||||
self._log(f"Processing URL: {input_path}")
|
||||
raise NotImplementedError("URL processing not yet implemented")
|
||||
|
||||
# Check if input ends with any supported extension
|
||||
is_supported_file = any(input_path.lower().endswith(ext)
|
||||
for exts in DOCUMENT_EXTENSIONS.values()
|
||||
for ext in (exts if isinstance(exts, tuple) else (exts,)))
|
||||
|
||||
if is_supported_file:
|
||||
self._log(f"Processing as file path: {input_path}")
|
||||
if not os.path.exists(input_path):
|
||||
logger.error(f"File not found: {input_path}")
|
||||
raise FileNotFoundError(f"File not found: {input_path}")
|
||||
|
||||
file_ext = '.' + input_path.lower().split('.')[-1] # Get extension reliably
|
||||
|
||||
# Process file based on type
|
||||
if file_ext in DOCUMENT_EXTENSIONS['text']:
|
||||
with open(input_path, 'r', encoding='utf-8') as file:
|
||||
content = file.read().strip()
|
||||
if not content:
|
||||
raise ValueError("Empty text file")
|
||||
memories = [self.normalize_content(content)]
|
||||
else:
|
||||
# Use MarkItDown for documents and media
|
||||
result = self.markdown.convert(input_path)
|
||||
content = result.text_content
|
||||
if not content:
|
||||
raise ValueError("No content could be extracted from file")
|
||||
chunks = self.chunker.chunk(content)
|
||||
memories = [chunk.text.strip() if hasattr(chunk, 'text') else str(chunk).strip()
|
||||
for chunk in chunks if chunk]
|
||||
|
||||
# Set metadata for file
|
||||
if not metadata:
|
||||
metadata = {}
|
||||
metadata['file_type'] = file_ext.lstrip('.')
|
||||
metadata['filename'] = os.path.basename(input_path)
|
||||
else:
|
||||
# Treat as raw text content only if no file extension
|
||||
memories = [self.normalize_content(input_path)]
|
||||
|
||||
# Create progress display
|
||||
progress = Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
BarColumn(),
|
||||
TaskProgressColumn(),
|
||||
transient=True
|
||||
)
|
||||
|
||||
# Store memories with progress bar
|
||||
all_results = []
|
||||
with progress:
|
||||
store_task = progress.add_task(f"Adding to Knowledge from {os.path.basename(input_path)}", total=len(memories))
|
||||
for memory in memories:
|
||||
if memory:
|
||||
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', []))
|
||||
progress.advance(store_task)
|
||||
|
||||
return {'results': all_results, 'relations': []}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing input {input_path}: {str(e)}", exc_info=True)
|
||||
raise
|
||||
@@ -23,6 +23,10 @@ logging.basicConfig(
|
||||
handlers=[RichHandler(rich_tracebacks=True)]
|
||||
)
|
||||
|
||||
# Add these lines to suppress markdown parser debug logs
|
||||
logging.getLogger('markdown_it').setLevel(logging.WARNING)
|
||||
logging.getLogger('rich.markdown').setLevel(logging.WARNING)
|
||||
|
||||
# Global list to store error logs
|
||||
error_logs = []
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ try:
|
||||
CHROMADB_AVAILABLE = True
|
||||
except ImportError:
|
||||
CHROMADB_AVAILABLE = False
|
||||
logger.warning("To use memory features, please run: pip install \"praisonaiagents[memory]\"")
|
||||
pass
|
||||
|
||||
try:
|
||||
import mem0
|
||||
|
||||
@@ -5,19 +5,23 @@ from pydantic import BaseModel
|
||||
from ..agent.agent import Agent
|
||||
from ..task.task import Task
|
||||
from ..main import display_error, client
|
||||
import csv
|
||||
import os
|
||||
|
||||
class LoopItems(BaseModel):
|
||||
items: List[Any]
|
||||
|
||||
class Process:
|
||||
def __init__(self, tasks: Dict[str, Task], agents: List[Agent], manager_llm: Optional[str] = None, verbose: bool = False):
|
||||
def __init__(self, tasks: Dict[str, Task], agents: List[Agent], manager_llm: Optional[str] = None, verbose: bool = False, max_iter: int = 10):
|
||||
self.tasks = tasks
|
||||
self.agents = agents
|
||||
self.manager_llm = manager_llm
|
||||
self.verbose = verbose
|
||||
self.max_iter = max_iter
|
||||
|
||||
async def aworkflow(self) -> AsyncGenerator[str, None]:
|
||||
"""Async version of workflow method"""
|
||||
current_iter = 0 # Track how many times we've looped
|
||||
# Build workflow relationships first
|
||||
for task in self.tasks.values():
|
||||
if task.next_tasks:
|
||||
@@ -41,7 +45,12 @@ class Process:
|
||||
visited_tasks = set()
|
||||
loop_data = {} # Store loop-specific data
|
||||
|
||||
while current_task and current_task.id not in visited_tasks:
|
||||
while current_task:
|
||||
current_iter += 1
|
||||
if current_iter > self.max_iter:
|
||||
logging.info(f"Max iteration limit {self.max_iter} reached, ending workflow.")
|
||||
break
|
||||
|
||||
task_id = current_task.id
|
||||
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
|
||||
|
||||
@@ -55,46 +64,47 @@ class Process:
|
||||
if prev_task and prev_task.result:
|
||||
# Handle loop data
|
||||
if current_task.task_type == "loop":
|
||||
# create a loop manager Agent
|
||||
loop_manager = Agent(
|
||||
name="Loop Manager",
|
||||
role="Loop data processor",
|
||||
goal="Process loop data and convert it to list format",
|
||||
backstory="Expert at handling loop data and converting it to proper format",
|
||||
llm=self.manager_llm,
|
||||
verbose=self.verbose,
|
||||
markdown=True
|
||||
)
|
||||
# # create a loop manager Agent
|
||||
# loop_manager = Agent(
|
||||
# name="Loop Manager",
|
||||
# role="Loop data processor",
|
||||
# goal="Process loop data and convert it to list format",
|
||||
# backstory="Expert at handling loop data and converting it to proper format",
|
||||
# llm=self.manager_llm,
|
||||
# verbose=self.verbose,
|
||||
# markdown=True
|
||||
# )
|
||||
|
||||
# get the loop data convert it to list using calling Agent class chat
|
||||
loop_prompt = f"""
|
||||
Process this data into a list format:
|
||||
{prev_task.result.raw}
|
||||
# # get the loop data convert it to list using calling Agent class chat
|
||||
# loop_prompt = f"""
|
||||
# Process this data into a list format:
|
||||
# {prev_task.result.raw}
|
||||
|
||||
Return a JSON object with an 'items' array containing the items to process.
|
||||
"""
|
||||
if current_task.async_execution:
|
||||
loop_data_str = await loop_manager.achat(
|
||||
prompt=loop_prompt,
|
||||
output_json=LoopItems
|
||||
)
|
||||
else:
|
||||
loop_data_str = loop_manager.chat(
|
||||
prompt=loop_prompt,
|
||||
output_json=LoopItems
|
||||
)
|
||||
# Return a JSON object with an 'items' array containing the items to process.
|
||||
# """
|
||||
# if current_task.async_execution:
|
||||
# loop_data_str = await loop_manager.achat(
|
||||
# prompt=loop_prompt,
|
||||
# output_json=LoopItems
|
||||
# )
|
||||
# else:
|
||||
# loop_data_str = loop_manager.chat(
|
||||
# prompt=loop_prompt,
|
||||
# output_json=LoopItems
|
||||
# )
|
||||
|
||||
try:
|
||||
# The response will already be parsed into LoopItems model
|
||||
loop_data[f"loop_{current_task.name}"] = {
|
||||
"items": loop_data_str.items,
|
||||
"index": 0,
|
||||
"remaining": len(loop_data_str.items)
|
||||
}
|
||||
context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
||||
except Exception as e:
|
||||
display_error(f"Failed to process loop data: {e}")
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
# try:
|
||||
# # The response will already be parsed into LoopItems model
|
||||
# loop_data[f"loop_{current_task.name}"] = {
|
||||
# "items": loop_data_str.items,
|
||||
# "index": 0,
|
||||
# "remaining": len(loop_data_str.items)
|
||||
# }
|
||||
# context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
||||
# except Exception as e:
|
||||
# display_error(f"Failed to process loop data: {e}")
|
||||
# context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
else:
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
|
||||
@@ -111,6 +121,11 @@ Return a JSON object with an 'items' array containing the items to process.
|
||||
yield task_id
|
||||
visited_tasks.add(task_id)
|
||||
|
||||
# Reset completed task to "not started" so it can run again
|
||||
if self.tasks[task_id].status == "completed":
|
||||
logging.debug(f"Task {task_id} was completed, resetting to 'not started' for next iteration.")
|
||||
self.tasks[task_id].status = "not started"
|
||||
|
||||
# Handle loop progression
|
||||
if current_task.task_type == "loop":
|
||||
loop_key = f"loop_{current_task.name}"
|
||||
@@ -130,22 +145,32 @@ Return a JSON object with an 'items' array containing the items to process.
|
||||
|
||||
# Determine next task based on result
|
||||
next_task = None
|
||||
if current_task.result:
|
||||
if current_task and current_task.result:
|
||||
if current_task.task_type in ["decision", "loop"]:
|
||||
result = current_task.result.raw.lower()
|
||||
# MINIMAL CHANGE: use pydantic decision if present
|
||||
decision_str = current_task.result.raw.lower()
|
||||
if current_task.result.pydantic and hasattr(current_task.result.pydantic, "decision"):
|
||||
decision_str = current_task.result.pydantic.decision.lower()
|
||||
|
||||
# Check conditions
|
||||
for condition, tasks in current_task.condition.items():
|
||||
if condition.lower() in result and tasks:
|
||||
next_task_name = tasks[0]
|
||||
if condition.lower() == decision_str:
|
||||
# Handle both list and direct string values
|
||||
task_value = tasks[0] if isinstance(tasks, list) else tasks
|
||||
if not task_value or task_value == "exit":
|
||||
logging.info("Workflow exit condition met, ending workflow")
|
||||
current_task = None
|
||||
break
|
||||
next_task_name = task_value
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
# For loops, allow revisiting the same task
|
||||
if next_task and next_task.id == current_task.id:
|
||||
visited_tasks.discard(current_task.id)
|
||||
break
|
||||
|
||||
if not next_task and current_task.next_tasks:
|
||||
next_task_name = current_task.next_tasks[0]
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
if not next_task and current_task and current_task.next_tasks:
|
||||
next_task_name = current_task.next_tasks[0]
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
|
||||
current_task = next_task
|
||||
if not current_task:
|
||||
@@ -285,6 +310,7 @@ Provide a JSON with the structure:
|
||||
|
||||
def workflow(self):
|
||||
"""Synchronous version of workflow method"""
|
||||
current_iter = 0 # Track how many times we've looped
|
||||
# Build workflow relationships first
|
||||
for task in self.tasks.values():
|
||||
if task.next_tasks:
|
||||
@@ -303,12 +329,86 @@ Provide a JSON with the structure:
|
||||
if not start_task:
|
||||
start_task = list(self.tasks.values())[0]
|
||||
logging.info("No start task marked, using first task")
|
||||
|
||||
|
||||
# If loop type and no input_file, default to tasks.csv
|
||||
if start_task and start_task.task_type == "loop" and not start_task.input_file:
|
||||
start_task.input_file = "tasks.csv"
|
||||
|
||||
# --- If loop + input_file, read file & create tasks
|
||||
if start_task and start_task.task_type == "loop" and getattr(start_task, "input_file", None):
|
||||
try:
|
||||
file_ext = os.path.splitext(start_task.input_file)[1].lower()
|
||||
new_tasks = []
|
||||
|
||||
if file_ext == ".csv":
|
||||
# existing CSV reading logic
|
||||
with open(start_task.input_file, "r", encoding="utf-8") as f:
|
||||
# Try as simple CSV first
|
||||
reader = csv.reader(f)
|
||||
previous_task = None
|
||||
for i, row in enumerate(reader):
|
||||
if row: # Skip empty rows
|
||||
task_desc = row[0] # Take first column
|
||||
row_task = Task(
|
||||
description=task_desc, # Keep full row as description
|
||||
agent=start_task.agent,
|
||||
name=task_desc, # Use first column as name
|
||||
is_start=(i == 0),
|
||||
task_type="task",
|
||||
condition={
|
||||
"complete": ["next"],
|
||||
"retry": ["current"]
|
||||
}
|
||||
)
|
||||
self.tasks[row_task.id] = row_task
|
||||
new_tasks.append(row_task)
|
||||
|
||||
if previous_task:
|
||||
previous_task.next_tasks = [row_task.name]
|
||||
previous_task.condition["complete"] = [row_task.name]
|
||||
previous_task = row_task
|
||||
else:
|
||||
# If not CSV, read lines
|
||||
with open(start_task.input_file, "r", encoding="utf-8") as f:
|
||||
lines = f.read().splitlines()
|
||||
previous_task = None
|
||||
for i, line in enumerate(lines):
|
||||
row_task = Task(
|
||||
description=line.strip(),
|
||||
agent=start_task.agent,
|
||||
name=line.strip(),
|
||||
is_start=(i == 0),
|
||||
task_type="task",
|
||||
condition={
|
||||
"complete": ["next"],
|
||||
"retry": ["current"]
|
||||
}
|
||||
)
|
||||
self.tasks[row_task.id] = row_task
|
||||
new_tasks.append(row_task)
|
||||
|
||||
if previous_task:
|
||||
previous_task.next_tasks = [row_task.name]
|
||||
previous_task.condition["complete"] = [row_task.name]
|
||||
previous_task = row_task
|
||||
|
||||
if new_tasks:
|
||||
start_task = new_tasks[0]
|
||||
logging.info(f"Created {len(new_tasks)} tasks from: {start_task.input_file}")
|
||||
except Exception as e:
|
||||
logging.error(f"Failed to read file tasks: {e}")
|
||||
|
||||
# end of the new block
|
||||
current_task = start_task
|
||||
visited_tasks = set()
|
||||
loop_data = {} # Store loop-specific data
|
||||
|
||||
while current_task and current_task.id not in visited_tasks:
|
||||
while current_task:
|
||||
current_iter += 1
|
||||
if current_iter > self.max_iter:
|
||||
logging.info(f"Max iteration limit {self.max_iter} reached, ending workflow.")
|
||||
break
|
||||
|
||||
task_id = current_task.id
|
||||
logging.info(f"Executing workflow task: {current_task.name if current_task.name else task_id}")
|
||||
|
||||
@@ -322,40 +422,41 @@ Provide a JSON with the structure:
|
||||
if prev_task and prev_task.result:
|
||||
# Handle loop data
|
||||
if current_task.task_type == "loop":
|
||||
# create a loop manager Agent
|
||||
loop_manager = Agent(
|
||||
name="Loop Manager",
|
||||
role="Loop data processor",
|
||||
goal="Process loop data and convert it to list format",
|
||||
backstory="Expert at handling loop data and converting it to proper format",
|
||||
llm=self.manager_llm,
|
||||
verbose=self.verbose,
|
||||
markdown=True
|
||||
)
|
||||
# # create a loop manager Agent
|
||||
# loop_manager = Agent(
|
||||
# name="Loop Manager",
|
||||
# role="Loop data processor",
|
||||
# goal="Process loop data and convert it to list format",
|
||||
# backstory="Expert at handling loop data and converting it to proper format",
|
||||
# llm=self.manager_llm,
|
||||
# verbose=self.verbose,
|
||||
# markdown=True
|
||||
# )
|
||||
|
||||
# get the loop data convert it to list using calling Agent class chat
|
||||
loop_prompt = f"""
|
||||
Process this data into a list format:
|
||||
{prev_task.result.raw}
|
||||
# # get the loop data convert it to list using calling Agent class chat
|
||||
# loop_prompt = f"""
|
||||
# Process this data into a list format:
|
||||
# {prev_task.result.raw}
|
||||
|
||||
Return a JSON object with an 'items' array containing the items to process.
|
||||
"""
|
||||
loop_data_str = loop_manager.chat(
|
||||
prompt=loop_prompt,
|
||||
output_json=LoopItems
|
||||
)
|
||||
# Return a JSON object with an 'items' array containing the items to process.
|
||||
# """
|
||||
# loop_data_str = loop_manager.chat(
|
||||
# prompt=loop_prompt,
|
||||
# output_json=LoopItems
|
||||
# )
|
||||
|
||||
try:
|
||||
# The response will already be parsed into LoopItems model
|
||||
loop_data[f"loop_{current_task.name}"] = {
|
||||
"items": loop_data_str.items,
|
||||
"index": 0,
|
||||
"remaining": len(loop_data_str.items)
|
||||
}
|
||||
context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
||||
except Exception as e:
|
||||
display_error(f"Failed to process loop data: {e}")
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
# try:
|
||||
# # The response will already be parsed into LoopItems model
|
||||
# loop_data[f"loop_{current_task.name}"] = {
|
||||
# "items": loop_data_str.items,
|
||||
# "index": 0,
|
||||
# "remaining": len(loop_data_str.items)
|
||||
# }
|
||||
# context += f"\nCurrent loop item: {loop_data_str.items[0]}"
|
||||
# except Exception as e:
|
||||
# display_error(f"Failed to process loop data: {e}")
|
||||
# context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
else:
|
||||
context += f"\n{prev_name}: {prev_task.result.raw}"
|
||||
|
||||
@@ -372,6 +473,11 @@ Return a JSON object with an 'items' array containing the items to process.
|
||||
yield task_id
|
||||
visited_tasks.add(task_id)
|
||||
|
||||
# Reset completed task to "not started" so it can run again: Only for workflow because some tasks may be revisited
|
||||
if self.tasks[task_id].status == "completed":
|
||||
logging.debug(f"Task {task_id} was completed, resetting to 'not started' for next iteration.")
|
||||
self.tasks[task_id].status = "not started"
|
||||
|
||||
# Handle loop progression
|
||||
if current_task.task_type == "loop":
|
||||
loop_key = f"loop_{current_task.name}"
|
||||
@@ -391,22 +497,32 @@ Return a JSON object with an 'items' array containing the items to process.
|
||||
|
||||
# Determine next task based on result
|
||||
next_task = None
|
||||
if current_task.result:
|
||||
if current_task and current_task.result:
|
||||
if current_task.task_type in ["decision", "loop"]:
|
||||
result = current_task.result.raw.lower()
|
||||
# MINIMAL CHANGE: use pydantic decision if present
|
||||
decision_str = current_task.result.raw.lower()
|
||||
if current_task.result.pydantic and hasattr(current_task.result.pydantic, "decision"):
|
||||
decision_str = current_task.result.pydantic.decision.lower()
|
||||
|
||||
# Check conditions
|
||||
for condition, tasks in current_task.condition.items():
|
||||
if condition.lower() in result and tasks:
|
||||
next_task_name = tasks[0]
|
||||
if condition.lower() == decision_str:
|
||||
# Handle both list and direct string values
|
||||
task_value = tasks[0] if isinstance(tasks, list) else tasks
|
||||
if not task_value or task_value == "exit":
|
||||
logging.info("Workflow exit condition met, ending workflow")
|
||||
current_task = None
|
||||
break
|
||||
next_task_name = task_value
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
# For loops, allow revisiting the same task
|
||||
if next_task and next_task.id == current_task.id:
|
||||
visited_tasks.discard(current_task.id)
|
||||
break
|
||||
|
||||
if not next_task and current_task.next_tasks:
|
||||
next_task_name = current_task.next_tasks[0]
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
if not next_task and current_task and current_task.next_tasks:
|
||||
next_task_name = current_task.next_tasks[0]
|
||||
next_task = next((t for t in self.tasks.values() if t.name == next_task_name), None)
|
||||
|
||||
current_task = next_task
|
||||
if not current_task:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import logging
|
||||
import asyncio
|
||||
from typing import List, Optional, Dict, Any, Type, Callable, Union, Coroutine
|
||||
from typing import List, Optional, Dict, Any, Type, Callable, Union, Coroutine, Literal
|
||||
from pydantic import BaseModel
|
||||
from ..main import TaskOutput
|
||||
from ..agent.agent import Agent
|
||||
@@ -19,7 +19,7 @@ class Task:
|
||||
agent: Optional[Agent] = None,
|
||||
name: Optional[str] = None,
|
||||
tools: Optional[List[Any]] = None,
|
||||
context: Optional[List["Task"]] = None,
|
||||
context: Optional[List[Union[str, List, 'Task']]] = None,
|
||||
async_execution: Optional[bool] = False,
|
||||
config: Optional[Dict[str, Any]] = None,
|
||||
output_file: Optional[str] = None,
|
||||
@@ -37,8 +37,21 @@ class Task:
|
||||
is_start: bool = False,
|
||||
loop_state: Optional[Dict[str, Union[str, int]]] = None,
|
||||
memory=None,
|
||||
quality_check=True
|
||||
quality_check=True,
|
||||
input_file: Optional[str] = None
|
||||
):
|
||||
# Add check if memory config is provided
|
||||
if memory is not None or (config and config.get('memory_config')):
|
||||
try:
|
||||
from ..memory.memory import Memory
|
||||
MEMORY_AVAILABLE = True
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"Memory features requested in Task but memory dependencies not installed. "
|
||||
"Please install with: pip install \"praisonaiagents[memory]\""
|
||||
)
|
||||
|
||||
self.input_file = input_file
|
||||
self.id = str(uuid.uuid4()) if id is None else str(id)
|
||||
self.name = name
|
||||
self.description = description
|
||||
@@ -83,6 +96,47 @@ class Task:
|
||||
# Track previous tasks based on next_tasks relationships
|
||||
self.previous_tasks = []
|
||||
|
||||
# If task_type="decision" and output_pydantic is not set
|
||||
if self.task_type == "decision" and not self.output_pydantic:
|
||||
from pydantic import BaseModel
|
||||
from typing import Literal
|
||||
|
||||
# Gather condition keys for the "decision" field
|
||||
condition_keys = list(self.condition.keys())
|
||||
if not condition_keys:
|
||||
# Fall back to placeholders if nothing is specified
|
||||
condition_keys = ["next_task", "exit"]
|
||||
|
||||
# Create a dynamic literal type from condition keys
|
||||
DecisionLiteral = Literal.__getitem__(tuple(condition_keys))
|
||||
|
||||
class DecisionModel(BaseModel):
|
||||
response: str
|
||||
decision: DecisionLiteral
|
||||
|
||||
self.output_pydantic = DecisionModel
|
||||
|
||||
# If task_type="loop" and output_pydantic is not set
|
||||
if self.task_type == "loop" and not self.output_pydantic:
|
||||
from pydantic import BaseModel
|
||||
from typing import Literal
|
||||
|
||||
# Gather condition keys for the "decision" field
|
||||
condition_keys = list(self.condition.keys())
|
||||
if not condition_keys:
|
||||
# Fall back to placeholders if nothing is specified
|
||||
condition_keys = ["next_item", "exit"]
|
||||
|
||||
# Create a dynamic literal type
|
||||
LoopLiteral = Literal.__getitem__(tuple(condition_keys))
|
||||
|
||||
class LoopModel(BaseModel):
|
||||
response: str
|
||||
decision: LoopLiteral
|
||||
loop_id: str # Additional field for loop
|
||||
|
||||
self.output_pydantic = LoopModel
|
||||
|
||||
def __str__(self):
|
||||
return f"Task(name='{self.name if self.name else 'None'}', description='{self.description}', agent='{self.agent.name if self.agent else 'None'}', status='{self.status}')"
|
||||
|
||||
@@ -219,4 +273,33 @@ class Task:
|
||||
self.callback(task_output)
|
||||
except Exception as e:
|
||||
logger.error(f"Task {self.id}: Failed to execute callback: {e}")
|
||||
logger.exception(e)
|
||||
logger.exception(e)
|
||||
|
||||
task_prompt = f"""
|
||||
You need to do the following task: {self.description}.
|
||||
Expected Output: {self.expected_output}.
|
||||
"""
|
||||
if self.context:
|
||||
context_results = [] # Use list to avoid duplicates
|
||||
for context_item in self.context:
|
||||
if isinstance(context_item, str):
|
||||
context_results.append(f"Input Content:\n{context_item}")
|
||||
elif isinstance(context_item, list):
|
||||
context_results.append(f"Input Content: {' '.join(str(x) for x in context_item)}")
|
||||
elif hasattr(context_item, 'result'): # Task object
|
||||
if context_item.result:
|
||||
context_results.append(
|
||||
f"Result of previous task {context_item.name if context_item.name else context_item.description}:\n{context_item.result.raw}"
|
||||
)
|
||||
else:
|
||||
context_results.append(
|
||||
f"Previous task {context_item.name if context_item.name else context_item.description} has no result yet."
|
||||
)
|
||||
|
||||
# Join unique context results
|
||||
unique_contexts = list(dict.fromkeys(context_results)) # Remove duplicates
|
||||
task_prompt += f"""
|
||||
Context:
|
||||
|
||||
{' '.join(unique_contexts)}
|
||||
"""
|
||||
@@ -160,6 +160,9 @@ class PandasTools:
|
||||
Dict: Summary statistics and information
|
||||
"""
|
||||
try:
|
||||
if not isinstance(df, pd.DataFrame):
|
||||
raise TypeError(f"Expected pandas DataFrame, got {type(df).__name__}")
|
||||
|
||||
numeric_summary = df.describe().to_dict()
|
||||
# Convert numpy types to native Python types
|
||||
for col in numeric_summary:
|
||||
|
||||
@@ -145,7 +145,15 @@ class YFinanceTools:
|
||||
return [{"error": "yfinance package not available"}]
|
||||
|
||||
hist = ticker.history(period=period, interval=interval, start=start, end=end)
|
||||
return hist.reset_index().to_dict('records')
|
||||
data = hist.reset_index().to_dict('records')
|
||||
|
||||
# Convert timestamps to ISO format strings
|
||||
for record in data:
|
||||
if 'Date' in record and hasattr(record['Date'], 'isoformat'):
|
||||
record['Date'] = record['Date'].isoformat()
|
||||
if 'Datetime' in record and hasattr(record['Datetime'], 'isoformat'):
|
||||
record['Datetime'] = record['Datetime'].isoformat()
|
||||
return data
|
||||
except Exception as e:
|
||||
error_msg = f"Error fetching historical data: {str(e)}"
|
||||
logging.error(error_msg)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import execute_code, analyze_code, format_code, lint_code, disassemble_code # Code Tools
|
||||
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info # Shell Tools
|
||||
from praisonaiagents.tools import duckduckgo # Web Search Tool
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Programming Agent", self_reflect=True, min_reflect=5, max_reflect=10,
|
||||
tools=[execute_code, analyze_code, format_code, lint_code, disassemble_code, execute_command, list_processes, kill_process, get_system_info, duckduckgo]
|
||||
)
|
||||
agent.start(
|
||||
"Write a python script using yfinance to find the stock price of Tesla"
|
||||
"First check if required packages are installed"
|
||||
"Run it using execute_code"
|
||||
"execute_command if you want to run any terminal command"
|
||||
"search internet using duckduckgo if you want to know update python package information"
|
||||
"Analyse the output using analyze_code and fix error if required"
|
||||
"if no package is installed, install it"
|
||||
"then run the code"
|
||||
)
|
||||
@@ -0,0 +1,91 @@
|
||||
from praisonaiagents.agent import Agent
|
||||
from praisonaiagents.task import Task
|
||||
from praisonaiagents.agents import PraisonAIAgents
|
||||
from typing import List, Dict
|
||||
import time
|
||||
|
||||
def get_time_check():
|
||||
current_time = int(time.time())
|
||||
result = "even" if current_time % 2 == 0 else "odd"
|
||||
print(f"Time check: {current_time} is {result}")
|
||||
return result
|
||||
|
||||
def create_prompt_chain():
|
||||
# Create agents for each step in the chain
|
||||
agent1 = Agent(
|
||||
name="Time Checker",
|
||||
role="Time checker",
|
||||
goal="Check if the time is even or odd",
|
||||
instructions="Check if the time is even or odd",
|
||||
tools=[get_time_check]
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
name="Advanced Analyzer",
|
||||
role="Advanced data analyzer",
|
||||
goal="Perform in-depth analysis of processed data",
|
||||
instructions="Analyze the processed data in detail"
|
||||
)
|
||||
|
||||
agent3 = Agent(
|
||||
name="Final Processor",
|
||||
role="Final data processor",
|
||||
goal="Generate final output based on analysis",
|
||||
instructions="Create final output based on analyzed data"
|
||||
)
|
||||
|
||||
# Create tasks for each step
|
||||
initial_task = Task(
|
||||
name="time_check",
|
||||
description="Getting time check and checking if it is even or odd",
|
||||
expected_output="Getting time check and checking if it is even or odd",
|
||||
agent=agent1,
|
||||
is_start=True, # Mark as the starting task
|
||||
task_type="decision", # This task will make a decision
|
||||
next_tasks=["advanced_analysis"], # Next task if condition passes
|
||||
condition={
|
||||
"even": ["advanced_analysis"], # If passes, go to advanced analysis
|
||||
"odd": ["final_processing"] # If fails, exit the chain
|
||||
}
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
name="advanced_analysis",
|
||||
description="Perform advanced analysis on the processed data",
|
||||
expected_output="Analyzed data ready for final processing",
|
||||
agent=agent2,
|
||||
next_tasks=["final_processing"]
|
||||
)
|
||||
|
||||
final_task = Task(
|
||||
name="final_processing",
|
||||
description="Generate final output",
|
||||
expected_output="Final processed result",
|
||||
agent=agent3
|
||||
)
|
||||
|
||||
# Create the workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[agent1, agent2, agent3],
|
||||
tasks=[initial_task, analysis_task, final_task],
|
||||
process="workflow", # Use workflow process type
|
||||
verbose=True
|
||||
)
|
||||
|
||||
return workflow
|
||||
|
||||
def main():
|
||||
# Create and run the prompt chain
|
||||
workflow = create_prompt_chain()
|
||||
|
||||
# Run the workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nWorkflow Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,78 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import time
|
||||
|
||||
def get_time_check():
|
||||
current_time = int(time.time())
|
||||
result = "even" if current_time % 2 == 0 else "odd"
|
||||
print(f"Time check: {current_time} is {result}")
|
||||
return result
|
||||
|
||||
# Create agents for each step in the chain
|
||||
agent1 = Agent(
|
||||
name="Time Checker",
|
||||
role="Time checker",
|
||||
goal="Check if the time is even or odd",
|
||||
instructions="Check if the time is even or odd",
|
||||
tools=[get_time_check]
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
name="Advanced Analyzer",
|
||||
role="Advanced data analyzer",
|
||||
goal="Perform in-depth analysis of processed data",
|
||||
instructions="Analyze the processed data in detail"
|
||||
)
|
||||
|
||||
agent3 = Agent(
|
||||
name="Final Processor",
|
||||
role="Final data processor",
|
||||
goal="Generate final output based on analysis",
|
||||
instructions="Create final output based on analyzed data"
|
||||
)
|
||||
|
||||
# Create tasks for each step
|
||||
initial_task = Task(
|
||||
name="time_check",
|
||||
description="Getting time check and checking if it is even or odd",
|
||||
expected_output="Getting time check and checking if it is even or odd",
|
||||
agent=agent1,
|
||||
is_start=True, # Mark as the starting task
|
||||
task_type="decision", # This task will make a decision
|
||||
next_tasks=["advanced_analysis"], # Next task if condition passes
|
||||
condition={
|
||||
"even": ["advanced_analysis"], # If passes, go to advanced analysis
|
||||
"odd": "exit" # If fails, exit the chain
|
||||
}
|
||||
)
|
||||
|
||||
analysis_task = Task(
|
||||
name="advanced_analysis",
|
||||
description="Perform advanced analysis on the processed data",
|
||||
expected_output="Analyzed data ready for final processing",
|
||||
agent=agent2,
|
||||
next_tasks=["final_processing"]
|
||||
)
|
||||
|
||||
final_task = Task(
|
||||
name="final_processing",
|
||||
description="Generate final output",
|
||||
expected_output="Final processed result",
|
||||
agent=agent3
|
||||
)
|
||||
|
||||
# Create the workflow manager
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[agent1, agent2, agent3],
|
||||
tasks=[initial_task, analysis_task, final_task],
|
||||
process="workflow", # Use workflow process type
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Run the workflow
|
||||
results = workflow.start()
|
||||
|
||||
# Print results
|
||||
print("\nWorkflow Results:")
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
print(f"Task {task_id}: {result.raw}")
|
||||
+16
-3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "praisonaiagents"
|
||||
version = "0.0.31"
|
||||
version = "0.0.46"
|
||||
description = "Praison AI agents for completing complex tasks with Self Reflection Agents"
|
||||
authors = [
|
||||
{ name="Mervin Praison" }
|
||||
@@ -17,5 +17,18 @@ dependencies = [
|
||||
|
||||
[project.optional-dependencies]
|
||||
memory = [
|
||||
"chromadb>=0.6.0"
|
||||
]
|
||||
"chromadb>=0.5.23"
|
||||
]
|
||||
|
||||
knowledge = [
|
||||
"mem0ai>=0.1.0",
|
||||
"chromadb==0.5.23",
|
||||
"markitdown",
|
||||
"chonkie"
|
||||
]
|
||||
|
||||
# Combined features
|
||||
all = [
|
||||
"praisonaiagents[memory]",
|
||||
"praisonaiagents[knowledge]"
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Recommendation Agent", tools=[duckduckgo])
|
||||
agent.start("Recommend me a good movie to watch in 2025")
|
||||
@@ -0,0 +1,22 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a loop agent that creating a loop of tasks.",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
task = Task(
|
||||
description="Create the list of tasks to be looped through.",
|
||||
agent=agent,
|
||||
task_type="loop",
|
||||
input_file="tasks.csv"
|
||||
)
|
||||
|
||||
agents = PraisonAIAgents(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
process="workflow",
|
||||
max_iter=30
|
||||
)
|
||||
|
||||
agents.start()
|
||||
@@ -0,0 +1,139 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import read_csv, write_csv
|
||||
import pandas as pd
|
||||
|
||||
def read_csv_smart(csv_path: str) -> pd.DataFrame:
|
||||
"""Read CSV and use first column as task, handling both header/no-header cases"""
|
||||
# Try reading with headers first
|
||||
df = pd.read_csv(csv_path)
|
||||
|
||||
# Check if first row looks like data
|
||||
if not any(col.lower() in ['task', 'description', 'status', 'state'] for col in df.columns):
|
||||
# If no header-like names found, read without headers
|
||||
df = pd.read_csv(csv_path, header=None)
|
||||
|
||||
# Rename columns consistently
|
||||
df.columns = [*['task'], *[f'col_{i}' for i in range(1, len(df.columns))]]
|
||||
if 'status' not in df.columns:
|
||||
df['status'] = 'pending'
|
||||
if 'loop_id' not in df.columns:
|
||||
# Start loop_id from 1 instead of 0
|
||||
df['loop_id'] = (df.index + 1).astype(str)
|
||||
return df[['task', 'status', 'loop_id']]
|
||||
|
||||
def has_pending_tasks(df: pd.DataFrame) -> bool:
|
||||
"""Check if there are any pending tasks in the DataFrame"""
|
||||
return not df[df['status'] == 'pending'].empty
|
||||
|
||||
def check_task_status(csv_path: str) -> dict:
|
||||
"""Read task status from CSV file"""
|
||||
try:
|
||||
# Always read directly from CSV file
|
||||
df = pd.read_csv(csv_path, keep_default_na=False)
|
||||
|
||||
# Get only pending tasks from original status
|
||||
pending_tasks = df[df['status'].str.lower() == 'pending']
|
||||
|
||||
if not pending_tasks.empty:
|
||||
task_data = pending_tasks.iloc[0].to_dict()
|
||||
return {
|
||||
'has_pending': True,
|
||||
'next_task': task_data
|
||||
}
|
||||
return {'has_pending': False, 'next_task': None}
|
||||
except Exception as e:
|
||||
print(f"Error reading CSV: {e}")
|
||||
return {'has_pending': False, 'next_task': None, 'error': str(e)}
|
||||
|
||||
def get_next_task() -> dict:
|
||||
"""Get the next pending task from CSV"""
|
||||
status = check_task_status("tasks.csv")
|
||||
if status['has_pending'] and status['next_task']:
|
||||
task = status['next_task']
|
||||
if task['status'].lower() == 'pending':
|
||||
return {
|
||||
'loop_data': {
|
||||
'task': task['task'],
|
||||
'loop_id': task['loop_id'],
|
||||
'status': task['status']
|
||||
}
|
||||
}
|
||||
return None
|
||||
|
||||
def update_task_status(loop_id: str, new_status: str) -> bool:
|
||||
"""Update task status in CSV file using loop_id as identifier"""
|
||||
try:
|
||||
# Read directly from CSV file
|
||||
df = pd.read_csv("tasks.csv", keep_default_na=False)
|
||||
df['loop_id'] = df['loop_id'].astype(str)
|
||||
mask = df['loop_id'] == str(loop_id)
|
||||
if mask.any():
|
||||
df.loc[mask, 'status'] = new_status
|
||||
df.to_csv("tasks.csv", index=False)
|
||||
return True
|
||||
print(f"No task found with loop_id: {loop_id}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Error updating status: {e}")
|
||||
return False
|
||||
|
||||
identify_agent = Agent(
|
||||
name="Identify Agent",
|
||||
role="Pending Task Identifier",
|
||||
goal="Identify the next pending task",
|
||||
tools=[get_next_task],
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create the repetitive agent
|
||||
repetitive_agent = Agent(
|
||||
name="TaskProcessor",
|
||||
role="Task Processing Specialist",
|
||||
goal="Complete the task response",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
update_status_agent = Agent(
|
||||
name="UpdateStatusAgent",
|
||||
role="Status Updater",
|
||||
goal="Update the status of the task in CSV",
|
||||
tools=[update_task_status],
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Define the repetitive task
|
||||
identify_task = Task(
|
||||
name="identify_task",
|
||||
description="Identify the next pending task. If there are no pending tasks decision is completed.",
|
||||
agent=identify_agent,
|
||||
task_type="loop",
|
||||
condition={
|
||||
"pending": ["process_task"],
|
||||
"completed": "exit"
|
||||
}
|
||||
)
|
||||
|
||||
process_task = Task(
|
||||
name="process_task",
|
||||
description="Complete the task mentioned in the response",
|
||||
agent=repetitive_agent,
|
||||
context=[identify_task],
|
||||
task_type="loop",
|
||||
next_tasks=["update_task"]
|
||||
)
|
||||
|
||||
update_task = Task(
|
||||
name="update_task",
|
||||
description="Update the task status",
|
||||
agent=update_status_agent,
|
||||
next_tasks= ["identify_task"]
|
||||
)
|
||||
|
||||
# Create and run agents manager
|
||||
agents = PraisonAIAgents(
|
||||
agents=[identify_agent, repetitive_agent],
|
||||
tasks=[identify_task, process_task, update_task],
|
||||
process="workflow"
|
||||
)
|
||||
|
||||
agents.start()
|
||||
@@ -0,0 +1,15 @@
|
||||
# Core dependencies
|
||||
pydantic
|
||||
rich
|
||||
openai>=1.30.0
|
||||
|
||||
# Memory dependencies
|
||||
chromadb>=0.5.23
|
||||
|
||||
# Knowledge dependencies
|
||||
mem0ai>=0.1.0
|
||||
markitdown
|
||||
chonkie
|
||||
|
||||
# Development dependencies
|
||||
python-dotenv>=0.19.0
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
|
||||
agent.start("Research about AI 2024")
|
||||
@@ -0,0 +1,82 @@
|
||||
from praisonaiagents.agent import Agent
|
||||
from praisonaiagents.task import Task
|
||||
from praisonaiagents.agents import PraisonAIAgents
|
||||
import time
|
||||
|
||||
current_time = int(time.time())
|
||||
result = "even" if current_time % 2 == 0 else "odd"
|
||||
print(f"Time check: {current_time} is {result}")
|
||||
|
||||
# Create specialized agents
|
||||
router = Agent(
|
||||
name="Router",
|
||||
role="Input Router",
|
||||
goal="Evaluate input and determine routing path",
|
||||
instructions="Analyze input and decide whether to proceed or exit",
|
||||
tools=[get_time_check]
|
||||
)
|
||||
|
||||
processor1 = Agent(
|
||||
name="Processor 1",
|
||||
role="Secondary Processor",
|
||||
goal="Process valid inputs that passed initial check",
|
||||
instructions="Process data that passed the routing check"
|
||||
)
|
||||
|
||||
processor2 = Agent(
|
||||
name="Processor 2",
|
||||
role="Final Processor",
|
||||
goal="Perform final processing on validated data",
|
||||
instructions="Generate final output for processed data"
|
||||
)
|
||||
|
||||
# Create tasks with routing logic
|
||||
routing_task = Task(
|
||||
name="initial_routing",
|
||||
description="check the time and return according to what is returned",
|
||||
expected_output="pass or fail based on what is returned",
|
||||
agent=router,
|
||||
is_start=True,
|
||||
task_type="decision",
|
||||
condition={
|
||||
"pass": ["process_valid"],
|
||||
"fail": "exit"
|
||||
}
|
||||
)
|
||||
|
||||
processing_task = Task(
|
||||
name="process_valid",
|
||||
description="Process validated input",
|
||||
expected_output="Processed data ready for final step",
|
||||
agent=processor1,
|
||||
next_tasks=["final_process"]
|
||||
)
|
||||
|
||||
final_task = Task(
|
||||
name="final_process",
|
||||
description="Generate final output",
|
||||
expected_output="Final processed result",
|
||||
agent=processor2
|
||||
)
|
||||
|
||||
# Create and run workflow
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[router, processor1, processor2],
|
||||
tasks=[routing_task, processing_task, final_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
print("\nStarting Routing Workflow...")
|
||||
print("=" * 50)
|
||||
|
||||
results = workflow.start()
|
||||
|
||||
print("\nWorkflow Results:")
|
||||
print("=" * 50)
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
task_name = result.description
|
||||
print(f"\nTask: {task_name}")
|
||||
print(f"Result: {result.raw}")
|
||||
print("-" * 50)
|
||||
@@ -0,0 +1,83 @@
|
||||
from praisonaiagents.agent import Agent
|
||||
from praisonaiagents.task import Task
|
||||
from praisonaiagents.agents import PraisonAIAgents
|
||||
import time
|
||||
|
||||
def get_time_check():
|
||||
current_time = int(time.time())
|
||||
result = "even" if current_time % 2 == 0 else "odd"
|
||||
print(f"Time check: {current_time} is {result}")
|
||||
return result
|
||||
|
||||
# Create specialized agents
|
||||
router = Agent(
|
||||
name="Router",
|
||||
role="Input Router",
|
||||
goal="Evaluate input and determine routing path",
|
||||
instructions="Analyze input and decide whether to proceed or exit",
|
||||
tools=[get_time_check]
|
||||
)
|
||||
|
||||
processor1 = Agent(
|
||||
name="Processor 1",
|
||||
role="Secondary Processor",
|
||||
goal="Process valid inputs that passed initial check",
|
||||
instructions="Process data that passed the routing check"
|
||||
)
|
||||
|
||||
processor2 = Agent(
|
||||
name="Processor 2",
|
||||
role="Final Processor",
|
||||
goal="Perform final processing on validated data",
|
||||
instructions="Generate final output for processed data"
|
||||
)
|
||||
|
||||
# Create tasks with routing logic
|
||||
routing_task = Task(
|
||||
name="initial_routing",
|
||||
description="check the time and return according to what is returned",
|
||||
expected_output="pass or fail based on what is returned",
|
||||
agent=router,
|
||||
is_start=True,
|
||||
task_type="decision",
|
||||
condition={
|
||||
"pass": ["process_valid"],
|
||||
"fail": ["process_invalid"]
|
||||
}
|
||||
)
|
||||
|
||||
processing_task = Task(
|
||||
name="process_valid",
|
||||
description="Process validated input",
|
||||
expected_output="Processed data ready for final step",
|
||||
agent=processor1,
|
||||
)
|
||||
|
||||
final_task = Task(
|
||||
name="process_invalid",
|
||||
description="Generate final output",
|
||||
expected_output="Final processed result",
|
||||
agent=processor2
|
||||
)
|
||||
|
||||
# Create and run workflow
|
||||
workflow = PraisonAIAgents(
|
||||
agents=[router, processor1, processor2],
|
||||
tasks=[routing_task, processing_task, final_task],
|
||||
process="workflow",
|
||||
verbose=True
|
||||
)
|
||||
|
||||
print("\nStarting Routing Workflow...")
|
||||
print("=" * 50)
|
||||
|
||||
results = workflow.start()
|
||||
|
||||
print("\nWorkflow Results:")
|
||||
print("=" * 50)
|
||||
for task_id, result in results["task_results"].items():
|
||||
if result:
|
||||
task_name = result.description
|
||||
print(f"\nTask: {task_name}")
|
||||
print(f"Result: {result.raw}")
|
||||
print("-" * 50)
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
# Sample Markdown
|
||||
## Section 1
|
||||
This is a test markdown file.
|
||||
## Section 2
|
||||
It contains some formatted text and sections.
|
||||
@@ -0,0 +1,3 @@
|
||||
This is a sample text file.
|
||||
It contains multiple lines.
|
||||
This is for testing purposes.
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Shopping Agent", tools=[duckduckgo])
|
||||
agent.start("I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table")
|
||||
@@ -0,0 +1,4 @@
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(instructions="You are a Markdown Agent, output in markdown format")
|
||||
agent.start("Write a blog post about AI")
|
||||
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
import streamlit as st
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
st.title("AI Research Assistant")
|
||||
st.write("Enter your research query below to get started!")
|
||||
|
||||
# Initialize the research agent
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
|
||||
|
||||
# Create the input field
|
||||
query = st.text_input("Research Query", placeholder="Enter your research topic...")
|
||||
|
||||
# Add a search button
|
||||
if st.button("Search"):
|
||||
if query:
|
||||
with st.spinner("Researching..."):
|
||||
result = agent.start(query)
|
||||
st.write(result)
|
||||
else:
|
||||
st.warning("Please enter a research query")
|
||||
Whitespace-only changes.
@@ -0,0 +1,100 @@
|
||||
Write a product description for a smartwatch in 2 lines.
|
||||
Create a user manual for a blender in 2 lines.
|
||||
Draft an apology email for delayed delivery in 2 lines.
|
||||
Write a blog post on "Benefits of Meditation" in 2 lines.
|
||||
Create a privacy policy for a website in 2 lines.
|
||||
Write instructions for setting up a Wi-Fi router in 2 lines.
|
||||
Draft an email to follow up after a job interview in 2 lines.
|
||||
Create a FAQ page for an e-commerce store in 2 lines.
|
||||
Write an invitation email for a webinar in 2 lines.
|
||||
Create a terms and conditions page for an app in 2 lines.
|
||||
Write a press release for a product launch in 2 lines.
|
||||
Create a checklist for house cleaning tasks in 2 lines.
|
||||
Draft a resignation letter template in 2 lines.
|
||||
Write a cover letter for a software developer role in 2 lines.
|
||||
Create onboarding instructions for new employees in 2 lines.
|
||||
Write a memo announcing a new policy in a company in 2 lines.
|
||||
Create a safety guidelines document for a workplace in 2 lines.
|
||||
Write a pitch email to potential investors in 2 lines.
|
||||
Draft a thank-you email for attending a conference in 2 lines.
|
||||
Create a refund policy template for an online store in 2 lines.
|
||||
Write a blog on "How to Improve Time Management" in 2 lines.
|
||||
Create step-by-step instructions for changing a car tyre in 2 lines.
|
||||
Write a welcome email for new subscribers in 2 lines.
|
||||
Draft an event agenda template in 2 lines.
|
||||
Create a code of conduct for an online forum in 2 lines.
|
||||
Write a guide for beginners to start a blog in 2 lines.
|
||||
Create a checklist for organising a party in 2 lines.
|
||||
Draft an email to request a product review in 2 lines.
|
||||
Write a policy for remote work in a company in 2 lines.
|
||||
Create a simple tutorial for using Excel formulas in 2 lines.
|
||||
Write a thank-you letter for a donation in 2 lines.
|
||||
Draft a meeting minutes template in 2 lines.
|
||||
Create an FAQ for a gym membership in 2 lines.
|
||||
Write a blog post about "Healthy Snacks for Kids" in 2 lines.
|
||||
Create a guide for securing your social media accounts in 2 lines.
|
||||
Draft an email to request a testimonial from a client in 2 lines.
|
||||
Write a safety checklist for camping trips in 2 lines.
|
||||
Create a script for a customer service call in 2 lines.
|
||||
Write a tutorial for creating a simple PowerPoint presentation in 2 lines.
|
||||
Create a packing list for a beach vacation in 2 lines.
|
||||
Draft an email to cancel a service subscription in 2 lines.
|
||||
Write a personal statement for university admission in 2 lines.
|
||||
Create a template for tracking monthly expenses in 2 lines.
|
||||
Write a guide for planting and caring for succulents in 2 lines.
|
||||
Create a simple user guide for a mobile app in 2 lines.
|
||||
Draft an email to announce a team-building activity in 2 lines.
|
||||
Write a step-by-step guide for baking a cake in 2 lines.
|
||||
Create a list of house maintenance tasks in 2 lines.
|
||||
Draft a partnership proposal email in 2 lines.
|
||||
Write a guide for basic photography tips in 2 lines.
|
||||
Create a feedback form template for an online course in 2 lines.
|
||||
Write a blog on "Top 5 Budget Travel Destinations" in 2 lines.
|
||||
Draft a letter of recommendation for a colleague in 2 lines.
|
||||
Create a workout plan for beginners in 2 lines.
|
||||
Write a guide for troubleshooting common tech issues in 2 lines.
|
||||
Draft a reminder email for an upcoming appointment in 2 lines.
|
||||
Create a guide for setting personal goals in 2 lines.
|
||||
Write a blog post about "How to Start Freelancing" in 2 lines.
|
||||
Create a template for event planning in 2 lines.
|
||||
Draft an email to notify users about system maintenance in 2 lines.
|
||||
Write a guide for choosing the right laptop in 2 lines.
|
||||
Create a checklist for moving to a new house in 2 lines.
|
||||
Draft an email to update a client on project status in 2 lines.
|
||||
Write a guide for reducing screen time in 2 lines.
|
||||
Create a shopping list template for weekly groceries in 2 lines.
|
||||
Draft a thank-you email for completing a survey in 2 lines.
|
||||
Write a blog on "Simple DIY Crafts for Beginners" in 2 lines.
|
||||
Create a checklist for starting a small business in 2 lines.
|
||||
Draft an email to apologise for a customer complaint in 2 lines.
|
||||
Write a guide for setting up a personal budget in 2 lines.
|
||||
Create a policy for using company-provided equipment in 2 lines.
|
||||
Draft an email to notify about a price increase in 2 lines.
|
||||
Write a tutorial for creating a resume using Word in 2 lines.
|
||||
Create a simple guide for organising a charity event in 2 lines.
|
||||
Draft a formal invitation letter for a conference in 2 lines.
|
||||
Write a blog post about "Top Productivity Apps" in 2 lines.
|
||||
Create a checklist for first-time pet owners in 2 lines.
|
||||
Draft an email to confirm a service appointment in 2 lines.
|
||||
Write a beginner’s guide for learning to code in 2 lines.
|
||||
Create a guide for assembling a basic toolkit in 2 lines.
|
||||
Draft a welcome email for a new team member in 2 lines.
|
||||
Write a guide for preparing a home for winter in 2 lines.
|
||||
Create a schedule template for meal planning in 2 lines.
|
||||
Draft an email to request feedback from a customer in 2 lines.
|
||||
Write a guide on "How to Build a Morning Routine" in 2 lines.
|
||||
Create a checklist for hosting a virtual meeting in 2 lines.
|
||||
Draft a newsletter for a non-profit organisation in 2 lines.
|
||||
Write a guide for beginners to use Canva in 2 lines.
|
||||
Create a guide for organising your workspace in 2 lines.
|
||||
Draft an email to invite users to a beta program in 2 lines.
|
||||
Write a step-by-step guide for creating a podcast in 2 lines.
|
||||
Create a simple guide for buying your first car in 2 lines.
|
||||
Draft an email to announce a new team member in 2 lines.
|
||||
Write a tutorial on creating basic charts in Excel in 2 lines.
|
||||
Create a guide for teaching basic first aid in 2 lines.
|
||||
Draft an email to follow up after a sales call in 2 lines.
|
||||
Write a blog post on "How to Save Money on Utilities" in 2 lines.
|
||||
Create a guide for designing a basic website in 2 lines.
|
||||
Draft a thank-you email for a business referral in 2 lines.
|
||||
Write a guide for setting up a new smartphone in 2 lines.
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 22.
|
@@ -0,0 +1,758 @@
|
||||
"date","close","volume","open","high","low"
|
||||
"11:34","270.49","4,787,699","264.50","273.88","262.24"
|
||||
"2018/10/15","259.5900","6189026.0000","259.0600","263.2800","254.5367"
|
||||
"2018/10/12","258.7800","7189257.0000","261.0000","261.9900","252.0100"
|
||||
"2018/10/11","252.2300","8128184.0000","257.5300","262.2500","249.0300"
|
||||
"2018/10/10","256.8800","12781560.0000","264.6100","265.5100","247.7700"
|
||||
"2018/10/09","262.8000","12037780.0000","255.2500","266.7700","253.3000"
|
||||
"2018/10/08","250.5600","13371180.0000","264.5200","267.7599","249.0000"
|
||||
"2018/10/05","261.9500","17900710.0000","274.6500","274.8800","260.0000"
|
||||
"2018/10/04","281.8300","9638885.0000","293.9500","294.0000","277.6700"
|
||||
"2018/10/03","294.8000","7982272.0000","303.3300","304.6000","291.5700"
|
||||
"2018/10/02","301.0200","11699690.0000","313.9500","316.8400","299.1500"
|
||||
"2018/10/01","310.7000","21714210.0000","305.7700","311.4400","301.0500"
|
||||
"2018/09/28","264.7700","33597290.0000","270.2600","278.0000","260.5550"
|
||||
"2018/09/27","307.5200","7337760.0000","312.9000","314.9600","306.9100"
|
||||
"2018/09/26","309.5800","7835863.0000","301.9100","313.8900","301.1093"
|
||||
"2018/09/25","300.9900","4472287.0000","300.0000","304.6000","296.5000"
|
||||
"2018/09/24","299.6800","4834384.0000","298.4800","302.9993","293.5800"
|
||||
"2018/09/21","299.1000","5038497.0000","297.7000","300.5800","295.3700"
|
||||
"2018/09/20","298.3300","7332477.0000","303.5600","305.9800","293.3300"
|
||||
"2018/09/19","299.0200","8264353.0000","280.5100","300.0000","280.5000"
|
||||
"2018/09/18","284.9600","16494280.0000","296.6900","302.6400","275.5000"
|
||||
"2018/09/17","294.8400","6866208.0000","290.0400","300.8700","288.1300"
|
||||
"2018/09/14","295.2000","6757652.0000","288.7600","297.3256","286.5200"
|
||||
"2018/09/13","289.4600","6333281.0000","288.0200","295.0000","285.1800"
|
||||
"2018/09/12","290.5400","10002150.0000","281.4400","292.5000","278.6463"
|
||||
"2018/09/11","279.4400","9161061.0000","279.4700","282.0000","273.5500"
|
||||
"2018/09/10","285.5000","14232250.0000","273.2600","286.0300","271.0000"
|
||||
"2018/09/07","263.2400","22442310.0000","260.1000","268.3500","252.2548"
|
||||
"2018/09/06","280.9500","7472756.0000","284.8000","291.1700","278.8800"
|
||||
"2018/09/05","280.7400","7707342.0000","285.0500","286.7800","277.1800"
|
||||
"2018/09/04","288.9500","8304571.0000","296.9400","298.1900","288.0000"
|
||||
"2018/08/31","301.6600","5367048.0000","302.0000","305.3082","298.6000"
|
||||
"2018/08/30","303.1500","7210625.0000","302.2600","304.6000","297.7200"
|
||||
"2018/08/29","305.0100","7410538.0000","310.2700","311.8500","303.6900"
|
||||
"2018/08/28","311.8600","7639453.0000","318.4100","318.8800","311.1900"
|
||||
"2018/08/27","319.2700","13062650.0000","318.0000","322.4350","308.8100"
|
||||
"2018/08/24","322.8200","3592734.0000","320.7000","323.8500","319.4000"
|
||||
"2018/08/23","320.1000","5138685.0000","319.1400","327.3200","318.1000"
|
||||
"2018/08/22","321.6400","5935853.0000","320.8700","323.8800","314.6700"
|
||||
"2018/08/21","321.9000","13147770.0000","310.6100","324.7900","309.0000"
|
||||
"2018/08/20","308.4400","17380430.0000","291.7040","308.5000","288.2000"
|
||||
"2018/08/17","305.5000","18895880.0000","323.5000","326.7700","303.5300"
|
||||
"2018/08/16","335.4500","6045392.0000","339.9100","342.2800","333.8200"
|
||||
"2018/08/15","338.6900","9073033.0000","341.9060","344.4900","332.1400"
|
||||
"2018/08/14","347.6400","6948511.0000","358.4500","359.1995","347.1000"
|
||||
"2018/08/13","356.4100","10444920.0000","361.1300","363.1900","349.0200"
|
||||
"2018/08/10","355.4900","11530510.0000","354.0000","360.0000","346.0000"
|
||||
"2018/08/09","352.4500","16951800.0000","365.5500","367.0100","345.7300"
|
||||
"2018/08/08","370.3400","24535420.0000","369.0900","382.6400","367.1200"
|
||||
"2018/08/07","379.5700","30596400.0000","343.8400","387.4600","339.1501"
|
||||
"2018/08/06","341.9900","8536766.0000","345.4600","354.9800","341.8200"
|
||||
"2018/08/03","348.1700","13646640.0000","347.8100","355.0000","342.5300"
|
||||
"2018/08/02","349.5400","23159160.0000","328.4400","349.9900","323.1600"
|
||||
"2018/08/01","300.8400","8768099.0000","297.9900","303.0000","293.0000"
|
||||
"2018/07/31","298.1400","5055094.0000","292.2500","298.3200","289.0700"
|
||||
"2018/07/30","290.1700","6799581.0000","295.9000","296.1000","286.1300"
|
||||
"2018/07/27","297.1800","5694690.0000","307.2500","307.6933","295.3404"
|
||||
"2018/07/26","306.6500","4619567.0000","304.8500","310.7000","303.6411"
|
||||
"2018/07/25","308.7400","7031382.0000","296.7400","309.6200","294.5025"
|
||||
"2018/07/24","297.4300","9586186.0000","304.4209","307.7171","292.5452"
|
||||
"2018/07/23","303.2000","10974820.0000","301.8400","305.5000","292.8601"
|
||||
"2018/07/20","313.5800","5159831.0000","321.2300","323.2400","311.7093"
|
||||
"2018/07/19","320.2300","5907116.0000","316.3300","323.5400","314.0100"
|
||||
"2018/07/18","323.8500","5610085.0000","325.0000","325.5000","316.2500"
|
||||
"2018/07/17","322.6900","6987782.0000","308.8100","324.7400","308.5000"
|
||||
"2018/07/16","310.1000","7800454.0000","311.7100","315.1600","306.2500"
|
||||
"2018/07/13","318.8700","5866776.0000","315.5800","319.5849","309.2500"
|
||||
"2018/07/12","316.7100","5711851.0000","321.4300","323.2300","312.7700"
|
||||
"2018/07/11","318.9600","4878595.0000","315.8000","321.9400","315.0700"
|
||||
"2018/07/10","322.4700","9437557.0000","324.5600","327.6771","319.2000"
|
||||
"2018/07/09","318.5100","7579541.0000","311.9900","318.5200","308.0000"
|
||||
"2018/07/06","308.9000","8860198.0000","304.9550","312.0700","302.0000"
|
||||
"2018/07/05","309.1600","17457570.0000","313.7600","314.3900","296.2200"
|
||||
"2018/07/03","310.8600","12282640.0000","331.7500","332.4900","309.6900"
|
||||
"2018/07/02","335.0700","18732710.0000","360.0700","364.7800","329.8500"
|
||||
"2018/06/29","342.9500","6475903.0000","353.3300","353.8600","342.4100"
|
||||
"2018/06/28","349.9300","8388172.0000","348.6600","357.0200","346.1100"
|
||||
"2018/06/27","344.5000","8313817.0000","345.0000","350.7900","339.5000"
|
||||
"2018/06/26","342.0000","7434749.0000","336.0540","343.5500","325.7990"
|
||||
"2018/06/25","333.0100","6925089.0000","330.1200","338.4700","327.5000"
|
||||
"2018/06/22","333.6300","10253770.0000","351.5400","352.2500","332.0000"
|
||||
"2018/06/21","347.5100","7949846.0000","362.0000","366.2139","346.2700"
|
||||
"2018/06/20","362.2200","8370268.0000","358.0400","364.3800","352.0000"
|
||||
"2018/06/19","352.5500","12734840.0000","365.1600","370.0000","346.2500"
|
||||
"2018/06/18","370.8300","12025450.0000","355.4000","373.7300","354.5000"
|
||||
"2018/06/15","358.1700","10827560.0000","353.8400","364.6700","351.2500"
|
||||
"2018/06/14","357.7200","10961150.0000","347.6300","358.7500","346.6000"
|
||||
"2018/06/13","344.7800","9401467.0000","346.7060","347.2000","339.8000"
|
||||
"2018/06/12","342.7700","22256430.0000","344.7000","354.9700","338.0000"
|
||||
"2018/06/11","332.1000","13166050.0000","322.5100","334.6600","322.5000"
|
||||
"2018/06/08","317.6600","8192175.0000","319.0000","324.4800","317.1500"
|
||||
"2018/06/07","316.0900","14336110.0000","316.1500","330.0000","313.5800"
|
||||
"2018/06/06","319.5000","18742400.0000","300.5000","322.1700","297.4800"
|
||||
"2018/06/05","291.1300","5877873.0000","297.7000","297.8000","286.7400"
|
||||
"2018/06/04","296.7400","4793787.0000","294.3400","299.0000","293.5480"
|
||||
"2018/06/01","291.8200","5417984.0000","285.8600","291.9500","283.8390"
|
||||
"2018/05/31","284.7300","5912825.0000","287.2100","290.3700","282.9300"
|
||||
"2018/05/30","291.7200","7473590.0000","283.2900","295.0050","281.6000"
|
||||
"2018/05/29","283.7600","5657153.0000","278.5100","286.5000","276.1500"
|
||||
"2018/05/25","278.8500","3872621.0000","277.6250","279.6400","275.6100"
|
||||
"2018/05/24","277.8500","4170789.0000","278.4000","281.1100","274.8900"
|
||||
"2018/05/23","279.0700","5972237.0000","277.7600","279.9099","274.0000"
|
||||
"2018/05/22","275.0100","8938501.0000","287.7620","288.0000","273.4220"
|
||||
"2018/05/21","284.4900","9167844.0000","281.3300","291.4900","281.3000"
|
||||
"2018/05/18","276.8200","7243699.0000","284.6500","284.6500","274.0000"
|
||||
"2018/05/17","284.5400","4418258.0000","285.9000","289.1873","283.9700"
|
||||
"2018/05/16","286.4800","5669644.0000","283.8300","288.8100","281.5600"
|
||||
"2018/05/15","284.1800","9509753.0000","285.0100","286.9600","280.5000"
|
||||
"2018/05/14","291.9700","7265501.0000","303.3200","304.9400","291.6200"
|
||||
"2018/05/11","301.0600","4665321.0000","307.7000","308.8800","299.0800"
|
||||
"2018/05/10","305.0200","5642771.0000","307.4997","312.9900","304.1119"
|
||||
"2018/05/09","306.8500","5712255.0000","300.4100","307.0100","300.0500"
|
||||
"2018/05/08","301.9700","5927447.0000","300.7950","307.7500","299.0000"
|
||||
"2018/05/07","302.7700","8673090.0000","297.5000","305.9588","295.1700"
|
||||
"2018/05/04","294.0900","8565506.0000","283.0000","296.8600","279.5200"
|
||||
"2018/05/03","284.4500","17339090.0000","278.7900","288.0400","275.2300"
|
||||
"2018/05/02","301.1500","8346176.0000","298.5700","306.8500","297.7844"
|
||||
"2018/05/01","299.9200","4614946.0000","293.5100","300.8200","293.2200"
|
||||
"2018/04/30","293.9000","4224068.0000","293.6100","298.7300","292.5000"
|
||||
"2018/04/27","294.0750","4346854.0000","285.3700","294.4700","283.8300"
|
||||
"2018/04/26","285.4800","4348108.0000","278.7500","285.7900","276.5000"
|
||||
"2018/04/25","280.6900","4000421.0000","283.5000","285.1600","277.2500"
|
||||
"2018/04/24","283.4600","5678242.0000","285.0000","287.0900","278.4600"
|
||||
"2018/04/23","283.3700","4880743.0000","291.2900","291.6200","282.3300"
|
||||
"2018/04/20","290.2400","5622630.0000","295.1700","299.9800","289.7500"
|
||||
"2018/04/19","300.0800","6083800.0000","291.0800","301.0100","288.5500"
|
||||
"2018/04/18","293.3500","6531563.0000","291.0800","300.2400","288.1600"
|
||||
"2018/04/17","287.6900","6931152.0000","288.8700","292.1700","282.5100"
|
||||
"2018/04/16","291.2100","6289497.0000","299.0000","299.6600","289.0100"
|
||||
"2018/04/13","300.3400","7319225.0000","303.6000","303.9499","295.9800"
|
||||
"2018/04/12","294.0800","7595525.0000","302.3200","303.9500","293.6800"
|
||||
"2018/04/11","300.9300","7470204.0000","300.7400","308.9800","299.6600"
|
||||
"2018/04/10","304.7000","11017010.0000","298.9700","307.1000","293.6800"
|
||||
"2018/04/09","289.6600","10241410.0000","300.3700","309.5000","289.2100"
|
||||
"2018/04/06","299.3000","13516530.0000","301.0000","309.2800","295.5000"
|
||||
"2018/04/05","305.7200","19025860.0000","289.3400","306.2600","288.2000"
|
||||
"2018/04/04","286.9400","19880180.0000","252.7800","288.3700","252.0000"
|
||||
"2018/04/03","267.5300","18829650.0000","269.8200","273.3500","254.4900"
|
||||
"2018/04/02","252.4800","16093290.0000","256.2600","260.3318","244.5901"
|
||||
"2018/03/29","266.1300","15014440.0000","256.4900","270.9599","248.2100"
|
||||
"2018/03/28","257.7800","20962280.0000","264.5800","268.6800","252.1000"
|
||||
"2018/03/27","279.1800","13787060.0000","304.0000","304.2700","277.1800"
|
||||
"2018/03/26","304.1800","8364937.0000","307.3400","307.5900","291.3600"
|
||||
"2018/03/23","301.5400","6639960.0000","311.2500","311.6100","300.4500"
|
||||
"2018/03/22","309.1000","4924928.0000","313.8900","318.8200","308.1800"
|
||||
"2018/03/21","316.5300","5954247.0000","310.2500","322.4400","310.1900"
|
||||
"2018/03/20","310.5500","4761031.0000","314.8700","316.2500","308.7600"
|
||||
"2018/03/19","313.5600","7467890.0000","316.5000","320.7500","309.6700"
|
||||
"2018/03/16","321.3500","6113365.0000","325.9600","327.4000","319.0700"
|
||||
"2018/03/15","325.6000","6554568.0000","329.3800","332.8500","321.1000"
|
||||
"2018/03/14","326.6300","7952152.0000","336.7600","339.8100","323.9300"
|
||||
"2018/03/13","341.8400","5960636.0000","344.9200","345.1200","336.2635"
|
||||
"2018/03/12","345.5100","8252919.0000","328.6100","347.2100","326.5000"
|
||||
"2018/03/09","327.1700","5502779.0000","324.1000","328.4900","322.3700"
|
||||
"2018/03/08","329.1000","3514367.0000","332.8600","333.3000","326.2740"
|
||||
"2018/03/07","332.3000","5001940.0000","325.4400","332.5000","321.7400"
|
||||
"2018/03/06","328.2000","4236483.0000","333.7500","336.3700","327.0300"
|
||||
"2018/03/05","333.3500","3820702.0000","332.3900","337.7500","329.2929"
|
||||
"2018/03/02","335.1200","5088789.0000","326.9800","335.2200","322.9700"
|
||||
"2018/03/01","330.9300","6872552.0000","345.0100","348.6700","330.0700"
|
||||
"2018/02/28","343.0600","6066044.0000","352.5700","355.2400","342.2200"
|
||||
"2018/02/27","350.9900","4785022.0000","356.2500","359.9900","350.0100"
|
||||
"2018/02/26","357.4200","4334500.0000","353.5000","359.0000","352.3550"
|
||||
"2018/02/23","352.0500","5814177.0000","347.8300","354.9900","347.1000"
|
||||
"2018/02/22","346.1700","6961880.0000","335.5300","347.4400","334.7501"
|
||||
"2018/02/21","333.3000","3207250.0000","336.0300","339.6929","333.1700"
|
||||
"2018/02/20","334.7700","4005962.0000","334.4700","340.8400","331.5000"
|
||||
"2018/02/16","335.4900","5640184.0000","332.5000","343.1200","331.6400"
|
||||
"2018/02/15","334.0650","5909823.0000","324.5000","334.1200","322.4000"
|
||||
"2018/02/14","322.3100","3948077.0000","320.8400","326.1700","318.5200"
|
||||
"2018/02/13","323.6600","4554631.0000","315.0200","324.1900","312.5105"
|
||||
"2018/02/12","315.7300","6224479.0000","316.1300","318.0800","306.2500"
|
||||
"2018/02/09","310.4200","12924430.0000","319.9300","320.9845","294.7600"
|
||||
"2018/02/08","315.2300","10296420.0000","343.3100","348.6200","314.6000"
|
||||
"2018/02/07","345.0000","6729682.0000","338.9900","346.0000","335.6600"
|
||||
"2018/02/06","333.9700","5080032.0000","325.2100","336.2200","323.5000"
|
||||
"2018/02/05","333.1300","4441166.0000","337.9700","344.4700","333.0000"
|
||||
"2018/02/02","343.7500","3696157.0000","348.4400","351.9500","340.5100"
|
||||
"2018/02/01","349.2500","4187440.0000","351.0000","359.6600","348.6300"
|
||||
"2018/01/31","354.3100","6199373.0000","347.5100","356.1900","345.1900"
|
||||
"2018/01/30","345.8200","4710684.0000","345.1400","348.2700","342.1700"
|
||||
"2018/01/29","349.5300","4738208.0000","339.8500","350.8500","338.2800"
|
||||
"2018/01/26","342.8500","4535457.0000","341.5000","344.0000","335.7100"
|
||||
"2018/01/25","337.6400","6725208.0000","348.2700","349.2000","336.4000"
|
||||
"2018/01/24","345.8900","5277386.0000","354.5800","354.7500","343.5200"
|
||||
"2018/01/23","352.7900","5447622.0000","360.0000","360.5000","351.0000"
|
||||
"2018/01/22","351.5600","6199777.0000","349.4000","357.8300","349.2000"
|
||||
"2018/01/19","350.0200","4871181.0000","345.0000","350.5899","342.6000"
|
||||
"2018/01/18","344.5700","5679629.0000","345.6700","352.3000","343.7400"
|
||||
"2018/01/17","347.1600","7092554.0000","340.4700","349.0000","339.7500"
|
||||
"2018/01/16","340.0600","6429234.0000","337.5400","345.0000","334.8000"
|
||||
"2018/01/12","336.2200","4822509.0000","338.6300","340.4100","333.6700"
|
||||
"2018/01/11","337.9500","6640863.0000","335.2400","344.8099","333.2600"
|
||||
"2018/01/10","334.8000","4303053.0000","332.2000","337.0000","330.0000"
|
||||
"2018/01/09","333.6900","7134525.0000","335.1600","338.8000","327.4050"
|
||||
"2018/01/08","336.4100","9832610.0000","316.0000","337.0199","315.5000"
|
||||
"2018/01/05","316.5800","4588728.0000","316.6200","317.2400","312.0000"
|
||||
"2018/01/04","314.6200","9944593.0000","312.8700","318.5500","305.6800"
|
||||
"2018/01/03","317.2500","4438520.0000","321.0000","325.2500","315.5500"
|
||||
"2018/01/02","320.5300","4345615.0000","312.0000","322.1099","311.0000"
|
||||
"2017/12/29","311.3500","3769504.0000","316.1800","316.4100","310.0000"
|
||||
"2017/12/28","315.3600","4306746.0000","311.7500","315.8200","309.5400"
|
||||
"2017/12/27","311.6400","4705084.0000","316.0000","317.6800","310.7500"
|
||||
"2017/12/26","317.2900","4368699.0000","323.8300","323.9400","316.5800"
|
||||
"2017/12/22","325.2000","4207602.0000","329.5100","330.9214","324.8200"
|
||||
"2017/12/21","331.6600","4369994.0000","329.5900","333.7400","327.2100"
|
||||
"2017/12/20","328.9800","5907378.0000","332.6900","333.1000","325.0400"
|
||||
"2017/12/19","331.1000","6820868.0000","340.2600","341.4925","330.3000"
|
||||
"2017/12/18","338.8700","5466546.0000","344.9000","346.7300","337.5800"
|
||||
"2017/12/15","343.4500","6921246.0000","342.0400","343.9000","335.7600"
|
||||
"2017/12/14","337.8900","5792024.0000","341.0100","347.4400","336.9000"
|
||||
"2017/12/13","339.0300","6217701.0000","340.9300","344.2200","336.5000"
|
||||
"2017/12/12","341.0300","8715570.0000","330.4500","341.4400","330.0300"
|
||||
"2017/12/11","328.9100","7926090.0000","314.6300","329.0100","313.7500"
|
||||
"2017/12/08","315.1300","3466088.0000","314.6000","316.9800","311.2600"
|
||||
"2017/12/07","311.2400","4779590.0000","312.0000","318.6341","311.0500"
|
||||
"2017/12/06","313.2600","7184477.0000","300.1000","313.3900","300.0000"
|
||||
"2017/12/05","303.7000","4643708.0000","302.0000","308.0000","301.0000"
|
||||
"2017/12/04","305.2000","5834227.0000","306.5000","308.2650","300.6100"
|
||||
"2017/12/01","306.5300","4286082.0000","305.4400","310.3200","305.0500"
|
||||
"2017/11/30","308.8500","4345434.0000","308.5600","310.7000","304.5400"
|
||||
"2017/11/29","307.5400","8757463.0000","317.3000","318.0000","301.2300"
|
||||
"2017/11/28","317.5500","4941703.0000","316.3600","320.0000","313.9200"
|
||||
"2017/11/27","316.8100","4537779.0000","313.2500","317.3400","309.5100"
|
||||
"2017/11/24","315.5500","3244065.0000","313.7900","316.4100","311.0000"
|
||||
"2017/11/22","312.6000","4913283.0000","316.7700","317.4200","311.8400"
|
||||
"2017/11/21","317.8100","7256381.0000","310.8600","318.2300","308.7100"
|
||||
"2017/11/20","308.7400","8241821.0000","313.7900","315.5000","304.7500"
|
||||
"2017/11/17","315.0500","13720830.0000","325.6700","326.6700","313.1500"
|
||||
"2017/11/16","312.5000","5794409.0000","313.9900","318.1400","311.3000"
|
||||
"2017/11/15","311.3000","5951835.0000","306.0100","312.4900","301.5000"
|
||||
"2017/11/14","308.7000","5661904.0000","315.0000","316.3500","306.9000"
|
||||
"2017/11/13","315.4000","7565242.0000","300.1300","316.8000","299.1100"
|
||||
"2017/11/10","302.9900","4621080.0000","302.5000","308.3600","301.8500"
|
||||
"2017/11/09","302.9900","5440173.0000","302.5000","304.4600","296.3000"
|
||||
"2017/11/08","304.3900","4725355.0000","305.5000","306.8900","301.3001"
|
||||
"2017/11/07","306.0500","5284844.0000","301.0200","306.5000","300.0300"
|
||||
"2017/11/06","302.7800","6480689.0000","307.0000","307.5000","299.0100"
|
||||
"2017/11/03","306.0900","8885933.0000","299.5000","306.2500","295.1300"
|
||||
"2017/11/02","299.2600","19771280.0000","300.1300","308.6900","292.6300"
|
||||
"2017/11/01","321.0800","8242487.0000","332.2500","332.6089","320.2600"
|
||||
"2017/10/31","331.5300","5650062.0000","320.2300","331.9500","320.1800"
|
||||
"2017/10/30","320.0800","4247619.0000","319.1800","323.7800","317.2500"
|
||||
"2017/10/27","320.8700","6968365.0000","319.7500","324.5900","316.6600"
|
||||
"2017/10/26","326.1700","5010087.0000","327.7800","330.2300","323.2000"
|
||||
"2017/10/25","325.8400","8583619.0000","336.7000","337.5000","323.5600"
|
||||
"2017/10/24","337.3400","4485692.0000","338.8000","342.8000","336.1600"
|
||||
"2017/10/23","337.0200","5739598.0000","349.8800","349.9500","336.2500"
|
||||
"2017/10/20","345.1000","4925657.0000","352.6900","354.5500","344.3400"
|
||||
"2017/10/19","351.8100","5055715.0000","355.5600","357.1465","348.2000"
|
||||
"2017/10/18","359.6500","4936024.0000","355.9700","363.0000","354.1300"
|
||||
"2017/10/17","355.7500","3290290.0000","350.9100","356.2200","350.0700"
|
||||
"2017/10/16","350.6000","5373090.0000","353.7600","354.4800","347.1600"
|
||||
"2017/10/13","355.5700","3538807.0000","356.9800","358.4900","353.6800"
|
||||
"2017/10/12","355.6800","4073552.0000","352.9500","359.7800","352.6400"
|
||||
"2017/10/11","354.6000","4494733.0000","353.8900","357.6000","351.1500"
|
||||
"2017/10/10","355.5900","6972263.0000","346.8000","355.6300","345.5305"
|
||||
"2017/10/09","342.9400","7461461.0000","349.6500","351.7500","342.6700"
|
||||
"2017/10/06","356.8800","4272866.0000","353.1000","360.0992","352.2500"
|
||||
"2017/10/05","355.3300","4167913.0000","356.0000","357.4350","351.3500"
|
||||
"2017/10/04","355.0100","8147995.0000","351.2500","358.6200","349.6000"
|
||||
"2017/10/03","348.1400","10122550.0000","335.9000","348.5500","331.2800"
|
||||
"2017/10/02","341.5300","5227547.0000","342.5200","343.7000","335.5100"
|
||||
"2017/09/29","341.1000","5099051.0000","341.8600","344.6800","338.6010"
|
||||
"2017/09/28","339.6000","5309779.0000","339.8800","342.7500","335.4000"
|
||||
"2017/09/27","340.9700","6027375.0000","349.9000","351.4890","340.5000"
|
||||
"2017/09/26","345.2500","7149649.0000","350.9300","351.2400","340.9000"
|
||||
"2017/09/25","344.9900","7587158.0000","353.1500","357.4690","342.8800"
|
||||
"2017/09/22","351.0900","8142895.0000","366.4900","369.8999","350.8800"
|
||||
"2017/09/21","366.4800","4610872.0000","374.9000","376.8300","364.5100"
|
||||
"2017/09/20","373.9100","4909958.0000","373.0000","378.2490","371.0700"
|
||||
"2017/09/19","375.1000","6435208.0000","380.0000","382.3900","373.5700"
|
||||
"2017/09/18","385.0000","7177773.0000","380.2500","389.6100","377.6800"
|
||||
"2017/09/15","379.8100","5407227.0000","374.5100","380.0000","372.7000"
|
||||
"2017/09/14","377.6400","7170263.0000","364.3300","377.9600","362.6300"
|
||||
"2017/09/13","366.2300","4171185.0000","363.8200","368.0700","359.5900"
|
||||
"2017/09/12","362.7500","5966204.0000","364.4900","368.7600","360.4000"
|
||||
"2017/09/11","363.6900","7651000.0000","351.3500","363.7100","350.0000"
|
||||
"2017/09/08","343.4000","3261333.0000","348.9900","349.7800","342.3000"
|
||||
"2017/09/07","350.6100","4235045.0000","345.9800","352.4800","343.4500"
|
||||
"2017/09/06","344.5300","4082001.0000","349.5000","350.9790","341.5600"
|
||||
"2017/09/05","349.5900","3836402.0000","353.8000","355.4900","345.8900"
|
||||
"2017/09/01","355.4000","3048550.0000","356.1200","357.5900","353.6902"
|
||||
"2017/08/31","355.9000","4063330.0000","353.5500","358.4400","352.8200"
|
||||
"2017/08/30","353.1800","3404165.0000","349.6700","353.4700","347.0000"
|
||||
"2017/08/29","347.3600","4069303.0000","339.4800","349.0500","338.7500"
|
||||
"2017/08/28","345.6600","3746240.0000","347.2800","347.3500","339.7200"
|
||||
"2017/08/25","348.0500","3475186.0000","354.2400","355.6900","347.3000"
|
||||
"2017/08/24","352.9300","4571574.0000","352.5200","356.6600","349.7400"
|
||||
"2017/08/23","352.7700","4941947.0000","338.9900","353.4900","338.3041"
|
||||
"2017/08/22","341.3500","4314268.0000","341.1300","342.2400","337.3725"
|
||||
"2017/08/21","337.8600","6489850.0000","345.8200","345.8200","331.8500"
|
||||
"2017/08/18","347.4600","5390805.0000","352.9100","354.0000","345.8000"
|
||||
"2017/08/17","351.9200","5010825.0000","361.2100","363.3000","351.5900"
|
||||
"2017/08/16","362.9100","3406173.0000","363.0000","366.5000","362.5200"
|
||||
"2017/08/15","362.3300","3084601.0000","365.2000","365.4900","359.3700"
|
||||
"2017/08/14","363.8000","4507969.0000","364.6300","367.6600","362.6000"
|
||||
"2017/08/11","357.8700","4357562.0000","356.9700","361.2600","353.6200"
|
||||
"2017/08/10","355.4000","7063054.0000","361.6000","366.6504","354.6600"
|
||||
"2017/08/09","363.5300","6881182.0000","361.0000","370.0000","358.9500"
|
||||
"2017/08/08","365.2200","7431838.0000","357.5300","368.5800","357.4000"
|
||||
"2017/08/07","355.1700","6309331.0000","357.3500","359.4800","352.7500"
|
||||
"2017/08/04","356.9100","9233295.0000","347.0000","357.2700","343.3000"
|
||||
"2017/08/03","347.0900","13524270.0000","345.3300","350.0000","343.1500"
|
||||
"2017/08/02","325.8900","11942350.0000","318.9400","327.1200","311.2200"
|
||||
"2017/08/01","319.5700","8284997.0000","323.0000","324.4500","316.1300"
|
||||
"2017/07/31","323.4700","8525454.0000","335.5000","341.4900","321.0400"
|
||||
"2017/07/28","335.0700","4869891.0000","336.8900","339.6000","332.5100"
|
||||
"2017/07/27","334.4600","8285879.0000","346.0000","347.5000","326.2900"
|
||||
"2017/07/26","343.8500","4809514.0000","340.3600","345.5000","338.1200"
|
||||
"2017/07/25","339.6000","6977932.0000","345.0000","345.6000","334.1500"
|
||||
"2017/07/24","342.5200","8598292.0000","330.2400","343.3990","330.0100"
|
||||
"2017/07/21","328.4000","4871708.0000","329.4600","331.2575","325.8000"
|
||||
"2017/07/20","329.9200","5142516.0000","326.9000","330.2200","324.2000"
|
||||
"2017/07/19","325.2600","6345884.0000","328.2300","331.6500","323.2193"
|
||||
"2017/07/18","328.2400","6360710.0000","317.5000","329.1300","315.6600"
|
||||
"2017/07/17","319.5700","9827506.0000","325.5400","327.1000","313.4500"
|
||||
"2017/07/14","327.7800","5607924.0000","323.1900","328.4200","321.2200"
|
||||
"2017/07/13","323.4100","8582315.0000","330.1100","331.6000","319.9700"
|
||||
"2017/07/12","329.5200","10317240.0000","330.4000","333.1000","324.5000"
|
||||
"2017/07/11","327.2200","11526760.0000","316.0000","327.2800","314.3000"
|
||||
"2017/07/10","316.0500","13760290.0000","312.9000","317.9400","303.1300"
|
||||
"2017/07/07","313.2200","14129950.0000","313.5000","317.0000","307.3800"
|
||||
"2017/07/06","308.8300","19258040.0000","317.2600","320.7899","306.3000"
|
||||
"2017/07/05","327.0900","16998300.0000","347.2000","347.2400","326.3300"
|
||||
"2017/07/03","352.6200","6305401.0000","370.2400","371.3500","351.5000"
|
||||
"2017/06/30","361.6100","5823046.0000","363.7100","366.7674","359.6187"
|
||||
"2017/06/29","360.7500","8202463.0000","370.6100","371.0000","354.1000"
|
||||
"2017/06/28","371.2400","6290323.0000","366.6800","371.7400","362.5200"
|
||||
"2017/06/27","362.3700","6977494.0000","376.4000","376.4000","362.0200"
|
||||
"2017/06/26","377.4900","6596854.0000","386.6900","386.9500","373.1000"
|
||||
"2017/06/23","383.4500","6425180.0000","382.4500","386.9900","379.3450"
|
||||
"2017/06/22","382.6100","7510406.0000","377.9900","385.0000","373.5700"
|
||||
"2017/06/21","376.4000","4916770.0000","374.3500","376.9900","368.0200"
|
||||
"2017/06/20","372.2400","7419110.0000","376.6700","378.8800","369.7300"
|
||||
"2017/06/19","369.8000","6433434.0000","375.0000","376.7000","367.8000"
|
||||
"2017/06/16","371.4000","6347450.0000","377.9750","378.0100","370.1000"
|
||||
"2017/06/15","375.3400","10412650.0000","372.5000","375.4600","366.4900"
|
||||
"2017/06/14","380.6600","12778480.0000","381.0850","384.2500","376.3100"
|
||||
"2017/06/13","375.9500","11773370.0000","367.6200","376.0000","366.6100"
|
||||
"2017/06/12","359.0100","10507860.0000","357.9900","364.5000","350.6200"
|
||||
"2017/06/09","357.3200","17250060.0000","374.4200","376.8700","354.8000"
|
||||
"2017/06/08","370.0000","9028677.0000","363.7500","371.9000","360.2200"
|
||||
"2017/06/07","359.6500","9348692.0000","356.3400","360.5000","355.1400"
|
||||
"2017/06/06","352.8500","11031920.0000","344.7000","359.4929","339.9700"
|
||||
"2017/06/05","347.3200","6769174.0000","338.5000","348.4400","334.2100"
|
||||
"2017/06/02","339.8500","5583952.0000","339.7700","342.8800","335.9300"
|
||||
"2017/06/01","340.3700","7601764.0000","344.0000","344.8800","337.2900"
|
||||
"2017/05/31","341.0100","9937556.0000","337.6900","342.8900","335.1600"
|
||||
"2017/05/30","335.1000","7771536.0000","326.0000","336.2800","325.7600"
|
||||
"2017/05/26","325.1400","7793009.0000","317.2800","325.4900","316.3100"
|
||||
"2017/05/25","316.8300","5000432.0000","311.0200","316.9700","307.8100"
|
||||
"2017/05/24","310.2200","5035192.0000","306.5100","311.0000","305.4000"
|
||||
"2017/05/23","303.8600","4314267.0000","310.4600","310.7300","303.4800"
|
||||
"2017/05/22","310.3500","4324305.0000","312.8000","314.3700","306.8000"
|
||||
"2017/05/19","310.8300","4654580.0000","315.5000","316.5000","310.2000"
|
||||
"2017/05/18","313.0600","5609153.0000","307.0000","313.9400","305.3100"
|
||||
"2017/05/17","306.1100","6695657.0000","314.3900","314.6300","305.5000"
|
||||
"2017/05/16","317.0100","4141066.0000","317.5900","320.0600","315.1400"
|
||||
"2017/05/15","315.8800","7606854.0000","318.3800","320.2000","312.5300"
|
||||
"2017/05/12","324.8100","4118613.0000","325.4800","327.0000","321.5300"
|
||||
"2017/05/11","323.1000","4747172.0000","323.4000","326.0000","319.6000"
|
||||
"2017/05/10","325.2200","5734524.0000","321.5600","325.5000","318.1200"
|
||||
"2017/05/09","321.2600","9663374.0000","309.3800","321.9900","309.1000"
|
||||
"2017/05/08","307.1900","7002907.0000","310.9000","313.7900","305.8200"
|
||||
"2017/05/05","308.3500","8117449.0000","298.0000","308.5500","296.8000"
|
||||
"2017/05/04","295.4600","14135990.0000","307.4350","307.7700","290.7601"
|
||||
"2017/05/03","311.0200","6879259.0000","317.6700","321.5300","310.4500"
|
||||
"2017/05/02","318.8900","5316551.0000","324.0000","327.6599","316.5601"
|
||||
"2017/05/01","322.8300","8819888.0000","314.8800","327.2500","314.8100"
|
||||
"2017/04/28","314.0700","4496659.0000","309.8300","314.8000","308.0000"
|
||||
"2017/04/27","308.6300","3462663.0000","311.6900","313.0900","307.5000"
|
||||
"2017/04/26","310.1700","4683131.0000","312.3700","314.5000","309.0000"
|
||||
"2017/04/25","313.7900","6734162.0000","308.0000","313.9800","305.8600"
|
||||
"2017/04/24","308.0300","5077771.0000","309.2200","310.5500","306.0215"
|
||||
"2017/04/21","305.6000","4501958.0000","302.0000","306.4000","300.4200"
|
||||
"2017/04/20","302.5100","6145961.0000","306.5100","309.1500","300.2300"
|
||||
"2017/04/19","305.5200","3891145.0000","302.4600","306.6200","302.1100"
|
||||
"2017/04/18","300.2500","3034225.0000","299.7000","300.8399","297.9000"
|
||||
"2017/04/17","301.4400","4128067.0000","302.7000","304.0000","298.6800"
|
||||
"2017/04/13","304.0000","9275682.0000","296.7000","307.3900","295.3000"
|
||||
"2017/04/12","296.8400","6043648.0000","306.3400","308.4481","296.3200"
|
||||
"2017/04/11","308.7100","5718053.0000","313.3800","313.4700","305.5000"
|
||||
"2017/04/10","312.3900","7653623.0000","309.1500","313.7299","308.7100"
|
||||
"2017/04/07","302.5400","4566632.0000","297.5000","302.6900","297.1500"
|
||||
"2017/04/06","298.7000","5517731.0000","296.8800","301.9400","294.1000"
|
||||
"2017/04/05","295.0000","7858565.0000","302.0400","304.8800","294.2000"
|
||||
"2017/04/04","303.7000","10108230.0000","296.8900","304.8100","294.5300"
|
||||
"2017/04/03","298.5200","13864850.0000","286.9000","299.0000","284.5800"
|
||||
"2017/03/31","278.3000","3293698.0000","278.7300","279.6800","276.3197"
|
||||
"2017/03/30","277.9200","4141437.0000","278.0400","282.0000","277.2100"
|
||||
"2017/03/29","277.3800","3672526.0000","278.3400","279.6000","275.5400"
|
||||
"2017/03/28","277.4500","7978665.0000","277.0200","280.6800","275.0000"
|
||||
"2017/03/27","270.2200","6221361.0000","260.6000","270.5700","259.7500"
|
||||
"2017/03/24","263.1600","5637668.0000","255.7000","263.8900","255.0100"
|
||||
"2017/03/23","254.7800","3309844.0000","255.3900","257.6720","253.3000"
|
||||
"2017/03/22","255.0100","4056735.0000","251.5600","255.0700","250.5100"
|
||||
"2017/03/21","250.6800","6901555.0000","262.8300","264.8000","250.2400"
|
||||
"2017/03/20","261.9200","3601616.0000","260.6000","264.5500","258.8210"
|
||||
"2017/03/17","261.5000","6491018.0000","264.0000","265.3300","261.2000"
|
||||
"2017/03/16","262.0500","7127180.0000","262.4000","265.7500","259.0600"
|
||||
"2017/03/15","255.7300","5233365.0000","257.0000","261.0000","254.2700"
|
||||
"2017/03/14","258.0000","7581719.0000","246.1100","258.1200","246.0200"
|
||||
"2017/03/13","246.1700","3011280.0000","244.8200","246.8500","242.7810"
|
||||
"2017/03/10","243.6900","3062785.0000","246.2100","246.5000","243.0000"
|
||||
"2017/03/09","244.9000","3876494.0000","247.6300","248.6600","243.0000"
|
||||
"2017/03/08","246.8700","3726746.0000","247.0000","250.0700","245.3200"
|
||||
"2017/03/07","248.5900","3452587.0000","251.9200","253.8900","248.3200"
|
||||
"2017/03/06","251.2100","3353601.0000","247.9100","251.7000","247.5100"
|
||||
"2017/03/03","251.5700","2925481.0000","250.7400","251.9000","249.0000"
|
||||
"2017/03/02","250.4800","3345751.0000","249.7100","253.2800","248.2700"
|
||||
"2017/03/01","250.0200","4804963.0000","254.1800","254.8500","249.1100"
|
||||
"2017/02/28","249.9900","6073890.0000","244.1900","251.0000","243.9000"
|
||||
"2017/02/27","246.2300","11450160.0000","248.1700","248.3600","242.0100"
|
||||
"2017/02/24","257.0000","8166869.0000","252.6600","258.2500","250.2000"
|
||||
"2017/02/23","255.9900","14877090.0000","264.0000","264.6600","255.5600"
|
||||
"2017/02/22","273.5100","8537811.0000","280.3100","283.4500","272.6000"
|
||||
"2017/02/21","277.3900","5647575.0000","275.4500","281.4000","274.0100"
|
||||
"2017/02/17","272.2300","6251469.0000","265.8000","272.8900","264.1500"
|
||||
"2017/02/16","268.9500","7063860.0000","277.6000","280.0000","268.5000"
|
||||
"2017/02/15","279.7600","4943879.0000","280.0000","282.2400","276.4400"
|
||||
"2017/02/14","280.9800","7341450.0000","279.0300","287.3900","278.6100"
|
||||
"2017/02/13","280.6000","7023072.0000","270.7400","280.7899","270.5100"
|
||||
"2017/02/10","269.2300","3618336.0000","269.7900","270.9500","266.1100"
|
||||
"2017/02/09","269.2000","7812600.0000","266.2500","271.1800","266.1500"
|
||||
"2017/02/08","262.0800","3912428.0000","257.3500","263.3600","256.2000"
|
||||
"2017/02/07","257.4800","4244063.0000","258.1900","260.0000","256.4200"
|
||||
"2017/02/06","257.7700","3557600.0000","251.0000","257.8200","250.6300"
|
||||
"2017/02/03","251.3300","2185230.0000","251.9100","252.1790","249.6800"
|
||||
"2017/02/02","251.5500","2498799.0000","248.3400","252.4200","247.7100"
|
||||
"2017/02/01","249.2400","3953105.0000","253.0500","253.2000","249.0500"
|
||||
"2017/01/31","251.9300","4112013.0000","249.2400","255.8900","247.7000"
|
||||
"2017/01/30","250.6300","3798638.0000","252.5300","255.2899","247.1000"
|
||||
"2017/01/27","252.9500","3161774.0000","251.3800","253.0000","248.5200"
|
||||
"2017/01/26","252.5100","3143717.0000","254.2900","255.7400","250.7500"
|
||||
"2017/01/25","254.4700","5145301.0000","257.3100","258.4600","251.8000"
|
||||
"2017/01/24","254.6100","4958144.0000","250.0000","254.8000","249.6500"
|
||||
"2017/01/23","248.9200","6262097.0000","245.8500","250.8899","245.5000"
|
||||
"2017/01/20","244.7300","4199720.0000","245.4600","246.0000","243.0100"
|
||||
"2017/01/19","243.7600","7717244.0000","247.2500","248.6800","240.7500"
|
||||
"2017/01/18","238.3600","3767272.0000","236.6500","239.7100","235.5800"
|
||||
"2017/01/17","235.5800","4614731.0000","236.7000","239.9600","234.3700"
|
||||
"2017/01/13","237.7500","6085610.0000","230.0000","237.8500","229.5900"
|
||||
"2017/01/12","229.5900","3787547.0000","229.0600","230.7000","225.5800"
|
||||
"2017/01/11","229.7300","3649910.0000","229.0700","229.9800","226.6800"
|
||||
"2017/01/10","229.8700","3658981.0000","232.0000","232.0000","226.8900"
|
||||
"2017/01/09","231.2800","3972716.0000","228.9700","231.9200","228.0000"
|
||||
"2017/01/06","229.0100","5524153.0000","226.9300","230.3100","225.4500"
|
||||
"2017/01/05","226.7500","5908927.0000","226.4200","227.4800","221.9500"
|
||||
"2017/01/04","226.9900","11204560.0000","214.7500","228.0000","214.3100"
|
||||
"2017/01/03","216.9900","5901494.0000","214.8600","220.3300","210.9600"
|
||||
"2016/12/30","213.6900","4641288.0000","216.3000","217.5000","211.6800"
|
||||
"2016/12/29","214.6800","4043086.0000","218.5600","219.2000","214.1225"
|
||||
"2016/12/28","219.7400","3778544.0000","221.5300","223.8000","217.2000"
|
||||
"2016/12/27","219.5300","5913335.0000","214.8800","222.2500","214.4200"
|
||||
"2016/12/23","213.3400","4668263.0000","208.0000","213.4500","207.7100"
|
||||
"2016/12/22","208.4500","3108427.0000","208.2200","209.9900","206.5000"
|
||||
"2016/12/21","207.7000","5206143.0000","208.4500","212.2300","207.4100"
|
||||
"2016/12/20","208.7900","4684269.0000","203.0500","209.0000","202.5000"
|
||||
"2016/12/19","202.7300","3486937.0000","202.4900","204.4500","199.8400"
|
||||
"2016/12/16","202.4900","3795444.0000","198.0800","202.5900","197.6000"
|
||||
"2016/12/15","197.5800","3218653.0000","198.4100","200.7400","197.3900"
|
||||
"2016/12/14","198.6900","4147314.0000","198.7400","203.0000","196.7600"
|
||||
"2016/12/13","198.1500","6819322.0000","193.1800","201.2800","193.0000"
|
||||
"2016/12/12","192.4300","2436428.0000","192.8000","194.4200","191.0400"
|
||||
"2016/12/09","192.1800","2720937.0000","190.8700","193.8360","190.8100"
|
||||
"2016/12/08","192.2900","3193684.0000","192.0500","192.5000","189.5400"
|
||||
"2016/12/07","193.1500","5457071.0000","186.1500","193.4000","185.0000"
|
||||
"2016/12/06","185.8500","3389365.0000","185.5200","186.5800","182.6825"
|
||||
"2016/12/05","186.8000","4069480.0000","182.5100","188.8900","182.5100"
|
||||
"2016/12/02","181.4700","4040201.0000","182.8800","184.8800","180.0000"
|
||||
"2016/12/01","181.8800","5119105.0000","188.2500","188.5300","181.0000"
|
||||
"2016/11/30","189.4000","3544891.0000","191.0000","191.8900","187.5000"
|
||||
"2016/11/29","189.5700","4435312.0000","195.5600","196.7300","189.5000"
|
||||
"2016/11/28","196.1200","4521082.0000","195.4800","199.3500","194.5500"
|
||||
"2016/11/25","196.6500","2366098.0000","193.6400","197.2372","193.6400"
|
||||
"2016/11/23","193.1400","4890285.0000","190.6100","195.6440","189.0000"
|
||||
"2016/11/22","191.1700","5601238.0000","185.8400","191.4700","183.7100"
|
||||
"2016/11/21","184.5200","4355872.0000","185.0400","188.8900","184.4100"
|
||||
"2016/11/18","185.0200","5206473.0000","190.6500","193.0000","185.0000"
|
||||
"2016/11/17","188.6600","4880969.0000","183.4900","189.4900","182.1101"
|
||||
"2016/11/16","183.9300","3432668.0000","182.6500","184.7300","181.2100"
|
||||
"2016/11/15","183.7700","3899743.0000","182.7800","186.4300","182.0500"
|
||||
"2016/11/14","181.4500","6547913.0000","188.0000","188.2500","178.1900"
|
||||
"2016/11/11","188.5600","3987091.0000","184.2400","188.8800","183.0000"
|
||||
"2016/11/10","185.3500","6746290.0000","191.0500","191.6100","180.4200"
|
||||
"2016/11/09","190.0600","8166447.0000","186.8750","192.0000","183.9500"
|
||||
"2016/11/08","194.9400","3252927.0000","193.7900","197.4900","191.2600"
|
||||
"2016/11/07","193.2100","3857682.0000","193.5900","194.2900","190.0500"
|
||||
"2016/11/04","190.5600","5143915.0000","189.0000","193.4600","185.9600"
|
||||
"2016/11/03","187.4200","2644550.0000","189.0000","191.4700","187.0401"
|
||||
"2016/11/02","188.0200","4242250.0000","190.0500","192.6951","187.5050"
|
||||
"2016/11/01","190.7900","7023674.0000","198.0400","198.5000","188.1050"
|
||||
"2016/10/31","197.7300","4691320.0000","202.4900","202.4900","195.8100"
|
||||
"2016/10/28","199.9700","4273456.0000","204.0000","205.3200","199.8300"
|
||||
"2016/10/27","204.0100","13070990.0000","211.3400","213.7000","201.6500"
|
||||
"2016/10/26","202.2400","5346893.0000","201.0000","203.1900","200.1000"
|
||||
"2016/10/25","202.3400","2442118.0000","202.9000","204.6900","201.2000"
|
||||
"2016/10/24","202.7600","2747344.0000","201.0000","203.9452","200.2500"
|
||||
"2016/10/21","200.0900","2936908.0000","198.6000","201.5700","197.4100"
|
||||
"2016/10/20","199.1000","5069410.0000","202.1200","203.0000","197.0500"
|
||||
"2016/10/19","203.5600","6966185.0000","199.7400","206.6600","198.0600"
|
||||
"2016/10/18","199.1000","5676046.0000","195.9900","199.4700","193.2600"
|
||||
"2016/10/17","193.9600","4518331.0000","197.0500","198.3900","192.0000"
|
||||
"2016/10/14","196.5100","4265471.0000","200.6600","201.4300","196.3000"
|
||||
"2016/10/13","200.2400","2495140.0000","200.5000","200.8950","197.0500"
|
||||
"2016/10/12","201.5100","1969099.0000","200.9500","203.8800","200.4200"
|
||||
"2016/10/11","200.1000","2326754.0000","201.8500","202.2000","198.3100"
|
||||
"2016/10/10","200.9500","3311340.0000","201.3500","204.1400","199.6600"
|
||||
"2016/10/07","196.6100","3489480.0000","201.0000","201.3200","195.8000"
|
||||
"2016/10/06","201.0000","4697937.0000","202.4600","204.2099","200.2100"
|
||||
"2016/10/05","208.4600","1872456.0000","212.2400","213.1500","208.1200"
|
||||
"2016/10/04","211.4100","3537953.0000","213.1000","213.3200","208.8200"
|
||||
"2016/10/03","213.7000","5989342.0000","212.3000","215.6688","208.2500"
|
||||
"2016/09/30","204.0300","2581730.0000","202.2100","204.9800","199.5500"
|
||||
"2016/09/29","200.7000","2714040.0000","205.6000","207.3300","200.5800"
|
||||
"2016/09/28","206.2700","2079324.0000","207.5100","208.2500","205.2600"
|
||||
"2016/09/27","205.8100","3367907.0000","209.6500","209.9818","204.6093"
|
||||
"2016/09/26","208.9900","2393373.0000","206.5000","211.0000","206.5000"
|
||||
"2016/09/23","207.4500","2904125.0000","205.9900","210.1800","205.6700"
|
||||
"2016/09/22","206.4300","2381600.0000","206.4000","207.2800","203.0000"
|
||||
"2016/09/21","205.2200","2631285.0000","206.3700","207.0000","201.5600"
|
||||
"2016/09/20","204.6400","2408556.0000","206.8500","207.7500","203.9100"
|
||||
"2016/09/19","206.3400","2298318.0000","207.0000","209.4300","205.0000"
|
||||
"2016/09/16","205.4000","3104266.0000","200.4200","205.7000","199.0000"
|
||||
"2016/09/15","200.4200","3082942.0000","196.4900","202.5193","196.4000"
|
||||
"2016/09/14","196.4100","2256143.0000","195.7500","197.9248","194.8562"
|
||||
"2016/09/13","196.0500","3583140.0000","197.0600","198.4900","193.4500"
|
||||
"2016/09/12","198.3000","3714049.0000","195.0000","201.3690","194.1000"
|
||||
"2016/09/09","194.4700","3753734.0000","199.0900","199.9200","193.7000"
|
||||
"2016/09/08","197.3600","3372293.0000","199.5500","199.8900","196.3600"
|
||||
"2016/09/07","201.7100","3637918.0000","205.5000","206.4968","200.7100"
|
||||
"2016/09/06","202.8300","4386193.0000","199.0200","203.2500","199.0000"
|
||||
"2016/09/02","197.7800","5970154.0000","202.3300","203.2000","196.2000"
|
||||
"2016/09/01","200.7700","7932444.0000","209.0100","211.0999","200.5000"
|
||||
"2016/08/31","212.0100","3274854.0000","210.4300","212.6000","208.6500"
|
||||
"2016/08/30","211.3400","3164222.0000","216.1100","216.1100","210.5200"
|
||||
"2016/08/29","215.2000","3261381.0000","220.1500","220.4000","215.0000"
|
||||
"2016/08/26","219.9900","2238087.0000","222.1400","222.8550","218.8200"
|
||||
"2016/08/25","220.9600","1760212.0000","223.1100","223.8000","220.7700"
|
||||
"2016/08/24","222.6200","2566947.0000","227.0500","227.1500","222.2200"
|
||||
"2016/08/23","224.8400","4747745.0000","224.3200","228.4900","222.8000"
|
||||
"2016/08/22","222.9300","2061692.0000","224.1700","225.1100","222.6800"
|
||||
"2016/08/19","225.0000","1658616.0000","223.5400","225.1690","222.5300"
|
||||
"2016/08/18","223.5100","1699300.0000","223.8200","225.6600","222.2900"
|
||||
"2016/08/17","223.2400","1786408.0000","224.3300","224.8300","222.8000"
|
||||
"2016/08/16","223.6100","2251115.0000","225.4900","227.1900","223.4101"
|
||||
"2016/08/15","225.5900","2017964.0000","226.0200","229.5000","224.9300"
|
||||
"2016/08/12","225.6100","1811850.0000","225.4100","226.6500","224.0400"
|
||||
"2016/08/11","224.9100","1876959.0000","226.1700","227.5700","223.4100"
|
||||
"2016/08/10","225.6500","2336496.0000","228.2400","229.8700","224.6200"
|
||||
"2016/08/09","229.0800","2199766.0000","226.8200","231.5375","226.6500"
|
||||
"2016/08/08","226.1600","2259465.0000","228.0000","229.6000","226.0900"
|
||||
"2016/08/05","230.0300","3190342.0000","230.0000","232.0000","227.4000"
|
||||
"2016/08/04","230.6100","4142155.0000","225.6900","230.8600","222.0500"
|
||||
"2016/08/03","225.7900","3808747.0000","227.3700","229.6990","224.2100"
|
||||
"2016/08/02","227.2000","3928706.0000","229.3700","229.8700","221.4000"
|
||||
"2016/08/01","230.0100","4014048.0000","235.5000","236.6300","229.3800"
|
||||
"2016/07/29","234.7900","3061574.0000","230.7000","235.2800","230.2400"
|
||||
"2016/07/28","230.6100","2415462.0000","227.9500","230.7600","226.6000"
|
||||
"2016/07/27","228.4900","2887028.0000","229.3400","233.3600","226.9200"
|
||||
"2016/07/26","229.5100","3427251.0000","227.6900","230.0000","225.3000"
|
||||
"2016/07/25","230.0100","4479483.0000","222.2700","231.3900","221.3715"
|
||||
"2016/07/22","222.2700","2570462.0000","221.9900","224.5000","218.8800"
|
||||
"2016/07/21","220.5000","4425756.0000","226.0000","227.8470","219.1000"
|
||||
"2016/07/20","228.3600","2556119.0000","226.4700","229.8000","225.0000"
|
||||
"2016/07/19","225.2600","3047535.0000","225.0000","229.1000","224.7500"
|
||||
"2016/07/18","226.2500","3394588.0000","219.6400","227.0900","218.3000"
|
||||
"2016/07/15","220.4000","2230821.0000","222.5200","222.7499","219.6400"
|
||||
"2016/07/14","221.5300","2657899.0000","223.1200","224.9400","221.0500"
|
||||
"2016/07/13","222.5300","3540699.0000","225.5000","225.5900","220.2900"
|
||||
"2016/07/12","224.6500","4573875.0000","224.1000","227.5000","223.2200"
|
||||
"2016/07/11","224.7800","5369066.0000","219.9600","226.7800","219.5100"
|
||||
"2016/07/08","216.7800","4067131.0000","217.8000","219.8100","214.5000"
|
||||
"2016/07/07","215.9400","3603385.0000","213.1000","218.1200","213.0100"
|
||||
"2016/07/06","214.4400","4910285.0000","210.0000","215.2300","209.0000"
|
||||
"2016/07/05","213.9800","5169832.0000","209.7300","214.5441","208.0000"
|
||||
"2016/07/01","216.5000","5396030.0000","206.1400","218.2400","206.0000"
|
||||
"2016/06/30","212.2800","4794440.0000","212.9700","213.4999","209.0200"
|
||||
"2016/06/29","210.1900","5987120.0000","205.1300","211.7800","203.0000"
|
||||
"2016/06/28","201.7900","6158996.0000","201.8900","204.0500","199.4100"
|
||||
"2016/06/27","198.5500","7211823.0000","190.8600","198.8100","187.8700"
|
||||
"2016/06/24","193.1500","6988949.0000","190.0500","195.1200","189.7300"
|
||||
"2016/06/23","196.4000","10098190.0000","195.6900","197.5500","192.1300"
|
||||
"2016/06/22","196.6600","23706100.0000","199.4700","205.9500","195.7500"
|
||||
"2016/06/21","219.6100","2855619.0000","220.6800","222.5690","218.8100"
|
||||
"2016/06/20","219.7000","3549768.0000","219.5000","223.7500","218.2300"
|
||||
"2016/06/17","215.4700","3107734.0000","217.8100","219.9900","214.5000"
|
||||
"2016/06/16","217.9300","2438692.0000","217.4200","218.0400","213.5000"
|
||||
"2016/06/15","217.7000","2905002.0000","216.9500","221.9000","215.1300"
|
||||
"2016/06/14","214.9600","3575822.0000","218.8800","222.2000","212.5300"
|
||||
"2016/06/13","217.8700","4187833.0000","219.5000","225.7700","217.6600"
|
||||
"2016/06/10","218.7900","5994548.0000","227.3900","227.9700","218.4217"
|
||||
"2016/06/09","229.3600","4454222.0000","234.9800","235.3300","227.0600"
|
||||
"2016/06/08","235.5200","5965110.0000","233.8000","240.8450","232.6050"
|
||||
"2016/06/07","232.3400","6194154.0000","222.2400","234.4400","221.5200"
|
||||
"2016/06/06","220.6800","2242634.0000","218.0000","220.9000","215.4500"
|
||||
"2016/06/03","218.9900","2226110.0000","220.0000","221.9400","218.0100"
|
||||
"2016/06/02","218.9600","2017279.0000","219.5900","219.9090","217.1100"
|
||||
"2016/06/01","219.5600","2982270.0000","221.4800","222.4000","216.8900"
|
||||
"2016/05/31","223.2300","2786682.0000","223.0400","224.7497","221.5001"
|
||||
"2016/05/27","223.0400","3645792.0000","224.9900","225.9300","220.7500"
|
||||
"2016/05/26","225.1200","4066512.0000","220.5000","225.2600","219.0500"
|
||||
"2016/05/25","219.5800","3131279.0000","217.9100","221.3600","216.5100"
|
||||
"2016/05/24","217.9100","3009327.0000","216.6000","218.7400","215.1800"
|
||||
"2016/05/23","216.2200","5096751.0000","219.8700","222.6000","215.8600"
|
||||
"2016/05/20","220.2800","8996546.0000","216.9900","220.5500","216.3500"
|
||||
"2016/05/19","215.2100","6817922.0000","213.6200","216.7900","207.3000"
|
||||
"2016/05/18","211.1700","5552692.0000","209.1500","215.3100","207.7500"
|
||||
"2016/05/17","204.6600","2842028.0000","209.0500","209.8199","204.0200"
|
||||
"2016/05/16","208.2900","2945754.0000","208.1500","213.1500","207.9200"
|
||||
"2016/05/13","207.6100","2820616.0000","207.7800","211.2000","206.7000"
|
||||
"2016/05/12","207.2800","3650075.0000","211.4400","211.6700","203.6572"
|
||||
"2016/05/11","208.9600","5159640.0000","207.5900","215.4800","206.0500"
|
||||
"2016/05/10","208.6900","4068053.0000","207.5500","209.4700","205.0000"
|
||||
"2016/05/09","208.9200","4772992.0000","215.7200","216.1500","206.8000"
|
||||
"2016/05/06","214.9300","5683675.0000","210.8700","216.3700","208.1100"
|
||||
"2016/05/05","211.5300","11248340.0000","228.4600","228.6400","209.7900"
|
||||
"2016/05/04","222.5600","8550004.0000","230.2900","234.4600","220.4000"
|
||||
"2016/05/03","232.3200","4296325.0000","237.3600","238.9100","231.6200"
|
||||
"2016/05/02","241.8000","3838958.0000","241.5000","243.1900","234.8200"
|
||||
"2016/04/29","240.7600","5405164.0000","248.1400","248.4300","237.8100"
|
||||
"2016/04/28","247.7100","2515595.0000","249.8500","253.4300","247.4400"
|
||||
"2016/04/27","251.4700","3198105.0000","252.7500","255.0000","249.4000"
|
||||
"2016/04/26","253.7400","3217779.0000","252.0500","255.7300","249.3900"
|
||||
"2016/04/25","251.8200","3665088.0000","253.0100","257.3800","250.7600"
|
||||
"2016/04/22","253.7500","3783126.0000","248.8900","254.0000","245.7100"
|
||||
"2016/04/21","248.2900","2777079.0000","248.9900","250.9000","246.9100"
|
||||
"2016/04/20","249.9700","5192343.0000","246.2600","253.6600","241.5000"
|
||||
"2016/04/19","247.3700","6351360.0000","253.1200","254.3699","241.2510"
|
||||
"2016/04/18","253.8800","4263246.0000","252.2300","258.3100","251.6600"
|
||||
"2016/04/15","254.5100","3748593.0000","251.3100","254.6000","249.1200"
|
||||
"2016/04/14","251.8600","4129258.0000","253.0000","256.8390","251.0501"
|
||||
"2016/04/13","254.5300","4921554.0000","248.5100","255.5000","247.3300"
|
||||
"2016/04/12","247.8200","5755351.0000","249.5000","251.8000","243.6300"
|
||||
"2016/04/11","249.9200","9156404.0000","251.0000","258.9900","245.3000"
|
||||
"2016/04/08","250.0700","7352707.0000","260.5000","260.8200","248.0201"
|
||||
"2016/04/07","257.2000","8845567.0000","266.4500","269.3400","254.5100"
|
||||
"2016/04/06","265.4200","11695760.0000","253.9700","267.7400","253.4500"
|
||||
"2016/04/05","255.4700","9931470.0000","240.5000","256.5600","240.0000"
|
||||
"2016/04/04","246.9900","13381160.0000","249.1200","252.1200","243.6400"
|
||||
"2016/04/01","237.5900","15979910.0000","244.8250","247.9000","233.2500"
|
||||
"2016/03/31","229.7700","7975638.0000","229.3400","237.4200","225.0100"
|
||||
"2016/03/30","226.8900","4025670.0000","235.0900","235.5000","226.5000"
|
||||
"2016/03/29","230.1300","4006037.0000","229.8900","232.3800","225.3300"
|
||||
"2016/03/28","230.2600","3878599.0000","231.6100","234.8100","225.0000"
|
||||
"2016/03/24","227.7500","4956604.0000","215.7800","228.8877","215.0000"
|
||||
"2016/03/23","222.5800","4936203.0000","232.3700","234.7300","222.0300"
|
||||
"2016/03/22","234.2400","4303052.0000","237.2100","238.9900","232.5580"
|
||||
"2016/03/21","238.3200","5289014.0000","235.3400","239.8800","235.0000"
|
||||
"2016/03/18","232.7400","4704761.0000","229.1000","234.4800","228.0600"
|
||||
"2016/03/17","226.3800","3769083.0000","221.4700","228.5000","220.0000"
|
||||
"2016/03/16","221.9300","3511873.0000","218.0000","222.5800","217.0200"
|
||||
"2016/03/15","218.3400","3133230.0000","214.2700","218.9700","211.5000"
|
||||
"2016/03/14","215.1500","4062304.0000","212.6500","216.7200","210.6400"
|
||||
"2016/03/11","207.5000","3339148.0000","207.9300","209.4200","205.3300"
|
||||
"2016/03/10","205.1800","5191602.0000","210.0000","213.2900","200.6710"
|
||||
"2016/03/09","208.7200","3207597.0000","204.5200","209.3726","202.7900"
|
||||
"2016/03/08","202.6000","4175498.0000","203.5000","207.5000","202.2000"
|
||||
"2016/03/07","205.2900","5331097.0000","197.6800","209.7000","197.4000"
|
||||
"2016/03/04","201.0400","6479858.0000","198.0000","204.0300","197.5001"
|
||||
"2016/03/03","195.7400","4822993.0000","188.2800","197.4200","184.2200"
|
||||
"2016/03/02","188.3400","4858631.0000","183.7300","188.5200","181.5000"
|
||||
"2016/03/01","186.3500","6695704.0000","194.2500","195.9484","182.7000"
|
||||
"2016/02/29","191.9300","4495402.0000","192.4000","196.3500","189.2220"
|
||||
"2016/02/26","190.3400","6054061.0000","188.7000","192.0000","185.0000"
|
||||
"2016/02/25","187.4300","5727008.0000","178.6500","188.5192","175.2000"
|
||||
"2016/02/24","179.0000","5385369.0000","172.7500","179.5000","167.8400"
|
||||
"2016/02/23","177.2100","5982993.0000","176.1600","181.7300","173.6800"
|
||||
"2016/02/22","177.7400","5055340.0000","170.1200","178.9100","169.8500"
|
||||
"2016/02/19","166.5800","2955832.0000","163.6600","167.4900","162.5000"
|
||||
"2016/02/18","166.7700","3883107.0000","172.4200","172.9500","164.7700"
|
||||
"2016/02/17","168.6800","5820264.0000","159.0000","169.3400","156.6800"
|
||||
"2016/02/16","155.1700","5561638.0000","158.7000","162.9500","154.1100"
|
||||
"2016/02/12","151.0400","7233264.0000","155.0000","157.0100","143.7000"
|
||||
"2016/02/11","150.4700","14236900.0000","152.0000","163.2600","147.0000"
|
||||
"2016/02/10","143.6700","10104690.0000","150.5000","154.9700","141.7400"
|
||||
"2016/02/09","148.2500","8639661.0000","142.3200","159.7900","141.0500"
|
||||
"2016/02/08","147.9900","9306754.0000","157.1050","157.1500","146.0000"
|
||||
"2016/02/05","162.6000","9434495.0000","171.3000","173.0000","157.7442"
|
||||
"2016/02/04","175.3300","4379442.0000","170.7000","175.9800","166.9900"
|
||||
"2016/02/03","173.4800","7927640.0000","183.5900","183.9400","170.1800"
|
||||
"2016/02/02","182.7800","5764817.0000","192.4200","193.1200","180.2300"
|
||||
"2016/02/01","196.9400","5295685.0000","188.7600","199.5200","182.7500"
|
||||
"2016/01/29","191.2000","2848929.0000","189.9500","193.7400","188.0800"
|
||||
"2016/01/28","189.7000","4586328.0000","190.7900","191.2800","182.4100"
|
||||
"2016/01/27","188.0700","3577353.0000","192.3800","193.2600","185.7700"
|
||||
"2016/01/26","193.5600","4956918.0000","196.7000","197.8200","188.8800"
|
||||
"2016/01/25","196.3800","2695408.0000","200.0600","203.5700","195.8800"
|
||||
"2016/01/22","202.5500","3122066.0000","204.8010","205.5000","199.0300"
|
||||
"2016/01/21","199.9700","3164424.0000","201.5500","203.2300","195.0200"
|
||||
"2016/01/20","198.7000","5826110.0000","199.4000","201.2800","191.2500"
|
||||
"2016/01/19","204.7200","4031271.0000","208.7100","210.4700","200.7800"
|
||||
"2016/01/15","204.9900","5325773.0000","198.9700","205.0700","197.2500"
|
||||
"2016/01/14","206.1800","6490579.0000","202.2100","210.0000","193.3800"
|
||||
"2016/01/13","200.3100","4120993.0000","212.0100","212.6500","200.0000"
|
||||
"2016/01/12","209.9700","3079051.0000","211.6000","213.7395","205.3100"
|
||||
"2016/01/11","207.8500","4090843.0000","214.0100","214.4500","203.0000"
|
||||
"2016/01/08","211.0000","3572360.0000","217.8600","220.4400","210.7700"
|
||||
"2016/01/07","215.6500","3550704.0000","214.1900","218.4400","213.6700"
|
||||
"2016/01/06","219.0400","3774353.0000","220.0000","220.0500","215.9800"
|
||||
"2016/01/05","223.4300","3185525.0000","226.3600","226.8900","220.0000"
|
||||
"2016/01/04","223.4100","6823510.0000","230.7200","231.3800","219.0000"
|
||||
"2015/12/31","240.0100","2713817.0000","238.5100","243.4500","238.3700"
|
||||
"2015/12/30","238.0900","3694448.0000","236.6000","243.6340","235.6707"
|
||||
"2015/12/29","237.1900","2402438.0000","230.0600","237.7200","229.5470"
|
||||
"2015/12/28","228.9500","1900171.0000","231.4900","231.9800","225.5400"
|
||||
"2015/12/24","230.5700","710277.0000","230.5600","231.8800","228.2800"
|
||||
"2015/12/23","229.7000","1551031.0000","232.1800","233.4500","228.1300"
|
||||
"2015/12/22","229.9500","1958836.0000","234.9900","236.5500","229.6300"
|
||||
"2015/12/21","232.5600","1951581.0000","231.6900","235.8300","231.0800"
|
||||
"2015/12/18","230.4600","3008057.0000","232.8900","235.9000","229.2900"
|
||||
"2015/12/17","233.3900","3294460.0000","233.9400","237.7600","229.8149"
|
||||
"2015/12/16","234.5100","5100443.0000","222.1000","234.8800","220.7300"
|
||||
"2015/12/15","221.0900","2241686.0000","221.8200","222.2200","218.0000"
|
||||
"2015/12/14","218.5800","2827797.0000","217.5100","220.9200","214.8700"
|
||||
"2015/12/11","217.0200","3259114.0000","225.2400","225.7500","216.6400"
|
||||
"2015/12/10","227.0700","2070088.0000","224.7100","228.4900","223.6400"
|
||||
"2015/12/09","224.5200","3057036.0000","226.7000","227.5000","220.7200"
|
||||
"2015/12/08","226.7200","2682259.0000","227.5200","228.8000","224.2000"
|
||||
"2015/12/07","231.1300","3140864.0000","227.7000","235.6300","226.1500"
|
||||
"2015/12/04","230.3800","2572014.0000","232.4600","233.2700","227.6600"
|
||||
"2015/12/03","232.7100","2937233.0000","235.4800","237.4500","230.0000"
|
||||
"2015/12/02","231.9900","2980644.0000","237.0000","238.6000","231.2300"
|
||||
"2015/12/01","237.1900","3728562.0000","231.0600","238.0000","231.0500"
|
||||
"2015/11/30","230.2600","2591205.0000","231.7900","234.2800","229.0800"
|
||||
"2015/11/27","231.6100","1949353.0000","231.0600","232.2500","227.0100"
|
||||
"2015/11/25","229.6400","3986945.0000","221.3400","230.8250","220.3750"
|
||||
"2015/11/24","218.2500","2478389.0000","215.3700","221.0000","215.0000"
|
||||
"2015/11/23","217.7500","2525196.0000","217.3500","219.1800","214.6798"
|
||||
"2015/11/20","220.0100","4394199.0000","223.4900","225.0000","213.5800"
|
||||
"2015/11/19","221.8000","2499593.0000","220.5400","226.1900","220.3000"
|
||||
"2015/11/18","221.0700","2810200.0000","214.5000","221.3800","212.5200"
|
||||
"2015/11/17","214.0000","2148326.0000","215.2000","216.0000","211.4000"
|
||||
"2015/11/16","214.3100","2920362.0000","206.0900","214.9800","205.8000"
|
||||
"2015/11/13","207.1900","3423139.0000","212.9500","212.9900","206.5200"
|
||||
"2015/11/12","212.9400","2913511.0000","217.8500","219.0000","212.6600"
|
||||
"2015/11/11","219.0800","3337501.0000","217.7700","219.4800","213.6300"
|
||||
"2015/11/10","216.5000","4612408.0000","223.4800","223.7000","216.0800"
|
||||
"2015/11/09","225.3300","3846179.0000","232.9900","232.9900","224.3100"
|
||||
"2015/11/06","232.3600","2444264.0000","230.7000","233.3590","229.5000"
|
||||
"2015/11/05","231.7700","4494944.0000","230.5800","234.5843","229.1900"
|
||||
"2015/11/04","231.6300","12713530.0000","227.0000","232.7400","225.2000"
|
||||
"2015/11/03","208.3500","8065091.0000","213.8500","214.4400","207.7500"
|
||||
"2015/11/02","213.7900","3924514.0000","208.9200","215.8000","207.2200"
|
||||
"2015/10/30","206.9300","4432433.0000","210.4000","211.6300","203.8900"
|
||||
"2015/10/29","211.6300","1794743.0000","211.7500","213.7481","210.6400"
|
||||
"2015/10/28","212.9600","2726880.0000","211.3100","213.4500","208.3000"
|
||||
"2015/10/27","210.3500","3512832.0000","214.8400","217.1000","207.5100"
|
||||
"2015/10/26","215.2600","3388227.0000","211.3800","215.8800","210.0000"
|
||||
"2015/10/23","209.0900","4226411.0000","215.0000","215.3500","207.6900"
|
||||
"2015/10/22","211.7200","2818801.0000","211.5600","215.7500","209.4000"
|
||||
"2015/10/21","210.0900","4177956.0000","211.9900","214.8100","208.8000"
|
||||
"2015/10/20","213.0300","14877020.0000","227.7200","228.6000","202.0000"
|
||||
"2015/10/19","228.1000","2506836.0000","226.5000","231.1500","224.9400"
|
||||
"2015/10/16","227.0100","4327574.0000","223.0400","230.4805","222.8700"
|
||||
"2015/10/15","221.3100","2835920.0000","216.4300","221.7300","213.7000"
|
||||
|
@@ -0,0 +1,115 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import os
|
||||
import requests
|
||||
from typing import Any, Dict, List, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
class EXASearchTool(BaseModel):
|
||||
"""Wrapper for EXA Search API."""
|
||||
search_url: str = "https://api.exa.ai/search"
|
||||
headers: Dict = {
|
||||
"accept": "application/json",
|
||||
"content-type": "application/json",
|
||||
}
|
||||
max_results: Optional[int] = None
|
||||
|
||||
def run(self, query: str) -> str:
|
||||
"""Run query through EXA and return concatenated results.
|
||||
|
||||
Args:
|
||||
query (str): The search query to use
|
||||
|
||||
Returns:
|
||||
str: The concatenated search results
|
||||
"""
|
||||
payload = {
|
||||
"query": query,
|
||||
"type": "magic",
|
||||
}
|
||||
|
||||
headers = self.headers.copy()
|
||||
headers["x-api-key"] = os.environ['EXA_API_KEY']
|
||||
|
||||
response = requests.post(self.search_url, json=payload, headers=headers)
|
||||
results = response.json()
|
||||
|
||||
if 'results' in results:
|
||||
return self._parse_results(results['results'])
|
||||
return ""
|
||||
|
||||
def results(self, query: str, max_results: Optional[int] = None) -> List[Dict[str, Any]]:
|
||||
"""Run query through EXA and return metadata.
|
||||
|
||||
Args:
|
||||
query (str): The search query to use
|
||||
max_results (Optional[int]): Maximum number of results to return
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: List of result dictionaries
|
||||
"""
|
||||
payload = {
|
||||
"query": query,
|
||||
"type": "magic",
|
||||
}
|
||||
|
||||
headers = self.headers.copy()
|
||||
headers["x-api-key"] = os.environ['EXA_API_KEY']
|
||||
|
||||
response = requests.post(self.search_url, json=payload, headers=headers)
|
||||
results = response.json()
|
||||
|
||||
if 'results' in results:
|
||||
return results['results'][:max_results] if max_results else results['results']
|
||||
return []
|
||||
|
||||
def _parse_results(self, results: List[Dict[str, Any]]) -> str:
|
||||
"""Parse results into a readable string format.
|
||||
|
||||
Args:
|
||||
results (List[Dict[str, Any]]): List of result dictionaries
|
||||
|
||||
Returns:
|
||||
str: Formatted string of results
|
||||
"""
|
||||
strings = []
|
||||
for result in results:
|
||||
try:
|
||||
strings.append('\n'.join([
|
||||
f"Title: {result['title']}",
|
||||
f"Score: {result['score']}",
|
||||
f"Url: {result['url']}",
|
||||
f"ID: {result['id']}",
|
||||
"---"
|
||||
]))
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
content = '\n'.join(strings)
|
||||
return f"\nSearch results: {content}\n"
|
||||
|
||||
# Create an agent with the tool
|
||||
agent = Agent(
|
||||
name="SearchAgent",
|
||||
role="Research Assistant",
|
||||
goal="Search for information about 'AI Agents Framework'",
|
||||
backstory="I am an AI assistant that can search GitHub.",
|
||||
tools=[EXASearchTool],
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create tasks to demonstrate both tools
|
||||
task = Task(
|
||||
name="search_task",
|
||||
description="Search for information about 'AI Agents Framework'",
|
||||
expected_output="Information about AI Agents Framework",
|
||||
agent=agent
|
||||
)
|
||||
|
||||
# Create and start the workflow
|
||||
agents = PraisonAIAgents(
|
||||
agents=[agent],
|
||||
tasks=[task],
|
||||
verbose=True
|
||||
)
|
||||
|
||||
agents.start()
|
||||
Generated
+919
-21
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,39 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "praison",
|
||||
"path": ".praison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent
|
||||
rag_agent = Agent(
|
||||
name="RAG Agent",
|
||||
role="Information Specialist",
|
||||
goal="Retrieve knowledge efficiently",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
rag_task = Task(
|
||||
name="RAG Task",
|
||||
description="What is KAG?",
|
||||
expected_output="Answer to the question",
|
||||
agent=rag_agent,
|
||||
context=[config] # Vector Database provided as context
|
||||
)
|
||||
|
||||
# Build Agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[rag_agent],
|
||||
tasks=[rag_task],
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start Agents
|
||||
agents.start()
|
||||
@@ -0,0 +1,36 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Video Analysis Agent
|
||||
video_agent = Agent(
|
||||
name="VideoAnalyst",
|
||||
role="Video Analysis Specialist",
|
||||
goal="Analyze images and videos to extract meaningful information",
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Task with Video File
|
||||
task1 = Task(
|
||||
name="analyze_video",
|
||||
description="""Watch this video and provide:
|
||||
1. A summary of the main events
|
||||
2. Key objects and people visible
|
||||
3. Any text or important information shown
|
||||
4. The overall context and setting""",
|
||||
expected_output="Comprehensive analysis of the video content",
|
||||
agent=video_agent,
|
||||
images=["video.mp4"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[video_agent],
|
||||
tasks=[task1],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run all tasks
|
||||
agents.start()
|
||||
@@ -0,0 +1,5 @@
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Web Search Agent", tools=[duckduckgo])
|
||||
agent.start("Search about AI 2024")
|
||||
@@ -0,0 +1,16 @@
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Wikipedia Agent",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
|
||||
self_reflect=True,
|
||||
min_reflect=3,
|
||||
max_reflect=5,
|
||||
)
|
||||
agent.start(
|
||||
"What is the history of AI?"
|
||||
"First search the history of AI"
|
||||
"Read the page of the history of AI"
|
||||
"Get the summary of the page"
|
||||
)
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: "AI Agents"
|
||||
description: "Overview of all available PraisonAI agents and their capabilities"
|
||||
icon: "robot"
|
||||
---
|
||||
|
||||
PraisonAI provides a diverse set of specialized agents for various tasks. Each agent is designed with specific capabilities and tools to handle different types of tasks effectively.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
%% Define the main flow
|
||||
Start([▶ Start]) --> Agent1
|
||||
Agent1 --> Process[⚙ Process]
|
||||
Process --> Agent2
|
||||
Agent2 --> Output([✓ Output])
|
||||
Process -.-> Agent1
|
||||
|
||||
%% Define subgraphs for agents and their tasks
|
||||
subgraph Agent1[ ]
|
||||
Task1[📋 Task]
|
||||
AgentIcon1[🤖 AI Agent]
|
||||
Tools1[🔧 Tools]
|
||||
|
||||
Task1 --- AgentIcon1
|
||||
AgentIcon1 --- Tools1
|
||||
end
|
||||
|
||||
subgraph Agent2[ ]
|
||||
Task2[📋 Task]
|
||||
AgentIcon2[🤖 AI Agent]
|
||||
Tools2[🔧 Tools]
|
||||
|
||||
Task2 --- AgentIcon2
|
||||
AgentIcon2 --- Tools2
|
||||
end
|
||||
|
||||
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
|
||||
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
|
||||
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
|
||||
classDef transparent fill:none,stroke:none
|
||||
|
||||
class Start,Output,Task1,Task2 input
|
||||
class Process,AgentIcon1,AgentIcon2 process
|
||||
class Tools1,Tools2 tools
|
||||
class Agent1,Agent2 transparent
|
||||
```
|
||||
|
||||
## Data & Analysis
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Data Analyst" icon="chart-line" href="/agents/data-analyst">
|
||||
Analyze data from various sources, create visualizations, and generate insights.
|
||||
</Card>
|
||||
<Card title="Finance" icon="money-bill-trend-up" href="/agents/finance">
|
||||
Track stocks, analyze financial data, and provide investment recommendations.
|
||||
</Card>
|
||||
<Card title="Research" icon="magnifying-glass-chart" href="/agents/research">
|
||||
Conduct comprehensive research and analysis across various topics.
|
||||
</Card>
|
||||
<Card title="Wikipedia" icon="book" href="/agents/wikipedia">
|
||||
Search and extract information from Wikipedia articles.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Media & Content
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Image Analysis" icon="image" href="/agents/image">
|
||||
Analyze and understand visual content from images.
|
||||
</Card>
|
||||
<Card title="Image to Text" icon="text" href="/agents/image-to-text">
|
||||
Convert images to textual descriptions and extract text content.
|
||||
</Card>
|
||||
<Card title="Video" icon="video" href="/agents/video">
|
||||
Analyze video content and extract meaningful information.
|
||||
</Card>
|
||||
<Card title="Markdown" icon="markdown" href="/agents/markdown">
|
||||
Generate and format content in Markdown syntax.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Search & Recommendations
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Web Search" icon="globe" href="/agents/websearch">
|
||||
Perform intelligent web searches and gather information.
|
||||
</Card>
|
||||
<Card title="Recommendation" icon="thumbs-up" href="/agents/recommendation">
|
||||
Generate personalized recommendations based on preferences.
|
||||
</Card>
|
||||
<Card title="Shopping" icon="shop" href="/agents/shopping">
|
||||
Compare prices and find the best deals across stores.
|
||||
</Card>
|
||||
<Card title="Planning" icon="calendar" href="/agents/planning">
|
||||
Create travel plans and detailed itineraries.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Development
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Programming" icon="code" href="/agents/programming">
|
||||
Write, analyze, and debug code across multiple languages.
|
||||
</Card>
|
||||
<Card title="Single Agent" icon="circle-1" href="/agents/single">
|
||||
Simple, focused agent for basic tasks without external tools.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Getting Started
|
||||
|
||||
Each agent can be easily initialized and customized for your specific needs. Here's a basic example:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Create an agent with specific instructions
|
||||
agent = Agent(instructions="Your task-specific instructions")
|
||||
|
||||
# Start the agent with a task
|
||||
response = agent.start("Your task description")
|
||||
```
|
||||
|
||||
For more detailed information about each agent, click on the respective cards above.
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: "Data Analyst Agent"
|
||||
sidebarTitle: "Data Analyst"
|
||||
description: "Learn how to create AI agents for data analysis and insights generation."
|
||||
icon: "chart-line"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Data Source] --> Reader[Data Reader]
|
||||
Reader --> Analyzer[Data Analyzer]
|
||||
Analyzer --> Generator[Insights Generator]
|
||||
Generator --> Out[Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Reader fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Data Analyst Agent can read data from various sources, analyze it, and generate insights.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `data_analysis.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import (
|
||||
read_csv, read_excel, write_csv, write_excel,
|
||||
filter_data, get_summary, group_by, pivot_table
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Data Analyst Agent",
|
||||
tools=[
|
||||
read_csv, read_excel, write_csv, write_excel,
|
||||
filter_data, get_summary, group_by, pivot_table
|
||||
]
|
||||
)
|
||||
|
||||
# Start analysis with a specific task
|
||||
agent.start(f"""
|
||||
Read the data from the csv file {os.path.join(os.path.dirname(__file__), "tesla-stock-price.csv")}
|
||||
Analyse the data and give me the insights
|
||||
read_csv to read the file
|
||||
""")
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Data Analysis Workflow
|
||||
|
||||
The Data Analyst Agent is designed to perform comprehensive data analysis tasks using a suite of specialized tools. Here's how it works:
|
||||
|
||||
1. **Data Reading**: The agent can read data from various sources:
|
||||
- CSV files using `read_csv`
|
||||
- Excel files using `read_excel`
|
||||
|
||||
2. **Data Analysis**: Multiple analysis tools are available:
|
||||
- `filter_data`: Filter datasets based on conditions
|
||||
- `get_summary`: Generate statistical summaries
|
||||
- `group_by`: Group data by specific columns
|
||||
- `pivot_table`: Create pivot tables for analysis
|
||||
|
||||
3. **Data Export**: Results can be exported to:
|
||||
- CSV format using `write_csv`
|
||||
- Excel format using `write_excel`
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Multiple Data Sources" icon="table">
|
||||
Support for both CSV and Excel file formats.
|
||||
</Card>
|
||||
<Card title="Analysis Tools" icon="calculator">
|
||||
Comprehensive suite of analysis tools including filtering, summarization, and pivoting.
|
||||
</Card>
|
||||
<Card title="Data Export" icon="file-export">
|
||||
Export capabilities to various formats.
|
||||
</Card>
|
||||
<Card title="Automated Insights" icon="lightbulb">
|
||||
Automatic generation of data insights and patterns.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Analyzing stock data
|
||||
agent.start("""
|
||||
1. Read 'stock_data.csv'
|
||||
2. Filter data for the last 30 days
|
||||
3. Calculate daily returns
|
||||
4. Generate summary statistics
|
||||
5. Export results to 'analysis_results.xlsx'
|
||||
""")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex analysis workflows
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
|
||||
- Check out other specialized agents like the [Finance Agent](/agents/finance) for specific use cases
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "Finance Agent"
|
||||
sidebarTitle: "Finance"
|
||||
description: "Learn how to create AI agents for financial analysis and investment recommendations."
|
||||
icon: "money-bill-trend-up"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Request] --> Price[Stock Price]
|
||||
Price --> Info[Stock Info]
|
||||
Info --> History[Historical Data]
|
||||
History --> Out[Investment Advice]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Price fill:#2E8B57,color:#fff
|
||||
style Info fill:#2E8B57,color:#fff
|
||||
style History fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Finance Agent can analyze stock market data and provide investment recommendations.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `finance_analysis.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import get_stock_price, get_stock_info, get_historical_data
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Research Agent",
|
||||
tools=[get_stock_price, get_stock_info, get_historical_data]
|
||||
)
|
||||
agent.start("Understand current stock price and historical data of Apple and Google. Tell me if I can invest in them")
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Financial Analysis
|
||||
|
||||
The Finance Agent specializes in stock market analysis and investment recommendations using three key components:
|
||||
|
||||
1. **Real-time Price Data**: Uses `get_stock_price` to fetch current market prices
|
||||
2. **Company Information**: Retrieves company details using `get_stock_info`
|
||||
3. **Historical Analysis**: Analyzes trends with `get_historical_data`
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Real-time Data" icon="clock">
|
||||
Access to current stock market prices and information.
|
||||
</Card>
|
||||
<Card title="Company Analysis" icon="building">
|
||||
Detailed company information and fundamentals.
|
||||
</Card>
|
||||
<Card title="Historical Trends" icon="chart-line">
|
||||
Analysis of historical price movements and patterns.
|
||||
</Card>
|
||||
<Card title="Investment Advice" icon="money-bill">
|
||||
AI-powered investment recommendations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Analyzing specific stocks
|
||||
agent.start("""
|
||||
1. Get current prices for AAPL and GOOGL
|
||||
2. Retrieve company information
|
||||
3. Analyze 6-month historical data
|
||||
4. Provide investment recommendations
|
||||
""")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex financial analysis
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
|
||||
- Check out the [Data Analyst Agent](/agents/data-analyst) for detailed data analysis capabilities
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: "Image to Text Agent"
|
||||
sidebarTitle: "Image to Text"
|
||||
description: "Learn how to create AI agents for converting images to textual descriptions and extracting text from images."
|
||||
icon: "text"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Image Input] --> OCR[Text Extractor]
|
||||
OCR --> Analyzer[Content Analyzer]
|
||||
Analyzer --> Generator[Description Generator]
|
||||
Generator --> Out[Text Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style OCR fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Image-to-Text Agent can extract text from images and generate comprehensive descriptions.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `image_to_text.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Image-to-Text Agent
|
||||
image_text_agent = Agent(
|
||||
name="ImageTextConverter",
|
||||
role="Image Text Extraction Specialist",
|
||||
goal="Convert image content to textual descriptions and extract text",
|
||||
backstory="""You are an expert in OCR and image understanding.
|
||||
You excel at extracting text from images and generating detailed descriptions.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create text extraction task
|
||||
extraction_task = Task(
|
||||
name="extract_text",
|
||||
description="Extract all text from this image and describe its layout.",
|
||||
expected_output="Extracted text and layout description",
|
||||
agent=image_text_agent,
|
||||
images=["document.jpg"]
|
||||
)
|
||||
|
||||
# Create description task
|
||||
description_task = Task(
|
||||
name="generate_description",
|
||||
description="Generate a detailed description of the image content.",
|
||||
expected_output="Comprehensive description of visual elements",
|
||||
agent=image_text_agent,
|
||||
images=["scene.jpg"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_text_agent],
|
||||
tasks=[extraction_task, description_task],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Image-to-Text Conversion
|
||||
|
||||
The Image-to-Text Agent combines multiple capabilities to convert visual content into textual form:
|
||||
|
||||
1. **OCR Processing**: Extracts text from images using optical character recognition
|
||||
2. **Layout Analysis**: Understands the spatial arrangement of text and visual elements
|
||||
3. **Content Description**: Generates natural language descriptions of image content
|
||||
4. **Text Formatting**: Preserves text formatting and structure where possible
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Text Extraction" icon="text">
|
||||
Advanced OCR capabilities for text extraction.
|
||||
</Card>
|
||||
<Card title="Layout Understanding" icon="table-layout">
|
||||
Analysis of text and content layout.
|
||||
</Card>
|
||||
<Card title="Content Description" icon="pen-to-square">
|
||||
Detailed descriptions of visual content.
|
||||
</Card>
|
||||
<Card title="Format Preservation" icon="paragraph">
|
||||
Maintains text formatting and structure.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Processing a document image
|
||||
document_task = Task(
|
||||
name="process_document",
|
||||
description="Extract text and analyze document layout",
|
||||
expected_output="Extracted text with layout information",
|
||||
agent=image_text_agent,
|
||||
images=["business_document.jpg"]
|
||||
)
|
||||
|
||||
# Run single task
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_text_agent],
|
||||
tasks=[document_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex document processing
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving text extraction accuracy
|
||||
- Check out the [Image Agent](/agents/image) for pure image analysis capabilities
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: "Image Analysis Agent"
|
||||
sidebarTitle: "Image Analysis"
|
||||
description: "Learn how to create AI agents for image analysis and visual content understanding."
|
||||
icon: "image"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Image Input] --> Analyzer[Image Analyzer]
|
||||
Analyzer --> Detector[Object Detector]
|
||||
Detector --> Generator[Description Generator]
|
||||
Generator --> Out[Analysis Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Detector fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Image Analysis Agent can process and analyze visual content, detect objects, and generate detailed descriptions.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `image_analysis.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Image Analysis Agent
|
||||
image_agent = Agent(
|
||||
name="ImageAnalyst",
|
||||
role="Image Analysis Specialist",
|
||||
goal="Analyze images and videos to extract meaningful information",
|
||||
backstory="""You are an expert in computer vision and image analysis.
|
||||
You excel at describing images, detecting objects, and understanding visual content.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create tasks for different types of analysis
|
||||
task1 = Task(
|
||||
name="analyze_landmark",
|
||||
description="Describe this famous landmark and its architectural features.",
|
||||
expected_output="Detailed description of the landmark's architecture and significance",
|
||||
agent=image_agent,
|
||||
images=["https://example.com/landmark.jpg"]
|
||||
)
|
||||
|
||||
task2 = Task(
|
||||
name="analyze_local_image",
|
||||
description="What objects can you see in this image? Describe their arrangement.",
|
||||
expected_output="Detailed description of objects and their spatial relationships",
|
||||
agent=image_agent,
|
||||
images=["local_image.jpg"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_agent],
|
||||
tasks=[task1, task2],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Image Analysis
|
||||
|
||||
The Image Analysis Agent is designed to process and understand visual content through several key capabilities:
|
||||
|
||||
1. **Image Input**: Supports both URL and local file inputs
|
||||
2. **Object Detection**: Identifies and locates objects within images
|
||||
3. **Architectural Analysis**: Specialized in analyzing architectural features
|
||||
4. **Spatial Understanding**: Describes spatial relationships between objects
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Multiple Input Sources" icon="images">
|
||||
Support for both URL and local image files.
|
||||
</Card>
|
||||
<Card title="Object Detection" icon="magnifying-glass">
|
||||
Advanced object detection and recognition.
|
||||
</Card>
|
||||
<Card title="Architectural Analysis" icon="building">
|
||||
Specialized analysis of architectural features.
|
||||
</Card>
|
||||
<Card title="Detailed Descriptions" icon="pen">
|
||||
Generation of comprehensive visual descriptions.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Analyzing a landmark image
|
||||
landmark_task = Task(
|
||||
name="analyze_famous_landmark",
|
||||
description="Analyze this historical landmark",
|
||||
expected_output="Architectural details and historical significance",
|
||||
agent=image_agent,
|
||||
images=["https://example.com/landmark.jpg"]
|
||||
)
|
||||
|
||||
# Run single task
|
||||
agents = PraisonAIAgents(
|
||||
agents=[image_agent],
|
||||
tasks=[landmark_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex image analysis workflows
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
|
||||
- Check out the [Video Agent](/agents/video) for video content analysis
|
||||
@@ -0,0 +1,120 @@
|
||||
---
|
||||
title: "Markdown Agent"
|
||||
sidebarTitle: "Markdown"
|
||||
description: "Learn how to create AI agents for generating and formatting content in Markdown."
|
||||
icon: "markdown"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Content Request] --> Generator[Content Generator]
|
||||
Generator --> Formatter[Markdown Formatter]
|
||||
Formatter --> Validator[Format Validator]
|
||||
Validator --> Out[Markdown Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Formatter fill:#2E8B57,color:#fff
|
||||
style Validator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Markdown Agent can generate and format content in Markdown syntax.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `markdown_generator.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Create Markdown Agent
|
||||
markdown_agent = Agent(
|
||||
name="MarkdownWriter",
|
||||
role="Markdown Content Specialist",
|
||||
goal="Generate well-formatted content in Markdown syntax",
|
||||
instructions="You are a Markdown Agent, output in markdown format",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Generate content
|
||||
response = markdown_agent.start(
|
||||
"Write a blog post about artificial intelligence"
|
||||
)
|
||||
|
||||
# Save to file
|
||||
with open('blog_post.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Markdown Generation
|
||||
|
||||
The Markdown Agent specializes in creating properly formatted Markdown content:
|
||||
|
||||
1. **Content Generation**: Creates original content based on prompts
|
||||
2. **Markdown Formatting**: Applies proper Markdown syntax
|
||||
3. **Structure Validation**: Ensures correct formatting
|
||||
4. **Document Organization**: Creates well-structured documents
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Content Creation" icon="pen-to-square">
|
||||
Generates original, well-structured content.
|
||||
</Card>
|
||||
<Card title="Markdown Syntax" icon="code">
|
||||
Proper implementation of Markdown formatting.
|
||||
</Card>
|
||||
<Card title="Document Structure" icon="sitemap">
|
||||
Organized document hierarchy and sections.
|
||||
</Card>
|
||||
<Card title="Format Validation" icon="check">
|
||||
Ensures correct Markdown syntax usage.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Generate a technical documentation
|
||||
agent = Agent(
|
||||
instructions="You are a Markdown Agent, output in markdown format"
|
||||
)
|
||||
|
||||
# Generate API documentation
|
||||
response = agent.start("""
|
||||
Create technical documentation for a REST API with:
|
||||
- Introduction
|
||||
- Authentication
|
||||
- Endpoints
|
||||
- Examples
|
||||
""")
|
||||
|
||||
# Save documentation
|
||||
with open('api_docs.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex document generation
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving content quality
|
||||
- Check out the [Documentation Agent](/agents/documentation) for specialized documentation generation
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Planning Agent"
|
||||
sidebarTitle: "Planning"
|
||||
description: "Learn how to create AI agents for trip planning and itinerary generation."
|
||||
icon: "calendar"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Request] --> Search[Web Search]
|
||||
Search --> Analyzer[Options Analyzer]
|
||||
Analyzer --> Generator[Plan Generator]
|
||||
Generator --> Out[Itinerary]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Planning Agent can search for travel options and create detailed itineraries.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `travel_planner.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create Planning Agent
|
||||
planning_agent = Agent(
|
||||
name="TravelPlanner",
|
||||
role="Travel Planning Specialist",
|
||||
goal="Create comprehensive travel plans and itineraries",
|
||||
instructions="You are a Planning Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Generate travel plan
|
||||
response = planning_agent.start(
|
||||
"I want to go to London next week, find me a good hotel and flight"
|
||||
)
|
||||
|
||||
# Save plan
|
||||
with open('travel_plan.txt', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Travel Planning
|
||||
|
||||
The Planning Agent combines multiple capabilities to create comprehensive travel plans:
|
||||
|
||||
1. **Web Search**: Uses DuckDuckGo to find current travel options
|
||||
2. **Options Analysis**: Evaluates and compares different choices
|
||||
3. **Plan Generation**: Creates detailed itineraries
|
||||
4. **Recommendations**: Provides personalized suggestions
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Flight Search" icon="plane">
|
||||
Finds and compares flight options.
|
||||
</Card>
|
||||
<Card title="Hotel Booking" icon="hotel">
|
||||
Recommends suitable accommodations.
|
||||
</Card>
|
||||
<Card title="Itinerary Creation" icon="calendar-days">
|
||||
Generates detailed travel schedules.
|
||||
</Card>
|
||||
<Card title="Real-time Data" icon="clock">
|
||||
Uses current pricing and availability.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Create a weekend trip plan
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Planning Agent", tools=[duckduckgo])
|
||||
agent.start("I want to go London next week, find me a good hotel and flight")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex travel planning
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendations
|
||||
- Check out the [Research Agent](/agents/research) for detailed destination research
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: "Programming Agent"
|
||||
sidebarTitle: "Programming"
|
||||
description: "Learn how to create AI agents for code development, analysis, and execution."
|
||||
icon: "code"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Code Request] --> Analyzer[Code Analyzer]
|
||||
Analyzer --> Generator[Code Generator]
|
||||
Generator --> Executor[Code Executor]
|
||||
Executor --> Debugger[Code Debugger]
|
||||
Debugger --> Out[Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Executor fill:#2E8B57,color:#fff
|
||||
style Debugger fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Programming Agent can analyze, generate, execute, and debug code.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `code_assistant.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import execute_code, analyze_code, format_code, lint_code, disassemble_code # Code Tools
|
||||
from praisonaiagents.tools import execute_command, list_processes, kill_process, get_system_info # Shell Tools
|
||||
from praisonaiagents.tools import duckduckgo # Web Search Tool
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Programming Agent", self_reflect=True, min_reflect=5, max_reflect=10,
|
||||
tools=[execute_code, analyze_code, format_code, lint_code, disassemble_code, execute_command, list_processes, kill_process, get_system_info, duckduckgo]
|
||||
)
|
||||
agent.start(
|
||||
"Write a python script using yfinance to find the stock price of Tesla"
|
||||
"First check if required packages are installed"
|
||||
"Run it using execute_code"
|
||||
"execute_command if you want to run any terminal command"
|
||||
"search internet using duckduckgo if you want to know update python package information"
|
||||
"Analyse the output using analyze_code and fix error if required"
|
||||
"if no package is installed, install it"
|
||||
"then run the code"
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Code Development
|
||||
|
||||
The Programming Agent combines multiple tools for comprehensive code development:
|
||||
|
||||
1. **Code Tools**:
|
||||
- `execute_code`: Run Python code
|
||||
- `analyze_code`: Analyze code structure
|
||||
- `format_code`: Format code to standards
|
||||
- `lint_code`: Check code quality
|
||||
- `disassemble_code`: View bytecode
|
||||
|
||||
2. **Shell Tools**:
|
||||
- `execute_command`: Run terminal commands
|
||||
- `list_processes`: View running processes
|
||||
- `kill_process`: Terminate processes
|
||||
- `get_system_info`: System information
|
||||
|
||||
3. **Web Tools**:
|
||||
- `duckduckgo`: Search for programming resources
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Code Execution" icon="play">
|
||||
Run and test code directly.
|
||||
</Card>
|
||||
<Card title="Code Analysis" icon="magnifying-glass-code">
|
||||
Analyze and improve code quality.
|
||||
</Card>
|
||||
<Card title="System Integration" icon="terminal">
|
||||
Execute system commands and manage processes.
|
||||
</Card>
|
||||
<Card title="Package Management" icon="box">
|
||||
Handle dependencies and installations.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Create and run a data analysis script
|
||||
response = agent.start("""
|
||||
1. Create a script that:
|
||||
- Uses pandas for data analysis
|
||||
- Reads a CSV file
|
||||
- Performs basic statistics
|
||||
- Creates a visualization
|
||||
2. Check and install required packages
|
||||
3. Execute and analyze the results
|
||||
""")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex development workflows
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving code quality
|
||||
- Check out the [Data Analyst Agent](/agents/data-analyst) for specialized data analysis
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Recommendation Agent"
|
||||
sidebarTitle: "Recommendation"
|
||||
description: "Learn how to create AI agents for personalized recommendations across various domains."
|
||||
icon: "thumbs-up"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[User Preferences] --> Search[Content Search]
|
||||
Search --> Analyzer[Preference Analyzer]
|
||||
Analyzer --> Generator[Recommendation Generator]
|
||||
Generator --> Out[Recommendations]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Generator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Recommendation Agent can analyze preferences and generate personalized recommendations.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `recommendation_system.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create Recommendation Agent
|
||||
recommendation_agent = Agent(
|
||||
name="RecommendationEngine",
|
||||
role="Recommendation Specialist",
|
||||
goal="Generate personalized recommendations based on preferences",
|
||||
instructions="You are a Recommendation Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Get recommendations
|
||||
response = recommendation_agent.start(
|
||||
"Recommend me a good movie to watch in 2025"
|
||||
)
|
||||
|
||||
# Save recommendations
|
||||
with open('recommendations.txt', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Recommendation System
|
||||
|
||||
The Recommendation Agent uses multiple approaches to generate personalized suggestions:
|
||||
|
||||
1. **Content Search**: Uses DuckDuckGo to find current options
|
||||
2. **Preference Analysis**: Understands user preferences
|
||||
3. **Recommendation Generation**: Creates personalized suggestions
|
||||
4. **Content Filtering**: Filters based on relevance and quality
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Personalization" icon="user">
|
||||
Tailored recommendations based on preferences.
|
||||
</Card>
|
||||
<Card title="Real-time Data" icon="clock">
|
||||
Up-to-date content and information.
|
||||
</Card>
|
||||
<Card title="Multi-domain" icon="layer-group">
|
||||
Recommendations across various categories.
|
||||
</Card>
|
||||
<Card title="Content Filtering" icon="filter">
|
||||
Quality-based content selection.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Get personalized recommendations
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Recommendation Agent", tools=[duckduckgo])
|
||||
agent.start("Recommend me a good movie to watch in 2025")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex recommendation systems
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving recommendation accuracy
|
||||
- Check out the [Research Agent](/agents/research) for detailed content research
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: "Research Agent"
|
||||
sidebarTitle: "Research"
|
||||
description: "Learn how to create AI agents for conducting comprehensive research and analysis."
|
||||
icon: "magnifying-glass-chart"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Research Query] --> Search[Web Search]
|
||||
Search --> Analyzer[Content Analyzer]
|
||||
Analyzer --> Synthesizer[Information Synthesizer]
|
||||
Synthesizer --> Out[Research Report]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Synthesizer fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Research Agent can gather, analyze, and synthesize information from various sources.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `research_assistant.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create Research Agent
|
||||
research_agent = Agent(
|
||||
name="ResearchAssistant",
|
||||
role="Research Specialist",
|
||||
goal="Conduct comprehensive research and analysis",
|
||||
instructions="You are a Research Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Conduct research
|
||||
response = research_agent.start(
|
||||
"Research about AI developments in 2024"
|
||||
)
|
||||
|
||||
# Save research findings
|
||||
with open('research_report.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Research Process
|
||||
|
||||
The Research Agent employs a systematic approach to information gathering and analysis:
|
||||
|
||||
1. **Web Search**: Uses DuckDuckGo to find relevant sources
|
||||
2. **Content Analysis**: Evaluates source credibility and relevance
|
||||
3. **Information Synthesis**: Combines findings into coherent insights
|
||||
4. **Report Generation**: Creates structured research reports
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Web Research" icon="globe">
|
||||
Comprehensive online information gathering.
|
||||
</Card>
|
||||
<Card title="Content Analysis" icon="microscope">
|
||||
In-depth evaluation of sources.
|
||||
</Card>
|
||||
<Card title="Information Synthesis" icon="layer-group">
|
||||
Integration of multiple sources.
|
||||
</Card>
|
||||
<Card title="Report Generation" icon="file-lines">
|
||||
Structured research documentation.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Research Agent", tools=[duckduckgo])
|
||||
agent.start("Research about AI 2024")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex research projects
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
|
||||
- Check out the [Data Analyst Agent](/agents/data-analyst) for data-driven research
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: "Shopping Agent"
|
||||
sidebarTitle: "Shopping"
|
||||
description: "Learn how to create AI agents for price comparison and shopping assistance."
|
||||
icon: "shop"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Product Query] --> Search[Store Search]
|
||||
Search --> Analyzer[Price Analyzer]
|
||||
Analyzer --> Comparator[Price Comparator]
|
||||
Comparator --> Out[Price Report]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Comparator fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Shopping Agent can search for products, compare prices, and provide shopping recommendations.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `shopping_assistant.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create Shopping Agent
|
||||
shopping_agent = Agent(
|
||||
name="ShoppingAssistant",
|
||||
role="Shopping Specialist",
|
||||
goal="Find the best prices and deals across stores",
|
||||
instructions="You are a Shopping Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Search for product prices
|
||||
response = shopping_agent.start(
|
||||
"I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table"
|
||||
)
|
||||
|
||||
# Save price comparison
|
||||
with open('price_comparison.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Shopping Assistant
|
||||
|
||||
The Shopping Agent combines multiple capabilities for effective price comparison:
|
||||
|
||||
1. **Store Search**: Uses DuckDuckGo to find retailers
|
||||
2. **Price Analysis**: Gathers pricing information
|
||||
3. **Price Comparison**: Compares prices across stores
|
||||
4. **Deal Finding**: Identifies special offers and discounts
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Price Comparison" icon="scale-balanced">
|
||||
Compare prices across multiple stores.
|
||||
</Card>
|
||||
<Card title="Deal Detection" icon="tag">
|
||||
Find special offers and discounts.
|
||||
</Card>
|
||||
<Card title="Store Analysis" icon="store">
|
||||
Evaluate retailer reliability.
|
||||
</Card>
|
||||
<Card title="Price Tracking" icon="chart-line">
|
||||
Monitor price changes over time.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Compare product prices
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(instructions="You are a Shopping Agent", tools=[duckduckgo])
|
||||
agent.start("I want to buy iPhone 16 Pro Max, check 5 stores and give me price in table")
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex shopping research
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving price accuracy
|
||||
- Check out the [Research Agent](/agents/research) for detailed product research
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: "Single Agent"
|
||||
sidebarTitle: "Single"
|
||||
description: "Learn how to create a basic single-purpose AI agent for simple tasks."
|
||||
icon: "circle-1"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Input] --> Agent[Single Agent]
|
||||
Agent --> Out[Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Agent fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how to create and use a simple single-purpose agent.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `simple_agent.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(instructions="You are a Markdown Agent, output in markdown format")
|
||||
agent.start("Write a blog post about AI")
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Single Agent
|
||||
|
||||
The Single Agent is the simplest form of PraisonAI agent:
|
||||
|
||||
1. **Simple Setup**: Minimal configuration required
|
||||
2. **Single Purpose**: Focused on one specific task
|
||||
3. **Direct Execution**: Straightforward input-output flow
|
||||
4. **No Dependencies**: No external tools required
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Simple Setup" icon="square-1">
|
||||
Minimal configuration needed.
|
||||
</Card>
|
||||
<Card title="Focused Task" icon="bullseye">
|
||||
Single-purpose execution.
|
||||
</Card>
|
||||
<Card title="Quick Start" icon="bolt">
|
||||
Rapid implementation.
|
||||
</Card>
|
||||
<Card title="No Tools" icon="toolbox">
|
||||
No external dependencies.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Create a content generation agent
|
||||
from praisonaiagents import Agent
|
||||
|
||||
# Create content agent
|
||||
agent = Agent(
|
||||
instructions="You are a Content Generation Agent, create engaging content"
|
||||
)
|
||||
|
||||
# Generate content
|
||||
response = agent.start("""
|
||||
Write a short story about:
|
||||
- A future world
|
||||
- With advanced AI
|
||||
- And human collaboration
|
||||
""")
|
||||
|
||||
# Save the story
|
||||
with open('ai_story.txt', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for more complex workflows
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving output quality
|
||||
- Check out other specialized agents like the [Markdown Agent](/agents/markdown) for specific use cases
|
||||
@@ -0,0 +1,149 @@
|
||||
---
|
||||
title: "Video Agent"
|
||||
sidebarTitle: "Video"
|
||||
description: "Learn how to create AI agents for video analysis and content understanding."
|
||||
icon: "video"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Video Input] --> Analyzer[Content Analyzer]
|
||||
Analyzer --> Detector[Object Detector]
|
||||
Detector --> Transcriber[Text Transcriber]
|
||||
Transcriber --> Out[Analysis Report]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Analyzer fill:#2E8B57,color:#fff
|
||||
style Detector fill:#2E8B57,color:#fff
|
||||
style Transcriber fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Video Agent can analyze video content, detect objects, and extract meaningful information.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `video_analyzer.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
# Create Video Analysis Agent
|
||||
video_agent = Agent(
|
||||
name="VideoAnalyst",
|
||||
role="Video Analysis Specialist",
|
||||
goal="Analyze videos to extract meaningful information",
|
||||
backstory="""You are an expert in computer vision and video analysis.
|
||||
You excel at describing content, detecting objects, and understanding context.""",
|
||||
llm="gpt-4o-mini",
|
||||
self_reflect=False
|
||||
)
|
||||
|
||||
# Create video analysis task
|
||||
analysis_task = Task(
|
||||
name="analyze_video",
|
||||
description="""Analyze this video and provide:
|
||||
1. Summary of main events
|
||||
2. Key objects and people
|
||||
3. Text and important information
|
||||
4. Context and setting""",
|
||||
expected_output="Comprehensive video analysis",
|
||||
agent=video_agent,
|
||||
images=["video.mp4"]
|
||||
)
|
||||
|
||||
# Create PraisonAIAgents instance
|
||||
agents = PraisonAIAgents(
|
||||
agents=[video_agent],
|
||||
tasks=[analysis_task],
|
||||
process="sequential",
|
||||
verbose=1
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents.start()
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Video Analysis
|
||||
|
||||
The Video Agent combines multiple capabilities for comprehensive video understanding:
|
||||
|
||||
1. **Content Analysis**: Analyzes video scenes and events
|
||||
2. **Object Detection**: Identifies objects and people
|
||||
3. **Text Extraction**: Captures text shown in videos
|
||||
4. **Context Understanding**: Interprets settings and situations
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Scene Analysis" icon="film">
|
||||
Detailed analysis of video scenes.
|
||||
</Card>
|
||||
<Card title="Object Detection" icon="cube">
|
||||
Identification of objects and people.
|
||||
</Card>
|
||||
<Card title="Text Extraction" icon="closed-captioning">
|
||||
Capture of text and captions.
|
||||
</Card>
|
||||
<Card title="Context Analysis" icon="sitemap">
|
||||
Understanding of video context.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Analyze a presentation video
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
|
||||
video_agent = Agent(
|
||||
name="VideoAnalyst",
|
||||
role="Video Analysis Specialist",
|
||||
goal="Extract information from presentation videos",
|
||||
llm="gpt-4o-mini"
|
||||
)
|
||||
|
||||
# Create presentation analysis task
|
||||
presentation_task = Task(
|
||||
name="analyze_presentation",
|
||||
description="""Analyze this presentation video:
|
||||
1. Extract key points
|
||||
2. Capture slide content
|
||||
3. Note speaker's main arguments
|
||||
4. Summarize Q&A session""",
|
||||
expected_output="Detailed presentation summary",
|
||||
agent=video_agent,
|
||||
images=["presentation.mp4"]
|
||||
)
|
||||
|
||||
# Run analysis
|
||||
agents = PraisonAIAgents(
|
||||
agents=[video_agent],
|
||||
tasks=[presentation_task],
|
||||
process="sequential"
|
||||
)
|
||||
agents.start()
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex video analysis
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving analysis accuracy
|
||||
- Check out the [Image Agent](/agents/image) for still image analysis
|
||||
@@ -0,0 +1,124 @@
|
||||
---
|
||||
title: "Web Search Agent"
|
||||
sidebarTitle: "Web Search"
|
||||
description: "Learn how to create AI agents for intelligent web searching and information gathering."
|
||||
icon: "globe"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Search Query] --> Search[Web Search]
|
||||
Search --> Filter[Content Filter]
|
||||
Filter --> Summarizer[Content Summarizer]
|
||||
Summarizer --> Out[Search Results]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Filter fill:#2E8B57,color:#fff
|
||||
style Summarizer fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Web Search Agent can perform intelligent searches and process web content.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `web_search.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
# Create Web Search Agent
|
||||
search_agent = Agent(
|
||||
name="WebSearcher",
|
||||
role="Web Search Specialist",
|
||||
goal="Perform intelligent web searches and gather information",
|
||||
instructions="You are a Web Search Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Perform search
|
||||
response = search_agent.start(
|
||||
"Search about AI developments in 2024"
|
||||
)
|
||||
|
||||
# Save search results
|
||||
with open('search_results.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Web Search
|
||||
|
||||
The Web Search Agent employs sophisticated search strategies:
|
||||
|
||||
1. **Query Processing**: Optimizes search queries
|
||||
2. **Content Filtering**: Filters relevant results
|
||||
3. **Information Extraction**: Extracts key information
|
||||
4. **Result Summarization**: Summarizes findings
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Smart Search" icon="magnifying-glass">
|
||||
Intelligent query processing.
|
||||
</Card>
|
||||
<Card title="Content Filtering" icon="filter">
|
||||
Relevance-based filtering.
|
||||
</Card>
|
||||
<Card title="Information Extraction" icon="scissors">
|
||||
Key information extraction.
|
||||
</Card>
|
||||
<Card title="Result Summary" icon="list">
|
||||
Concise result summaries.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Perform topic research
|
||||
from praisonaiagents import Agent, Tools
|
||||
from praisonaiagents.tools import duckduckgo
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Web Search Agent",
|
||||
tools=[duckduckgo]
|
||||
)
|
||||
|
||||
# Research specific topic
|
||||
response = agent.start("""
|
||||
Search for information about quantum computing:
|
||||
- Recent breakthroughs
|
||||
- Leading companies
|
||||
- Current applications
|
||||
- Future predictions
|
||||
""")
|
||||
|
||||
# Save research results
|
||||
with open('quantum_computing_research.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex search workflows
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving search relevance
|
||||
- Check out the [Research Agent](/agents/research) for comprehensive research capabilities
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: "Wikipedia Agent"
|
||||
sidebarTitle: "Wikipedia"
|
||||
description: "Learn how to create AI agents for searching and extracting information from Wikipedia."
|
||||
icon: "book"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
In[Query] --> Search[Wiki Search]
|
||||
Search --> Page[Page Retrieval]
|
||||
Page --> Summary[Content Summary]
|
||||
Summary --> Out[Knowledge Output]
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Search fill:#2E8B57,color:#fff
|
||||
style Page fill:#2E8B57,color:#fff
|
||||
style Summary fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
A workflow demonstrating how the Wikipedia Agent can search, retrieve, and summarize Wikipedia content.
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
First, install the PraisonAI Agents package:
|
||||
```bash
|
||||
pip install praisonaiagents
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key as an environment variable:
|
||||
```bash
|
||||
export OPENAI_API_KEY=your_api_key_here
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `wikipedia_assistant.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
from praisonaiagents.tools import (
|
||||
wiki_search,
|
||||
wiki_summary,
|
||||
wiki_page,
|
||||
wiki_random,
|
||||
wiki_language
|
||||
)
|
||||
|
||||
# Create Wikipedia Agent
|
||||
wiki_agent = Agent(
|
||||
name="WikipediaAssistant",
|
||||
role="Wikipedia Research Specialist",
|
||||
goal="Extract and summarize Wikipedia content",
|
||||
instructions="You are a Wikipedia Agent",
|
||||
tools=[
|
||||
wiki_search,
|
||||
wiki_summary,
|
||||
wiki_page,
|
||||
wiki_random,
|
||||
wiki_language
|
||||
],
|
||||
self_reflect=True,
|
||||
min_reflect=3,
|
||||
max_reflect=5
|
||||
)
|
||||
|
||||
# Research a topic
|
||||
response = wiki_agent.start("""
|
||||
What is the history of AI?
|
||||
First search the history of AI
|
||||
Read the page of the history of AI
|
||||
Get the summary of the page
|
||||
""")
|
||||
|
||||
# Save research results
|
||||
with open('ai_history.md', 'w') as f:
|
||||
f.write(response)
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Understanding Wikipedia Research
|
||||
|
||||
The Wikipedia Agent provides comprehensive Wikipedia access through multiple tools:
|
||||
|
||||
1. **Wiki Search**: `wiki_search` for finding relevant articles
|
||||
2. **Page Access**: `wiki_page` for retrieving full articles
|
||||
3. **Summarization**: `wiki_summary` for concise overviews
|
||||
4. **Random Articles**: `wiki_random` for discovering content
|
||||
5. **Language Support**: `wiki_language` for multilingual access
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Article Search" icon="magnifying-glass">
|
||||
Find relevant Wikipedia articles.
|
||||
</Card>
|
||||
<Card title="Content Retrieval" icon="book-open">
|
||||
Access complete article content.
|
||||
</Card>
|
||||
<Card title="Summarization" icon="compress">
|
||||
Generate concise article summaries.
|
||||
</Card>
|
||||
<Card title="Multilingual" icon="language">
|
||||
Access content in multiple languages.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Example Usage
|
||||
|
||||
```python
|
||||
# Example: Research a scientific topic
|
||||
from praisonaiagents import Agent
|
||||
from praisonaiagents.tools import wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language
|
||||
|
||||
agent = Agent(
|
||||
instructions="You are a Wikipedia Agent",
|
||||
tools=[wiki_search, wiki_summary, wiki_page, wiki_random, wiki_language],
|
||||
self_reflect=True,
|
||||
min_reflect=3,
|
||||
max_reflect=5,
|
||||
)
|
||||
agent.start(
|
||||
"What is the history of AI?"
|
||||
"First search the history of AI"
|
||||
"Read the page of the history of AI"
|
||||
"Get the summary of the page"
|
||||
)
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Prompt Chaining](/features/promptchaining) for complex Wikipedia research
|
||||
- Explore [Evaluator Optimizer](/features/evaluator-optimiser) for improving research quality
|
||||
- Check out the [Research Agent](/agents/research) for broader research capabilities
|
||||
@@ -110,7 +110,7 @@ Loads environment variables from .env file or system and sets them.</p>
|
||||
file.write("FROM python:3.11-slim\n")
|
||||
file.write("WORKDIR /app\n")
|
||||
file.write("COPY . .\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.41 gunicorn markdown\n")
|
||||
file.write("RUN pip install flask praisonai==2.0.55 gunicorn markdown\n")
|
||||
file.write("EXPOSE 8080\n")
|
||||
file.write('CMD ["gunicorn", "-b", "0.0.0.0:8080", "api:app"]\n')
|
||||
|
||||
|
||||
+13
-27
@@ -4,11 +4,8 @@ description: "Understanding Agents in PraisonAI"
|
||||
icon: "user"
|
||||
---
|
||||
|
||||
<Note>
|
||||
Agents are the core building blocks of PraisonAI. Each agent is an autonomous AI entity with specific roles, goals, and capabilities.
|
||||
</Note>
|
||||
|
||||
# Understanding Agents
|
||||
Agents are the core building blocks of PraisonAI. Each agent is an autonomous AI entity with specific roles, goals, and capabilities.
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -19,45 +16,34 @@ graph LR
|
||||
Agent2 --> Output([✓ Output])
|
||||
Process -.-> Agent1
|
||||
|
||||
%% Styling for main elements
|
||||
style Start fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
style Output fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
style Process fill:#5C80BC,stroke:#7C90A0,color:#fff
|
||||
|
||||
%% Define subgraphs for agents and their tasks
|
||||
subgraph Agent1[" "]
|
||||
subgraph Agent1[ ]
|
||||
Task1[📋 Task]
|
||||
AgentIcon1[🤖 AI Agent]
|
||||
Tools1[🔧 Tools]
|
||||
|
||||
Task1 --- AgentIcon1
|
||||
AgentIcon1 --- Tools1
|
||||
|
||||
style Task1 fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
style AgentIcon1 fill:#5C80BC,stroke:#7C90A0,color:#fff
|
||||
style Tools1 fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
end
|
||||
|
||||
subgraph Agent2[" "]
|
||||
subgraph Agent2[ ]
|
||||
Task2[📋 Task]
|
||||
AgentIcon2[🤖 AI Agent]
|
||||
Tools2[🔧 Tools]
|
||||
|
||||
Task2 --- AgentIcon2
|
||||
AgentIcon2 --- Tools2
|
||||
|
||||
style Task2 fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
style AgentIcon2 fill:#5C80BC,stroke:#7C90A0,color:#fff
|
||||
style Tools2 fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
end
|
||||
|
||||
%% Style for agent containers
|
||||
style Agent1 fill:#1B1F3B,stroke:#7C90A0,color:#fff
|
||||
style Agent2 fill:#1B1F3B,stroke:#7C90A0,color:#fff
|
||||
|
||||
%% Global styles
|
||||
classDef default fill:#2D3047,stroke:#7C90A0,color:#fff
|
||||
linkStyle default stroke:#7C90A0,stroke-width:2px
|
||||
|
||||
classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
|
||||
classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
|
||||
classDef tools fill:#2E8B57,stroke:#7C90A0,color:#fff
|
||||
classDef transparent fill:none,stroke:none
|
||||
|
||||
class Start,Output,Task1,Task2 input
|
||||
class Process,AgentIcon1,AgentIcon2 process
|
||||
class Tools1,Tools2 tools
|
||||
class Agent1,Agent2 transparent
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
---
|
||||
title: "AI Agents with Knowledge"
|
||||
sidebarTitle: "Knowledge"
|
||||
description: "Learn how to create AI agents with custom knowledge bases"
|
||||
icon: "book"
|
||||
---
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph In[Input]
|
||||
PDF[PDF]
|
||||
TXT[TXT]
|
||||
MD[MD]
|
||||
end
|
||||
|
||||
subgraph Router[Vector Store]
|
||||
DB[(Vector DB)]
|
||||
end
|
||||
|
||||
subgraph Out[Agents]
|
||||
A1[Agent 1]
|
||||
A2[Agent 2]
|
||||
A3[Agent 3]
|
||||
end
|
||||
|
||||
In --> Router
|
||||
Router --> A1
|
||||
Router --> A2
|
||||
Router --> A3
|
||||
|
||||
style In fill:#8B0000,color:#fff
|
||||
style Router fill:#2E8B57,color:#fff
|
||||
style Out fill:#8B0000,color:#fff
|
||||
```
|
||||
|
||||
| Feature | [Knowledge](/concepts/knowledge) | [Memory](/concepts/memory) |
|
||||
|---------|--------------------------------|---------------------------|
|
||||
| When Used | Pre-loaded before agent execution | Created and updated during runtime |
|
||||
| Purpose | Provide static reference information | Store dynamic context and interactions |
|
||||
| Storage | Read-only knowledge base | Read-write memory store |
|
||||
| Persistence | Permanent until explicitly changed | Can be temporary (STM) or persistent (LTM) |
|
||||
| Updates | Manual updates through knowledge files | Automatic updates during agent execution |
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Package">
|
||||
Install PraisonAI Agents with knowledge support:
|
||||
```bash
|
||||
pip install "praisonaiagents[knowledge]"
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Set API Key">
|
||||
Set your OpenAI API key:
|
||||
```bash
|
||||
export OPENAI_API_KEY=xxxxx
|
||||
```
|
||||
</Step>
|
||||
|
||||
<Step title="Create Script">
|
||||
Create a new file `app.py`:
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"]
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Basic Usage
|
||||
|
||||
The simplest way to create a knowledge-based agent is without any configuration:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"]
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
For more control over the knowledge base, you can specify a configuration:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "custom_knowledge",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
agent = Agent(
|
||||
name="Knowledge Agent",
|
||||
instructions="You answer questions based on the provided knowledge.",
|
||||
knowledge=["small.pdf"],
|
||||
knowledge_config=config
|
||||
)
|
||||
|
||||
agent.start("What is KAG in one line?")
|
||||
```
|
||||
|
||||
## Multi-Agent Knowledge System
|
||||
|
||||
For more complex scenarios, you can create a knowledge-based system with multiple agents:
|
||||
|
||||
```python
|
||||
from praisonaiagents import Agent, Task, PraisonAIAgents
|
||||
import logging
|
||||
import os
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Define the configuration for the Knowledge instance
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "knowledge_test",
|
||||
"path": ".praison",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create an agent with knowledge capabilities
|
||||
knowledge_agent = Agent(
|
||||
name="KnowledgeAgent",
|
||||
role="Information Specialist",
|
||||
goal="Store and retrieve knowledge efficiently",
|
||||
backstory="Expert in managing and utilizing stored knowledge",
|
||||
knowledge=["sample.pdf"],
|
||||
knowledge_config=config,
|
||||
verbose=True
|
||||
)
|
||||
|
||||
# Define a task for the agent
|
||||
knowledge_task = Task(
|
||||
name="knowledge_task",
|
||||
description="Who is Mervin Praison?",
|
||||
expected_output="Answer to the question",
|
||||
agent=knowledge_agent
|
||||
)
|
||||
|
||||
# Create and start the agents
|
||||
agents = PraisonAIAgents(
|
||||
agents=[knowledge_agent],
|
||||
tasks=[knowledge_task],
|
||||
process="sequential",
|
||||
user_id="user1"
|
||||
)
|
||||
|
||||
# Start execution
|
||||
result = agents.start()
|
||||
```
|
||||
|
||||
## Understanding Knowledge Configuration
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Vector Store Options">
|
||||
- **Provider**: Choose between different vector store backends (e.g., "chroma")
|
||||
- **Collection Name**: Name for your knowledge collection
|
||||
- **Path**: Location to store the vector database
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Supported File Types">
|
||||
- PDF documents (*.pdf)
|
||||
- Text files (*.txt)
|
||||
- Markdown files (*.md, *.mdx)
|
||||
- And more...
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Multi-Agent Setup">
|
||||
- **Role**: Define specialized roles for knowledge agents
|
||||
- **Goal**: Set specific knowledge management objectives
|
||||
- **Process**: Choose between sequential or parallel execution
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Features
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Custom Knowledge" icon="book">
|
||||
Import your own documents and data as knowledge sources
|
||||
</Card>
|
||||
<Card title="Vector Storage" icon="database">
|
||||
Efficient storage and retrieval of knowledge embeddings
|
||||
</Card>
|
||||
<Card title="Multiple Sources" icon="layer-group">
|
||||
Combine multiple documents and file types
|
||||
</Card>
|
||||
<Card title="Persistent Storage" icon="hard-drive">
|
||||
Save and reuse knowledge bases across sessions
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Document Preparation**
|
||||
- Clean and well-formatted documents work best
|
||||
- Break large documents into smaller chunks
|
||||
- Use consistent formatting
|
||||
|
||||
2. **Knowledge Organization**
|
||||
- Group related documents together
|
||||
- Use meaningful file names
|
||||
- Keep knowledge bases focused and relevant
|
||||
|
||||
3. **Performance Optimization**
|
||||
- Monitor vector store size
|
||||
- Clean up unused collections
|
||||
- Use appropriate chunk sizes
|
||||
|
||||
4. **Multi-Agent Coordination**
|
||||
- Define clear roles and responsibilities
|
||||
- Set appropriate logging levels for debugging
|
||||
- Use unique collection names for different agent groups
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Learn about [Memory Management](/concepts/memory) for long-term recall
|
||||
- Explore [Tool Integration](/concepts/tools) for enhanced capabilities
|
||||
- Check out [Examples](/examples) for implementation ideas
|
||||
Loaded 100 of 236 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user